The InfoTaskForce Guide to Z-Code Versions ========================================== Copyright (c) 1992 InfoTaskForce Introduction ------------ Infocom have produced several different Z-Code Interpreters, each one providing more features than the previous ones. The first byte of each game's data file indicates which interpreter version it was compiled to use. This file describes some of the differences between Z-Code versions. Z-Code Version 1. ----------------- The initial Infocom games produced for the Apple ][ series of personal computers running Apple DOS 3.2 used Z-Code Version 1. The Z-Machine's stack was 512 bytes. The resident portion of a data file was limited to less than 48 Kbytes (the limit of the Apple ][+ main memory). Features of the Version 1 interpreter included: * The global property table was $35 bytes. * The maximum number of properties per object is 32. * The maximum length of any property is 8 bytes. * Any address given in Page/Offset form represents a data file offset in words, not bytes. The Version 1 object structure was as follows: typedef struct { byte attributes[4] ; byte location[1] ; byte link[1] ; byte holds[1] ; byte prop_ptr[2] ; } std_object ; The Version 1 data file header has the following structure: struct header { byte z_code_version ; /* Game's Z-CODE Version Number */ byte mode_bits ; /* Status Bar display indicator */ word release ; /* Game Release Number */ word resident_bytes ; /* No. bytes in the Resident Area */ word start ; /* Offset to Start of Game */ word vocab ; /* Offset to VocabtList */ word object_list ; /* Offset to Object/Room List */ word globals ; /* Offset to Global Variables */ word save_bytes ; /* No. bytes in the Save Game Area */ word padding[24] ; /* Blank */ } ; Z-Code Version 2. ----------------- Infocom games produced for the Apple ][ running DOS 3.3 initially used Z-Code Version 2 (and later Z-Code Version 3). Version 2 introduced several minor enhancements: * The character table used in the encoding of the game's vocabulary and text was changed. * The method of encoding a carriage return/line feed was changed. * The concept of a common word list was introduced. The Version 2 data file header has the following structure: struct header { byte z_code_version ; /* Game's Z-CODE Version Number */ byte mode_bits ; /* Status Bar display indicator */ word release ; /* Game Release Number */ word resident_bytes ; /* No. bytes in the Resident Area */ word start ; /* Offset to Start of Game */ word vocab ; /* Offset to VocabtList */ word object_list ; /* Offset to Object/Room List */ word globals ; /* Offset to Global Variables */ word save_bytes ; /* No. bytes in the Save Game Area */ word script_status ; /* Z-CODE printing modes */ char serial_no[6] ; /* Game's Serial Number */ word common_word ; /* Offset to Common Word List */ word padding[19] ; /* Blank */ } ; Z-Code Version 3. ("Standard") ----------------- The most common game format is Z-Code Version 3, which includes games such as: Ballyhoo Cutthroats Deadline Enchanter Hitchhiker Hollywood Hijinx Infidel Leather Goddesses Lurking Horror Moonmist Planetfall Plundered Hearts Seastalker Sorceror Spellbreaker Starcross Stationfall Suspect Suspended Wishbringer Witness Zork I Zork II Zork III Version 3 introduced the following enhancements: * The common word list was expanded from one bank of 64 words to 3 banks of 64 words. * The way of encoding capital letters and punctuation symbols was changed. * Two new opcodes: "prt_status" (Opcode 0xBC) and "verify" (Opcode 0xBD). Neither opcode takes any arguements. The "verify" opcode is used to verify the integrity of the game's data file and the "prt_status" opcode prints the status bar at the top of the screen. In previous versions, the status bar was printed solely by a subroutine of the "input" opcode. * Some Version 3 interpreters included two additional opcodes for use on machines with control over the cursor and CRT being used. These are "split_screen" (Opcode 0xEA) and "set_current_window" (Opcode 0xEB). If an interpreter includes these opcodes, it should set bit 5 of the "mode_bits" byte in the data file's header before running the game. The data file contains opcodes which examine this byte on the fly and only execute these opcodes if bit 5 is set. Each take a single arguement. The only game that I have found that uses these opcodes is Seastalker (Revision: 15) - when in the scimitar submarine, type "set sonar to auto" invokes a splitting of the display into two windows. Typing "set sonar to manual" restores the screen to normal. This data file also makes use of the TANDY flag in the game header's "mode_bits" field and the USE_NON_PROP_FONT flag in the game header's "script_status" field. The Version 3 data file header has the following structure: struct header { byte z_code_version ; /* Game's Z-CODE Version Number */ byte mode_bits ; /* Status Bar display indicator */ word release ; /* Game Release Number */ word resident_bytes ; /* No. bytes in the Resident Area */ word start ; /* Offset to Start of Game */ word vocab ; /* Offset to VocabtList */ word object_list ; /* Offset to Object/Room List */ word globals ; /* Offset to Global Variables */ word save_bytes ; /* No. bytes in the Save Game Area */ word script_status ; /* Z-CODE printing modes */ char serial_no[6] ; /* Game's Serial Number */ word common_word ; /* Offset to Common Word List */ word verify_length ; /* No. words in the Game File */ word verify_checksum ; /* Game Checksum - used by Verify */ word padding[17] ; /* Blank */ } ; Z-Code Version 4. ("Plus") ----------------- Z-Code was completely overhauled with the introduction of Version 4, which lifted many of the memory size constraints imposed on the earlier interpreter versions. This allowed games such as A Mind Forever Voyaging Bureaucracy Nord & Bert Trinity to be created. The changes in Z-Code Version 4 included: * The Z-Machine's stack was increased from 512 bytes to 1024 bytes. * The memory limit of 48 Kbytes placed on the resident portion of a data file was changed to 128 Kbytes. * The size of the vocabulary words was increased from 6 characters to 9 characters. * The size of the global property table was increased from $35 bytes to $70 bytes. * The maximum number of properties per object was increased from 32 to 64. * The maximum length of any property was increased from 8 bytes to 64 bytes. * Any address given in Page/Offset form represents a data file offset in longwords, not words as in previous versions. * In order to increase the number of objects in a game above the 256 object limit imposed in earlier interpreter versions, the definition of an object was changed to the following: typedef struct { byte attributes[6] ; byte location[2] ; byte link[2] ; byte holds[2] ; byte prop_ptr[2] ; } plus_object ; * This change in the definition of an object caused the following opcodes to be modified: "get_link", "get_holds", "get_loc", "get_p_len", "remove_obj", "p_obj", "check_loc", "test_attr", "set_attr", "clr_attr", "transfer", "get_prop", "get_prop_addr", "get_next_prop" and "put_prop". * The following opcodes were also modified: "print2", "gosub" and "random". * The "prt_status" opcode was removed. * The following new opcodes were introduced: "gosub2", "gosub3", "clear_screen", "erase_line", "set_cursor_posn", "null2", "set_text_mode", "io_buffer_mode", "io_mode", "null3", "beep", "get_key" and "compare2". The Version 4 data file header has the following structure: struct header { byte z_code_version ; /* Game's Z-CODE Version Number */ byte mode_bits ; /* Status Bar display indicator */ word release ; /* Game Release Number */ word resident_bytes ; /* No. bytes in the Resident Area */ word start ; /* Offset to Start of Game */ word vocab ; /* Offset to VocabtList */ word object_list ; /* Offset to Object/Room List */ word globals ; /* Offset to Global Variables */ word save_bytes ; /* No. bytes in the Save Game Area */ word script_status ; /* Z-CODE printing modes */ char serial_no[6] ; /* Game's Serial Number */ word common_word ; /* Offset to Common Word List */ word verify_length ; /* No. words in the Game File */ word verify_checksum ; /* Game Checksum - used by Verify */ byte interpreter_number ; /* Number - Set by Interpreter */ byte interpreter_version ; /* ASCII Char - Set by Interpreter */ byte screen_height ; /* Screen Height - Set by Interpreter */ byte screen_width ; /* Screen Width - Set by Interpreter */ word padding[15] ; /* Blank */ } ; Z-Code Version 5. ("Advanced") ----------------- The screen handling facilities of Version 4 were enhanced with the release of Version 5 allowing such games as: Beyond Zork Border Zone Sherlock Enhancements included the addition of mouse support (for machines like the Macintosh and the IBM PC) and sound (the game Sherlock for the Macintosh initially contained no sound support. A sound data file was included in a later release). Support was also added for extended charcter sets (the game Beyond Zork on the IBM PC uses the extended IBM PC character set to print graphics symbols and on the Macintosh uses a custom font for the same purpose). The following changes were made in Version 5: * The following opcodes were removed: "save_game" and "restore_game". * The following opcodes were modified: "pop_stack","rtn","gosub" and "compare2". * The "not" opcode was moved. * The following opcodes were added: "branch_true","gosub4", "gosub5", "throw_away_stack_frame", "parse", "encrypt", "block_copy", "print_text", "num_local_params", "logical_shift", "arithmetic_shift", "clear_flag", "test_byte_array" and "set_flag". The Version 5 data file header has the following structure: struct header { byte z_code_version ; /* Game's Z-CODE Version Number */ byte mode_bits ; /* Status Bar display indicator */ word release ; /* Game Release Number */ word resident_bytes ; /* No. bytes in the Resident Area */ word start ; /* Offset to Start of Game */ word vocab ; /* Offset to VocabtList */ word object_list ; /* Offset to Object/Room List */ word globals ; /* Offset to Global Variables */ word save_bytes ; /* No. bytes in the Save Game Area */ word script_status ; /* Z-CODE printing modes */ char serial_no[6] ; /* Game's Serial Number */ word common_word ; /* Offset to Common Word List */ word verify_length ; /* No. words in the Game File */ word verify_checksum ; /* Game Checksum - used by Verify */ byte interpreter_number ; /* Number - Set by Interpreter */ byte interpreter_version ; /* ASCII Char - Set by Interpreter */ byte screen_height ; /* Screen Height - Set by Interpreter */ byte screen_width ; /* Screen Width - Set by Interpreter */ byte left ; /* Left Coord. - Set by Interpreter */ byte right ; /* Right Coord. - Set by Interpreter */ byte top ; /* Top Coordinate - Set by Interpreter*/ byte bottom ; /* Bottom Coord. - Set by Interpreter */ byte unknown1 ; /* Unknown - Set by Interpreter */ byte unknown2 ; /* Unknown - Set by Interpreter */ word padding1[2] ; /* Blank */ byte unknown3 ; /* Unknown - Set by Interpreter */ byte unknown4 ; /* Unknown - Set by Interpreter */ word unknown5 ; /* Unknown - Set in Data File */ word padding2[3] ; /* Blank */ word unknown6 ; /* Unknown - Set in Data File */ word padding3[4] ; /* Blank */ } ;