4 Copyright (C) 2024 Jason Self <j@jxself.org>
6 You can redistribute and/or modify this file under the terms of the
7 GNU General Public License as published by the Free Software
8 Foundation, either version 3 of the License, or (at your option) any
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this file. If not, see <https://www.gnu.org/licenses/>.
19 Chapter 1.1: Overview of ZAP and its Purpose
20 --------------------------------------------
22 ZAP (Z-language Assembly Program) is a software tool used to translate
23 assembly language code written for the Z-machine into a binary format
24 that can be directly executed by a compatible Z-language Interpreter
27 The Z-machine is a virtual machine specifically designed for running
28 interactive fiction games, also known as text adventures. Infocom
29 originally developed the Z-machine and its associated programming
30 language, ZIL (Zork Implementation Language) but now these belong to
33 ZAP is the last stage of the toolchain, after the source code has been
34 compiled into a a human-readable assembly language format. This
35 assembly language is then processed by ZAP, which converts it into the
36 binary format understood by the Z-machine.
38 ZAP is a two-pass assembler, meaning it processes the input file
39 twice. In the first pass, it analyzes the code, builds symbol tables,
40 and calculates addresses. In the second pass, it generates the binary
41 code and resolves any forward references to symbols.
43 This specification document provides a detailed explanation of ZAP's
44 functionality, including the supported assembly language syntax, data
45 structures, algorithms, and error handling mechanisms. It serves as a
46 guide for understanding and implementing ZAP.
48 ZAP is an integral component of the development system for interactive
49 fiction games. It bridges the gap between the high-level ZIL (Zork
50 Implementation Language) and the low-level Z-code that runs on the
51 Z-machine. Here's how ZAP fits into the overall development process:
53 1. **Game Design and Implementation:** Game designers and programmers
54 use a high-level language (the Zork Implementation Language, or
55 ZIL) to define the game's world, objects, characters, and
56 interactions. ZIL provides a more abstract and convenient way to
57 express the game's logic compared to directly writing Z-code
59 2. **ZIL Compilation:** The ZIL code is compiled into Z-code assembly
60 language. This assembly language represents the Z-code
61 instructions and data in a human-readable format.
62 3. **ZAP Assembly:** ZAP takes the Z-code assembly language as input
63 and translates it into the binary format understood by the
64 Z-machine. This binary code is what ultimately gets executed by
67 Chapter 1.2: Goals and Design Principles of ZAP
68 -----------------------------------------------
70 ZAP was designed with several key goals and principles in mind:
74 - **Provide a convenient and efficient way to write Z-code
75 programs:** ZAP's assembly language allows programmers to express
76 Z-code instructions and data in a more readable and structured
77 format compared to directly writing binary code.
78 - **Generate optimized and efficient Z-code:** ZAP optimizes the
79 generated code for efficient execution on the Z-machine, ensuring
80 smooth gameplay and minimizing memory usage.
81 - **Support debugging and troubleshooting:** ZAP can generate
82 optional listing files that provide insights into the generated
83 code, aiding in debugging and identifying issues.
84 - **Maintain portability across different platforms:** ZAP itself is
85 designed to be portable and run on various machines, allowing for
86 cross-platform development.
88 **Design Principles:**
90 - **Simplicity and clarity:** ZAP's assembly language syntax is
91 designed to be straightforward and easy to understand, minimizing
92 the learning curve for programmers.
93 - **Efficiency:** ZAP optimizes the generated code for efficient
94 execution on the Z-machine, taking advantage of the architecture's
96 - **Flexibility:** ZAP provides various directives and options to
97 give programmers control over the assembly process and allow for
99 - **Error detection and reporting:** ZAP incorporates robust error
100 detection mechanisms and provides informative error messages to
101 help programmers identify and fix issues.
102 - **Modularity:** ZAP is organized into well-defined modules, each
103 responsible for specific tasks, promoting code maintainability and
106 These goals and design principles have guided the development of ZAP
107 and continue to be relevant in understanding its functionality and
108 behavior. By adhering to these principles, ZAP provides a powerful and
109 efficient tool for assembling Z-code programs for interactive fiction
112 Chapter 1.3: Target Audience for the Specification
113 --------------------------------------------------
115 This specification document is primarily intended for the following
118 - **Z-machine enthusiasts and researchers:** The specification
119 offers detailed insights into the Z-code assembly language, ZAP's
120 internal workings, and the overall structure of Z-machine
121 programs. This information can be valuable for individuals
122 interested in understanding the Z-machine architecture and its
124 - **Interactive fiction developers:** Understanding ZAP's
125 functionality and the Z-code it generates can be beneficial for
126 game designers and programmers.
128 The document assumes a basic understanding of assembly language
129 concepts and the Z-machine architecture. However, it provides
130 sufficient detail and explanations to be accessible to individuals
131 with a general interest in interactive fiction and the technical
132 aspects of the Z-machine.
134 By catering to these different audiences, the specification aims to
135 contribute to the understanding of the Z-machine, and support the
136 continued development of interactive fiction games.
138 Chapter 2.1: Character Set and Lexical Elements
139 -----------------------------------------------
141 The Z-code assembly language used by ZAP consists of a defined
142 character set and specific lexical elements that form the building
143 blocks of instructions and directives.
147 The following characters are allowed in a ZAP program:
149 - **Letters:** A-Z (case-insensitive)
151 - **Special characters:** , ? \# . - \_ ' \" / : ( )
152 - **Whitespace:** Space and tab characters are ignored except as
154 - **Line endings:** Carriage return (`\r`), line feed (``), and form
155 feed (`\f`) characters are ignored.
157 **Lexical Elements:**
159 ZAP recognizes the following lexical elements:
161 - **Symbols:** Used to represent values and labels. They consist of
162 letters, digits, and some special characters. By convention,
163 pseudo-ops (assembler directives) begin with a period (`.`).
164 - **Numbers:** Represent integer values.
165 - **Strings:** Enclosed in double quotes (`"`). Double quotes within
166 strings are escaped by using two consecutive double quotes.
167 - **Operators:** Predefined symbols representing Z-machine
169 - **Pseudo-ops (directives):** Instructions to the assembler, such
170 as `.word`, `.str`, and `.funct`.
171 - **Operand prefixes:** Special characters used to indicate the type
172 of operand following them (e.g., `,` for general operand, `>` for
174 - **Comments:** Begin with a semicolon (`;`) and extend to the end
177 These lexical elements are combined to form valid assembly language
178 statements that are processed by ZAP.
180 **Note:** This chapter provides a basic overview of the character set
181 and lexical elements. More detailed information about specific
182 elements and their usage will be presented in subsequent chapters.
184 Chapter 2.2: Symbol Definition and Types (Global, Local, Constants)
185 -------------------------------------------------------------------
187 Symbols in ZAP are used to represent various types of values and
188 labels within the program. They play a crucial role in code
189 organization, readability, and address resolution.
191 **Symbol Definition:**
193 A symbol is defined by assigning it a value using either:
195 - **Equate statement:** `symbol = value`
196 - **Pseudo-op:** `.equal symbol, value`
197 - **Label definition:** `symbol::` or `symbol:`
201 ZAP distinguishes between three main types of symbols:
203 - **Global symbols:** Defined outside of any function and accessible
204 throughout the entire program. They can represent global
205 variables, function names, table names, and string names.
206 - **Local symbols:** Defined within a function using the `.funct`
207 directive and accessible only within that function. They represent
208 local variables and labels used for branching within the function.
209 - **Constants:** Represent fixed values that cannot be changed. They
210 are defined using equate statements or specific pseudo-ops like
213 **Naming Conventions:**
215 The following naming conventions exist:
217 - **Pseudo-ops:** Begin with a period (`.`).
218 - **Global labels:** End with two colons (`::`).
219 - **Local labels:** End with one colon (`:`)
221 **Symbol Redefinition:**
223 - **Global and local symbols:** Cannot be redefined within their
224 scope. Attempting to do so will result in an error.
225 - **Constants:** Can be redefined at any point in the program.
227 **Predefined Symbols:**
229 ZAP includes several predefined global symbols:
231 - **Operators:** Represent Z-machine instructions (e.g., `ADD`,
233 - **Pseudo-ops:** Represent assembler directives (e.g., `.word`,
235 - **Special symbols:** Represent specific data structures or
236 locations within the program (e.g., `VOCAB`, `OBJECT`, `STACK`).
238 Understanding symbol definition and types is essential for writing
239 well-structured and organized Z-code assembly programs. By following
240 the conventions and understanding the scope of different symbol types,
241 programmers can ensure proper address resolution and code
244 Chapter 2.3: Statement Syntax and Structure
245 -------------------------------------------
247 ZAP assembly language statements are line-oriented, meaning each
248 statement occupies a single line in the source file. Each statement
249 consists of four optional fields:
251 **Statement Structure:**
253 [label] [operator] [operands] [comment]
255 **Field Descriptions:**
257 - **Label:** A symbol followed by one or two colons, depending on
258 whether it's a local or global label.
259 - **Operator:** A predefined symbol representing either an operator
260 (Z-machine instruction) or a pseudo-op (assembler directive).
261 - **Operands:** A space or tab-separated list of operands, each
262 optionally preceded by an operand prefix character.
263 - **Comment:** Begins with a semicolon (`;`) and extends to the end
269 START:: .funct main ; Define the main function
270 add 1, 2 ; Add two constants
271 print "Hello" ; Print a string
272 jump END ; Jump to the END label
276 **Operand Prefixes:**
278 Operand prefixes are special characters used to indicate the type of
279 operand following them and provide additional information:
281 - **`,` (comma):** General operand.
282 - **`>` (greater than):** Return value operand. Specifies where the
283 return value of an instruction should be stored
284 - **`\` (backslash):** Branch on failure operand. Indicates the
285 branch target if the predicate fails
286 - **`/` (forward slash):** Branch on success operand. Indicates the
287 branch target if the predicate succeeds.
288 - **`=` (equal sign):** Value operand for assignments. Used for
289 assigning values to symbols
290 - **`+` (plus sign):** Addend operand for constant addition.
292 **Line Continuation:**
294 Operands can be continued to the next line by placing the operand
295 prefix character on one line and the corresponding operand on the next
298 **Note:** This chapter provides a general overview of statement syntax
299 and structure. More detailed information about specific operators,
300 pseudo-ops, and operands will be presented in subsequent chapters.
302 Chapter 2.4: Operands and Addressing Modes
303 ------------------------------------------
305 Operands in ZAP assembly language specify the data or values that
306 instructions operate on. ZAP supports three main types of operands:
310 - **Immediate:** A constant value directly encoded within the
311 instruction. It can be either a short (one-byte) or long
313 - **Variable:** A reference to a variable stored in memory. The
314 operand specifies the variable number, which is interpreted
315 differently depending on the context.
316 - **Other:** Represents special values like labels, function
317 pointers, or string pointers.
319 **Addressing Modes:**
321 ZAP uses different addressing modes to access and interpret operands:
323 - **Direct addressing:** The operand directly specifies the value or
324 memory address of the data. This is used for immediate operands
325 and some other types.
326 - **Indirect addressing:** The operand specifies the number of a
327 variable, which is then used to access the actual data in memory.
328 This is used for variable operands.
330 **Variable Addressing:**
332 Variable operands are interpreted as follows:
334 - **0:** Refers to the top of the game stack.
335 - **1-15:** Refer to local variables within the current function.
336 - **16-255:** Refer to global variables.
341 add 1, 2 ; Add two immediate operands
342 set var1, 5 ; Set the variable var1 to 5
343 jump START ; Jump to the label START
344 get table, 3 ; Get the 3rd element from the table
347 Understanding operand types and addressing modes is crucial for
348 writing correct and efficient Z-code assembly programs. By using the
349 appropriate operand prefixes and addressing modes, programmers can
350 ensure that instructions operate on the intended data and achieve the
353 Chapter 2.5: Instruction Formats (2OP, 1OP, 0OP, EXT)
354 -----------------------------------------------------
356 ZAP instructions are encoded in different formats depending on the
357 number and type of operands they require. This allows for efficient
358 use of memory while providing flexibility in instruction design.
360 **Instruction Formats:**
362 - **2OP (Two-operand):** This format is used for instructions with
363 two operands, typically immediate values or variables. It is the
364 most compact format but has limitations on the types of operands
366 - **1OP (One-operand):** This format is used for instructions with a
367 single operand, which can be an immediate value, variable, or
369 - **0OP (Zero-operand):** This format is used for instructions that
370 do not require any explicit operands.
371 - **EXT (Extended):** This format is used for instructions that
372 cannot be represented in the other formats due to:
373 - Having more than two operands.
374 - Requiring long immediate operands.
375 - Being rarely used instructions.
377 **Encoding Details:**
379 The specific encoding of each format varies, but generally:
381 - **2OP:** The opcode byte contains both the operator and mode bits,
382 specifying the instruction and the types of its two operands.
383 - **1OP:** The opcode byte contains the operator and mode bits for
385 - **0OP:** The opcode byte solely represents the instruction, as
386 there are no operands.
387 - **EXT:** The opcode byte identifies the instruction, and a
388 separate byte (or two bytes for some instructions) follows the
389 opcode to specify the operand types and modes.
391 **Extended Opcode Prefix (EXTOP):**
393 ZAP provides an additional 256 extended opcodes through the `EXTOP`
394 instruction. When `EXTOP` is encountered, the next byte is interpreted
395 as an opcode with its value increased by 256. This allows for a larger
396 instruction set while maintaining backward compatibility with older
399 **Choosing the Right Format:**
401 The assembler automatically chooses the most efficient format for each
402 instruction based on the number and types of operands. Programmers do
403 not need to explicitly specify the format.
405 The assembler determines the most efficient instruction format by
406 following a set of rules based on the number and types of operands
407 involved. Here's a simplified explanation of the process:
409 1. **Count the number of operands:**
410 - If there are **zero operands**, the **0OP format** is used.
411 - If there is **one operand**, the **1OP format** is used,
412 unless the operand is a long immediate value, in which case
413 the **EXT format** is necessary.
414 - If there are **two operands**:
415 - If both operands are either immediate values or variables,
416 and neither is a long immediate, the **2OP format** is
418 - Otherwise, the **EXT format** is used.
419 2. **Check for special cases:**
420 - Some instructions, like `EQUAL?`, can take a variable number
421 of operands. In such cases, the **EXT format** is used
422 regardless of the actual number of operands provided.
423 - Certain rarely used instructions might also be encoded in the
424 **EXT format** even if they could fit in other formats. This
425 is done to optimize the overall instruction set usage.
427 By following these rules, the assembler ensures that each instruction
428 is encoded in the most compact and efficient format possible, reducing
429 the overall size of the Z-code program and improving its execution
434 - The instruction `add 1, 2` has two immediate operands, so it can
435 be encoded in the **2OP format**.
436 - The instruction `set var1, 5` has one variable operand and one
437 immediate operand, so it can also be encoded in the **2OP
439 - The instruction `print "Hello"` has one string operand, which is
440 considered an "other" type. Therefore, it needs the **EXT
442 - The instruction `jump START` has one label operand, also requiring
445 Understanding instruction formats is helpful for comprehending the
446 structure of Z-code programs and how instructions are encoded in
447 memory. However, for most programming tasks, it is sufficient to focus
448 on the instruction names and operands, as ZAP handles the format
449 selection automatically.
451 Chapter 2.6: Instruction Values and Predicates
452 ----------------------------------------------
454 Some ZAP instructions return values or act as predicates, influencing
455 the flow of control in the program.
457 **Instruction Values:**
459 Certain instructions, such as arithmetic and logical operations,
460 produce a value as a result of their execution. This value can be:
462 - **Pushed onto the game stack:** This is the default behavior if no
463 explicit destination is specified.
464 - **Stored in a variable:** The instruction can be followed by an
465 operand prefix `>` and a variable number to indicate where the
466 value should be stored.
471 add 1, 2 ; Value is pushed onto the stack
472 add 1, 2 > var1 ; Value is stored in the variable var1
477 Predicate instructions evaluate a condition and implicitly perform a
478 conditional branch based on the result. They are typically used for
479 decision-making and control flow within the program.
481 **Branch Polarity and Offset:**
483 Predicate instructions are followed by one or two bytes that specify:
485 - **Branch polarity:** Whether the branch occurs on success
486 (predicate evaluates to true) or failure (predicate evaluates to
487 false). This is indicated by the high-order bit of the first byte.
488 - **Branch offset:** The distance to jump if the branch condition is
489 met. This can be either a short (6-bit) or long (14-bit) offset.
493 The branch offset determines the target of the conditional jump:
495 - **Offset 0:** Executes an `RFALSE` instruction, returning false
496 from the current function.
497 - **Offset 1:** Executes an `RTRUE` instruction, returning true from
498 the current function.
499 - **Other offsets:** Jumps to the instruction located at the current
500 address plus the offset minus two.
505 less? var1, 5 / label1 ; Branch to label1 if var1 is less than 5
508 Understanding instruction values and predicates is essential for
509 controlling the flow of execution in Z-code programs. By using
510 predicates and specifying appropriate branch targets, programmers can
511 implement conditional logic and decision-making within their games.
513 Chapter 3.1: Detailed Description of Each Opcode and Directive
514 --------------------------------------------------------------
516 This chapter provides a comprehensive description of each opcode and
517 directive supported by ZAP. For each element, the following
518 information is provided:
520 - **Name:** The name of the opcode or directive.
521 - **Syntax:** The format of the instruction or directive, including
522 operand types and prefixes.
523 - **Functionality:** A detailed explanation of what the opcode or
525 - **Special cases:** Any special conditions or behaviors to be aware
527 - **Error conditions:** Potential errors that might occur during
528 assembly or execution.
529 - **Examples:** Illustrative examples of how the opcode or directive
532 This chapter serves as a reference for understanding the functionality
533 and usage of each opcode and directive available in ZAP. By consulting
534 this information, programmers can write accurate and efficient Z-code
539 **.ALIGN** is a directive that instructs the assembler to align the
540 next generated code or data to a specified byte boundary. This can be
541 useful for ensuring proper memory access and improving performance on
542 certain architectures.
552 The `.align` directive pads the object file with zero bytes until the
553 current address is a multiple of the specified `value`. This
554 effectively aligns the next instruction or data element to the
559 - If `value` is 1, the directive has no effect, as all data is
560 already aligned to a byte boundary.
561 - If `value` is not a power of two, the assembler may align to the
562 next higher power of two.
564 **Error Conditions:**
566 An error occurs if `value` is zero or negative.
572 .word data1 ; data1 will be aligned to a 4-byte boundary
575 .funct func1 ; func1 will be aligned to an 8-byte boundary
580 - Aligning data structures to their natural word or longword
581 boundaries can improve memory access efficiency.
582 - Some Z-machine instructions might have specific alignment
583 requirements for optimal performance.
584 - Aligning functions can be helpful for debugging and code analysis.
586 **Note:** While `.align` can be used to enforce specific alignment, it
587 is generally recommended to let the assembler choose the appropriate
588 alignment for optimal code generation.
592 The `.BYTE` directive instructs the assembler to generate one or more
593 byte values in the object file. It is used to define raw byte data or
594 initialize specific memory locations with byte values.
599 .byte value1 [, value2 ...]
604 The `.byte` directive generates the specified byte values sequentially
605 in the object file. Each value must be a constant expression that
606 evaluates to a number within the range of 0 to 255.
612 **Error Conditions:**
614 An error occurs if a value exceeds the byte range (0-255).
619 .byte 10, 20, 30 ; Generates three bytes with values 10, 20, and 30
620 .byte 'A' ; Generates a byte with the ASCII value of 'A' (65)
625 - Defining raw byte data for specific purposes, such as flags or
627 - Initializing memory locations with specific byte values.
628 - Embedding special characters or control codes within the object
631 **Note:** While `.byte` allows for precise control over byte values,
632 it is generally recommended to use higher-level directives like
633 `.word` or `.str` whenever possible, as they provide better
634 readability and maintainability.
638 The `.CHRSET` directive allows the programmer to redefine the
639 character sets used for encoding strings in the Z-machine. This can be
640 useful for optimizing string storage and handling characters specific
641 to certain languages or display systems.
646 .chrset id, char1, char2, ..., charN
651 The `.chrset` directive redefines one of the three character sets used
654 - **`id`:** Specifies the character set to modify (0, 1, or 2).
655 - **`char1, char2, ..., charN`:** A list of characters (specified as
656 their ASCII values) that will be assigned to the character set.
658 The number of characters provided depends on the `id`:
660 - **Set 0 and 1:** 26 characters are expected.
661 - **Set 2:** 24 characters are expected (excluding ASCII escape and
666 - Character set 2 has two special characters that cannot be
668 - **6:** Represents the ASCII escape sequence.
669 - **7:** Represents the newline character.
671 **Error Conditions:**
673 - An error occurs if `id` is not 0, 1, or 2.
674 - An error occurs if the number of characters provided does not
675 match the expected count for the specified `id`.
680 .chrset 0, 'a', 'b', ..., 'z' ; Redefines character set 0 with lowercase letters
681 .chrset 1, 'A', 'B', ..., 'Z' ; Redefines character set 1 with uppercase letters
686 - Optimizing string storage by assigning frequently used characters
687 to the compact character sets.
688 - Handling characters specific to certain languages or display
689 systems that are not included in the default character sets.
691 **Note:** Redefining character sets can have significant implications
692 for string encoding and decoding. It is generally recommended to use
693 the default character sets unless there is a specific need for
694 optimization or handling special characters.
698 The `.DEFSEG` directive is used to define a segment and specify its
699 relationships with other segments. Segments are logical divisions of
700 the Z-code program that can be used to optimize disk usage and loading
701 times in multi-disk games.
706 .defseg name, seg1, seg2, seg3
711 The `.DEFSEG` directive performs the following:
713 - **Defines a segment:** Creates a new segment with the specified
715 - **Specifies adjacent segments:** Declares that the segment is
716 adjacent to the segments `seg1`, `seg2`, and `seg3`. This
717 information is used by the `zsplit` tool to determine how to
718 distribute segments across multiple disks.
722 - If the segment `name` is "0", it refers to the default segment
723 that contains all preloaded data and code.
724 - If a segment name is not defined with `.DEFSEG`, it is implicitly
725 considered adjacent to segment 0.
727 **Error Conditions:**
729 An error occurs if a segment name is not a valid symbol.
734 .defseg "ROOM", "HALL", "GARDEN" ; Defines the "ROOM" segment and declares it adjacent to "HALL" and "GARDEN" segments
735 .defseg "STARTUP", "MAIN" ; Defines the "STARTUP" segment and declares it adjacent to the "MAIN" segment
740 - Organizing the game's code and data into logical segments for
741 efficient disk usage and loading.
742 - Informing the `zsplit` tool about segment relationships to
743 optimize the distribution of segments across multiple disks.
745 **Note:** Segment definitions and adjacency information are primarily
746 used by the `zsplit` tool and do not directly affect the execution of
751 The `.END` directive marks the end of the assembly language program.
752 It instructs the assembler to stop processing input and perform final
763 When the `.END` directive is encountered, the assembler performs the
766 - **Stops processing input:** Any code or directives following
768 - **Resolves forward references:** Performs fixup operations to
769 resolve any outstanding forward references to symbols.
770 - **Generates final output:** Writes the assembled Z-code program to
771 the object file and generates any optional listing or error files.
777 **Error Conditions:**
779 An error might occur during fixup if undefined symbols are
792 The `.END` directive is mandatory and must be placed at the end of
793 every Z-code assembly program to signal the completion of the assembly
796 **Note:** It is essential to ensure that all necessary code and data
797 have been defined before the `.END` directive, as anything following
798 it will not be processed by the assembler.
802 The `.ENDI` directive marks the end of an `.INSERT` file. It instructs
803 the assembler to return to the previous input source and continue
814 The `.ENDI` directive is used in conjunction with the `.INSERT`
815 directive, which allows the contents of another file to be inserted
816 and assembled at a specific point in the main source file. When
817 `.ENDI` is encountered, the assembler:
819 - **Stops processing the inserted file:** Any code or directives
820 following `.ENDI` in the inserted file are ignored.
821 - **Returns to the previous input source:** The assembler resumes
822 processing the main source file from the point where the `.INSERT`
823 directive was encountered.
827 - A `.ENDI` directive without a preceding `.INSERT` directive is an
830 **Error Conditions:**
832 An error occurs if `.ENDI` is found outside of an inserted file.
837 ; ... main source file ...
841 ; ... contents of header.zap ...
845 ; ... main source file continues ...
850 - Modularizing code by separating commonly used routines or data
851 into separate files that can be inserted into multiple programs.
852 - Including header files that define constants, macros, or other
855 **Note:** The `.INSERT` and `.ENDI` directives provide a mechanism for
856 code inclusion and modularity, but their usage should be carefully
857 considered to avoid potential complexity and maintainability issues.
861 The `.ENDSEG` directive closes all currently open segments. Segments
862 are logical divisions of the Z-code program used to optimize disk
863 usage and loading times in multi-disk games.
873 The `.ENDSEG` directive closes any segments that were previously
874 opened with the `.SEGMENT` directive. This indicates to the assembler
875 that the code and data belonging to those segments have been defined.
879 - If no segments are currently open, the `.ENDSEG` directive has no
882 **Error Conditions:**
891 ; ... code and data for the ROOM segment ...
898 - Ensuring that all segments are properly closed before the end of
899 the assembly process.
900 - Organizing code and data into logical segments for efficient disk
903 **Note:** Segment definitions and closures are primarily used by the
904 `zsplit` tool and do not directly affect the execution of the Z-code
909 The `.ENDT` directive marks the end of a table definition. Tables are
910 logical structures used to organize data in Z-code programs.
920 The `.ENDT` directive must be used to terminate a table that was
921 previously declared with the `.TABLE` directive. It performs the
924 - **Checks table size:** If a size was specified in the `.TABLE`
925 directive, the assembler verifies that the actual table size does
926 not exceed the declared size.
927 - **Finalizes table data:** The assembler performs any necessary
928 operations to finalize the table data, such as padding or
933 - A `.ENDT` directive without a preceding `.TABLE` directive is an
936 **Error Conditions:**
938 - An error occurs if the actual table size exceeds the declared size
939 (if specified in `.TABLE`).
945 .word data1, data2, data3
951 - Defining tables of data with a specific size and ensuring that the
952 size is not exceeded.
953 - Organizing data into logical structures for easier access and
956 **Note:** The `.TABLE` and `.ENDT` directives provide a way to define
957 and manage tables in Z-code programs, but their usage should be
958 consistent and well-structured to avoid potential errors and
959 maintainability issues.
963 The `.FALSE` directive generates a word (two-byte) value of 0 in the
964 object file. It is used to represent the boolean value `false` or to
965 initialize memory locations with a zero value.
975 The `.false` directive simply generates a word with the value 0 at the
976 current address in the object file.
982 **Error Conditions:**
989 .false ; Generates a word with value 0
990 set flag1, .false ; Sets the flag variable `flag1` to false
995 - Representing the boolean value `false` in conditional statements
997 - Initializing variables or memory locations with a zero value.
999 **Note:** The `.false` directive is equivalent to using `.word 0`.
1000 However, `.false` provides better readability and clarity when
1001 representing boolean values.
1005 The `.FSTR` directive defines a string as a "frequent string" and adds
1006 it to the frequent words table. Frequent strings are short, commonly
1007 used substrings that can be referenced efficiently within other
1008 strings, reducing overall memory usage.
1018 The `.fstr` directive performs the following:
1020 - **Defines a symbol:** Creates a global symbol with the specified
1021 `name`. The value of the symbol is the address of the string
1022 divided by 2 (since strings are stored as words).
1023 - **Outputs the string:** Generates the string in the object file,
1024 aligning it to a word boundary.
1025 - **Adds to frequent words table:** Adds the string to the frequent
1026 words table, which is used by the Z-machine to efficiently
1027 reference frequently used substrings within other strings.
1031 - Frequent strings cannot contain other frequent strings within
1033 - The frequent words table has a limited size (96 entries). If this
1034 limit is exceeded, the assembler will issue an error.
1036 **Error Conditions:**
1038 - An error occurs if `name` is not a valid symbol.
1039 - An error occurs if the frequent words table is full.
1044 .fstr "the", "the " ; Defines the frequent string "the"
1045 .fstr "and", "and " ; Defines the frequent string "and"
1050 - Optimizing string storage by defining frequently used words or
1051 phrases as frequent strings.
1052 - Reducing the overall size of the Z-code program by efficiently
1053 referencing common substrings.
1055 **Note:** The use of frequent strings can improve memory efficiency,
1056 but it is important to choose appropriate strings and avoid exceeding
1057 the table size limit.
1061 The `.FUNCT` directive defines a function and begins a new local
1062 symbol block. Functions are subroutines that can be called and return
1063 values, allowing for modular and reusable code.
1068 .funct name [, arg1 [: type] [, arg2 [: type] ...]]
1073 The `.funct` directive performs the following:
1075 - **Defines a function:** Creates a new function with the specified
1076 `name`. The function name becomes a global symbol.
1077 - **Starts a new local symbol block:** Any symbols defined after
1078 `.funct` are considered local to the function and are not
1079 accessible outside of it.
1080 - **Defines local variables:** The optional `arg1`, `arg2`, etc.,
1081 specify local variables for the function. Each variable can
1082 optionally have a type specified after a colon (`:`) to indicate
1084 - **Aligns function:** Aligns the function to a quad-byte boundary
1085 for efficient execution.
1089 - If no arguments are provided, the function has no local variables.
1090 - If a type is not specified for a local variable, it is assumed to
1093 **Error Conditions:**
1095 - An error occurs if `name` is not a valid symbol.
1096 - An error occurs if the function is defined within another function
1097 (nested functions are not supported).
1103 ; ... code for the main function ...
1105 .funct add, num1: int, num2: int > result: int
1106 ; ... code for the add function ...
1111 - Defining functions to modularize code and promote reusability.
1112 - Creating subroutines to perform specific tasks within the program.
1113 - Utilizing local variables to manage data within functions.
1115 **Note:** The `.funct` directive is essential for defining functions
1116 in Z-code assembly programs. Proper function definition and usage are
1117 crucial for code organization and maintainability.
1121 The `.GSTR` directive defines a global string and stores it in the
1122 string area of the Z-code program. Global strings are accessible from
1123 anywhere in the program and are typically used for longer text
1124 passages or messages.
1134 The `.gstr` directive performs the following:
1136 - **Defines a symbol:** Creates a global symbol with the specified
1137 `name`. The value of the symbol is the address of the string in
1138 the string area, adjusted for the string offset (`SOFF`).
1139 - **Outputs the string:** Generates the string in the object file,
1140 aligning it to a quad-byte boundary.
1141 - **Updates string offset:** If necessary, updates the `SOFF` value
1142 to reflect the new string's location.
1146 - The string area is located in a separate section of the Z-code
1147 program and is accessed using the `SOFF` value.
1148 - Strings are encoded in a special 5-bit byte format for efficient
1151 **Error Conditions:**
1153 - An error occurs if `name` is not a valid symbol.
1158 .gstr "intro", "Welcome to the game!"
1159 print intro ; Prints the "intro" string
1164 - Defining long text passages or messages that need to be accessed
1165 from various parts of the program.
1166 - Storing strings that are too large to be defined as immediate
1167 operands within instructions.
1169 **Note:** The `.gstr` directive is used to define global strings,
1170 while the `.str` directive is used for defining strings within tables
1171 or as immediate operands.
1175 The `.GVAR` directive defines a global variable and assigns it a
1176 default value. Global variables are accessible from anywhere in the
1177 program and are typically used to store persistent data or game state.
1182 .gvar name [= value]
1187 The `.gvar` directive performs the following:
1189 - **Defines a symbol:** Creates a global symbol with the specified
1190 `name`. The value of the symbol is the variable number, which is
1191 used to access the variable in the global table.
1192 - **Assigns a default value:** If `value` is provided, it is
1193 assigned as the initial value of the global variable. Otherwise,
1194 the default value is 0.
1195 - **Outputs the value:** Generates the default value in the object
1196 file, placing it in the global table.
1200 - Global variables are stored in a dedicated table pointed to by the
1201 `GLOBALS` word in the program header.
1202 - The first global variable has a variable number of 16, and
1203 subsequent variables are assigned incrementing numbers.
1205 **Error Conditions:**
1207 - An error occurs if `name` is not a valid symbol.
1208 - An error occurs if the maximum number of global variables is
1214 .gvar score = 0 ; Defines a global variable "score" with initial value 0
1215 .gvar health ; Defines a global variable "health" with default value 0
1220 - Storing persistent data that needs to be accessed from different
1221 parts of the program.
1222 - Managing game state and tracking variables like score, health, or
1225 **Note:** The `.gvar` directive is used to define global variables,
1226 while local variables are defined within functions using the `.funct`
1231 The `.INSERT` directive instructs the assembler to insert the contents
1232 of another file at the current point in the assembly process. This
1233 allows for code modularity and reuse.
1243 The `.insert` directive opens the specified `filename` and inserts its
1244 contents into the assembly stream as if they were part of the main
1245 source file. The assembler processes the inserted file's code and
1246 directives, including any symbols or definitions it contains.
1250 - The inserted file must be a valid Z-code assembly language file.
1251 - The `.insert` directive can be nested, meaning inserted files can
1252 themselves contain `.insert` directives.
1253 - The `.ENDI` directive is used to mark the end of an inserted file
1254 and return to the previous input source.
1256 **Error Conditions:**
1258 - An error occurs if the specified `filename` cannot be opened.
1259 - An error occurs if the inserted file contains syntax errors or
1265 ; ... main source file ...
1267 .insert "header.zap" ; Inserts the contents of header.zap
1269 ; ... main source file continues ...
1274 - Including header files that define constants, macros, or other
1275 commonly used elements.
1276 - Modularizing code by separating routines or data into separate
1277 files that can be inserted into multiple programs.
1279 **Note:** While `.insert` provides a mechanism for code inclusion and
1280 modularity, its usage should be carefully considered to avoid
1281 potential complexity and maintainability issues. Excessive nesting of
1282 `.insert` directives can make code harder to understand and debug.
1286 The `.LANG` directive specifies the language and escape character used
1287 for string encoding. This allows ZAP to generate Z-code programs that
1288 support different languages and character sets.
1298 The `.lang` directive sets the following parameters for string
1301 - **`id`:** Specifies the language ID. Currently, only two languages
1303 - **0:** English (default)
1305 - **`escape`:** Specifies the escape character used to represent
1306 special characters or switch character sets within strings.
1310 - The default language is English with the `%` character as the
1312 - The German language setting modifies the character set used for
1313 compact encoding to include German-specific characters.
1315 **Error Conditions:**
1317 - An error occurs if `id` is not 0 or 1.
1322 .lang 1, '%' ; Sets the language to German with '%' as the escape character
1327 - Creating Z-code programs that support languages other than
1329 - Optimizing string storage for languages with specific character
1332 **Note:** The `.lang` directive is typically used at the beginning of
1333 the assembly program to set the language and escape character for all
1334 subsequent string definitions.
1338 The `.LEN` directive calculates the length of a string in words and
1339 generates a byte containing that length in the object file. This is
1340 typically used in conjunction with the `.STR` directive to create
1341 self-contained string definitions.
1351 The `.len` directive performs the following:
1353 - **Calculates string length:** Determines the length of the
1354 specified string in words, taking into account the Z-machine's
1355 5-bit byte encoding for strings.
1356 - **Generates length byte:** Outputs a single byte containing the
1357 calculated length to the object file.
1361 - The string must be a short string, meaning it can be represented
1362 in 255 words or less.
1364 **Error Conditions:**
1366 An error occurs if the string length exceeds 255 words.
1372 .str "Hello" ; This string will be preceded by a byte indicating its length
1377 - Creating self-contained string definitions where the length is
1378 explicitly stored alongside the string data.
1379 - Facilitating string manipulation routines that require knowledge
1380 of the string length.
1382 **Note:** The `.len` directive is often used together with the `.strl`
1383 directive, which combines the functionality of `.len` and `.str` into
1388 The `.NEW` directive sets the release level of the Z-code program
1389 being assembled. This information is used to ensure compatibility with
1390 different versions of the ZIP interpreter.
1400 The `.new` directive sets the `Version` variable in ZAP, which
1401 determines the version of the Z-machine that the generated program is
1402 compatible with. The `level` argument must be a constant expression
1403 that evaluates to one of the supported Z-machine versions:
1412 - The default release level is 5 (XZIP).
1413 - Some features and opcodes might not be available in older versions
1416 **Error Conditions:**
1418 An error occurs if `level` is not a supported Z-machine version.
1423 .new 6 ; Sets the release level to YZIP
1428 - Ensuring compatibility with specific versions of the ZIP
1430 - Taking advantage of features and opcodes introduced in newer
1433 **Note:** The `.new` directive should be used at the beginning of the
1434 assembly program to set the release level before any other code or
1439 The `.OBJECT` directive defines an object and assigns it a unique
1440 object number. Objects are complex data structures used to represent
1441 entities and items within the game world.
1446 .object name, flag1, flag2, ..., flag7
1451 The `.object` directive performs the following:
1453 - **Defines a symbol:** Creates a global symbol with the specified
1454 `name`. The value of the symbol is the object number.
1455 - **Assigns object number:** Assigns a unique, incrementing object
1456 number to the object.
1457 - **Outputs object data:** Generates the object data in the object
1458 file, including flag words and property table pointer.
1462 - Objects are stored in a dedicated table pointed to by the `OBJECT`
1463 word in the program header.
1464 - The first object has an object number of 1, and subsequent objects
1465 are assigned incrementing numbers.
1466 - The `flag1` to `flag7` arguments represent the initial values of
1467 the object's 48 one-bit flags, divided into seven words.
1469 **Error Conditions:**
1471 - An error occurs if `name` is not a valid symbol.
1472 - An error occurs if the maximum number of objects is exceeded.
1477 .object "player", 0, 0, 0, 0, 0, 0 ; Defines the "player" object
1478 .object "sword", 1, 0, 0, 0, 0, 0 ; Defines the "sword" object
1483 - Defining objects to represent entities and items in the game
1485 - Assigning properties and flags to objects to track their state and
1488 **Note:** The `.object` directive is used to define objects, while
1489 properties are defined within the object's property table using the
1494 The `.OPTIONS` directive is used to set options that control the
1495 behavior of the ZIP interpreter. These options affect features such as
1496 scripting and user input.
1501 .options script, ask
1506 The `.options` directive sets the following options:
1508 - **`script`:** A boolean value (0 or 1) indicating whether
1509 scripting is enabled. When scripting is enabled, the interpreter
1510 can read commands from a script file instead of from the user.
1511 - **`ask`:** A boolean value (0 or 1) indicating whether the
1512 interpreter should ask the user for confirmation before executing
1513 certain actions, such as restarting or restoring the game.
1517 - If either `script` or `ask` is omitted, the corresponding option
1520 **Error Conditions:**
1522 An error occurs if `script` or `ask` is not a valid boolean value (0
1528 .options 1, 0 ; Enables scripting and disables confirmation prompts
1533 - Enabling scripting for automated testing or gameplay recording.
1534 - Disabling confirmation prompts for a more streamlined user
1537 **Note:** The `.options` directive is typically used at the beginning
1538 of the assembly program to set the desired interpreter options.
1542 The `.PCSET` directive sets the program counter (PC) to a specific
1543 value. This directive is used to jump to a specific address within the
1544 program or to align code and data to specific memory locations.
1554 The `.pcset` directive sets the program counter to the specified
1555 `value`. The assembler then continues generating code and data from
1556 that address onwards.
1560 - If `value` is less than the current program counter, the assembler
1561 will issue a warning but will still set the PC to the specified
1564 **Error Conditions:**
1566 An error occurs if `value` is negative.
1571 .pcset 1000 ; Sets the program counter to 1000
1576 - Jumping to a specific address within the program, typically for
1577 implementing subroutines or handling error conditions.
1578 - Aligning code or data to specific memory locations for
1579 optimization or compatibility purposes.
1581 **Note:** The `.PCSET` directive should be used with caution, as it
1582 can lead to unexpected behavior if not used correctly. It is generally
1583 recommended to use labels and jump instructions for control flow
1588 The `.PDEF` directive aligns the next generated code or data to the
1589 next word boundary. This directive is used to ensure proper alignment
1590 for word-sized data elements.
1600 The `.pdef` directive pads the object file with a zero byte if the
1601 current address is not already a multiple of two. This ensures that
1602 the next word (two-byte) value will be aligned to a word boundary.
1608 **Error Conditions:**
1616 .word data1 ; data1 will be aligned to a word boundary
1621 - Ensuring proper alignment for word-sized data elements, such as
1622 numbers and pointers.
1623 - Improving memory access efficiency on architectures that require
1626 **Note:** The `.PDEF` directive is typically used before defining
1627 word-sized data elements to guarantee their alignment. However, the
1628 assembler generally handles alignment automatically, so explicit use
1629 of `.PDEF` is often unnecessary.
1633 The `.PICFILE` directive defines a picture file and specifies its
1634 properties. Picture files contain images and associated data used by
1635 the `DISPLAY` and `DCLEAR` instructions.
1640 .picfile filename, machine, ideal-x, ideal-y, base-x, base-y
1645 The `.picfile` directive defines a picture file with the following
1648 - **`filename`:** The name of the picture file.
1649 - **`machine`:** The target machine for which the picture file is
1650 intended (e.g., "apple", "ega", "mac").
1651 - **`ideal-x` and `ideal-y`:** The ideal dimensions of the picture
1653 - **`base-x` and `base-y`:** The base coordinates of the picture in
1656 This information is used by the interpreter to properly display and
1657 manage pictures from the specified file.
1661 - The picture file format and encoding are specific to the Z-machine
1662 and may vary depending on the target machine.
1663 - The `zsplit` tool uses the picture file information to distribute
1664 pictures across multiple disks in multi-disk games.
1666 **Error Conditions:**
1668 - An error occurs if `filename` is not a valid string.
1669 - An error occurs if `machine` is not a recognized target machine.
1674 .picfile "pictures.p", "mac", 320, 200, 0, 0
1679 - Defining picture files for use with the `DISPLAY` and `DCLEAR`
1681 - Providing information to the interpreter and `zsplit` tool for
1684 **Note:** The `.PICFILE` directive is used in conjunction with the
1685 `DISPLAY` and `DCLEAR` instructions to display and manage pictures
1686 within Z-code programs.
1690 The `.PROP` directive defines a property within an object's property
1691 table. Properties are used to associate additional data and attributes
1697 .prop length, number
1702 The `.prop` directive defines a property with the following
1705 - **`length`:** The length of the property value in bytes.
1706 - **`number`:** The property number.
1708 The assembler generates the property data in the object file,
1709 including the length, number, and value.
1713 - Properties are stored in a sorted order within the object's
1715 - The length of a property value can be 1, 2, or more bytes. The
1716 encoding of the length depends on the size:
1717 - 1 byte: The high-order bit of the length byte is 0.
1718 - 2 bytes: The high-order bit is 1, and the second-highest bit
1720 - More than 2 bytes: The high-order two bits are both 1, and the
1721 remaining 6 bits specify the length.
1723 **Error Conditions:**
1725 - An error occurs if `length` is zero or negative.
1726 - An error occurs if `number` is not within the valid range (1-63).
1731 .object "player", ...
1732 .prop 1, 1 ; Defines a one-byte property with number 1
1733 .prop 2, 10 ; Defines a two-byte property with number 10
1738 - Associating additional data with objects, such as descriptions,
1739 attributes, or inventory items.
1740 - Extending the functionality of objects beyond their basic flags
1743 **Note:** The `.PROP` directive is used within an object definition to
1744 define its properties. The object itself is defined using the
1745 `.OBJECT` directive.
1749 The `.SEGMENT` directive opens a new segment for code and data
1750 definition. Segments are logical divisions of the Z-code program used
1751 to optimize disk usage and loading times in multi-disk games.
1761 The `.segment` directive opens a new segment with the specified
1762 `name`. All subsequent code and data definitions are considered to
1763 belong to this segment until a `.ENDSEG` directive is encountered or
1764 another `.SEGMENT` directive opens a different segment.
1768 - If the segment "0" is opened, it refers to the default segment
1769 that contains all preloaded data and code.
1770 - If a segment name is not defined with `.DEFSEG`, it is implicitly
1771 considered adjacent to segment 0.
1773 **Error Conditions:**
1775 An error occurs if `name` is not a valid string.
1782 ; ... code and data for the ROOM segment ...
1789 - Organizing the game's code and data into logical segments for
1790 efficient disk usage and loading.
1791 - Informing the `zsplit` tool about segment boundaries to optimize
1792 the distribution of segments across multiple disks.
1794 **Note:** Segment definitions and closures are primarily used by the
1795 `zsplit` tool and do not directly affect the execution of the Z-code
1800 The `.SEQ` directive assigns sequential values to a list of symbols,
1801 starting from 0. This is a convenient way to define a series of
1802 constants or variables with incrementing values.
1807 .seq symbol1 [, symbol2 ...]
1812 The `.seq` directive assigns values to the specified symbols in the
1815 - `symbol1` is assigned the value 0.
1816 - `symbol2` is assigned the value 1.
1819 The symbols become global constants with their respective values.
1825 **Error Conditions:**
1827 An error occurs if any of the symbols are already defined.
1832 .seq color_red, color_green, color_blue ; Defines three constants with values 0, 1, and 2
1837 - Defining a series of constants with incrementing values, such as
1838 color codes or status flags.
1839 - Creating a sequence of variables with unique identifiers.
1841 **Note:** The `.seq` directive provides a concise way to define
1842 multiple constants or variables with sequential values.
1846 The `.SEQ` directive assigns sequential values to a list of symbols,
1847 starting from 0. This is a convenient way to define a series of
1848 constants or variables with incrementing values.
1853 .seq symbol1 [, symbol2 ...]
1858 The `.seq` directive assigns values to the specified symbols in the
1861 - `symbol1` is assigned the value 0.
1862 - `symbol2` is assigned the value 1.
1865 The symbols become global constants with their respective values.
1871 **Error Conditions:**
1873 An error occurs if any of the symbols are already defined.
1878 .seq color_red, color_green, color_blue ; Defines three constants with values 0, 1, and 2
1883 - Defining a series of constants with incrementing values, such as
1884 color codes or status flags.
1885 - Creating a sequence of variables with unique identifiers.
1887 **Note:** The `.seq` directive provides a concise way to define
1888 multiple constants or variables with sequential values.
1892 The `.STR` directive generates a string in the object file, encoding
1893 it in the Z-machine's 5-bit byte format. It is used to define strings
1894 that can be referenced and printed by instructions like `PRINT` and
1905 The `.str` directive performs the following:
1907 - **Encodes the string:** Converts the ASCII string into the
1908 Z-machine's 5-bit byte format, using frequent words and character
1909 set shifting as needed.
1910 - **Outputs the string:** Generates the encoded string data in the
1912 - **Sets the end-of-string bit:** Marks the last word of the string
1913 with the end-of-string bit to indicate its termination.
1917 - If a string is provided without an explicit directive, it is
1918 implicitly treated as a `.str` directive.
1919 - Strings are aligned to word boundaries in the object file.
1921 **Error Conditions:**
1928 .str "Hello, world!" ; Defines a string
1929 print message ; Prints the string defined above
1934 - Defining strings that can be printed or manipulated by the Z-code
1936 - Storing text data efficiently using the Z-machine's string
1939 **Note:** The `.str` directive is used to define strings within tables
1940 or as immediate operands. For defining global strings in the string
1941 area, the `.GSTR` directive is used.
1945 The `.STRL` directive combines the functionality of the `.LEN` and
1946 `.STR` directives. It calculates the length of a string in words,
1947 generates a byte containing that length, and then generates the
1948 encoded string data in the object file.
1958 The `.strl` directive performs the following:
1960 - **Calculates string length:** Determines the length of the
1961 specified string in words, taking into account the Z-machine's
1962 5-bit byte encoding for strings.
1963 - **Generates length byte:** Outputs a single byte containing the
1964 calculated length to the object file.
1965 - **Encodes the string:** Converts the ASCII string into the
1966 Z-machine's 5-bit byte format, using frequent words and character
1967 set shifting as needed.
1968 - **Outputs the string:** Generates the encoded string data in the
1969 object file, following the length byte.
1973 - The string must be a short string, meaning it can be represented
1974 in 255 words or less.
1976 **Error Conditions:**
1978 An error occurs if the string length exceeds 255 words.
1983 .strl "Hello, world!" ; Defines a string with its length
1988 - Creating self-contained string definitions where the length is
1989 explicitly stored alongside the string data.
1990 - Simplifying string definition by combining the functionality of
1991 `.LEN` and `.STR` into a single directive.
1993 **Note:** The `.strl` directive is a convenient way to define strings
1994 with their lengths, but it is equivalent to using `.len` followed by
1999 The `.TABLE` directive declares the beginning of a table definition.
2000 Tables are logical structures used to organize data in Z-code
2011 The `.table` directive marks the start of a table definition. It can
2012 optionally take a `size` argument, which specifies the maximum size of
2013 the table in bytes. The assembler uses this information to:
2015 - **Check for size violations:** If a size is specified, the
2016 assembler ensures that the actual table data generated does not
2017 exceed the declared size.
2018 - **Perform alignment:** The assembler may align the table data to a
2019 specific boundary depending on the target architecture or data
2024 - If the `size` argument is omitted, the table size is not checked
2025 by the assembler. However, debugging versions of the ZIP
2026 interpreter may perform bounds checking at runtime.
2028 **Error Conditions:**
2030 An error occurs if the actual table size exceeds the declared size (if
2036 .table 100 ; Declares a table with a maximum size of 100 bytes
2037 .word data1, data2, data3
2043 - Defining tables of data with a specific size and ensuring that the
2044 size is not exceeded.
2045 - Organizing data into logical structures for easier access and
2048 **Note:** The `.TABLE` directive must be paired with a `.ENDT`
2049 directive to mark the end of the table definition.
2053 The `.TRUE` directive generates a word (two-byte) value of 1 in the
2054 object file. It is used to represent the boolean value `true` or to
2055 initialize memory locations with a non-zero value.
2065 The `.true` directive simply generates a word with the value 1 at the
2066 current address in the object file.
2072 **Error Conditions:**
2079 .true ; Generates a word with value 1
2080 set flag1, .true ; Sets the flag variable `flag1` to true
2085 - Representing the boolean value `true` in conditional statements or
2087 - Initializing variables or memory locations with a non-zero value.
2089 **Note:** The `.true` directive is equivalent to using `.word 1`.
2090 However, `.true` provides better readability and clarity when
2091 representing boolean values.
2095 The `.VOCBEG` directive declares the beginning of the vocabulary area.
2096 The vocabulary area contains words and associated information used by
2097 the `READ` and `LEX` instructions for parsing player input.
2102 .vocbeg record-length, key-length
2107 The `.vocbeg` directive defines the following parameters for the
2110 - **`record-length`:** Specifies the length of each vocabulary entry
2111 in bytes. This includes the word itself and any additional
2113 - **`key-length`:** Specifies the length of the key used for sorting
2114 vocabulary entries. The key is typically the word itself, but it
2115 can be a shorter substring.
2117 The assembler uses this information to:
2119 - **Allocate space for vocabulary entries:** Ensures that enough
2120 space is allocated in the object file for the vocabulary data.
2121 - **Sort vocabulary entries (optional):** If the number of entries
2122 in the vocabulary table is specified as negative, the vocabulary
2123 is considered unsorted. Otherwise, the assembler sorts the entries
2124 based on their keys for efficient searching during input parsing.
2128 - The vocabulary area is located in a separate section of the Z-code
2129 program and is accessed using the `VOCAB` word in the program
2131 - The first byte of the vocabulary area specifies the number of
2132 self-inserting break characters used by the `READ` instruction.
2133 - The format of the vocabulary entries depends on the
2134 `record-length` and `key-length` values specified in `.VOCBEG`.
2136 **Error Conditions:**
2138 - An error occurs if `record-length` or `key-length` is zero or
2140 - An error occurs if the vocabulary area has an invalid length or
2146 .vocbeg 6, 3 ; Define vocabulary with 6-byte entries and 3-byte keys
2148 ; ... vocabulary words and data ...
2155 - Defining the vocabulary of words that the game understands and can
2156 parse from player input.
2157 - Optimizing input parsing by sorting the vocabulary for efficient
2160 **Note:** The `.VOCBEG` directive must be paired with a `.VOCEND`
2161 directive to mark the end of the vocabulary area.
2165 The `.VOCEND` directive marks the end of the vocabulary area. The
2166 vocabulary area contains words and associated information used by the
2167 `READ` and `LEX` instructions for parsing player input.
2177 The `.VOCEND` directive must be used to terminate a vocabulary area
2178 that was previously declared with the `.VOCBEG` directive. It performs
2181 - **Sorts vocabulary entries:** If the vocabulary is defined as
2182 sorted, the assembler sorts the entries based on their keys.
2183 - **Outputs vocabulary data:** The assembler writes the vocabulary
2184 data to the object file in the appropriate format.
2185 - **Finalizes vocabulary table:** The assembler performs any
2186 necessary operations to finalize the vocabulary table, such as
2187 calculating the total number of words.
2191 - A `.VOCEND` directive without a preceding `.VOCBEG` directive is
2194 **Error Conditions:**
2196 - An error occurs if the vocabulary area has an invalid length or
2202 .vocbeg 6, 3 ; Define vocabulary with 6-byte entries and 3-byte keys
2204 ; ... vocabulary words and data ...
2211 - Defining the vocabulary of words that the game understands and can
2212 parse from player input.
2213 - Optimizing input parsing by sorting the vocabulary for efficient
2216 **Note:** The `.VOCBEG` and `.VOCEND` directives are essential for
2217 defining and managing the vocabulary used by the `READ` and `LEX`
2218 instructions. Proper structure and usage of the vocabulary area are
2219 crucial for correct input parsing.
2223 The `.WORD` directive instructs the assembler to generate one or more
2224 word (two-byte) values in the object file. It is used to define
2225 word-sized data or initialize specific memory locations with word
2231 .word value1 [, value2 ...]
2236 The `.word` directive generates the specified word values sequentially
2237 in the object file. Each value can be:
2239 - **A constant expression:** Evaluates to a number within the range
2241 - **A symbol:** Refers to a previously defined symbol representing a
2246 - If a single value is provided without the `.word` directive, it is
2247 implicitly treated as a `.word` directive.
2249 **Error Conditions:**
2251 An error occurs if a value exceeds the 16-bit word range.
2256 .word 1000, 2000, 3000 ; Generates three words with values 1000, 2000, and 3000
2257 .word counter ; Generates a word with the value of the symbol `counter`
2262 - Defining word-sized data, such as numbers, pointers, or flags.
2263 - Initializing memory locations with specific word values.
2265 **Note:** The `.word` directive is a fundamental data definition
2266 directive used to generate word-sized data in Z-code programs.
2270 The `.ZWORD` directive generates a Z-word string in the object file.
2271 Z-word strings are similar to regular Z-strings but are limited to a
2272 maximum of two words (four bytes). They are used to store short text
2273 snippets or identifiers efficiently.
2283 The `.zword` directive performs the following:
2285 - **Encodes the string:** Converts the ASCII string into the
2286 Z-machine's 5-bit byte format, similar to the `.STR` directive but
2287 limited to two words.
2288 - **Outputs the string:** Generates the encoded string data in the
2290 - **Pads the string:** If the string is less than two words, it is
2291 padded with the standard pad character (5) to fill the remaining
2296 - Z-word strings are always four bytes long, regardless of the
2297 actual string length.
2299 **Error Conditions:**
2301 An error occurs if the string length exceeds two words.
2306 .zword "OK" ; Defines a Z-word string
2311 - Storing short text snippets or identifiers efficiently.
2312 - Defining data structures that require fixed-length strings.
2314 **Note:** The `.ZWORD` directive is used for defining short strings
2315 that need to be stored efficiently. For longer strings, the `.STR` or
2316 `.GSTR` directives are more appropriate.
2320 **ADD** is an opcode that performs addition on two 16-bit word values.
2321 It adds the first operand to the second operand and returns the
2327 add arg1:int, arg2:int > val
2332 The `add` opcode performs the following:
2334 - **Adds `arg1` and `arg2`:** Performs integer addition.
2335 - **Stores the result:** The sum is stored in the specified
2336 destination (`val`). If no destination is provided, the result is
2337 pushed onto the game stack.
2341 - If the result of the addition overflows the 16-bit word size, an
2344 **Error Conditions:**
2346 An error occurs if the addition result overflows the 16-bit word
2352 add 5, 10 > result ; Adds 5 and 10, stores the sum (15) in `result`
2357 - Performing integer addition calculations.
2358 - Increasing values or accumulating totals.
2360 **Note:** The `add` opcode performs signed integer addition. If the
2361 operands are unsigned, the programmer needs to handle potential
2362 overflow conditions.
2366 **ASHIFT** is an opcode that performs an arithmetic shift on a 16-bit
2367 integer value. It shifts the bits of the operand to the left or right,
2368 depending on the specified shift amount.
2378 The `ashift` opcode performs the following:
2380 - **Shifts the bits of `int`:**
2381 - If `n` is positive, `int` is shifted left by `n` bits.
2382 - If `n` is negative, `int` is shifted right by the absolute
2384 - **Preserves the sign bit:** In an arithmetic shift, the sign bit
2385 of the operand is replicated to fill in the vacated bits during a
2386 right shift. This ensures that the sign of the number is
2388 - **Stores the result:** The shifted value is stored in the
2389 specified destination (`val`). If no destination is provided, the
2390 result is pushed onto the game stack.
2394 - If `n` is zero, the value of `int` remains unchanged.
2395 - If the shift amount exceeds the word size (16 bits), the result is
2398 **Error Conditions:**
2405 ashift num, 2 > shifted ; Shifts the value in `num` left by 2 bits
2406 ashift num, -1 > shifted ; Shifts the value in `num` right by 1 bit
2411 - Multiplying or dividing numbers by powers of two efficiently.
2412 - Manipulating individual bits within a word.
2413 - Implementing bitwise operations and algorithms.
2415 **Note:** The `ashift` opcode performs an arithmetic shift, which
2416 preserves the sign of the operand. For a logical shift, where the sign
2417 bit is not replicated, use the `shift` opcode.
2421 **ASSIGNED?** is an opcode that checks whether an optional argument
2422 was provided when calling the current function. It is used to
2423 implement conditional logic based on the presence or absence of
2429 assigned? opt:var /pred
2434 The `assigned?` opcode evaluates to true if an optional argument was
2435 supplied for the variable `opt`. Otherwise, it evaluates to false. The
2436 result is used to determine whether to take a conditional branch, as
2437 specified by the predicate (`/pred`) syntax.
2441 - The `assigned?` opcode can only be used within a function to check
2442 for optional arguments passed to that function.
2443 - The variable `opt` must be a local variable of the function.
2445 **Error Conditions:**
2447 An error occurs if `assigned?` is used outside of a function or if
2448 `opt` is not a local variable.
2453 .funct my_function, optional_arg
2454 assigned? optional_arg / handle_optional
2455 ; ... code if optional_arg is not assigned ...
2457 ; ... code to handle optional_arg ...
2462 - Implementing functions with optional arguments.
2463 - Performing different actions depending on whether optional
2464 arguments are provided.
2466 **Note:** The `assigned?` opcode is specific to the Z-machine and does
2467 not have a direct equivalent in most other assembly languages. It is a
2468 useful feature for implementing functions with flexible argument
2473 **BAND** is an opcode that performs a bitwise AND operation on two
2474 16-bit word values. It combines the corresponding bits of the
2475 operands, setting each bit in the result to 1 only if both
2476 corresponding bits in the operands are also 1.
2481 band word1, word2 > val
2486 The `band` opcode performs the following:
2488 - **Performs bitwise AND:** Combines the corresponding bits of
2489 `word1` and `word2` using the logical AND operation.
2490 - **Stores the result:** The resulting word is stored in the
2491 specified destination (`val`). If no destination is provided, the
2492 result is pushed onto the game stack.
2498 **Error Conditions:**
2505 band flags, mask > result ; Performs bitwise AND between `flags` and `mask`
2510 - Masking out specific bits in a word.
2511 - Checking the state of individual bits or groups of bits.
2512 - Implementing bitwise algorithms and operations.
2514 **Note:** The `band` opcode is a fundamental bitwise operation used in
2515 various programming tasks, including data manipulation, flag handling,
2516 and low-level control.
2520 **BCOM** is an opcode that performs a bitwise complement (NOT)
2521 operation on a 16-bit word value. It inverts each bit in the operand,
2522 setting 1s to 0s and vice versa.
2532 The `bcom` opcode performs the following:
2534 - **Inverts the bits of `word`:** Flips each bit in the operand,
2535 changing 1s to 0s and 0s to 1s.
2536 - **Stores the result:** The resulting word is stored in the
2537 specified destination (`val`). If no destination is provided, the
2538 result is pushed onto the game stack.
2544 **Error Conditions:**
2551 bcom flags > inverted ; Inverts the bits in the `flags` word
2556 - Inverting the state of individual bits or groups of bits.
2557 - Implementing bitwise algorithms and operations.
2558 - Toggling the values of flags or status bits.
2560 **Note:** The `bcom` opcode is a fundamental bitwise operation used in
2561 various programming tasks, including data manipulation, flag handling,
2562 and low-level control.
2566 **BOR** is an opcode that performs a bitwise OR operation on two
2567 16-bit word values. It combines the corresponding bits of the
2568 operands, setting each bit in the result to 1 if either or both of the
2569 corresponding bits in the operands are 1.
2574 bor word1, word2 > val
2579 The `bor` opcode performs the following:
2581 - **Performs bitwise OR:** Combines the corresponding bits of
2582 `word1` and `word2` using the logical OR operation.
2583 - **Stores the result:** The resulting word is stored in the
2584 specified destination (`val`). If no destination is provided, the
2585 result is pushed onto the game stack.
2591 **Error Conditions:**
2598 bor flags, mask > result ; Performs bitwise OR between `flags` and `mask`
2603 - Setting specific bits in a word.
2604 - Combining flags or status bits.
2605 - Implementing bitwise algorithms and operations.
2607 **Note:** The `bor` opcode is a fundamental bitwise operation used in
2608 various programming tasks, including data manipulation, flag handling,
2609 and low-level control.
2613 **BTST** is an opcode that tests whether specific bits are set in a
2614 16-bit word value. It acts as a predicate, meaning it evaluates a
2615 condition and implicitly performs a conditional branch based on the
2621 btst word1, word2 /pred
2626 The `btst` opcode performs the following:
2628 - **Checks bit states:** Compares the corresponding bits of `word1`
2630 - **Evaluates predicate:** The predicate succeeds (evaluates to
2631 true) if every bit that is set (1) in `word2` is also set in
2632 `word1`. Otherwise, the predicate fails (evaluates to false).
2633 - **Conditional branch:** Based on the predicate result and the
2634 specified branch polarity (`/pred`), the interpreter may perform a
2635 conditional jump to a specified target.
2639 - If all bits in `word2` are 0, the predicate always succeeds.
2641 **Error Conditions:**
2648 btst flags, mask / handle_flags ; Branch to `handle_flags` if all bits set in `mask` are also set in `flags`
2653 - Checking the state of individual bits or groups of bits within a
2655 - Implementing conditional logic based on bit states.
2656 - Handling flags or status bits efficiently.
2658 **Note:** The `btst` opcode is a useful tool for working with bitwise
2659 data and implementing conditional behavior based on specific bit
2664 **BUFOUT** is an opcode that controls whether output to the screen is
2665 buffered or unbuffered. Buffering allows the interpreter to optimize
2666 line breaks and handle text wrapping more effectively.
2676 The `bufout` opcode sets the output buffering mode based on the value
2679 - **`int` = 1:** Enables output buffering (default). Output is
2680 accumulated in a buffer and printed to the screen when a newline
2681 character is encountered or the buffer is full.
2682 - **`int` = 0:** Disables output buffering. All currently buffered
2683 output is immediately sent to the screen, and subsequent output is
2684 printed as it is generated.
2688 - Output redirected to a table using `DIROUT 3` is never buffered,
2689 regardless of the `bufout` setting.
2691 **Error Conditions:**
2693 An error occurs if `int` is not 0 or 1.
2698 bufout 0 ; Disables output buffering
2699 print "Immediate output"
2700 bufout 1 ; Re-enables output buffering
2705 - Disabling output buffering can be useful for displaying text
2706 immediately without waiting for a newline or buffer to fill. This
2707 might be used for real-time updates or interactive prompts.
2708 - In most cases, output buffering should be enabled to allow the
2709 interpreter to handle line breaks and text wrapping efficiently.
2711 **Note:** The `bufout` opcode is rarely needed in typical Z-code
2712 programs, as most output operations implicitly handle buffering as
2717 **CALL** is an opcode that calls a function with three arguments and
2718 returns a value. It is the most general form of the function call
2719 instruction, allowing for a flexible number of arguments and return
2725 call fcn, arg1:any, arg2:any, arg3:any > val
2730 The `call` opcode performs the following:
2732 - **Pushes arguments onto the stack:** Pushes the three arguments
2733 (`arg1`, `arg2`, and `arg3`) onto the game stack.
2734 - **Calls the function:** Transfers control to the function
2735 specified by `fcn`. The function address is calculated by shifting
2736 `fcn` left by two bits and adding the function offset (`FOFF`)
2737 shifted left by three bits.
2738 - **Retrieves return value:** When the function returns, its return
2739 value is retrieved and stored in the specified destination
2740 (`val`). If no destination is provided, the value is pushed onto
2745 - If `fcn` is zero, the `call` opcode acts as if it called a
2746 function that immediately returned false.
2748 **Error Conditions:**
2750 An error occurs if `fcn` is not a valid function pointer.
2755 call process_input, input_buffer, parse_buffer, options > result ; Calls the `process_input` function with three arguments
2760 - Calling functions with three arguments.
2761 - Implementing subroutines and modular code structures.
2763 **Note:** The `CALL` opcode is the most general form of the function
2764 call instruction. For functions with fewer arguments, the `CALL1` and
2765 `CALL2` opcodes can be used for more efficient encoding. The compiler
2766 automatically chooses the appropriate opcode based on the number of
2767 arguments and their types.
2771 **CALL1** is an opcode that calls a function with one argument and
2772 returns a value. It is a more compact version of the `CALL` opcode,
2773 optimized for functions with a single argument.
2783 The `call1` opcode performs the following:
2785 - **Pushes arguments onto the stack:** Pushes the single argument
2786 onto the game stack.
2787 - **Calls the function:** Transfers control to the function
2788 specified by `fcn`. The function address is calculated by shifting
2789 `fcn` left by two bits and adding the function offset (`FOFF`)
2790 shifted left by three bits.
2791 - **Retrieves return value:** When the function returns, its return
2792 value is retrieved and stored in the specified destination
2793 (`val`). If no destination is provided, the value is pushed onto
2798 - If `fcn` is zero, the `call1` opcode acts as if it called a
2799 function that immediately returned false.
2801 **Error Conditions:**
2803 An error occurs if `fcn` is not a valid function pointer.
2808 call1 get_input > input_char ; Calls the `get_input` function and stores the returned character in `input_char`
2813 - Calling functions with a single argument efficiently.
2814 - Implementing subroutines and modular code structures.
2816 **Note:** The `call1` opcode is generated by the compiler when it
2817 detects a function call with one argument. It is not typically used
2818 directly by programmers.
2822 **CALL2** is an opcode that calls a function with two arguments and
2823 returns a value. It is a more compact version of the `CALL` opcode,
2824 optimized for functions with two arguments.
2829 call2 fcn, arg > val
2834 The `call2` opcode performs the following:
2836 - **Pushes arguments onto the stack:** Pushes the two arguments
2837 (`fcn` and `arg`) onto the game stack.
2838 - **Calls the function:** Transfers control to the function
2839 specified by `fcn`. The function address is calculated by shifting
2840 `fcn` left by two bits and adding the function offset (`FOFF`)
2841 shifted left by three bits.
2842 - **Retrieves return value:** When the function returns, its return
2843 value is retrieved and stored in the specified destination
2844 (`val`). If no destination is provided, the value is pushed onto
2849 - If `fcn` is zero, the `call2` opcode acts as if it called a
2850 function that immediately returned false.
2852 **Error Conditions:**
2854 An error occurs if `fcn` is not a valid function pointer.
2859 call2 add, num1, num2 > sum ; Calls the `add` function with `num1` and `num2` as arguments, stores the sum in `sum`
2864 - Calling functions with two arguments efficiently.
2865 - Implementing subroutines and modular code structures.
2867 **Note:** The `call2` opcode is generated by the compiler when it
2868 detects a function call with two arguments. It is not typically used
2869 directly by programmers.
2873 **CATCH** is an opcode that captures an exception thrown by the
2874 `THROW` opcode and provides a way to handle it. It is used in
2875 conjunction with `THROW` to implement exception handling and non-local
2886 The `catch` opcode performs the following:
2888 - **Captures exception:** If an exception has been thrown using the
2889 `THROW` opcode, the `catch` opcode captures it and prevents the
2890 program from terminating.
2891 - **Stores frame pointer:** The opcode stores a pointer to the
2892 current call frame in the specified destination (`frame`). This
2893 frame pointer identifies the point in the call stack where the
2894 exception was caught.
2895 - **Continues execution:** The program continues execution from the
2896 instruction following the `catch` opcode.
2900 - If no exception has been thrown, the `catch` opcode stores 0 in
2901 the `frame` variable and continues execution.
2902 - The `CATCH` and `THROW` opcodes do not work within "internal"
2903 calls, such as timeout handling routines called by `READ` or
2906 **Error Conditions:**
2914 ; ... some code that might throw an exception ...
2916 ; ... handle the exception ...
2921 - Implementing exception handling to deal with errors or unexpected
2923 - Performing non-local control flow, such as exiting multiple nested
2926 **Note:** The `CATCH` and `THROW` opcodes provide a mechanism for
2927 exception handling and non-local control flow in Z-code programs. They
2928 should be used with caution to avoid complex control flow and
2933 **CLEAR** is an opcode that clears a window or the entire screen,
2934 filling it with the current background color.
2944 The `clear` opcode clears the specified window or the entire screen:
2946 - **`window` = 0 to 7:** Clears the corresponding window.
2947 - **`window` = -1:** Unsplits the screen (if it was previously
2948 split) and clears the entire screen.
2949 - **`window` = -2:** Clears the entire screen without affecting
2950 window attributes or cursor position.
2952 When a window is cleared, the cursor is moved to the top-left corner
2957 - If the `window` argument is omitted, the current window is
2960 **Error Conditions:**
2962 An error occurs if `window` is not within the valid range (-2 to 7).
2967 clear 0 ; Clears the main window (window 0)
2968 clear -2 ; Clears the entire screen
2973 - Clearing the screen or a window to prepare for new output.
2974 - Erasing previous content and resetting the display.
2976 **Note:** The `clear` opcode is a convenient way to clear the screen
2977 or a window. It is important to remember that clearing a window moves
2978 the cursor to its top-left corner.
2982 **COLOR** is an opcode that sets the foreground and background colors
2983 for subsequent text output.
2988 color fore:int, back:int
2993 The `color` opcode sets the colors for text output as follows:
2995 - **`fore`:** Specifies the foreground color (text color).
2996 - **`back`:** Specifies the background color.
2998 The colors are interpreted according to the following values:
3000 - **-1:** Use the color of the pixel at the current cursor position.
3002 - **1:** System default color.
3011 - **10:** Light gray
3017 - The availability of colors and their specific shades may vary
3018 depending on the target machine and display capabilities.
3019 - On some machines, like the Amiga, the colors set for the main
3020 window (window 0) are used for all windows.
3022 **Error Conditions:**
3024 An error occurs if `fore` or `back` is not within the valid range (-1
3030 color 3, 2 ; Sets foreground color to red and background color to black
3031 color 0, 1 ; Sets background color to the system default
3036 - Changing the colors of text output for visual distinction or
3038 - Enhancing the game's appearance and atmosphere.
3040 **Note:** Games should be designed to handle machines that do not
3041 support color selection. The `MODE` byte in the program header
3042 indicates whether the `COLOR` operation is available.
3046 **COPYT** is an opcode that copies a specified number of bytes from
3047 one table to another. It can also be used to zero out a section of
3048 memory or duplicate data within a table.
3053 copyt source:tbl, dest:tbl, length:int
3058 The `copyt` opcode copies bytes from the source table (`source`) to
3059 the destination table (`dest`) according to the specified `length`:
3061 - **Positive `length`:** Copies `length` bytes from `source` to
3062 `dest`. If the source and destination regions overlap, the opcode
3063 performs a "backwards" copy to avoid overwriting data before it is
3065 - **Negative `length`:** Copies `length` bytes from `source` to
3066 `dest` without checking for overlap. This allows for data
3067 duplication within the source table.
3068 - **Zero `dest`:** If `dest` is zero, the opcode zeroes out `length`
3069 bytes in the source table.
3073 - The `copyt` opcode can be used to copy data to itself, allowing
3074 for shifting or duplication of data within a table.
3076 **Error Conditions:**
3080 - `source` or `dest` is not a valid table pointer.
3081 - The copy operation would exceed the bounds of the tables.
3086 copyt buffer1, buffer2, 100 ; Copies 100 bytes from buffer1 to buffer2
3087 copyt table, 0, 50 ; Zeroes out the first 50 bytes of table
3088 copyt table, table + 10, 20 ; Duplicates 20 bytes within table, shifting them by 10 bytes
3093 - Copying data between tables.
3094 - Zeroing out sections of memory.
3095 - Duplicating data within a table.
3096 - Implementing memory management or data manipulation routines.
3098 **Note:** The `copyt` opcode provides a flexible way to copy and
3099 manipulate data within tables. It is important to be aware of the
3100 overlap behavior when using positive lengths to avoid unintended data
3105 **CRLF** is an opcode that prints an end-of-line sequence to the
3106 screen. This typically results in a carriage return and line feed,
3107 moving the cursor to the beginning of the next line.
3117 The `crlf` opcode outputs an end-of-line sequence to the current
3118 window. The specific behavior depends on the window's attributes:
3120 - **Scrolling window:** The window contents scroll up by one line,
3121 and the cursor is moved to the beginning of the newly created
3123 - **Non-scrolling window:** The cursor is moved to the beginning of
3124 the next line within the window. If the window is full, the output
3125 may be clipped or overwritten.
3131 **Error Conditions:**
3138 print "This is a line."
3140 print "This is on the next line."
3145 - Starting a new line of output.
3146 - Separating paragraphs or sections of text.
3147 - Formatting text display within windows.
3149 **Note:** The `crlf` opcode is a basic output operation used to
3150 control the vertical positioning of text on the screen.
3154 **CURGET** is an opcode that retrieves the current cursor position
3155 within a window and stores it in a table.
3165 The `curget` opcode retrieves the current cursor position in the
3166 specified window and writes the coordinates into the `output` table:
3168 - **Word 0 of `output`:** Contains the Y coordinate of the cursor
3169 (row number, 1-based).
3170 - **Word 1 of `output`:** Contains the X coordinate of the cursor
3171 (column number, 1-based).
3175 - If the `window` argument is omitted, the current window is used.
3177 **Error Conditions:**
3181 - `output` is not a valid table pointer.
3182 - The `output` table does not have enough space to store the
3183 coordinates (at least two words).
3188 curget cursor_pos ; Retrieves the cursor position in the current window
3193 - Determining the current cursor position for display or interaction
3195 - Implementing custom cursor movement or text editing routines.
3197 **Note:** While `CURGET` can be used to retrieve the cursor position,
3198 it is generally recommended to use the `WINGET` opcode with the
3199 appropriate offset values, as it provides more flexibility and can
3200 access other window properties as well.
3204 **CURSET** is an opcode that sets the cursor position within a window
3205 to specified coordinates.
3210 curset y:int, x:int [, window:int]
3215 The `curset` opcode sets the cursor position in the specified window
3216 to the coordinates (`y`, `x`):
3218 - **`y`:** The Y coordinate (row number, 1-based).
3219 - **`x`:** The X coordinate (column number, 1-based).
3221 If the coordinates are outside the window's boundaries, they are
3222 adjusted to the closest valid position within the window.
3226 - If the `window` argument is omitted, the current window is used.
3227 - If `y` is -1, the cursor is turned off.
3228 - If `y` is -2, the cursor is turned on. In this case, the `x`
3229 argument is ignored.
3231 **Error Conditions:**
3235 - `window` is not within the valid range (-3 to 7).
3236 - `y` or `x` is negative (except for the special cases mentioned
3242 curset 5, 10 ; Sets the cursor to row 5, column 10 in the current window
3243 curset 1, 1, 2 ; Sets the cursor to the top-left corner of window 2
3244 curset -1 ; Turns off the cursor
3249 - Positioning the cursor for text output or user interaction.
3250 - Implementing custom cursor movement or text editing routines.
3252 **Note:** The `curset` opcode provides a direct way to set the cursor
3253 position. However, for more complex window manipulations, consider
3254 using the `WINPOS` and `WINSIZE` opcodes.
3258 **DCLEAR** is an opcode that clears the area occupied by a previously
3259 displayed picture, restoring the window's background color.
3264 dclear picture:int [, y:int, x:int]
3269 The `dclear` opcode clears the area of the specified picture:
3271 - **`picture`:** The ID number of the picture to clear.
3272 - **`y` and `x` (optional):** The coordinates where the picture was
3273 displayed (in pixels). If omitted, the opcode uses the coordinates
3274 where the picture was last displayed.
3276 The opcode restores the window's background color in the area
3277 previously occupied by the picture.
3283 **Error Conditions:**
3287 - `picture` is not a valid picture ID.
3288 - The coordinates (`y`, `x`) are outside the window's boundaries.
3293 display 10, 10, 10 ; Displays picture 10 at coordinates (10, 10)
3294 dclear 10 ; Clears the area occupied by picture 10
3299 - Removing pictures from the screen.
3300 - Restoring the window's background color after displaying a
3303 **Note:** The `DCLEAR` opcode is used in conjunction with the
3304 `DISPLAY` opcode to manage the display of pictures within Z-code
3309 **DEC** is an opcode that decrements the value of a variable by 1.
3319 The `dec` opcode subtracts 1 from the value of the specified variable
3326 **Error Conditions:**
3333 dec counter ; Decrements the value of the variable `counter`
3338 - Decrementing counters or loop variables.
3339 - Reducing the value of a variable by a fixed amount.
3341 **Note:** The `dec` opcode is a convenient way to decrement a variable
3342 by 1. For more complex arithmetic operations, use the `SUB` opcode.
3346 **DIRIN** is an opcode that redirects input from a specified device.
3347 It allows the Z-code program to receive input from sources other than
3348 the keyboard, such as command files or scripts.
3353 dirin device:int [, any1, any2, any3]
3358 The `dirin` opcode redirects input based on the value of `device`:
3360 - **`device` = 0:** Keyboard input (default).
3361 - **`device` = 1:** Command file input. The interpreter reads input
3362 from a previously created command file, typically generated using
3365 The additional arguments (`any1`, `any2`, `any3`) are currently unused
3366 and should be ignored by the interpreter.
3370 - Not all interpreters implement command file input. If the
3371 interpreter does not support it, the `dirin 1` instruction should
3374 **Error Conditions:**
3376 An error occurs if `device` is not 0 or 1.
3381 dirin 1 ; Redirects input to the command file
3386 - Reading commands from a script file for automated testing or
3388 - Implementing custom input methods or interactive sequences.
3390 **Note:** The `dirin` opcode is used in conjunction with `DIROUT` to
3391 manage input and output redirection.
3395 **DIROUT** is an opcode that redirects output to a specified device.
3396 It allows the Z-code program to send output to destinations other than
3397 the screen, such as the transcript or a table.
3402 dirout device:int [, any1, any2, any3]
3407 The `dirout` opcode redirects output based on the value of `device`:
3409 - **`device` = 1:** Screen output (default).
3410 - **`device` = -1:** Disables screen output.
3411 - **`device` = 2:** Transcript output. Sends all subsequent output
3412 to the transcript device, which can be a file, printer, or other
3413 suitable destination.
3414 - **`device` = -2:** Disables transcript output.
3415 - **`device` = 3:** Table output. Sends output to the table
3416 specified by `any1`. The `any2` argument can optionally specify
3417 justification for formatted tables.
3418 - **`device` = -3:** Disables table output.
3419 - **`device` = 4:** Command recording. Creates a command file and
3420 writes all subsequent input commands to it.
3421 - **`device` = -4:** Disables command recording.
3425 - If the screen device is disabled and the transcript device is
3426 enabled, output is still sent to the transcript.
3427 - Table output using `dirout 3` is not buffered, regardless of the
3429 - Not all interpreters implement command recording (device 4).
3431 **Error Conditions:**
3433 An error occurs if `device` is not within the valid range (-4 to 4).
3438 dirout 2 ; Enables transcript output
3439 dirout -1 ; Disables screen output
3440 dirout 3, table, 80 ; Redirects output to `table` with right justification at 80 pixels
3445 - Sending output to the transcript for debugging or recording
3447 - Creating formatted tables for display using `PRINTF`.
3448 - Recording player input commands for testing or analysis.
3450 **Note:** The `dirout` opcode is used in conjunction with `DIRIN` to
3451 manage input and output redirection.
3455 **DISPLAY** is an opcode that displays a picture at a specified
3456 location on the screen. Pictures are images stored in a separate
3457 picture file and referenced by their ID numbers.
3462 display picture:int [, y:int, x:int]
3467 The `display` opcode displays the picture with the specified ID number
3468 (`picture`) at the given coordinates (`y`, `x`) in pixels:
3470 - **`picture`:** The ID number of the picture to display.
3471 - **`y` and `x` (optional):** The coordinates where the picture
3472 should be displayed, relative to the top-left corner of the
3473 current window. If omitted, the opcode uses the current cursor
3478 - If the picture ID is 0, the opcode does nothing.
3479 - If the coordinates are outside the window's boundaries, the
3480 picture may be clipped or partially displayed.
3482 **Error Conditions:**
3486 - `picture` is not a valid picture ID.
3487 - The coordinates (`y`, `x`) are outside the window's boundaries.
3492 display 10, 10, 10 ; Displays picture 10 at coordinates (10, 10) in the current window
3493 display 5 ; Displays picture 5 at the current cursor position
3498 - Displaying images and graphics on the screen.
3499 - Creating visual elements for the game world or user interface.
3501 **Note:** The `DISPLAY` opcode requires the interpreter to support
3502 picture display. The `MODE` byte in the program header indicates
3503 whether the `DISPLAY` operation is available.
3507 **DIV** is an opcode that performs integer division on two 16-bit word
3508 values. It divides the first operand by the second operand and returns
3509 the truncated quotient.
3514 div arg1:int, arg2:int > val
3519 The `div` opcode performs the following:
3521 - **Divides `arg1` by `arg2`:** Performs integer division,
3522 discarding any remainder.
3523 - **Stores the result:** The quotient is stored in the specified
3524 destination (`val`). If no destination is provided, the result is
3525 pushed onto the game stack.
3529 - Division by zero results in an error.
3531 **Error Conditions:**
3533 An error occurs if `arg2` is zero.
3538 div 10, 2 > result ; Divides 10 by 2, stores the quotient (5) in `result`
3543 - Performing integer division calculations.
3544 - Scaling values or calculating ratios.
3546 **Note:** The `div` opcode performs integer division, meaning it
3547 discards any remainder. For operations that require the remainder, use
3552 **DLESS?** is an opcode that decrements a variable and then checks if
3553 the new value is less than a specified integer. It acts as a
3554 predicate, meaning it evaluates a condition and implicitly performs a
3555 conditional branch based on the result.
3560 dless? var, int /pred
3565 The `dless?` opcode performs the following:
3567 - **Decrements `var`:** Subtracts 1 from the value of the variable
3569 - **Compares with `int`:** Checks if the new value of `var` is less
3571 - **Evaluates predicate:** The predicate succeeds (evaluates to
3572 true) if the new value of `var` is indeed less than `int`.
3573 Otherwise, the predicate fails (evaluates to false).
3574 - **Conditional branch:** Based on the predicate result and the
3575 specified branch polarity (`/pred`), the interpreter may perform a
3576 conditional jump to a specified target.
3582 **Error Conditions:**
3589 dless? counter, 0 / end_loop ; Branch to `end_loop` if `counter` is decremented to a value less than 0
3594 - Implementing loops or conditional statements that depend on
3595 decrementing a variable and comparing it to a threshold.
3596 - Optimizing code by combining decrement and comparison operations
3597 into a single instruction.
3599 **Note:** The `dless?` opcode is a useful tool for writing efficient
3600 and concise code when dealing with decrementing variables and
3605 **EQUAL?** is an opcode that checks whether its first operand is equal
3606 to any of the subsequent operands. It acts as a predicate, meaning it
3607 evaluates a condition and implicitly performs a conditional branch
3608 based on the result.
3613 equal? arg1:any, arg2:any [, arg3:any ...] /pred
3618 The `equal?` opcode performs the following:
3620 - **Compares `arg1` with other arguments:** Checks if `arg1` is
3621 equal to any of the `arg2`, `arg3`, etc., operands.
3622 - **Evaluates predicate:** The predicate succeeds (evaluates to
3623 true) if `arg1` is equal to at least one of the other arguments.
3624 Otherwise, the predicate fails (evaluates to false).
3625 - **Conditional branch:** Based on the predicate result and the
3626 specified branch polarity (`/pred`), the interpreter may perform a
3627 conditional jump to a specified target.
3631 - The `equal?` opcode can take a variable number of operands in the
3632 extended (`EXT`) format. The 2OP format is limited to two
3635 **Error Conditions:**
3642 equal? object, "sword", "axe" / handle_weapon ; Branch to `handle_weapon` if `object` is equal to either "sword" or "axe"
3647 - Implementing conditional logic based on equality comparisons.
3648 - Checking if a variable or object matches one of several possible
3651 **Note:** The `equal?` opcode is a versatile tool for performing
3652 equality checks and implementing conditional behavior based on the
3657 **ERASE** is an opcode that erases a portion of the current window,
3658 filling it with the current background color.
3668 The `erase` opcode erases a section of the current window based on the
3671 - **`int` = 1:** Erases from the current cursor position to the end
3673 - **`int` \> 1:** Erases a rectangular area starting at the current
3674 cursor position, with a width of `int` pixels and a height equal
3675 to the current font height. The erased area does not extend past
3676 the right edge of the window.
3682 **Error Conditions:**
3689 erase 1 ; Erases from the cursor to the end of the line
3690 erase 20 ; Erases a 20-pixel wide rectangle starting at the cursor
3695 - Erasing text or graphics from the screen.
3696 - Clearing portions of the window for new output.
3698 **Note:** The `ERASE` opcode is used to selectively erase parts of the
3699 window. For clearing the entire window, use the `CLEAR` opcode.
3703 **EXTOP** is an opcode that signals to the interpreter that the next
3704 byte is an extended opcode. Extended opcodes are part of an additional
3705 set of 256 instructions beyond the standard opcode set.
3715 The `extop` opcode itself does not perform any operation. Instead, it
3716 indicates that the following byte (`opcode`) should be interpreted as
3717 an extended opcode. The interpreter adds 256 to the value of `opcode`
3718 to obtain the actual extended opcode number.
3722 - The `extop` opcode is never explicitly used by programmers. It is
3723 generated by the assembler when encoding instructions that require
3724 the extended format.
3726 **Error Conditions:**
3728 An error occurs if `opcode` is not a valid extended opcode number.
3732 The `extop` opcode is not used directly in assembly code. It is
3733 handled internally by the assembler and interpreter.
3737 The `extop` opcode allows ZAP to generate a wider range of
3738 instructions while maintaining backward compatibility with older ZIP
3739 interpreters that only recognize the standard opcode set.
3741 **Note:** The `extop` opcode is a low-level mechanism used by the
3742 assembler and interpreter to handle extended opcodes. Programmers do
3743 not need to be concerned with its usage directly.
3747 **FCLEAR** is an opcode that clears a specific flag within an object's
3748 flag list. Objects have 48 one-bit flags that can be used to track
3749 their state or attributes.
3759 The `fclear` opcode sets the specified flag (`flag`) in the object
3766 **Error Conditions:**
3770 - `obj` is not a valid object number.
3771 - `flag` is not within the valid range (0-47).
3776 fclear player, 10 ; Clears flag number 10 in the "player" object
3781 - Resetting flags or attributes associated with objects.
3782 - Changing the state of objects based on game logic or player
3785 **Note:** The `FCLEAR` opcode is used to clear individual flags within
3786 an object. To set a flag, use the `FSET` opcode.
3790 **FIRST?** is an opcode that retrieves the "first" property of an
3791 object and checks if it is non-zero. It acts as a predicate, meaning
3792 it evaluates a condition and implicitly performs a conditional branch
3793 based on the result.
3798 first? obj > val /pred
3803 The `first?` opcode performs the following:
3805 - **Retrieves "first" property:** Gets the value of the "first" slot
3806 within the object (`obj`). This slot typically contains the object
3807 number of the first object contained within `obj`.
3808 - **Checks for non-zero value:** Evaluates to true if the retrieved
3809 value is not zero (meaning there is a "first" object). Otherwise,
3810 it evaluates to false.
3811 - **Stores the value (optional):** If the `> val` operand is
3812 provided, the retrieved value is also stored in the specified
3814 - **Conditional branch:** Based on the predicate result and the
3815 specified branch polarity (`/pred`), the interpreter may perform a
3816 conditional jump to a specified target.
3820 - If the object `obj` does not have any contained objects, the
3821 "first" slot will be zero, and the predicate will fail.
3823 **Error Conditions:**
3825 An error occurs if `obj` is not a valid object number.
3830 first? container > first_item / process_item ; Branch to `process_item` if `container` has a "first" object
3835 - Checking if an object contains other objects.
3836 - Iterating through a chain of objects linked by their "next"
3838 - Implementing inventory management or object interaction logic.
3840 **Note:** The `FIRST?` opcode is used to access and check the "first"
3841 property of an object. To retrieve the "next" property in a chain, use
3846 **FONT** is an opcode that selects a font for text output in a
3847 specified window. Fonts determine the style and appearance of the
3853 font font:int, window:int > val
3858 The `font` opcode sets the font for the specified window (`window`) to
3859 the font identified by `font`:
3861 - **`font`:** The ID number of the font to select.
3862 - **`window`:** The window number where the font should be applied.
3864 The opcode returns the ID number of the previously selected font for
3869 - If the `window` argument is omitted, the current window is used.
3870 - Font 1 is typically the "normal" font for the machine and is
3871 selected by default for all windows.
3872 - Some interpreters may not support all font IDs or may have
3873 different fonts available.
3875 **Error Conditions:**
3879 - `window` is not within the valid range (-3 to 7).
3880 - `font` is not a valid font ID.
3885 font 4, 0 ; Selects the monospace font for the main window (window 0)
3886 font 2, 3 ; Selects font 2 for window 3
3891 - Changing the appearance of text for visual distinction or
3893 - Displaying text in different styles, such as bold, italic, or
3895 - Enhancing the game's visual presentation and atmosphere.
3897 **Note:** The `FONT` opcode requires the interpreter to support font
3898 selection. The `MODE` byte in the program header indicates whether the
3899 `FONT` operation is available.
3903 **FSET** is an opcode that sets a specific flag within an object's
3904 flag list to 1. Objects have 48 one-bit flags that can be used to
3905 track their state or attributes.
3915 The `fset` opcode sets the specified flag (`flag`) in the object
3922 **Error Conditions:**
3926 - `obj` is not a valid object number.
3927 - `flag` is not within the valid range (0-47).
3932 fset player, 5 ; Sets flag number 5 in the "player" object to 1
3937 - Setting flags or attributes associated with objects.
3938 - Changing the state of objects based on game logic or player
3941 **Note:** The `FSET` opcode is used to set individual flags within an
3942 object. To clear a flag, use the `FCLEAR` opcode.
3946 **FSET?** is an opcode that checks whether a specific flag is set
3947 within an object's flag list. It acts as a predicate, meaning it
3948 evaluates a condition and implicitly performs a conditional branch
3949 based on the result.
3954 fset? obj, flag /pred
3959 The `fset?` opcode performs the following:
3961 - **Checks flag state:** Determines whether the specified flag
3962 (`flag`) in the object (`obj`) is set (1) or cleared (0).
3963 - **Evaluates predicate:** The predicate succeeds (evaluates to
3964 true) if the flag is set. Otherwise, the predicate fails
3965 (evaluates to false).
3966 - **Conditional branch:** Based on the predicate result and the
3967 specified branch polarity (`/pred`), the interpreter may perform a
3968 conditional jump to a specified target.
3974 **Error Conditions:**
3978 - `obj` is not a valid object number.
3979 - `flag` is not within the valid range (0-47).
3984 fset? player, 15 / handle_flag ; Branch to `handle_flag` if flag number 15 in the "player" object is set
3989 - Implementing conditional logic based on the state of object flags.
3990 - Checking for specific object attributes or conditions.
3992 **Note:** The `FSET?` opcode is used to test the state of individual
3993 flags within an object. To set or clear a flag, use the `FSET` or
3994 `FCLEAR` opcodes, respectively.
3998 **FSTACK** is an opcode that flushes (removes) a specified number of
3999 elements from a stack. It can be used to clear the game stack or a
4005 fstack n [, stack:tbl]
4010 The `fstack` opcode removes elements from a stack as follows:
4012 - **`n`:** The number of elements to flush from the stack.
4013 - **`stack` (optional):** A pointer to a table representing a
4014 user-defined stack. If omitted, the opcode flushes elements from
4017 The opcode does not return any value.
4021 - Flushing more elements than are present on the stack is an error.
4023 **Error Conditions:**
4028 - `stack` is not a valid table pointer (if provided).
4029 - Attempting to flush more elements than are present on the stack.
4034 fstack 3 ; Flushes 3 elements from the game stack
4035 fstack 2, user_stack ; Flushes 2 elements from the `user_stack` table
4040 - Clearing the game stack before calling a function or performing a
4042 - Resetting user-defined stacks to a known state.
4044 **Note:** The `FSTACK` opcode is used to remove elements from stacks.
4045 To add elements, use the `PUSH` or `XPUSH` opcodes.
4049 **GET** is an opcode that retrieves the value of an element from a
4050 word-oriented table. It is used to access data stored in tables based
4051 on their index or offset.
4056 get table, item > val
4061 The `get` opcode performs the following:
4063 - **Calculates element address:** Multiplies the `item` (index or
4064 offset) by 2 and adds it to the base address of the `table`. This
4065 gives the address of the desired element in memory.
4066 - **Retrieves the value:** Reads the word value at the calculated
4068 - **Stores the result:** The retrieved value is stored in the
4069 specified destination (`val`). If no destination is provided, the
4070 result is pushed onto the game stack.
4074 - Table offsets are zero-based, meaning the first element has an
4076 - The interpreter does not perform bounds checking on table
4077 accesses. It is the programmer's responsibility to ensure that
4078 `item` is within the valid range of the table.
4080 **Error Conditions:**
4082 An error may occur if:
4084 - `table` is not a valid table pointer.
4085 - `item` is outside the bounds of the table.
4090 get inventory, 3 > item ; Retrieves the 4th element from the `inventory` table and stores it in `item`
4095 - Accessing data stored in tables based on their index or offset.
4096 - Implementing data structures and algorithms that rely on table
4099 **Note:** The `GET` opcode is used for accessing word-sized elements
4100 in tables. For byte-sized elements, use the `GETB` opcode.
4104 **GETB** is an opcode that retrieves the value of an element from a
4105 byte-oriented table. It is used to access data stored in tables based
4106 on their index or offset.
4111 getb table, item > val
4116 The `getb` opcode performs the following:
4118 - **Calculates element address:** Adds the `item` (index or offset)
4119 to the base address of the `table`. This gives the address of the
4120 desired element in memory.
4121 - **Retrieves the value:** Reads the byte value at the calculated
4123 - **Converts to word:** The retrieved byte value is converted to a
4125 - **Stores the result:** The word value is stored in the specified
4126 destination (`val`). If no destination is provided, the result is
4127 pushed onto the game stack.
4131 - Table offsets are zero-based, meaning the first element has an
4133 - The interpreter does not perform bounds checking on table
4134 accesses. It is the programmer's responsibility to ensure that
4135 `item` is within the valid range of the table.
4137 **Error Conditions:**
4139 An error may occur if:
4141 - `table` is not a valid table pointer.
4142 - `item` is outside the bounds of the table.
4147 getb text_buffer, 5 > char ; Retrieves the 6th byte from the `text_buffer` table and stores it as a word in `char`
4152 - Accessing data stored in byte-oriented tables.
4153 - Reading individual characters from text buffers.
4154 - Implementing data structures and algorithms that rely on
4155 byte-level table access.
4157 **Note:** The `GETB` opcode is used for accessing byte-sized elements
4158 in tables. For word-sized elements, use the `GET` opcode.
4162 **GETP** is an opcode that retrieves the value of a property from an
4163 object. Properties are used to associate additional data and
4164 attributes with objects.
4169 getp obj, prop > val
4174 The `getp` opcode performs the following:
4176 - **Locates property table:** Finds the property table associated
4177 with the object (`obj`).
4178 - **Searches for property:** Searches the property table for the
4179 property with the specified number (`prop`).
4180 - **Retrieves the value:** If the property is found, its value is
4182 - **Handles default properties:** If the property is not found in
4183 the object's property table, the opcode retrieves the default
4184 value from the default property table.
4185 - **Stores the result:** The retrieved value is stored in the
4186 specified destination (`val`). If no destination is provided, the
4187 result is pushed onto the game stack.
4191 - Properties are stored in a sorted order within the object's
4193 - The `GETP` opcode can only be used to retrieve properties with a
4194 length of 1 or 2 bytes. For properties of arbitrary length, use
4197 **Error Conditions:**
4201 - `obj` is not a valid object number.
4202 - `prop` is not within the valid range (1-63).
4207 getp player, 1 > strength ; Retrieves the value of property 1 ("strength") from the "player" object
4212 - Accessing data associated with objects through properties.
4213 - Retrieving object attributes or characteristics.
4215 **Note:** The `GETP` opcode is used to retrieve properties with a
4216 length of 1 or 2 bytes. For properties of arbitrary length, use the
4221 **GETPT** is an opcode that retrieves a pointer to a property within
4222 an object's property table. Unlike `GETP`, which can only retrieve
4223 properties of 1 or 2 bytes, `GETPT` can access properties of any
4229 getpt obj, prop > val
4234 The `getpt` opcode performs the following:
4236 - **Locates property table:** Finds the property table associated
4237 with the object (`obj`).
4238 - **Searches for property:** Searches the property table for the
4239 property with the specified number (`prop`).
4240 - **Retrieves the pointer:** If the property is found, a pointer to
4241 its value is retrieved.
4242 - **Handles default properties:** If the property is not found in
4243 the object's property table, the opcode retrieves a pointer to the
4244 default value from the default property table.
4245 - **Stores the result:** The retrieved pointer is stored in the
4246 specified destination (`val`). If no destination is provided, the
4247 result is pushed onto the game stack.
4251 - Properties are stored in a sorted order within the object's
4253 - The retrieved pointer can be used as a table pointer in other
4254 table operations like `GET`, `GETB`, `PUT`, and `PUTB`.
4256 **Error Conditions:**
4260 - `obj` is not a valid object number.
4261 - `prop` is not within the valid range (1-63).
4266 getpt object, 10 > prop_ptr ; Retrieves a pointer to property 10 of `object`
4267 getb prop_ptr, 0 > first_byte ; Retrieves the first byte of the property value
4272 - Accessing properties of arbitrary length.
4273 - Implementing data structures or algorithms that require accessing
4274 variable-length properties.
4276 **Note:** The `GETPT` opcode is used to retrieve pointers to
4277 properties, while `GETP` is used to directly retrieve property values
4282 **GRTR?** is an opcode that compares two integer values and checks if
4283 the first operand is greater than the second operand. It acts as a
4284 predicate, meaning it evaluates a condition and implicitly performs a
4285 conditional branch based on the result.
4290 grtr? arg1:int, arg2:int /pred
4295 The `grtr?` opcode performs the following:
4297 - **Compares `arg1` and `arg2`:** Checks if the integer value `arg1`
4298 is greater than `arg2`.
4299 - **Evaluates predicate:** The predicate succeeds (evaluates to
4300 true) if `arg1` is indeed greater than `arg2`. Otherwise, the
4301 predicate fails (evaluates to false).
4302 - **Conditional branch:** Based on the predicate result and the
4303 specified branch polarity (`/pred`), the interpreter may perform a
4304 conditional jump to a specified target.
4310 **Error Conditions:**
4317 grtr? health, 0 / game_over ; Branch to `game_over` if `health` is greater than 0
4322 - Implementing conditional logic based on greater-than comparisons.
4323 - Making decisions based on numerical values, such as health, score,
4324 or inventory counts.
4326 **Note:** The `grtr?` opcode is a basic comparison operator used for
4327 implementing conditional behavior in Z-code programs.
4331 **HLIGHT** is an opcode that sets the highlighting mode for subsequent
4332 text output. Highlighting can be used to emphasize text, change its
4333 appearance, or create special visual effects.
4343 The `hlight` opcode sets the highlighting mode based on the value of
4346 - **`int` = 0:** No highlighting (normal text).
4347 - **`int` = 1:** Inverse video (text and background colors are
4349 - **`int` = 2:** Bold text.
4350 - **`int` = 4:** Underline or italic text
4351 (implementation-dependent).
4352 - **`int` = 8:** Monospaced font.
4356 - The availability of highlighting modes depends on the capabilities
4357 of the interpreter and the target machine.
4358 - The `MODE` byte in the program header specifies which highlighting
4359 modes are supported.
4360 - The monospace font mode may either select an actual monospaced
4361 font or modify the display of a variable-width font to appear
4364 **Error Conditions:**
4366 An error occurs if `int` specifies an unsupported highlighting mode.
4371 hlight 2 ; Sets bold text highlighting
4372 print "Important message!"
4373 hlight 0 ; Resets to normal text
4378 - Emphasizing important text or messages.
4379 - Creating visual distinctions between different types of text.
4380 - Implementing special visual effects or text-based graphics.
4382 **Note:** Games should be designed to handle machines that do not
4383 support all highlighting modes. The `MODE` byte can be used to check
4384 which modes are available.
4388 **ICALL** is an opcode that calls a function with three arguments but
4389 does not return a value. It is similar to the `CALL` opcode but
4390 optimized for situations where the function's return value is not
4396 icall routine:fcn, arg1:any, arg2:any, arg3:any
4401 The `icall` opcode performs the following:
4403 - **Pushes arguments onto the stack:** Pushes the three arguments
4404 (`arg1`, `arg2`, and `arg3`) onto the game stack.
4405 - **Calls the function:** Transfers control to the function
4406 specified by `routine`. The function address is calculated by
4407 shifting `routine` left by two bits and adding the function offset
4408 (`FOFF`) shifted left by three bits.
4409 - **Does not retrieve return value:** When the function returns, its
4410 return value is discarded.
4414 - If `routine` is zero, the `icall` opcode acts as if it called a
4415 function that immediately returned false.
4417 **Error Conditions:**
4419 An error occurs if `routine` is not a valid function pointer.
4424 icall update_score, player, points, bonus ; Calls the `update_score` function without using its return value
4429 - Calling functions where the return value is not needed, reducing
4430 stack usage and potential stack overflows.
4431 - Implementing subroutines or actions that do not produce a result.
4433 **Note:** The `icall` opcode is generated by the compiler when it
4434 detects a function call where the return value is not used. It is not
4435 typically used directly by programmers.
4439 **ICALL1** is an opcode that calls a function with one argument but
4440 does not return a value. It is similar to the `CALL1` opcode but
4441 optimized for situations where the function's return value is not
4452 The `icall1` opcode performs the following:
4454 - **Pushes arguments onto the stack:** Pushes the single argument
4455 onto the game stack.
4456 - **Calls the function:** Transfers control to the function
4457 specified by `routine`. The function address is calculated by
4458 shifting `routine` left by two bits and adding the function offset
4459 (`FOFF`) shifted left by three bits.
4460 - **Does not retrieve return value:** When the function returns, its
4461 return value is discarded.
4465 - If `routine` is zero, the `icall1` opcode acts as if it called a
4466 function that immediately returned false.
4468 **Error Conditions:**
4470 An error occurs if `routine` is not a valid function pointer.
4475 icall1 play_sound, sound_id ; Calls the `play_sound` function without using its return value
4480 - Calling functions with a single argument where the return value is
4481 not needed, reducing stack usage and potential stack overflows.
4482 - Implementing subroutines or actions that do not produce a result.
4484 **Note:** The `icall1` opcode is generated by the compiler when it
4485 detects a function call with one argument where the return value is
4486 not used. It is not typically used directly by programmers.
4490 **ICALL2** is an opcode that calls a function with two arguments but
4491 does not return a value. It is similar to the `CALL2` opcode but
4492 optimized for situations where the function's return value is not
4498 icall2 routine:fcn, arg:any
4503 The `icall2` opcode performs the following:
4505 - **Pushes arguments onto the stack:** Pushes the two arguments
4506 (`routine` and `arg`) onto the game stack.
4507 - **Calls the function:** Transfers control to the function
4508 specified by `routine`. The function address is calculated by
4509 shifting `routine` left by two bits and adding the function offset
4510 (`FOFF`) shifted left by three bits.
4511 - **Does not retrieve return value:** When the function returns, its
4512 return value is discarded.
4516 - If `routine` is zero, the `icall2` opcode acts as if it called a
4517 function that immediately returned false.
4519 **Error Conditions:**
4521 An error occurs if `routine` is not a valid function pointer.
4526 icall2 set_color, foreground, background ; Calls the `set_color` function without using its return value
4531 - Calling functions with two arguments where the return value is not
4532 needed, reducing stack usage and potential stack overflows.
4533 - Implementing subroutines or actions that do not produce a result.
4535 **Note:** The `icall2` opcode is generated by the compiler when it
4536 detects a function call with two arguments where the return value is
4537 not used. It is not typically used directly by programmers.
4541 **IGRTR?** is an opcode that increments a variable and then checks if
4542 the new value is greater than a specified integer. It acts as a
4543 predicate, meaning it evaluates a condition and implicitly performs a
4544 conditional branch based on the result.
4549 igrtr? var, int /pred
4554 The `igrtr?` opcode performs the following:
4556 - **Increments `var`:** Adds 1 to the value of the variable `var`.
4557 - **Compares with `int`:** Checks if the new value of `var` is
4559 - **Evaluates predicate:** The predicate succeeds (evaluates to
4560 true) if the new value of `var` is indeed greater than `int`.
4561 Otherwise, the predicate fails (evaluates to false).
4562 - **Conditional branch:** Based on the predicate result and the
4563 specified branch polarity (`/pred`), the interpreter may perform a
4564 conditional jump to a specified target.
4570 **Error Conditions:**
4577 igrtr? counter, limit / overflow ; Branch to `overflow` if `counter` is incremented to a value greater than `limit`
4582 - Implementing loops or conditional statements that depend on
4583 incrementing a variable and comparing it to a threshold.
4584 - Optimizing code by combining increment and comparison operations
4585 into a single instruction.
4587 **Note:** The `igrtr?` opcode is a useful tool for writing efficient
4588 and concise code when dealing with incrementing variables and
4593 **IN?** is an opcode that checks whether one object is contained
4594 within another object. It acts as a predicate, meaning it evaluates a
4595 condition and implicitly performs a conditional branch based on the
4601 in? child:obj, parent:obj /pred
4606 The `in?` opcode performs the following:
4608 - **Checks containment:** Compares the `LOC` property of the `child`
4609 object with the object number of the `parent` object.
4610 - **Evaluates predicate:** The predicate succeeds (evaluates to
4611 true) if the `LOC` of `child` is equal to `parent`, meaning
4612 `child` is contained within `parent`. Otherwise, the predicate
4613 fails (evaluates to false).
4614 - **Conditional branch:** Based on the predicate result and the
4615 specified branch polarity (`/pred`), the interpreter may perform a
4616 conditional jump to a specified target.
4620 - An object is considered to be contained within itself.
4622 **Error Conditions:**
4624 An error occurs if `child` or `parent` is not a valid object number.
4629 in? item, player / take_item ; Branch to `take_item` if `item` is contained within the "player" object
4634 - Implementing inventory management and object interaction logic.
4635 - Checking the location of objects within the game world.
4636 - Determining containment relationships between objects.
4638 **Note:** The `IN?` opcode is a fundamental operation for working with
4639 object hierarchies and containment in Z-code programs.
4643 **INC** is an opcode that increments the value of a variable by 1.
4653 The `inc` opcode adds 1 to the value of the specified variable
4660 **Error Conditions:**
4667 inc counter ; Increments the value of the variable `counter`
4672 - Incrementing counters or loop variables.
4673 - Increasing the value of a variable by a fixed amount.
4675 **Note:** The `inc` opcode is a convenient way to increment a variable
4676 by 1. For more complex arithmetic operations, use the `ADD` opcode.
4680 **INPUT** is an opcode that reads a single byte of input from a
4681 specified device, typically the keyboard. It allows the Z-code program
4682 to receive input from the user or other input sources.
4687 input dev:int [, time:int, routine:fcn] > val
4692 The `input` opcode reads input based on the value of `dev`:
4694 - **`dev` = 1:** Keyboard input (default). The opcode reads the next
4695 key pressed by the user and returns its ASCII value.
4696 - **Other values of `dev`:** May be used for other input devices,
4697 but their behavior is implementation-dependent.
4699 **Optional Arguments:**
4701 - **`time`:** Specifies a timeout value in tenths of a second. If no
4702 input is received within the specified time, the interpreter calls
4703 the `routine` function.
4704 - **`routine`:** A function to call when a timeout occurs. The
4705 function should return true (1) to abort the input operation or
4706 false (0) to continue waiting for input.
4710 The `input` opcode returns the value of the input byte, which is
4711 stored in the specified destination (`val`). If no destination is
4712 provided, the value is pushed onto the game stack.
4716 - Function keys and other special keys may return values greater
4717 than 127, with the high bit of the byte set.
4718 - The interpreter may handle timeout behavior differently depending
4719 on the target machine and implementation.
4721 **Error Conditions:**
4725 - `dev` is not a valid device code.
4726 - `time` is negative (if provided).
4727 - `routine` is not a valid function pointer (if provided).
4732 input 1 > key ; Reads a key from the keyboard and stores its ASCII value in `key`
4733 input 1, 50, handle_timeout > key ; Reads a key with a 5-second timeout
4738 - Getting input from the user, such as commands, responses, or key
4740 - Implementing timed input or interactive sequences.
4742 **Note:** The `INPUT` opcode is a fundamental operation for receiving
4743 input in Z-code programs. The specific behavior and available devices
4744 may vary depending on the interpreter and target machine.
4748 **INTBL?** is an opcode that searches for a specific item within a
4749 table and returns a pointer to its location if found. It acts as both
4750 an opcode and a predicate, meaning it can return a value and also
4751 influence control flow based on the search result.
4756 intbl? item, table, length:int [, record-spec:int] > val /pred
4761 The `intbl?` opcode performs the following:
4763 - **Searches for `item`:** Looks for the specified `item` within the
4765 - **Table length:** The `length` argument specifies the number of
4766 elements to search within the table.
4767 - **Record specification (optional):** The `record-spec` argument,
4768 if provided, defines the format of each element in the table. It
4769 is a byte value where:
4770 - The high-order bit indicates whether the table elements are
4771 words (1) or bytes (0).
4772 - The low-order seven bits specify the length of each element in
4774 - **Returns a pointer:** If `item` is found, the opcode returns a
4775 pointer to its location within the table. Otherwise, it returns 0.
4776 - **Stores the result (optional):** If the `> val` operand is
4777 provided, the returned pointer is also stored in the specified
4779 - **Evaluates predicate:** The predicate succeeds (evaluates to
4780 true) if `item` is found in the table. Otherwise, the predicate
4781 fails (evaluates to false).
4782 - **Conditional branch:** Based on the predicate result and the
4783 specified branch polarity (`/pred`), the interpreter may perform a
4784 conditional jump to a specified target.
4788 - If `record-spec` is omitted or 0, it defaults to 130
4789 (word-oriented elements with a length of 2 bytes).
4791 **Error Conditions:**
4795 - `table` is not a valid table pointer.
4796 - `length` is negative.
4801 intbl? "north", directions, 4 > direction_ptr / handle_direction ; Searches for "north" in the `directions` table
4802 intbl? char, buffer, buffer_length, 1 > char_ptr / process_char ; Searches for `char` in a byte-oriented buffer
4807 - Searching for specific elements within tables.
4808 - Implementing data structures and algorithms that require table
4810 - Performing conditional logic based on search results.
4812 **Note:** The `INTBL?` opcode is a versatile tool for searching tables
4813 and implementing conditional behavior based on the results. The
4814 optional `record-spec` argument allows for searching tables with
4815 different element formats.
4819 **IRESTORE** is an opcode that restores the game state from a
4820 previously saved copy in memory. It is used to implement a
4821 single-level undo functionality.
4831 The `irestore` opcode restores the game state from a copy of the
4832 impure area that was previously saved using the `ISAVE` opcode. The
4833 impure area contains all modifiable data in the Z-code program,
4834 including global variables, object flags, and table contents.
4838 The `irestore` opcode returns 0 if it fails or if the instruction is
4839 not implemented on the target machine. Otherwise, it returns -1.
4843 - The `IRESTORE` opcode only works if a previous `ISAVE` operation
4845 - The interpreter may not implement the `ISAVE` and `IRESTORE`
4846 opcodes on all machines.
4848 **Error Conditions:**
4855 isave ; Saves the current game state
4856 ; ... some actions that modify the game state ...
4857 irestore ; Restores the previously saved game state
4862 - Implementing an undo feature in the game.
4863 - Restoring the game state to a previous point after an error or
4866 **Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple
4867 mechanism for implementing undo functionality. However, they are not
4868 supported on all interpreters and may require additional memory
4873 **ISAVE** is an opcode that saves a copy of the current game state in
4874 memory. It is used in conjunction with the `IRESTORE` opcode to
4875 implement a single-level undo functionality.
4885 The `isave` opcode copies the impure area of the Z-code program to a
4886 reserved section of memory. The impure area contains all modifiable
4887 data, including global variables, object flags, and table contents.
4891 The `isave` opcode returns 0 if it fails or if the instruction is not
4892 implemented on the target machine. Otherwise, it returns -1.
4896 - The interpreter may not implement the `ISAVE` and `IRESTORE`
4897 opcodes on all machines.
4898 - The reserved memory area for storing the saved game state may have
4901 **Error Conditions:**
4908 isave ; Saves the current game state
4909 ; ... some actions that modify the game state ...
4910 irestore ; Restores the previously saved game state
4915 - Implementing an undo feature in the game.
4916 - Saving the game state before performing an action that might have
4917 unintended consequences.
4919 **Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple
4920 mechanism for implementing undo functionality. However, they are not
4921 supported on all interpreters and may require additional memory
4926 **IXCALL** is an opcode that calls a function with a variable number
4927 of arguments but does not return a value. It is similar to the `XCALL`
4928 opcode but optimized for situations where the function's return value
4934 ixcall routine:fcn, arg1:any [, arg2:any ...]
4939 The `ixcall` opcode performs the following:
4941 - **Pushes arguments onto the stack:** Pushes the variable number of
4942 arguments (`arg1`, `arg2`, etc.) onto the game stack. The number
4943 of arguments is determined by the operand types specified in the
4945 - **Calls the function:** Transfers control to the function
4946 specified by `routine`. The function address is calculated by
4947 shifting `routine` left by two bits and adding the function offset
4948 (`FOFF`) shifted left by three bits.
4949 - **Does not retrieve return value:** When the function returns, its
4950 return value is discarded.
4954 - If `routine` is zero, the `ixcall` opcode acts as if it called a
4955 function that immediately returned false.
4957 **Error Conditions:**
4959 An error occurs if `routine` is not a valid function pointer.
4964 ixcall print_list, item1, item2, item3 ; Calls the `print_list` function with three arguments
4969 - Calling functions with a variable number of arguments where the
4970 return value is not needed, reducing stack usage and potential
4972 - Implementing functions that take a flexible number of arguments.
4974 **Note:** The `ixcall` opcode is generated by the compiler when it
4975 detects a function call with a variable number of arguments where the
4976 return value is not used. It is not typically used directly by
4981 **JUMP** is an opcode that performs an unconditional relative jump to
4982 a specified location within the program. It is used to control the
4983 flow of execution and implement loops or conditional branching.
4993 The `jump` opcode performs the following:
4995 - **Calculates target address:** Adds the `offset` value to the
4996 address of the next instruction. This gives the target address of
4998 - **Jumps to target:** Transfers control to the calculated target
5003 - The `offset` value is a signed 16-bit integer, allowing for both
5004 forward and backward jumps within the program.
5006 **Error Conditions:**
5013 jump start_loop ; Jumps to the label `start_loop`
5014 jump -5 ; Jumps back 5 instructions
5019 - Implementing loops by jumping back to the beginning of the loop
5021 - Performing conditional branching by jumping to different sections
5022 of code based on the results of predicates.
5023 - Creating subroutines or functions by jumping to their starting
5026 **Note:** The `JUMP` opcode is a fundamental control flow instruction
5027 used to direct the execution of Z-code programs.
5031 **LESS?** is an opcode that compares two integer values and checks if
5032 the first operand is less than the second operand. It acts as a
5033 predicate, meaning it evaluates a condition and implicitly performs a
5034 conditional branch based on the result.
5039 less? arg1:int, arg2:int /pred
5044 The `less?` opcode performs the following:
5046 - **Compares `arg1` and `arg2`:** Checks if the integer value `arg1`
5047 is less than `arg2`.
5048 - **Evaluates predicate:** The predicate succeeds (evaluates to
5049 true) if `arg1` is indeed less than `arg2`. Otherwise, the
5050 predicate fails (evaluates to false).
5051 - **Conditional branch:** Based on the predicate result and the
5052 specified branch polarity (`/pred`), the interpreter may perform a
5053 conditional jump to a specified target.
5059 **Error Conditions:**
5066 less? count, 10 / continue_loop ; Branch to `continue_loop` if `count` is less than 10
5071 - Implementing conditional logic based on less-than comparisons.
5072 - Making decisions based on numerical values, such as health, score,
5073 or inventory counts.
5075 **Note:** The `less?` opcode is a basic comparison operator used for
5076 implementing conditional behavior in Z-code programs.
5080 **LEX** is an opcode that parses the contents of an input buffer and
5081 looks up the words in a vocabulary table. It is similar to the parsing
5082 phase of the `READ` opcode but offers more flexibility in choosing the
5088 lex inbuf:tbl, lexv:tbl [, lexicon:tbl, preserve:bool]
5093 The `lex` opcode performs the following:
5095 - **Parses input buffer:** Reads the contents of the `inbuf` table,
5096 which is assumed to contain a string of text.
5097 - **Tokenizes words:** Breaks the text into individual words based
5098 on whitespace and self-inserting break characters defined in the
5100 - **Looks up words:** Searches for each word in the specified
5101 `lexicon` table. If `lexicon` is omitted, the default vocabulary
5102 table (pointed to by the `VOCAB` word in the program header) is
5104 - **Stores results:** For each word, the opcode stores the following
5105 information in the `lexv` table:
5106 - A pointer to the word entry in the vocabulary table (or 0 if
5108 - The length of the word in bytes.
5109 - The byte offset of the word within the input buffer.
5110 - **Preserves existing entries (optional):** If the `preserve`
5111 argument is provided and non-zero, the opcode does not modify
5112 entries in `lexv` for words that are not found in the vocabulary.
5116 - The `lexv` table must have enough space to store the parsing
5118 - The format of the `lexv` table is specific to the Z-machine and is
5119 used by other opcodes like `PRINTC` to reprint words from the
5122 **Error Conditions:**
5126 - `inbuf` or `lexv` is not a valid table pointer.
5127 - `lexicon` is not a valid table pointer (if provided).
5128 - The `lexv` table does not have enough space to store the parsing
5134 lex input_buffer, parsed_words ; Parses `input_buffer` using the default vocabulary
5135 lex input_buffer, parsed_words, special_vocab, 1 ; Parses using `special_vocab` and preserves existing entries
5140 - Parsing player input and looking up words in a vocabulary.
5141 - Implementing custom parsers or natural language processing
5143 - Using multiple vocabularies for different contexts or situations.
5145 **Note:** The `LEX` opcode provides more flexibility than the parsing
5146 phase of the `READ` opcode by allowing the programmer to specify the
5151 **LOC** is an opcode that retrieves the "parent" object of a given
5152 object. Objects in Z-code programs are organized in a hierarchical
5153 structure, where each object can be contained within another object.
5163 The `loc` opcode retrieves the object number of the object that
5164 contains the specified object (`obj`). This is done by reading the
5165 value of the `LOC` property of `obj`.
5167 - **Stores the result:** The retrieved object number is stored in
5168 the specified destination (`val`). If no destination is provided,
5169 the result is pushed onto the game stack.
5173 - If the object `obj` is not contained within any other object
5174 (i.e., it is a top-level object), the `LOC` property will be 0,
5175 and the opcode will return 0.
5177 **Error Conditions:**
5179 An error occurs if `obj` is not a valid object number.
5184 loc item > container ; Retrieves the object number of the container that holds `item`
5189 - Determining the location of objects within the game world.
5190 - Implementing inventory management and object interaction logic.
5191 - Traversing the object hierarchy to find related objects.
5193 **Note:** The `LOC` opcode is used to navigate the object hierarchy
5194 and determine containment relationships between objects.
5198 **MARGIN** is an opcode that sets the left and right margins for text
5199 output in a window. Margins control the horizontal spacing of text
5205 margin left:int, right:int [, window:int]
5210 The `margin` opcode sets the margins for the specified window
5211 (`window`) as follows:
5213 - **`left`:** The width of the left margin in pixels.
5214 - **`right`:** The width of the right margin in pixels.
5216 The opcode stores the margin values in the `LMRG` and `RMRG` words
5217 associated with the window.
5221 - If the `window` argument is omitted, the current window is used.
5222 - Margins only affect windows that have text wrapping enabled.
5223 - The opcode must be executed before any text is buffered for the
5226 **Error Conditions:**
5230 - `window` is not within the valid range (-3 to 7).
5231 - `left` or `right` is negative.
5236 margin 10, 20 ; Sets a 10-pixel left margin and a 20-pixel right margin in the current window
5241 - Indenting text within a window.
5242 - Creating visual distinctions between different sections of text.
5243 - Implementing custom text formatting or layout.
5245 **Note:** The `MARGIN` opcode is used to control the horizontal
5246 spacing of text within windows. It is important to consider the
5247 window's wrapping attribute and the timing of the opcode execution.
5251 **MENU** is an opcode that adds or removes a menu from the menu bar.
5252 This feature is currently only supported on the Macintosh platform.
5257 menu id, table /pred
5262 The `menu` opcode performs the following:
5264 - **Adds a menu (table is non-zero):**
5265 - **`id`:** Specifies the slot in the menu bar where the menu
5266 should be added. Slots 0, 1, and 2 are reserved for the Apple
5267 menu, File menu, and Edit menu, respectively.
5268 - **`table`:** A pointer to an LTABLE containing the menu data.
5269 The first element of the table is the menu name, and
5270 subsequent elements are the menu items.
5271 - **Removes a menu (table is zero):**
5272 - **`id`:** Specifies the slot of the menu to remove.
5274 **Predicate Behavior:**
5276 The `menu` opcode also acts as a predicate:
5278 - **Success:** The predicate succeeds if the menu was successfully
5280 - **Failure:** The predicate fails if there is no room in the menu
5281 bar for the new menu or if the specified menu ID is invalid.
5285 - The `MENU` opcode is only supported on the Macintosh platform.
5286 - The interpreter must have the `%FMENU` flag set in the `FLAGS`
5287 word to indicate support for menus.
5289 **Error Conditions:**
5293 - The interpreter does not support menus.
5294 - `id` is not a valid menu slot number.
5295 - `table` is not a valid table pointer (when adding a menu).
5300 menu 3, my_menu / check_menu ; Adds `my_menu` to the menu bar in slot 3
5301 menu 3, 0 ; Removes the menu from slot 3
5306 - Creating custom menus for user interaction.
5307 - Providing additional options or commands within the game
5310 **Note:** The `MENU` opcode is platform-specific and requires
5311 interpreter support. It is important to check the `FLAGS` word before
5316 **MOD** is an opcode that performs modulo operation on two 16-bit word
5317 values. It divides the first operand by the second operand and returns
5323 mod arg1:int, arg2:int > val
5328 The `mod` opcode performs the following:
5330 - **Divides `arg1` by `arg2`:** Performs integer division.
5331 - **Calculates the remainder:** Determines the remainder of the
5333 - **Stores the result:** The remainder is stored in the specified
5334 destination (`val`). If no destination is provided, the result is
5335 pushed onto the game stack.
5339 - Modulo by zero results in an error.
5341 **Error Conditions:**
5343 An error occurs if `arg2` is zero.
5348 mod 10, 3 > result ; Divides 10 by 3, stores the remainder (1) in `result`
5353 - Calculating the remainder of a division.
5354 - Implementing cyclic behavior or patterns.
5355 - Performing operations based on the position within a cycle.
5357 **Note:** The `mod` opcode is used to obtain the remainder of an
5358 integer division. For operations that require the quotient, use the
5363 **MOUSE-INFO** is an opcode that retrieves information about the
5364 current state of the mouse and stores it in a table. This information
5365 includes the mouse cursor position, button status, and any selected
5376 The `mouse-info` opcode fills the specified `table` with the following
5379 - **Word 0:** Y coordinate of the mouse cursor (row number, in
5381 - **Word 1:** X coordinate of the mouse cursor (column number, in
5383 - **Word 2:** Button status. Each bit represents a mouse button,
5384 with bit 1 corresponding to the rightmost button. A set bit
5385 indicates that the button is currently pressed.
5386 - **Word 3:** Menu/item selection. The high byte contains the menu
5387 number (1 for the default menu), and the low byte contains the
5388 selected item number within that menu.
5392 - The `table` argument must be a table with at least four words of
5394 - The interpretation of button status and menu/item selection may
5395 vary depending on the target machine and the number of buttons or
5398 **Error Conditions:**
5402 - `table` is not a valid table pointer.
5403 - The `table` does not have enough space to store the mouse
5404 information (at least four words).
5409 mouse-info mouse_data ; Retrieves the current mouse state
5414 - Implementing mouse-based interaction and controls.
5415 - Tracking the mouse cursor position for display or game logic
5417 - Handling mouse button clicks and menu selections.
5419 **Note:** The `MOUSE-INFO` opcode requires the interpreter to support
5420 mouse input. The `%FMOUS` flag in the `FLAGS` word indicates whether
5421 mouse operations are available.
5425 **MOUSE-LIMIT** is an opcode that restricts the movement of the mouse
5426 cursor to a specific window. This can be used to confine mouse
5427 interactions to a particular area of the screen.
5432 mouse-limit window:int
5437 The `mouse-limit` opcode restricts the mouse cursor movement to the
5438 specified window (`window`). The interpreter, if possible, will
5439 prevent the cursor from moving outside the boundaries of that window.
5440 Mouse events, such as button clicks or movements, will only be
5441 reported if the cursor is within the limited window.
5445 - **`window` = -1:** Removes any mouse cursor restrictions, allowing
5446 it to move freely across the entire screen.
5447 - Initially, the mouse cursor is assumed to be limited to window 1.
5449 **Error Conditions:**
5451 An error occurs if `window` is not within the valid range (-1 to 7).
5456 mouse-limit 0 ; Limits the mouse cursor to the main window (window 0)
5457 mouse-limit -1 ; Removes mouse cursor restrictions
5462 - Confining mouse interactions to a specific area of the screen,
5463 such as a menu or game window.
5464 - Preventing accidental clicks or movements outside the intended
5467 **Note:** The ability to limit the mouse cursor may vary depending on
5468 the capabilities of the interpreter and the target machine.
5472 **MOVE** is an opcode that moves an object from one location to
5473 another within the object hierarchy. Objects in Z-code programs are
5474 organized in a tree structure, where each object can be contained
5475 within another object.
5480 move thing:obj, dest:obj
5485 The `move` opcode moves the object `thing` into the object `dest`:
5487 - **Checks for existing containment:** If `thing` is already
5488 contained within `dest`, the opcode does nothing.
5489 - **Removes from previous location:** If `thing` is contained within
5490 another object, it is removed from that object's containment
5492 - **Adds to new location:** The `LOC` property of `thing` is set to
5493 the object number of `dest`, and `thing` is added as the first
5494 object in `dest`'s containment chain. This means the `FIRST`
5495 property of `dest` will now point to `thing`.
5499 - If `dest` is 0, the `thing` object is effectively removed from the
5500 object hierarchy, as its `LOC` property is set to 0.
5502 **Error Conditions:**
5506 - `thing` or `dest` is not a valid object number.
5511 move sword, player ; Moves the "sword" object into the "player" object's inventory
5512 move box, room ; Moves the "box" object into the "room" object
5517 - Implementing inventory management and object interaction.
5518 - Changing the location of objects within the game world.
5519 - Updating the object hierarchy based on game logic or player
5522 **Note:** The `MOVE` opcode is a fundamental operation for
5523 manipulating the object hierarchy and managing object containment in
5528 **MUL** is an opcode that performs multiplication on two 16-bit word
5529 values. It multiplies the first operand by the second operand and
5535 mul arg1:int, arg2:int > val
5540 The `mul` opcode performs the following:
5542 - **Multiplies `arg1` by `arg2`:** Performs integer multiplication.
5543 - **Stores the result:** The product is stored in the specified
5544 destination (`val`). If no destination is provided, the result is
5545 pushed onto the game stack.
5549 - If the result of the multiplication overflows the 16-bit word
5550 size, an error occurs.
5552 **Error Conditions:**
5554 An error occurs if the multiplication result overflows the 16-bit word
5560 mul 5, 10 > result ; Multiplies 5 by 10, stores the product (50) in `result`
5565 - Performing integer multiplication calculations.
5566 - Scaling values or calculating areas and volumes.
5568 **Note:** The `mul` opcode performs signed integer multiplication. If
5569 the operands are unsigned, the programmer needs to handle potential
5570 overflow conditions.
5574 **NEXT?** is an opcode that retrieves the "next" property of an object
5575 and checks if it is non-zero. It acts as a predicate, meaning it
5576 evaluates a condition and implicitly performs a conditional branch
5577 based on the result.
5582 next? obj > val /pred
5587 The `next?` opcode performs the following:
5589 - **Retrieves "next" property:** Gets the value of the "next" slot
5590 within the object (`obj`). This slot typically contains the object
5591 number of the next object in a linked chain.
5592 - **Checks for non-zero value:** Evaluates to true if the retrieved
5593 value is not zero (meaning there is a "next" object). Otherwise,
5594 it evaluates to false.
5595 - **Stores the value (optional):** If the `> val` operand is
5596 provided, the retrieved value is also stored in the specified
5598 - **Conditional branch:** Based on the predicate result and the
5599 specified branch polarity (`/pred`), the interpreter may perform a
5600 conditional jump to a specified target.
5604 - If the object `obj` is the last object in a chain, the "next" slot
5605 will be zero, and the predicate will fail.
5607 **Error Conditions:**
5609 An error occurs if `obj` is not a valid object number.
5614 next? item > next_item / process_item ; Branch to `process_item` if `item` has a "next" object in the chain
5619 - Iterating through a chain of objects linked by their "next"
5621 - Implementing inventory management or object interaction logic.
5623 **Note:** The `NEXT?` opcode is used to access and check the "next"
5624 property of an object. To retrieve the "first" property in a chain,
5625 use the `FIRST?` opcode.
5629 **NEXTP** is an opcode that retrieves the number of the property
5630 following a specified property within an object's property table. It
5631 is used to iterate through the properties of an object.
5636 nextp obj, prop > val
5641 The `nextp` opcode performs the following:
5643 - **Locates property table:** Finds the property table associated
5644 with the object (`obj`).
5645 - **Searches for property:** Searches the property table for the
5646 property with the specified number (`prop`).
5647 - **Finds next property:** If the property is found, the opcode
5648 determines the number of the next property in the table.
5649 - **Handles circularity:** If `prop` is the last property in the
5650 table, the opcode returns the number of the first property,
5651 creating a circular iteration.
5652 - **Stores the result:** The retrieved property number is stored in
5653 the specified destination (`val`). If no destination is provided,
5654 the result is pushed onto the game stack.
5658 - If `prop` is 0, the opcode returns the number of the first
5659 property in the table.
5660 - Properties are stored in a sorted order within the object's
5663 **Error Conditions:**
5667 - `obj` is not a valid object number.
5668 - `prop` is not a valid property number within the object's property
5674 nextp object, 5 > next_prop ; Retrieves the number of the property following property 5 in `object`
5679 - Iterating through the properties of an object.
5680 - Implementing generic routines that need to access all properties
5683 **Note:** The `NEXTP` opcode provides a way to navigate through the
5684 properties of an object in a circular manner. It is important to
5685 handle the case where the last property is reached and the opcode
5686 returns the first property number.
5690 **ORIGINAL?** is an opcode that checks whether the game is running
5691 from the original distribution disk. It acts as a predicate, meaning
5692 it evaluates a condition and implicitly performs a conditional branch
5693 based on the result.
5703 The `original?` opcode checks if the game is running from the original
5704 distribution disk. The specific method for determining originality is
5705 implementation-dependent and may vary between interpreters.
5707 - **Evaluates predicate:** The predicate succeeds (evaluates to
5708 true) if the game is determined to be running from the original
5709 disk. Otherwise, the predicate fails (evaluates to false).
5710 - **Conditional branch:** Based on the predicate result and the
5711 specified branch polarity (`/pred`), the interpreter may perform a
5712 conditional jump to a specified target.
5716 The implementation of originality checking is left to the interpreter.
5718 - Checking for specific files or data on the disk.
5719 - Comparing checksums or other validation data.
5720 - Using copy protection mechanisms.
5722 **Error Conditions:**
5729 original? / display_warning ; Branch to `display_warning` if the game is not running from the original disk
5734 **NOOP** is an opcode that performs no operation. It is essentially a
5735 placeholder instruction that does nothing and simply advances the
5736 program counter to the next instruction.
5746 The `noop` opcode has no effect on the program state or data. It
5747 simply increments the program counter, causing the interpreter to move
5748 on to the next instruction in the sequence.
5754 **Error Conditions:**
5766 - Aligning code or data to specific memory locations.
5767 - Providing a placeholder for future instructions or as a debugging
5769 - Implementing timing delays or loops with empty bodies.
5771 **Note:** The `NOOP` opcode is rarely used in typical Z-code programs
5772 but can be helpful in specific situations where a placeholder or delay
5777 **PICINF** is an opcode that retrieves information about a picture,
5778 such as its dimensions. Pictures are images stored in a separate
5779 picture file and referenced by their ID numbers.
5784 picinf picture:int, data:tbl /pred
5789 The `picinf` opcode retrieves information about the specified picture
5790 (`picture`) and stores it in the `data` table:
5792 - **Word 0 of `data`:** The width of the picture in pixels.
5793 - **Word 1 of `data`:** The height of the picture in pixels.
5795 **Predicate Behavior:**
5797 The `picinf` opcode also acts as a predicate:
5799 - **Success:** The predicate succeeds if the picture ID is valid and
5800 the information is successfully retrieved.
5801 - **Failure:** The predicate fails if the picture ID is invalid.
5805 - If the picture ID is 0, the opcode stores the highest picture ID
5806 in the picture library (the number of pictures) in word 0 of the
5809 **Error Conditions:**
5816 picinf 10, pic_data / handle_picture ; Retrieves information about picture 10
5817 picinf 0, pic_data > num_pictures ; Retrieves the number of pictures in the library
5822 - Determining the dimensions of a picture before displaying it.
5823 - Implementing custom picture handling or display routines.
5824 - Checking the validity of a picture ID.
5826 **Note:** The `PICINF` opcode is used in conjunction with the
5827 `DISPLAY` and `DCLEAR` opcodes to manage the display of pictures
5828 within Z-code programs.
5832 **PICSET** is an opcode that defines a group of pictures that should
5833 be loaded together from the picture file. This can be used to optimize
5834 picture loading and reduce disk access times.
5839 picset picture:int, count:int
5844 The `picset` opcode defines a group of pictures starting from the
5845 specified picture ID (`picture`) and including the next `count`
5846 pictures. The interpreter should attempt to load all pictures in the
5847 group from the picture file simultaneously, reducing the need for
5848 multiple disk accesses.
5852 - All pictures within a group must be located in the same picture
5854 - If the interpreter does not support picture grouping, the opcode
5857 **Error Conditions:**
5861 - `picture` is not a valid picture ID.
5862 - `count` is negative.
5867 picset 10, 5 ; Defines a group of 5 pictures starting from picture ID 10
5872 - Optimizing picture loading by grouping related pictures together.
5873 - Reducing disk access times in multi-disk games.
5875 **Note:** The `PICSET` opcode is an optimization feature that may not
5876 be supported by all interpreters. It is important to check the
5877 interpreter's capabilities before using this opcode.
5881 **POP** is an opcode that removes the top element from a stack and
5882 returns its value. It can be used to retrieve values from the game
5883 stack or a user-defined stack.
5888 pop [, stack:tbl] > val
5893 The `pop` opcode removes the top element from the specified stack and
5896 - **Game stack (default):** If the `stack` argument is omitted, the
5897 opcode pops the top element from the game stack.
5898 - **User-defined stack:** If the `stack` argument is provided, the
5899 opcode pops the top element from the table pointed to by `stack`.
5903 The popped value is stored in the specified destination (`val`). If no
5904 destination is provided, the value is pushed onto the game stack.
5908 - Attempting to pop from an empty stack is an error.
5910 **Error Conditions:**
5914 - `stack` is not a valid table pointer (if provided).
5915 - The stack is empty.
5920 pop > value ; Pops the top element from the game stack and stores it in `value`
5921 pop user_stack > value ; Pops the top element from `user_stack`
5926 - Retrieving values from the game stack or user-defined stacks.
5927 - Implementing stack-based data structures and algorithms.
5929 **Note:** The `POP` opcode is used to remove and retrieve elements
5930 from stacks. To add elements, use the `PUSH` or `XPUSH` opcodes.
5934 **PRINT** is an opcode that prints a string to the screen. It is used
5935 to display text output in the current window.
5945 The `print` opcode prints the string pointed to by `str`. The string
5946 address is calculated by shifting `str` left by two bits and adding
5947 the string offset (`SOFF`) shifted left by three bits.
5951 - The `str` argument is a quad-pointer, meaning it points to a
5952 string that is aligned to a quad-byte boundary in the string area.
5953 - The string area is located in a separate section of the Z-code
5954 program and is accessed using the `SOFF` value.
5955 - Strings are encoded in a special 5-bit byte format for efficient
5958 **Error Conditions:**
5960 An error occurs if `str` is not a valid string pointer.
5965 .gstr "message", "Hello, world!"
5966 print message ; Prints the "message" string
5971 - Displaying text output to the user.
5972 - Printing messages, prompts, or descriptions.
5974 **Note:** The `PRINT` opcode is used to print strings from the string
5975 area. For printing strings within tables or as immediate operands, use
5976 the `PRINTB` opcode.
5980 **PRINTB** is an opcode that prints a string from a table or an
5981 immediate string operand. It is used to display text output that is
5982 not stored in the string area.
5992 The `printb` opcode prints the string pointed to by `str`. The string
5995 - **A string within a table:** The `str` argument is a byte pointer
5996 to the beginning of the string within a table.
5997 - **An immediate string operand:** The string is directly encoded
5998 within the instruction as a sequence of bytes.
6002 - The `printb` opcode is typically used for printing shorter strings
6003 or strings that are dynamically generated.
6004 - Strings printed with `printb` are not subject to the string offset
6005 (`SOFF`) adjustment.
6007 **Error Conditions:**
6009 An error occurs if `str` is not a valid string pointer or if the
6010 immediate string operand is malformed.
6015 printb vocabulary[word_index] ; Prints the word from the vocabulary table at the specified index
6016 printb "This is an immediate string." ; Prints the immediate string
6021 - Printing strings from tables, such as vocabulary entries or text
6023 - Displaying short messages or prompts that do not need to be stored
6026 **Note:** The `PRINTB` opcode is used for printing strings that are
6027 not located in the string area. For printing strings from the string
6028 area, use the `PRINT` opcode.
6032 **PRINTC** is an opcode that prints a word from the game's vocabulary
6033 table. It is typically used to reprint words that were previously
6034 parsed from player input.
6044 The `printc` opcode performs the following:
6046 - **Looks up word:** Uses the value of `text-char` as an index into
6047 the vocabulary table (pointed to by the `VOCAB` word in the
6049 - **Retrieves word data:** If the index is valid, the opcode
6050 retrieves the word data from the vocabulary table. This data
6051 includes the encoded Z-string representation of the word and its
6053 - **Prints the word:** Decodes the Z-string and prints the
6054 corresponding characters to the screen.
6058 - The `text-char` argument is typically obtained from the `lexv`
6059 table, which is filled by the `READ` or `LEX` opcodes during input
6061 - The format of the vocabulary table entries is specific to the
6062 Z-machine and is defined by the `.VOCBEG` directive.
6064 **Error Conditions:**
6068 - `text-char` is not a valid index into the vocabulary table.
6073 read input_buffer, lexv
6074 printc lexv[1] ; Prints the second word from the parsed input
6079 - Reprinting words that were previously entered by the player.
6080 - Implementing text-based menus or displays that use words from the
6083 **Note:** The `PRINTC` opcode is used to print words from the
6084 vocabulary table. For printing arbitrary strings, use the `PRINT` or
6089 **PRINTD** is an opcode that prints the short description of an
6090 object. Objects in Z-code programs can have a short description
6091 associated with them, which is typically used for providing a brief
6092 textual representation of the object.
6102 The `printd` opcode performs the following:
6104 - **Locates object:** Finds the object with the specified object
6106 - **Retrieves short description:** Accesses the object's property
6107 table and retrieves the value of the `DESC` property, which
6108 contains the short description.
6109 - **Prints the description:** Decodes the Z-string representation of
6110 the short description and prints the corresponding characters to
6115 - If the object does not have a `DESC` property, the opcode does
6117 - The short description is typically a short string encoded in the
6118 Z-machine's 5-bit byte format.
6120 **Error Conditions:**
6122 An error occurs if `obj` is not a valid object number.
6127 printd player ; Prints the short description of the "player" object
6132 - Displaying a brief description of an object to the player.
6133 - Providing context or information about objects in the game world.
6135 **Note:** The `PRINTD` opcode is a convenient way to print the short
6136 description associated with an object. For printing other properties
6137 or arbitrary strings, use the `GETP`, `GETPT`, `PRINT`, or `PRINTB`
6142 **PRINTF** is an opcode that prints a formatted table to the screen.
6143 Formatted tables allow for more flexible text layout and can include
6144 variable-length lines, different fonts, and highlighting.
6154 The `printf` opcode prints the contents of the specified `table` as a
6155 formatted block of text. The table format is as follows:
6157 - **Line length indicators:** Each line of text is preceded by a
6158 word (two bytes) that specifies the number of characters in that
6160 - **Character data:** The characters of each line are stored as
6162 - **End of table marker:** A word with the value 0 marks the end of
6165 The opcode interprets the line length indicators and character data to
6166 print the text with the appropriate formatting, including line breaks
6167 and potential justification.
6171 - Formatted tables are typically generated using the `DIROUT 3`
6172 opcode with the `just` argument to specify justification.
6173 - The `printf` opcode can handle tables with variable-length lines,
6174 different fonts, and highlighting.
6176 **Error Conditions:**
6180 - `table` is not a valid table pointer.
6181 - The table format is invalid.
6186 dirout 3, formatted_text, 80 ; Redirects output to `formatted_text` with right justification at 80 pixels
6187 ; ... generate formatted text ...
6189 printf formatted_text ; Prints the formatted table
6194 - Displaying text with custom formatting and layout.
6195 - Creating menus or dialog boxes with variable-length lines and
6197 - Implementing text-based graphics or visual effects.
6199 **Note:** The `PRINTF` opcode provides a more flexible way to display
6200 text compared to the `PRINT` or `PRINTB` opcodes. It is particularly
6201 useful for situations where precise control over text layout and
6202 formatting is required.
6206 **PRINTI** is an opcode that prints an immediate string directly
6207 encoded within the instruction. It is used to display short, fixed
6208 messages or prompts without the need to define them as separate
6209 strings in the string area.
6219 The `printi` opcode decodes and prints the string literal `"string"`
6220 that is included directly within the instruction.
6224 - The string literal must be enclosed in double quotes (`"`).
6225 - Double quotes within the string are escaped by using two
6226 consecutive double quotes.
6228 **Error Conditions:**
6230 An error occurs if the string literal is malformed or not properly
6236 printi "Hello, world!" ; Prints the string "Hello, world!"
6237 printi "He said, ""Hello!""" ; Prints the string "He said, "Hello!""
6242 - Printing short, fixed messages or prompts.
6243 - Displaying error messages or debugging information.
6245 **Note:** The `PRINTI` opcode is a convenient way to print short
6246 strings without the overhead of defining them as separate entities in
6247 the string area. However, for longer or more complex strings, using
6248 the `PRINT` or `PRINTB` opcodes with strings defined using `.STR` or
6249 `.GSTR` is more efficient.
6253 **PRINTN** is an opcode that prints a signed integer value as a
6254 decimal number. It is used to display numerical values on the screen.
6264 The `printn` opcode converts the signed integer value `number` into a
6265 decimal string representation and prints it to the current window.
6269 - Negative numbers are printed with a leading minus sign (`-`).
6270 - The number is printed using the current font and highlighting
6273 **Error Conditions:**
6280 printn score ; Prints the value of the variable `score` as a decimal number
6281 printn -10 ; Prints the number -10
6286 - Displaying numerical values, such as scores, health points, or
6288 - Printing the results of calculations or comparisons.
6290 **Note:** The `PRINTN` opcode is used to print signed integer values.
6291 For printing unsigned values or values in other formats, use the
6292 `PRINT` or `PRINTB` opcodes with appropriate string formatting.
6296 **PRINTR** is an opcode that prints an immediate string and then
6297 performs a carriage return and line feed (CRLF), effectively moving
6298 the cursor to the beginning of the next line. It also implicitly
6299 returns true from the current function.
6309 The `printr` opcode performs the following:
6311 1. **Prints the string:** Decodes and prints the string literal
6312 `"string"` that is included directly within the instruction.
6313 2. **Outputs CRLF:** Prints a carriage return and line feed sequence,
6314 moving the cursor to the beginning of the next line.
6315 3. **Returns true:** Implicitly returns the value 1 (true) from the
6320 - The string literal must be enclosed in double quotes (`"`).
6321 - Double quotes within the string are escaped by using two
6322 consecutive double quotes.
6324 **Error Conditions:**
6326 An error occurs if the string literal is malformed or not properly
6332 printr "Game over!" ; Prints "Game over!" and then returns true, ending the current function
6337 - Printing a final message or prompt before ending the current
6339 - Displaying error messages or debugging information and then
6340 returning from the function.
6342 **Note:** The `PRINTR` opcode combines string printing, line
6343 termination, and function return into a single operation. It is a
6344 convenient way to print a message and then exit the current function.
6348 **PRINTT** is an opcode that prints a rectangular block of text from a
6349 byte-oriented table. It allows for flexible formatting and display of
6355 printt bytes:tbl, width:int, height:int [, skip:int]
6360 The `printt` opcode prints a block of text from the specified table
6361 (`bytes`) according to the given dimensions and skip value:
6363 - **`bytes`:** A pointer to a byte-oriented table containing the
6365 - **`width`:** The width of the text block in columns (number of
6366 characters per line).
6367 - **`height`:** The height of the text block in lines.
6368 - **`skip` (optional):** The number of bytes to skip at the end of
6369 each line. This allows for printing rectangular blocks from within
6370 larger tables. If omitted, the default skip value is 0.
6372 The opcode prints the text line by line, wrapping to the next line
6373 when the `width` is reached. After each line, it skips `skip` bytes in
6374 the table before starting the next line.
6378 - If the `skip` argument is 0, the opcode prints a continuous block
6379 of text without skipping any bytes.
6380 - The `printt` opcode does not perform any character set decoding or
6381 string interpretation. It simply prints the raw bytes from the
6384 **Error Conditions:**
6388 - `bytes` is not a valid table pointer.
6389 - `width` or `height` is zero or negative.
6390 - `skip` is negative.
6395 printt text_buffer, 80, 24 ; Prints a 24-line block of text from `text_buffer`, 80 characters per line
6396 printt table, 10, 5, 20 ; Prints a 5-line block from `table`, 10 characters per line, skipping 20 bytes after each line
6401 - Displaying formatted text from tables.
6402 - Printing text-based graphics or user interface elements.
6403 - Implementing custom text layout and formatting.
6405 **Note:** The `PRINTT` opcode provides a flexible way to print text
6406 from tables. It is important to ensure that the table format and
6407 dimensions are correct to avoid unexpected output.
6411 **PTSIZE** is an opcode that returns the size of a property table in
6412 bytes. Property tables are associated with objects and contain
6413 additional data and attributes.
6423 The `ptsize` opcode calculates the size of the property table pointed
6424 to by `table` and stores the result in the specified destination
6425 (`val`). If no destination is provided, the result is pushed onto the
6430 - The `ptsize` opcode is typically used with property tables
6431 obtained using the `GETPT` opcode.
6432 - The opcode assumes that the property table has the correct format,
6433 with properties stored in a sorted order and appropriate length
6436 **Error Conditions:**
6438 An error may occur if `table` is not a valid property table pointer or
6439 if the table format is invalid.
6444 getpt object, 10 > prop_ptr ; Retrieves a pointer to property 10 of `object`
6445 ptsize prop_ptr > prop_size ; Calculates the size of the property value
6450 - Determining the size of a property value before accessing or
6452 - Implementing routines that need to handle properties of varying
6455 **Note:** The `PTSIZE` opcode is used to determine the size of
6456 property tables. It is important to ensure that the table pointer is
6457 valid and the table format is correct.
6461 **PUSH** is an opcode that pushes a value onto the game stack. The
6462 game stack is a LIFO (Last-In-First-Out) data structure used to store
6463 temporary values and function arguments.
6473 The `push` opcode pushes the specified `value` onto the top of the
6478 - Pushing a value onto a full stack results in a stack overflow
6481 **Error Conditions:**
6483 An error occurs if the game stack is full.
6488 push 5 ; Pushes the value 5 onto the stack
6489 push var1 ; Pushes the value of the variable `var1` onto the stack
6494 - Storing temporary values during calculations or operations.
6495 - Passing arguments to functions.
6496 - Implementing stack-based data structures and algorithms.
6498 **Note:** The `PUSH` opcode is used to add elements to the game stack.
6499 To remove elements, use the `POP` or `FSTACK` opcodes.
6503 **PUT** is an opcode that stores a word value into a specified element
6504 of a word-oriented table. It is used to modify data stored in tables
6505 based on their index or offset.
6510 put table, item, value
6515 The `put` opcode performs the following:
6517 - **Calculates element address:** Multiplies the `item` (index or
6518 offset) by 2 and adds it to the base address of the `table`. This
6519 gives the address of the desired element in memory.
6520 - **Stores the value:** Writes the word value `value` to the
6525 - Table offsets are zero-based, meaning the first element has an
6527 - The interpreter does not perform bounds checking on table
6528 accesses. It is the programmer's responsibility to ensure that
6529 `item` is within the valid range of the table.
6531 **Error Conditions:**
6533 An error may occur if:
6535 - `table` is not a valid table pointer.
6536 - `item` is outside the bounds of the table.
6541 put inventory, 3, "sword" ; Stores the word "sword" in the 4th element of the `inventory` table
6546 - Modifying data stored in tables based on their index or offset.
6547 - Implementing data structures and algorithms that require updating
6550 **Note:** The `PUT` opcode is used for storing word-sized elements in
6551 tables. For byte-sized elements, use the `PUTB` opcode.
6555 **PUTB** is an opcode that stores a byte value into a specified
6556 element of a byte-oriented table. It is used to modify data stored in
6557 tables based on their index or offset.
6562 putb table, item, value
6567 The `putb` opcode performs the following:
6569 - **Calculates element address:** Adds the `item` (index or offset)
6570 to the base address of the `table`. This gives the address of the
6571 desired element in memory.
6572 - **Extracts byte value:** Takes the low-order byte of `value` as
6573 the byte to be stored.
6574 - **Stores the byte:** Writes the extracted byte value to the
6579 - Table offsets are zero-based, meaning the first element has an
6581 - The interpreter does not perform bounds checking on table
6582 accesses. It is the programmer's responsibility to ensure that
6583 `item` is within the valid range of the table.
6584 - The high-order byte of `value` is ignored.
6586 **Error Conditions:**
6588 An error may occur if:
6590 - `table` is not a valid table pointer.
6591 - `item` is outside the bounds of the table.
6596 putb text_buffer, 5, 'A' ; Stores the ASCII value of 'A' in the 6th byte of the `text_buffer` table
6601 - Modifying data stored in byte-oriented tables.
6602 - Writing individual characters to text buffers.
6603 - Implementing data structures and algorithms that require updating
6604 byte-level table values.
6606 **Note:** The `PUTB` opcode is used for storing byte-sized elements in
6607 tables. For word-sized elements, use the `PUT` opcode.
6611 **PUTP** is an opcode that sets the value of a property within an
6612 object's property table. Properties are used to associate additional
6613 data and attributes with objects.
6618 putp obj, prop, value
6623 The `putp` opcode modifies a property within an object's property
6626 - **Locates property table:** Finds the property table associated
6627 with the object (`obj`).
6628 - **Searches for property:** Searches the property table for the
6629 property with the specified number (`prop`).
6630 - **Updates property value:** If the property is found, its value is
6632 - **Error if property not found:** If the property is not found in
6633 the object's property table, an error occurs.
6637 - The `PUTP` opcode can only be used to modify properties with a
6638 length of 1 or 2 bytes. For properties of arbitrary length, use a
6639 combination of `GETPT` and table manipulation opcodes.
6641 **Error Conditions:**
6645 - `obj` is not a valid object number.
6646 - `prop` is not a valid property number within the object's property
6648 - The property does not exist in the object's property table.
6653 putp player, 1, 15 ; Sets the value of property 1 ("strength") in the "player" object to 15
6658 - Modifying data associated with objects through properties.
6659 - Updating object attributes or characteristics based on game logic
6662 **Note:** The `PUTP` opcode is used to modify properties with a length
6663 of 1 or 2 bytes. For properties of arbitrary length, use a combination
6664 of `GETPT` and table manipulation opcodes.
6668 **QUIT** is an opcode that terminates the execution of the Z-code
6669 program. It is used to end the game or exit the interpreter.
6679 The `quit` opcode signals to the interpreter that the program should
6680 terminate. The interpreter performs any necessary cleanup operations
6687 **Error Conditions:**
6694 quit ; Terminates the program
6699 - Ending the game when the player reaches a specific condition or
6700 completes all objectives.
6701 - Exiting the interpreter in response to a user command or error
6704 **Note:** The `QUIT` opcode is a terminal instruction that stops the
6705 execution of the Z-code program. It is important to ensure that all
6706 necessary cleanup or saving operations are performed before using this
6711 **RANDOM** is an opcode that generates a random number within a
6712 specified range. It is used to introduce randomness and
6713 unpredictability into the game.
6718 random range:int > val
6723 The `random` opcode generates a random integer value between 1 and
6724 `range` (inclusive) and stores it in the specified destination
6725 (`val`). If no destination is provided, the result is pushed onto the
6730 - **Negative `range`:** If `range` is negative, the opcode enters a
6731 "predictable" mode. The absolute value of `range` is saved, and
6732 subsequent calls to `random` with a positive range will generate
6733 numbers in a sequence from 1 to the saved absolute value.
6734 - **`range` = 0:** Resets the random number generator to its normal
6735 (unpredictable) mode.
6737 **Error Conditions:**
6744 random 6 > dice_roll ; Generates a random number between 1 and 6
6745 random -10 ; Enters predictable mode with a sequence of 1 to 10
6746 random 4 > next_num ; Generates the next number in the predictable sequence (e.g., 1, 2, 3, 4, 1, ...)
6747 random 0 ; Resets to unpredictable mode
6752 - Generating random events or outcomes in the game.
6753 - Simulating dice rolls or other random processes.
6754 - Introducing variability and replayability into the game
6757 **Note:** The implementation of the random number generator may vary
6758 between interpreters. The predictable mode allows for testing and
6759 debugging scenarios where consistent random values are desired.
6763 **READ** is an opcode that reads a line of input from the user, parses
6764 it into words, and looks up the words in the vocabulary table. It is a
6765 fundamental operation for receiving player input and interpreting
6771 read text-buffer:tbl, parse-buffer:tbl [, time:int, routine:fcn] > val
6776 The `read` opcode performs the following:
6778 1. **Clears output buffer:** Prints and empties the current output
6779 buffer, ensuring that any pending output is displayed before
6781 2. **Reads input:** Reads a line of text from the user, storing the
6782 characters in the `text-buffer` table. The first byte of
6783 `text-buffer` specifies the maximum length of the buffer, and the
6784 second byte is used by the opcode to store the number of
6786 3. **Converts to lowercase:** Converts all uppercase letters in the
6788 4. **Parses input (optional):** If `parse-buffer` is non-zero, the
6789 opcode parses the input text into words and stores information
6790 about each word in the `parse-buffer` table. The format of the
6791 `parse-buffer` is specific to the Z-machine and is used by other
6792 opcodes like `PRINTC` to reprint words from the input.
6793 5. **Returns terminator:** The opcode returns the character that
6794 terminated the input (e.g., newline, space, or a character from
6795 the `TCHARS` table). This value is stored in the specified
6796 destination (`val`). If no destination is provided, the value is
6797 pushed onto the game stack.
6799 **Optional Arguments:**
6801 - **`time`:** Specifies a timeout value in tenths of a second. If no
6802 input is received within the specified time, the interpreter calls
6803 the `routine` function.
6804 - **`routine`:** A function to call when a timeout occurs. The
6805 function should return true (1) to abort the input operation or
6806 false (0) to continue waiting for input.
6810 - The `TCHARS` table in the program header specifies which
6811 characters can terminate input.
6812 - The vocabulary table (pointed to by the `VOCAB` word) is used to
6813 look up words during parsing.
6814 - The interpreter may handle timeout behavior differently depending
6815 on the target machine and implementation.
6817 **Error Conditions:**
6821 - `text-buffer` or `parse-buffer` is not a valid table pointer.
6822 - The `text-buffer` is not large enough to hold the input line.
6823 - `time` is negative (if provided).
6824 - `routine` is not a valid function pointer (if provided).
6829 read input_buffer, parse_buffer > terminator ; Reads input and parses it into words
6830 read input_buffer, 0 > terminator ; Reads input without parsing
6835 - Getting input from the user, such as commands, responses, or text
6837 - Implementing a text parser to interpret player commands.
6838 - Handling timed input or interactive sequences.
6840 **Note:** The `READ` opcode is a fundamental operation for receiving
6841 and processing player input in Z-code programs.
6845 **REMOVE** is an opcode that removes an object from the object
6846 hierarchy. Objects in Z-code programs are organized in a tree
6847 structure, where each object can be contained within another object.
6857 The `remove` opcode removes the specified object (`obj`) from the
6860 1. **Finds the containing object:** Determines the object that
6861 currently contains `obj` by examining its `LOC` property.
6862 2. **Updates containment chain:** Removes `obj` from the containment
6863 chain of the containing object. This involves updating the `FIRST`
6864 and `NEXT` properties of the objects in the chain.
6865 3. **Clears object properties:** Sets the `LOC`, `FIRST`, and `NEXT`
6866 properties of `obj` to 0, effectively removing it from the object
6871 - If `obj` is not contained within any other object (i.e., it is a
6872 top-level object), the opcode only clears its `LOC`, `FIRST`, and
6875 **Error Conditions:**
6877 An error occurs if `obj` is not a valid object number.
6882 remove item ; Removes the `item` object from its container
6887 - Implementing inventory management and object interaction.
6888 - Removing objects from the game world when they are no longer
6890 - Updating the object hierarchy based on game logic or player
6893 **Note:** The `REMOVE` opcode is used to remove objects from the
6894 object hierarchy. It is important to ensure that the object is
6895 properly removed from any containment chains to avoid dangling
6896 references or memory leaks.
6900 **RESTART** is an opcode that reinitializes the Z-code program and
6901 restarts the game from the beginning. It is used to reset the game
6902 state and start a new playthrough.
6912 The `restart` opcode performs the following:
6914 1. **Reloads the preloaded area:** The interpreter reloads the
6915 portion of the game file that is below the `ENDLOD` address, which
6916 includes all modifiable data and essential tables.
6917 2. **Resets the game state:** All global variables, object flags, and
6918 other modifiable data are reset to their initial values.
6919 3. **Jumps to the start address:** The program counter is set to the
6920 address specified by the `START` word in the program header, which
6921 is typically the beginning of the main game function.
6925 - The `RESTART` opcode does not affect the state of the interpreter
6926 itself, such as window configurations or display settings.
6927 - The random number generator may or may not be reseeded, depending
6928 on the interpreter implementation.
6930 **Error Conditions:**
6937 restart ; Restarts the game
6942 - Starting a new game from the beginning.
6943 - Resetting the game state after an error or unexpected event.
6944 - Implementing a "restart game" command for the player.
6946 **Note:** The `RESTART` opcode provides a way to reset the game state
6947 and start a new playthrough. It is important to ensure that all
6948 necessary data is properly reinitialized during the restart process.
6952 **RESTORE** is an opcode that restores a previously saved game state
6953 from disk. It allows players to resume a game from a saved point.
6958 restore [, start:int, length:int, name:tbl] > val
6963 The `restore` opcode has two modes of operation:
6965 **1. Full Restore (no arguments):**
6967 - **Prompts for filename:** The interpreter typically prompts the
6968 user to provide a filename or select a saved game file.
6969 - **Reads saved data:** The interpreter reads the saved game data
6970 from the specified file.
6971 - **Restores game state:** The impure area of the Z-code program,
6972 which includes global variables, object flags, and table contents,
6973 is restored to the state it was in when the game was saved.
6974 - **Continues execution:** The program resumes execution from the
6975 point where it was saved.
6977 **2. Partial Restore (with arguments):**
6979 - **`start`:** The starting address of the memory region to restore.
6980 - **`length`:** The length of the memory region to restore in bytes.
6981 - **`name`:** A string specifying the name of the saved data.
6983 This mode allows for restoring specific sections of the impure area,
6984 such as individual tables or groups of variables.
6988 - **Full restore:** The opcode does not return a value.
6989 - **Partial restore:** The opcode returns the number of bytes
6990 successfully read from the saved data.
6994 - The format of the saved game data is specific to the Z-machine and
6995 may vary depending on the interpreter implementation.
6996 - The `RESTORE` opcode does not restore the state of the interpreter
6997 itself, such as window configurations or display settings.
6998 - The random number generator may or may not be reseeded, depending
6999 on the interpreter implementation.
7001 **Error Conditions:**
7005 - The specified saved game file cannot be found or opened.
7006 - The saved game data is corrupted or invalid.
7007 - The `start` or `length` arguments are invalid (in partial restore
7013 restore ; Restores a saved game from a file
7014 restore table_address, table_size, "my_table" ; Restores a specific table from saved data
7019 - Allowing players to save and resume their progress in the game.
7020 - Implementing checkpoint or save-game functionality.
7021 - Restoring specific data structures or variables from saved data.
7023 **Note:** The `RESTORE` opcode is essential for providing save and
7024 restore functionality in Z-code games. The specific implementation and
7025 user interface for saving and loading games may vary depending on the
7030 **RETURN** is an opcode that returns from the current function and
7031 resumes execution in the calling function. It also allows for
7032 specifying a return value.
7042 The `return` opcode performs the following:
7044 1. **Sets return value:** The specified `value` is set as the return
7045 value of the function.
7046 2. **Restores stack frame:** The interpreter restores the stack frame
7047 of the calling function, including local variables, stack pointer,
7049 3. **Resumes execution:** Control is transferred back to the
7050 instruction following the `CALL` instruction that invoked the
7055 - If the current function was called using an `ICALL` variant (which
7056 does not expect a return value), the `value` argument is ignored.
7058 **Error Conditions:**
7065 return 5 ; Returns the value 5 from the function
7066 return result ; Returns the value of the variable `result`
7071 - Returning from functions and providing a result to the calling
7073 - Implementing subroutines and modular code structures.
7075 **Note:** The `RETURN` opcode is essential for controlling the flow of
7076 execution between functions in Z-code programs.
7080 **RFALSE** is an opcode that returns the value 0 (false) from the
7081 current function. It is typically used as a branch target for
7082 predicate instructions that evaluate to false.
7092 The `rfalse` opcode sets the return value of the current function to 0
7093 and then returns control to the calling function.
7099 **Error Conditions:**
7106 equal? object, "sword" / handle_sword
7107 rfalse ; Returns false if the object is not a sword
7112 - Returning false from a function when a condition is not met.
7113 - Implementing conditional logic and branching based on predicate
7116 **Note:** The `RFALSE` opcode is often used as a branch target for
7117 predicate instructions that evaluate to false. It provides a
7118 convenient way to return a false value and exit the current function.
7122 **RSTACK** is an opcode that returns from the current function and
7123 uses the value on top of the stack as the return value. This allows
7124 for a more flexible way to return values from functions without
7125 explicitly specifying them in the `RETURN` instruction.
7135 The `rstack` opcode performs the following:
7137 1. **Pops return value:** Removes the top element from the game stack
7138 and uses it as the return value of the function.
7139 2. **Restores stack frame:** The interpreter restores the stack frame
7140 of the calling function, including local variables, stack pointer,
7142 3. **Resumes execution:** Control is transferred back to the
7143 instruction following the `CALL` instruction that invoked the
7148 - If the game stack is empty, a stack underflow error occurs.
7150 **Error Conditions:**
7152 An error occurs if the game stack is empty when the `RSTACK` opcode is
7158 ; ... function code that pushes a value onto the stack ...
7159 rstack ; Returns the value from the top of the stack
7164 - Returning values from functions without explicitly specifying them
7165 in the `RETURN` instruction.
7166 - Implementing functions that can return different types of values
7167 depending on the context.
7169 **Note:** The `RSTACK` opcode provides a more flexible way to return
7170 values from functions, but it is important to ensure that the stack
7171 contains the correct value before using this opcode.
7175 **RTRUE** is an opcode that returns the value 1 (true) from the
7176 current function. It is typically used as a branch target for
7177 predicate instructions that evaluate to true.
7187 The `rtrue` opcode sets the return value of the current function to 1
7188 and then returns control to the calling function.
7194 **Error Conditions:**
7201 equal? object, "sword" / handle_sword
7202 rtrue ; Returns true if the object is a sword
7207 - Returning true from a function when a condition is met.
7208 - Implementing conditional logic and branching based on predicate
7211 **Note:** The `RTRUE` opcode is often used as a branch target for
7212 predicate instructions that evaluate to true. It provides a convenient
7213 way to return a true value and exit the current function.
7217 **SAVE** is an opcode that saves the current game state to disk,
7218 allowing players to resume their progress later.
7223 save [, start:int, length:int, name:tbl] > val
7228 The `save` opcode has two modes of operation:
7230 **1. Full Save (no arguments):**
7232 - **Prompts for filename:** The interpreter typically prompts the
7233 user to provide a filename or select a save game slot.
7234 - **Writes game data:** The interpreter writes the current game
7235 state to the specified file. This includes the contents of the
7236 impure area, which contains all modifiable data such as global
7237 variables, object flags, and table contents.
7238 - **Returns status:** The opcode returns 0 if the save operation
7239 fails and 1 if it succeeds.
7241 **2. Partial Save (with arguments):**
7243 - **`start`:** The starting address of the memory region to save.
7244 - **`length`:** The length of the memory region to save in bytes.
7245 - **`name`:** A string specifying a unique name for the saved data.
7247 This mode allows for saving specific sections of the impure area, such
7248 as individual tables or groups of variables.
7252 - **Full save:** Returns 0 if the save operation fails and 1 if it
7254 - **Partial save:** Returns 2 to indicate successful completion.
7258 - The format of the saved game data is specific to the Z-machine and
7259 may vary depending on the interpreter implementation.
7260 - The `SAVE` opcode does not save the state of the interpreter
7261 itself, such as window configurations or display settings.
7262 - The random number generator seed is typically not saved to ensure
7263 that restoring a saved game does not result in the same sequence
7266 **Error Conditions:**
7270 - The specified save game file cannot be created or written to.
7271 - The `start` or `length` arguments are invalid (in partial save
7277 save ; Saves the entire game state to a file
7278 save table_address, table_size, "my_table" ; Saves a specific table to a file
7283 - Allowing players to save their progress in the game.
7284 - Implementing checkpoint or save-game functionality.
7285 - Saving specific data structures or variables for later retrieval.
7287 **Note:** The `SAVE` opcode is essential for providing save and
7288 restore functionality in Z-code games. The specific implementation and
7289 user interface for saving and loading games may vary depending on the
7294 **SCREEN** is an opcode that selects the active window for subsequent
7295 text output. Z-code programs can have multiple windows, each with its
7296 own properties and display area.
7306 The `screen` opcode sets the current window to the window specified by
7307 `window`. All subsequent text output, including printing strings and
7308 characters, will be directed to this window.
7312 - If the `window` argument is omitted, the current window remains
7314 - Each window maintains its own cursor position and other
7315 attributes. When switching between windows, the cursor position
7316 and attributes of the previously active window are preserved.
7318 **Error Conditions:**
7320 An error occurs if `window` is not within the valid range (0 to 7).
7325 screen 1 ; Switches to window 1 for output
7326 print "This text will appear in window 1."
7327 screen 0 ; Switches back to the main window (window 0)
7332 - Managing multiple windows for displaying different types of
7333 information or creating a more complex user interface.
7334 - Implementing split-screen displays or separate areas for text
7337 **Note:** The `SCREEN` opcode is used to control which window receives
7338 text output. It is important to keep track of the current window and
7339 switch between windows as needed to ensure that text is displayed in
7340 the correct location.
7344 **SCROLL** is an opcode that scrolls the contents of a window up or
7345 down by a specified number of lines. This can be used to create
7346 scrolling text displays or to shift the contents of a window.
7351 scroll window:int, lines:int
7356 The `scroll` opcode scrolls the contents of the specified window
7357 (`window`) by the number of lines indicated by `lines`:
7359 - **Positive `lines`:** Scrolls the window contents up by `lines`
7360 lines. Blank lines are inserted at the bottom of the window,
7361 filled with the current background color.
7362 - **Negative `lines`:** Scrolls the window contents down by the
7363 absolute value of `lines` lines. Lines at the top of the window
7365 - **`lines` = 0:** Has no effect.
7369 - The `scroll` opcode works on both scrolling and non-scrolling
7371 - The cursor position is not affected by scrolling.
7373 **Error Conditions:**
7377 - `window` is not within the valid range (-3 to 7).
7382 scroll 0, 1 ; Scrolls the main window (window 0) up by one line
7383 scroll 2, -3 ; Scrolls window 2 down by three lines
7388 - Creating scrolling text displays, such as status messages or
7390 - Shifting the contents of a window to make room for new output.
7391 - Implementing custom scrolling behavior or animations.
7393 **Note:** The `SCROLL` opcode provides a way to manipulate the
7394 contents of a window by scrolling it up or down. It is important to
7395 consider the window's scrolling attribute and the desired visual
7396 effect when using this opcode.
7400 **SET** is an opcode that assigns a value to a variable. It is used to
7401 modify the contents of variables and update the program state.
7411 The `set` opcode assigns the specified `value` to the variable `var`.
7412 The type of `value` can be:
7414 - **Immediate value:** A constant value directly encoded within the
7416 - **Variable:** A reference to another variable.
7417 - **Other:** A value obtained from another instruction or
7424 **Error Conditions:**
7431 set counter, 0 ; Initializes the variable `counter` to 0
7432 set player_health, health_potion ; Assigns the value of `health_potion` to `player_health`
7437 - Initializing variables with specific values.
7438 - Updating variables based on game logic or player actions.
7439 - Assigning the results of calculations or expressions to variables.
7441 **Note:** The `SET` opcode is a fundamental operation for modifying
7442 variables and managing the program state in Z-code programs.
7446 **SHIFT** is an opcode that performs a logical shift on a 16-bit
7447 integer value. It shifts the bits of the operand to the left or right,
7448 depending on the specified shift amount.
7458 The `shift` opcode performs the following:
7460 - **Shifts the bits of `int`:**
7461 - If `n` is positive, `int` is shifted left by `n` bits. Zeros
7462 are shifted into the least significant bits.
7463 - If `n` is negative, `int` is shifted right by the absolute
7464 value of `n` bits. Zeros are shifted into the most significant
7466 - **Does not preserve the sign bit:** In a logical shift, the sign
7467 bit is not replicated during a right shift. This means that the
7468 sign of the number may change after the shift.
7469 - **Stores the result:** The shifted value is stored in the
7470 specified destination (`val`). If no destination is provided, the
7471 result is pushed onto the game stack.
7475 - If `n` is zero, the value of `int` remains unchanged.
7476 - If the shift amount exceeds the word size (16 bits), the result is
7479 **Error Conditions:**
7486 shift num, 2 > shifted ; Shifts the value in `num` left by 2 bits, filling with zeros
7487 shift num, -1 > shifted ; Shifts the value in `num` right by 1 bit, filling with zeros
7492 - Multiplying or dividing numbers by powers of two efficiently.
7493 - Manipulating individual bits within a word.
7494 - Implementing bitwise operations and algorithms.
7496 **Note:** The `shift` opcode performs a logical shift, which does not
7497 preserve the sign of the operand. For an arithmetic shift, where the
7498 sign bit is replicated, use the `ashift` opcode.
7502 **SOUND** is an opcode that plays a sound effect. It allows Z-code
7503 programs to incorporate audio feedback and enhance the game
7509 sound id:int, op:int [, volume:int, repeat:int]
7514 The `sound` opcode performs sound operations based on the specified
7517 - **`id`:** The ID number of the sound effect to play.
7518 - **`op`:** The sound operation to perform:
7519 - **1:** Initialize the specified sound.
7520 - **2:** Start playing the specified sound (default if `op` is
7522 - **3:** Stop playing the specified sound.
7523 - **4:** Clean up buffers associated with the specified sound.
7524 - **`volume` (optional):** The volume level at which to play the
7525 sound. -1 indicates the default volume.
7526 - **`repeat` (optional):** The number of times to repeat the sound.
7527 -1 indicates that the sound should repeat indefinitely until
7532 - **`id` = 0:** Uses the last sound ID specified.
7533 - **`id` = 1 or 2:** Plays a simple beep or boop sound, ignoring the
7535 - The availability of sound effects and the range of volume levels
7536 depend on the interpreter and target machine capabilities.
7538 **Error Conditions:**
7542 - The interpreter does not support sound effects.
7543 - `id` is not a valid sound ID.
7544 - `op` is not within the valid range (1-4).
7545 - `volume` or `repeat` is invalid (if provided).
7550 sound 10, 2 ; Starts playing sound effect with ID 10
7551 sound 0, 3 ; Stops playing the last sound effect
7552 sound 5, 2, 50, 3 ; Plays sound effect 5 three times at 50% volume
7557 - Playing sound effects to provide feedback or enhance the game
7559 - Creating audio cues for events or actions.
7560 - Implementing music or background sounds.
7562 **Note:** The `SOUND` opcode requires the interpreter to support sound
7563 effects. The `%FSOUN` flag in the `FLAGS` word and the `%XSOUN` bit in
7564 the `MODE` byte indicate whether sound operations are available.
7568 **SPLIT** is an opcode that divides the screen vertically between
7569 windows 0 and 1. It is used to create a split-screen display, with
7570 each window showing different content.
7580 The `split` opcode adjusts the vertical dimensions and positions of
7581 windows 0 and 1 as follows:
7583 - **Sets window 1 height:** The height of window 1 is set to the
7584 value of `height` in lines.
7585 - **Sets window 1 position:** The top of window 1 is placed at the
7586 top of the screen (line 1).
7587 - **Adjusts window 0 position:** The top of window 0 is moved down
7588 to the line following the bottom of window 1.
7589 - **Adjusts window 0 height:** The height of window 0 is adjusted to
7590 fill the remaining space on the screen.
7591 - **Selects window 0:** After splitting the screen, window 0 becomes
7592 the active window for output.
7596 - **`height` = 0:** This effectively unsplits the screen, setting
7597 the height of window 1 to 0 and making window 0 occupy the entire
7600 **Error Conditions:**
7607 split 10 ; Splits the screen, giving window 1 a height of 10 lines
7608 split 0 ; Unsplits the screen
7613 - Creating a split-screen display to show different information or
7614 perspectives simultaneously.
7615 - Implementing status displays or separate areas for text output and
7618 **Note:** The `SPLIT` opcode is a convenient way to create a
7619 split-screen display, but it only affects windows 0 and 1. For more
7620 flexible window management, consider using the `WINPOS` and `WINSIZE`
7625 **SUB** is an opcode that performs subtraction on two 16-bit word
7626 values. It subtracts the second operand from the first operand and
7632 sub arg1:int, arg2:int > val
7637 The `sub` opcode performs the following:
7639 - **Subtracts `arg2` from `arg1`:** Performs integer subtraction.
7640 - **Stores the result:** The difference is stored in the specified
7641 destination (`val`). If no destination is provided, the result is
7642 pushed onto the game stack.
7646 - If the result of the subtraction overflows the 16-bit word size,
7649 **Error Conditions:**
7651 An error occurs if the subtraction result overflows the 16-bit word
7657 sub 10, 5 > result ; Subtracts 5 from 10, stores the difference (5) in `result`
7662 - Performing integer subtraction calculations.
7663 - Decreasing values or calculating differences between numbers.
7665 **Note:** The `sub` opcode performs signed integer subtraction. If the
7666 operands are unsigned, the programmer needs to handle potential
7667 overflow conditions.
7671 **THROW** is an opcode that throws an exception and returns from a
7672 previously called function with a specified value. It is used in
7673 conjunction with the `CATCH` opcode to implement exception handling
7674 and non-local control flow.
7684 The `throw` opcode performs the following:
7686 - **Sets return value:** The specified `value` is set as the return
7687 value of the function identified by the `frame` pointer.
7688 - **Unwinds stack:** The interpreter unwinds the call stack,
7689 returning from all functions called since the function where the
7690 corresponding `CATCH` opcode was executed.
7691 - **Resumes execution:** Control is transferred back to the
7692 instruction following the `CATCH` opcode in the function that
7693 caught the exception.
7697 - The `frame` pointer must be a valid frame pointer obtained from a
7698 previous `CATCH` opcode.
7699 - Throwing an exception to a frame that is no longer on the call
7700 stack results in an error.
7702 **Error Conditions:**
7706 - `frame` is not a valid frame pointer.
7707 - The frame pointed to by `frame` is no longer on the call stack.
7713 ; ... some code that might throw an exception ...
7714 throw "Error!", frame ; Throws an exception and returns to the `catch` instruction
7719 - Implementing exception handling to deal with errors or unexpected
7721 - Performing non-local control flow, such as exiting multiple nested
7724 **Note:** The `THROW` and `CATCH` opcodes provide a mechanism for
7725 exception handling and non-local control flow in Z-code programs. They
7726 should be used with caution to avoid complex control flow and
7731 **VALUE** is an opcode that retrieves the value of a variable and
7732 stores it in a specified destination. It is used to access the current
7733 value of a variable and use it in calculations or other operations.
7743 The `value` opcode performs the following:
7745 - **Retrieves variable value:** Reads the value of the specified
7747 - **Stores the result:** The retrieved value is stored in the
7748 specified destination (`val`). If no destination is provided, the
7749 result is pushed onto the game stack.
7755 **Error Conditions:**
7762 value score > current_score ; Retrieves the value of `score` and stores it in `current_score`
7767 - Accessing the current value of a variable for calculations or
7769 - Passing variable values as arguments to functions.
7770 - Storing variable values in other variables or data structures.
7772 **Note:** The `VALUE` opcode is a simple way to retrieve the value of
7773 a variable. It is equivalent to using the variable directly as an
7774 operand in most instructions.
7778 **VERIFY** is an opcode that checks the integrity of the game file by
7779 comparing a calculated checksum with a stored checksum value. It is
7780 used to detect potential corruption or modifications of the game data.
7790 The `verify` opcode performs the following:
7792 - **Calculates checksum:** Computes a 16-bit checksum of the game
7793 file data from byte 64 to the end of the file (excluding the
7795 - **Compares with stored checksum:** Compares the calculated
7796 checksum with the value stored in the `PCHKSM` word of the program
7798 - **Evaluates predicate:** The predicate succeeds (evaluates to
7799 true) if the calculated checksum matches the stored checksum.
7800 Otherwise, the predicate fails (evaluates to false).
7801 - **Conditional branch:** Based on the predicate result and the
7802 specified branch polarity (`/pred`), the interpreter may perform a
7803 conditional jump to a specified target.
7807 - The checksum calculation excludes the first 64 bytes of the game
7808 file, which contain the program header.
7809 - The `PLENTH` word in the program header specifies the length of
7810 the game file in units of 8 bytes.
7812 **Error Conditions:**
7819 verify / handle_corruption ; Branch to `handle_corruption` if the game file is corrupted
7824 - Detecting unauthorized modifications or corruption of the game
7826 - Implementing copy protection mechanisms.
7827 - Ensuring data integrity before loading or saving games.
7829 **Note:** The effectiveness of the `VERIFY` opcode depends on the
7830 strength of the checksum algorithm and the implementation of copy
7831 protection measures.
7835 **WINATTR** is an opcode that modifies the attributes of a window.
7836 Window attributes control various aspects of the window's behavior,
7837 such as text wrapping, scrolling, and transcripting.
7842 winattr window:int, bits:int, operation:int
7847 The `winattr` opcode modifies the attributes of the specified window
7848 (`window`) based on the `bits` and `operation` arguments:
7850 - **`bits`:** A bitmask where each bit represents a specific window
7852 - Bit 0: Text wrapping (1 = enabled, 0 = disabled).
7853 - Bit 1: Scrolling (1 = enabled, 0 = disabled).
7854 - Bit 2: Transcripting (1 = enabled, 0 = disabled).
7855 - Bit 3: Buffering (1 = enabled, 0 = disabled).
7856 - **`operation`:** Specifies how to modify the attributes:
7857 - **0 (MOVE):** Sets the window attributes to the values
7858 specified by `bits`.
7859 - **1 (SET):** Sets the attributes corresponding to the bits
7860 that are set (1) in `bits`.
7861 - **2 (CLEAR):** Clears the attributes corresponding to the bits
7862 that are set (1) in `bits`.
7863 - **3 (COMP):** Toggles the attributes corresponding to the bits
7864 that are set (1) in `bits`.
7868 - If the `operation` argument is omitted, it defaults to 0 (MOVE).
7870 **Error Conditions:**
7874 - `window` is not within the valid range (-3 to 7).
7875 - `operation` is not within the valid range (0-3).
7880 winattr 1, 1, 1 ; Enables text wrapping for window 1
7881 winattr 2, 6, 2 ; Disables scrolling and transcripting for window 2
7886 - Changing the behavior of windows based on game logic or player
7888 - Enabling or disabling text wrapping, scrolling, or transcripting
7889 for specific windows.
7890 - Customizing the appearance and functionality of the game
7893 **Note:** The `WINATTR` opcode provides a flexible way to modify
7894 window attributes. It is important to understand the meaning of each
7895 bit in the `bits` argument and the effect of the different operations.
7899 **WINGET** is an opcode that retrieves the value of a specific
7900 property from a window's property table. Window properties store
7901 information about the window's position, size, attributes, and other
7907 winget window:int, property:int > val
7912 The `winget` opcode retrieves the value of the property specified by
7913 `property` from the property table of the window identified by
7916 - **`window`:** The number of the window to access.
7917 - **`property`:** The number of the property to retrieve. Valid
7918 property numbers and their corresponding meanings are:
7919 - 0: `WTOP` - Y position of the window (top edge, in screen
7921 - 1: `WLEFT` - X position of the window (left edge, in screen
7923 - 2: `WHIGH` - Height of the window in screen units.
7924 - 3: `WWIDE` - Width of the window in screen units.
7925 - 4: `WYPOS` - Y coordinate of the cursor within the window (row
7927 - 5: `WXPOS` - X coordinate of the cursor within the window
7928 (column number, 1-based).
7929 - 6: `WLMARG` - Left margin of the window in pixels.
7930 - 7: `WRMARG` - Right margin of the window in pixels.
7931 - 8: `WCRFCN` - Function to call for carriage return interrupts.
7932 - 9: `WCRCNT` - Counter for carriage return interrupts.
7933 - 10: `WHLIGHT` - Highlighting mode of the window.
7934 - 11: `WCOLOR` - Color word of the window (background and
7936 - 12: `WFONT` - Font ID used in the window.
7937 - 13: `WFSIZE` - Font size (height and width) used in the
7939 - 14: `WATTRS` - Window attributes (wrapping, scrolling,
7940 transcripting, buffering).
7941 - 15: `WLCNT` - Line counter for the window.
7942 - **Stores the result:** The retrieved property value is stored in
7943 the specified destination (`val`). If no destination is provided,
7944 the result is pushed onto the game stack.
7948 - If the `window` argument is omitted, the current window is used.
7950 **Error Conditions:**
7954 - `window` is not within the valid range (-3 to 7).
7955 - `property` is not a valid property number.
7960 winget 0, 2 > window_height ; Retrieves the height of the main window (window 0)
7961 winget 1, 14 > window_attrs ; Retrieves the attributes of window 1
7966 - Accessing information about window properties, such as position,
7967 size, or attributes.
7968 - Implementing custom window management or display routines.
7969 - Checking the state of specific window features.
7971 **Note:** The `WINGET` opcode provides a flexible way to access
7972 various window properties. It is important to use the correct property
7973 numbers to retrieve the desired information.
7977 **WINPOS** is an opcode that sets the position of a window on the
7978 screen. It allows for precise control over the location of windows
7979 within the display area.
7984 winpos window:int, y:int, x:int
7989 The `winpos` opcode sets the position of the specified window
7990 (`window`) to the coordinates (`y`, `x`):
7992 - **`window`:** The number of the window to reposition.
7993 - **`y`:** The Y coordinate of the top-left corner of the window
7994 (row number, 1-based).
7995 - **`x`:** The X coordinate of the top-left corner of the window
7996 (column number, 1-based).
7998 The coordinates are specified in screen units, with the top-left
7999 corner of the screen being (1, 1).
8003 - If the `window` argument is omitted, the current window is
8005 - The opcode does not check if the new window position would place
8006 the window partially or completely off-screen.
8008 **Error Conditions:**
8012 - `window` is not within the valid range (-3 to 7).
8013 - `y` or `x` is negative.
8018 winpos 1, 5, 10 ; Positions window 1 at row 5, column 10
8019 winpos 2, 1, 1 ; Positions window 2 at the top-left corner of the screen
8024 - Positioning windows for optimal layout and user interface design.
8025 - Creating overlapping windows or dynamic window arrangements.
8026 - Implementing custom window management or animation routines.
8028 **Note:** The `WINPOS` opcode provides direct control over window
8029 positioning. It is important to consider the window's size and the
8030 overall screen layout when using this opcode.
8034 **WINPUT** is an opcode that sets the value of a specific property
8035 within a window's property table. It allows for modifying various
8036 aspects of a window's behavior and appearance.
8041 winput window:int, property:int, value
8046 The `winput` opcode sets the value of the property specified by
8047 `property` in the property table of the window identified by `window`:
8049 - **`window`:** The number of the window to modify.
8050 - **`property`:** The number of the property to set. See the
8051 description of `WINGET` for a list of valid property numbers and
8053 - **`value`:** The new value to assign to the property.
8057 - Not all window properties are writable using `WINPUT`. Some
8058 properties, such as window size and position, require specific
8059 opcodes like `WINSIZE` and `WINPOS` for modification.
8060 - If the `window` argument is omitted, the current window is used.
8062 **Error Conditions:**
8066 - `window` is not within the valid range (-3 to 7).
8067 - `property` is not a valid property number or is not writable.
8072 winput 1, 10, 2 ; Sets the highlighting mode of window 1 to bold
8073 winput 2, 6, 15 ; Sets the left margin of window 2 to 15 pixels
8078 - Modifying window properties to change their behavior or
8080 - Setting the highlighting mode, color, or font of a window.
8081 - Adjusting margins or other window settings.
8083 **Note:** The `WINPUT` opcode provides a way to modify window
8084 properties, but it is important to check which properties are writable
8085 and use the appropriate opcodes for those that are not.
8089 **WINSIZE** is an opcode that sets the size of a window on the screen.
8090 It allows for controlling the dimensions of windows and adjusting the
8091 display area they occupy.
8096 winsize window:int, height:int, width:int
8101 The `winsize` opcode sets the size of the specified window (`window`)
8102 to the given dimensions:
8104 - **`window`:** The number of the window to resize.
8105 - **`height`:** The new height of the window in screen units (number
8107 - **`width`:** The new width of the window in screen units (number
8110 If the new size would cause the window to extend beyond the screen
8111 boundaries, the dimensions are adjusted to fit within the available
8116 - If the `window` argument is omitted, the current window is
8118 - If the new size is smaller than the current cursor position, the
8119 cursor is moved to the bottom-right corner of the resized window.
8121 **Error Conditions:**
8125 - `window` is not within the valid range (-3 to 7).
8126 - `height` or `width` is zero or negative.
8131 winsize 1, 10, 40 ; Sets the size of window 1 to 10 lines by 40 characters
8132 winsize 2, 25, 80 ; Sets the size of window 2 to 25 lines by 80 characters (full screen width)
8137 - Adjusting the size of windows to fit content or accommodate
8138 different display requirements.
8139 - Creating windows with specific dimensions for menus, dialog boxes,
8140 or other UI elements.
8141 - Implementing dynamic window resizing or animations.
8143 **Note:** The `WINSIZE` opcode provides direct control over window
8144 size. It is important to consider the window's position and the
8145 overall screen layout when using this opcode.
8149 **XCALL** is an opcode that calls a function with a variable number of
8150 arguments and returns a value. It is the most general form of the
8151 `CALL` instruction, allowing for up to seven arguments to be passed to
8157 xcall fcn, arg1:any [, arg2:any ...] > val
8162 The `xcall` opcode performs the following:
8164 - **Pushes arguments onto the stack:** Pushes the variable number of
8165 arguments (`arg1`, `arg2`, etc.) onto the game stack. The number
8166 of arguments is determined by the operand types specified in the
8168 - **Calls the function:** Transfers control to the function
8169 specified by `fcn`. The function address is calculated by shifting
8170 `fcn` left by two bits and adding the function offset (`FOFF`)
8171 shifted left by three bits.
8172 - **Retrieves return value:** When the function returns, its return
8173 value is retrieved and stored in the specified destination
8174 (`val`). If no destination is provided, the value is pushed onto
8179 - If `fcn` is zero, the `xcall` opcode acts as if it called a
8180 function that immediately returned false.
8182 **Error Conditions:**
8184 An error occurs if `fcn` is not a valid function pointer.
8189 xcall format_string, buffer, arg1, arg2, arg3 > formatted_text ; Calls the `format_string` function with four arguments
8194 - Calling functions with a variable number of arguments.
8195 - Implementing functions that take a flexible number of parameters.
8197 **Note:** The `XCALL` opcode is generated by the compiler when it
8198 detects a function call with more than two arguments or when the
8199 argument types require the extended format. It is not typically used
8200 directly by programmers.
8204 **XPUSH** is an opcode that attempts to push a value onto a stack and
8205 acts as a predicate based on the success of the operation. It can be
8206 used with both the game stack and user-defined stacks.
8211 xpush value, stack:tbl /pred
8216 The `xpush` opcode performs the following:
8218 - **Checks stack space:** Determines if there is enough space
8219 available on the specified stack (`stack`) to push the value.
8220 - **Pushes value (if space available):** If there is sufficient
8221 space, the opcode pushes the `value` onto the top of the stack.
8222 - **Evaluates predicate:** The predicate succeeds (evaluates to
8223 true) if the value was successfully pushed onto the stack.
8224 Otherwise, the predicate fails (evaluates to false).
8225 - **Conditional branch:** Based on the predicate result and the
8226 specified branch polarity (`/pred`), the interpreter may perform a
8227 conditional jump to a specified target.
8231 - If the `stack` argument is omitted, the opcode operates on the
8234 **Error Conditions:**
8236 An error occurs if `stack` is not a valid table pointer (if provided).
8241 xpush item, inventory / inventory_full ; Attempts to push `item` onto the `inventory` stack
8242 ; ... code to handle full inventory ...
8248 - Pushing values onto stacks while checking for potential stack
8249 overflow conditions.
8250 - Implementing stack-based data structures with overflow handling.
8252 **Note:** The `XPUSH` opcode provides a way to push values onto stacks
8253 while simultaneously checking for available space. This can be useful
8254 for preventing stack overflow errors and implementing robust stack
8259 **ZERO?** is an opcode that checks whether a value is equal to zero.
8260 It acts as a predicate, meaning it evaluates a condition and
8261 implicitly performs a conditional branch based on the result.
8271 The `zero?` opcode performs the following:
8273 - **Checks for zero:** Determines if the value of `arg` is equal to
8275 - **Evaluates predicate:** The predicate succeeds (evaluates to
8276 true) if `arg` is indeed zero. Otherwise, the predicate fails
8277 (evaluates to false).
8278 - **Conditional branch:** Based on the predicate result and the
8279 specified branch polarity (`/pred`), the interpreter may perform a
8280 conditional jump to a specified target.
8286 **Error Conditions:**
8293 zero? counter / end_loop ; Branch to `end_loop` if `counter` is zero
8298 - Implementing conditional logic based on zero checks.
8299 - Determining if a variable or expression has a value of zero.
8300 - Loop termination conditions.
8302 **Note:** The `ZERO?` opcode is a simple but useful predicate for
8303 checking for zero values and implementing conditional behavior in
8308 **ZWSTR** is an opcode that converts a word from an input buffer into
8309 a Z-string and stores it in a specified location. Z-strings are the
8310 standard format for representing text in Z-code programs.
8315 zwstr inbuf:tbl, inlen:int, inbeg:int, zword:tbl
8320 The `zwstr` opcode performs the following:
8322 - **Reads input word:** Extracts the word starting at the byte
8323 offset `inbeg` within the input buffer `inbuf`. The `inlen`
8324 argument specifies the length of the word in bytes, but it is not
8325 strictly necessary as the opcode assumes the word is terminated by
8326 a break character (whitespace or a self-inserting break
8328 - **Converts to Z-string:** Encodes the extracted word into a
8329 Z-string using the current character set and frequent words table.
8330 - **Stores the result:** The encoded Z-string is stored in the first
8331 three words of the `zword` table.
8335 - The `inbuf` argument is typically a pointer to the text buffer
8336 used by the `READ` or `LEX` opcodes.
8337 - The `zword` table must have at least three words of available
8338 space to store the Z-string.
8340 **Error Conditions:**
8344 - `inbuf` or `zword` is not a valid table pointer.
8345 - `inbeg` is outside the bounds of the `inbuf` table.
8346 - The `zword` table does not have enough space to store the
8352 read input_buffer, lexv
8353 zwstr input_buffer, 0, lexv[1].offset, word_buffer ; Converts the second word from the parsed input into a Z-string
8358 - Converting words from input buffers into Z-strings for further
8359 processing or comparison.
8360 - Implementing custom parsing or text manipulation routines.
8362 **Note:** The `ZWSTR` opcode is used to convert words from input
8363 buffers into the Z-string format used by the Z-machine. It is
8364 typically used in conjunction with the `READ` or `LEX` opcodes for
8365 processing player input.
8367 Chapter 3.2: Opcode Summary Table
8368 ---------------------------------
8370 --------------------------------------------------------------------------------------
8371 Opcode Name Operands Type Description
8372 -------- ------------- --------------- ------ ----------------------------------------
8373 1 EQUAL? arg1:any, 2OP Is arg1 equal to any one of arg2, arg3,
8374 arg2:any or arg4? Note that in the extended form,
8375 EQUAL? can take more than two operands.
8377 2 LESS? arg1:int, 2OP Is arg1 less than arg2?
8380 3 GRTR? arg1:int, 2OP Is arg1 greater than arg2?
8383 4 DLESS? var, int 2OP Decrements var and succeeds if new value
8386 5 IGRTR? var, int 2OP Increments var and succeeds if new value
8387 is greater than int.
8389 6 IN? child:obj, 2OP Is child contained in parent?
8392 7 BTST arg1:word, 2OP Are bits on in arg2 also on in arg1?
8395 8 BOR arg1:word, 2OP Bitwise logical OR.
8398 9 BAND arg1:word, 2OP Bitwise logical AND.
8401 10 FSET? obj, flag 2OP Is flag number set in obj?
8403 11 FSET obj, flag 2OP Sets flag in obj.
8405 12 FCLEAR obj, flag 2OP Clears flag in obj.
8407 13 SET var, any 2OP Sets variable to any.
8409 14 MOVE thing:obj, 2OP Puts thing into dest as the first
8412 15 GET table, item 2OP Returns item'th element of table
8415 16 GETB table, item 2OP Returns item'th element of table
8418 17 GETP obj, prop 2OP Returns prop property of obj.
8420 18 GETPT obj, prop 2OP Returns pointer to property table prop
8423 19 NEXTP obj, prop 2OP Returns number of the property following
8426 20 ADD arg1:int, 2OP Adds the integers.
8429 21 SUB arg1:int, 2OP Subtracts arg2 from arg1.
8432 22 MUL arg1:int, 2OP Multiplies the integers.
8435 23 DIV arg1:int, 2OP Divides arg1 by arg2, returning the
8436 arg2:int truncated quotient.
8438 24 MOD arg1:int, 2OP Divides arg1 by arg2, returning the
8441 25 CALL2 fcn, any 2OP Calls the function pointed to by fcn.
8443 26 ICALL2 routine:fcn, 2OP Calls the function pointed to by fcn (no
8444 arg1:any return value).
8446 27 COLOR fore:int, 2OP Sets foreground and background color.
8449 28 THROW any, frame 2OP Returns any from a frame (see CATCH).
8451 128 ZERO? arg:any 1OP Is arg equal to zero?
8453 129 NEXT? obj 1OP Returns the "next" slot of obj (fails if
8456 130 FIRST? obj 1OP Returns the "first" slot of obj (fails
8459 131 LOC obj 1OP Returns the "parent" of obj (zero if
8462 132 PTSIZE table 1OP Returns length of property table in
8465 133 INC var 1OP Increments the value of var by one.
8467 134 DEC var 1OP Decrements the value of var by one.
8469 135 PRINTB str 1OP Prints the string pointed to by str
8472 136 CALL1 fcn 1OP Calls the function pointed to by fcn.
8474 137 REMOVE obj 1OP Removes obj from the object tree.
8476 138 PRINTD obj 1OP Prints the short description of obj.
8478 139 RETURN any 1OP Returns from the most recently executed
8481 140 JUMP loc 1OP Unconditional relative branch.
8483 141 PRINT str 1OP Prints the string pointed to by str
8486 142 VALUE var 1OP Returns the value of var.
8488 143 ICALL1 routine:fcn 1OP Calls the function pointed to by fcn (no
8491 176 RTRUE 0OP Returns 1 (true).
8493 177 RFALSE 0OP Returns 0 (false).
8495 178 PRINTI (in-line 0OP Prints an immediate string.
8498 179 PRINTR (in-line 0OP Prints an immediate string and executes
8499 string) CRLF + RTRUE.
8501 180 NOOP 0OP No operation.
8503 183 RESTART 0OP Reinitializes the game.
8505 184 RSTACK 0OP Returns from a call and takes value from
8508 185 CATCH 0OP Returns a pointer to the current call
8511 186 QUIT 0OP Terminates the game.
8513 187 CRLF 0OP Prints an end-of-line sequence.
8517 189 VERIFY 0OP Verifies the game program on disk.
8519 190 EXTOP opcode:int 0OP Signals the next opcode is an extended
8522 191 ORIGINAL? 0OP Returns non-false if the game disk is
8525 193 EQUAL? arg1:any, EXT Is arg1 equal to any of the other
8526 arg2:any, ... arguments?
8528 224 CALL fcn, any1, EXT Calls the function pointed to by fcn.
8531 225 PUT table, item, EXT Sets the word pointed to in table to
8534 226 PUTB table, item, EXT Sets the byte pointed to in table to the
8535 any low byte of any.
8537 227 PUTP obj, prop, any EXT Changes the value of obj's property prop
8540 228 READ inbuf:tbl, EXT Reads a line of input and parses it.
8545 229 PRINTC int EXT Prints the character whose ASCII value
8548 230 PRINTN int EXT Prints int as a signed number.
8550 231 RANDOM arg:int EXT Returns a random value between 1 and
8553 232 PUSH value EXT Pushes value onto the game stack.
8555 233 POP stack EXT Pops a value from the stack.
8557 234 SPLIT height:int EXT Splits the screen vertically between
8560 235 SCREEN window:int EXT Selects the specified window for output.
8562 236 XCALL fcn, any1, ..., EXT Calls the function pointed to by fcn (up
8565 237 CLEAR window:int EXT Clears the specified window.
8567 238 ERASE int EXT Erases a portion of the current line.
8569 239 CURSET y:int, x:int, EXT Sets the cursor position in the
8570 window specified window.
8572 240 CURGET output:tbl EXT Returns information about the current
8575 241 HLIGHT int EXT Sets the display highlighting mode.
8577 242 BUFOUT int EXT Controls output buffering.
8579 243 DIROUT device:int, EXT Selects or deselects a virtual output
8583 244 DIRIN device:int, EXT Selects or deselects a virtual input
8587 245 SOUND id:int, op:int, EXT Produces a sound.
8591 246 INPUT dev:int, EXT Returns a single byte from the specified
8595 247 INTBL? item, tbl, EXT Searches for a record in a table.
8599 248 BCOM arg:word 1OP Performs a bitwise logical NOT
8600 (complement) on the word.
8602 249 ICALL routine:fcn, EXT Calls the function pointed to by fcn (no
8603 arg1:any, return value).
8607 250 IXCALL routine:fcn, EXT Calls the function pointed to by fcn
8608 arg1,... (variable args, no return value).
8610 251 LEX inbuf:tbl, EXT Tokenizes and looks up an input buffer's
8615 252 ZWSTR inbuf:tbl, EXT Converts a word to a Z-string.
8620 253 COPYT source:tbl, EXT Copies bytes from source to dest.
8624 254 PRINTT bytes:tbl, EXT Prints a block of text from a table.
8629 255 ASSIGNED? opt:var EXT Checks if an optional argument was
8632 256 SAVE start:tbl, EXT Saves a section of the game state.
8636 257 RESTORE start:tbl, EXT Restores a section of the game state.
8640 258 SHIFT int, n EXT Performs a logical shift on int.
8642 259 ASHIFT int, n EXT Performs an arithmetic shift on int.
8644 260 FONT font:int, EXT Selects a font for the specified window.
8647 261 DISPLAY picture:int, EXT Displays a picture at the specified
8648 y:int, x:int location.
8650 262 PICINF picture:int, EXT Returns information about a picture.
8653 263 DCLEAR picture:int, EXT Clears the area occupied by a picture.
8656 264 MARGIN left:int, EXT Sets the left and right margins for a
8660 265 ISAVE EXT Saves the game state to a reserved area
8663 266 IRESTORE EXT Restores the game state from the
8664 reserved area in RAM.
8666 272 WINPOS window:int, y, EXT Sets the location of the top left corner
8669 273 WINSIZE window, y, x EXT Sets the size of a window.
8671 274 WINATTR window, bits, EXT Sets characteristics of a window.
8674 275 WINGET window, offset EXT Returns the value of a window property.
8676 276 SCROLL window, lines EXT Scrolls the specified window up or down.
8678 277 FSTACK n, stack EXT Flushes n elements from the specified
8681 278 MOUSE-INFO table EXT Returns information about the mouse
8684 279 MOUSE-LIMIT window EXT Restricts the mouse to a specific
8687 280 XPUSH value, stack EXT Pushes value onto the specified stack.
8689 281 WINPUT window, offset, EXT Sets the value of a window property.
8692 282 PRINTF tbl EXT Prints a formatted table.
8694 283 MENU id, tbl EXT Adds a menu to the menu bar.
8696 284 PICSET tbl EXT A table of picture numbers to pre-load
8697 or cache for faster display. Pictures not
8698 included in the most recent PICSET call are
8699 no longer considered "hot" and can be safely
8700 removed from the cache.
8701 --------------------------------------------------------------------------------------