AppleII-VGA and emulating other retro video subsystems

Recently I came across the AppleII-VGA project by Mark Aikens. It takes a Raspberry Pi Pico, adds some level converter transceivers, then attaches it to the address, data and control signals of an Apple II, and effectively it sits there doing two things. 1. It listens for ‘writes’ coming from the 6502 CPU to the memory where the Apple II thinks its video memory is and 2. It converts those writes into a pixel perfect VGA signal. So it’s like a video output converter that bypasses all the video logic in an Apple II that normally puts out a composite video signal, and instead it converts directly from writes to video memory and creates a perfect VGA image. There’s a fork of it too called ∀2 Analog VGA that adds some additional features.

Of course for someone who emulates ROMs and floppy chips, this is quite a cool project so I had to try it. There is a proper PCB for this, but I just hacked it together on a breadboard and added some jumper wires and used one of those MSX prototype boards I ordered heaps of some time back (though you have to cut some obvious traces to use on anything other than MSX). So the Apple II has 50 pin edge connector slots and conveniently MSX has a 50 pin cartridge slot.

Anyway, when I first hooked it up, it didn’t work at all. Doh!

My spider sense thought “maybe the four 74LVC245’s I had were not 100% genuine” . Fortunately I had four I had bought at my local Jaycar for another project. So I swapped them in and voila:

Loderunner never looked so good.

Actually it looks like I am running an emulator.

Is this cheating?

Probably 😉

Anyway, note to self “Unbelievably cheap 74LVC245s from aliexpress = Yeah right” and “74LVC245s from my local Jaycar = most likely genuine“. Why on earth anyone would go to the trouble of making 74LVC245’s that don’t quite work properly is beyond me. I did actually take a zoomed in look at the top of these fake-ish chips and they have the tell tale rough surface … that I had never noticed before. I guess my ‘guess’ relating to why it wasn’t working was because I also used some 74LVC245s to make a pitubedirect and they didn’t quite seem 100% either. And those 74LVC245s were part of the 10 or so I ordered off aliexpress. I’ve since ordered quite a lot of 74LVC245s from mouser/rs-online/element14/whoever , and at least they should be genuine.

Anyway, the AppleII VGA worked in an Apple II, but that got me thinking “How hard would it be to adapt it to other older computers?”. So then I sat down and stared at the source code for some time and discovered the world of PIOs. They are clever but weird. The rough way the Apple II VGA works is:

  • Have a PIO watching the phi0 signal and r/_w and every time there is a write to RAM, capture the address and databus and control signals and push the result into a FIFO. PIO’s don’t really have access to the Pico’s RAM , so they push to a FIFO
  • Then you get one of the Pico’s two ARM cores watching that FIFO and when there is new data,  it interprets the address, data and control signals and writes the video data to the Picos’ RAM. It’s just in a tight loop waiting for new data on the FIFO and writing it to RAM.
  • Then you have the other  ARM core that is effectively taking a scanline of video data (imagine there is a single scanline of video bytes) , does whatever conversion it needs and then pushes some data into a FIFO.
  • Then at the other end of that FIFO is a another PIO that transforms the data into ‘writes’ to the GPIO pins that form the 9 bit RGB colour. ie. 3 GPIO pins per colour, connected to an R2R network and you end up with an 8 level analog pin. One for Red, One for Green and one for Blue. There are other state machines within that PIO that handle all the synchronisation stuff.
  • This other ARM core just needs to send each scanline of pixels at the right time and you end up with a full screen.

That’s the gist of it. It’s very clever and it does not use any crazy assembly (unless you count the PIO code).

So in doing my floppy emulation projects I have to stare at source code for emulators a lot. They are really good sources of information about how older chips operate, and often emulator authors have to handle some of the more obscure quirks of some of these older chips.

So I thought “Let’s see how hard it is to take the emulator source code of an older video chip and wedge it into the Apple II VGA code”. I used the video chip code from MAME as a starting point.

I thought I would start with something ‘easier’ so I picked the 6847/6883 combo from the Tandy Color Computer/Dragon 32 systems. The 6847 only does a few specific video modes including a text mode. I knew the artifact mode stuff might be hard but I really just wanted to see what was possible. I sort of piggybacked it onto my ROM/Floppy emulator so I could use both at the same time:

