Blast from the Past: Retrieving Old Game Source Code

Way back in 1985, I created games on the ZX Spectrum/Timex and CBM-64. A friend and I set up a small software house, and in addition to creating our own games, we also (and more lucratively) converted games for other publishers from CBM-64 to other formats.

During this period, I wrote several original games in Z80 and 6502 assembler. I kept their sources on 5 1/4″ floppy disks, but after a few years I lost the floppy drive that could read the disks, and they were shoved in a cupboard. Somewhere between house moves, I lost the disks for all time.

Fast-forward to this past December. In a store, I spotted a cheap game console for roughly $100 (get a look at this absolute unit, sold under the brand name “RetroPi”). It came with 18,000 games for various old computers and consoles, including SNES, ZX Spectrum and CBM-64. The hardware was a Raspberry PI clone in a case, and included Nintendo-type game controllers, along with HDMI and USB power cables.

Given my history, this device interested me a great deal, so I explored further. The games were on a 16 GB SDHC card; the system was a RetrOrangePi (you can read the full specs of the hardware and emulators) running Armbian, a Debian derivative. (The entire software stack is on Github, if you’re curious.)

Browsing through the CBM-64 and ZX Spectrum menus, I discovered three of my Spectrum games and one for CBM-64. Not knowing much about the hardware or OS, I thought I’d investigate and see if I could fetch the game binaries and take a stab at disassembling them.

Now, I’ve used Raspberry Pi before. I also know that SD/SDHC cards are quite easy to corrupt and render non-bootable. So before taking any further steps, I made a backup copy. The open-source Win32DiskImager is very good for that purpose, and with a hardware adaptor to read the card, it took 20 minutes to read and create a 15 GB file on disk, then another 20 minutes to burn a backup card from the image (a backup SDHC card costs less than $5 and comes with a SD card adapter).

At this point, I put on my amateur computer forensic hat. Sure, the games were somewhere in the 15 GB disk image—but what was the format?

The disk was neither encrypted nor compressed. The Linux .img format was a file/folder dump in a file, and a bit of searching on the web revealed that Disk Internals would do the trick of reading it. Disk Internals is a Windows GUI freeware program that can read many Linux disk formats; it’s also rather good at reading Windows disks, so use with care.

Ten minutes of delving uncovered a folder with the various ROM collections in it (home\pi\RetroPie\roms\), and I not only found my four files, but I was able to export them as binary files. These files were between 27 KB and 45 KB, smaller than all but the smallest .jpg files! (Compare that to the huge games of today; a title like “Red Dead Redemption 2” might hit 100 GB in size.)

Disassembling

Both 6502 and Z80 CPUs are still popular, and there are a considerable number of assemblers and disassemblers available (many open-source, but also a few commercial ones).

6502.org is a good place to start, and I also found a half-decent free Z80 disassembler. One of my Z80 games disassembled to over 21,000 lines; it will take a while to manually add labels and make the code readable. Currently, the disassembly looks like this (Z80):

0240 21c4fa    ld      hl,0fac4h
0243 0632      ld      b,32h
0245 110300    ld      de,0003h
0248 7e        ld      a,(hl)
0249 e620      and     20h
024b 77        ld      (hl),a
024c 23        inc     hl
024d 3600      ld      (hl),00h
024f 19        add     hl,de
0250 10f6      djnz    0248h
0252 c9        ret  
...

The 6502 disassembly isn’t much easier, though:

                    dex
                    txs
                    ldy #$00
L086b               dec $fd
                    dec $0874
L0870               lda ($fc),y
                    sta $ffff,y
                    dey
                    bne L0870
...

Younger developers, remember: We used to write this stuff by hand! Many of the disassembled lines contain graphics, text or data tables.

After 1,500 lines of Z80, there are 30 Z80 jumps (jp) like this. Why is that?

17a0 c31299    jp      9912h
17a3 c3ee99    jp      99eeh
17a6 c3d79d    jp      9dd7h
17a9 c3c39e    jp      9ec3h
17ac c36e9f    jp      9f6eh
17af c3809f    jp      9f80h
...

That was something I did because my original development system (A Tatung Einstein running CP/M) only had about 48K RAM. The crude editor we used maxed out at a couple of thousand lines at most (Typically 40KB RAM limit!), so the source was split into several files, each starting with a jump table.

There was no linker back then, so each file’s code was loaded into memory at a fixed address. To call a routine in File B from File A, you had a list of routine addresses in File A, each pointing to a jump table entry in File B. That table had 30 jumps to the actual routines.

That way, you could change the code in File B without needing any other changes. No matter how the address of the routines moved in File B, the jump table stayed at the same address.

Conclusion

I priced out the hardware for the console, and reckon it would cost about $70 for the Pi, controllers and cables, so I don’t feel ripped off… especially as it gave me a chance to play “Legend of Zelda” and “Secret of Mana” for the first time in 25 years via the SNES emulator!

Although the emulator software (Mame, etc.) for this is legit, I’m quite certain that the ROMs are not! But it was still fun to dissect some older code. Meanwhile, someone also put the footage from one of my old games on YouTube (I swear, it wasn’t me!):