The Z-Machine is a text based interpreter which runs text adventures made by Infocom and Z-code files.
CPCZVM is a Z-Machine interpreter for the CPC. It is a modification of ZXZVM, an interpreter made by John Elliott for the PCW. The Amstrad version was converted by Kevin Thacker. There are two versions.
- A version for CPM
- A version for AMSDOS
CPCZVM for CPM features a virtual memory system supporting both the Z-machines RAM and ROM. It runs under CPM2.2 and CPM+. CPCZVM has been written to be as compatible with CPM as possible and should run on other CPMs for the Amstrad.
CPCZVM will not run under Amstrad's CPM2.2 distribution because it doesn't have enough TPA. However you can use DkTronics_CPM which has a larger TPA.
Running an adventure
- Copy CPCZVM.COM, ZXZVM.BIN and the game file (e.g. ADVENT.Z3) to media which has at least 64KB free. All of these should be in the same location.
- Boot into CP/M.
- Select the disc (e.g. B:)
- Type: CPCZVM ADVENT.Z3 to start.
- Timed input
- Italics, Bold and other font styles.
- CPM2.2 version is better than the CPM+ version because it can use windows like the AMSDOS version to allow individual sections of the display to be split or scrolling. Amstrad's implementation of CPM is assumed and that printing goes to the firmware functions and the firmware control codes can be executed.
- CPM+ version uses the VT52 terminal emulation but because that doesn't support windows it is less powerful.
- Using a RAMdisk under CPM+ doesn't make much of a difference to the speed of loading.
- The program reads the first 64KB of the game file, padding with 0's if less than 64KB, and writes out a SWAP.DAT file. A Z-machine has a maximum of 64KB of RAM. Therefore the disc which CPCZVM is run from must have at least 64KB free and be writeable. When the RAM is written to this swap file is updated. This swap file is also re-generated from the game file when the game is restarted.
- Part of the CPC's memory is used for the virtual memory cache. A page table describes which virtual memory blocks are loaded and their physical location within RAM. This is initially populated from the start from the game file. When a read is done, the virtual memory address is looked up in the page table, and if it is mapped to physical memory then the physical memory is read. A write is similar to a read with an additional flag being set if a write has been made to a mapped page. If a virtual memory page is not currently loaded, then depending on the metric used, a page is chosen to be evicted. If the page has been modified it is committed to the swap file. Then the new page is loaded into the same physical location. During game play, any access to virtual memory in the first 64KB comes from the swap file, and any accesses above 64KB come from the game file. In this way the virtual memory supports both Z-Machine RAM and Z-Machine ROM.
- CP/M is used because it has a random access filesystem compared to AMSDOS which doesn't. The random access is required to read blocks from the swap and game file when needed.
- Disc accesses use normal CP/M functions so it should work with other devices such as RAM discs, Harddisks etc.
CPCZVM for AMSDOS requires additional Dk'tronics compatible memory (e.g. X-MEM ). The entire game file is loaded into available RAM so it is recommended to use a 512KB RAM expansion. Loading uses CAS IN CHAR so is very slow.
- This version supports the v1.0 specification
- It has been tested against oztest, czech, etude and strict tests.
What is supported
- Transcript (goes to printer)
- Timed input
- Font styles (bold, italics etc)
- Z-Machine window opcodes
What isn't supported
- V6 or V7 games
- Colours (this requires that all the colours can be displayed at once)
Running an adventure
- Copy CPCZVM.BAS and the game file (e.g. ADVENT.Z3) to media. Both of these should be in the same location.
- Make a simple BASIC loader with this form:
5 BORDER 0:INK 0,0:INK 1,13 10 a$="advent.z3" 20 chain"cpczvm"
and save it:
- Now you can run your adventure:
- In the example above 'advent.z3' is the name of the game file. It should not have a header.
- 'a$' variable must be used. You can't use another name because CPCZVM.BAS requires it to have this name.
- In the example above 'advent' is the name of your basic loader. You can name it as you wish.
- It is advised to use a large ram expansion (>64KB) because many game files are large and you need plenty of extra ram to load large game files.
- If the adventure will not fit on a normal CPC Data format disk, use ParaDOS and copy the files to a ROMDOS D1 format disc.
- The CPCZVM.BAS contains a fixed basic stub followed by the machine code. The BASIC stub must not be modified or it will break CPCZVM.BAS. Using a BASIC stub means I don't need to re-enable any ROMs (like I would if RUN was used) and the current drive and filesystem remains active allowing hard disks and other DOS to be used. In addition I can pass HIMEM to know if there is enough RAM free (expansion ROMs can modify HIMEM to allocate work space) and a string variable containing the game filename.
- The program uses the firmware except TXT WRITE CHAR is patched so that bold, italics and inverse is supported. The font is manipulated as it is drawn.
- Transcript goes to the printer.
- The program detects the amount of additional RAM and will warn if there is not enough when loading the game file.
- The program only supports Dk'Tronics compatible RAM.
- The entire game file is loaded into extra ram using "CAS IN CHAR" functions. This is used because the extra memory is paged in 16KB at a time and CAS IN DIRECT reads in an entire block and the game files exceed the size of 16KB and do not require an AMSDOS header to be added.
- The BASIC boot program allows a game filename to be passed to CPCZVM.BAS without requiring it to be modified. The use of CHAIN keeps the defined variables and HIMEM.
- This version should run from X-MASS or other hardware.