IRQHack64 C64 Cartridge


IRQHack64 is a C64 cartridge designed to be used to load programs to C64. It's composed of an arduino pro mini, a micro sd card module and a 27c512 eprom mainly. It's very fast, faster than most of the fastloaders actually. It loads programs at speed of around 40KB per second. It doesn't have an IEC interface so it operates only with program files.

It also has these features

Note : POC features are not production ready and could only be realized into the final product if there is demand.

More details about the development of the cartridge

Initial Take Fail :)

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 :

Initial Success

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

http://forum.6502.org/viewtopic.php?f=10&t=3383

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 :

Speedup

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,

  1. Arduino resets C64, pulls the EXROM line low so that code on the eprom boots the C64
  2. Code on the eprom initializes C64 and starts waiting Arduino to generate NMI interrupts.
  3. To transfer a byte arduino switches A15-A8 of eprom to the desired byte. This is possible since code on the eprom only differs where the actual transfer takes place.
  4. Arduino generates an NMI interrupt and the nmi handler on the cartridge stores this byte.
  5. This process is repeated for every byte to transfer. Go to 3

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 :

Other Features

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.

  1. It doesn't disable the display. It only uses the processing space where VIC-II doesn't use DMA. About 1/3 of a VIC frame. Still it does 400 bytes of transfer each frame. Which makes 50*400 = 20000 bytes per second.
  2. It doesn't use the transfer handler on the rom but instead supplies it's own one on RAM which effectively shrinks the processing time required by the more general routine on the cartridge's eprom.
  3. Since it uses RAM and works with chunked transfers it has it's own transfer routine on the arduino which also handles the memory architecture of the C64 by timely toggling EXROM line. To start with C64 doesn't have a memory configuration where $8000-$9FFF is CART ROM LO and $E000-$FFFF is RAM which is required by a custom NMI handler.

Hardware & Software

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.

https://www.tepetaklak.com:8443/svn/Public/Hardware/IRQHack64/

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.

https://www.tepetaklak.com:8443/svn/Public/

You need Arduino IDE, 64Tass compiler, a tool to burn eprom image file.

Credits Without these people the work here would only be a prototype

Original hardware
Nejat Dilek (I.R.on)
Eagle schematic & pcb design
Özay Turay (Simon at CGTR forums)
Additional demo scene style menu
Gökhan Aşçıoğlu (wizofwor at CGTR forums)
Patching for 8k/16k cartridges and continuous motivation :)
İlker Fıçıcılar

Ordering

I've got a batch of them. If you are interested drop me a line. For price & stuff you can refer to below forum post at Lemon64. Beware though as Paypal stopped services in Turkey viable payment methods would only be Swift or Crypto coins.

IRQHack64 - Preorder

* : On C64 instead of 6502 a custom version of the chip named 6510 is actually used. It's still viable to call it a 6502 from a base hardware and programming perspective though.