Zeugma, a modern Z-machine interpreter for the 6502

The Z-machine lives again on the C64. This highly optimised interpreter supports versions 4, 5 and 8. The complete announcement is here:

linusakesson.net/software/zeugma/index.php

Quoting:

“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.”

Looks very cool! What will it take to add save/restore/undo functionality?

It looks so cool! Can’t wait to try it on my C64! :smiley:

You say that I6 games “walk” ; do you think it’s inherent to I6? Do you know if there’s a way for me, as an author, to make my games faster / more optimized? (I guess it’s a more general question other people on this forum might be able to answer too)

And it’s too bad it doesn’t support non-ASCII characters yet. If you have a chance, I’d say it’d be a good feature for your interpreter, since it runs I6 games faster than I7: lots of non-English authors are still using I6, because using I7 means mixing English sentences to French/Spanish/Italian/German text, which is not super convenient.
(According to the IFDB, in the last 2 years, more non-English games were written in I6 than in I7 (and among games in I6, they make for more than 50% of the total), when 97.6% of English games were written in I7!)

Thanks a lot for this!!

Yes, basically. I6 has a more complex parser and does an extra degree of error-checking on object/property operations. I6 also has many features which are not inherently slow, but which can be invoked in a slow way by incautious authors.

I7 has all of that, plus additional error-checking, plus additional hooks in the parser, plus a lot of features implemented by compiler-generated code which is not perfectly tuned for the problem at hand. (That is, situations where an experienced I6 coder optimizing for the specific game feature could write faster code than I7’s general solution.)

Optimization is a big topic and there are some threads about it in the Inform part of the forum. The simplest rule is “Don’t iterate the world or do a scope test unless you have to,” but really your best bet is to test on the slowest available interpreter. (The C64 emulator may well be it, but Parchment/Quixe are also good test platforms.)

Thank you for this feedback! I did not realise that accented characters were such an important feature, but your argument about non-English authors opting for I6 makes perfect sense. I’ll look into it.

Yes, this is true.

But looking at the generated Z-code, I would also say that much could be gained from adding a proper optimisation stage to the I6 compiler. There is plenty to do, ranging from simple stuff – constant propagation, dead code elimination, encoding multiplication and division as shift instructions where possible, folding chains of jump instructions – to more complex transformations like moving constants out of loops or replacing multiplications of the loop variable by a constant with additions.

True. The Inform 6 compiler is not at all sophisticated by compiler standards.

Unfortunately, by the same token, it will hard to smarten up its code generator without committing to a complete rewrite.

Side note: “encoding multiplication as a shift instruction” is almost certainly pointless. When the interpreter is decoding a series of instructions and data words from VM memory, the time spent actually doing arithmetic gets lost in the noise.

Awesome!! I’m stoked :smiley: Thanks a lot for your work!

What would probably help both Inform 6 and 7 a lot is if Inform 6 had macros. There are many short functions (especially in Inform 7) which could be inlined. The overhead of function calls is one of the main performance problems.

Infocom already wrote Z-machine interpreter for C64. Good thing anyways; they didn’t implement version 8.

Furthermore, I am also implementing (not finished yet) a Z-machine interpreter for 6502, but mine has some differences:

  • It is going by the “quixotic” Z-machine specification, rather than the Z-Machine Standards Document (which still helps though; thanks)
  • It implements versions 1, 2, and 3; not any others.
  • It is for the Famicom and not the C64.
  • Lowercase isn’t implemented (it isn’t required in versions 1 to 3, according to Infocom’s documentation; it isn’t difficult to see why, one thing is that since the INPUT instruction doesn’t exist, and READ isn’t case-sensitive).
  • The header is read and updated at compile-time. This would make it faster, since the program doesn’t need to update the header when the program starts, or to read the header; a compile-time macro contains the addresses of the object table, fwords table, vocabulary table, etc

Also, if you want to make your game faster try ZILF and see if that works better? You can also try programming the game in assembly language, if you want to.

Slowly but surely, Rellor is getting there.

What is Rellor? A tool to optimize the code generator? (Sorry, I can’t really understand what it does by looking at the doc! :slight_smile: )

It’s a completely rewritten compiler for the Inform 6 language. Among other things, it should be able to do the kind of optimizations lft and Dannii mentioned… although it’s nowhere near ready to use yet.

Wow, that’s awesome! Looking forward to trying this! :smiley:

Well, like I wrote on the web page, that implementation is much slower than Zeugma. It is also copyright Infocom, all rights reserved, whereas Zeugma is open-source and released under an MIT license. But the biggest improvement is that Zeugma doesn’t limit the size of the so called dynamic and static memory areas. These are swapped in and out as needed, while the Infocom interpreter keeps them swapped-in at all times, and only pages high memory. Several Infocom games (such as Bureaucracy, which incidentally is in .z4 format) were never released for the C64, because they required too much dynamic and static memory. These games, as well as most modern games, cannot run in Infocom’s C64 interpreter regardless of which versions of the Z-machine it supports.

I understand you. Those are good reasons too; I do think it is good you are making these things.

Still, I am writing another one, for the Nintendo Family Computer (I don’t think anyone has done that yet), and version 1 to 3. It is also open source, and public domain. It supports the full 128K, which is stored in ROM, and the entire core memory (including the static memory) is stored in RAM. (The mapper it uses is a very small subset of MMC5; the only feature it retains is the RAM and ROM bankswitching, and even that is limited.) The screen size is even more cramped; once overscan is considered, it is 30x28. Since the I haven’t written a lot of it enough to be able to compare speed, but I expect it will be comparable speed; version 3 uses only 8-bit object numbers, I am not implementing lowercase, many things are precomputed at compile-time, and due to other things too, it shouldn’t be too slow. However, it doesn’t expect that ZIL or Inform will compile the story file, so optimizations specific to those compilers aren’t used.

The implementation I had previously written for Famicom is abandoned; I have started a new one (but have abandoned that too), but I have written some ideas about how to do so. Only Z-code version 3 (ZIP) is implemented, although both big-endian and small-endian is. Here are my ideas about doing so: http://zzo38computer.org/textfile/miscellaneous/famicom_zmachine Note that I designed a custom mapper for doing so (which is strange compared to other mappers; I don’t know of any other mapper that maps stuff at $1xxx like I have; mapping it there is actually deliberate, and the program actually uses that mapping, because it interferes with Famicom’s internal RAM).