I have disassembled, dissected, and modified the latest officially-released C64 interpreters to work with the uIEC without REU, and high-storage Commodore drives with REU or GeoRAM. The v4 interpreter allows the C128-only games to work on a C64.
Infocom games, as released for the Commodore 64, are very tied to the 1541 disk format. Commodore didn’t believe that random-access files had any purpose, so the Infocom engineers were forced into using raw-sector access schemes to jump around in the story file. When the REU was released, Infocom modified the interpreter to load the entire story file into RAM, but continued using the raw-sector disk format to maintain backwards compatibility for non-REU owners.
This, naturally, makes playing these games on non-1541 drives somewhat unpleasant. One would have to use d64 emulation, swap virtual floppy images to save games, and so forth.
I have an uIEC. In fact, I have several. I love the uIEC. And I wanted to be able to play Infocom games on it, with as little effort as when I play on a UNIX workstation.
To that end, I have disassembled, dissected, and modified various revisions of the C64 v3/v4/v5 interpreter to work with the uIEC (and other large storage devices). It requires a REU.
Instructions: To use these interpreters: Create a directory on the uIEC for each separate v3 game, Create the binaries by running “make” in the directory sourced from GitHub. You’ll need exomizer2 from here, and xa65/printcbm from here. Copy the story file into that directory as “STORY.DAT” Load and run “INFOCOM3”, “INFOCOM4”, or “INFOCOM5”
- The 1541/1571 fastload routines were removed.
- The story file is loaded from “STORY.DAT” instead of raw blocks.
- To accomodate the above, an REU is now required.
- The number of save slots has been increased from five to nine.
- Save games are 49-block seq files named “SAVEn”, where n is 1 through 9
- The game can be run from any device number, not just device 8.
- REU mirrored register access has been fixed.
- TODO: use George Hug’s 2400bps RS232 routines to replace printer code
- TODO: C128 80 column support
The source code (no binaries, sorry) can be found on GitHub here.
The v4 interpreter, as sourced from the “Nord and Bert” d64, does something really interesting with the resident size when setting up the virtual memory scheme. If you look at a non-C64-sourced version of N&B with infodump, you’ll see that the resident size is hardcoded to $AEFF.
Forcing that value with all other v4 games results in a working game, even if the resident size overflows available physical memory. The interpreter already assumes that anything over $F900 (start of $3A00, skipping $D000-DFFF) needs to be paged in from REU/DISK, even if it is “resident”.
This implies that the lack of support for v4 on a stock C64 was not due to lack of physical memory, but rather lack of available disk space. Infocom could have supported the C64 on all of the eight-bit titles that it released, if they’d embraced the 1581 or went to a multi-disk scheme.
There’s a fair amount of weird stuff in these interps. There’s orphaned code fragments in v3/v4, a “Test1” string referenced nowhere in v5, and I’m still trying to understand why the author(s) went to separate hi/lo jump tables in v4/v5 rather than continuing with the unified tables in v3.
I have read that the fabled Infocom backup drive that surfaced a few years ago includes complete source code to the various interpreters, including the ones I’m reverse-engineering. I’d very much like to see that source code.
They made a mistake with the latest official version of the v3 interpreter … since the $DF00 range isn’t completely decoded by the 64, there are mirror registers every thirty-two bytes. The v3 interpreter uses $DF28 instead of $DF08 in several places. This isn’t a problem with original hardware, but things that emulate the Commodore REU (particularly the 1541-Ultimate) fully decode that memory page. People needing fixed d64 images (i.e., those using the 1541-Ultimate or an emulator) can obtain fixed images here.
The interpreter source code has been sanitized; it lacks all of the #ifdef’ed code that made it possible to generate the original unmodified interpreters from these sources. That means that the weirder original implementation oddities aren’t included. I can/will make that available later … it was interesting reading.
I’ve concluded that the Apple ][ target was the reference platform, and other 6502 ports were derived from it with differing degrees of Apple-specific code accidentally left in the Commodore versions.
Also, the guy(s) who hacked the Commodore code into the v4 (and by extension v5) interpreter was probably an intern, not terribly familiar with rational code flow. And I do mean “hacked” — subroutines will suddenly jump past a bunch of unrelated code, the elegant word-based jump tables were deprecated in favor of split-byte jump tables, and there was some unholy stuff going on in the virtual-to-physical-address logic. Most memorable was the bit that asked which of seven slots the printer was at.
While I was looking at the SD2IEC docs to see if UI or UJ was the preferred way of getting a 73 status for identification, I noticed this:
Positioning doesn’t just work for REL files but also for regular files on a FAT partition. When used for regular files the format is “P”+chr$(channel)+chr$(lo)+chr$(midlo)+chr$(midhi)+chr$(hi) which will seek to the 0-based offset hi*2^24+midhi*65536+256*midlo+lo in the file.
… which means that running from the uIEC doesn’t require any RAM expansion. We can just seek to the proper offset in the story file. It’ll be a tad slower than running from REU/EasyFlash/GeoRAM, but it’ll work.
The banking/addressing scheme for GeoRAM is exactly the same as for EasyFlash, so I have implemented that also. It’s actually slightly faster than the Commodore REU.