Initial design used SRAM and tri-state buffer chips and was merely a cartridge emulator. That design failed because I was not completely aware of the implications imposed by the VIC-II chip on the bus at that time.
Here is the failed work in action :
Project's code name was NoFlash64 back then. Then all of a sudden I thought it would be a good idea to use the technique I employed on my Hardware Sid Player. It was using 6502's not much used SO input to synchronize sending of data with IRQ and NMI interrupts.
Here is an initial version of my sid player at work :
Technically, you have some boot code on eprom that hooks the interrupts and the data to be transferred is sent using either IRQs or NMIs, 0s and 1s respectively. And SO input is used to syncronize the whole process.
Later it was seen that a simple programmable logic device could also be used to emulate the short code that needs to be put on eprom. And it was also clear that SO input was actually redundant and the same thing could be accomplished using either IRQs or NMIs
Now back to our Cartridge project. Actually my first implementation was similar to the one used on my sid player. Since it was transferring data bit by bit, it was a bit slow.
See it in action here :
Then an idea arised, I got the 16Mhz arduino which was more than 16 times faster than 6502*. Instead of generating interrupts to send 1s and 0s why didn't I just switched the high address lines of the eprom to accomplish executing code to transfer the requested byte? It was a prompt success. I shrunked the boot code on the cartridge to be at most 256 bytes so that I can duplicate the code 256 times to layout on a 64KB 27C512 eprom chip.
256 bytes code is responsible for resetting c64 and initializing it and also contains a nmi transfer handler. With this design interrupts are only used to synchronize the individual bytes to be transferred and using both NMI and IRQs would be a redundant choice. So cartridge only generates NMI interrupts. This clears the transfer from Arduino to C64 part but we also need to send data from C64 to arduino. For this task arduino listens to IRQ line. Sending back data to arduino is possible by correctly timing of generation of IRQ interrupts. I use raster interrupts for this purpose.
Anyway, here is how cartridge works,
Of course it's not that simple, sending of some kind of meta data is needed like the start address of the transfer, length of the data and so on. And most importantly : Even if interrupts are used to synchronize arduino to c64 we still have to handle DMA by the VIC-II. VIC-II stalls the 6502 when it needs to get extra data. This stalls the cpu for 40-43 cycle. It's perfectly possible to handle this in the transfer routine but the throughput of the cartridge would suffer. So cartridge's boot code disables the screen before the transfer so that VIC-II doesn't need DMA.
With this speed improvement, this was the outcome,
The throughput was 15K per second or so. Later, I optimized the NMI handler to do transfers of 2, 4 and 8 bytes with delays in arduino's transfer routine to time the relevant code executing on c64. This reduced the overhead of generating NMI interrupts for individual bytes and effectively increased the speed to around 30-40K per second.
Here is the result :
Naturally since cartridge employs a prebuilt arduino pro mini it has a serial interface. It's possible to load programs using this serial interface. Though I've not yet successfully tested but using bluetooth or wireless serial interfaces should also be possible.
Also, since cartridge doesn't employ a flash to store programs and gets the data directly from an sd card some nifty tricks to use it for other purposes than loading programs is possible.
Such as? Streaming wave files of arbitrary length,
Like this :
Writing programs that request data to be streamed from sd card :
In this example the executable code on the C64 is intact but commands arduino to load sequential files to a certain address.
And finally to stream videos of arbitrary length. In this example 160x80 5fps multicolor video is being played. Video conversion depicted in this video is a bit experimental and not mature. Programs like Project One does a better job of converting images to c64 multicolor restrictions. I used my own program since Project One didn't have a batch mode.
In this video playing feature cartridge works completely differently. Here are the differences to the original program loading feature.
Here is the block diagram of the cartridge.
As I'm a bit lazy I sought help for the PCB design and a forum friend (Özay Turay) gave hand so the production was possible. You can access eagle schematics / board design files from below link.
Note: It's on a private server with self issued ssl certificates, please ignore the security alert of the browser. There is nothing fishy.
Arduino sources, 6502 loader code that should be burned on the eprom and c64 menu code is in the below link. This is the initial software pack that I bundled with the early preorder builts.
You need Arduino IDE, 64Tass compiler, a tool to burn eprom image file.