Games

Zeugma

Zeugma is a modern, highly optimised, open-source Z-machine implementation for the 6502 processor family. It is designed around a virtual memory model, where pages are retrieved on demand from an external storage resource, 512 KB in size, which must be preloaded with the game file.

Screenshot

There are tools to extract story files from Infocom's C64 releases, and if you load those files into zeugma you will experience a dramatic speed improvement compared to the original, despite the fact that text is now rendered using bitmap graphics in order to fit more characters on the screen. Apart from the obvious benefits of loading from REU rather than floppy, the increased responsiveness is the result of highly optimised code, with extensive use of redundant decoding look-up tables, inlining, self-modifying zero-page code and other trickery. But see below for some depressing facts about recent games.

While the Z-code engine itself is written in generic 6502 assembly language, the virtual memory solution and input/output facilities are platform-dependent. Currently, there is only one implementation, Zeugma-C64-REU, for a Commodore 64 (or a C128 in C64 mode) with a 512 KB RAM Expansion Unit. Today, most active C64 users own a multi-function cartridge such as the 1541 Ultimate, which can be configured to provide REU functionality. For now, zeugma requires the game file to be preloaded into the REU before the program is run, something which is easily done via the menu system of the 1541 Ultimate. Should you wish to use this program with a vintage REU from Commodore, you'll have to devise some alternative way of getting the story file into the REU.

Note

Added 131001: To run Zeugma on a 1541 Ultimate II, configure the Ultimate for a 16 MB REU and use at least version 1.2 of Zeugma.

Download

The widehack version is required for the Infocom game Trinity.

Zeugma is released under the MIT license (included in the source tarball). The font (Schumacher Clean 6x8) is redistributed in compliance with its license, also included in the source tarball, and a copyright notice is displayed when the program starts.

Background

Being active in the C64 demoscene, and more of a lurker in the world of interactive fiction, it struck me that the two communities have certain things in common. Both are about exploring an obscure art form and finding joy in constraints that appear stifling or pointless to outsiders. Both have formed around some once-blossoming technology — commercially viable years ago, now overtaken by shinier gadgets and left by the wayside — that has been picked up by amateurs and nourished into sprouting more beautiful flowers than ever. Likewise, both communities attract the kind of patient, intelligent people who understand the distinction between vivid imagery and photorealistic graphics, and for whom instant gratification has about as much appeal as instant coffee.

The history of the Z-machine goes as follows: Drafted in 1979 on a coffee table in Pittsburgh, with the aim of making the game Zork (hence 'Z') platform independent, it went on to give the company Infocom a competitive edge: Their text adventure games could be developed once, and then released for an assortment of computer systems. In the mid-1990s, thanks to Graham Nelson, Mark Howell and several other enthusiasts, the format was reverse-engineered. A high-level language, Inform, was invented for writing interactive fiction that would run on all the existing Z-code interpreters.

As technology marched on, people got their hands on more powerful computers, and Z-code interpreters were implemented for them. Newly written games were larger, because computer memory had become plentiful. The file format was extended, and at some point backwards-compatibility with the old interpreters was abandoned. Furthermore, as computers got faster, games got slower, but nobody noticed.

Fans of interactive fiction and vintage computer enthusiasts flocked together into separate subcultures. Zeugma is an attempt to bridge the gap between them. C64 aficionados now have access to a wide selection of interactive fiction, some of very high quality. For the interactive fiction crowd, the benefits are not as obvious. However, I personally find that the vintage hardware brings back something to the playing experience that got lost along the way. You sit down in front of a physical machine that is running nothing but the game. There are no distractions, popups, forums, inboxes, reminders, instant messages and what have you. Every turn takes a few seconds, so you think before you type. You don't speed-read for keywords while fluttering aimlessly around the map, instead taking the time to actually read the text and let it sink in. I find that this does wonders for the sense of immersion. Also, because there's no scrollback, and because you can't conveniently have a text-editor running in another window like on a modern computer, you'll find yourself drawing maps and making notes in pencil. All of this makes the exploration of the game delightfully tangible, and the notes become an embodiment of your personal view of the fictional world.

Fiction compatibility

Zeugma supports Z-code versions 4, 5 and 8 (story files with filename extensions .z4, .z5 and .z8). Some games come in blorb files, from which the story file must be extracted. Here are some tools for that.

Old Infocom games fly. Inform 6 games walk. Inform 7 games are unfortunately way too slow to be playable (unless you happen to have a 20 MHz SuperCPU). I might elaborate on the technical reasons for this in a later post.

Recommendations

