Add initial work for zap documentation
[zap-docs.git] / zap
1 Copyright & Licensing
2 ---------------------
3
4 Copyright (C) 2024 Jason Self <j@jxself.org>
5
6 You can redistribute and/or modify this file under the terms of the
7 GNU General Public License as published by the Free Software
8 Foundation, either version 3 of the License, or (at your option) any
9 later version.
10
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this file. If not, see <https://www.gnu.org/licenses/>.
18
19 Chapter 1.1: Overview of ZAP and its Purpose
20 --------------------------------------------
21
22 ZAP (Z-language Assembly Program) is a software tool used to translate 
23 assembly language code written for the Z-machine into a binary format 
24 that can be directly executed by a compatible Z-language Interpreter 
25 Program (ZIP).
26
27 The Z-machine is a virtual machine specifically designed for running 
28 interactive fiction games, also known as text adventures. Infocom 
29 originally developed the Z-machine and its associated programming 
30 language, ZIL (Zork Implementation Language) but now these belong to 
31 the community.
32
33 ZAP is the last stage of the toolchain, after the source code has been 
34 compiled into a a human-readable assembly language format. This 
35 assembly language is then processed by ZAP, which converts it into the 
36 binary format understood by the Z-machine.
37
38 ZAP is a two-pass assembler, meaning it processes the input file
39 twice. In the first pass, it analyzes the code, builds symbol tables,
40 and calculates addresses. In the second pass, it generates the binary
41 code and resolves any forward references to symbols.
42
43 This specification document provides a detailed explanation of ZAP's
44 functionality, including the supported assembly language syntax, data
45 structures, algorithms, and error handling mechanisms. It serves as a
46 guide for understanding and implementing ZAP.
47
48 ZAP is an integral component of the development system for interactive 
49 fiction games. It bridges the gap between the high-level ZIL (Zork 
50 Implementation Language) and the low-level Z-code that runs on the 
51 Z-machine. Here's how ZAP fits into the overall development process:
52
53 1.  **Game Design and Implementation:** Game designers and programmers
54     use a high-level language (the Zork Implementation Language, or 
55     ZIL) to define the game's world, objects, characters, and 
56     interactions. ZIL provides a more abstract and convenient way to 
57     express the game's logic compared to directly writing Z-code 
58     instructions.
59 2.  **ZIL Compilation:** The ZIL code is compiled into Z-code assembly
60     language. This assembly language represents the Z-code
61     instructions and data in a human-readable format.
62 3.  **ZAP Assembly:** ZAP takes the Z-code assembly language as input
63     and translates it into the binary format understood by the
64     Z-machine. This binary code is what ultimately gets executed by
65     the ZIP interpreter.
66
67 Chapter 1.2: Goals and Design Principles of ZAP
68 -----------------------------------------------
69
70 ZAP was designed with several key goals and principles in mind:
71
72 **Goals:**
73
74 -   **Provide a convenient and efficient way to write Z-code
75     programs:** ZAP's assembly language allows programmers to express
76     Z-code instructions and data in a more readable and structured
77     format compared to directly writing binary code.
78 -   **Generate optimized and efficient Z-code:** ZAP optimizes the
79     generated code for efficient execution on the Z-machine, ensuring
80     smooth gameplay and minimizing memory usage.
81 -   **Support debugging and troubleshooting:** ZAP can generate
82     optional listing files that provide insights into the generated
83     code, aiding in debugging and identifying issues.
84 -   **Maintain portability across different platforms:** ZAP itself is
85     designed to be portable and run on various machines, allowing for
86     cross-platform development.
87
88 **Design Principles:**
89
90 -   **Simplicity and clarity:** ZAP's assembly language syntax is
91     designed to be straightforward and easy to understand, minimizing
92     the learning curve for programmers.
93 -   **Efficiency:** ZAP optimizes the generated code for efficient
94     execution on the Z-machine, taking advantage of the architecture's
95     features.
96 -   **Flexibility:** ZAP provides various directives and options to
97     give programmers control over the assembly process and allow for
98     customization.
99 -   **Error detection and reporting:** ZAP incorporates robust error
100     detection mechanisms and provides informative error messages to
101     help programmers identify and fix issues.
102 -   **Modularity:** ZAP is organized into well-defined modules, each
103     responsible for specific tasks, promoting code maintainability and
104     extensibility.
105
106 These goals and design principles have guided the development of ZAP
107 and continue to be relevant in understanding its functionality and
108 behavior. By adhering to these principles, ZAP provides a powerful and
109 efficient tool for assembling Z-code programs for interactive fiction
110 games.
111
112 Chapter 1.3: Target Audience for the Specification
113 --------------------------------------------------
114
115 This specification document is primarily intended for the following
116 audiences:
117
118 -   **Z-machine enthusiasts and researchers:** The specification
119     offers detailed insights into the Z-code assembly language, ZAP's
120     internal workings, and the overall structure of Z-machine
121     programs. This information can be valuable for individuals
122     interested in understanding the Z-machine architecture and its
123     associated tools.
124 -   **Interactive fiction developers:** Understanding ZAP's 
125     functionality and the Z-code it generates can be beneficial for
126     game designers and programmers.
127
128 The document assumes a basic understanding of assembly language
129 concepts and the Z-machine architecture. However, it provides
130 sufficient detail and explanations to be accessible to individuals
131 with a general interest in interactive fiction and the technical
132 aspects of the Z-machine.
133
134 By catering to these different audiences, the specification aims to 
135 contribute to the understanding of the Z-machine, and support the 
136 continued development of interactive fiction games.
137
138 Chapter 2.1: Character Set and Lexical Elements
139 -----------------------------------------------
140
141 The Z-code assembly language used by ZAP consists of a defined
142 character set and specific lexical elements that form the building
143 blocks of instructions and directives.
144
145 **Character Set:**
146
147 The following characters are allowed in a ZAP program:
148
149 -   **Letters:** A-Z (case-insensitive)
150 -   **Digits:** 0-9
151 -   **Special characters:** , ? \# . - \_ ' \" /  : ( )
152 -   **Whitespace:** Space and tab characters are ignored except as
153     operand prefixes.
154 -   **Line endings:** Carriage return (`\r`), line feed (``), and form
155     feed (`\f`) characters are ignored.
156
157 **Lexical Elements:**
158
159 ZAP recognizes the following lexical elements:
160
161 -   **Symbols:** Used to represent values and labels. They consist of
162     letters, digits, and some special characters. By convention,
163     pseudo-ops (assembler directives) begin with a period (`.`).
164 -   **Numbers:** Represent integer values.
165 -   **Strings:** Enclosed in double quotes (`"`). Double quotes within
166     strings are escaped by using two consecutive double quotes.
167 -   **Operators:** Predefined symbols representing Z-machine
168     instructions.
169 -   **Pseudo-ops (directives):** Instructions to the assembler, such
170     as `.word`, `.str`, and `.funct`.
171 -   **Operand prefixes:** Special characters used to indicate the type
172     of operand following them (e.g., `,` for general operand, `>` for
173     return value).
174 -   **Comments:** Begin with a semicolon (`;`) and extend to the end
175     of the line.
176
177 These lexical elements are combined to form valid assembly language
178 statements that are processed by ZAP.
179
180 **Note:** This chapter provides a basic overview of the character set
181 and lexical elements. More detailed information about specific
182 elements and their usage will be presented in subsequent chapters.
183
184 Chapter 2.2: Symbol Definition and Types (Global, Local, Constants)
185 -------------------------------------------------------------------
186
187 Symbols in ZAP are used to represent various types of values and
188 labels within the program. They play a crucial role in code
189 organization, readability, and address resolution.
190
191 **Symbol Definition:**
192
193 A symbol is defined by assigning it a value using either:
194
195 -   **Equate statement:** `symbol = value`
196 -   **Pseudo-op:** `.equal symbol, value`
197 -   **Label definition:** `symbol::` or `symbol:`
198
199 **Symbol Types:**
200
201 ZAP distinguishes between three main types of symbols:
202
203 -   **Global symbols:** Defined outside of any function and accessible
204     throughout the entire program. They can represent global
205     variables, function names, table names, and string names.
206 -   **Local symbols:** Defined within a function using the `.funct`
207     directive and accessible only within that function. They represent
208     local variables and labels used for branching within the function.
209 -   **Constants:** Represent fixed values that cannot be changed. They
210     are defined using equate statements or specific pseudo-ops like
211     `.seq`.
212
213 **Naming Conventions:**
214
215 The following naming conventions exist:
216
217 -   **Pseudo-ops:** Begin with a period (`.`).
218 -   **Global labels:** End with two colons (`::`).
219 -   **Local labels:** End with one colon (`:`)
220
221 **Symbol Redefinition:**
222
223 -   **Global and local symbols:** Cannot be redefined within their
224     scope. Attempting to do so will result in an error.
225 -   **Constants:** Can be redefined at any point in the program.
226
227 **Predefined Symbols:**
228
229 ZAP includes several predefined global symbols:
230
231 -   **Operators:** Represent Z-machine instructions (e.g., `ADD`,
232     `SUB`, `PRINT`).
233 -   **Pseudo-ops:** Represent assembler directives (e.g., `.word`,
234     `.str`, `.funct`).
235 -   **Special symbols:** Represent specific data structures or
236     locations within the program (e.g., `VOCAB`, `OBJECT`, `STACK`).
237
238 Understanding symbol definition and types is essential for writing
239 well-structured and organized Z-code assembly programs. By following
240 the conventions and understanding the scope of different symbol types,
241 programmers can ensure proper address resolution and code
242 functionality.
243
244 Chapter 2.3: Statement Syntax and Structure
245 -------------------------------------------
246
247 ZAP assembly language statements are line-oriented, meaning each
248 statement occupies a single line in the source file. Each statement
249 consists of four optional fields:
250
251 **Statement Structure:**
252
253     [label] [operator] [operands] [comment]
254
255 **Field Descriptions:**
256
257 -   **Label:** A symbol followed by one or two colons, depending on
258     whether it's a local or global label.
259 -   **Operator:** A predefined symbol representing either an operator
260     (Z-machine instruction) or a pseudo-op (assembler directive).
261 -   **Operands:** A space or tab-separated list of operands, each
262     optionally preceded by an operand prefix character.
263 -   **Comment:** Begins with a semicolon (`;`) and extends to the end
264     of the line.
265
266 **Examples:**
267
268 ``` {.assembly}
269 START::  .funct main        ; Define the main function
270         add 1, 2           ; Add two constants
271         print "Hello"       ; Print a string
272         jump END            ; Jump to the END label
273 END:
274 ```
275
276 **Operand Prefixes:**
277
278 Operand prefixes are special characters used to indicate the type of 
279 operand following them and provide additional information:
280
281 -   **`,` (comma):** General operand.
282 -   **`>` (greater than):** Return value operand. Specifies where the 
283     return value of an instruction should be stored
284 -   **`\` (backslash):** Branch on failure operand. Indicates the 
285     branch target if the predicate fails
286 -   **`/` (forward slash):** Branch on success operand. Indicates the
287     branch target if the predicate succeeds.
288 -   **`=` (equal sign):** Value operand for assignments. Used for 
289     assigning values to symbols
290 -   **`+` (plus sign):** Addend operand for constant addition.
291
292 **Line Continuation:**
293
294 Operands can be continued to the next line by placing the operand
295 prefix character on one line and the corresponding operand on the next
296 line.
297
298 **Note:** This chapter provides a general overview of statement syntax
299 and structure. More detailed information about specific operators,
300 pseudo-ops, and operands will be presented in subsequent chapters.
301
302 Chapter 2.4: Operands and Addressing Modes
303 ------------------------------------------
304
305 Operands in ZAP assembly language specify the data or values that
306 instructions operate on. ZAP supports three main types of operands:
307
308 **Operand Types:**
309
310 -   **Immediate:** A constant value directly encoded within the
311     instruction. It can be either a short (one-byte) or long
312     (two-byte) constant.
313 -   **Variable:** A reference to a variable stored in memory. The
314     operand specifies the variable number, which is interpreted
315     differently depending on the context.
316 -   **Other:** Represents special values like labels, function
317     pointers, or string pointers.
318
319 **Addressing Modes:**
320
321 ZAP uses different addressing modes to access and interpret operands:
322
323 -   **Direct addressing:** The operand directly specifies the value or
324     memory address of the data. This is used for immediate operands
325     and some other types.
326 -   **Indirect addressing:** The operand specifies the number of a
327     variable, which is then used to access the actual data in memory.
328     This is used for variable operands.
329
330 **Variable Addressing:**
331
332 Variable operands are interpreted as follows:
333
334 -   **0:** Refers to the top of the game stack.
335 -   **1-15:** Refer to local variables within the current function.
336 -   **16-255:** Refer to global variables.
337
338 **Examples:**
339
340 ``` {.assembly}
341 add 1, 2       ; Add two immediate operands
342 set var1, 5     ; Set the variable var1 to 5
343 jump START      ; Jump to the label START
344 get table, 3    ; Get the 3rd element from the table
345 ```
346
347 Understanding operand types and addressing modes is crucial for
348 writing correct and efficient Z-code assembly programs. By using the
349 appropriate operand prefixes and addressing modes, programmers can
350 ensure that instructions operate on the intended data and achieve the
351 desired results.
352
353 Chapter 2.5: Instruction Formats (2OP, 1OP, 0OP, EXT)
354 -----------------------------------------------------
355
356 ZAP instructions are encoded in different formats depending on the
357 number and type of operands they require. This allows for efficient
358 use of memory while providing flexibility in instruction design.
359
360 **Instruction Formats:**
361
362 -   **2OP (Two-operand):** This format is used for instructions with
363     two operands, typically immediate values or variables. It is the
364     most compact format but has limitations on the types of operands
365     it can handle.
366 -   **1OP (One-operand):** This format is used for instructions with a
367     single operand, which can be an immediate value, variable, or
368     other type.
369 -   **0OP (Zero-operand):** This format is used for instructions that
370     do not require any explicit operands.
371 -   **EXT (Extended):** This format is used for instructions that
372     cannot be represented in the other formats due to:
373     -   Having more than two operands.
374     -   Requiring long immediate operands.
375     -   Being rarely used instructions.
376
377 **Encoding Details:**
378
379 The specific encoding of each format varies, but generally:
380
381 -   **2OP:** The opcode byte contains both the operator and mode bits,
382     specifying the instruction and the types of its two operands.
383 -   **1OP:** The opcode byte contains the operator and mode bits for
384     the single operand.
385 -   **0OP:** The opcode byte solely represents the instruction, as
386     there are no operands.
387 -   **EXT:** The opcode byte identifies the instruction, and a
388     separate byte (or two bytes for some instructions) follows the
389     opcode to specify the operand types and modes.
390
391 **Extended Opcode Prefix (EXTOP):**
392
393 ZAP provides an additional 256 extended opcodes through the `EXTOP`
394 instruction. When `EXTOP` is encountered, the next byte is interpreted
395 as an opcode with its value increased by 256. This allows for a larger
396 instruction set while maintaining backward compatibility with older
397 ZIP interpreters.
398
399 **Choosing the Right Format:**
400
401 The assembler automatically chooses the most efficient format for each
402 instruction based on the number and types of operands. Programmers do
403 not need to explicitly specify the format.
404
405 The assembler determines the most efficient instruction format by
406 following a set of rules based on the number and types of operands
407 involved. Here's a simplified explanation of the process:
408
409 1.  **Count the number of operands:**
410     -   If there are **zero operands**, the **0OP format** is used.
411     -   If there is **one operand**, the **1OP format** is used,
412         unless the operand is a long immediate value, in which case
413         the **EXT format** is necessary.
414     -   If there are **two operands**:
415         -   If both operands are either immediate values or variables,
416             and neither is a long immediate, the **2OP format** is
417             used.
418         -   Otherwise, the **EXT format** is used.
419 2.  **Check for special cases:**
420     -   Some instructions, like `EQUAL?`, can take a variable number
421         of operands. In such cases, the **EXT format** is used
422         regardless of the actual number of operands provided.
423     -   Certain rarely used instructions might also be encoded in the
424         **EXT format** even if they could fit in other formats. This
425         is done to optimize the overall instruction set usage.
426
427 By following these rules, the assembler ensures that each instruction
428 is encoded in the most compact and efficient format possible, reducing
429 the overall size of the Z-code program and improving its execution
430 speed.
431
432 **Example:**
433
434 -   The instruction `add 1, 2` has two immediate operands, so it can
435     be encoded in the **2OP format**.
436 -   The instruction `set var1, 5` has one variable operand and one
437     immediate operand, so it can also be encoded in the **2OP
438     format**.
439 -   The instruction `print "Hello"` has one string operand, which is
440     considered an "other" type. Therefore, it needs the **EXT
441     format**.
442 -   The instruction `jump START` has one label operand, also requiring
443     the **EXT format**.
444
445 Understanding instruction formats is helpful for comprehending the 
446 structure of Z-code programs and how instructions are encoded in 
447 memory. However, for most programming tasks, it is sufficient to focus 
448 on the instruction names and operands, as ZAP handles the format 
449 selection automatically.
450
451 Chapter 2.6: Instruction Values and Predicates
452 ----------------------------------------------
453
454 Some ZAP instructions return values or act as predicates, influencing
455 the flow of control in the program.
456
457 **Instruction Values:**
458
459 Certain instructions, such as arithmetic and logical operations,
460 produce a value as a result of their execution. This value can be:
461
462 -   **Pushed onto the game stack:** This is the default behavior if no
463     explicit destination is specified.
464 -   **Stored in a variable:** The instruction can be followed by an
465     operand prefix `>` and a variable number to indicate where the
466     value should be stored.
467
468 **Example:**
469
470 ``` {.assembly}
471 add 1, 2       ; Value is pushed onto the stack
472 add 1, 2 > var1 ; Value is stored in the variable var1
473 ```
474
475 **Predicates:**
476
477 Predicate instructions evaluate a condition and implicitly perform a
478 conditional branch based on the result. They are typically used for
479 decision-making and control flow within the program.
480
481 **Branch Polarity and Offset:**
482
483 Predicate instructions are followed by one or two bytes that specify:
484
485 -   **Branch polarity:** Whether the branch occurs on success
486     (predicate evaluates to true) or failure (predicate evaluates to
487     false). This is indicated by the high-order bit of the first byte.
488 -   **Branch offset:** The distance to jump if the branch condition is
489     met. This can be either a short (6-bit) or long (14-bit) offset.
490
491 **Branch Targets:**
492
493 The branch offset determines the target of the conditional jump:
494
495 -   **Offset 0:** Executes an `RFALSE` instruction, returning false
496     from the current function.
497 -   **Offset 1:** Executes an `RTRUE` instruction, returning true from
498     the current function.
499 -   **Other offsets:** Jumps to the instruction located at the current
500     address plus the offset minus two.
501
502 **Example:**
503
504 ``` {.assembly}
505 less? var1, 5 / label1  ; Branch to label1 if var1 is less than 5
506 ```
507
508 Understanding instruction values and predicates is essential for
509 controlling the flow of execution in Z-code programs. By using
510 predicates and specifying appropriate branch targets, programmers can
511 implement conditional logic and decision-making within their games.
512
513 Chapter 3.1: Detailed Description of Each Opcode and Directive
514 --------------------------------------------------------------
515
516 This chapter provides a comprehensive description of each opcode and
517 directive supported by ZAP. For each element, the following
518 information is provided:
519
520 -   **Name:** The name of the opcode or directive.
521 -   **Syntax:** The format of the instruction or directive, including
522     operand types and prefixes.
523 -   **Functionality:** A detailed explanation of what the opcode or
524     directive does.
525 -   **Special cases:** Any special conditions or behaviors to be aware
526     of.
527 -   **Error conditions:** Potential errors that might occur during
528     assembly or execution.
529 -   **Examples:** Illustrative examples of how the opcode or directive
530     can be used.
531
532 This chapter serves as a reference for understanding the functionality
533 and usage of each opcode and directive available in ZAP. By consulting
534 this information, programmers can write accurate and efficient Z-code
535 assembly programs.
536
537 ### .ALIGN
538
539 **.ALIGN** is a directive that instructs the assembler to align the
540 next generated code or data to a specified byte boundary. This can be
541 useful for ensuring proper memory access and improving performance on
542 certain architectures.
543
544 **Syntax:**
545
546 ``` {.assembly}
547 .align value
548 ```
549
550 **Functionality:**
551
552 The `.align` directive pads the object file with zero bytes until the
553 current address is a multiple of the specified `value`. This
554 effectively aligns the next instruction or data element to the
555 specified boundary.
556
557 **Special Cases:**
558
559 -   If `value` is 1, the directive has no effect, as all data is
560     already aligned to a byte boundary.
561 -   If `value` is not a power of two, the assembler may align to the
562     next higher power of two.
563
564 **Error Conditions:**
565
566 An error occurs if `value` is zero or negative.
567
568 **Examples:**
569
570 ``` {.assembly}
571 .align 4
572 .word data1   ; data1 will be aligned to a 4-byte boundary
573
574 .align 8
575 .funct func1  ; func1 will be aligned to an 8-byte boundary
576 ```
577
578 **Use Cases:**
579
580 -   Aligning data structures to their natural word or longword
581     boundaries can improve memory access efficiency.
582 -   Some Z-machine instructions might have specific alignment
583     requirements for optimal performance.
584 -   Aligning functions can be helpful for debugging and code analysis.
585
586 **Note:** While `.align` can be used to enforce specific alignment, it
587 is generally recommended to let the assembler choose the appropriate
588 alignment for optimal code generation.
589
590 ### .BYTE
591
592 The `.BYTE` directive instructs the assembler to generate one or more
593 byte values in the object file. It is used to define raw byte data or
594 initialize specific memory locations with byte values.
595
596 **Syntax:**
597
598 ``` {.assembly}
599 .byte value1 [, value2 ...]
600 ```
601
602 **Functionality:**
603
604 The `.byte` directive generates the specified byte values sequentially
605 in the object file. Each value must be a constant expression that
606 evaluates to a number within the range of 0 to 255.
607
608 **Special Cases:**
609
610 None.
611
612 **Error Conditions:**
613
614 An error occurs if a value exceeds the byte range (0-255).
615
616 **Examples:**
617
618 ``` {.assembly}
619 .byte 10, 20, 30   ; Generates three bytes with values 10, 20, and 30
620 .byte 'A'          ; Generates a byte with the ASCII value of 'A' (65)
621 ```
622
623 **Use Cases:**
624
625 -   Defining raw byte data for specific purposes, such as flags or
626     status codes.
627 -   Initializing memory locations with specific byte values.
628 -   Embedding special characters or control codes within the object
629     file.
630
631 **Note:** While `.byte` allows for precise control over byte values,
632 it is generally recommended to use higher-level directives like
633 `.word` or `.str` whenever possible, as they provide better
634 readability and maintainability.
635
636 ### .CHRSET
637
638 The `.CHRSET` directive allows the programmer to redefine the
639 character sets used for encoding strings in the Z-machine. This can be
640 useful for optimizing string storage and handling characters specific
641 to certain languages or display systems.
642
643 **Syntax:**
644
645 ``` {.assembly}
646 .chrset id, char1, char2, ..., charN
647 ```
648
649 **Functionality:**
650
651 The `.chrset` directive redefines one of the three character sets used
652 for string encoding:
653
654 -   **`id`:** Specifies the character set to modify (0, 1, or 2).
655 -   **`char1, char2, ..., charN`:** A list of characters (specified as
656     their ASCII values) that will be assigned to the character set.
657
658 The number of characters provided depends on the `id`:
659
660 -   **Set 0 and 1:** 26 characters are expected.
661 -   **Set 2:** 24 characters are expected (excluding ASCII escape and
662     newline characters).
663
664 **Special Cases:**
665
666 -   Character set 2 has two special characters that cannot be
667     redefined:
668     -   **6:** Represents the ASCII escape sequence.
669     -   **7:** Represents the newline character.
670
671 **Error Conditions:**
672
673 -   An error occurs if `id` is not 0, 1, or 2.
674 -   An error occurs if the number of characters provided does not
675     match the expected count for the specified `id`.
676
677 **Examples:**
678
679 ``` {.assembly}
680 .chrset 0, 'a', 'b', ..., 'z'   ; Redefines character set 0 with lowercase letters
681 .chrset 1, 'A', 'B', ..., 'Z'   ; Redefines character set 1 with uppercase letters
682 ```
683
684 **Use Cases:**
685
686 -   Optimizing string storage by assigning frequently used characters
687     to the compact character sets.
688 -   Handling characters specific to certain languages or display
689     systems that are not included in the default character sets.
690
691 **Note:** Redefining character sets can have significant implications
692 for string encoding and decoding. It is generally recommended to use
693 the default character sets unless there is a specific need for
694 optimization or handling special characters.
695
696 ### .DEFSEG
697
698 The `.DEFSEG` directive is used to define a segment and specify its
699 relationships with other segments. Segments are logical divisions of
700 the Z-code program that can be used to optimize disk usage and loading
701 times in multi-disk games.
702
703 **Syntax:**
704
705 ``` {.assembly}
706 .defseg name, seg1, seg2, seg3
707 ```
708
709 **Functionality:**
710
711 The `.DEFSEG` directive performs the following:
712
713 -   **Defines a segment:** Creates a new segment with the specified
714     `name`.
715 -   **Specifies adjacent segments:** Declares that the segment is
716     adjacent to the segments `seg1`, `seg2`, and `seg3`. This
717     information is used by the `zsplit` tool to determine how to
718     distribute segments across multiple disks.
719
720 **Special Cases:**
721
722 -   If the segment `name` is "0", it refers to the default segment
723     that contains all preloaded data and code.
724 -   If a segment name is not defined with `.DEFSEG`, it is implicitly
725     considered adjacent to segment 0.
726
727 **Error Conditions:**
728
729 An error occurs if a segment name is not a valid symbol.
730
731 **Examples:**
732
733 ``` {.assembly}
734 .defseg "ROOM", "HALL", "GARDEN"  ; Defines the "ROOM" segment and declares it adjacent to "HALL" and "GARDEN" segments
735 .defseg "STARTUP", "MAIN"         ; Defines the "STARTUP" segment and declares it adjacent to the "MAIN" segment
736 ```
737
738 **Use Cases:**
739
740 -   Organizing the game's code and data into logical segments for
741     efficient disk usage and loading.
742 -   Informing the `zsplit` tool about segment relationships to
743     optimize the distribution of segments across multiple disks.
744
745 **Note:** Segment definitions and adjacency information are primarily
746 used by the `zsplit` tool and do not directly affect the execution of
747 the Z-code program.
748
749 ### .END
750
751 The `.END` directive marks the end of the assembly language program.
752 It instructs the assembler to stop processing input and perform final
753 operations.
754
755 **Syntax:**
756
757 ``` {.assembly}
758 .end
759 ```
760
761 **Functionality:**
762
763 When the `.END` directive is encountered, the assembler performs the
764 following:
765
766 -   **Stops processing input:** Any code or directives following
767     `.END` are ignored.
768 -   **Resolves forward references:** Performs fixup operations to
769     resolve any outstanding forward references to symbols.
770 -   **Generates final output:** Writes the assembled Z-code program to
771     the object file and generates any optional listing or error files.
772
773 **Special Cases:**
774
775 None.
776
777 **Error Conditions:**
778
779 An error might occur during fixup if undefined symbols are
780 encountered.
781
782 **Examples:**
783
784 ``` {.assembly}
785 ; ... game code ...
786
787 .end
788 ```
789
790 **Use Cases:**
791
792 The `.END` directive is mandatory and must be placed at the end of
793 every Z-code assembly program to signal the completion of the assembly
794 process.
795
796 **Note:** It is essential to ensure that all necessary code and data
797 have been defined before the `.END` directive, as anything following
798 it will not be processed by the assembler.
799
800 ### .ENDI
801
802 The `.ENDI` directive marks the end of an `.INSERT` file. It instructs
803 the assembler to return to the previous input source and continue
804 processing.
805
806 **Syntax:**
807
808 ``` {.assembly}
809 .endi
810 ```
811
812 **Functionality:**
813
814 The `.ENDI` directive is used in conjunction with the `.INSERT`
815 directive, which allows the contents of another file to be inserted
816 and assembled at a specific point in the main source file. When
817 `.ENDI` is encountered, the assembler:
818
819 -   **Stops processing the inserted file:** Any code or directives
820     following `.ENDI` in the inserted file are ignored.
821 -   **Returns to the previous input source:** The assembler resumes
822     processing the main source file from the point where the `.INSERT`
823     directive was encountered.
824
825 **Special Cases:**
826
827 -   A `.ENDI` directive without a preceding `.INSERT` directive is an
828     error.
829
830 **Error Conditions:**
831
832 An error occurs if `.ENDI` is found outside of an inserted file.
833
834 **Examples:**
835
836 ``` {.assembly}
837 ; ... main source file ...
838
839 .insert "header.zap"
840
841 ; ... contents of header.zap ...
842
843 .endi
844
845 ; ... main source file continues ...
846 ```
847
848 **Use Cases:**
849
850 -   Modularizing code by separating commonly used routines or data
851     into separate files that can be inserted into multiple programs.
852 -   Including header files that define constants, macros, or other
853     elements.
854
855 **Note:** The `.INSERT` and `.ENDI` directives provide a mechanism for
856 code inclusion and modularity, but their usage should be carefully
857 considered to avoid potential complexity and maintainability issues.
858
859 ### .ENDSEG
860
861 The `.ENDSEG` directive closes all currently open segments. Segments
862 are logical divisions of the Z-code program used to optimize disk
863 usage and loading times in multi-disk games.
864
865 **Syntax:**
866
867 ``` {.assembly}
868 .endseg
869 ```
870
871 **Functionality:**
872
873 The `.ENDSEG` directive closes any segments that were previously
874 opened with the `.SEGMENT` directive. This indicates to the assembler
875 that the code and data belonging to those segments have been defined.
876
877 **Special Cases:**
878
879 -   If no segments are currently open, the `.ENDSEG` directive has no
880     effect.
881
882 **Error Conditions:**
883
884 None.
885
886 **Examples:**
887
888 ``` {.assembly}
889 .segment "ROOM"
890
891 ; ... code and data for the ROOM segment ...
892
893 .endseg
894 ```
895
896 **Use Cases:**
897
898 -   Ensuring that all segments are properly closed before the end of
899     the assembly process.
900 -   Organizing code and data into logical segments for efficient disk
901     usage and loading.
902
903 **Note:** Segment definitions and closures are primarily used by the
904 `zsplit` tool and do not directly affect the execution of the Z-code
905 program.
906
907 ### .ENDT
908
909 The `.ENDT` directive marks the end of a table definition. Tables are
910 logical structures used to organize data in Z-code programs.
911
912 **Syntax:**
913
914 ``` {.assembly}
915 .endt
916 ```
917
918 **Functionality:**
919
920 The `.ENDT` directive must be used to terminate a table that was
921 previously declared with the `.TABLE` directive. It performs the
922 following:
923
924 -   **Checks table size:** If a size was specified in the `.TABLE`
925     directive, the assembler verifies that the actual table size does
926     not exceed the declared size.
927 -   **Finalizes table data:** The assembler performs any necessary
928     operations to finalize the table data, such as padding or
929     alignment.
930
931 **Special Cases:**
932
933 -   A `.ENDT` directive without a preceding `.TABLE` directive is an
934     error.
935
936 **Error Conditions:**
937
938 -   An error occurs if the actual table size exceeds the declared size
939     (if specified in `.TABLE`).
940
941 **Examples:**
942
943 ``` {.assembly}
944 .table 10
945 .word data1, data2, data3
946 .endt
947 ```
948
949 **Use Cases:**
950
951 -   Defining tables of data with a specific size and ensuring that the
952     size is not exceeded.
953 -   Organizing data into logical structures for easier access and
954     manipulation.
955
956 **Note:** The `.TABLE` and `.ENDT` directives provide a way to define
957 and manage tables in Z-code programs, but their usage should be
958 consistent and well-structured to avoid potential errors and
959 maintainability issues.
960
961 ### .FALSE
962
963 The `.FALSE` directive generates a word (two-byte) value of 0 in the
964 object file. It is used to represent the boolean value `false` or to
965 initialize memory locations with a zero value.
966
967 **Syntax:**
968
969 ``` {.assembly}
970 .false
971 ```
972
973 **Functionality:**
974
975 The `.false` directive simply generates a word with the value 0 at the
976 current address in the object file.
977
978 **Special Cases:**
979
980 None.
981
982 **Error Conditions:**
983
984 None.
985
986 **Examples:**
987
988 ``` {.assembly}
989 .false        ; Generates a word with value 0
990 set flag1, .false  ; Sets the flag variable `flag1` to false
991 ```
992
993 **Use Cases:**
994
995 -   Representing the boolean value `false` in conditional statements
996     or data structures.
997 -   Initializing variables or memory locations with a zero value.
998
999 **Note:** The `.false` directive is equivalent to using `.word 0`.
1000 However, `.false` provides better readability and clarity when
1001 representing boolean values.
1002
1003 ### .FSTR
1004
1005 The `.FSTR` directive defines a string as a "frequent string" and adds
1006 it to the frequent words table. Frequent strings are short, commonly
1007 used substrings that can be referenced efficiently within other
1008 strings, reducing overall memory usage.
1009
1010 **Syntax:**
1011
1012 ``` {.assembly}
1013 .fstr name, string
1014 ```
1015
1016 **Functionality:**
1017
1018 The `.fstr` directive performs the following:
1019
1020 -   **Defines a symbol:** Creates a global symbol with the specified
1021     `name`. The value of the symbol is the address of the string
1022     divided by 2 (since strings are stored as words).
1023 -   **Outputs the string:** Generates the string in the object file,
1024     aligning it to a word boundary.
1025 -   **Adds to frequent words table:** Adds the string to the frequent
1026     words table, which is used by the Z-machine to efficiently
1027     reference frequently used substrings within other strings.
1028
1029 **Special Cases:**
1030
1031 -   Frequent strings cannot contain other frequent strings within
1032     them.
1033 -   The frequent words table has a limited size (96 entries). If this
1034     limit is exceeded, the assembler will issue an error.
1035
1036 **Error Conditions:**
1037
1038 -   An error occurs if `name` is not a valid symbol.
1039 -   An error occurs if the frequent words table is full.
1040
1041 **Examples:**
1042
1043 ``` {.assembly}
1044 .fstr "the", "the "   ; Defines the frequent string "the"
1045 .fstr "and", "and "  ; Defines the frequent string "and"
1046 ```
1047
1048 **Use Cases:**
1049
1050 -   Optimizing string storage by defining frequently used words or
1051     phrases as frequent strings.
1052 -   Reducing the overall size of the Z-code program by efficiently
1053     referencing common substrings.
1054
1055 **Note:** The use of frequent strings can improve memory efficiency,
1056 but it is important to choose appropriate strings and avoid exceeding
1057 the table size limit.
1058
1059 ### .FUNCT
1060
1061 The `.FUNCT` directive defines a function and begins a new local
1062 symbol block. Functions are subroutines that can be called and return
1063 values, allowing for modular and reusable code.
1064
1065 **Syntax:**
1066
1067 ``` {.assembly}
1068 .funct name [, arg1 [: type] [, arg2 [: type] ...]]
1069 ```
1070
1071 **Functionality:**
1072
1073 The `.funct` directive performs the following:
1074
1075 -   **Defines a function:** Creates a new function with the specified
1076     `name`. The function name becomes a global symbol.
1077 -   **Starts a new local symbol block:** Any symbols defined after
1078     `.funct` are considered local to the function and are not
1079     accessible outside of it.
1080 -   **Defines local variables:** The optional `arg1`, `arg2`, etc.,
1081     specify local variables for the function. Each variable can
1082     optionally have a type specified after a colon (`:`) to indicate
1083     its data type.
1084 -   **Aligns function:** Aligns the function to a quad-byte boundary
1085     for efficient execution.
1086
1087 **Special Cases:**
1088
1089 -   If no arguments are provided, the function has no local variables.
1090 -   If a type is not specified for a local variable, it is assumed to
1091     be of type `ANY`.
1092
1093 **Error Conditions:**
1094
1095 -   An error occurs if `name` is not a valid symbol.
1096 -   An error occurs if the function is defined within another function
1097     (nested functions are not supported).
1098
1099 **Examples:**
1100
1101 ``` {.assembly}
1102 .funct main
1103 ; ... code for the main function ...
1104
1105 .funct add, num1: int, num2: int > result: int
1106 ; ... code for the add function ...
1107 ```
1108
1109 **Use Cases:**
1110
1111 -   Defining functions to modularize code and promote reusability.
1112 -   Creating subroutines to perform specific tasks within the program.
1113 -   Utilizing local variables to manage data within functions.
1114
1115 **Note:** The `.funct` directive is essential for defining functions
1116 in Z-code assembly programs. Proper function definition and usage are
1117 crucial for code organization and maintainability.
1118
1119 ### .GSTR
1120
1121 The `.GSTR` directive defines a global string and stores it in the
1122 string area of the Z-code program. Global strings are accessible from
1123 anywhere in the program and are typically used for longer text
1124 passages or messages.
1125
1126 **Syntax:**
1127
1128 ``` {.assembly}
1129 .gstr name, string
1130 ```
1131
1132 **Functionality:**
1133
1134 The `.gstr` directive performs the following:
1135
1136 -   **Defines a symbol:** Creates a global symbol with the specified
1137     `name`. The value of the symbol is the address of the string in
1138     the string area, adjusted for the string offset (`SOFF`).
1139 -   **Outputs the string:** Generates the string in the object file,
1140     aligning it to a quad-byte boundary.
1141 -   **Updates string offset:** If necessary, updates the `SOFF` value
1142     to reflect the new string's location.
1143
1144 **Special Cases:**
1145
1146 -   The string area is located in a separate section of the Z-code
1147     program and is accessed using the `SOFF` value.
1148 -   Strings are encoded in a special 5-bit byte format for efficient
1149     storage.
1150
1151 **Error Conditions:**
1152
1153 -   An error occurs if `name` is not a valid symbol.
1154
1155 **Examples:**
1156
1157 ``` {.assembly}
1158 .gstr "intro", "Welcome to the game!"
1159 print intro  ; Prints the "intro" string
1160 ```
1161
1162 **Use Cases:**
1163
1164 -   Defining long text passages or messages that need to be accessed
1165     from various parts of the program.
1166 -   Storing strings that are too large to be defined as immediate
1167     operands within instructions.
1168
1169 **Note:** The `.gstr` directive is used to define global strings,
1170 while the `.str` directive is used for defining strings within tables
1171 or as immediate operands.
1172
1173 ### .GVAR
1174
1175 The `.GVAR` directive defines a global variable and assigns it a
1176 default value. Global variables are accessible from anywhere in the
1177 program and are typically used to store persistent data or game state.
1178
1179 **Syntax:**
1180
1181 ``` {.assembly}
1182 .gvar name [= value]
1183 ```
1184
1185 **Functionality:**
1186
1187 The `.gvar` directive performs the following:
1188
1189 -   **Defines a symbol:** Creates a global symbol with the specified
1190     `name`. The value of the symbol is the variable number, which is
1191     used to access the variable in the global table.
1192 -   **Assigns a default value:** If `value` is provided, it is
1193     assigned as the initial value of the global variable. Otherwise,
1194     the default value is 0.
1195 -   **Outputs the value:** Generates the default value in the object
1196     file, placing it in the global table.
1197
1198 **Special Cases:**
1199
1200 -   Global variables are stored in a dedicated table pointed to by the
1201     `GLOBALS` word in the program header.
1202 -   The first global variable has a variable number of 16, and
1203     subsequent variables are assigned incrementing numbers.
1204
1205 **Error Conditions:**
1206
1207 -   An error occurs if `name` is not a valid symbol.
1208 -   An error occurs if the maximum number of global variables is
1209     exceeded.
1210
1211 **Examples:**
1212
1213 ``` {.assembly}
1214 .gvar score = 0   ; Defines a global variable "score" with initial value 0
1215 .gvar health       ; Defines a global variable "health" with default value 0
1216 ```
1217
1218 **Use Cases:**
1219
1220 -   Storing persistent data that needs to be accessed from different
1221     parts of the program.
1222 -   Managing game state and tracking variables like score, health, or
1223     inventory items.
1224
1225 **Note:** The `.gvar` directive is used to define global variables,
1226 while local variables are defined within functions using the `.funct`
1227 directive.
1228
1229 ### .INSERT
1230
1231 The `.INSERT` directive instructs the assembler to insert the contents
1232 of another file at the current point in the assembly process. This
1233 allows for code modularity and reuse.
1234
1235 **Syntax:**
1236
1237 ``` {.assembly}
1238 .insert "filename"
1239 ```
1240
1241 **Functionality:**
1242
1243 The `.insert` directive opens the specified `filename` and inserts its
1244 contents into the assembly stream as if they were part of the main
1245 source file. The assembler processes the inserted file's code and
1246 directives, including any symbols or definitions it contains.
1247
1248 **Special Cases:**
1249
1250 -   The inserted file must be a valid Z-code assembly language file.
1251 -   The `.insert` directive can be nested, meaning inserted files can
1252     themselves contain `.insert` directives.
1253 -   The `.ENDI` directive is used to mark the end of an inserted file
1254     and return to the previous input source.
1255
1256 **Error Conditions:**
1257
1258 -   An error occurs if the specified `filename` cannot be opened.
1259 -   An error occurs if the inserted file contains syntax errors or
1260     invalid directives.
1261
1262 **Examples:**
1263
1264 ``` {.assembly}
1265 ; ... main source file ...
1266
1267 .insert "header.zap"  ; Inserts the contents of header.zap
1268
1269 ; ... main source file continues ...
1270 ```
1271
1272 **Use Cases:**
1273
1274 -   Including header files that define constants, macros, or other
1275     commonly used elements.
1276 -   Modularizing code by separating routines or data into separate
1277     files that can be inserted into multiple programs.
1278
1279 **Note:** While `.insert` provides a mechanism for code inclusion and
1280 modularity, its usage should be carefully considered to avoid
1281 potential complexity and maintainability issues. Excessive nesting of
1282 `.insert` directives can make code harder to understand and debug.
1283
1284 ### .LANG
1285
1286 The `.LANG` directive specifies the language and escape character used
1287 for string encoding. This allows ZAP to generate Z-code programs that
1288 support different languages and character sets.
1289
1290 **Syntax:**
1291
1292 ``` {.assembly}
1293 .lang id, escape
1294 ```
1295
1296 **Functionality:**
1297
1298 The `.lang` directive sets the following parameters for string
1299 encoding:
1300
1301 -   **`id`:** Specifies the language ID. Currently, only two languages
1302     are supported:
1303     -   **0:** English (default)
1304     -   **1:** German
1305 -   **`escape`:** Specifies the escape character used to represent
1306     special characters or switch character sets within strings.
1307
1308 **Special Cases:**
1309
1310 -   The default language is English with the `%` character as the
1311     escape character.
1312 -   The German language setting modifies the character set used for
1313     compact encoding to include German-specific characters.
1314
1315 **Error Conditions:**
1316
1317 -   An error occurs if `id` is not 0 or 1.
1318
1319 **Examples:**
1320
1321 ``` {.assembly}
1322 .lang 1, '%'  ; Sets the language to German with '%' as the escape character
1323 ```
1324
1325 **Use Cases:**
1326
1327 -   Creating Z-code programs that support languages other than
1328     English.
1329 -   Optimizing string storage for languages with specific character
1330     sets.
1331
1332 **Note:** The `.lang` directive is typically used at the beginning of
1333 the assembly program to set the language and escape character for all
1334 subsequent string definitions.
1335
1336 ### .LEN
1337
1338 The `.LEN` directive calculates the length of a string in words and
1339 generates a byte containing that length in the object file. This is
1340 typically used in conjunction with the `.STR` directive to create
1341 self-contained string definitions.
1342
1343 **Syntax:**
1344
1345 ``` {.assembly}
1346 .len string
1347 ```
1348
1349 **Functionality:**
1350
1351 The `.len` directive performs the following:
1352
1353 -   **Calculates string length:** Determines the length of the
1354     specified string in words, taking into account the Z-machine's
1355     5-bit byte encoding for strings.
1356 -   **Generates length byte:** Outputs a single byte containing the
1357     calculated length to the object file.
1358
1359 **Special Cases:**
1360
1361 -   The string must be a short string, meaning it can be represented
1362     in 255 words or less.
1363
1364 **Error Conditions:**
1365
1366 An error occurs if the string length exceeds 255 words.
1367
1368 **Examples:**
1369
1370 ``` {.assembly}
1371 .len "Hello"
1372 .str "Hello"  ; This string will be preceded by a byte indicating its length
1373 ```
1374
1375 **Use Cases:**
1376
1377 -   Creating self-contained string definitions where the length is
1378     explicitly stored alongside the string data.
1379 -   Facilitating string manipulation routines that require knowledge
1380     of the string length.
1381
1382 **Note:** The `.len` directive is often used together with the `.strl`
1383 directive, which combines the functionality of `.len` and `.str` into
1384 a single operation.
1385
1386 ### .NEW
1387
1388 The `.NEW` directive sets the release level of the Z-code program
1389 being assembled. This information is used to ensure compatibility with
1390 different versions of the ZIP interpreter.
1391
1392 **Syntax:**
1393
1394 ``` {.assembly}
1395 .new level
1396 ```
1397
1398 **Functionality:**
1399
1400 The `.new` directive sets the `Version` variable in ZAP, which
1401 determines the version of the Z-machine that the generated program is
1402 compatible with. The `level` argument must be a constant expression
1403 that evaluates to one of the supported Z-machine versions:
1404
1405 -   **3:** ZIP
1406 -   **4:** EZIP
1407 -   **5:** XZIP
1408 -   **6:** YZIP
1409
1410 **Special Cases:**
1411
1412 -   The default release level is 5 (XZIP).
1413 -   Some features and opcodes might not be available in older versions
1414     of ZIP.
1415
1416 **Error Conditions:**
1417
1418 An error occurs if `level` is not a supported Z-machine version.
1419
1420 **Examples:**
1421
1422 ``` {.assembly}
1423 .new 6  ; Sets the release level to YZIP
1424 ```
1425
1426 **Use Cases:**
1427
1428 -   Ensuring compatibility with specific versions of the ZIP
1429     interpreter.
1430 -   Taking advantage of features and opcodes introduced in newer
1431     Z-machine versions.
1432
1433 **Note:** The `.new` directive should be used at the beginning of the
1434 assembly program to set the release level before any other code or
1435 directives.
1436
1437 ### .OBJECT
1438
1439 The `.OBJECT` directive defines an object and assigns it a unique
1440 object number. Objects are complex data structures used to represent
1441 entities and items within the game world.
1442
1443 **Syntax:**
1444
1445 ``` {.assembly}
1446 .object name, flag1, flag2, ..., flag7
1447 ```
1448
1449 **Functionality:**
1450
1451 The `.object` directive performs the following:
1452
1453 -   **Defines a symbol:** Creates a global symbol with the specified
1454     `name`. The value of the symbol is the object number.
1455 -   **Assigns object number:** Assigns a unique, incrementing object
1456     number to the object.
1457 -   **Outputs object data:** Generates the object data in the object
1458     file, including flag words and property table pointer.
1459
1460 **Special Cases:**
1461
1462 -   Objects are stored in a dedicated table pointed to by the `OBJECT`
1463     word in the program header.
1464 -   The first object has an object number of 1, and subsequent objects
1465     are assigned incrementing numbers.
1466 -   The `flag1` to `flag7` arguments represent the initial values of
1467     the object's 48 one-bit flags, divided into seven words.
1468
1469 **Error Conditions:**
1470
1471 -   An error occurs if `name` is not a valid symbol.
1472 -   An error occurs if the maximum number of objects is exceeded.
1473
1474 **Examples:**
1475
1476 ``` {.assembly}
1477 .object "player", 0, 0, 0, 0, 0, 0  ; Defines the "player" object
1478 .object "sword", 1, 0, 0, 0, 0, 0   ; Defines the "sword" object
1479 ```
1480
1481 **Use Cases:**
1482
1483 -   Defining objects to represent entities and items in the game
1484     world.
1485 -   Assigning properties and flags to objects to track their state and
1486     characteristics.
1487
1488 **Note:** The `.object` directive is used to define objects, while
1489 properties are defined within the object's property table using the
1490 `.PROP` directive.
1491
1492 ### .OPTIONS
1493
1494 The `.OPTIONS` directive is used to set options that control the
1495 behavior of the ZIP interpreter. These options affect features such as
1496 scripting and user input.
1497
1498 **Syntax:**
1499
1500 ``` {.assembly}
1501 .options script, ask
1502 ```
1503
1504 **Functionality:**
1505
1506 The `.options` directive sets the following options:
1507
1508 -   **`script`:** A boolean value (0 or 1) indicating whether
1509     scripting is enabled. When scripting is enabled, the interpreter
1510     can read commands from a script file instead of from the user.
1511 -   **`ask`:** A boolean value (0 or 1) indicating whether the
1512     interpreter should ask the user for confirmation before executing
1513     certain actions, such as restarting or restoring the game.
1514
1515 **Special Cases:**
1516
1517 -   If either `script` or `ask` is omitted, the corresponding option
1518     is not modified.
1519
1520 **Error Conditions:**
1521
1522 An error occurs if `script` or `ask` is not a valid boolean value (0
1523 or 1).
1524
1525 **Examples:**
1526
1527 ``` {.assembly}
1528 .options 1, 0  ; Enables scripting and disables confirmation prompts
1529 ```
1530
1531 **Use Cases:**
1532
1533 -   Enabling scripting for automated testing or gameplay recording.
1534 -   Disabling confirmation prompts for a more streamlined user
1535     experience.
1536
1537 **Note:** The `.options` directive is typically used at the beginning
1538 of the assembly program to set the desired interpreter options.
1539
1540 ### .PCSET
1541
1542 The `.PCSET` directive sets the program counter (PC) to a specific
1543 value. This directive is used to jump to a specific address within the
1544 program or to align code and data to specific memory locations.
1545
1546 **Syntax:**
1547
1548 ``` {.assembly}
1549 .pcset value
1550 ```
1551
1552 **Functionality:**
1553
1554 The `.pcset` directive sets the program counter to the specified
1555 `value`. The assembler then continues generating code and data from
1556 that address onwards.
1557
1558 **Special Cases:**
1559
1560 -   If `value` is less than the current program counter, the assembler
1561     will issue a warning but will still set the PC to the specified
1562     value.
1563
1564 **Error Conditions:**
1565
1566 An error occurs if `value` is negative.
1567
1568 **Examples:**
1569
1570 ``` {.assembly}
1571 .pcset 1000  ; Sets the program counter to 1000
1572 ```
1573
1574 **Use Cases:**
1575
1576 -   Jumping to a specific address within the program, typically for
1577     implementing subroutines or handling error conditions.
1578 -   Aligning code or data to specific memory locations for
1579     optimization or compatibility purposes.
1580
1581 **Note:** The `.PCSET` directive should be used with caution, as it
1582 can lead to unexpected behavior if not used correctly. It is generally
1583 recommended to use labels and jump instructions for control flow
1584 whenever possible.
1585
1586 ### .PDEF
1587
1588 The `.PDEF` directive aligns the next generated code or data to the
1589 next word boundary. This directive is used to ensure proper alignment
1590 for word-sized data elements.
1591
1592 **Syntax:**
1593
1594 ``` {.assembly}
1595 .pdef
1596 ```
1597
1598 **Functionality:**
1599
1600 The `.pdef` directive pads the object file with a zero byte if the
1601 current address is not already a multiple of two. This ensures that
1602 the next word (two-byte) value will be aligned to a word boundary.
1603
1604 **Special Cases:**
1605
1606 None.
1607
1608 **Error Conditions:**
1609
1610 None.
1611
1612 **Examples:**
1613
1614 ``` {.assembly}
1615 .pdef
1616 .word data1   ; data1 will be aligned to a word boundary
1617 ```
1618
1619 **Use Cases:**
1620
1621 -   Ensuring proper alignment for word-sized data elements, such as
1622     numbers and pointers.
1623 -   Improving memory access efficiency on architectures that require
1624     word alignment.
1625
1626 **Note:** The `.PDEF` directive is typically used before defining
1627 word-sized data elements to guarantee their alignment. However, the
1628 assembler generally handles alignment automatically, so explicit use
1629 of `.PDEF` is often unnecessary.
1630
1631 ### .PICFILE
1632
1633 The `.PICFILE` directive defines a picture file and specifies its
1634 properties. Picture files contain images and associated data used by
1635 the `DISPLAY` and `DCLEAR` instructions.
1636
1637 **Syntax:**
1638
1639 ``` {.assembly}
1640 .picfile filename, machine, ideal-x, ideal-y, base-x, base-y
1641 ```
1642
1643 **Functionality:**
1644
1645 The `.picfile` directive defines a picture file with the following
1646 properties:
1647
1648 -   **`filename`:** The name of the picture file.
1649 -   **`machine`:** The target machine for which the picture file is
1650     intended (e.g., "apple", "ega", "mac").
1651 -   **`ideal-x` and `ideal-y`:** The ideal dimensions of the picture
1652     in pixels.
1653 -   **`base-x` and `base-y`:** The base coordinates of the picture in
1654     pixels.
1655
1656 This information is used by the interpreter to properly display and
1657 manage pictures from the specified file.
1658
1659 **Special Cases:**
1660
1661 -   The picture file format and encoding are specific to the Z-machine
1662     and may vary depending on the target machine.
1663 -   The `zsplit` tool uses the picture file information to distribute
1664     pictures across multiple disks in multi-disk games.
1665
1666 **Error Conditions:**
1667
1668 -   An error occurs if `filename` is not a valid string.
1669 -   An error occurs if `machine` is not a recognized target machine.
1670
1671 **Examples:**
1672
1673 ``` {.assembly}
1674 .picfile "pictures.p", "mac", 320, 200, 0, 0
1675 ```
1676
1677 **Use Cases:**
1678
1679 -   Defining picture files for use with the `DISPLAY` and `DCLEAR`
1680     instructions.
1681 -   Providing information to the interpreter and `zsplit` tool for
1682     picture management.
1683
1684 **Note:** The `.PICFILE` directive is used in conjunction with the
1685 `DISPLAY` and `DCLEAR` instructions to display and manage pictures
1686 within Z-code programs.
1687
1688 ### .PROP
1689
1690 The `.PROP` directive defines a property within an object's property
1691 table. Properties are used to associate additional data and attributes
1692 with objects.
1693
1694 **Syntax:**
1695
1696 ``` {.assembly}
1697 .prop length, number
1698 ```
1699
1700 **Functionality:**
1701
1702 The `.prop` directive defines a property with the following
1703 characteristics:
1704
1705 -   **`length`:** The length of the property value in bytes.
1706 -   **`number`:** The property number.
1707
1708 The assembler generates the property data in the object file,
1709 including the length, number, and value.
1710
1711 **Special Cases:**
1712
1713 -   Properties are stored in a sorted order within the object's
1714     property table.
1715 -   The length of a property value can be 1, 2, or more bytes. The
1716     encoding of the length depends on the size:
1717     -   1 byte: The high-order bit of the length byte is 0.
1718     -   2 bytes: The high-order bit is 1, and the second-highest bit
1719         is 0.
1720     -   More than 2 bytes: The high-order two bits are both 1, and the
1721         remaining 6 bits specify the length.
1722
1723 **Error Conditions:**
1724
1725 -   An error occurs if `length` is zero or negative.
1726 -   An error occurs if `number` is not within the valid range (1-63).
1727
1728 **Examples:**
1729
1730 ``` {.assembly}
1731 .object "player", ...
1732 .prop 1, 1  ; Defines a one-byte property with number 1
1733 .prop 2, 10 ; Defines a two-byte property with number 10
1734 ```
1735
1736 **Use Cases:**
1737
1738 -   Associating additional data with objects, such as descriptions,
1739     attributes, or inventory items.
1740 -   Extending the functionality of objects beyond their basic flags
1741     and attributes.
1742
1743 **Note:** The `.PROP` directive is used within an object definition to
1744 define its properties. The object itself is defined using the
1745 `.OBJECT` directive.
1746
1747 ### .SEGMENT
1748
1749 The `.SEGMENT` directive opens a new segment for code and data
1750 definition. Segments are logical divisions of the Z-code program used
1751 to optimize disk usage and loading times in multi-disk games.
1752
1753 **Syntax:**
1754
1755 ``` {.assembly}
1756 .segment "name"
1757 ```
1758
1759 **Functionality:**
1760
1761 The `.segment` directive opens a new segment with the specified
1762 `name`. All subsequent code and data definitions are considered to
1763 belong to this segment until a `.ENDSEG` directive is encountered or
1764 another `.SEGMENT` directive opens a different segment.
1765
1766 **Special Cases:**
1767
1768 -   If the segment "0" is opened, it refers to the default segment
1769     that contains all preloaded data and code.
1770 -   If a segment name is not defined with `.DEFSEG`, it is implicitly
1771     considered adjacent to segment 0.
1772
1773 **Error Conditions:**
1774
1775 An error occurs if `name` is not a valid string.
1776
1777 **Examples:**
1778
1779 ``` {.assembly}
1780 .segment "ROOM"
1781
1782 ; ... code and data for the ROOM segment ...
1783
1784 .endseg
1785 ```
1786
1787 **Use Cases:**
1788
1789 -   Organizing the game's code and data into logical segments for
1790     efficient disk usage and loading.
1791 -   Informing the `zsplit` tool about segment boundaries to optimize
1792     the distribution of segments across multiple disks.
1793
1794 **Note:** Segment definitions and closures are primarily used by the
1795 `zsplit` tool and do not directly affect the execution of the Z-code
1796 program.
1797
1798 ### .SEQ
1799
1800 The `.SEQ` directive assigns sequential values to a list of symbols,
1801 starting from 0. This is a convenient way to define a series of
1802 constants or variables with incrementing values.
1803
1804 **Syntax:**
1805
1806 ``` {.assembly}
1807 .seq symbol1 [, symbol2 ...]
1808 ```
1809
1810 **Functionality:**
1811
1812 The `.seq` directive assigns values to the specified symbols in the
1813 following manner:
1814
1815 -   `symbol1` is assigned the value 0.
1816 -   `symbol2` is assigned the value 1.
1817 -   ... and so on.
1818
1819 The symbols become global constants with their respective values.
1820
1821 **Special Cases:**
1822
1823 None.
1824
1825 **Error Conditions:**
1826
1827 An error occurs if any of the symbols are already defined.
1828
1829 **Examples:**
1830
1831 ``` {.assembly}
1832 .seq color_red, color_green, color_blue  ; Defines three constants with values 0, 1, and 2
1833 ```
1834
1835 **Use Cases:**
1836
1837 -   Defining a series of constants with incrementing values, such as
1838     color codes or status flags.
1839 -   Creating a sequence of variables with unique identifiers.
1840
1841 **Note:** The `.seq` directive provides a concise way to define
1842 multiple constants or variables with sequential values.
1843
1844 ### .SEQ
1845
1846 The `.SEQ` directive assigns sequential values to a list of symbols,
1847 starting from 0. This is a convenient way to define a series of
1848 constants or variables with incrementing values.
1849
1850 **Syntax:**
1851
1852 ``` {.assembly}
1853 .seq symbol1 [, symbol2 ...]
1854 ```
1855
1856 **Functionality:**
1857
1858 The `.seq` directive assigns values to the specified symbols in the
1859 following manner:
1860
1861 -   `symbol1` is assigned the value 0.
1862 -   `symbol2` is assigned the value 1.
1863 -   ... and so on.
1864
1865 The symbols become global constants with their respective values.
1866
1867 **Special Cases:**
1868
1869 None.
1870
1871 **Error Conditions:**
1872
1873 An error occurs if any of the symbols are already defined.
1874
1875 **Examples:**
1876
1877 ``` {.assembly}
1878 .seq color_red, color_green, color_blue  ; Defines three constants with values 0, 1, and 2
1879 ```
1880
1881 **Use Cases:**
1882
1883 -   Defining a series of constants with incrementing values, such as
1884     color codes or status flags.
1885 -   Creating a sequence of variables with unique identifiers.
1886
1887 **Note:** The `.seq` directive provides a concise way to define
1888 multiple constants or variables with sequential values.
1889
1890 ### .STR
1891
1892 The `.STR` directive generates a string in the object file, encoding
1893 it in the Z-machine's 5-bit byte format. It is used to define strings
1894 that can be referenced and printed by instructions like `PRINT` and
1895 `PRINTB`.
1896
1897 **Syntax:**
1898
1899 ``` {.assembly}
1900 .str string
1901 ```
1902
1903 **Functionality:**
1904
1905 The `.str` directive performs the following:
1906
1907 -   **Encodes the string:** Converts the ASCII string into the
1908     Z-machine's 5-bit byte format, using frequent words and character
1909     set shifting as needed.
1910 -   **Outputs the string:** Generates the encoded string data in the
1911     object file.
1912 -   **Sets the end-of-string bit:** Marks the last word of the string
1913     with the end-of-string bit to indicate its termination.
1914
1915 **Special Cases:**
1916
1917 -   If a string is provided without an explicit directive, it is
1918     implicitly treated as a `.str` directive.
1919 -   Strings are aligned to word boundaries in the object file.
1920
1921 **Error Conditions:**
1922
1923 None.
1924
1925 **Examples:**
1926
1927 ``` {.assembly}
1928 .str "Hello, world!"  ; Defines a string
1929 print message         ; Prints the string defined above
1930 ```
1931
1932 **Use Cases:**
1933
1934 -   Defining strings that can be printed or manipulated by the Z-code
1935     program.
1936 -   Storing text data efficiently using the Z-machine's string
1937     encoding format.
1938
1939 **Note:** The `.str` directive is used to define strings within tables
1940 or as immediate operands. For defining global strings in the string
1941 area, the `.GSTR` directive is used.
1942
1943 ### .STRL
1944
1945 The `.STRL` directive combines the functionality of the `.LEN` and
1946 `.STR` directives. It calculates the length of a string in words,
1947 generates a byte containing that length, and then generates the
1948 encoded string data in the object file.
1949
1950 **Syntax:**
1951
1952 ``` {.assembly}
1953 .strl string
1954 ```
1955
1956 **Functionality:**
1957
1958 The `.strl` directive performs the following:
1959
1960 -   **Calculates string length:** Determines the length of the
1961     specified string in words, taking into account the Z-machine's
1962     5-bit byte encoding for strings.
1963 -   **Generates length byte:** Outputs a single byte containing the
1964     calculated length to the object file.
1965 -   **Encodes the string:** Converts the ASCII string into the
1966     Z-machine's 5-bit byte format, using frequent words and character
1967     set shifting as needed.
1968 -   **Outputs the string:** Generates the encoded string data in the
1969     object file, following the length byte.
1970
1971 **Special Cases:**
1972
1973 -   The string must be a short string, meaning it can be represented
1974     in 255 words or less.
1975
1976 **Error Conditions:**
1977
1978 An error occurs if the string length exceeds 255 words.
1979
1980 **Examples:**
1981
1982 ``` {.assembly}
1983 .strl "Hello, world!"  ; Defines a string with its length
1984 ```
1985
1986 **Use Cases:**
1987
1988 -   Creating self-contained string definitions where the length is
1989     explicitly stored alongside the string data.
1990 -   Simplifying string definition by combining the functionality of
1991     `.LEN` and `.STR` into a single directive.
1992
1993 **Note:** The `.strl` directive is a convenient way to define strings
1994 with their lengths, but it is equivalent to using `.len` followed by
1995 `.str`.
1996
1997 ### .TABLE
1998
1999 The `.TABLE` directive declares the beginning of a table definition.
2000 Tables are logical structures used to organize data in Z-code
2001 programs.
2002
2003 **Syntax:**
2004
2005 ``` {.assembly}
2006 .table [size]
2007 ```
2008
2009 **Functionality:**
2010
2011 The `.table` directive marks the start of a table definition. It can
2012 optionally take a `size` argument, which specifies the maximum size of
2013 the table in bytes. The assembler uses this information to:
2014
2015 -   **Check for size violations:** If a size is specified, the
2016     assembler ensures that the actual table data generated does not
2017     exceed the declared size.
2018 -   **Perform alignment:** The assembler may align the table data to a
2019     specific boundary depending on the target architecture or data
2020     type.
2021
2022 **Special Cases:**
2023
2024 -   If the `size` argument is omitted, the table size is not checked
2025     by the assembler. However, debugging versions of the ZIP
2026     interpreter may perform bounds checking at runtime.
2027
2028 **Error Conditions:**
2029
2030 An error occurs if the actual table size exceeds the declared size (if
2031 specified).
2032
2033 **Examples:**
2034
2035 ``` {.assembly}
2036 .table 100  ; Declares a table with a maximum size of 100 bytes
2037 .word data1, data2, data3
2038 .endt
2039 ```
2040
2041 **Use Cases:**
2042
2043 -   Defining tables of data with a specific size and ensuring that the
2044     size is not exceeded.
2045 -   Organizing data into logical structures for easier access and
2046     manipulation.
2047
2048 **Note:** The `.TABLE` directive must be paired with a `.ENDT`
2049 directive to mark the end of the table definition.
2050
2051 ### .TRUE
2052
2053 The `.TRUE` directive generates a word (two-byte) value of 1 in the
2054 object file. It is used to represent the boolean value `true` or to
2055 initialize memory locations with a non-zero value.
2056
2057 **Syntax:**
2058
2059 ``` {.assembly}
2060 .true
2061 ```
2062
2063 **Functionality:**
2064
2065 The `.true` directive simply generates a word with the value 1 at the
2066 current address in the object file.
2067
2068 **Special Cases:**
2069
2070 None.
2071
2072 **Error Conditions:**
2073
2074 None.
2075
2076 **Examples:**
2077
2078 ``` {.assembly}
2079 .true         ; Generates a word with value 1
2080 set flag1, .true  ; Sets the flag variable `flag1` to true
2081 ```
2082
2083 **Use Cases:**
2084
2085 -   Representing the boolean value `true` in conditional statements or
2086     data structures.
2087 -   Initializing variables or memory locations with a non-zero value.
2088
2089 **Note:** The `.true` directive is equivalent to using `.word 1`.
2090 However, `.true` provides better readability and clarity when
2091 representing boolean values.
2092
2093 ### .VOCBEG
2094
2095 The `.VOCBEG` directive declares the beginning of the vocabulary area.
2096 The vocabulary area contains words and associated information used by
2097 the `READ` and `LEX` instructions for parsing player input.
2098
2099 **Syntax:**
2100
2101 ``` {.assembly}
2102 .vocbeg record-length, key-length
2103 ```
2104
2105 **Functionality:**
2106
2107 The `.vocbeg` directive defines the following parameters for the
2108 vocabulary area:
2109
2110 -   **`record-length`:** Specifies the length of each vocabulary entry
2111     in bytes. This includes the word itself and any additional
2112     associated data.
2113 -   **`key-length`:** Specifies the length of the key used for sorting
2114     vocabulary entries. The key is typically the word itself, but it
2115     can be a shorter substring.
2116
2117 The assembler uses this information to:
2118
2119 -   **Allocate space for vocabulary entries:** Ensures that enough
2120     space is allocated in the object file for the vocabulary data.
2121 -   **Sort vocabulary entries (optional):** If the number of entries
2122     in the vocabulary table is specified as negative, the vocabulary
2123     is considered unsorted. Otherwise, the assembler sorts the entries
2124     based on their keys for efficient searching during input parsing.
2125
2126 **Special Cases:**
2127
2128 -   The vocabulary area is located in a separate section of the Z-code
2129     program and is accessed using the `VOCAB` word in the program
2130     header.
2131 -   The first byte of the vocabulary area specifies the number of
2132     self-inserting break characters used by the `READ` instruction.
2133 -   The format of the vocabulary entries depends on the
2134     `record-length` and `key-length` values specified in `.VOCBEG`.
2135
2136 **Error Conditions:**
2137
2138 -   An error occurs if `record-length` or `key-length` is zero or
2139     negative.
2140 -   An error occurs if the vocabulary area has an invalid length or
2141     structure.
2142
2143 **Examples:**
2144
2145 ``` {.assembly}
2146 .vocbeg 6, 3  ; Define vocabulary with 6-byte entries and 3-byte keys
2147
2148 ; ... vocabulary words and data ...
2149
2150 .vocend
2151 ```
2152
2153 **Use Cases:**
2154
2155 -   Defining the vocabulary of words that the game understands and can
2156     parse from player input.
2157 -   Optimizing input parsing by sorting the vocabulary for efficient
2158     searching.
2159
2160 **Note:** The `.VOCBEG` directive must be paired with a `.VOCEND`
2161 directive to mark the end of the vocabulary area.
2162
2163 ### .VOCEND
2164
2165 The `.VOCEND` directive marks the end of the vocabulary area. The
2166 vocabulary area contains words and associated information used by the
2167 `READ` and `LEX` instructions for parsing player input.
2168
2169 **Syntax:**
2170
2171 ``` {.assembly}
2172 .vocend
2173 ```
2174
2175 **Functionality:**
2176
2177 The `.VOCEND` directive must be used to terminate a vocabulary area
2178 that was previously declared with the `.VOCBEG` directive. It performs
2179 the following:
2180
2181 -   **Sorts vocabulary entries:** If the vocabulary is defined as
2182     sorted, the assembler sorts the entries based on their keys.
2183 -   **Outputs vocabulary data:** The assembler writes the vocabulary
2184     data to the object file in the appropriate format.
2185 -   **Finalizes vocabulary table:** The assembler performs any
2186     necessary operations to finalize the vocabulary table, such as
2187     calculating the total number of words.
2188
2189 **Special Cases:**
2190
2191 -   A `.VOCEND` directive without a preceding `.VOCBEG` directive is
2192     an error.
2193
2194 **Error Conditions:**
2195
2196 -   An error occurs if the vocabulary area has an invalid length or
2197     structure.
2198
2199 **Examples:**
2200
2201 ``` {.assembly}
2202 .vocbeg 6, 3  ; Define vocabulary with 6-byte entries and 3-byte keys
2203
2204 ; ... vocabulary words and data ...
2205
2206 .vocend
2207 ```
2208
2209 **Use Cases:**
2210
2211 -   Defining the vocabulary of words that the game understands and can
2212     parse from player input.
2213 -   Optimizing input parsing by sorting the vocabulary for efficient
2214     searching.
2215
2216 **Note:** The `.VOCBEG` and `.VOCEND` directives are essential for
2217 defining and managing the vocabulary used by the `READ` and `LEX`
2218 instructions. Proper structure and usage of the vocabulary area are
2219 crucial for correct input parsing.
2220
2221 ### .WORD
2222
2223 The `.WORD` directive instructs the assembler to generate one or more
2224 word (two-byte) values in the object file. It is used to define
2225 word-sized data or initialize specific memory locations with word
2226 values.
2227
2228 **Syntax:**
2229
2230 ``` {.assembly}
2231 .word value1 [, value2 ...]
2232 ```
2233
2234 **Functionality:**
2235
2236 The `.word` directive generates the specified word values sequentially
2237 in the object file. Each value can be:
2238
2239 -   **A constant expression:** Evaluates to a number within the range
2240     of -32768 to 65535.
2241 -   **A symbol:** Refers to a previously defined symbol representing a
2242     word value.
2243
2244 **Special Cases:**
2245
2246 -   If a single value is provided without the `.word` directive, it is
2247     implicitly treated as a `.word` directive.
2248
2249 **Error Conditions:**
2250
2251 An error occurs if a value exceeds the 16-bit word range.
2252
2253 **Examples:**
2254
2255 ``` {.assembly}
2256 .word 1000, 2000, 3000  ; Generates three words with values 1000, 2000, and 3000
2257 .word counter           ; Generates a word with the value of the symbol `counter`
2258 ```
2259
2260 **Use Cases:**
2261
2262 -   Defining word-sized data, such as numbers, pointers, or flags.
2263 -   Initializing memory locations with specific word values.
2264
2265 **Note:** The `.word` directive is a fundamental data definition
2266 directive used to generate word-sized data in Z-code programs.
2267
2268 ### .ZWORD
2269
2270 The `.ZWORD` directive generates a Z-word string in the object file.
2271 Z-word strings are similar to regular Z-strings but are limited to a
2272 maximum of two words (four bytes). They are used to store short text
2273 snippets or identifiers efficiently.
2274
2275 **Syntax:**
2276
2277 ``` {.assembly}
2278 .zword string
2279 ```
2280
2281 **Functionality:**
2282
2283 The `.zword` directive performs the following:
2284
2285 -   **Encodes the string:** Converts the ASCII string into the
2286     Z-machine's 5-bit byte format, similar to the `.STR` directive but
2287     limited to two words.
2288 -   **Outputs the string:** Generates the encoded string data in the
2289     object file.
2290 -   **Pads the string:** If the string is less than two words, it is
2291     padded with the standard pad character (5) to fill the remaining
2292     space.
2293
2294 **Special Cases:**
2295
2296 -   Z-word strings are always four bytes long, regardless of the
2297     actual string length.
2298
2299 **Error Conditions:**
2300
2301 An error occurs if the string length exceeds two words.
2302
2303 **Examples:**
2304
2305 ``` {.assembly}
2306 .zword "OK"  ; Defines a Z-word string
2307 ```
2308
2309 **Use Cases:**
2310
2311 -   Storing short text snippets or identifiers efficiently.
2312 -   Defining data structures that require fixed-length strings.
2313
2314 **Note:** The `.ZWORD` directive is used for defining short strings
2315 that need to be stored efficiently. For longer strings, the `.STR` or
2316 `.GSTR` directives are more appropriate.
2317
2318 ### ADD
2319
2320 **ADD** is an opcode that performs addition on two 16-bit word values.
2321 It adds the first operand to the second operand and returns the
2322 result.
2323
2324 **Syntax:**
2325
2326 ``` {.assembly}
2327 add arg1:int, arg2:int > val
2328 ```
2329
2330 **Functionality:**
2331
2332 The `add` opcode performs the following:
2333
2334 -   **Adds `arg1` and `arg2`:** Performs integer addition.
2335 -   **Stores the result:** The sum is stored in the specified
2336     destination (`val`). If no destination is provided, the result is
2337     pushed onto the game stack.
2338
2339 **Special Cases:**
2340
2341 -   If the result of the addition overflows the 16-bit word size, an
2342     error occurs.
2343
2344 **Error Conditions:**
2345
2346 An error occurs if the addition result overflows the 16-bit word
2347 range.
2348
2349 **Examples:**
2350
2351 ``` {.assembly}
2352 add 5, 10 > result  ; Adds 5 and 10, stores the sum (15) in `result`
2353 ```
2354
2355 **Use Cases:**
2356
2357 -   Performing integer addition calculations.
2358 -   Increasing values or accumulating totals.
2359
2360 **Note:** The `add` opcode performs signed integer addition. If the
2361 operands are unsigned, the programmer needs to handle potential
2362 overflow conditions.
2363
2364 ### ASHIFT
2365
2366 **ASHIFT** is an opcode that performs an arithmetic shift on a 16-bit
2367 integer value. It shifts the bits of the operand to the left or right,
2368 depending on the specified shift amount.
2369
2370 **Syntax:**
2371
2372 ``` {.assembly}
2373 ashift int, n > val
2374 ```
2375
2376 **Functionality:**
2377
2378 The `ashift` opcode performs the following:
2379
2380 -   **Shifts the bits of `int`:**
2381     -   If `n` is positive, `int` is shifted left by `n` bits.
2382     -   If `n` is negative, `int` is shifted right by the absolute
2383         value of `n` bits.
2384 -   **Preserves the sign bit:** In an arithmetic shift, the sign bit
2385     of the operand is replicated to fill in the vacated bits during a
2386     right shift. This ensures that the sign of the number is
2387     preserved.
2388 -   **Stores the result:** The shifted value is stored in the
2389     specified destination (`val`). If no destination is provided, the
2390     result is pushed onto the game stack.
2391
2392 **Special Cases:**
2393
2394 -   If `n` is zero, the value of `int` remains unchanged.
2395 -   If the shift amount exceeds the word size (16 bits), the result is
2396     undefined.
2397
2398 **Error Conditions:**
2399
2400 None.
2401
2402 **Examples:**
2403
2404 ``` {.assembly}
2405 ashift num, 2 > shifted  ; Shifts the value in `num` left by 2 bits
2406 ashift num, -1 > shifted ; Shifts the value in `num` right by 1 bit
2407 ```
2408
2409 **Use Cases:**
2410
2411 -   Multiplying or dividing numbers by powers of two efficiently.
2412 -   Manipulating individual bits within a word.
2413 -   Implementing bitwise operations and algorithms.
2414
2415 **Note:** The `ashift` opcode performs an arithmetic shift, which
2416 preserves the sign of the operand. For a logical shift, where the sign
2417 bit is not replicated, use the `shift` opcode.
2418
2419 ### ASSIGNED?
2420
2421 **ASSIGNED?** is an opcode that checks whether an optional argument
2422 was provided when calling the current function. It is used to
2423 implement conditional logic based on the presence or absence of
2424 optional arguments.
2425
2426 **Syntax:**
2427
2428 ``` {.assembly}
2429 assigned? opt:var /pred
2430 ```
2431
2432 **Functionality:**
2433
2434 The `assigned?` opcode evaluates to true if an optional argument was
2435 supplied for the variable `opt`. Otherwise, it evaluates to false. The
2436 result is used to determine whether to take a conditional branch, as
2437 specified by the predicate (`/pred`) syntax.
2438
2439 **Special Cases:**
2440
2441 -   The `assigned?` opcode can only be used within a function to check
2442     for optional arguments passed to that function.
2443 -   The variable `opt` must be a local variable of the function.
2444
2445 **Error Conditions:**
2446
2447 An error occurs if `assigned?` is used outside of a function or if
2448 `opt` is not a local variable.
2449
2450 **Examples:**
2451
2452 ``` {.assembly}
2453 .funct my_function, optional_arg
2454     assigned? optional_arg / handle_optional
2455     ; ... code if optional_arg is not assigned ...
2456 handle_optional:
2457     ; ... code to handle optional_arg ...
2458 ```
2459
2460 **Use Cases:**
2461
2462 -   Implementing functions with optional arguments.
2463 -   Performing different actions depending on whether optional
2464     arguments are provided.
2465
2466 **Note:** The `assigned?` opcode is specific to the Z-machine and does
2467 not have a direct equivalent in most other assembly languages. It is a
2468 useful feature for implementing functions with flexible argument
2469 lists.
2470
2471 ### BAND
2472
2473 **BAND** is an opcode that performs a bitwise AND operation on two
2474 16-bit word values. It combines the corresponding bits of the
2475 operands, setting each bit in the result to 1 only if both
2476 corresponding bits in the operands are also 1.
2477
2478 **Syntax:**
2479
2480 ``` {.assembly}
2481 band word1, word2 > val
2482 ```
2483
2484 **Functionality:**
2485
2486 The `band` opcode performs the following:
2487
2488 -   **Performs bitwise AND:** Combines the corresponding bits of
2489     `word1` and `word2` using the logical AND operation.
2490 -   **Stores the result:** The resulting word is stored in the
2491     specified destination (`val`). If no destination is provided, the
2492     result is pushed onto the game stack.
2493
2494 **Special Cases:**
2495
2496 None.
2497
2498 **Error Conditions:**
2499
2500 None.
2501
2502 **Examples:**
2503
2504 ``` {.assembly}
2505 band flags, mask > result  ; Performs bitwise AND between `flags` and `mask`
2506 ```
2507
2508 **Use Cases:**
2509
2510 -   Masking out specific bits in a word.
2511 -   Checking the state of individual bits or groups of bits.
2512 -   Implementing bitwise algorithms and operations.
2513
2514 **Note:** The `band` opcode is a fundamental bitwise operation used in
2515 various programming tasks, including data manipulation, flag handling,
2516 and low-level control.
2517
2518 ### BCOM
2519
2520 **BCOM** is an opcode that performs a bitwise complement (NOT)
2521 operation on a 16-bit word value. It inverts each bit in the operand,
2522 setting 1s to 0s and vice versa.
2523
2524 **Syntax:**
2525
2526 ``` {.assembly}
2527 bcom word > val
2528 ```
2529
2530 **Functionality:**
2531
2532 The `bcom` opcode performs the following:
2533
2534 -   **Inverts the bits of `word`:** Flips each bit in the operand,
2535     changing 1s to 0s and 0s to 1s.
2536 -   **Stores the result:** The resulting word is stored in the
2537     specified destination (`val`). If no destination is provided, the
2538     result is pushed onto the game stack.
2539
2540 **Special Cases:**
2541
2542 None.
2543
2544 **Error Conditions:**
2545
2546 None.
2547
2548 **Examples:**
2549
2550 ``` {.assembly}
2551 bcom flags > inverted  ; Inverts the bits in the `flags` word
2552 ```
2553
2554 **Use Cases:**
2555
2556 -   Inverting the state of individual bits or groups of bits.
2557 -   Implementing bitwise algorithms and operations.
2558 -   Toggling the values of flags or status bits.
2559
2560 **Note:** The `bcom` opcode is a fundamental bitwise operation used in
2561 various programming tasks, including data manipulation, flag handling,
2562 and low-level control.
2563
2564 ### BOR
2565
2566 **BOR** is an opcode that performs a bitwise OR operation on two
2567 16-bit word values. It combines the corresponding bits of the
2568 operands, setting each bit in the result to 1 if either or both of the
2569 corresponding bits in the operands are 1.
2570
2571 **Syntax:**
2572
2573 ``` {.assembly}
2574 bor word1, word2 > val
2575 ```
2576
2577 **Functionality:**
2578
2579 The `bor` opcode performs the following:
2580
2581 -   **Performs bitwise OR:** Combines the corresponding bits of
2582     `word1` and `word2` using the logical OR operation.
2583 -   **Stores the result:** The resulting word is stored in the
2584     specified destination (`val`). If no destination is provided, the
2585     result is pushed onto the game stack.
2586
2587 **Special Cases:**
2588
2589 None.
2590
2591 **Error Conditions:**
2592
2593 None.
2594
2595 **Examples:**
2596
2597 ``` {.assembly}
2598 bor flags, mask > result  ; Performs bitwise OR between `flags` and `mask`
2599 ```
2600
2601 **Use Cases:**
2602
2603 -   Setting specific bits in a word.
2604 -   Combining flags or status bits.
2605 -   Implementing bitwise algorithms and operations.
2606
2607 **Note:** The `bor` opcode is a fundamental bitwise operation used in
2608 various programming tasks, including data manipulation, flag handling,
2609 and low-level control.
2610
2611 ### BTST
2612
2613 **BTST** is an opcode that tests whether specific bits are set in a
2614 16-bit word value. It acts as a predicate, meaning it evaluates a
2615 condition and implicitly performs a conditional branch based on the
2616 result.
2617
2618 **Syntax:**
2619
2620 ``` {.assembly}
2621 btst word1, word2 /pred
2622 ```
2623
2624 **Functionality:**
2625
2626 The `btst` opcode performs the following:
2627
2628 -   **Checks bit states:** Compares the corresponding bits of `word1`
2629     and `word2`.
2630 -   **Evaluates predicate:** The predicate succeeds (evaluates to
2631     true) if every bit that is set (1) in `word2` is also set in
2632     `word1`. Otherwise, the predicate fails (evaluates to false).
2633 -   **Conditional branch:** Based on the predicate result and the
2634     specified branch polarity (`/pred`), the interpreter may perform a
2635     conditional jump to a specified target.
2636
2637 **Special Cases:**
2638
2639 -   If all bits in `word2` are 0, the predicate always succeeds.
2640
2641 **Error Conditions:**
2642
2643 None.
2644
2645 **Examples:**
2646
2647 ``` {.assembly}
2648 btst flags, mask / handle_flags  ; Branch to `handle_flags` if all bits set in `mask` are also set in `flags`
2649 ```
2650
2651 **Use Cases:**
2652
2653 -   Checking the state of individual bits or groups of bits within a
2654     word.
2655 -   Implementing conditional logic based on bit states.
2656 -   Handling flags or status bits efficiently.
2657
2658 **Note:** The `btst` opcode is a useful tool for working with bitwise
2659 data and implementing conditional behavior based on specific bit
2660 patterns.
2661
2662 ### BUFOUT
2663
2664 **BUFOUT** is an opcode that controls whether output to the screen is
2665 buffered or unbuffered. Buffering allows the interpreter to optimize
2666 line breaks and handle text wrapping more effectively.
2667
2668 **Syntax:**
2669
2670 ``` {.assembly}
2671 bufout int
2672 ```
2673
2674 **Functionality:**
2675
2676 The `bufout` opcode sets the output buffering mode based on the value
2677 of `int`:
2678
2679 -   **`int` = 1:** Enables output buffering (default). Output is
2680     accumulated in a buffer and printed to the screen when a newline
2681     character is encountered or the buffer is full.
2682 -   **`int` = 0:** Disables output buffering. All currently buffered
2683     output is immediately sent to the screen, and subsequent output is
2684     printed as it is generated.
2685
2686 **Special Cases:**
2687
2688 -   Output redirected to a table using `DIROUT 3` is never buffered,
2689     regardless of the `bufout` setting.
2690
2691 **Error Conditions:**
2692
2693 An error occurs if `int` is not 0 or 1.
2694
2695 **Examples:**
2696
2697 ``` {.assembly}
2698 bufout 0  ; Disables output buffering
2699 print "Immediate output"
2700 bufout 1  ; Re-enables output buffering
2701 ```
2702
2703 **Use Cases:**
2704
2705 -   Disabling output buffering can be useful for displaying text
2706     immediately without waiting for a newline or buffer to fill. This
2707     might be used for real-time updates or interactive prompts.
2708 -   In most cases, output buffering should be enabled to allow the
2709     interpreter to handle line breaks and text wrapping efficiently.
2710
2711 **Note:** The `bufout` opcode is rarely needed in typical Z-code
2712 programs, as most output operations implicitly handle buffering as
2713 necessary.
2714
2715 ### CALL
2716
2717 **CALL** is an opcode that calls a function with three arguments and
2718 returns a value. It is the most general form of the function call
2719 instruction, allowing for a flexible number of arguments and return
2720 values.
2721
2722 **Syntax:**
2723
2724 ``` {.assembly}
2725 call fcn, arg1:any, arg2:any, arg3:any > val
2726 ```
2727
2728 **Functionality:**
2729
2730 The `call` opcode performs the following:
2731
2732 -   **Pushes arguments onto the stack:** Pushes the three arguments
2733     (`arg1`, `arg2`, and `arg3`) onto the game stack.
2734 -   **Calls the function:** Transfers control to the function
2735     specified by `fcn`. The function address is calculated by shifting
2736     `fcn` left by two bits and adding the function offset (`FOFF`)
2737     shifted left by three bits.
2738 -   **Retrieves return value:** When the function returns, its return
2739     value is retrieved and stored in the specified destination
2740     (`val`). If no destination is provided, the value is pushed onto
2741     the game stack.
2742
2743 **Special Cases:**
2744
2745 -   If `fcn` is zero, the `call` opcode acts as if it called a
2746     function that immediately returned false.
2747
2748 **Error Conditions:**
2749
2750 An error occurs if `fcn` is not a valid function pointer.
2751
2752 **Examples:**
2753
2754 ``` {.assembly}
2755 call process_input, input_buffer, parse_buffer, options > result  ; Calls the `process_input` function with three arguments
2756 ```
2757
2758 **Use Cases:**
2759
2760 -   Calling functions with three arguments.
2761 -   Implementing subroutines and modular code structures.
2762
2763 **Note:** The `CALL` opcode is the most general form of the function
2764 call instruction. For functions with fewer arguments, the `CALL1` and
2765 `CALL2` opcodes can be used for more efficient encoding. The compiler
2766 automatically chooses the appropriate opcode based on the number of
2767 arguments and their types.
2768
2769 ### CALL1
2770
2771 **CALL1** is an opcode that calls a function with one argument and
2772 returns a value. It is a more compact version of the `CALL` opcode,
2773 optimized for functions with a single argument.
2774
2775 **Syntax:**
2776
2777 ``` {.assembly}
2778 call1 fcn > val
2779 ```
2780
2781 **Functionality:**
2782
2783 The `call1` opcode performs the following:
2784
2785 -   **Pushes arguments onto the stack:** Pushes the single argument
2786     onto the game stack.
2787 -   **Calls the function:** Transfers control to the function
2788     specified by `fcn`. The function address is calculated by shifting
2789     `fcn` left by two bits and adding the function offset (`FOFF`)
2790     shifted left by three bits.
2791 -   **Retrieves return value:** When the function returns, its return
2792     value is retrieved and stored in the specified destination
2793     (`val`). If no destination is provided, the value is pushed onto
2794     the game stack.
2795
2796 **Special Cases:**
2797
2798 -   If `fcn` is zero, the `call1` opcode acts as if it called a
2799     function that immediately returned false.
2800
2801 **Error Conditions:**
2802
2803 An error occurs if `fcn` is not a valid function pointer.
2804
2805 **Examples:**
2806
2807 ``` {.assembly}
2808 call1 get_input > input_char  ; Calls the `get_input` function and stores the returned character in `input_char`
2809 ```
2810
2811 **Use Cases:**
2812
2813 -   Calling functions with a single argument efficiently.
2814 -   Implementing subroutines and modular code structures.
2815
2816 **Note:** The `call1` opcode is generated by the compiler when it
2817 detects a function call with one argument. It is not typically used
2818 directly by programmers.
2819
2820 ### CALL2
2821
2822 **CALL2** is an opcode that calls a function with two arguments and
2823 returns a value. It is a more compact version of the `CALL` opcode,
2824 optimized for functions with two arguments.
2825
2826 **Syntax:**
2827
2828 ``` {.assembly}
2829 call2 fcn, arg > val
2830 ```
2831
2832 **Functionality:**
2833
2834 The `call2` opcode performs the following:
2835
2836 -   **Pushes arguments onto the stack:** Pushes the two arguments
2837     (`fcn` and `arg`) onto the game stack.
2838 -   **Calls the function:** Transfers control to the function
2839     specified by `fcn`. The function address is calculated by shifting
2840     `fcn` left by two bits and adding the function offset (`FOFF`)
2841     shifted left by three bits.
2842 -   **Retrieves return value:** When the function returns, its return
2843     value is retrieved and stored in the specified destination
2844     (`val`). If no destination is provided, the value is pushed onto
2845     the game stack.
2846
2847 **Special Cases:**
2848
2849 -   If `fcn` is zero, the `call2` opcode acts as if it called a
2850     function that immediately returned false.
2851
2852 **Error Conditions:**
2853
2854 An error occurs if `fcn` is not a valid function pointer.
2855
2856 **Examples:**
2857
2858 ``` {.assembly}
2859 call2 add, num1, num2 > sum  ; Calls the `add` function with `num1` and `num2` as arguments, stores the sum in `sum`
2860 ```
2861
2862 **Use Cases:**
2863
2864 -   Calling functions with two arguments efficiently.
2865 -   Implementing subroutines and modular code structures.
2866
2867 **Note:** The `call2` opcode is generated by the compiler when it
2868 detects a function call with two arguments. It is not typically used
2869 directly by programmers.
2870
2871 ### CATCH
2872
2873 **CATCH** is an opcode that captures an exception thrown by the
2874 `THROW` opcode and provides a way to handle it. It is used in
2875 conjunction with `THROW` to implement exception handling and non-local
2876 control flow.
2877
2878 **Syntax:**
2879
2880 ``` {.assembly}
2881 catch > frame
2882 ```
2883
2884 **Functionality:**
2885
2886 The `catch` opcode performs the following:
2887
2888 -   **Captures exception:** If an exception has been thrown using the
2889     `THROW` opcode, the `catch` opcode captures it and prevents the
2890     program from terminating.
2891 -   **Stores frame pointer:** The opcode stores a pointer to the
2892     current call frame in the specified destination (`frame`). This
2893     frame pointer identifies the point in the call stack where the
2894     exception was caught.
2895 -   **Continues execution:** The program continues execution from the
2896     instruction following the `catch` opcode.
2897
2898 **Special Cases:**
2899
2900 -   If no exception has been thrown, the `catch` opcode stores 0 in
2901     the `frame` variable and continues execution.
2902 -   The `CATCH` and `THROW` opcodes do not work within "internal"
2903     calls, such as timeout handling routines called by `READ` or
2904     `INPUT`.
2905
2906 **Error Conditions:**
2907
2908 None.
2909
2910 **Examples:**
2911
2912 ``` {.assembly}
2913 catch > frame
2914 ; ... some code that might throw an exception ...
2915 if frame != 0
2916     ; ... handle the exception ...
2917 ```
2918
2919 **Use Cases:**
2920
2921 -   Implementing exception handling to deal with errors or unexpected
2922     conditions.
2923 -   Performing non-local control flow, such as exiting multiple nested
2924     functions at once.
2925
2926 **Note:** The `CATCH` and `THROW` opcodes provide a mechanism for
2927 exception handling and non-local control flow in Z-code programs. They
2928 should be used with caution to avoid complex control flow and
2929 potential errors.
2930
2931 ### CLEAR
2932
2933 **CLEAR** is an opcode that clears a window or the entire screen,
2934 filling it with the current background color.
2935
2936 **Syntax:**
2937
2938 ``` {.assembly}
2939 clear window:int
2940 ```
2941
2942 **Functionality:**
2943
2944 The `clear` opcode clears the specified window or the entire screen:
2945
2946 -   **`window` = 0 to 7:** Clears the corresponding window.
2947 -   **`window` = -1:** Unsplits the screen (if it was previously
2948     split) and clears the entire screen.
2949 -   **`window` = -2:** Clears the entire screen without affecting
2950     window attributes or cursor position.
2951
2952 When a window is cleared, the cursor is moved to the top-left corner
2953 of that window.
2954
2955 **Special Cases:**
2956
2957 -   If the `window` argument is omitted, the current window is
2958     cleared.
2959
2960 **Error Conditions:**
2961
2962 An error occurs if `window` is not within the valid range (-2 to 7).
2963
2964 **Examples:**
2965
2966 ``` {.assembly}
2967 clear 0      ; Clears the main window (window 0)
2968 clear -2     ; Clears the entire screen
2969 ```
2970
2971 **Use Cases:**
2972
2973 -   Clearing the screen or a window to prepare for new output.
2974 -   Erasing previous content and resetting the display.
2975
2976 **Note:** The `clear` opcode is a convenient way to clear the screen
2977 or a window. It is important to remember that clearing a window moves
2978 the cursor to its top-left corner.
2979
2980 ### COLOR
2981
2982 **COLOR** is an opcode that sets the foreground and background colors
2983 for subsequent text output.
2984
2985 **Syntax:**
2986
2987 ``` {.assembly}
2988 color fore:int, back:int
2989 ```
2990
2991 **Functionality:**
2992
2993 The `color` opcode sets the colors for text output as follows:
2994
2995 -   **`fore`:** Specifies the foreground color (text color).
2996 -   **`back`:** Specifies the background color.
2997
2998 The colors are interpreted according to the following values:
2999
3000 -   **-1:** Use the color of the pixel at the current cursor position.
3001 -   **0:** No change.
3002 -   **1:** System default color.
3003 -   **2:** Black.
3004 -   **3:** Red.
3005 -   **4:** Green.
3006 -   **5:** Yellow.
3007 -   **6:** Blue.
3008 -   **7:** Magenta.
3009 -   **8:** Cyan.
3010 -   **9:** White.
3011 -   **10:** Light gray
3012 -   **11:** Gray
3013 -   **12:** Dark gray
3014
3015 **Special Cases:**
3016
3017 -   The availability of colors and their specific shades may vary
3018     depending on the target machine and display capabilities.
3019 -   On some machines, like the Amiga, the colors set for the main
3020     window (window 0) are used for all windows.
3021
3022 **Error Conditions:**
3023
3024 An error occurs if `fore` or `back` is not within the valid range (-1
3025 to 12).
3026
3027 **Examples:**
3028
3029 ``` {.assembly}
3030 color 3, 2  ; Sets foreground color to red and background color to black
3031 color 0, 1  ; Sets background color to the system default
3032 ```
3033
3034 **Use Cases:**
3035
3036 -   Changing the colors of text output for visual distinction or
3037     emphasis.
3038 -   Enhancing the game's appearance and atmosphere.
3039
3040 **Note:** Games should be designed to handle machines that do not
3041 support color selection. The `MODE` byte in the program header
3042 indicates whether the `COLOR` operation is available.
3043
3044 ### COPYT
3045
3046 **COPYT** is an opcode that copies a specified number of bytes from
3047 one table to another. It can also be used to zero out a section of
3048 memory or duplicate data within a table.
3049
3050 **Syntax:**
3051
3052 ``` {.assembly}
3053 copyt source:tbl, dest:tbl, length:int
3054 ```
3055
3056 **Functionality:**
3057
3058 The `copyt` opcode copies bytes from the source table (`source`) to
3059 the destination table (`dest`) according to the specified `length`:
3060
3061 -   **Positive `length`:** Copies `length` bytes from `source` to
3062     `dest`. If the source and destination regions overlap, the opcode
3063     performs a "backwards" copy to avoid overwriting data before it is
3064     copied.
3065 -   **Negative `length`:** Copies `length` bytes from `source` to
3066     `dest` without checking for overlap. This allows for data
3067     duplication within the source table.
3068 -   **Zero `dest`:** If `dest` is zero, the opcode zeroes out `length`
3069     bytes in the source table.
3070
3071 **Special Cases:**
3072
3073 -   The `copyt` opcode can be used to copy data to itself, allowing
3074     for shifting or duplication of data within a table.
3075
3076 **Error Conditions:**
3077
3078 An error occurs if:
3079
3080 -   `source` or `dest` is not a valid table pointer.
3081 -   The copy operation would exceed the bounds of the tables.
3082
3083 **Examples:**
3084
3085 ``` {.assembly}
3086 copyt buffer1, buffer2, 100  ; Copies 100 bytes from buffer1 to buffer2
3087 copyt table, 0, 50           ; Zeroes out the first 50 bytes of table
3088 copyt table, table + 10, 20  ; Duplicates 20 bytes within table, shifting them by 10 bytes
3089 ```
3090
3091 **Use Cases:**
3092
3093 -   Copying data between tables.
3094 -   Zeroing out sections of memory.
3095 -   Duplicating data within a table.
3096 -   Implementing memory management or data manipulation routines.
3097
3098 **Note:** The `copyt` opcode provides a flexible way to copy and
3099 manipulate data within tables. It is important to be aware of the
3100 overlap behavior when using positive lengths to avoid unintended data
3101 overwrites.
3102
3103 ### CRLF
3104
3105 **CRLF** is an opcode that prints an end-of-line sequence to the
3106 screen. This typically results in a carriage return and line feed,
3107 moving the cursor to the beginning of the next line.
3108
3109 **Syntax:**
3110
3111 ``` {.assembly}
3112 crlf
3113 ```
3114
3115 **Functionality:**
3116
3117 The `crlf` opcode outputs an end-of-line sequence to the current
3118 window. The specific behavior depends on the window's attributes:
3119
3120 -   **Scrolling window:** The window contents scroll up by one line,
3121     and the cursor is moved to the beginning of the newly created
3122     empty line.
3123 -   **Non-scrolling window:** The cursor is moved to the beginning of
3124     the next line within the window. If the window is full, the output
3125     may be clipped or overwritten.
3126
3127 **Special Cases:**
3128
3129 None.
3130
3131 **Error Conditions:**
3132
3133 None.
3134
3135 **Examples:**
3136
3137 ``` {.assembly}
3138 print "This is a line."
3139 crlf
3140 print "This is on the next line."
3141 ```
3142
3143 **Use Cases:**
3144
3145 -   Starting a new line of output.
3146 -   Separating paragraphs or sections of text.
3147 -   Formatting text display within windows.
3148
3149 **Note:** The `crlf` opcode is a basic output operation used to
3150 control the vertical positioning of text on the screen.
3151
3152 ### CURGET
3153
3154 **CURGET** is an opcode that retrieves the current cursor position
3155 within a window and stores it in a table.
3156
3157 **Syntax:**
3158
3159 ``` {.assembly}
3160 curget output:tbl
3161 ```
3162
3163 **Functionality:**
3164
3165 The `curget` opcode retrieves the current cursor position in the
3166 specified window and writes the coordinates into the `output` table:
3167
3168 -   **Word 0 of `output`:** Contains the Y coordinate of the cursor
3169     (row number, 1-based).
3170 -   **Word 1 of `output`:** Contains the X coordinate of the cursor
3171     (column number, 1-based).
3172
3173 **Special Cases:**
3174
3175 -   If the `window` argument is omitted, the current window is used.
3176
3177 **Error Conditions:**
3178
3179 An error occurs if:
3180
3181 -   `output` is not a valid table pointer.
3182 -   The `output` table does not have enough space to store the
3183     coordinates (at least two words).
3184
3185 **Examples:**
3186
3187 ``` {.assembly}
3188 curget cursor_pos  ; Retrieves the cursor position in the current window
3189 ```
3190
3191 **Use Cases:**
3192
3193 -   Determining the current cursor position for display or interaction
3194     purposes.
3195 -   Implementing custom cursor movement or text editing routines.
3196
3197 **Note:** While `CURGET` can be used to retrieve the cursor position,
3198 it is generally recommended to use the `WINGET` opcode with the
3199 appropriate offset values, as it provides more flexibility and can
3200 access other window properties as well.
3201
3202 ### CURSET
3203
3204 **CURSET** is an opcode that sets the cursor position within a window
3205 to specified coordinates.
3206
3207 **Syntax:**
3208
3209 ``` {.assembly}
3210 curset y:int, x:int [, window:int]
3211 ```
3212
3213 **Functionality:**
3214
3215 The `curset` opcode sets the cursor position in the specified window
3216 to the coordinates (`y`, `x`):
3217
3218 -   **`y`:** The Y coordinate (row number, 1-based).
3219 -   **`x`:** The X coordinate (column number, 1-based).
3220
3221 If the coordinates are outside the window's boundaries, they are
3222 adjusted to the closest valid position within the window.
3223
3224 **Special Cases:**
3225
3226 -   If the `window` argument is omitted, the current window is used.
3227 -   If `y` is -1, the cursor is turned off.
3228 -   If `y` is -2, the cursor is turned on. In this case, the `x`
3229     argument is ignored.
3230
3231 **Error Conditions:**
3232
3233 An error occurs if:
3234
3235 -   `window` is not within the valid range (-3 to 7).
3236 -   `y` or `x` is negative (except for the special cases mentioned
3237     above).
3238
3239 **Examples:**
3240
3241 ``` {.assembly}
3242 curset 5, 10        ; Sets the cursor to row 5, column 10 in the current window
3243 curset 1, 1, 2      ; Sets the cursor to the top-left corner of window 2
3244 curset -1           ; Turns off the cursor
3245 ```
3246
3247 **Use Cases:**
3248
3249 -   Positioning the cursor for text output or user interaction.
3250 -   Implementing custom cursor movement or text editing routines.
3251
3252 **Note:** The `curset` opcode provides a direct way to set the cursor
3253 position. However, for more complex window manipulations, consider
3254 using the `WINPOS` and `WINSIZE` opcodes.
3255
3256 ### DCLEAR
3257
3258 **DCLEAR** is an opcode that clears the area occupied by a previously
3259 displayed picture, restoring the window's background color.
3260
3261 **Syntax:**
3262
3263 ``` {.assembly}
3264 dclear picture:int [, y:int, x:int]
3265 ```
3266
3267 **Functionality:**
3268
3269 The `dclear` opcode clears the area of the specified picture:
3270
3271 -   **`picture`:** The ID number of the picture to clear.
3272 -   **`y` and `x` (optional):** The coordinates where the picture was
3273     displayed (in pixels). If omitted, the opcode uses the coordinates
3274     where the picture was last displayed.
3275
3276 The opcode restores the window's background color in the area
3277 previously occupied by the picture.
3278
3279 **Special Cases:**
3280
3281 None.
3282
3283 **Error Conditions:**
3284
3285 An error occurs if:
3286
3287 -   `picture` is not a valid picture ID.
3288 -   The coordinates (`y`, `x`) are outside the window's boundaries.
3289
3290 **Examples:**
3291
3292 ``` {.assembly}
3293 display 10, 10, 10  ; Displays picture 10 at coordinates (10, 10)
3294 dclear 10          ; Clears the area occupied by picture 10
3295 ```
3296
3297 **Use Cases:**
3298
3299 -   Removing pictures from the screen.
3300 -   Restoring the window's background color after displaying a
3301     picture.
3302
3303 **Note:** The `DCLEAR` opcode is used in conjunction with the
3304 `DISPLAY` opcode to manage the display of pictures within Z-code
3305 programs.
3306
3307 ### DEC
3308
3309 **DEC** is an opcode that decrements the value of a variable by 1.
3310
3311 **Syntax:**
3312
3313 ``` {.assembly}
3314 dec var
3315 ```
3316
3317 **Functionality:**
3318
3319 The `dec` opcode subtracts 1 from the value of the specified variable
3320 (`var`).
3321
3322 **Special Cases:**
3323
3324 None.
3325
3326 **Error Conditions:**
3327
3328 None.
3329
3330 **Examples:**
3331
3332 ``` {.assembly}
3333 dec counter  ; Decrements the value of the variable `counter`
3334 ```
3335
3336 **Use Cases:**
3337
3338 -   Decrementing counters or loop variables.
3339 -   Reducing the value of a variable by a fixed amount.
3340
3341 **Note:** The `dec` opcode is a convenient way to decrement a variable
3342 by 1. For more complex arithmetic operations, use the `SUB` opcode.
3343
3344 ### DIRIN
3345
3346 **DIRIN** is an opcode that redirects input from a specified device.
3347 It allows the Z-code program to receive input from sources other than
3348 the keyboard, such as command files or scripts.
3349
3350 **Syntax:**
3351
3352 ``` {.assembly}
3353 dirin device:int [, any1, any2, any3]
3354 ```
3355
3356 **Functionality:**
3357
3358 The `dirin` opcode redirects input based on the value of `device`:
3359
3360 -   **`device` = 0:** Keyboard input (default).
3361 -   **`device` = 1:** Command file input. The interpreter reads input
3362     from a previously created command file, typically generated using
3363     `DIROUT 4`.
3364
3365 The additional arguments (`any1`, `any2`, `any3`) are currently unused
3366 and should be ignored by the interpreter.
3367
3368 **Special Cases:**
3369
3370 -   Not all interpreters implement command file input. If the
3371     interpreter does not support it, the `dirin 1` instruction should
3372     be ignored.
3373
3374 **Error Conditions:**
3375
3376 An error occurs if `device` is not 0 or 1.
3377
3378 **Examples:**
3379
3380 ``` {.assembly}
3381 dirin 1  ; Redirects input to the command file
3382 ```
3383
3384 **Use Cases:**
3385
3386 -   Reading commands from a script file for automated testing or
3387     gameplay recording.
3388 -   Implementing custom input methods or interactive sequences.
3389
3390 **Note:** The `dirin` opcode is used in conjunction with `DIROUT` to
3391 manage input and output redirection.
3392
3393 ### DIROUT
3394
3395 **DIROUT** is an opcode that redirects output to a specified device.
3396 It allows the Z-code program to send output to destinations other than
3397 the screen, such as the transcript or a table.
3398
3399 **Syntax:**
3400
3401 ``` {.assembly}
3402 dirout device:int [, any1, any2, any3]
3403 ```
3404
3405 **Functionality:**
3406
3407 The `dirout` opcode redirects output based on the value of `device`:
3408
3409 -   **`device` = 1:** Screen output (default).
3410 -   **`device` = -1:** Disables screen output.
3411 -   **`device` = 2:** Transcript output. Sends all subsequent output
3412     to the transcript device, which can be a file, printer, or other
3413     suitable destination.
3414 -   **`device` = -2:** Disables transcript output.
3415 -   **`device` = 3:** Table output. Sends output to the table
3416     specified by `any1`. The `any2` argument can optionally specify
3417     justification for formatted tables.
3418 -   **`device` = -3:** Disables table output.
3419 -   **`device` = 4:** Command recording. Creates a command file and
3420     writes all subsequent input commands to it.
3421 -   **`device` = -4:** Disables command recording.
3422
3423 **Special Cases:**
3424
3425 -   If the screen device is disabled and the transcript device is
3426     enabled, output is still sent to the transcript.
3427 -   Table output using `dirout 3` is not buffered, regardless of the
3428     `BUFOUT` setting.
3429 -   Not all interpreters implement command recording (device 4).
3430
3431 **Error Conditions:**
3432
3433 An error occurs if `device` is not within the valid range (-4 to 4).
3434
3435 **Examples:**
3436
3437 ``` {.assembly}
3438 dirout 2  ; Enables transcript output
3439 dirout -1 ; Disables screen output
3440 dirout 3, table, 80  ; Redirects output to `table` with right justification at 80 pixels
3441 ```
3442
3443 **Use Cases:**
3444
3445 -   Sending output to the transcript for debugging or recording
3446     purposes.
3447 -   Creating formatted tables for display using `PRINTF`.
3448 -   Recording player input commands for testing or analysis.
3449
3450 **Note:** The `dirout` opcode is used in conjunction with `DIRIN` to
3451 manage input and output redirection.
3452
3453 ### DISPLAY
3454
3455 **DISPLAY** is an opcode that displays a picture at a specified
3456 location on the screen. Pictures are images stored in a separate
3457 picture file and referenced by their ID numbers.
3458
3459 **Syntax:**
3460
3461 ``` {.assembly}
3462 display picture:int [, y:int, x:int]
3463 ```
3464
3465 **Functionality:**
3466
3467 The `display` opcode displays the picture with the specified ID number
3468 (`picture`) at the given coordinates (`y`, `x`) in pixels:
3469
3470 -   **`picture`:** The ID number of the picture to display.
3471 -   **`y` and `x` (optional):** The coordinates where the picture
3472     should be displayed, relative to the top-left corner of the
3473     current window. If omitted, the opcode uses the current cursor
3474     position.
3475
3476 **Special Cases:**
3477
3478 -   If the picture ID is 0, the opcode does nothing.
3479 -   If the coordinates are outside the window's boundaries, the
3480     picture may be clipped or partially displayed.
3481
3482 **Error Conditions:**
3483
3484 An error occurs if:
3485
3486 -   `picture` is not a valid picture ID.
3487 -   The coordinates (`y`, `x`) are outside the window's boundaries.
3488
3489 **Examples:**
3490
3491 ``` {.assembly}
3492 display 10, 10, 10  ; Displays picture 10 at coordinates (10, 10) in the current window
3493 display 5           ; Displays picture 5 at the current cursor position
3494 ```
3495
3496 **Use Cases:**
3497
3498 -   Displaying images and graphics on the screen.
3499 -   Creating visual elements for the game world or user interface.
3500
3501 **Note:** The `DISPLAY` opcode requires the interpreter to support
3502 picture display. The `MODE` byte in the program header indicates
3503 whether the `DISPLAY` operation is available.
3504
3505 ### DIV
3506
3507 **DIV** is an opcode that performs integer division on two 16-bit word
3508 values. It divides the first operand by the second operand and returns
3509 the truncated quotient.
3510
3511 **Syntax:**
3512
3513 ``` {.assembly}
3514 div arg1:int, arg2:int > val
3515 ```
3516
3517 **Functionality:**
3518
3519 The `div` opcode performs the following:
3520
3521 -   **Divides `arg1` by `arg2`:** Performs integer division,
3522     discarding any remainder.
3523 -   **Stores the result:** The quotient is stored in the specified
3524     destination (`val`). If no destination is provided, the result is
3525     pushed onto the game stack.
3526
3527 **Special Cases:**
3528
3529 -   Division by zero results in an error.
3530
3531 **Error Conditions:**
3532
3533 An error occurs if `arg2` is zero.
3534
3535 **Examples:**
3536
3537 ``` {.assembly}
3538 div 10, 2 > result  ; Divides 10 by 2, stores the quotient (5) in `result`
3539 ```
3540
3541 **Use Cases:**
3542
3543 -   Performing integer division calculations.
3544 -   Scaling values or calculating ratios.
3545
3546 **Note:** The `div` opcode performs integer division, meaning it
3547 discards any remainder. For operations that require the remainder, use
3548 the `MOD` opcode.
3549
3550 ### DLESS?
3551
3552 **DLESS?** is an opcode that decrements a variable and then checks if
3553 the new value is less than a specified integer. It acts as a
3554 predicate, meaning it evaluates a condition and implicitly performs a
3555 conditional branch based on the result.
3556
3557 **Syntax:**
3558
3559 ``` {.assembly}
3560 dless? var, int /pred
3561 ```
3562
3563 **Functionality:**
3564
3565 The `dless?` opcode performs the following:
3566
3567 -   **Decrements `var`:** Subtracts 1 from the value of the variable
3568     `var`.
3569 -   **Compares with `int`:** Checks if the new value of `var` is less
3570     than `int`.
3571 -   **Evaluates predicate:** The predicate succeeds (evaluates to
3572     true) if the new value of `var` is indeed less than `int`.
3573     Otherwise, the predicate fails (evaluates to false).
3574 -   **Conditional branch:** Based on the predicate result and the
3575     specified branch polarity (`/pred`), the interpreter may perform a
3576     conditional jump to a specified target.
3577
3578 **Special Cases:**
3579
3580 None.
3581
3582 **Error Conditions:**
3583
3584 None.
3585
3586 **Examples:**
3587
3588 ``` {.assembly}
3589 dless? counter, 0 / end_loop  ; Branch to `end_loop` if `counter` is decremented to a value less than 0
3590 ```
3591
3592 **Use Cases:**
3593
3594 -   Implementing loops or conditional statements that depend on
3595     decrementing a variable and comparing it to a threshold.
3596 -   Optimizing code by combining decrement and comparison operations
3597     into a single instruction.
3598
3599 **Note:** The `dless?` opcode is a useful tool for writing efficient
3600 and concise code when dealing with decrementing variables and
3601 comparisons.
3602
3603 ### EQUAL?
3604
3605 **EQUAL?** is an opcode that checks whether its first operand is equal
3606 to any of the subsequent operands. It acts as a predicate, meaning it
3607 evaluates a condition and implicitly performs a conditional branch
3608 based on the result.
3609
3610 **Syntax:**
3611
3612 ``` {.assembly}
3613 equal? arg1:any, arg2:any [, arg3:any ...] /pred
3614 ```
3615
3616 **Functionality:**
3617
3618 The `equal?` opcode performs the following:
3619
3620 -   **Compares `arg1` with other arguments:** Checks if `arg1` is
3621     equal to any of the `arg2`, `arg3`, etc., operands.
3622 -   **Evaluates predicate:** The predicate succeeds (evaluates to
3623     true) if `arg1` is equal to at least one of the other arguments.
3624     Otherwise, the predicate fails (evaluates to false).
3625 -   **Conditional branch:** Based on the predicate result and the
3626     specified branch polarity (`/pred`), the interpreter may perform a
3627     conditional jump to a specified target.
3628
3629 **Special Cases:**
3630
3631 -   The `equal?` opcode can take a variable number of operands in the
3632     extended (`EXT`) format. The 2OP format is limited to two
3633     operands.
3634
3635 **Error Conditions:**
3636
3637 None.
3638
3639 **Examples:**
3640
3641 ``` {.assembly}
3642 equal? object, "sword", "axe" / handle_weapon  ; Branch to `handle_weapon` if `object` is equal to either "sword" or "axe"
3643 ```
3644
3645 **Use Cases:**
3646
3647 -   Implementing conditional logic based on equality comparisons.
3648 -   Checking if a variable or object matches one of several possible
3649     values.
3650
3651 **Note:** The `equal?` opcode is a versatile tool for performing
3652 equality checks and implementing conditional behavior based on the
3653 results.
3654
3655 ### ERASE
3656
3657 **ERASE** is an opcode that erases a portion of the current window,
3658 filling it with the current background color.
3659
3660 **Syntax:**
3661
3662 ``` {.assembly}
3663 erase int
3664 ```
3665
3666 **Functionality:**
3667
3668 The `erase` opcode erases a section of the current window based on the
3669 value of `int`:
3670
3671 -   **`int` = 1:** Erases from the current cursor position to the end
3672     of the line.
3673 -   **`int` \> 1:** Erases a rectangular area starting at the current
3674     cursor position, with a width of `int` pixels and a height equal
3675     to the current font height. The erased area does not extend past
3676     the right edge of the window.
3677
3678 **Special Cases:**
3679
3680 None.
3681
3682 **Error Conditions:**
3683
3684 None.
3685
3686 **Examples:**
3687
3688 ``` {.assembly}
3689 erase 1     ; Erases from the cursor to the end of the line
3690 erase 20    ; Erases a 20-pixel wide rectangle starting at the cursor
3691 ```
3692
3693 **Use Cases:**
3694
3695 -   Erasing text or graphics from the screen.
3696 -   Clearing portions of the window for new output.
3697
3698 **Note:** The `ERASE` opcode is used to selectively erase parts of the
3699 window. For clearing the entire window, use the `CLEAR` opcode.
3700
3701 ### EXTOP
3702
3703 **EXTOP** is an opcode that signals to the interpreter that the next
3704 byte is an extended opcode. Extended opcodes are part of an additional
3705 set of 256 instructions beyond the standard opcode set.
3706
3707 **Syntax:**
3708
3709 ``` {.assembly}
3710 extop opcode:int
3711 ```
3712
3713 **Functionality:**
3714
3715 The `extop` opcode itself does not perform any operation. Instead, it
3716 indicates that the following byte (`opcode`) should be interpreted as
3717 an extended opcode. The interpreter adds 256 to the value of `opcode`
3718 to obtain the actual extended opcode number.
3719
3720 **Special Cases:**
3721
3722 -   The `extop` opcode is never explicitly used by programmers. It is
3723     generated by the assembler when encoding instructions that require
3724     the extended format.
3725
3726 **Error Conditions:**
3727
3728 An error occurs if `opcode` is not a valid extended opcode number.
3729
3730 **Examples:**
3731
3732 The `extop` opcode is not used directly in assembly code. It is
3733 handled internally by the assembler and interpreter.
3734
3735 **Use Cases:**
3736
3737 The `extop` opcode allows ZAP to generate a wider range of
3738 instructions while maintaining backward compatibility with older ZIP
3739 interpreters that only recognize the standard opcode set.
3740
3741 **Note:** The `extop` opcode is a low-level mechanism used by the
3742 assembler and interpreter to handle extended opcodes. Programmers do
3743 not need to be concerned with its usage directly.
3744
3745 ### FCLEAR
3746
3747 **FCLEAR** is an opcode that clears a specific flag within an object's
3748 flag list. Objects have 48 one-bit flags that can be used to track
3749 their state or attributes.
3750
3751 **Syntax:**
3752
3753 ``` {.assembly}
3754 fclear obj, flag
3755 ```
3756
3757 **Functionality:**
3758
3759 The `fclear` opcode sets the specified flag (`flag`) in the object
3760 (`obj`) to 0.
3761
3762 **Special Cases:**
3763
3764 None.
3765
3766 **Error Conditions:**
3767
3768 An error occurs if:
3769
3770 -   `obj` is not a valid object number.
3771 -   `flag` is not within the valid range (0-47).
3772
3773 **Examples:**
3774
3775 ``` {.assembly}
3776 fclear player, 10  ; Clears flag number 10 in the "player" object
3777 ```
3778
3779 **Use Cases:**
3780
3781 -   Resetting flags or attributes associated with objects.
3782 -   Changing the state of objects based on game logic or player
3783     actions.
3784
3785 **Note:** The `FCLEAR` opcode is used to clear individual flags within
3786 an object. To set a flag, use the `FSET` opcode.
3787
3788 ### FIRST?
3789
3790 **FIRST?** is an opcode that retrieves the "first" property of an
3791 object and checks if it is non-zero. It acts as a predicate, meaning
3792 it evaluates a condition and implicitly performs a conditional branch
3793 based on the result.
3794
3795 **Syntax:**
3796
3797 ``` {.assembly}
3798 first? obj > val /pred
3799 ```
3800
3801 **Functionality:**
3802
3803 The `first?` opcode performs the following:
3804
3805 -   **Retrieves "first" property:** Gets the value of the "first" slot
3806     within the object (`obj`). This slot typically contains the object
3807     number of the first object contained within `obj`.
3808 -   **Checks for non-zero value:** Evaluates to true if the retrieved
3809     value is not zero (meaning there is a "first" object). Otherwise,
3810     it evaluates to false.
3811 -   **Stores the value (optional):** If the `> val` operand is
3812     provided, the retrieved value is also stored in the specified
3813     variable.
3814 -   **Conditional branch:** Based on the predicate result and the
3815     specified branch polarity (`/pred`), the interpreter may perform a
3816     conditional jump to a specified target.
3817
3818 **Special Cases:**
3819
3820 -   If the object `obj` does not have any contained objects, the
3821     "first" slot will be zero, and the predicate will fail.
3822
3823 **Error Conditions:**
3824
3825 An error occurs if `obj` is not a valid object number.
3826
3827 **Examples:**
3828
3829 ``` {.assembly}
3830 first? container > first_item / process_item  ; Branch to `process_item` if `container` has a "first" object
3831 ```
3832
3833 **Use Cases:**
3834
3835 -   Checking if an object contains other objects.
3836 -   Iterating through a chain of objects linked by their "next"
3837     properties.
3838 -   Implementing inventory management or object interaction logic.
3839
3840 **Note:** The `FIRST?` opcode is used to access and check the "first"
3841 property of an object. To retrieve the "next" property in a chain, use
3842 the `NEXT?` opcode.
3843
3844 ### FONT
3845
3846 **FONT** is an opcode that selects a font for text output in a
3847 specified window. Fonts determine the style and appearance of the
3848 displayed text.
3849
3850 **Syntax:**
3851
3852 ``` {.assembly}
3853 font font:int, window:int > val
3854 ```
3855
3856 **Functionality:**
3857
3858 The `font` opcode sets the font for the specified window (`window`) to
3859 the font identified by `font`:
3860
3861 -   **`font`:** The ID number of the font to select.
3862 -   **`window`:** The window number where the font should be applied.
3863
3864 The opcode returns the ID number of the previously selected font for
3865 the window.
3866
3867 **Special Cases:**
3868
3869 -   If the `window` argument is omitted, the current window is used.
3870 -   Font 1 is typically the "normal" font for the machine and is
3871     selected by default for all windows.
3872 -   Some interpreters may not support all font IDs or may have
3873     different fonts available.
3874
3875 **Error Conditions:**
3876
3877 An error occurs if:
3878
3879 -   `window` is not within the valid range (-3 to 7).
3880 -   `font` is not a valid font ID.
3881
3882 **Examples:**
3883
3884 ``` {.assembly}
3885 font 4, 0  ; Selects the monospace font for the main window (window 0)
3886 font 2, 3  ; Selects font 2 for window 3
3887 ```
3888
3889 **Use Cases:**
3890
3891 -   Changing the appearance of text for visual distinction or
3892     emphasis.
3893 -   Displaying text in different styles, such as bold, italic, or
3894     monospace.
3895 -   Enhancing the game's visual presentation and atmosphere.
3896
3897 **Note:** The `FONT` opcode requires the interpreter to support font
3898 selection. The `MODE` byte in the program header indicates whether the
3899 `FONT` operation is available.
3900
3901 ### FSET
3902
3903 **FSET** is an opcode that sets a specific flag within an object's
3904 flag list to 1. Objects have 48 one-bit flags that can be used to
3905 track their state or attributes.
3906
3907 **Syntax:**
3908
3909 ``` {.assembly}
3910 fset obj, flag
3911 ```
3912
3913 **Functionality:**
3914
3915 The `fset` opcode sets the specified flag (`flag`) in the object
3916 (`obj`) to 1.
3917
3918 **Special Cases:**
3919
3920 None.
3921
3922 **Error Conditions:**
3923
3924 An error occurs if:
3925
3926 -   `obj` is not a valid object number.
3927 -   `flag` is not within the valid range (0-47).
3928
3929 **Examples:**
3930
3931 ``` {.assembly}
3932 fset player, 5  ; Sets flag number 5 in the "player" object to 1
3933 ```
3934
3935 **Use Cases:**
3936
3937 -   Setting flags or attributes associated with objects.
3938 -   Changing the state of objects based on game logic or player
3939     actions.
3940
3941 **Note:** The `FSET` opcode is used to set individual flags within an
3942 object. To clear a flag, use the `FCLEAR` opcode.
3943
3944 ### FSET?
3945
3946 **FSET?** is an opcode that checks whether a specific flag is set
3947 within an object's flag list. It acts as a predicate, meaning it
3948 evaluates a condition and implicitly performs a conditional branch
3949 based on the result.
3950
3951 **Syntax:**
3952
3953 ``` {.assembly}
3954 fset? obj, flag /pred
3955 ```
3956
3957 **Functionality:**
3958
3959 The `fset?` opcode performs the following:
3960
3961 -   **Checks flag state:** Determines whether the specified flag
3962     (`flag`) in the object (`obj`) is set (1) or cleared (0).
3963 -   **Evaluates predicate:** The predicate succeeds (evaluates to
3964     true) if the flag is set. Otherwise, the predicate fails
3965     (evaluates to false).
3966 -   **Conditional branch:** Based on the predicate result and the
3967     specified branch polarity (`/pred`), the interpreter may perform a
3968     conditional jump to a specified target.
3969
3970 **Special Cases:**
3971
3972 None.
3973
3974 **Error Conditions:**
3975
3976 An error occurs if:
3977
3978 -   `obj` is not a valid object number.
3979 -   `flag` is not within the valid range (0-47).
3980
3981 **Examples:**
3982
3983 ``` {.assembly}
3984 fset? player, 15 / handle_flag  ; Branch to `handle_flag` if flag number 15 in the "player" object is set
3985 ```
3986
3987 **Use Cases:**
3988
3989 -   Implementing conditional logic based on the state of object flags.
3990 -   Checking for specific object attributes or conditions.
3991
3992 **Note:** The `FSET?` opcode is used to test the state of individual
3993 flags within an object. To set or clear a flag, use the `FSET` or
3994 `FCLEAR` opcodes, respectively.
3995
3996 ### FSTACK
3997
3998 **FSTACK** is an opcode that flushes (removes) a specified number of
3999 elements from a stack. It can be used to clear the game stack or a
4000 user-defined stack.
4001
4002 **Syntax:**
4003
4004 ``` {.assembly}
4005 fstack n [, stack:tbl]
4006 ```
4007
4008 **Functionality:**
4009
4010 The `fstack` opcode removes elements from a stack as follows:
4011
4012 -   **`n`:** The number of elements to flush from the stack.
4013 -   **`stack` (optional):** A pointer to a table representing a
4014     user-defined stack. If omitted, the opcode flushes elements from
4015     the game stack.
4016
4017 The opcode does not return any value.
4018
4019 **Special Cases:**
4020
4021 -   Flushing more elements than are present on the stack is an error.
4022
4023 **Error Conditions:**
4024
4025 An error occurs if:
4026
4027 -   `n` is negative.
4028 -   `stack` is not a valid table pointer (if provided).
4029 -   Attempting to flush more elements than are present on the stack.
4030
4031 **Examples:**
4032
4033 ``` {.assembly}
4034 fstack 3     ; Flushes 3 elements from the game stack
4035 fstack 2, user_stack  ; Flushes 2 elements from the `user_stack` table
4036 ```
4037
4038 **Use Cases:**
4039
4040 -   Clearing the game stack before calling a function or performing a
4041     specific operation.
4042 -   Resetting user-defined stacks to a known state.
4043
4044 **Note:** The `FSTACK` opcode is used to remove elements from stacks.
4045 To add elements, use the `PUSH` or `XPUSH` opcodes.
4046
4047 ### GET
4048
4049 **GET** is an opcode that retrieves the value of an element from a
4050 word-oriented table. It is used to access data stored in tables based
4051 on their index or offset.
4052
4053 **Syntax:**
4054
4055 ``` {.assembly}
4056 get table, item > val
4057 ```
4058
4059 **Functionality:**
4060
4061 The `get` opcode performs the following:
4062
4063 -   **Calculates element address:** Multiplies the `item` (index or
4064     offset) by 2 and adds it to the base address of the `table`. This
4065     gives the address of the desired element in memory.
4066 -   **Retrieves the value:** Reads the word value at the calculated
4067     address.
4068 -   **Stores the result:** The retrieved value is stored in the
4069     specified destination (`val`). If no destination is provided, the
4070     result is pushed onto the game stack.
4071
4072 **Special Cases:**
4073
4074 -   Table offsets are zero-based, meaning the first element has an
4075     index of 0.
4076 -   The interpreter does not perform bounds checking on table
4077     accesses. It is the programmer's responsibility to ensure that
4078     `item` is within the valid range of the table.
4079
4080 **Error Conditions:**
4081
4082 An error may occur if:
4083
4084 -   `table` is not a valid table pointer.
4085 -   `item` is outside the bounds of the table.
4086
4087 **Examples:**
4088
4089 ``` {.assembly}
4090 get inventory, 3 > item  ; Retrieves the 4th element from the `inventory` table and stores it in `item`
4091 ```
4092
4093 **Use Cases:**
4094
4095 -   Accessing data stored in tables based on their index or offset.
4096 -   Implementing data structures and algorithms that rely on table
4097     lookups.
4098
4099 **Note:** The `GET` opcode is used for accessing word-sized elements
4100 in tables. For byte-sized elements, use the `GETB` opcode.
4101
4102 ### GETB
4103
4104 **GETB** is an opcode that retrieves the value of an element from a
4105 byte-oriented table. It is used to access data stored in tables based
4106 on their index or offset.
4107
4108 **Syntax:**
4109
4110 ``` {.assembly}
4111 getb table, item > val
4112 ```
4113
4114 **Functionality:**
4115
4116 The `getb` opcode performs the following:
4117
4118 -   **Calculates element address:** Adds the `item` (index or offset)
4119     to the base address of the `table`. This gives the address of the
4120     desired element in memory.
4121 -   **Retrieves the value:** Reads the byte value at the calculated
4122     address.
4123 -   **Converts to word:** The retrieved byte value is converted to a
4124     word (two bytes).
4125 -   **Stores the result:** The word value is stored in the specified
4126     destination (`val`). If no destination is provided, the result is
4127     pushed onto the game stack.
4128
4129 **Special Cases:**
4130
4131 -   Table offsets are zero-based, meaning the first element has an
4132     index of 0.
4133 -   The interpreter does not perform bounds checking on table
4134     accesses. It is the programmer's responsibility to ensure that
4135     `item` is within the valid range of the table.
4136
4137 **Error Conditions:**
4138
4139 An error may occur if:
4140
4141 -   `table` is not a valid table pointer.
4142 -   `item` is outside the bounds of the table.
4143
4144 **Examples:**
4145
4146 ``` {.assembly}
4147 getb text_buffer, 5 > char  ; Retrieves the 6th byte from the `text_buffer` table and stores it as a word in `char`
4148 ```
4149
4150 **Use Cases:**
4151
4152 -   Accessing data stored in byte-oriented tables.
4153 -   Reading individual characters from text buffers.
4154 -   Implementing data structures and algorithms that rely on
4155     byte-level table access.
4156
4157 **Note:** The `GETB` opcode is used for accessing byte-sized elements
4158 in tables. For word-sized elements, use the `GET` opcode.
4159
4160 ### GETP
4161
4162 **GETP** is an opcode that retrieves the value of a property from an
4163 object. Properties are used to associate additional data and
4164 attributes with objects.
4165
4166 **Syntax:**
4167
4168 ``` {.assembly}
4169 getp obj, prop > val
4170 ```
4171
4172 **Functionality:**
4173
4174 The `getp` opcode performs the following:
4175
4176 -   **Locates property table:** Finds the property table associated
4177     with the object (`obj`).
4178 -   **Searches for property:** Searches the property table for the
4179     property with the specified number (`prop`).
4180 -   **Retrieves the value:** If the property is found, its value is
4181     retrieved.
4182 -   **Handles default properties:** If the property is not found in
4183     the object's property table, the opcode retrieves the default
4184     value from the default property table.
4185 -   **Stores the result:** The retrieved value is stored in the
4186     specified destination (`val`). If no destination is provided, the
4187     result is pushed onto the game stack.
4188
4189 **Special Cases:**
4190
4191 -   Properties are stored in a sorted order within the object's
4192     property table.
4193 -   The `GETP` opcode can only be used to retrieve properties with a
4194     length of 1 or 2 bytes. For properties of arbitrary length, use
4195     the `GETPT` opcode.
4196
4197 **Error Conditions:**
4198
4199 An error occurs if:
4200
4201 -   `obj` is not a valid object number.
4202 -   `prop` is not within the valid range (1-63).
4203
4204 **Examples:**
4205
4206 ``` {.assembly}
4207 getp player, 1 > strength  ; Retrieves the value of property 1 ("strength") from the "player" object
4208 ```
4209
4210 **Use Cases:**
4211
4212 -   Accessing data associated with objects through properties.
4213 -   Retrieving object attributes or characteristics.
4214
4215 **Note:** The `GETP` opcode is used to retrieve properties with a
4216 length of 1 or 2 bytes. For properties of arbitrary length, use the
4217 `GETPT` opcode.
4218
4219 ### GETPT
4220
4221 **GETPT** is an opcode that retrieves a pointer to a property within
4222 an object's property table. Unlike `GETP`, which can only retrieve
4223 properties of 1 or 2 bytes, `GETPT` can access properties of any
4224 length.
4225
4226 **Syntax:**
4227
4228 ``` {.assembly}
4229 getpt obj, prop > val
4230 ```
4231
4232 **Functionality:**
4233
4234 The `getpt` opcode performs the following:
4235
4236 -   **Locates property table:** Finds the property table associated
4237     with the object (`obj`).
4238 -   **Searches for property:** Searches the property table for the
4239     property with the specified number (`prop`).
4240 -   **Retrieves the pointer:** If the property is found, a pointer to
4241     its value is retrieved.
4242 -   **Handles default properties:** If the property is not found in
4243     the object's property table, the opcode retrieves a pointer to the
4244     default value from the default property table.
4245 -   **Stores the result:** The retrieved pointer is stored in the
4246     specified destination (`val`). If no destination is provided, the
4247     result is pushed onto the game stack.
4248
4249 **Special Cases:**
4250
4251 -   Properties are stored in a sorted order within the object's
4252     property table.
4253 -   The retrieved pointer can be used as a table pointer in other
4254     table operations like `GET`, `GETB`, `PUT`, and `PUTB`.
4255
4256 **Error Conditions:**
4257
4258 An error occurs if:
4259
4260 -   `obj` is not a valid object number.
4261 -   `prop` is not within the valid range (1-63).
4262
4263 **Examples:**
4264
4265 ``` {.assembly}
4266 getpt object, 10 > prop_ptr  ; Retrieves a pointer to property 10 of `object`
4267 getb prop_ptr, 0 > first_byte ; Retrieves the first byte of the property value
4268 ```
4269
4270 **Use Cases:**
4271
4272 -   Accessing properties of arbitrary length.
4273 -   Implementing data structures or algorithms that require accessing
4274     variable-length properties.
4275
4276 **Note:** The `GETPT` opcode is used to retrieve pointers to
4277 properties, while `GETP` is used to directly retrieve property values
4278 of 1 or 2 bytes.
4279
4280 ### GRTR?
4281
4282 **GRTR?** is an opcode that compares two integer values and checks if
4283 the first operand is greater than the second operand. It acts as a
4284 predicate, meaning it evaluates a condition and implicitly performs a
4285 conditional branch based on the result.
4286
4287 **Syntax:**
4288
4289 ``` {.assembly}
4290 grtr? arg1:int, arg2:int /pred
4291 ```
4292
4293 **Functionality:**
4294
4295 The `grtr?` opcode performs the following:
4296
4297 -   **Compares `arg1` and `arg2`:** Checks if the integer value `arg1`
4298     is greater than `arg2`.
4299 -   **Evaluates predicate:** The predicate succeeds (evaluates to
4300     true) if `arg1` is indeed greater than `arg2`. Otherwise, the
4301     predicate fails (evaluates to false).
4302 -   **Conditional branch:** Based on the predicate result and the
4303     specified branch polarity (`/pred`), the interpreter may perform a
4304     conditional jump to a specified target.
4305
4306 **Special Cases:**
4307
4308 None.
4309
4310 **Error Conditions:**
4311
4312 None.
4313
4314 **Examples:**
4315
4316 ``` {.assembly}
4317 grtr? health, 0 / game_over  ; Branch to `game_over` if `health` is greater than 0
4318 ```
4319
4320 **Use Cases:**
4321
4322 -   Implementing conditional logic based on greater-than comparisons.
4323 -   Making decisions based on numerical values, such as health, score,
4324     or inventory counts.
4325
4326 **Note:** The `grtr?` opcode is a basic comparison operator used for
4327 implementing conditional behavior in Z-code programs.
4328
4329 ### HLIGHT
4330
4331 **HLIGHT** is an opcode that sets the highlighting mode for subsequent
4332 text output. Highlighting can be used to emphasize text, change its
4333 appearance, or create special visual effects.
4334
4335 **Syntax:**
4336
4337 ``` {.assembly}
4338 hlight int
4339 ```
4340
4341 **Functionality:**
4342
4343 The `hlight` opcode sets the highlighting mode based on the value of
4344 `int`:
4345
4346 -   **`int` = 0:** No highlighting (normal text).
4347 -   **`int` = 1:** Inverse video (text and background colors are
4348     swapped).
4349 -   **`int` = 2:** Bold text.
4350 -   **`int` = 4:** Underline or italic text
4351     (implementation-dependent).
4352 -   **`int` = 8:** Monospaced font.
4353
4354 **Special Cases:**
4355
4356 -   The availability of highlighting modes depends on the capabilities
4357     of the interpreter and the target machine.
4358 -   The `MODE` byte in the program header specifies which highlighting
4359     modes are supported.
4360 -   The monospace font mode may either select an actual monospaced
4361     font or modify the display of a variable-width font to appear
4362     monospaced.
4363
4364 **Error Conditions:**
4365
4366 An error occurs if `int` specifies an unsupported highlighting mode.
4367
4368 **Examples:**
4369
4370 ``` {.assembly}
4371 hlight 2   ; Sets bold text highlighting
4372 print "Important message!"
4373 hlight 0   ; Resets to normal text
4374 ```
4375
4376 **Use Cases:**
4377
4378 -   Emphasizing important text or messages.
4379 -   Creating visual distinctions between different types of text.
4380 -   Implementing special visual effects or text-based graphics.
4381
4382 **Note:** Games should be designed to handle machines that do not
4383 support all highlighting modes. The `MODE` byte can be used to check
4384 which modes are available.
4385
4386 ### ICALL
4387
4388 **ICALL** is an opcode that calls a function with three arguments but
4389 does not return a value. It is similar to the `CALL` opcode but
4390 optimized for situations where the function's return value is not
4391 needed.
4392
4393 **Syntax:**
4394
4395 ``` {.assembly}
4396 icall routine:fcn, arg1:any, arg2:any, arg3:any
4397 ```
4398
4399 **Functionality:**
4400
4401 The `icall` opcode performs the following:
4402
4403 -   **Pushes arguments onto the stack:** Pushes the three arguments
4404     (`arg1`, `arg2`, and `arg3`) onto the game stack.
4405 -   **Calls the function:** Transfers control to the function
4406     specified by `routine`. The function address is calculated by
4407     shifting `routine` left by two bits and adding the function offset
4408     (`FOFF`) shifted left by three bits.
4409 -   **Does not retrieve return value:** When the function returns, its
4410     return value is discarded.
4411
4412 **Special Cases:**
4413
4414 -   If `routine` is zero, the `icall` opcode acts as if it called a
4415     function that immediately returned false.
4416
4417 **Error Conditions:**
4418
4419 An error occurs if `routine` is not a valid function pointer.
4420
4421 **Examples:**
4422
4423 ``` {.assembly}
4424 icall update_score, player, points, bonus  ; Calls the `update_score` function without using its return value
4425 ```
4426
4427 **Use Cases:**
4428
4429 -   Calling functions where the return value is not needed, reducing
4430     stack usage and potential stack overflows.
4431 -   Implementing subroutines or actions that do not produce a result.
4432
4433 **Note:** The `icall` opcode is generated by the compiler when it
4434 detects a function call where the return value is not used. It is not
4435 typically used directly by programmers.
4436
4437 ### ICALL1
4438
4439 **ICALL1** is an opcode that calls a function with one argument but
4440 does not return a value. It is similar to the `CALL1` opcode but
4441 optimized for situations where the function's return value is not
4442 needed.
4443
4444 **Syntax:**
4445
4446 ``` {.assembly}
4447 icall1 routine:fcn
4448 ```
4449
4450 **Functionality:**
4451
4452 The `icall1` opcode performs the following:
4453
4454 -   **Pushes arguments onto the stack:** Pushes the single argument
4455     onto the game stack.
4456 -   **Calls the function:** Transfers control to the function
4457     specified by `routine`. The function address is calculated by
4458     shifting `routine` left by two bits and adding the function offset
4459     (`FOFF`) shifted left by three bits.
4460 -   **Does not retrieve return value:** When the function returns, its
4461     return value is discarded.
4462
4463 **Special Cases:**
4464
4465 -   If `routine` is zero, the `icall1` opcode acts as if it called a
4466     function that immediately returned false.
4467
4468 **Error Conditions:**
4469
4470 An error occurs if `routine` is not a valid function pointer.
4471
4472 **Examples:**
4473
4474 ``` {.assembly}
4475 icall1 play_sound, sound_id  ; Calls the `play_sound` function without using its return value
4476 ```
4477
4478 **Use Cases:**
4479
4480 -   Calling functions with a single argument where the return value is
4481     not needed, reducing stack usage and potential stack overflows.
4482 -   Implementing subroutines or actions that do not produce a result.
4483
4484 **Note:** The `icall1` opcode is generated by the compiler when it
4485 detects a function call with one argument where the return value is
4486 not used. It is not typically used directly by programmers.
4487
4488 ### ICALL2
4489
4490 **ICALL2** is an opcode that calls a function with two arguments but
4491 does not return a value. It is similar to the `CALL2` opcode but
4492 optimized for situations where the function's return value is not
4493 needed.
4494
4495 **Syntax:**
4496
4497 ``` {.assembly}
4498 icall2 routine:fcn, arg:any
4499 ```
4500
4501 **Functionality:**
4502
4503 The `icall2` opcode performs the following:
4504
4505 -   **Pushes arguments onto the stack:** Pushes the two arguments
4506     (`routine` and `arg`) onto the game stack.
4507 -   **Calls the function:** Transfers control to the function
4508     specified by `routine`. The function address is calculated by
4509     shifting `routine` left by two bits and adding the function offset
4510     (`FOFF`) shifted left by three bits.
4511 -   **Does not retrieve return value:** When the function returns, its
4512     return value is discarded.
4513
4514 **Special Cases:**
4515
4516 -   If `routine` is zero, the `icall2` opcode acts as if it called a
4517     function that immediately returned false.
4518
4519 **Error Conditions:**
4520
4521 An error occurs if `routine` is not a valid function pointer.
4522
4523 **Examples:**
4524
4525 ``` {.assembly}
4526 icall2 set_color, foreground, background  ; Calls the `set_color` function without using its return value
4527 ```
4528
4529 **Use Cases:**
4530
4531 -   Calling functions with two arguments where the return value is not
4532     needed, reducing stack usage and potential stack overflows.
4533 -   Implementing subroutines or actions that do not produce a result.
4534
4535 **Note:** The `icall2` opcode is generated by the compiler when it
4536 detects a function call with two arguments where the return value is
4537 not used. It is not typically used directly by programmers.
4538
4539 ### IGRTR?
4540
4541 **IGRTR?** is an opcode that increments a variable and then checks if
4542 the new value is greater than a specified integer. It acts as a
4543 predicate, meaning it evaluates a condition and implicitly performs a
4544 conditional branch based on the result.
4545
4546 **Syntax:**
4547
4548 ``` {.assembly}
4549 igrtr? var, int /pred
4550 ```
4551
4552 **Functionality:**
4553
4554 The `igrtr?` opcode performs the following:
4555
4556 -   **Increments `var`:** Adds 1 to the value of the variable `var`.
4557 -   **Compares with `int`:** Checks if the new value of `var` is
4558     greater than `int`.
4559 -   **Evaluates predicate:** The predicate succeeds (evaluates to
4560     true) if the new value of `var` is indeed greater than `int`.
4561     Otherwise, the predicate fails (evaluates to false).
4562 -   **Conditional branch:** Based on the predicate result and the
4563     specified branch polarity (`/pred`), the interpreter may perform a
4564     conditional jump to a specified target.
4565
4566 **Special Cases:**
4567
4568 None.
4569
4570 **Error Conditions:**
4571
4572 None.
4573
4574 **Examples:**
4575
4576 ``` {.assembly}
4577 igrtr? counter, limit / overflow  ; Branch to `overflow` if `counter` is incremented to a value greater than `limit`
4578 ```
4579
4580 **Use Cases:**
4581
4582 -   Implementing loops or conditional statements that depend on
4583     incrementing a variable and comparing it to a threshold.
4584 -   Optimizing code by combining increment and comparison operations
4585     into a single instruction.
4586
4587 **Note:** The `igrtr?` opcode is a useful tool for writing efficient
4588 and concise code when dealing with incrementing variables and
4589 comparisons.
4590
4591 ### IN?
4592
4593 **IN?** is an opcode that checks whether one object is contained
4594 within another object. It acts as a predicate, meaning it evaluates a
4595 condition and implicitly performs a conditional branch based on the
4596 result.
4597
4598 **Syntax:**
4599
4600 ``` {.assembly}
4601 in? child:obj, parent:obj /pred
4602 ```
4603
4604 **Functionality:**
4605
4606 The `in?` opcode performs the following:
4607
4608 -   **Checks containment:** Compares the `LOC` property of the `child`
4609     object with the object number of the `parent` object.
4610 -   **Evaluates predicate:** The predicate succeeds (evaluates to
4611     true) if the `LOC` of `child` is equal to `parent`, meaning
4612     `child` is contained within `parent`. Otherwise, the predicate
4613     fails (evaluates to false).
4614 -   **Conditional branch:** Based on the predicate result and the
4615     specified branch polarity (`/pred`), the interpreter may perform a
4616     conditional jump to a specified target.
4617
4618 **Special Cases:**
4619
4620 -   An object is considered to be contained within itself.
4621
4622 **Error Conditions:**
4623
4624 An error occurs if `child` or `parent` is not a valid object number.
4625
4626 **Examples:**
4627
4628 ``` {.assembly}
4629 in? item, player / take_item  ; Branch to `take_item` if `item` is contained within the "player" object
4630 ```
4631
4632 **Use Cases:**
4633
4634 -   Implementing inventory management and object interaction logic.
4635 -   Checking the location of objects within the game world.
4636 -   Determining containment relationships between objects.
4637
4638 **Note:** The `IN?` opcode is a fundamental operation for working with
4639 object hierarchies and containment in Z-code programs.
4640
4641 ### INC
4642
4643 **INC** is an opcode that increments the value of a variable by 1.
4644
4645 **Syntax:**
4646
4647 ``` {.assembly}
4648 inc var
4649 ```
4650
4651 **Functionality:**
4652
4653 The `inc` opcode adds 1 to the value of the specified variable
4654 (`var`).
4655
4656 **Special Cases:**
4657
4658 None.
4659
4660 **Error Conditions:**
4661
4662 None.
4663
4664 **Examples:**
4665
4666 ``` {.assembly}
4667 inc counter  ; Increments the value of the variable `counter`
4668 ```
4669
4670 **Use Cases:**
4671
4672 -   Incrementing counters or loop variables.
4673 -   Increasing the value of a variable by a fixed amount.
4674
4675 **Note:** The `inc` opcode is a convenient way to increment a variable
4676 by 1. For more complex arithmetic operations, use the `ADD` opcode.
4677
4678 ### INPUT
4679
4680 **INPUT** is an opcode that reads a single byte of input from a
4681 specified device, typically the keyboard. It allows the Z-code program
4682 to receive input from the user or other input sources.
4683
4684 **Syntax:**
4685
4686 ``` {.assembly}
4687 input dev:int [, time:int, routine:fcn] > val
4688 ```
4689
4690 **Functionality:**
4691
4692 The `input` opcode reads input based on the value of `dev`:
4693
4694 -   **`dev` = 1:** Keyboard input (default). The opcode reads the next
4695     key pressed by the user and returns its ASCII value.
4696 -   **Other values of `dev`:** May be used for other input devices,
4697     but their behavior is implementation-dependent.
4698
4699 **Optional Arguments:**
4700
4701 -   **`time`:** Specifies a timeout value in tenths of a second. If no
4702     input is received within the specified time, the interpreter calls
4703     the `routine` function.
4704 -   **`routine`:** A function to call when a timeout occurs. The
4705     function should return true (1) to abort the input operation or
4706     false (0) to continue waiting for input.
4707
4708 **Return Value:**
4709
4710 The `input` opcode returns the value of the input byte, which is
4711 stored in the specified destination (`val`). If no destination is
4712 provided, the value is pushed onto the game stack.
4713
4714 **Special Cases:**
4715
4716 -   Function keys and other special keys may return values greater
4717     than 127, with the high bit of the byte set.
4718 -   The interpreter may handle timeout behavior differently depending
4719     on the target machine and implementation.
4720
4721 **Error Conditions:**
4722
4723 An error occurs if:
4724
4725 -   `dev` is not a valid device code.
4726 -   `time` is negative (if provided).
4727 -   `routine` is not a valid function pointer (if provided).
4728
4729 **Examples:**
4730
4731 ``` {.assembly}
4732 input 1 > key  ; Reads a key from the keyboard and stores its ASCII value in `key`
4733 input 1, 50, handle_timeout > key  ; Reads a key with a 5-second timeout
4734 ```
4735
4736 **Use Cases:**
4737
4738 -   Getting input from the user, such as commands, responses, or key
4739     presses.
4740 -   Implementing timed input or interactive sequences.
4741
4742 **Note:** The `INPUT` opcode is a fundamental operation for receiving
4743 input in Z-code programs. The specific behavior and available devices
4744 may vary depending on the interpreter and target machine.
4745
4746 ### INTBL?
4747
4748 **INTBL?** is an opcode that searches for a specific item within a
4749 table and returns a pointer to its location if found. It acts as both
4750 an opcode and a predicate, meaning it can return a value and also
4751 influence control flow based on the search result.
4752
4753 **Syntax:**
4754
4755 ``` {.assembly}
4756 intbl? item, table, length:int [, record-spec:int] > val /pred
4757 ```
4758
4759 **Functionality:**
4760
4761 The `intbl?` opcode performs the following:
4762
4763 -   **Searches for `item`:** Looks for the specified `item` within the
4764     `table`.
4765 -   **Table length:** The `length` argument specifies the number of
4766     elements to search within the table.
4767 -   **Record specification (optional):** The `record-spec` argument,
4768     if provided, defines the format of each element in the table. It
4769     is a byte value where:
4770     -   The high-order bit indicates whether the table elements are
4771         words (1) or bytes (0).
4772     -   The low-order seven bits specify the length of each element in
4773         bytes.
4774 -   **Returns a pointer:** If `item` is found, the opcode returns a
4775     pointer to its location within the table. Otherwise, it returns 0.
4776 -   **Stores the result (optional):** If the `> val` operand is
4777     provided, the returned pointer is also stored in the specified
4778     variable.
4779 -   **Evaluates predicate:** The predicate succeeds (evaluates to
4780     true) if `item` is found in the table. Otherwise, the predicate
4781     fails (evaluates to false).
4782 -   **Conditional branch:** Based on the predicate result and the
4783     specified branch polarity (`/pred`), the interpreter may perform a
4784     conditional jump to a specified target.
4785
4786 **Special Cases:**
4787
4788 -   If `record-spec` is omitted or 0, it defaults to 130
4789     (word-oriented elements with a length of 2 bytes).
4790
4791 **Error Conditions:**
4792
4793 An error occurs if:
4794
4795 -   `table` is not a valid table pointer.
4796 -   `length` is negative.
4797
4798 **Examples:**
4799
4800 ``` {.assembly}
4801 intbl? "north", directions, 4 > direction_ptr / handle_direction  ; Searches for "north" in the `directions` table
4802 intbl? char, buffer, buffer_length, 1 > char_ptr / process_char   ; Searches for `char` in a byte-oriented buffer
4803 ```
4804
4805 **Use Cases:**
4806
4807 -   Searching for specific elements within tables.
4808 -   Implementing data structures and algorithms that require table
4809     lookups.
4810 -   Performing conditional logic based on search results.
4811
4812 **Note:** The `INTBL?` opcode is a versatile tool for searching tables
4813 and implementing conditional behavior based on the results. The
4814 optional `record-spec` argument allows for searching tables with
4815 different element formats.
4816
4817 ### IRESTORE
4818
4819 **IRESTORE** is an opcode that restores the game state from a
4820 previously saved copy in memory. It is used to implement a
4821 single-level undo functionality.
4822
4823 **Syntax:**
4824
4825 ``` {.assembly}
4826 irestore > val
4827 ```
4828
4829 **Functionality:**
4830
4831 The `irestore` opcode restores the game state from a copy of the
4832 impure area that was previously saved using the `ISAVE` opcode. The
4833 impure area contains all modifiable data in the Z-code program,
4834 including global variables, object flags, and table contents.
4835
4836 **Return Value:**
4837
4838 The `irestore` opcode returns 0 if it fails or if the instruction is
4839 not implemented on the target machine. Otherwise, it returns -1.
4840
4841 **Special Cases:**
4842
4843 -   The `IRESTORE` opcode only works if a previous `ISAVE` operation
4844     was successful.
4845 -   The interpreter may not implement the `ISAVE` and `IRESTORE`
4846     opcodes on all machines.
4847
4848 **Error Conditions:**
4849
4850 None.
4851
4852 **Examples:**
4853
4854 ``` {.assembly}
4855 isave       ; Saves the current game state
4856 ; ... some actions that modify the game state ...
4857 irestore    ; Restores the previously saved game state
4858 ```
4859
4860 **Use Cases:**
4861
4862 -   Implementing an undo feature in the game.
4863 -   Restoring the game state to a previous point after an error or
4864     unexpected event.
4865
4866 **Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple
4867 mechanism for implementing undo functionality. However, they are not
4868 supported on all interpreters and may require additional memory
4869 resources.
4870
4871 ### ISAVE
4872
4873 **ISAVE** is an opcode that saves a copy of the current game state in
4874 memory. It is used in conjunction with the `IRESTORE` opcode to
4875 implement a single-level undo functionality.
4876
4877 **Syntax:**
4878
4879 ``` {.assembly}
4880 isave > val
4881 ```
4882
4883 **Functionality:**
4884
4885 The `isave` opcode copies the impure area of the Z-code program to a
4886 reserved section of memory. The impure area contains all modifiable
4887 data, including global variables, object flags, and table contents.
4888
4889 **Return Value:**
4890
4891 The `isave` opcode returns 0 if it fails or if the instruction is not
4892 implemented on the target machine. Otherwise, it returns -1.
4893
4894 **Special Cases:**
4895
4896 -   The interpreter may not implement the `ISAVE` and `IRESTORE`
4897     opcodes on all machines.
4898 -   The reserved memory area for storing the saved game state may have
4899     limited size.
4900
4901 **Error Conditions:**
4902
4903 None.
4904
4905 **Examples:**
4906
4907 ``` {.assembly}
4908 isave       ; Saves the current game state
4909 ; ... some actions that modify the game state ...
4910 irestore    ; Restores the previously saved game state
4911 ```
4912
4913 **Use Cases:**
4914
4915 -   Implementing an undo feature in the game.
4916 -   Saving the game state before performing an action that might have
4917     unintended consequences.
4918
4919 **Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple
4920 mechanism for implementing undo functionality. However, they are not
4921 supported on all interpreters and may require additional memory
4922 resources.
4923
4924 ### IXCALL
4925
4926 **IXCALL** is an opcode that calls a function with a variable number
4927 of arguments but does not return a value. It is similar to the `XCALL`
4928 opcode but optimized for situations where the function's return value
4929 is not needed.
4930
4931 **Syntax:**
4932
4933 ``` {.assembly}
4934 ixcall routine:fcn, arg1:any [, arg2:any ...]
4935 ```
4936
4937 **Functionality:**
4938
4939 The `ixcall` opcode performs the following:
4940
4941 -   **Pushes arguments onto the stack:** Pushes the variable number of
4942     arguments (`arg1`, `arg2`, etc.) onto the game stack. The number
4943     of arguments is determined by the operand types specified in the
4944     instruction.
4945 -   **Calls the function:** Transfers control to the function
4946     specified by `routine`. The function address is calculated by
4947     shifting `routine` left by two bits and adding the function offset
4948     (`FOFF`) shifted left by three bits.
4949 -   **Does not retrieve return value:** When the function returns, its
4950     return value is discarded.
4951
4952 **Special Cases:**
4953
4954 -   If `routine` is zero, the `ixcall` opcode acts as if it called a
4955     function that immediately returned false.
4956
4957 **Error Conditions:**
4958
4959 An error occurs if `routine` is not a valid function pointer.
4960
4961 **Examples:**
4962
4963 ``` {.assembly}
4964 ixcall print_list, item1, item2, item3  ; Calls the `print_list` function with three arguments
4965 ```
4966
4967 **Use Cases:**
4968
4969 -   Calling functions with a variable number of arguments where the
4970     return value is not needed, reducing stack usage and potential
4971     stack overflows.
4972 -   Implementing functions that take a flexible number of arguments.
4973
4974 **Note:** The `ixcall` opcode is generated by the compiler when it
4975 detects a function call with a variable number of arguments where the
4976 return value is not used. It is not typically used directly by
4977 programmers.
4978
4979 ### JUMP
4980
4981 **JUMP** is an opcode that performs an unconditional relative jump to
4982 a specified location within the program. It is used to control the
4983 flow of execution and implement loops or conditional branching.
4984
4985 **Syntax:**
4986
4987 ``` {.assembly}
4988 jump offset:loc
4989 ```
4990
4991 **Functionality:**
4992
4993 The `jump` opcode performs the following:
4994
4995 -   **Calculates target address:** Adds the `offset` value to the
4996     address of the next instruction. This gives the target address of
4997     the jump.
4998 -   **Jumps to target:** Transfers control to the calculated target
4999     address.
5000
5001 **Special Cases:**
5002
5003 -   The `offset` value is a signed 16-bit integer, allowing for both
5004     forward and backward jumps within the program.
5005
5006 **Error Conditions:**
5007
5008 None.
5009
5010 **Examples:**
5011
5012 ``` {.assembly}
5013 jump start_loop  ; Jumps to the label `start_loop`
5014 jump -5          ; Jumps back 5 instructions
5015 ```
5016
5017 **Use Cases:**
5018
5019 -   Implementing loops by jumping back to the beginning of the loop
5020     code.
5021 -   Performing conditional branching by jumping to different sections
5022     of code based on the results of predicates.
5023 -   Creating subroutines or functions by jumping to their starting
5024     addresses.
5025
5026 **Note:** The `JUMP` opcode is a fundamental control flow instruction
5027 used to direct the execution of Z-code programs.
5028
5029 ### LESS?
5030
5031 **LESS?** is an opcode that compares two integer values and checks if
5032 the first operand is less than the second operand. It acts as a
5033 predicate, meaning it evaluates a condition and implicitly performs a
5034 conditional branch based on the result.
5035
5036 **Syntax:**
5037
5038 ``` {.assembly}
5039 less? arg1:int, arg2:int /pred
5040 ```
5041
5042 **Functionality:**
5043
5044 The `less?` opcode performs the following:
5045
5046 -   **Compares `arg1` and `arg2`:** Checks if the integer value `arg1`
5047     is less than `arg2`.
5048 -   **Evaluates predicate:** The predicate succeeds (evaluates to
5049     true) if `arg1` is indeed less than `arg2`. Otherwise, the
5050     predicate fails (evaluates to false).
5051 -   **Conditional branch:** Based on the predicate result and the
5052     specified branch polarity (`/pred`), the interpreter may perform a
5053     conditional jump to a specified target.
5054
5055 **Special Cases:**
5056
5057 None.
5058
5059 **Error Conditions:**
5060
5061 None.
5062
5063 **Examples:**
5064
5065 ``` {.assembly}
5066 less? count, 10 / continue_loop  ; Branch to `continue_loop` if `count` is less than 10
5067 ```
5068
5069 **Use Cases:**
5070
5071 -   Implementing conditional logic based on less-than comparisons.
5072 -   Making decisions based on numerical values, such as health, score,
5073     or inventory counts.
5074
5075 **Note:** The `less?` opcode is a basic comparison operator used for
5076 implementing conditional behavior in Z-code programs.
5077
5078 ### LEX
5079
5080 **LEX** is an opcode that parses the contents of an input buffer and
5081 looks up the words in a vocabulary table. It is similar to the parsing
5082 phase of the `READ` opcode but offers more flexibility in choosing the
5083 vocabulary.
5084
5085 **Syntax:**
5086
5087 ``` {.assembly}
5088 lex inbuf:tbl, lexv:tbl [, lexicon:tbl, preserve:bool]
5089 ```
5090
5091 **Functionality:**
5092
5093 The `lex` opcode performs the following:
5094
5095 -   **Parses input buffer:** Reads the contents of the `inbuf` table,
5096     which is assumed to contain a string of text.
5097 -   **Tokenizes words:** Breaks the text into individual words based
5098     on whitespace and self-inserting break characters defined in the
5099     vocabulary.
5100 -   **Looks up words:** Searches for each word in the specified
5101     `lexicon` table. If `lexicon` is omitted, the default vocabulary
5102     table (pointed to by the `VOCAB` word in the program header) is
5103     used.
5104 -   **Stores results:** For each word, the opcode stores the following
5105     information in the `lexv` table:
5106     -   A pointer to the word entry in the vocabulary table (or 0 if
5107         not found).
5108     -   The length of the word in bytes.
5109     -   The byte offset of the word within the input buffer.
5110 -   **Preserves existing entries (optional):** If the `preserve`
5111     argument is provided and non-zero, the opcode does not modify
5112     entries in `lexv` for words that are not found in the vocabulary.
5113
5114 **Special Cases:**
5115
5116 -   The `lexv` table must have enough space to store the parsing
5117     results.
5118 -   The format of the `lexv` table is specific to the Z-machine and is
5119     used by other opcodes like `PRINTC` to reprint words from the
5120     input buffer.
5121
5122 **Error Conditions:**
5123
5124 An error occurs if:
5125
5126 -   `inbuf` or `lexv` is not a valid table pointer.
5127 -   `lexicon` is not a valid table pointer (if provided).
5128 -   The `lexv` table does not have enough space to store the parsing
5129     results.
5130
5131 **Examples:**
5132
5133 ``` {.assembly}
5134 lex input_buffer, parsed_words  ; Parses `input_buffer` using the default vocabulary
5135 lex input_buffer, parsed_words, special_vocab, 1  ; Parses using `special_vocab` and preserves existing entries
5136 ```
5137
5138 **Use Cases:**
5139
5140 -   Parsing player input and looking up words in a vocabulary.
5141 -   Implementing custom parsers or natural language processing
5142     routines.
5143 -   Using multiple vocabularies for different contexts or situations.
5144
5145 **Note:** The `LEX` opcode provides more flexibility than the parsing
5146 phase of the `READ` opcode by allowing the programmer to specify the
5147 vocabulary table.
5148
5149 ### LOC
5150
5151 **LOC** is an opcode that retrieves the "parent" object of a given
5152 object. Objects in Z-code programs are organized in a hierarchical
5153 structure, where each object can be contained within another object.
5154
5155 **Syntax:**
5156
5157 ``` {.assembly}
5158 loc obj > val
5159 ```
5160
5161 **Functionality:**
5162
5163 The `loc` opcode retrieves the object number of the object that
5164 contains the specified object (`obj`). This is done by reading the
5165 value of the `LOC` property of `obj`.
5166
5167 -   **Stores the result:** The retrieved object number is stored in
5168     the specified destination (`val`). If no destination is provided,
5169     the result is pushed onto the game stack.
5170
5171 **Special Cases:**
5172
5173 -   If the object `obj` is not contained within any other object
5174     (i.e., it is a top-level object), the `LOC` property will be 0,
5175     and the opcode will return 0.
5176
5177 **Error Conditions:**
5178
5179 An error occurs if `obj` is not a valid object number.
5180
5181 **Examples:**
5182
5183 ``` {.assembly}
5184 loc item > container  ; Retrieves the object number of the container that holds `item`
5185 ```
5186
5187 **Use Cases:**
5188
5189 -   Determining the location of objects within the game world.
5190 -   Implementing inventory management and object interaction logic.
5191 -   Traversing the object hierarchy to find related objects.
5192
5193 **Note:** The `LOC` opcode is used to navigate the object hierarchy
5194 and determine containment relationships between objects.
5195
5196 ### MARGIN
5197
5198 **MARGIN** is an opcode that sets the left and right margins for text
5199 output in a window. Margins control the horizontal spacing of text
5200 within the window.
5201
5202 **Syntax:**
5203
5204 ``` {.assembly}
5205 margin left:int, right:int [, window:int]
5206 ```
5207
5208 **Functionality:**
5209
5210 The `margin` opcode sets the margins for the specified window
5211 (`window`) as follows:
5212
5213 -   **`left`:** The width of the left margin in pixels.
5214 -   **`right`:** The width of the right margin in pixels.
5215
5216 The opcode stores the margin values in the `LMRG` and `RMRG` words
5217 associated with the window.
5218
5219 **Special Cases:**
5220
5221 -   If the `window` argument is omitted, the current window is used.
5222 -   Margins only affect windows that have text wrapping enabled.
5223 -   The opcode must be executed before any text is buffered for the
5224     current line.
5225
5226 **Error Conditions:**
5227
5228 An error occurs if:
5229
5230 -   `window` is not within the valid range (-3 to 7).
5231 -   `left` or `right` is negative.
5232
5233 **Examples:**
5234
5235 ``` {.assembly}
5236 margin 10, 20  ; Sets a 10-pixel left margin and a 20-pixel right margin in the current window
5237 ```
5238
5239 **Use Cases:**
5240
5241 -   Indenting text within a window.
5242 -   Creating visual distinctions between different sections of text.
5243 -   Implementing custom text formatting or layout.
5244
5245 **Note:** The `MARGIN` opcode is used to control the horizontal
5246 spacing of text within windows. It is important to consider the
5247 window's wrapping attribute and the timing of the opcode execution.
5248
5249 ### MENU
5250
5251 **MENU** is an opcode that adds or removes a menu from the menu bar.
5252 This feature is currently only supported on the Macintosh platform.
5253
5254 **Syntax:**
5255
5256 ``` {.assembly}
5257 menu id, table /pred
5258 ```
5259
5260 **Functionality:**
5261
5262 The `menu` opcode performs the following:
5263
5264 -   **Adds a menu (table is non-zero):**
5265     -   **`id`:** Specifies the slot in the menu bar where the menu
5266         should be added. Slots 0, 1, and 2 are reserved for the Apple
5267         menu, File menu, and Edit menu, respectively.
5268     -   **`table`:** A pointer to an LTABLE containing the menu data.
5269         The first element of the table is the menu name, and
5270         subsequent elements are the menu items.
5271 -   **Removes a menu (table is zero):**
5272     -   **`id`:** Specifies the slot of the menu to remove.
5273
5274 **Predicate Behavior:**
5275
5276 The `menu` opcode also acts as a predicate:
5277
5278 -   **Success:** The predicate succeeds if the menu was successfully
5279     added or removed.
5280 -   **Failure:** The predicate fails if there is no room in the menu
5281     bar for the new menu or if the specified menu ID is invalid.
5282
5283 **Special Cases:**
5284
5285 -   The `MENU` opcode is only supported on the Macintosh platform.
5286 -   The interpreter must have the `%FMENU` flag set in the `FLAGS`
5287     word to indicate support for menus.
5288
5289 **Error Conditions:**
5290
5291 An error occurs if:
5292
5293 -   The interpreter does not support menus.
5294 -   `id` is not a valid menu slot number.
5295 -   `table` is not a valid table pointer (when adding a menu).
5296
5297 **Examples:**
5298
5299 ``` {.assembly}
5300 menu 3, my_menu / check_menu  ; Adds `my_menu` to the menu bar in slot 3
5301 menu 3, 0                    ; Removes the menu from slot 3
5302 ```
5303
5304 **Use Cases:**
5305
5306 -   Creating custom menus for user interaction.
5307 -   Providing additional options or commands within the game
5308     interface.
5309
5310 **Note:** The `MENU` opcode is platform-specific and requires
5311 interpreter support. It is important to check the `FLAGS` word before
5312 using this opcode.
5313
5314 ### MOD
5315
5316 **MOD** is an opcode that performs modulo operation on two 16-bit word
5317 values. It divides the first operand by the second operand and returns
5318 the remainder.
5319
5320 **Syntax:**
5321
5322 ``` {.assembly}
5323 mod arg1:int, arg2:int > val
5324 ```
5325
5326 **Functionality:**
5327
5328 The `mod` opcode performs the following:
5329
5330 -   **Divides `arg1` by `arg2`:** Performs integer division.
5331 -   **Calculates the remainder:** Determines the remainder of the
5332     division.
5333 -   **Stores the result:** The remainder is stored in the specified
5334     destination (`val`). If no destination is provided, the result is
5335     pushed onto the game stack.
5336
5337 **Special Cases:**
5338
5339 -   Modulo by zero results in an error.
5340
5341 **Error Conditions:**
5342
5343 An error occurs if `arg2` is zero.
5344
5345 **Examples:**
5346
5347 ``` {.assembly}
5348 mod 10, 3 > result  ; Divides 10 by 3, stores the remainder (1) in `result`
5349 ```
5350
5351 **Use Cases:**
5352
5353 -   Calculating the remainder of a division.
5354 -   Implementing cyclic behavior or patterns.
5355 -   Performing operations based on the position within a cycle.
5356
5357 **Note:** The `mod` opcode is used to obtain the remainder of an
5358 integer division. For operations that require the quotient, use the
5359 `DIV` opcode.
5360
5361 ### MOUSE-INFO
5362
5363 **MOUSE-INFO** is an opcode that retrieves information about the
5364 current state of the mouse and stores it in a table. This information
5365 includes the mouse cursor position, button status, and any selected
5366 menu items.
5367
5368 **Syntax:**
5369
5370 ``` {.assembly}
5371 mouse-info table
5372 ```
5373
5374 **Functionality:**
5375
5376 The `mouse-info` opcode fills the specified `table` with the following
5377 information:
5378
5379 -   **Word 0:** Y coordinate of the mouse cursor (row number, in
5380     screen units).
5381 -   **Word 1:** X coordinate of the mouse cursor (column number, in
5382     screen units).
5383 -   **Word 2:** Button status. Each bit represents a mouse button,
5384     with bit 1 corresponding to the rightmost button. A set bit
5385     indicates that the button is currently pressed.
5386 -   **Word 3:** Menu/item selection. The high byte contains the menu
5387     number (1 for the default menu), and the low byte contains the
5388     selected item number within that menu.
5389
5390 **Special Cases:**
5391
5392 -   The `table` argument must be a table with at least four words of
5393     available space.
5394 -   The interpretation of button status and menu/item selection may
5395     vary depending on the target machine and the number of buttons or
5396     menus available.
5397
5398 **Error Conditions:**
5399
5400 An error occurs if:
5401
5402 -   `table` is not a valid table pointer.
5403 -   The `table` does not have enough space to store the mouse
5404     information (at least four words).
5405
5406 **Examples:**
5407
5408 ``` {.assembly}
5409 mouse-info mouse_data  ; Retrieves the current mouse state
5410 ```
5411
5412 **Use Cases:**
5413
5414 -   Implementing mouse-based interaction and controls.
5415 -   Tracking the mouse cursor position for display or game logic
5416     purposes.
5417 -   Handling mouse button clicks and menu selections.
5418
5419 **Note:** The `MOUSE-INFO` opcode requires the interpreter to support
5420 mouse input. The `%FMOUS` flag in the `FLAGS` word indicates whether
5421 mouse operations are available.
5422
5423 ### MOUSE-LIMIT
5424
5425 **MOUSE-LIMIT** is an opcode that restricts the movement of the mouse
5426 cursor to a specific window. This can be used to confine mouse
5427 interactions to a particular area of the screen.
5428
5429 **Syntax:**
5430
5431 ``` {.assembly}
5432 mouse-limit window:int
5433 ```
5434
5435 **Functionality:**
5436
5437 The `mouse-limit` opcode restricts the mouse cursor movement to the
5438 specified window (`window`). The interpreter, if possible, will
5439 prevent the cursor from moving outside the boundaries of that window.
5440 Mouse events, such as button clicks or movements, will only be
5441 reported if the cursor is within the limited window.
5442
5443 **Special Cases:**
5444
5445 -   **`window` = -1:** Removes any mouse cursor restrictions, allowing
5446     it to move freely across the entire screen.
5447 -   Initially, the mouse cursor is assumed to be limited to window 1.
5448
5449 **Error Conditions:**
5450
5451 An error occurs if `window` is not within the valid range (-1 to 7).
5452
5453 **Examples:**
5454
5455 ``` {.assembly}
5456 mouse-limit 0  ; Limits the mouse cursor to the main window (window 0)
5457 mouse-limit -1 ; Removes mouse cursor restrictions
5458 ```
5459
5460 **Use Cases:**
5461
5462 -   Confining mouse interactions to a specific area of the screen,
5463     such as a menu or game window.
5464 -   Preventing accidental clicks or movements outside the intended
5465     interaction area.
5466
5467 **Note:** The ability to limit the mouse cursor may vary depending on
5468 the capabilities of the interpreter and the target machine.
5469
5470 ### MOVE
5471
5472 **MOVE** is an opcode that moves an object from one location to
5473 another within the object hierarchy. Objects in Z-code programs are
5474 organized in a tree structure, where each object can be contained
5475 within another object.
5476
5477 **Syntax:**
5478
5479 ``` {.assembly}
5480 move thing:obj, dest:obj
5481 ```
5482
5483 **Functionality:**
5484
5485 The `move` opcode moves the object `thing` into the object `dest`:
5486
5487 -   **Checks for existing containment:** If `thing` is already
5488     contained within `dest`, the opcode does nothing.
5489 -   **Removes from previous location:** If `thing` is contained within
5490     another object, it is removed from that object's containment
5491     chain.
5492 -   **Adds to new location:** The `LOC` property of `thing` is set to
5493     the object number of `dest`, and `thing` is added as the first
5494     object in `dest`'s containment chain. This means the `FIRST`
5495     property of `dest` will now point to `thing`.
5496
5497 **Special Cases:**
5498
5499 -   If `dest` is 0, the `thing` object is effectively removed from the
5500     object hierarchy, as its `LOC` property is set to 0.
5501
5502 **Error Conditions:**
5503
5504 An error occurs if:
5505
5506 -   `thing` or `dest` is not a valid object number.
5507
5508 **Examples:**
5509
5510 ``` {.assembly}
5511 move sword, player  ; Moves the "sword" object into the "player" object's inventory
5512 move box, room      ; Moves the "box" object into the "room" object
5513 ```
5514
5515 **Use Cases:**
5516
5517 -   Implementing inventory management and object interaction.
5518 -   Changing the location of objects within the game world.
5519 -   Updating the object hierarchy based on game logic or player
5520     actions.
5521
5522 **Note:** The `MOVE` opcode is a fundamental operation for
5523 manipulating the object hierarchy and managing object containment in
5524 Z-code programs.
5525
5526 ### MUL
5527
5528 **MUL** is an opcode that performs multiplication on two 16-bit word
5529 values. It multiplies the first operand by the second operand and
5530 returns the result.
5531
5532 **Syntax:**
5533
5534 ``` {.assembly}
5535 mul arg1:int, arg2:int > val
5536 ```
5537
5538 **Functionality:**
5539
5540 The `mul` opcode performs the following:
5541
5542 -   **Multiplies `arg1` by `arg2`:** Performs integer multiplication.
5543 -   **Stores the result:** The product is stored in the specified
5544     destination (`val`). If no destination is provided, the result is
5545     pushed onto the game stack.
5546
5547 **Special Cases:**
5548
5549 -   If the result of the multiplication overflows the 16-bit word
5550     size, an error occurs.
5551
5552 **Error Conditions:**
5553
5554 An error occurs if the multiplication result overflows the 16-bit word
5555 range.
5556
5557 **Examples:**
5558
5559 ``` {.assembly}
5560 mul 5, 10 > result  ; Multiplies 5 by 10, stores the product (50) in `result`
5561 ```
5562
5563 **Use Cases:**
5564
5565 -   Performing integer multiplication calculations.
5566 -   Scaling values or calculating areas and volumes.
5567
5568 **Note:** The `mul` opcode performs signed integer multiplication. If
5569 the operands are unsigned, the programmer needs to handle potential
5570 overflow conditions.
5571
5572 ### NEXT?
5573
5574 **NEXT?** is an opcode that retrieves the "next" property of an object
5575 and checks if it is non-zero. It acts as a predicate, meaning it
5576 evaluates a condition and implicitly performs a conditional branch
5577 based on the result.
5578
5579 **Syntax:**
5580
5581 ``` {.assembly}
5582 next? obj > val /pred
5583 ```
5584
5585 **Functionality:**
5586
5587 The `next?` opcode performs the following:
5588
5589 -   **Retrieves "next" property:** Gets the value of the "next" slot
5590     within the object (`obj`). This slot typically contains the object
5591     number of the next object in a linked chain.
5592 -   **Checks for non-zero value:** Evaluates to true if the retrieved
5593     value is not zero (meaning there is a "next" object). Otherwise,
5594     it evaluates to false.
5595 -   **Stores the value (optional):** If the `> val` operand is
5596     provided, the retrieved value is also stored in the specified
5597     variable.
5598 -   **Conditional branch:** Based on the predicate result and the
5599     specified branch polarity (`/pred`), the interpreter may perform a
5600     conditional jump to a specified target.
5601
5602 **Special Cases:**
5603
5604 -   If the object `obj` is the last object in a chain, the "next" slot
5605     will be zero, and the predicate will fail.
5606
5607 **Error Conditions:**
5608
5609 An error occurs if `obj` is not a valid object number.
5610
5611 **Examples:**
5612
5613 ``` {.assembly}
5614 next? item > next_item / process_item  ; Branch to `process_item` if `item` has a "next" object in the chain
5615 ```
5616
5617 **Use Cases:**
5618
5619 -   Iterating through a chain of objects linked by their "next"
5620     properties.
5621 -   Implementing inventory management or object interaction logic.
5622
5623 **Note:** The `NEXT?` opcode is used to access and check the "next"
5624 property of an object. To retrieve the "first" property in a chain,
5625 use the `FIRST?` opcode.
5626
5627 ### NEXTP
5628
5629 **NEXTP** is an opcode that retrieves the number of the property
5630 following a specified property within an object's property table. It
5631 is used to iterate through the properties of an object.
5632
5633 **Syntax:**
5634
5635 ``` {.assembly}
5636 nextp obj, prop > val
5637 ```
5638
5639 **Functionality:**
5640
5641 The `nextp` opcode performs the following:
5642
5643 -   **Locates property table:** Finds the property table associated
5644     with the object (`obj`).
5645 -   **Searches for property:** Searches the property table for the
5646     property with the specified number (`prop`).
5647 -   **Finds next property:** If the property is found, the opcode
5648     determines the number of the next property in the table.
5649 -   **Handles circularity:** If `prop` is the last property in the
5650     table, the opcode returns the number of the first property,
5651     creating a circular iteration.
5652 -   **Stores the result:** The retrieved property number is stored in
5653     the specified destination (`val`). If no destination is provided,
5654     the result is pushed onto the game stack.
5655
5656 **Special Cases:**
5657
5658 -   If `prop` is 0, the opcode returns the number of the first
5659     property in the table.
5660 -   Properties are stored in a sorted order within the object's
5661     property table.
5662
5663 **Error Conditions:**
5664
5665 An error occurs if:
5666
5667 -   `obj` is not a valid object number.
5668 -   `prop` is not a valid property number within the object's property
5669     table.
5670
5671 **Examples:**
5672
5673 ``` {.assembly}
5674 nextp object, 5 > next_prop  ; Retrieves the number of the property following property 5 in `object`
5675 ```
5676
5677 **Use Cases:**
5678
5679 -   Iterating through the properties of an object.
5680 -   Implementing generic routines that need to access all properties
5681     of an object.
5682
5683 **Note:** The `NEXTP` opcode provides a way to navigate through the
5684 properties of an object in a circular manner. It is important to
5685 handle the case where the last property is reached and the opcode
5686 returns the first property number.
5687
5688 ### ORIGINAL?
5689
5690 **ORIGINAL?** is an opcode that checks whether the game is running
5691 from the original distribution disk. It acts as a predicate, meaning
5692 it evaluates a condition and implicitly performs a conditional branch
5693 based on the result.
5694
5695 **Syntax:**
5696
5697 ``` {.assembly}
5698 original? /pred
5699 ```
5700
5701 **Functionality:**
5702
5703 The `original?` opcode checks if the game is running from the original
5704 distribution disk. The specific method for determining originality is
5705 implementation-dependent and may vary between interpreters.
5706
5707 -   **Evaluates predicate:** The predicate succeeds (evaluates to
5708     true) if the game is determined to be running from the original
5709     disk. Otherwise, the predicate fails (evaluates to false).
5710 -   **Conditional branch:** Based on the predicate result and the
5711     specified branch polarity (`/pred`), the interpreter may perform a
5712     conditional jump to a specified target.
5713
5714 **Special Cases:**
5715
5716 The implementation of originality checking is left to the interpreter.
5717
5718 -   Checking for specific files or data on the disk.
5719 -   Comparing checksums or other validation data.
5720 -   Using copy protection mechanisms.
5721
5722 **Error Conditions:**
5723
5724 None.
5725
5726 **Examples:**
5727
5728 ``` {.assembly}
5729 original? / display_warning  ; Branch to `display_warning` if the game is not running from the original disk
5730 ```
5731
5732 ### NOOP
5733
5734 **NOOP** is an opcode that performs no operation. It is essentially a
5735 placeholder instruction that does nothing and simply advances the
5736 program counter to the next instruction.
5737
5738 **Syntax:**
5739
5740 ``` {.assembly}
5741 noop
5742 ```
5743
5744 **Functionality:**
5745
5746 The `noop` opcode has no effect on the program state or data. It
5747 simply increments the program counter, causing the interpreter to move
5748 on to the next instruction in the sequence.
5749
5750 **Special Cases:**
5751
5752 None.
5753
5754 **Error Conditions:**
5755
5756 None.
5757
5758 **Examples:**
5759
5760 ``` {.assembly}
5761 noop  ; Does nothing
5762 ```
5763
5764 **Use Cases:**
5765
5766 -   Aligning code or data to specific memory locations.
5767 -   Providing a placeholder for future instructions or as a debugging
5768     aid.
5769 -   Implementing timing delays or loops with empty bodies.
5770
5771 **Note:** The `NOOP` opcode is rarely used in typical Z-code programs
5772 but can be helpful in specific situations where a placeholder or delay
5773 is needed.
5774
5775 ### PICINF
5776
5777 **PICINF** is an opcode that retrieves information about a picture,
5778 such as its dimensions. Pictures are images stored in a separate
5779 picture file and referenced by their ID numbers.
5780
5781 **Syntax:**
5782
5783 ``` {.assembly}
5784 picinf picture:int, data:tbl /pred
5785 ```
5786
5787 **Functionality:**
5788
5789 The `picinf` opcode retrieves information about the specified picture
5790 (`picture`) and stores it in the `data` table:
5791
5792 -   **Word 0 of `data`:** The width of the picture in pixels.
5793 -   **Word 1 of `data`:** The height of the picture in pixels.
5794
5795 **Predicate Behavior:**
5796
5797 The `picinf` opcode also acts as a predicate:
5798
5799 -   **Success:** The predicate succeeds if the picture ID is valid and
5800     the information is successfully retrieved.
5801 -   **Failure:** The predicate fails if the picture ID is invalid.
5802
5803 **Special Cases:**
5804
5805 -   If the picture ID is 0, the opcode stores the highest picture ID
5806     in the picture library (the number of pictures) in word 0 of the
5807     `data` table.
5808
5809 **Error Conditions:**
5810
5811 None.
5812
5813 **Examples:**
5814
5815 ``` {.assembly}
5816 picinf 10, pic_data / handle_picture  ; Retrieves information about picture 10
5817 picinf 0, pic_data > num_pictures    ; Retrieves the number of pictures in the library
5818 ```
5819
5820 **Use Cases:**
5821
5822 -   Determining the dimensions of a picture before displaying it.
5823 -   Implementing custom picture handling or display routines.
5824 -   Checking the validity of a picture ID.
5825
5826 **Note:** The `PICINF` opcode is used in conjunction with the
5827 `DISPLAY` and `DCLEAR` opcodes to manage the display of pictures
5828 within Z-code programs.
5829
5830 ### PICSET
5831
5832 **PICSET** is an opcode that defines a group of pictures that should
5833 be loaded together from the picture file. This can be used to optimize
5834 picture loading and reduce disk access times.
5835
5836 **Syntax:**
5837
5838 ``` {.assembly}
5839 picset picture:int, count:int
5840 ```
5841
5842 **Functionality:**
5843
5844 The `picset` opcode defines a group of pictures starting from the
5845 specified picture ID (`picture`) and including the next `count`
5846 pictures. The interpreter should attempt to load all pictures in the
5847 group from the picture file simultaneously, reducing the need for
5848 multiple disk accesses.
5849
5850 **Special Cases:**
5851
5852 -   All pictures within a group must be located in the same picture
5853     file.
5854 -   If the interpreter does not support picture grouping, the opcode
5855     should be ignored.
5856
5857 **Error Conditions:**
5858
5859 An error occurs if:
5860
5861 -   `picture` is not a valid picture ID.
5862 -   `count` is negative.
5863
5864 **Examples:**
5865
5866 ``` {.assembly}
5867 picset 10, 5  ; Defines a group of 5 pictures starting from picture ID 10
5868 ```
5869
5870 **Use Cases:**
5871
5872 -   Optimizing picture loading by grouping related pictures together.
5873 -   Reducing disk access times in multi-disk games.
5874
5875 **Note:** The `PICSET` opcode is an optimization feature that may not
5876 be supported by all interpreters. It is important to check the
5877 interpreter's capabilities before using this opcode.
5878
5879 ### POP
5880
5881 **POP** is an opcode that removes the top element from a stack and
5882 returns its value. It can be used to retrieve values from the game
5883 stack or a user-defined stack.
5884
5885 **Syntax:**
5886
5887 ``` {.assembly}
5888 pop [, stack:tbl] > val
5889 ```
5890
5891 **Functionality:**
5892
5893 The `pop` opcode removes the top element from the specified stack and
5894 returns its value:
5895
5896 -   **Game stack (default):** If the `stack` argument is omitted, the
5897     opcode pops the top element from the game stack.
5898 -   **User-defined stack:** If the `stack` argument is provided, the
5899     opcode pops the top element from the table pointed to by `stack`.
5900
5901 **Return Value:**
5902
5903 The popped value is stored in the specified destination (`val`). If no
5904 destination is provided, the value is pushed onto the game stack.
5905
5906 **Special Cases:**
5907
5908 -   Attempting to pop from an empty stack is an error.
5909
5910 **Error Conditions:**
5911
5912 An error occurs if:
5913
5914 -   `stack` is not a valid table pointer (if provided).
5915 -   The stack is empty.
5916
5917 **Examples:**
5918
5919 ``` {.assembly}
5920 pop > value  ; Pops the top element from the game stack and stores it in `value`
5921 pop user_stack > value  ; Pops the top element from `user_stack`
5922 ```
5923
5924 **Use Cases:**
5925
5926 -   Retrieving values from the game stack or user-defined stacks.
5927 -   Implementing stack-based data structures and algorithms.
5928
5929 **Note:** The `POP` opcode is used to remove and retrieve elements
5930 from stacks. To add elements, use the `PUSH` or `XPUSH` opcodes.
5931
5932 ### PRINT
5933
5934 **PRINT** is an opcode that prints a string to the screen. It is used
5935 to display text output in the current window.
5936
5937 **Syntax:**
5938
5939 ``` {.assembly}
5940 print str
5941 ```
5942
5943 **Functionality:**
5944
5945 The `print` opcode prints the string pointed to by `str`. The string
5946 address is calculated by shifting `str` left by two bits and adding
5947 the string offset (`SOFF`) shifted left by three bits.
5948
5949 **Special Cases:**
5950
5951 -   The `str` argument is a quad-pointer, meaning it points to a
5952     string that is aligned to a quad-byte boundary in the string area.
5953 -   The string area is located in a separate section of the Z-code
5954     program and is accessed using the `SOFF` value.
5955 -   Strings are encoded in a special 5-bit byte format for efficient
5956     storage.
5957
5958 **Error Conditions:**
5959
5960 An error occurs if `str` is not a valid string pointer.
5961
5962 **Examples:**
5963
5964 ``` {.assembly}
5965 .gstr "message", "Hello, world!"
5966 print message  ; Prints the "message" string
5967 ```
5968
5969 **Use Cases:**
5970
5971 -   Displaying text output to the user.
5972 -   Printing messages, prompts, or descriptions.
5973
5974 **Note:** The `PRINT` opcode is used to print strings from the string
5975 area. For printing strings within tables or as immediate operands, use
5976 the `PRINTB` opcode.
5977
5978 ### PRINTB
5979
5980 **PRINTB** is an opcode that prints a string from a table or an
5981 immediate string operand. It is used to display text output that is
5982 not stored in the string area.
5983
5984 **Syntax:**
5985
5986 ``` {.assembly}
5987 printb str
5988 ```
5989
5990 **Functionality:**
5991
5992 The `printb` opcode prints the string pointed to by `str`. The string
5993 can be:
5994
5995 -   **A string within a table:** The `str` argument is a byte pointer
5996     to the beginning of the string within a table.
5997 -   **An immediate string operand:** The string is directly encoded
5998     within the instruction as a sequence of bytes.
5999
6000 **Special Cases:**
6001
6002 -   The `printb` opcode is typically used for printing shorter strings
6003     or strings that are dynamically generated.
6004 -   Strings printed with `printb` are not subject to the string offset
6005     (`SOFF`) adjustment.
6006
6007 **Error Conditions:**
6008
6009 An error occurs if `str` is not a valid string pointer or if the
6010 immediate string operand is malformed.
6011
6012 **Examples:**
6013
6014 ``` {.assembly}
6015 printb vocabulary[word_index]  ; Prints the word from the vocabulary table at the specified index
6016 printb "This is an immediate string."  ; Prints the immediate string
6017 ```
6018
6019 **Use Cases:**
6020
6021 -   Printing strings from tables, such as vocabulary entries or text
6022     buffers.
6023 -   Displaying short messages or prompts that do not need to be stored
6024     in the string area.
6025
6026 **Note:** The `PRINTB` opcode is used for printing strings that are
6027 not located in the string area. For printing strings from the string
6028 area, use the `PRINT` opcode.
6029
6030 ### PRINTC
6031
6032 **PRINTC** is an opcode that prints a word from the game's vocabulary
6033 table. It is typically used to reprint words that were previously
6034 parsed from player input.
6035
6036 **Syntax:**
6037
6038 ``` {.assembly}
6039 printc text-char
6040 ```
6041
6042 **Functionality:**
6043
6044 The `printc` opcode performs the following:
6045
6046 -   **Looks up word:** Uses the value of `text-char` as an index into
6047     the vocabulary table (pointed to by the `VOCAB` word in the
6048     program header).
6049 -   **Retrieves word data:** If the index is valid, the opcode
6050     retrieves the word data from the vocabulary table. This data
6051     includes the encoded Z-string representation of the word and its
6052     length.
6053 -   **Prints the word:** Decodes the Z-string and prints the
6054     corresponding characters to the screen.
6055
6056 **Special Cases:**
6057
6058 -   The `text-char` argument is typically obtained from the `lexv`
6059     table, which is filled by the `READ` or `LEX` opcodes during input
6060     parsing.
6061 -   The format of the vocabulary table entries is specific to the
6062     Z-machine and is defined by the `.VOCBEG` directive.
6063
6064 **Error Conditions:**
6065
6066 An error occurs if:
6067
6068 -   `text-char` is not a valid index into the vocabulary table.
6069
6070 **Examples:**
6071
6072 ``` {.assembly}
6073 read input_buffer, lexv
6074 printc lexv[1]  ; Prints the second word from the parsed input
6075 ```
6076
6077 **Use Cases:**
6078
6079 -   Reprinting words that were previously entered by the player.
6080 -   Implementing text-based menus or displays that use words from the
6081     game's vocabulary.
6082
6083 **Note:** The `PRINTC` opcode is used to print words from the
6084 vocabulary table. For printing arbitrary strings, use the `PRINT` or
6085 `PRINTB` opcodes.
6086
6087 ### PRINTD
6088
6089 **PRINTD** is an opcode that prints the short description of an
6090 object. Objects in Z-code programs can have a short description
6091 associated with them, which is typically used for providing a brief
6092 textual representation of the object.
6093
6094 **Syntax:**
6095
6096 ``` {.assembly}
6097 printd obj
6098 ```
6099
6100 **Functionality:**
6101
6102 The `printd` opcode performs the following:
6103
6104 -   **Locates object:** Finds the object with the specified object
6105     number (`obj`).
6106 -   **Retrieves short description:** Accesses the object's property
6107     table and retrieves the value of the `DESC` property, which
6108     contains the short description.
6109 -   **Prints the description:** Decodes the Z-string representation of
6110     the short description and prints the corresponding characters to
6111     the screen.
6112
6113 **Special Cases:**
6114
6115 -   If the object does not have a `DESC` property, the opcode does
6116     nothing.
6117 -   The short description is typically a short string encoded in the
6118     Z-machine's 5-bit byte format.
6119
6120 **Error Conditions:**
6121
6122 An error occurs if `obj` is not a valid object number.
6123
6124 **Examples:**
6125
6126 ``` {.assembly}
6127 printd player  ; Prints the short description of the "player" object
6128 ```
6129
6130 **Use Cases:**
6131
6132 -   Displaying a brief description of an object to the player.
6133 -   Providing context or information about objects in the game world.
6134
6135 **Note:** The `PRINTD` opcode is a convenient way to print the short
6136 description associated with an object. For printing other properties
6137 or arbitrary strings, use the `GETP`, `GETPT`, `PRINT`, or `PRINTB`
6138 opcodes.
6139
6140 ### PRINTF
6141
6142 **PRINTF** is an opcode that prints a formatted table to the screen.
6143 Formatted tables allow for more flexible text layout and can include
6144 variable-length lines, different fonts, and highlighting.
6145
6146 **Syntax:**
6147
6148 ``` {.assembly}
6149 printf table
6150 ```
6151
6152 **Functionality:**
6153
6154 The `printf` opcode prints the contents of the specified `table` as a
6155 formatted block of text. The table format is as follows:
6156
6157 -   **Line length indicators:** Each line of text is preceded by a
6158     word (two bytes) that specifies the number of characters in that
6159     line.
6160 -   **Character data:** The characters of each line are stored as
6161     consecutive bytes.
6162 -   **End of table marker:** A word with the value 0 marks the end of
6163     the table.
6164
6165 The opcode interprets the line length indicators and character data to
6166 print the text with the appropriate formatting, including line breaks
6167 and potential justification.
6168
6169 **Special Cases:**
6170
6171 -   Formatted tables are typically generated using the `DIROUT 3`
6172     opcode with the `just` argument to specify justification.
6173 -   The `printf` opcode can handle tables with variable-length lines,
6174     different fonts, and highlighting.
6175
6176 **Error Conditions:**
6177
6178 An error occurs if:
6179
6180 -   `table` is not a valid table pointer.
6181 -   The table format is invalid.
6182
6183 **Examples:**
6184
6185 ``` {.assembly}
6186 dirout 3, formatted_text, 80  ; Redirects output to `formatted_text` with right justification at 80 pixels
6187 ; ... generate formatted text ...
6188 dirout -3
6189 printf formatted_text        ; Prints the formatted table
6190 ```
6191
6192 **Use Cases:**
6193
6194 -   Displaying text with custom formatting and layout.
6195 -   Creating menus or dialog boxes with variable-length lines and
6196     different styles.
6197 -   Implementing text-based graphics or visual effects.
6198
6199 **Note:** The `PRINTF` opcode provides a more flexible way to display
6200 text compared to the `PRINT` or `PRINTB` opcodes. It is particularly
6201 useful for situations where precise control over text layout and
6202 formatting is required.
6203
6204 ### PRINTI
6205
6206 **PRINTI** is an opcode that prints an immediate string directly
6207 encoded within the instruction. It is used to display short, fixed
6208 messages or prompts without the need to define them as separate
6209 strings in the string area.
6210
6211 **Syntax:**
6212
6213 ``` {.assembly}
6214 printi "string"
6215 ```
6216
6217 **Functionality:**
6218
6219 The `printi` opcode decodes and prints the string literal `"string"`
6220 that is included directly within the instruction.
6221
6222 **Special Cases:**
6223
6224 -   The string literal must be enclosed in double quotes (`"`).
6225 -   Double quotes within the string are escaped by using two
6226     consecutive double quotes.
6227
6228 **Error Conditions:**
6229
6230 An error occurs if the string literal is malformed or not properly
6231 terminated.
6232
6233 **Examples:**
6234
6235 ``` {.assembly}
6236 printi "Hello, world!"  ; Prints the string "Hello, world!"
6237 printi "He said, ""Hello!"""  ; Prints the string "He said, "Hello!""
6238 ```
6239
6240 **Use Cases:**
6241
6242 -   Printing short, fixed messages or prompts.
6243 -   Displaying error messages or debugging information.
6244
6245 **Note:** The `PRINTI` opcode is a convenient way to print short
6246 strings without the overhead of defining them as separate entities in
6247 the string area. However, for longer or more complex strings, using
6248 the `PRINT` or `PRINTB` opcodes with strings defined using `.STR` or
6249 `.GSTR` is more efficient.
6250
6251 ### PRINTN
6252
6253 **PRINTN** is an opcode that prints a signed integer value as a
6254 decimal number. It is used to display numerical values on the screen.
6255
6256 **Syntax:**
6257
6258 ``` {.assembly}
6259 printn number:int
6260 ```
6261
6262 **Functionality:**
6263
6264 The `printn` opcode converts the signed integer value `number` into a
6265 decimal string representation and prints it to the current window.
6266
6267 **Special Cases:**
6268
6269 -   Negative numbers are printed with a leading minus sign (`-`).
6270 -   The number is printed using the current font and highlighting
6271     settings.
6272
6273 **Error Conditions:**
6274
6275 None.
6276
6277 **Examples:**
6278
6279 ``` {.assembly}
6280 printn score  ; Prints the value of the variable `score` as a decimal number
6281 printn -10    ; Prints the number -10
6282 ```
6283
6284 **Use Cases:**
6285
6286 -   Displaying numerical values, such as scores, health points, or
6287     inventory counts.
6288 -   Printing the results of calculations or comparisons.
6289
6290 **Note:** The `PRINTN` opcode is used to print signed integer values.
6291 For printing unsigned values or values in other formats, use the
6292 `PRINT` or `PRINTB` opcodes with appropriate string formatting.
6293
6294 ### PRINTR
6295
6296 **PRINTR** is an opcode that prints an immediate string and then
6297 performs a carriage return and line feed (CRLF), effectively moving
6298 the cursor to the beginning of the next line. It also implicitly
6299 returns true from the current function.
6300
6301 **Syntax:**
6302
6303 ``` {.assembly}
6304 printr "string"
6305 ```
6306
6307 **Functionality:**
6308
6309 The `printr` opcode performs the following:
6310
6311 1.  **Prints the string:** Decodes and prints the string literal
6312     `"string"` that is included directly within the instruction.
6313 2.  **Outputs CRLF:** Prints a carriage return and line feed sequence,
6314     moving the cursor to the beginning of the next line.
6315 3.  **Returns true:** Implicitly returns the value 1 (true) from the
6316     current function.
6317
6318 **Special Cases:**
6319
6320 -   The string literal must be enclosed in double quotes (`"`).
6321 -   Double quotes within the string are escaped by using two
6322     consecutive double quotes.
6323
6324 **Error Conditions:**
6325
6326 An error occurs if the string literal is malformed or not properly
6327 terminated.
6328
6329 **Examples:**
6330
6331 ``` {.assembly}
6332 printr "Game over!"  ; Prints "Game over!" and then returns true, ending the current function
6333 ```
6334
6335 **Use Cases:**
6336
6337 -   Printing a final message or prompt before ending the current
6338     function.
6339 -   Displaying error messages or debugging information and then
6340     returning from the function.
6341
6342 **Note:** The `PRINTR` opcode combines string printing, line
6343 termination, and function return into a single operation. It is a
6344 convenient way to print a message and then exit the current function.
6345
6346 ### PRINTT
6347
6348 **PRINTT** is an opcode that prints a rectangular block of text from a
6349 byte-oriented table. It allows for flexible formatting and display of
6350 text data.
6351
6352 **Syntax:**
6353
6354 ``` {.assembly}
6355 printt bytes:tbl, width:int, height:int [, skip:int]
6356 ```
6357
6358 **Functionality:**
6359
6360 The `printt` opcode prints a block of text from the specified table
6361 (`bytes`) according to the given dimensions and skip value:
6362
6363 -   **`bytes`:** A pointer to a byte-oriented table containing the
6364     text data.
6365 -   **`width`:** The width of the text block in columns (number of
6366     characters per line).
6367 -   **`height`:** The height of the text block in lines.
6368 -   **`skip` (optional):** The number of bytes to skip at the end of
6369     each line. This allows for printing rectangular blocks from within
6370     larger tables. If omitted, the default skip value is 0.
6371
6372 The opcode prints the text line by line, wrapping to the next line
6373 when the `width` is reached. After each line, it skips `skip` bytes in
6374 the table before starting the next line.
6375
6376 **Special Cases:**
6377
6378 -   If the `skip` argument is 0, the opcode prints a continuous block
6379     of text without skipping any bytes.
6380 -   The `printt` opcode does not perform any character set decoding or
6381     string interpretation. It simply prints the raw bytes from the
6382     table.
6383
6384 **Error Conditions:**
6385
6386 An error occurs if:
6387
6388 -   `bytes` is not a valid table pointer.
6389 -   `width` or `height` is zero or negative.
6390 -   `skip` is negative.
6391
6392 **Examples:**
6393
6394 ``` {.assembly}
6395 printt text_buffer, 80, 24  ; Prints a 24-line block of text from `text_buffer`, 80 characters per line
6396 printt table, 10, 5, 20     ; Prints a 5-line block from `table`, 10 characters per line, skipping 20 bytes after each line
6397 ```
6398
6399 **Use Cases:**
6400
6401 -   Displaying formatted text from tables.
6402 -   Printing text-based graphics or user interface elements.
6403 -   Implementing custom text layout and formatting.
6404
6405 **Note:** The `PRINTT` opcode provides a flexible way to print text
6406 from tables. It is important to ensure that the table format and
6407 dimensions are correct to avoid unexpected output.
6408
6409 ### PTSIZE
6410
6411 **PTSIZE** is an opcode that returns the size of a property table in
6412 bytes. Property tables are associated with objects and contain
6413 additional data and attributes.
6414
6415 **Syntax:**
6416
6417 ``` {.assembly}
6418 ptsize table > val
6419 ```
6420
6421 **Functionality:**
6422
6423 The `ptsize` opcode calculates the size of the property table pointed
6424 to by `table` and stores the result in the specified destination
6425 (`val`). If no destination is provided, the result is pushed onto the
6426 game stack.
6427
6428 **Special Cases:**
6429
6430 -   The `ptsize` opcode is typically used with property tables
6431     obtained using the `GETPT` opcode.
6432 -   The opcode assumes that the property table has the correct format,
6433     with properties stored in a sorted order and appropriate length
6434     indicators.
6435
6436 **Error Conditions:**
6437
6438 An error may occur if `table` is not a valid property table pointer or
6439 if the table format is invalid.
6440
6441 **Examples:**
6442
6443 ``` {.assembly}
6444 getpt object, 10 > prop_ptr  ; Retrieves a pointer to property 10 of `object`
6445 ptsize prop_ptr > prop_size   ; Calculates the size of the property value
6446 ```
6447
6448 **Use Cases:**
6449
6450 -   Determining the size of a property value before accessing or
6451     manipulating it.
6452 -   Implementing routines that need to handle properties of varying
6453     lengths.
6454
6455 **Note:** The `PTSIZE` opcode is used to determine the size of
6456 property tables. It is important to ensure that the table pointer is
6457 valid and the table format is correct.
6458
6459 ### PUSH
6460
6461 **PUSH** is an opcode that pushes a value onto the game stack. The
6462 game stack is a LIFO (Last-In-First-Out) data structure used to store
6463 temporary values and function arguments.
6464
6465 **Syntax:**
6466
6467 ``` {.assembly}
6468 push value
6469 ```
6470
6471 **Functionality:**
6472
6473 The `push` opcode pushes the specified `value` onto the top of the
6474 game stack.
6475
6476 **Special Cases:**
6477
6478 -   Pushing a value onto a full stack results in a stack overflow
6479     error.
6480
6481 **Error Conditions:**
6482
6483 An error occurs if the game stack is full.
6484
6485 **Examples:**
6486
6487 ``` {.assembly}
6488 push 5      ; Pushes the value 5 onto the stack
6489 push var1   ; Pushes the value of the variable `var1` onto the stack
6490 ```
6491
6492 **Use Cases:**
6493
6494 -   Storing temporary values during calculations or operations.
6495 -   Passing arguments to functions.
6496 -   Implementing stack-based data structures and algorithms.
6497
6498 **Note:** The `PUSH` opcode is used to add elements to the game stack.
6499 To remove elements, use the `POP` or `FSTACK` opcodes.
6500
6501 ### PUT
6502
6503 **PUT** is an opcode that stores a word value into a specified element
6504 of a word-oriented table. It is used to modify data stored in tables
6505 based on their index or offset.
6506
6507 **Syntax:**
6508
6509 ``` {.assembly}
6510 put table, item, value
6511 ```
6512
6513 **Functionality:**
6514
6515 The `put` opcode performs the following:
6516
6517 -   **Calculates element address:** Multiplies the `item` (index or
6518     offset) by 2 and adds it to the base address of the `table`. This
6519     gives the address of the desired element in memory.
6520 -   **Stores the value:** Writes the word value `value` to the
6521     calculated address.
6522
6523 **Special Cases:**
6524
6525 -   Table offsets are zero-based, meaning the first element has an
6526     index of 0.
6527 -   The interpreter does not perform bounds checking on table
6528     accesses. It is the programmer's responsibility to ensure that
6529     `item` is within the valid range of the table.
6530
6531 **Error Conditions:**
6532
6533 An error may occur if:
6534
6535 -   `table` is not a valid table pointer.
6536 -   `item` is outside the bounds of the table.
6537
6538 **Examples:**
6539
6540 ``` {.assembly}
6541 put inventory, 3, "sword"  ; Stores the word "sword" in the 4th element of the `inventory` table
6542 ```
6543
6544 **Use Cases:**
6545
6546 -   Modifying data stored in tables based on their index or offset.
6547 -   Implementing data structures and algorithms that require updating
6548     table values.
6549
6550 **Note:** The `PUT` opcode is used for storing word-sized elements in
6551 tables. For byte-sized elements, use the `PUTB` opcode.
6552
6553 ### PUTB
6554
6555 **PUTB** is an opcode that stores a byte value into a specified
6556 element of a byte-oriented table. It is used to modify data stored in
6557 tables based on their index or offset.
6558
6559 **Syntax:**
6560
6561 ``` {.assembly}
6562 putb table, item, value
6563 ```
6564
6565 **Functionality:**
6566
6567 The `putb` opcode performs the following:
6568
6569 -   **Calculates element address:** Adds the `item` (index or offset)
6570     to the base address of the `table`. This gives the address of the
6571     desired element in memory.
6572 -   **Extracts byte value:** Takes the low-order byte of `value` as
6573     the byte to be stored.
6574 -   **Stores the byte:** Writes the extracted byte value to the
6575     calculated address.
6576
6577 **Special Cases:**
6578
6579 -   Table offsets are zero-based, meaning the first element has an
6580     index of 0.
6581 -   The interpreter does not perform bounds checking on table
6582     accesses. It is the programmer's responsibility to ensure that
6583     `item` is within the valid range of the table.
6584 -   The high-order byte of `value` is ignored.
6585
6586 **Error Conditions:**
6587
6588 An error may occur if:
6589
6590 -   `table` is not a valid table pointer.
6591 -   `item` is outside the bounds of the table.
6592
6593 **Examples:**
6594
6595 ``` {.assembly}
6596 putb text_buffer, 5, 'A'  ; Stores the ASCII value of 'A' in the 6th byte of the `text_buffer` table
6597 ```
6598
6599 **Use Cases:**
6600
6601 -   Modifying data stored in byte-oriented tables.
6602 -   Writing individual characters to text buffers.
6603 -   Implementing data structures and algorithms that require updating
6604     byte-level table values.
6605
6606 **Note:** The `PUTB` opcode is used for storing byte-sized elements in
6607 tables. For word-sized elements, use the `PUT` opcode.
6608
6609 ### PUTP
6610
6611 **PUTP** is an opcode that sets the value of a property within an
6612 object's property table. Properties are used to associate additional
6613 data and attributes with objects.
6614
6615 **Syntax:**
6616
6617 ``` {.assembly}
6618 putp obj, prop, value
6619 ```
6620
6621 **Functionality:**
6622
6623 The `putp` opcode modifies a property within an object's property
6624 table:
6625
6626 -   **Locates property table:** Finds the property table associated
6627     with the object (`obj`).
6628 -   **Searches for property:** Searches the property table for the
6629     property with the specified number (`prop`).
6630 -   **Updates property value:** If the property is found, its value is
6631     updated to `value`.
6632 -   **Error if property not found:** If the property is not found in
6633     the object's property table, an error occurs.
6634
6635 **Special Cases:**
6636
6637 -   The `PUTP` opcode can only be used to modify properties with a
6638     length of 1 or 2 bytes. For properties of arbitrary length, use a
6639     combination of `GETPT` and table manipulation opcodes.
6640
6641 **Error Conditions:**
6642
6643 An error occurs if:
6644
6645 -   `obj` is not a valid object number.
6646 -   `prop` is not a valid property number within the object's property
6647     table.
6648 -   The property does not exist in the object's property table.
6649
6650 **Examples:**
6651
6652 ``` {.assembly}
6653 putp player, 1, 15  ; Sets the value of property 1 ("strength") in the "player" object to 15
6654 ```
6655
6656 **Use Cases:**
6657
6658 -   Modifying data associated with objects through properties.
6659 -   Updating object attributes or characteristics based on game logic
6660     or player actions.
6661
6662 **Note:** The `PUTP` opcode is used to modify properties with a length
6663 of 1 or 2 bytes. For properties of arbitrary length, use a combination
6664 of `GETPT` and table manipulation opcodes.
6665
6666 ### QUIT
6667
6668 **QUIT** is an opcode that terminates the execution of the Z-code
6669 program. It is used to end the game or exit the interpreter.
6670
6671 **Syntax:**
6672
6673 ``` {.assembly}
6674 quit
6675 ```
6676
6677 **Functionality:**
6678
6679 The `quit` opcode signals to the interpreter that the program should
6680 terminate. The interpreter performs any necessary cleanup operations
6681 and then exits.
6682
6683 **Special Cases:**
6684
6685 None.
6686
6687 **Error Conditions:**
6688
6689 None.
6690
6691 **Examples:**
6692
6693 ``` {.assembly}
6694 quit  ; Terminates the program
6695 ```
6696
6697 **Use Cases:**
6698
6699 -   Ending the game when the player reaches a specific condition or
6700     completes all objectives.
6701 -   Exiting the interpreter in response to a user command or error
6702     condition.
6703
6704 **Note:** The `QUIT` opcode is a terminal instruction that stops the
6705 execution of the Z-code program. It is important to ensure that all
6706 necessary cleanup or saving operations are performed before using this
6707 opcode.
6708
6709 ### RANDOM
6710
6711 **RANDOM** is an opcode that generates a random number within a
6712 specified range. It is used to introduce randomness and
6713 unpredictability into the game.
6714
6715 **Syntax:**
6716
6717 ``` {.assembly}
6718 random range:int > val
6719 ```
6720
6721 **Functionality:**
6722
6723 The `random` opcode generates a random integer value between 1 and
6724 `range` (inclusive) and stores it in the specified destination
6725 (`val`). If no destination is provided, the result is pushed onto the
6726 game stack.
6727
6728 **Special Cases:**
6729
6730 -   **Negative `range`:** If `range` is negative, the opcode enters a
6731     "predictable" mode. The absolute value of `range` is saved, and
6732     subsequent calls to `random` with a positive range will generate
6733     numbers in a sequence from 1 to the saved absolute value.
6734 -   **`range` = 0:** Resets the random number generator to its normal
6735     (unpredictable) mode.
6736
6737 **Error Conditions:**
6738
6739 None.
6740
6741 **Examples:**
6742
6743 ``` {.assembly}
6744 random 6 > dice_roll  ; Generates a random number between 1 and 6
6745 random -10           ; Enters predictable mode with a sequence of 1 to 10
6746 random 4 > next_num  ; Generates the next number in the predictable sequence (e.g., 1, 2, 3, 4, 1, ...)
6747 random 0            ; Resets to unpredictable mode
6748 ```
6749
6750 **Use Cases:**
6751
6752 -   Generating random events or outcomes in the game.
6753 -   Simulating dice rolls or other random processes.
6754 -   Introducing variability and replayability into the game
6755     experience.
6756
6757 **Note:** The implementation of the random number generator may vary
6758 between interpreters. The predictable mode allows for testing and
6759 debugging scenarios where consistent random values are desired.
6760
6761 ### READ
6762
6763 **READ** is an opcode that reads a line of input from the user, parses
6764 it into words, and looks up the words in the vocabulary table. It is a
6765 fundamental operation for receiving player input and interpreting
6766 commands.
6767
6768 **Syntax:**
6769
6770 ``` {.assembly}
6771 read text-buffer:tbl, parse-buffer:tbl [, time:int, routine:fcn] > val
6772 ```
6773
6774 **Functionality:**
6775
6776 The `read` opcode performs the following:
6777
6778 1.  **Clears output buffer:** Prints and empties the current output
6779     buffer, ensuring that any pending output is displayed before
6780     reading input.
6781 2.  **Reads input:** Reads a line of text from the user, storing the
6782     characters in the `text-buffer` table. The first byte of
6783     `text-buffer` specifies the maximum length of the buffer, and the
6784     second byte is used by the opcode to store the number of
6785     characters read.
6786 3.  **Converts to lowercase:** Converts all uppercase letters in the
6787     input to lowercase.
6788 4.  **Parses input (optional):** If `parse-buffer` is non-zero, the
6789     opcode parses the input text into words and stores information
6790     about each word in the `parse-buffer` table. The format of the
6791     `parse-buffer` is specific to the Z-machine and is used by other
6792     opcodes like `PRINTC` to reprint words from the input.
6793 5.  **Returns terminator:** The opcode returns the character that
6794     terminated the input (e.g., newline, space, or a character from
6795     the `TCHARS` table). This value is stored in the specified
6796     destination (`val`). If no destination is provided, the value is
6797     pushed onto the game stack.
6798
6799 **Optional Arguments:**
6800
6801 -   **`time`:** Specifies a timeout value in tenths of a second. If no
6802     input is received within the specified time, the interpreter calls
6803     the `routine` function.
6804 -   **`routine`:** A function to call when a timeout occurs. The
6805     function should return true (1) to abort the input operation or
6806     false (0) to continue waiting for input.
6807
6808 **Special Cases:**
6809
6810 -   The `TCHARS` table in the program header specifies which
6811     characters can terminate input.
6812 -   The vocabulary table (pointed to by the `VOCAB` word) is used to
6813     look up words during parsing.
6814 -   The interpreter may handle timeout behavior differently depending
6815     on the target machine and implementation.
6816
6817 **Error Conditions:**
6818
6819 An error occurs if:
6820
6821 -   `text-buffer` or `parse-buffer` is not a valid table pointer.
6822 -   The `text-buffer` is not large enough to hold the input line.
6823 -   `time` is negative (if provided).
6824 -   `routine` is not a valid function pointer (if provided).
6825
6826 **Examples:**
6827
6828 ``` {.assembly}
6829 read input_buffer, parse_buffer > terminator  ; Reads input and parses it into words
6830 read input_buffer, 0 > terminator             ; Reads input without parsing
6831 ```
6832
6833 **Use Cases:**
6834
6835 -   Getting input from the user, such as commands, responses, or text
6836     entry.
6837 -   Implementing a text parser to interpret player commands.
6838 -   Handling timed input or interactive sequences.
6839
6840 **Note:** The `READ` opcode is a fundamental operation for receiving
6841 and processing player input in Z-code programs.
6842
6843 ### REMOVE
6844
6845 **REMOVE** is an opcode that removes an object from the object
6846 hierarchy. Objects in Z-code programs are organized in a tree
6847 structure, where each object can be contained within another object.
6848
6849 **Syntax:**
6850
6851 ``` {.assembly}
6852 remove obj
6853 ```
6854
6855 **Functionality:**
6856
6857 The `remove` opcode removes the specified object (`obj`) from the
6858 object hierarchy:
6859
6860 1.  **Finds the containing object:** Determines the object that
6861     currently contains `obj` by examining its `LOC` property.
6862 2.  **Updates containment chain:** Removes `obj` from the containment
6863     chain of the containing object. This involves updating the `FIRST`
6864     and `NEXT` properties of the objects in the chain.
6865 3.  **Clears object properties:** Sets the `LOC`, `FIRST`, and `NEXT`
6866     properties of `obj` to 0, effectively removing it from the object
6867     hierarchy.
6868
6869 **Special Cases:**
6870
6871 -   If `obj` is not contained within any other object (i.e., it is a
6872     top-level object), the opcode only clears its `LOC`, `FIRST`, and
6873     `NEXT` properties.
6874
6875 **Error Conditions:**
6876
6877 An error occurs if `obj` is not a valid object number.
6878
6879 **Examples:**
6880
6881 ``` {.assembly}
6882 remove item  ; Removes the `item` object from its container
6883 ```
6884
6885 **Use Cases:**
6886
6887 -   Implementing inventory management and object interaction.
6888 -   Removing objects from the game world when they are no longer
6889     needed.
6890 -   Updating the object hierarchy based on game logic or player
6891     actions.
6892
6893 **Note:** The `REMOVE` opcode is used to remove objects from the
6894 object hierarchy. It is important to ensure that the object is
6895 properly removed from any containment chains to avoid dangling
6896 references or memory leaks.
6897
6898 ### RESTART
6899
6900 **RESTART** is an opcode that reinitializes the Z-code program and
6901 restarts the game from the beginning. It is used to reset the game
6902 state and start a new playthrough.
6903
6904 **Syntax:**
6905
6906 ``` {.assembly}
6907 restart
6908 ```
6909
6910 **Functionality:**
6911
6912 The `restart` opcode performs the following:
6913
6914 1.  **Reloads the preloaded area:** The interpreter reloads the
6915     portion of the game file that is below the `ENDLOD` address, which
6916     includes all modifiable data and essential tables.
6917 2.  **Resets the game state:** All global variables, object flags, and
6918     other modifiable data are reset to their initial values.
6919 3.  **Jumps to the start address:** The program counter is set to the
6920     address specified by the `START` word in the program header, which
6921     is typically the beginning of the main game function.
6922
6923 **Special Cases:**
6924
6925 -   The `RESTART` opcode does not affect the state of the interpreter
6926     itself, such as window configurations or display settings.
6927 -   The random number generator may or may not be reseeded, depending
6928     on the interpreter implementation.
6929
6930 **Error Conditions:**
6931
6932 None.
6933
6934 **Examples:**
6935
6936 ``` {.assembly}
6937 restart  ; Restarts the game
6938 ```
6939
6940 **Use Cases:**
6941
6942 -   Starting a new game from the beginning.
6943 -   Resetting the game state after an error or unexpected event.
6944 -   Implementing a "restart game" command for the player.
6945
6946 **Note:** The `RESTART` opcode provides a way to reset the game state
6947 and start a new playthrough. It is important to ensure that all
6948 necessary data is properly reinitialized during the restart process.
6949
6950 ### RESTORE
6951
6952 **RESTORE** is an opcode that restores a previously saved game state
6953 from disk. It allows players to resume a game from a saved point.
6954
6955 **Syntax:**
6956
6957 ``` {.assembly}
6958 restore [, start:int, length:int, name:tbl] > val
6959 ```
6960
6961 **Functionality:**
6962
6963 The `restore` opcode has two modes of operation:
6964
6965 **1. Full Restore (no arguments):**
6966
6967 -   **Prompts for filename:** The interpreter typically prompts the
6968     user to provide a filename or select a saved game file.
6969 -   **Reads saved data:** The interpreter reads the saved game data
6970     from the specified file.
6971 -   **Restores game state:** The impure area of the Z-code program,
6972     which includes global variables, object flags, and table contents,
6973     is restored to the state it was in when the game was saved.
6974 -   **Continues execution:** The program resumes execution from the
6975     point where it was saved.
6976
6977 **2. Partial Restore (with arguments):**
6978
6979 -   **`start`:** The starting address of the memory region to restore.
6980 -   **`length`:** The length of the memory region to restore in bytes.
6981 -   **`name`:** A string specifying the name of the saved data.
6982
6983 This mode allows for restoring specific sections of the impure area,
6984 such as individual tables or groups of variables.
6985
6986 **Return Value:**
6987
6988 -   **Full restore:** The opcode does not return a value.
6989 -   **Partial restore:** The opcode returns the number of bytes
6990     successfully read from the saved data.
6991
6992 **Special Cases:**
6993
6994 -   The format of the saved game data is specific to the Z-machine and
6995     may vary depending on the interpreter implementation.
6996 -   The `RESTORE` opcode does not restore the state of the interpreter
6997     itself, such as window configurations or display settings.
6998 -   The random number generator may or may not be reseeded, depending
6999     on the interpreter implementation.
7000
7001 **Error Conditions:**
7002
7003 An error occurs if:
7004
7005 -   The specified saved game file cannot be found or opened.
7006 -   The saved game data is corrupted or invalid.
7007 -   The `start` or `length` arguments are invalid (in partial restore
7008     mode).
7009
7010 **Examples:**
7011
7012 ``` {.assembly}
7013 restore  ; Restores a saved game from a file
7014 restore table_address, table_size, "my_table"  ; Restores a specific table from saved data
7015 ```
7016
7017 **Use Cases:**
7018
7019 -   Allowing players to save and resume their progress in the game.
7020 -   Implementing checkpoint or save-game functionality.
7021 -   Restoring specific data structures or variables from saved data.
7022
7023 **Note:** The `RESTORE` opcode is essential for providing save and
7024 restore functionality in Z-code games. The specific implementation and
7025 user interface for saving and loading games may vary depending on the
7026 interpreter.
7027
7028 ### RETURN
7029
7030 **RETURN** is an opcode that returns from the current function and
7031 resumes execution in the calling function. It also allows for
7032 specifying a return value.
7033
7034 **Syntax:**
7035
7036 ``` {.assembly}
7037 return value
7038 ```
7039
7040 **Functionality:**
7041
7042 The `return` opcode performs the following:
7043
7044 1.  **Sets return value:** The specified `value` is set as the return
7045     value of the function.
7046 2.  **Restores stack frame:** The interpreter restores the stack frame
7047     of the calling function, including local variables, stack pointer,
7048     and argument count.
7049 3.  **Resumes execution:** Control is transferred back to the
7050     instruction following the `CALL` instruction that invoked the
7051     current function.
7052
7053 **Special Cases:**
7054
7055 -   If the current function was called using an `ICALL` variant (which
7056     does not expect a return value), the `value` argument is ignored.
7057
7058 **Error Conditions:**
7059
7060 None.
7061
7062 **Examples:**
7063
7064 ``` {.assembly}
7065 return 5     ; Returns the value 5 from the function
7066 return result ; Returns the value of the variable `result`
7067 ```
7068
7069 **Use Cases:**
7070
7071 -   Returning from functions and providing a result to the calling
7072     function.
7073 -   Implementing subroutines and modular code structures.
7074
7075 **Note:** The `RETURN` opcode is essential for controlling the flow of
7076 execution between functions in Z-code programs.
7077
7078 ### RFALSE
7079
7080 **RFALSE** is an opcode that returns the value 0 (false) from the
7081 current function. It is typically used as a branch target for
7082 predicate instructions that evaluate to false.
7083
7084 **Syntax:**
7085
7086 ``` {.assembly}
7087 rfalse
7088 ```
7089
7090 **Functionality:**
7091
7092 The `rfalse` opcode sets the return value of the current function to 0
7093 and then returns control to the calling function.
7094
7095 **Special Cases:**
7096
7097 None.
7098
7099 **Error Conditions:**
7100
7101 None.
7102
7103 **Examples:**
7104
7105 ``` {.assembly}
7106 equal? object, "sword" / handle_sword
7107 rfalse                 ; Returns false if the object is not a sword
7108 ```
7109
7110 **Use Cases:**
7111
7112 -   Returning false from a function when a condition is not met.
7113 -   Implementing conditional logic and branching based on predicate
7114     results.
7115
7116 **Note:** The `RFALSE` opcode is often used as a branch target for
7117 predicate instructions that evaluate to false. It provides a
7118 convenient way to return a false value and exit the current function.
7119
7120 ### RSTACK
7121
7122 **RSTACK** is an opcode that returns from the current function and
7123 uses the value on top of the stack as the return value. This allows
7124 for a more flexible way to return values from functions without
7125 explicitly specifying them in the `RETURN` instruction.
7126
7127 **Syntax:**
7128
7129 ``` {.assembly}
7130 rstack
7131 ```
7132
7133 **Functionality:**
7134
7135 The `rstack` opcode performs the following:
7136
7137 1.  **Pops return value:** Removes the top element from the game stack
7138     and uses it as the return value of the function.
7139 2.  **Restores stack frame:** The interpreter restores the stack frame
7140     of the calling function, including local variables, stack pointer,
7141     and argument count.
7142 3.  **Resumes execution:** Control is transferred back to the
7143     instruction following the `CALL` instruction that invoked the
7144     current function.
7145
7146 **Special Cases:**
7147
7148 -   If the game stack is empty, a stack underflow error occurs.
7149
7150 **Error Conditions:**
7151
7152 An error occurs if the game stack is empty when the `RSTACK` opcode is
7153 executed.
7154
7155 **Examples:**
7156
7157 ``` {.assembly}
7158 ; ... function code that pushes a value onto the stack ...
7159 rstack  ; Returns the value from the top of the stack
7160 ```
7161
7162 **Use Cases:**
7163
7164 -   Returning values from functions without explicitly specifying them
7165     in the `RETURN` instruction.
7166 -   Implementing functions that can return different types of values
7167     depending on the context.
7168
7169 **Note:** The `RSTACK` opcode provides a more flexible way to return
7170 values from functions, but it is important to ensure that the stack
7171 contains the correct value before using this opcode.
7172
7173 ### RTRUE
7174
7175 **RTRUE** is an opcode that returns the value 1 (true) from the
7176 current function. It is typically used as a branch target for
7177 predicate instructions that evaluate to true.
7178
7179 **Syntax:**
7180
7181 ``` {.assembly}
7182 rtrue
7183 ```
7184
7185 **Functionality:**
7186
7187 The `rtrue` opcode sets the return value of the current function to 1
7188 and then returns control to the calling function.
7189
7190 **Special Cases:**
7191
7192 None.
7193
7194 **Error Conditions:**
7195
7196 None.
7197
7198 **Examples:**
7199
7200 ``` {.assembly}
7201 equal? object, "sword" / handle_sword
7202 rtrue                  ; Returns true if the object is a sword
7203 ```
7204
7205 **Use Cases:**
7206
7207 -   Returning true from a function when a condition is met.
7208 -   Implementing conditional logic and branching based on predicate
7209     results.
7210
7211 **Note:** The `RTRUE` opcode is often used as a branch target for
7212 predicate instructions that evaluate to true. It provides a convenient
7213 way to return a true value and exit the current function.
7214
7215 ### SAVE
7216
7217 **SAVE** is an opcode that saves the current game state to disk,
7218 allowing players to resume their progress later.
7219
7220 **Syntax:**
7221
7222 ``` {.assembly}
7223 save [, start:int, length:int, name:tbl] > val
7224 ```
7225
7226 **Functionality:**
7227
7228 The `save` opcode has two modes of operation:
7229
7230 **1. Full Save (no arguments):**
7231
7232 -   **Prompts for filename:** The interpreter typically prompts the
7233     user to provide a filename or select a save game slot.
7234 -   **Writes game data:** The interpreter writes the current game
7235     state to the specified file. This includes the contents of the
7236     impure area, which contains all modifiable data such as global
7237     variables, object flags, and table contents.
7238 -   **Returns status:** The opcode returns 0 if the save operation
7239     fails and 1 if it succeeds.
7240
7241 **2. Partial Save (with arguments):**
7242
7243 -   **`start`:** The starting address of the memory region to save.
7244 -   **`length`:** The length of the memory region to save in bytes.
7245 -   **`name`:** A string specifying a unique name for the saved data.
7246
7247 This mode allows for saving specific sections of the impure area, such
7248 as individual tables or groups of variables.
7249
7250 **Return Value:**
7251
7252 -   **Full save:** Returns 0 if the save operation fails and 1 if it
7253     succeeds.
7254 -   **Partial save:** Returns 2 to indicate successful completion.
7255
7256 **Special Cases:**
7257
7258 -   The format of the saved game data is specific to the Z-machine and
7259     may vary depending on the interpreter implementation.
7260 -   The `SAVE` opcode does not save the state of the interpreter
7261     itself, such as window configurations or display settings.
7262 -   The random number generator seed is typically not saved to ensure
7263     that restoring a saved game does not result in the same sequence
7264     of random events.
7265
7266 **Error Conditions:**
7267
7268 An error occurs if:
7269
7270 -   The specified save game file cannot be created or written to.
7271 -   The `start` or `length` arguments are invalid (in partial save
7272     mode).
7273
7274 **Examples:**
7275
7276 ``` {.assembly}
7277 save  ; Saves the entire game state to a file
7278 save table_address, table_size, "my_table"  ; Saves a specific table to a file
7279 ```
7280
7281 **Use Cases:**
7282
7283 -   Allowing players to save their progress in the game.
7284 -   Implementing checkpoint or save-game functionality.
7285 -   Saving specific data structures or variables for later retrieval.
7286
7287 **Note:** The `SAVE` opcode is essential for providing save and
7288 restore functionality in Z-code games. The specific implementation and
7289 user interface for saving and loading games may vary depending on the
7290 interpreter.
7291
7292 ### SCREEN
7293
7294 **SCREEN** is an opcode that selects the active window for subsequent
7295 text output. Z-code programs can have multiple windows, each with its
7296 own properties and display area.
7297
7298 **Syntax:**
7299
7300 ``` {.assembly}
7301 screen window:int
7302 ```
7303
7304 **Functionality:**
7305
7306 The `screen` opcode sets the current window to the window specified by
7307 `window`. All subsequent text output, including printing strings and
7308 characters, will be directed to this window.
7309
7310 **Special Cases:**
7311
7312 -   If the `window` argument is omitted, the current window remains
7313     unchanged.
7314 -   Each window maintains its own cursor position and other
7315     attributes. When switching between windows, the cursor position
7316     and attributes of the previously active window are preserved.
7317
7318 **Error Conditions:**
7319
7320 An error occurs if `window` is not within the valid range (0 to 7).
7321
7322 **Examples:**
7323
7324 ``` {.assembly}
7325 screen 1  ; Switches to window 1 for output
7326 print "This text will appear in window 1."
7327 screen 0  ; Switches back to the main window (window 0)
7328 ```
7329
7330 **Use Cases:**
7331
7332 -   Managing multiple windows for displaying different types of
7333     information or creating a more complex user interface.
7334 -   Implementing split-screen displays or separate areas for text
7335     output.
7336
7337 **Note:** The `SCREEN` opcode is used to control which window receives
7338 text output. It is important to keep track of the current window and
7339 switch between windows as needed to ensure that text is displayed in
7340 the correct location.
7341
7342 ### SCROLL
7343
7344 **SCROLL** is an opcode that scrolls the contents of a window up or
7345 down by a specified number of lines. This can be used to create
7346 scrolling text displays or to shift the contents of a window.
7347
7348 **Syntax:**
7349
7350 ``` {.assembly}
7351 scroll window:int, lines:int
7352 ```
7353
7354 **Functionality:**
7355
7356 The `scroll` opcode scrolls the contents of the specified window
7357 (`window`) by the number of lines indicated by `lines`:
7358
7359 -   **Positive `lines`:** Scrolls the window contents up by `lines`
7360     lines. Blank lines are inserted at the bottom of the window,
7361     filled with the current background color.
7362 -   **Negative `lines`:** Scrolls the window contents down by the
7363     absolute value of `lines` lines. Lines at the top of the window
7364     are removed.
7365 -   **`lines` = 0:** Has no effect.
7366
7367 **Special Cases:**
7368
7369 -   The `scroll` opcode works on both scrolling and non-scrolling
7370     windows.
7371 -   The cursor position is not affected by scrolling.
7372
7373 **Error Conditions:**
7374
7375 An error occurs if:
7376
7377 -   `window` is not within the valid range (-3 to 7).
7378
7379 **Examples:**
7380
7381 ``` {.assembly}
7382 scroll 0, 1  ; Scrolls the main window (window 0) up by one line
7383 scroll 2, -3 ; Scrolls window 2 down by three lines
7384 ```
7385
7386 **Use Cases:**
7387
7388 -   Creating scrolling text displays, such as status messages or
7389     dialogue boxes.
7390 -   Shifting the contents of a window to make room for new output.
7391 -   Implementing custom scrolling behavior or animations.
7392
7393 **Note:** The `SCROLL` opcode provides a way to manipulate the
7394 contents of a window by scrolling it up or down. It is important to
7395 consider the window's scrolling attribute and the desired visual
7396 effect when using this opcode.
7397
7398 ### SET
7399
7400 **SET** is an opcode that assigns a value to a variable. It is used to
7401 modify the contents of variables and update the program state.
7402
7403 **Syntax:**
7404
7405 ``` {.assembly}
7406 set var, value
7407 ```
7408
7409 **Functionality:**
7410
7411 The `set` opcode assigns the specified `value` to the variable `var`.
7412 The type of `value` can be:
7413
7414 -   **Immediate value:** A constant value directly encoded within the
7415     instruction.
7416 -   **Variable:** A reference to another variable.
7417 -   **Other:** A value obtained from another instruction or
7418     expression.
7419
7420 **Special Cases:**
7421
7422 None.
7423
7424 **Error Conditions:**
7425
7426 None.
7427
7428 **Examples:**
7429
7430 ``` {.assembly}
7431 set counter, 0    ; Initializes the variable `counter` to 0
7432 set player_health, health_potion  ; Assigns the value of `health_potion` to `player_health`
7433 ```
7434
7435 **Use Cases:**
7436
7437 -   Initializing variables with specific values.
7438 -   Updating variables based on game logic or player actions.
7439 -   Assigning the results of calculations or expressions to variables.
7440
7441 **Note:** The `SET` opcode is a fundamental operation for modifying
7442 variables and managing the program state in Z-code programs.
7443
7444 ### SHIFT
7445
7446 **SHIFT** is an opcode that performs a logical shift on a 16-bit
7447 integer value. It shifts the bits of the operand to the left or right,
7448 depending on the specified shift amount.
7449
7450 **Syntax:**
7451
7452 ``` {.assembly}
7453 shift int, n > val
7454 ```
7455
7456 **Functionality:**
7457
7458 The `shift` opcode performs the following:
7459
7460 -   **Shifts the bits of `int`:**
7461     -   If `n` is positive, `int` is shifted left by `n` bits. Zeros
7462         are shifted into the least significant bits.
7463     -   If `n` is negative, `int` is shifted right by the absolute
7464         value of `n` bits. Zeros are shifted into the most significant
7465         bits.
7466 -   **Does not preserve the sign bit:** In a logical shift, the sign
7467     bit is not replicated during a right shift. This means that the
7468     sign of the number may change after the shift.
7469 -   **Stores the result:** The shifted value is stored in the
7470     specified destination (`val`). If no destination is provided, the
7471     result is pushed onto the game stack.
7472
7473 **Special Cases:**
7474
7475 -   If `n` is zero, the value of `int` remains unchanged.
7476 -   If the shift amount exceeds the word size (16 bits), the result is
7477     undefined.
7478
7479 **Error Conditions:**
7480
7481 None.
7482
7483 **Examples:**
7484
7485 ``` {.assembly}
7486 shift num, 2 > shifted  ; Shifts the value in `num` left by 2 bits, filling with zeros
7487 shift num, -1 > shifted ; Shifts the value in `num` right by 1 bit, filling with zeros
7488 ```
7489
7490 **Use Cases:**
7491
7492 -   Multiplying or dividing numbers by powers of two efficiently.
7493 -   Manipulating individual bits within a word.
7494 -   Implementing bitwise operations and algorithms.
7495
7496 **Note:** The `shift` opcode performs a logical shift, which does not
7497 preserve the sign of the operand. For an arithmetic shift, where the
7498 sign bit is replicated, use the `ashift` opcode.
7499
7500 ### SOUND
7501
7502 **SOUND** is an opcode that plays a sound effect. It allows Z-code
7503 programs to incorporate audio feedback and enhance the game
7504 experience.
7505
7506 **Syntax:**
7507
7508 ``` {.assembly}
7509 sound id:int, op:int [, volume:int, repeat:int]
7510 ```
7511
7512 **Functionality:**
7513
7514 The `sound` opcode performs sound operations based on the specified
7515 arguments:
7516
7517 -   **`id`:** The ID number of the sound effect to play.
7518 -   **`op`:** The sound operation to perform:
7519     -   **1:** Initialize the specified sound.
7520     -   **2:** Start playing the specified sound (default if `op` is
7521         omitted).
7522     -   **3:** Stop playing the specified sound.
7523     -   **4:** Clean up buffers associated with the specified sound.
7524 -   **`volume` (optional):** The volume level at which to play the
7525     sound. -1 indicates the default volume.
7526 -   **`repeat` (optional):** The number of times to repeat the sound.
7527     -1 indicates that the sound should repeat indefinitely until
7528     explicitly stopped.
7529
7530 **Special Cases:**
7531
7532 -   **`id` = 0:** Uses the last sound ID specified.
7533 -   **`id` = 1 or 2:** Plays a simple beep or boop sound, ignoring the
7534     `op` argument.
7535 -   The availability of sound effects and the range of volume levels
7536     depend on the interpreter and target machine capabilities.
7537
7538 **Error Conditions:**
7539
7540 An error occurs if:
7541
7542 -   The interpreter does not support sound effects.
7543 -   `id` is not a valid sound ID.
7544 -   `op` is not within the valid range (1-4).
7545 -   `volume` or `repeat` is invalid (if provided).
7546
7547 **Examples:**
7548
7549 ``` {.assembly}
7550 sound 10, 2  ; Starts playing sound effect with ID 10
7551 sound 0, 3   ; Stops playing the last sound effect
7552 sound 5, 2, 50, 3  ; Plays sound effect 5 three times at 50% volume
7553 ```
7554
7555 **Use Cases:**
7556
7557 -   Playing sound effects to provide feedback or enhance the game
7558     atmosphere.
7559 -   Creating audio cues for events or actions.
7560 -   Implementing music or background sounds.
7561
7562 **Note:** The `SOUND` opcode requires the interpreter to support sound
7563 effects. The `%FSOUN` flag in the `FLAGS` word and the `%XSOUN` bit in
7564 the `MODE` byte indicate whether sound operations are available.
7565
7566 ### SPLIT
7567
7568 **SPLIT** is an opcode that divides the screen vertically between
7569 windows 0 and 1. It is used to create a split-screen display, with
7570 each window showing different content.
7571
7572 **Syntax:**
7573
7574 ``` {.assembly}
7575 split height:int
7576 ```
7577
7578 **Functionality:**
7579
7580 The `split` opcode adjusts the vertical dimensions and positions of
7581 windows 0 and 1 as follows:
7582
7583 -   **Sets window 1 height:** The height of window 1 is set to the
7584     value of `height` in lines.
7585 -   **Sets window 1 position:** The top of window 1 is placed at the
7586     top of the screen (line 1).
7587 -   **Adjusts window 0 position:** The top of window 0 is moved down
7588     to the line following the bottom of window 1.
7589 -   **Adjusts window 0 height:** The height of window 0 is adjusted to
7590     fill the remaining space on the screen.
7591 -   **Selects window 0:** After splitting the screen, window 0 becomes
7592     the active window for output.
7593
7594 **Special Cases:**
7595
7596 -   **`height` = 0:** This effectively unsplits the screen, setting
7597     the height of window 1 to 0 and making window 0 occupy the entire
7598     screen.
7599
7600 **Error Conditions:**
7601
7602 None.
7603
7604 **Examples:**
7605
7606 ``` {.assembly}
7607 split 10  ; Splits the screen, giving window 1 a height of 10 lines
7608 split 0   ; Unsplits the screen
7609 ```
7610
7611 **Use Cases:**
7612
7613 -   Creating a split-screen display to show different information or
7614     perspectives simultaneously.
7615 -   Implementing status displays or separate areas for text output and
7616     input.
7617
7618 **Note:** The `SPLIT` opcode is a convenient way to create a
7619 split-screen display, but it only affects windows 0 and 1. For more
7620 flexible window management, consider using the `WINPOS` and `WINSIZE`
7621 opcodes.
7622
7623 ### SUB
7624
7625 **SUB** is an opcode that performs subtraction on two 16-bit word
7626 values. It subtracts the second operand from the first operand and
7627 returns the result.
7628
7629 **Syntax:**
7630
7631 ``` {.assembly}
7632 sub arg1:int, arg2:int > val
7633 ```
7634
7635 **Functionality:**
7636
7637 The `sub` opcode performs the following:
7638
7639 -   **Subtracts `arg2` from `arg1`:** Performs integer subtraction.
7640 -   **Stores the result:** The difference is stored in the specified
7641     destination (`val`). If no destination is provided, the result is
7642     pushed onto the game stack.
7643
7644 **Special Cases:**
7645
7646 -   If the result of the subtraction overflows the 16-bit word size,
7647     an error occurs.
7648
7649 **Error Conditions:**
7650
7651 An error occurs if the subtraction result overflows the 16-bit word
7652 range.
7653
7654 **Examples:**
7655
7656 ``` {.assembly}
7657 sub 10, 5 > result  ; Subtracts 5 from 10, stores the difference (5) in `result`
7658 ```
7659
7660 **Use Cases:**
7661
7662 -   Performing integer subtraction calculations.
7663 -   Decreasing values or calculating differences between numbers.
7664
7665 **Note:** The `sub` opcode performs signed integer subtraction. If the
7666 operands are unsigned, the programmer needs to handle potential
7667 overflow conditions.
7668
7669 ### THROW
7670
7671 **THROW** is an opcode that throws an exception and returns from a
7672 previously called function with a specified value. It is used in
7673 conjunction with the `CATCH` opcode to implement exception handling
7674 and non-local control flow.
7675
7676 **Syntax:**
7677
7678 ``` {.assembly}
7679 throw value, frame
7680 ```
7681
7682 **Functionality:**
7683
7684 The `throw` opcode performs the following:
7685
7686 -   **Sets return value:** The specified `value` is set as the return
7687     value of the function identified by the `frame` pointer.
7688 -   **Unwinds stack:** The interpreter unwinds the call stack,
7689     returning from all functions called since the function where the
7690     corresponding `CATCH` opcode was executed.
7691 -   **Resumes execution:** Control is transferred back to the
7692     instruction following the `CATCH` opcode in the function that
7693     caught the exception.
7694
7695 **Special Cases:**
7696
7697 -   The `frame` pointer must be a valid frame pointer obtained from a
7698     previous `CATCH` opcode.
7699 -   Throwing an exception to a frame that is no longer on the call
7700     stack results in an error.
7701
7702 **Error Conditions:**
7703
7704 An error occurs if:
7705
7706 -   `frame` is not a valid frame pointer.
7707 -   The frame pointed to by `frame` is no longer on the call stack.
7708
7709 **Examples:**
7710
7711 ``` {.assembly}
7712 catch > frame
7713 ; ... some code that might throw an exception ...
7714 throw "Error!", frame  ; Throws an exception and returns to the `catch` instruction
7715 ```
7716
7717 **Use Cases:**
7718
7719 -   Implementing exception handling to deal with errors or unexpected
7720     conditions.
7721 -   Performing non-local control flow, such as exiting multiple nested
7722     functions at once.
7723
7724 **Note:** The `THROW` and `CATCH` opcodes provide a mechanism for
7725 exception handling and non-local control flow in Z-code programs. They
7726 should be used with caution to avoid complex control flow and
7727 potential errors.
7728
7729 ### VALUE
7730
7731 **VALUE** is an opcode that retrieves the value of a variable and
7732 stores it in a specified destination. It is used to access the current
7733 value of a variable and use it in calculations or other operations.
7734
7735 **Syntax:**
7736
7737 ``` {.assembly}
7738 value var > val
7739 ```
7740
7741 **Functionality:**
7742
7743 The `value` opcode performs the following:
7744
7745 -   **Retrieves variable value:** Reads the value of the specified
7746     variable (`var`).
7747 -   **Stores the result:** The retrieved value is stored in the
7748     specified destination (`val`). If no destination is provided, the
7749     result is pushed onto the game stack.
7750
7751 **Special Cases:**
7752
7753 None.
7754
7755 **Error Conditions:**
7756
7757 None.
7758
7759 **Examples:**
7760
7761 ``` {.assembly}
7762 value score > current_score  ; Retrieves the value of `score` and stores it in `current_score`
7763 ```
7764
7765 **Use Cases:**
7766
7767 -   Accessing the current value of a variable for calculations or
7768     comparisons.
7769 -   Passing variable values as arguments to functions.
7770 -   Storing variable values in other variables or data structures.
7771
7772 **Note:** The `VALUE` opcode is a simple way to retrieve the value of
7773 a variable. It is equivalent to using the variable directly as an
7774 operand in most instructions.
7775
7776 ### VERIFY
7777
7778 **VERIFY** is an opcode that checks the integrity of the game file by
7779 comparing a calculated checksum with a stored checksum value. It is
7780 used to detect potential corruption or modifications of the game data.
7781
7782 **Syntax:**
7783
7784 ``` {.assembly}
7785 verify /pred
7786 ```
7787
7788 **Functionality:**
7789
7790 The `verify` opcode performs the following:
7791
7792 -   **Calculates checksum:** Computes a 16-bit checksum of the game
7793     file data from byte 64 to the end of the file (excluding the
7794     header).
7795 -   **Compares with stored checksum:** Compares the calculated
7796     checksum with the value stored in the `PCHKSM` word of the program
7797     header.
7798 -   **Evaluates predicate:** The predicate succeeds (evaluates to
7799     true) if the calculated checksum matches the stored checksum.
7800     Otherwise, the predicate fails (evaluates to false).
7801 -   **Conditional branch:** Based on the predicate result and the
7802     specified branch polarity (`/pred`), the interpreter may perform a
7803     conditional jump to a specified target.
7804
7805 **Special Cases:**
7806
7807 -   The checksum calculation excludes the first 64 bytes of the game
7808     file, which contain the program header.
7809 -   The `PLENTH` word in the program header specifies the length of
7810     the game file in units of 8 bytes.
7811
7812 **Error Conditions:**
7813
7814 None.
7815
7816 **Examples:**
7817
7818 ``` {.assembly}
7819 verify / handle_corruption  ; Branch to `handle_corruption` if the game file is corrupted
7820 ```
7821
7822 **Use Cases:**
7823
7824 -   Detecting unauthorized modifications or corruption of the game
7825     file.
7826 -   Implementing copy protection mechanisms.
7827 -   Ensuring data integrity before loading or saving games.
7828
7829 **Note:** The effectiveness of the `VERIFY` opcode depends on the
7830 strength of the checksum algorithm and the implementation of copy
7831 protection measures.
7832
7833 ### WINATTR
7834
7835 **WINATTR** is an opcode that modifies the attributes of a window.
7836 Window attributes control various aspects of the window's behavior,
7837 such as text wrapping, scrolling, and transcripting.
7838
7839 **Syntax:**
7840
7841 ``` {.assembly}
7842 winattr window:int, bits:int, operation:int
7843 ```
7844
7845 **Functionality:**
7846
7847 The `winattr` opcode modifies the attributes of the specified window
7848 (`window`) based on the `bits` and `operation` arguments:
7849
7850 -   **`bits`:** A bitmask where each bit represents a specific window
7851     attribute:
7852     -   Bit 0: Text wrapping (1 = enabled, 0 = disabled).
7853     -   Bit 1: Scrolling (1 = enabled, 0 = disabled).
7854     -   Bit 2: Transcripting (1 = enabled, 0 = disabled).
7855     -   Bit 3: Buffering (1 = enabled, 0 = disabled).
7856 -   **`operation`:** Specifies how to modify the attributes:
7857     -   **0 (MOVE):** Sets the window attributes to the values
7858         specified by `bits`.
7859     -   **1 (SET):** Sets the attributes corresponding to the bits
7860         that are set (1) in `bits`.
7861     -   **2 (CLEAR):** Clears the attributes corresponding to the bits
7862         that are set (1) in `bits`.
7863     -   **3 (COMP):** Toggles the attributes corresponding to the bits
7864         that are set (1) in `bits`.
7865
7866 **Special Cases:**
7867
7868 -   If the `operation` argument is omitted, it defaults to 0 (MOVE).
7869
7870 **Error Conditions:**
7871
7872 An error occurs if:
7873
7874 -   `window` is not within the valid range (-3 to 7).
7875 -   `operation` is not within the valid range (0-3).
7876
7877 **Examples:**
7878
7879 ``` {.assembly}
7880 winattr 1, 1, 1  ; Enables text wrapping for window 1
7881 winattr 2, 6, 2  ; Disables scrolling and transcripting for window 2
7882 ```
7883
7884 **Use Cases:**
7885
7886 -   Changing the behavior of windows based on game logic or player
7887     actions.
7888 -   Enabling or disabling text wrapping, scrolling, or transcripting
7889     for specific windows.
7890 -   Customizing the appearance and functionality of the game
7891     interface.
7892
7893 **Note:** The `WINATTR` opcode provides a flexible way to modify
7894 window attributes. It is important to understand the meaning of each
7895 bit in the `bits` argument and the effect of the different operations.
7896
7897 ### WINGET
7898
7899 **WINGET** is an opcode that retrieves the value of a specific
7900 property from a window's property table. Window properties store
7901 information about the window's position, size, attributes, and other
7902 characteristics.
7903
7904 **Syntax:**
7905
7906 ``` {.assembly}
7907 winget window:int, property:int > val
7908 ```
7909
7910 **Functionality:**
7911
7912 The `winget` opcode retrieves the value of the property specified by
7913 `property` from the property table of the window identified by
7914 `window`:
7915
7916 -   **`window`:** The number of the window to access.
7917 -   **`property`:** The number of the property to retrieve. Valid
7918     property numbers and their corresponding meanings are:
7919     -   0: `WTOP` - Y position of the window (top edge, in screen
7920         units).
7921     -   1: `WLEFT` - X position of the window (left edge, in screen
7922         units).
7923     -   2: `WHIGH` - Height of the window in screen units.
7924     -   3: `WWIDE` - Width of the window in screen units.
7925     -   4: `WYPOS` - Y coordinate of the cursor within the window (row
7926         number, 1-based).
7927     -   5: `WXPOS` - X coordinate of the cursor within the window
7928         (column number, 1-based).
7929     -   6: `WLMARG` - Left margin of the window in pixels.
7930     -   7: `WRMARG` - Right margin of the window in pixels.
7931     -   8: `WCRFCN` - Function to call for carriage return interrupts.
7932     -   9: `WCRCNT` - Counter for carriage return interrupts.
7933     -   10: `WHLIGHT` - Highlighting mode of the window.
7934     -   11: `WCOLOR` - Color word of the window (background and
7935         foreground colors).
7936     -   12: `WFONT` - Font ID used in the window.
7937     -   13: `WFSIZE` - Font size (height and width) used in the
7938         window.
7939     -   14: `WATTRS` - Window attributes (wrapping, scrolling,
7940         transcripting, buffering).
7941     -   15: `WLCNT` - Line counter for the window.
7942 -   **Stores the result:** The retrieved property value is stored in
7943     the specified destination (`val`). If no destination is provided,
7944     the result is pushed onto the game stack.
7945
7946 **Special Cases:**
7947
7948 -   If the `window` argument is omitted, the current window is used.
7949
7950 **Error Conditions:**
7951
7952 An error occurs if:
7953
7954 -   `window` is not within the valid range (-3 to 7).
7955 -   `property` is not a valid property number.
7956
7957 **Examples:**
7958
7959 ``` {.assembly}
7960 winget 0, 2 > window_height  ; Retrieves the height of the main window (window 0)
7961 winget 1, 14 > window_attrs  ; Retrieves the attributes of window 1
7962 ```
7963
7964 **Use Cases:**
7965
7966 -   Accessing information about window properties, such as position,
7967     size, or attributes.
7968 -   Implementing custom window management or display routines.
7969 -   Checking the state of specific window features.
7970
7971 **Note:** The `WINGET` opcode provides a flexible way to access
7972 various window properties. It is important to use the correct property
7973 numbers to retrieve the desired information.
7974
7975 ### WINPOS
7976
7977 **WINPOS** is an opcode that sets the position of a window on the
7978 screen. It allows for precise control over the location of windows
7979 within the display area.
7980
7981 **Syntax:**
7982
7983 ``` {.assembly}
7984 winpos window:int, y:int, x:int
7985 ```
7986
7987 **Functionality:**
7988
7989 The `winpos` opcode sets the position of the specified window
7990 (`window`) to the coordinates (`y`, `x`):
7991
7992 -   **`window`:** The number of the window to reposition.
7993 -   **`y`:** The Y coordinate of the top-left corner of the window
7994     (row number, 1-based).
7995 -   **`x`:** The X coordinate of the top-left corner of the window
7996     (column number, 1-based).
7997
7998 The coordinates are specified in screen units, with the top-left
7999 corner of the screen being (1, 1).
8000
8001 **Special Cases:**
8002
8003 -   If the `window` argument is omitted, the current window is
8004     repositioned.
8005 -   The opcode does not check if the new window position would place
8006     the window partially or completely off-screen.
8007
8008 **Error Conditions:**
8009
8010 An error occurs if:
8011
8012 -   `window` is not within the valid range (-3 to 7).
8013 -   `y` or `x` is negative.
8014
8015 **Examples:**
8016
8017 ``` {.assembly}
8018 winpos 1, 5, 10  ; Positions window 1 at row 5, column 10
8019 winpos 2, 1, 1   ; Positions window 2 at the top-left corner of the screen
8020 ```
8021
8022 **Use Cases:**
8023
8024 -   Positioning windows for optimal layout and user interface design.
8025 -   Creating overlapping windows or dynamic window arrangements.
8026 -   Implementing custom window management or animation routines.
8027
8028 **Note:** The `WINPOS` opcode provides direct control over window
8029 positioning. It is important to consider the window's size and the
8030 overall screen layout when using this opcode.
8031
8032 ### WINPUT
8033
8034 **WINPUT** is an opcode that sets the value of a specific property
8035 within a window's property table. It allows for modifying various
8036 aspects of a window's behavior and appearance.
8037
8038 **Syntax:**
8039
8040 ``` {.assembly}
8041 winput window:int, property:int, value
8042 ```
8043
8044 **Functionality:**
8045
8046 The `winput` opcode sets the value of the property specified by
8047 `property` in the property table of the window identified by `window`:
8048
8049 -   **`window`:** The number of the window to modify.
8050 -   **`property`:** The number of the property to set. See the
8051     description of `WINGET` for a list of valid property numbers and
8052     their meanings.
8053 -   **`value`:** The new value to assign to the property.
8054
8055 **Special Cases:**
8056
8057 -   Not all window properties are writable using `WINPUT`. Some
8058     properties, such as window size and position, require specific
8059     opcodes like `WINSIZE` and `WINPOS` for modification.
8060 -   If the `window` argument is omitted, the current window is used.
8061
8062 **Error Conditions:**
8063
8064 An error occurs if:
8065
8066 -   `window` is not within the valid range (-3 to 7).
8067 -   `property` is not a valid property number or is not writable.
8068
8069 **Examples:**
8070
8071 ``` {.assembly}
8072 winput 1, 10, 2  ; Sets the highlighting mode of window 1 to bold
8073 winput 2, 6, 15  ; Sets the left margin of window 2 to 15 pixels
8074 ```
8075
8076 **Use Cases:**
8077
8078 -   Modifying window properties to change their behavior or
8079     appearance.
8080 -   Setting the highlighting mode, color, or font of a window.
8081 -   Adjusting margins or other window settings.
8082
8083 **Note:** The `WINPUT` opcode provides a way to modify window
8084 properties, but it is important to check which properties are writable
8085 and use the appropriate opcodes for those that are not.
8086
8087 ### WINSIZE
8088
8089 **WINSIZE** is an opcode that sets the size of a window on the screen.
8090 It allows for controlling the dimensions of windows and adjusting the
8091 display area they occupy.
8092
8093 **Syntax:**
8094
8095 ``` {.assembly}
8096 winsize window:int, height:int, width:int
8097 ```
8098
8099 **Functionality:**
8100
8101 The `winsize` opcode sets the size of the specified window (`window`)
8102 to the given dimensions:
8103
8104 -   **`window`:** The number of the window to resize.
8105 -   **`height`:** The new height of the window in screen units (number
8106     of lines).
8107 -   **`width`:** The new width of the window in screen units (number
8108     of characters).
8109
8110 If the new size would cause the window to extend beyond the screen
8111 boundaries, the dimensions are adjusted to fit within the available
8112 space.
8113
8114 **Special Cases:**
8115
8116 -   If the `window` argument is omitted, the current window is
8117     resized.
8118 -   If the new size is smaller than the current cursor position, the
8119     cursor is moved to the bottom-right corner of the resized window.
8120
8121 **Error Conditions:**
8122
8123 An error occurs if:
8124
8125 -   `window` is not within the valid range (-3 to 7).
8126 -   `height` or `width` is zero or negative.
8127
8128 **Examples:**
8129
8130 ``` {.assembly}
8131 winsize 1, 10, 40  ; Sets the size of window 1 to 10 lines by 40 characters
8132 winsize 2, 25, 80  ; Sets the size of window 2 to 25 lines by 80 characters (full screen width)
8133 ```
8134
8135 **Use Cases:**
8136
8137 -   Adjusting the size of windows to fit content or accommodate
8138     different display requirements.
8139 -   Creating windows with specific dimensions for menus, dialog boxes,
8140     or other UI elements.
8141 -   Implementing dynamic window resizing or animations.
8142
8143 **Note:** The `WINSIZE` opcode provides direct control over window
8144 size. It is important to consider the window's position and the
8145 overall screen layout when using this opcode.
8146
8147 ### XCALL
8148
8149 **XCALL** is an opcode that calls a function with a variable number of
8150 arguments and returns a value. It is the most general form of the
8151 `CALL` instruction, allowing for up to seven arguments to be passed to
8152 the function.
8153
8154 **Syntax:**
8155
8156 ``` {.assembly}
8157 xcall fcn, arg1:any [, arg2:any ...] > val
8158 ```
8159
8160 **Functionality:**
8161
8162 The `xcall` opcode performs the following:
8163
8164 -   **Pushes arguments onto the stack:** Pushes the variable number of
8165     arguments (`arg1`, `arg2`, etc.) onto the game stack. The number
8166     of arguments is determined by the operand types specified in the
8167     instruction.
8168 -   **Calls the function:** Transfers control to the function
8169     specified by `fcn`. The function address is calculated by shifting
8170     `fcn` left by two bits and adding the function offset (`FOFF`)
8171     shifted left by three bits.
8172 -   **Retrieves return value:** When the function returns, its return
8173     value is retrieved and stored in the specified destination
8174     (`val`). If no destination is provided, the value is pushed onto
8175     the game stack.
8176
8177 **Special Cases:**
8178
8179 -   If `fcn` is zero, the `xcall` opcode acts as if it called a
8180     function that immediately returned false.
8181
8182 **Error Conditions:**
8183
8184 An error occurs if `fcn` is not a valid function pointer.
8185
8186 **Examples:**
8187
8188 ``` {.assembly}
8189 xcall format_string, buffer, arg1, arg2, arg3 > formatted_text  ; Calls the `format_string` function with four arguments
8190 ```
8191
8192 **Use Cases:**
8193
8194 -   Calling functions with a variable number of arguments.
8195 -   Implementing functions that take a flexible number of parameters.
8196
8197 **Note:** The `XCALL` opcode is generated by the compiler when it
8198 detects a function call with more than two arguments or when the
8199 argument types require the extended format. It is not typically used
8200 directly by programmers.
8201
8202 ### XPUSH
8203
8204 **XPUSH** is an opcode that attempts to push a value onto a stack and
8205 acts as a predicate based on the success of the operation. It can be
8206 used with both the game stack and user-defined stacks.
8207
8208 **Syntax:**
8209
8210 ``` {.assembly}
8211 xpush value, stack:tbl /pred
8212 ```
8213
8214 **Functionality:**
8215
8216 The `xpush` opcode performs the following:
8217
8218 -   **Checks stack space:** Determines if there is enough space
8219     available on the specified stack (`stack`) to push the value.
8220 -   **Pushes value (if space available):** If there is sufficient
8221     space, the opcode pushes the `value` onto the top of the stack.
8222 -   **Evaluates predicate:** The predicate succeeds (evaluates to
8223     true) if the value was successfully pushed onto the stack.
8224     Otherwise, the predicate fails (evaluates to false).
8225 -   **Conditional branch:** Based on the predicate result and the
8226     specified branch polarity (`/pred`), the interpreter may perform a
8227     conditional jump to a specified target.
8228
8229 **Special Cases:**
8230
8231 -   If the `stack` argument is omitted, the opcode operates on the
8232     game stack.
8233
8234 **Error Conditions:**
8235
8236 An error occurs if `stack` is not a valid table pointer (if provided).
8237
8238 **Examples:**
8239
8240 ``` {.assembly}
8241 xpush item, inventory / inventory_full  ; Attempts to push `item` onto the `inventory` stack
8242 ; ... code to handle full inventory ...
8243 inventory_full:
8244 ```
8245
8246 **Use Cases:**
8247
8248 -   Pushing values onto stacks while checking for potential stack
8249     overflow conditions.
8250 -   Implementing stack-based data structures with overflow handling.
8251
8252 **Note:** The `XPUSH` opcode provides a way to push values onto stacks
8253 while simultaneously checking for available space. This can be useful
8254 for preventing stack overflow errors and implementing robust stack
8255 management.
8256
8257 ### ZERO?
8258
8259 **ZERO?** is an opcode that checks whether a value is equal to zero.
8260 It acts as a predicate, meaning it evaluates a condition and
8261 implicitly performs a conditional branch based on the result.
8262
8263 **Syntax:**
8264
8265 ``` {.assembly}
8266 zero? arg:any /pred
8267 ```
8268
8269 **Functionality:**
8270
8271 The `zero?` opcode performs the following:
8272
8273 -   **Checks for zero:** Determines if the value of `arg` is equal to
8274     zero.
8275 -   **Evaluates predicate:** The predicate succeeds (evaluates to
8276     true) if `arg` is indeed zero. Otherwise, the predicate fails
8277     (evaluates to false).
8278 -   **Conditional branch:** Based on the predicate result and the
8279     specified branch polarity (`/pred`), the interpreter may perform a
8280     conditional jump to a specified target.
8281
8282 **Special Cases:**
8283
8284 None.
8285
8286 **Error Conditions:**
8287
8288 None.
8289
8290 **Examples:**
8291
8292 ``` {.assembly}
8293 zero? counter / end_loop  ; Branch to `end_loop` if `counter` is zero
8294 ```
8295
8296 **Use Cases:**
8297
8298 -   Implementing conditional logic based on zero checks.
8299 -   Determining if a variable or expression has a value of zero.
8300 -   Loop termination conditions.
8301
8302 **Note:** The `ZERO?` opcode is a simple but useful predicate for
8303 checking for zero values and implementing conditional behavior in
8304 Z-code programs.
8305
8306 ### ZWSTR
8307
8308 **ZWSTR** is an opcode that converts a word from an input buffer into
8309 a Z-string and stores it in a specified location. Z-strings are the
8310 standard format for representing text in Z-code programs.
8311
8312 **Syntax:**
8313
8314 ``` {.assembly}
8315 zwstr inbuf:tbl, inlen:int, inbeg:int, zword:tbl
8316 ```
8317
8318 **Functionality:**
8319
8320 The `zwstr` opcode performs the following:
8321
8322 -   **Reads input word:** Extracts the word starting at the byte
8323     offset `inbeg` within the input buffer `inbuf`. The `inlen`
8324     argument specifies the length of the word in bytes, but it is not
8325     strictly necessary as the opcode assumes the word is terminated by
8326     a break character (whitespace or a self-inserting break
8327     character).
8328 -   **Converts to Z-string:** Encodes the extracted word into a
8329     Z-string using the current character set and frequent words table.
8330 -   **Stores the result:** The encoded Z-string is stored in the first
8331     three words of the `zword` table.
8332
8333 **Special Cases:**
8334
8335 -   The `inbuf` argument is typically a pointer to the text buffer
8336     used by the `READ` or `LEX` opcodes.
8337 -   The `zword` table must have at least three words of available
8338     space to store the Z-string.
8339
8340 **Error Conditions:**
8341
8342 An error occurs if:
8343
8344 -   `inbuf` or `zword` is not a valid table pointer.
8345 -   `inbeg` is outside the bounds of the `inbuf` table.
8346 -   The `zword` table does not have enough space to store the
8347     Z-string.
8348
8349 **Examples:**
8350
8351 ``` {.assembly}
8352 read input_buffer, lexv
8353 zwstr input_buffer, 0, lexv[1].offset, word_buffer  ; Converts the second word from the parsed input into a Z-string
8354 ```
8355
8356 **Use Cases:**
8357
8358 -   Converting words from input buffers into Z-strings for further
8359     processing or comparison.
8360 -   Implementing custom parsing or text manipulation routines.
8361
8362 **Note:** The `ZWSTR` opcode is used to convert words from input
8363 buffers into the Z-string format used by the Z-machine. It is
8364 typically used in conjunction with the `READ` or `LEX` opcodes for
8365 processing player input.
8366
8367 Chapter 3.2: Opcode Summary Table
8368 ---------------------------------
8369
8370   --------------------------------------------------------------------------------------
8371   Opcode   Name          Operands        Type   Description
8372   -------- ------------- --------------- ------ ----------------------------------------
8373   1        EQUAL?        arg1:any,       2OP    Is arg1 equal to any one of arg2, arg3,
8374                          arg2:any               or arg4? Note that in the extended form,
8375                                                 EQUAL? can take more than two operands.
8376
8377   2        LESS?         arg1:int,       2OP    Is arg1 less than arg2?
8378                          arg2:int
8379
8380   3        GRTR?         arg1:int,       2OP    Is arg1 greater than arg2?
8381                          arg2:int
8382
8383   4        DLESS?        var, int        2OP    Decrements var and succeeds if new value
8384                                                 is less than int.
8385
8386   5        IGRTR?        var, int        2OP    Increments var and succeeds if new value
8387                                                 is greater than int.
8388
8389   6        IN?           child:obj,      2OP    Is child contained in parent?
8390                          parent:obj
8391
8392   7        BTST          arg1:word,      2OP    Are bits on in arg2 also on in arg1?
8393                          arg2:word
8394
8395   8        BOR           arg1:word,      2OP    Bitwise logical OR.
8396                          arg2:word
8397
8398   9        BAND          arg1:word,      2OP    Bitwise logical AND.
8399                          arg2:word
8400
8401   10       FSET?         obj, flag       2OP    Is flag number set in obj?
8402
8403   11       FSET          obj, flag       2OP    Sets flag in obj.
8404
8405   12       FCLEAR        obj, flag       2OP    Clears flag in obj.
8406
8407   13       SET           var, any        2OP    Sets variable to any.
8408
8409   14       MOVE          thing:obj,      2OP    Puts thing into dest as the first
8410                          dest:obj               object.
8411
8412   15       GET           table, item     2OP    Returns item'th element of table
8413                                                 (word-oriented).
8414
8415   16       GETB          table, item     2OP    Returns item'th element of table
8416                                                 (byte-oriented).
8417
8418   17       GETP          obj, prop       2OP    Returns prop property of obj.
8419
8420   18       GETPT         obj, prop       2OP    Returns pointer to property table prop
8421                                                 from obj.
8422
8423   19       NEXTP         obj, prop       2OP    Returns number of the property following
8424                                                 prop in obj.
8425
8426   20       ADD           arg1:int,       2OP    Adds the integers.
8427                          arg2:int
8428
8429   21       SUB           arg1:int,       2OP    Subtracts arg2 from arg1.
8430                          arg2:int
8431
8432   22       MUL           arg1:int,       2OP    Multiplies the integers.
8433                          arg2:int
8434
8435   23       DIV           arg1:int,       2OP    Divides arg1 by arg2, returning the
8436                          arg2:int               truncated quotient.
8437
8438   24       MOD           arg1:int,       2OP    Divides arg1 by arg2, returning the
8439                          arg2:int               remainder.
8440
8441   25       CALL2         fcn, any        2OP    Calls the function pointed to by fcn.
8442
8443   26       ICALL2        routine:fcn,    2OP    Calls the function pointed to by fcn (no
8444                          arg1:any               return value).
8445
8446   27       COLOR         fore:int,       2OP    Sets foreground and background color.
8447                          back:int
8448
8449   28       THROW         any, frame      2OP    Returns any from a frame (see CATCH).
8450
8451   128      ZERO?         arg:any         1OP    Is arg equal to zero?
8452
8453   129      NEXT?         obj             1OP    Returns the "next" slot of obj (fails if
8454                                                 none).
8455
8456   130      FIRST?        obj             1OP    Returns the "first" slot of obj (fails
8457                                                 if none).
8458
8459   131      LOC           obj             1OP    Returns the "parent" of obj (zero if
8460                                                 none).
8461
8462   132      PTSIZE        table           1OP    Returns length of property table in
8463                                                 bytes.
8464
8465   133      INC           var             1OP    Increments the value of var by one.
8466
8467   134      DEC           var             1OP    Decrements the value of var by one.
8468
8469   135      PRINTB        str             1OP    Prints the string pointed to by str
8470                                                 (byte pointer).
8471
8472   136      CALL1         fcn             1OP    Calls the function pointed to by fcn.
8473
8474   137      REMOVE        obj             1OP    Removes obj from the object tree.
8475
8476   138      PRINTD        obj             1OP    Prints the short description of obj.
8477
8478   139      RETURN        any             1OP    Returns from the most recently executed
8479                                                 call.
8480
8481   140      JUMP          loc             1OP    Unconditional relative branch.
8482
8483   141      PRINT         str             1OP    Prints the string pointed to by str
8484                                                 (quad pointer).
8485
8486   142      VALUE         var             1OP    Returns the value of var.
8487
8488   143      ICALL1        routine:fcn     1OP    Calls the function pointed to by fcn (no
8489                                                 return value).
8490
8491   176      RTRUE                         0OP    Returns 1 (true).
8492
8493   177      RFALSE                        0OP    Returns 0 (false).
8494
8495   178      PRINTI        (in-line        0OP    Prints an immediate string.
8496                          string)
8497
8498   179      PRINTR        (in-line        0OP    Prints an immediate string and executes
8499                          string)                CRLF + RTRUE.
8500
8501   180      NOOP                          0OP    No operation.
8502
8503   183      RESTART                       0OP    Reinitializes the game.
8504
8505   184      RSTACK                        0OP    Returns from a call and takes value from
8506                                                 stack.
8507
8508   185      CATCH                         0OP    Returns a pointer to the current call
8509                                                 frame.
8510
8511   186      QUIT                          0OP    Terminates the game.
8512
8513   187      CRLF                          0OP    Prints an end-of-line sequence.
8514
8515   188                                           (Unused)
8516
8517   189      VERIFY                        0OP    Verifies the game program on disk.
8518
8519   190      EXTOP         opcode:int      0OP    Signals the next opcode is an extended
8520                                                 opcode.
8521
8522   191      ORIGINAL?                     0OP    Returns non-false if the game disk is
8523                                                 the original.
8524
8525   193      EQUAL?        arg1:any,       EXT    Is arg1 equal to any of the other
8526                          arg2:any, ...          arguments?
8527
8528   224      CALL          fcn, any1,      EXT    Calls the function pointed to by fcn.
8529                          any2, any3
8530
8531   225      PUT           table, item,    EXT    Sets the word pointed to in table to
8532                          any                    any.
8533
8534   226      PUTB          table, item,    EXT    Sets the byte pointed to in table to the
8535                          any                    low byte of any.
8536
8537   227      PUTP          obj, prop, any  EXT    Changes the value of obj's property prop
8538                                                 to any.
8539
8540   228      READ          inbuf:tbl,      EXT    Reads a line of input and parses it.
8541                          lexv:tbl,
8542                          time:int,
8543                          handler:fcn
8544
8545   229      PRINTC        int             EXT    Prints the character whose ASCII value
8546                                                 is int.
8547
8548   230      PRINTN        int             EXT    Prints int as a signed number.
8549
8550   231      RANDOM        arg:int         EXT    Returns a random value between 1 and
8551                                                 arg.
8552
8553   232      PUSH          value           EXT    Pushes value onto the game stack.
8554
8555   233      POP           stack           EXT    Pops a value from the stack.
8556
8557   234      SPLIT         height:int      EXT    Splits the screen vertically between
8558                                                 windows 0 and 1.
8559
8560   235      SCREEN        window:int      EXT    Selects the specified window for output.
8561
8562   236      XCALL         fcn, any1, ..., EXT    Calls the function pointed to by fcn (up
8563                          any7                   to 7 args).
8564
8565   237      CLEAR         window:int      EXT    Clears the specified window.
8566
8567   238      ERASE         int             EXT    Erases a portion of the current line.
8568
8569   239      CURSET        y:int, x:int,   EXT    Sets the cursor position in the
8570                          window                 specified window.
8571
8572   240      CURGET        output:tbl      EXT    Returns information about the current
8573                                                 cursor position.
8574
8575   241      HLIGHT        int             EXT    Sets the display highlighting mode.
8576
8577   242      BUFOUT        int             EXT    Controls output buffering.
8578
8579   243      DIROUT        device:int,     EXT    Selects or deselects a virtual output
8580                          any1, any2,            device.
8581                          any3
8582
8583   244      DIRIN         device:int,     EXT    Selects or deselects a virtual input
8584                          any1, any2,            device.
8585                          any3
8586
8587   245      SOUND         id:int, op:int, EXT    Produces a sound.
8588                          volume:int,
8589                          repeat:int
8590
8591   246      INPUT         dev:int,        EXT    Returns a single byte from the specified
8592                          time:int,              device.
8593                          handler:fcn
8594
8595   247      INTBL?        item, tbl,      EXT    Searches for a record in a table.
8596                          len:int,
8597                          recspec:int
8598
8599   248      BCOM          arg:word        1OP    Performs a bitwise logical NOT
8600                                                 (complement) on the word.
8601
8602   249      ICALL         routine:fcn,    EXT    Calls the function pointed to by fcn (no
8603                          arg1:any,              return value).
8604                          arg2:any,
8605                          arg3:any
8606
8607   250      IXCALL        routine:fcn,    EXT    Calls the function pointed to by fcn
8608                          arg1,...               (variable args, no return value).
8609
8610   251      LEX           inbuf:tbl,      EXT    Tokenizes and looks up an input buffer's
8611                          lexv:tbl,              contents.
8612                          lexicon:tbl,
8613                          preserve:bool
8614
8615   252      ZWSTR         inbuf:tbl,      EXT    Converts a word to a Z-string.
8616                          inlen:int,
8617                          inbeg:int,
8618                          zword:tbl
8619
8620   253      COPYT         source:tbl,     EXT    Copies bytes from source to dest.
8621                          dest:tbl,
8622                          length:int
8623
8624   254      PRINTT        bytes:tbl,      EXT    Prints a block of text from a table.
8625                          width:int,
8626                          height:int,
8627                          skip:int
8628
8629   255      ASSIGNED?     opt:var         EXT    Checks if an optional argument was
8630                                                 supplied.
8631
8632   256      SAVE          start:tbl,      EXT    Saves a section of the game state.
8633                          length:int,
8634                          name:tbl
8635
8636   257      RESTORE       start:tbl,      EXT    Restores a section of the game state.
8637                          length:int,
8638                          name:tbl
8639
8640   258      SHIFT         int, n          EXT    Performs a logical shift on int.
8641
8642   259      ASHIFT        int, n          EXT    Performs an arithmetic shift on int.
8643
8644   260      FONT          font:int,       EXT    Selects a font for the specified window.
8645                          window
8646
8647   261      DISPLAY       picture:int,    EXT    Displays a picture at the specified
8648                          y:int, x:int           location.
8649
8650   262      PICINF        picture:int,    EXT    Returns information about a picture.
8651                          data:tbl
8652
8653   263      DCLEAR        picture:int,    EXT    Clears the area occupied by a picture.
8654                          y:int, x:int
8655
8656   264      MARGIN        left:int,       EXT    Sets the left and right margins for a
8657                          right:int,             window.
8658                          window
8659
8660   265      ISAVE                         EXT    Saves the game state to a reserved area
8661                                                 in RAM.
8662
8663   266      IRESTORE                      EXT    Restores the game state from the
8664                                                 reserved area in RAM.
8665
8666   272      WINPOS        window:int, y,  EXT    Sets the location of the top left corner
8667                          x                      of a window.
8668
8669   273      WINSIZE       window, y, x    EXT    Sets the size of a window.
8670
8671   274      WINATTR       window, bits,   EXT    Sets characteristics of a window.
8672                          operation
8673
8674   275      WINGET        window, offset  EXT    Returns the value of a window property.
8675
8676   276      SCROLL        window, lines   EXT    Scrolls the specified window up or down.
8677
8678   277      FSTACK        n, stack        EXT    Flushes n elements from the specified
8679                                                 stack.
8680
8681   278      MOUSE-INFO    table           EXT    Returns information about the mouse
8682                                                 status.
8683
8684   279      MOUSE-LIMIT   window          EXT    Restricts the mouse to a specific
8685                                                 window.
8686
8687   280      XPUSH         value, stack    EXT    Pushes value onto the specified stack.
8688
8689   281      WINPUT        window, offset, EXT    Sets the value of a window property.
8690                          value
8691
8692   282      PRINTF        tbl             EXT    Prints a formatted table.
8693
8694   283      MENU          id, tbl         EXT    Adds a menu to the menu bar.
8695
8696   284      PICSET        tbl             EXT    A table of picture numbers to pre-load 
8697                                                 or cache for faster display. Pictures not
8698                                                 included in the most recent PICSET call are
8699                                                 no longer considered "hot" and can be safely
8700                                                 removed from the cache.
8701   --------------------------------------------------------------------------------------