--- /dev/null
+Copyright & Licensing
+---------------------
+
+Copyright (C) 2024 Jason Self <j@jxself.org>
+
+You can redistribute and/or modify this file under the terms of the
+GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this file. If not, see <https://www.gnu.org/licenses/>.
+
+Chapter 1.1: Overview of ZAP and its Purpose
+--------------------------------------------
+
+ZAP (Z-language Assembly Program) is a software tool used to translate
+assembly language code written for the Z-machine into a binary format
+that can be directly executed by a compatible Z-language Interpreter
+Program (ZIP).
+
+The Z-machine is a virtual machine specifically designed for running
+interactive fiction games, also known as text adventures. Infocom
+originally developed the Z-machine and its associated programming
+language, ZIL (Zork Implementation Language) but now these belong to
+the community.
+
+ZAP is the last stage of the toolchain, after the source code has been
+compiled into a a human-readable assembly language format. This
+assembly language is then processed by ZAP, which converts it into the
+binary format understood by the Z-machine.
+
+ZAP is a two-pass assembler, meaning it processes the input file
+twice. In the first pass, it analyzes the code, builds symbol tables,
+and calculates addresses. In the second pass, it generates the binary
+code and resolves any forward references to symbols.
+
+This specification document provides a detailed explanation of ZAP's
+functionality, including the supported assembly language syntax, data
+structures, algorithms, and error handling mechanisms. It serves as a
+guide for understanding and implementing ZAP.
+
+ZAP is an integral component of the development system for interactive
+fiction games. It bridges the gap between the high-level ZIL (Zork
+Implementation Language) and the low-level Z-code that runs on the
+Z-machine. Here's how ZAP fits into the overall development process:
+
+1. **Game Design and Implementation:** Game designers and programmers
+ use a high-level language (the Zork Implementation Language, or
+ ZIL) to define the game's world, objects, characters, and
+ interactions. ZIL provides a more abstract and convenient way to
+ express the game's logic compared to directly writing Z-code
+ instructions.
+2. **ZIL Compilation:** The ZIL code is compiled into Z-code assembly
+ language. This assembly language represents the Z-code
+ instructions and data in a human-readable format.
+3. **ZAP Assembly:** ZAP takes the Z-code assembly language as input
+ and translates it into the binary format understood by the
+ Z-machine. This binary code is what ultimately gets executed by
+ the ZIP interpreter.
+
+Chapter 1.2: Goals and Design Principles of ZAP
+-----------------------------------------------
+
+ZAP was designed with several key goals and principles in mind:
+
+**Goals:**
+
+- **Provide a convenient and efficient way to write Z-code
+ programs:** ZAP's assembly language allows programmers to express
+ Z-code instructions and data in a more readable and structured
+ format compared to directly writing binary code.
+- **Generate optimized and efficient Z-code:** ZAP optimizes the
+ generated code for efficient execution on the Z-machine, ensuring
+ smooth gameplay and minimizing memory usage.
+- **Support debugging and troubleshooting:** ZAP can generate
+ optional listing files that provide insights into the generated
+ code, aiding in debugging and identifying issues.
+- **Maintain portability across different platforms:** ZAP itself is
+ designed to be portable and run on various machines, allowing for
+ cross-platform development.
+
+**Design Principles:**
+
+- **Simplicity and clarity:** ZAP's assembly language syntax is
+ designed to be straightforward and easy to understand, minimizing
+ the learning curve for programmers.
+- **Efficiency:** ZAP optimizes the generated code for efficient
+ execution on the Z-machine, taking advantage of the architecture's
+ features.
+- **Flexibility:** ZAP provides various directives and options to
+ give programmers control over the assembly process and allow for
+ customization.
+- **Error detection and reporting:** ZAP incorporates robust error
+ detection mechanisms and provides informative error messages to
+ help programmers identify and fix issues.
+- **Modularity:** ZAP is organized into well-defined modules, each
+ responsible for specific tasks, promoting code maintainability and
+ extensibility.
+
+These goals and design principles have guided the development of ZAP
+and continue to be relevant in understanding its functionality and
+behavior. By adhering to these principles, ZAP provides a powerful and
+efficient tool for assembling Z-code programs for interactive fiction
+games.
+
+Chapter 1.3: Target Audience for the Specification
+--------------------------------------------------
+
+This specification document is primarily intended for the following
+audiences:
+
+- **Z-machine enthusiasts and researchers:** The specification
+ offers detailed insights into the Z-code assembly language, ZAP's
+ internal workings, and the overall structure of Z-machine
+ programs. This information can be valuable for individuals
+ interested in understanding the Z-machine architecture and its
+ associated tools.
+- **Interactive fiction developers:** Understanding ZAP's
+ functionality and the Z-code it generates can be beneficial for
+ game designers and programmers.
+
+The document assumes a basic understanding of assembly language
+concepts and the Z-machine architecture. However, it provides
+sufficient detail and explanations to be accessible to individuals
+with a general interest in interactive fiction and the technical
+aspects of the Z-machine.
+
+By catering to these different audiences, the specification aims to
+contribute to the understanding of the Z-machine, and support the
+continued development of interactive fiction games.
+
+Chapter 2.1: Character Set and Lexical Elements
+-----------------------------------------------
+
+The Z-code assembly language used by ZAP consists of a defined
+character set and specific lexical elements that form the building
+blocks of instructions and directives.
+
+**Character Set:**
+
+The following characters are allowed in a ZAP program:
+
+- **Letters:** A-Z (case-insensitive)
+- **Digits:** 0-9
+- **Special characters:** , ? \# . - \_ ' \" / Â : ( )
+- **Whitespace:** Space and tab characters are ignored except as
+ operand prefixes.
+- **Line endings:** Carriage return (`\r`), line feed (``), and form
+ feed (`\f`) characters are ignored.
+
+**Lexical Elements:**
+
+ZAP recognizes the following lexical elements:
+
+- **Symbols:** Used to represent values and labels. They consist of
+ letters, digits, and some special characters. By convention,
+ pseudo-ops (assembler directives) begin with a period (`.`).
+- **Numbers:** Represent integer values.
+- **Strings:** Enclosed in double quotes (`"`). Double quotes within
+ strings are escaped by using two consecutive double quotes.
+- **Operators:** Predefined symbols representing Z-machine
+ instructions.
+- **Pseudo-ops (directives):** Instructions to the assembler, such
+ as `.word`, `.str`, and `.funct`.
+- **Operand prefixes:** Special characters used to indicate the type
+ of operand following them (e.g., `,` for general operand, `>` for
+ return value).
+- **Comments:** Begin with a semicolon (`;`) and extend to the end
+ of the line.
+
+These lexical elements are combined to form valid assembly language
+statements that are processed by ZAP.
+
+**Note:** This chapter provides a basic overview of the character set
+and lexical elements. More detailed information about specific
+elements and their usage will be presented in subsequent chapters.
+
+Chapter 2.2: Symbol Definition and Types (Global, Local, Constants)
+-------------------------------------------------------------------
+
+Symbols in ZAP are used to represent various types of values and
+labels within the program. They play a crucial role in code
+organization, readability, and address resolution.
+
+**Symbol Definition:**
+
+A symbol is defined by assigning it a value using either:
+
+- **Equate statement:** `symbol = value`
+- **Pseudo-op:** `.equal symbol, value`
+- **Label definition:** `symbol::` or `symbol:`
+
+**Symbol Types:**
+
+ZAP distinguishes between three main types of symbols:
+
+- **Global symbols:** Defined outside of any function and accessible
+ throughout the entire program. They can represent global
+ variables, function names, table names, and string names.
+- **Local symbols:** Defined within a function using the `.funct`
+ directive and accessible only within that function. They represent
+ local variables and labels used for branching within the function.
+- **Constants:** Represent fixed values that cannot be changed. They
+ are defined using equate statements or specific pseudo-ops like
+ `.seq`.
+
+**Naming Conventions:**
+
+The following naming conventions exist:
+
+- **Pseudo-ops:** Begin with a period (`.`).
+- **Global labels:** End with two colons (`::`).
+- **Local labels:** End with one colon (`:`)
+
+**Symbol Redefinition:**
+
+- **Global and local symbols:** Cannot be redefined within their
+ scope. Attempting to do so will result in an error.
+- **Constants:** Can be redefined at any point in the program.
+
+**Predefined Symbols:**
+
+ZAP includes several predefined global symbols:
+
+- **Operators:** Represent Z-machine instructions (e.g., `ADD`,
+ `SUB`, `PRINT`).
+- **Pseudo-ops:** Represent assembler directives (e.g., `.word`,
+ `.str`, `.funct`).
+- **Special symbols:** Represent specific data structures or
+ locations within the program (e.g., `VOCAB`, `OBJECT`, `STACK`).
+
+Understanding symbol definition and types is essential for writing
+well-structured and organized Z-code assembly programs. By following
+the conventions and understanding the scope of different symbol types,
+programmers can ensure proper address resolution and code
+functionality.
+
+Chapter 2.3: Statement Syntax and Structure
+-------------------------------------------
+
+ZAP assembly language statements are line-oriented, meaning each
+statement occupies a single line in the source file. Each statement
+consists of four optional fields:
+
+**Statement Structure:**
+
+ [label] [operator] [operands] [comment]
+
+**Field Descriptions:**
+
+- **Label:** A symbol followed by one or two colons, depending on
+ whether it's a local or global label.
+- **Operator:** A predefined symbol representing either an operator
+ (Z-machine instruction) or a pseudo-op (assembler directive).
+- **Operands:** A space or tab-separated list of operands, each
+ optionally preceded by an operand prefix character.
+- **Comment:** Begins with a semicolon (`;`) and extends to the end
+ of the line.
+
+**Examples:**
+
+``` {.assembly}
+START:: .funct main ; Define the main function
+ add 1, 2 ; Add two constants
+ print "Hello" ; Print a string
+ jump END ; Jump to the END label
+END:
+```
+
+**Operand Prefixes:**
+
+Operand prefixes are special characters used to indicate the type of
+operand following them and provide additional information:
+
+- **`,` (comma):** General operand.
+- **`>` (greater than):** Return value operand. Specifies where the
+ return value of an instruction should be stored
+- **`\` (backslash):** Branch on failure operand. Indicates the
+ branch target if the predicate fails
+- **`/` (forward slash):** Branch on success operand. Indicates the
+ branch target if the predicate succeeds.
+- **`=` (equal sign):** Value operand for assignments. Used for
+ assigning values to symbols
+- **`+` (plus sign):** Addend operand for constant addition.
+
+**Line Continuation:**
+
+Operands can be continued to the next line by placing the operand
+prefix character on one line and the corresponding operand on the next
+line.
+
+**Note:** This chapter provides a general overview of statement syntax
+and structure. More detailed information about specific operators,
+pseudo-ops, and operands will be presented in subsequent chapters.
+
+Chapter 2.4: Operands and Addressing Modes
+------------------------------------------
+
+Operands in ZAP assembly language specify the data or values that
+instructions operate on. ZAP supports three main types of operands:
+
+**Operand Types:**
+
+- **Immediate:** A constant value directly encoded within the
+ instruction. It can be either a short (one-byte) or long
+ (two-byte) constant.
+- **Variable:** A reference to a variable stored in memory. The
+ operand specifies the variable number, which is interpreted
+ differently depending on the context.
+- **Other:** Represents special values like labels, function
+ pointers, or string pointers.
+
+**Addressing Modes:**
+
+ZAP uses different addressing modes to access and interpret operands:
+
+- **Direct addressing:** The operand directly specifies the value or
+ memory address of the data. This is used for immediate operands
+ and some other types.
+- **Indirect addressing:** The operand specifies the number of a
+ variable, which is then used to access the actual data in memory.
+ This is used for variable operands.
+
+**Variable Addressing:**
+
+Variable operands are interpreted as follows:
+
+- **0:** Refers to the top of the game stack.
+- **1-15:** Refer to local variables within the current function.
+- **16-255:** Refer to global variables.
+
+**Examples:**
+
+``` {.assembly}
+add 1, 2 ; Add two immediate operands
+set var1, 5 ; Set the variable var1 to 5
+jump START ; Jump to the label START
+get table, 3 ; Get the 3rd element from the table
+```
+
+Understanding operand types and addressing modes is crucial for
+writing correct and efficient Z-code assembly programs. By using the
+appropriate operand prefixes and addressing modes, programmers can
+ensure that instructions operate on the intended data and achieve the
+desired results.
+
+Chapter 2.5: Instruction Formats (2OP, 1OP, 0OP, EXT)
+-----------------------------------------------------
+
+ZAP instructions are encoded in different formats depending on the
+number and type of operands they require. This allows for efficient
+use of memory while providing flexibility in instruction design.
+
+**Instruction Formats:**
+
+- **2OP (Two-operand):** This format is used for instructions with
+ two operands, typically immediate values or variables. It is the
+ most compact format but has limitations on the types of operands
+ it can handle.
+- **1OP (One-operand):** This format is used for instructions with a
+ single operand, which can be an immediate value, variable, or
+ other type.
+- **0OP (Zero-operand):** This format is used for instructions that
+ do not require any explicit operands.
+- **EXT (Extended):** This format is used for instructions that
+ cannot be represented in the other formats due to:
+ - Having more than two operands.
+ - Requiring long immediate operands.
+ - Being rarely used instructions.
+
+**Encoding Details:**
+
+The specific encoding of each format varies, but generally:
+
+- **2OP:** The opcode byte contains both the operator and mode bits,
+ specifying the instruction and the types of its two operands.
+- **1OP:** The opcode byte contains the operator and mode bits for
+ the single operand.
+- **0OP:** The opcode byte solely represents the instruction, as
+ there are no operands.
+- **EXT:** The opcode byte identifies the instruction, and a
+ separate byte (or two bytes for some instructions) follows the
+ opcode to specify the operand types and modes.
+
+**Extended Opcode Prefix (EXTOP):**
+
+ZAP provides an additional 256 extended opcodes through the `EXTOP`
+instruction. When `EXTOP` is encountered, the next byte is interpreted
+as an opcode with its value increased by 256. This allows for a larger
+instruction set while maintaining backward compatibility with older
+ZIP interpreters.
+
+**Choosing the Right Format:**
+
+The assembler automatically chooses the most efficient format for each
+instruction based on the number and types of operands. Programmers do
+not need to explicitly specify the format.
+
+The assembler determines the most efficient instruction format by
+following a set of rules based on the number and types of operands
+involved. Here's a simplified explanation of the process:
+
+1. **Count the number of operands:**
+ - If there are **zero operands**, the **0OP format** is used.
+ - If there is **one operand**, the **1OP format** is used,
+ unless the operand is a long immediate value, in which case
+ the **EXT format** is necessary.
+ - If there are **two operands**:
+ - If both operands are either immediate values or variables,
+ and neither is a long immediate, the **2OP format** is
+ used.
+ - Otherwise, the **EXT format** is used.
+2. **Check for special cases:**
+ - Some instructions, like `EQUAL?`, can take a variable number
+ of operands. In such cases, the **EXT format** is used
+ regardless of the actual number of operands provided.
+ - Certain rarely used instructions might also be encoded in the
+ **EXT format** even if they could fit in other formats. This
+ is done to optimize the overall instruction set usage.
+
+By following these rules, the assembler ensures that each instruction
+is encoded in the most compact and efficient format possible, reducing
+the overall size of the Z-code program and improving its execution
+speed.
+
+**Example:**
+
+- The instruction `add 1, 2` has two immediate operands, so it can
+ be encoded in the **2OP format**.
+- The instruction `set var1, 5` has one variable operand and one
+ immediate operand, so it can also be encoded in the **2OP
+ format**.
+- The instruction `print "Hello"` has one string operand, which is
+ considered an "other" type. Therefore, it needs the **EXT
+ format**.
+- The instruction `jump START` has one label operand, also requiring
+ the **EXT format**.
+
+Understanding instruction formats is helpful for comprehending the
+structure of Z-code programs and how instructions are encoded in
+memory. However, for most programming tasks, it is sufficient to focus
+on the instruction names and operands, as ZAP handles the format
+selection automatically.
+
+Chapter 2.6: Instruction Values and Predicates
+----------------------------------------------
+
+Some ZAP instructions return values or act as predicates, influencing
+the flow of control in the program.
+
+**Instruction Values:**
+
+Certain instructions, such as arithmetic and logical operations,
+produce a value as a result of their execution. This value can be:
+
+- **Pushed onto the game stack:** This is the default behavior if no
+ explicit destination is specified.
+- **Stored in a variable:** The instruction can be followed by an
+ operand prefix `>` and a variable number to indicate where the
+ value should be stored.
+
+**Example:**
+
+``` {.assembly}
+add 1, 2 ; Value is pushed onto the stack
+add 1, 2 > var1 ; Value is stored in the variable var1
+```
+
+**Predicates:**
+
+Predicate instructions evaluate a condition and implicitly perform a
+conditional branch based on the result. They are typically used for
+decision-making and control flow within the program.
+
+**Branch Polarity and Offset:**
+
+Predicate instructions are followed by one or two bytes that specify:
+
+- **Branch polarity:** Whether the branch occurs on success
+ (predicate evaluates to true) or failure (predicate evaluates to
+ false). This is indicated by the high-order bit of the first byte.
+- **Branch offset:** The distance to jump if the branch condition is
+ met. This can be either a short (6-bit) or long (14-bit) offset.
+
+**Branch Targets:**
+
+The branch offset determines the target of the conditional jump:
+
+- **Offset 0:** Executes an `RFALSE` instruction, returning false
+ from the current function.
+- **Offset 1:** Executes an `RTRUE` instruction, returning true from
+ the current function.
+- **Other offsets:** Jumps to the instruction located at the current
+ address plus the offset minus two.
+
+**Example:**
+
+``` {.assembly}
+less? var1, 5 / label1 ; Branch to label1 if var1 is less than 5
+```
+
+Understanding instruction values and predicates is essential for
+controlling the flow of execution in Z-code programs. By using
+predicates and specifying appropriate branch targets, programmers can
+implement conditional logic and decision-making within their games.
+
+Chapter 3.1: Detailed Description of Each Opcode and Directive
+--------------------------------------------------------------
+
+This chapter provides a comprehensive description of each opcode and
+directive supported by ZAP. For each element, the following
+information is provided:
+
+- **Name:** The name of the opcode or directive.
+- **Syntax:** The format of the instruction or directive, including
+ operand types and prefixes.
+- **Functionality:** A detailed explanation of what the opcode or
+ directive does.
+- **Special cases:** Any special conditions or behaviors to be aware
+ of.
+- **Error conditions:** Potential errors that might occur during
+ assembly or execution.
+- **Examples:** Illustrative examples of how the opcode or directive
+ can be used.
+
+This chapter serves as a reference for understanding the functionality
+and usage of each opcode and directive available in ZAP. By consulting
+this information, programmers can write accurate and efficient Z-code
+assembly programs.
+
+### .ALIGN
+
+**.ALIGN** is a directive that instructs the assembler to align the
+next generated code or data to a specified byte boundary. This can be
+useful for ensuring proper memory access and improving performance on
+certain architectures.
+
+**Syntax:**
+
+``` {.assembly}
+.align value
+```
+
+**Functionality:**
+
+The `.align` directive pads the object file with zero bytes until the
+current address is a multiple of the specified `value`. This
+effectively aligns the next instruction or data element to the
+specified boundary.
+
+**Special Cases:**
+
+- If `value` is 1, the directive has no effect, as all data is
+ already aligned to a byte boundary.
+- If `value` is not a power of two, the assembler may align to the
+ next higher power of two.
+
+**Error Conditions:**
+
+An error occurs if `value` is zero or negative.
+
+**Examples:**
+
+``` {.assembly}
+.align 4
+.word data1 ; data1 will be aligned to a 4-byte boundary
+
+.align 8
+.funct func1 ; func1 will be aligned to an 8-byte boundary
+```
+
+**Use Cases:**
+
+- Aligning data structures to their natural word or longword
+ boundaries can improve memory access efficiency.
+- Some Z-machine instructions might have specific alignment
+ requirements for optimal performance.
+- Aligning functions can be helpful for debugging and code analysis.
+
+**Note:** While `.align` can be used to enforce specific alignment, it
+is generally recommended to let the assembler choose the appropriate
+alignment for optimal code generation.
+
+### .BYTE
+
+The `.BYTE` directive instructs the assembler to generate one or more
+byte values in the object file. It is used to define raw byte data or
+initialize specific memory locations with byte values.
+
+**Syntax:**
+
+``` {.assembly}
+.byte value1 [, value2 ...]
+```
+
+**Functionality:**
+
+The `.byte` directive generates the specified byte values sequentially
+in the object file. Each value must be a constant expression that
+evaluates to a number within the range of 0 to 255.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if a value exceeds the byte range (0-255).
+
+**Examples:**
+
+``` {.assembly}
+.byte 10, 20, 30 ; Generates three bytes with values 10, 20, and 30
+.byte 'A' ; Generates a byte with the ASCII value of 'A' (65)
+```
+
+**Use Cases:**
+
+- Defining raw byte data for specific purposes, such as flags or
+ status codes.
+- Initializing memory locations with specific byte values.
+- Embedding special characters or control codes within the object
+ file.
+
+**Note:** While `.byte` allows for precise control over byte values,
+it is generally recommended to use higher-level directives like
+`.word` or `.str` whenever possible, as they provide better
+readability and maintainability.
+
+### .CHRSET
+
+The `.CHRSET` directive allows the programmer to redefine the
+character sets used for encoding strings in the Z-machine. This can be
+useful for optimizing string storage and handling characters specific
+to certain languages or display systems.
+
+**Syntax:**
+
+``` {.assembly}
+.chrset id, char1, char2, ..., charN
+```
+
+**Functionality:**
+
+The `.chrset` directive redefines one of the three character sets used
+for string encoding:
+
+- **`id`:** Specifies the character set to modify (0, 1, or 2).
+- **`char1, char2, ..., charN`:** A list of characters (specified as
+ their ASCII values) that will be assigned to the character set.
+
+The number of characters provided depends on the `id`:
+
+- **Set 0 and 1:** 26 characters are expected.
+- **Set 2:** 24 characters are expected (excluding ASCII escape and
+ newline characters).
+
+**Special Cases:**
+
+- Character set 2 has two special characters that cannot be
+ redefined:
+ - **6:** Represents the ASCII escape sequence.
+ - **7:** Represents the newline character.
+
+**Error Conditions:**
+
+- An error occurs if `id` is not 0, 1, or 2.
+- An error occurs if the number of characters provided does not
+ match the expected count for the specified `id`.
+
+**Examples:**
+
+``` {.assembly}
+.chrset 0, 'a', 'b', ..., 'z' ; Redefines character set 0 with lowercase letters
+.chrset 1, 'A', 'B', ..., 'Z' ; Redefines character set 1 with uppercase letters
+```
+
+**Use Cases:**
+
+- Optimizing string storage by assigning frequently used characters
+ to the compact character sets.
+- Handling characters specific to certain languages or display
+ systems that are not included in the default character sets.
+
+**Note:** Redefining character sets can have significant implications
+for string encoding and decoding. It is generally recommended to use
+the default character sets unless there is a specific need for
+optimization or handling special characters.
+
+### .DEFSEG
+
+The `.DEFSEG` directive is used to define a segment and specify its
+relationships with other segments. Segments are logical divisions of
+the Z-code program that can be used to optimize disk usage and loading
+times in multi-disk games.
+
+**Syntax:**
+
+``` {.assembly}
+.defseg name, seg1, seg2, seg3
+```
+
+**Functionality:**
+
+The `.DEFSEG` directive performs the following:
+
+- **Defines a segment:** Creates a new segment with the specified
+ `name`.
+- **Specifies adjacent segments:** Declares that the segment is
+ adjacent to the segments `seg1`, `seg2`, and `seg3`. This
+ information is used by the `zsplit` tool to determine how to
+ distribute segments across multiple disks.
+
+**Special Cases:**
+
+- If the segment `name` is "0", it refers to the default segment
+ that contains all preloaded data and code.
+- If a segment name is not defined with `.DEFSEG`, it is implicitly
+ considered adjacent to segment 0.
+
+**Error Conditions:**
+
+An error occurs if a segment name is not a valid symbol.
+
+**Examples:**
+
+``` {.assembly}
+.defseg "ROOM", "HALL", "GARDEN" ; Defines the "ROOM" segment and declares it adjacent to "HALL" and "GARDEN" segments
+.defseg "STARTUP", "MAIN" ; Defines the "STARTUP" segment and declares it adjacent to the "MAIN" segment
+```
+
+**Use Cases:**
+
+- Organizing the game's code and data into logical segments for
+ efficient disk usage and loading.
+- Informing the `zsplit` tool about segment relationships to
+ optimize the distribution of segments across multiple disks.
+
+**Note:** Segment definitions and adjacency information are primarily
+used by the `zsplit` tool and do not directly affect the execution of
+the Z-code program.
+
+### .END
+
+The `.END` directive marks the end of the assembly language program.
+It instructs the assembler to stop processing input and perform final
+operations.
+
+**Syntax:**
+
+``` {.assembly}
+.end
+```
+
+**Functionality:**
+
+When the `.END` directive is encountered, the assembler performs the
+following:
+
+- **Stops processing input:** Any code or directives following
+ `.END` are ignored.
+- **Resolves forward references:** Performs fixup operations to
+ resolve any outstanding forward references to symbols.
+- **Generates final output:** Writes the assembled Z-code program to
+ the object file and generates any optional listing or error files.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error might occur during fixup if undefined symbols are
+encountered.
+
+**Examples:**
+
+``` {.assembly}
+; ... game code ...
+
+.end
+```
+
+**Use Cases:**
+
+The `.END` directive is mandatory and must be placed at the end of
+every Z-code assembly program to signal the completion of the assembly
+process.
+
+**Note:** It is essential to ensure that all necessary code and data
+have been defined before the `.END` directive, as anything following
+it will not be processed by the assembler.
+
+### .ENDI
+
+The `.ENDI` directive marks the end of an `.INSERT` file. It instructs
+the assembler to return to the previous input source and continue
+processing.
+
+**Syntax:**
+
+``` {.assembly}
+.endi
+```
+
+**Functionality:**
+
+The `.ENDI` directive is used in conjunction with the `.INSERT`
+directive, which allows the contents of another file to be inserted
+and assembled at a specific point in the main source file. When
+`.ENDI` is encountered, the assembler:
+
+- **Stops processing the inserted file:** Any code or directives
+ following `.ENDI` in the inserted file are ignored.
+- **Returns to the previous input source:** The assembler resumes
+ processing the main source file from the point where the `.INSERT`
+ directive was encountered.
+
+**Special Cases:**
+
+- A `.ENDI` directive without a preceding `.INSERT` directive is an
+ error.
+
+**Error Conditions:**
+
+An error occurs if `.ENDI` is found outside of an inserted file.
+
+**Examples:**
+
+``` {.assembly}
+; ... main source file ...
+
+.insert "header.zap"
+
+; ... contents of header.zap ...
+
+.endi
+
+; ... main source file continues ...
+```
+
+**Use Cases:**
+
+- Modularizing code by separating commonly used routines or data
+ into separate files that can be inserted into multiple programs.
+- Including header files that define constants, macros, or other
+ elements.
+
+**Note:** The `.INSERT` and `.ENDI` directives provide a mechanism for
+code inclusion and modularity, but their usage should be carefully
+considered to avoid potential complexity and maintainability issues.
+
+### .ENDSEG
+
+The `.ENDSEG` directive closes all currently open segments. Segments
+are logical divisions of the Z-code program used to optimize disk
+usage and loading times in multi-disk games.
+
+**Syntax:**
+
+``` {.assembly}
+.endseg
+```
+
+**Functionality:**
+
+The `.ENDSEG` directive closes any segments that were previously
+opened with the `.SEGMENT` directive. This indicates to the assembler
+that the code and data belonging to those segments have been defined.
+
+**Special Cases:**
+
+- If no segments are currently open, the `.ENDSEG` directive has no
+ effect.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+.segment "ROOM"
+
+; ... code and data for the ROOM segment ...
+
+.endseg
+```
+
+**Use Cases:**
+
+- Ensuring that all segments are properly closed before the end of
+ the assembly process.
+- Organizing code and data into logical segments for efficient disk
+ usage and loading.
+
+**Note:** Segment definitions and closures are primarily used by the
+`zsplit` tool and do not directly affect the execution of the Z-code
+program.
+
+### .ENDT
+
+The `.ENDT` directive marks the end of a table definition. Tables are
+logical structures used to organize data in Z-code programs.
+
+**Syntax:**
+
+``` {.assembly}
+.endt
+```
+
+**Functionality:**
+
+The `.ENDT` directive must be used to terminate a table that was
+previously declared with the `.TABLE` directive. It performs the
+following:
+
+- **Checks table size:** If a size was specified in the `.TABLE`
+ directive, the assembler verifies that the actual table size does
+ not exceed the declared size.
+- **Finalizes table data:** The assembler performs any necessary
+ operations to finalize the table data, such as padding or
+ alignment.
+
+**Special Cases:**
+
+- A `.ENDT` directive without a preceding `.TABLE` directive is an
+ error.
+
+**Error Conditions:**
+
+- An error occurs if the actual table size exceeds the declared size
+ (if specified in `.TABLE`).
+
+**Examples:**
+
+``` {.assembly}
+.table 10
+.word data1, data2, data3
+.endt
+```
+
+**Use Cases:**
+
+- Defining tables of data with a specific size and ensuring that the
+ size is not exceeded.
+- Organizing data into logical structures for easier access and
+ manipulation.
+
+**Note:** The `.TABLE` and `.ENDT` directives provide a way to define
+and manage tables in Z-code programs, but their usage should be
+consistent and well-structured to avoid potential errors and
+maintainability issues.
+
+### .FALSE
+
+The `.FALSE` directive generates a word (two-byte) value of 0 in the
+object file. It is used to represent the boolean value `false` or to
+initialize memory locations with a zero value.
+
+**Syntax:**
+
+``` {.assembly}
+.false
+```
+
+**Functionality:**
+
+The `.false` directive simply generates a word with the value 0 at the
+current address in the object file.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+.false ; Generates a word with value 0
+set flag1, .false ; Sets the flag variable `flag1` to false
+```
+
+**Use Cases:**
+
+- Representing the boolean value `false` in conditional statements
+ or data structures.
+- Initializing variables or memory locations with a zero value.
+
+**Note:** The `.false` directive is equivalent to using `.word 0`.
+However, `.false` provides better readability and clarity when
+representing boolean values.
+
+### .FSTR
+
+The `.FSTR` directive defines a string as a "frequent string" and adds
+it to the frequent words table. Frequent strings are short, commonly
+used substrings that can be referenced efficiently within other
+strings, reducing overall memory usage.
+
+**Syntax:**
+
+``` {.assembly}
+.fstr name, string
+```
+
+**Functionality:**
+
+The `.fstr` directive performs the following:
+
+- **Defines a symbol:** Creates a global symbol with the specified
+ `name`. The value of the symbol is the address of the string
+ divided by 2 (since strings are stored as words).
+- **Outputs the string:** Generates the string in the object file,
+ aligning it to a word boundary.
+- **Adds to frequent words table:** Adds the string to the frequent
+ words table, which is used by the Z-machine to efficiently
+ reference frequently used substrings within other strings.
+
+**Special Cases:**
+
+- Frequent strings cannot contain other frequent strings within
+ them.
+- The frequent words table has a limited size (96 entries). If this
+ limit is exceeded, the assembler will issue an error.
+
+**Error Conditions:**
+
+- An error occurs if `name` is not a valid symbol.
+- An error occurs if the frequent words table is full.
+
+**Examples:**
+
+``` {.assembly}
+.fstr "the", "the " ; Defines the frequent string "the"
+.fstr "and", "and " ; Defines the frequent string "and"
+```
+
+**Use Cases:**
+
+- Optimizing string storage by defining frequently used words or
+ phrases as frequent strings.
+- Reducing the overall size of the Z-code program by efficiently
+ referencing common substrings.
+
+**Note:** The use of frequent strings can improve memory efficiency,
+but it is important to choose appropriate strings and avoid exceeding
+the table size limit.
+
+### .FUNCT
+
+The `.FUNCT` directive defines a function and begins a new local
+symbol block. Functions are subroutines that can be called and return
+values, allowing for modular and reusable code.
+
+**Syntax:**
+
+``` {.assembly}
+.funct name [, arg1 [: type] [, arg2 [: type] ...]]
+```
+
+**Functionality:**
+
+The `.funct` directive performs the following:
+
+- **Defines a function:** Creates a new function with the specified
+ `name`. The function name becomes a global symbol.
+- **Starts a new local symbol block:** Any symbols defined after
+ `.funct` are considered local to the function and are not
+ accessible outside of it.
+- **Defines local variables:** The optional `arg1`, `arg2`, etc.,
+ specify local variables for the function. Each variable can
+ optionally have a type specified after a colon (`:`) to indicate
+ its data type.
+- **Aligns function:** Aligns the function to a quad-byte boundary
+ for efficient execution.
+
+**Special Cases:**
+
+- If no arguments are provided, the function has no local variables.
+- If a type is not specified for a local variable, it is assumed to
+ be of type `ANY`.
+
+**Error Conditions:**
+
+- An error occurs if `name` is not a valid symbol.
+- An error occurs if the function is defined within another function
+ (nested functions are not supported).
+
+**Examples:**
+
+``` {.assembly}
+.funct main
+; ... code for the main function ...
+
+.funct add, num1: int, num2: int > result: int
+; ... code for the add function ...
+```
+
+**Use Cases:**
+
+- Defining functions to modularize code and promote reusability.
+- Creating subroutines to perform specific tasks within the program.
+- Utilizing local variables to manage data within functions.
+
+**Note:** The `.funct` directive is essential for defining functions
+in Z-code assembly programs. Proper function definition and usage are
+crucial for code organization and maintainability.
+
+### .GSTR
+
+The `.GSTR` directive defines a global string and stores it in the
+string area of the Z-code program. Global strings are accessible from
+anywhere in the program and are typically used for longer text
+passages or messages.
+
+**Syntax:**
+
+``` {.assembly}
+.gstr name, string
+```
+
+**Functionality:**
+
+The `.gstr` directive performs the following:
+
+- **Defines a symbol:** Creates a global symbol with the specified
+ `name`. The value of the symbol is the address of the string in
+ the string area, adjusted for the string offset (`SOFF`).
+- **Outputs the string:** Generates the string in the object file,
+ aligning it to a quad-byte boundary.
+- **Updates string offset:** If necessary, updates the `SOFF` value
+ to reflect the new string's location.
+
+**Special Cases:**
+
+- The string area is located in a separate section of the Z-code
+ program and is accessed using the `SOFF` value.
+- Strings are encoded in a special 5-bit byte format for efficient
+ storage.
+
+**Error Conditions:**
+
+- An error occurs if `name` is not a valid symbol.
+
+**Examples:**
+
+``` {.assembly}
+.gstr "intro", "Welcome to the game!"
+print intro ; Prints the "intro" string
+```
+
+**Use Cases:**
+
+- Defining long text passages or messages that need to be accessed
+ from various parts of the program.
+- Storing strings that are too large to be defined as immediate
+ operands within instructions.
+
+**Note:** The `.gstr` directive is used to define global strings,
+while the `.str` directive is used for defining strings within tables
+or as immediate operands.
+
+### .GVAR
+
+The `.GVAR` directive defines a global variable and assigns it a
+default value. Global variables are accessible from anywhere in the
+program and are typically used to store persistent data or game state.
+
+**Syntax:**
+
+``` {.assembly}
+.gvar name [= value]
+```
+
+**Functionality:**
+
+The `.gvar` directive performs the following:
+
+- **Defines a symbol:** Creates a global symbol with the specified
+ `name`. The value of the symbol is the variable number, which is
+ used to access the variable in the global table.
+- **Assigns a default value:** If `value` is provided, it is
+ assigned as the initial value of the global variable. Otherwise,
+ the default value is 0.
+- **Outputs the value:** Generates the default value in the object
+ file, placing it in the global table.
+
+**Special Cases:**
+
+- Global variables are stored in a dedicated table pointed to by the
+ `GLOBALS` word in the program header.
+- The first global variable has a variable number of 16, and
+ subsequent variables are assigned incrementing numbers.
+
+**Error Conditions:**
+
+- An error occurs if `name` is not a valid symbol.
+- An error occurs if the maximum number of global variables is
+ exceeded.
+
+**Examples:**
+
+``` {.assembly}
+.gvar score = 0 ; Defines a global variable "score" with initial value 0
+.gvar health ; Defines a global variable "health" with default value 0
+```
+
+**Use Cases:**
+
+- Storing persistent data that needs to be accessed from different
+ parts of the program.
+- Managing game state and tracking variables like score, health, or
+ inventory items.
+
+**Note:** The `.gvar` directive is used to define global variables,
+while local variables are defined within functions using the `.funct`
+directive.
+
+### .INSERT
+
+The `.INSERT` directive instructs the assembler to insert the contents
+of another file at the current point in the assembly process. This
+allows for code modularity and reuse.
+
+**Syntax:**
+
+``` {.assembly}
+.insert "filename"
+```
+
+**Functionality:**
+
+The `.insert` directive opens the specified `filename` and inserts its
+contents into the assembly stream as if they were part of the main
+source file. The assembler processes the inserted file's code and
+directives, including any symbols or definitions it contains.
+
+**Special Cases:**
+
+- The inserted file must be a valid Z-code assembly language file.
+- The `.insert` directive can be nested, meaning inserted files can
+ themselves contain `.insert` directives.
+- The `.ENDI` directive is used to mark the end of an inserted file
+ and return to the previous input source.
+
+**Error Conditions:**
+
+- An error occurs if the specified `filename` cannot be opened.
+- An error occurs if the inserted file contains syntax errors or
+ invalid directives.
+
+**Examples:**
+
+``` {.assembly}
+; ... main source file ...
+
+.insert "header.zap" ; Inserts the contents of header.zap
+
+; ... main source file continues ...
+```
+
+**Use Cases:**
+
+- Including header files that define constants, macros, or other
+ commonly used elements.
+- Modularizing code by separating routines or data into separate
+ files that can be inserted into multiple programs.
+
+**Note:** While `.insert` provides a mechanism for code inclusion and
+modularity, its usage should be carefully considered to avoid
+potential complexity and maintainability issues. Excessive nesting of
+`.insert` directives can make code harder to understand and debug.
+
+### .LANG
+
+The `.LANG` directive specifies the language and escape character used
+for string encoding. This allows ZAP to generate Z-code programs that
+support different languages and character sets.
+
+**Syntax:**
+
+``` {.assembly}
+.lang id, escape
+```
+
+**Functionality:**
+
+The `.lang` directive sets the following parameters for string
+encoding:
+
+- **`id`:** Specifies the language ID. Currently, only two languages
+ are supported:
+ - **0:** English (default)
+ - **1:** German
+- **`escape`:** Specifies the escape character used to represent
+ special characters or switch character sets within strings.
+
+**Special Cases:**
+
+- The default language is English with the `%` character as the
+ escape character.
+- The German language setting modifies the character set used for
+ compact encoding to include German-specific characters.
+
+**Error Conditions:**
+
+- An error occurs if `id` is not 0 or 1.
+
+**Examples:**
+
+``` {.assembly}
+.lang 1, '%' ; Sets the language to German with '%' as the escape character
+```
+
+**Use Cases:**
+
+- Creating Z-code programs that support languages other than
+ English.
+- Optimizing string storage for languages with specific character
+ sets.
+
+**Note:** The `.lang` directive is typically used at the beginning of
+the assembly program to set the language and escape character for all
+subsequent string definitions.
+
+### .LEN
+
+The `.LEN` directive calculates the length of a string in words and
+generates a byte containing that length in the object file. This is
+typically used in conjunction with the `.STR` directive to create
+self-contained string definitions.
+
+**Syntax:**
+
+``` {.assembly}
+.len string
+```
+
+**Functionality:**
+
+The `.len` directive performs the following:
+
+- **Calculates string length:** Determines the length of the
+ specified string in words, taking into account the Z-machine's
+ 5-bit byte encoding for strings.
+- **Generates length byte:** Outputs a single byte containing the
+ calculated length to the object file.
+
+**Special Cases:**
+
+- The string must be a short string, meaning it can be represented
+ in 255 words or less.
+
+**Error Conditions:**
+
+An error occurs if the string length exceeds 255 words.
+
+**Examples:**
+
+``` {.assembly}
+.len "Hello"
+.str "Hello" ; This string will be preceded by a byte indicating its length
+```
+
+**Use Cases:**
+
+- Creating self-contained string definitions where the length is
+ explicitly stored alongside the string data.
+- Facilitating string manipulation routines that require knowledge
+ of the string length.
+
+**Note:** The `.len` directive is often used together with the `.strl`
+directive, which combines the functionality of `.len` and `.str` into
+a single operation.
+
+### .NEW
+
+The `.NEW` directive sets the release level of the Z-code program
+being assembled. This information is used to ensure compatibility with
+different versions of the ZIP interpreter.
+
+**Syntax:**
+
+``` {.assembly}
+.new level
+```
+
+**Functionality:**
+
+The `.new` directive sets the `Version` variable in ZAP, which
+determines the version of the Z-machine that the generated program is
+compatible with. The `level` argument must be a constant expression
+that evaluates to one of the supported Z-machine versions:
+
+- **3:** ZIP
+- **4:** EZIP
+- **5:** XZIP
+- **6:** YZIP
+
+**Special Cases:**
+
+- The default release level is 5 (XZIP).
+- Some features and opcodes might not be available in older versions
+ of ZIP.
+
+**Error Conditions:**
+
+An error occurs if `level` is not a supported Z-machine version.
+
+**Examples:**
+
+``` {.assembly}
+.new 6 ; Sets the release level to YZIP
+```
+
+**Use Cases:**
+
+- Ensuring compatibility with specific versions of the ZIP
+ interpreter.
+- Taking advantage of features and opcodes introduced in newer
+ Z-machine versions.
+
+**Note:** The `.new` directive should be used at the beginning of the
+assembly program to set the release level before any other code or
+directives.
+
+### .OBJECT
+
+The `.OBJECT` directive defines an object and assigns it a unique
+object number. Objects are complex data structures used to represent
+entities and items within the game world.
+
+**Syntax:**
+
+``` {.assembly}
+.object name, flag1, flag2, ..., flag7
+```
+
+**Functionality:**
+
+The `.object` directive performs the following:
+
+- **Defines a symbol:** Creates a global symbol with the specified
+ `name`. The value of the symbol is the object number.
+- **Assigns object number:** Assigns a unique, incrementing object
+ number to the object.
+- **Outputs object data:** Generates the object data in the object
+ file, including flag words and property table pointer.
+
+**Special Cases:**
+
+- Objects are stored in a dedicated table pointed to by the `OBJECT`
+ word in the program header.
+- The first object has an object number of 1, and subsequent objects
+ are assigned incrementing numbers.
+- The `flag1` to `flag7` arguments represent the initial values of
+ the object's 48 one-bit flags, divided into seven words.
+
+**Error Conditions:**
+
+- An error occurs if `name` is not a valid symbol.
+- An error occurs if the maximum number of objects is exceeded.
+
+**Examples:**
+
+``` {.assembly}
+.object "player", 0, 0, 0, 0, 0, 0 ; Defines the "player" object
+.object "sword", 1, 0, 0, 0, 0, 0 ; Defines the "sword" object
+```
+
+**Use Cases:**
+
+- Defining objects to represent entities and items in the game
+ world.
+- Assigning properties and flags to objects to track their state and
+ characteristics.
+
+**Note:** The `.object` directive is used to define objects, while
+properties are defined within the object's property table using the
+`.PROP` directive.
+
+### .OPTIONS
+
+The `.OPTIONS` directive is used to set options that control the
+behavior of the ZIP interpreter. These options affect features such as
+scripting and user input.
+
+**Syntax:**
+
+``` {.assembly}
+.options script, ask
+```
+
+**Functionality:**
+
+The `.options` directive sets the following options:
+
+- **`script`:** A boolean value (0 or 1) indicating whether
+ scripting is enabled. When scripting is enabled, the interpreter
+ can read commands from a script file instead of from the user.
+- **`ask`:** A boolean value (0 or 1) indicating whether the
+ interpreter should ask the user for confirmation before executing
+ certain actions, such as restarting or restoring the game.
+
+**Special Cases:**
+
+- If either `script` or `ask` is omitted, the corresponding option
+ is not modified.
+
+**Error Conditions:**
+
+An error occurs if `script` or `ask` is not a valid boolean value (0
+or 1).
+
+**Examples:**
+
+``` {.assembly}
+.options 1, 0 ; Enables scripting and disables confirmation prompts
+```
+
+**Use Cases:**
+
+- Enabling scripting for automated testing or gameplay recording.
+- Disabling confirmation prompts for a more streamlined user
+ experience.
+
+**Note:** The `.options` directive is typically used at the beginning
+of the assembly program to set the desired interpreter options.
+
+### .PCSET
+
+The `.PCSET` directive sets the program counter (PC) to a specific
+value. This directive is used to jump to a specific address within the
+program or to align code and data to specific memory locations.
+
+**Syntax:**
+
+``` {.assembly}
+.pcset value
+```
+
+**Functionality:**
+
+The `.pcset` directive sets the program counter to the specified
+`value`. The assembler then continues generating code and data from
+that address onwards.
+
+**Special Cases:**
+
+- If `value` is less than the current program counter, the assembler
+ will issue a warning but will still set the PC to the specified
+ value.
+
+**Error Conditions:**
+
+An error occurs if `value` is negative.
+
+**Examples:**
+
+``` {.assembly}
+.pcset 1000 ; Sets the program counter to 1000
+```
+
+**Use Cases:**
+
+- Jumping to a specific address within the program, typically for
+ implementing subroutines or handling error conditions.
+- Aligning code or data to specific memory locations for
+ optimization or compatibility purposes.
+
+**Note:** The `.PCSET` directive should be used with caution, as it
+can lead to unexpected behavior if not used correctly. It is generally
+recommended to use labels and jump instructions for control flow
+whenever possible.
+
+### .PDEF
+
+The `.PDEF` directive aligns the next generated code or data to the
+next word boundary. This directive is used to ensure proper alignment
+for word-sized data elements.
+
+**Syntax:**
+
+``` {.assembly}
+.pdef
+```
+
+**Functionality:**
+
+The `.pdef` directive pads the object file with a zero byte if the
+current address is not already a multiple of two. This ensures that
+the next word (two-byte) value will be aligned to a word boundary.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+.pdef
+.word data1 ; data1 will be aligned to a word boundary
+```
+
+**Use Cases:**
+
+- Ensuring proper alignment for word-sized data elements, such as
+ numbers and pointers.
+- Improving memory access efficiency on architectures that require
+ word alignment.
+
+**Note:** The `.PDEF` directive is typically used before defining
+word-sized data elements to guarantee their alignment. However, the
+assembler generally handles alignment automatically, so explicit use
+of `.PDEF` is often unnecessary.
+
+### .PICFILE
+
+The `.PICFILE` directive defines a picture file and specifies its
+properties. Picture files contain images and associated data used by
+the `DISPLAY` and `DCLEAR` instructions.
+
+**Syntax:**
+
+``` {.assembly}
+.picfile filename, machine, ideal-x, ideal-y, base-x, base-y
+```
+
+**Functionality:**
+
+The `.picfile` directive defines a picture file with the following
+properties:
+
+- **`filename`:** The name of the picture file.
+- **`machine`:** The target machine for which the picture file is
+ intended (e.g., "apple", "ega", "mac").
+- **`ideal-x` and `ideal-y`:** The ideal dimensions of the picture
+ in pixels.
+- **`base-x` and `base-y`:** The base coordinates of the picture in
+ pixels.
+
+This information is used by the interpreter to properly display and
+manage pictures from the specified file.
+
+**Special Cases:**
+
+- The picture file format and encoding are specific to the Z-machine
+ and may vary depending on the target machine.
+- The `zsplit` tool uses the picture file information to distribute
+ pictures across multiple disks in multi-disk games.
+
+**Error Conditions:**
+
+- An error occurs if `filename` is not a valid string.
+- An error occurs if `machine` is not a recognized target machine.
+
+**Examples:**
+
+``` {.assembly}
+.picfile "pictures.p", "mac", 320, 200, 0, 0
+```
+
+**Use Cases:**
+
+- Defining picture files for use with the `DISPLAY` and `DCLEAR`
+ instructions.
+- Providing information to the interpreter and `zsplit` tool for
+ picture management.
+
+**Note:** The `.PICFILE` directive is used in conjunction with the
+`DISPLAY` and `DCLEAR` instructions to display and manage pictures
+within Z-code programs.
+
+### .PROP
+
+The `.PROP` directive defines a property within an object's property
+table. Properties are used to associate additional data and attributes
+with objects.
+
+**Syntax:**
+
+``` {.assembly}
+.prop length, number
+```
+
+**Functionality:**
+
+The `.prop` directive defines a property with the following
+characteristics:
+
+- **`length`:** The length of the property value in bytes.
+- **`number`:** The property number.
+
+The assembler generates the property data in the object file,
+including the length, number, and value.
+
+**Special Cases:**
+
+- Properties are stored in a sorted order within the object's
+ property table.
+- The length of a property value can be 1, 2, or more bytes. The
+ encoding of the length depends on the size:
+ - 1 byte: The high-order bit of the length byte is 0.
+ - 2 bytes: The high-order bit is 1, and the second-highest bit
+ is 0.
+ - More than 2 bytes: The high-order two bits are both 1, and the
+ remaining 6 bits specify the length.
+
+**Error Conditions:**
+
+- An error occurs if `length` is zero or negative.
+- An error occurs if `number` is not within the valid range (1-63).
+
+**Examples:**
+
+``` {.assembly}
+.object "player", ...
+.prop 1, 1 ; Defines a one-byte property with number 1
+.prop 2, 10 ; Defines a two-byte property with number 10
+```
+
+**Use Cases:**
+
+- Associating additional data with objects, such as descriptions,
+ attributes, or inventory items.
+- Extending the functionality of objects beyond their basic flags
+ and attributes.
+
+**Note:** The `.PROP` directive is used within an object definition to
+define its properties. The object itself is defined using the
+`.OBJECT` directive.
+
+### .SEGMENT
+
+The `.SEGMENT` directive opens a new segment for code and data
+definition. Segments are logical divisions of the Z-code program used
+to optimize disk usage and loading times in multi-disk games.
+
+**Syntax:**
+
+``` {.assembly}
+.segment "name"
+```
+
+**Functionality:**
+
+The `.segment` directive opens a new segment with the specified
+`name`. All subsequent code and data definitions are considered to
+belong to this segment until a `.ENDSEG` directive is encountered or
+another `.SEGMENT` directive opens a different segment.
+
+**Special Cases:**
+
+- If the segment "0" is opened, it refers to the default segment
+ that contains all preloaded data and code.
+- If a segment name is not defined with `.DEFSEG`, it is implicitly
+ considered adjacent to segment 0.
+
+**Error Conditions:**
+
+An error occurs if `name` is not a valid string.
+
+**Examples:**
+
+``` {.assembly}
+.segment "ROOM"
+
+; ... code and data for the ROOM segment ...
+
+.endseg
+```
+
+**Use Cases:**
+
+- Organizing the game's code and data into logical segments for
+ efficient disk usage and loading.
+- Informing the `zsplit` tool about segment boundaries to optimize
+ the distribution of segments across multiple disks.
+
+**Note:** Segment definitions and closures are primarily used by the
+`zsplit` tool and do not directly affect the execution of the Z-code
+program.
+
+### .SEQ
+
+The `.SEQ` directive assigns sequential values to a list of symbols,
+starting from 0. This is a convenient way to define a series of
+constants or variables with incrementing values.
+
+**Syntax:**
+
+``` {.assembly}
+.seq symbol1 [, symbol2 ...]
+```
+
+**Functionality:**
+
+The `.seq` directive assigns values to the specified symbols in the
+following manner:
+
+- `symbol1` is assigned the value 0.
+- `symbol2` is assigned the value 1.
+- ... and so on.
+
+The symbols become global constants with their respective values.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if any of the symbols are already defined.
+
+**Examples:**
+
+``` {.assembly}
+.seq color_red, color_green, color_blue ; Defines three constants with values 0, 1, and 2
+```
+
+**Use Cases:**
+
+- Defining a series of constants with incrementing values, such as
+ color codes or status flags.
+- Creating a sequence of variables with unique identifiers.
+
+**Note:** The `.seq` directive provides a concise way to define
+multiple constants or variables with sequential values.
+
+### .SEQ
+
+The `.SEQ` directive assigns sequential values to a list of symbols,
+starting from 0. This is a convenient way to define a series of
+constants or variables with incrementing values.
+
+**Syntax:**
+
+``` {.assembly}
+.seq symbol1 [, symbol2 ...]
+```
+
+**Functionality:**
+
+The `.seq` directive assigns values to the specified symbols in the
+following manner:
+
+- `symbol1` is assigned the value 0.
+- `symbol2` is assigned the value 1.
+- ... and so on.
+
+The symbols become global constants with their respective values.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if any of the symbols are already defined.
+
+**Examples:**
+
+``` {.assembly}
+.seq color_red, color_green, color_blue ; Defines three constants with values 0, 1, and 2
+```
+
+**Use Cases:**
+
+- Defining a series of constants with incrementing values, such as
+ color codes or status flags.
+- Creating a sequence of variables with unique identifiers.
+
+**Note:** The `.seq` directive provides a concise way to define
+multiple constants or variables with sequential values.
+
+### .STR
+
+The `.STR` directive generates a string in the object file, encoding
+it in the Z-machine's 5-bit byte format. It is used to define strings
+that can be referenced and printed by instructions like `PRINT` and
+`PRINTB`.
+
+**Syntax:**
+
+``` {.assembly}
+.str string
+```
+
+**Functionality:**
+
+The `.str` directive performs the following:
+
+- **Encodes the string:** Converts the ASCII string into the
+ Z-machine's 5-bit byte format, using frequent words and character
+ set shifting as needed.
+- **Outputs the string:** Generates the encoded string data in the
+ object file.
+- **Sets the end-of-string bit:** Marks the last word of the string
+ with the end-of-string bit to indicate its termination.
+
+**Special Cases:**
+
+- If a string is provided without an explicit directive, it is
+ implicitly treated as a `.str` directive.
+- Strings are aligned to word boundaries in the object file.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+.str "Hello, world!" ; Defines a string
+print message ; Prints the string defined above
+```
+
+**Use Cases:**
+
+- Defining strings that can be printed or manipulated by the Z-code
+ program.
+- Storing text data efficiently using the Z-machine's string
+ encoding format.
+
+**Note:** The `.str` directive is used to define strings within tables
+or as immediate operands. For defining global strings in the string
+area, the `.GSTR` directive is used.
+
+### .STRL
+
+The `.STRL` directive combines the functionality of the `.LEN` and
+`.STR` directives. It calculates the length of a string in words,
+generates a byte containing that length, and then generates the
+encoded string data in the object file.
+
+**Syntax:**
+
+``` {.assembly}
+.strl string
+```
+
+**Functionality:**
+
+The `.strl` directive performs the following:
+
+- **Calculates string length:** Determines the length of the
+ specified string in words, taking into account the Z-machine's
+ 5-bit byte encoding for strings.
+- **Generates length byte:** Outputs a single byte containing the
+ calculated length to the object file.
+- **Encodes the string:** Converts the ASCII string into the
+ Z-machine's 5-bit byte format, using frequent words and character
+ set shifting as needed.
+- **Outputs the string:** Generates the encoded string data in the
+ object file, following the length byte.
+
+**Special Cases:**
+
+- The string must be a short string, meaning it can be represented
+ in 255 words or less.
+
+**Error Conditions:**
+
+An error occurs if the string length exceeds 255 words.
+
+**Examples:**
+
+``` {.assembly}
+.strl "Hello, world!" ; Defines a string with its length
+```
+
+**Use Cases:**
+
+- Creating self-contained string definitions where the length is
+ explicitly stored alongside the string data.
+- Simplifying string definition by combining the functionality of
+ `.LEN` and `.STR` into a single directive.
+
+**Note:** The `.strl` directive is a convenient way to define strings
+with their lengths, but it is equivalent to using `.len` followed by
+`.str`.
+
+### .TABLE
+
+The `.TABLE` directive declares the beginning of a table definition.
+Tables are logical structures used to organize data in Z-code
+programs.
+
+**Syntax:**
+
+``` {.assembly}
+.table [size]
+```
+
+**Functionality:**
+
+The `.table` directive marks the start of a table definition. It can
+optionally take a `size` argument, which specifies the maximum size of
+the table in bytes. The assembler uses this information to:
+
+- **Check for size violations:** If a size is specified, the
+ assembler ensures that the actual table data generated does not
+ exceed the declared size.
+- **Perform alignment:** The assembler may align the table data to a
+ specific boundary depending on the target architecture or data
+ type.
+
+**Special Cases:**
+
+- If the `size` argument is omitted, the table size is not checked
+ by the assembler. However, debugging versions of the ZIP
+ interpreter may perform bounds checking at runtime.
+
+**Error Conditions:**
+
+An error occurs if the actual table size exceeds the declared size (if
+specified).
+
+**Examples:**
+
+``` {.assembly}
+.table 100 ; Declares a table with a maximum size of 100 bytes
+.word data1, data2, data3
+.endt
+```
+
+**Use Cases:**
+
+- Defining tables of data with a specific size and ensuring that the
+ size is not exceeded.
+- Organizing data into logical structures for easier access and
+ manipulation.
+
+**Note:** The `.TABLE` directive must be paired with a `.ENDT`
+directive to mark the end of the table definition.
+
+### .TRUE
+
+The `.TRUE` directive generates a word (two-byte) value of 1 in the
+object file. It is used to represent the boolean value `true` or to
+initialize memory locations with a non-zero value.
+
+**Syntax:**
+
+``` {.assembly}
+.true
+```
+
+**Functionality:**
+
+The `.true` directive simply generates a word with the value 1 at the
+current address in the object file.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+.true ; Generates a word with value 1
+set flag1, .true ; Sets the flag variable `flag1` to true
+```
+
+**Use Cases:**
+
+- Representing the boolean value `true` in conditional statements or
+ data structures.
+- Initializing variables or memory locations with a non-zero value.
+
+**Note:** The `.true` directive is equivalent to using `.word 1`.
+However, `.true` provides better readability and clarity when
+representing boolean values.
+
+### .VOCBEG
+
+The `.VOCBEG` directive declares the beginning of the vocabulary area.
+The vocabulary area contains words and associated information used by
+the `READ` and `LEX` instructions for parsing player input.
+
+**Syntax:**
+
+``` {.assembly}
+.vocbeg record-length, key-length
+```
+
+**Functionality:**
+
+The `.vocbeg` directive defines the following parameters for the
+vocabulary area:
+
+- **`record-length`:** Specifies the length of each vocabulary entry
+ in bytes. This includes the word itself and any additional
+ associated data.
+- **`key-length`:** Specifies the length of the key used for sorting
+ vocabulary entries. The key is typically the word itself, but it
+ can be a shorter substring.
+
+The assembler uses this information to:
+
+- **Allocate space for vocabulary entries:** Ensures that enough
+ space is allocated in the object file for the vocabulary data.
+- **Sort vocabulary entries (optional):** If the number of entries
+ in the vocabulary table is specified as negative, the vocabulary
+ is considered unsorted. Otherwise, the assembler sorts the entries
+ based on their keys for efficient searching during input parsing.
+
+**Special Cases:**
+
+- The vocabulary area is located in a separate section of the Z-code
+ program and is accessed using the `VOCAB` word in the program
+ header.
+- The first byte of the vocabulary area specifies the number of
+ self-inserting break characters used by the `READ` instruction.
+- The format of the vocabulary entries depends on the
+ `record-length` and `key-length` values specified in `.VOCBEG`.
+
+**Error Conditions:**
+
+- An error occurs if `record-length` or `key-length` is zero or
+ negative.
+- An error occurs if the vocabulary area has an invalid length or
+ structure.
+
+**Examples:**
+
+``` {.assembly}
+.vocbeg 6, 3 ; Define vocabulary with 6-byte entries and 3-byte keys
+
+; ... vocabulary words and data ...
+
+.vocend
+```
+
+**Use Cases:**
+
+- Defining the vocabulary of words that the game understands and can
+ parse from player input.
+- Optimizing input parsing by sorting the vocabulary for efficient
+ searching.
+
+**Note:** The `.VOCBEG` directive must be paired with a `.VOCEND`
+directive to mark the end of the vocabulary area.
+
+### .VOCEND
+
+The `.VOCEND` directive marks the end of the vocabulary area. The
+vocabulary area contains words and associated information used by the
+`READ` and `LEX` instructions for parsing player input.
+
+**Syntax:**
+
+``` {.assembly}
+.vocend
+```
+
+**Functionality:**
+
+The `.VOCEND` directive must be used to terminate a vocabulary area
+that was previously declared with the `.VOCBEG` directive. It performs
+the following:
+
+- **Sorts vocabulary entries:** If the vocabulary is defined as
+ sorted, the assembler sorts the entries based on their keys.
+- **Outputs vocabulary data:** The assembler writes the vocabulary
+ data to the object file in the appropriate format.
+- **Finalizes vocabulary table:** The assembler performs any
+ necessary operations to finalize the vocabulary table, such as
+ calculating the total number of words.
+
+**Special Cases:**
+
+- A `.VOCEND` directive without a preceding `.VOCBEG` directive is
+ an error.
+
+**Error Conditions:**
+
+- An error occurs if the vocabulary area has an invalid length or
+ structure.
+
+**Examples:**
+
+``` {.assembly}
+.vocbeg 6, 3 ; Define vocabulary with 6-byte entries and 3-byte keys
+
+; ... vocabulary words and data ...
+
+.vocend
+```
+
+**Use Cases:**
+
+- Defining the vocabulary of words that the game understands and can
+ parse from player input.
+- Optimizing input parsing by sorting the vocabulary for efficient
+ searching.
+
+**Note:** The `.VOCBEG` and `.VOCEND` directives are essential for
+defining and managing the vocabulary used by the `READ` and `LEX`
+instructions. Proper structure and usage of the vocabulary area are
+crucial for correct input parsing.
+
+### .WORD
+
+The `.WORD` directive instructs the assembler to generate one or more
+word (two-byte) values in the object file. It is used to define
+word-sized data or initialize specific memory locations with word
+values.
+
+**Syntax:**
+
+``` {.assembly}
+.word value1 [, value2 ...]
+```
+
+**Functionality:**
+
+The `.word` directive generates the specified word values sequentially
+in the object file. Each value can be:
+
+- **A constant expression:** Evaluates to a number within the range
+ of -32768 to 65535.
+- **A symbol:** Refers to a previously defined symbol representing a
+ word value.
+
+**Special Cases:**
+
+- If a single value is provided without the `.word` directive, it is
+ implicitly treated as a `.word` directive.
+
+**Error Conditions:**
+
+An error occurs if a value exceeds the 16-bit word range.
+
+**Examples:**
+
+``` {.assembly}
+.word 1000, 2000, 3000 ; Generates three words with values 1000, 2000, and 3000
+.word counter ; Generates a word with the value of the symbol `counter`
+```
+
+**Use Cases:**
+
+- Defining word-sized data, such as numbers, pointers, or flags.
+- Initializing memory locations with specific word values.
+
+**Note:** The `.word` directive is a fundamental data definition
+directive used to generate word-sized data in Z-code programs.
+
+### .ZWORD
+
+The `.ZWORD` directive generates a Z-word string in the object file.
+Z-word strings are similar to regular Z-strings but are limited to a
+maximum of two words (four bytes). They are used to store short text
+snippets or identifiers efficiently.
+
+**Syntax:**
+
+``` {.assembly}
+.zword string
+```
+
+**Functionality:**
+
+The `.zword` directive performs the following:
+
+- **Encodes the string:** Converts the ASCII string into the
+ Z-machine's 5-bit byte format, similar to the `.STR` directive but
+ limited to two words.
+- **Outputs the string:** Generates the encoded string data in the
+ object file.
+- **Pads the string:** If the string is less than two words, it is
+ padded with the standard pad character (5) to fill the remaining
+ space.
+
+**Special Cases:**
+
+- Z-word strings are always four bytes long, regardless of the
+ actual string length.
+
+**Error Conditions:**
+
+An error occurs if the string length exceeds two words.
+
+**Examples:**
+
+``` {.assembly}
+.zword "OK" ; Defines a Z-word string
+```
+
+**Use Cases:**
+
+- Storing short text snippets or identifiers efficiently.
+- Defining data structures that require fixed-length strings.
+
+**Note:** The `.ZWORD` directive is used for defining short strings
+that need to be stored efficiently. For longer strings, the `.STR` or
+`.GSTR` directives are more appropriate.
+
+### ADD
+
+**ADD** is an opcode that performs addition on two 16-bit word values.
+It adds the first operand to the second operand and returns the
+result.
+
+**Syntax:**
+
+``` {.assembly}
+add arg1:int, arg2:int > val
+```
+
+**Functionality:**
+
+The `add` opcode performs the following:
+
+- **Adds `arg1` and `arg2`:** Performs integer addition.
+- **Stores the result:** The sum is stored in the specified
+ destination (`val`). If no destination is provided, the result is
+ pushed onto the game stack.
+
+**Special Cases:**
+
+- If the result of the addition overflows the 16-bit word size, an
+ error occurs.
+
+**Error Conditions:**
+
+An error occurs if the addition result overflows the 16-bit word
+range.
+
+**Examples:**
+
+``` {.assembly}
+add 5, 10 > result ; Adds 5 and 10, stores the sum (15) in `result`
+```
+
+**Use Cases:**
+
+- Performing integer addition calculations.
+- Increasing values or accumulating totals.
+
+**Note:** The `add` opcode performs signed integer addition. If the
+operands are unsigned, the programmer needs to handle potential
+overflow conditions.
+
+### ASHIFT
+
+**ASHIFT** is an opcode that performs an arithmetic shift on a 16-bit
+integer value. It shifts the bits of the operand to the left or right,
+depending on the specified shift amount.
+
+**Syntax:**
+
+``` {.assembly}
+ashift int, n > val
+```
+
+**Functionality:**
+
+The `ashift` opcode performs the following:
+
+- **Shifts the bits of `int`:**
+ - If `n` is positive, `int` is shifted left by `n` bits.
+ - If `n` is negative, `int` is shifted right by the absolute
+ value of `n` bits.
+- **Preserves the sign bit:** In an arithmetic shift, the sign bit
+ of the operand is replicated to fill in the vacated bits during a
+ right shift. This ensures that the sign of the number is
+ preserved.
+- **Stores the result:** The shifted value is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+- If `n` is zero, the value of `int` remains unchanged.
+- If the shift amount exceeds the word size (16 bits), the result is
+ undefined.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+ashift num, 2 > shifted ; Shifts the value in `num` left by 2 bits
+ashift num, -1 > shifted ; Shifts the value in `num` right by 1 bit
+```
+
+**Use Cases:**
+
+- Multiplying or dividing numbers by powers of two efficiently.
+- Manipulating individual bits within a word.
+- Implementing bitwise operations and algorithms.
+
+**Note:** The `ashift` opcode performs an arithmetic shift, which
+preserves the sign of the operand. For a logical shift, where the sign
+bit is not replicated, use the `shift` opcode.
+
+### ASSIGNED?
+
+**ASSIGNED?** is an opcode that checks whether an optional argument
+was provided when calling the current function. It is used to
+implement conditional logic based on the presence or absence of
+optional arguments.
+
+**Syntax:**
+
+``` {.assembly}
+assigned? opt:var /pred
+```
+
+**Functionality:**
+
+The `assigned?` opcode evaluates to true if an optional argument was
+supplied for the variable `opt`. Otherwise, it evaluates to false. The
+result is used to determine whether to take a conditional branch, as
+specified by the predicate (`/pred`) syntax.
+
+**Special Cases:**
+
+- The `assigned?` opcode can only be used within a function to check
+ for optional arguments passed to that function.
+- The variable `opt` must be a local variable of the function.
+
+**Error Conditions:**
+
+An error occurs if `assigned?` is used outside of a function or if
+`opt` is not a local variable.
+
+**Examples:**
+
+``` {.assembly}
+.funct my_function, optional_arg
+ assigned? optional_arg / handle_optional
+ ; ... code if optional_arg is not assigned ...
+handle_optional:
+ ; ... code to handle optional_arg ...
+```
+
+**Use Cases:**
+
+- Implementing functions with optional arguments.
+- Performing different actions depending on whether optional
+ arguments are provided.
+
+**Note:** The `assigned?` opcode is specific to the Z-machine and does
+not have a direct equivalent in most other assembly languages. It is a
+useful feature for implementing functions with flexible argument
+lists.
+
+### BAND
+
+**BAND** is an opcode that performs a bitwise AND operation on two
+16-bit word values. It combines the corresponding bits of the
+operands, setting each bit in the result to 1 only if both
+corresponding bits in the operands are also 1.
+
+**Syntax:**
+
+``` {.assembly}
+band word1, word2 > val
+```
+
+**Functionality:**
+
+The `band` opcode performs the following:
+
+- **Performs bitwise AND:** Combines the corresponding bits of
+ `word1` and `word2` using the logical AND operation.
+- **Stores the result:** The resulting word is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+band flags, mask > result ; Performs bitwise AND between `flags` and `mask`
+```
+
+**Use Cases:**
+
+- Masking out specific bits in a word.
+- Checking the state of individual bits or groups of bits.
+- Implementing bitwise algorithms and operations.
+
+**Note:** The `band` opcode is a fundamental bitwise operation used in
+various programming tasks, including data manipulation, flag handling,
+and low-level control.
+
+### BCOM
+
+**BCOM** is an opcode that performs a bitwise complement (NOT)
+operation on a 16-bit word value. It inverts each bit in the operand,
+setting 1s to 0s and vice versa.
+
+**Syntax:**
+
+``` {.assembly}
+bcom word > val
+```
+
+**Functionality:**
+
+The `bcom` opcode performs the following:
+
+- **Inverts the bits of `word`:** Flips each bit in the operand,
+ changing 1s to 0s and 0s to 1s.
+- **Stores the result:** The resulting word is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+bcom flags > inverted ; Inverts the bits in the `flags` word
+```
+
+**Use Cases:**
+
+- Inverting the state of individual bits or groups of bits.
+- Implementing bitwise algorithms and operations.
+- Toggling the values of flags or status bits.
+
+**Note:** The `bcom` opcode is a fundamental bitwise operation used in
+various programming tasks, including data manipulation, flag handling,
+and low-level control.
+
+### BOR
+
+**BOR** is an opcode that performs a bitwise OR operation on two
+16-bit word values. It combines the corresponding bits of the
+operands, setting each bit in the result to 1 if either or both of the
+corresponding bits in the operands are 1.
+
+**Syntax:**
+
+``` {.assembly}
+bor word1, word2 > val
+```
+
+**Functionality:**
+
+The `bor` opcode performs the following:
+
+- **Performs bitwise OR:** Combines the corresponding bits of
+ `word1` and `word2` using the logical OR operation.
+- **Stores the result:** The resulting word is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+bor flags, mask > result ; Performs bitwise OR between `flags` and `mask`
+```
+
+**Use Cases:**
+
+- Setting specific bits in a word.
+- Combining flags or status bits.
+- Implementing bitwise algorithms and operations.
+
+**Note:** The `bor` opcode is a fundamental bitwise operation used in
+various programming tasks, including data manipulation, flag handling,
+and low-level control.
+
+### BTST
+
+**BTST** is an opcode that tests whether specific bits are set in a
+16-bit word value. It acts as a predicate, meaning it evaluates a
+condition and implicitly performs a conditional branch based on the
+result.
+
+**Syntax:**
+
+``` {.assembly}
+btst word1, word2 /pred
+```
+
+**Functionality:**
+
+The `btst` opcode performs the following:
+
+- **Checks bit states:** Compares the corresponding bits of `word1`
+ and `word2`.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if every bit that is set (1) in `word2` is also set in
+ `word1`. Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- If all bits in `word2` are 0, the predicate always succeeds.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+btst flags, mask / handle_flags ; Branch to `handle_flags` if all bits set in `mask` are also set in `flags`
+```
+
+**Use Cases:**
+
+- Checking the state of individual bits or groups of bits within a
+ word.
+- Implementing conditional logic based on bit states.
+- Handling flags or status bits efficiently.
+
+**Note:** The `btst` opcode is a useful tool for working with bitwise
+data and implementing conditional behavior based on specific bit
+patterns.
+
+### BUFOUT
+
+**BUFOUT** is an opcode that controls whether output to the screen is
+buffered or unbuffered. Buffering allows the interpreter to optimize
+line breaks and handle text wrapping more effectively.
+
+**Syntax:**
+
+``` {.assembly}
+bufout int
+```
+
+**Functionality:**
+
+The `bufout` opcode sets the output buffering mode based on the value
+of `int`:
+
+- **`int` = 1:** Enables output buffering (default). Output is
+ accumulated in a buffer and printed to the screen when a newline
+ character is encountered or the buffer is full.
+- **`int` = 0:** Disables output buffering. All currently buffered
+ output is immediately sent to the screen, and subsequent output is
+ printed as it is generated.
+
+**Special Cases:**
+
+- Output redirected to a table using `DIROUT 3` is never buffered,
+ regardless of the `bufout` setting.
+
+**Error Conditions:**
+
+An error occurs if `int` is not 0 or 1.
+
+**Examples:**
+
+``` {.assembly}
+bufout 0 ; Disables output buffering
+print "Immediate output"
+bufout 1 ; Re-enables output buffering
+```
+
+**Use Cases:**
+
+- Disabling output buffering can be useful for displaying text
+ immediately without waiting for a newline or buffer to fill. This
+ might be used for real-time updates or interactive prompts.
+- In most cases, output buffering should be enabled to allow the
+ interpreter to handle line breaks and text wrapping efficiently.
+
+**Note:** The `bufout` opcode is rarely needed in typical Z-code
+programs, as most output operations implicitly handle buffering as
+necessary.
+
+### CALL
+
+**CALL** is an opcode that calls a function with three arguments and
+returns a value. It is the most general form of the function call
+instruction, allowing for a flexible number of arguments and return
+values.
+
+**Syntax:**
+
+``` {.assembly}
+call fcn, arg1:any, arg2:any, arg3:any > val
+```
+
+**Functionality:**
+
+The `call` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the three arguments
+ (`arg1`, `arg2`, and `arg3`) onto the game stack.
+- **Calls the function:** Transfers control to the function
+ specified by `fcn`. The function address is calculated by shifting
+ `fcn` left by two bits and adding the function offset (`FOFF`)
+ shifted left by three bits.
+- **Retrieves return value:** When the function returns, its return
+ value is retrieved and stored in the specified destination
+ (`val`). If no destination is provided, the value is pushed onto
+ the game stack.
+
+**Special Cases:**
+
+- If `fcn` is zero, the `call` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `fcn` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+call process_input, input_buffer, parse_buffer, options > result ; Calls the `process_input` function with three arguments
+```
+
+**Use Cases:**
+
+- Calling functions with three arguments.
+- Implementing subroutines and modular code structures.
+
+**Note:** The `CALL` opcode is the most general form of the function
+call instruction. For functions with fewer arguments, the `CALL1` and
+`CALL2` opcodes can be used for more efficient encoding. The compiler
+automatically chooses the appropriate opcode based on the number of
+arguments and their types.
+
+### CALL1
+
+**CALL1** is an opcode that calls a function with one argument and
+returns a value. It is a more compact version of the `CALL` opcode,
+optimized for functions with a single argument.
+
+**Syntax:**
+
+``` {.assembly}
+call1 fcn > val
+```
+
+**Functionality:**
+
+The `call1` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the single argument
+ onto the game stack.
+- **Calls the function:** Transfers control to the function
+ specified by `fcn`. The function address is calculated by shifting
+ `fcn` left by two bits and adding the function offset (`FOFF`)
+ shifted left by three bits.
+- **Retrieves return value:** When the function returns, its return
+ value is retrieved and stored in the specified destination
+ (`val`). If no destination is provided, the value is pushed onto
+ the game stack.
+
+**Special Cases:**
+
+- If `fcn` is zero, the `call1` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `fcn` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+call1 get_input > input_char ; Calls the `get_input` function and stores the returned character in `input_char`
+```
+
+**Use Cases:**
+
+- Calling functions with a single argument efficiently.
+- Implementing subroutines and modular code structures.
+
+**Note:** The `call1` opcode is generated by the compiler when it
+detects a function call with one argument. It is not typically used
+directly by programmers.
+
+### CALL2
+
+**CALL2** is an opcode that calls a function with two arguments and
+returns a value. It is a more compact version of the `CALL` opcode,
+optimized for functions with two arguments.
+
+**Syntax:**
+
+``` {.assembly}
+call2 fcn, arg > val
+```
+
+**Functionality:**
+
+The `call2` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the two arguments
+ (`fcn` and `arg`) onto the game stack.
+- **Calls the function:** Transfers control to the function
+ specified by `fcn`. The function address is calculated by shifting
+ `fcn` left by two bits and adding the function offset (`FOFF`)
+ shifted left by three bits.
+- **Retrieves return value:** When the function returns, its return
+ value is retrieved and stored in the specified destination
+ (`val`). If no destination is provided, the value is pushed onto
+ the game stack.
+
+**Special Cases:**
+
+- If `fcn` is zero, the `call2` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `fcn` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+call2 add, num1, num2 > sum ; Calls the `add` function with `num1` and `num2` as arguments, stores the sum in `sum`
+```
+
+**Use Cases:**
+
+- Calling functions with two arguments efficiently.
+- Implementing subroutines and modular code structures.
+
+**Note:** The `call2` opcode is generated by the compiler when it
+detects a function call with two arguments. It is not typically used
+directly by programmers.
+
+### CATCH
+
+**CATCH** is an opcode that captures an exception thrown by the
+`THROW` opcode and provides a way to handle it. It is used in
+conjunction with `THROW` to implement exception handling and non-local
+control flow.
+
+**Syntax:**
+
+``` {.assembly}
+catch > frame
+```
+
+**Functionality:**
+
+The `catch` opcode performs the following:
+
+- **Captures exception:** If an exception has been thrown using the
+ `THROW` opcode, the `catch` opcode captures it and prevents the
+ program from terminating.
+- **Stores frame pointer:** The opcode stores a pointer to the
+ current call frame in the specified destination (`frame`). This
+ frame pointer identifies the point in the call stack where the
+ exception was caught.
+- **Continues execution:** The program continues execution from the
+ instruction following the `catch` opcode.
+
+**Special Cases:**
+
+- If no exception has been thrown, the `catch` opcode stores 0 in
+ the `frame` variable and continues execution.
+- The `CATCH` and `THROW` opcodes do not work within "internal"
+ calls, such as timeout handling routines called by `READ` or
+ `INPUT`.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+catch > frame
+; ... some code that might throw an exception ...
+if frame != 0
+ ; ... handle the exception ...
+```
+
+**Use Cases:**
+
+- Implementing exception handling to deal with errors or unexpected
+ conditions.
+- Performing non-local control flow, such as exiting multiple nested
+ functions at once.
+
+**Note:** The `CATCH` and `THROW` opcodes provide a mechanism for
+exception handling and non-local control flow in Z-code programs. They
+should be used with caution to avoid complex control flow and
+potential errors.
+
+### CLEAR
+
+**CLEAR** is an opcode that clears a window or the entire screen,
+filling it with the current background color.
+
+**Syntax:**
+
+``` {.assembly}
+clear window:int
+```
+
+**Functionality:**
+
+The `clear` opcode clears the specified window or the entire screen:
+
+- **`window` = 0 to 7:** Clears the corresponding window.
+- **`window` = -1:** Unsplits the screen (if it was previously
+ split) and clears the entire screen.
+- **`window` = -2:** Clears the entire screen without affecting
+ window attributes or cursor position.
+
+When a window is cleared, the cursor is moved to the top-left corner
+of that window.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is
+ cleared.
+
+**Error Conditions:**
+
+An error occurs if `window` is not within the valid range (-2 to 7).
+
+**Examples:**
+
+``` {.assembly}
+clear 0 ; Clears the main window (window 0)
+clear -2 ; Clears the entire screen
+```
+
+**Use Cases:**
+
+- Clearing the screen or a window to prepare for new output.
+- Erasing previous content and resetting the display.
+
+**Note:** The `clear` opcode is a convenient way to clear the screen
+or a window. It is important to remember that clearing a window moves
+the cursor to its top-left corner.
+
+### COLOR
+
+**COLOR** is an opcode that sets the foreground and background colors
+for subsequent text output.
+
+**Syntax:**
+
+``` {.assembly}
+color fore:int, back:int
+```
+
+**Functionality:**
+
+The `color` opcode sets the colors for text output as follows:
+
+- **`fore`:** Specifies the foreground color (text color).
+- **`back`:** Specifies the background color.
+
+The colors are interpreted according to the following values:
+
+- **-1:** Use the color of the pixel at the current cursor position.
+- **0:** No change.
+- **1:** System default color.
+- **2:** Black.
+- **3:** Red.
+- **4:** Green.
+- **5:** Yellow.
+- **6:** Blue.
+- **7:** Magenta.
+- **8:** Cyan.
+- **9:** White.
+- **10:** Light gray
+- **11:** Gray
+- **12:** Dark gray
+
+**Special Cases:**
+
+- The availability of colors and their specific shades may vary
+ depending on the target machine and display capabilities.
+- On some machines, like the Amiga, the colors set for the main
+ window (window 0) are used for all windows.
+
+**Error Conditions:**
+
+An error occurs if `fore` or `back` is not within the valid range (-1
+to 12).
+
+**Examples:**
+
+``` {.assembly}
+color 3, 2 ; Sets foreground color to red and background color to black
+color 0, 1 ; Sets background color to the system default
+```
+
+**Use Cases:**
+
+- Changing the colors of text output for visual distinction or
+ emphasis.
+- Enhancing the game's appearance and atmosphere.
+
+**Note:** Games should be designed to handle machines that do not
+support color selection. The `MODE` byte in the program header
+indicates whether the `COLOR` operation is available.
+
+### COPYT
+
+**COPYT** is an opcode that copies a specified number of bytes from
+one table to another. It can also be used to zero out a section of
+memory or duplicate data within a table.
+
+**Syntax:**
+
+``` {.assembly}
+copyt source:tbl, dest:tbl, length:int
+```
+
+**Functionality:**
+
+The `copyt` opcode copies bytes from the source table (`source`) to
+the destination table (`dest`) according to the specified `length`:
+
+- **Positive `length`:** Copies `length` bytes from `source` to
+ `dest`. If the source and destination regions overlap, the opcode
+ performs a "backwards" copy to avoid overwriting data before it is
+ copied.
+- **Negative `length`:** Copies `length` bytes from `source` to
+ `dest` without checking for overlap. This allows for data
+ duplication within the source table.
+- **Zero `dest`:** If `dest` is zero, the opcode zeroes out `length`
+ bytes in the source table.
+
+**Special Cases:**
+
+- The `copyt` opcode can be used to copy data to itself, allowing
+ for shifting or duplication of data within a table.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `source` or `dest` is not a valid table pointer.
+- The copy operation would exceed the bounds of the tables.
+
+**Examples:**
+
+``` {.assembly}
+copyt buffer1, buffer2, 100 ; Copies 100 bytes from buffer1 to buffer2
+copyt table, 0, 50 ; Zeroes out the first 50 bytes of table
+copyt table, table + 10, 20 ; Duplicates 20 bytes within table, shifting them by 10 bytes
+```
+
+**Use Cases:**
+
+- Copying data between tables.
+- Zeroing out sections of memory.
+- Duplicating data within a table.
+- Implementing memory management or data manipulation routines.
+
+**Note:** The `copyt` opcode provides a flexible way to copy and
+manipulate data within tables. It is important to be aware of the
+overlap behavior when using positive lengths to avoid unintended data
+overwrites.
+
+### CRLF
+
+**CRLF** is an opcode that prints an end-of-line sequence to the
+screen. This typically results in a carriage return and line feed,
+moving the cursor to the beginning of the next line.
+
+**Syntax:**
+
+``` {.assembly}
+crlf
+```
+
+**Functionality:**
+
+The `crlf` opcode outputs an end-of-line sequence to the current
+window. The specific behavior depends on the window's attributes:
+
+- **Scrolling window:** The window contents scroll up by one line,
+ and the cursor is moved to the beginning of the newly created
+ empty line.
+- **Non-scrolling window:** The cursor is moved to the beginning of
+ the next line within the window. If the window is full, the output
+ may be clipped or overwritten.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+print "This is a line."
+crlf
+print "This is on the next line."
+```
+
+**Use Cases:**
+
+- Starting a new line of output.
+- Separating paragraphs or sections of text.
+- Formatting text display within windows.
+
+**Note:** The `crlf` opcode is a basic output operation used to
+control the vertical positioning of text on the screen.
+
+### CURGET
+
+**CURGET** is an opcode that retrieves the current cursor position
+within a window and stores it in a table.
+
+**Syntax:**
+
+``` {.assembly}
+curget output:tbl
+```
+
+**Functionality:**
+
+The `curget` opcode retrieves the current cursor position in the
+specified window and writes the coordinates into the `output` table:
+
+- **Word 0 of `output`:** Contains the Y coordinate of the cursor
+ (row number, 1-based).
+- **Word 1 of `output`:** Contains the X coordinate of the cursor
+ (column number, 1-based).
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is used.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `output` is not a valid table pointer.
+- The `output` table does not have enough space to store the
+ coordinates (at least two words).
+
+**Examples:**
+
+``` {.assembly}
+curget cursor_pos ; Retrieves the cursor position in the current window
+```
+
+**Use Cases:**
+
+- Determining the current cursor position for display or interaction
+ purposes.
+- Implementing custom cursor movement or text editing routines.
+
+**Note:** While `CURGET` can be used to retrieve the cursor position,
+it is generally recommended to use the `WINGET` opcode with the
+appropriate offset values, as it provides more flexibility and can
+access other window properties as well.
+
+### CURSET
+
+**CURSET** is an opcode that sets the cursor position within a window
+to specified coordinates.
+
+**Syntax:**
+
+``` {.assembly}
+curset y:int, x:int [, window:int]
+```
+
+**Functionality:**
+
+The `curset` opcode sets the cursor position in the specified window
+to the coordinates (`y`, `x`):
+
+- **`y`:** The Y coordinate (row number, 1-based).
+- **`x`:** The X coordinate (column number, 1-based).
+
+If the coordinates are outside the window's boundaries, they are
+adjusted to the closest valid position within the window.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is used.
+- If `y` is -1, the cursor is turned off.
+- If `y` is -2, the cursor is turned on. In this case, the `x`
+ argument is ignored.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `y` or `x` is negative (except for the special cases mentioned
+ above).
+
+**Examples:**
+
+``` {.assembly}
+curset 5, 10 ; Sets the cursor to row 5, column 10 in the current window
+curset 1, 1, 2 ; Sets the cursor to the top-left corner of window 2
+curset -1 ; Turns off the cursor
+```
+
+**Use Cases:**
+
+- Positioning the cursor for text output or user interaction.
+- Implementing custom cursor movement or text editing routines.
+
+**Note:** The `curset` opcode provides a direct way to set the cursor
+position. However, for more complex window manipulations, consider
+using the `WINPOS` and `WINSIZE` opcodes.
+
+### DCLEAR
+
+**DCLEAR** is an opcode that clears the area occupied by a previously
+displayed picture, restoring the window's background color.
+
+**Syntax:**
+
+``` {.assembly}
+dclear picture:int [, y:int, x:int]
+```
+
+**Functionality:**
+
+The `dclear` opcode clears the area of the specified picture:
+
+- **`picture`:** The ID number of the picture to clear.
+- **`y` and `x` (optional):** The coordinates where the picture was
+ displayed (in pixels). If omitted, the opcode uses the coordinates
+ where the picture was last displayed.
+
+The opcode restores the window's background color in the area
+previously occupied by the picture.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `picture` is not a valid picture ID.
+- The coordinates (`y`, `x`) are outside the window's boundaries.
+
+**Examples:**
+
+``` {.assembly}
+display 10, 10, 10 ; Displays picture 10 at coordinates (10, 10)
+dclear 10 ; Clears the area occupied by picture 10
+```
+
+**Use Cases:**
+
+- Removing pictures from the screen.
+- Restoring the window's background color after displaying a
+ picture.
+
+**Note:** The `DCLEAR` opcode is used in conjunction with the
+`DISPLAY` opcode to manage the display of pictures within Z-code
+programs.
+
+### DEC
+
+**DEC** is an opcode that decrements the value of a variable by 1.
+
+**Syntax:**
+
+``` {.assembly}
+dec var
+```
+
+**Functionality:**
+
+The `dec` opcode subtracts 1 from the value of the specified variable
+(`var`).
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+dec counter ; Decrements the value of the variable `counter`
+```
+
+**Use Cases:**
+
+- Decrementing counters or loop variables.
+- Reducing the value of a variable by a fixed amount.
+
+**Note:** The `dec` opcode is a convenient way to decrement a variable
+by 1. For more complex arithmetic operations, use the `SUB` opcode.
+
+### DIRIN
+
+**DIRIN** is an opcode that redirects input from a specified device.
+It allows the Z-code program to receive input from sources other than
+the keyboard, such as command files or scripts.
+
+**Syntax:**
+
+``` {.assembly}
+dirin device:int [, any1, any2, any3]
+```
+
+**Functionality:**
+
+The `dirin` opcode redirects input based on the value of `device`:
+
+- **`device` = 0:** Keyboard input (default).
+- **`device` = 1:** Command file input. The interpreter reads input
+ from a previously created command file, typically generated using
+ `DIROUT 4`.
+
+The additional arguments (`any1`, `any2`, `any3`) are currently unused
+and should be ignored by the interpreter.
+
+**Special Cases:**
+
+- Not all interpreters implement command file input. If the
+ interpreter does not support it, the `dirin 1` instruction should
+ be ignored.
+
+**Error Conditions:**
+
+An error occurs if `device` is not 0 or 1.
+
+**Examples:**
+
+``` {.assembly}
+dirin 1 ; Redirects input to the command file
+```
+
+**Use Cases:**
+
+- Reading commands from a script file for automated testing or
+ gameplay recording.
+- Implementing custom input methods or interactive sequences.
+
+**Note:** The `dirin` opcode is used in conjunction with `DIROUT` to
+manage input and output redirection.
+
+### DIROUT
+
+**DIROUT** is an opcode that redirects output to a specified device.
+It allows the Z-code program to send output to destinations other than
+the screen, such as the transcript or a table.
+
+**Syntax:**
+
+``` {.assembly}
+dirout device:int [, any1, any2, any3]
+```
+
+**Functionality:**
+
+The `dirout` opcode redirects output based on the value of `device`:
+
+- **`device` = 1:** Screen output (default).
+- **`device` = -1:** Disables screen output.
+- **`device` = 2:** Transcript output. Sends all subsequent output
+ to the transcript device, which can be a file, printer, or other
+ suitable destination.
+- **`device` = -2:** Disables transcript output.
+- **`device` = 3:** Table output. Sends output to the table
+ specified by `any1`. The `any2` argument can optionally specify
+ justification for formatted tables.
+- **`device` = -3:** Disables table output.
+- **`device` = 4:** Command recording. Creates a command file and
+ writes all subsequent input commands to it.
+- **`device` = -4:** Disables command recording.
+
+**Special Cases:**
+
+- If the screen device is disabled and the transcript device is
+ enabled, output is still sent to the transcript.
+- Table output using `dirout 3` is not buffered, regardless of the
+ `BUFOUT` setting.
+- Not all interpreters implement command recording (device 4).
+
+**Error Conditions:**
+
+An error occurs if `device` is not within the valid range (-4 to 4).
+
+**Examples:**
+
+``` {.assembly}
+dirout 2 ; Enables transcript output
+dirout -1 ; Disables screen output
+dirout 3, table, 80 ; Redirects output to `table` with right justification at 80 pixels
+```
+
+**Use Cases:**
+
+- Sending output to the transcript for debugging or recording
+ purposes.
+- Creating formatted tables for display using `PRINTF`.
+- Recording player input commands for testing or analysis.
+
+**Note:** The `dirout` opcode is used in conjunction with `DIRIN` to
+manage input and output redirection.
+
+### DISPLAY
+
+**DISPLAY** is an opcode that displays a picture at a specified
+location on the screen. Pictures are images stored in a separate
+picture file and referenced by their ID numbers.
+
+**Syntax:**
+
+``` {.assembly}
+display picture:int [, y:int, x:int]
+```
+
+**Functionality:**
+
+The `display` opcode displays the picture with the specified ID number
+(`picture`) at the given coordinates (`y`, `x`) in pixels:
+
+- **`picture`:** The ID number of the picture to display.
+- **`y` and `x` (optional):** The coordinates where the picture
+ should be displayed, relative to the top-left corner of the
+ current window. If omitted, the opcode uses the current cursor
+ position.
+
+**Special Cases:**
+
+- If the picture ID is 0, the opcode does nothing.
+- If the coordinates are outside the window's boundaries, the
+ picture may be clipped or partially displayed.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `picture` is not a valid picture ID.
+- The coordinates (`y`, `x`) are outside the window's boundaries.
+
+**Examples:**
+
+``` {.assembly}
+display 10, 10, 10 ; Displays picture 10 at coordinates (10, 10) in the current window
+display 5 ; Displays picture 5 at the current cursor position
+```
+
+**Use Cases:**
+
+- Displaying images and graphics on the screen.
+- Creating visual elements for the game world or user interface.
+
+**Note:** The `DISPLAY` opcode requires the interpreter to support
+picture display. The `MODE` byte in the program header indicates
+whether the `DISPLAY` operation is available.
+
+### DIV
+
+**DIV** is an opcode that performs integer division on two 16-bit word
+values. It divides the first operand by the second operand and returns
+the truncated quotient.
+
+**Syntax:**
+
+``` {.assembly}
+div arg1:int, arg2:int > val
+```
+
+**Functionality:**
+
+The `div` opcode performs the following:
+
+- **Divides `arg1` by `arg2`:** Performs integer division,
+ discarding any remainder.
+- **Stores the result:** The quotient is stored in the specified
+ destination (`val`). If no destination is provided, the result is
+ pushed onto the game stack.
+
+**Special Cases:**
+
+- Division by zero results in an error.
+
+**Error Conditions:**
+
+An error occurs if `arg2` is zero.
+
+**Examples:**
+
+``` {.assembly}
+div 10, 2 > result ; Divides 10 by 2, stores the quotient (5) in `result`
+```
+
+**Use Cases:**
+
+- Performing integer division calculations.
+- Scaling values or calculating ratios.
+
+**Note:** The `div` opcode performs integer division, meaning it
+discards any remainder. For operations that require the remainder, use
+the `MOD` opcode.
+
+### DLESS?
+
+**DLESS?** is an opcode that decrements a variable and then checks if
+the new value is less than a specified integer. It acts as a
+predicate, meaning it evaluates a condition and implicitly performs a
+conditional branch based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+dless? var, int /pred
+```
+
+**Functionality:**
+
+The `dless?` opcode performs the following:
+
+- **Decrements `var`:** Subtracts 1 from the value of the variable
+ `var`.
+- **Compares with `int`:** Checks if the new value of `var` is less
+ than `int`.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the new value of `var` is indeed less than `int`.
+ Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+dless? counter, 0 / end_loop ; Branch to `end_loop` if `counter` is decremented to a value less than 0
+```
+
+**Use Cases:**
+
+- Implementing loops or conditional statements that depend on
+ decrementing a variable and comparing it to a threshold.
+- Optimizing code by combining decrement and comparison operations
+ into a single instruction.
+
+**Note:** The `dless?` opcode is a useful tool for writing efficient
+and concise code when dealing with decrementing variables and
+comparisons.
+
+### EQUAL?
+
+**EQUAL?** is an opcode that checks whether its first operand is equal
+to any of the subsequent operands. It acts as a predicate, meaning it
+evaluates a condition and implicitly performs a conditional branch
+based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+equal? arg1:any, arg2:any [, arg3:any ...] /pred
+```
+
+**Functionality:**
+
+The `equal?` opcode performs the following:
+
+- **Compares `arg1` with other arguments:** Checks if `arg1` is
+ equal to any of the `arg2`, `arg3`, etc., operands.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if `arg1` is equal to at least one of the other arguments.
+ Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- The `equal?` opcode can take a variable number of operands in the
+ extended (`EXT`) format. The 2OP format is limited to two
+ operands.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+equal? object, "sword", "axe" / handle_weapon ; Branch to `handle_weapon` if `object` is equal to either "sword" or "axe"
+```
+
+**Use Cases:**
+
+- Implementing conditional logic based on equality comparisons.
+- Checking if a variable or object matches one of several possible
+ values.
+
+**Note:** The `equal?` opcode is a versatile tool for performing
+equality checks and implementing conditional behavior based on the
+results.
+
+### ERASE
+
+**ERASE** is an opcode that erases a portion of the current window,
+filling it with the current background color.
+
+**Syntax:**
+
+``` {.assembly}
+erase int
+```
+
+**Functionality:**
+
+The `erase` opcode erases a section of the current window based on the
+value of `int`:
+
+- **`int` = 1:** Erases from the current cursor position to the end
+ of the line.
+- **`int` \> 1:** Erases a rectangular area starting at the current
+ cursor position, with a width of `int` pixels and a height equal
+ to the current font height. The erased area does not extend past
+ the right edge of the window.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+erase 1 ; Erases from the cursor to the end of the line
+erase 20 ; Erases a 20-pixel wide rectangle starting at the cursor
+```
+
+**Use Cases:**
+
+- Erasing text or graphics from the screen.
+- Clearing portions of the window for new output.
+
+**Note:** The `ERASE` opcode is used to selectively erase parts of the
+window. For clearing the entire window, use the `CLEAR` opcode.
+
+### EXTOP
+
+**EXTOP** is an opcode that signals to the interpreter that the next
+byte is an extended opcode. Extended opcodes are part of an additional
+set of 256 instructions beyond the standard opcode set.
+
+**Syntax:**
+
+``` {.assembly}
+extop opcode:int
+```
+
+**Functionality:**
+
+The `extop` opcode itself does not perform any operation. Instead, it
+indicates that the following byte (`opcode`) should be interpreted as
+an extended opcode. The interpreter adds 256 to the value of `opcode`
+to obtain the actual extended opcode number.
+
+**Special Cases:**
+
+- The `extop` opcode is never explicitly used by programmers. It is
+ generated by the assembler when encoding instructions that require
+ the extended format.
+
+**Error Conditions:**
+
+An error occurs if `opcode` is not a valid extended opcode number.
+
+**Examples:**
+
+The `extop` opcode is not used directly in assembly code. It is
+handled internally by the assembler and interpreter.
+
+**Use Cases:**
+
+The `extop` opcode allows ZAP to generate a wider range of
+instructions while maintaining backward compatibility with older ZIP
+interpreters that only recognize the standard opcode set.
+
+**Note:** The `extop` opcode is a low-level mechanism used by the
+assembler and interpreter to handle extended opcodes. Programmers do
+not need to be concerned with its usage directly.
+
+### FCLEAR
+
+**FCLEAR** is an opcode that clears a specific flag within an object's
+flag list. Objects have 48 one-bit flags that can be used to track
+their state or attributes.
+
+**Syntax:**
+
+``` {.assembly}
+fclear obj, flag
+```
+
+**Functionality:**
+
+The `fclear` opcode sets the specified flag (`flag`) in the object
+(`obj`) to 0.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `flag` is not within the valid range (0-47).
+
+**Examples:**
+
+``` {.assembly}
+fclear player, 10 ; Clears flag number 10 in the "player" object
+```
+
+**Use Cases:**
+
+- Resetting flags or attributes associated with objects.
+- Changing the state of objects based on game logic or player
+ actions.
+
+**Note:** The `FCLEAR` opcode is used to clear individual flags within
+an object. To set a flag, use the `FSET` opcode.
+
+### FIRST?
+
+**FIRST?** is an opcode that retrieves the "first" property of an
+object and checks if it is non-zero. It acts as a predicate, meaning
+it evaluates a condition and implicitly performs a conditional branch
+based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+first? obj > val /pred
+```
+
+**Functionality:**
+
+The `first?` opcode performs the following:
+
+- **Retrieves "first" property:** Gets the value of the "first" slot
+ within the object (`obj`). This slot typically contains the object
+ number of the first object contained within `obj`.
+- **Checks for non-zero value:** Evaluates to true if the retrieved
+ value is not zero (meaning there is a "first" object). Otherwise,
+ it evaluates to false.
+- **Stores the value (optional):** If the `> val` operand is
+ provided, the retrieved value is also stored in the specified
+ variable.
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- If the object `obj` does not have any contained objects, the
+ "first" slot will be zero, and the predicate will fail.
+
+**Error Conditions:**
+
+An error occurs if `obj` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+first? container > first_item / process_item ; Branch to `process_item` if `container` has a "first" object
+```
+
+**Use Cases:**
+
+- Checking if an object contains other objects.
+- Iterating through a chain of objects linked by their "next"
+ properties.
+- Implementing inventory management or object interaction logic.
+
+**Note:** The `FIRST?` opcode is used to access and check the "first"
+property of an object. To retrieve the "next" property in a chain, use
+the `NEXT?` opcode.
+
+### FONT
+
+**FONT** is an opcode that selects a font for text output in a
+specified window. Fonts determine the style and appearance of the
+displayed text.
+
+**Syntax:**
+
+``` {.assembly}
+font font:int, window:int > val
+```
+
+**Functionality:**
+
+The `font` opcode sets the font for the specified window (`window`) to
+the font identified by `font`:
+
+- **`font`:** The ID number of the font to select.
+- **`window`:** The window number where the font should be applied.
+
+The opcode returns the ID number of the previously selected font for
+the window.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is used.
+- Font 1 is typically the "normal" font for the machine and is
+ selected by default for all windows.
+- Some interpreters may not support all font IDs or may have
+ different fonts available.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `font` is not a valid font ID.
+
+**Examples:**
+
+``` {.assembly}
+font 4, 0 ; Selects the monospace font for the main window (window 0)
+font 2, 3 ; Selects font 2 for window 3
+```
+
+**Use Cases:**
+
+- Changing the appearance of text for visual distinction or
+ emphasis.
+- Displaying text in different styles, such as bold, italic, or
+ monospace.
+- Enhancing the game's visual presentation and atmosphere.
+
+**Note:** The `FONT` opcode requires the interpreter to support font
+selection. The `MODE` byte in the program header indicates whether the
+`FONT` operation is available.
+
+### FSET
+
+**FSET** is an opcode that sets a specific flag within an object's
+flag list to 1. Objects have 48 one-bit flags that can be used to
+track their state or attributes.
+
+**Syntax:**
+
+``` {.assembly}
+fset obj, flag
+```
+
+**Functionality:**
+
+The `fset` opcode sets the specified flag (`flag`) in the object
+(`obj`) to 1.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `flag` is not within the valid range (0-47).
+
+**Examples:**
+
+``` {.assembly}
+fset player, 5 ; Sets flag number 5 in the "player" object to 1
+```
+
+**Use Cases:**
+
+- Setting flags or attributes associated with objects.
+- Changing the state of objects based on game logic or player
+ actions.
+
+**Note:** The `FSET` opcode is used to set individual flags within an
+object. To clear a flag, use the `FCLEAR` opcode.
+
+### FSET?
+
+**FSET?** is an opcode that checks whether a specific flag is set
+within an object's flag list. It acts as a predicate, meaning it
+evaluates a condition and implicitly performs a conditional branch
+based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+fset? obj, flag /pred
+```
+
+**Functionality:**
+
+The `fset?` opcode performs the following:
+
+- **Checks flag state:** Determines whether the specified flag
+ (`flag`) in the object (`obj`) is set (1) or cleared (0).
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the flag is set. Otherwise, the predicate fails
+ (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `flag` is not within the valid range (0-47).
+
+**Examples:**
+
+``` {.assembly}
+fset? player, 15 / handle_flag ; Branch to `handle_flag` if flag number 15 in the "player" object is set
+```
+
+**Use Cases:**
+
+- Implementing conditional logic based on the state of object flags.
+- Checking for specific object attributes or conditions.
+
+**Note:** The `FSET?` opcode is used to test the state of individual
+flags within an object. To set or clear a flag, use the `FSET` or
+`FCLEAR` opcodes, respectively.
+
+### FSTACK
+
+**FSTACK** is an opcode that flushes (removes) a specified number of
+elements from a stack. It can be used to clear the game stack or a
+user-defined stack.
+
+**Syntax:**
+
+``` {.assembly}
+fstack n [, stack:tbl]
+```
+
+**Functionality:**
+
+The `fstack` opcode removes elements from a stack as follows:
+
+- **`n`:** The number of elements to flush from the stack.
+- **`stack` (optional):** A pointer to a table representing a
+ user-defined stack. If omitted, the opcode flushes elements from
+ the game stack.
+
+The opcode does not return any value.
+
+**Special Cases:**
+
+- Flushing more elements than are present on the stack is an error.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `n` is negative.
+- `stack` is not a valid table pointer (if provided).
+- Attempting to flush more elements than are present on the stack.
+
+**Examples:**
+
+``` {.assembly}
+fstack 3 ; Flushes 3 elements from the game stack
+fstack 2, user_stack ; Flushes 2 elements from the `user_stack` table
+```
+
+**Use Cases:**
+
+- Clearing the game stack before calling a function or performing a
+ specific operation.
+- Resetting user-defined stacks to a known state.
+
+**Note:** The `FSTACK` opcode is used to remove elements from stacks.
+To add elements, use the `PUSH` or `XPUSH` opcodes.
+
+### GET
+
+**GET** is an opcode that retrieves the value of an element from a
+word-oriented table. It is used to access data stored in tables based
+on their index or offset.
+
+**Syntax:**
+
+``` {.assembly}
+get table, item > val
+```
+
+**Functionality:**
+
+The `get` opcode performs the following:
+
+- **Calculates element address:** Multiplies the `item` (index or
+ offset) by 2 and adds it to the base address of the `table`. This
+ gives the address of the desired element in memory.
+- **Retrieves the value:** Reads the word value at the calculated
+ address.
+- **Stores the result:** The retrieved value is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+- Table offsets are zero-based, meaning the first element has an
+ index of 0.
+- The interpreter does not perform bounds checking on table
+ accesses. It is the programmer's responsibility to ensure that
+ `item` is within the valid range of the table.
+
+**Error Conditions:**
+
+An error may occur if:
+
+- `table` is not a valid table pointer.
+- `item` is outside the bounds of the table.
+
+**Examples:**
+
+``` {.assembly}
+get inventory, 3 > item ; Retrieves the 4th element from the `inventory` table and stores it in `item`
+```
+
+**Use Cases:**
+
+- Accessing data stored in tables based on their index or offset.
+- Implementing data structures and algorithms that rely on table
+ lookups.
+
+**Note:** The `GET` opcode is used for accessing word-sized elements
+in tables. For byte-sized elements, use the `GETB` opcode.
+
+### GETB
+
+**GETB** is an opcode that retrieves the value of an element from a
+byte-oriented table. It is used to access data stored in tables based
+on their index or offset.
+
+**Syntax:**
+
+``` {.assembly}
+getb table, item > val
+```
+
+**Functionality:**
+
+The `getb` opcode performs the following:
+
+- **Calculates element address:** Adds the `item` (index or offset)
+ to the base address of the `table`. This gives the address of the
+ desired element in memory.
+- **Retrieves the value:** Reads the byte value at the calculated
+ address.
+- **Converts to word:** The retrieved byte value is converted to a
+ word (two bytes).
+- **Stores the result:** The word value is stored in the specified
+ destination (`val`). If no destination is provided, the result is
+ pushed onto the game stack.
+
+**Special Cases:**
+
+- Table offsets are zero-based, meaning the first element has an
+ index of 0.
+- The interpreter does not perform bounds checking on table
+ accesses. It is the programmer's responsibility to ensure that
+ `item` is within the valid range of the table.
+
+**Error Conditions:**
+
+An error may occur if:
+
+- `table` is not a valid table pointer.
+- `item` is outside the bounds of the table.
+
+**Examples:**
+
+``` {.assembly}
+getb text_buffer, 5 > char ; Retrieves the 6th byte from the `text_buffer` table and stores it as a word in `char`
+```
+
+**Use Cases:**
+
+- Accessing data stored in byte-oriented tables.
+- Reading individual characters from text buffers.
+- Implementing data structures and algorithms that rely on
+ byte-level table access.
+
+**Note:** The `GETB` opcode is used for accessing byte-sized elements
+in tables. For word-sized elements, use the `GET` opcode.
+
+### GETP
+
+**GETP** is an opcode that retrieves the value of a property from an
+object. Properties are used to associate additional data and
+attributes with objects.
+
+**Syntax:**
+
+``` {.assembly}
+getp obj, prop > val
+```
+
+**Functionality:**
+
+The `getp` opcode performs the following:
+
+- **Locates property table:** Finds the property table associated
+ with the object (`obj`).
+- **Searches for property:** Searches the property table for the
+ property with the specified number (`prop`).
+- **Retrieves the value:** If the property is found, its value is
+ retrieved.
+- **Handles default properties:** If the property is not found in
+ the object's property table, the opcode retrieves the default
+ value from the default property table.
+- **Stores the result:** The retrieved value is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+- Properties are stored in a sorted order within the object's
+ property table.
+- The `GETP` opcode can only be used to retrieve properties with a
+ length of 1 or 2 bytes. For properties of arbitrary length, use
+ the `GETPT` opcode.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `prop` is not within the valid range (1-63).
+
+**Examples:**
+
+``` {.assembly}
+getp player, 1 > strength ; Retrieves the value of property 1 ("strength") from the "player" object
+```
+
+**Use Cases:**
+
+- Accessing data associated with objects through properties.
+- Retrieving object attributes or characteristics.
+
+**Note:** The `GETP` opcode is used to retrieve properties with a
+length of 1 or 2 bytes. For properties of arbitrary length, use the
+`GETPT` opcode.
+
+### GETPT
+
+**GETPT** is an opcode that retrieves a pointer to a property within
+an object's property table. Unlike `GETP`, which can only retrieve
+properties of 1 or 2 bytes, `GETPT` can access properties of any
+length.
+
+**Syntax:**
+
+``` {.assembly}
+getpt obj, prop > val
+```
+
+**Functionality:**
+
+The `getpt` opcode performs the following:
+
+- **Locates property table:** Finds the property table associated
+ with the object (`obj`).
+- **Searches for property:** Searches the property table for the
+ property with the specified number (`prop`).
+- **Retrieves the pointer:** If the property is found, a pointer to
+ its value is retrieved.
+- **Handles default properties:** If the property is not found in
+ the object's property table, the opcode retrieves a pointer to the
+ default value from the default property table.
+- **Stores the result:** The retrieved pointer is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+- Properties are stored in a sorted order within the object's
+ property table.
+- The retrieved pointer can be used as a table pointer in other
+ table operations like `GET`, `GETB`, `PUT`, and `PUTB`.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `prop` is not within the valid range (1-63).
+
+**Examples:**
+
+``` {.assembly}
+getpt object, 10 > prop_ptr ; Retrieves a pointer to property 10 of `object`
+getb prop_ptr, 0 > first_byte ; Retrieves the first byte of the property value
+```
+
+**Use Cases:**
+
+- Accessing properties of arbitrary length.
+- Implementing data structures or algorithms that require accessing
+ variable-length properties.
+
+**Note:** The `GETPT` opcode is used to retrieve pointers to
+properties, while `GETP` is used to directly retrieve property values
+of 1 or 2 bytes.
+
+### GRTR?
+
+**GRTR?** is an opcode that compares two integer values and checks if
+the first operand is greater than the second operand. It acts as a
+predicate, meaning it evaluates a condition and implicitly performs a
+conditional branch based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+grtr? arg1:int, arg2:int /pred
+```
+
+**Functionality:**
+
+The `grtr?` opcode performs the following:
+
+- **Compares `arg1` and `arg2`:** Checks if the integer value `arg1`
+ is greater than `arg2`.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if `arg1` is indeed greater than `arg2`. Otherwise, the
+ predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+grtr? health, 0 / game_over ; Branch to `game_over` if `health` is greater than 0
+```
+
+**Use Cases:**
+
+- Implementing conditional logic based on greater-than comparisons.
+- Making decisions based on numerical values, such as health, score,
+ or inventory counts.
+
+**Note:** The `grtr?` opcode is a basic comparison operator used for
+implementing conditional behavior in Z-code programs.
+
+### HLIGHT
+
+**HLIGHT** is an opcode that sets the highlighting mode for subsequent
+text output. Highlighting can be used to emphasize text, change its
+appearance, or create special visual effects.
+
+**Syntax:**
+
+``` {.assembly}
+hlight int
+```
+
+**Functionality:**
+
+The `hlight` opcode sets the highlighting mode based on the value of
+`int`:
+
+- **`int` = 0:** No highlighting (normal text).
+- **`int` = 1:** Inverse video (text and background colors are
+ swapped).
+- **`int` = 2:** Bold text.
+- **`int` = 4:** Underline or italic text
+ (implementation-dependent).
+- **`int` = 8:** Monospaced font.
+
+**Special Cases:**
+
+- The availability of highlighting modes depends on the capabilities
+ of the interpreter and the target machine.
+- The `MODE` byte in the program header specifies which highlighting
+ modes are supported.
+- The monospace font mode may either select an actual monospaced
+ font or modify the display of a variable-width font to appear
+ monospaced.
+
+**Error Conditions:**
+
+An error occurs if `int` specifies an unsupported highlighting mode.
+
+**Examples:**
+
+``` {.assembly}
+hlight 2 ; Sets bold text highlighting
+print "Important message!"
+hlight 0 ; Resets to normal text
+```
+
+**Use Cases:**
+
+- Emphasizing important text or messages.
+- Creating visual distinctions between different types of text.
+- Implementing special visual effects or text-based graphics.
+
+**Note:** Games should be designed to handle machines that do not
+support all highlighting modes. The `MODE` byte can be used to check
+which modes are available.
+
+### ICALL
+
+**ICALL** is an opcode that calls a function with three arguments but
+does not return a value. It is similar to the `CALL` opcode but
+optimized for situations where the function's return value is not
+needed.
+
+**Syntax:**
+
+``` {.assembly}
+icall routine:fcn, arg1:any, arg2:any, arg3:any
+```
+
+**Functionality:**
+
+The `icall` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the three arguments
+ (`arg1`, `arg2`, and `arg3`) onto the game stack.
+- **Calls the function:** Transfers control to the function
+ specified by `routine`. The function address is calculated by
+ shifting `routine` left by two bits and adding the function offset
+ (`FOFF`) shifted left by three bits.
+- **Does not retrieve return value:** When the function returns, its
+ return value is discarded.
+
+**Special Cases:**
+
+- If `routine` is zero, the `icall` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `routine` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+icall update_score, player, points, bonus ; Calls the `update_score` function without using its return value
+```
+
+**Use Cases:**
+
+- Calling functions where the return value is not needed, reducing
+ stack usage and potential stack overflows.
+- Implementing subroutines or actions that do not produce a result.
+
+**Note:** The `icall` opcode is generated by the compiler when it
+detects a function call where the return value is not used. It is not
+typically used directly by programmers.
+
+### ICALL1
+
+**ICALL1** is an opcode that calls a function with one argument but
+does not return a value. It is similar to the `CALL1` opcode but
+optimized for situations where the function's return value is not
+needed.
+
+**Syntax:**
+
+``` {.assembly}
+icall1 routine:fcn
+```
+
+**Functionality:**
+
+The `icall1` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the single argument
+ onto the game stack.
+- **Calls the function:** Transfers control to the function
+ specified by `routine`. The function address is calculated by
+ shifting `routine` left by two bits and adding the function offset
+ (`FOFF`) shifted left by three bits.
+- **Does not retrieve return value:** When the function returns, its
+ return value is discarded.
+
+**Special Cases:**
+
+- If `routine` is zero, the `icall1` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `routine` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+icall1 play_sound, sound_id ; Calls the `play_sound` function without using its return value
+```
+
+**Use Cases:**
+
+- Calling functions with a single argument where the return value is
+ not needed, reducing stack usage and potential stack overflows.
+- Implementing subroutines or actions that do not produce a result.
+
+**Note:** The `icall1` opcode is generated by the compiler when it
+detects a function call with one argument where the return value is
+not used. It is not typically used directly by programmers.
+
+### ICALL2
+
+**ICALL2** is an opcode that calls a function with two arguments but
+does not return a value. It is similar to the `CALL2` opcode but
+optimized for situations where the function's return value is not
+needed.
+
+**Syntax:**
+
+``` {.assembly}
+icall2 routine:fcn, arg:any
+```
+
+**Functionality:**
+
+The `icall2` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the two arguments
+ (`routine` and `arg`) onto the game stack.
+- **Calls the function:** Transfers control to the function
+ specified by `routine`. The function address is calculated by
+ shifting `routine` left by two bits and adding the function offset
+ (`FOFF`) shifted left by three bits.
+- **Does not retrieve return value:** When the function returns, its
+ return value is discarded.
+
+**Special Cases:**
+
+- If `routine` is zero, the `icall2` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `routine` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+icall2 set_color, foreground, background ; Calls the `set_color` function without using its return value
+```
+
+**Use Cases:**
+
+- Calling functions with two arguments where the return value is not
+ needed, reducing stack usage and potential stack overflows.
+- Implementing subroutines or actions that do not produce a result.
+
+**Note:** The `icall2` opcode is generated by the compiler when it
+detects a function call with two arguments where the return value is
+not used. It is not typically used directly by programmers.
+
+### IGRTR?
+
+**IGRTR?** is an opcode that increments a variable and then checks if
+the new value is greater than a specified integer. It acts as a
+predicate, meaning it evaluates a condition and implicitly performs a
+conditional branch based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+igrtr? var, int /pred
+```
+
+**Functionality:**
+
+The `igrtr?` opcode performs the following:
+
+- **Increments `var`:** Adds 1 to the value of the variable `var`.
+- **Compares with `int`:** Checks if the new value of `var` is
+ greater than `int`.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the new value of `var` is indeed greater than `int`.
+ Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+igrtr? counter, limit / overflow ; Branch to `overflow` if `counter` is incremented to a value greater than `limit`
+```
+
+**Use Cases:**
+
+- Implementing loops or conditional statements that depend on
+ incrementing a variable and comparing it to a threshold.
+- Optimizing code by combining increment and comparison operations
+ into a single instruction.
+
+**Note:** The `igrtr?` opcode is a useful tool for writing efficient
+and concise code when dealing with incrementing variables and
+comparisons.
+
+### IN?
+
+**IN?** is an opcode that checks whether one object is contained
+within another object. It acts as a predicate, meaning it evaluates a
+condition and implicitly performs a conditional branch based on the
+result.
+
+**Syntax:**
+
+``` {.assembly}
+in? child:obj, parent:obj /pred
+```
+
+**Functionality:**
+
+The `in?` opcode performs the following:
+
+- **Checks containment:** Compares the `LOC` property of the `child`
+ object with the object number of the `parent` object.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the `LOC` of `child` is equal to `parent`, meaning
+ `child` is contained within `parent`. Otherwise, the predicate
+ fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- An object is considered to be contained within itself.
+
+**Error Conditions:**
+
+An error occurs if `child` or `parent` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+in? item, player / take_item ; Branch to `take_item` if `item` is contained within the "player" object
+```
+
+**Use Cases:**
+
+- Implementing inventory management and object interaction logic.
+- Checking the location of objects within the game world.
+- Determining containment relationships between objects.
+
+**Note:** The `IN?` opcode is a fundamental operation for working with
+object hierarchies and containment in Z-code programs.
+
+### INC
+
+**INC** is an opcode that increments the value of a variable by 1.
+
+**Syntax:**
+
+``` {.assembly}
+inc var
+```
+
+**Functionality:**
+
+The `inc` opcode adds 1 to the value of the specified variable
+(`var`).
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+inc counter ; Increments the value of the variable `counter`
+```
+
+**Use Cases:**
+
+- Incrementing counters or loop variables.
+- Increasing the value of a variable by a fixed amount.
+
+**Note:** The `inc` opcode is a convenient way to increment a variable
+by 1. For more complex arithmetic operations, use the `ADD` opcode.
+
+### INPUT
+
+**INPUT** is an opcode that reads a single byte of input from a
+specified device, typically the keyboard. It allows the Z-code program
+to receive input from the user or other input sources.
+
+**Syntax:**
+
+``` {.assembly}
+input dev:int [, time:int, routine:fcn] > val
+```
+
+**Functionality:**
+
+The `input` opcode reads input based on the value of `dev`:
+
+- **`dev` = 1:** Keyboard input (default). The opcode reads the next
+ key pressed by the user and returns its ASCII value.
+- **Other values of `dev`:** May be used for other input devices,
+ but their behavior is implementation-dependent.
+
+**Optional Arguments:**
+
+- **`time`:** Specifies a timeout value in tenths of a second. If no
+ input is received within the specified time, the interpreter calls
+ the `routine` function.
+- **`routine`:** A function to call when a timeout occurs. The
+ function should return true (1) to abort the input operation or
+ false (0) to continue waiting for input.
+
+**Return Value:**
+
+The `input` opcode returns the value of the input byte, which is
+stored in the specified destination (`val`). If no destination is
+provided, the value is pushed onto the game stack.
+
+**Special Cases:**
+
+- Function keys and other special keys may return values greater
+ than 127, with the high bit of the byte set.
+- The interpreter may handle timeout behavior differently depending
+ on the target machine and implementation.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `dev` is not a valid device code.
+- `time` is negative (if provided).
+- `routine` is not a valid function pointer (if provided).
+
+**Examples:**
+
+``` {.assembly}
+input 1 > key ; Reads a key from the keyboard and stores its ASCII value in `key`
+input 1, 50, handle_timeout > key ; Reads a key with a 5-second timeout
+```
+
+**Use Cases:**
+
+- Getting input from the user, such as commands, responses, or key
+ presses.
+- Implementing timed input or interactive sequences.
+
+**Note:** The `INPUT` opcode is a fundamental operation for receiving
+input in Z-code programs. The specific behavior and available devices
+may vary depending on the interpreter and target machine.
+
+### INTBL?
+
+**INTBL?** is an opcode that searches for a specific item within a
+table and returns a pointer to its location if found. It acts as both
+an opcode and a predicate, meaning it can return a value and also
+influence control flow based on the search result.
+
+**Syntax:**
+
+``` {.assembly}
+intbl? item, table, length:int [, record-spec:int] > val /pred
+```
+
+**Functionality:**
+
+The `intbl?` opcode performs the following:
+
+- **Searches for `item`:** Looks for the specified `item` within the
+ `table`.
+- **Table length:** The `length` argument specifies the number of
+ elements to search within the table.
+- **Record specification (optional):** The `record-spec` argument,
+ if provided, defines the format of each element in the table. It
+ is a byte value where:
+ - The high-order bit indicates whether the table elements are
+ words (1) or bytes (0).
+ - The low-order seven bits specify the length of each element in
+ bytes.
+- **Returns a pointer:** If `item` is found, the opcode returns a
+ pointer to its location within the table. Otherwise, it returns 0.
+- **Stores the result (optional):** If the `> val` operand is
+ provided, the returned pointer is also stored in the specified
+ variable.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if `item` is found in the table. Otherwise, the predicate
+ fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- If `record-spec` is omitted or 0, it defaults to 130
+ (word-oriented elements with a length of 2 bytes).
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `table` is not a valid table pointer.
+- `length` is negative.
+
+**Examples:**
+
+``` {.assembly}
+intbl? "north", directions, 4 > direction_ptr / handle_direction ; Searches for "north" in the `directions` table
+intbl? char, buffer, buffer_length, 1 > char_ptr / process_char ; Searches for `char` in a byte-oriented buffer
+```
+
+**Use Cases:**
+
+- Searching for specific elements within tables.
+- Implementing data structures and algorithms that require table
+ lookups.
+- Performing conditional logic based on search results.
+
+**Note:** The `INTBL?` opcode is a versatile tool for searching tables
+and implementing conditional behavior based on the results. The
+optional `record-spec` argument allows for searching tables with
+different element formats.
+
+### IRESTORE
+
+**IRESTORE** is an opcode that restores the game state from a
+previously saved copy in memory. It is used to implement a
+single-level undo functionality.
+
+**Syntax:**
+
+``` {.assembly}
+irestore > val
+```
+
+**Functionality:**
+
+The `irestore` opcode restores the game state from a copy of the
+impure area that was previously saved using the `ISAVE` opcode. The
+impure area contains all modifiable data in the Z-code program,
+including global variables, object flags, and table contents.
+
+**Return Value:**
+
+The `irestore` opcode returns 0 if it fails or if the instruction is
+not implemented on the target machine. Otherwise, it returns -1.
+
+**Special Cases:**
+
+- The `IRESTORE` opcode only works if a previous `ISAVE` operation
+ was successful.
+- The interpreter may not implement the `ISAVE` and `IRESTORE`
+ opcodes on all machines.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+isave ; Saves the current game state
+; ... some actions that modify the game state ...
+irestore ; Restores the previously saved game state
+```
+
+**Use Cases:**
+
+- Implementing an undo feature in the game.
+- Restoring the game state to a previous point after an error or
+ unexpected event.
+
+**Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple
+mechanism for implementing undo functionality. However, they are not
+supported on all interpreters and may require additional memory
+resources.
+
+### ISAVE
+
+**ISAVE** is an opcode that saves a copy of the current game state in
+memory. It is used in conjunction with the `IRESTORE` opcode to
+implement a single-level undo functionality.
+
+**Syntax:**
+
+``` {.assembly}
+isave > val
+```
+
+**Functionality:**
+
+The `isave` opcode copies the impure area of the Z-code program to a
+reserved section of memory. The impure area contains all modifiable
+data, including global variables, object flags, and table contents.
+
+**Return Value:**
+
+The `isave` opcode returns 0 if it fails or if the instruction is not
+implemented on the target machine. Otherwise, it returns -1.
+
+**Special Cases:**
+
+- The interpreter may not implement the `ISAVE` and `IRESTORE`
+ opcodes on all machines.
+- The reserved memory area for storing the saved game state may have
+ limited size.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+isave ; Saves the current game state
+; ... some actions that modify the game state ...
+irestore ; Restores the previously saved game state
+```
+
+**Use Cases:**
+
+- Implementing an undo feature in the game.
+- Saving the game state before performing an action that might have
+ unintended consequences.
+
+**Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple
+mechanism for implementing undo functionality. However, they are not
+supported on all interpreters and may require additional memory
+resources.
+
+### IXCALL
+
+**IXCALL** is an opcode that calls a function with a variable number
+of arguments but does not return a value. It is similar to the `XCALL`
+opcode but optimized for situations where the function's return value
+is not needed.
+
+**Syntax:**
+
+``` {.assembly}
+ixcall routine:fcn, arg1:any [, arg2:any ...]
+```
+
+**Functionality:**
+
+The `ixcall` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the variable number of
+ arguments (`arg1`, `arg2`, etc.) onto the game stack. The number
+ of arguments is determined by the operand types specified in the
+ instruction.
+- **Calls the function:** Transfers control to the function
+ specified by `routine`. The function address is calculated by
+ shifting `routine` left by two bits and adding the function offset
+ (`FOFF`) shifted left by three bits.
+- **Does not retrieve return value:** When the function returns, its
+ return value is discarded.
+
+**Special Cases:**
+
+- If `routine` is zero, the `ixcall` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `routine` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+ixcall print_list, item1, item2, item3 ; Calls the `print_list` function with three arguments
+```
+
+**Use Cases:**
+
+- Calling functions with a variable number of arguments where the
+ return value is not needed, reducing stack usage and potential
+ stack overflows.
+- Implementing functions that take a flexible number of arguments.
+
+**Note:** The `ixcall` opcode is generated by the compiler when it
+detects a function call with a variable number of arguments where the
+return value is not used. It is not typically used directly by
+programmers.
+
+### JUMP
+
+**JUMP** is an opcode that performs an unconditional relative jump to
+a specified location within the program. It is used to control the
+flow of execution and implement loops or conditional branching.
+
+**Syntax:**
+
+``` {.assembly}
+jump offset:loc
+```
+
+**Functionality:**
+
+The `jump` opcode performs the following:
+
+- **Calculates target address:** Adds the `offset` value to the
+ address of the next instruction. This gives the target address of
+ the jump.
+- **Jumps to target:** Transfers control to the calculated target
+ address.
+
+**Special Cases:**
+
+- The `offset` value is a signed 16-bit integer, allowing for both
+ forward and backward jumps within the program.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+jump start_loop ; Jumps to the label `start_loop`
+jump -5 ; Jumps back 5 instructions
+```
+
+**Use Cases:**
+
+- Implementing loops by jumping back to the beginning of the loop
+ code.
+- Performing conditional branching by jumping to different sections
+ of code based on the results of predicates.
+- Creating subroutines or functions by jumping to their starting
+ addresses.
+
+**Note:** The `JUMP` opcode is a fundamental control flow instruction
+used to direct the execution of Z-code programs.
+
+### LESS?
+
+**LESS?** is an opcode that compares two integer values and checks if
+the first operand is less than the second operand. It acts as a
+predicate, meaning it evaluates a condition and implicitly performs a
+conditional branch based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+less? arg1:int, arg2:int /pred
+```
+
+**Functionality:**
+
+The `less?` opcode performs the following:
+
+- **Compares `arg1` and `arg2`:** Checks if the integer value `arg1`
+ is less than `arg2`.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if `arg1` is indeed less than `arg2`. Otherwise, the
+ predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+less? count, 10 / continue_loop ; Branch to `continue_loop` if `count` is less than 10
+```
+
+**Use Cases:**
+
+- Implementing conditional logic based on less-than comparisons.
+- Making decisions based on numerical values, such as health, score,
+ or inventory counts.
+
+**Note:** The `less?` opcode is a basic comparison operator used for
+implementing conditional behavior in Z-code programs.
+
+### LEX
+
+**LEX** is an opcode that parses the contents of an input buffer and
+looks up the words in a vocabulary table. It is similar to the parsing
+phase of the `READ` opcode but offers more flexibility in choosing the
+vocabulary.
+
+**Syntax:**
+
+``` {.assembly}
+lex inbuf:tbl, lexv:tbl [, lexicon:tbl, preserve:bool]
+```
+
+**Functionality:**
+
+The `lex` opcode performs the following:
+
+- **Parses input buffer:** Reads the contents of the `inbuf` table,
+ which is assumed to contain a string of text.
+- **Tokenizes words:** Breaks the text into individual words based
+ on whitespace and self-inserting break characters defined in the
+ vocabulary.
+- **Looks up words:** Searches for each word in the specified
+ `lexicon` table. If `lexicon` is omitted, the default vocabulary
+ table (pointed to by the `VOCAB` word in the program header) is
+ used.
+- **Stores results:** For each word, the opcode stores the following
+ information in the `lexv` table:
+ - A pointer to the word entry in the vocabulary table (or 0 if
+ not found).
+ - The length of the word in bytes.
+ - The byte offset of the word within the input buffer.
+- **Preserves existing entries (optional):** If the `preserve`
+ argument is provided and non-zero, the opcode does not modify
+ entries in `lexv` for words that are not found in the vocabulary.
+
+**Special Cases:**
+
+- The `lexv` table must have enough space to store the parsing
+ results.
+- The format of the `lexv` table is specific to the Z-machine and is
+ used by other opcodes like `PRINTC` to reprint words from the
+ input buffer.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `inbuf` or `lexv` is not a valid table pointer.
+- `lexicon` is not a valid table pointer (if provided).
+- The `lexv` table does not have enough space to store the parsing
+ results.
+
+**Examples:**
+
+``` {.assembly}
+lex input_buffer, parsed_words ; Parses `input_buffer` using the default vocabulary
+lex input_buffer, parsed_words, special_vocab, 1 ; Parses using `special_vocab` and preserves existing entries
+```
+
+**Use Cases:**
+
+- Parsing player input and looking up words in a vocabulary.
+- Implementing custom parsers or natural language processing
+ routines.
+- Using multiple vocabularies for different contexts or situations.
+
+**Note:** The `LEX` opcode provides more flexibility than the parsing
+phase of the `READ` opcode by allowing the programmer to specify the
+vocabulary table.
+
+### LOC
+
+**LOC** is an opcode that retrieves the "parent" object of a given
+object. Objects in Z-code programs are organized in a hierarchical
+structure, where each object can be contained within another object.
+
+**Syntax:**
+
+``` {.assembly}
+loc obj > val
+```
+
+**Functionality:**
+
+The `loc` opcode retrieves the object number of the object that
+contains the specified object (`obj`). This is done by reading the
+value of the `LOC` property of `obj`.
+
+- **Stores the result:** The retrieved object number is stored in
+ the specified destination (`val`). If no destination is provided,
+ the result is pushed onto the game stack.
+
+**Special Cases:**
+
+- If the object `obj` is not contained within any other object
+ (i.e., it is a top-level object), the `LOC` property will be 0,
+ and the opcode will return 0.
+
+**Error Conditions:**
+
+An error occurs if `obj` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+loc item > container ; Retrieves the object number of the container that holds `item`
+```
+
+**Use Cases:**
+
+- Determining the location of objects within the game world.
+- Implementing inventory management and object interaction logic.
+- Traversing the object hierarchy to find related objects.
+
+**Note:** The `LOC` opcode is used to navigate the object hierarchy
+and determine containment relationships between objects.
+
+### MARGIN
+
+**MARGIN** is an opcode that sets the left and right margins for text
+output in a window. Margins control the horizontal spacing of text
+within the window.
+
+**Syntax:**
+
+``` {.assembly}
+margin left:int, right:int [, window:int]
+```
+
+**Functionality:**
+
+The `margin` opcode sets the margins for the specified window
+(`window`) as follows:
+
+- **`left`:** The width of the left margin in pixels.
+- **`right`:** The width of the right margin in pixels.
+
+The opcode stores the margin values in the `LMRG` and `RMRG` words
+associated with the window.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is used.
+- Margins only affect windows that have text wrapping enabled.
+- The opcode must be executed before any text is buffered for the
+ current line.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `left` or `right` is negative.
+
+**Examples:**
+
+``` {.assembly}
+margin 10, 20 ; Sets a 10-pixel left margin and a 20-pixel right margin in the current window
+```
+
+**Use Cases:**
+
+- Indenting text within a window.
+- Creating visual distinctions between different sections of text.
+- Implementing custom text formatting or layout.
+
+**Note:** The `MARGIN` opcode is used to control the horizontal
+spacing of text within windows. It is important to consider the
+window's wrapping attribute and the timing of the opcode execution.
+
+### MENU
+
+**MENU** is an opcode that adds or removes a menu from the menu bar.
+This feature is currently only supported on the Macintosh platform.
+
+**Syntax:**
+
+``` {.assembly}
+menu id, table /pred
+```
+
+**Functionality:**
+
+The `menu` opcode performs the following:
+
+- **Adds a menu (table is non-zero):**
+ - **`id`:** Specifies the slot in the menu bar where the menu
+ should be added. Slots 0, 1, and 2 are reserved for the Apple
+ menu, File menu, and Edit menu, respectively.
+ - **`table`:** A pointer to an LTABLE containing the menu data.
+ The first element of the table is the menu name, and
+ subsequent elements are the menu items.
+- **Removes a menu (table is zero):**
+ - **`id`:** Specifies the slot of the menu to remove.
+
+**Predicate Behavior:**
+
+The `menu` opcode also acts as a predicate:
+
+- **Success:** The predicate succeeds if the menu was successfully
+ added or removed.
+- **Failure:** The predicate fails if there is no room in the menu
+ bar for the new menu or if the specified menu ID is invalid.
+
+**Special Cases:**
+
+- The `MENU` opcode is only supported on the Macintosh platform.
+- The interpreter must have the `%FMENU` flag set in the `FLAGS`
+ word to indicate support for menus.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- The interpreter does not support menus.
+- `id` is not a valid menu slot number.
+- `table` is not a valid table pointer (when adding a menu).
+
+**Examples:**
+
+``` {.assembly}
+menu 3, my_menu / check_menu ; Adds `my_menu` to the menu bar in slot 3
+menu 3, 0 ; Removes the menu from slot 3
+```
+
+**Use Cases:**
+
+- Creating custom menus for user interaction.
+- Providing additional options or commands within the game
+ interface.
+
+**Note:** The `MENU` opcode is platform-specific and requires
+interpreter support. It is important to check the `FLAGS` word before
+using this opcode.
+
+### MOD
+
+**MOD** is an opcode that performs modulo operation on two 16-bit word
+values. It divides the first operand by the second operand and returns
+the remainder.
+
+**Syntax:**
+
+``` {.assembly}
+mod arg1:int, arg2:int > val
+```
+
+**Functionality:**
+
+The `mod` opcode performs the following:
+
+- **Divides `arg1` by `arg2`:** Performs integer division.
+- **Calculates the remainder:** Determines the remainder of the
+ division.
+- **Stores the result:** The remainder is stored in the specified
+ destination (`val`). If no destination is provided, the result is
+ pushed onto the game stack.
+
+**Special Cases:**
+
+- Modulo by zero results in an error.
+
+**Error Conditions:**
+
+An error occurs if `arg2` is zero.
+
+**Examples:**
+
+``` {.assembly}
+mod 10, 3 > result ; Divides 10 by 3, stores the remainder (1) in `result`
+```
+
+**Use Cases:**
+
+- Calculating the remainder of a division.
+- Implementing cyclic behavior or patterns.
+- Performing operations based on the position within a cycle.
+
+**Note:** The `mod` opcode is used to obtain the remainder of an
+integer division. For operations that require the quotient, use the
+`DIV` opcode.
+
+### MOUSE-INFO
+
+**MOUSE-INFO** is an opcode that retrieves information about the
+current state of the mouse and stores it in a table. This information
+includes the mouse cursor position, button status, and any selected
+menu items.
+
+**Syntax:**
+
+``` {.assembly}
+mouse-info table
+```
+
+**Functionality:**
+
+The `mouse-info` opcode fills the specified `table` with the following
+information:
+
+- **Word 0:** Y coordinate of the mouse cursor (row number, in
+ screen units).
+- **Word 1:** X coordinate of the mouse cursor (column number, in
+ screen units).
+- **Word 2:** Button status. Each bit represents a mouse button,
+ with bit 1 corresponding to the rightmost button. A set bit
+ indicates that the button is currently pressed.
+- **Word 3:** Menu/item selection. The high byte contains the menu
+ number (1 for the default menu), and the low byte contains the
+ selected item number within that menu.
+
+**Special Cases:**
+
+- The `table` argument must be a table with at least four words of
+ available space.
+- The interpretation of button status and menu/item selection may
+ vary depending on the target machine and the number of buttons or
+ menus available.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `table` is not a valid table pointer.
+- The `table` does not have enough space to store the mouse
+ information (at least four words).
+
+**Examples:**
+
+``` {.assembly}
+mouse-info mouse_data ; Retrieves the current mouse state
+```
+
+**Use Cases:**
+
+- Implementing mouse-based interaction and controls.
+- Tracking the mouse cursor position for display or game logic
+ purposes.
+- Handling mouse button clicks and menu selections.
+
+**Note:** The `MOUSE-INFO` opcode requires the interpreter to support
+mouse input. The `%FMOUS` flag in the `FLAGS` word indicates whether
+mouse operations are available.
+
+### MOUSE-LIMIT
+
+**MOUSE-LIMIT** is an opcode that restricts the movement of the mouse
+cursor to a specific window. This can be used to confine mouse
+interactions to a particular area of the screen.
+
+**Syntax:**
+
+``` {.assembly}
+mouse-limit window:int
+```
+
+**Functionality:**
+
+The `mouse-limit` opcode restricts the mouse cursor movement to the
+specified window (`window`). The interpreter, if possible, will
+prevent the cursor from moving outside the boundaries of that window.
+Mouse events, such as button clicks or movements, will only be
+reported if the cursor is within the limited window.
+
+**Special Cases:**
+
+- **`window` = -1:** Removes any mouse cursor restrictions, allowing
+ it to move freely across the entire screen.
+- Initially, the mouse cursor is assumed to be limited to window 1.
+
+**Error Conditions:**
+
+An error occurs if `window` is not within the valid range (-1 to 7).
+
+**Examples:**
+
+``` {.assembly}
+mouse-limit 0 ; Limits the mouse cursor to the main window (window 0)
+mouse-limit -1 ; Removes mouse cursor restrictions
+```
+
+**Use Cases:**
+
+- Confining mouse interactions to a specific area of the screen,
+ such as a menu or game window.
+- Preventing accidental clicks or movements outside the intended
+ interaction area.
+
+**Note:** The ability to limit the mouse cursor may vary depending on
+the capabilities of the interpreter and the target machine.
+
+### MOVE
+
+**MOVE** is an opcode that moves an object from one location to
+another within the object hierarchy. Objects in Z-code programs are
+organized in a tree structure, where each object can be contained
+within another object.
+
+**Syntax:**
+
+``` {.assembly}
+move thing:obj, dest:obj
+```
+
+**Functionality:**
+
+The `move` opcode moves the object `thing` into the object `dest`:
+
+- **Checks for existing containment:** If `thing` is already
+ contained within `dest`, the opcode does nothing.
+- **Removes from previous location:** If `thing` is contained within
+ another object, it is removed from that object's containment
+ chain.
+- **Adds to new location:** The `LOC` property of `thing` is set to
+ the object number of `dest`, and `thing` is added as the first
+ object in `dest`'s containment chain. This means the `FIRST`
+ property of `dest` will now point to `thing`.
+
+**Special Cases:**
+
+- If `dest` is 0, the `thing` object is effectively removed from the
+ object hierarchy, as its `LOC` property is set to 0.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `thing` or `dest` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+move sword, player ; Moves the "sword" object into the "player" object's inventory
+move box, room ; Moves the "box" object into the "room" object
+```
+
+**Use Cases:**
+
+- Implementing inventory management and object interaction.
+- Changing the location of objects within the game world.
+- Updating the object hierarchy based on game logic or player
+ actions.
+
+**Note:** The `MOVE` opcode is a fundamental operation for
+manipulating the object hierarchy and managing object containment in
+Z-code programs.
+
+### MUL
+
+**MUL** is an opcode that performs multiplication on two 16-bit word
+values. It multiplies the first operand by the second operand and
+returns the result.
+
+**Syntax:**
+
+``` {.assembly}
+mul arg1:int, arg2:int > val
+```
+
+**Functionality:**
+
+The `mul` opcode performs the following:
+
+- **Multiplies `arg1` by `arg2`:** Performs integer multiplication.
+- **Stores the result:** The product is stored in the specified
+ destination (`val`). If no destination is provided, the result is
+ pushed onto the game stack.
+
+**Special Cases:**
+
+- If the result of the multiplication overflows the 16-bit word
+ size, an error occurs.
+
+**Error Conditions:**
+
+An error occurs if the multiplication result overflows the 16-bit word
+range.
+
+**Examples:**
+
+``` {.assembly}
+mul 5, 10 > result ; Multiplies 5 by 10, stores the product (50) in `result`
+```
+
+**Use Cases:**
+
+- Performing integer multiplication calculations.
+- Scaling values or calculating areas and volumes.
+
+**Note:** The `mul` opcode performs signed integer multiplication. If
+the operands are unsigned, the programmer needs to handle potential
+overflow conditions.
+
+### NEXT?
+
+**NEXT?** is an opcode that retrieves the "next" property of an object
+and checks if it is non-zero. It acts as a predicate, meaning it
+evaluates a condition and implicitly performs a conditional branch
+based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+next? obj > val /pred
+```
+
+**Functionality:**
+
+The `next?` opcode performs the following:
+
+- **Retrieves "next" property:** Gets the value of the "next" slot
+ within the object (`obj`). This slot typically contains the object
+ number of the next object in a linked chain.
+- **Checks for non-zero value:** Evaluates to true if the retrieved
+ value is not zero (meaning there is a "next" object). Otherwise,
+ it evaluates to false.
+- **Stores the value (optional):** If the `> val` operand is
+ provided, the retrieved value is also stored in the specified
+ variable.
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- If the object `obj` is the last object in a chain, the "next" slot
+ will be zero, and the predicate will fail.
+
+**Error Conditions:**
+
+An error occurs if `obj` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+next? item > next_item / process_item ; Branch to `process_item` if `item` has a "next" object in the chain
+```
+
+**Use Cases:**
+
+- Iterating through a chain of objects linked by their "next"
+ properties.
+- Implementing inventory management or object interaction logic.
+
+**Note:** The `NEXT?` opcode is used to access and check the "next"
+property of an object. To retrieve the "first" property in a chain,
+use the `FIRST?` opcode.
+
+### NEXTP
+
+**NEXTP** is an opcode that retrieves the number of the property
+following a specified property within an object's property table. It
+is used to iterate through the properties of an object.
+
+**Syntax:**
+
+``` {.assembly}
+nextp obj, prop > val
+```
+
+**Functionality:**
+
+The `nextp` opcode performs the following:
+
+- **Locates property table:** Finds the property table associated
+ with the object (`obj`).
+- **Searches for property:** Searches the property table for the
+ property with the specified number (`prop`).
+- **Finds next property:** If the property is found, the opcode
+ determines the number of the next property in the table.
+- **Handles circularity:** If `prop` is the last property in the
+ table, the opcode returns the number of the first property,
+ creating a circular iteration.
+- **Stores the result:** The retrieved property number is stored in
+ the specified destination (`val`). If no destination is provided,
+ the result is pushed onto the game stack.
+
+**Special Cases:**
+
+- If `prop` is 0, the opcode returns the number of the first
+ property in the table.
+- Properties are stored in a sorted order within the object's
+ property table.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `prop` is not a valid property number within the object's property
+ table.
+
+**Examples:**
+
+``` {.assembly}
+nextp object, 5 > next_prop ; Retrieves the number of the property following property 5 in `object`
+```
+
+**Use Cases:**
+
+- Iterating through the properties of an object.
+- Implementing generic routines that need to access all properties
+ of an object.
+
+**Note:** The `NEXTP` opcode provides a way to navigate through the
+properties of an object in a circular manner. It is important to
+handle the case where the last property is reached and the opcode
+returns the first property number.
+
+### ORIGINAL?
+
+**ORIGINAL?** is an opcode that checks whether the game is running
+from the original distribution disk. It acts as a predicate, meaning
+it evaluates a condition and implicitly performs a conditional branch
+based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+original? /pred
+```
+
+**Functionality:**
+
+The `original?` opcode checks if the game is running from the original
+distribution disk. The specific method for determining originality is
+implementation-dependent and may vary between interpreters.
+
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the game is determined to be running from the original
+ disk. Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+The implementation of originality checking is left to the interpreter.
+
+- Checking for specific files or data on the disk.
+- Comparing checksums or other validation data.
+- Using copy protection mechanisms.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+original? / display_warning ; Branch to `display_warning` if the game is not running from the original disk
+```
+
+### NOOP
+
+**NOOP** is an opcode that performs no operation. It is essentially a
+placeholder instruction that does nothing and simply advances the
+program counter to the next instruction.
+
+**Syntax:**
+
+``` {.assembly}
+noop
+```
+
+**Functionality:**
+
+The `noop` opcode has no effect on the program state or data. It
+simply increments the program counter, causing the interpreter to move
+on to the next instruction in the sequence.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+noop ; Does nothing
+```
+
+**Use Cases:**
+
+- Aligning code or data to specific memory locations.
+- Providing a placeholder for future instructions or as a debugging
+ aid.
+- Implementing timing delays or loops with empty bodies.
+
+**Note:** The `NOOP` opcode is rarely used in typical Z-code programs
+but can be helpful in specific situations where a placeholder or delay
+is needed.
+
+### PICINF
+
+**PICINF** is an opcode that retrieves information about a picture,
+such as its dimensions. Pictures are images stored in a separate
+picture file and referenced by their ID numbers.
+
+**Syntax:**
+
+``` {.assembly}
+picinf picture:int, data:tbl /pred
+```
+
+**Functionality:**
+
+The `picinf` opcode retrieves information about the specified picture
+(`picture`) and stores it in the `data` table:
+
+- **Word 0 of `data`:** The width of the picture in pixels.
+- **Word 1 of `data`:** The height of the picture in pixels.
+
+**Predicate Behavior:**
+
+The `picinf` opcode also acts as a predicate:
+
+- **Success:** The predicate succeeds if the picture ID is valid and
+ the information is successfully retrieved.
+- **Failure:** The predicate fails if the picture ID is invalid.
+
+**Special Cases:**
+
+- If the picture ID is 0, the opcode stores the highest picture ID
+ in the picture library (the number of pictures) in word 0 of the
+ `data` table.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+picinf 10, pic_data / handle_picture ; Retrieves information about picture 10
+picinf 0, pic_data > num_pictures ; Retrieves the number of pictures in the library
+```
+
+**Use Cases:**
+
+- Determining the dimensions of a picture before displaying it.
+- Implementing custom picture handling or display routines.
+- Checking the validity of a picture ID.
+
+**Note:** The `PICINF` opcode is used in conjunction with the
+`DISPLAY` and `DCLEAR` opcodes to manage the display of pictures
+within Z-code programs.
+
+### PICSET
+
+**PICSET** is an opcode that defines a group of pictures that should
+be loaded together from the picture file. This can be used to optimize
+picture loading and reduce disk access times.
+
+**Syntax:**
+
+``` {.assembly}
+picset picture:int, count:int
+```
+
+**Functionality:**
+
+The `picset` opcode defines a group of pictures starting from the
+specified picture ID (`picture`) and including the next `count`
+pictures. The interpreter should attempt to load all pictures in the
+group from the picture file simultaneously, reducing the need for
+multiple disk accesses.
+
+**Special Cases:**
+
+- All pictures within a group must be located in the same picture
+ file.
+- If the interpreter does not support picture grouping, the opcode
+ should be ignored.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `picture` is not a valid picture ID.
+- `count` is negative.
+
+**Examples:**
+
+``` {.assembly}
+picset 10, 5 ; Defines a group of 5 pictures starting from picture ID 10
+```
+
+**Use Cases:**
+
+- Optimizing picture loading by grouping related pictures together.
+- Reducing disk access times in multi-disk games.
+
+**Note:** The `PICSET` opcode is an optimization feature that may not
+be supported by all interpreters. It is important to check the
+interpreter's capabilities before using this opcode.
+
+### POP
+
+**POP** is an opcode that removes the top element from a stack and
+returns its value. It can be used to retrieve values from the game
+stack or a user-defined stack.
+
+**Syntax:**
+
+``` {.assembly}
+pop [, stack:tbl] > val
+```
+
+**Functionality:**
+
+The `pop` opcode removes the top element from the specified stack and
+returns its value:
+
+- **Game stack (default):** If the `stack` argument is omitted, the
+ opcode pops the top element from the game stack.
+- **User-defined stack:** If the `stack` argument is provided, the
+ opcode pops the top element from the table pointed to by `stack`.
+
+**Return Value:**
+
+The popped value is stored in the specified destination (`val`). If no
+destination is provided, the value is pushed onto the game stack.
+
+**Special Cases:**
+
+- Attempting to pop from an empty stack is an error.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `stack` is not a valid table pointer (if provided).
+- The stack is empty.
+
+**Examples:**
+
+``` {.assembly}
+pop > value ; Pops the top element from the game stack and stores it in `value`
+pop user_stack > value ; Pops the top element from `user_stack`
+```
+
+**Use Cases:**
+
+- Retrieving values from the game stack or user-defined stacks.
+- Implementing stack-based data structures and algorithms.
+
+**Note:** The `POP` opcode is used to remove and retrieve elements
+from stacks. To add elements, use the `PUSH` or `XPUSH` opcodes.
+
+### PRINT
+
+**PRINT** is an opcode that prints a string to the screen. It is used
+to display text output in the current window.
+
+**Syntax:**
+
+``` {.assembly}
+print str
+```
+
+**Functionality:**
+
+The `print` opcode prints the string pointed to by `str`. The string
+address is calculated by shifting `str` left by two bits and adding
+the string offset (`SOFF`) shifted left by three bits.
+
+**Special Cases:**
+
+- The `str` argument is a quad-pointer, meaning it points to a
+ string that is aligned to a quad-byte boundary in the string area.
+- The string area is located in a separate section of the Z-code
+ program and is accessed using the `SOFF` value.
+- Strings are encoded in a special 5-bit byte format for efficient
+ storage.
+
+**Error Conditions:**
+
+An error occurs if `str` is not a valid string pointer.
+
+**Examples:**
+
+``` {.assembly}
+.gstr "message", "Hello, world!"
+print message ; Prints the "message" string
+```
+
+**Use Cases:**
+
+- Displaying text output to the user.
+- Printing messages, prompts, or descriptions.
+
+**Note:** The `PRINT` opcode is used to print strings from the string
+area. For printing strings within tables or as immediate operands, use
+the `PRINTB` opcode.
+
+### PRINTB
+
+**PRINTB** is an opcode that prints a string from a table or an
+immediate string operand. It is used to display text output that is
+not stored in the string area.
+
+**Syntax:**
+
+``` {.assembly}
+printb str
+```
+
+**Functionality:**
+
+The `printb` opcode prints the string pointed to by `str`. The string
+can be:
+
+- **A string within a table:** The `str` argument is a byte pointer
+ to the beginning of the string within a table.
+- **An immediate string operand:** The string is directly encoded
+ within the instruction as a sequence of bytes.
+
+**Special Cases:**
+
+- The `printb` opcode is typically used for printing shorter strings
+ or strings that are dynamically generated.
+- Strings printed with `printb` are not subject to the string offset
+ (`SOFF`) adjustment.
+
+**Error Conditions:**
+
+An error occurs if `str` is not a valid string pointer or if the
+immediate string operand is malformed.
+
+**Examples:**
+
+``` {.assembly}
+printb vocabulary[word_index] ; Prints the word from the vocabulary table at the specified index
+printb "This is an immediate string." ; Prints the immediate string
+```
+
+**Use Cases:**
+
+- Printing strings from tables, such as vocabulary entries or text
+ buffers.
+- Displaying short messages or prompts that do not need to be stored
+ in the string area.
+
+**Note:** The `PRINTB` opcode is used for printing strings that are
+not located in the string area. For printing strings from the string
+area, use the `PRINT` opcode.
+
+### PRINTC
+
+**PRINTC** is an opcode that prints a word from the game's vocabulary
+table. It is typically used to reprint words that were previously
+parsed from player input.
+
+**Syntax:**
+
+``` {.assembly}
+printc text-char
+```
+
+**Functionality:**
+
+The `printc` opcode performs the following:
+
+- **Looks up word:** Uses the value of `text-char` as an index into
+ the vocabulary table (pointed to by the `VOCAB` word in the
+ program header).
+- **Retrieves word data:** If the index is valid, the opcode
+ retrieves the word data from the vocabulary table. This data
+ includes the encoded Z-string representation of the word and its
+ length.
+- **Prints the word:** Decodes the Z-string and prints the
+ corresponding characters to the screen.
+
+**Special Cases:**
+
+- The `text-char` argument is typically obtained from the `lexv`
+ table, which is filled by the `READ` or `LEX` opcodes during input
+ parsing.
+- The format of the vocabulary table entries is specific to the
+ Z-machine and is defined by the `.VOCBEG` directive.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `text-char` is not a valid index into the vocabulary table.
+
+**Examples:**
+
+``` {.assembly}
+read input_buffer, lexv
+printc lexv[1] ; Prints the second word from the parsed input
+```
+
+**Use Cases:**
+
+- Reprinting words that were previously entered by the player.
+- Implementing text-based menus or displays that use words from the
+ game's vocabulary.
+
+**Note:** The `PRINTC` opcode is used to print words from the
+vocabulary table. For printing arbitrary strings, use the `PRINT` or
+`PRINTB` opcodes.
+
+### PRINTD
+
+**PRINTD** is an opcode that prints the short description of an
+object. Objects in Z-code programs can have a short description
+associated with them, which is typically used for providing a brief
+textual representation of the object.
+
+**Syntax:**
+
+``` {.assembly}
+printd obj
+```
+
+**Functionality:**
+
+The `printd` opcode performs the following:
+
+- **Locates object:** Finds the object with the specified object
+ number (`obj`).
+- **Retrieves short description:** Accesses the object's property
+ table and retrieves the value of the `DESC` property, which
+ contains the short description.
+- **Prints the description:** Decodes the Z-string representation of
+ the short description and prints the corresponding characters to
+ the screen.
+
+**Special Cases:**
+
+- If the object does not have a `DESC` property, the opcode does
+ nothing.
+- The short description is typically a short string encoded in the
+ Z-machine's 5-bit byte format.
+
+**Error Conditions:**
+
+An error occurs if `obj` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+printd player ; Prints the short description of the "player" object
+```
+
+**Use Cases:**
+
+- Displaying a brief description of an object to the player.
+- Providing context or information about objects in the game world.
+
+**Note:** The `PRINTD` opcode is a convenient way to print the short
+description associated with an object. For printing other properties
+or arbitrary strings, use the `GETP`, `GETPT`, `PRINT`, or `PRINTB`
+opcodes.
+
+### PRINTF
+
+**PRINTF** is an opcode that prints a formatted table to the screen.
+Formatted tables allow for more flexible text layout and can include
+variable-length lines, different fonts, and highlighting.
+
+**Syntax:**
+
+``` {.assembly}
+printf table
+```
+
+**Functionality:**
+
+The `printf` opcode prints the contents of the specified `table` as a
+formatted block of text. The table format is as follows:
+
+- **Line length indicators:** Each line of text is preceded by a
+ word (two bytes) that specifies the number of characters in that
+ line.
+- **Character data:** The characters of each line are stored as
+ consecutive bytes.
+- **End of table marker:** A word with the value 0 marks the end of
+ the table.
+
+The opcode interprets the line length indicators and character data to
+print the text with the appropriate formatting, including line breaks
+and potential justification.
+
+**Special Cases:**
+
+- Formatted tables are typically generated using the `DIROUT 3`
+ opcode with the `just` argument to specify justification.
+- The `printf` opcode can handle tables with variable-length lines,
+ different fonts, and highlighting.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `table` is not a valid table pointer.
+- The table format is invalid.
+
+**Examples:**
+
+``` {.assembly}
+dirout 3, formatted_text, 80 ; Redirects output to `formatted_text` with right justification at 80 pixels
+; ... generate formatted text ...
+dirout -3
+printf formatted_text ; Prints the formatted table
+```
+
+**Use Cases:**
+
+- Displaying text with custom formatting and layout.
+- Creating menus or dialog boxes with variable-length lines and
+ different styles.
+- Implementing text-based graphics or visual effects.
+
+**Note:** The `PRINTF` opcode provides a more flexible way to display
+text compared to the `PRINT` or `PRINTB` opcodes. It is particularly
+useful for situations where precise control over text layout and
+formatting is required.
+
+### PRINTI
+
+**PRINTI** is an opcode that prints an immediate string directly
+encoded within the instruction. It is used to display short, fixed
+messages or prompts without the need to define them as separate
+strings in the string area.
+
+**Syntax:**
+
+``` {.assembly}
+printi "string"
+```
+
+**Functionality:**
+
+The `printi` opcode decodes and prints the string literal `"string"`
+that is included directly within the instruction.
+
+**Special Cases:**
+
+- The string literal must be enclosed in double quotes (`"`).
+- Double quotes within the string are escaped by using two
+ consecutive double quotes.
+
+**Error Conditions:**
+
+An error occurs if the string literal is malformed or not properly
+terminated.
+
+**Examples:**
+
+``` {.assembly}
+printi "Hello, world!" ; Prints the string "Hello, world!"
+printi "He said, ""Hello!""" ; Prints the string "He said, "Hello!""
+```
+
+**Use Cases:**
+
+- Printing short, fixed messages or prompts.
+- Displaying error messages or debugging information.
+
+**Note:** The `PRINTI` opcode is a convenient way to print short
+strings without the overhead of defining them as separate entities in
+the string area. However, for longer or more complex strings, using
+the `PRINT` or `PRINTB` opcodes with strings defined using `.STR` or
+`.GSTR` is more efficient.
+
+### PRINTN
+
+**PRINTN** is an opcode that prints a signed integer value as a
+decimal number. It is used to display numerical values on the screen.
+
+**Syntax:**
+
+``` {.assembly}
+printn number:int
+```
+
+**Functionality:**
+
+The `printn` opcode converts the signed integer value `number` into a
+decimal string representation and prints it to the current window.
+
+**Special Cases:**
+
+- Negative numbers are printed with a leading minus sign (`-`).
+- The number is printed using the current font and highlighting
+ settings.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+printn score ; Prints the value of the variable `score` as a decimal number
+printn -10 ; Prints the number -10
+```
+
+**Use Cases:**
+
+- Displaying numerical values, such as scores, health points, or
+ inventory counts.
+- Printing the results of calculations or comparisons.
+
+**Note:** The `PRINTN` opcode is used to print signed integer values.
+For printing unsigned values or values in other formats, use the
+`PRINT` or `PRINTB` opcodes with appropriate string formatting.
+
+### PRINTR
+
+**PRINTR** is an opcode that prints an immediate string and then
+performs a carriage return and line feed (CRLF), effectively moving
+the cursor to the beginning of the next line. It also implicitly
+returns true from the current function.
+
+**Syntax:**
+
+``` {.assembly}
+printr "string"
+```
+
+**Functionality:**
+
+The `printr` opcode performs the following:
+
+1. **Prints the string:** Decodes and prints the string literal
+ `"string"` that is included directly within the instruction.
+2. **Outputs CRLF:** Prints a carriage return and line feed sequence,
+ moving the cursor to the beginning of the next line.
+3. **Returns true:** Implicitly returns the value 1 (true) from the
+ current function.
+
+**Special Cases:**
+
+- The string literal must be enclosed in double quotes (`"`).
+- Double quotes within the string are escaped by using two
+ consecutive double quotes.
+
+**Error Conditions:**
+
+An error occurs if the string literal is malformed or not properly
+terminated.
+
+**Examples:**
+
+``` {.assembly}
+printr "Game over!" ; Prints "Game over!" and then returns true, ending the current function
+```
+
+**Use Cases:**
+
+- Printing a final message or prompt before ending the current
+ function.
+- Displaying error messages or debugging information and then
+ returning from the function.
+
+**Note:** The `PRINTR` opcode combines string printing, line
+termination, and function return into a single operation. It is a
+convenient way to print a message and then exit the current function.
+
+### PRINTT
+
+**PRINTT** is an opcode that prints a rectangular block of text from a
+byte-oriented table. It allows for flexible formatting and display of
+text data.
+
+**Syntax:**
+
+``` {.assembly}
+printt bytes:tbl, width:int, height:int [, skip:int]
+```
+
+**Functionality:**
+
+The `printt` opcode prints a block of text from the specified table
+(`bytes`) according to the given dimensions and skip value:
+
+- **`bytes`:** A pointer to a byte-oriented table containing the
+ text data.
+- **`width`:** The width of the text block in columns (number of
+ characters per line).
+- **`height`:** The height of the text block in lines.
+- **`skip` (optional):** The number of bytes to skip at the end of
+ each line. This allows for printing rectangular blocks from within
+ larger tables. If omitted, the default skip value is 0.
+
+The opcode prints the text line by line, wrapping to the next line
+when the `width` is reached. After each line, it skips `skip` bytes in
+the table before starting the next line.
+
+**Special Cases:**
+
+- If the `skip` argument is 0, the opcode prints a continuous block
+ of text without skipping any bytes.
+- The `printt` opcode does not perform any character set decoding or
+ string interpretation. It simply prints the raw bytes from the
+ table.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `bytes` is not a valid table pointer.
+- `width` or `height` is zero or negative.
+- `skip` is negative.
+
+**Examples:**
+
+``` {.assembly}
+printt text_buffer, 80, 24 ; Prints a 24-line block of text from `text_buffer`, 80 characters per line
+printt table, 10, 5, 20 ; Prints a 5-line block from `table`, 10 characters per line, skipping 20 bytes after each line
+```
+
+**Use Cases:**
+
+- Displaying formatted text from tables.
+- Printing text-based graphics or user interface elements.
+- Implementing custom text layout and formatting.
+
+**Note:** The `PRINTT` opcode provides a flexible way to print text
+from tables. It is important to ensure that the table format and
+dimensions are correct to avoid unexpected output.
+
+### PTSIZE
+
+**PTSIZE** is an opcode that returns the size of a property table in
+bytes. Property tables are associated with objects and contain
+additional data and attributes.
+
+**Syntax:**
+
+``` {.assembly}
+ptsize table > val
+```
+
+**Functionality:**
+
+The `ptsize` opcode calculates the size of the property table pointed
+to by `table` and stores the result in the specified destination
+(`val`). If no destination is provided, the result is pushed onto the
+game stack.
+
+**Special Cases:**
+
+- The `ptsize` opcode is typically used with property tables
+ obtained using the `GETPT` opcode.
+- The opcode assumes that the property table has the correct format,
+ with properties stored in a sorted order and appropriate length
+ indicators.
+
+**Error Conditions:**
+
+An error may occur if `table` is not a valid property table pointer or
+if the table format is invalid.
+
+**Examples:**
+
+``` {.assembly}
+getpt object, 10 > prop_ptr ; Retrieves a pointer to property 10 of `object`
+ptsize prop_ptr > prop_size ; Calculates the size of the property value
+```
+
+**Use Cases:**
+
+- Determining the size of a property value before accessing or
+ manipulating it.
+- Implementing routines that need to handle properties of varying
+ lengths.
+
+**Note:** The `PTSIZE` opcode is used to determine the size of
+property tables. It is important to ensure that the table pointer is
+valid and the table format is correct.
+
+### PUSH
+
+**PUSH** is an opcode that pushes a value onto the game stack. The
+game stack is a LIFO (Last-In-First-Out) data structure used to store
+temporary values and function arguments.
+
+**Syntax:**
+
+``` {.assembly}
+push value
+```
+
+**Functionality:**
+
+The `push` opcode pushes the specified `value` onto the top of the
+game stack.
+
+**Special Cases:**
+
+- Pushing a value onto a full stack results in a stack overflow
+ error.
+
+**Error Conditions:**
+
+An error occurs if the game stack is full.
+
+**Examples:**
+
+``` {.assembly}
+push 5 ; Pushes the value 5 onto the stack
+push var1 ; Pushes the value of the variable `var1` onto the stack
+```
+
+**Use Cases:**
+
+- Storing temporary values during calculations or operations.
+- Passing arguments to functions.
+- Implementing stack-based data structures and algorithms.
+
+**Note:** The `PUSH` opcode is used to add elements to the game stack.
+To remove elements, use the `POP` or `FSTACK` opcodes.
+
+### PUT
+
+**PUT** is an opcode that stores a word value into a specified element
+of a word-oriented table. It is used to modify data stored in tables
+based on their index or offset.
+
+**Syntax:**
+
+``` {.assembly}
+put table, item, value
+```
+
+**Functionality:**
+
+The `put` opcode performs the following:
+
+- **Calculates element address:** Multiplies the `item` (index or
+ offset) by 2 and adds it to the base address of the `table`. This
+ gives the address of the desired element in memory.
+- **Stores the value:** Writes the word value `value` to the
+ calculated address.
+
+**Special Cases:**
+
+- Table offsets are zero-based, meaning the first element has an
+ index of 0.
+- The interpreter does not perform bounds checking on table
+ accesses. It is the programmer's responsibility to ensure that
+ `item` is within the valid range of the table.
+
+**Error Conditions:**
+
+An error may occur if:
+
+- `table` is not a valid table pointer.
+- `item` is outside the bounds of the table.
+
+**Examples:**
+
+``` {.assembly}
+put inventory, 3, "sword" ; Stores the word "sword" in the 4th element of the `inventory` table
+```
+
+**Use Cases:**
+
+- Modifying data stored in tables based on their index or offset.
+- Implementing data structures and algorithms that require updating
+ table values.
+
+**Note:** The `PUT` opcode is used for storing word-sized elements in
+tables. For byte-sized elements, use the `PUTB` opcode.
+
+### PUTB
+
+**PUTB** is an opcode that stores a byte value into a specified
+element of a byte-oriented table. It is used to modify data stored in
+tables based on their index or offset.
+
+**Syntax:**
+
+``` {.assembly}
+putb table, item, value
+```
+
+**Functionality:**
+
+The `putb` opcode performs the following:
+
+- **Calculates element address:** Adds the `item` (index or offset)
+ to the base address of the `table`. This gives the address of the
+ desired element in memory.
+- **Extracts byte value:** Takes the low-order byte of `value` as
+ the byte to be stored.
+- **Stores the byte:** Writes the extracted byte value to the
+ calculated address.
+
+**Special Cases:**
+
+- Table offsets are zero-based, meaning the first element has an
+ index of 0.
+- The interpreter does not perform bounds checking on table
+ accesses. It is the programmer's responsibility to ensure that
+ `item` is within the valid range of the table.
+- The high-order byte of `value` is ignored.
+
+**Error Conditions:**
+
+An error may occur if:
+
+- `table` is not a valid table pointer.
+- `item` is outside the bounds of the table.
+
+**Examples:**
+
+``` {.assembly}
+putb text_buffer, 5, 'A' ; Stores the ASCII value of 'A' in the 6th byte of the `text_buffer` table
+```
+
+**Use Cases:**
+
+- Modifying data stored in byte-oriented tables.
+- Writing individual characters to text buffers.
+- Implementing data structures and algorithms that require updating
+ byte-level table values.
+
+**Note:** The `PUTB` opcode is used for storing byte-sized elements in
+tables. For word-sized elements, use the `PUT` opcode.
+
+### PUTP
+
+**PUTP** is an opcode that sets the value of a property within an
+object's property table. Properties are used to associate additional
+data and attributes with objects.
+
+**Syntax:**
+
+``` {.assembly}
+putp obj, prop, value
+```
+
+**Functionality:**
+
+The `putp` opcode modifies a property within an object's property
+table:
+
+- **Locates property table:** Finds the property table associated
+ with the object (`obj`).
+- **Searches for property:** Searches the property table for the
+ property with the specified number (`prop`).
+- **Updates property value:** If the property is found, its value is
+ updated to `value`.
+- **Error if property not found:** If the property is not found in
+ the object's property table, an error occurs.
+
+**Special Cases:**
+
+- The `PUTP` opcode can only be used to modify properties with a
+ length of 1 or 2 bytes. For properties of arbitrary length, use a
+ combination of `GETPT` and table manipulation opcodes.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `obj` is not a valid object number.
+- `prop` is not a valid property number within the object's property
+ table.
+- The property does not exist in the object's property table.
+
+**Examples:**
+
+``` {.assembly}
+putp player, 1, 15 ; Sets the value of property 1 ("strength") in the "player" object to 15
+```
+
+**Use Cases:**
+
+- Modifying data associated with objects through properties.
+- Updating object attributes or characteristics based on game logic
+ or player actions.
+
+**Note:** The `PUTP` opcode is used to modify properties with a length
+of 1 or 2 bytes. For properties of arbitrary length, use a combination
+of `GETPT` and table manipulation opcodes.
+
+### QUIT
+
+**QUIT** is an opcode that terminates the execution of the Z-code
+program. It is used to end the game or exit the interpreter.
+
+**Syntax:**
+
+``` {.assembly}
+quit
+```
+
+**Functionality:**
+
+The `quit` opcode signals to the interpreter that the program should
+terminate. The interpreter performs any necessary cleanup operations
+and then exits.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+quit ; Terminates the program
+```
+
+**Use Cases:**
+
+- Ending the game when the player reaches a specific condition or
+ completes all objectives.
+- Exiting the interpreter in response to a user command or error
+ condition.
+
+**Note:** The `QUIT` opcode is a terminal instruction that stops the
+execution of the Z-code program. It is important to ensure that all
+necessary cleanup or saving operations are performed before using this
+opcode.
+
+### RANDOM
+
+**RANDOM** is an opcode that generates a random number within a
+specified range. It is used to introduce randomness and
+unpredictability into the game.
+
+**Syntax:**
+
+``` {.assembly}
+random range:int > val
+```
+
+**Functionality:**
+
+The `random` opcode generates a random integer value between 1 and
+`range` (inclusive) and stores it in the specified destination
+(`val`). If no destination is provided, the result is pushed onto the
+game stack.
+
+**Special Cases:**
+
+- **Negative `range`:** If `range` is negative, the opcode enters a
+ "predictable" mode. The absolute value of `range` is saved, and
+ subsequent calls to `random` with a positive range will generate
+ numbers in a sequence from 1 to the saved absolute value.
+- **`range` = 0:** Resets the random number generator to its normal
+ (unpredictable) mode.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+random 6 > dice_roll ; Generates a random number between 1 and 6
+random -10 ; Enters predictable mode with a sequence of 1 to 10
+random 4 > next_num ; Generates the next number in the predictable sequence (e.g., 1, 2, 3, 4, 1, ...)
+random 0 ; Resets to unpredictable mode
+```
+
+**Use Cases:**
+
+- Generating random events or outcomes in the game.
+- Simulating dice rolls or other random processes.
+- Introducing variability and replayability into the game
+ experience.
+
+**Note:** The implementation of the random number generator may vary
+between interpreters. The predictable mode allows for testing and
+debugging scenarios where consistent random values are desired.
+
+### READ
+
+**READ** is an opcode that reads a line of input from the user, parses
+it into words, and looks up the words in the vocabulary table. It is a
+fundamental operation for receiving player input and interpreting
+commands.
+
+**Syntax:**
+
+``` {.assembly}
+read text-buffer:tbl, parse-buffer:tbl [, time:int, routine:fcn] > val
+```
+
+**Functionality:**
+
+The `read` opcode performs the following:
+
+1. **Clears output buffer:** Prints and empties the current output
+ buffer, ensuring that any pending output is displayed before
+ reading input.
+2. **Reads input:** Reads a line of text from the user, storing the
+ characters in the `text-buffer` table. The first byte of
+ `text-buffer` specifies the maximum length of the buffer, and the
+ second byte is used by the opcode to store the number of
+ characters read.
+3. **Converts to lowercase:** Converts all uppercase letters in the
+ input to lowercase.
+4. **Parses input (optional):** If `parse-buffer` is non-zero, the
+ opcode parses the input text into words and stores information
+ about each word in the `parse-buffer` table. The format of the
+ `parse-buffer` is specific to the Z-machine and is used by other
+ opcodes like `PRINTC` to reprint words from the input.
+5. **Returns terminator:** The opcode returns the character that
+ terminated the input (e.g., newline, space, or a character from
+ the `TCHARS` table). This value is stored in the specified
+ destination (`val`). If no destination is provided, the value is
+ pushed onto the game stack.
+
+**Optional Arguments:**
+
+- **`time`:** Specifies a timeout value in tenths of a second. If no
+ input is received within the specified time, the interpreter calls
+ the `routine` function.
+- **`routine`:** A function to call when a timeout occurs. The
+ function should return true (1) to abort the input operation or
+ false (0) to continue waiting for input.
+
+**Special Cases:**
+
+- The `TCHARS` table in the program header specifies which
+ characters can terminate input.
+- The vocabulary table (pointed to by the `VOCAB` word) is used to
+ look up words during parsing.
+- The interpreter may handle timeout behavior differently depending
+ on the target machine and implementation.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `text-buffer` or `parse-buffer` is not a valid table pointer.
+- The `text-buffer` is not large enough to hold the input line.
+- `time` is negative (if provided).
+- `routine` is not a valid function pointer (if provided).
+
+**Examples:**
+
+``` {.assembly}
+read input_buffer, parse_buffer > terminator ; Reads input and parses it into words
+read input_buffer, 0 > terminator ; Reads input without parsing
+```
+
+**Use Cases:**
+
+- Getting input from the user, such as commands, responses, or text
+ entry.
+- Implementing a text parser to interpret player commands.
+- Handling timed input or interactive sequences.
+
+**Note:** The `READ` opcode is a fundamental operation for receiving
+and processing player input in Z-code programs.
+
+### REMOVE
+
+**REMOVE** is an opcode that removes an object from the object
+hierarchy. Objects in Z-code programs are organized in a tree
+structure, where each object can be contained within another object.
+
+**Syntax:**
+
+``` {.assembly}
+remove obj
+```
+
+**Functionality:**
+
+The `remove` opcode removes the specified object (`obj`) from the
+object hierarchy:
+
+1. **Finds the containing object:** Determines the object that
+ currently contains `obj` by examining its `LOC` property.
+2. **Updates containment chain:** Removes `obj` from the containment
+ chain of the containing object. This involves updating the `FIRST`
+ and `NEXT` properties of the objects in the chain.
+3. **Clears object properties:** Sets the `LOC`, `FIRST`, and `NEXT`
+ properties of `obj` to 0, effectively removing it from the object
+ hierarchy.
+
+**Special Cases:**
+
+- If `obj` is not contained within any other object (i.e., it is a
+ top-level object), the opcode only clears its `LOC`, `FIRST`, and
+ `NEXT` properties.
+
+**Error Conditions:**
+
+An error occurs if `obj` is not a valid object number.
+
+**Examples:**
+
+``` {.assembly}
+remove item ; Removes the `item` object from its container
+```
+
+**Use Cases:**
+
+- Implementing inventory management and object interaction.
+- Removing objects from the game world when they are no longer
+ needed.
+- Updating the object hierarchy based on game logic or player
+ actions.
+
+**Note:** The `REMOVE` opcode is used to remove objects from the
+object hierarchy. It is important to ensure that the object is
+properly removed from any containment chains to avoid dangling
+references or memory leaks.
+
+### RESTART
+
+**RESTART** is an opcode that reinitializes the Z-code program and
+restarts the game from the beginning. It is used to reset the game
+state and start a new playthrough.
+
+**Syntax:**
+
+``` {.assembly}
+restart
+```
+
+**Functionality:**
+
+The `restart` opcode performs the following:
+
+1. **Reloads the preloaded area:** The interpreter reloads the
+ portion of the game file that is below the `ENDLOD` address, which
+ includes all modifiable data and essential tables.
+2. **Resets the game state:** All global variables, object flags, and
+ other modifiable data are reset to their initial values.
+3. **Jumps to the start address:** The program counter is set to the
+ address specified by the `START` word in the program header, which
+ is typically the beginning of the main game function.
+
+**Special Cases:**
+
+- The `RESTART` opcode does not affect the state of the interpreter
+ itself, such as window configurations or display settings.
+- The random number generator may or may not be reseeded, depending
+ on the interpreter implementation.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+restart ; Restarts the game
+```
+
+**Use Cases:**
+
+- Starting a new game from the beginning.
+- Resetting the game state after an error or unexpected event.
+- Implementing a "restart game" command for the player.
+
+**Note:** The `RESTART` opcode provides a way to reset the game state
+and start a new playthrough. It is important to ensure that all
+necessary data is properly reinitialized during the restart process.
+
+### RESTORE
+
+**RESTORE** is an opcode that restores a previously saved game state
+from disk. It allows players to resume a game from a saved point.
+
+**Syntax:**
+
+``` {.assembly}
+restore [, start:int, length:int, name:tbl] > val
+```
+
+**Functionality:**
+
+The `restore` opcode has two modes of operation:
+
+**1. Full Restore (no arguments):**
+
+- **Prompts for filename:** The interpreter typically prompts the
+ user to provide a filename or select a saved game file.
+- **Reads saved data:** The interpreter reads the saved game data
+ from the specified file.
+- **Restores game state:** The impure area of the Z-code program,
+ which includes global variables, object flags, and table contents,
+ is restored to the state it was in when the game was saved.
+- **Continues execution:** The program resumes execution from the
+ point where it was saved.
+
+**2. Partial Restore (with arguments):**
+
+- **`start`:** The starting address of the memory region to restore.
+- **`length`:** The length of the memory region to restore in bytes.
+- **`name`:** A string specifying the name of the saved data.
+
+This mode allows for restoring specific sections of the impure area,
+such as individual tables or groups of variables.
+
+**Return Value:**
+
+- **Full restore:** The opcode does not return a value.
+- **Partial restore:** The opcode returns the number of bytes
+ successfully read from the saved data.
+
+**Special Cases:**
+
+- The format of the saved game data is specific to the Z-machine and
+ may vary depending on the interpreter implementation.
+- The `RESTORE` opcode does not restore the state of the interpreter
+ itself, such as window configurations or display settings.
+- The random number generator may or may not be reseeded, depending
+ on the interpreter implementation.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- The specified saved game file cannot be found or opened.
+- The saved game data is corrupted or invalid.
+- The `start` or `length` arguments are invalid (in partial restore
+ mode).
+
+**Examples:**
+
+``` {.assembly}
+restore ; Restores a saved game from a file
+restore table_address, table_size, "my_table" ; Restores a specific table from saved data
+```
+
+**Use Cases:**
+
+- Allowing players to save and resume their progress in the game.
+- Implementing checkpoint or save-game functionality.
+- Restoring specific data structures or variables from saved data.
+
+**Note:** The `RESTORE` opcode is essential for providing save and
+restore functionality in Z-code games. The specific implementation and
+user interface for saving and loading games may vary depending on the
+interpreter.
+
+### RETURN
+
+**RETURN** is an opcode that returns from the current function and
+resumes execution in the calling function. It also allows for
+specifying a return value.
+
+**Syntax:**
+
+``` {.assembly}
+return value
+```
+
+**Functionality:**
+
+The `return` opcode performs the following:
+
+1. **Sets return value:** The specified `value` is set as the return
+ value of the function.
+2. **Restores stack frame:** The interpreter restores the stack frame
+ of the calling function, including local variables, stack pointer,
+ and argument count.
+3. **Resumes execution:** Control is transferred back to the
+ instruction following the `CALL` instruction that invoked the
+ current function.
+
+**Special Cases:**
+
+- If the current function was called using an `ICALL` variant (which
+ does not expect a return value), the `value` argument is ignored.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+return 5 ; Returns the value 5 from the function
+return result ; Returns the value of the variable `result`
+```
+
+**Use Cases:**
+
+- Returning from functions and providing a result to the calling
+ function.
+- Implementing subroutines and modular code structures.
+
+**Note:** The `RETURN` opcode is essential for controlling the flow of
+execution between functions in Z-code programs.
+
+### RFALSE
+
+**RFALSE** is an opcode that returns the value 0 (false) from the
+current function. It is typically used as a branch target for
+predicate instructions that evaluate to false.
+
+**Syntax:**
+
+``` {.assembly}
+rfalse
+```
+
+**Functionality:**
+
+The `rfalse` opcode sets the return value of the current function to 0
+and then returns control to the calling function.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+equal? object, "sword" / handle_sword
+rfalse ; Returns false if the object is not a sword
+```
+
+**Use Cases:**
+
+- Returning false from a function when a condition is not met.
+- Implementing conditional logic and branching based on predicate
+ results.
+
+**Note:** The `RFALSE` opcode is often used as a branch target for
+predicate instructions that evaluate to false. It provides a
+convenient way to return a false value and exit the current function.
+
+### RSTACK
+
+**RSTACK** is an opcode that returns from the current function and
+uses the value on top of the stack as the return value. This allows
+for a more flexible way to return values from functions without
+explicitly specifying them in the `RETURN` instruction.
+
+**Syntax:**
+
+``` {.assembly}
+rstack
+```
+
+**Functionality:**
+
+The `rstack` opcode performs the following:
+
+1. **Pops return value:** Removes the top element from the game stack
+ and uses it as the return value of the function.
+2. **Restores stack frame:** The interpreter restores the stack frame
+ of the calling function, including local variables, stack pointer,
+ and argument count.
+3. **Resumes execution:** Control is transferred back to the
+ instruction following the `CALL` instruction that invoked the
+ current function.
+
+**Special Cases:**
+
+- If the game stack is empty, a stack underflow error occurs.
+
+**Error Conditions:**
+
+An error occurs if the game stack is empty when the `RSTACK` opcode is
+executed.
+
+**Examples:**
+
+``` {.assembly}
+; ... function code that pushes a value onto the stack ...
+rstack ; Returns the value from the top of the stack
+```
+
+**Use Cases:**
+
+- Returning values from functions without explicitly specifying them
+ in the `RETURN` instruction.
+- Implementing functions that can return different types of values
+ depending on the context.
+
+**Note:** The `RSTACK` opcode provides a more flexible way to return
+values from functions, but it is important to ensure that the stack
+contains the correct value before using this opcode.
+
+### RTRUE
+
+**RTRUE** is an opcode that returns the value 1 (true) from the
+current function. It is typically used as a branch target for
+predicate instructions that evaluate to true.
+
+**Syntax:**
+
+``` {.assembly}
+rtrue
+```
+
+**Functionality:**
+
+The `rtrue` opcode sets the return value of the current function to 1
+and then returns control to the calling function.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+equal? object, "sword" / handle_sword
+rtrue ; Returns true if the object is a sword
+```
+
+**Use Cases:**
+
+- Returning true from a function when a condition is met.
+- Implementing conditional logic and branching based on predicate
+ results.
+
+**Note:** The `RTRUE` opcode is often used as a branch target for
+predicate instructions that evaluate to true. It provides a convenient
+way to return a true value and exit the current function.
+
+### SAVE
+
+**SAVE** is an opcode that saves the current game state to disk,
+allowing players to resume their progress later.
+
+**Syntax:**
+
+``` {.assembly}
+save [, start:int, length:int, name:tbl] > val
+```
+
+**Functionality:**
+
+The `save` opcode has two modes of operation:
+
+**1. Full Save (no arguments):**
+
+- **Prompts for filename:** The interpreter typically prompts the
+ user to provide a filename or select a save game slot.
+- **Writes game data:** The interpreter writes the current game
+ state to the specified file. This includes the contents of the
+ impure area, which contains all modifiable data such as global
+ variables, object flags, and table contents.
+- **Returns status:** The opcode returns 0 if the save operation
+ fails and 1 if it succeeds.
+
+**2. Partial Save (with arguments):**
+
+- **`start`:** The starting address of the memory region to save.
+- **`length`:** The length of the memory region to save in bytes.
+- **`name`:** A string specifying a unique name for the saved data.
+
+This mode allows for saving specific sections of the impure area, such
+as individual tables or groups of variables.
+
+**Return Value:**
+
+- **Full save:** Returns 0 if the save operation fails and 1 if it
+ succeeds.
+- **Partial save:** Returns 2 to indicate successful completion.
+
+**Special Cases:**
+
+- The format of the saved game data is specific to the Z-machine and
+ may vary depending on the interpreter implementation.
+- The `SAVE` opcode does not save the state of the interpreter
+ itself, such as window configurations or display settings.
+- The random number generator seed is typically not saved to ensure
+ that restoring a saved game does not result in the same sequence
+ of random events.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- The specified save game file cannot be created or written to.
+- The `start` or `length` arguments are invalid (in partial save
+ mode).
+
+**Examples:**
+
+``` {.assembly}
+save ; Saves the entire game state to a file
+save table_address, table_size, "my_table" ; Saves a specific table to a file
+```
+
+**Use Cases:**
+
+- Allowing players to save their progress in the game.
+- Implementing checkpoint or save-game functionality.
+- Saving specific data structures or variables for later retrieval.
+
+**Note:** The `SAVE` opcode is essential for providing save and
+restore functionality in Z-code games. The specific implementation and
+user interface for saving and loading games may vary depending on the
+interpreter.
+
+### SCREEN
+
+**SCREEN** is an opcode that selects the active window for subsequent
+text output. Z-code programs can have multiple windows, each with its
+own properties and display area.
+
+**Syntax:**
+
+``` {.assembly}
+screen window:int
+```
+
+**Functionality:**
+
+The `screen` opcode sets the current window to the window specified by
+`window`. All subsequent text output, including printing strings and
+characters, will be directed to this window.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window remains
+ unchanged.
+- Each window maintains its own cursor position and other
+ attributes. When switching between windows, the cursor position
+ and attributes of the previously active window are preserved.
+
+**Error Conditions:**
+
+An error occurs if `window` is not within the valid range (0 to 7).
+
+**Examples:**
+
+``` {.assembly}
+screen 1 ; Switches to window 1 for output
+print "This text will appear in window 1."
+screen 0 ; Switches back to the main window (window 0)
+```
+
+**Use Cases:**
+
+- Managing multiple windows for displaying different types of
+ information or creating a more complex user interface.
+- Implementing split-screen displays or separate areas for text
+ output.
+
+**Note:** The `SCREEN` opcode is used to control which window receives
+text output. It is important to keep track of the current window and
+switch between windows as needed to ensure that text is displayed in
+the correct location.
+
+### SCROLL
+
+**SCROLL** is an opcode that scrolls the contents of a window up or
+down by a specified number of lines. This can be used to create
+scrolling text displays or to shift the contents of a window.
+
+**Syntax:**
+
+``` {.assembly}
+scroll window:int, lines:int
+```
+
+**Functionality:**
+
+The `scroll` opcode scrolls the contents of the specified window
+(`window`) by the number of lines indicated by `lines`:
+
+- **Positive `lines`:** Scrolls the window contents up by `lines`
+ lines. Blank lines are inserted at the bottom of the window,
+ filled with the current background color.
+- **Negative `lines`:** Scrolls the window contents down by the
+ absolute value of `lines` lines. Lines at the top of the window
+ are removed.
+- **`lines` = 0:** Has no effect.
+
+**Special Cases:**
+
+- The `scroll` opcode works on both scrolling and non-scrolling
+ windows.
+- The cursor position is not affected by scrolling.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+
+**Examples:**
+
+``` {.assembly}
+scroll 0, 1 ; Scrolls the main window (window 0) up by one line
+scroll 2, -3 ; Scrolls window 2 down by three lines
+```
+
+**Use Cases:**
+
+- Creating scrolling text displays, such as status messages or
+ dialogue boxes.
+- Shifting the contents of a window to make room for new output.
+- Implementing custom scrolling behavior or animations.
+
+**Note:** The `SCROLL` opcode provides a way to manipulate the
+contents of a window by scrolling it up or down. It is important to
+consider the window's scrolling attribute and the desired visual
+effect when using this opcode.
+
+### SET
+
+**SET** is an opcode that assigns a value to a variable. It is used to
+modify the contents of variables and update the program state.
+
+**Syntax:**
+
+``` {.assembly}
+set var, value
+```
+
+**Functionality:**
+
+The `set` opcode assigns the specified `value` to the variable `var`.
+The type of `value` can be:
+
+- **Immediate value:** A constant value directly encoded within the
+ instruction.
+- **Variable:** A reference to another variable.
+- **Other:** A value obtained from another instruction or
+ expression.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+set counter, 0 ; Initializes the variable `counter` to 0
+set player_health, health_potion ; Assigns the value of `health_potion` to `player_health`
+```
+
+**Use Cases:**
+
+- Initializing variables with specific values.
+- Updating variables based on game logic or player actions.
+- Assigning the results of calculations or expressions to variables.
+
+**Note:** The `SET` opcode is a fundamental operation for modifying
+variables and managing the program state in Z-code programs.
+
+### SHIFT
+
+**SHIFT** is an opcode that performs a logical shift on a 16-bit
+integer value. It shifts the bits of the operand to the left or right,
+depending on the specified shift amount.
+
+**Syntax:**
+
+``` {.assembly}
+shift int, n > val
+```
+
+**Functionality:**
+
+The `shift` opcode performs the following:
+
+- **Shifts the bits of `int`:**
+ - If `n` is positive, `int` is shifted left by `n` bits. Zeros
+ are shifted into the least significant bits.
+ - If `n` is negative, `int` is shifted right by the absolute
+ value of `n` bits. Zeros are shifted into the most significant
+ bits.
+- **Does not preserve the sign bit:** In a logical shift, the sign
+ bit is not replicated during a right shift. This means that the
+ sign of the number may change after the shift.
+- **Stores the result:** The shifted value is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+- If `n` is zero, the value of `int` remains unchanged.
+- If the shift amount exceeds the word size (16 bits), the result is
+ undefined.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+shift num, 2 > shifted ; Shifts the value in `num` left by 2 bits, filling with zeros
+shift num, -1 > shifted ; Shifts the value in `num` right by 1 bit, filling with zeros
+```
+
+**Use Cases:**
+
+- Multiplying or dividing numbers by powers of two efficiently.
+- Manipulating individual bits within a word.
+- Implementing bitwise operations and algorithms.
+
+**Note:** The `shift` opcode performs a logical shift, which does not
+preserve the sign of the operand. For an arithmetic shift, where the
+sign bit is replicated, use the `ashift` opcode.
+
+### SOUND
+
+**SOUND** is an opcode that plays a sound effect. It allows Z-code
+programs to incorporate audio feedback and enhance the game
+experience.
+
+**Syntax:**
+
+``` {.assembly}
+sound id:int, op:int [, volume:int, repeat:int]
+```
+
+**Functionality:**
+
+The `sound` opcode performs sound operations based on the specified
+arguments:
+
+- **`id`:** The ID number of the sound effect to play.
+- **`op`:** The sound operation to perform:
+ - **1:** Initialize the specified sound.
+ - **2:** Start playing the specified sound (default if `op` is
+ omitted).
+ - **3:** Stop playing the specified sound.
+ - **4:** Clean up buffers associated with the specified sound.
+- **`volume` (optional):** The volume level at which to play the
+ sound. -1 indicates the default volume.
+- **`repeat` (optional):** The number of times to repeat the sound.
+ -1 indicates that the sound should repeat indefinitely until
+ explicitly stopped.
+
+**Special Cases:**
+
+- **`id` = 0:** Uses the last sound ID specified.
+- **`id` = 1 or 2:** Plays a simple beep or boop sound, ignoring the
+ `op` argument.
+- The availability of sound effects and the range of volume levels
+ depend on the interpreter and target machine capabilities.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- The interpreter does not support sound effects.
+- `id` is not a valid sound ID.
+- `op` is not within the valid range (1-4).
+- `volume` or `repeat` is invalid (if provided).
+
+**Examples:**
+
+``` {.assembly}
+sound 10, 2 ; Starts playing sound effect with ID 10
+sound 0, 3 ; Stops playing the last sound effect
+sound 5, 2, 50, 3 ; Plays sound effect 5 three times at 50% volume
+```
+
+**Use Cases:**
+
+- Playing sound effects to provide feedback or enhance the game
+ atmosphere.
+- Creating audio cues for events or actions.
+- Implementing music or background sounds.
+
+**Note:** The `SOUND` opcode requires the interpreter to support sound
+effects. The `%FSOUN` flag in the `FLAGS` word and the `%XSOUN` bit in
+the `MODE` byte indicate whether sound operations are available.
+
+### SPLIT
+
+**SPLIT** is an opcode that divides the screen vertically between
+windows 0 and 1. It is used to create a split-screen display, with
+each window showing different content.
+
+**Syntax:**
+
+``` {.assembly}
+split height:int
+```
+
+**Functionality:**
+
+The `split` opcode adjusts the vertical dimensions and positions of
+windows 0 and 1 as follows:
+
+- **Sets window 1 height:** The height of window 1 is set to the
+ value of `height` in lines.
+- **Sets window 1 position:** The top of window 1 is placed at the
+ top of the screen (line 1).
+- **Adjusts window 0 position:** The top of window 0 is moved down
+ to the line following the bottom of window 1.
+- **Adjusts window 0 height:** The height of window 0 is adjusted to
+ fill the remaining space on the screen.
+- **Selects window 0:** After splitting the screen, window 0 becomes
+ the active window for output.
+
+**Special Cases:**
+
+- **`height` = 0:** This effectively unsplits the screen, setting
+ the height of window 1 to 0 and making window 0 occupy the entire
+ screen.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+split 10 ; Splits the screen, giving window 1 a height of 10 lines
+split 0 ; Unsplits the screen
+```
+
+**Use Cases:**
+
+- Creating a split-screen display to show different information or
+ perspectives simultaneously.
+- Implementing status displays or separate areas for text output and
+ input.
+
+**Note:** The `SPLIT` opcode is a convenient way to create a
+split-screen display, but it only affects windows 0 and 1. For more
+flexible window management, consider using the `WINPOS` and `WINSIZE`
+opcodes.
+
+### SUB
+
+**SUB** is an opcode that performs subtraction on two 16-bit word
+values. It subtracts the second operand from the first operand and
+returns the result.
+
+**Syntax:**
+
+``` {.assembly}
+sub arg1:int, arg2:int > val
+```
+
+**Functionality:**
+
+The `sub` opcode performs the following:
+
+- **Subtracts `arg2` from `arg1`:** Performs integer subtraction.
+- **Stores the result:** The difference is stored in the specified
+ destination (`val`). If no destination is provided, the result is
+ pushed onto the game stack.
+
+**Special Cases:**
+
+- If the result of the subtraction overflows the 16-bit word size,
+ an error occurs.
+
+**Error Conditions:**
+
+An error occurs if the subtraction result overflows the 16-bit word
+range.
+
+**Examples:**
+
+``` {.assembly}
+sub 10, 5 > result ; Subtracts 5 from 10, stores the difference (5) in `result`
+```
+
+**Use Cases:**
+
+- Performing integer subtraction calculations.
+- Decreasing values or calculating differences between numbers.
+
+**Note:** The `sub` opcode performs signed integer subtraction. If the
+operands are unsigned, the programmer needs to handle potential
+overflow conditions.
+
+### THROW
+
+**THROW** is an opcode that throws an exception and returns from a
+previously called function with a specified value. It is used in
+conjunction with the `CATCH` opcode to implement exception handling
+and non-local control flow.
+
+**Syntax:**
+
+``` {.assembly}
+throw value, frame
+```
+
+**Functionality:**
+
+The `throw` opcode performs the following:
+
+- **Sets return value:** The specified `value` is set as the return
+ value of the function identified by the `frame` pointer.
+- **Unwinds stack:** The interpreter unwinds the call stack,
+ returning from all functions called since the function where the
+ corresponding `CATCH` opcode was executed.
+- **Resumes execution:** Control is transferred back to the
+ instruction following the `CATCH` opcode in the function that
+ caught the exception.
+
+**Special Cases:**
+
+- The `frame` pointer must be a valid frame pointer obtained from a
+ previous `CATCH` opcode.
+- Throwing an exception to a frame that is no longer on the call
+ stack results in an error.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `frame` is not a valid frame pointer.
+- The frame pointed to by `frame` is no longer on the call stack.
+
+**Examples:**
+
+``` {.assembly}
+catch > frame
+; ... some code that might throw an exception ...
+throw "Error!", frame ; Throws an exception and returns to the `catch` instruction
+```
+
+**Use Cases:**
+
+- Implementing exception handling to deal with errors or unexpected
+ conditions.
+- Performing non-local control flow, such as exiting multiple nested
+ functions at once.
+
+**Note:** The `THROW` and `CATCH` opcodes provide a mechanism for
+exception handling and non-local control flow in Z-code programs. They
+should be used with caution to avoid complex control flow and
+potential errors.
+
+### VALUE
+
+**VALUE** is an opcode that retrieves the value of a variable and
+stores it in a specified destination. It is used to access the current
+value of a variable and use it in calculations or other operations.
+
+**Syntax:**
+
+``` {.assembly}
+value var > val
+```
+
+**Functionality:**
+
+The `value` opcode performs the following:
+
+- **Retrieves variable value:** Reads the value of the specified
+ variable (`var`).
+- **Stores the result:** The retrieved value is stored in the
+ specified destination (`val`). If no destination is provided, the
+ result is pushed onto the game stack.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+value score > current_score ; Retrieves the value of `score` and stores it in `current_score`
+```
+
+**Use Cases:**
+
+- Accessing the current value of a variable for calculations or
+ comparisons.
+- Passing variable values as arguments to functions.
+- Storing variable values in other variables or data structures.
+
+**Note:** The `VALUE` opcode is a simple way to retrieve the value of
+a variable. It is equivalent to using the variable directly as an
+operand in most instructions.
+
+### VERIFY
+
+**VERIFY** is an opcode that checks the integrity of the game file by
+comparing a calculated checksum with a stored checksum value. It is
+used to detect potential corruption or modifications of the game data.
+
+**Syntax:**
+
+``` {.assembly}
+verify /pred
+```
+
+**Functionality:**
+
+The `verify` opcode performs the following:
+
+- **Calculates checksum:** Computes a 16-bit checksum of the game
+ file data from byte 64 to the end of the file (excluding the
+ header).
+- **Compares with stored checksum:** Compares the calculated
+ checksum with the value stored in the `PCHKSM` word of the program
+ header.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the calculated checksum matches the stored checksum.
+ Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- The checksum calculation excludes the first 64 bytes of the game
+ file, which contain the program header.
+- The `PLENTH` word in the program header specifies the length of
+ the game file in units of 8 bytes.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+verify / handle_corruption ; Branch to `handle_corruption` if the game file is corrupted
+```
+
+**Use Cases:**
+
+- Detecting unauthorized modifications or corruption of the game
+ file.
+- Implementing copy protection mechanisms.
+- Ensuring data integrity before loading or saving games.
+
+**Note:** The effectiveness of the `VERIFY` opcode depends on the
+strength of the checksum algorithm and the implementation of copy
+protection measures.
+
+### WINATTR
+
+**WINATTR** is an opcode that modifies the attributes of a window.
+Window attributes control various aspects of the window's behavior,
+such as text wrapping, scrolling, and transcripting.
+
+**Syntax:**
+
+``` {.assembly}
+winattr window:int, bits:int, operation:int
+```
+
+**Functionality:**
+
+The `winattr` opcode modifies the attributes of the specified window
+(`window`) based on the `bits` and `operation` arguments:
+
+- **`bits`:** A bitmask where each bit represents a specific window
+ attribute:
+ - Bit 0: Text wrapping (1 = enabled, 0 = disabled).
+ - Bit 1: Scrolling (1 = enabled, 0 = disabled).
+ - Bit 2: Transcripting (1 = enabled, 0 = disabled).
+ - Bit 3: Buffering (1 = enabled, 0 = disabled).
+- **`operation`:** Specifies how to modify the attributes:
+ - **0 (MOVE):** Sets the window attributes to the values
+ specified by `bits`.
+ - **1 (SET):** Sets the attributes corresponding to the bits
+ that are set (1) in `bits`.
+ - **2 (CLEAR):** Clears the attributes corresponding to the bits
+ that are set (1) in `bits`.
+ - **3 (COMP):** Toggles the attributes corresponding to the bits
+ that are set (1) in `bits`.
+
+**Special Cases:**
+
+- If the `operation` argument is omitted, it defaults to 0 (MOVE).
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `operation` is not within the valid range (0-3).
+
+**Examples:**
+
+``` {.assembly}
+winattr 1, 1, 1 ; Enables text wrapping for window 1
+winattr 2, 6, 2 ; Disables scrolling and transcripting for window 2
+```
+
+**Use Cases:**
+
+- Changing the behavior of windows based on game logic or player
+ actions.
+- Enabling or disabling text wrapping, scrolling, or transcripting
+ for specific windows.
+- Customizing the appearance and functionality of the game
+ interface.
+
+**Note:** The `WINATTR` opcode provides a flexible way to modify
+window attributes. It is important to understand the meaning of each
+bit in the `bits` argument and the effect of the different operations.
+
+### WINGET
+
+**WINGET** is an opcode that retrieves the value of a specific
+property from a window's property table. Window properties store
+information about the window's position, size, attributes, and other
+characteristics.
+
+**Syntax:**
+
+``` {.assembly}
+winget window:int, property:int > val
+```
+
+**Functionality:**
+
+The `winget` opcode retrieves the value of the property specified by
+`property` from the property table of the window identified by
+`window`:
+
+- **`window`:** The number of the window to access.
+- **`property`:** The number of the property to retrieve. Valid
+ property numbers and their corresponding meanings are:
+ - 0: `WTOP` - Y position of the window (top edge, in screen
+ units).
+ - 1: `WLEFT` - X position of the window (left edge, in screen
+ units).
+ - 2: `WHIGH` - Height of the window in screen units.
+ - 3: `WWIDE` - Width of the window in screen units.
+ - 4: `WYPOS` - Y coordinate of the cursor within the window (row
+ number, 1-based).
+ - 5: `WXPOS` - X coordinate of the cursor within the window
+ (column number, 1-based).
+ - 6: `WLMARG` - Left margin of the window in pixels.
+ - 7: `WRMARG` - Right margin of the window in pixels.
+ - 8: `WCRFCN` - Function to call for carriage return interrupts.
+ - 9: `WCRCNT` - Counter for carriage return interrupts.
+ - 10: `WHLIGHT` - Highlighting mode of the window.
+ - 11: `WCOLOR` - Color word of the window (background and
+ foreground colors).
+ - 12: `WFONT` - Font ID used in the window.
+ - 13: `WFSIZE` - Font size (height and width) used in the
+ window.
+ - 14: `WATTRS` - Window attributes (wrapping, scrolling,
+ transcripting, buffering).
+ - 15: `WLCNT` - Line counter for the window.
+- **Stores the result:** The retrieved property value is stored in
+ the specified destination (`val`). If no destination is provided,
+ the result is pushed onto the game stack.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is used.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `property` is not a valid property number.
+
+**Examples:**
+
+``` {.assembly}
+winget 0, 2 > window_height ; Retrieves the height of the main window (window 0)
+winget 1, 14 > window_attrs ; Retrieves the attributes of window 1
+```
+
+**Use Cases:**
+
+- Accessing information about window properties, such as position,
+ size, or attributes.
+- Implementing custom window management or display routines.
+- Checking the state of specific window features.
+
+**Note:** The `WINGET` opcode provides a flexible way to access
+various window properties. It is important to use the correct property
+numbers to retrieve the desired information.
+
+### WINPOS
+
+**WINPOS** is an opcode that sets the position of a window on the
+screen. It allows for precise control over the location of windows
+within the display area.
+
+**Syntax:**
+
+``` {.assembly}
+winpos window:int, y:int, x:int
+```
+
+**Functionality:**
+
+The `winpos` opcode sets the position of the specified window
+(`window`) to the coordinates (`y`, `x`):
+
+- **`window`:** The number of the window to reposition.
+- **`y`:** The Y coordinate of the top-left corner of the window
+ (row number, 1-based).
+- **`x`:** The X coordinate of the top-left corner of the window
+ (column number, 1-based).
+
+The coordinates are specified in screen units, with the top-left
+corner of the screen being (1, 1).
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is
+ repositioned.
+- The opcode does not check if the new window position would place
+ the window partially or completely off-screen.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `y` or `x` is negative.
+
+**Examples:**
+
+``` {.assembly}
+winpos 1, 5, 10 ; Positions window 1 at row 5, column 10
+winpos 2, 1, 1 ; Positions window 2 at the top-left corner of the screen
+```
+
+**Use Cases:**
+
+- Positioning windows for optimal layout and user interface design.
+- Creating overlapping windows or dynamic window arrangements.
+- Implementing custom window management or animation routines.
+
+**Note:** The `WINPOS` opcode provides direct control over window
+positioning. It is important to consider the window's size and the
+overall screen layout when using this opcode.
+
+### WINPUT
+
+**WINPUT** is an opcode that sets the value of a specific property
+within a window's property table. It allows for modifying various
+aspects of a window's behavior and appearance.
+
+**Syntax:**
+
+``` {.assembly}
+winput window:int, property:int, value
+```
+
+**Functionality:**
+
+The `winput` opcode sets the value of the property specified by
+`property` in the property table of the window identified by `window`:
+
+- **`window`:** The number of the window to modify.
+- **`property`:** The number of the property to set. See the
+ description of `WINGET` for a list of valid property numbers and
+ their meanings.
+- **`value`:** The new value to assign to the property.
+
+**Special Cases:**
+
+- Not all window properties are writable using `WINPUT`. Some
+ properties, such as window size and position, require specific
+ opcodes like `WINSIZE` and `WINPOS` for modification.
+- If the `window` argument is omitted, the current window is used.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `property` is not a valid property number or is not writable.
+
+**Examples:**
+
+``` {.assembly}
+winput 1, 10, 2 ; Sets the highlighting mode of window 1 to bold
+winput 2, 6, 15 ; Sets the left margin of window 2 to 15 pixels
+```
+
+**Use Cases:**
+
+- Modifying window properties to change their behavior or
+ appearance.
+- Setting the highlighting mode, color, or font of a window.
+- Adjusting margins or other window settings.
+
+**Note:** The `WINPUT` opcode provides a way to modify window
+properties, but it is important to check which properties are writable
+and use the appropriate opcodes for those that are not.
+
+### WINSIZE
+
+**WINSIZE** is an opcode that sets the size of a window on the screen.
+It allows for controlling the dimensions of windows and adjusting the
+display area they occupy.
+
+**Syntax:**
+
+``` {.assembly}
+winsize window:int, height:int, width:int
+```
+
+**Functionality:**
+
+The `winsize` opcode sets the size of the specified window (`window`)
+to the given dimensions:
+
+- **`window`:** The number of the window to resize.
+- **`height`:** The new height of the window in screen units (number
+ of lines).
+- **`width`:** The new width of the window in screen units (number
+ of characters).
+
+If the new size would cause the window to extend beyond the screen
+boundaries, the dimensions are adjusted to fit within the available
+space.
+
+**Special Cases:**
+
+- If the `window` argument is omitted, the current window is
+ resized.
+- If the new size is smaller than the current cursor position, the
+ cursor is moved to the bottom-right corner of the resized window.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `window` is not within the valid range (-3 to 7).
+- `height` or `width` is zero or negative.
+
+**Examples:**
+
+``` {.assembly}
+winsize 1, 10, 40 ; Sets the size of window 1 to 10 lines by 40 characters
+winsize 2, 25, 80 ; Sets the size of window 2 to 25 lines by 80 characters (full screen width)
+```
+
+**Use Cases:**
+
+- Adjusting the size of windows to fit content or accommodate
+ different display requirements.
+- Creating windows with specific dimensions for menus, dialog boxes,
+ or other UI elements.
+- Implementing dynamic window resizing or animations.
+
+**Note:** The `WINSIZE` opcode provides direct control over window
+size. It is important to consider the window's position and the
+overall screen layout when using this opcode.
+
+### XCALL
+
+**XCALL** is an opcode that calls a function with a variable number of
+arguments and returns a value. It is the most general form of the
+`CALL` instruction, allowing for up to seven arguments to be passed to
+the function.
+
+**Syntax:**
+
+``` {.assembly}
+xcall fcn, arg1:any [, arg2:any ...] > val
+```
+
+**Functionality:**
+
+The `xcall` opcode performs the following:
+
+- **Pushes arguments onto the stack:** Pushes the variable number of
+ arguments (`arg1`, `arg2`, etc.) onto the game stack. The number
+ of arguments is determined by the operand types specified in the
+ instruction.
+- **Calls the function:** Transfers control to the function
+ specified by `fcn`. The function address is calculated by shifting
+ `fcn` left by two bits and adding the function offset (`FOFF`)
+ shifted left by three bits.
+- **Retrieves return value:** When the function returns, its return
+ value is retrieved and stored in the specified destination
+ (`val`). If no destination is provided, the value is pushed onto
+ the game stack.
+
+**Special Cases:**
+
+- If `fcn` is zero, the `xcall` opcode acts as if it called a
+ function that immediately returned false.
+
+**Error Conditions:**
+
+An error occurs if `fcn` is not a valid function pointer.
+
+**Examples:**
+
+``` {.assembly}
+xcall format_string, buffer, arg1, arg2, arg3 > formatted_text ; Calls the `format_string` function with four arguments
+```
+
+**Use Cases:**
+
+- Calling functions with a variable number of arguments.
+- Implementing functions that take a flexible number of parameters.
+
+**Note:** The `XCALL` opcode is generated by the compiler when it
+detects a function call with more than two arguments or when the
+argument types require the extended format. It is not typically used
+directly by programmers.
+
+### XPUSH
+
+**XPUSH** is an opcode that attempts to push a value onto a stack and
+acts as a predicate based on the success of the operation. It can be
+used with both the game stack and user-defined stacks.
+
+**Syntax:**
+
+``` {.assembly}
+xpush value, stack:tbl /pred
+```
+
+**Functionality:**
+
+The `xpush` opcode performs the following:
+
+- **Checks stack space:** Determines if there is enough space
+ available on the specified stack (`stack`) to push the value.
+- **Pushes value (if space available):** If there is sufficient
+ space, the opcode pushes the `value` onto the top of the stack.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if the value was successfully pushed onto the stack.
+ Otherwise, the predicate fails (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+- If the `stack` argument is omitted, the opcode operates on the
+ game stack.
+
+**Error Conditions:**
+
+An error occurs if `stack` is not a valid table pointer (if provided).
+
+**Examples:**
+
+``` {.assembly}
+xpush item, inventory / inventory_full ; Attempts to push `item` onto the `inventory` stack
+; ... code to handle full inventory ...
+inventory_full:
+```
+
+**Use Cases:**
+
+- Pushing values onto stacks while checking for potential stack
+ overflow conditions.
+- Implementing stack-based data structures with overflow handling.
+
+**Note:** The `XPUSH` opcode provides a way to push values onto stacks
+while simultaneously checking for available space. This can be useful
+for preventing stack overflow errors and implementing robust stack
+management.
+
+### ZERO?
+
+**ZERO?** is an opcode that checks whether a value is equal to zero.
+It acts as a predicate, meaning it evaluates a condition and
+implicitly performs a conditional branch based on the result.
+
+**Syntax:**
+
+``` {.assembly}
+zero? arg:any /pred
+```
+
+**Functionality:**
+
+The `zero?` opcode performs the following:
+
+- **Checks for zero:** Determines if the value of `arg` is equal to
+ zero.
+- **Evaluates predicate:** The predicate succeeds (evaluates to
+ true) if `arg` is indeed zero. Otherwise, the predicate fails
+ (evaluates to false).
+- **Conditional branch:** Based on the predicate result and the
+ specified branch polarity (`/pred`), the interpreter may perform a
+ conditional jump to a specified target.
+
+**Special Cases:**
+
+None.
+
+**Error Conditions:**
+
+None.
+
+**Examples:**
+
+``` {.assembly}
+zero? counter / end_loop ; Branch to `end_loop` if `counter` is zero
+```
+
+**Use Cases:**
+
+- Implementing conditional logic based on zero checks.
+- Determining if a variable or expression has a value of zero.
+- Loop termination conditions.
+
+**Note:** The `ZERO?` opcode is a simple but useful predicate for
+checking for zero values and implementing conditional behavior in
+Z-code programs.
+
+### ZWSTR
+
+**ZWSTR** is an opcode that converts a word from an input buffer into
+a Z-string and stores it in a specified location. Z-strings are the
+standard format for representing text in Z-code programs.
+
+**Syntax:**
+
+``` {.assembly}
+zwstr inbuf:tbl, inlen:int, inbeg:int, zword:tbl
+```
+
+**Functionality:**
+
+The `zwstr` opcode performs the following:
+
+- **Reads input word:** Extracts the word starting at the byte
+ offset `inbeg` within the input buffer `inbuf`. The `inlen`
+ argument specifies the length of the word in bytes, but it is not
+ strictly necessary as the opcode assumes the word is terminated by
+ a break character (whitespace or a self-inserting break
+ character).
+- **Converts to Z-string:** Encodes the extracted word into a
+ Z-string using the current character set and frequent words table.
+- **Stores the result:** The encoded Z-string is stored in the first
+ three words of the `zword` table.
+
+**Special Cases:**
+
+- The `inbuf` argument is typically a pointer to the text buffer
+ used by the `READ` or `LEX` opcodes.
+- The `zword` table must have at least three words of available
+ space to store the Z-string.
+
+**Error Conditions:**
+
+An error occurs if:
+
+- `inbuf` or `zword` is not a valid table pointer.
+- `inbeg` is outside the bounds of the `inbuf` table.
+- The `zword` table does not have enough space to store the
+ Z-string.
+
+**Examples:**
+
+``` {.assembly}
+read input_buffer, lexv
+zwstr input_buffer, 0, lexv[1].offset, word_buffer ; Converts the second word from the parsed input into a Z-string
+```
+
+**Use Cases:**
+
+- Converting words from input buffers into Z-strings for further
+ processing or comparison.
+- Implementing custom parsing or text manipulation routines.
+
+**Note:** The `ZWSTR` opcode is used to convert words from input
+buffers into the Z-string format used by the Z-machine. It is
+typically used in conjunction with the `READ` or `LEX` opcodes for
+processing player input.
+
+Chapter 3.2: Opcode Summary Table
+---------------------------------
+
+ --------------------------------------------------------------------------------------
+ Opcode Name Operands Type Description
+ -------- ------------- --------------- ------ ----------------------------------------
+ 1 EQUAL? arg1:any, 2OP Is arg1 equal to any one of arg2, arg3,
+ arg2:any or arg4? Note that in the extended form,
+ EQUAL? can take more than two operands.
+
+ 2 LESS? arg1:int, 2OP Is arg1 less than arg2?
+ arg2:int
+
+ 3 GRTR? arg1:int, 2OP Is arg1 greater than arg2?
+ arg2:int
+
+ 4 DLESS? var, int 2OP Decrements var and succeeds if new value
+ is less than int.
+
+ 5 IGRTR? var, int 2OP Increments var and succeeds if new value
+ is greater than int.
+
+ 6 IN? child:obj, 2OP Is child contained in parent?
+ parent:obj
+
+ 7 BTST arg1:word, 2OP Are bits on in arg2 also on in arg1?
+ arg2:word
+
+ 8 BOR arg1:word, 2OP Bitwise logical OR.
+ arg2:word
+
+ 9 BAND arg1:word, 2OP Bitwise logical AND.
+ arg2:word
+
+ 10 FSET? obj, flag 2OP Is flag number set in obj?
+
+ 11 FSET obj, flag 2OP Sets flag in obj.
+
+ 12 FCLEAR obj, flag 2OP Clears flag in obj.
+
+ 13 SET var, any 2OP Sets variable to any.
+
+ 14 MOVE thing:obj, 2OP Puts thing into dest as the first
+ dest:obj object.
+
+ 15 GET table, item 2OP Returns item'th element of table
+ (word-oriented).
+
+ 16 GETB table, item 2OP Returns item'th element of table
+ (byte-oriented).
+
+ 17 GETP obj, prop 2OP Returns prop property of obj.
+
+ 18 GETPT obj, prop 2OP Returns pointer to property table prop
+ from obj.
+
+ 19 NEXTP obj, prop 2OP Returns number of the property following
+ prop in obj.
+
+ 20 ADD arg1:int, 2OP Adds the integers.
+ arg2:int
+
+ 21 SUB arg1:int, 2OP Subtracts arg2 from arg1.
+ arg2:int
+
+ 22 MUL arg1:int, 2OP Multiplies the integers.
+ arg2:int
+
+ 23 DIV arg1:int, 2OP Divides arg1 by arg2, returning the
+ arg2:int truncated quotient.
+
+ 24 MOD arg1:int, 2OP Divides arg1 by arg2, returning the
+ arg2:int remainder.
+
+ 25 CALL2 fcn, any 2OP Calls the function pointed to by fcn.
+
+ 26 ICALL2 routine:fcn, 2OP Calls the function pointed to by fcn (no
+ arg1:any return value).
+
+ 27 COLOR fore:int, 2OP Sets foreground and background color.
+ back:int
+
+ 28 THROW any, frame 2OP Returns any from a frame (see CATCH).
+
+ 128 ZERO? arg:any 1OP Is arg equal to zero?
+
+ 129 NEXT? obj 1OP Returns the "next" slot of obj (fails if
+ none).
+
+ 130 FIRST? obj 1OP Returns the "first" slot of obj (fails
+ if none).
+
+ 131 LOC obj 1OP Returns the "parent" of obj (zero if
+ none).
+
+ 132 PTSIZE table 1OP Returns length of property table in
+ bytes.
+
+ 133 INC var 1OP Increments the value of var by one.
+
+ 134 DEC var 1OP Decrements the value of var by one.
+
+ 135 PRINTB str 1OP Prints the string pointed to by str
+ (byte pointer).
+
+ 136 CALL1 fcn 1OP Calls the function pointed to by fcn.
+
+ 137 REMOVE obj 1OP Removes obj from the object tree.
+
+ 138 PRINTD obj 1OP Prints the short description of obj.
+
+ 139 RETURN any 1OP Returns from the most recently executed
+ call.
+
+ 140 JUMP loc 1OP Unconditional relative branch.
+
+ 141 PRINT str 1OP Prints the string pointed to by str
+ (quad pointer).
+
+ 142 VALUE var 1OP Returns the value of var.
+
+ 143 ICALL1 routine:fcn 1OP Calls the function pointed to by fcn (no
+ return value).
+
+ 176 RTRUE 0OP Returns 1 (true).
+
+ 177 RFALSE 0OP Returns 0 (false).
+
+ 178 PRINTI (in-line 0OP Prints an immediate string.
+ string)
+
+ 179 PRINTR (in-line 0OP Prints an immediate string and executes
+ string) CRLF + RTRUE.
+
+ 180 NOOP 0OP No operation.
+
+ 183 RESTART 0OP Reinitializes the game.
+
+ 184 RSTACK 0OP Returns from a call and takes value from
+ stack.
+
+ 185 CATCH 0OP Returns a pointer to the current call
+ frame.
+
+ 186 QUIT 0OP Terminates the game.
+
+ 187 CRLF 0OP Prints an end-of-line sequence.
+
+ 188 (Unused)
+
+ 189 VERIFY 0OP Verifies the game program on disk.
+
+ 190 EXTOP opcode:int 0OP Signals the next opcode is an extended
+ opcode.
+
+ 191 ORIGINAL? 0OP Returns non-false if the game disk is
+ the original.
+
+ 193 EQUAL? arg1:any, EXT Is arg1 equal to any of the other
+ arg2:any, ... arguments?
+
+ 224 CALL fcn, any1, EXT Calls the function pointed to by fcn.
+ any2, any3
+
+ 225 PUT table, item, EXT Sets the word pointed to in table to
+ any any.
+
+ 226 PUTB table, item, EXT Sets the byte pointed to in table to the
+ any low byte of any.
+
+ 227 PUTP obj, prop, any EXT Changes the value of obj's property prop
+ to any.
+
+ 228 READ inbuf:tbl, EXT Reads a line of input and parses it.
+ lexv:tbl,
+ time:int,
+ handler:fcn
+
+ 229 PRINTC int EXT Prints the character whose ASCII value
+ is int.
+
+ 230 PRINTN int EXT Prints int as a signed number.
+
+ 231 RANDOM arg:int EXT Returns a random value between 1 and
+ arg.
+
+ 232 PUSH value EXT Pushes value onto the game stack.
+
+ 233 POP stack EXT Pops a value from the stack.
+
+ 234 SPLIT height:int EXT Splits the screen vertically between
+ windows 0 and 1.
+
+ 235 SCREEN window:int EXT Selects the specified window for output.
+
+ 236 XCALL fcn, any1, ..., EXT Calls the function pointed to by fcn (up
+ any7 to 7 args).
+
+ 237 CLEAR window:int EXT Clears the specified window.
+
+ 238 ERASE int EXT Erases a portion of the current line.
+
+ 239 CURSET y:int, x:int, EXT Sets the cursor position in the
+ window specified window.
+
+ 240 CURGET output:tbl EXT Returns information about the current
+ cursor position.
+
+ 241 HLIGHT int EXT Sets the display highlighting mode.
+
+ 242 BUFOUT int EXT Controls output buffering.
+
+ 243 DIROUT device:int, EXT Selects or deselects a virtual output
+ any1, any2, device.
+ any3
+
+ 244 DIRIN device:int, EXT Selects or deselects a virtual input
+ any1, any2, device.
+ any3
+
+ 245 SOUND id:int, op:int, EXT Produces a sound.
+ volume:int,
+ repeat:int
+
+ 246 INPUT dev:int, EXT Returns a single byte from the specified
+ time:int, device.
+ handler:fcn
+
+ 247 INTBL? item, tbl, EXT Searches for a record in a table.
+ len:int,
+ recspec:int
+
+ 248 BCOM arg:word 1OP Performs a bitwise logical NOT
+ (complement) on the word.
+
+ 249 ICALL routine:fcn, EXT Calls the function pointed to by fcn (no
+ arg1:any, return value).
+ arg2:any,
+ arg3:any
+
+ 250 IXCALL routine:fcn, EXT Calls the function pointed to by fcn
+ arg1,... (variable args, no return value).
+
+ 251 LEX inbuf:tbl, EXT Tokenizes and looks up an input buffer's
+ lexv:tbl, contents.
+ lexicon:tbl,
+ preserve:bool
+
+ 252 ZWSTR inbuf:tbl, EXT Converts a word to a Z-string.
+ inlen:int,
+ inbeg:int,
+ zword:tbl
+
+ 253 COPYT source:tbl, EXT Copies bytes from source to dest.
+ dest:tbl,
+ length:int
+
+ 254 PRINTT bytes:tbl, EXT Prints a block of text from a table.
+ width:int,
+ height:int,
+ skip:int
+
+ 255 ASSIGNED? opt:var EXT Checks if an optional argument was
+ supplied.
+
+ 256 SAVE start:tbl, EXT Saves a section of the game state.
+ length:int,
+ name:tbl
+
+ 257 RESTORE start:tbl, EXT Restores a section of the game state.
+ length:int,
+ name:tbl
+
+ 258 SHIFT int, n EXT Performs a logical shift on int.
+
+ 259 ASHIFT int, n EXT Performs an arithmetic shift on int.
+
+ 260 FONT font:int, EXT Selects a font for the specified window.
+ window
+
+ 261 DISPLAY picture:int, EXT Displays a picture at the specified
+ y:int, x:int location.
+
+ 262 PICINF picture:int, EXT Returns information about a picture.
+ data:tbl
+
+ 263 DCLEAR picture:int, EXT Clears the area occupied by a picture.
+ y:int, x:int
+
+ 264 MARGIN left:int, EXT Sets the left and right margins for a
+ right:int, window.
+ window
+
+ 265 ISAVE EXT Saves the game state to a reserved area
+ in RAM.
+
+ 266 IRESTORE EXT Restores the game state from the
+ reserved area in RAM.
+
+ 272 WINPOS window:int, y, EXT Sets the location of the top left corner
+ x of a window.
+
+ 273 WINSIZE window, y, x EXT Sets the size of a window.
+
+ 274 WINATTR window, bits, EXT Sets characteristics of a window.
+ operation
+
+ 275 WINGET window, offset EXT Returns the value of a window property.
+
+ 276 SCROLL window, lines EXT Scrolls the specified window up or down.
+
+ 277 FSTACK n, stack EXT Flushes n elements from the specified
+ stack.
+
+ 278 MOUSE-INFO table EXT Returns information about the mouse
+ status.
+
+ 279 MOUSE-LIMIT window EXT Restricts the mouse to a specific
+ window.
+
+ 280 XPUSH value, stack EXT Pushes value onto the specified stack.
+
+ 281 WINPUT window, offset, EXT Sets the value of a window property.
+ value
+
+ 282 PRINTF tbl EXT Prints a formatted table.
+
+ 283 MENU id, tbl EXT Adds a menu to the menu bar.
+
+ 284 PICSET tbl EXT A table of picture numbers to pre-load
+ or cache for faster display. Pictures not
+ included in the most recent PICSET call are
+ no longer considered "hot" and can be safely
+ removed from the cache.
+ --------------------------------------------------------------------------------------