If you are familiar with interactive fiction, you probably already know what games you'd like to try out. Otherwise, head to the Interactive Fiction Archive, and look in the zcode directory, as well as the zcode subdirectories of the yearly competition directories. Most games begin in medias res, after which they display a banner with version information. If this banner contains the text "Inform 7" anywhere, you'll find the game unbearably slow. Inform 7 was released in 2006, so earlier competition directories are safe. Wikipedia has a list of notable Inform 6 games. A few personal recommendations follow; these are some of the games that I played while testing zeugma:

  • Spiral (Justin Morgan, 2012). This game ranked #6 in the 2012 Interactive Fiction Competition, proving that high-quality games are still being developed in Inform 6.
  • Varicella (Adam Cadre, 1999). This is a difficult game, but many agree that it's a masterpiece.
  • Trinity (Brian Moriarty, 1986) and Bureaucracy (Douglas Adams et al., 1987) are two lovely games from Infocom. Activision, the owner of the copyrights, has been re-releasing Infocom games as recently as 2012 (for iOS), so these titles can't really be regarded as abandonware. If you own the original disks, there are tools to extract the .z4 files from them.

Trinity refuses to run in the relatively cramped screen space provided by Zeugma-C64-REU (53 x 25 characters). Use the widehack version of the interpreter to get around this; it will lie to the game about the size of the screen, so some quote boxes will end up in strange places, but the game is playable.

Limitations

As mentioned, Inform 7 games are too slow to play. This is the greatest limitation in my opinion.

In addition, zeugma currently doesn't support file system operations. This means you can't save or restore games, and you can't work with transcripts. Also, for reasons of performance and memory conservation, undo and restart are not supported. To restart the game, you have to preload the REU again, and relaunch zeugma.

Zeugma-C64-REU is monochrome, but provides bold and reverse text styles. Non-ASCII characters are currently not displayed correctly.

The name

A zeugma is a rhetorical device that, much like a virtual machine, lets you re-use a piece of meaning in several contexts without having to write it all over again: With zeugma, authors have access to an antique type-saving device; an antique tape-loading device, authors.

Version history

1308221.0Initial release.
1309151.1Bugfix in op_tokenise. Tolerate invalid property numbers.
1310011.2Bugfix for REU > 512 kB

Posted Friday 23-Aug-2013 01:14

Discuss this page

Disclaimer: I am not responsible for what people (other than myself) write in the forums. Please report any abuse, such as insults, slander, spam and illegal material, and I will take appropriate actions. Don't feed the trolls.

Jag tar inget ansvar för det som skrivs i forumet, förutom mina egna inlägg. Vänligen rapportera alla inlägg som bryter mot reglerna, så ska jag se vad jag kan göra. Som regelbrott räknas till exempel förolämpningar, förtal, spam och olagligt material. Mata inte trålarna.

ralph
Ralph Corderoy
Fri 23-Aug-2013 16:43
"I might elaborate on the technical reasons for this in a later post."
Please do, the nitty-gritty in your posts is often very interesting.
Anonymous
Wed 28-Aug-2013 13:13
Splendid as always! Will have great fun trying this out!

Now we all await a C64 REU version of ScummVM ;^)

//P-a Bäckström
Anonymous
Mon 2-Sep-2013 04:49
First bug report: no support for Z-machine versions 1, 2 or 3. Yeah this is a bug report not a feature request, 'cause as of now you can't actually play Zork, which is some kind of criminal shortcoming!
Anonymous
Sat 14-Sep-2013 02:25
"Sweet, a C64 terp! I'll try _Spider and Web_."

It didn't exactly go to plan. I get "That's not a verb I recognise." in response to anything. Except "oops" and "o", oddly enough. (Screenshot: http://sphere.chronosempire.org.uk/~HEx/shots/zeugma-fail.png)

Several hours of debugging later, I still have no idea what's wrong with your code but I am now very confused.

What is "dictordered" for? The spec (§13.5) requires the dictionary to be ordered. (No mention is made of whether this is required for user dictionaries; I assume so.)

In particular the code between "nowrap5" and "noneg" eludes me. It seems to set dictordered to zero iff the MSB of the number of dictionary entries is set. (This number is fetched correctly by the preceding code.) This seems an utterly bizarre thing to do, and the code if this is true is even more bizarre (invert the number of dictionary entries?!). The only possible thing I can think of is that for some reason you were manually inverting dictionary tables in games and testing (and reverting) that at runtime to determine whether to use a binary search, perhaps for debugging the search code (but then why modify the game rather than the code?).

Also, why does mulloop iterate 8 times? Surely finishing the loop early (suggested code below) would save several iterations in the common case where the dictionary entry size is small (guaranteed to be 9 bytes for Inform games, for example). I can't imagine you would begrudge four extra bytes for this.

