From: Jason Self Date: Sun, 7 Apr 2024 17:28:34 +0000 (-0700) Subject: Add initial work for zap documentation X-Git-Url: https://jxself.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=zap-docs.git Add initial work for zap documentation --- 1180286e03ae208dcd30a3a181e32a1446ebe73b diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/zap b/zap new file mode 100644 index 0000000..e3087b9 --- /dev/null +++ b/zap @@ -0,0 +1,8701 @@ +Copyright & Licensing +--------------------- + +Copyright (C) 2024 Jason Self + +You can redistribute and/or modify this file under the terms of the +GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any +later version. + +This file is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file. If not, see . + +Chapter 1.1: Overview of ZAP and its Purpose +-------------------------------------------- + +ZAP (Z-language Assembly Program) is a software tool used to translate +assembly language code written for the Z-machine into a binary format +that can be directly executed by a compatible Z-language Interpreter +Program (ZIP). + +The Z-machine is a virtual machine specifically designed for running +interactive fiction games, also known as text adventures. Infocom +originally developed the Z-machine and its associated programming +language, ZIL (Zork Implementation Language) but now these belong to +the community. + +ZAP is the last stage of the toolchain, after the source code has been +compiled into a a human-readable assembly language format. This +assembly language is then processed by ZAP, which converts it into the +binary format understood by the Z-machine. + +ZAP is a two-pass assembler, meaning it processes the input file +twice. In the first pass, it analyzes the code, builds symbol tables, +and calculates addresses. In the second pass, it generates the binary +code and resolves any forward references to symbols. + +This specification document provides a detailed explanation of ZAP's +functionality, including the supported assembly language syntax, data +structures, algorithms, and error handling mechanisms. It serves as a +guide for understanding and implementing ZAP. + +ZAP is an integral component of the development system for interactive +fiction games. It bridges the gap between the high-level ZIL (Zork +Implementation Language) and the low-level Z-code that runs on the +Z-machine. Here's how ZAP fits into the overall development process: + +1. **Game Design and Implementation:** Game designers and programmers + use a high-level language (the Zork Implementation Language, or + ZIL) to define the game's world, objects, characters, and + interactions. ZIL provides a more abstract and convenient way to + express the game's logic compared to directly writing Z-code + instructions. +2. **ZIL Compilation:** The ZIL code is compiled into Z-code assembly + language. This assembly language represents the Z-code + instructions and data in a human-readable format. +3. **ZAP Assembly:** ZAP takes the Z-code assembly language as input + and translates it into the binary format understood by the + Z-machine. This binary code is what ultimately gets executed by + the ZIP interpreter. + +Chapter 1.2: Goals and Design Principles of ZAP +----------------------------------------------- + +ZAP was designed with several key goals and principles in mind: + +**Goals:** + +- **Provide a convenient and efficient way to write Z-code + programs:** ZAP's assembly language allows programmers to express + Z-code instructions and data in a more readable and structured + format compared to directly writing binary code. +- **Generate optimized and efficient Z-code:** ZAP optimizes the + generated code for efficient execution on the Z-machine, ensuring + smooth gameplay and minimizing memory usage. +- **Support debugging and troubleshooting:** ZAP can generate + optional listing files that provide insights into the generated + code, aiding in debugging and identifying issues. +- **Maintain portability across different platforms:** ZAP itself is + designed to be portable and run on various machines, allowing for + cross-platform development. + +**Design Principles:** + +- **Simplicity and clarity:** ZAP's assembly language syntax is + designed to be straightforward and easy to understand, minimizing + the learning curve for programmers. +- **Efficiency:** ZAP optimizes the generated code for efficient + execution on the Z-machine, taking advantage of the architecture's + features. +- **Flexibility:** ZAP provides various directives and options to + give programmers control over the assembly process and allow for + customization. +- **Error detection and reporting:** ZAP incorporates robust error + detection mechanisms and provides informative error messages to + help programmers identify and fix issues. +- **Modularity:** ZAP is organized into well-defined modules, each + responsible for specific tasks, promoting code maintainability and + extensibility. + +These goals and design principles have guided the development of ZAP +and continue to be relevant in understanding its functionality and +behavior. By adhering to these principles, ZAP provides a powerful and +efficient tool for assembling Z-code programs for interactive fiction +games. + +Chapter 1.3: Target Audience for the Specification +-------------------------------------------------- + +This specification document is primarily intended for the following +audiences: + +- **Z-machine enthusiasts and researchers:** The specification + offers detailed insights into the Z-code assembly language, ZAP's + internal workings, and the overall structure of Z-machine + programs. This information can be valuable for individuals + interested in understanding the Z-machine architecture and its + associated tools. +- **Interactive fiction developers:** Understanding ZAP's + functionality and the Z-code it generates can be beneficial for + game designers and programmers. + +The document assumes a basic understanding of assembly language +concepts and the Z-machine architecture. However, it provides +sufficient detail and explanations to be accessible to individuals +with a general interest in interactive fiction and the technical +aspects of the Z-machine. + +By catering to these different audiences, the specification aims to +contribute to the understanding of the Z-machine, and support the +continued development of interactive fiction games. + +Chapter 2.1: Character Set and Lexical Elements +----------------------------------------------- + +The Z-code assembly language used by ZAP consists of a defined +character set and specific lexical elements that form the building +blocks of instructions and directives. + +**Character Set:** + +The following characters are allowed in a ZAP program: + +- **Letters:** A-Z (case-insensitive) +- **Digits:** 0-9 +- **Special characters:** , ? \# . - \_ ' \" /  : ( ) +- **Whitespace:** Space and tab characters are ignored except as + operand prefixes. +- **Line endings:** Carriage return (`\r`), line feed (``), and form + feed (`\f`) characters are ignored. + +**Lexical Elements:** + +ZAP recognizes the following lexical elements: + +- **Symbols:** Used to represent values and labels. They consist of + letters, digits, and some special characters. By convention, + pseudo-ops (assembler directives) begin with a period (`.`). +- **Numbers:** Represent integer values. +- **Strings:** Enclosed in double quotes (`"`). Double quotes within + strings are escaped by using two consecutive double quotes. +- **Operators:** Predefined symbols representing Z-machine + instructions. +- **Pseudo-ops (directives):** Instructions to the assembler, such + as `.word`, `.str`, and `.funct`. +- **Operand prefixes:** Special characters used to indicate the type + of operand following them (e.g., `,` for general operand, `>` for + return value). +- **Comments:** Begin with a semicolon (`;`) and extend to the end + of the line. + +These lexical elements are combined to form valid assembly language +statements that are processed by ZAP. + +**Note:** This chapter provides a basic overview of the character set +and lexical elements. More detailed information about specific +elements and their usage will be presented in subsequent chapters. + +Chapter 2.2: Symbol Definition and Types (Global, Local, Constants) +------------------------------------------------------------------- + +Symbols in ZAP are used to represent various types of values and +labels within the program. They play a crucial role in code +organization, readability, and address resolution. + +**Symbol Definition:** + +A symbol is defined by assigning it a value using either: + +- **Equate statement:** `symbol = value` +- **Pseudo-op:** `.equal symbol, value` +- **Label definition:** `symbol::` or `symbol:` + +**Symbol Types:** + +ZAP distinguishes between three main types of symbols: + +- **Global symbols:** Defined outside of any function and accessible + throughout the entire program. They can represent global + variables, function names, table names, and string names. +- **Local symbols:** Defined within a function using the `.funct` + directive and accessible only within that function. They represent + local variables and labels used for branching within the function. +- **Constants:** Represent fixed values that cannot be changed. They + are defined using equate statements or specific pseudo-ops like + `.seq`. + +**Naming Conventions:** + +The following naming conventions exist: + +- **Pseudo-ops:** Begin with a period (`.`). +- **Global labels:** End with two colons (`::`). +- **Local labels:** End with one colon (`:`) + +**Symbol Redefinition:** + +- **Global and local symbols:** Cannot be redefined within their + scope. Attempting to do so will result in an error. +- **Constants:** Can be redefined at any point in the program. + +**Predefined Symbols:** + +ZAP includes several predefined global symbols: + +- **Operators:** Represent Z-machine instructions (e.g., `ADD`, + `SUB`, `PRINT`). +- **Pseudo-ops:** Represent assembler directives (e.g., `.word`, + `.str`, `.funct`). +- **Special symbols:** Represent specific data structures or + locations within the program (e.g., `VOCAB`, `OBJECT`, `STACK`). + +Understanding symbol definition and types is essential for writing +well-structured and organized Z-code assembly programs. By following +the conventions and understanding the scope of different symbol types, +programmers can ensure proper address resolution and code +functionality. + +Chapter 2.3: Statement Syntax and Structure +------------------------------------------- + +ZAP assembly language statements are line-oriented, meaning each +statement occupies a single line in the source file. Each statement +consists of four optional fields: + +**Statement Structure:** + + [label] [operator] [operands] [comment] + +**Field Descriptions:** + +- **Label:** A symbol followed by one or two colons, depending on + whether it's a local or global label. +- **Operator:** A predefined symbol representing either an operator + (Z-machine instruction) or a pseudo-op (assembler directive). +- **Operands:** A space or tab-separated list of operands, each + optionally preceded by an operand prefix character. +- **Comment:** Begins with a semicolon (`;`) and extends to the end + of the line. + +**Examples:** + +``` {.assembly} +START:: .funct main ; Define the main function + add 1, 2 ; Add two constants + print "Hello" ; Print a string + jump END ; Jump to the END label +END: +``` + +**Operand Prefixes:** + +Operand prefixes are special characters used to indicate the type of +operand following them and provide additional information: + +- **`,` (comma):** General operand. +- **`>` (greater than):** Return value operand. Specifies where the + return value of an instruction should be stored +- **`\` (backslash):** Branch on failure operand. Indicates the + branch target if the predicate fails +- **`/` (forward slash):** Branch on success operand. Indicates the + branch target if the predicate succeeds. +- **`=` (equal sign):** Value operand for assignments. Used for + assigning values to symbols +- **`+` (plus sign):** Addend operand for constant addition. + +**Line Continuation:** + +Operands can be continued to the next line by placing the operand +prefix character on one line and the corresponding operand on the next +line. + +**Note:** This chapter provides a general overview of statement syntax +and structure. More detailed information about specific operators, +pseudo-ops, and operands will be presented in subsequent chapters. + +Chapter 2.4: Operands and Addressing Modes +------------------------------------------ + +Operands in ZAP assembly language specify the data or values that +instructions operate on. ZAP supports three main types of operands: + +**Operand Types:** + +- **Immediate:** A constant value directly encoded within the + instruction. It can be either a short (one-byte) or long + (two-byte) constant. +- **Variable:** A reference to a variable stored in memory. The + operand specifies the variable number, which is interpreted + differently depending on the context. +- **Other:** Represents special values like labels, function + pointers, or string pointers. + +**Addressing Modes:** + +ZAP uses different addressing modes to access and interpret operands: + +- **Direct addressing:** The operand directly specifies the value or + memory address of the data. This is used for immediate operands + and some other types. +- **Indirect addressing:** The operand specifies the number of a + variable, which is then used to access the actual data in memory. + This is used for variable operands. + +**Variable Addressing:** + +Variable operands are interpreted as follows: + +- **0:** Refers to the top of the game stack. +- **1-15:** Refer to local variables within the current function. +- **16-255:** Refer to global variables. + +**Examples:** + +``` {.assembly} +add 1, 2 ; Add two immediate operands +set var1, 5 ; Set the variable var1 to 5 +jump START ; Jump to the label START +get table, 3 ; Get the 3rd element from the table +``` + +Understanding operand types and addressing modes is crucial for +writing correct and efficient Z-code assembly programs. By using the +appropriate operand prefixes and addressing modes, programmers can +ensure that instructions operate on the intended data and achieve the +desired results. + +Chapter 2.5: Instruction Formats (2OP, 1OP, 0OP, EXT) +----------------------------------------------------- + +ZAP instructions are encoded in different formats depending on the +number and type of operands they require. This allows for efficient +use of memory while providing flexibility in instruction design. + +**Instruction Formats:** + +- **2OP (Two-operand):** This format is used for instructions with + two operands, typically immediate values or variables. It is the + most compact format but has limitations on the types of operands + it can handle. +- **1OP (One-operand):** This format is used for instructions with a + single operand, which can be an immediate value, variable, or + other type. +- **0OP (Zero-operand):** This format is used for instructions that + do not require any explicit operands. +- **EXT (Extended):** This format is used for instructions that + cannot be represented in the other formats due to: + - Having more than two operands. + - Requiring long immediate operands. + - Being rarely used instructions. + +**Encoding Details:** + +The specific encoding of each format varies, but generally: + +- **2OP:** The opcode byte contains both the operator and mode bits, + specifying the instruction and the types of its two operands. +- **1OP:** The opcode byte contains the operator and mode bits for + the single operand. +- **0OP:** The opcode byte solely represents the instruction, as + there are no operands. +- **EXT:** The opcode byte identifies the instruction, and a + separate byte (or two bytes for some instructions) follows the + opcode to specify the operand types and modes. + +**Extended Opcode Prefix (EXTOP):** + +ZAP provides an additional 256 extended opcodes through the `EXTOP` +instruction. When `EXTOP` is encountered, the next byte is interpreted +as an opcode with its value increased by 256. This allows for a larger +instruction set while maintaining backward compatibility with older +ZIP interpreters. + +**Choosing the Right Format:** + +The assembler automatically chooses the most efficient format for each +instruction based on the number and types of operands. Programmers do +not need to explicitly specify the format. + +The assembler determines the most efficient instruction format by +following a set of rules based on the number and types of operands +involved. Here's a simplified explanation of the process: + +1. **Count the number of operands:** + - If there are **zero operands**, the **0OP format** is used. + - If there is **one operand**, the **1OP format** is used, + unless the operand is a long immediate value, in which case + the **EXT format** is necessary. + - If there are **two operands**: + - If both operands are either immediate values or variables, + and neither is a long immediate, the **2OP format** is + used. + - Otherwise, the **EXT format** is used. +2. **Check for special cases:** + - Some instructions, like `EQUAL?`, can take a variable number + of operands. In such cases, the **EXT format** is used + regardless of the actual number of operands provided. + - Certain rarely used instructions might also be encoded in the + **EXT format** even if they could fit in other formats. This + is done to optimize the overall instruction set usage. + +By following these rules, the assembler ensures that each instruction +is encoded in the most compact and efficient format possible, reducing +the overall size of the Z-code program and improving its execution +speed. + +**Example:** + +- The instruction `add 1, 2` has two immediate operands, so it can + be encoded in the **2OP format**. +- The instruction `set var1, 5` has one variable operand and one + immediate operand, so it can also be encoded in the **2OP + format**. +- The instruction `print "Hello"` has one string operand, which is + considered an "other" type. Therefore, it needs the **EXT + format**. +- The instruction `jump START` has one label operand, also requiring + the **EXT format**. + +Understanding instruction formats is helpful for comprehending the +structure of Z-code programs and how instructions are encoded in +memory. However, for most programming tasks, it is sufficient to focus +on the instruction names and operands, as ZAP handles the format +selection automatically. + +Chapter 2.6: Instruction Values and Predicates +---------------------------------------------- + +Some ZAP instructions return values or act as predicates, influencing +the flow of control in the program. + +**Instruction Values:** + +Certain instructions, such as arithmetic and logical operations, +produce a value as a result of their execution. This value can be: + +- **Pushed onto the game stack:** This is the default behavior if no + explicit destination is specified. +- **Stored in a variable:** The instruction can be followed by an + operand prefix `>` and a variable number to indicate where the + value should be stored. + +**Example:** + +``` {.assembly} +add 1, 2 ; Value is pushed onto the stack +add 1, 2 > var1 ; Value is stored in the variable var1 +``` + +**Predicates:** + +Predicate instructions evaluate a condition and implicitly perform a +conditional branch based on the result. They are typically used for +decision-making and control flow within the program. + +**Branch Polarity and Offset:** + +Predicate instructions are followed by one or two bytes that specify: + +- **Branch polarity:** Whether the branch occurs on success + (predicate evaluates to true) or failure (predicate evaluates to + false). This is indicated by the high-order bit of the first byte. +- **Branch offset:** The distance to jump if the branch condition is + met. This can be either a short (6-bit) or long (14-bit) offset. + +**Branch Targets:** + +The branch offset determines the target of the conditional jump: + +- **Offset 0:** Executes an `RFALSE` instruction, returning false + from the current function. +- **Offset 1:** Executes an `RTRUE` instruction, returning true from + the current function. +- **Other offsets:** Jumps to the instruction located at the current + address plus the offset minus two. + +**Example:** + +``` {.assembly} +less? var1, 5 / label1 ; Branch to label1 if var1 is less than 5 +``` + +Understanding instruction values and predicates is essential for +controlling the flow of execution in Z-code programs. By using +predicates and specifying appropriate branch targets, programmers can +implement conditional logic and decision-making within their games. + +Chapter 3.1: Detailed Description of Each Opcode and Directive +-------------------------------------------------------------- + +This chapter provides a comprehensive description of each opcode and +directive supported by ZAP. For each element, the following +information is provided: + +- **Name:** The name of the opcode or directive. +- **Syntax:** The format of the instruction or directive, including + operand types and prefixes. +- **Functionality:** A detailed explanation of what the opcode or + directive does. +- **Special cases:** Any special conditions or behaviors to be aware + of. +- **Error conditions:** Potential errors that might occur during + assembly or execution. +- **Examples:** Illustrative examples of how the opcode or directive + can be used. + +This chapter serves as a reference for understanding the functionality +and usage of each opcode and directive available in ZAP. By consulting +this information, programmers can write accurate and efficient Z-code +assembly programs. + +### .ALIGN + +**.ALIGN** is a directive that instructs the assembler to align the +next generated code or data to a specified byte boundary. This can be +useful for ensuring proper memory access and improving performance on +certain architectures. + +**Syntax:** + +``` {.assembly} +.align value +``` + +**Functionality:** + +The `.align` directive pads the object file with zero bytes until the +current address is a multiple of the specified `value`. This +effectively aligns the next instruction or data element to the +specified boundary. + +**Special Cases:** + +- If `value` is 1, the directive has no effect, as all data is + already aligned to a byte boundary. +- If `value` is not a power of two, the assembler may align to the + next higher power of two. + +**Error Conditions:** + +An error occurs if `value` is zero or negative. + +**Examples:** + +``` {.assembly} +.align 4 +.word data1 ; data1 will be aligned to a 4-byte boundary + +.align 8 +.funct func1 ; func1 will be aligned to an 8-byte boundary +``` + +**Use Cases:** + +- Aligning data structures to their natural word or longword + boundaries can improve memory access efficiency. +- Some Z-machine instructions might have specific alignment + requirements for optimal performance. +- Aligning functions can be helpful for debugging and code analysis. + +**Note:** While `.align` can be used to enforce specific alignment, it +is generally recommended to let the assembler choose the appropriate +alignment for optimal code generation. + +### .BYTE + +The `.BYTE` directive instructs the assembler to generate one or more +byte values in the object file. It is used to define raw byte data or +initialize specific memory locations with byte values. + +**Syntax:** + +``` {.assembly} +.byte value1 [, value2 ...] +``` + +**Functionality:** + +The `.byte` directive generates the specified byte values sequentially +in the object file. Each value must be a constant expression that +evaluates to a number within the range of 0 to 255. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if a value exceeds the byte range (0-255). + +**Examples:** + +``` {.assembly} +.byte 10, 20, 30 ; Generates three bytes with values 10, 20, and 30 +.byte 'A' ; Generates a byte with the ASCII value of 'A' (65) +``` + +**Use Cases:** + +- Defining raw byte data for specific purposes, such as flags or + status codes. +- Initializing memory locations with specific byte values. +- Embedding special characters or control codes within the object + file. + +**Note:** While `.byte` allows for precise control over byte values, +it is generally recommended to use higher-level directives like +`.word` or `.str` whenever possible, as they provide better +readability and maintainability. + +### .CHRSET + +The `.CHRSET` directive allows the programmer to redefine the +character sets used for encoding strings in the Z-machine. This can be +useful for optimizing string storage and handling characters specific +to certain languages or display systems. + +**Syntax:** + +``` {.assembly} +.chrset id, char1, char2, ..., charN +``` + +**Functionality:** + +The `.chrset` directive redefines one of the three character sets used +for string encoding: + +- **`id`:** Specifies the character set to modify (0, 1, or 2). +- **`char1, char2, ..., charN`:** A list of characters (specified as + their ASCII values) that will be assigned to the character set. + +The number of characters provided depends on the `id`: + +- **Set 0 and 1:** 26 characters are expected. +- **Set 2:** 24 characters are expected (excluding ASCII escape and + newline characters). + +**Special Cases:** + +- Character set 2 has two special characters that cannot be + redefined: + - **6:** Represents the ASCII escape sequence. + - **7:** Represents the newline character. + +**Error Conditions:** + +- An error occurs if `id` is not 0, 1, or 2. +- An error occurs if the number of characters provided does not + match the expected count for the specified `id`. + +**Examples:** + +``` {.assembly} +.chrset 0, 'a', 'b', ..., 'z' ; Redefines character set 0 with lowercase letters +.chrset 1, 'A', 'B', ..., 'Z' ; Redefines character set 1 with uppercase letters +``` + +**Use Cases:** + +- Optimizing string storage by assigning frequently used characters + to the compact character sets. +- Handling characters specific to certain languages or display + systems that are not included in the default character sets. + +**Note:** Redefining character sets can have significant implications +for string encoding and decoding. It is generally recommended to use +the default character sets unless there is a specific need for +optimization or handling special characters. + +### .DEFSEG + +The `.DEFSEG` directive is used to define a segment and specify its +relationships with other segments. Segments are logical divisions of +the Z-code program that can be used to optimize disk usage and loading +times in multi-disk games. + +**Syntax:** + +``` {.assembly} +.defseg name, seg1, seg2, seg3 +``` + +**Functionality:** + +The `.DEFSEG` directive performs the following: + +- **Defines a segment:** Creates a new segment with the specified + `name`. +- **Specifies adjacent segments:** Declares that the segment is + adjacent to the segments `seg1`, `seg2`, and `seg3`. This + information is used by the `zsplit` tool to determine how to + distribute segments across multiple disks. + +**Special Cases:** + +- If the segment `name` is "0", it refers to the default segment + that contains all preloaded data and code. +- If a segment name is not defined with `.DEFSEG`, it is implicitly + considered adjacent to segment 0. + +**Error Conditions:** + +An error occurs if a segment name is not a valid symbol. + +**Examples:** + +``` {.assembly} +.defseg "ROOM", "HALL", "GARDEN" ; Defines the "ROOM" segment and declares it adjacent to "HALL" and "GARDEN" segments +.defseg "STARTUP", "MAIN" ; Defines the "STARTUP" segment and declares it adjacent to the "MAIN" segment +``` + +**Use Cases:** + +- Organizing the game's code and data into logical segments for + efficient disk usage and loading. +- Informing the `zsplit` tool about segment relationships to + optimize the distribution of segments across multiple disks. + +**Note:** Segment definitions and adjacency information are primarily +used by the `zsplit` tool and do not directly affect the execution of +the Z-code program. + +### .END + +The `.END` directive marks the end of the assembly language program. +It instructs the assembler to stop processing input and perform final +operations. + +**Syntax:** + +``` {.assembly} +.end +``` + +**Functionality:** + +When the `.END` directive is encountered, the assembler performs the +following: + +- **Stops processing input:** Any code or directives following + `.END` are ignored. +- **Resolves forward references:** Performs fixup operations to + resolve any outstanding forward references to symbols. +- **Generates final output:** Writes the assembled Z-code program to + the object file and generates any optional listing or error files. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error might occur during fixup if undefined symbols are +encountered. + +**Examples:** + +``` {.assembly} +; ... game code ... + +.end +``` + +**Use Cases:** + +The `.END` directive is mandatory and must be placed at the end of +every Z-code assembly program to signal the completion of the assembly +process. + +**Note:** It is essential to ensure that all necessary code and data +have been defined before the `.END` directive, as anything following +it will not be processed by the assembler. + +### .ENDI + +The `.ENDI` directive marks the end of an `.INSERT` file. It instructs +the assembler to return to the previous input source and continue +processing. + +**Syntax:** + +``` {.assembly} +.endi +``` + +**Functionality:** + +The `.ENDI` directive is used in conjunction with the `.INSERT` +directive, which allows the contents of another file to be inserted +and assembled at a specific point in the main source file. When +`.ENDI` is encountered, the assembler: + +- **Stops processing the inserted file:** Any code or directives + following `.ENDI` in the inserted file are ignored. +- **Returns to the previous input source:** The assembler resumes + processing the main source file from the point where the `.INSERT` + directive was encountered. + +**Special Cases:** + +- A `.ENDI` directive without a preceding `.INSERT` directive is an + error. + +**Error Conditions:** + +An error occurs if `.ENDI` is found outside of an inserted file. + +**Examples:** + +``` {.assembly} +; ... main source file ... + +.insert "header.zap" + +; ... contents of header.zap ... + +.endi + +; ... main source file continues ... +``` + +**Use Cases:** + +- Modularizing code by separating commonly used routines or data + into separate files that can be inserted into multiple programs. +- Including header files that define constants, macros, or other + elements. + +**Note:** The `.INSERT` and `.ENDI` directives provide a mechanism for +code inclusion and modularity, but their usage should be carefully +considered to avoid potential complexity and maintainability issues. + +### .ENDSEG + +The `.ENDSEG` directive closes all currently open segments. Segments +are logical divisions of the Z-code program used to optimize disk +usage and loading times in multi-disk games. + +**Syntax:** + +``` {.assembly} +.endseg +``` + +**Functionality:** + +The `.ENDSEG` directive closes any segments that were previously +opened with the `.SEGMENT` directive. This indicates to the assembler +that the code and data belonging to those segments have been defined. + +**Special Cases:** + +- If no segments are currently open, the `.ENDSEG` directive has no + effect. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +.segment "ROOM" + +; ... code and data for the ROOM segment ... + +.endseg +``` + +**Use Cases:** + +- Ensuring that all segments are properly closed before the end of + the assembly process. +- Organizing code and data into logical segments for efficient disk + usage and loading. + +**Note:** Segment definitions and closures are primarily used by the +`zsplit` tool and do not directly affect the execution of the Z-code +program. + +### .ENDT + +The `.ENDT` directive marks the end of a table definition. Tables are +logical structures used to organize data in Z-code programs. + +**Syntax:** + +``` {.assembly} +.endt +``` + +**Functionality:** + +The `.ENDT` directive must be used to terminate a table that was +previously declared with the `.TABLE` directive. It performs the +following: + +- **Checks table size:** If a size was specified in the `.TABLE` + directive, the assembler verifies that the actual table size does + not exceed the declared size. +- **Finalizes table data:** The assembler performs any necessary + operations to finalize the table data, such as padding or + alignment. + +**Special Cases:** + +- A `.ENDT` directive without a preceding `.TABLE` directive is an + error. + +**Error Conditions:** + +- An error occurs if the actual table size exceeds the declared size + (if specified in `.TABLE`). + +**Examples:** + +``` {.assembly} +.table 10 +.word data1, data2, data3 +.endt +``` + +**Use Cases:** + +- Defining tables of data with a specific size and ensuring that the + size is not exceeded. +- Organizing data into logical structures for easier access and + manipulation. + +**Note:** The `.TABLE` and `.ENDT` directives provide a way to define +and manage tables in Z-code programs, but their usage should be +consistent and well-structured to avoid potential errors and +maintainability issues. + +### .FALSE + +The `.FALSE` directive generates a word (two-byte) value of 0 in the +object file. It is used to represent the boolean value `false` or to +initialize memory locations with a zero value. + +**Syntax:** + +``` {.assembly} +.false +``` + +**Functionality:** + +The `.false` directive simply generates a word with the value 0 at the +current address in the object file. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +.false ; Generates a word with value 0 +set flag1, .false ; Sets the flag variable `flag1` to false +``` + +**Use Cases:** + +- Representing the boolean value `false` in conditional statements + or data structures. +- Initializing variables or memory locations with a zero value. + +**Note:** The `.false` directive is equivalent to using `.word 0`. +However, `.false` provides better readability and clarity when +representing boolean values. + +### .FSTR + +The `.FSTR` directive defines a string as a "frequent string" and adds +it to the frequent words table. Frequent strings are short, commonly +used substrings that can be referenced efficiently within other +strings, reducing overall memory usage. + +**Syntax:** + +``` {.assembly} +.fstr name, string +``` + +**Functionality:** + +The `.fstr` directive performs the following: + +- **Defines a symbol:** Creates a global symbol with the specified + `name`. The value of the symbol is the address of the string + divided by 2 (since strings are stored as words). +- **Outputs the string:** Generates the string in the object file, + aligning it to a word boundary. +- **Adds to frequent words table:** Adds the string to the frequent + words table, which is used by the Z-machine to efficiently + reference frequently used substrings within other strings. + +**Special Cases:** + +- Frequent strings cannot contain other frequent strings within + them. +- The frequent words table has a limited size (96 entries). If this + limit is exceeded, the assembler will issue an error. + +**Error Conditions:** + +- An error occurs if `name` is not a valid symbol. +- An error occurs if the frequent words table is full. + +**Examples:** + +``` {.assembly} +.fstr "the", "the " ; Defines the frequent string "the" +.fstr "and", "and " ; Defines the frequent string "and" +``` + +**Use Cases:** + +- Optimizing string storage by defining frequently used words or + phrases as frequent strings. +- Reducing the overall size of the Z-code program by efficiently + referencing common substrings. + +**Note:** The use of frequent strings can improve memory efficiency, +but it is important to choose appropriate strings and avoid exceeding +the table size limit. + +### .FUNCT + +The `.FUNCT` directive defines a function and begins a new local +symbol block. Functions are subroutines that can be called and return +values, allowing for modular and reusable code. + +**Syntax:** + +``` {.assembly} +.funct name [, arg1 [: type] [, arg2 [: type] ...]] +``` + +**Functionality:** + +The `.funct` directive performs the following: + +- **Defines a function:** Creates a new function with the specified + `name`. The function name becomes a global symbol. +- **Starts a new local symbol block:** Any symbols defined after + `.funct` are considered local to the function and are not + accessible outside of it. +- **Defines local variables:** The optional `arg1`, `arg2`, etc., + specify local variables for the function. Each variable can + optionally have a type specified after a colon (`:`) to indicate + its data type. +- **Aligns function:** Aligns the function to a quad-byte boundary + for efficient execution. + +**Special Cases:** + +- If no arguments are provided, the function has no local variables. +- If a type is not specified for a local variable, it is assumed to + be of type `ANY`. + +**Error Conditions:** + +- An error occurs if `name` is not a valid symbol. +- An error occurs if the function is defined within another function + (nested functions are not supported). + +**Examples:** + +``` {.assembly} +.funct main +; ... code for the main function ... + +.funct add, num1: int, num2: int > result: int +; ... code for the add function ... +``` + +**Use Cases:** + +- Defining functions to modularize code and promote reusability. +- Creating subroutines to perform specific tasks within the program. +- Utilizing local variables to manage data within functions. + +**Note:** The `.funct` directive is essential for defining functions +in Z-code assembly programs. Proper function definition and usage are +crucial for code organization and maintainability. + +### .GSTR + +The `.GSTR` directive defines a global string and stores it in the +string area of the Z-code program. Global strings are accessible from +anywhere in the program and are typically used for longer text +passages or messages. + +**Syntax:** + +``` {.assembly} +.gstr name, string +``` + +**Functionality:** + +The `.gstr` directive performs the following: + +- **Defines a symbol:** Creates a global symbol with the specified + `name`. The value of the symbol is the address of the string in + the string area, adjusted for the string offset (`SOFF`). +- **Outputs the string:** Generates the string in the object file, + aligning it to a quad-byte boundary. +- **Updates string offset:** If necessary, updates the `SOFF` value + to reflect the new string's location. + +**Special Cases:** + +- The string area is located in a separate section of the Z-code + program and is accessed using the `SOFF` value. +- Strings are encoded in a special 5-bit byte format for efficient + storage. + +**Error Conditions:** + +- An error occurs if `name` is not a valid symbol. + +**Examples:** + +``` {.assembly} +.gstr "intro", "Welcome to the game!" +print intro ; Prints the "intro" string +``` + +**Use Cases:** + +- Defining long text passages or messages that need to be accessed + from various parts of the program. +- Storing strings that are too large to be defined as immediate + operands within instructions. + +**Note:** The `.gstr` directive is used to define global strings, +while the `.str` directive is used for defining strings within tables +or as immediate operands. + +### .GVAR + +The `.GVAR` directive defines a global variable and assigns it a +default value. Global variables are accessible from anywhere in the +program and are typically used to store persistent data or game state. + +**Syntax:** + +``` {.assembly} +.gvar name [= value] +``` + +**Functionality:** + +The `.gvar` directive performs the following: + +- **Defines a symbol:** Creates a global symbol with the specified + `name`. The value of the symbol is the variable number, which is + used to access the variable in the global table. +- **Assigns a default value:** If `value` is provided, it is + assigned as the initial value of the global variable. Otherwise, + the default value is 0. +- **Outputs the value:** Generates the default value in the object + file, placing it in the global table. + +**Special Cases:** + +- Global variables are stored in a dedicated table pointed to by the + `GLOBALS` word in the program header. +- The first global variable has a variable number of 16, and + subsequent variables are assigned incrementing numbers. + +**Error Conditions:** + +- An error occurs if `name` is not a valid symbol. +- An error occurs if the maximum number of global variables is + exceeded. + +**Examples:** + +``` {.assembly} +.gvar score = 0 ; Defines a global variable "score" with initial value 0 +.gvar health ; Defines a global variable "health" with default value 0 +``` + +**Use Cases:** + +- Storing persistent data that needs to be accessed from different + parts of the program. +- Managing game state and tracking variables like score, health, or + inventory items. + +**Note:** The `.gvar` directive is used to define global variables, +while local variables are defined within functions using the `.funct` +directive. + +### .INSERT + +The `.INSERT` directive instructs the assembler to insert the contents +of another file at the current point in the assembly process. This +allows for code modularity and reuse. + +**Syntax:** + +``` {.assembly} +.insert "filename" +``` + +**Functionality:** + +The `.insert` directive opens the specified `filename` and inserts its +contents into the assembly stream as if they were part of the main +source file. The assembler processes the inserted file's code and +directives, including any symbols or definitions it contains. + +**Special Cases:** + +- The inserted file must be a valid Z-code assembly language file. +- The `.insert` directive can be nested, meaning inserted files can + themselves contain `.insert` directives. +- The `.ENDI` directive is used to mark the end of an inserted file + and return to the previous input source. + +**Error Conditions:** + +- An error occurs if the specified `filename` cannot be opened. +- An error occurs if the inserted file contains syntax errors or + invalid directives. + +**Examples:** + +``` {.assembly} +; ... main source file ... + +.insert "header.zap" ; Inserts the contents of header.zap + +; ... main source file continues ... +``` + +**Use Cases:** + +- Including header files that define constants, macros, or other + commonly used elements. +- Modularizing code by separating routines or data into separate + files that can be inserted into multiple programs. + +**Note:** While `.insert` provides a mechanism for code inclusion and +modularity, its usage should be carefully considered to avoid +potential complexity and maintainability issues. Excessive nesting of +`.insert` directives can make code harder to understand and debug. + +### .LANG + +The `.LANG` directive specifies the language and escape character used +for string encoding. This allows ZAP to generate Z-code programs that +support different languages and character sets. + +**Syntax:** + +``` {.assembly} +.lang id, escape +``` + +**Functionality:** + +The `.lang` directive sets the following parameters for string +encoding: + +- **`id`:** Specifies the language ID. Currently, only two languages + are supported: + - **0:** English (default) + - **1:** German +- **`escape`:** Specifies the escape character used to represent + special characters or switch character sets within strings. + +**Special Cases:** + +- The default language is English with the `%` character as the + escape character. +- The German language setting modifies the character set used for + compact encoding to include German-specific characters. + +**Error Conditions:** + +- An error occurs if `id` is not 0 or 1. + +**Examples:** + +``` {.assembly} +.lang 1, '%' ; Sets the language to German with '%' as the escape character +``` + +**Use Cases:** + +- Creating Z-code programs that support languages other than + English. +- Optimizing string storage for languages with specific character + sets. + +**Note:** The `.lang` directive is typically used at the beginning of +the assembly program to set the language and escape character for all +subsequent string definitions. + +### .LEN + +The `.LEN` directive calculates the length of a string in words and +generates a byte containing that length in the object file. This is +typically used in conjunction with the `.STR` directive to create +self-contained string definitions. + +**Syntax:** + +``` {.assembly} +.len string +``` + +**Functionality:** + +The `.len` directive performs the following: + +- **Calculates string length:** Determines the length of the + specified string in words, taking into account the Z-machine's + 5-bit byte encoding for strings. +- **Generates length byte:** Outputs a single byte containing the + calculated length to the object file. + +**Special Cases:** + +- The string must be a short string, meaning it can be represented + in 255 words or less. + +**Error Conditions:** + +An error occurs if the string length exceeds 255 words. + +**Examples:** + +``` {.assembly} +.len "Hello" +.str "Hello" ; This string will be preceded by a byte indicating its length +``` + +**Use Cases:** + +- Creating self-contained string definitions where the length is + explicitly stored alongside the string data. +- Facilitating string manipulation routines that require knowledge + of the string length. + +**Note:** The `.len` directive is often used together with the `.strl` +directive, which combines the functionality of `.len` and `.str` into +a single operation. + +### .NEW + +The `.NEW` directive sets the release level of the Z-code program +being assembled. This information is used to ensure compatibility with +different versions of the ZIP interpreter. + +**Syntax:** + +``` {.assembly} +.new level +``` + +**Functionality:** + +The `.new` directive sets the `Version` variable in ZAP, which +determines the version of the Z-machine that the generated program is +compatible with. The `level` argument must be a constant expression +that evaluates to one of the supported Z-machine versions: + +- **3:** ZIP +- **4:** EZIP +- **5:** XZIP +- **6:** YZIP + +**Special Cases:** + +- The default release level is 5 (XZIP). +- Some features and opcodes might not be available in older versions + of ZIP. + +**Error Conditions:** + +An error occurs if `level` is not a supported Z-machine version. + +**Examples:** + +``` {.assembly} +.new 6 ; Sets the release level to YZIP +``` + +**Use Cases:** + +- Ensuring compatibility with specific versions of the ZIP + interpreter. +- Taking advantage of features and opcodes introduced in newer + Z-machine versions. + +**Note:** The `.new` directive should be used at the beginning of the +assembly program to set the release level before any other code or +directives. + +### .OBJECT + +The `.OBJECT` directive defines an object and assigns it a unique +object number. Objects are complex data structures used to represent +entities and items within the game world. + +**Syntax:** + +``` {.assembly} +.object name, flag1, flag2, ..., flag7 +``` + +**Functionality:** + +The `.object` directive performs the following: + +- **Defines a symbol:** Creates a global symbol with the specified + `name`. The value of the symbol is the object number. +- **Assigns object number:** Assigns a unique, incrementing object + number to the object. +- **Outputs object data:** Generates the object data in the object + file, including flag words and property table pointer. + +**Special Cases:** + +- Objects are stored in a dedicated table pointed to by the `OBJECT` + word in the program header. +- The first object has an object number of 1, and subsequent objects + are assigned incrementing numbers. +- The `flag1` to `flag7` arguments represent the initial values of + the object's 48 one-bit flags, divided into seven words. + +**Error Conditions:** + +- An error occurs if `name` is not a valid symbol. +- An error occurs if the maximum number of objects is exceeded. + +**Examples:** + +``` {.assembly} +.object "player", 0, 0, 0, 0, 0, 0 ; Defines the "player" object +.object "sword", 1, 0, 0, 0, 0, 0 ; Defines the "sword" object +``` + +**Use Cases:** + +- Defining objects to represent entities and items in the game + world. +- Assigning properties and flags to objects to track their state and + characteristics. + +**Note:** The `.object` directive is used to define objects, while +properties are defined within the object's property table using the +`.PROP` directive. + +### .OPTIONS + +The `.OPTIONS` directive is used to set options that control the +behavior of the ZIP interpreter. These options affect features such as +scripting and user input. + +**Syntax:** + +``` {.assembly} +.options script, ask +``` + +**Functionality:** + +The `.options` directive sets the following options: + +- **`script`:** A boolean value (0 or 1) indicating whether + scripting is enabled. When scripting is enabled, the interpreter + can read commands from a script file instead of from the user. +- **`ask`:** A boolean value (0 or 1) indicating whether the + interpreter should ask the user for confirmation before executing + certain actions, such as restarting or restoring the game. + +**Special Cases:** + +- If either `script` or `ask` is omitted, the corresponding option + is not modified. + +**Error Conditions:** + +An error occurs if `script` or `ask` is not a valid boolean value (0 +or 1). + +**Examples:** + +``` {.assembly} +.options 1, 0 ; Enables scripting and disables confirmation prompts +``` + +**Use Cases:** + +- Enabling scripting for automated testing or gameplay recording. +- Disabling confirmation prompts for a more streamlined user + experience. + +**Note:** The `.options` directive is typically used at the beginning +of the assembly program to set the desired interpreter options. + +### .PCSET + +The `.PCSET` directive sets the program counter (PC) to a specific +value. This directive is used to jump to a specific address within the +program or to align code and data to specific memory locations. + +**Syntax:** + +``` {.assembly} +.pcset value +``` + +**Functionality:** + +The `.pcset` directive sets the program counter to the specified +`value`. The assembler then continues generating code and data from +that address onwards. + +**Special Cases:** + +- If `value` is less than the current program counter, the assembler + will issue a warning but will still set the PC to the specified + value. + +**Error Conditions:** + +An error occurs if `value` is negative. + +**Examples:** + +``` {.assembly} +.pcset 1000 ; Sets the program counter to 1000 +``` + +**Use Cases:** + +- Jumping to a specific address within the program, typically for + implementing subroutines or handling error conditions. +- Aligning code or data to specific memory locations for + optimization or compatibility purposes. + +**Note:** The `.PCSET` directive should be used with caution, as it +can lead to unexpected behavior if not used correctly. It is generally +recommended to use labels and jump instructions for control flow +whenever possible. + +### .PDEF + +The `.PDEF` directive aligns the next generated code or data to the +next word boundary. This directive is used to ensure proper alignment +for word-sized data elements. + +**Syntax:** + +``` {.assembly} +.pdef +``` + +**Functionality:** + +The `.pdef` directive pads the object file with a zero byte if the +current address is not already a multiple of two. This ensures that +the next word (two-byte) value will be aligned to a word boundary. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +.pdef +.word data1 ; data1 will be aligned to a word boundary +``` + +**Use Cases:** + +- Ensuring proper alignment for word-sized data elements, such as + numbers and pointers. +- Improving memory access efficiency on architectures that require + word alignment. + +**Note:** The `.PDEF` directive is typically used before defining +word-sized data elements to guarantee their alignment. However, the +assembler generally handles alignment automatically, so explicit use +of `.PDEF` is often unnecessary. + +### .PICFILE + +The `.PICFILE` directive defines a picture file and specifies its +properties. Picture files contain images and associated data used by +the `DISPLAY` and `DCLEAR` instructions. + +**Syntax:** + +``` {.assembly} +.picfile filename, machine, ideal-x, ideal-y, base-x, base-y +``` + +**Functionality:** + +The `.picfile` directive defines a picture file with the following +properties: + +- **`filename`:** The name of the picture file. +- **`machine`:** The target machine for which the picture file is + intended (e.g., "apple", "ega", "mac"). +- **`ideal-x` and `ideal-y`:** The ideal dimensions of the picture + in pixels. +- **`base-x` and `base-y`:** The base coordinates of the picture in + pixels. + +This information is used by the interpreter to properly display and +manage pictures from the specified file. + +**Special Cases:** + +- The picture file format and encoding are specific to the Z-machine + and may vary depending on the target machine. +- The `zsplit` tool uses the picture file information to distribute + pictures across multiple disks in multi-disk games. + +**Error Conditions:** + +- An error occurs if `filename` is not a valid string. +- An error occurs if `machine` is not a recognized target machine. + +**Examples:** + +``` {.assembly} +.picfile "pictures.p", "mac", 320, 200, 0, 0 +``` + +**Use Cases:** + +- Defining picture files for use with the `DISPLAY` and `DCLEAR` + instructions. +- Providing information to the interpreter and `zsplit` tool for + picture management. + +**Note:** The `.PICFILE` directive is used in conjunction with the +`DISPLAY` and `DCLEAR` instructions to display and manage pictures +within Z-code programs. + +### .PROP + +The `.PROP` directive defines a property within an object's property +table. Properties are used to associate additional data and attributes +with objects. + +**Syntax:** + +``` {.assembly} +.prop length, number +``` + +**Functionality:** + +The `.prop` directive defines a property with the following +characteristics: + +- **`length`:** The length of the property value in bytes. +- **`number`:** The property number. + +The assembler generates the property data in the object file, +including the length, number, and value. + +**Special Cases:** + +- Properties are stored in a sorted order within the object's + property table. +- The length of a property value can be 1, 2, or more bytes. The + encoding of the length depends on the size: + - 1 byte: The high-order bit of the length byte is 0. + - 2 bytes: The high-order bit is 1, and the second-highest bit + is 0. + - More than 2 bytes: The high-order two bits are both 1, and the + remaining 6 bits specify the length. + +**Error Conditions:** + +- An error occurs if `length` is zero or negative. +- An error occurs if `number` is not within the valid range (1-63). + +**Examples:** + +``` {.assembly} +.object "player", ... +.prop 1, 1 ; Defines a one-byte property with number 1 +.prop 2, 10 ; Defines a two-byte property with number 10 +``` + +**Use Cases:** + +- Associating additional data with objects, such as descriptions, + attributes, or inventory items. +- Extending the functionality of objects beyond their basic flags + and attributes. + +**Note:** The `.PROP` directive is used within an object definition to +define its properties. The object itself is defined using the +`.OBJECT` directive. + +### .SEGMENT + +The `.SEGMENT` directive opens a new segment for code and data +definition. Segments are logical divisions of the Z-code program used +to optimize disk usage and loading times in multi-disk games. + +**Syntax:** + +``` {.assembly} +.segment "name" +``` + +**Functionality:** + +The `.segment` directive opens a new segment with the specified +`name`. All subsequent code and data definitions are considered to +belong to this segment until a `.ENDSEG` directive is encountered or +another `.SEGMENT` directive opens a different segment. + +**Special Cases:** + +- If the segment "0" is opened, it refers to the default segment + that contains all preloaded data and code. +- If a segment name is not defined with `.DEFSEG`, it is implicitly + considered adjacent to segment 0. + +**Error Conditions:** + +An error occurs if `name` is not a valid string. + +**Examples:** + +``` {.assembly} +.segment "ROOM" + +; ... code and data for the ROOM segment ... + +.endseg +``` + +**Use Cases:** + +- Organizing the game's code and data into logical segments for + efficient disk usage and loading. +- Informing the `zsplit` tool about segment boundaries to optimize + the distribution of segments across multiple disks. + +**Note:** Segment definitions and closures are primarily used by the +`zsplit` tool and do not directly affect the execution of the Z-code +program. + +### .SEQ + +The `.SEQ` directive assigns sequential values to a list of symbols, +starting from 0. This is a convenient way to define a series of +constants or variables with incrementing values. + +**Syntax:** + +``` {.assembly} +.seq symbol1 [, symbol2 ...] +``` + +**Functionality:** + +The `.seq` directive assigns values to the specified symbols in the +following manner: + +- `symbol1` is assigned the value 0. +- `symbol2` is assigned the value 1. +- ... and so on. + +The symbols become global constants with their respective values. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if any of the symbols are already defined. + +**Examples:** + +``` {.assembly} +.seq color_red, color_green, color_blue ; Defines three constants with values 0, 1, and 2 +``` + +**Use Cases:** + +- Defining a series of constants with incrementing values, such as + color codes or status flags. +- Creating a sequence of variables with unique identifiers. + +**Note:** The `.seq` directive provides a concise way to define +multiple constants or variables with sequential values. + +### .SEQ + +The `.SEQ` directive assigns sequential values to a list of symbols, +starting from 0. This is a convenient way to define a series of +constants or variables with incrementing values. + +**Syntax:** + +``` {.assembly} +.seq symbol1 [, symbol2 ...] +``` + +**Functionality:** + +The `.seq` directive assigns values to the specified symbols in the +following manner: + +- `symbol1` is assigned the value 0. +- `symbol2` is assigned the value 1. +- ... and so on. + +The symbols become global constants with their respective values. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if any of the symbols are already defined. + +**Examples:** + +``` {.assembly} +.seq color_red, color_green, color_blue ; Defines three constants with values 0, 1, and 2 +``` + +**Use Cases:** + +- Defining a series of constants with incrementing values, such as + color codes or status flags. +- Creating a sequence of variables with unique identifiers. + +**Note:** The `.seq` directive provides a concise way to define +multiple constants or variables with sequential values. + +### .STR + +The `.STR` directive generates a string in the object file, encoding +it in the Z-machine's 5-bit byte format. It is used to define strings +that can be referenced and printed by instructions like `PRINT` and +`PRINTB`. + +**Syntax:** + +``` {.assembly} +.str string +``` + +**Functionality:** + +The `.str` directive performs the following: + +- **Encodes the string:** Converts the ASCII string into the + Z-machine's 5-bit byte format, using frequent words and character + set shifting as needed. +- **Outputs the string:** Generates the encoded string data in the + object file. +- **Sets the end-of-string bit:** Marks the last word of the string + with the end-of-string bit to indicate its termination. + +**Special Cases:** + +- If a string is provided without an explicit directive, it is + implicitly treated as a `.str` directive. +- Strings are aligned to word boundaries in the object file. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +.str "Hello, world!" ; Defines a string +print message ; Prints the string defined above +``` + +**Use Cases:** + +- Defining strings that can be printed or manipulated by the Z-code + program. +- Storing text data efficiently using the Z-machine's string + encoding format. + +**Note:** The `.str` directive is used to define strings within tables +or as immediate operands. For defining global strings in the string +area, the `.GSTR` directive is used. + +### .STRL + +The `.STRL` directive combines the functionality of the `.LEN` and +`.STR` directives. It calculates the length of a string in words, +generates a byte containing that length, and then generates the +encoded string data in the object file. + +**Syntax:** + +``` {.assembly} +.strl string +``` + +**Functionality:** + +The `.strl` directive performs the following: + +- **Calculates string length:** Determines the length of the + specified string in words, taking into account the Z-machine's + 5-bit byte encoding for strings. +- **Generates length byte:** Outputs a single byte containing the + calculated length to the object file. +- **Encodes the string:** Converts the ASCII string into the + Z-machine's 5-bit byte format, using frequent words and character + set shifting as needed. +- **Outputs the string:** Generates the encoded string data in the + object file, following the length byte. + +**Special Cases:** + +- The string must be a short string, meaning it can be represented + in 255 words or less. + +**Error Conditions:** + +An error occurs if the string length exceeds 255 words. + +**Examples:** + +``` {.assembly} +.strl "Hello, world!" ; Defines a string with its length +``` + +**Use Cases:** + +- Creating self-contained string definitions where the length is + explicitly stored alongside the string data. +- Simplifying string definition by combining the functionality of + `.LEN` and `.STR` into a single directive. + +**Note:** The `.strl` directive is a convenient way to define strings +with their lengths, but it is equivalent to using `.len` followed by +`.str`. + +### .TABLE + +The `.TABLE` directive declares the beginning of a table definition. +Tables are logical structures used to organize data in Z-code +programs. + +**Syntax:** + +``` {.assembly} +.table [size] +``` + +**Functionality:** + +The `.table` directive marks the start of a table definition. It can +optionally take a `size` argument, which specifies the maximum size of +the table in bytes. The assembler uses this information to: + +- **Check for size violations:** If a size is specified, the + assembler ensures that the actual table data generated does not + exceed the declared size. +- **Perform alignment:** The assembler may align the table data to a + specific boundary depending on the target architecture or data + type. + +**Special Cases:** + +- If the `size` argument is omitted, the table size is not checked + by the assembler. However, debugging versions of the ZIP + interpreter may perform bounds checking at runtime. + +**Error Conditions:** + +An error occurs if the actual table size exceeds the declared size (if +specified). + +**Examples:** + +``` {.assembly} +.table 100 ; Declares a table with a maximum size of 100 bytes +.word data1, data2, data3 +.endt +``` + +**Use Cases:** + +- Defining tables of data with a specific size and ensuring that the + size is not exceeded. +- Organizing data into logical structures for easier access and + manipulation. + +**Note:** The `.TABLE` directive must be paired with a `.ENDT` +directive to mark the end of the table definition. + +### .TRUE + +The `.TRUE` directive generates a word (two-byte) value of 1 in the +object file. It is used to represent the boolean value `true` or to +initialize memory locations with a non-zero value. + +**Syntax:** + +``` {.assembly} +.true +``` + +**Functionality:** + +The `.true` directive simply generates a word with the value 1 at the +current address in the object file. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +.true ; Generates a word with value 1 +set flag1, .true ; Sets the flag variable `flag1` to true +``` + +**Use Cases:** + +- Representing the boolean value `true` in conditional statements or + data structures. +- Initializing variables or memory locations with a non-zero value. + +**Note:** The `.true` directive is equivalent to using `.word 1`. +However, `.true` provides better readability and clarity when +representing boolean values. + +### .VOCBEG + +The `.VOCBEG` directive declares the beginning of the vocabulary area. +The vocabulary area contains words and associated information used by +the `READ` and `LEX` instructions for parsing player input. + +**Syntax:** + +``` {.assembly} +.vocbeg record-length, key-length +``` + +**Functionality:** + +The `.vocbeg` directive defines the following parameters for the +vocabulary area: + +- **`record-length`:** Specifies the length of each vocabulary entry + in bytes. This includes the word itself and any additional + associated data. +- **`key-length`:** Specifies the length of the key used for sorting + vocabulary entries. The key is typically the word itself, but it + can be a shorter substring. + +The assembler uses this information to: + +- **Allocate space for vocabulary entries:** Ensures that enough + space is allocated in the object file for the vocabulary data. +- **Sort vocabulary entries (optional):** If the number of entries + in the vocabulary table is specified as negative, the vocabulary + is considered unsorted. Otherwise, the assembler sorts the entries + based on their keys for efficient searching during input parsing. + +**Special Cases:** + +- The vocabulary area is located in a separate section of the Z-code + program and is accessed using the `VOCAB` word in the program + header. +- The first byte of the vocabulary area specifies the number of + self-inserting break characters used by the `READ` instruction. +- The format of the vocabulary entries depends on the + `record-length` and `key-length` values specified in `.VOCBEG`. + +**Error Conditions:** + +- An error occurs if `record-length` or `key-length` is zero or + negative. +- An error occurs if the vocabulary area has an invalid length or + structure. + +**Examples:** + +``` {.assembly} +.vocbeg 6, 3 ; Define vocabulary with 6-byte entries and 3-byte keys + +; ... vocabulary words and data ... + +.vocend +``` + +**Use Cases:** + +- Defining the vocabulary of words that the game understands and can + parse from player input. +- Optimizing input parsing by sorting the vocabulary for efficient + searching. + +**Note:** The `.VOCBEG` directive must be paired with a `.VOCEND` +directive to mark the end of the vocabulary area. + +### .VOCEND + +The `.VOCEND` directive marks the end of the vocabulary area. The +vocabulary area contains words and associated information used by the +`READ` and `LEX` instructions for parsing player input. + +**Syntax:** + +``` {.assembly} +.vocend +``` + +**Functionality:** + +The `.VOCEND` directive must be used to terminate a vocabulary area +that was previously declared with the `.VOCBEG` directive. It performs +the following: + +- **Sorts vocabulary entries:** If the vocabulary is defined as + sorted, the assembler sorts the entries based on their keys. +- **Outputs vocabulary data:** The assembler writes the vocabulary + data to the object file in the appropriate format. +- **Finalizes vocabulary table:** The assembler performs any + necessary operations to finalize the vocabulary table, such as + calculating the total number of words. + +**Special Cases:** + +- A `.VOCEND` directive without a preceding `.VOCBEG` directive is + an error. + +**Error Conditions:** + +- An error occurs if the vocabulary area has an invalid length or + structure. + +**Examples:** + +``` {.assembly} +.vocbeg 6, 3 ; Define vocabulary with 6-byte entries and 3-byte keys + +; ... vocabulary words and data ... + +.vocend +``` + +**Use Cases:** + +- Defining the vocabulary of words that the game understands and can + parse from player input. +- Optimizing input parsing by sorting the vocabulary for efficient + searching. + +**Note:** The `.VOCBEG` and `.VOCEND` directives are essential for +defining and managing the vocabulary used by the `READ` and `LEX` +instructions. Proper structure and usage of the vocabulary area are +crucial for correct input parsing. + +### .WORD + +The `.WORD` directive instructs the assembler to generate one or more +word (two-byte) values in the object file. It is used to define +word-sized data or initialize specific memory locations with word +values. + +**Syntax:** + +``` {.assembly} +.word value1 [, value2 ...] +``` + +**Functionality:** + +The `.word` directive generates the specified word values sequentially +in the object file. Each value can be: + +- **A constant expression:** Evaluates to a number within the range + of -32768 to 65535. +- **A symbol:** Refers to a previously defined symbol representing a + word value. + +**Special Cases:** + +- If a single value is provided without the `.word` directive, it is + implicitly treated as a `.word` directive. + +**Error Conditions:** + +An error occurs if a value exceeds the 16-bit word range. + +**Examples:** + +``` {.assembly} +.word 1000, 2000, 3000 ; Generates three words with values 1000, 2000, and 3000 +.word counter ; Generates a word with the value of the symbol `counter` +``` + +**Use Cases:** + +- Defining word-sized data, such as numbers, pointers, or flags. +- Initializing memory locations with specific word values. + +**Note:** The `.word` directive is a fundamental data definition +directive used to generate word-sized data in Z-code programs. + +### .ZWORD + +The `.ZWORD` directive generates a Z-word string in the object file. +Z-word strings are similar to regular Z-strings but are limited to a +maximum of two words (four bytes). They are used to store short text +snippets or identifiers efficiently. + +**Syntax:** + +``` {.assembly} +.zword string +``` + +**Functionality:** + +The `.zword` directive performs the following: + +- **Encodes the string:** Converts the ASCII string into the + Z-machine's 5-bit byte format, similar to the `.STR` directive but + limited to two words. +- **Outputs the string:** Generates the encoded string data in the + object file. +- **Pads the string:** If the string is less than two words, it is + padded with the standard pad character (5) to fill the remaining + space. + +**Special Cases:** + +- Z-word strings are always four bytes long, regardless of the + actual string length. + +**Error Conditions:** + +An error occurs if the string length exceeds two words. + +**Examples:** + +``` {.assembly} +.zword "OK" ; Defines a Z-word string +``` + +**Use Cases:** + +- Storing short text snippets or identifiers efficiently. +- Defining data structures that require fixed-length strings. + +**Note:** The `.ZWORD` directive is used for defining short strings +that need to be stored efficiently. For longer strings, the `.STR` or +`.GSTR` directives are more appropriate. + +### ADD + +**ADD** is an opcode that performs addition on two 16-bit word values. +It adds the first operand to the second operand and returns the +result. + +**Syntax:** + +``` {.assembly} +add arg1:int, arg2:int > val +``` + +**Functionality:** + +The `add` opcode performs the following: + +- **Adds `arg1` and `arg2`:** Performs integer addition. +- **Stores the result:** The sum is stored in the specified + destination (`val`). If no destination is provided, the result is + pushed onto the game stack. + +**Special Cases:** + +- If the result of the addition overflows the 16-bit word size, an + error occurs. + +**Error Conditions:** + +An error occurs if the addition result overflows the 16-bit word +range. + +**Examples:** + +``` {.assembly} +add 5, 10 > result ; Adds 5 and 10, stores the sum (15) in `result` +``` + +**Use Cases:** + +- Performing integer addition calculations. +- Increasing values or accumulating totals. + +**Note:** The `add` opcode performs signed integer addition. If the +operands are unsigned, the programmer needs to handle potential +overflow conditions. + +### ASHIFT + +**ASHIFT** is an opcode that performs an arithmetic shift on a 16-bit +integer value. It shifts the bits of the operand to the left or right, +depending on the specified shift amount. + +**Syntax:** + +``` {.assembly} +ashift int, n > val +``` + +**Functionality:** + +The `ashift` opcode performs the following: + +- **Shifts the bits of `int`:** + - If `n` is positive, `int` is shifted left by `n` bits. + - If `n` is negative, `int` is shifted right by the absolute + value of `n` bits. +- **Preserves the sign bit:** In an arithmetic shift, the sign bit + of the operand is replicated to fill in the vacated bits during a + right shift. This ensures that the sign of the number is + preserved. +- **Stores the result:** The shifted value is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +- If `n` is zero, the value of `int` remains unchanged. +- If the shift amount exceeds the word size (16 bits), the result is + undefined. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +ashift num, 2 > shifted ; Shifts the value in `num` left by 2 bits +ashift num, -1 > shifted ; Shifts the value in `num` right by 1 bit +``` + +**Use Cases:** + +- Multiplying or dividing numbers by powers of two efficiently. +- Manipulating individual bits within a word. +- Implementing bitwise operations and algorithms. + +**Note:** The `ashift` opcode performs an arithmetic shift, which +preserves the sign of the operand. For a logical shift, where the sign +bit is not replicated, use the `shift` opcode. + +### ASSIGNED? + +**ASSIGNED?** is an opcode that checks whether an optional argument +was provided when calling the current function. It is used to +implement conditional logic based on the presence or absence of +optional arguments. + +**Syntax:** + +``` {.assembly} +assigned? opt:var /pred +``` + +**Functionality:** + +The `assigned?` opcode evaluates to true if an optional argument was +supplied for the variable `opt`. Otherwise, it evaluates to false. The +result is used to determine whether to take a conditional branch, as +specified by the predicate (`/pred`) syntax. + +**Special Cases:** + +- The `assigned?` opcode can only be used within a function to check + for optional arguments passed to that function. +- The variable `opt` must be a local variable of the function. + +**Error Conditions:** + +An error occurs if `assigned?` is used outside of a function or if +`opt` is not a local variable. + +**Examples:** + +``` {.assembly} +.funct my_function, optional_arg + assigned? optional_arg / handle_optional + ; ... code if optional_arg is not assigned ... +handle_optional: + ; ... code to handle optional_arg ... +``` + +**Use Cases:** + +- Implementing functions with optional arguments. +- Performing different actions depending on whether optional + arguments are provided. + +**Note:** The `assigned?` opcode is specific to the Z-machine and does +not have a direct equivalent in most other assembly languages. It is a +useful feature for implementing functions with flexible argument +lists. + +### BAND + +**BAND** is an opcode that performs a bitwise AND operation on two +16-bit word values. It combines the corresponding bits of the +operands, setting each bit in the result to 1 only if both +corresponding bits in the operands are also 1. + +**Syntax:** + +``` {.assembly} +band word1, word2 > val +``` + +**Functionality:** + +The `band` opcode performs the following: + +- **Performs bitwise AND:** Combines the corresponding bits of + `word1` and `word2` using the logical AND operation. +- **Stores the result:** The resulting word is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +band flags, mask > result ; Performs bitwise AND between `flags` and `mask` +``` + +**Use Cases:** + +- Masking out specific bits in a word. +- Checking the state of individual bits or groups of bits. +- Implementing bitwise algorithms and operations. + +**Note:** The `band` opcode is a fundamental bitwise operation used in +various programming tasks, including data manipulation, flag handling, +and low-level control. + +### BCOM + +**BCOM** is an opcode that performs a bitwise complement (NOT) +operation on a 16-bit word value. It inverts each bit in the operand, +setting 1s to 0s and vice versa. + +**Syntax:** + +``` {.assembly} +bcom word > val +``` + +**Functionality:** + +The `bcom` opcode performs the following: + +- **Inverts the bits of `word`:** Flips each bit in the operand, + changing 1s to 0s and 0s to 1s. +- **Stores the result:** The resulting word is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +bcom flags > inverted ; Inverts the bits in the `flags` word +``` + +**Use Cases:** + +- Inverting the state of individual bits or groups of bits. +- Implementing bitwise algorithms and operations. +- Toggling the values of flags or status bits. + +**Note:** The `bcom` opcode is a fundamental bitwise operation used in +various programming tasks, including data manipulation, flag handling, +and low-level control. + +### BOR + +**BOR** is an opcode that performs a bitwise OR operation on two +16-bit word values. It combines the corresponding bits of the +operands, setting each bit in the result to 1 if either or both of the +corresponding bits in the operands are 1. + +**Syntax:** + +``` {.assembly} +bor word1, word2 > val +``` + +**Functionality:** + +The `bor` opcode performs the following: + +- **Performs bitwise OR:** Combines the corresponding bits of + `word1` and `word2` using the logical OR operation. +- **Stores the result:** The resulting word is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +bor flags, mask > result ; Performs bitwise OR between `flags` and `mask` +``` + +**Use Cases:** + +- Setting specific bits in a word. +- Combining flags or status bits. +- Implementing bitwise algorithms and operations. + +**Note:** The `bor` opcode is a fundamental bitwise operation used in +various programming tasks, including data manipulation, flag handling, +and low-level control. + +### BTST + +**BTST** is an opcode that tests whether specific bits are set in a +16-bit word value. It acts as a predicate, meaning it evaluates a +condition and implicitly performs a conditional branch based on the +result. + +**Syntax:** + +``` {.assembly} +btst word1, word2 /pred +``` + +**Functionality:** + +The `btst` opcode performs the following: + +- **Checks bit states:** Compares the corresponding bits of `word1` + and `word2`. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if every bit that is set (1) in `word2` is also set in + `word1`. Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- If all bits in `word2` are 0, the predicate always succeeds. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +btst flags, mask / handle_flags ; Branch to `handle_flags` if all bits set in `mask` are also set in `flags` +``` + +**Use Cases:** + +- Checking the state of individual bits or groups of bits within a + word. +- Implementing conditional logic based on bit states. +- Handling flags or status bits efficiently. + +**Note:** The `btst` opcode is a useful tool for working with bitwise +data and implementing conditional behavior based on specific bit +patterns. + +### BUFOUT + +**BUFOUT** is an opcode that controls whether output to the screen is +buffered or unbuffered. Buffering allows the interpreter to optimize +line breaks and handle text wrapping more effectively. + +**Syntax:** + +``` {.assembly} +bufout int +``` + +**Functionality:** + +The `bufout` opcode sets the output buffering mode based on the value +of `int`: + +- **`int` = 1:** Enables output buffering (default). Output is + accumulated in a buffer and printed to the screen when a newline + character is encountered or the buffer is full. +- **`int` = 0:** Disables output buffering. All currently buffered + output is immediately sent to the screen, and subsequent output is + printed as it is generated. + +**Special Cases:** + +- Output redirected to a table using `DIROUT 3` is never buffered, + regardless of the `bufout` setting. + +**Error Conditions:** + +An error occurs if `int` is not 0 or 1. + +**Examples:** + +``` {.assembly} +bufout 0 ; Disables output buffering +print "Immediate output" +bufout 1 ; Re-enables output buffering +``` + +**Use Cases:** + +- Disabling output buffering can be useful for displaying text + immediately without waiting for a newline or buffer to fill. This + might be used for real-time updates or interactive prompts. +- In most cases, output buffering should be enabled to allow the + interpreter to handle line breaks and text wrapping efficiently. + +**Note:** The `bufout` opcode is rarely needed in typical Z-code +programs, as most output operations implicitly handle buffering as +necessary. + +### CALL + +**CALL** is an opcode that calls a function with three arguments and +returns a value. It is the most general form of the function call +instruction, allowing for a flexible number of arguments and return +values. + +**Syntax:** + +``` {.assembly} +call fcn, arg1:any, arg2:any, arg3:any > val +``` + +**Functionality:** + +The `call` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the three arguments + (`arg1`, `arg2`, and `arg3`) onto the game stack. +- **Calls the function:** Transfers control to the function + specified by `fcn`. The function address is calculated by shifting + `fcn` left by two bits and adding the function offset (`FOFF`) + shifted left by three bits. +- **Retrieves return value:** When the function returns, its return + value is retrieved and stored in the specified destination + (`val`). If no destination is provided, the value is pushed onto + the game stack. + +**Special Cases:** + +- If `fcn` is zero, the `call` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `fcn` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +call process_input, input_buffer, parse_buffer, options > result ; Calls the `process_input` function with three arguments +``` + +**Use Cases:** + +- Calling functions with three arguments. +- Implementing subroutines and modular code structures. + +**Note:** The `CALL` opcode is the most general form of the function +call instruction. For functions with fewer arguments, the `CALL1` and +`CALL2` opcodes can be used for more efficient encoding. The compiler +automatically chooses the appropriate opcode based on the number of +arguments and their types. + +### CALL1 + +**CALL1** is an opcode that calls a function with one argument and +returns a value. It is a more compact version of the `CALL` opcode, +optimized for functions with a single argument. + +**Syntax:** + +``` {.assembly} +call1 fcn > val +``` + +**Functionality:** + +The `call1` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the single argument + onto the game stack. +- **Calls the function:** Transfers control to the function + specified by `fcn`. The function address is calculated by shifting + `fcn` left by two bits and adding the function offset (`FOFF`) + shifted left by three bits. +- **Retrieves return value:** When the function returns, its return + value is retrieved and stored in the specified destination + (`val`). If no destination is provided, the value is pushed onto + the game stack. + +**Special Cases:** + +- If `fcn` is zero, the `call1` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `fcn` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +call1 get_input > input_char ; Calls the `get_input` function and stores the returned character in `input_char` +``` + +**Use Cases:** + +- Calling functions with a single argument efficiently. +- Implementing subroutines and modular code structures. + +**Note:** The `call1` opcode is generated by the compiler when it +detects a function call with one argument. It is not typically used +directly by programmers. + +### CALL2 + +**CALL2** is an opcode that calls a function with two arguments and +returns a value. It is a more compact version of the `CALL` opcode, +optimized for functions with two arguments. + +**Syntax:** + +``` {.assembly} +call2 fcn, arg > val +``` + +**Functionality:** + +The `call2` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the two arguments + (`fcn` and `arg`) onto the game stack. +- **Calls the function:** Transfers control to the function + specified by `fcn`. The function address is calculated by shifting + `fcn` left by two bits and adding the function offset (`FOFF`) + shifted left by three bits. +- **Retrieves return value:** When the function returns, its return + value is retrieved and stored in the specified destination + (`val`). If no destination is provided, the value is pushed onto + the game stack. + +**Special Cases:** + +- If `fcn` is zero, the `call2` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `fcn` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +call2 add, num1, num2 > sum ; Calls the `add` function with `num1` and `num2` as arguments, stores the sum in `sum` +``` + +**Use Cases:** + +- Calling functions with two arguments efficiently. +- Implementing subroutines and modular code structures. + +**Note:** The `call2` opcode is generated by the compiler when it +detects a function call with two arguments. It is not typically used +directly by programmers. + +### CATCH + +**CATCH** is an opcode that captures an exception thrown by the +`THROW` opcode and provides a way to handle it. It is used in +conjunction with `THROW` to implement exception handling and non-local +control flow. + +**Syntax:** + +``` {.assembly} +catch > frame +``` + +**Functionality:** + +The `catch` opcode performs the following: + +- **Captures exception:** If an exception has been thrown using the + `THROW` opcode, the `catch` opcode captures it and prevents the + program from terminating. +- **Stores frame pointer:** The opcode stores a pointer to the + current call frame in the specified destination (`frame`). This + frame pointer identifies the point in the call stack where the + exception was caught. +- **Continues execution:** The program continues execution from the + instruction following the `catch` opcode. + +**Special Cases:** + +- If no exception has been thrown, the `catch` opcode stores 0 in + the `frame` variable and continues execution. +- The `CATCH` and `THROW` opcodes do not work within "internal" + calls, such as timeout handling routines called by `READ` or + `INPUT`. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +catch > frame +; ... some code that might throw an exception ... +if frame != 0 + ; ... handle the exception ... +``` + +**Use Cases:** + +- Implementing exception handling to deal with errors or unexpected + conditions. +- Performing non-local control flow, such as exiting multiple nested + functions at once. + +**Note:** The `CATCH` and `THROW` opcodes provide a mechanism for +exception handling and non-local control flow in Z-code programs. They +should be used with caution to avoid complex control flow and +potential errors. + +### CLEAR + +**CLEAR** is an opcode that clears a window or the entire screen, +filling it with the current background color. + +**Syntax:** + +``` {.assembly} +clear window:int +``` + +**Functionality:** + +The `clear` opcode clears the specified window or the entire screen: + +- **`window` = 0 to 7:** Clears the corresponding window. +- **`window` = -1:** Unsplits the screen (if it was previously + split) and clears the entire screen. +- **`window` = -2:** Clears the entire screen without affecting + window attributes or cursor position. + +When a window is cleared, the cursor is moved to the top-left corner +of that window. + +**Special Cases:** + +- If the `window` argument is omitted, the current window is + cleared. + +**Error Conditions:** + +An error occurs if `window` is not within the valid range (-2 to 7). + +**Examples:** + +``` {.assembly} +clear 0 ; Clears the main window (window 0) +clear -2 ; Clears the entire screen +``` + +**Use Cases:** + +- Clearing the screen or a window to prepare for new output. +- Erasing previous content and resetting the display. + +**Note:** The `clear` opcode is a convenient way to clear the screen +or a window. It is important to remember that clearing a window moves +the cursor to its top-left corner. + +### COLOR + +**COLOR** is an opcode that sets the foreground and background colors +for subsequent text output. + +**Syntax:** + +``` {.assembly} +color fore:int, back:int +``` + +**Functionality:** + +The `color` opcode sets the colors for text output as follows: + +- **`fore`:** Specifies the foreground color (text color). +- **`back`:** Specifies the background color. + +The colors are interpreted according to the following values: + +- **-1:** Use the color of the pixel at the current cursor position. +- **0:** No change. +- **1:** System default color. +- **2:** Black. +- **3:** Red. +- **4:** Green. +- **5:** Yellow. +- **6:** Blue. +- **7:** Magenta. +- **8:** Cyan. +- **9:** White. +- **10:** Light gray +- **11:** Gray +- **12:** Dark gray + +**Special Cases:** + +- The availability of colors and their specific shades may vary + depending on the target machine and display capabilities. +- On some machines, like the Amiga, the colors set for the main + window (window 0) are used for all windows. + +**Error Conditions:** + +An error occurs if `fore` or `back` is not within the valid range (-1 +to 12). + +**Examples:** + +``` {.assembly} +color 3, 2 ; Sets foreground color to red and background color to black +color 0, 1 ; Sets background color to the system default +``` + +**Use Cases:** + +- Changing the colors of text output for visual distinction or + emphasis. +- Enhancing the game's appearance and atmosphere. + +**Note:** Games should be designed to handle machines that do not +support color selection. The `MODE` byte in the program header +indicates whether the `COLOR` operation is available. + +### COPYT + +**COPYT** is an opcode that copies a specified number of bytes from +one table to another. It can also be used to zero out a section of +memory or duplicate data within a table. + +**Syntax:** + +``` {.assembly} +copyt source:tbl, dest:tbl, length:int +``` + +**Functionality:** + +The `copyt` opcode copies bytes from the source table (`source`) to +the destination table (`dest`) according to the specified `length`: + +- **Positive `length`:** Copies `length` bytes from `source` to + `dest`. If the source and destination regions overlap, the opcode + performs a "backwards" copy to avoid overwriting data before it is + copied. +- **Negative `length`:** Copies `length` bytes from `source` to + `dest` without checking for overlap. This allows for data + duplication within the source table. +- **Zero `dest`:** If `dest` is zero, the opcode zeroes out `length` + bytes in the source table. + +**Special Cases:** + +- The `copyt` opcode can be used to copy data to itself, allowing + for shifting or duplication of data within a table. + +**Error Conditions:** + +An error occurs if: + +- `source` or `dest` is not a valid table pointer. +- The copy operation would exceed the bounds of the tables. + +**Examples:** + +``` {.assembly} +copyt buffer1, buffer2, 100 ; Copies 100 bytes from buffer1 to buffer2 +copyt table, 0, 50 ; Zeroes out the first 50 bytes of table +copyt table, table + 10, 20 ; Duplicates 20 bytes within table, shifting them by 10 bytes +``` + +**Use Cases:** + +- Copying data between tables. +- Zeroing out sections of memory. +- Duplicating data within a table. +- Implementing memory management or data manipulation routines. + +**Note:** The `copyt` opcode provides a flexible way to copy and +manipulate data within tables. It is important to be aware of the +overlap behavior when using positive lengths to avoid unintended data +overwrites. + +### CRLF + +**CRLF** is an opcode that prints an end-of-line sequence to the +screen. This typically results in a carriage return and line feed, +moving the cursor to the beginning of the next line. + +**Syntax:** + +``` {.assembly} +crlf +``` + +**Functionality:** + +The `crlf` opcode outputs an end-of-line sequence to the current +window. The specific behavior depends on the window's attributes: + +- **Scrolling window:** The window contents scroll up by one line, + and the cursor is moved to the beginning of the newly created + empty line. +- **Non-scrolling window:** The cursor is moved to the beginning of + the next line within the window. If the window is full, the output + may be clipped or overwritten. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +print "This is a line." +crlf +print "This is on the next line." +``` + +**Use Cases:** + +- Starting a new line of output. +- Separating paragraphs or sections of text. +- Formatting text display within windows. + +**Note:** The `crlf` opcode is a basic output operation used to +control the vertical positioning of text on the screen. + +### CURGET + +**CURGET** is an opcode that retrieves the current cursor position +within a window and stores it in a table. + +**Syntax:** + +``` {.assembly} +curget output:tbl +``` + +**Functionality:** + +The `curget` opcode retrieves the current cursor position in the +specified window and writes the coordinates into the `output` table: + +- **Word 0 of `output`:** Contains the Y coordinate of the cursor + (row number, 1-based). +- **Word 1 of `output`:** Contains the X coordinate of the cursor + (column number, 1-based). + +**Special Cases:** + +- If the `window` argument is omitted, the current window is used. + +**Error Conditions:** + +An error occurs if: + +- `output` is not a valid table pointer. +- The `output` table does not have enough space to store the + coordinates (at least two words). + +**Examples:** + +``` {.assembly} +curget cursor_pos ; Retrieves the cursor position in the current window +``` + +**Use Cases:** + +- Determining the current cursor position for display or interaction + purposes. +- Implementing custom cursor movement or text editing routines. + +**Note:** While `CURGET` can be used to retrieve the cursor position, +it is generally recommended to use the `WINGET` opcode with the +appropriate offset values, as it provides more flexibility and can +access other window properties as well. + +### CURSET + +**CURSET** is an opcode that sets the cursor position within a window +to specified coordinates. + +**Syntax:** + +``` {.assembly} +curset y:int, x:int [, window:int] +``` + +**Functionality:** + +The `curset` opcode sets the cursor position in the specified window +to the coordinates (`y`, `x`): + +- **`y`:** The Y coordinate (row number, 1-based). +- **`x`:** The X coordinate (column number, 1-based). + +If the coordinates are outside the window's boundaries, they are +adjusted to the closest valid position within the window. + +**Special Cases:** + +- If the `window` argument is omitted, the current window is used. +- If `y` is -1, the cursor is turned off. +- If `y` is -2, the cursor is turned on. In this case, the `x` + argument is ignored. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `y` or `x` is negative (except for the special cases mentioned + above). + +**Examples:** + +``` {.assembly} +curset 5, 10 ; Sets the cursor to row 5, column 10 in the current window +curset 1, 1, 2 ; Sets the cursor to the top-left corner of window 2 +curset -1 ; Turns off the cursor +``` + +**Use Cases:** + +- Positioning the cursor for text output or user interaction. +- Implementing custom cursor movement or text editing routines. + +**Note:** The `curset` opcode provides a direct way to set the cursor +position. However, for more complex window manipulations, consider +using the `WINPOS` and `WINSIZE` opcodes. + +### DCLEAR + +**DCLEAR** is an opcode that clears the area occupied by a previously +displayed picture, restoring the window's background color. + +**Syntax:** + +``` {.assembly} +dclear picture:int [, y:int, x:int] +``` + +**Functionality:** + +The `dclear` opcode clears the area of the specified picture: + +- **`picture`:** The ID number of the picture to clear. +- **`y` and `x` (optional):** The coordinates where the picture was + displayed (in pixels). If omitted, the opcode uses the coordinates + where the picture was last displayed. + +The opcode restores the window's background color in the area +previously occupied by the picture. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if: + +- `picture` is not a valid picture ID. +- The coordinates (`y`, `x`) are outside the window's boundaries. + +**Examples:** + +``` {.assembly} +display 10, 10, 10 ; Displays picture 10 at coordinates (10, 10) +dclear 10 ; Clears the area occupied by picture 10 +``` + +**Use Cases:** + +- Removing pictures from the screen. +- Restoring the window's background color after displaying a + picture. + +**Note:** The `DCLEAR` opcode is used in conjunction with the +`DISPLAY` opcode to manage the display of pictures within Z-code +programs. + +### DEC + +**DEC** is an opcode that decrements the value of a variable by 1. + +**Syntax:** + +``` {.assembly} +dec var +``` + +**Functionality:** + +The `dec` opcode subtracts 1 from the value of the specified variable +(`var`). + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +dec counter ; Decrements the value of the variable `counter` +``` + +**Use Cases:** + +- Decrementing counters or loop variables. +- Reducing the value of a variable by a fixed amount. + +**Note:** The `dec` opcode is a convenient way to decrement a variable +by 1. For more complex arithmetic operations, use the `SUB` opcode. + +### DIRIN + +**DIRIN** is an opcode that redirects input from a specified device. +It allows the Z-code program to receive input from sources other than +the keyboard, such as command files or scripts. + +**Syntax:** + +``` {.assembly} +dirin device:int [, any1, any2, any3] +``` + +**Functionality:** + +The `dirin` opcode redirects input based on the value of `device`: + +- **`device` = 0:** Keyboard input (default). +- **`device` = 1:** Command file input. The interpreter reads input + from a previously created command file, typically generated using + `DIROUT 4`. + +The additional arguments (`any1`, `any2`, `any3`) are currently unused +and should be ignored by the interpreter. + +**Special Cases:** + +- Not all interpreters implement command file input. If the + interpreter does not support it, the `dirin 1` instruction should + be ignored. + +**Error Conditions:** + +An error occurs if `device` is not 0 or 1. + +**Examples:** + +``` {.assembly} +dirin 1 ; Redirects input to the command file +``` + +**Use Cases:** + +- Reading commands from a script file for automated testing or + gameplay recording. +- Implementing custom input methods or interactive sequences. + +**Note:** The `dirin` opcode is used in conjunction with `DIROUT` to +manage input and output redirection. + +### DIROUT + +**DIROUT** is an opcode that redirects output to a specified device. +It allows the Z-code program to send output to destinations other than +the screen, such as the transcript or a table. + +**Syntax:** + +``` {.assembly} +dirout device:int [, any1, any2, any3] +``` + +**Functionality:** + +The `dirout` opcode redirects output based on the value of `device`: + +- **`device` = 1:** Screen output (default). +- **`device` = -1:** Disables screen output. +- **`device` = 2:** Transcript output. Sends all subsequent output + to the transcript device, which can be a file, printer, or other + suitable destination. +- **`device` = -2:** Disables transcript output. +- **`device` = 3:** Table output. Sends output to the table + specified by `any1`. The `any2` argument can optionally specify + justification for formatted tables. +- **`device` = -3:** Disables table output. +- **`device` = 4:** Command recording. Creates a command file and + writes all subsequent input commands to it. +- **`device` = -4:** Disables command recording. + +**Special Cases:** + +- If the screen device is disabled and the transcript device is + enabled, output is still sent to the transcript. +- Table output using `dirout 3` is not buffered, regardless of the + `BUFOUT` setting. +- Not all interpreters implement command recording (device 4). + +**Error Conditions:** + +An error occurs if `device` is not within the valid range (-4 to 4). + +**Examples:** + +``` {.assembly} +dirout 2 ; Enables transcript output +dirout -1 ; Disables screen output +dirout 3, table, 80 ; Redirects output to `table` with right justification at 80 pixels +``` + +**Use Cases:** + +- Sending output to the transcript for debugging or recording + purposes. +- Creating formatted tables for display using `PRINTF`. +- Recording player input commands for testing or analysis. + +**Note:** The `dirout` opcode is used in conjunction with `DIRIN` to +manage input and output redirection. + +### DISPLAY + +**DISPLAY** is an opcode that displays a picture at a specified +location on the screen. Pictures are images stored in a separate +picture file and referenced by their ID numbers. + +**Syntax:** + +``` {.assembly} +display picture:int [, y:int, x:int] +``` + +**Functionality:** + +The `display` opcode displays the picture with the specified ID number +(`picture`) at the given coordinates (`y`, `x`) in pixels: + +- **`picture`:** The ID number of the picture to display. +- **`y` and `x` (optional):** The coordinates where the picture + should be displayed, relative to the top-left corner of the + current window. If omitted, the opcode uses the current cursor + position. + +**Special Cases:** + +- If the picture ID is 0, the opcode does nothing. +- If the coordinates are outside the window's boundaries, the + picture may be clipped or partially displayed. + +**Error Conditions:** + +An error occurs if: + +- `picture` is not a valid picture ID. +- The coordinates (`y`, `x`) are outside the window's boundaries. + +**Examples:** + +``` {.assembly} +display 10, 10, 10 ; Displays picture 10 at coordinates (10, 10) in the current window +display 5 ; Displays picture 5 at the current cursor position +``` + +**Use Cases:** + +- Displaying images and graphics on the screen. +- Creating visual elements for the game world or user interface. + +**Note:** The `DISPLAY` opcode requires the interpreter to support +picture display. The `MODE` byte in the program header indicates +whether the `DISPLAY` operation is available. + +### DIV + +**DIV** is an opcode that performs integer division on two 16-bit word +values. It divides the first operand by the second operand and returns +the truncated quotient. + +**Syntax:** + +``` {.assembly} +div arg1:int, arg2:int > val +``` + +**Functionality:** + +The `div` opcode performs the following: + +- **Divides `arg1` by `arg2`:** Performs integer division, + discarding any remainder. +- **Stores the result:** The quotient is stored in the specified + destination (`val`). If no destination is provided, the result is + pushed onto the game stack. + +**Special Cases:** + +- Division by zero results in an error. + +**Error Conditions:** + +An error occurs if `arg2` is zero. + +**Examples:** + +``` {.assembly} +div 10, 2 > result ; Divides 10 by 2, stores the quotient (5) in `result` +``` + +**Use Cases:** + +- Performing integer division calculations. +- Scaling values or calculating ratios. + +**Note:** The `div` opcode performs integer division, meaning it +discards any remainder. For operations that require the remainder, use +the `MOD` opcode. + +### DLESS? + +**DLESS?** is an opcode that decrements a variable and then checks if +the new value is less than a specified integer. It acts as a +predicate, meaning it evaluates a condition and implicitly performs a +conditional branch based on the result. + +**Syntax:** + +``` {.assembly} +dless? var, int /pred +``` + +**Functionality:** + +The `dless?` opcode performs the following: + +- **Decrements `var`:** Subtracts 1 from the value of the variable + `var`. +- **Compares with `int`:** Checks if the new value of `var` is less + than `int`. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the new value of `var` is indeed less than `int`. + Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +dless? counter, 0 / end_loop ; Branch to `end_loop` if `counter` is decremented to a value less than 0 +``` + +**Use Cases:** + +- Implementing loops or conditional statements that depend on + decrementing a variable and comparing it to a threshold. +- Optimizing code by combining decrement and comparison operations + into a single instruction. + +**Note:** The `dless?` opcode is a useful tool for writing efficient +and concise code when dealing with decrementing variables and +comparisons. + +### EQUAL? + +**EQUAL?** is an opcode that checks whether its first operand is equal +to any of the subsequent operands. It acts as a predicate, meaning it +evaluates a condition and implicitly performs a conditional branch +based on the result. + +**Syntax:** + +``` {.assembly} +equal? arg1:any, arg2:any [, arg3:any ...] /pred +``` + +**Functionality:** + +The `equal?` opcode performs the following: + +- **Compares `arg1` with other arguments:** Checks if `arg1` is + equal to any of the `arg2`, `arg3`, etc., operands. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if `arg1` is equal to at least one of the other arguments. + Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- The `equal?` opcode can take a variable number of operands in the + extended (`EXT`) format. The 2OP format is limited to two + operands. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +equal? object, "sword", "axe" / handle_weapon ; Branch to `handle_weapon` if `object` is equal to either "sword" or "axe" +``` + +**Use Cases:** + +- Implementing conditional logic based on equality comparisons. +- Checking if a variable or object matches one of several possible + values. + +**Note:** The `equal?` opcode is a versatile tool for performing +equality checks and implementing conditional behavior based on the +results. + +### ERASE + +**ERASE** is an opcode that erases a portion of the current window, +filling it with the current background color. + +**Syntax:** + +``` {.assembly} +erase int +``` + +**Functionality:** + +The `erase` opcode erases a section of the current window based on the +value of `int`: + +- **`int` = 1:** Erases from the current cursor position to the end + of the line. +- **`int` \> 1:** Erases a rectangular area starting at the current + cursor position, with a width of `int` pixels and a height equal + to the current font height. The erased area does not extend past + the right edge of the window. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +erase 1 ; Erases from the cursor to the end of the line +erase 20 ; Erases a 20-pixel wide rectangle starting at the cursor +``` + +**Use Cases:** + +- Erasing text or graphics from the screen. +- Clearing portions of the window for new output. + +**Note:** The `ERASE` opcode is used to selectively erase parts of the +window. For clearing the entire window, use the `CLEAR` opcode. + +### EXTOP + +**EXTOP** is an opcode that signals to the interpreter that the next +byte is an extended opcode. Extended opcodes are part of an additional +set of 256 instructions beyond the standard opcode set. + +**Syntax:** + +``` {.assembly} +extop opcode:int +``` + +**Functionality:** + +The `extop` opcode itself does not perform any operation. Instead, it +indicates that the following byte (`opcode`) should be interpreted as +an extended opcode. The interpreter adds 256 to the value of `opcode` +to obtain the actual extended opcode number. + +**Special Cases:** + +- The `extop` opcode is never explicitly used by programmers. It is + generated by the assembler when encoding instructions that require + the extended format. + +**Error Conditions:** + +An error occurs if `opcode` is not a valid extended opcode number. + +**Examples:** + +The `extop` opcode is not used directly in assembly code. It is +handled internally by the assembler and interpreter. + +**Use Cases:** + +The `extop` opcode allows ZAP to generate a wider range of +instructions while maintaining backward compatibility with older ZIP +interpreters that only recognize the standard opcode set. + +**Note:** The `extop` opcode is a low-level mechanism used by the +assembler and interpreter to handle extended opcodes. Programmers do +not need to be concerned with its usage directly. + +### FCLEAR + +**FCLEAR** is an opcode that clears a specific flag within an object's +flag list. Objects have 48 one-bit flags that can be used to track +their state or attributes. + +**Syntax:** + +``` {.assembly} +fclear obj, flag +``` + +**Functionality:** + +The `fclear` opcode sets the specified flag (`flag`) in the object +(`obj`) to 0. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `flag` is not within the valid range (0-47). + +**Examples:** + +``` {.assembly} +fclear player, 10 ; Clears flag number 10 in the "player" object +``` + +**Use Cases:** + +- Resetting flags or attributes associated with objects. +- Changing the state of objects based on game logic or player + actions. + +**Note:** The `FCLEAR` opcode is used to clear individual flags within +an object. To set a flag, use the `FSET` opcode. + +### FIRST? + +**FIRST?** is an opcode that retrieves the "first" property of an +object and checks if it is non-zero. It acts as a predicate, meaning +it evaluates a condition and implicitly performs a conditional branch +based on the result. + +**Syntax:** + +``` {.assembly} +first? obj > val /pred +``` + +**Functionality:** + +The `first?` opcode performs the following: + +- **Retrieves "first" property:** Gets the value of the "first" slot + within the object (`obj`). This slot typically contains the object + number of the first object contained within `obj`. +- **Checks for non-zero value:** Evaluates to true if the retrieved + value is not zero (meaning there is a "first" object). Otherwise, + it evaluates to false. +- **Stores the value (optional):** If the `> val` operand is + provided, the retrieved value is also stored in the specified + variable. +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- If the object `obj` does not have any contained objects, the + "first" slot will be zero, and the predicate will fail. + +**Error Conditions:** + +An error occurs if `obj` is not a valid object number. + +**Examples:** + +``` {.assembly} +first? container > first_item / process_item ; Branch to `process_item` if `container` has a "first" object +``` + +**Use Cases:** + +- Checking if an object contains other objects. +- Iterating through a chain of objects linked by their "next" + properties. +- Implementing inventory management or object interaction logic. + +**Note:** The `FIRST?` opcode is used to access and check the "first" +property of an object. To retrieve the "next" property in a chain, use +the `NEXT?` opcode. + +### FONT + +**FONT** is an opcode that selects a font for text output in a +specified window. Fonts determine the style and appearance of the +displayed text. + +**Syntax:** + +``` {.assembly} +font font:int, window:int > val +``` + +**Functionality:** + +The `font` opcode sets the font for the specified window (`window`) to +the font identified by `font`: + +- **`font`:** The ID number of the font to select. +- **`window`:** The window number where the font should be applied. + +The opcode returns the ID number of the previously selected font for +the window. + +**Special Cases:** + +- If the `window` argument is omitted, the current window is used. +- Font 1 is typically the "normal" font for the machine and is + selected by default for all windows. +- Some interpreters may not support all font IDs or may have + different fonts available. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `font` is not a valid font ID. + +**Examples:** + +``` {.assembly} +font 4, 0 ; Selects the monospace font for the main window (window 0) +font 2, 3 ; Selects font 2 for window 3 +``` + +**Use Cases:** + +- Changing the appearance of text for visual distinction or + emphasis. +- Displaying text in different styles, such as bold, italic, or + monospace. +- Enhancing the game's visual presentation and atmosphere. + +**Note:** The `FONT` opcode requires the interpreter to support font +selection. The `MODE` byte in the program header indicates whether the +`FONT` operation is available. + +### FSET + +**FSET** is an opcode that sets a specific flag within an object's +flag list to 1. Objects have 48 one-bit flags that can be used to +track their state or attributes. + +**Syntax:** + +``` {.assembly} +fset obj, flag +``` + +**Functionality:** + +The `fset` opcode sets the specified flag (`flag`) in the object +(`obj`) to 1. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `flag` is not within the valid range (0-47). + +**Examples:** + +``` {.assembly} +fset player, 5 ; Sets flag number 5 in the "player" object to 1 +``` + +**Use Cases:** + +- Setting flags or attributes associated with objects. +- Changing the state of objects based on game logic or player + actions. + +**Note:** The `FSET` opcode is used to set individual flags within an +object. To clear a flag, use the `FCLEAR` opcode. + +### FSET? + +**FSET?** is an opcode that checks whether a specific flag is set +within an object's flag list. It acts as a predicate, meaning it +evaluates a condition and implicitly performs a conditional branch +based on the result. + +**Syntax:** + +``` {.assembly} +fset? obj, flag /pred +``` + +**Functionality:** + +The `fset?` opcode performs the following: + +- **Checks flag state:** Determines whether the specified flag + (`flag`) in the object (`obj`) is set (1) or cleared (0). +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the flag is set. Otherwise, the predicate fails + (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +None. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `flag` is not within the valid range (0-47). + +**Examples:** + +``` {.assembly} +fset? player, 15 / handle_flag ; Branch to `handle_flag` if flag number 15 in the "player" object is set +``` + +**Use Cases:** + +- Implementing conditional logic based on the state of object flags. +- Checking for specific object attributes or conditions. + +**Note:** The `FSET?` opcode is used to test the state of individual +flags within an object. To set or clear a flag, use the `FSET` or +`FCLEAR` opcodes, respectively. + +### FSTACK + +**FSTACK** is an opcode that flushes (removes) a specified number of +elements from a stack. It can be used to clear the game stack or a +user-defined stack. + +**Syntax:** + +``` {.assembly} +fstack n [, stack:tbl] +``` + +**Functionality:** + +The `fstack` opcode removes elements from a stack as follows: + +- **`n`:** The number of elements to flush from the stack. +- **`stack` (optional):** A pointer to a table representing a + user-defined stack. If omitted, the opcode flushes elements from + the game stack. + +The opcode does not return any value. + +**Special Cases:** + +- Flushing more elements than are present on the stack is an error. + +**Error Conditions:** + +An error occurs if: + +- `n` is negative. +- `stack` is not a valid table pointer (if provided). +- Attempting to flush more elements than are present on the stack. + +**Examples:** + +``` {.assembly} +fstack 3 ; Flushes 3 elements from the game stack +fstack 2, user_stack ; Flushes 2 elements from the `user_stack` table +``` + +**Use Cases:** + +- Clearing the game stack before calling a function or performing a + specific operation. +- Resetting user-defined stacks to a known state. + +**Note:** The `FSTACK` opcode is used to remove elements from stacks. +To add elements, use the `PUSH` or `XPUSH` opcodes. + +### GET + +**GET** is an opcode that retrieves the value of an element from a +word-oriented table. It is used to access data stored in tables based +on their index or offset. + +**Syntax:** + +``` {.assembly} +get table, item > val +``` + +**Functionality:** + +The `get` opcode performs the following: + +- **Calculates element address:** Multiplies the `item` (index or + offset) by 2 and adds it to the base address of the `table`. This + gives the address of the desired element in memory. +- **Retrieves the value:** Reads the word value at the calculated + address. +- **Stores the result:** The retrieved value is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +- Table offsets are zero-based, meaning the first element has an + index of 0. +- The interpreter does not perform bounds checking on table + accesses. It is the programmer's responsibility to ensure that + `item` is within the valid range of the table. + +**Error Conditions:** + +An error may occur if: + +- `table` is not a valid table pointer. +- `item` is outside the bounds of the table. + +**Examples:** + +``` {.assembly} +get inventory, 3 > item ; Retrieves the 4th element from the `inventory` table and stores it in `item` +``` + +**Use Cases:** + +- Accessing data stored in tables based on their index or offset. +- Implementing data structures and algorithms that rely on table + lookups. + +**Note:** The `GET` opcode is used for accessing word-sized elements +in tables. For byte-sized elements, use the `GETB` opcode. + +### GETB + +**GETB** is an opcode that retrieves the value of an element from a +byte-oriented table. It is used to access data stored in tables based +on their index or offset. + +**Syntax:** + +``` {.assembly} +getb table, item > val +``` + +**Functionality:** + +The `getb` opcode performs the following: + +- **Calculates element address:** Adds the `item` (index or offset) + to the base address of the `table`. This gives the address of the + desired element in memory. +- **Retrieves the value:** Reads the byte value at the calculated + address. +- **Converts to word:** The retrieved byte value is converted to a + word (two bytes). +- **Stores the result:** The word value is stored in the specified + destination (`val`). If no destination is provided, the result is + pushed onto the game stack. + +**Special Cases:** + +- Table offsets are zero-based, meaning the first element has an + index of 0. +- The interpreter does not perform bounds checking on table + accesses. It is the programmer's responsibility to ensure that + `item` is within the valid range of the table. + +**Error Conditions:** + +An error may occur if: + +- `table` is not a valid table pointer. +- `item` is outside the bounds of the table. + +**Examples:** + +``` {.assembly} +getb text_buffer, 5 > char ; Retrieves the 6th byte from the `text_buffer` table and stores it as a word in `char` +``` + +**Use Cases:** + +- Accessing data stored in byte-oriented tables. +- Reading individual characters from text buffers. +- Implementing data structures and algorithms that rely on + byte-level table access. + +**Note:** The `GETB` opcode is used for accessing byte-sized elements +in tables. For word-sized elements, use the `GET` opcode. + +### GETP + +**GETP** is an opcode that retrieves the value of a property from an +object. Properties are used to associate additional data and +attributes with objects. + +**Syntax:** + +``` {.assembly} +getp obj, prop > val +``` + +**Functionality:** + +The `getp` opcode performs the following: + +- **Locates property table:** Finds the property table associated + with the object (`obj`). +- **Searches for property:** Searches the property table for the + property with the specified number (`prop`). +- **Retrieves the value:** If the property is found, its value is + retrieved. +- **Handles default properties:** If the property is not found in + the object's property table, the opcode retrieves the default + value from the default property table. +- **Stores the result:** The retrieved value is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +- Properties are stored in a sorted order within the object's + property table. +- The `GETP` opcode can only be used to retrieve properties with a + length of 1 or 2 bytes. For properties of arbitrary length, use + the `GETPT` opcode. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `prop` is not within the valid range (1-63). + +**Examples:** + +``` {.assembly} +getp player, 1 > strength ; Retrieves the value of property 1 ("strength") from the "player" object +``` + +**Use Cases:** + +- Accessing data associated with objects through properties. +- Retrieving object attributes or characteristics. + +**Note:** The `GETP` opcode is used to retrieve properties with a +length of 1 or 2 bytes. For properties of arbitrary length, use the +`GETPT` opcode. + +### GETPT + +**GETPT** is an opcode that retrieves a pointer to a property within +an object's property table. Unlike `GETP`, which can only retrieve +properties of 1 or 2 bytes, `GETPT` can access properties of any +length. + +**Syntax:** + +``` {.assembly} +getpt obj, prop > val +``` + +**Functionality:** + +The `getpt` opcode performs the following: + +- **Locates property table:** Finds the property table associated + with the object (`obj`). +- **Searches for property:** Searches the property table for the + property with the specified number (`prop`). +- **Retrieves the pointer:** If the property is found, a pointer to + its value is retrieved. +- **Handles default properties:** If the property is not found in + the object's property table, the opcode retrieves a pointer to the + default value from the default property table. +- **Stores the result:** The retrieved pointer is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +- Properties are stored in a sorted order within the object's + property table. +- The retrieved pointer can be used as a table pointer in other + table operations like `GET`, `GETB`, `PUT`, and `PUTB`. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `prop` is not within the valid range (1-63). + +**Examples:** + +``` {.assembly} +getpt object, 10 > prop_ptr ; Retrieves a pointer to property 10 of `object` +getb prop_ptr, 0 > first_byte ; Retrieves the first byte of the property value +``` + +**Use Cases:** + +- Accessing properties of arbitrary length. +- Implementing data structures or algorithms that require accessing + variable-length properties. + +**Note:** The `GETPT` opcode is used to retrieve pointers to +properties, while `GETP` is used to directly retrieve property values +of 1 or 2 bytes. + +### GRTR? + +**GRTR?** is an opcode that compares two integer values and checks if +the first operand is greater than the second operand. It acts as a +predicate, meaning it evaluates a condition and implicitly performs a +conditional branch based on the result. + +**Syntax:** + +``` {.assembly} +grtr? arg1:int, arg2:int /pred +``` + +**Functionality:** + +The `grtr?` opcode performs the following: + +- **Compares `arg1` and `arg2`:** Checks if the integer value `arg1` + is greater than `arg2`. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if `arg1` is indeed greater than `arg2`. Otherwise, the + predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +grtr? health, 0 / game_over ; Branch to `game_over` if `health` is greater than 0 +``` + +**Use Cases:** + +- Implementing conditional logic based on greater-than comparisons. +- Making decisions based on numerical values, such as health, score, + or inventory counts. + +**Note:** The `grtr?` opcode is a basic comparison operator used for +implementing conditional behavior in Z-code programs. + +### HLIGHT + +**HLIGHT** is an opcode that sets the highlighting mode for subsequent +text output. Highlighting can be used to emphasize text, change its +appearance, or create special visual effects. + +**Syntax:** + +``` {.assembly} +hlight int +``` + +**Functionality:** + +The `hlight` opcode sets the highlighting mode based on the value of +`int`: + +- **`int` = 0:** No highlighting (normal text). +- **`int` = 1:** Inverse video (text and background colors are + swapped). +- **`int` = 2:** Bold text. +- **`int` = 4:** Underline or italic text + (implementation-dependent). +- **`int` = 8:** Monospaced font. + +**Special Cases:** + +- The availability of highlighting modes depends on the capabilities + of the interpreter and the target machine. +- The `MODE` byte in the program header specifies which highlighting + modes are supported. +- The monospace font mode may either select an actual monospaced + font or modify the display of a variable-width font to appear + monospaced. + +**Error Conditions:** + +An error occurs if `int` specifies an unsupported highlighting mode. + +**Examples:** + +``` {.assembly} +hlight 2 ; Sets bold text highlighting +print "Important message!" +hlight 0 ; Resets to normal text +``` + +**Use Cases:** + +- Emphasizing important text or messages. +- Creating visual distinctions between different types of text. +- Implementing special visual effects or text-based graphics. + +**Note:** Games should be designed to handle machines that do not +support all highlighting modes. The `MODE` byte can be used to check +which modes are available. + +### ICALL + +**ICALL** is an opcode that calls a function with three arguments but +does not return a value. It is similar to the `CALL` opcode but +optimized for situations where the function's return value is not +needed. + +**Syntax:** + +``` {.assembly} +icall routine:fcn, arg1:any, arg2:any, arg3:any +``` + +**Functionality:** + +The `icall` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the three arguments + (`arg1`, `arg2`, and `arg3`) onto the game stack. +- **Calls the function:** Transfers control to the function + specified by `routine`. The function address is calculated by + shifting `routine` left by two bits and adding the function offset + (`FOFF`) shifted left by three bits. +- **Does not retrieve return value:** When the function returns, its + return value is discarded. + +**Special Cases:** + +- If `routine` is zero, the `icall` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `routine` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +icall update_score, player, points, bonus ; Calls the `update_score` function without using its return value +``` + +**Use Cases:** + +- Calling functions where the return value is not needed, reducing + stack usage and potential stack overflows. +- Implementing subroutines or actions that do not produce a result. + +**Note:** The `icall` opcode is generated by the compiler when it +detects a function call where the return value is not used. It is not +typically used directly by programmers. + +### ICALL1 + +**ICALL1** is an opcode that calls a function with one argument but +does not return a value. It is similar to the `CALL1` opcode but +optimized for situations where the function's return value is not +needed. + +**Syntax:** + +``` {.assembly} +icall1 routine:fcn +``` + +**Functionality:** + +The `icall1` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the single argument + onto the game stack. +- **Calls the function:** Transfers control to the function + specified by `routine`. The function address is calculated by + shifting `routine` left by two bits and adding the function offset + (`FOFF`) shifted left by three bits. +- **Does not retrieve return value:** When the function returns, its + return value is discarded. + +**Special Cases:** + +- If `routine` is zero, the `icall1` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `routine` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +icall1 play_sound, sound_id ; Calls the `play_sound` function without using its return value +``` + +**Use Cases:** + +- Calling functions with a single argument where the return value is + not needed, reducing stack usage and potential stack overflows. +- Implementing subroutines or actions that do not produce a result. + +**Note:** The `icall1` opcode is generated by the compiler when it +detects a function call with one argument where the return value is +not used. It is not typically used directly by programmers. + +### ICALL2 + +**ICALL2** is an opcode that calls a function with two arguments but +does not return a value. It is similar to the `CALL2` opcode but +optimized for situations where the function's return value is not +needed. + +**Syntax:** + +``` {.assembly} +icall2 routine:fcn, arg:any +``` + +**Functionality:** + +The `icall2` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the two arguments + (`routine` and `arg`) onto the game stack. +- **Calls the function:** Transfers control to the function + specified by `routine`. The function address is calculated by + shifting `routine` left by two bits and adding the function offset + (`FOFF`) shifted left by three bits. +- **Does not retrieve return value:** When the function returns, its + return value is discarded. + +**Special Cases:** + +- If `routine` is zero, the `icall2` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `routine` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +icall2 set_color, foreground, background ; Calls the `set_color` function without using its return value +``` + +**Use Cases:** + +- Calling functions with two arguments where the return value is not + needed, reducing stack usage and potential stack overflows. +- Implementing subroutines or actions that do not produce a result. + +**Note:** The `icall2` opcode is generated by the compiler when it +detects a function call with two arguments where the return value is +not used. It is not typically used directly by programmers. + +### IGRTR? + +**IGRTR?** is an opcode that increments a variable and then checks if +the new value is greater than a specified integer. It acts as a +predicate, meaning it evaluates a condition and implicitly performs a +conditional branch based on the result. + +**Syntax:** + +``` {.assembly} +igrtr? var, int /pred +``` + +**Functionality:** + +The `igrtr?` opcode performs the following: + +- **Increments `var`:** Adds 1 to the value of the variable `var`. +- **Compares with `int`:** Checks if the new value of `var` is + greater than `int`. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the new value of `var` is indeed greater than `int`. + Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +igrtr? counter, limit / overflow ; Branch to `overflow` if `counter` is incremented to a value greater than `limit` +``` + +**Use Cases:** + +- Implementing loops or conditional statements that depend on + incrementing a variable and comparing it to a threshold. +- Optimizing code by combining increment and comparison operations + into a single instruction. + +**Note:** The `igrtr?` opcode is a useful tool for writing efficient +and concise code when dealing with incrementing variables and +comparisons. + +### IN? + +**IN?** is an opcode that checks whether one object is contained +within another object. It acts as a predicate, meaning it evaluates a +condition and implicitly performs a conditional branch based on the +result. + +**Syntax:** + +``` {.assembly} +in? child:obj, parent:obj /pred +``` + +**Functionality:** + +The `in?` opcode performs the following: + +- **Checks containment:** Compares the `LOC` property of the `child` + object with the object number of the `parent` object. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the `LOC` of `child` is equal to `parent`, meaning + `child` is contained within `parent`. Otherwise, the predicate + fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- An object is considered to be contained within itself. + +**Error Conditions:** + +An error occurs if `child` or `parent` is not a valid object number. + +**Examples:** + +``` {.assembly} +in? item, player / take_item ; Branch to `take_item` if `item` is contained within the "player" object +``` + +**Use Cases:** + +- Implementing inventory management and object interaction logic. +- Checking the location of objects within the game world. +- Determining containment relationships between objects. + +**Note:** The `IN?` opcode is a fundamental operation for working with +object hierarchies and containment in Z-code programs. + +### INC + +**INC** is an opcode that increments the value of a variable by 1. + +**Syntax:** + +``` {.assembly} +inc var +``` + +**Functionality:** + +The `inc` opcode adds 1 to the value of the specified variable +(`var`). + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +inc counter ; Increments the value of the variable `counter` +``` + +**Use Cases:** + +- Incrementing counters or loop variables. +- Increasing the value of a variable by a fixed amount. + +**Note:** The `inc` opcode is a convenient way to increment a variable +by 1. For more complex arithmetic operations, use the `ADD` opcode. + +### INPUT + +**INPUT** is an opcode that reads a single byte of input from a +specified device, typically the keyboard. It allows the Z-code program +to receive input from the user or other input sources. + +**Syntax:** + +``` {.assembly} +input dev:int [, time:int, routine:fcn] > val +``` + +**Functionality:** + +The `input` opcode reads input based on the value of `dev`: + +- **`dev` = 1:** Keyboard input (default). The opcode reads the next + key pressed by the user and returns its ASCII value. +- **Other values of `dev`:** May be used for other input devices, + but their behavior is implementation-dependent. + +**Optional Arguments:** + +- **`time`:** Specifies a timeout value in tenths of a second. If no + input is received within the specified time, the interpreter calls + the `routine` function. +- **`routine`:** A function to call when a timeout occurs. The + function should return true (1) to abort the input operation or + false (0) to continue waiting for input. + +**Return Value:** + +The `input` opcode returns the value of the input byte, which is +stored in the specified destination (`val`). If no destination is +provided, the value is pushed onto the game stack. + +**Special Cases:** + +- Function keys and other special keys may return values greater + than 127, with the high bit of the byte set. +- The interpreter may handle timeout behavior differently depending + on the target machine and implementation. + +**Error Conditions:** + +An error occurs if: + +- `dev` is not a valid device code. +- `time` is negative (if provided). +- `routine` is not a valid function pointer (if provided). + +**Examples:** + +``` {.assembly} +input 1 > key ; Reads a key from the keyboard and stores its ASCII value in `key` +input 1, 50, handle_timeout > key ; Reads a key with a 5-second timeout +``` + +**Use Cases:** + +- Getting input from the user, such as commands, responses, or key + presses. +- Implementing timed input or interactive sequences. + +**Note:** The `INPUT` opcode is a fundamental operation for receiving +input in Z-code programs. The specific behavior and available devices +may vary depending on the interpreter and target machine. + +### INTBL? + +**INTBL?** is an opcode that searches for a specific item within a +table and returns a pointer to its location if found. It acts as both +an opcode and a predicate, meaning it can return a value and also +influence control flow based on the search result. + +**Syntax:** + +``` {.assembly} +intbl? item, table, length:int [, record-spec:int] > val /pred +``` + +**Functionality:** + +The `intbl?` opcode performs the following: + +- **Searches for `item`:** Looks for the specified `item` within the + `table`. +- **Table length:** The `length` argument specifies the number of + elements to search within the table. +- **Record specification (optional):** The `record-spec` argument, + if provided, defines the format of each element in the table. It + is a byte value where: + - The high-order bit indicates whether the table elements are + words (1) or bytes (0). + - The low-order seven bits specify the length of each element in + bytes. +- **Returns a pointer:** If `item` is found, the opcode returns a + pointer to its location within the table. Otherwise, it returns 0. +- **Stores the result (optional):** If the `> val` operand is + provided, the returned pointer is also stored in the specified + variable. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if `item` is found in the table. Otherwise, the predicate + fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- If `record-spec` is omitted or 0, it defaults to 130 + (word-oriented elements with a length of 2 bytes). + +**Error Conditions:** + +An error occurs if: + +- `table` is not a valid table pointer. +- `length` is negative. + +**Examples:** + +``` {.assembly} +intbl? "north", directions, 4 > direction_ptr / handle_direction ; Searches for "north" in the `directions` table +intbl? char, buffer, buffer_length, 1 > char_ptr / process_char ; Searches for `char` in a byte-oriented buffer +``` + +**Use Cases:** + +- Searching for specific elements within tables. +- Implementing data structures and algorithms that require table + lookups. +- Performing conditional logic based on search results. + +**Note:** The `INTBL?` opcode is a versatile tool for searching tables +and implementing conditional behavior based on the results. The +optional `record-spec` argument allows for searching tables with +different element formats. + +### IRESTORE + +**IRESTORE** is an opcode that restores the game state from a +previously saved copy in memory. It is used to implement a +single-level undo functionality. + +**Syntax:** + +``` {.assembly} +irestore > val +``` + +**Functionality:** + +The `irestore` opcode restores the game state from a copy of the +impure area that was previously saved using the `ISAVE` opcode. The +impure area contains all modifiable data in the Z-code program, +including global variables, object flags, and table contents. + +**Return Value:** + +The `irestore` opcode returns 0 if it fails or if the instruction is +not implemented on the target machine. Otherwise, it returns -1. + +**Special Cases:** + +- The `IRESTORE` opcode only works if a previous `ISAVE` operation + was successful. +- The interpreter may not implement the `ISAVE` and `IRESTORE` + opcodes on all machines. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +isave ; Saves the current game state +; ... some actions that modify the game state ... +irestore ; Restores the previously saved game state +``` + +**Use Cases:** + +- Implementing an undo feature in the game. +- Restoring the game state to a previous point after an error or + unexpected event. + +**Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple +mechanism for implementing undo functionality. However, they are not +supported on all interpreters and may require additional memory +resources. + +### ISAVE + +**ISAVE** is an opcode that saves a copy of the current game state in +memory. It is used in conjunction with the `IRESTORE` opcode to +implement a single-level undo functionality. + +**Syntax:** + +``` {.assembly} +isave > val +``` + +**Functionality:** + +The `isave` opcode copies the impure area of the Z-code program to a +reserved section of memory. The impure area contains all modifiable +data, including global variables, object flags, and table contents. + +**Return Value:** + +The `isave` opcode returns 0 if it fails or if the instruction is not +implemented on the target machine. Otherwise, it returns -1. + +**Special Cases:** + +- The interpreter may not implement the `ISAVE` and `IRESTORE` + opcodes on all machines. +- The reserved memory area for storing the saved game state may have + limited size. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +isave ; Saves the current game state +; ... some actions that modify the game state ... +irestore ; Restores the previously saved game state +``` + +**Use Cases:** + +- Implementing an undo feature in the game. +- Saving the game state before performing an action that might have + unintended consequences. + +**Note:** The `ISAVE` and `IRESTORE` opcodes provide a simple +mechanism for implementing undo functionality. However, they are not +supported on all interpreters and may require additional memory +resources. + +### IXCALL + +**IXCALL** is an opcode that calls a function with a variable number +of arguments but does not return a value. It is similar to the `XCALL` +opcode but optimized for situations where the function's return value +is not needed. + +**Syntax:** + +``` {.assembly} +ixcall routine:fcn, arg1:any [, arg2:any ...] +``` + +**Functionality:** + +The `ixcall` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the variable number of + arguments (`arg1`, `arg2`, etc.) onto the game stack. The number + of arguments is determined by the operand types specified in the + instruction. +- **Calls the function:** Transfers control to the function + specified by `routine`. The function address is calculated by + shifting `routine` left by two bits and adding the function offset + (`FOFF`) shifted left by three bits. +- **Does not retrieve return value:** When the function returns, its + return value is discarded. + +**Special Cases:** + +- If `routine` is zero, the `ixcall` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `routine` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +ixcall print_list, item1, item2, item3 ; Calls the `print_list` function with three arguments +``` + +**Use Cases:** + +- Calling functions with a variable number of arguments where the + return value is not needed, reducing stack usage and potential + stack overflows. +- Implementing functions that take a flexible number of arguments. + +**Note:** The `ixcall` opcode is generated by the compiler when it +detects a function call with a variable number of arguments where the +return value is not used. It is not typically used directly by +programmers. + +### JUMP + +**JUMP** is an opcode that performs an unconditional relative jump to +a specified location within the program. It is used to control the +flow of execution and implement loops or conditional branching. + +**Syntax:** + +``` {.assembly} +jump offset:loc +``` + +**Functionality:** + +The `jump` opcode performs the following: + +- **Calculates target address:** Adds the `offset` value to the + address of the next instruction. This gives the target address of + the jump. +- **Jumps to target:** Transfers control to the calculated target + address. + +**Special Cases:** + +- The `offset` value is a signed 16-bit integer, allowing for both + forward and backward jumps within the program. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +jump start_loop ; Jumps to the label `start_loop` +jump -5 ; Jumps back 5 instructions +``` + +**Use Cases:** + +- Implementing loops by jumping back to the beginning of the loop + code. +- Performing conditional branching by jumping to different sections + of code based on the results of predicates. +- Creating subroutines or functions by jumping to their starting + addresses. + +**Note:** The `JUMP` opcode is a fundamental control flow instruction +used to direct the execution of Z-code programs. + +### LESS? + +**LESS?** is an opcode that compares two integer values and checks if +the first operand is less than the second operand. It acts as a +predicate, meaning it evaluates a condition and implicitly performs a +conditional branch based on the result. + +**Syntax:** + +``` {.assembly} +less? arg1:int, arg2:int /pred +``` + +**Functionality:** + +The `less?` opcode performs the following: + +- **Compares `arg1` and `arg2`:** Checks if the integer value `arg1` + is less than `arg2`. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if `arg1` is indeed less than `arg2`. Otherwise, the + predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +less? count, 10 / continue_loop ; Branch to `continue_loop` if `count` is less than 10 +``` + +**Use Cases:** + +- Implementing conditional logic based on less-than comparisons. +- Making decisions based on numerical values, such as health, score, + or inventory counts. + +**Note:** The `less?` opcode is a basic comparison operator used for +implementing conditional behavior in Z-code programs. + +### LEX + +**LEX** is an opcode that parses the contents of an input buffer and +looks up the words in a vocabulary table. It is similar to the parsing +phase of the `READ` opcode but offers more flexibility in choosing the +vocabulary. + +**Syntax:** + +``` {.assembly} +lex inbuf:tbl, lexv:tbl [, lexicon:tbl, preserve:bool] +``` + +**Functionality:** + +The `lex` opcode performs the following: + +- **Parses input buffer:** Reads the contents of the `inbuf` table, + which is assumed to contain a string of text. +- **Tokenizes words:** Breaks the text into individual words based + on whitespace and self-inserting break characters defined in the + vocabulary. +- **Looks up words:** Searches for each word in the specified + `lexicon` table. If `lexicon` is omitted, the default vocabulary + table (pointed to by the `VOCAB` word in the program header) is + used. +- **Stores results:** For each word, the opcode stores the following + information in the `lexv` table: + - A pointer to the word entry in the vocabulary table (or 0 if + not found). + - The length of the word in bytes. + - The byte offset of the word within the input buffer. +- **Preserves existing entries (optional):** If the `preserve` + argument is provided and non-zero, the opcode does not modify + entries in `lexv` for words that are not found in the vocabulary. + +**Special Cases:** + +- The `lexv` table must have enough space to store the parsing + results. +- The format of the `lexv` table is specific to the Z-machine and is + used by other opcodes like `PRINTC` to reprint words from the + input buffer. + +**Error Conditions:** + +An error occurs if: + +- `inbuf` or `lexv` is not a valid table pointer. +- `lexicon` is not a valid table pointer (if provided). +- The `lexv` table does not have enough space to store the parsing + results. + +**Examples:** + +``` {.assembly} +lex input_buffer, parsed_words ; Parses `input_buffer` using the default vocabulary +lex input_buffer, parsed_words, special_vocab, 1 ; Parses using `special_vocab` and preserves existing entries +``` + +**Use Cases:** + +- Parsing player input and looking up words in a vocabulary. +- Implementing custom parsers or natural language processing + routines. +- Using multiple vocabularies for different contexts or situations. + +**Note:** The `LEX` opcode provides more flexibility than the parsing +phase of the `READ` opcode by allowing the programmer to specify the +vocabulary table. + +### LOC + +**LOC** is an opcode that retrieves the "parent" object of a given +object. Objects in Z-code programs are organized in a hierarchical +structure, where each object can be contained within another object. + +**Syntax:** + +``` {.assembly} +loc obj > val +``` + +**Functionality:** + +The `loc` opcode retrieves the object number of the object that +contains the specified object (`obj`). This is done by reading the +value of the `LOC` property of `obj`. + +- **Stores the result:** The retrieved object number is stored in + the specified destination (`val`). If no destination is provided, + the result is pushed onto the game stack. + +**Special Cases:** + +- If the object `obj` is not contained within any other object + (i.e., it is a top-level object), the `LOC` property will be 0, + and the opcode will return 0. + +**Error Conditions:** + +An error occurs if `obj` is not a valid object number. + +**Examples:** + +``` {.assembly} +loc item > container ; Retrieves the object number of the container that holds `item` +``` + +**Use Cases:** + +- Determining the location of objects within the game world. +- Implementing inventory management and object interaction logic. +- Traversing the object hierarchy to find related objects. + +**Note:** The `LOC` opcode is used to navigate the object hierarchy +and determine containment relationships between objects. + +### MARGIN + +**MARGIN** is an opcode that sets the left and right margins for text +output in a window. Margins control the horizontal spacing of text +within the window. + +**Syntax:** + +``` {.assembly} +margin left:int, right:int [, window:int] +``` + +**Functionality:** + +The `margin` opcode sets the margins for the specified window +(`window`) as follows: + +- **`left`:** The width of the left margin in pixels. +- **`right`:** The width of the right margin in pixels. + +The opcode stores the margin values in the `LMRG` and `RMRG` words +associated with the window. + +**Special Cases:** + +- If the `window` argument is omitted, the current window is used. +- Margins only affect windows that have text wrapping enabled. +- The opcode must be executed before any text is buffered for the + current line. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `left` or `right` is negative. + +**Examples:** + +``` {.assembly} +margin 10, 20 ; Sets a 10-pixel left margin and a 20-pixel right margin in the current window +``` + +**Use Cases:** + +- Indenting text within a window. +- Creating visual distinctions between different sections of text. +- Implementing custom text formatting or layout. + +**Note:** The `MARGIN` opcode is used to control the horizontal +spacing of text within windows. It is important to consider the +window's wrapping attribute and the timing of the opcode execution. + +### MENU + +**MENU** is an opcode that adds or removes a menu from the menu bar. +This feature is currently only supported on the Macintosh platform. + +**Syntax:** + +``` {.assembly} +menu id, table /pred +``` + +**Functionality:** + +The `menu` opcode performs the following: + +- **Adds a menu (table is non-zero):** + - **`id`:** Specifies the slot in the menu bar where the menu + should be added. Slots 0, 1, and 2 are reserved for the Apple + menu, File menu, and Edit menu, respectively. + - **`table`:** A pointer to an LTABLE containing the menu data. + The first element of the table is the menu name, and + subsequent elements are the menu items. +- **Removes a menu (table is zero):** + - **`id`:** Specifies the slot of the menu to remove. + +**Predicate Behavior:** + +The `menu` opcode also acts as a predicate: + +- **Success:** The predicate succeeds if the menu was successfully + added or removed. +- **Failure:** The predicate fails if there is no room in the menu + bar for the new menu or if the specified menu ID is invalid. + +**Special Cases:** + +- The `MENU` opcode is only supported on the Macintosh platform. +- The interpreter must have the `%FMENU` flag set in the `FLAGS` + word to indicate support for menus. + +**Error Conditions:** + +An error occurs if: + +- The interpreter does not support menus. +- `id` is not a valid menu slot number. +- `table` is not a valid table pointer (when adding a menu). + +**Examples:** + +``` {.assembly} +menu 3, my_menu / check_menu ; Adds `my_menu` to the menu bar in slot 3 +menu 3, 0 ; Removes the menu from slot 3 +``` + +**Use Cases:** + +- Creating custom menus for user interaction. +- Providing additional options or commands within the game + interface. + +**Note:** The `MENU` opcode is platform-specific and requires +interpreter support. It is important to check the `FLAGS` word before +using this opcode. + +### MOD + +**MOD** is an opcode that performs modulo operation on two 16-bit word +values. It divides the first operand by the second operand and returns +the remainder. + +**Syntax:** + +``` {.assembly} +mod arg1:int, arg2:int > val +``` + +**Functionality:** + +The `mod` opcode performs the following: + +- **Divides `arg1` by `arg2`:** Performs integer division. +- **Calculates the remainder:** Determines the remainder of the + division. +- **Stores the result:** The remainder is stored in the specified + destination (`val`). If no destination is provided, the result is + pushed onto the game stack. + +**Special Cases:** + +- Modulo by zero results in an error. + +**Error Conditions:** + +An error occurs if `arg2` is zero. + +**Examples:** + +``` {.assembly} +mod 10, 3 > result ; Divides 10 by 3, stores the remainder (1) in `result` +``` + +**Use Cases:** + +- Calculating the remainder of a division. +- Implementing cyclic behavior or patterns. +- Performing operations based on the position within a cycle. + +**Note:** The `mod` opcode is used to obtain the remainder of an +integer division. For operations that require the quotient, use the +`DIV` opcode. + +### MOUSE-INFO + +**MOUSE-INFO** is an opcode that retrieves information about the +current state of the mouse and stores it in a table. This information +includes the mouse cursor position, button status, and any selected +menu items. + +**Syntax:** + +``` {.assembly} +mouse-info table +``` + +**Functionality:** + +The `mouse-info` opcode fills the specified `table` with the following +information: + +- **Word 0:** Y coordinate of the mouse cursor (row number, in + screen units). +- **Word 1:** X coordinate of the mouse cursor (column number, in + screen units). +- **Word 2:** Button status. Each bit represents a mouse button, + with bit 1 corresponding to the rightmost button. A set bit + indicates that the button is currently pressed. +- **Word 3:** Menu/item selection. The high byte contains the menu + number (1 for the default menu), and the low byte contains the + selected item number within that menu. + +**Special Cases:** + +- The `table` argument must be a table with at least four words of + available space. +- The interpretation of button status and menu/item selection may + vary depending on the target machine and the number of buttons or + menus available. + +**Error Conditions:** + +An error occurs if: + +- `table` is not a valid table pointer. +- The `table` does not have enough space to store the mouse + information (at least four words). + +**Examples:** + +``` {.assembly} +mouse-info mouse_data ; Retrieves the current mouse state +``` + +**Use Cases:** + +- Implementing mouse-based interaction and controls. +- Tracking the mouse cursor position for display or game logic + purposes. +- Handling mouse button clicks and menu selections. + +**Note:** The `MOUSE-INFO` opcode requires the interpreter to support +mouse input. The `%FMOUS` flag in the `FLAGS` word indicates whether +mouse operations are available. + +### MOUSE-LIMIT + +**MOUSE-LIMIT** is an opcode that restricts the movement of the mouse +cursor to a specific window. This can be used to confine mouse +interactions to a particular area of the screen. + +**Syntax:** + +``` {.assembly} +mouse-limit window:int +``` + +**Functionality:** + +The `mouse-limit` opcode restricts the mouse cursor movement to the +specified window (`window`). The interpreter, if possible, will +prevent the cursor from moving outside the boundaries of that window. +Mouse events, such as button clicks or movements, will only be +reported if the cursor is within the limited window. + +**Special Cases:** + +- **`window` = -1:** Removes any mouse cursor restrictions, allowing + it to move freely across the entire screen. +- Initially, the mouse cursor is assumed to be limited to window 1. + +**Error Conditions:** + +An error occurs if `window` is not within the valid range (-1 to 7). + +**Examples:** + +``` {.assembly} +mouse-limit 0 ; Limits the mouse cursor to the main window (window 0) +mouse-limit -1 ; Removes mouse cursor restrictions +``` + +**Use Cases:** + +- Confining mouse interactions to a specific area of the screen, + such as a menu or game window. +- Preventing accidental clicks or movements outside the intended + interaction area. + +**Note:** The ability to limit the mouse cursor may vary depending on +the capabilities of the interpreter and the target machine. + +### MOVE + +**MOVE** is an opcode that moves an object from one location to +another within the object hierarchy. Objects in Z-code programs are +organized in a tree structure, where each object can be contained +within another object. + +**Syntax:** + +``` {.assembly} +move thing:obj, dest:obj +``` + +**Functionality:** + +The `move` opcode moves the object `thing` into the object `dest`: + +- **Checks for existing containment:** If `thing` is already + contained within `dest`, the opcode does nothing. +- **Removes from previous location:** If `thing` is contained within + another object, it is removed from that object's containment + chain. +- **Adds to new location:** The `LOC` property of `thing` is set to + the object number of `dest`, and `thing` is added as the first + object in `dest`'s containment chain. This means the `FIRST` + property of `dest` will now point to `thing`. + +**Special Cases:** + +- If `dest` is 0, the `thing` object is effectively removed from the + object hierarchy, as its `LOC` property is set to 0. + +**Error Conditions:** + +An error occurs if: + +- `thing` or `dest` is not a valid object number. + +**Examples:** + +``` {.assembly} +move sword, player ; Moves the "sword" object into the "player" object's inventory +move box, room ; Moves the "box" object into the "room" object +``` + +**Use Cases:** + +- Implementing inventory management and object interaction. +- Changing the location of objects within the game world. +- Updating the object hierarchy based on game logic or player + actions. + +**Note:** The `MOVE` opcode is a fundamental operation for +manipulating the object hierarchy and managing object containment in +Z-code programs. + +### MUL + +**MUL** is an opcode that performs multiplication on two 16-bit word +values. It multiplies the first operand by the second operand and +returns the result. + +**Syntax:** + +``` {.assembly} +mul arg1:int, arg2:int > val +``` + +**Functionality:** + +The `mul` opcode performs the following: + +- **Multiplies `arg1` by `arg2`:** Performs integer multiplication. +- **Stores the result:** The product is stored in the specified + destination (`val`). If no destination is provided, the result is + pushed onto the game stack. + +**Special Cases:** + +- If the result of the multiplication overflows the 16-bit word + size, an error occurs. + +**Error Conditions:** + +An error occurs if the multiplication result overflows the 16-bit word +range. + +**Examples:** + +``` {.assembly} +mul 5, 10 > result ; Multiplies 5 by 10, stores the product (50) in `result` +``` + +**Use Cases:** + +- Performing integer multiplication calculations. +- Scaling values or calculating areas and volumes. + +**Note:** The `mul` opcode performs signed integer multiplication. If +the operands are unsigned, the programmer needs to handle potential +overflow conditions. + +### NEXT? + +**NEXT?** is an opcode that retrieves the "next" property of an object +and checks if it is non-zero. It acts as a predicate, meaning it +evaluates a condition and implicitly performs a conditional branch +based on the result. + +**Syntax:** + +``` {.assembly} +next? obj > val /pred +``` + +**Functionality:** + +The `next?` opcode performs the following: + +- **Retrieves "next" property:** Gets the value of the "next" slot + within the object (`obj`). This slot typically contains the object + number of the next object in a linked chain. +- **Checks for non-zero value:** Evaluates to true if the retrieved + value is not zero (meaning there is a "next" object). Otherwise, + it evaluates to false. +- **Stores the value (optional):** If the `> val` operand is + provided, the retrieved value is also stored in the specified + variable. +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- If the object `obj` is the last object in a chain, the "next" slot + will be zero, and the predicate will fail. + +**Error Conditions:** + +An error occurs if `obj` is not a valid object number. + +**Examples:** + +``` {.assembly} +next? item > next_item / process_item ; Branch to `process_item` if `item` has a "next" object in the chain +``` + +**Use Cases:** + +- Iterating through a chain of objects linked by their "next" + properties. +- Implementing inventory management or object interaction logic. + +**Note:** The `NEXT?` opcode is used to access and check the "next" +property of an object. To retrieve the "first" property in a chain, +use the `FIRST?` opcode. + +### NEXTP + +**NEXTP** is an opcode that retrieves the number of the property +following a specified property within an object's property table. It +is used to iterate through the properties of an object. + +**Syntax:** + +``` {.assembly} +nextp obj, prop > val +``` + +**Functionality:** + +The `nextp` opcode performs the following: + +- **Locates property table:** Finds the property table associated + with the object (`obj`). +- **Searches for property:** Searches the property table for the + property with the specified number (`prop`). +- **Finds next property:** If the property is found, the opcode + determines the number of the next property in the table. +- **Handles circularity:** If `prop` is the last property in the + table, the opcode returns the number of the first property, + creating a circular iteration. +- **Stores the result:** The retrieved property number is stored in + the specified destination (`val`). If no destination is provided, + the result is pushed onto the game stack. + +**Special Cases:** + +- If `prop` is 0, the opcode returns the number of the first + property in the table. +- Properties are stored in a sorted order within the object's + property table. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `prop` is not a valid property number within the object's property + table. + +**Examples:** + +``` {.assembly} +nextp object, 5 > next_prop ; Retrieves the number of the property following property 5 in `object` +``` + +**Use Cases:** + +- Iterating through the properties of an object. +- Implementing generic routines that need to access all properties + of an object. + +**Note:** The `NEXTP` opcode provides a way to navigate through the +properties of an object in a circular manner. It is important to +handle the case where the last property is reached and the opcode +returns the first property number. + +### ORIGINAL? + +**ORIGINAL?** is an opcode that checks whether the game is running +from the original distribution disk. It acts as a predicate, meaning +it evaluates a condition and implicitly performs a conditional branch +based on the result. + +**Syntax:** + +``` {.assembly} +original? /pred +``` + +**Functionality:** + +The `original?` opcode checks if the game is running from the original +distribution disk. The specific method for determining originality is +implementation-dependent and may vary between interpreters. + +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the game is determined to be running from the original + disk. Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +The implementation of originality checking is left to the interpreter. + +- Checking for specific files or data on the disk. +- Comparing checksums or other validation data. +- Using copy protection mechanisms. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +original? / display_warning ; Branch to `display_warning` if the game is not running from the original disk +``` + +### NOOP + +**NOOP** is an opcode that performs no operation. It is essentially a +placeholder instruction that does nothing and simply advances the +program counter to the next instruction. + +**Syntax:** + +``` {.assembly} +noop +``` + +**Functionality:** + +The `noop` opcode has no effect on the program state or data. It +simply increments the program counter, causing the interpreter to move +on to the next instruction in the sequence. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +noop ; Does nothing +``` + +**Use Cases:** + +- Aligning code or data to specific memory locations. +- Providing a placeholder for future instructions or as a debugging + aid. +- Implementing timing delays or loops with empty bodies. + +**Note:** The `NOOP` opcode is rarely used in typical Z-code programs +but can be helpful in specific situations where a placeholder or delay +is needed. + +### PICINF + +**PICINF** is an opcode that retrieves information about a picture, +such as its dimensions. Pictures are images stored in a separate +picture file and referenced by their ID numbers. + +**Syntax:** + +``` {.assembly} +picinf picture:int, data:tbl /pred +``` + +**Functionality:** + +The `picinf` opcode retrieves information about the specified picture +(`picture`) and stores it in the `data` table: + +- **Word 0 of `data`:** The width of the picture in pixels. +- **Word 1 of `data`:** The height of the picture in pixels. + +**Predicate Behavior:** + +The `picinf` opcode also acts as a predicate: + +- **Success:** The predicate succeeds if the picture ID is valid and + the information is successfully retrieved. +- **Failure:** The predicate fails if the picture ID is invalid. + +**Special Cases:** + +- If the picture ID is 0, the opcode stores the highest picture ID + in the picture library (the number of pictures) in word 0 of the + `data` table. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +picinf 10, pic_data / handle_picture ; Retrieves information about picture 10 +picinf 0, pic_data > num_pictures ; Retrieves the number of pictures in the library +``` + +**Use Cases:** + +- Determining the dimensions of a picture before displaying it. +- Implementing custom picture handling or display routines. +- Checking the validity of a picture ID. + +**Note:** The `PICINF` opcode is used in conjunction with the +`DISPLAY` and `DCLEAR` opcodes to manage the display of pictures +within Z-code programs. + +### PICSET + +**PICSET** is an opcode that defines a group of pictures that should +be loaded together from the picture file. This can be used to optimize +picture loading and reduce disk access times. + +**Syntax:** + +``` {.assembly} +picset picture:int, count:int +``` + +**Functionality:** + +The `picset` opcode defines a group of pictures starting from the +specified picture ID (`picture`) and including the next `count` +pictures. The interpreter should attempt to load all pictures in the +group from the picture file simultaneously, reducing the need for +multiple disk accesses. + +**Special Cases:** + +- All pictures within a group must be located in the same picture + file. +- If the interpreter does not support picture grouping, the opcode + should be ignored. + +**Error Conditions:** + +An error occurs if: + +- `picture` is not a valid picture ID. +- `count` is negative. + +**Examples:** + +``` {.assembly} +picset 10, 5 ; Defines a group of 5 pictures starting from picture ID 10 +``` + +**Use Cases:** + +- Optimizing picture loading by grouping related pictures together. +- Reducing disk access times in multi-disk games. + +**Note:** The `PICSET` opcode is an optimization feature that may not +be supported by all interpreters. It is important to check the +interpreter's capabilities before using this opcode. + +### POP + +**POP** is an opcode that removes the top element from a stack and +returns its value. It can be used to retrieve values from the game +stack or a user-defined stack. + +**Syntax:** + +``` {.assembly} +pop [, stack:tbl] > val +``` + +**Functionality:** + +The `pop` opcode removes the top element from the specified stack and +returns its value: + +- **Game stack (default):** If the `stack` argument is omitted, the + opcode pops the top element from the game stack. +- **User-defined stack:** If the `stack` argument is provided, the + opcode pops the top element from the table pointed to by `stack`. + +**Return Value:** + +The popped value is stored in the specified destination (`val`). If no +destination is provided, the value is pushed onto the game stack. + +**Special Cases:** + +- Attempting to pop from an empty stack is an error. + +**Error Conditions:** + +An error occurs if: + +- `stack` is not a valid table pointer (if provided). +- The stack is empty. + +**Examples:** + +``` {.assembly} +pop > value ; Pops the top element from the game stack and stores it in `value` +pop user_stack > value ; Pops the top element from `user_stack` +``` + +**Use Cases:** + +- Retrieving values from the game stack or user-defined stacks. +- Implementing stack-based data structures and algorithms. + +**Note:** The `POP` opcode is used to remove and retrieve elements +from stacks. To add elements, use the `PUSH` or `XPUSH` opcodes. + +### PRINT + +**PRINT** is an opcode that prints a string to the screen. It is used +to display text output in the current window. + +**Syntax:** + +``` {.assembly} +print str +``` + +**Functionality:** + +The `print` opcode prints the string pointed to by `str`. The string +address is calculated by shifting `str` left by two bits and adding +the string offset (`SOFF`) shifted left by three bits. + +**Special Cases:** + +- The `str` argument is a quad-pointer, meaning it points to a + string that is aligned to a quad-byte boundary in the string area. +- The string area is located in a separate section of the Z-code + program and is accessed using the `SOFF` value. +- Strings are encoded in a special 5-bit byte format for efficient + storage. + +**Error Conditions:** + +An error occurs if `str` is not a valid string pointer. + +**Examples:** + +``` {.assembly} +.gstr "message", "Hello, world!" +print message ; Prints the "message" string +``` + +**Use Cases:** + +- Displaying text output to the user. +- Printing messages, prompts, or descriptions. + +**Note:** The `PRINT` opcode is used to print strings from the string +area. For printing strings within tables or as immediate operands, use +the `PRINTB` opcode. + +### PRINTB + +**PRINTB** is an opcode that prints a string from a table or an +immediate string operand. It is used to display text output that is +not stored in the string area. + +**Syntax:** + +``` {.assembly} +printb str +``` + +**Functionality:** + +The `printb` opcode prints the string pointed to by `str`. The string +can be: + +- **A string within a table:** The `str` argument is a byte pointer + to the beginning of the string within a table. +- **An immediate string operand:** The string is directly encoded + within the instruction as a sequence of bytes. + +**Special Cases:** + +- The `printb` opcode is typically used for printing shorter strings + or strings that are dynamically generated. +- Strings printed with `printb` are not subject to the string offset + (`SOFF`) adjustment. + +**Error Conditions:** + +An error occurs if `str` is not a valid string pointer or if the +immediate string operand is malformed. + +**Examples:** + +``` {.assembly} +printb vocabulary[word_index] ; Prints the word from the vocabulary table at the specified index +printb "This is an immediate string." ; Prints the immediate string +``` + +**Use Cases:** + +- Printing strings from tables, such as vocabulary entries or text + buffers. +- Displaying short messages or prompts that do not need to be stored + in the string area. + +**Note:** The `PRINTB` opcode is used for printing strings that are +not located in the string area. For printing strings from the string +area, use the `PRINT` opcode. + +### PRINTC + +**PRINTC** is an opcode that prints a word from the game's vocabulary +table. It is typically used to reprint words that were previously +parsed from player input. + +**Syntax:** + +``` {.assembly} +printc text-char +``` + +**Functionality:** + +The `printc` opcode performs the following: + +- **Looks up word:** Uses the value of `text-char` as an index into + the vocabulary table (pointed to by the `VOCAB` word in the + program header). +- **Retrieves word data:** If the index is valid, the opcode + retrieves the word data from the vocabulary table. This data + includes the encoded Z-string representation of the word and its + length. +- **Prints the word:** Decodes the Z-string and prints the + corresponding characters to the screen. + +**Special Cases:** + +- The `text-char` argument is typically obtained from the `lexv` + table, which is filled by the `READ` or `LEX` opcodes during input + parsing. +- The format of the vocabulary table entries is specific to the + Z-machine and is defined by the `.VOCBEG` directive. + +**Error Conditions:** + +An error occurs if: + +- `text-char` is not a valid index into the vocabulary table. + +**Examples:** + +``` {.assembly} +read input_buffer, lexv +printc lexv[1] ; Prints the second word from the parsed input +``` + +**Use Cases:** + +- Reprinting words that were previously entered by the player. +- Implementing text-based menus or displays that use words from the + game's vocabulary. + +**Note:** The `PRINTC` opcode is used to print words from the +vocabulary table. For printing arbitrary strings, use the `PRINT` or +`PRINTB` opcodes. + +### PRINTD + +**PRINTD** is an opcode that prints the short description of an +object. Objects in Z-code programs can have a short description +associated with them, which is typically used for providing a brief +textual representation of the object. + +**Syntax:** + +``` {.assembly} +printd obj +``` + +**Functionality:** + +The `printd` opcode performs the following: + +- **Locates object:** Finds the object with the specified object + number (`obj`). +- **Retrieves short description:** Accesses the object's property + table and retrieves the value of the `DESC` property, which + contains the short description. +- **Prints the description:** Decodes the Z-string representation of + the short description and prints the corresponding characters to + the screen. + +**Special Cases:** + +- If the object does not have a `DESC` property, the opcode does + nothing. +- The short description is typically a short string encoded in the + Z-machine's 5-bit byte format. + +**Error Conditions:** + +An error occurs if `obj` is not a valid object number. + +**Examples:** + +``` {.assembly} +printd player ; Prints the short description of the "player" object +``` + +**Use Cases:** + +- Displaying a brief description of an object to the player. +- Providing context or information about objects in the game world. + +**Note:** The `PRINTD` opcode is a convenient way to print the short +description associated with an object. For printing other properties +or arbitrary strings, use the `GETP`, `GETPT`, `PRINT`, or `PRINTB` +opcodes. + +### PRINTF + +**PRINTF** is an opcode that prints a formatted table to the screen. +Formatted tables allow for more flexible text layout and can include +variable-length lines, different fonts, and highlighting. + +**Syntax:** + +``` {.assembly} +printf table +``` + +**Functionality:** + +The `printf` opcode prints the contents of the specified `table` as a +formatted block of text. The table format is as follows: + +- **Line length indicators:** Each line of text is preceded by a + word (two bytes) that specifies the number of characters in that + line. +- **Character data:** The characters of each line are stored as + consecutive bytes. +- **End of table marker:** A word with the value 0 marks the end of + the table. + +The opcode interprets the line length indicators and character data to +print the text with the appropriate formatting, including line breaks +and potential justification. + +**Special Cases:** + +- Formatted tables are typically generated using the `DIROUT 3` + opcode with the `just` argument to specify justification. +- The `printf` opcode can handle tables with variable-length lines, + different fonts, and highlighting. + +**Error Conditions:** + +An error occurs if: + +- `table` is not a valid table pointer. +- The table format is invalid. + +**Examples:** + +``` {.assembly} +dirout 3, formatted_text, 80 ; Redirects output to `formatted_text` with right justification at 80 pixels +; ... generate formatted text ... +dirout -3 +printf formatted_text ; Prints the formatted table +``` + +**Use Cases:** + +- Displaying text with custom formatting and layout. +- Creating menus or dialog boxes with variable-length lines and + different styles. +- Implementing text-based graphics or visual effects. + +**Note:** The `PRINTF` opcode provides a more flexible way to display +text compared to the `PRINT` or `PRINTB` opcodes. It is particularly +useful for situations where precise control over text layout and +formatting is required. + +### PRINTI + +**PRINTI** is an opcode that prints an immediate string directly +encoded within the instruction. It is used to display short, fixed +messages or prompts without the need to define them as separate +strings in the string area. + +**Syntax:** + +``` {.assembly} +printi "string" +``` + +**Functionality:** + +The `printi` opcode decodes and prints the string literal `"string"` +that is included directly within the instruction. + +**Special Cases:** + +- The string literal must be enclosed in double quotes (`"`). +- Double quotes within the string are escaped by using two + consecutive double quotes. + +**Error Conditions:** + +An error occurs if the string literal is malformed or not properly +terminated. + +**Examples:** + +``` {.assembly} +printi "Hello, world!" ; Prints the string "Hello, world!" +printi "He said, ""Hello!""" ; Prints the string "He said, "Hello!"" +``` + +**Use Cases:** + +- Printing short, fixed messages or prompts. +- Displaying error messages or debugging information. + +**Note:** The `PRINTI` opcode is a convenient way to print short +strings without the overhead of defining them as separate entities in +the string area. However, for longer or more complex strings, using +the `PRINT` or `PRINTB` opcodes with strings defined using `.STR` or +`.GSTR` is more efficient. + +### PRINTN + +**PRINTN** is an opcode that prints a signed integer value as a +decimal number. It is used to display numerical values on the screen. + +**Syntax:** + +``` {.assembly} +printn number:int +``` + +**Functionality:** + +The `printn` opcode converts the signed integer value `number` into a +decimal string representation and prints it to the current window. + +**Special Cases:** + +- Negative numbers are printed with a leading minus sign (`-`). +- The number is printed using the current font and highlighting + settings. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +printn score ; Prints the value of the variable `score` as a decimal number +printn -10 ; Prints the number -10 +``` + +**Use Cases:** + +- Displaying numerical values, such as scores, health points, or + inventory counts. +- Printing the results of calculations or comparisons. + +**Note:** The `PRINTN` opcode is used to print signed integer values. +For printing unsigned values or values in other formats, use the +`PRINT` or `PRINTB` opcodes with appropriate string formatting. + +### PRINTR + +**PRINTR** is an opcode that prints an immediate string and then +performs a carriage return and line feed (CRLF), effectively moving +the cursor to the beginning of the next line. It also implicitly +returns true from the current function. + +**Syntax:** + +``` {.assembly} +printr "string" +``` + +**Functionality:** + +The `printr` opcode performs the following: + +1. **Prints the string:** Decodes and prints the string literal + `"string"` that is included directly within the instruction. +2. **Outputs CRLF:** Prints a carriage return and line feed sequence, + moving the cursor to the beginning of the next line. +3. **Returns true:** Implicitly returns the value 1 (true) from the + current function. + +**Special Cases:** + +- The string literal must be enclosed in double quotes (`"`). +- Double quotes within the string are escaped by using two + consecutive double quotes. + +**Error Conditions:** + +An error occurs if the string literal is malformed or not properly +terminated. + +**Examples:** + +``` {.assembly} +printr "Game over!" ; Prints "Game over!" and then returns true, ending the current function +``` + +**Use Cases:** + +- Printing a final message or prompt before ending the current + function. +- Displaying error messages or debugging information and then + returning from the function. + +**Note:** The `PRINTR` opcode combines string printing, line +termination, and function return into a single operation. It is a +convenient way to print a message and then exit the current function. + +### PRINTT + +**PRINTT** is an opcode that prints a rectangular block of text from a +byte-oriented table. It allows for flexible formatting and display of +text data. + +**Syntax:** + +``` {.assembly} +printt bytes:tbl, width:int, height:int [, skip:int] +``` + +**Functionality:** + +The `printt` opcode prints a block of text from the specified table +(`bytes`) according to the given dimensions and skip value: + +- **`bytes`:** A pointer to a byte-oriented table containing the + text data. +- **`width`:** The width of the text block in columns (number of + characters per line). +- **`height`:** The height of the text block in lines. +- **`skip` (optional):** The number of bytes to skip at the end of + each line. This allows for printing rectangular blocks from within + larger tables. If omitted, the default skip value is 0. + +The opcode prints the text line by line, wrapping to the next line +when the `width` is reached. After each line, it skips `skip` bytes in +the table before starting the next line. + +**Special Cases:** + +- If the `skip` argument is 0, the opcode prints a continuous block + of text without skipping any bytes. +- The `printt` opcode does not perform any character set decoding or + string interpretation. It simply prints the raw bytes from the + table. + +**Error Conditions:** + +An error occurs if: + +- `bytes` is not a valid table pointer. +- `width` or `height` is zero or negative. +- `skip` is negative. + +**Examples:** + +``` {.assembly} +printt text_buffer, 80, 24 ; Prints a 24-line block of text from `text_buffer`, 80 characters per line +printt table, 10, 5, 20 ; Prints a 5-line block from `table`, 10 characters per line, skipping 20 bytes after each line +``` + +**Use Cases:** + +- Displaying formatted text from tables. +- Printing text-based graphics or user interface elements. +- Implementing custom text layout and formatting. + +**Note:** The `PRINTT` opcode provides a flexible way to print text +from tables. It is important to ensure that the table format and +dimensions are correct to avoid unexpected output. + +### PTSIZE + +**PTSIZE** is an opcode that returns the size of a property table in +bytes. Property tables are associated with objects and contain +additional data and attributes. + +**Syntax:** + +``` {.assembly} +ptsize table > val +``` + +**Functionality:** + +The `ptsize` opcode calculates the size of the property table pointed +to by `table` and stores the result in the specified destination +(`val`). If no destination is provided, the result is pushed onto the +game stack. + +**Special Cases:** + +- The `ptsize` opcode is typically used with property tables + obtained using the `GETPT` opcode. +- The opcode assumes that the property table has the correct format, + with properties stored in a sorted order and appropriate length + indicators. + +**Error Conditions:** + +An error may occur if `table` is not a valid property table pointer or +if the table format is invalid. + +**Examples:** + +``` {.assembly} +getpt object, 10 > prop_ptr ; Retrieves a pointer to property 10 of `object` +ptsize prop_ptr > prop_size ; Calculates the size of the property value +``` + +**Use Cases:** + +- Determining the size of a property value before accessing or + manipulating it. +- Implementing routines that need to handle properties of varying + lengths. + +**Note:** The `PTSIZE` opcode is used to determine the size of +property tables. It is important to ensure that the table pointer is +valid and the table format is correct. + +### PUSH + +**PUSH** is an opcode that pushes a value onto the game stack. The +game stack is a LIFO (Last-In-First-Out) data structure used to store +temporary values and function arguments. + +**Syntax:** + +``` {.assembly} +push value +``` + +**Functionality:** + +The `push` opcode pushes the specified `value` onto the top of the +game stack. + +**Special Cases:** + +- Pushing a value onto a full stack results in a stack overflow + error. + +**Error Conditions:** + +An error occurs if the game stack is full. + +**Examples:** + +``` {.assembly} +push 5 ; Pushes the value 5 onto the stack +push var1 ; Pushes the value of the variable `var1` onto the stack +``` + +**Use Cases:** + +- Storing temporary values during calculations or operations. +- Passing arguments to functions. +- Implementing stack-based data structures and algorithms. + +**Note:** The `PUSH` opcode is used to add elements to the game stack. +To remove elements, use the `POP` or `FSTACK` opcodes. + +### PUT + +**PUT** is an opcode that stores a word value into a specified element +of a word-oriented table. It is used to modify data stored in tables +based on their index or offset. + +**Syntax:** + +``` {.assembly} +put table, item, value +``` + +**Functionality:** + +The `put` opcode performs the following: + +- **Calculates element address:** Multiplies the `item` (index or + offset) by 2 and adds it to the base address of the `table`. This + gives the address of the desired element in memory. +- **Stores the value:** Writes the word value `value` to the + calculated address. + +**Special Cases:** + +- Table offsets are zero-based, meaning the first element has an + index of 0. +- The interpreter does not perform bounds checking on table + accesses. It is the programmer's responsibility to ensure that + `item` is within the valid range of the table. + +**Error Conditions:** + +An error may occur if: + +- `table` is not a valid table pointer. +- `item` is outside the bounds of the table. + +**Examples:** + +``` {.assembly} +put inventory, 3, "sword" ; Stores the word "sword" in the 4th element of the `inventory` table +``` + +**Use Cases:** + +- Modifying data stored in tables based on their index or offset. +- Implementing data structures and algorithms that require updating + table values. + +**Note:** The `PUT` opcode is used for storing word-sized elements in +tables. For byte-sized elements, use the `PUTB` opcode. + +### PUTB + +**PUTB** is an opcode that stores a byte value into a specified +element of a byte-oriented table. It is used to modify data stored in +tables based on their index or offset. + +**Syntax:** + +``` {.assembly} +putb table, item, value +``` + +**Functionality:** + +The `putb` opcode performs the following: + +- **Calculates element address:** Adds the `item` (index or offset) + to the base address of the `table`. This gives the address of the + desired element in memory. +- **Extracts byte value:** Takes the low-order byte of `value` as + the byte to be stored. +- **Stores the byte:** Writes the extracted byte value to the + calculated address. + +**Special Cases:** + +- Table offsets are zero-based, meaning the first element has an + index of 0. +- The interpreter does not perform bounds checking on table + accesses. It is the programmer's responsibility to ensure that + `item` is within the valid range of the table. +- The high-order byte of `value` is ignored. + +**Error Conditions:** + +An error may occur if: + +- `table` is not a valid table pointer. +- `item` is outside the bounds of the table. + +**Examples:** + +``` {.assembly} +putb text_buffer, 5, 'A' ; Stores the ASCII value of 'A' in the 6th byte of the `text_buffer` table +``` + +**Use Cases:** + +- Modifying data stored in byte-oriented tables. +- Writing individual characters to text buffers. +- Implementing data structures and algorithms that require updating + byte-level table values. + +**Note:** The `PUTB` opcode is used for storing byte-sized elements in +tables. For word-sized elements, use the `PUT` opcode. + +### PUTP + +**PUTP** is an opcode that sets the value of a property within an +object's property table. Properties are used to associate additional +data and attributes with objects. + +**Syntax:** + +``` {.assembly} +putp obj, prop, value +``` + +**Functionality:** + +The `putp` opcode modifies a property within an object's property +table: + +- **Locates property table:** Finds the property table associated + with the object (`obj`). +- **Searches for property:** Searches the property table for the + property with the specified number (`prop`). +- **Updates property value:** If the property is found, its value is + updated to `value`. +- **Error if property not found:** If the property is not found in + the object's property table, an error occurs. + +**Special Cases:** + +- The `PUTP` opcode can only be used to modify properties with a + length of 1 or 2 bytes. For properties of arbitrary length, use a + combination of `GETPT` and table manipulation opcodes. + +**Error Conditions:** + +An error occurs if: + +- `obj` is not a valid object number. +- `prop` is not a valid property number within the object's property + table. +- The property does not exist in the object's property table. + +**Examples:** + +``` {.assembly} +putp player, 1, 15 ; Sets the value of property 1 ("strength") in the "player" object to 15 +``` + +**Use Cases:** + +- Modifying data associated with objects through properties. +- Updating object attributes or characteristics based on game logic + or player actions. + +**Note:** The `PUTP` opcode is used to modify properties with a length +of 1 or 2 bytes. For properties of arbitrary length, use a combination +of `GETPT` and table manipulation opcodes. + +### QUIT + +**QUIT** is an opcode that terminates the execution of the Z-code +program. It is used to end the game or exit the interpreter. + +**Syntax:** + +``` {.assembly} +quit +``` + +**Functionality:** + +The `quit` opcode signals to the interpreter that the program should +terminate. The interpreter performs any necessary cleanup operations +and then exits. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +quit ; Terminates the program +``` + +**Use Cases:** + +- Ending the game when the player reaches a specific condition or + completes all objectives. +- Exiting the interpreter in response to a user command or error + condition. + +**Note:** The `QUIT` opcode is a terminal instruction that stops the +execution of the Z-code program. It is important to ensure that all +necessary cleanup or saving operations are performed before using this +opcode. + +### RANDOM + +**RANDOM** is an opcode that generates a random number within a +specified range. It is used to introduce randomness and +unpredictability into the game. + +**Syntax:** + +``` {.assembly} +random range:int > val +``` + +**Functionality:** + +The `random` opcode generates a random integer value between 1 and +`range` (inclusive) and stores it in the specified destination +(`val`). If no destination is provided, the result is pushed onto the +game stack. + +**Special Cases:** + +- **Negative `range`:** If `range` is negative, the opcode enters a + "predictable" mode. The absolute value of `range` is saved, and + subsequent calls to `random` with a positive range will generate + numbers in a sequence from 1 to the saved absolute value. +- **`range` = 0:** Resets the random number generator to its normal + (unpredictable) mode. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +random 6 > dice_roll ; Generates a random number between 1 and 6 +random -10 ; Enters predictable mode with a sequence of 1 to 10 +random 4 > next_num ; Generates the next number in the predictable sequence (e.g., 1, 2, 3, 4, 1, ...) +random 0 ; Resets to unpredictable mode +``` + +**Use Cases:** + +- Generating random events or outcomes in the game. +- Simulating dice rolls or other random processes. +- Introducing variability and replayability into the game + experience. + +**Note:** The implementation of the random number generator may vary +between interpreters. The predictable mode allows for testing and +debugging scenarios where consistent random values are desired. + +### READ + +**READ** is an opcode that reads a line of input from the user, parses +it into words, and looks up the words in the vocabulary table. It is a +fundamental operation for receiving player input and interpreting +commands. + +**Syntax:** + +``` {.assembly} +read text-buffer:tbl, parse-buffer:tbl [, time:int, routine:fcn] > val +``` + +**Functionality:** + +The `read` opcode performs the following: + +1. **Clears output buffer:** Prints and empties the current output + buffer, ensuring that any pending output is displayed before + reading input. +2. **Reads input:** Reads a line of text from the user, storing the + characters in the `text-buffer` table. The first byte of + `text-buffer` specifies the maximum length of the buffer, and the + second byte is used by the opcode to store the number of + characters read. +3. **Converts to lowercase:** Converts all uppercase letters in the + input to lowercase. +4. **Parses input (optional):** If `parse-buffer` is non-zero, the + opcode parses the input text into words and stores information + about each word in the `parse-buffer` table. The format of the + `parse-buffer` is specific to the Z-machine and is used by other + opcodes like `PRINTC` to reprint words from the input. +5. **Returns terminator:** The opcode returns the character that + terminated the input (e.g., newline, space, or a character from + the `TCHARS` table). This value is stored in the specified + destination (`val`). If no destination is provided, the value is + pushed onto the game stack. + +**Optional Arguments:** + +- **`time`:** Specifies a timeout value in tenths of a second. If no + input is received within the specified time, the interpreter calls + the `routine` function. +- **`routine`:** A function to call when a timeout occurs. The + function should return true (1) to abort the input operation or + false (0) to continue waiting for input. + +**Special Cases:** + +- The `TCHARS` table in the program header specifies which + characters can terminate input. +- The vocabulary table (pointed to by the `VOCAB` word) is used to + look up words during parsing. +- The interpreter may handle timeout behavior differently depending + on the target machine and implementation. + +**Error Conditions:** + +An error occurs if: + +- `text-buffer` or `parse-buffer` is not a valid table pointer. +- The `text-buffer` is not large enough to hold the input line. +- `time` is negative (if provided). +- `routine` is not a valid function pointer (if provided). + +**Examples:** + +``` {.assembly} +read input_buffer, parse_buffer > terminator ; Reads input and parses it into words +read input_buffer, 0 > terminator ; Reads input without parsing +``` + +**Use Cases:** + +- Getting input from the user, such as commands, responses, or text + entry. +- Implementing a text parser to interpret player commands. +- Handling timed input or interactive sequences. + +**Note:** The `READ` opcode is a fundamental operation for receiving +and processing player input in Z-code programs. + +### REMOVE + +**REMOVE** is an opcode that removes an object from the object +hierarchy. Objects in Z-code programs are organized in a tree +structure, where each object can be contained within another object. + +**Syntax:** + +``` {.assembly} +remove obj +``` + +**Functionality:** + +The `remove` opcode removes the specified object (`obj`) from the +object hierarchy: + +1. **Finds the containing object:** Determines the object that + currently contains `obj` by examining its `LOC` property. +2. **Updates containment chain:** Removes `obj` from the containment + chain of the containing object. This involves updating the `FIRST` + and `NEXT` properties of the objects in the chain. +3. **Clears object properties:** Sets the `LOC`, `FIRST`, and `NEXT` + properties of `obj` to 0, effectively removing it from the object + hierarchy. + +**Special Cases:** + +- If `obj` is not contained within any other object (i.e., it is a + top-level object), the opcode only clears its `LOC`, `FIRST`, and + `NEXT` properties. + +**Error Conditions:** + +An error occurs if `obj` is not a valid object number. + +**Examples:** + +``` {.assembly} +remove item ; Removes the `item` object from its container +``` + +**Use Cases:** + +- Implementing inventory management and object interaction. +- Removing objects from the game world when they are no longer + needed. +- Updating the object hierarchy based on game logic or player + actions. + +**Note:** The `REMOVE` opcode is used to remove objects from the +object hierarchy. It is important to ensure that the object is +properly removed from any containment chains to avoid dangling +references or memory leaks. + +### RESTART + +**RESTART** is an opcode that reinitializes the Z-code program and +restarts the game from the beginning. It is used to reset the game +state and start a new playthrough. + +**Syntax:** + +``` {.assembly} +restart +``` + +**Functionality:** + +The `restart` opcode performs the following: + +1. **Reloads the preloaded area:** The interpreter reloads the + portion of the game file that is below the `ENDLOD` address, which + includes all modifiable data and essential tables. +2. **Resets the game state:** All global variables, object flags, and + other modifiable data are reset to their initial values. +3. **Jumps to the start address:** The program counter is set to the + address specified by the `START` word in the program header, which + is typically the beginning of the main game function. + +**Special Cases:** + +- The `RESTART` opcode does not affect the state of the interpreter + itself, such as window configurations or display settings. +- The random number generator may or may not be reseeded, depending + on the interpreter implementation. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +restart ; Restarts the game +``` + +**Use Cases:** + +- Starting a new game from the beginning. +- Resetting the game state after an error or unexpected event. +- Implementing a "restart game" command for the player. + +**Note:** The `RESTART` opcode provides a way to reset the game state +and start a new playthrough. It is important to ensure that all +necessary data is properly reinitialized during the restart process. + +### RESTORE + +**RESTORE** is an opcode that restores a previously saved game state +from disk. It allows players to resume a game from a saved point. + +**Syntax:** + +``` {.assembly} +restore [, start:int, length:int, name:tbl] > val +``` + +**Functionality:** + +The `restore` opcode has two modes of operation: + +**1. Full Restore (no arguments):** + +- **Prompts for filename:** The interpreter typically prompts the + user to provide a filename or select a saved game file. +- **Reads saved data:** The interpreter reads the saved game data + from the specified file. +- **Restores game state:** The impure area of the Z-code program, + which includes global variables, object flags, and table contents, + is restored to the state it was in when the game was saved. +- **Continues execution:** The program resumes execution from the + point where it was saved. + +**2. Partial Restore (with arguments):** + +- **`start`:** The starting address of the memory region to restore. +- **`length`:** The length of the memory region to restore in bytes. +- **`name`:** A string specifying the name of the saved data. + +This mode allows for restoring specific sections of the impure area, +such as individual tables or groups of variables. + +**Return Value:** + +- **Full restore:** The opcode does not return a value. +- **Partial restore:** The opcode returns the number of bytes + successfully read from the saved data. + +**Special Cases:** + +- The format of the saved game data is specific to the Z-machine and + may vary depending on the interpreter implementation. +- The `RESTORE` opcode does not restore the state of the interpreter + itself, such as window configurations or display settings. +- The random number generator may or may not be reseeded, depending + on the interpreter implementation. + +**Error Conditions:** + +An error occurs if: + +- The specified saved game file cannot be found or opened. +- The saved game data is corrupted or invalid. +- The `start` or `length` arguments are invalid (in partial restore + mode). + +**Examples:** + +``` {.assembly} +restore ; Restores a saved game from a file +restore table_address, table_size, "my_table" ; Restores a specific table from saved data +``` + +**Use Cases:** + +- Allowing players to save and resume their progress in the game. +- Implementing checkpoint or save-game functionality. +- Restoring specific data structures or variables from saved data. + +**Note:** The `RESTORE` opcode is essential for providing save and +restore functionality in Z-code games. The specific implementation and +user interface for saving and loading games may vary depending on the +interpreter. + +### RETURN + +**RETURN** is an opcode that returns from the current function and +resumes execution in the calling function. It also allows for +specifying a return value. + +**Syntax:** + +``` {.assembly} +return value +``` + +**Functionality:** + +The `return` opcode performs the following: + +1. **Sets return value:** The specified `value` is set as the return + value of the function. +2. **Restores stack frame:** The interpreter restores the stack frame + of the calling function, including local variables, stack pointer, + and argument count. +3. **Resumes execution:** Control is transferred back to the + instruction following the `CALL` instruction that invoked the + current function. + +**Special Cases:** + +- If the current function was called using an `ICALL` variant (which + does not expect a return value), the `value` argument is ignored. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +return 5 ; Returns the value 5 from the function +return result ; Returns the value of the variable `result` +``` + +**Use Cases:** + +- Returning from functions and providing a result to the calling + function. +- Implementing subroutines and modular code structures. + +**Note:** The `RETURN` opcode is essential for controlling the flow of +execution between functions in Z-code programs. + +### RFALSE + +**RFALSE** is an opcode that returns the value 0 (false) from the +current function. It is typically used as a branch target for +predicate instructions that evaluate to false. + +**Syntax:** + +``` {.assembly} +rfalse +``` + +**Functionality:** + +The `rfalse` opcode sets the return value of the current function to 0 +and then returns control to the calling function. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +equal? object, "sword" / handle_sword +rfalse ; Returns false if the object is not a sword +``` + +**Use Cases:** + +- Returning false from a function when a condition is not met. +- Implementing conditional logic and branching based on predicate + results. + +**Note:** The `RFALSE` opcode is often used as a branch target for +predicate instructions that evaluate to false. It provides a +convenient way to return a false value and exit the current function. + +### RSTACK + +**RSTACK** is an opcode that returns from the current function and +uses the value on top of the stack as the return value. This allows +for a more flexible way to return values from functions without +explicitly specifying them in the `RETURN` instruction. + +**Syntax:** + +``` {.assembly} +rstack +``` + +**Functionality:** + +The `rstack` opcode performs the following: + +1. **Pops return value:** Removes the top element from the game stack + and uses it as the return value of the function. +2. **Restores stack frame:** The interpreter restores the stack frame + of the calling function, including local variables, stack pointer, + and argument count. +3. **Resumes execution:** Control is transferred back to the + instruction following the `CALL` instruction that invoked the + current function. + +**Special Cases:** + +- If the game stack is empty, a stack underflow error occurs. + +**Error Conditions:** + +An error occurs if the game stack is empty when the `RSTACK` opcode is +executed. + +**Examples:** + +``` {.assembly} +; ... function code that pushes a value onto the stack ... +rstack ; Returns the value from the top of the stack +``` + +**Use Cases:** + +- Returning values from functions without explicitly specifying them + in the `RETURN` instruction. +- Implementing functions that can return different types of values + depending on the context. + +**Note:** The `RSTACK` opcode provides a more flexible way to return +values from functions, but it is important to ensure that the stack +contains the correct value before using this opcode. + +### RTRUE + +**RTRUE** is an opcode that returns the value 1 (true) from the +current function. It is typically used as a branch target for +predicate instructions that evaluate to true. + +**Syntax:** + +``` {.assembly} +rtrue +``` + +**Functionality:** + +The `rtrue` opcode sets the return value of the current function to 1 +and then returns control to the calling function. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +equal? object, "sword" / handle_sword +rtrue ; Returns true if the object is a sword +``` + +**Use Cases:** + +- Returning true from a function when a condition is met. +- Implementing conditional logic and branching based on predicate + results. + +**Note:** The `RTRUE` opcode is often used as a branch target for +predicate instructions that evaluate to true. It provides a convenient +way to return a true value and exit the current function. + +### SAVE + +**SAVE** is an opcode that saves the current game state to disk, +allowing players to resume their progress later. + +**Syntax:** + +``` {.assembly} +save [, start:int, length:int, name:tbl] > val +``` + +**Functionality:** + +The `save` opcode has two modes of operation: + +**1. Full Save (no arguments):** + +- **Prompts for filename:** The interpreter typically prompts the + user to provide a filename or select a save game slot. +- **Writes game data:** The interpreter writes the current game + state to the specified file. This includes the contents of the + impure area, which contains all modifiable data such as global + variables, object flags, and table contents. +- **Returns status:** The opcode returns 0 if the save operation + fails and 1 if it succeeds. + +**2. Partial Save (with arguments):** + +- **`start`:** The starting address of the memory region to save. +- **`length`:** The length of the memory region to save in bytes. +- **`name`:** A string specifying a unique name for the saved data. + +This mode allows for saving specific sections of the impure area, such +as individual tables or groups of variables. + +**Return Value:** + +- **Full save:** Returns 0 if the save operation fails and 1 if it + succeeds. +- **Partial save:** Returns 2 to indicate successful completion. + +**Special Cases:** + +- The format of the saved game data is specific to the Z-machine and + may vary depending on the interpreter implementation. +- The `SAVE` opcode does not save the state of the interpreter + itself, such as window configurations or display settings. +- The random number generator seed is typically not saved to ensure + that restoring a saved game does not result in the same sequence + of random events. + +**Error Conditions:** + +An error occurs if: + +- The specified save game file cannot be created or written to. +- The `start` or `length` arguments are invalid (in partial save + mode). + +**Examples:** + +``` {.assembly} +save ; Saves the entire game state to a file +save table_address, table_size, "my_table" ; Saves a specific table to a file +``` + +**Use Cases:** + +- Allowing players to save their progress in the game. +- Implementing checkpoint or save-game functionality. +- Saving specific data structures or variables for later retrieval. + +**Note:** The `SAVE` opcode is essential for providing save and +restore functionality in Z-code games. The specific implementation and +user interface for saving and loading games may vary depending on the +interpreter. + +### SCREEN + +**SCREEN** is an opcode that selects the active window for subsequent +text output. Z-code programs can have multiple windows, each with its +own properties and display area. + +**Syntax:** + +``` {.assembly} +screen window:int +``` + +**Functionality:** + +The `screen` opcode sets the current window to the window specified by +`window`. All subsequent text output, including printing strings and +characters, will be directed to this window. + +**Special Cases:** + +- If the `window` argument is omitted, the current window remains + unchanged. +- Each window maintains its own cursor position and other + attributes. When switching between windows, the cursor position + and attributes of the previously active window are preserved. + +**Error Conditions:** + +An error occurs if `window` is not within the valid range (0 to 7). + +**Examples:** + +``` {.assembly} +screen 1 ; Switches to window 1 for output +print "This text will appear in window 1." +screen 0 ; Switches back to the main window (window 0) +``` + +**Use Cases:** + +- Managing multiple windows for displaying different types of + information or creating a more complex user interface. +- Implementing split-screen displays or separate areas for text + output. + +**Note:** The `SCREEN` opcode is used to control which window receives +text output. It is important to keep track of the current window and +switch between windows as needed to ensure that text is displayed in +the correct location. + +### SCROLL + +**SCROLL** is an opcode that scrolls the contents of a window up or +down by a specified number of lines. This can be used to create +scrolling text displays or to shift the contents of a window. + +**Syntax:** + +``` {.assembly} +scroll window:int, lines:int +``` + +**Functionality:** + +The `scroll` opcode scrolls the contents of the specified window +(`window`) by the number of lines indicated by `lines`: + +- **Positive `lines`:** Scrolls the window contents up by `lines` + lines. Blank lines are inserted at the bottom of the window, + filled with the current background color. +- **Negative `lines`:** Scrolls the window contents down by the + absolute value of `lines` lines. Lines at the top of the window + are removed. +- **`lines` = 0:** Has no effect. + +**Special Cases:** + +- The `scroll` opcode works on both scrolling and non-scrolling + windows. +- The cursor position is not affected by scrolling. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). + +**Examples:** + +``` {.assembly} +scroll 0, 1 ; Scrolls the main window (window 0) up by one line +scroll 2, -3 ; Scrolls window 2 down by three lines +``` + +**Use Cases:** + +- Creating scrolling text displays, such as status messages or + dialogue boxes. +- Shifting the contents of a window to make room for new output. +- Implementing custom scrolling behavior or animations. + +**Note:** The `SCROLL` opcode provides a way to manipulate the +contents of a window by scrolling it up or down. It is important to +consider the window's scrolling attribute and the desired visual +effect when using this opcode. + +### SET + +**SET** is an opcode that assigns a value to a variable. It is used to +modify the contents of variables and update the program state. + +**Syntax:** + +``` {.assembly} +set var, value +``` + +**Functionality:** + +The `set` opcode assigns the specified `value` to the variable `var`. +The type of `value` can be: + +- **Immediate value:** A constant value directly encoded within the + instruction. +- **Variable:** A reference to another variable. +- **Other:** A value obtained from another instruction or + expression. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +set counter, 0 ; Initializes the variable `counter` to 0 +set player_health, health_potion ; Assigns the value of `health_potion` to `player_health` +``` + +**Use Cases:** + +- Initializing variables with specific values. +- Updating variables based on game logic or player actions. +- Assigning the results of calculations or expressions to variables. + +**Note:** The `SET` opcode is a fundamental operation for modifying +variables and managing the program state in Z-code programs. + +### SHIFT + +**SHIFT** is an opcode that performs a logical shift on a 16-bit +integer value. It shifts the bits of the operand to the left or right, +depending on the specified shift amount. + +**Syntax:** + +``` {.assembly} +shift int, n > val +``` + +**Functionality:** + +The `shift` opcode performs the following: + +- **Shifts the bits of `int`:** + - If `n` is positive, `int` is shifted left by `n` bits. Zeros + are shifted into the least significant bits. + - If `n` is negative, `int` is shifted right by the absolute + value of `n` bits. Zeros are shifted into the most significant + bits. +- **Does not preserve the sign bit:** In a logical shift, the sign + bit is not replicated during a right shift. This means that the + sign of the number may change after the shift. +- **Stores the result:** The shifted value is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +- If `n` is zero, the value of `int` remains unchanged. +- If the shift amount exceeds the word size (16 bits), the result is + undefined. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +shift num, 2 > shifted ; Shifts the value in `num` left by 2 bits, filling with zeros +shift num, -1 > shifted ; Shifts the value in `num` right by 1 bit, filling with zeros +``` + +**Use Cases:** + +- Multiplying or dividing numbers by powers of two efficiently. +- Manipulating individual bits within a word. +- Implementing bitwise operations and algorithms. + +**Note:** The `shift` opcode performs a logical shift, which does not +preserve the sign of the operand. For an arithmetic shift, where the +sign bit is replicated, use the `ashift` opcode. + +### SOUND + +**SOUND** is an opcode that plays a sound effect. It allows Z-code +programs to incorporate audio feedback and enhance the game +experience. + +**Syntax:** + +``` {.assembly} +sound id:int, op:int [, volume:int, repeat:int] +``` + +**Functionality:** + +The `sound` opcode performs sound operations based on the specified +arguments: + +- **`id`:** The ID number of the sound effect to play. +- **`op`:** The sound operation to perform: + - **1:** Initialize the specified sound. + - **2:** Start playing the specified sound (default if `op` is + omitted). + - **3:** Stop playing the specified sound. + - **4:** Clean up buffers associated with the specified sound. +- **`volume` (optional):** The volume level at which to play the + sound. -1 indicates the default volume. +- **`repeat` (optional):** The number of times to repeat the sound. + -1 indicates that the sound should repeat indefinitely until + explicitly stopped. + +**Special Cases:** + +- **`id` = 0:** Uses the last sound ID specified. +- **`id` = 1 or 2:** Plays a simple beep or boop sound, ignoring the + `op` argument. +- The availability of sound effects and the range of volume levels + depend on the interpreter and target machine capabilities. + +**Error Conditions:** + +An error occurs if: + +- The interpreter does not support sound effects. +- `id` is not a valid sound ID. +- `op` is not within the valid range (1-4). +- `volume` or `repeat` is invalid (if provided). + +**Examples:** + +``` {.assembly} +sound 10, 2 ; Starts playing sound effect with ID 10 +sound 0, 3 ; Stops playing the last sound effect +sound 5, 2, 50, 3 ; Plays sound effect 5 three times at 50% volume +``` + +**Use Cases:** + +- Playing sound effects to provide feedback or enhance the game + atmosphere. +- Creating audio cues for events or actions. +- Implementing music or background sounds. + +**Note:** The `SOUND` opcode requires the interpreter to support sound +effects. The `%FSOUN` flag in the `FLAGS` word and the `%XSOUN` bit in +the `MODE` byte indicate whether sound operations are available. + +### SPLIT + +**SPLIT** is an opcode that divides the screen vertically between +windows 0 and 1. It is used to create a split-screen display, with +each window showing different content. + +**Syntax:** + +``` {.assembly} +split height:int +``` + +**Functionality:** + +The `split` opcode adjusts the vertical dimensions and positions of +windows 0 and 1 as follows: + +- **Sets window 1 height:** The height of window 1 is set to the + value of `height` in lines. +- **Sets window 1 position:** The top of window 1 is placed at the + top of the screen (line 1). +- **Adjusts window 0 position:** The top of window 0 is moved down + to the line following the bottom of window 1. +- **Adjusts window 0 height:** The height of window 0 is adjusted to + fill the remaining space on the screen. +- **Selects window 0:** After splitting the screen, window 0 becomes + the active window for output. + +**Special Cases:** + +- **`height` = 0:** This effectively unsplits the screen, setting + the height of window 1 to 0 and making window 0 occupy the entire + screen. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +split 10 ; Splits the screen, giving window 1 a height of 10 lines +split 0 ; Unsplits the screen +``` + +**Use Cases:** + +- Creating a split-screen display to show different information or + perspectives simultaneously. +- Implementing status displays or separate areas for text output and + input. + +**Note:** The `SPLIT` opcode is a convenient way to create a +split-screen display, but it only affects windows 0 and 1. For more +flexible window management, consider using the `WINPOS` and `WINSIZE` +opcodes. + +### SUB + +**SUB** is an opcode that performs subtraction on two 16-bit word +values. It subtracts the second operand from the first operand and +returns the result. + +**Syntax:** + +``` {.assembly} +sub arg1:int, arg2:int > val +``` + +**Functionality:** + +The `sub` opcode performs the following: + +- **Subtracts `arg2` from `arg1`:** Performs integer subtraction. +- **Stores the result:** The difference is stored in the specified + destination (`val`). If no destination is provided, the result is + pushed onto the game stack. + +**Special Cases:** + +- If the result of the subtraction overflows the 16-bit word size, + an error occurs. + +**Error Conditions:** + +An error occurs if the subtraction result overflows the 16-bit word +range. + +**Examples:** + +``` {.assembly} +sub 10, 5 > result ; Subtracts 5 from 10, stores the difference (5) in `result` +``` + +**Use Cases:** + +- Performing integer subtraction calculations. +- Decreasing values or calculating differences between numbers. + +**Note:** The `sub` opcode performs signed integer subtraction. If the +operands are unsigned, the programmer needs to handle potential +overflow conditions. + +### THROW + +**THROW** is an opcode that throws an exception and returns from a +previously called function with a specified value. It is used in +conjunction with the `CATCH` opcode to implement exception handling +and non-local control flow. + +**Syntax:** + +``` {.assembly} +throw value, frame +``` + +**Functionality:** + +The `throw` opcode performs the following: + +- **Sets return value:** The specified `value` is set as the return + value of the function identified by the `frame` pointer. +- **Unwinds stack:** The interpreter unwinds the call stack, + returning from all functions called since the function where the + corresponding `CATCH` opcode was executed. +- **Resumes execution:** Control is transferred back to the + instruction following the `CATCH` opcode in the function that + caught the exception. + +**Special Cases:** + +- The `frame` pointer must be a valid frame pointer obtained from a + previous `CATCH` opcode. +- Throwing an exception to a frame that is no longer on the call + stack results in an error. + +**Error Conditions:** + +An error occurs if: + +- `frame` is not a valid frame pointer. +- The frame pointed to by `frame` is no longer on the call stack. + +**Examples:** + +``` {.assembly} +catch > frame +; ... some code that might throw an exception ... +throw "Error!", frame ; Throws an exception and returns to the `catch` instruction +``` + +**Use Cases:** + +- Implementing exception handling to deal with errors or unexpected + conditions. +- Performing non-local control flow, such as exiting multiple nested + functions at once. + +**Note:** The `THROW` and `CATCH` opcodes provide a mechanism for +exception handling and non-local control flow in Z-code programs. They +should be used with caution to avoid complex control flow and +potential errors. + +### VALUE + +**VALUE** is an opcode that retrieves the value of a variable and +stores it in a specified destination. It is used to access the current +value of a variable and use it in calculations or other operations. + +**Syntax:** + +``` {.assembly} +value var > val +``` + +**Functionality:** + +The `value` opcode performs the following: + +- **Retrieves variable value:** Reads the value of the specified + variable (`var`). +- **Stores the result:** The retrieved value is stored in the + specified destination (`val`). If no destination is provided, the + result is pushed onto the game stack. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +value score > current_score ; Retrieves the value of `score` and stores it in `current_score` +``` + +**Use Cases:** + +- Accessing the current value of a variable for calculations or + comparisons. +- Passing variable values as arguments to functions. +- Storing variable values in other variables or data structures. + +**Note:** The `VALUE` opcode is a simple way to retrieve the value of +a variable. It is equivalent to using the variable directly as an +operand in most instructions. + +### VERIFY + +**VERIFY** is an opcode that checks the integrity of the game file by +comparing a calculated checksum with a stored checksum value. It is +used to detect potential corruption or modifications of the game data. + +**Syntax:** + +``` {.assembly} +verify /pred +``` + +**Functionality:** + +The `verify` opcode performs the following: + +- **Calculates checksum:** Computes a 16-bit checksum of the game + file data from byte 64 to the end of the file (excluding the + header). +- **Compares with stored checksum:** Compares the calculated + checksum with the value stored in the `PCHKSM` word of the program + header. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the calculated checksum matches the stored checksum. + Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- The checksum calculation excludes the first 64 bytes of the game + file, which contain the program header. +- The `PLENTH` word in the program header specifies the length of + the game file in units of 8 bytes. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +verify / handle_corruption ; Branch to `handle_corruption` if the game file is corrupted +``` + +**Use Cases:** + +- Detecting unauthorized modifications or corruption of the game + file. +- Implementing copy protection mechanisms. +- Ensuring data integrity before loading or saving games. + +**Note:** The effectiveness of the `VERIFY` opcode depends on the +strength of the checksum algorithm and the implementation of copy +protection measures. + +### WINATTR + +**WINATTR** is an opcode that modifies the attributes of a window. +Window attributes control various aspects of the window's behavior, +such as text wrapping, scrolling, and transcripting. + +**Syntax:** + +``` {.assembly} +winattr window:int, bits:int, operation:int +``` + +**Functionality:** + +The `winattr` opcode modifies the attributes of the specified window +(`window`) based on the `bits` and `operation` arguments: + +- **`bits`:** A bitmask where each bit represents a specific window + attribute: + - Bit 0: Text wrapping (1 = enabled, 0 = disabled). + - Bit 1: Scrolling (1 = enabled, 0 = disabled). + - Bit 2: Transcripting (1 = enabled, 0 = disabled). + - Bit 3: Buffering (1 = enabled, 0 = disabled). +- **`operation`:** Specifies how to modify the attributes: + - **0 (MOVE):** Sets the window attributes to the values + specified by `bits`. + - **1 (SET):** Sets the attributes corresponding to the bits + that are set (1) in `bits`. + - **2 (CLEAR):** Clears the attributes corresponding to the bits + that are set (1) in `bits`. + - **3 (COMP):** Toggles the attributes corresponding to the bits + that are set (1) in `bits`. + +**Special Cases:** + +- If the `operation` argument is omitted, it defaults to 0 (MOVE). + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `operation` is not within the valid range (0-3). + +**Examples:** + +``` {.assembly} +winattr 1, 1, 1 ; Enables text wrapping for window 1 +winattr 2, 6, 2 ; Disables scrolling and transcripting for window 2 +``` + +**Use Cases:** + +- Changing the behavior of windows based on game logic or player + actions. +- Enabling or disabling text wrapping, scrolling, or transcripting + for specific windows. +- Customizing the appearance and functionality of the game + interface. + +**Note:** The `WINATTR` opcode provides a flexible way to modify +window attributes. It is important to understand the meaning of each +bit in the `bits` argument and the effect of the different operations. + +### WINGET + +**WINGET** is an opcode that retrieves the value of a specific +property from a window's property table. Window properties store +information about the window's position, size, attributes, and other +characteristics. + +**Syntax:** + +``` {.assembly} +winget window:int, property:int > val +``` + +**Functionality:** + +The `winget` opcode retrieves the value of the property specified by +`property` from the property table of the window identified by +`window`: + +- **`window`:** The number of the window to access. +- **`property`:** The number of the property to retrieve. Valid + property numbers and their corresponding meanings are: + - 0: `WTOP` - Y position of the window (top edge, in screen + units). + - 1: `WLEFT` - X position of the window (left edge, in screen + units). + - 2: `WHIGH` - Height of the window in screen units. + - 3: `WWIDE` - Width of the window in screen units. + - 4: `WYPOS` - Y coordinate of the cursor within the window (row + number, 1-based). + - 5: `WXPOS` - X coordinate of the cursor within the window + (column number, 1-based). + - 6: `WLMARG` - Left margin of the window in pixels. + - 7: `WRMARG` - Right margin of the window in pixels. + - 8: `WCRFCN` - Function to call for carriage return interrupts. + - 9: `WCRCNT` - Counter for carriage return interrupts. + - 10: `WHLIGHT` - Highlighting mode of the window. + - 11: `WCOLOR` - Color word of the window (background and + foreground colors). + - 12: `WFONT` - Font ID used in the window. + - 13: `WFSIZE` - Font size (height and width) used in the + window. + - 14: `WATTRS` - Window attributes (wrapping, scrolling, + transcripting, buffering). + - 15: `WLCNT` - Line counter for the window. +- **Stores the result:** The retrieved property value is stored in + the specified destination (`val`). If no destination is provided, + the result is pushed onto the game stack. + +**Special Cases:** + +- If the `window` argument is omitted, the current window is used. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `property` is not a valid property number. + +**Examples:** + +``` {.assembly} +winget 0, 2 > window_height ; Retrieves the height of the main window (window 0) +winget 1, 14 > window_attrs ; Retrieves the attributes of window 1 +``` + +**Use Cases:** + +- Accessing information about window properties, such as position, + size, or attributes. +- Implementing custom window management or display routines. +- Checking the state of specific window features. + +**Note:** The `WINGET` opcode provides a flexible way to access +various window properties. It is important to use the correct property +numbers to retrieve the desired information. + +### WINPOS + +**WINPOS** is an opcode that sets the position of a window on the +screen. It allows for precise control over the location of windows +within the display area. + +**Syntax:** + +``` {.assembly} +winpos window:int, y:int, x:int +``` + +**Functionality:** + +The `winpos` opcode sets the position of the specified window +(`window`) to the coordinates (`y`, `x`): + +- **`window`:** The number of the window to reposition. +- **`y`:** The Y coordinate of the top-left corner of the window + (row number, 1-based). +- **`x`:** The X coordinate of the top-left corner of the window + (column number, 1-based). + +The coordinates are specified in screen units, with the top-left +corner of the screen being (1, 1). + +**Special Cases:** + +- If the `window` argument is omitted, the current window is + repositioned. +- The opcode does not check if the new window position would place + the window partially or completely off-screen. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `y` or `x` is negative. + +**Examples:** + +``` {.assembly} +winpos 1, 5, 10 ; Positions window 1 at row 5, column 10 +winpos 2, 1, 1 ; Positions window 2 at the top-left corner of the screen +``` + +**Use Cases:** + +- Positioning windows for optimal layout and user interface design. +- Creating overlapping windows or dynamic window arrangements. +- Implementing custom window management or animation routines. + +**Note:** The `WINPOS` opcode provides direct control over window +positioning. It is important to consider the window's size and the +overall screen layout when using this opcode. + +### WINPUT + +**WINPUT** is an opcode that sets the value of a specific property +within a window's property table. It allows for modifying various +aspects of a window's behavior and appearance. + +**Syntax:** + +``` {.assembly} +winput window:int, property:int, value +``` + +**Functionality:** + +The `winput` opcode sets the value of the property specified by +`property` in the property table of the window identified by `window`: + +- **`window`:** The number of the window to modify. +- **`property`:** The number of the property to set. See the + description of `WINGET` for a list of valid property numbers and + their meanings. +- **`value`:** The new value to assign to the property. + +**Special Cases:** + +- Not all window properties are writable using `WINPUT`. Some + properties, such as window size and position, require specific + opcodes like `WINSIZE` and `WINPOS` for modification. +- If the `window` argument is omitted, the current window is used. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `property` is not a valid property number or is not writable. + +**Examples:** + +``` {.assembly} +winput 1, 10, 2 ; Sets the highlighting mode of window 1 to bold +winput 2, 6, 15 ; Sets the left margin of window 2 to 15 pixels +``` + +**Use Cases:** + +- Modifying window properties to change their behavior or + appearance. +- Setting the highlighting mode, color, or font of a window. +- Adjusting margins or other window settings. + +**Note:** The `WINPUT` opcode provides a way to modify window +properties, but it is important to check which properties are writable +and use the appropriate opcodes for those that are not. + +### WINSIZE + +**WINSIZE** is an opcode that sets the size of a window on the screen. +It allows for controlling the dimensions of windows and adjusting the +display area they occupy. + +**Syntax:** + +``` {.assembly} +winsize window:int, height:int, width:int +``` + +**Functionality:** + +The `winsize` opcode sets the size of the specified window (`window`) +to the given dimensions: + +- **`window`:** The number of the window to resize. +- **`height`:** The new height of the window in screen units (number + of lines). +- **`width`:** The new width of the window in screen units (number + of characters). + +If the new size would cause the window to extend beyond the screen +boundaries, the dimensions are adjusted to fit within the available +space. + +**Special Cases:** + +- If the `window` argument is omitted, the current window is + resized. +- If the new size is smaller than the current cursor position, the + cursor is moved to the bottom-right corner of the resized window. + +**Error Conditions:** + +An error occurs if: + +- `window` is not within the valid range (-3 to 7). +- `height` or `width` is zero or negative. + +**Examples:** + +``` {.assembly} +winsize 1, 10, 40 ; Sets the size of window 1 to 10 lines by 40 characters +winsize 2, 25, 80 ; Sets the size of window 2 to 25 lines by 80 characters (full screen width) +``` + +**Use Cases:** + +- Adjusting the size of windows to fit content or accommodate + different display requirements. +- Creating windows with specific dimensions for menus, dialog boxes, + or other UI elements. +- Implementing dynamic window resizing or animations. + +**Note:** The `WINSIZE` opcode provides direct control over window +size. It is important to consider the window's position and the +overall screen layout when using this opcode. + +### XCALL + +**XCALL** is an opcode that calls a function with a variable number of +arguments and returns a value. It is the most general form of the +`CALL` instruction, allowing for up to seven arguments to be passed to +the function. + +**Syntax:** + +``` {.assembly} +xcall fcn, arg1:any [, arg2:any ...] > val +``` + +**Functionality:** + +The `xcall` opcode performs the following: + +- **Pushes arguments onto the stack:** Pushes the variable number of + arguments (`arg1`, `arg2`, etc.) onto the game stack. The number + of arguments is determined by the operand types specified in the + instruction. +- **Calls the function:** Transfers control to the function + specified by `fcn`. The function address is calculated by shifting + `fcn` left by two bits and adding the function offset (`FOFF`) + shifted left by three bits. +- **Retrieves return value:** When the function returns, its return + value is retrieved and stored in the specified destination + (`val`). If no destination is provided, the value is pushed onto + the game stack. + +**Special Cases:** + +- If `fcn` is zero, the `xcall` opcode acts as if it called a + function that immediately returned false. + +**Error Conditions:** + +An error occurs if `fcn` is not a valid function pointer. + +**Examples:** + +``` {.assembly} +xcall format_string, buffer, arg1, arg2, arg3 > formatted_text ; Calls the `format_string` function with four arguments +``` + +**Use Cases:** + +- Calling functions with a variable number of arguments. +- Implementing functions that take a flexible number of parameters. + +**Note:** The `XCALL` opcode is generated by the compiler when it +detects a function call with more than two arguments or when the +argument types require the extended format. It is not typically used +directly by programmers. + +### XPUSH + +**XPUSH** is an opcode that attempts to push a value onto a stack and +acts as a predicate based on the success of the operation. It can be +used with both the game stack and user-defined stacks. + +**Syntax:** + +``` {.assembly} +xpush value, stack:tbl /pred +``` + +**Functionality:** + +The `xpush` opcode performs the following: + +- **Checks stack space:** Determines if there is enough space + available on the specified stack (`stack`) to push the value. +- **Pushes value (if space available):** If there is sufficient + space, the opcode pushes the `value` onto the top of the stack. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if the value was successfully pushed onto the stack. + Otherwise, the predicate fails (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +- If the `stack` argument is omitted, the opcode operates on the + game stack. + +**Error Conditions:** + +An error occurs if `stack` is not a valid table pointer (if provided). + +**Examples:** + +``` {.assembly} +xpush item, inventory / inventory_full ; Attempts to push `item` onto the `inventory` stack +; ... code to handle full inventory ... +inventory_full: +``` + +**Use Cases:** + +- Pushing values onto stacks while checking for potential stack + overflow conditions. +- Implementing stack-based data structures with overflow handling. + +**Note:** The `XPUSH` opcode provides a way to push values onto stacks +while simultaneously checking for available space. This can be useful +for preventing stack overflow errors and implementing robust stack +management. + +### ZERO? + +**ZERO?** is an opcode that checks whether a value is equal to zero. +It acts as a predicate, meaning it evaluates a condition and +implicitly performs a conditional branch based on the result. + +**Syntax:** + +``` {.assembly} +zero? arg:any /pred +``` + +**Functionality:** + +The `zero?` opcode performs the following: + +- **Checks for zero:** Determines if the value of `arg` is equal to + zero. +- **Evaluates predicate:** The predicate succeeds (evaluates to + true) if `arg` is indeed zero. Otherwise, the predicate fails + (evaluates to false). +- **Conditional branch:** Based on the predicate result and the + specified branch polarity (`/pred`), the interpreter may perform a + conditional jump to a specified target. + +**Special Cases:** + +None. + +**Error Conditions:** + +None. + +**Examples:** + +``` {.assembly} +zero? counter / end_loop ; Branch to `end_loop` if `counter` is zero +``` + +**Use Cases:** + +- Implementing conditional logic based on zero checks. +- Determining if a variable or expression has a value of zero. +- Loop termination conditions. + +**Note:** The `ZERO?` opcode is a simple but useful predicate for +checking for zero values and implementing conditional behavior in +Z-code programs. + +### ZWSTR + +**ZWSTR** is an opcode that converts a word from an input buffer into +a Z-string and stores it in a specified location. Z-strings are the +standard format for representing text in Z-code programs. + +**Syntax:** + +``` {.assembly} +zwstr inbuf:tbl, inlen:int, inbeg:int, zword:tbl +``` + +**Functionality:** + +The `zwstr` opcode performs the following: + +- **Reads input word:** Extracts the word starting at the byte + offset `inbeg` within the input buffer `inbuf`. The `inlen` + argument specifies the length of the word in bytes, but it is not + strictly necessary as the opcode assumes the word is terminated by + a break character (whitespace or a self-inserting break + character). +- **Converts to Z-string:** Encodes the extracted word into a + Z-string using the current character set and frequent words table. +- **Stores the result:** The encoded Z-string is stored in the first + three words of the `zword` table. + +**Special Cases:** + +- The `inbuf` argument is typically a pointer to the text buffer + used by the `READ` or `LEX` opcodes. +- The `zword` table must have at least three words of available + space to store the Z-string. + +**Error Conditions:** + +An error occurs if: + +- `inbuf` or `zword` is not a valid table pointer. +- `inbeg` is outside the bounds of the `inbuf` table. +- The `zword` table does not have enough space to store the + Z-string. + +**Examples:** + +``` {.assembly} +read input_buffer, lexv +zwstr input_buffer, 0, lexv[1].offset, word_buffer ; Converts the second word from the parsed input into a Z-string +``` + +**Use Cases:** + +- Converting words from input buffers into Z-strings for further + processing or comparison. +- Implementing custom parsing or text manipulation routines. + +**Note:** The `ZWSTR` opcode is used to convert words from input +buffers into the Z-string format used by the Z-machine. It is +typically used in conjunction with the `READ` or `LEX` opcodes for +processing player input. + +Chapter 3.2: Opcode Summary Table +--------------------------------- + + -------------------------------------------------------------------------------------- + Opcode Name Operands Type Description + -------- ------------- --------------- ------ ---------------------------------------- + 1 EQUAL? arg1:any, 2OP Is arg1 equal to any one of arg2, arg3, + arg2:any or arg4? Note that in the extended form, + EQUAL? can take more than two operands. + + 2 LESS? arg1:int, 2OP Is arg1 less than arg2? + arg2:int + + 3 GRTR? arg1:int, 2OP Is arg1 greater than arg2? + arg2:int + + 4 DLESS? var, int 2OP Decrements var and succeeds if new value + is less than int. + + 5 IGRTR? var, int 2OP Increments var and succeeds if new value + is greater than int. + + 6 IN? child:obj, 2OP Is child contained in parent? + parent:obj + + 7 BTST arg1:word, 2OP Are bits on in arg2 also on in arg1? + arg2:word + + 8 BOR arg1:word, 2OP Bitwise logical OR. + arg2:word + + 9 BAND arg1:word, 2OP Bitwise logical AND. + arg2:word + + 10 FSET? obj, flag 2OP Is flag number set in obj? + + 11 FSET obj, flag 2OP Sets flag in obj. + + 12 FCLEAR obj, flag 2OP Clears flag in obj. + + 13 SET var, any 2OP Sets variable to any. + + 14 MOVE thing:obj, 2OP Puts thing into dest as the first + dest:obj object. + + 15 GET table, item 2OP Returns item'th element of table + (word-oriented). + + 16 GETB table, item 2OP Returns item'th element of table + (byte-oriented). + + 17 GETP obj, prop 2OP Returns prop property of obj. + + 18 GETPT obj, prop 2OP Returns pointer to property table prop + from obj. + + 19 NEXTP obj, prop 2OP Returns number of the property following + prop in obj. + + 20 ADD arg1:int, 2OP Adds the integers. + arg2:int + + 21 SUB arg1:int, 2OP Subtracts arg2 from arg1. + arg2:int + + 22 MUL arg1:int, 2OP Multiplies the integers. + arg2:int + + 23 DIV arg1:int, 2OP Divides arg1 by arg2, returning the + arg2:int truncated quotient. + + 24 MOD arg1:int, 2OP Divides arg1 by arg2, returning the + arg2:int remainder. + + 25 CALL2 fcn, any 2OP Calls the function pointed to by fcn. + + 26 ICALL2 routine:fcn, 2OP Calls the function pointed to by fcn (no + arg1:any return value). + + 27 COLOR fore:int, 2OP Sets foreground and background color. + back:int + + 28 THROW any, frame 2OP Returns any from a frame (see CATCH). + + 128 ZERO? arg:any 1OP Is arg equal to zero? + + 129 NEXT? obj 1OP Returns the "next" slot of obj (fails if + none). + + 130 FIRST? obj 1OP Returns the "first" slot of obj (fails + if none). + + 131 LOC obj 1OP Returns the "parent" of obj (zero if + none). + + 132 PTSIZE table 1OP Returns length of property table in + bytes. + + 133 INC var 1OP Increments the value of var by one. + + 134 DEC var 1OP Decrements the value of var by one. + + 135 PRINTB str 1OP Prints the string pointed to by str + (byte pointer). + + 136 CALL1 fcn 1OP Calls the function pointed to by fcn. + + 137 REMOVE obj 1OP Removes obj from the object tree. + + 138 PRINTD obj 1OP Prints the short description of obj. + + 139 RETURN any 1OP Returns from the most recently executed + call. + + 140 JUMP loc 1OP Unconditional relative branch. + + 141 PRINT str 1OP Prints the string pointed to by str + (quad pointer). + + 142 VALUE var 1OP Returns the value of var. + + 143 ICALL1 routine:fcn 1OP Calls the function pointed to by fcn (no + return value). + + 176 RTRUE 0OP Returns 1 (true). + + 177 RFALSE 0OP Returns 0 (false). + + 178 PRINTI (in-line 0OP Prints an immediate string. + string) + + 179 PRINTR (in-line 0OP Prints an immediate string and executes + string) CRLF + RTRUE. + + 180 NOOP 0OP No operation. + + 183 RESTART 0OP Reinitializes the game. + + 184 RSTACK 0OP Returns from a call and takes value from + stack. + + 185 CATCH 0OP Returns a pointer to the current call + frame. + + 186 QUIT 0OP Terminates the game. + + 187 CRLF 0OP Prints an end-of-line sequence. + + 188 (Unused) + + 189 VERIFY 0OP Verifies the game program on disk. + + 190 EXTOP opcode:int 0OP Signals the next opcode is an extended + opcode. + + 191 ORIGINAL? 0OP Returns non-false if the game disk is + the original. + + 193 EQUAL? arg1:any, EXT Is arg1 equal to any of the other + arg2:any, ... arguments? + + 224 CALL fcn, any1, EXT Calls the function pointed to by fcn. + any2, any3 + + 225 PUT table, item, EXT Sets the word pointed to in table to + any any. + + 226 PUTB table, item, EXT Sets the byte pointed to in table to the + any low byte of any. + + 227 PUTP obj, prop, any EXT Changes the value of obj's property prop + to any. + + 228 READ inbuf:tbl, EXT Reads a line of input and parses it. + lexv:tbl, + time:int, + handler:fcn + + 229 PRINTC int EXT Prints the character whose ASCII value + is int. + + 230 PRINTN int EXT Prints int as a signed number. + + 231 RANDOM arg:int EXT Returns a random value between 1 and + arg. + + 232 PUSH value EXT Pushes value onto the game stack. + + 233 POP stack EXT Pops a value from the stack. + + 234 SPLIT height:int EXT Splits the screen vertically between + windows 0 and 1. + + 235 SCREEN window:int EXT Selects the specified window for output. + + 236 XCALL fcn, any1, ..., EXT Calls the function pointed to by fcn (up + any7 to 7 args). + + 237 CLEAR window:int EXT Clears the specified window. + + 238 ERASE int EXT Erases a portion of the current line. + + 239 CURSET y:int, x:int, EXT Sets the cursor position in the + window specified window. + + 240 CURGET output:tbl EXT Returns information about the current + cursor position. + + 241 HLIGHT int EXT Sets the display highlighting mode. + + 242 BUFOUT int EXT Controls output buffering. + + 243 DIROUT device:int, EXT Selects or deselects a virtual output + any1, any2, device. + any3 + + 244 DIRIN device:int, EXT Selects or deselects a virtual input + any1, any2, device. + any3 + + 245 SOUND id:int, op:int, EXT Produces a sound. + volume:int, + repeat:int + + 246 INPUT dev:int, EXT Returns a single byte from the specified + time:int, device. + handler:fcn + + 247 INTBL? item, tbl, EXT Searches for a record in a table. + len:int, + recspec:int + + 248 BCOM arg:word 1OP Performs a bitwise logical NOT + (complement) on the word. + + 249 ICALL routine:fcn, EXT Calls the function pointed to by fcn (no + arg1:any, return value). + arg2:any, + arg3:any + + 250 IXCALL routine:fcn, EXT Calls the function pointed to by fcn + arg1,... (variable args, no return value). + + 251 LEX inbuf:tbl, EXT Tokenizes and looks up an input buffer's + lexv:tbl, contents. + lexicon:tbl, + preserve:bool + + 252 ZWSTR inbuf:tbl, EXT Converts a word to a Z-string. + inlen:int, + inbeg:int, + zword:tbl + + 253 COPYT source:tbl, EXT Copies bytes from source to dest. + dest:tbl, + length:int + + 254 PRINTT bytes:tbl, EXT Prints a block of text from a table. + width:int, + height:int, + skip:int + + 255 ASSIGNED? opt:var EXT Checks if an optional argument was + supplied. + + 256 SAVE start:tbl, EXT Saves a section of the game state. + length:int, + name:tbl + + 257 RESTORE start:tbl, EXT Restores a section of the game state. + length:int, + name:tbl + + 258 SHIFT int, n EXT Performs a logical shift on int. + + 259 ASHIFT int, n EXT Performs an arithmetic shift on int. + + 260 FONT font:int, EXT Selects a font for the specified window. + window + + 261 DISPLAY picture:int, EXT Displays a picture at the specified + y:int, x:int location. + + 262 PICINF picture:int, EXT Returns information about a picture. + data:tbl + + 263 DCLEAR picture:int, EXT Clears the area occupied by a picture. + y:int, x:int + + 264 MARGIN left:int, EXT Sets the left and right margins for a + right:int, window. + window + + 265 ISAVE EXT Saves the game state to a reserved area + in RAM. + + 266 IRESTORE EXT Restores the game state from the + reserved area in RAM. + + 272 WINPOS window:int, y, EXT Sets the location of the top left corner + x of a window. + + 273 WINSIZE window, y, x EXT Sets the size of a window. + + 274 WINATTR window, bits, EXT Sets characteristics of a window. + operation + + 275 WINGET window, offset EXT Returns the value of a window property. + + 276 SCROLL window, lines EXT Scrolls the specified window up or down. + + 277 FSTACK n, stack EXT Flushes n elements from the specified + stack. + + 278 MOUSE-INFO table EXT Returns information about the mouse + status. + + 279 MOUSE-LIMIT window EXT Restricts the mouse to a specific + window. + + 280 XPUSH value, stack EXT Pushes value onto the specified stack. + + 281 WINPUT window, offset, EXT Sets the value of a window property. + value + + 282 PRINTF tbl EXT Prints a formatted table. + + 283 MENU id, tbl EXT Adds a menu to the menu bar. + + 284 PICSET tbl EXT A table of picture numbers to pre-load + or cache for faster display. Pictures not + included in the most recent PICSET call are + no longer considered "hot" and can be safely + removed from the cache. + --------------------------------------------------------------------------------------