So I hacked away at src/devices/video/mc6847.cpp (and also ended up looking at https://github.com/eyalabraham/Dragon32-RPi-Bare-Metal )and first I got text mode going:

   

And then some graphics modes, with a main aim to get some artifact colours working (but the code is hard coded for one colour set). The way I do artifact stuff is really quite wrong, but it generally looks ok-ish in a decent selection of games.

   

So it looks pretty good, but I knew at the outset that some games would be quite iffy.I make no attempt to synchronise with the drawing of the VGA screen with the actual drawing of the screen. Logically if a game is closely synchronised with the horizontal beam it may not work well.

However, I found a lot of games do work really well .. but a few you can tell are out of sync like DragonFire below.

I got bored with the CoCo and wanted to try something else.

Next on my list was 9918 emulation. I hooked up my dodgy AppleII-VGA breadboard to my MSX1 breadboard computer. And then I used MAME’s tms9928a.cpp as a base. This also wasn’t as hard as I thought . Most stuff works pretty well. I do get the occasional graphical error (see the Arctic Adventure shot. I have not resolved that one) , but everything is very playable and very clear (and yes that’s a Coleco conversion in one of the screenshots).

   

So next on my list was V9938 emulation for MSX2. I was on a roll and I thought ‘this would be so cool’. Of course I failed to have bothered to look up what additional features a V9938 has over the 9918. Sure it has some better video modes and better sprites but it also has a bunch of blitter like functions … and technically the approach the AppleII-VGA stuff takes is unlikely to work well if the video chip has the ability to write back to memory … as you would need to exactly synchonise the emulation inside the pico with the activities within the real V9938.

That didn’t stop me. I used MAME’s v9938.cpp code as a base and hacked away at it. I then hooked it all up to my Panasonic FS-A1. A super convenient thing with MSX computers is that they generally have two cartridge slots. So I could plug my ROM/Floppy emulator in one cart slot and the AppleII-VGA thing in the other.

 

Anyway, I did not get this to work completely. I’ll repeat that. It doesn’t work! (if you’re curious you’ll ignore me and try it anyway). But … the V9938 works just like a 9918 for MSX1 games, and this 9918 emulation in the v9938.cpp code is possibly better than in the 9918 emulation I did previously, but the MSX2 V9938 emulation is a work in progress. There’s a few difficulties.

  • There’s sometimes more CPU time needed per scanline to generate the display than there is allowed time. This is really noticeable in games where you are close to the 8 sprites per line max in the V9938. You’ll see some serious graphical weirdness. I’d probably need to go back and optimise/assembly-arise parts of the code to have a fighting chance.    This appears to be fixed now. I thought I was overclocking the pico, but actually wasn’t. Now that its running at 252MHz , having 8 sprites per horizontal line is not an issue.
  • Not sure why the V9938 sprite modes get the colours wrong.  This now works fine as well. If you look at the screenshots below for Usas and King Kong, you’ll see the incorrect colours for some of the sprites. Turns out these extra colours are the MSX ‘OR’ colours. So this is fixed as well now.
  • A lot of the blitter type functions give the impression that they are sort of mostly working, but not quite.

Here’s some screenshots. You can see how in a lot of cases it looks ‘almost right, but weird’, or in some cases (Zanac) it’s a giberrish mess.

            

I got to a point and thought … yeah … no … maybe and decided to try another computer.

This time the ZX-Spectrum. The old Speccy has one of the simplest video subsystems … so this ended up being quite easy. I tried a few games and they all look fantastic. Benny Hill never looked so good.

       

For lack of my own imagination, I just have a fork of AppleII-VGA on github with different branches for the different emulations described. I’ve placed a branch specific README in each branch (in the ‘pico’ directory) that contains details on wiring (as apart from the address and databus there are subtle differences in how you wire up control signals) and what works and what doesn’t work.  They are all proof of concepts. None are ‘complete’ . Things like ‘border colours’ I have often ignored, and even the accuracy of some colour palettes might be wrong, but that is dead easy to fix.  I’d encourage anyone who’s interested to just ‘have a go’ at them. The ZX-Spectrum and 9918 emulations you could probably use as is. The 6847/6883 one you might need to experiment with especially if you really like artifact games. The V9938/MSX2 stuff is a bit of a pipe dream, but interesting nonetheless.

Also, if you are having trouble compiling, grab the 1.5.1 version of the pico sdk. They changed a lot of stuff in 2.0.0.

Having played with these a bit, they are far more useful on systems with kinda/sorta/not-so-great composite output as the ‘net improvement’ in screen quality is quite large. However, it possibly comes down to personal taste though in terms of whether you want your composite output as sharp as what you see in an emulator. For systems like MSX2 that already have RGB output, you may as well use a Gonbes or similar to get high quality VGA output.

Have fun.