mulloop
lsr temp3+2
bcs yesadd
bne noadd
bcc aftermul
yesadd
lda temp3
[...]
noadd
asl temp3
rol temp3+1
dex
bne mulloop
aftermul
ldx #0
[...]

(Gah, how do you format code fragments using this thing?)

Some documentation really would be nice. At this rate of reverse engineering I'll never get a BBC Micro port done :(

Also a github project maybe?
lft
Linus Åkesson
Sun 15-Sep-2013 17:30
"Sweet, a C64 terp! I'll try _Spider and Web_."

It didn't exactly go to plan. I get "That's not a verb I recognise." in response to anything. Except "oops" and "o", oddly enough. (Screenshot: http://sphere.chronosempire.org.uk/~HEx/shots/zeugma-fail.png)

Thanks for the bug report! This is now fixed in v1.1.

Several hours of debugging later, I still have no idea what's wrong with your code but I am now very confused.

What is "dictordered" for? The spec (§13.5) requires the dictionary to be ordered. (No mention is made of whether this is required for user dictionaries; I assume so.)

The same code is used for the tokenise opcode, which does allow unsorted dictionaries, indicated by a negated number of entries.

Also, why does mulloop iterate 8 times? Surely finishing the loop early (suggested code below) would save several iterations in the common case where the dictionary entry size is small (guaranteed to be 9 bytes for Inform games, for example). I can't imagine you would begrudge four extra bytes for this.

Yep, I didn't bother to optimise this multiplication as it doesn't happen very often. The regular mul opcode is optimised.

(Gah, how do you format code fragments using this thing?)

I might have to add support for that. Thanks for persevering.

Some documentation really would be nice. At this rate of reverse engineering I'll never get a BBC Micro port done :(

Also a github project maybe?

I'll think about it. Thanks for showing an interest!
Anonymous
Thu 19-Sep-2013 10:33
I've tryed but something goes wrong.
I load the file renamed (.REU) into the REU and then I load the Zeugma.prg but it doesn't work. What do I do wrong?

Bieno.
Anonymous
Fri 20-Sep-2013 19:09
Same here. Seems that with my 1541U-II, it's not merely a question of renaming a .z8-file to .reu. What am I doing wrong?

REU is enabled, set to 512KB, loading a REU-file (ie. spiral.z8.reu), and then loading and running zeugmav1.1.prg results in 'Z-machine version (anything between 0 and 255) not supported.'
Anonymous
Sat 21-Sep-2013 17:00
Seems that with 1541U-II, you need to set your REU size to 16M (as you would for GEOS to have it use 512KB).

For some reason, Spiral gives me all sorts of messages and I get to press [more] a couple of times inbetween those errors.
Anonymous
Fri 27-Sep-2013 15:03
Bug report on CSDb. Please check it!
lft
Linus Åkesson
Tue 1-Oct-2013 23:52
The bug should be fixed now in version 1.2. Configure your 1541U-II for a 16 MB REU.
Anonymous
Sat 5-Oct-2013 04:57
There is now an easy way to load gamefile images into REU on real hardware: REU Image Loader, http://csdb.dk/release/?id=122290 . It's relatively speedy if you have JiffyDOS, not sure if other turbos are supported/applicable. Just point it at the z4/z5/z8 file, wait for the image load, then load and run Zeugma.
Anonymous
Sun 15-Dec-2013 06:43
Doesn't work on NTSC. :(

I get an [Illegal opcode] error.
Anonymous
Tue 31-Dec-2013 09:00
Zeugma 1.2 worked fine on my real NTSC C64 when I was testing REU Image Loader, with my 1750 REU + uIEC. -Macbeth/PSW
johnwbyrd
John Byrd
Tue 25-Feb-2014 23:47
It's possible to run Zeugma using the Windows version of the VICE emulator; however, the VICE emulator will stomp on any REU save file that is not exactly the size that VICE expects it to be. Your story file will be full of zeros and Zeugma will report that it cannot run a story file of version 0. To work around this behavior, you will need to pad the z8 story file to exactly the size of the expected REU before loading it in VICE.

There is a padbin.exe file in http://www.pineight.com/gba/gbfs.zip which can be used to do this padding, with the following command line for a 512 KB emulated REU:

padbin.exe 524288 your-story-file.z8

Then you can load the padded file into the emulated REU and start zeugma.
johnwbyrd
John Byrd
Wed 26-Feb-2014 00:03
Such beautiful and outstanding work on getting this emulator operational.

