Spectrum pages
Home -> Spectrum -> ZXZVM -> Porting hints


Porting ZXZVM

ZXZVM is composed of two modules: a machine-independent interpreter core and a machine-dependent front end. If you want to port it to another system, it should be sufficient to write a new front end.

In all existing systems, the interpreter core loads at 7000h (though this could easily be changed by reassembling vm.zsm at a different base address). If you do change this, then you'll have to adjust any addresses below in the 7000h-70FFh range.

The addresses used by the front ends differ depending on the host system.

The jump table

The key to the interface between the two components is the jump table. This is described in the source file in_zxzvm.inc; it is located at address ZJT, which is 0E020h under ResiDOS and 04000h in the other versions. The table has 41 functions, covering access to Z-machine memory, screen I/O and file I/O.


In the Spectrum version, the startup code is in the form of a short BASIC program that loads the two machine-code modules and jumps to the interpreter entry point at 7000h. In the two PCW versions, the startup code is incorporated in the front-end programs (JOYCEIO.COM and ANNEIO.PRG respectively). Either way, the startup code loads both modules into memory and makes a call to 7000h.

Memory from 705Ch-70FFh can be used to store parameters for the front end, such as the filename to load or (in the case of the Spectrum versions) which font to use. The front end initialisation will be called with DE holding the address of this area. Memory from 7003h-705Bh is reserved for parameters for the interpreter itself. Currently, only the byte at 7003h is used; it holds the system type. This is usually 7 (Commodore 128), though the PcW16 front end sets it to 2 (Apple IIe).

Pretty much the first thing the interpreter core does is call the code at ZJT, to initialise the front end. At this point the front end would load some or all of the Z-code file (either using the filename at 705Ch, or asking interactively), initialise the screen, and so on.


The Z-machine has 64k of RAM and up to 448k of ROM. Representing all of this in the Z80's 64k address space along with the two ZXZVM modules and the host operating system can be something of a challenge.

The Spectrum +3 version allocates memory as follows:

The ResiDOS version allocates memory as follows:

The PCW10 version allocates memory as follows:

The PcW16 version allocates memory as follows:

Note that with all of these systems, there is at least 64k of extra banked memory containing the Z-machine's RAM. This isn't to say that all implementations must use banked memory; it's just that if banked memory isn't available, you'll have to find some other way of getting the same effect. Swapping to floppy may not perform well enough.

Screen model

The existing implementations all use screen drivers which can position the cursor, do reverse video (and in some cases other special effects), erase a line, and scroll a number of lines at the bottom of the screen while leaving the top untouched. In addition, the PCW10 and Spectrum front ends use software font redefinition to provide the Beyond Zork graphics font.

Colour support in ZXZVM is untested as none of the existing front ends implement it.


Versions 4 and later of the Z-machine allow text input to be interrupted by a timeout. Ideally your system should have a clock with 1/10 sec resolution; the PCW10 version uses the CP/M 3 clock and therefore has a 1 sec resolution.


ZXZVM's demands on the filesystem are fairly modest (apart from anything else, it has to support the PcW16, a system that allows at most two files open at any one time). For Z-machine file operations, it doesn't require anything fancy; just the ability to open a file and do sequential reads or writes.

If there isn't enough memory available to hold the whole gamefile, then you will have to write a virtual memory system capable of paging bits of it in and out as required. Under these circumstances, such features as random access will become necessary.

On porting ZXZVM to generic CP/M

From time to time, I've seen people discuss the lack of a version 5 Z-code interpreter for CP/M. And inevitably, someone points out that ZXZVM exists on the PCW, and reasons "surely it can't be that hard to port it to the CPC / Kaypro / Osborne / whatever platform we're discussing?"

Since no-one's done it in the last ten years, I think you can assume that it is that hard. It's not just a matter of tweaking a few escape codes to match whatever terminal your system has. The PCW front end makes no attempt at portability; it loads the entire story file into the PCW's RAMdisc, using direct hardware access to do so. (It also uses direct hardware access to redefine the font, but that's a less fundamental requirement).

As it is, therefore, the PCW front end can only be ported to a system with a similarly large amount of banked memory. If you're planning to port to another CP/M system, you may want to try one of the following strategies:

Exercises for the interested reader


John Elliott 2006-05-05