1.1 Regions of memory / 1.2 Addresses
The memory map of the Z-machine is an array of bytes with "byte addresses" running from 0 upwards. This is divided into three regions: "dynamic", "static" and "high". Dynamic memory begins from byte address $00000 and runs up to the byte before the byte address stored in the word at $0e in the header. (Dynamic memory must contain at least 64 bytes.) Static memory follows immediately on. Its extent is not defined in the header (or anywhere else), though it must end by the last byte of the story file or by byte address $0ffff (whichever is lower). High memory begins at the "high memory mark" (the byte address stored in the word at $04 in the header) and continues to the end of the story file. The bottom of high memory may overlap with the top of static memory (but not with dynamic memory).
Dynamic memory can be read or written to (either directly, using loadb, loadw, storeb and storew, or indirectly with opcodes such as insert_obj and remove_obj).
By tradition, the first 64 bytes are known as the "header". The contents of this are given later but note that games are not permitted to alter many bits inside it.
It is legal for games to alter any of the tables stored in dynamic memory above the header, provided they leave the tables in legal states.
Static memory can be read using the opcodes loadb and loadw. It is illegal for a game to attempt to write to static memory.
Except for its (possible) overlap with static memory, high memory cannot be directly accessed at all by a game program. It contains routines, which can be called, and strings, which can be printed using print_paddr.
The maximum permitted length of a story file depends on the Version, as follows:
V1-3 V4-5 V6-8 128 256 512
There are three kinds of address in the Z-machine, all of which can be stored in a 2-byte number: byte addresses, word addresses and packed addresses.
A byte address specifies a byte in memory in the range 0 up to the last byte of static memory.
A word address specifies an even address in the bottom 128K of memory (by giving the address divided by 2). (Word addresses are used only in the abbreviations table.)
***[1.0] A packed address specifies where a routine or string begins in high memory. Given a packed address P, the formula to obtain the corresponding byte address B is:
2P Versions 1, 2 and 3 4P Versions 4 and 5 4P + 8R_O Versions 6 and 7, for routine calls 4P + 8S_O Versions 6 and 7, for print_paddr 8P Version 8
R_O and S_O are the routine and strings offsets (specified in the header as words at $28 and $2a, respectively).
|002f0||object descriptions and properties|
|06ae6||end of file|
Inform never compiles any overlap between static and high memory (it places all data tables in dynamic memory). However, many Infocom games group tables of static data just above the high memory mark, before routines begin; some, such as 'Nord 'n' Bert...', interleave static data between routines, so that static memory actually overlaps code; and a few, such as 'Seastalker' release 15, even contain routines placed below the high memory mark. (The original idea behind the high memory mark was that everything below it should be stored in the interpreter's RAM, while what was above could reasonably be kept in "virtual memory", i.e., loaded off disc as needed.)
Note that the total of dynamic plus static memory must not exceed 64K. (In fact, 64K minus 2 bytes.) This is the most serious limitation on the Z-machine.
Throughout the specification, Versions 7 and 8 are identical to Version 5 except as stated at 1.1.4 and 1.2.3 above.
Contents / Preface / Overview
Section 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10 / 11 / 12 / 13 / 14 / 15 / 16
Appendix A / B / C / D / E / F