I confess however that for us emulator users, part of the attraction is the ability to have a "true" C64 experience... I would like to therefore politely request the ability to revert Zeugma back to classic C64 fonts and colors, perhaps via one of the function keys.
Anonymous
Mon 7-Apr-2014 00:01
Hello.
I am most impressed with the speed and clear font of this interpreter. It's even faster than the official Infocom games on my Atari ST!

I would like to change the default colors to green on black, as black on white is a little hard on my eyes.

I have tried changing the values for 'black' and 'white' in the source code, and recompiling it, but that doesn't seem to do anything. (It compiles fine, but the colors don't change.)

Unfortunately, I don't understand assembler at the best of times, and am getting a bit lost!
Anonymous
Sat 10-May-2014 17:58
I'd love to try this but am confused about how to load the z-file into the C64. I assume I just copy the file onto a floppy (or D64)? I know it is probably screamingly simple, but has anyone written a step-by-step guide on the whole process? Ideally I'd like to try this on a Win-based emulator like VICE or CCS64.
Anonymous
Sat 4-Apr-2015 01:27
Revisiting the BBC micro port idea.

Here's hello world:
https://sphere.chronosempire.org.uk/~HEx/shots/zeugmab.png

(Story was the smallest, simplest file I had to hand, namely that discussed in https://groups.google.com/forum/#!topic/parchment/CeUK2Ry6Yvk .)

Adventures so far: the Beeb, which has an actual OS[1], uses the top of zero page for its own purposes, so the code residing there on the C64 needed splitting out into the self-modifying bit at the bottom, and the rest, which can usefully be stored at the bottom of page 1. Current zp usage is 153 bytes.

Then there was figuring out why the VM was trying to access addresses starting at 5fff00 and working downwards, well beyond the extent of the story file. Hmm, "property cache", you say?

Most recent facepalm was when I was single-stepping a crash and came across the instruction "jmp ($3dff)". This is a self-modifying jump table (jumptbl_oper) at $3d00 ($3300 on the C64 version) indexed by odd values. Early 6502s (including the 6510) perform the wraparound incorrectly, and indeed you have put the high byte at the beginning of the table as the buggy CPU in the C64 expects.

But not the more recent, non-buggy 65SC12 in the BBC Master[2] I was emulating! It does wraparound correctly, and thus loads the "wrong" value. Does this code really work on a SuperCPU?

[1] More to the point, an actual OS that can't be paged out, so any help it can provide is useful in alleviating the critical address space shortage. Also I can understand writing your own display routines, but your own *keyboard scanning code*? Is this what life is like on the C64?

[2] I would like to support a plain model B (32K should be enough for everybody, right?). But, well, if you can require a Commodore 576, I can probably get away with suggesting a Master 128 :)
lft
Linus Åkesson
Sat 11-Apr-2015 00:48
Hi! Great work on the BBC Micro, and sorry for the C64-isms. I haven't actually tested on a SuperCPU, and I agree in hindsight that it might fail for the reason you suggest.

As for keyboard scanning, there's a routine in the OS, but mine supports 3-key rollover and flexible key-repeat functionality. Besides, to use the stock routine, some research would be necessary to figure out what memory areas to leave intact. With 64 kB of RAM at hand, it was easier to just implement it.
Anonymous
Sun 5-Jul-2015 04:32
I made some versions with different color schemes: https://www.dropbox.com/s/1hel51jdbvp2rzs/zeugma-c64-reu-src-1.2_color.zip?dl=1

Man, that was a hassle to compile/assemble on winderps...

Also, why have black on light grey in the first place, just hurts both eyes and screens?
Anonymous
Sun 20-Sep-2015 15:37
How to use Zeugma on VICE emulator:

Go to the Settings menu and select Cartridge/IO settings
Select REU settings
Enable REU and set size to 16mb
Browse to the z-file you want to play. (You may need to rename the extension to .reu first.)
Run the Zeugma program.

So far I have not got a game to run, but the error message I see - "z-machine version 0 not supported" - gives me hope I am making some progress.
lft
Linus Åkesson
Sun 20-Sep-2015 16:07
...

So far I have not got a game to run, but the error message I see - "z-machine version 0 not supported" - gives me hope I am making some progress.

Check the earlier comment from johnwbyrd. VICE requires you to pad the file to the correct size.
thanius
Tobias Hellgren
Sun 15-May-2016 13:23
Drog in Stugan, men fonten verkar sakna ÅÄÖ. Något för framtida versioner?
Anonymous
Sat 24-Dec-2016 08:21
Hi
Do you know if they will work with z8 files?. It would be cool to play current IF games on the C64. Thanks.

--KMBR