% -------------------------------------------------------------------------
%
%   The Specification of the Z-Machine
%
%   This file is formatted in the TeX typesetting language,
%   but after the initial pages of macro definitions is relatively
%   straightforward to read as plain text.
%
%   After the \end directive, the file also contains five short Inform
%   programs useful for testing compliance with the specification.
%
%   -- GAN, 951115
%
% -------------------------------------------------------------------------
% ---------------------------------------------------------------------------
% ---------------------------------------------------------------------------

\newif\iffiles\filesfalse
%  Manual macros
%
%  Page layout
%
\newif\ifshutup\shutupfalse
\newif\iflexicon\lexiconfalse
\newif\ifanswers\answersfalse
\magnification=\magstep 1
\hoffset=0.15 true in
\voffset=2\baselineskip
%
%  General hacks
%
\def\PAR{\par}
%
%  Font loading
%
\font\medfont=cmr10 scaled \magstep2
\font\bigfont=cmr10 scaled \magstep3
%\def\sectfont{\bf}
\font\sectfont=cmbx12
\def\small{\sevenrm}
\font\rhrm=cmr8
\font\rhit=cmsl8
%
%  Titles
%
\newcount\subsectno    %  Subsection number
\def\rhead{{\rhrm\topmark}}           %  The running head will go here
%
\def\newsection#1#2{%     To begin a section...
%\global\titletrue%        Declare this as a title page
%\xdef\rhead{{\rhrm #1}\quad #2}%       Initialise running head and ssn
\subsectno=0%
\iffiles
\write\conts{\string\sli\string{#1\string}\string{#2\string}\string{\the\pageno\string}}%
\fi
}
%
\def\section#1#2{\mark{}\vskip 1 true in\goodbreak
\noindent{\sectfont #1\quad #2}\bigskip\newsection{#1}{#2}\noindent\mark{#1\quad #2}}
\def\sectionx#1{\mark{}\vskip 1 true in\goodbreak
\noindent{\sectfont #1}\bigskip\newsection{}{#1}\noindent\mark{\quad #1}}
%
\def\newpage{\mark{}\vfill\eject}
%
%  Headers and footers
%
\newif\iftitle
\headline={\iftitle\hfil\global\titlefalse%
          \else{\iflexicon{\bf\firstmark}\hfil{\bf\botmark}\else%
                \ifanswers{\hfil\ifnum\firstmark=\botmark%
                           {\rhit Answer to exercise \rhrm\firstmark}%
                           \else{\rhit Answers to exercises \rhrm\firstmark-\botmark}%
                          \fi}\else%
                \hfil{\rhit \rhead}\fi\fi}%
          \fi}
\footline={\ifnum\pageno<0\hfil{\tenbf\romannumeral -\pageno}%
\else\hfil{\tenbf \number\pageno}\fi}
%\footline={\ifnum\pageno=1\hfil\else\hfil{\tenbf \number\pageno}\fi}
%
%  (Old date-stamping version:)
% \footline={\hfil{\rm \number\pageno}\hfil{\rm \number\day/\number\month}}
%
% If this works I'll be impressed
%

\font\ninerm=cmr9
\font\ninei=cmmi9
\font\ninesy=cmsy9
\font\ninebf=cmbx9
\font\eightbf=cmbx8
\font\ninett=cmtt9
\font\nineit=cmti9
\font\ninesl=cmsl9
\def\ninepoint{\def\rm{\fam0\ninerm}%
 \textfont0=\ninerm
 \textfont1=\ninei
 \textfont2=\ninesy
 \textfont3=\tenex
 \textfont\itfam=\nineit \def\it{\fam\itfam\nineit}%
 \textfont\slfam=\ninesl \def\sl{\fam\slfam\ninesl}%
 \textfont\ttfam=\ninett \def\tt{\fam\ttfam\ninett}%
 \textfont\bffam=\ninebf
 \normalbaselineskip=11pt
 \setbox\strutbox=\hbox{\vrule height8pt depth3pt width0pt}%
 \normalbaselines\rm}

\def\tenpoint{\def\rm{\fam0\tenrm}%
 \textfont0=\tenrm
 \textfont1=\teni
 \textfont2=\tensy
 \textfont3=\tenex
 \textfont\itfam=\tenit \def\it{\fam\itfam\tenit}%
 \textfont\slfam=\tensl \def\sl{\fam\slfam\tensl}%
 \textfont\ttfam=\tentt \def\tt{\fam\ttfam\tentt}%
 \textfont\bffam=\tenbf
 \normalbaselineskip=12pt
 \setbox\strutbox=\hbox{\vrule height8.5pt depth3.5pt width0pt}%
 \normalbaselines\rm}

\parindent=30pt
\def\inpar{\hangindent40pt\hangafter1\qquad}
\def\onpar{\par\hangindent40pt\hangafter0}

\newskip\ttglue
\ttglue=.5em plus.25em minus.15em

\def\orsign{$\mid\mid$}

\outer\def\begindisplay{\obeylines\startdisplay}
{\obeylines\gdef\startdisplay#1
 {\catcode`\^^M=5$$#1\halign\bgroup\indent##\hfil&&\qquad##\hfil\cr}}
\outer\def\enddisplay{\crcr\egroup$$}

\chardef\other=12

\def\ttverbatim{\begingroup \catcode`\\=\other \catcode`\{=\other
 \catcode`\}=\other \catcode`\$=\other \catcode`\&=\other
 \catcode`\#=\other \catcode`\%=\other \catcode`\~=\other
 \catcode`\_=\other \catcode`\^=\other
 \obeyspaces \obeylines \tt}
{\obeyspaces\gdef {\ }}

\outer\def\beginstt{$$\let\par=\endgraf \ttverbatim\ninett \parskip=0pt
 \catcode`\|=0 \rightskip=-5pc \ttfinish}
\outer\def\begintt{$$\let\par=\endgraf \ttverbatim \parskip=0pt
 \catcode`\|=0 \rightskip=-5pc \ttfinish}
{\catcode`\|=0 |catcode`|\=\other
 |obeylines
 |gdef|ttfinish#1^^M#2\endtt{#1|vbox{#2}|endgroup$$}}

\catcode`\|=\active
{\obeylines\gdef|{\ttverbatim\spaceskip=\ttglue\let^^M=\ \let|=\endgroup}}

\def\beginlines{\par\begingroup\nobreak\medskip\parindent=0pt
 \nobreak\ninepoint \obeylines \everypar{\strut}}
\def\endlines{\endgroup\medbreak\noindent}

\def\<#1>{\leavevmode\hbox{$\langle$#1\/$\rangle$}}

\def\dbend{{$\triangle$}}
\def\d@nger{\medbreak\begingroup\clubpenalty=10000
 \def\par{\endgraf\endgroup\medbreak} \noindent\hang\hangafter=-1   % -2
 \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ninepoint}
\def\refd@nger{\par\nobreak\noindent\begingroup\clubpenalty=10000
 \def\par{\endgraf\endgroup\medbreak}\ninepoint}
\outer\def\danger{\d@nger}
\def\dd@nger{\medskip\begingroup\clubpenalty=10000
 \def\par{\endgraf\endgroup\medbreak} \noindent\hang\hangafter=-1   % -2
 \hbox to0pt{\hskip-\hangindent\dbend\kern 1pt\dbend\hfill}\ninepoint}
\outer\def\ddanger{\dd@nger}
\def\ddd@nger{\medskip\begingroup\clubpenalty=10000
 \def\par{\endgraf\endgroup\medbreak} \noindent\hang\hangafter=-1   % -2
 \hbox to0pt{\hskip-\hangindent\dbend\kern 1pt\dbend\kern 1pt\dbend\hfill}\ninepoint}
\outer\def\dddanger{\dd@nger}
\def\enddanger{\endgraf\endsubgroup}

\def\cstok#1{\leavevmode\thinspace\hbox{\vrule\vtop{\vbox{\hrule\kern1pt
      \hbox{\vphantom{\tt/}\thinspace{\tt#1}\thinspace}}
    \kern1pt\hrule}\vrule}\thinspace}

\def\rstok#1{\leavevmode\thinspace\hbox{\vrule\vtop{\vbox{\hrule\kern1pt
      \hbox{\vphantom{\rm!}\thinspace{\rm#1}\thinspace}}
    \kern1pt\hrule}\vrule}\thinspace}

\newcount\exno
\exno=0

\def\xd@nger{%
 \begingroup\def\par{\endgraf\endgroup\medbreak}\ninepoint}

\outer\def\warning{\medbreak
 \noindent\llap{$\bullet$\rm\kern.15em}%
 {\ninebf WARNING}\par\nobreak\noindent}
\outer\def\refs{\medbreak
 \noindent\llap{$\bullet$\rm\kern.15em}%
 {\eightbf REFERENCES}\refd@nger}
\outer\def\nextref{\quad$\bullet$\quad}%
\outer\def\exercise{\medbreak \global\advance\exno by 1
 \noindent\llap{$\bullet$\rm\kern.15em}%
 {\eightbf EXERCISE \bf\the\exno}\refd@nger}
%\par\noindent
\def\dexercise#1{\global\advance\exno by 1
 \medbreak\noindent\llap{$\bullet$\rm\kern.15em}%
 #1{\eightbf ~EXERCISE \bf\the\exno}\refd@nger}
%   \hfil\break}
\outer\def\dangerexercise{\xd@nger \dexercise{\dbend}}
\outer\def\ddangerexercise{\xd@nger \dexercise{\dbend\dbend}}


\newwrite\ans%
\newwrite\conts%
\iffiles
\immediate\openout\conts=conts
\fi

\iffiles\else\outer\def\answer#1{\par\medbreak}\shutuptrue\fi

\newwrite\inx
\ifshutup\else
\immediate\openout\inx=inxdata
\fi
\def\marginstyle{\sevenrm %
 \vrule height6pt depth2pt width0pt } %

\newif\ifsilent
\def\specialhat{\ifmmode\def\next{^}\else\let\next=\beginxref\fi\next}
\def\beginxref{\futurelet\next\beginxrefswitch}
\def\beginxrefswitch{\ifx\next\specialhat\let\next=\silentxref
 \else\silentfalse\let\next=\xref\fi \next}
\catcode`\^=\active \let ^=\specialhat
\def\silentxref^{\silenttrue\xref}

\newif\ifproofmode
\proofmodetrue %

\def\xref{\futurelet\next\xrefswitch}
\def\xrefswitch{\begingroup\ifx\next|\aftergroup\vxref
 \else\ifx\next\<\aftergroup\anglexref
   \else\aftergroup\normalxref \fi\fi \endgroup}
\def\vxref|{\catcode`\\=\active \futurelet\next\vxrefswitch}
\def\vxrefswitch#1|{\catcode`\\=0
 \ifx\next\empty\def\xreftype{2}%
   \def\next{{\tt\text}}%
 \else\def\xreftype{1}\def\next{{\tt\text}}\fi %
 \edef\text{#1}\makexref}
{\catcode`\|=0 \catcode`\\=\active |gdef\{}}
\def\anglexref\<#1>{\def\xreftype{3}\def\text{#1}%
 \def\next{\<\text>}\makexref} %
\def\normalxref#1{\def\xreftype{0}\def\text{#1}\let\next=\text\makexref}

\def\makexref{\ifproofmode%
 \xdef\writeit{\write\inx{\text\space!\xreftype\space
   \noexpand\number\pageno.}}\iffiles\writeit\fi
 \else\ifhmode\kern0pt \fi\fi
\ifsilent\ignorespaces\else\next\fi}

\newdimen\fullhsize
\def\fullline{\hbox to\fullhsize}
\let\lr=L \newbox\leftcolumn

\def\doubleformat{\shipout\vbox{\makeheadline
   \fullline{\box\leftcolumn\hfil\columnbox}
   \makefootline}
 \advancepageno}
\def\tripleformat{\shipout\vbox{\makeheadline
   \fullline{\box\leftcolumn\hfil\box\midcolumn\hfil\columnbox}
   \makefootline}
 \advancepageno}
\def\columnbox{\leftline{\pagebody}}

\newbox\leftcolumn
\newbox\midcolumn
\def\beginindex{
\fullhsize=6.5true in \hsize=2.1true in
\global\def\makeheadline{\vbox to 0pt{\vskip-22.5pt
     \fullline{\vbox to8.5pt{}\the\headline}\vss}\nointerlineskip}
\global\def\makefootline{\baselineskip=24pt \fullline{\the\footline}}
\output={\if L\lr
  \global\setbox\leftcolumn=\columnbox \global\let\lr=M
\else\if M\lr
  \global\setbox\midcolumn=\columnbox \global\let\lr=R
\else\tripleformat \global\let\lr=L\fi\fi
\ifnum\outputpenalty>-20000 \else\dosupereject\fi}
\begingroup
 \parindent=1em \maxdepth=\maxdimen
 \def\par{\endgraf \futurelet\next\inxentry}
 \obeylines \everypar={\hangindent 2\parindent}
 \exhyphenpenalty=10000 \raggedright}
\def\inxentry{\ifx\next\sub \let\next=\subentry
 \else\ifx\next\endindex \let\next=\vfill
 \else\let\next=\mainentry \fi\fi\next}
\def\endindex{\mark{}\break\endgroup
\supereject
\if L\lr \else\null\vfill\eject\fi
\if L\lr \else\null\vfill\eject\fi
}
\let\sub=\indent \newtoks\maintoks \newtoks\subtoks
\def\mainentry#1,{\mark{}\noindent
 \maintoks={#1}\mark{\the\maintoks}#1,}
\def\subentry\sub#1,{\mark{\the\maintoks}\indent
 \subtoks={#1}\mark{\the\maintoks\sub\the\subtoks}#1,}

\def\subsection#1{\medbreak\par\noindent{\bf #1}\qquad}

%  For contents

\def\cl#1#2{\bigskip\par\noindent{\bf #1}\quad {\bf #2}}
\def\li#1#2#3{\smallskip\par\noindent\hbox to 5 in{{\bf #1}\quad #2\dotfill #3}}
\def\sli#1#2#3{\par\noindent\hbox to 5 in{\qquad\item{#1}\quad #2\dotfill #3}}
\def\fcl#1#2{\bigskip\par\noindent\hbox to 5 in{\phantom{\bf 1}\quad {\bf #1}\dotfill #2}}

% Epigrams

\def\poem{\begingroup\narrower\narrower\narrower\obeylines\ninepoint}
\def\widepoem{\begingroup\narrower\narrower\obeylines\ninepoint}
\def\verywidepoem{\begingroup\narrower\obeylines\ninepoint}
\def\quote{\medskip\begingroup\narrower\narrower\noindent\ninepoint}
\def\widequote{\medskip\begingroup\narrower\noindent\ninepoint}
\def\poemby#1#2{\par\smallskip\qquad\qquad\qquad\qquad\qquad -- #1, {\it #2}
\tenpoint\endgroup\bigskip}
\def\widepoemby#1#2{\par\smallskip\qquad\qquad\qquad -- #1, {\it #2}
\tenpoint\endgroup\bigskip}
\def\quoteby#1{\par\smallskip\qquad\qquad\qquad\qquad\qquad
-- #1\tenpoint\endgroup\bigskip}
\def\tlwidequoteby#1#2{\par\smallskip\qquad
-- #1\par\smallskip\qquad\qquad\qquad
-- #2\tenpoint\endgroup\bigskip}
\def\tvquoteby#1#2{\par\smallskip\qquad
-- #1\par\qquad\qquad\quad
\phantom{--} #2\tenpoint\endgroup\bigskip}
\def\endquote{\par\tenpoint\endgroup\medskip}

%
%  End of macros

\def\subtitle#1{\bigbreak\noindent{\bf #1}\medskip}
\newdimen\stepin
\newdimen\tstepin
\stepin=60pt
\def\block#1{\par%\rlap{{\tt #1}}
\hangindent\stepin\hangafter0\noindent\strut\llap{\hbox to\stepin{{\tt #1}\hfill}}%
\noindent}
\def\continue{\block{}}
\newcount\sectno
\stepin=40pt
\def\orm{\smallskip\par\noindent\hangindent=0pt}
\def\frm{\par\parindent=20pt\hangindent=20pt}
\def\sp#1{\smallskip\noindent {\bf{\the\sectno.#1}}\quad\hangindent=20pt}
\def\nsp#1{\medskip\sp{#1}}
\def\specs#1#2{\tenpoint\section{#1}{#2}\sectno=#1}
\def\remarks{\medskip\ninepoint\noindent {\sl Remarks.}\qquad}
\pageno=2

% ---------------------------------------------------------------------------
% ---------------------------------------------------------------------------
% ---------------------------------------------------------------------------

\section{}{Preface}

The Z-machine was created on a coffee table in Pittsburgh in 1979.  It
is an imaginary computer whose programs are adventure games, and is
well-adapted to its task, implementing complex games remarkably compactly.
They were still perhaps 100K long and the Z-machine seems to have made the
first usage of virtual memory on a microcomputer.  Further ahead of its time
was the ability to efficiently save and restore the entire execution state
(something we would do well to rediscover as parallel processing takes
over).

The design's cardinal principle is that any game is 100\% portable to
different computers: that is, any legal program exactly determines its
behaviour.  This portability is largely made possible by a willingness to
constrain maximum as well as minimum levels of performance (for instance,
dynamic memory allocation is impossible) and by a very primitive
operating-system interface (so file-naming issues hardly arise).  The
strategy is the opposite extreme to that of the C language, which sacrifices
predictable behaviour for performance: for instance, a programmer never
knows how many bits will make up an |int| or whether |char| will be signed.

But this is not a historical or theoretical paper, because the Z-machine is
widely used in practice to play Infocom and Inform-produced games.  It is a
standards document which aims to exactly describe the correct behaviour, and
is a variorum description in that it describes every different Version of
the machine.  (However, the Version 6 standard will remain provisional until
we have more experience with it.)

\subtitle{Why do we need a ``standards'' document?}

Since the end of the 1980s, interpreters have been in the public domain
which almost properly implement the Z-machine.  Good portable source code
for these has twice been published.  Each interpreter was then ported to
many different machines, where its behaviour was subtly altered, usually
because the porter noticed a missing feature and added it, or had to guess
something.  The ports have grown elaborate and corrections are now difficult
to propagate.  The casual user who downloads an interpreter cannot be sure
how accurate it will be: a ``new'' interpreter (with a beautiful new user
interface) may be built on a partly-repaired core which is five years old.
One reason for a standard, then, is to increase the pressure to return to a
good common release.  Players will know what to ask for (can you get
interpreter 1.1 for the Mac?) and porters will be aware if the core has
changed.

More fundamentally, the problem has changed.  Until 1993 there were only
about 130 story files known, variant forms of 35 games and a few oddments,
all produced by the same compiler's code generator.  An interpreter could
safely be incomplete.  For instance, the |not| opcode was unnecessary
since it never occurred in any game.  Today there is a quite large base of
Inform users and many more games will be in circulation: and designers of
these new games want to know what they can depend on.  There is also
pressure for future extension of the format, so a game itself will need to
know what kind of interpreter is running it.

\subtitle{So what is ``standard''?}

To call itself ``Standard'', an interpreter should (as far as anyone knows)
obey this document exactly for every Version of the Z-machine it claims to
interpret.  (There's no problem with a standard interpreter which interprets
Version 5 only, for instance.)  Each edition of this document will be given
a Revision number (from 1.0 upwards), somewhat like the JFIF identification
number used by the JPEG standard.  A standard interpreter should communicate
the revision number it obeys in three ways:

\item{(a)} To someone downloading it from an FTP site or bulletin board:
by including it in its filename.
\item{(b)} To the player: for instance by means of an ``information'' option
on a menu, or in an initialisation sequence.
\item{(c)} To the game: by writing it into bytes in the header which were
always left zero before this standard was devised (see \S 11).  A game
compiled with Inform library 5/12 or later prints the revision number in its
banner (if this isn't 0.0).

\noindent Few arbitrary choices have been made in writing this document.  On
the few points where Infocom's own shipped interpreters disagree it has
usually been possible to decide which was ``correct''.  Elsewhere, minimum
levels of performance have been invented where necessary.  (For example, a
minimum call-stack size is needed for programmers to be sure of what level
of recursion is safe.  The call-stack size currently used by |Zip| has
been taken as the standard.)

Existing interpreters are close to the standard already.  Most ``difficult''
features (colours, fonts, sound effects, pictures, etc.) are optional, so
that a port only needs to set some header bit to indicate that it can't
oblige.  The big exception is timed input (in which an interrupt routine is
run every few tenths of a second while the player is deciding what to type).
Some ports can't manage this for operating-system reasons, others can but
don't because it's too much trouble.  In Infocom's specification the feature
is mandatory, but many ports of |Zip| ignore it.  In this document it is
optional and a new header bit has been allocated: see \S 11.

The very few paragraphs which actually extend the Infocom format, such as
the one describing this header bit, are marked |***|.

\subtitle{Terminology}

It is assumed that the reader is familiar with terms like `object', `tree',
`attribute', `property', `local and global variable'.  (See Chapter I of the
{\sl Inform Designer's Manual} for explanation of these.)

So far, eight Versions of the Z-machine exist, and the first byte of any
``story file'' (that is: any game program in the Infocom format) gives the
Version number it must be interpreted under.

The opcode names used in this document are those used by Inform 5.4 and
later.  The names are extended from those chosen by Mark Howell for his
disassembler |Txd| and were agreed on between him and the author as
a standard set.  We hope this will provide interpreter writers and
others with a common lexicon, and it would be helpful if future interpreter
sources use these names internally.

Hexadecimal numbers are written with an initial dollar, as in |$ff|, while
binary numbers are written with a double-dollar as in |$$11011|, according
to Inform conventions.  The bits in a byte are numbered 0 to 7, 0 being
the least significant and the top bit, 7, the most.

\subtitle{Where are all the grammar tables?}

The Z-machine has some lexical acuity but it doesn't contain a full parser:
it's like a computer without an operating system.
A game program has to contain its own parser
and the tables this uses are not part of the formal Z-machine specification.
(The Infocom games have similar parsing table formats since all the
Versions 1 to 5 games used a parser which slowly evolved from the
`Zork I' parser.)  Inform's parsing table
format is documented in the {\sl Inform Technical Manual}.  For the usual
format of Infocom's parsing tables, see the C source code to Mark Howell's
utility ``Infodump''.

\subtitle{Acknowledgements}

\quote
    There is an obvious resemblance between an unreadable script
    and a secret code; similar methods can be employed to break
    both.  But the differences must not be overlooked.  The code is
    deliberately designed to baffle the investigator; the script
    is only puzzling by accident.
\poemby{John Chadwick}{The Decipherment of Linear B}

The Z-machine was originally devised by Joel Berez and Marc Blank in 1979.
Marc Blank made most of the Version 4 extensions, and Version 5 was created
by Dave Lebling (with contributions from others including Brian Moriarty,
Duncan Blanchard and Linde Dynneson).  Version 6 was largely the work of Tim
Anderson and Dave Lebling.

In the reverse direction, decipherment is mostly due to the InfoTaskForce
(David Beazley, George Janczuk, Peter Lisle, Russell Hoare and Chris Tham),
Matthias Pfaller, Mike Threepoint, Mark Howell and Paul David Doherty.
(Only a few of the pieces in the jigsaw were placed by myself.)

I gratefully acknowledge the help of Paul David Doherty and Mark Howell, who
each drafts of this paper and sent back detailed corrections; also, of
Stefan Jokisch and Marnix Klooster who have put a great deal of work into
the fine detail of the specification; and of all those who commented on
the circulated draft, whose comments were mainly presentational but no less
important for that.  Mistakes and misunderstandings remain my own.

\medskip
\hbox to\hsize{\hfill\it Graham Nelson}
\hbox to\hsize{\hfill\it St Anne's College, Oxford}
\hbox to\hsize{\hfill\it 15 November 1995}
\medskip

\newpage

% ----------------------------------------------------------------------------

\specs{1}{The memory map}
\sp{1} The memory map of the Z-machine is an array of bytes with
``byte addresses'' running from 0 upwards.  This is divided into
three regions: ``dynamic'', ``static'' and ``high''.  Dynamic
memory begins from byte address |$00000| and runs up to the byte
before the byte address stored in the word at |$0e| in the header.
(Dynamic memory must contain at least 64 bytes.)  Static memory
follows immediately on.  Its extent is not defined in the header
(or anywhere else), though it must end by the last byte of the
story file or by byte address |$0ffff| (whichever is lower).
High memory begins at the ``high memory mark'' (the byte address
stored in the word at |$04| in the header) and continues to the
end of the story file.  The bottom of high memory may overlap with
the top of static memory (but not with dynamic memory).

\sp{1.1} Dynamic memory can be read or written to (either directly,
using |loadb|, |loadw|, |storeb| and |storew|, or indirectly with
opcodes such as |insert_obj| and |remove_obj|).

\sp{1.1.1} By tradition, the first 64 bytes are known as the
``header''.  The contents of this are given later but note that games
are not permitted to alter many bits inside it.

\sp{1.1.2} It is legal for games to alter any of the tables stored
in dynamic memory above the header, provided they leave the tables
in legal states.

\sp{1.2} Static memory can be read using the opcodes |loadb| and
|loadw|.  It is illegal for a game to attempt to write to static
memory.

\sp{1.3} Except for its (possible) overlap with static memory,
high memory cannot be directly accessed at all by a
game program.  It contains routines, which can be called,
and strings, which can be printed using |print_paddr|.

\sp{1.4} The maximum permitted length of a story file depends
on the Version, as follows:
$$ \matrix{{\rm V}1-3 & {\rm V}4-5  & {\rm V}6 & {\rm V}7 & {\rm V}8\cr
                 128 &   256       &   576    &   320    &   512\cr} $$

\nsp{2} There are three kinds of address in the Z-machine, all of
which can be stored in a 2-byte number: byte addresses, word
addresses and packed addresses.

\sp{2.1} A byte address specifies a byte in memory in the range 0
up to the last byte of static memory.

\sp{2.2} A word address specifies an even address in the bottom
128K of memory (by giving the address divided by 2).  (Word addresses
are used only in the abbreviations table.)

\sp{2.3} |***| A packed address specifies where a routine or string begins
in high memory.  Given a packed address $P$, the formula to obtain the
corresponding byte address $B$ is:
$$ B = \cases { 2P & Versions 1, 2 and 3\cr
               4P & Versions 4 and 5\cr
               4(P+R_O) & Versions 6 and 7, for routine calls\cr
               4(P+S_O) & Versions 6 and 7, for {\tt print\_paddr}\cr
               8P & Version 8\cr
} $$
$R_O$ and $S_O$ are the routine and strings offsets (specified in the
header as words at |$28| and |$2a|, respectively).

% ----------------------------------------------------------------------------
\topinsert
\centerline{\sl An example memory map of a small game}
\medskip
$$ \vbox{\offinterlineskip
\hrule
\halign{\vrule#&\strut\quad{\it #}\hfil\quad&\hfil # \quad&%
\vrule#&\strut\quad\hfil#\hfil\quad&\vrule#\cr
height2pt&\omit&\omit&&\omit&\cr
&& Start && Contains &\cr
height2pt&\omit&\omit&&\omit&\cr
\noalign{\hrule}
height2pt&\omit&\omit&&\omit&\cr
& Dynamic& |00000| && header &\cr
&        & |00040| && abbreviation strings &\cr
&        & |00042| && abbreviation table &\cr
&        & |00102| && property defaults &\cr
&        & |00140| && objects &\cr
&        & |002f0| && object descriptions &\cr
&        &         && and properties &\cr
&        & |006e3| && global variables &\cr
&        & |008c3| && arrays &\cr
& Static & |00b48| && grammar table &\cr
&        & |010a7| && actions table &\cr
&        & |01153| && preactions table &\cr
&        & |01201| && adjectives table &\cr
&        & |0124d| && dictionary &\cr
& High   & |01a0a| && Z-code &\cr
&        & |05d56| && static strings &\cr
&        & |06ae6| && end of file &\cr
height2pt&\omit&\omit&&\omit&\cr
}\hrule}$$
\endinsert

\remarks
Inform never compiles any overlap between static and high memory
(it places all data tables in dynamic memory).  However, many
Infocom games group tables of static data just above the high
memory mark, before routines begin; some, such as `Nord 'n'
Bert...', interleave static data between routines, so that static
memory actually overlaps code; and a few, such as `Seastalker'
release 15, even contain routines placed below the high memory
mark.  (The original idea behind the high memory mark was that
everything below it should be stored in the interpreter's RAM, while
what was above could reasonably be kept in ``virtual memory'', i.e.,
loaded off disc as needed.)

Note that the total of dynamic plus static memory must not exceed 64K.
(In fact, 64K minus 2 bytes.)  This is the most serious limitation
on the Z-machine (though it has not yet been reached by anyone).

Throughout the specification, Versions 7 and 8 are identical
to Version 5 except as stated at 1.1.4 and 1.2.3 above.

\newpage

% ----------------------------------------------------------------------------

\specs{2}{Numbers and arithmetic}

\sp{1} In the Z-machine, numbers are usually stored in 2 bytes
(in the form most-significant-byte first, then least-significant)
and hold any value in the range |$0000| to |$ffff| (0 to 65535
decimal).

\nsp{2} These values are sometimes regarded as signed, in the range
$-32768$ to $32767$.  In effect $-n$ is stored as $65536-n$
and so the top bit is the sign bit.

\sp{2.1} The operations of numerical comparison, multiplication,
addition, subtraction and printing of numbers are signed; bitwise
operations, division and remainder-after-division are unsigned.
(In particular, since comparison is signed, it is unsafe to compare
two addresses using simply |jl| and |jg|.)

\nsp{3} Arithmetic errors:

\sp{3.1} It is illegal to divide by 0 (or to ask for remainder after
division by 0) and an interpreter should halt with an error message
if this occurs.

\sp{3.2} Formally it has never been specified what the result of an
out-of-range calculation should be.  The author suggests that the
result should be reduced modulo |$10000|.

\nsp{4} The Z-machine needs a random number generator which at any time
has one of two states, ``random'' and ``predictable''.  When the game
starts or restarts the state becomes ``random''.  Ideally the generator
should not produce identical sequences after each restart.

\sp{4.1} When ``random'', it must be capable of generating a uniformly
random integer in the range $1\leq x\leq n$, for any value
$1\leq n\leq 32767$.  Any method can be used for this (for instance,
using the host computer's clock time in milliseconds).  The uniformity
of randomness should be optimised for low values of $n$ (say, up to
100 or so) and it is especially important to avoid regular patterns
appearing in remainders after division (most crudely, being alternately
odd and even).

\sp{4.2} The generator is switched into ``predictable'' state with a
seed value.  On any two occasions when the same seed is sown, identical
sequences of values must result (for an indefinite period) until
the generator is switched back into ``random'' mode.  The generator
should cope well with very low seed values, such as 10, and should not
depend on the seed containing many non-zero bits.

\sp{4.3} The interpreter is permitted to switch between these states
on request of the player.  (This is useful for testing purposes.)

\remarks
It is dangerous to rely on the ANSI C random number routines, as some
implementations of these are very poor.  This has made some games (in
particular, `Balances') unwinnable on some Unix ports of |Zip|.

The author suggests the following algorithm:
\item{1.} In ``random'' mode, the generator uses the host computer's
clock to obtain a random sequence of bits.
\item{2.} In ``predictable'' mode, the generator should store the
seed value $S$.  If $S<1000$ it should then internally generate
$$ 1, 2, 3, ..., S, 1, 2, 3, ..., S, 1, ... $$
so that |random n| produces the next entry in this sequence modulo $n$.
If $S\geq 1000$ then $S$ is used as a seed in a standard seeded
random-number generator.

\par\noindent (The rising sequence is useful for testing, since it will
produce all possible values in sequence.  On the other hand, a seeded
but fairly random generator is useful for testing entire scripts.)

% ----------------------------------------------------------------------------

\specs{3}{How text is encoded and printed}

\quote
   This technique is similar to the five-bit Baudot code, which
   was used by early Teletypes before ASCII was invented.
\endquote
\quote
   \quad -- Marc S. Blank and S. W. Galley, {\sl How to Fit a Large Program Into
a Small Machine}
\endquote

\sp{1} A string of encoded text is stored as a sequence of 2-byte
words.  Each of these is divided into three 5-bit `Z-characters', plus
1 bit left over, arranged as
\orm\beginstt
  --first byte-------   --second byte---
  7    6 5 4 3 2  1 0   7 6 5  4 3 2 1 0
  bit  --first--  --second---  --third--
\endtt\frm
The bit is set only on the last 2-byte word of the text, and so marks the
end.

\nsp{2} There are three `alphabets', A0 (lower case), A1 (upper case) and
A2 (punctuation) and during printing one of these is current at any given
time.  Initially A0 is current.  The meaning of a Z-character may depend on
which alphabet is current.

\sp{2.1} In Versions 1 and 2, the current alphabet can be any of the
three.  The Z-characters 2 and 3 are called `shift' characters and change
the alphabet for the next character only.  The new alphabet depends on
what the current one is:
\orm\beginstt
            from A0  from A1  from A2
 Z-char 2      A1       A2       A0
 Z-char 3      A2       A0       A1
\endtt\frm
Z-characters 4 and 5 permanently change alphabet, according to the
same table, and are called `shift lock' characters.

\sp{2.2} In Versions 3 and later, the current alphabet is always A0
unless changed for 1 character only: Z-characters 4 and 5 are shift
characters.  Thus 4 means ``the next character is in A1'' and 5 means
``the next is in A2''.  There are no shift lock characters.

\sp{2.3} An indefinite sequence of shift or shift lock characters is
legal (but prints nothing).

\nsp{3} In Versions 3 and later, Z-characters 1, 2 and 3 represent
abbreviations, sometimes also called `synonyms' (for traditional reasons):
the next Z-character indicates which abbreviation string to print.  If $z$
is the first Z-character (1, 2 or 3) and $x$ the subsequent one, then the
interpreter must look up entry $32(z-1)+x$ in the abbreviations table and
print the string at that word address.  In Version 2, Z-character 1 has this
effect (but 2 and 3 do not, so there are only 32 abbreviations).

\sp{3.1} Abbreviation string-printing follows all the rules of this section
except that an abbreviation string must not itself use abbreviations and
must not end with an incomplete multi-Z-character construction (see \S 3.6.1
below).

\nsp{4} Z-character 6 from A2 means that the two subsequent Z-characters
specify a ten-bit character code: the next Z-character gives the top 5
bits and the one after the bottom 5.  As detailed below, this is
printed using an extended form of the ASCII standard (for seven-bit
character codes).

\sp{4.1} Some Inform users require unusual accented characters (in one
case, Chinese characters).  Inform is able to produce `ASCII' values
which use the full 10 bits (using the |@@| string escape).  Game
designers may want to be able to modify the interpreter to print
something suitable when a value of 256 or above is found, and interpreter
writers are asked to make this easy.

\sp{4.1.1} The author wishes to reserve the `ASCII' values
768 to 1023 for future specification.  (One idea would be that
such a code causes a routine in Z-code to be called.  This would allow
much greater flexibility in variable printing.)

\sp{4.2} ASCII ``control codes'' in the range 0 to 31 are illegal
(i.e. should not be printed in any story file) except as follows:

\sp{4.2.1} Character 0 (ASCII ``null'') is legal but prints nothing.

\sp{4.2.2} Character 13 (``carriage return'') prints a newline.

\sp{4.2.3} In Version 6, character 9 (``tab'') at the start of a screen line
should print a paragraph indentation suitable for the font being used: if it
is printed in the middle of a screen line, it should be a space.  Character
11 (``cursor up'') should be printed as a suitable gap between two
sentences (in the same way that typographers normally place larger spaces
after the full stops ending sentences than after words or commas).

\sp{4.3} Character codes between 32 (``space'') and 126 (``tilde'') are
legal and are printed from the standard ASCII character set:
\orm\beginstt
     0123456789abcdef0123456789abcdef
     --------------------------------
$20   !"#$%&'()*+,-./0123456789:;<=>?
$40  @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
$60  `abcdefghijklmnopqrstuvwxyz{!}~
     --------------------------------
\endtt\frm
In particular code |$23| (35 decimal) is a hash mark, not a pound sign.
(Code |$7c| (124 decimal) is a vertical stroke which is shown as |!|
here for typesetting reasons.)  Character 127 (``delete'') is illegal.

\sp{4.4} The `ASCII' values between 128 and 154 are at present
undefined: undefined character values should be printed as question
marks.  The range 155 to 251 is reserved for European accented
characters, but 220 to 251 are undefined.  Accented characters should
either be printed from a suitable font (they are all taken from the
`ISO Latin 1' standard set) or transliterated into plain text as in
the following table:
\orm\beginstt
155:  a-umlaut      ae            191:  a-circumflex      a
156:  o-unlaut      oe            192:  e-circumflex      e
157:  u-umlaut      ue            193:  i-circumflex      i
158:  A-umlaut      Ae            194:  o-circumflex      o
159:  O-umlaut      Oe            195:  u-circumflex      u
160:  U-umlaut      Ue            196:  A-circumflex      A
161:  sz-ligature   ss            197:  E-circumflex      E
162:  quotation     << or "       198:  I-circumflex      I
163:    marks       >> or "       199:  O-circumflex      O
164:  e-umlaut      e             200:  U-circumflex      U
165:  i-umlaut      i             201:  a-ring            a
166:  y-umlaut      y             202:  A-ring            A
167:  E-umlaut      E             203:  o-slash           o
168:  I-umlaut      I             204:  O-slash           O
169:  a-acute       a             205:  a-tilde           a
170:  e-acute       e             206:  n-tilde           n
171:  i-acute       i             207:  o-tilde           o
172:  o-acute       o             208:  A-tilde           A
173:  u-acute       u             209:  N-tilde           N
174:  y-acute       y             210:  O-tilde           O
175:  A-acute       A             211:  ae-ligature       ae
176:  E-acute       E             212:  AE-ligature       AE
177:  I-acute       I             213:  c-cedilla         c
178:  O-acute       O             214:  C-cedilla         C
179:  U-acute       U             215:  Icelandic thorn   th
180:  Y-acute       Y             216:  Icelandic eth     th
181:  a-grave       a             217:  Icelandic Thorn   Th
182:  e-grave       e             218:  Icelandic Eth     Th
183:  i-grave       i             219:  pound symbol      L
184:  o-grave       o
185:  u-grave       u
186:  A-grave       A
187:  E-grave       E
188:  I-grave       I
189:  O-grave       O
190:  U-grave       U
\endtt\frm
|***| The values from 164 onward are defined for the first time
in this standard.  (Note that all these values are the same as the
keyboard input character codes for the same letters.)

\sp{4.5} The `ASCII' values 252 to 255 are illegal, not undefined.

\nsp{5} The remaining Z-characters translate directly into printed
characters:

\sp{5.1} The Z-character 0 is printed as a space.

\sp{5.2} In Version 1, Z-character 1 is printed as a new-line.

\sp{5.3} In Versions 2 and later, Z-characters in the range 6 to 31
depend on the current alphabet.  Except for character 6 in A2, they
are printed as:
\orm\beginstt
  Z-char 6789abcdef0123456789abcdef
current   --------------------------
 A0      abcdefghijklmnopqrstuvwxyz
 A1      ABCDEFGHIJKLMNOPQRSTUVWXYZ
 A2       ^0123456789.,!?_#'"/\-:()
         --------------------------
\endtt\frm
(Character 7 in A2, written here as a circumflex |^|, is a new-line.)

\sp{5.4} Version 1 has the same table except that A2 (needing no
new-line) accommodates the |<| character as well.  It has the form:
\orm\beginstt
         6789abcdef0123456789abcdef
         --------------------------
 A2       0123456789.,!?_#'"/\<-:()
         --------------------------
\endtt\frm

\sp{5.5} In Versions 5 and later, a game may replace the above
table by providing its own ``character set table''.  It does this
by giving the byte address of such a table in the word at |$34| in
the header.  (If this byte address is 0, then the default table
above is used.)

\sp{5.5.1} The character set table consists of 78 bytes arranged
as 3 blocks of 26 ASCII values, translating Z-characters 6 to 31
for alphabets A0, A1 and A2.  Z-characters 6 and 7 of A2, however,
are still translated as escape and newline codes (as above).

\nsp{6} Since the end-bit only comes up once every three Z-characters,
a string may have to be `padded out' with null values.  This is
conventionally achieved with a sequence of 5's, though a sequence of
(for example) 4's would work equally well.

\sp{6.1} It is legal for the string to end while a multi-Z-character
construction is incomplete: for instance, after only the top half of
an ASCII value has been given.  The partial construction is simply
ignored.  (This can happen in printing dictionary words which have
been guillotined to the dictionary resolution of 6 or 9 Z-characters.)

\nsp{7} When encrypting text for a dictionary word: A1 may not be
used; nor may abbreviations; the pad character, if needed, must be 5; and
the total string length must be 6 Z-characters (in Versions 1 to 3) or 9
(Versions 4 and later).  For example, ``i'' is encrypted as
\begindisplay
14, 5, 5, 5, 5, 5, 5, 5, 5\quad |$48a5| |$14a5| |$94a5|\cr
\enddisplay

\remarks
In practice the text compression factor is not really very good: for
instance, 155000 characters of text squashes into 99000 bytes.  (Text
usually accounts for about 75\% of a story file.)  Encoding does
at least encrypt the text so that casual browsers can't read it.
Well-chosen abbreviations will reduce total story file size by 10\% or so.

The German translation of `Zork I' uses a character set table for accented
letters and is illegible on interpreters (like |ITF|) which do not implement
this feature.  (`Shogun' also needs the character set table.)

It is helpful for an interpreter to filter out any ASCII control
characters other than those explicitly legalised above, as this makes
run-time crashes of the ``printing random text'' kind much less
severe for the terminal.

The continental European quotation marks |<<| and |>>| should have
spacing which looks sensible either in French style |<<|Merci!|>>|
or in German style |>>|Danke!|<<|.

Further accented characters may be allocated codes later.  Other graphical
or unusual characters are best handled by creating a new font (see \S 16
for an example font).

% ----------------------------------------------------------------------------

\specs{4}{How instructions are encoded}

\widepoem
We do but teach bloody instructions
Which, being taught, return to plague th' inventor
\poemby{Shakespeare}{Macbeth}

\sp{1} A single Z-machine instruction consists of the following
sections (and in the order shown):
\orm\beginstt
 Opcode               1 or 2 bytes
 (Types of operands)  1 or 2 bytes: 4 or 8 2-bit fields
 Operands             Between 0 and 8 of these: each 1 or 2 bytes
 (Store variable)     1 byte
 (Branch offset)      1 or 2 bytes
 (Text to print)      An encoded string (of unlimited length)
\endtt\frm
Bracketed sections are not present in all opcodes.  (A few opcodes
take both ``store'' and ``branch''.)

\nsp{2} There are four `types' of operand.  These are often specified
by a number stored in 2 binary digits:
\orm\beginstt
 $$00    Large constant (0 to 65535)    2 bytes
 $$01    Small constant (0 to 255)      1 byte
 $$10    Variable                       1 byte
 $$11    Omitted altogether             0 bytes
\endtt\frm

\sp{2.1} Large constants, like all 2-byte words of data in the Z-machine,
are stored with most significant byte first (e.g. |$2478| is stored as
|$24| followed by |$78|).  A `large constant' may in fact be a small
number.

\sp{2.2} Variable number |$00| refers to the top of the stack,
|$01| to |$0f| mean the local variables of the current routine
and |$10| to |$ff| mean the global variables.  It is illegal to
refer to local variables which do not exist for the current routine
(there may even be none).

\sp{2.3} The type `Variable' really means ``variable by value''.  Some
instructions take as an operand a ``variable by reference'': for instance,
|inc| has one operand, the reference number of a variable to increment.
This operand usually has type `Small constant' (and Inform automatically
assembles a line like |@inc turns| by writing the operand |turns| as
a small constant with value the reference number of the variable |turns|).

\nsp{3} Each instruction has a form (long, short, extended or variable)
and an operand count (0OP, 1OP, 2OP or VAR).
If the top two bits of the opcode are |$$11| the form is variable;
if |$$10|, the form is short.  If the opcode is 190 (|$BE| in hexadecimal)
and the version is 5 or later, the form is ``extended''.  Otherwise, the
form is ``long''.

\sp{3.1} In short form, bits 4 and 5 of the opcode byte give an operand
type as above.  If this is |$11| then the operand count is
0OP; otherwise, 1OP.  In either case the opcode number is
given in the bottom 4 bits.

\sp{3.2} In long form the operand count is always 2OP.  The opcode number
is given in the bottom 5 bits.

\sp{3.3} In variable form, if bit 5 is 0 then the count is 2OP;
if it is 1, then the count is VAR.  The opcode number is given
in the bottom 5 bits.

\sp{3.4} In extended form, the operand count is VAR.  The opcode number
is given in a second opcode byte.

\nsp{4} Next, the types of the operands are specified.

\sp{4.1} In short form, bits 4 and 5 of the opcode give the type.

\sp{4.2} In long form, bit 6 of the opcode gives the type of
the first operand, bit 5 of the second.  A value of 0 means a small
constant and 1 means a variable.  (If a 2OP instruction needs a
large constant as operand, then it should be assembled in variable
rather than long form.)

\sp{4.3} In variable or extended forms, a byte of 4 operand types is
given next.  This contains 4 2-bit fields: bits 6 and 7 are the first
field, bits 0 and 1 the fourth.  The values are operand types as above.
Once one type has been given as `omitted', all subsequent ones must
be.  Example: |$$00101111| means large constant followed by variable
(and no third or fourth opcode).

\sp{4.3.1} In the special case of the ``double variable'' VAR opcodes
|call_vs2| and |call_vn2| (opcode numbers 12 and 26), a second byte
of types is given, containing the types for the next four operands.

\nsp{5} The operands are given next.  Operand counts of 0OP, 1OP or 2OP
require 0, 1 or 2 operands to be given, respectively.  If the count is VAR,
there must be as many operands as there were types other than `omitted'.

\sp{5.1} Note that only |call_vs2| and |call_vn2| can have more than 4
operands, and no instruction can have more than 8.

\nsp{6} ``Store'' instructions return a value: e.g., |mul| multiplies
its two operands together.  Such instructions must be followed by a
single byte giving the variable number of where to put the result.

\nsp{7} Instructions which test a condition are called ``branch''
instructions.  The branch information is stored in one or two bytes,
indicating what to do with the result of the test.  If bit 7 of
the first byte is 0, a branch occurs when the condition was false;
if 1, then branch is on true.  If bit 6 is set, then the branch
occupies 1 byte only, and the ``offset'' is in the range 0 to 63,
given in the bottom 6 bits.  If bit 6 is clear, then the offset is
a signed 14-bit number given in bits 0 to 5 of the first byte
followed by all 8 of the second.

\sp{7.1} An offset of 0 means ``return false from the current
routine'', and 1 means ``return true from the current routine''.

\sp{7.2} Otherwise, a branch moves execution to the instruction at
address
\orm\beginstt
 Address after branch data + Offset - 2.
\endtt\frm

\nsp{8} Two opcodes, |print| and |print_ret|, are followed by a text
string.  This is stored according to the usual rules: in particular
execution continues after the last 2-byte word of text (the one with
top bit set).

\remarks
Some opcodes have type VAR only because the available codes for
the other types had run out; |print_char|, for instance.  Others, especially
|call|, need the flexibility to have between 1 and 4 operands.

The Inform assembler can assemble branches in either form, but the compiler
always writes 2-byte branch data and never uses offset values of 0 or 1.
(The computation involved in achieving these optimisations outweighs the
slight gain.)

The disassembler |Txd| numbers locals from 0 to 14 and globals from
0 to 239 in its output (corresponding to variable numbers 1 to 15, and
16 to 255, respectively).

The branch formula is sensible because in the natural implementation,
the program counter is at the address after the branch data when the branch
takes place: thus it can be regarded as
\beginstt
 PC = PC + Offset - 2.
\endtt
If the rule were simply ``add the offset'' then, since the offset couldn't
be 0 or 1 (because of the return-false and return-true values), we would
never be able to skip past a 1-byte instruction (say, a 0OP like |quit|),
or specify the branch ``don't branch at all'' (sometimes useful to ignore
the result of the test altogether).  Subtracting 2 means that the only
effects we can't achieve are
\beginstt
 PC = PC - 1     and     PC = PC - 2
\endtt
and we would never want these anyway, since they would put the program
counter somewhere back inside the same instruction, with horrid
consequences.

\bigskip\noindent{\sl On disassembly}
\medskip
\noindent Briefly, the first byte of an instruction can be decoded
using the following table:
\beginstt
 $00 -- $1f  long      2OP     small constant, small constant
 $20 -- $3f  long      2OP     small constant, variable
 $40 -- $5f  long      2OP     variable, small constant
 $60 -- $7f  long      2OP     variable, variable
 $80 -- $8f  short     1OP     large constant
 $90 -- $9f  short     1OP     small constant
 $a0 -- $af  short     1OP     variable
 $b0 -- $bf  short     0OP
 except $be  extended opcode given in next byte
 $c0 -- $df  variable  2OP     (operand types in next byte)
 $e0 -- $ff  variable  VAR     (operand types in next byte(s))
\endtt
Here is an example disassembly:
\beginlines
|  @inc_chk c 0 label;    05 02 00 d4|
|      long form; count 2OP; opcode number 5; operands:|
|          02     small constant (referring to variable c)|
|          00     small constant 0|
|      branch if true: 1-byte offset, 20 (since label is|
|      18 bytes forward from here).|
|  @print "Hello.^";      b2 11 aa 46 34 16 45 9c a5 |
|      short form; count 0OP.|
|      literal string, Z-chars: 4 13 10  17 17 20  5 18 5  7 5 5.|
|  @mul 1000 c sp;        d6 1f 03 e8 02 00|
|      variable form; count 2OP; opcode number 22; operands:|
|          03 e8  long constant (1000 decimal)|
|          02     variable c|
|      store result to stack pointer (var number 00).|
|  @call_1n Message;      8f 01 56|
|      short form; count 1OP; opcode number 15; operand:|
|          01 56  long constant (packed address of routine)|
|  .label;|
\endlines

% ----------------------------------------------------------------------------

\specs{5}{How routines are encoded}

\sp{1} A routine is required to begin at an address in memory which
can be represented by a packed address (for instance, in Version 5
it must occur at a byte address which is divisible by 4).

\nsp{2} A routine begins with one byte indicating the number of local
variables it has (between 0 and 15 inclusive).

\sp{2.1} In Versions 1 to 4, that number of 2-byte words follows,
giving initial values for these local variables.  In Versions 5 and
later, the initial values are all zero.

\nsp{3} Execution of instructions begins from the byte after this
header information.  There is no formal `end-marker' for a routine
(it is simply assumed that execution eventually results in a return
taking place).

\nsp{4} In Version 6, there is a ``main'' routine (whose packed address
is stored in the word at |$06| in the header) called when the game
starts up.  It is illegal to return from this routine.

\nsp{5} In all other Versions, the word at |$06| contains the
byte address of the first instruction to execute.  The Z-machine
starts in an environment with no local variables from which, again,
a return is illegal.

\remarks
Note that it is permissible for a routine to be in dynamic memory.
Marnix Klooster suggests this might be used for compiling code at
run time!

In Versions 3 and 4, Inform always stores 0 as the initial values
for local variables.

Inform's ``main'' routine is required not to have local variables
and has to be the first defined routine.  This ensures it is in the
bottom 64K of memory, as it must be (in Versions other than 6).

% ----------------------------------------------------------------------------

\specs{6}{The game state: storage and routine calls}

\sp{1} The ``state of play'' is defined as the following: the contents
of dynamic memory; the contents of the stack; the value of the program
counter (PC), and the ``routine call state'' (that is, the chain of routines
which have called each other in sequence, and the values of their local
variables).  Note that the routine call state, the stack and the PC
must be stored outside the Z-machine memory map, in the interpreter's
private memory.

\sp{1.1} The entire state of play must be stored when the game is saved.

\sp{1.1.1} The format of a saved game file is not specified.

\sp{1.1.2} An internal saved game for ``undo'' purposes (if there is one) is
not part of the state of play.  This is important: if a saved game file also
contained the internal saved game at the time of saving, it would be
impossible to undo the act of restoration.  It also prevents internal
saved games from growing larger and larger as they include their
predecessors.

\sp{1.2} On a ``restore'' or ``undo'' (which restores a game saved into
internal memory), the entire state of play is written back except for one
bit: bit 0 of `Flags 2' in the header, the flag revealing whether the game
is being transcribed to printer.

\sp{1.2.1} Before a ``restore'', an interpreter should check that the
file to be used has been saved from the same game currently being played.
(See remark below.)

\sp{1.2.2} After a ``restore'' or ``undo'', an interpreter should reset
the header values marked |Rst| in the header table of \S 11.  (It should
not be assumed that the game was saved by the same interpreter.)

\sp{1.3} A ``restart'' is similar: the entire state is restored from the
original story file; but the transcription bit is preserved; and the
interpreter should reset the |Rst| parts of the header.

\sp{1.4} In Versions 5 and later, an interpreter unable to save the game
state into internal memory (for ``undo'' purposes) must clear bit 4 of
`Flags 2' in the header.

\nsp{2} Global variables (variable numbers |$10| to |$ff|) are stored
in a table in the Z-machine's dynamic memory, at a byte address given in
word 6 of the header.  The table consists of 240 2-byte words and the
initial values of the global variables are the values initially contained in
the table.  (It is legal for a program to alter the table's contents
directly in play, though not for it to change the table's address.)

\nsp{3} Writing to the stack pointer (variable number |$00|) pushes a
value onto the stack; reading from it pulls a value off.  Stack entries
are 2-byte words as usual.

\sp{3.1} The stack is considered as empty at the start of each routine:
it is illegal to pull values from it unless values have first been pushed
on.

\sp{3.2} The stack is left empty at the end of each routine: when a
return occurs, any values pushed during the routine are thrown away.

\sp{3.3} Stack size has not previously been specified.  The author
proposes the present capacity of |Zip| as a future minimum standard:
let the `usage' of a routine call be 4 plus the number of local
variables it has.  During a game the total of the usages for each
routine in the recursive chain of routines being called, plus the
game's own stack usage, must never reach 1024.

\nsp{4} Routine calls occur in the following circumstances: when one
of the |call...| opcodes is executed; in Versions 4 and later, when
timed keyboard input is being monitored; in Versions 5 and later,
when a sound effect finishes; in Version 6, when the game begins
(to call the ``main'' routine); in Version 6, when a ``newline
interrupt'' occurs.

\sp{4.1} A routine call may have any number of arguments, from 0 to
3 (in Versions 1 to 4) or 0 to 7 (Versions 5 and later).  All
routines return a value (though sometimes this value is thrown away
afterward: for example by opcodes in the form |call_vn*|).

\sp{4.2} Routine calls preserve local variables and the stack
(except when the return value is stored in a local variable or onto
the top of the stack).

\sp{4.3} A routine call to packed address 0 is legal: it does nothing
and returns false (0).  Otherwise it is illegal to call a packed
address where no routine is present.

\sp{4.4} When a routine is called, its local variables are created
with initial values taken from the routine header (Versions 1 to
4) or with initial value 0 (Versions 5 and later).  Next, the
arguments are written into the local variables (argument 1 into
local 1 and so on).

\sp{4.4.1} It is legal for there to be more arguments than local
variables (any spare arguments are thrown away) or for there to
be fewer.

\sp{4.5} The return value of a routine can be any Z-machine number.
Returning `false' means returning 0; returning `true' means
returning 1.

\nsp{5} A ``stack frame'' is an index to the routine call state
(that is, the call-stack of return addresses from routines currently
running, and values of local variables within them).  This index
is a Z-machine number.  The interpreter must be able to produce the
current value and to set a value further down the call-stack than
the current one, effectively throwing away its recent history
(see |catch| and |throw|).

\nsp{6} In Version 6, the Z-machine understands a third kind of stack: a
``user stack'', which is a table of words in dynamic memory.  The first word
in this table always holds the number of spare slots on the stack (so the
initial value is the capacity of the stack).  The Z-machine makes no
check on stack under-flow (i.e., pulling more values than were pushed)
which would over-run the length of the table if the program allowed it
to happen.

\remarks
Most interpreters store the whole of dynamic memory to disc as part of their
saved game files, which can make them as much as 45K or so long.  A player
making a serious attack on a game may end up wasting a whole megabyte, more
than convenient without a hard disc.  Bryan Scattergood's Psion interpreter
ingeniously avoids this by only saving bytes of dynamic memory which are
different from the initial state of the game.

It is unspecified how an interpreter should decide whether a saved game file
belongs to the game currently being played.  It is normal to insist that the
release numbers, serial codes and checksums all match.  The |Pinfocom|
interpreter deliberately checks only the release number, so that saved games
can be exchanged between different editions of `Seastalker' (presumably
compiled to handle the sonarscope differently).

The stack is stored in the interpreter's own memory, not anywhere in the
Z-machine.  The game program has no direct access to the stack memory or
stack pointer; on some implementations the game's main stack is also used to
store the routine call state (i.e. the game stack and the call-stack are the
same) but this need not be true.

The stack size specification guarantees in particular that if the game
itself never uses more than 32 stack entries at once then it can have
a recursive depth of at least 90 routine calls.  The author believes
that old Infocom games will all run with a stack size of 512 words.

Note that the ``state of play'' does not include numerous input/output
settings (the current window, cursor position, splitness or otherwise,
which streams are selected, etc.): neither does it include the state
of the random-number generator.  (Games with elaborate status lines
must redraw them after a restore has taken place.)

|Zip| provides ``undo'', but the |ITF| interpreter currently does not (and
|save_undo| returns 0, unfortunately).  This is probably its greatest
failing.  Some Infocom-written interpreters will only provide ``undo'' to a
game which has bit 4 of `Flags 2' set: but Inform 5.5 doesn't set this bit,
so modern interpreters should be more generous.

% ----------------------------------------------------------------------------

\specs{7}{Output streams and file handling}

\sp{1} At any given time text is being output through a selection of
``output streams" (possibly none, possibly several at once).

\sp{1.1} Two output streams are common to all Versions:
number 1 (the screen) and 2 (the game transcript, usually printed
to a printer or a file).

\sp{1.2} Versions 3 and later supply these and two other output streams,
numbered 3 (Z-machine memory) and 4 (a script file of the player's whole
commands and of individual keypresses as read by |read_char|).

\sp{1.2.1} Output stream 3 writes to a table in dynamic memory.  When the
stream is selected, the table may have any contents (even the initial `size'
word will be ignored by the interpreter).  While the stream is selected, the
table's contents are unspecified (and a game cannot safely read or write
to it).  When the stream is deselected, the initial word of the table holds
the number of characters printed and subsequent bytes hold those characters.
Similarly, in Version 6, the total width of printing (in units) will then be
stored in the word at |$30| in the header.  (It is the programmer's
responsibility to make the table large enough: the interpreter performs no
overflow checking.)

\sp{1.2.2} Output stream 3 is unusual in that, while it is selected, no
text is sent to any other output streams which are selected.  (However,
they remain selected.)

\sp{1.2.2.1} Newlines are written to output stream 3 as ASCII 13.  Any
character 10 codes printed should be converted to 13.

\sp{1.2.3} Output stream 4 is unusual in that, when it is selected,
the only text printed to it is that of the player's commands and
keypresses (as read by |read_char|).  (Each command is written, in
one go, when it has been finished: a command which has been timed-out,
or has been terminated by a code in the terminating character codes
table, is not written.  Mistypes and uses of `delete' are not written.)

\nsp{2} On output streams 1 and 2 (only), text printing may be ``buffered''
in that new-lines are automatically printed to ensure that no word
(of length less than the width of the screen) spreads across two lines.
(This process is sometimes called ``word-wrapping''.)

\sp{2.1} In Versions 1 to 3, buffering is always on.  In Versions 4
and later it is on by default (at the start of a game) and a game can
switch it on or off using the |buffer_mode| opcode.

\sp{2.2} In Version 6, each of the eight windows has its own ``buffering
flag''.  In other Versions, the |buffer_mode| applies
only to the lower window.  Output should never be buffered on
the upper window.

\nsp{3} In Versions 1 and 2, output stream 1 is always selected and
stream 2 can be selected or deselected by the game, by setting or clearing
bit 0 of `Flags 2'.

\nsp{4} In Versions 3 and later, all four output streams can be selected
or deselected using the |output_stream| opcode.  In addition, stream 2
can be selected or deselected by setting or clearing bit 0 of `Flags 2'.

\nsp{5} Character codes in the range 256 to 767 can only be printed on
the screen.  The author encourages interpreter-writers to make it easy
for game designers to modify the interpreter to print suitable substitutes
on the other streams.  (For instance, if 500 represents a Chinese dragon
character, this routine might print ``dragon'' on the other streams.)
Failing this, good practice would be to print a question mark on the
other streams.

\nsp{6} In Versions 5 and later, the Z-machine has the ability to load
and save files (using optional operands with the |save| and |restore|
opcodes).

\sp{6.1} |***| Filenames have the following format (approximately the MS-DOS
8.3 rule): one to eight alphanumeric characters, a full stop and zero to
three alphanumeric characters (the ``file extension'').

\sp{6.1.1} The interpreter must convert all filenames to upper case before
use.  If no full stop is given, ``.AUX'' should be appended.

\sp{6.1.2} Games should avoid the extensions ``.INF'', ``.H'', ``.Z''
followed by a number or ``.SAV'': otherwise they may be in danger of erasing
their own object code, source code or saved game files.

\sp{6.2} |***| Saved files are not associated with any particular session
of a game.  They are not part of the ``state of play''.

\sp{6.3} |***| A game may depend on having up to 32 auxiliary files (with
different names).

\sp{6.4} File-handling errors such as ``disc corrupt'' and ``disc full''
should be reported directly to the player by the interpreter.  The error
``file not found'' should only cause a failure return code from |restore|.

\remarks
The {\sl Inform Designer's Manual} advises games always to switch
buffering off when printing to the upper window.  This is wise since
the |ITF| interpreter does not behave correctly on this point.

An ambiguous point about output stream 4 is whether it should contain
the answers to interpreter questions like ``what file name should your
saved game have?'': it can actually be quite useful to be able to include
such answers in test script files.  (When running a long script, I often
save the game at several places during it, in order to save time in
re-running passages.)

Ideally, an interpreter should be able to write time delays (for timed input)
into stream 4 (i.e., to a script file).  In practice this is formidably
hard to implement.

A typical auxiliary file might be one containing the player's preferred
choices.  This would be created when he first changed any of the default
settings, and loaded (if present) whenever the game started up.

% ----------------------------------------------------------------------------

\specs{8}{The screen model}

\sp{1} Text may be printed in any font of the interpreter's choice,
variable- or fixed-pitch: except that when bit 1 of `Flags 2' in
the header is set, or when the text style has been set to Fixed Pitch,
then a fixed-pitch font must be used.

\sp{1.1} In Versions 5 and later, the height and width of the current
font (in units (see below)) should be written to bytes |$26| and
|$27| of the header, respectively.  The width of a font is defined
as the width of its `0' character.

\sp{1.2} An interpreter should ideally provide 4 fonts, with ID numbers
as follows:
\orm\beginstt
  1: the normal font
  2: a picture font
  3: a character graphics font
  4: a Courier-style font with fixed pitch
\endtt\frm
(In addition, font ID 0 means ``the previous font''.)
Ideally all text styles should be available for each font (for instance,
Courier bold should be obtainable) except that font 3 need only be
available in Roman and Reverse Video.  Each font should provide characters
for character codes 32 to 126 (plus character codes for any accented
characters with codes greater than 127 which are being implemented as single
accented letters on-screen).

\sp{1.3} A game must not use fonts other than 1 unless allowed to by the
interpreter: see the |set_font| opcode for how to give or refuse permission.
(`Beyond Zork' produces different character graphics according to whether or
not font 3 is available: see \S 16 for the full story.)  This permission
may, at the interpreter's whim, depend on which window is active.

\sp{1.3.1} It is legal for a game to change font at any time,
including halfway through the printing of a word.

\sp{1.4} The specification of the ``picture font'' is unknown
(conjecturally, it was intended to provide pictures before Version
6 was properly developed).  Interpreters need not implement it.

\sp{1.5} The specification of the character graphics font is given
in \S 16.

\sp{1.5.1} In Version 5 (only), an interpreter which cannot provide
the character graphics font should clear bit 3 of `Flags 2' in the
header.

\nsp{2} In Versions 1 to 3, a status line should be printed by the
interpreter, as follows.  In Version 3, it must set bit 4 of
`Flags 1' in the header if it is unable to produce a status line.

\sp{2.1} In Versions 1 and 2, all games are ``score games''.  In
Version 3, if bit 1 of `Flags 1' is set then the game is a ``score game'';
otherwise, a ``time game''.

\sp{2.2} The short name of the object whose number is in the first global
variable should be printed on the left hand side of the line.

\sp{2.2.1} Whenever the status line is being printed the first global
must contain a valid object number.  (It would be useful if interpreters
could protect themselves in case the game accidentally violates this
requirement.)

\sp{2.2.2} If the object's short name exceeds the available room on
the status line, the author suggests that an interpreter should break
it at the last space and append an ellipsis ``...''.  There is no
guaranteed maximum length for location names but an interpreter should
expect names of length up to at least 49 characters.

\sp{2.3} If there is room, the right hand side of the status line should
display:

\sp{2.3.1} For ``score games'': the score and number of turns, held in
the values of the second and third global variables respectively.  The
score may be assumed to be in the range $-99$ to $999$ inclusive, and
the turn number in the range $0$ to $9999$.

\sp{2.3.2} For ``time games'': the time, in the form |hours:minutes| (held
in the second and third globals).  The time may be given on a 24-hour clock
or the number of hours may be reduced modulo 12 (but if so, ``AM'' or ``PM''
should be appended).  Either way the player should be able to see the
difference between 4am and 4pm, for example.  The hours global may be
assumed to be in the range 0 to 23 and the minutes global in the range
0 to 59.

\sp{2.4} The status line is updated in exactly two circumstances: when
a |show_status| opcode is executed, and just before the keyboard is
read by |read|.  (It is not displayed when the game begins.)

\nsp{3} Under Versions 5 and later, text printing has a current
foreground and background colour.  (In Version 6, each window has its
own pair.)

\sp{3.1} The following codes are used to refer to colours:
\orm\beginstt
   -1 =  the colour of the pixel under the mouse arrow (if any)
   0  =  the current setting of this colour
   1  =  the default setting of this colour
   2  =  black   3 = red       4 = green    5 = yellow
   6  =  blue    7 = magenta   8 = cyan     9 = white
\endtt\frm
(These are loosely based on the IBM PC colour-scheme.)

\sp{3.2} If the interpreter cannot produce colours, it should clear
bit 0 of `Flags 1' in the header.

\sp{3.3} If the interpreter can produce colours, it should set bit
0 of `Flags 1' in the header, and write its default background
and foreground colours into bytes |$2c| and |$2d| of the header.

\sp{3.4} If a game wishes to use colours, it should have bit 6 in
`Flags 2' set in its story file.  (However, an interpreter should not
rule out the use of colours just because this has not been done.)

\nsp{4} The screen should ideally be at least 60 characters wide by 14 lines
deep.  (Old Apple II interpreters had a 40 character width and some modern
laptop ones have a 9 line height, but implementors should seek to avoid
these extremes if possible.)  The interpreter may change the exact
dimensions whenever it likes but must write the current height (in lines)
and width (in characters) into bytes |$20| and |$21| in the header.

\sp{4.1} The interpreter should use the screen height for calculating
when to pause and print ``[MORE]''.  A screen height of 255 lines means
``infinite height'', in which case the interpreter should never stop
printing for a ``[MORE]'' prompt.  (In case, say, the screen is actually
a teletype printer, or has very good ``scrollback''.)

\sp{4.2} Screen dimensions are measured in notional ``units''.  In
Versions 1 to 4, one unit is simply the height or width of one character.
In Version 5 and later, the interpreter is free to implement units as
anything from character sizes down to individual pixels.

\sp{4.3} In Version 5 and later, the screen's width and height in units
should be written to the words at |$22| and |$24|.

\nsp{5} The screen model for Versions 1 and 2 is as follows:

\sp{5.1} The screen can only be printed to (like a teletype) and there
is no control of the cursor.

\sp{5.2} At the start of a game, the screen should be cleared and the text
cursor placed at the bottom left (so that text scrolls upwards as the game
gets under way).

\nsp{6} The screen model for Version 3 is as follows:

\sp{6.1} The screen is divided into a lower and an upper window and at any
given time one of these is selected.  (Initially it is the lower
window.)  The game uses the |set_window| opcode to select one of the
two.  Each window has its own cursor position at which text is
printed.  Operations in the upper window do not move the cursor of the
lower.  Whenever the upper window is selected, its cursor position is
reset to the top left.  Selecting, or re-sizing, the upper window does
not change the screen's appearance.

\sp{6.1.1} The upper window has variable height (of $n$ lines) and the
same width as the screen.  This should be displayed on the $n$ lines of
the screen below the top one (which continues to hold the status line).
Initially the upper window has
height 0.  When the lower window is selected, the game can split off
an upper window of any chosen size by using the |split_window| opcode.

\sp{6.1.1.1} Printing onto the upper window overlays whatever text is
already there.  Printing is normally buffered (unless the game has turned
this off), just as in the lower window.

\sp{6.1.2} An interpreter need not provide the upper window at all.  If
it is going to do so, it should set bit 5 of `Flags 1' in the header to
signal this to the game.  It is only legal for a game to use
|set_window| or |split_window| if this bit has been set.

\sp{6.1.3} Following a ``restore'' of the game, the interpreter should
automatically collapse the upper window to size 0.

\sp{6.2} When text reaches the bottom right of the lower window, it
should be scrolled upwards.  The upper window should never be scrolled:
it is legal for a character to be printed on the bottom right position
of the upper window (but the position of the cursor after this operation
is undefined: the author suggests that it stay put).

\sp{6.3} At the start of a game, the screen should be cleared and the text
cursor placed at the bottom left (so that text scrolls upwards as the game
gets under way).

\nsp{7} The screen model for Versions 4 and later, except Version 6,
is as follows:

\sp{7.1} Text can be printed in five different styles (modelled on the
VT100 design of terminal).  These are: Roman (the default), Bold, Italic,
Reverse Video (usually printed with foreground and background colours
reversed) and Fixed Pitch.  The specification does not require the
interpreter to be able to display more than one of these at once (e.g. to
combine italic and bold), and most interpreters can't.  If the interpreter
is going to allow certain combinations, then note that changing back to
Roman should turn off all the text styles currently active.

\sp{7.1.1} An interpreter need not provide Bold or Italic (even for font 1)
and is free to interpret them broadly.  (For example, rendering bold-face by
changing the colour, or rendering italic with underlining.)

\sp{7.1.2} It is legal to change text style at any point, including in
the middle of a word being printed.

\sp{7.2} There are two ``windows'', called ``upper'' and ``lower'': at
any given time one of these two is selected.  (Initially it is the lower
window.)  The game uses the |set_window| opcode to select one of the
two.  Each window has its own cursor position at which text is
printed.  Operations in the upper window do not move the cursor of the
lower.  Whenever the upper window is selected, its cursor position is
reset to the top left.

\sp{7.2.1} The upper window has variable height (of $n$ lines) and the
same width as the screen.  (It is usual for interpreters to print the
upper window on the top $n$ lines of the screen, overlaying any text
which is already there, having been printed in the lower window some
time ago.)  Initially the upper window has height 0.  When the lower
window is selected, the game can split off an upper window of any
chosen size by using the |split_window| opcode.

\sp{7.2.1.1} It is unclear exactly what |split_window| should do if
the upper window is currently selected.  The author suggests that
it should work as usual, leaving the cursor where it is if the
cursor is still inside the new upper window, and otherwise moving
the cursor back to the top left.  (This is analogous to the Version 6
practice.)

\sp{7.2.2} In Version 4, the lower window's cursor is always on
the bottom screen line.  In Version 5 it can be at any line which is
not underneath the upper window.  If a split takes place which would
cause the upper window to swallow the lower window's cursor position,
the interpreter should move the lower window's cursor down to the
line just below the upper window's new size.

\sp{7.2.3} When the upper window is selected, its cursor position
can be moved with |set_cursor|.  This position is given in characters
in the form (row, column), with $(1,1)$ at the top left.  The opcode
has no effect when the lower window is selected.  It is illegal
to move the cursor outside the current size of the upper window.

\sp{7.2.4} An interpreter should use a fixed-pitch font when printing on
the upper window.

\sp{7.2.5} In Version 4, text buffering should work in the upper window
exactly as it does in the lower one (i.e., it must be turned off by
the game if it is not required).  In Versions 5 and later, text buffering
is never active in the upper window (even if a game begins printing there
without having turned it off).

\sp{7.3} Clearing regions of the screen:

\sp{7.3.1} When text reaches the bottom right of the lower window, it
should be scrolled upwards.  (When the text style is Reverse Video
the new blank line should {\bf not} have reversed colours.)  The upper
window should never be scrolled: it is legal for a character to be
printed on the bottom right position of the upper window (but the
position of the cursor after this operation is undefined: the author
suggests that it stay put).

\sp{7.3.2} Using the opcode |erase_window|, the specified window
can be cleared to background colour.  (Even if the text style is Reverse
Video the new blank space should not have reversed colours.)

\sp{7.3.2.1} In Versions 5 and later, the cursor for the window being erased
should be moved to the top left.  In Version 4, the lower window's cursor
moves to its bottom left, while the upper window's cursor moves to top left.

\sp{7.3.3} Erasing window $-1$ clears the whole screen, collapses the
upper window to height 0 and moves the cursor of the lower screen
to bottom left (in Version 4) or top left (in Versions 5 and
later).  The same operation should happen at the start of a game.

\sp{7.3.4} Using |erase_line| in the upper window should erase
the current line from the cursor position to the right-hand edge,
clearing it to background colour.  (Even if the text style is
Reverse Video the new blank space should not have reversed colours.)

\nsp{8} The screen model for Version 6 is as follows:

\sp{8.1} The display is an array of pixels.  Coordinates are usually
given (in units) in the form $(y,x)$, with $(1,1)$ in the top left.

\sp{8.2} If the interpreter thinks the status line should be redrawn
(e.g. because a menu window has been clicked over it), it may set bit
2 of `Flags 2'.  The game is expected to notice, take action and clear
the bit.  (However, a more efficient interpreter would cache
the status line and handle redraws itself.)

\sp{8.3} There are eight ``windows'', numbered 0 to 7.  The code $-3$
is used as a window number to mean ``the currently selected window''.
This selection can be changed with the |set_window| opcode.
Windows are invisible and usually lie on top of each other.  When
something is printed in a window, it appears on the screen, but
subsequent movements of the window do not move what was printed and
there is no sense in which characters `belong' to any particular
window once printed.  Each window has a position (in units), a size
(in units), a cursor position within it (in units, relative to its
own origin), a number of flags called ``attributes'' and a number
of variables called ``properties''.

\sp{8.3.1} There are four attributes, numbered as follows:
\orm\beginstt
   1: character wrapping
   2: scrolling
   3: text copied to output stream 2 (the transcript, if selected)
   4: buffered printing
\endtt\frm
Each can be turned on or off, using the |window_style| opcode.

\sp{8.3.1.1} Character wrapping takes place (if set) when printing
a character would push beyond the right-hand edge of the window:
if set, then the character is printed on the left of the next line.
If it is clear, then text is printed along the line but clipped
to the window size.

\sp{8.3.2} There are 16 properties, numbered as follows:
\orm\beginstt
   0  y coordinate    6   left margin size            12  font number
   1  x coordinate    7   right margin size           13  font size
   2  y size          8   newline interrupt routine   14  attributes
   3  x size          9   interrupt countdown         15  line count
   4  y cursor        10  text style
   5  x cursor        11  colour data
\endtt\frm
Each property is a standard Z-machine number and is readable
with |get_wind_prop| and writeable with |put_wind_prop|.  However,
a game should only use |put_wind_prop| to set the newline
interrupt routine and interrupt countdown: everything else is
either set by the interpreter (such as the line count) or
set using specialised opcodes (such as |set_font|).

\sp{8.3.2.1} If a window has character wrapping, then text is
clipped to stay inside the left and right margins.  After a
new-line, the cursor moves to the left margin on the next line.
Margins can be set with |set_margins| but this should only be
done just after a newline or just after the window has been
selected.  (These values are margin sizes in pixels, and are by
default 0.)

\sp{8.3.2.2} If the interrupt countdown is set to a non-zero value
(which by default it is not), then the line count is decremented on each
new-line, and when it hits zero the routine whose packed address is stored
in the ``newline interrupt routine'' property is called before text printing
resumes.  (This routine may, for example, meddle with margins to roll text
around a crinkly-shaped picture.)  The interrupt routine should not attempt
to print anything.

\sp{8.3.2.3} The text style is set just as in Version 4, using
|set_text_style| (which sets that for the current window).  The
property holds the operand of that instruction (e.g. 4 for italic).

\sp{8.3.2.4} The foreground colour is stored in the upper byte of the
colour data property, the background colour in the lower byte.

\sp{8.3.2.5} The font height (in pixels) is stored in the upper byte of the
font size property, the font width (in pixels) in the lower byte.

\sp{8.3.2.6} The interpreter may use the line count to see when it
should print ``[MORE]''.

\sp{8.3.3} All eight windows begin at $(1,1)$.  Window 0 occupies the
whole screen and is initially selected.
Window 1 is as wide as the screen but has zero height.  Windows 2 to 7
have zero width and height.  All eight windows begin with buffered
printing on, and the other attributes off.

\sp{8.3.4} A window can be moved with |move_window| and resized with
|window_size|.  If the window size is reduced so that its cursor lies
outside it, the cursor should be reset to the left margin on the top
line.

\sp{8.3.5} Each window remembers its own cursor position (relative
to its own coordinates, so that the position $(1,1)$ is at its top
left).  These can
be changed using |set_cursor| (and it is legal to move the cursor
for an unselected window).  It is illegal to move the cursor outside
the current window.

\sp{8.3.6} Each window can be scrolled vertically (up or down) any
number of pixels, using the |scroll_window| opcode.

\sp{8.4} To some extent windows 0 and 1 mimic the behaviour of the
lower and upper windows in the Version 4 screen model:

\sp{8.4.1} The
|split_screen| opcode tiles windows 0 and 1 so that window 1 has
the given height and is placed at the top left, while window 0 is
moved to be just below it and has its height shortened by the
height of window 1.  (If this makes a negative amount, the height
becomes 0.)  Finally, window 0 is selected.

\sp{8.4.2} An ``unsplit'' (that is, a |split_screen 0|) takes place
when the entire screen is cleared with |erase_window -1|, if a
``split'' has previously occurred (meaning that windows 0 and 1
have been set up as above).

\sp{8.5} Screen clearing operations:

\sp{8.5.1} Erasing a picture is like drawing it (see below), except
that the space where it would appear is painted over with background
colour instead.

\sp{8.5.2} The current line can be erased using |erase_line|, either
all the way to the right margin or by any positive number of pixels in
that direction.  The space is painted over with background colour
(even if the current text style is Reverse Video).

\sp{8.5.3} Each window can be erased using |erase_window|, erasing to
background colour (even if the current text style is Reverse Video).

\sp{8.5.3.1} Erasing window number -1 erases the entire screen
and unsplits windows 0 and 1 (see above).

\sp{8.5.3.2} Erasing window -2 erases the entire screen (without
changing any window attributes or cursor positions).

\sp{8.6} Pictures may accompany the game.  They are not stored in the
story file (or the Z-machine) itself, and the interpreter is simply
expected to know where to find them.  Infocom supplied files of
pictures in different formats on different machines.  The exact format of
such files is not specified here.

\sp{8.6.1} Pictures are numbered from 1 upwards (not necessarily
contiguously).  They can be ``drawn'' or ``erased'' (using |draw_picture|
and |erase_picture|).  Before attempting to do so, a game may ask the
interpreter about the picture (using |picture_data|): this allows the
interpreter to signal that the picture in question is unavailable,
or to specify its height and width.

\sp{8.6.2} The game may, if it wishes, use the |picture_table| opcode
to give the interpreter advance warning that a group of pictures will
soon be needed (for instance, a collection of icons making up a control
panel).  The interpreter may want to load these pictures off disc and
into a memory cache.

\remarks
See \S 16 for comment on how `Beyond Zork' uses fonts.

Some interpreters print the status line when they begin running a Version
3 game, but this is incorrect.  (It means that a small game printing text
and then quitting cannot be run unless it includes an object.)  The author's
preferred status line formats are:
\beginstt
Hall of Mists                                 80/733
Lincoln Memorial                              12:03 PM
\endtt
Thus the score/turns block always fits in $3+1+4=8$ characters and the
time in $2+1+2+1+2=8$ characters.  (Games needing more exotic time lines,
for example, should not be written in Version 3.)

The only existing Version 3 game to use an upper window is `Seastalker'
(for its sonarscope display).

Some ports of |ITF| apply buffering (i.e. word-wrapping) and scrolling to
the upper window, with unfortunate consequences.  This is why
the standard Inform status line is one character short of the width
of the screen.

The original Infocom files seldom use |erase_window|, except with window
$-1$ (for instance `Trinity' only uses it in this form).  |ITF| does not
implement it in any other case.

The Version 5 re-releases of older games make use of consecutive
|set_text_style| instructions to attempt to combine boldface reverse video
(in the hints system).

None of Infocom's Version 4 or 5 files use |erase_line| at all, and |ITF|
implements it badly (with unpredictable behaviour in Reverse Video text
style).  (It's interesting to note that the Version-5 edition of `Zork I'
- one of the earliest Version 5 files -- blanks out lines by looking up
the screen width and printing that many spaces.)

Note that a minor bug in |Zip| writes bytes |$22| to |$25| in the
header as four values, giving the screen dimensions in the form left,
right, top, bottom: provided units are characters (i.e. provided the
font width and height are both 1) then since ``left'' and ``top''
are both 0, this bug has no effect.

Some details of the known IBM graphics files are given in Paul David
Doherty's ``Infocom Fact Sheet''.  See also Mark Howell's program
``pix2gif'', which extracts pictures to GIF files.  (This is one of
his ``Infocom toolkit'' programs.)

% ----------------------------------------------------------------------------

\specs{9}{Sound effects}

\sp{1} Some games, from Version 3 onward, have sound effects attached.
These are not stored in the story files (or the Z-machine) itself,
and the interpreter is simply expected to know where to find them.
Infocom implemented sound effects differently on different machines.

\sp{1.1} In Version 6, the interpreter should set bit 5 of `Flags 1'
if it can provide sound effects.

\sp{1.2} In Version 5 and later, a game should have bit 7 of `Flags 2'
set in its story file if it wants to use sound effects.  The interpreter
should then clear this bit if it cannot oblige.

\nsp{2} Sound effects are numbered upwards from 1.  Number 1 is a
high-pitched beep, number 2 a low-pitched one and effects from 3 upward
are supplied by the interpreter somehow for the particular game in
question.

\nsp{3} A sound effect can be played at any volume level from 1 to 8 (8
being loudest of these).  The volume level $-1$ should be implemented as
``loudest possible''.

\nsp{4} Sound effects take place in the background, while normal operation
of the Z-machine is going on.  Control is via the |sound_effect| opcode,
allowing the game to prepare, start, stop or finish with an effect.

\sp{4.1} The game may (but need not) ``prepare'' a sound effect before
use.  This would indicate to the interpreter that the game intends
to use the effect soon: an interpreter might act on this information by
loading the sampled sound off disc and into a memory cache.

\sp{4.2} A sound effect can then be ``stopped'' or ``started''.  Only one
sound effect is playing at any given time, and starting a new sound effect
automatically stops any current one.

\sp{4.3} In Versions 5 and later, a sound effect may repeat any specified
number of times, or repeat forever (until stopped).

\sp{4.4} Eventually, though, if it has not been stopped, it may end by itself.
A routine (specified at start time) can then be called.  The intention is that
this routine may implement effects such as fading in and out, by replaying
the sound effect at a different volume.  (A game should not place any important
code in such a routine.)

\sp{4.5} The game should explicitly ``finish with'' any sound effect which is
not likely to occur again for a while: the interpreter can then throw it out
of memory.

\remarks
The safest way an Inform program can try to produce a bleep is by
executing |@sound_effect 1|.  Some ports of |Zip| believe that the
first operand of this is the number of bleeps to make (so that
|@sound_effect 2| bleeps twice), but this is incorrect.

Only two Infocom games provided sound effects: `The Lurking Horror'
and `Sherlock'.  Their story files only contain the following usages of
|sound_effect|:
\beginstt
 sound_effect 1
 sound_effect 2
 sound_effect number 2 volume                   (in TLH)
 sound_effect number 2 volume/repeats function  (in Sherlock)
 sound_effect 0 3
 sound_effect 0 4
\endtt

The format of Infocom's shipped sound effects files has been documented by
Stefan Jokisch and his notes are available from |ftp.gmd.de|.

% ----------------------------------------------------------------------------

\specs{10}{Input streams and devices}

\sp{1} In Versions 1 and 2, the player's commands can only be
drawn from the keyboard.

\nsp{2} In Versions 3 and later, the player's keypresses are drawn
from the current ``input stream''.  There are two input streams:
numbered 0 (the keyboard) and 1 (a file containing commands).
Other inputs (mouse clicks or menu selections), if available,
are also implemented as keypresses (see below).

\sp{2.1} The format of a file containing commands must be the same as
that written in output stream 4.

\sp{2.2} The game can change the current input stream itself, using
the opcode |input_stream|.  It has no way of finding out which input
stream is currently in use.  An interpreter is free to change the
input stream whenever it likes (e.g. at the player's request) or,
indeed, to run the entire game under input stream 1 (for testing
purposes).

\sp{2.3} When input stream 1 is first selected, the interpreter may
use any method of choosing a file name for the file of commands.  (Good
practice is to use the same conventions as when choosing a filename
for output to stream 4.)

\sp{2.4} When the the current stream is stream 1, the interpreter
should not hold up long passages of text (by printing ``[MORE]''
and waiting for a keypress, for instance).

\nsp{3} Mouse support is optional but can be provided in Versions 5 and
later.

\sp{3.1} In a game which wishes to use the mouse, bit 5 of `Flags 2'
in the header should be set in the story file, and word |$36| of the
header should be the byte address of the mouse data table in dynamic
memory.

\sp{3.1.1} If the interpreter cannot offer mouse support, then it
should clear bit 5 of `Flags 2' to signal this to the game.

\sp{3.2} The mouse data table has the format:
\orm\beginstt
  Word 0:  Length of the table (in words)
  Word 1:  Mouse x coordinate
  Word 2:  Mouse y coordinate
\endtt\frm
(The table length is usually 2.)  These coordinates should be
updated regularly by the interpreter.

\sp{3.3} The mouse is presumed to have between 0 and 16 buttons.
The state of these buttons can be read by the |read_mouse| opcode
in Version 6.  Otherwise, mouse clicks are treated as keyboard
input codes (see below).

\sp{3.4} In Version 6, the mouse can either be free or constrained
to one of the 8 windows: if so, clicks outside the `mouse window'
must be ignored, and the interpreter is at liberty to confine the
mouse's movement to the boundary of its window.

\nsp{4} Menu support can optionally be provided in Version 6.

\sp{4.1} In a game which wishes to use menus, bit 8 of `Flags 2'
in the header should be set in the story file.

\sp{4.1.1} If the interpreter cannot offer menu support, then it
should clear bit 8 of `Flags 2' to signal this to the game.

\sp{4.2} Menus are numbered from 0 upwards.  0, 1 and 2 are reserved for
the interpreter to manage (this system has only been implemented on
the Macintosh, wherein 0 is the Apple menu, 1 the File menu and 2 the
Edit menu).  Menus numbered 3 and upwards can be created or removed with
the |make_menu| opcode.

\sp{4.3} Menu selection is reported to the game as a keypress
(see below).  Details of what selection has been made are read with
|read_mouse|.

\nsp{5} Whole commands are read from the input stream using the |read|
opcode.  (Note that this has two different internal names in Inform,
|sread| for Versions 1 to 4 and |aread| subsequently.)

\sp{5.1} In Versions 1 to 3, the interpreter must redisplay the status
line before it begins accepting input.

\sp{5.2} Commands are normally terminated by a new-line (a carriage
return or a line feed as appropriate for the machine's keyboard or
file format).

\sp{5.2.1} In Versions 5 and later, the game may provide a
``terminating characters table'' by giving its byte address in
the word at |$2e| in the header.  This table is a zero-terminated
list of input character codes which cause |aread| to finish the
command (in addition to new-line).  Only function key codes are
permitted: these are defined as those between 129 and 154
inclusive, together with 252, 253 and 254.  The special value
255 means ``any function key code is terminating''.

\sp{5.3} |***| In Versions 4 and later, an interpreter should ideally
be able to time input and to call a (game) routine at periodic
intervals: see the |aread| opcode.  If it is able to do this, it
should set bit 7 of `Flags 1' in the header.

\nsp{6} In Versions 4 and later, individual characters can be read
from the current input stream, using |read_char|.  Again, the interpreter
should ideally be able to time input and to call a (game) routine at
periodic intervals.  If it is able to do this, it should set bit 7 of `Flags
1' in the header.

\nsp{7} For input purposes the character set is as follows:
\orm\beginstt
0-9       ----
10        New-line   (ends input of a command)
11-12     ----
13        New-line   (ends input of a command)
14-26     ----
27        Escape
28-31     ----
32-126    Standard ASCII           (see 3.4.3)
127-128   ----
129-154   Function key codes       (see below)
155-251   Accented letter codes    (see below)
252-254   Function key codes       (see below)
255-      ----
\endtt\frm
The codes marked |----| should never be read.  (Of course an
interpreter may well want to use other ASCII codes for its own
line-editor when the player is typing a command: 127 for ``delete'',
for instance.  The table means only that these codes should not
be passed to the game.)  Note that an interpreter can return
either 10 or 13 as ``new-line''.  (The recommended choice is
10.)

\sp{7.1} The ``escape'' code is optional: an interpreter need not
provide an escape key.  (The Inform library clears and quits menus
if Escape is pressed.)

\sp{7.2} The first block of function key codes is as follows:
\orm\beginstt
129: cursor up  130: cursor down  131: cursor left  132: cursor right
133: f1         134: f2           ....              144: f12
145: keypad 0   146: keypad 1     ....              154: keypad 9
\endtt\frm

\sp{7.3} The input codes 155 to 251 refer to European accented
letters: see the table in \S 3.4.4.

\sp{7.4} In Version 6, mouse clicks and menu selections are reported
as the function key codes:
\orm\beginstt
252: menu click   253: mouse double-click   254: mouse single-click
\endtt\frm
In Versions 5 and later (except 6), menus are unavailable, and it is
legal for an interpreter to translate both forms of mouse-click as
code 254.  This is the recommended practice but a game should not
depend on it.

\sp{7.5} All the codes not marked as |----| should be passed to
|read_char|.  Function key codes and the code for ``escape'' should
not be entered by |read| into the input buffer (they have no
specified appearance on screen), but accented letter codes should.

\remarks
Menus in `Beyond Zork' define cursor up and cursor down as terminating
characters, and make use of |read| in the upper window.

Ideally, an interpreter should be able to read time delays (for timed input)
from stream 1 (i.e., from a script file).  In practice this is formidably
hard to implement.

The `Beyond Zork' story file is capable of receiving both mouse-click
codes (253 and 254), listing both in its terminating characters table
and treating them equally.

% ----------------------------------------------------------------------------

\specs{11}{The format of the header}

\sp{1} The header table summarises those locations in the Z-machine's
header which an interpreter must deal with.  (For much fuller details,
see Appendix A.)  ``Hex'' means the address, in hexadecimal;
``V'' the earliest Version to which the rule is applicable; ``Dyn'' means
that the byte or bit may legally be changed by the game during play;
``Int'' means that the interpreter may change it; ``Rst'' means that the
interpreter must set it correctly after loading the game, after a restore
or after a restart.

\pageinsert
\smallskip\hrule\smallskip
\beginlines
| Hex  V  Dyn Int Rst  Contents|
\endlines\smallskip\hrule\smallskip\beginlines
|  0   1               Version number (1 to 6)|
|  1   3               Flags 1:|
|      .3                Bit 1    Status line type: 0=score/turns, 1=hours:mins|
|      .3      *   *         4    Status line not available?|
|      .3      *   *         5    Screen-splitting available?|
|      .3      *   *         6    Is a variable-pitch font the default?|
|      4               Flags 1:|
|      .5      *   *     Bit 0    Colours available?|
|      .6      *   *         1    Picture displaying available?|
|      .4      *   *         2    Boldface available?|
|      .4      *   *         3    Italic available?|
|      .4      *   *         4    Fixed-space font available?|
|      .6      *   *         5    Sound effects available?|
|      .4      *   *         7    Timed keyboard input available?|
|  4   1               Base of high memory (byte address)|
|  6   1               Initial value of program counter (byte address)|
|      6               Packed address of initial "main" routine|
|  8   1               Location of dictionary (byte address)|
|  A   1               Location of object table (byte address)|
|  C   1               Location of global variables table (byte address)|
|  E   1               Base of static memory (byte address)|
| 10   1               Flags 2:|
|      .1  *   *   *     Bit 0    Set when transcripting is on|
|      .3  *                 1    Game sets to force printing in fixed-pitch font|
|      .6  *   *             2    Int sets to request status line redraw:|
|                                   game clears when it complies with this.|
|      .5      *   *         3    If set, game wants to use pictures|
|      .5      *   *         4    If set, game wants to use the UNDO opcodes|
|      .5      *   *         5    If set, game wants to use a mouse|
|      .5                    6    If set, game wants to use colours|
|      .5      *   *         7    If set, game wants to use sound effects|
|      .6      *   *         8    If set, game wants to use menus|
|                                   (For bits 3,4,5,7 and 8, Int clears again|
|                                   if it cannot provide the requested effect.)|
| 18   2               Location of abbreviations table (byte address)|
| 1A   3+              Length of file (see note)|
| 1C   3+              Checksum of file|
| 1E   4       *   *   Interpreter number|
| 1F   4       *   *   Interpreter version (single ASCII character)|
\endlines\smallskip\hrule\smallskip
\noindent Some early Version 3 files do not contain length and checksum
data, hence the notation |3+|.
\vfill\endinsert

\topinsert
\smallskip\hrule\beginlines
| Hex  V  Dyn Int Rst  Contents|
\endlines\smallskip\hrule\smallskip\beginlines
| 20   4       *   *   Screen height (lines): 255 means "infinite"|
| 21   4       *   *   Screen width (characters)|
| 22   5       *   *   Screen width in units|
| 24   5       *   *   Screen height in units|
| 26   5       *   *   Font height in units|
| 27   5       *   *   Font width in units (defined as width of a '0')|
| 28   6               Routines offset (divided by 8)|
| 2A   6               Static strings offset (divided by 8)|
| 2C   5       *   *   Default background colour|
| 2D   5       *   *   Default foreground colour|
| 2E   5               Address of terminating characters table (bytes)|
| 30   6       *       Total width in pixels of text sent to output stream 3|
| 32   1       *   *   Standard revision number|
| 34   5               Character set table address (bytes), or 0 for default|
| 36   5               Mouse data table address (bytes)|
\endlines\smallskip\hrule\bigskip
\endinsert

\sp{1.1} It is illegal for a game to alter those
fields not marked as ``Dyn''.  An interpreter is therefore free to
store values of such fields in its own variables.

\sp{1.2} The state of the transcription bit (bit 0 of Flags 2) is only
changed by the game (see \S 7.3, \S 7.4), but the interpreter ensures that
its value survives a restart or restore.

\sp{1.3} Infocom used the interpreter numbers:
\orm\beginstt
  1   DECSystem-20     5   Atari ST           9   Apple IIc
  2   Apple IIe        6   IBM PC            10   Apple IIgs
  3   Macintosh        7   Commodore 128     11   Tandy Color
  4   Amiga            8   Commodore 64
\endtt\frm
(The DECSystem-20 was Infocom's own in-house mainframe.)  An interpreter
should choose the interpreter number most suitable for the machine it
will run on.  (The main consideration is that the behaviour of `Beyond Zork'
actually depends on the interpreter number.)

\sp{1.4} |***| The use of bit 7 in `Flags 1' to signal whether timed
input is available is new in this document: see the preface.

\sp{1.5} |***| If an interpreter obeys Revision |n.m| of this document {\sl
perfectly}, as far as anyone knows, then byte |$32| should be written with
|n| and byte |$33| with |m|.  If it is an earlier (non-standard)
interpreter, it should leave these bytes as 0.

\sp{1.6} The file length stored at |$1a| is actually divided by a constant,
depending on the Version, to make it fit into a header word.  This constant
is 2 for Versions 1 to 3, 4 for Versions 4 to 5 or 8 for Versions 6 and
later.

\remarks
See the ``Infocom fact sheet'' for numbers and letters of the known
interpreters shipped by Infocom.  Interpreter versions are conventionally
the upper case letters in sequence (A, B, C, ...).  At present most ports
of |Zip| use interpreter number 6, and most of |ITF| use number 2.

The unusual behaviour of `Beyond Zork' concerns its character graphics:
see the remarks to \S 16.

% ----------------------------------------------------------------------------

\specs{12}{The object table}

\sp{1} The object table is held in dynamic memory and its byte address
is stored in the word at |$0a| in the header.  (Recall that objects
have flags attached called attributes, numbered from 0 upward, and
variables attached called properties, numbered from 1 upward.  An
object need not provide every property.)

\nsp{2} The table begins with a block known as the property defaults table.
This contains 31 words in Versions 1 to 3 and 63 in Versions 4 and later.
When the game attempts to read the value of property $n$ for an object
which does not provide property $n$, the $n$-th entry in this table
is the resulting value.

\nsp{3} Next is the object tree.  Objects are numbered consecutively from
1 upward, with object number 0 being used to mean ``nothing'' (though
there is formally no such object).  The table consists of a list of
entries, one for each object.

\sp{3.1} In Versions 1 to 3, there are at most 255 objects, each having
a 9-byte entry as follows:
\orm\beginstt
  <the 32 attribute flags>   <parent>  <sibling>  <child>  <properties>
  ---32 bits in 4 bytes---   ---3 bytes------------------  ---2 bytes--
\endtt\frm
|parent|, |sibling| and |child| must all hold valid object numbers.
The |properties| pointer is the byte address of the list of
properties attached to the object.  Attributes 0 to 31 are flags
(at any given time, they are either on (1) or off (0)) and are stored topmost
bit first: e.g., attribute 0 is stored in bit 7 of the first byte,
attribute 31 is stored in bit 0 of the fourth.

\sp{3.2} In Version 4 and later, there are at most 65535 objects, each
having a 14-byte entry as follows:
\orm\beginstt
  <the 48 attribute flags>   <parent>  <sibling>  <child>  <properties>
  ---48 bits in 6 bytes---   ---3 words, i.e. 6 bytes----  ---2 bytes--
\endtt\frm

\nsp{4} Each object has its own property table.  Each of these can be
anywhere in dynamic memory (indeed, a game can legally change an object's
properties table address in play, provided the new address points to
another valid properties table).

\sp{4.1} In Versions 1 to 3, a property table has header:
\orm\beginstt
 <text-length>   <text of short name of object>
 -----byte----   --some even number of bytes---
\endtt\frm
where the |text-length| is the number of 2-byte words making up the text,
which is stored in the usual format.  (This means that an object's short
name is limited to 765 Z-characters.)  After the header, the properties
are listed in descending numerical order.  (This order is essential and
is not a matter of convention.)  Each property is stored as a block
\orm\beginstt
 <size byte>   <the actual property data>
               ---between 1 and 8 bytes--
\endtt\frm
where the |size byte| is arranged as 32 times the number of data bytes
minus one, plus the property number.  A property list is terminated by
a size byte of 0.  (It is otherwise illegal for a size byte to be a
multiple of 32.)

\sp{4.2} In Versions 4 and later, a property block instead has the form
\orm\beginstt
 <size and number>     <the actual property data>
 --1 or 2 bytes---     --between 1 and 64 bytes--
\endtt\frm
The property number occupies the bottom 6 bits of the first size byte.

\sp{4.2.1} If the top bit of the size byte is set, then there is a
second size byte.  The bottom six bits contain the property data
length (counting in bytes), minus 1, and the top two bits must be
|$$10|.

\sp{4.2.2} Otherwise, if bit 6 of the size byte is set then the
length is 2, and if it is clear then the length is 1.

\sp{5} It is the game's responsibility to keep the object tree
well-founded: the interpreter is not required to check.
``Well-founded'' means the following:
\item{(a)} An object with a sibling also has a parent.
\item{(b)} An object is the parent of exactly those objects
in the sibling list of its child.
\item{(c)} Each object can be given a level $n$, such that
parentless objects have level $0$ and all children of a level
$n$ object have level $n+1$.

\remarks
The largest valid object number is not directly stored anywhere
in the Z-machine.  Utility programs like ``Infodump'' deduce this
number by assuming that, initially, the object entries end where
the first property table begins.

The reason why the second property size byte needs to have top bits set
to |$$10| is that the size field must be parsable either
forwards or backwards -- the Z-machine needs to be able to reconstruct the
length of a property given only the address of the first byte of its data.
(There are very many (e.g. 2000) property entries in a story file, so
optimising size into one byte most of the time is worthwhile.)

In fact only the top bit of the second byte needs to be set, so it
would be extremely easy to modify an interpreter to allow up to 128
bytes of property data.  Infocom seem not to have noticed, or not to
have needed this.

Inform can only construct well-founded object trees as the initial game
state, but it is easy to compile sequences of code like ``move red box to
blue box'' followed by ``move blue box to red box'' which leave the object
tree in an ill-founded state.  (The Inform library protects the standard
object-movement verbs against this.)

% ----------------------------------------------------------------------------

\specs{13}{The dictionary and lexical analysis}

\sp{1} The dictionary table is held in static memory and its byte address
is stored in the word at |$08| in the header.

\nsp{2} The table begins with a short header:
\orm\beginstt
 n    <list of keyboard input codes>  entry-length  number-of-entries
byte  ------n bytes-----------------      byte         2-byte word
\endtt\frm
The keyboard input codes are ``word-separators'': typically (and under
Inform mandatorily) these are the ASCII codes for full stop, comma and
double-quote.  Note that a space character (32) should never be a
word-separator.  The ``entry length'' is the length of each word's
entry in the dictionary table.  (It must be at least 4 in Versions
1 to 3, and at least 6 in later Versions.)

\sp{2.1} Note that control codes such as the ASCII for ``tab'' are
never given in the word-separators table: they aren't legal keyboard
input codes (an interpreter might sensibly convert a tab to a space).

\nsp{3} In Versions 1 to 3, each word has an entry in the form
\orm\beginstt
 <encoded text of word>      <bytes of data>
 ------- 4 bytes ------   (entry length-4) bytes
\endtt\frm
The interpreter ignores the bytes of data (presumably the game's parser will
use them).  The encoded text contains 6 Z-characters (it is always padded
out with Z-character 5's to make up 4 bytes: see ``How strings are
encoded'').  The text may include spaces or other word-separators
(though, if so, the interpreter will never match any text to the
dictionary word in question: surprisingly, this can be useful and is
a trick used in Inform 5/12).

\nsp{4} In Versions 4 and later, the encoded text has 6 bytes and
always contains 9 Z-characters.

\nsp{5} The word entries follow immediately after the dictionary header
and must be given in numerical order of the encoded text (when the encoded
text is regarded as a 32 or 48-bit binary number with most-significant
byte first).  It must not contain two entries with the same encoded text.

\nsp{6} Lexical analysis takes place in two circumstances: on request
of a |tokenise| opcode (in which case it can use any dictionary table
it likes, in the format above) and during acceptance of a game command
(in which case the standard dictionary is used).

\sp{6.1} First, the text is broken up into words.  Spaces divide up
words and are otherwise ignored.  Word separators also divide words,
but each one of them is considered a word in its own right.  Thus,
the erratically-spaced text ``fred,go  fishing'' is divided into four
words:
\orm\beginstt
fred / , / go / fishing
\endtt\frm

\sp{6.2} Each word is then encoded as a Z-machine string in
dictionary form, and searched for in the dictionary.

\sp{6.3} A ``parse table'' is then written, recording the number of
words, the length and position of each word and the dictionary
address of each word which is recognised.  For the format, see the
|sread| opcode.

\remarks
Usually (under Inform, mandatorily) there are three bytes of data
in the word entries, so that dictionary entry lengths are 7 and 9
in the early and late Z-machine, respectively.

It is essential that dictionary entries are in numerical order of the
bytes of encrypted text so that interpreters can search the dictionary
efficiently (e.g. by a binary-chop algorithm).  Because the letters in
A0 are in alphabetical order, because the bits are ordered in the right
way and because the pad character 5 is less than the values for the
letters, the numerical ordering corresponds to normal English alphabetical
order for ordinary words.  (For instance ``an'' comes before
``anaconda''.)

The Infocom games do contain words whose initial
character is not a letter (words such as ``\#record'').

% ----------------------------------------------------------------------------

\specs{14}{Complete table of opcodes}

\sp{1} This table contains all 117 opcodes and, taken with the dictionary
in \S 15, describes exactly what each should do.  In addition, it lists which
opcodes are actually used in the known Infocom story files, and documents the
Inform assembly language syntax.

\subtitle{Reading the opcode tables}

The two columns ``St" and ``Br" (store and branch) mark whether an
instruction stores a result in a variable, and whether it must provide a
label to jump to, respectively.

The ``Opcode" is written |TYPE:Decimal| where the |TYPE| is the operand
count (2OP, 1OP, 0OP or VAR) or else EXT for two-byte opcodes (where the
first byte is (decimal) 190).  The decimal number is the lowest possible
decimal opcode value (by convention, 256 is added for extended opcodes).
The hex number is the opcode number within each |TYPE|.

The ``V" column gives the Version information.  If nothing is specified, the
opcode is as stated from Version 1 onwards.  Otherwise, it exists only from
the version quoted onwards.  Before this time, its use is illegal.  Some
opcodes change their meanings as the Version increases, and these have more
than one line of specification.  Others become illegal again, and these are
marked |[illegal]|.

In a few cases, the Version is given as ``3/4" or some such.  The first
number is the Version number whose specification the opcode belongs to, and
the second is the earliest Version in which the opcode is known actually to
be used in an Infocom-produced story file.  A dash means that it is seems
never to have been used (in any Version).

The table explicitly marks opcodes which do not exist in any version of the
Z-machine as |------|: in addition, none of the extended set of codes from
|$1d| to |$ff| were ever used.

\subtitle{Inform assembly language}

An Inform line beginning with an |@| is sent directly to the assembler. In
the syntax below, |<variable>| and |<result>| must be variables (or |sp|,
the stack pointer); |<label>| a label (not a routine name).
|<literal-string>| must be literal text in quotation marks ``thus".
|routine| should be the name of a routine (this assembles to its packed
address).  Otherwise any Inform constant term (such as |'/'| or |'beetle'|)
can be given as an operand.

In a branch instruction, the logical effect can be negated using a tilde
|~| before the label name, so for instance
\beginstt
   @je a b ~Different;  ! Jump to Different if a not equal to b
\endtt
The programmer must specify whether a branch is in the ``near" or ``far"
form, the default being ``near".  A question mark |?| before the label (and
tilde, if present) forces it to be ``far''.

Note that the operands marked as |<variable>| are assembled with ``small
constant'' type, not ``variable'' type (see \S 4.2.3).  This affects the
opcodes
\beginstt
   inc,  dec,  inc_chk,  dec_chk,  store,  pull,  load.
\endtt
For example, Inform assembles |@inc score;| to something looking like
``increment 16'', because 16 is the variable number of |score|.
(Such behaviour can be seen, for instance, at |$5051| in Zork II,
48.840904.  Some Infocom games use ``indirect addressing'' by
|load [sp] sp| (load the value of the variable held on the stack,
and put it on the stack).  However, this syntax is not understood
by Inform.)

\vfill\eject
\hrule\smallskip
\centerline{\bf Two-operand (long) opcodes 2OP}\smallskip\hrule
\beginlines
|   St  Br  Opcode Hex  V  Inform name and syntax|
\endlines\smallskip\hrule\smallskip\beginlines
|           ------   0  ------|
|       *   2OP:1    1     je              a b <label>|
|       *   2OP:2    2     jl              a b <label>|
|       *   2OP:3    3     jg              a b <label>|
|       *   2OP:4    4     dec_chk         <variable> value <label>|
|       *   2OP:5    5     inc_chk         <variable> value <label>|
|       *   2OP:6    6     jin             obj1 obj2 <label>|
|       *   2OP:7    7     test            bitmap flags <label>|
|   *       2OP:8    8     or              a b <result>|
|   *       2OP:9    9     and             a b <result>|
|       *   2OP:10   A     test_attr       object attribute <label>|
|           2OP:11   B     set_attr        object attribute|
|           2OP:12   C     clear_attr      object attribute|
|           2OP:13   D     store           <variable> value|
|           2OP:14   E     insert_obj      object destination|
|   *       2OP:15   F     loadw           array word-index <result>|
|   *       2OP:16  10     loadb           array byte-index <result>|
|   *       2OP:17  11     get_prop        object property <result>|
|   *       2OP:18  12     get_prop_addr   object property <result>|
|   *       2OP:19  13     get_next_prop   object property <result>|
|   *       2OP:20  14     add             a b <result>|
|   *       2OP:21  15     sub             a b <result>|
|   *       2OP:22  16     mul             a b <result>|
|   *       2OP:23  17     div             a b <result>|
|   *       2OP:24  18     mod             a b <result>|
|   *       2OP:25  19  4  call_2s         routine arg1 <result>|
|           2OP:26  1A  5  call_2n         routine arg1|
|           2OP:27  1B  5  set_colour      foreground background|
|           2OP:28  1C 5/- throw           value stack-frame|
|           ------  1D  ------|
|           ------  1E  ------|
|           ------  1F  ------|
\endlines\smallskip\hrule\smallskip
\centerline{32 to 127: other forms of 2OP with different types.}
\vfill\eject
\smallskip\hrule\smallskip
\centerline{\bf One-operand opcodes \rm 1OP}\smallskip\hrule
\beginlines
|   St  Br  Opcode Hex  V  Inform name and syntax|
\endlines\smallskip\hrule\smallskip\beginlines
|       *   1OP:128  0     jz              a <label>|
|   *   *   1OP:129  1     get_sibling     object <result> <label>|
|   *   *   1OP:130  2     get_child       object <result> <label>|
|   *       1OP:131  3     get_parent      object <result>|
|   *       1OP:132  4     get_prop_len    property-address <result>|
|           1OP:133  5     inc             <variable>|
|           1OP:134  6     dec             <variable>|
|           1OP:135  7     print_addr      byte-address-of-string|
|   *       1OP:136  8  4  call_1s         routine <result>|
|           1OP:137  9     remove_obj      object|
|           1OP:138  A     print_obj       object|
|           1OP:139  B     ret             value|
|           1OP:140  C     jump            <label>|
|           1OP:141  D     print_paddr     packed-address-of-string|
|   *       1OP:142  E     load            <variable> <result>|
|   *       1OP:143  F 1/4 not             value <result>|
|                       5  call_1n         routine|
\endlines\smallskip\hrule\smallskip
\centerline{144 to 175: other forms of 1OP with different types.}
\medskip\hrule\smallskip
\centerline{\bf Zero-operand opcodes \rm 0OP}\smallskip\hrule
\beginlines
|   St  Br  Opcode Hex  V  Inform name and syntax|
\endlines\smallskip\hrule\smallskip\beginlines
|           0OP:176  0     rtrue|
|           0OP:177  1     rfalse|
|           0OP:178  2     print           <literal-string>|
|           0OP:179  3     print_ret       <literal-string>|
|           0OP:180  4 1/- nop|
|       *   0OP:181  5  1  save            <label>|
|                       5  [illegal]|
|       *   0OP:182  6  1  restore         <label>|
|                       5  [illegal]|
|           0OP:183  7     restart|
|           0OP:184  8     ret_popped|
|           0OP:185  9  1  pop|
|   *                  5/- catch           <result>|
|           0OP:186  A     quit|
|           0OP:187  B     new_line|
|           0OP:188  C  3  show_status|
|                       4  [illegal]|
|       *   0OP:189  D  3  verify          <label>|
|           0OP:190  E  5  [first byte of extended opcode]|
|       *   0OP:191  F 5/- piracy          <label>|
\endlines\smallskip\hrule\smallskip
\centerline{192 to 223: VAR forms of 2OP:0 to 2OP:31.}
\vfill\eject
\smallskip\hrule\smallskip
\centerline{\bf Variable-operand opcodes \rm VAR}\smallskip\hrule
\beginlines
|   St  Br  Opcode Hex  V  Inform name and syntax|
\endlines\smallskip\hrule\smallskip\beginlines
|   *       VAR:224  0  1  call            routine ...up to 3 args... <result>|
|                          icall           packed-address-of-routine <result>|
|                       4  call_vs         routine ...up to 3 args... <result>|
|           VAR:225  1     storew          array word-index value|
|           VAR:226  2     storeb          array byte-index value|
|           VAR:227  3     put_prop        object property value|
|           VAR:228  4  1  sread           text parse|
|                       4  sread           text parse time routine|
|   *                   5  aread           text parse time routine <result>|
|           VAR:229  5     print_char      output-character-code|
|           VAR:230  6     print_num       value|
|   *       VAR:231  7     random          range <result>|
|           VAR:232  8     push            value|
|           VAR:233  9  1  pull            <variable>|
|   *                  6/- pull            stack <result>|
|           VAR:234  A  3  split_window    lines|
|           VAR:235  B  3  set_window      window|
|   *       VAR:236  C  4  call_vs2        routine ...up to 7 args... <result>|
|           VAR:237  D  4  erase_window    window|
|           VAR:238  E 4/- erase_line      value|
|                       6  erase_line      pixels|
|           VAR:239  F  4  set_cursor      line column|
|                       6  set_cursor      line column window|
|           VAR:240 10 4/- get_cursor      table|
|           VAR:241 11  4  set_text_style  style|
|           VAR:242 12  4  buffer_mode     flag|
|           VAR:243 13  3  output_stream   number|
|                       5  output_stream   number table|
|                       6  output_stream   number table width|
|           VAR:244 14  3  input_stream    number|
|           VAR:245 15 5/3 sound_effect    number effect volume routine|
|   *       VAR:246 16  4  read_char       1 time routine <result>|
|   *    *  VAR:247 17  4  scan_table      x table len|
|   *       VAR:248 18 5/- not             value <result>|
|           VAR:249 19  5  call_vn         routine ...up to 3 args...|
|           VAR:250 1A  5  call_vn2        routine ...up to 7 args...|
|           VAR:251 1B  5  tokenise        text parse dictionary flag|
|           VAR:252 1C  5  encode_text     ascii-text length from coded-text|
|           VAR:253 1D  5  copy_table      first second size|
|           VAR:254 1E  5  print_table     ascii-text width height skip|
|        *  VAR:255 1F  5  check_arg_count argument-number|
\endlines\smallskip\hrule\smallskip
\vfill\eject
\smallskip\hrule\smallskip
\centerline{\bf Extended opcodes \rm EXT}\smallskip\hrule
\beginlines
|   St  Br  Opcode Hex  V  Inform name and syntax|
\endlines\smallskip\hrule\smallskip\beginlines
|   *       EXT:256  0  5  save            table bytes name <result>|
|   *       EXT:257  1  5  restore         table bytes name <result>|
|   *       EXT:258  2  5  log_shift       number places <result>|
|   *       EXT:259  3 5/- art_shift       number places <result>|
|   *       EXT:260  4  5  set_font        font window <result>|
|           EXT:261  5  6  draw_picture    picture-number y x|
|        *  EXT:262  6  6  picture_data    picture-number table <label>|
|           EXT:263  7  6  erase_picture   picture-number y x|
|           EXT:264  8  6  set_margins     left right window|
|   *       EXT:265  9  5  save_undo       <result>|
|   *       EXT:266  A  5  restore_undo    <result>|
|           -------  B  ------|
|           -------  C  ------|
|           -------  D  ------|
|           -------  E  ------|
|           -------  F  ------|
|           EXT:272 10  6  move_window     window y x|
|           EXT:273 11  6  window_size     window y x|
|           EXT:274 12  6  window_style    window flags operation|
|   *       EXT:275 13  6  get_wind_prop   window property-number <result>|
|           EXT:276 14  6  scroll_window   window pixels|
|           EXT:277 15  6  pop_stack       items stack|
|           EXT:278 16  6  read_mouse      table|
|           EXT:279 17  6  mouse_window    window|
|        *  EXT:280 18  6  push_stack      value stack <label>|
|           EXT:281 19  6  put_wind_prop   window property-number value|
|           EXT:282 1A  6  print_form      formatted-table|
|        *  EXT:283 1B  6  make_menu       number table <label>|
|           EXT:284 1C  6  picture_table   table|
\endlines\smallskip\hrule\bigskip

\nsp{2} Formally, it is illegal for a game to contain an opcode
not specified for its version.  An interpreter should normally halt with
a suitable message.

\sp{2.1} However, extended opcodes in the range EXT:285 to EXT:511
should be simply ignored (perhaps with a warning message somewhere
off-screen).

\sp{2.2} EXT:285 to EXT:383 are reserved for future common extensions of
the Z-machine.

\sp{2.3} Game-writers who wish to create their own ``new'' opcodes, for one
specific game only, are asked to use opcode numbers in the range EXT:384 to
EXT:511.  It is easy to modify Inform to name and assemble such opcodes.
(Of course the game will then have to be circulated with a suitably modified
interpreter to run it.)

\sp{2.4} Interpreter-writers should make this easy by providing a
routine which is called if EXT:384 to EXT:511 are found, so that
the minimum possible modification to the interpreter is needed.

\remarks
The opcodes 5, 6, 7, 8 in the extended set were very likely in Infocom's
own V5 specification (now lost): they seem to have been partially implemented
in existing Infocom interpreters, but do not occur in any existing V5
story file.  They are here left unspecified.

The notation ``5/3" for |sound_effect| is because this plainly
version-5 feature was used also in one solitary Version-3 game,
`The Lurking Horror' (the sound version of which was the last V3 release,
in September 1987).

The 2OP opcode 0 was possibly intended for setting break-points
in debugging.  It was not |nop|.  (The Infix debugger uses the actual
|nop| instruction as a break-point instead.)

|read_mouse| and |make_menu| are believed to have been used only in
`Journey' (based on a check of 11 V6 story files).  |picture_table| is
used once by `Shogun' and several times by `Zork Zero'.


\specs{15}{Dictionary of opcodes}

\quote
      The highest ideal of a translation... is achieved when the
      reader flings it impatiently into the fire, and begins
      patiently to learn the language for himself.
\quoteby{Philip Vellacott}

\sp{1} The dictionary below is alphabetical and includes entries on every
opcode listed in the table above, as well as brief notes on some Inform
internal synonyms which might otherwise be confused with opcodes.

\nsp{2} The Z-machine has the same concept of ``table'' (as an internal
data structure) as Inform.  Specifically, a table is an array of words
(in dynamic or static memory) of which the initial entry is the number
of subsequent words in the table.  For example, a table with three
entries occupies 8 bytes, arranged as the words 3, $x$, $y$, $z$.

\nsp{3} In all cases below where one operand is supposed to be an object
number, the behaviour is undefined if it isn't a legal object number
(and this includes 0).  Ideally an interpreter should halt with a suitable
error message.  This is especially true of |print_obj| (which is not
required to run very quickly, so that an interpreter can safely ``waste''
time checking this common error condition).  Similar remarks apply to
attribute numbers exceeding 32 or 48; and to window numbers, window
attribute numbers and window property numbers in Version 6.
\bigskip
\stepin=75pt
\ninepoint
\def\de{\medskip\noindent}

\block{add}|2OP:20  14     add             a b <result>|
   \continue
   Signed 16-bit addition.

\block{and}|2OP:9    9     and             a b <result>|
   \continue
   Bitwise AND.

\block{"aparse"}Obsolete name for |tokenise|.

\block{aread}This is the Inform name for the keyboard-reading opcode
   under Version 5 and later.  (Inform calls the same opcode |sread|
   under Versions 3 and 4.)  See |read| for the specification.

\block{art\_shift}|EXT:259  3 5/- art_shift       number places <result>|
   \continue
   Does an arithmetic shift of |number| by the given number
   of places, shifting left (i.e. increasing) if places is positive, right
   if negative.  In a right shift, the sign bit is preserved as well as
   being shifted on down.  (The alternative behaviour is |log_shift|.)

\block{"beep"}Inform currently uses this name for |sound_effect| in Versions
   before 5 (since public interpreters provide only minimal facilities),
   but the name is being withdrawn.  See |sound_effect|.

\block{buffer\_mode}|VAR:242 12  4  buffer_mode     flag|
   \continue
   If set to 1, text output on the lower window in stream 1
   is buffered up so that it can be word-wrapped properly.  If set to 0, it
   isn't.

\block{call}|VAR:224  0  1  call            routine ...up to 3 args... <result>|
   \continue
   The only call instruction in Version 3, Inform reads this as
   |call_vs| in higher versions: it calls the routine with 0, 1, 2 or 3
   arguments as supplied and stores the resulting return value.  (When the
   address 0 is called as a routine, nothing happens and the return value
   is false.)

\block{call\_1n}|1OP:143  F  5  call_1n         routine|
   \continue
   Executes |routine()| and throws away result.

\block{call\_1s}|1OP:136  8  4  call_1s         routine <result>|
   \continue
   Stores |routine()|.

\block{call\_2n}|2OP:26  1A  5  call_2n         routine arg1|
   \continue
   Executes |routine(arg1)| and throws away result.

\block{call\_2s}|2OP:25  19  4  call_2s         routine arg1 <result>|
   \continue
   Stores |routine(arg1)|.

\block{call\_vn}|VAR:249 19  5  call_vn         routine ...up to 3 args...|
   \continue
   Like |call|, but throws away result.

\block{call\_vs}|VAR:224  0  4  call_vs         routine ...up to 3 args... <result>|
   \continue
   See |call|.

\block{call\_vn2}|VAR:250 1A  5  call_vn2        routine ...up to 7 args...|
   \continue
   Call with a variable number (from 0 to 7) of arguments, then
   throw away the result.  This (and |call_vs2|) uniquely have an extra byte
   of opcode types to specify the types of arguments 4 to 7.  Note that it is
   legal to use these opcodes with fewer than 4 arguments (in which case the
   second byte of type information will just be |$ff|).

\block{call\_vs2}|VAR:236  C  4  call_vs2        routine ...up to 7 args... <result>|
   \continue
   See |call_vn2|.

\block{catch}|0OP:185  9  5  catch           <result>|
   \continue
   Opposite to |throw| (and occupying the same opcode that |pop|
   used in Versions 3 and 4).  |catch| returns the current ``stack frame''.

\block{check\_arg\_count}|VAR:255 1F  5  check_arg_count argument-number|
   \continue
   Branches if the given argument-number (counting
   from 1) has been provided by the routine call to the current routine.
   (This allows routines in Versions 5 and later to distinguish between
   the calls |routine(1)| and |routine(1,0)|, which would otherwise be
   impossible to tell apart.)

\block{"check\_no\_args"}Obsolete name for |check_arg_count|.

\block{clear\_attr}|2OP:12   C     clear_attr      object attribute|
   \continue
   Make |object| not have the attribute numbered |attribute|.

\block{"clear\_flag"}A name once used for one of the not-really-present
   extended Version 5 opcodes (now removed from the specification).

\block{"colour"}Obsolete name for |set_colour|.

\block{"compare\_pobj"}Obsolete name for |jin|.

\block{copy\_table}|VAR:253 1D  5  copy_table      first second size|
   \continue
   Copies |size| bytes from the |first| table to
   the |second|.  If |second| table is 0, then it zeroes the bytes in
   |first|.
   \continue
   If |size| is positive, copying takes place backwards:
   \continue |copy_table $1000 $1001 20|
   \continue
   pushes the first 20 bytes forward by one.  However, if the |size| is
   negative then copying is forwards.  Thus the same operation with |size|
   -20 would result in the byte at |$1000| being copied into the 20
   following bytes.

\block{dec}|1OP:134  6     dec             <variable>|
   \continue
   Decrement variable by 1.  This is signed, so $0$ decrements to $-1$.

\block{dec\_chk}|2OP:4    4     dec_chk         <variable> value <label>|
   \continue
   Decrement variable, and branch if it is now less than the given value.

\block{div}|2OP:23  17     div             a b <result>|
   \continue
   Unsigned 16-bit division.  Division by zero
   should halt the interpreter with a suitable error message.

\block{draw\_picture}|EXT:261  5  6  draw_picture    picture-number y x|
   \continue
   Displays the picture with the given number.  $(y,x)$
   coordinates (of the top left of the picture) are optional: if they are
   zero or not supplied, then the picture appears in the current window at
   the current cursor position.  It is illegal to call this with an invalid
   picture number.

\block{encode\_text}|VAR:252 1C  5  encode_text     ascii-text length from coded-text|
   \continue
   Translates an ASCII word to Z-encoded text format
   (stored at |coded-text|), as if it were an entry in the dictionary.
   The text begins at |from| in the |ascii-text| buffer and is |length|
   characters long.  (Some interpreters ignore this and keep translating
   until they hit a 0 character anyway, or have already filled up the 6-byte
   Z-encoded string.)

\block{"encrypt"}Obsolete name for |encode_text|.

\block{erase\_line}|VAR:238  E 4/- erase_line      value|
   \continue
   Before Version 6: erase from the current cursor position
   to the end of the its line in the current window.  Version 6: if the value
   is 1, do just that: if not, erase the given number of pixels minus one
   across from the cursor (clipped to stay inside the right margin).  The
   cursor does not move.

\block{erase\_picture}|EXT:263  7  6  erase_picture   picture-number y x|
   \continue
   Like |draw_picture|, but paints the appropriate region
   to the background colour for the given window.  It is illegal to call this
   with an invalid picture number.

\block{erase\_window}|VAR:237  D  4  erase_window    window|
   \continue
   Erases window with given number (to background colour);
   or if -1 it unsplits the screen and clears the lot (see \S 8); or if
   -2 it clears the screen without unsplitting it.  In cases -1 and -2, the
   cursor moves back to top left.

\block{"extended"}This byte (decimal 190) is not an instruction, but
   indicates that the opcode is ``extended": the next byte contains the
   number in the extended set.

\block{get\_next\_prop}|2OP:19  13     get_next_prop   object property <result>|
   \continue
   Gives the number of the next property provided by the
   quoted object.  This may be zero, indicating the end of the property list;
   if called with zero, it gives the first property number present.  It is
   illegal to try to find the next property of a property which does not
   exist, and an interpreter should halt with an error message (if it can
   efficiently check this condition).

\block{get\_prop}|2OP:17  11     get_prop        object property <result>|
   \continue
   Read property from object (resulting in the default value
   if it had no such declared property).  If the property has length 1, the
   value is only that byte.  Otherwise, the first two bytes of the property
   are taken as a word value.  (It is legal to apply |get_prop| to an array
   property, i.e. a property of length greater than 2, but |ITF| behaves
   strangely in this case.)

\block{get\_prop\_addr}|2OP:18  12     get_prop_addr   object property <result>|
   \continue
   Get the byte address (in dynamic memory) of the
   property data for the given object's property.  This must return 0 if
   the object hasn't got the property.

\block{get\_prop\_len}|1OP:132  4     get_prop_len    property-address <result>|
   \continue
   Get length of property data (in bytes) for the given
   object's property.  It is illegal to try to find the property length
   of a property which does not exist for the given object, and an
   interpreter should halt with an error message (if it can efficiently
   check this condition).

\block{get\_child}|1OP:130  2     get_child       object <result> <label>|
   \continue
   Get first object contained in given object, branching if
   this exists, i.e. is not |nothing| (i.e., is not 0).

\block{get\_cursor}|VAR:240 10 4/- get_cursor      table|
   \continue
   Puts the current cursor row into the first word of the
   given table, and the current cursor column into the second word.

\block{get\_parent}|1OP:131  3     get_parent      object <result>|
   \continue
   Get parent object (note that this has no ``branch if
   exists" clause).

\block{get\_sibling}|1OP:129  1     get_sibling     object <result> <label>|
   \continue
   Get next object in tree, branching if this exists, i.e.
   is not 0.

\block{get\_wind\_prop}|EXT:275 13  6  get_wind_prop   window property-number <result>|
   \continue
   Reads the given property of the given window (see
   \S 8).

\block{"icall"}This is an Inform internal name for ``call to a routine whose
   address is supplied, not its name", used in the implementation of the
   Inform |indirect| function.

\block{inc}|1OP:133  5     inc             <variable>|
   \continue
   Increment variable by 1.  (This is signed, so $-1$ increments
   to 0.)

\block{inc\_chk}|2OP:5    5     inc_chk         <variable> value <label>|
   \continue
   Increment variable, and branch if now greater than value.

\block{input\_stream}|VAR:244 14  3  input_stream    number|
   \continue
   Selects the current input stream.

\block{insert\_obj}|2OP:14   E     insert_obj      object destination|
   \continue
   Moves object $O$ to become the first child of the
   destination object $D$.  (Thus, after the operation the |child| of $D$
   is $O$, and the |sibling| of $O$ is whatever was previously the |child|
   of $D$.)  All children of $O$ move with it.  (Initially $O$ can be at
   any point in the object tree; it may legally have |parent| zero.)

\block{je}|2OP:1    1     je              a b <label>|
   \continue
   Jump if |a| is equal to any of the subsequent operands.  (Thus
   |@je a| never jumps and |@je a b| jumps if |a = b|.)

\block{jg}|2OP:3    3     jg              a b <label>|
   \continue
   Jump if |a > b| (using a signed 16-bit comparison).

\block{"jge"}An old, confusing name for |jg|, long since withdrawn.

\block{jin}|2OP:6    6     jin             obj1 obj2 <label>|
   \continue
   Jump if object |a| is a direct child of |b|, i.e., if
   |parent| of |a| is |b|.

\block{jl}|2OP:2    2     jl              a b <label>|
   \continue
   Jump if |a < b| (using a signed 16-bit comparison).

\block{"jle"}An old, confusing name for |jl|, long since withdrawn.

\block{jump}|1OP:140  C     jump            <label>|
   \continue
   Jump (unconditionally) to the given label.  (This is not a
   branch instruction and the operand is a 2-byte signed offset to apply
   to the program counter.)  It is legal for this to jump into a different
   routine (which should not change the routine call state), although it
   is considered bad practice to do so and the |Txd| disassembler is
   confused by it.

\block{jz}|1OP:128  0     jz              a <label>|
   \continue
   Jump if |a = 0|.

\block{load}|1OP:142  E     load            <variable> <result>|
   \continue
   The value of the variable referred to by the operand
   is stored in the result.  (Inform doesn't use this; see the notes to
   \S 14.)

\block{loadb}|2OP:16  10     loadb           array byte-index <result>|
   \continue
   Stores |array->byte-index| (i.e., the byte at address
   |array+byte-index|, which must lie in static or dynamic memory).

\block{loadw}|2OP:15   F     loadw           array word-index <result>|
   \continue
   Stores |array-->word-index| (i.e., the word at address
   |array+2*word-index|, which must lie in static or dynamic memory).

\block{log\_shift}|EXT:258  2  5  log_shift       number places <result>|
   \continue
   Does a logical shift of |number| by the given number of
   |places|, shifting left (i.e. increasing) if |places| is positive, right
   if |negative|.  In a right shift, the sign is zeroed instead of being
   shifted on.  (See also |art_shift|.)

\block{"lstore"}An internal Inform name for ``the long form of |store|''.

\block{make\_menu}|EXT:283 1B  6  make_menu       number table <label>|
   \continue
   Controls menus with numbers greater than 2 (i.e., it
   doesn't control the three system menus).  If the table supplied is 0,
   the menu is removed.  Otherwise it is a table of tables.  Each table is
   an ASCII string: the first item being a menu name, subsequent ones the
   entries.

\block{mod}|2OP:24  18     mod             a b <result>|
   \continue
   Remainder after unsigned 16-bit division.  Division by zero
   should halt the interpreter with a suitable error message.

\block{mouse\_window}|EXT:279 17  6  mouse_window    window|
   \continue
   Constrain the mouse arrow to sit inside the given window.
   By default it sits in window 1.  Setting to -1 takes all restriction away.
   (The mouse clicks are not reported if the arrow is outside the window
   and interpreters are presumably supposed to hold the arrow there by
   hardware means if possible.)

\block{move\_window}|EXT:272 10  6  move_window     window y x|
   \continue
   Moves the given window to pixels $(y,x)$: $(1,1)$ being
   the top left.  Nothing actually happens (since windows are entirely
   notional transparencies): but any future plotting happens in the new place.

\block{mul}|2OP:22  16     mul             a b <result>|
   \continue
   Signed 16-bit multiplication.

\block{new\_line}|0OP:187  B     new_line|
   \continue
   Print carriage return.

\block{nop}|0OP:180  4 1/- nop|
   \continue
   Probably the official ``no operation" instruction, which,
   appropriately, was never operated (in any of the Infocom datafiles).
   It is conceivably useful for self-modifying code, and this is
   conceivably possible in the Z-machine: so the author would like to
   specify it as |nop|.

\block{not}|1OP:143  F 1/4 not             value <result>|
   \continue
   Bitwise NOT (i.e., all 16 bits reversed).  Note: in Versions
   3 and 4 this is a 1OP instruction (as expected) but in later Versions
   it was moved into the extended set to make room for |call_1n|.
   (The Inform assembler knows which opcode number to assemble to.)

\block{or}|2OP:8    8     or              a b <result>|
   \continue
   Bitwise OR.

\block{output\_stream}%
|VAR:243 13  3  output_stream   number|
   \continue
   |            5  output_stream   number table|
   \continue
   |            6  output_stream   number table width|
   \continue
   If |stream| is 0, nothing happens.  If it is
   positive, then that stream is selected; if negative, deselected.
   (Recall that several different streams can be selected at once.)
   \continue
   When stream 3 is selected, a |table| must be given into which text
   can be printed.  The first word always holds the number of characters
   printed, the actual text being stored at bytes |table+2| onward.
   It is not the interpreter's responsibility to worry about the length
   of this table being overrun.
   \continue
   In Version 6, a |width| field may optionally be given: if this is
   non-zero, text will then be justified as if it were in the window with
   that number (if width is positive) or a box -|width| pixels wide (if
   negative).  Then the table will contain not ordinary text but formatted
   text: see |print_form|.

\block{picture\_data}|EXT:262  6  6  picture_data    picture-number table <label>|
   \continue
   Asks the interpreter for data on the picture with
   the given number.  If the picture number is valid, a branch occurs and
   information is written to the table: the height in the first word,
   the width in the second, in pixels.
   \continue
   Otherwise, if the picture number is zero, the interpreter writes the
   highest legal picture number into the first word of the table.
   \continue
   Otherwise, nothing happens.

\block{picture\_table}|EXT:284 1C  6  picture_table   table|
   \continue
   (Warning: this is only a conjecture.)  Given
   a table of picture numbers, load in these pictures from disc into a cache
   for convenient rapid plotting later.  (For instance, the peggleboard
   sprites in `Zork Zero'.)

\block{piracy}|0OP:191  F 5/- piracy          <label>|
   \continue
   Branches if the game disc is believed to be genuine by the
   interpreter (which is assumed to have some arcane way of finding out).
   Interpreters are asked to be gullible and to unconditionally branch.

\block{pop}|0OP:185  9  1  pop|
   \continue
   Throws away the top item on the stack.  (This was useful to
   lose unwanted routine call results in early Versions.)

\block{pop\_stack}|EXT:277 15  6  pop_stack       items stack|
   \continue
   The given number of items are thrown away from the top
   of a stack: by default the system stack, otherwise the one given as a
   second operand.

\block{print}|0OP:178  2     print           <literal-string>|
   \continue
   Print the quoted (literal) Z-encoded string.

\block{print\_addr}|1OP:135  7     print_addr      byte-address-of-string|
   \continue
   Print (Z-encoded) string at given byte address,
   in dynamic or static memory.

\block{print\_char}|VAR:229  5     print_char      output-character-code|
   \continue
   Print `ASCII' character.  The operand is interpreted
   as an extended `ASCII' code, as specified in \S 3.  The operand
   may not legally be (negative or) larger than 1023.

\block{print\_form}|EXT:282 1A  6  print_form      formatted-table|
   \continue
   Prints a formatted table of the kind written to
   output stream 3 when formatting is on.  This is an elaborated version
   of |print_table| to cope with
   fonts, pixels and other impedimenta.  It is a sequence of lines,
   terminated with a zero word.  Each line is a word containing the number
   of characters, followed by that many bytes which hold the characters
   concerned.

\block{print\_num}|VAR:230  6     print_num       value|
   \continue
   Print (signed) number in decimal.

\block{print\_obj}|1OP:138  A     print_obj       object|
   \continue
   Print short name of object (the Z-encoded string in the
   object header, not a property).  If the object number is invalid, the
   interpreter should halt with a suitable error message.

\block{print\_paddr}|1OP:141  D     print_paddr     packed-address-of-string|
   \continue
   Print the (Z-encoded) string at the given packed
   address in high memory.

\block{print\_ret}|0OP:179  3     print_ret       <literal-string>|
   \continue
   Print the quoted (literal) Z-encoded string, then print
   a new-line and then return true (i.e., 1).

\block{print\_table}|VAR:254 1E  5  print_table     ascii-text width height skip|
   \continue
   Print a rectangle of text on screen spreading right and
   down from the current cursor position, of given |width| and |height|, from
   the table of ASCII text given.  (Height is optional and defaults to 1.)
   If a |skip| value is given, then that many characters of text are skipped
   over in between each line and the next.  (So one could make this display,
   for instance, a 2 by 3 window onto a giant 40 by 40 character graphics
   map.)
   \continue
   Some Infocom-written interpreters stop printing if a zero byte is found
   in the text: this is not understood.  Future games should not include
   a zero byte in a table to be printed.


\block{pull}|VAR:233  9  1  pull            <variable>|
   \continue
   |           6/- pull            stack <result>|
   \continue
   Pulls value off a stack.  (If the stack underflows, the
   interpreter should halt with a suitable error message.)  In Version 6,
   the stack in question may be specified as a user one: otherwise it
   is the game stack.

\block{push}|VAR:232  8     push            value|
   \continue
   Pushes value onto the game stack.

\block{push\_stack}|EXT:280 18  6  push_stack      value stack <label>|
   \continue
   Pushes the value onto the specified user stack, and
   branching if this was successful.  If the stack overflows, nothing
   happens (this is not an error condition).

\block{put\_prop}|VAR:227  3     put_prop        object property value|
   \continue
   Writes the given value to the given property of the
   given object.  If the property does not exist for that object, the
   interpreter should halt with a suitable error message.  If the
   property length is 1, then the interpreter should store only the
   least significant byte of the value.  (For instance, storing $-1$
   into a 1-byte property results in the property value 255.)
   Otherwise the value is stored in the first word of the property data.

\block{put\_wind\_prop}|EXT:281 19  6  put_wind_prop   window property-number value|
   \continue
   Writes a window property (see |get_wind_prop|).
   This should only be used when there is no direct command (such as
   |move_window|) to use instead, as some such operations may have
   side-effects.

\block{quit}|0OP:186  A     quit|
   \continue
   Exit the game immediately.  (Any ``Are you sure?" question
   must be asked by the game, not the interpreter.)  It is not legal to
   return from the main routine (that is, from where execution first
   begins) and this must be used instead.

\block{random}|VAR:231  7     random          range <result>|
   \continue
   If |range| is positive, returns a uniformly random number
   between 1 and |range|.  If |range| is negative, the random number generator
   is seeded to that value and the return value is 0.  Most interpreters
   consider giving 0 as |range| illegal (because they attempt a division
   with remainder by the |range|), but correct behaviour is to reseed the
   generator in as random a way as the interpreter can (e.g. by using the
   time in milliseconds).
   \continue
   (Some version 3 games, such as `Enchanter' release 29, had a debugging
   verb |#random| such that typing, say, |#random 14| caused a call of
   |random| with -14.)

\block{read}|VAR:228  4  1  sread           text parse|
   \continue
   |            4  sread           text parse time routine|
   \continue
   |            5  aread           text parse time routine <result>|
   \continue
   (Note that Inform internally names the |read| opcode as |aread|
   in Versions 5 and later and |sread| in Versions 3 and 4.)
   \continue
   This opcode reads a whole command from the keyboard (no prompt is
   automatically displayed).  It is legal for this to be called with the
   cursor at any position on any window.
   \continue
   In Versions 1 to 3, the status line is automatically redisplayed first.
   \continue
   A sequence of characters is read in from the current input stream until
   a carriage return (or, in Versions 5 and later, any terminating character)
   is found.
   \continue
   In Versions 1 to 4, byte 0 of the |text-buffer| should initially contain
   the maximum number of letters which can be typed, minus 1 (the interpreter
   should not accept more than this).  The text typed is reduced to lower case
   (so that it can tidily be printed back by the program if need be)
   and stored in bytes 1 onward, with a zero terminator (but without any other
   terminator, such as a carriage return code).  (This means that
   if byte 0 contains $n$ then the buffer must contain $n+1$ bytes, which
   makes it a |string| array of length $n$ in Inform terminology.)
   \continue
   In Versions 5 and later, byte 0 of the |text-buffer| should initially contain
   the maximum number of letters which can be typed (the interpreter should
   not accept more than this).  The interpreter stores the number of characters
   actually typed in byte 1 (not counting the terminating character), and the
   characters themselves in bytes 2 onward (not storing the terminating
   character).  (Some interpreters wrongly add a zero byte after the text anyway,
   so it is wise for the buffer to contain at least $n+3$ bytes.)  Moreover,
   if byte 1 contains a positive value at the start of the
   input, then |read| assumes that number of characters are left over from an
   interrupted previous input, and writes the new characters after those
   already there.  (This is used by `Beyond Zork' to handle function key
   presses during input.)
   \continue
   In Version 4 and later, if the operands |time| and |routine| are
   supplied (and non-zero) then the routine call |routine()| is
   made every |time/10| seconds during the keyboard-reading process.  If
   this routine returns true, all input is erased (to zero) and the
   reading process is terminated at once.  (The terminating character code
   is 0.)  The |routine| is permitted to print to the screen even if it
   returns false to signal ``carry on'': the interpreter should notice and
   redraw the input line so far, before input continues.
   \continue
   (Note that |Zip| contains a bug causing |routine| to be called
   with |time| as an argument, owing to a misunderstanding arising from a
   usage in `Border Zone': and calls it every |time| seconds, not every
   |time/10| seconds.  These two bugs cancel each other out so that
   `BZ' does in fact run (roughly) correctly.  However, Infocom's own
   interpreters run the infamous `Freefall' much faster than modern ones.)
   \continue
   Next, lexical analysis is performed on the text (except that in Versions 5
   and later, if |parse-buffer| is zero then this is omitted).  Initially,
   byte 0 of the |parse-buffer| should hold the maximum number of textual
   words which can be parsed.  (If this is $n$, the buffer must be at least
   $2+4*n$ bytes long to hold the results of the analysis.)
   \continue
   The interpreter divides the text into words and looks them up in the
   dictionary, as described in \S 13.  The number of words is written in
   byte 1 and one 4-byte block is
   written for each word, from byte 2 onwards (except that it should stop
   before going beyond the maximum number of words specified).  Each block
   consists of the byte address
   of the word in the dictionary, if it is in the dictionary, or 0 if it isn't;
   followed by a byte giving the number of letters in the word; and finally
   a byte giving the position in the |text-buffer| of the first letter of
   the word.
   \continue
   In Version 5 and later, this is a store instruction: the return value
   is the terminating character (note that the user pressing his ``enter''
   key may cause either 10 or 13 to be returned; the author recommends
   that interpreters return 10).  A timed-out input returns 0.
   \continue
   (Versions 1 and 2 and early Version 3 games mistakenly write the parse buffer
   length 240 into byte 0 of the parse buffer: later games fix this bug and
   write 59, because $2+4\times 59 = 238$ so that 59 is the maximum number
   of textual words which can be parsed into a buffer of length 240 bytes.  The
   Inform library makes a similar mistake.  Neither mistake has very serious
   consequences.)
   \continue
   (Interpreters are asked to halt with a suitable error message if
   the text or parse buffers have length of less than 3 or 6 bytes,
   respectively: this sometimes occurs due to a previous array being
   overrun, causing bugs which are very difficult to find.)

\block{read\_char}|VAR:246 16  4  read_char       1 time routine <result>|
   \continue
   Reads a single character from input stream 0 (the
   keyboard).  The first operand must be 1 (presumably it was provided
   to support multiple input devices, but only the keyboard was ever
   used).  |time| and |routine| are optional (in Versions 4 and
   later only) and dealt with as in |read| above.

\block{read\_mouse}|EXT:278 16  6  read_mouse      table|
   \continue
   The four words in the |table| are written with the mouse
   y coordinate, x coordinate, button bits (low bits on the right of the
   mouse, rising as one looks left), and a menu word.  In the menu word,
   the upper byte is the menu number and the lower byte is the
   item number (from 0).

\block{remove\_obj}|1OP:137  9     remove_obj      object|
   \continue
   Detach the object from its parent, so that it no longer
   has any parent.  (Its children remain in its possession.)

\block{restart}|0OP:183  7  1  restart|
   \continue
   Restart the game.  (Any ``Are you sure?" question
   must be asked by the game, not the interpreter.)  The unique piece of
   information surviving from the previous state is the ``transcribing
   to printer'' bit (bit 0 of `Flags 2' in the header, at address |$10|),
   so that restarts are neatly printed in transcripts.
   (In particular, changing the program start address before a restart will
   not have the effect of restarting from this new address.)

\block{restore}|0OP:182  6  1  restore         <label>|
   \continue
   |EXT:257  1  5  restore         table bytes name <result>|
   \continue
   See |save|.  In Version 3, the branch is never actually made,
   since either the game has successfully picked up again from where it
   was saved, or it failed to load the save game file.
   \continue
   As with |restart|, the transcription bit survives.  The interpreter
   gives the game a way of knowing that a restore has just happened
   (see |save|).
   \continue
   From Version 5
   it can have optional parameters as |save| does, and returns the number
   of bytes loaded if so.  If the restore fails, 0 is returned, but once
   again this necessarily happens since otherwise control is already
   elsewhere.

\block{restore\_undo}|EXT:266  A  5  restore_undo    <result>|
   \continue
   Like |restore|, but restores the state saved to memory
   by |save_undo|.  (The optional parameters of |restore| may not be
   supplied.)  The behaviour of |restore_undo| is unspecified if no
   |save_undo| has previously occurred (and a game may not legally use it):
   an interpreter might simply ignore this.

\block{ret}|1OP:139  B     ret             value|
   \continue
   Returns from the current routine with the value given.

\block{ret\_popped}|0OP:184  8     ret_popped|
   \continue
   Pops top of stack and returns that.  (This is equivalent
   to |ret sp|, but is one byte cheaper.)

\block{"retsp"}Obsolete name for |ret_popped|.

\block{rfalse}|0OP:177  1     rfalse|
   \continue
   Return false (i.e., 0) from the current routine.

\block{rtrue}|0OP:176  0     rtrue|
   \continue
   Return true (i.e., 1) from the current routine.

\block{"same\_parent"}An obsolete (and misguided) Inform name for the
   opcode now called |jin|.

\block{save}|0OP:181  5  1  save            <label>|
   \continue
   On Versions 3 and 4, attempts to save the game (all questions
   about filenames are asked by interpreters) and branches if successful.
   From Version 5 it is a store rather than a branch instruction;
   the store value is 0 for failure, 1 for ``save succeeded" and 2 for
   ``the game is being restored and is resuming execution again from here,
   the point where it was saved".
   \continue
   The extension also has (optional) parameters, which save a region of
   the save area, whose address and length are in bytes, and provides a
   suggested filename: name is a pointer to an array of ASCII characters
   giving this name (as usual preceded by a byte giving the number of
   characters).  See \S 7.6.

\block{save\_undo}|EXT:265  9  5  save_undo       <result>|
   \continue
   Like |save|, except that the optional parameters may not
   be specified: it saves the game into a cache of memory held by the
   interpreter.  If the interpreter is unable to provide this feature, it
   must return -1: otherwise it returns the |save| return value.
   \continue
   (This call is typically needed once per turn, in order to implement
   ``UNDO", so it needs to be quick.)

\block{scan\_table}|VAR:247 17  4  scan_table      x table len|
   \continue
   Is |x| one of the words in |table|, which is |len| words
   long?  If so, return the address where it first occurs and branch.  If not,
   return 0 and don't.
   \continue
   The |form| is optional (and only used in Version 5?): bit 8 is set for
   words, clear for bytes: the rest contains the length of each field in
   the table.  (The first word or byte in each field being the one looked
   at.)  Thus |$82| is the default.

\block{"scanw"}Obsolete name for |scan_table|.

\block{scroll\_window}|EXT:276 14  6  scroll_window   window pixels|
   \continue
   Scrolls the given window by the given number of pixels
   (a negative value scrolls backwards, i.e., down) writing in blank
   (background colour) pixels in the new lines.  This can be done to any
   window and is not related to the ``scrolling" attribute of a window.

\block{set\_attr}|2OP:11   B     set_attr        object attribute|
   \continue
   Make |object| have the attribute numbered |attribute|.

\block{set\_colour}|2OP:27  1B  5  set_colour      foreground background|
   \continue
   If coloured text is available, set text to be
   foreground-against-background.
   \continue
   (One Version 5 game uses this: `Beyond Zork' (Paul David Doherty reports
   it as used ``76 times in 870915 and 870917, 58 times in 871221'') and from
   the structure of the table it clearly logically belongs in version 5.)

\block{set\_cursor}|VAR:239  F  4  set_cursor      line column|
   \continue
   |            6  set_cursor      line column window|
   \continue
   Move cursor in the current window to $(x,y)$ character
   position (relative to $(1,1)$ in the top left).  (In Version 6 the
   window is supplied and need not be the current one.)  Using this call may
   result in any buffered text being printed out first (if word-wrapping is
   going on, for instance).
   \continue
   In Version 6, |set_cursor -1| turns the cursor off, and either
   |set_cursor -2| or |set_cursor -2 0| turn it back on.  It is not known
   what, if anything, this second argument means: in all known cases it is 0.

\block{"set\_flag"}See |clear_flag|.

\block{set\_font}|EXT:260  4  5  set_font        font window <result>|
   \continue
   If the requested font is available, then it is chosen as
   the font for the given window, and the store value is the font ID of
   the previous font (which is always positive).  If the font is unavailable,
   nothing will happen and the store value is 0.

\block{set\_margins}|EXT:264  8  6  set_margins     left right window|
   \continue
   Sets the margin widths (in pixels) on the left and right
   for the given window (which are by default 0).

\block{set\_text\_style}|VAR:241 11  4  set_text_style  style|
   \continue
   Sets the text style to: Roman (if 0), Reverse
   Video (if 1), Bold (if 2), Italic (4), Fixed Pitch (8).  In some
   interpreters (though this is not required) a combination of styles is
   possible (such as reverse video and bold).  In these, changing to
   Roman should turn off all the other styles currently set.

\block{set\_window}|VAR:235  B  3  set_window      window|
   \continue
   Selects the given window for text output.

\block{"show\_score"}Obsolete name for |show_status|.

\block{show\_status}|0OP:188  C  3  show_status|
   \continue
   (In Version 3 only.)  Display and update the
   status line now (don't wait until the next keyboard input).  (In theory
   this opcode is illegal in later Versions but an interpreter should treat
   it as |nop|, because Version 5 Release 23 of `Wishbringer' contains
   this opcode by accident.)

\block{sound\_effect}|VAR:245 15 5/3 sound_effect    number effect volume routine|
   \continue
   (Inform also uses the name |beep| for this opcode,
   though this name is being withdrawn.)
   \continue
   The given effect happens to the given sound number.  The low byte of
   |volume| holds the volume level, the high byte the number of repeats.
   (The value 255 means ``loudest possible'' and ``forever'' respectively.)
   (In Version 3, repeats are unsupported and the high byte must be 0.)
   \continue
   The |effect| can be: 1 (prepare), 2 (start), 3 (stop), 4 (finish with).
   \continue
   In Versions 5 and later, the |routine| is called (with no parameters)
   after the sound has been finished (it has been playing in the background
   while the Z-machine has been working on other things).  (This is used by
   `Sherlock' to implement fading in and out, which explains why mysterious
   numbers like |$34FB| were previously thought to be to do with fading.)
   The routine is not called if the sound is stopped by another sound or by
   an effect 3 call.
   \continue
   See the remarks to \S 9 for which forms of this opcode were actually
   used by Infocom.
   \continue
   In theory, |@sound_effect;| (with no operands at all) is illegal.
   However interpreters are asked to beep (as if the operand were 1) if
   possible, and in any case not to halt.

\block{split\_window}|VAR:234  A  3  split_window    lines|
   \continue
   Splits the screen so that the upper window has the
   given number of lines: or, if this is zero, unsplits the screen again.
   In Version 6, this is supposed to roughly emulate the earlier Version
   behaviour (see \S 8).  (However, existing Version 6 games seem to use
   it just for bounding cursor movement.  `Journey' creates a status region
   which is the whole screen and then overlays it with two other windows.)

\block{sread}This is the Inform name for the keyboard-reading opcode
   under Versions 3 and 4.  (Inform calls the same opcode |aread| in later
   Versions.)  See |read| for the specification.

\block{store}|2OP:13   D     store           <variable> value|
   \continue
   Set the |variable| referenced by the operand to |value|.

\block{storeb}|VAR:226  2     storeb          array byte-index value|
   \continue
   |array->byte-index = value|, i.e. stores the given value
   in the byte at address |array+byte-index| (which must lie in dynamic
   memory).  (See |loadb|.)

\block{storew}|VAR:225  1     storew          array word-index value|
   \continue
   |array-->word-index = value|, i.e. stores the given value
   in the word at address |array+2*word-index| (which must lie in dynamic
   memory).  (See |loadw|.)

\block{sub}|2OP:21  15     sub             a b <result>|
   \continue
   Signed 16-bit subtraction.

\block{test}|2OP:7    7     test            bitmap flags <label>|
   \continue
   Jump if all of the flags in bitmap are set
   (i.e. if |bitmap & flags == flags|).

\block{"test\_array"}See |clear_flag|.  (|ITF| implements this as
   unconditionally false.)

\block{test\_attr}|2OP:10   A     test_attr       object attribute <label>|
   \continue
   Jump if |object| has |attribute|.

\block{throw}|2OP:28  1C 5/- throw           value stack-frame|
   \continue
   Opposite of |catch|: resets the routine call state to
   the state it had when the given stack frame value was `caught', and
   then returns.  In other words, it returns as if from the routine
   which executed the |catch| which found this stack frame value.

\block{tokenise}|VAR:251 1B  5  tokenise        text parse dictionary flag|
   \continue
   This performs lexical analysis (see |read| above).
   \continue
   If a non-zero |dictionary| is supplied, it is used (if not, the ordinary
   game dictionary is).  If the |flag| is set, unrecognised words are not
   written into the parse buffer and their slots are left unchanged: this
   is presumably so that if several |tokenise| instructions are performed
   in a row, each fills in more slots without wiping those
   filled by the others.
   \continue
   Parsing a user dictionary is slightly different.  A user dictionary
   should look just like the main one but need not be alphabetically sorted.
   If the number of entries is given as $-n$, then the interpreter reads
   this as ``$n$ entries unsorted".  This is very convenient if the table
   is being altered in play: if, for instance, the player is naming things.

\block{verify}|0OP:189  D  3  verify          <label>|
   \continue
   Verification counts a (two byte, unsigned) checksum of the
   file from |$0040| onwards (by taking the sum of the values of each byte
   in the file, modulo |$10000|) and compares this against the value in the
   game header, branching if the two values agree.  (Early Version 3 games
   do not have the necessary checksums to make this possible.)
   \continue
   The interpreter may stop calculating when the file length (as given in
   the header) is reached.  It is legal for the file to contain more bytes
   than this, but if so the extra bytes must all be 0, which would contribute
   nothing the the checksum anyway.  (Some story files are padded
   out to an exact number of virtual-memory pages using 0s.)

\block{"vje"}Internal Inform name for the variable-length form of |je| (for
   compiling conditions such as |a==1 or 2 or 4|).

\block{window\_size}|EXT:273 11  6  window_size     window y x|
   \continue
   Change size of window in pixels.  (Does not change the
   current display.)

\block{window\_style}|EXT:274 12  6  window_style    window flags operation|
   \continue
   Changes attributes for a given window.  A bitmap of
   attributes is given, in which the bits are: 1 -- keep text within margins,
   2 -- scroll when at bottom, 3 -- copy text to output stream 2 (the printer),
   4 -- buffer text to word-wrap it between the margins of the window.
   \continue
   The operation, by default, is 0, meaning ``set to these settings".  1 means
   ``set the bits supplied".  2 means ``clear the ones supplied", and 3 means
   ``reverse the bits supplied" (i.e. eXclusive OR).

\newpage

\specs{16}{Font 3 and character graphics}
\sp{1} The following table of $8\times 8$ bitmaps gives a suitable appearance
for font 3.  The font must have a fixed pitch and characters must be printed
immediately next to each other in all four directions.
\orm\beginstt
32( ):  76543210   33(!):  76543210   34("):  76543210   35(#):  76543210
       0                  0                  0                  0       #
       1                  1                  1                  1      #
       2                  2  #               2    #             2     #
       3                  3 ##               3    ##            3    #
       4                  4#######           4#######           4   #
       5                  5 ##               5    ##            5  #
       6                  6  #               6    #             6 #
       7                  7                  7                  7#
36($):  76543210   37(%):  76543210   38(&):  76543210   39('):  76543210
       0#                 0                  0                  0
       1 #                1                  1                  1
       2  #               2                  2                  2
       3   #              3                  3                  3########
       4    #             4                  4########          4
       5     #            5                  5                  5
       6      #           6                  6                  6
       7       #          7                  7                  7
40(():  76543210   41()):  76543210   42(*):  76543210   43(+):  76543210
       0    #             0   #              0    #             0
       1    #             1   #              1    #             1
       2    #             2   #              2    #             2
       3    #             3   #              3########          3
       4    #             4   #              4                  4########
       5    #             5   #              5                  5    #
       6    #             6   #              6                  6    #
       7    #             7   #              7                  7    #
44(,):  76543210   45(-):  76543210   46(.):  76543210   47(/):  76543210
       0    #             0   #              0   #              0
       1    #             1   #              1   #              1
       2    #             2   #              2   #              2
       3    #             3   #              3   #              3   #####
       4    ####          4####              4   #####          4   #
       5    #             5   #              5                  5   #
       6    #             6   #              6                  6   #
       7    #             7   #              7                  7   #
\endtt\vfill\eject
\orm\beginstt
48(0):  76543210   49(1):  76543210   50(2):  76543210   51(3):  76543210
       0                  0    #             0   #              0#
       1                  1    #             1   #              1 #
       2                  2    #             2   #              2  #
       3#####             3    #             3   #              3   #####
       4    #             4#####             4   #####          4   #
       5    #             5                  5  #               5   #
       6    #             6                  6 #                6   #
       7    #             7                  7#                 7   #
52(4):  76543210   53(5):  76543210   54(6):  76543210   55(7):  76543210
       0       #          0    #             0########          0########
       1      #           1    #             1########          1########
       2     #            2    #             2########          2########
       3#####             3    #             3########          3########
       4    #             4#####             4########          4########
       5    #             5     #            5########          5
       6    #             6      #           6########          6
       7    #             7       #          7########          7
56(8):  76543210   57(9):  76543210   58(:):  76543210   59(;):  76543210
       0                  0#####             0   #####          0    #
       1                  1#####             1   #####          1    #
       2                  2#####             2   #####          2    #
       3########          3#####             3   #####          3########
       4########          4#####             4   #####          4########
       5########          5#####             5   #####          5########
       6########          6#####             6   #####          6########
       7########          7#####             7   #####          7########
60(<):  76543210   61(=):  76543210   62(>):  76543210   63(?):  76543210
       0########          0#####             0   #####          0   #####
       1########          1#####             1   #####          1   #####
       2########          2#####             2   #####          2   #####
       3########          3#####             3   #####          3   #####
       4########          4########          4########          4   #####
       5    #             5#####             5   #####          5
       6    #             6#####             6   #####          6
       7    #             7#####             7   #####          7
64(@):  76543210   65(A):  76543210   66(B):  76543210   67(C):  76543210
       0                  0                  0#####             0   #####
       1                  1                  1#####             1   #####
       2                  2                  2#####             2   #####
       3   #####          3#####             3#####             3   #####
       4   #####          4#####             4#####             4   #####
       5   #####          5#####             5                  5  #
       6   #####          6#####             6                  6 #
       7   #####          7#####             7                  7#
\endtt\vfill\eject
\orm\beginstt
68(D):  76543210   69(E):  76543210   70(F):  76543210   71(G):  76543210
       0#                 0       #          0#####             0       #
       1 #                1      #           1#####             1
       2  #               2     #            2#####             2
       3   #####          3#####             3#####             3
       4   #####          4#####             4#####             4
       5   #####          5#####             5     #            5
       6   #####          6#####             6      #           6
       7   #####          7#####             7       #          7
72(H):  76543210   73(I):  76543210   74(J):  76543210   75(K):  76543210
       0                  0                  0#                 0########
       1                  1                  1                  1
       2                  2                  2                  2
       3                  3                  3                  3
       4                  4                  4                  4
       5                  5                  5                  5
       6                  6                  6                  6
       7       #          7#                 7                  7
76(L):  76543210   77(M):  76543210   78(N):  76543210   79(O):  76543210
       0                  0#                 0       #          0
       1                  1#                 1       #          1########
       2                  2#                 2       #          2
       3                  3#                 3       #          3
       4                  4#                 4       #          4
       5                  5#                 5       #          5
       6                  6#                 6       #          6########
       7########          7#                 7       #          7
80(P):  76543210   81(Q):  76543210   82(R):  76543210   83(S):  76543210
       0                  0                  0                  0
       1########          1########          1########          1########
       2#                 2##                2###               2####
       3#                 3##                3###               3####
       4#                 4##                4###               4####
       5#                 5##                5###               5####
       6########          6########          6########          6########
       7                  7                  7                  7
84(T):  76543210   85(U):  76543210   86(V):  76543210   87(W):  76543210
       0                  0                  0                  0
       1########          1########          1########          1########
       2#####             2######            2#######           2########
       3#####             3######            3#######           3########
       4#####             4######            4#######           4########
       5#####             5######            5#######           5########
       6########          6########          6########          6########
       7                  7                  7                  7
\endtt\vfill\eject
\orm\beginstt
88(X):  76543210   89(Y):  76543210   90(Z):  76543210   91([):  76543210
       0                  0                  0#      #          0    #
       1       #          1#                 1 #    #           1    #
       2       #          2#                 2  #  #            2    #
       3       #          3#                 3   ##             3    #
       4       #          4#                 4   ##             4########
       5       #          5#                 5  #  #            5    #
       6       #          6#                 6 #    #           6    #
       7                  7                  7#      #          7    #
92(\):  76543210   93(]):  76543210   94(^):  76543210   95(_):  76543210
       0   ##             0   ##             0   ##             0########
       1  ####            1   ##             1  ####            1#      #
       2## ## ##          2   ##             2## ## ##          2#      #
       3   ##             3   ##             3   ##             3#      #
       4   ##             4## ## ##          4## ## ##          4#      #
       5   ##             5  ####            5  ####            5#      #
       6   ##             6   ##             6   ##             6#      #
       7                  7                  7                  7########
96(`):  76543210   97(a):  76543210   98(b):  76543210   99(c):  76543210
       0  ####            0##   #            0 ##               0   #
       1 ##  ##           1# # #             1 # #              1   ##
       2     ##           2#  #              2 #  #             2   # #
       3    ##            3##                3 ###              3#  #  #
       4   ##             4# #               4 #  #             4 # #
       5                  5#  #              5 # #              5  ##
       6   ##             6#                 6 ##               6   #
       7                  7                  7                  7
100(d):  76543210  101(e):  76543210  102(f):  76543210  103(g):  76543210
       0#     #           0#     #           0#  # #            0#     #
       1##   ##           1##   ##           1# # #             1 #   #
       2# # # #           2# # # #           2## #              2  # #
       3#  #  #           3#  #  #           3# #               3   #
       4# # # #           4#     #           4##                4  # #
       5##   ##           5#     #           5#                 5 #   #
       6#     #           6#     #           6#                 6#     #
       7                  7                  7                  7
104(h):  76543210  105(i):  76543210  106(j):  76543210  107(k):  76543210
       0##    #           0   #              0   #              0   #
       1# #   #           1   #              1  ###             1   #
       2## #  #           2   #              2 # # #            2   #
       3# # # #           3   #              3#  #  #           3  ###
       4#  # ##           4   #              4 # # #            4 # # #
       5#   # #           5   #              5  ###             5#  #  #
       6#    ##           6   #              6   #              6#  #  #
       7                  7                  7                  7
\endtt\vfill\eject
\orm\beginstt
108(l):  76543210  109(m):  76543210  110(n):  76543210  111(o):  76543210
       0   #              0##   ##           0#  #              0##   #
       1   ##             1# # # #           1 # #              1# # ##
       2   # #            2#  #  #           2  ###             2## # #
       3   #  #           3# # # #           3   # #            3# # #
       4   #              4##   ##           4   #  #           4#  #
       5   #              5#     #           5   #              5#
       6   #              6#     #           6   #              6#
       7                  7                  7                  7
112(p):  76543210  113(q):  76543210  114(r):  76543210  115(s):  76543210
       0#                 0 #                0 ##               0 #
       1#                 1 #                1 # #              1 #   #
       2#                 2 #                2 #  #             2 #  ##
       3#  #              3 ####             3 # #              3 # # #
       4# # #             4 #   #            4 ##               4 ##  #
       5##   #            5 #   #            5 # #              5 #   #
       6#     #           6 #   #            6 #  #             6     #
       7                  7                  7                  7
116(t):  76543210  117(u):  76543210  118(v):  76543210  119(w):  76543210
       0   #              0 ##               0   #              0 ##
       1  ###             1 # #              1# ### #           1 # #
       2 # # #            2 #  #             2 # # #            2 #  #
       3#  #  #           3 #   #            3   #              3 # #
       4   #              4 #   #            4   #              4 ##
       5   #              5 #   #            5   #              5 #
       6   #              6 #   #            6   #              6 #
       7                  7                  7                  7
120(x):  76543210  121(y):  76543210  122(z):  76543210  123({):  76543210
       0#  #  #           0###               0   #              0###  ###
       1 # # #            1## #              1  # #             1##    ##
       2  ###             2# # #             2 #   #            2  #  #
       3   #              3#  # #            3  # #             3###  ###
       4   #              4#  ## #           4   #              4###  ###
       5   #              5#  # ##           5  # #             5###  ###
       6   #              6#  #  #           6 #   #            6###  ###
       7                  7                  7                  7########
124( ):  76543210  125(}):  76543210  126(~):  76543210
       0###  ###          0###  ###          0##    ##
       1###  ###          1##    ##          1#  ##  #
       2###  ###          2  #  #            2#####  #
       3###  ###          3###  ###          3####  ##
       4  #  #            4  #  #            4###  ###
       5##    ##          5##    ##          5########
       6###  ###          6###  ###          6###  ###
       7########          7########          7########
\endtt
\vfill\eject

\remarks
The short Inform program ``fonts.inf'' may be useful for testing the fonts
produced by an interpreter (at least in their appearance on the upper
window).

Two different versions of font 3 were supplied by Infocom, which we shall
call the Amiga and PC forms (the Atari form is the same as for the PC).  The
arrow shape differed slightly and so did the rune alphabet.  (A game can
rely only on the 26 letters each having its own rune.)  Each was an attempt
to map the late Anglian (``futhorc'') runic alphabet, which has 33
characters, onto our Latin alphabet.  The drawings above are from the Amiga
set.

Most of the mappings are straightforward (e.g., Latin A maps to Anglian a),
except that: Latin C is mapped to Anglian eo; K to ``other k'' (previously a
z sound); Q to Anglian k (the same rune as c); V to ea; X to z and Z to oe.
The PC runes differ as follows: G has an ornamental circle making it more
look like ``other z''; K maps to Anglian k (or c); Q is an Anglian ea (which
resembles the late Anglian q); V is an oe; X is an ``other k'' and Z is a
symbol Infocom seem to have invented themselves.  (Though less well drawn
the PC runes arguably have a better sound-mapping.)

The font behaviour of `Beyond Zork' is rather complicated and depends on
the interpreter number if finds in the header (see \S 11).  If this is 1
(for Infocom's own mainframe) it asks whether the player has a VT220
terminal (a Digital terminal capable of character graphics) and, if so,
always uses font 3 (whatever |set_font| returns, whatever the interpreter
did with bit 3 of `Flags 2').  Here Infocom were clearly violating their
own specification for in-house convenience.

`Beyond Zork' story files initially have bit 3 of `Flags 2' set, and
for higher interpreter numbers (i.e. for Infocom's released interpreters)
the game does avoid font 3 if the interpreter has cleared this bit again.

If interpreter number 6 (for MS-DOS, i.e., an IBM PC) clears the bit,
though, `BZ' does something redundant: it uses |set_font 3|
anyway (ignoring the return code, which should be always be a refusal)
and then prints using IBM PC graphics codes.  This is a problem for
|Zip|, since many non-IBM ports of it still have interpreter number 6.
|Zip| therefore has to convert these IBM PC codes back into ASCII,
which it does as follows:
\beginstt
179 becomes a vertical stroke (ASCII 124)
186         a hash (ASCII 35)
196         a minus sign (ASCII 45)
205         an equals sign (ASCII 61)
all others in the range 179 <= c <= 218 become a plus sign (ASCII 43)
\endtt
`BZ' treats interpreter number 8 (for the Commodore 64) similarly, using
various Commodore character codes if it can't use font 3.  Formally,
the use of these machine-dependent character codes is a violation of
this document's specification.  (So to run a Beyond Zork correctly,
the interpreter should either: (i) not number itself 6 or 8, or
(ii) provide font 3, or (iii) number itself 6 but use the above
translation.)

The ``COLOR'' command in `BZ' (typed at the keyboard) also behaves
differently depending on the interpreter number, which is legal behaviour
and has no impact on the specification.
\tenpoint\newpage

\section{A}{Error messages and debugging}

Older interpreters, such as |ITF|, are extremely curt when an error condition
is reached (for example, an illegal opcode).  Such a thing could only then
arise as a result of a bug elsewhere in the interpreter, so it was
understandable that no effort went into error messages.

In debugging Inform games, though, many error conditions can arise and it is
extremely helpful to report these as fully as possible.  These include:
\item{1.} An illegal opcode being hit;
\item{2.} Nonsense operands (such as reference to non-existent local
variables);
\item{3.} A call to what can't be a routine (because the initial byte is not
between 0 and 15);
\item{4.} A jump or call to an address beyond the size of the story file;
\item{5.} An attempt to |print_object| an object which doesn't exist
(especially on the status line in V3 games);
\item{6.} Division by zero.
\noindent The player sometimes then has the annoying task of working out
where the error took place in source code.  Providing a stack back-trace
would be a help.

In addition, an interpreter might provide options for keeping track of
maximum stack usage and the typical number of opcodes executed between
each read from the keyboard.  (But watching these is a time-wasting
activity, so they should be options.)

Finally, infinite loops fairly often happen, as in any programming
language.  On a system without pre-emptive multi-tasking, this may lock
up the whole machine, as the usual way that porters implement multi-tasking
is to return control to the host operating system only when the keyboard
is read.  This can be avoided by providing a point in the code which
could return control to the OS from time to time: on an Acorn
Archimedes, for instance, passing control out of |Zip| once every
2000 instructions has solved the problem without noticeably slowing
game play.

\section{B}{Conventional contents of the header}

The header table in \S 11 details everything the interpreter needs to know
about the header's contents.  A few other slots in the header are meaningful
but only by convention (since existing Infocom and Inform games write them).
These additional slots are described here.

As in \S 11, ``Hex'' means the address, in hexadecimal; ``V'' the
earliest version in which the feature appeared; ``Dyn'' means that the byte
or bit may legally be changed by the game during play (no others may legally
be changed by the game); ``Int'' means that the interpreter may (in some
cases must) do so.
\midinsert\smallskip\hrule\smallskip\beginlines
| Hex  V  Dyn Int  Contents|
\endlines\smallskip\hrule\smallskip\beginlines
|  1   1           Flags 1:|
|      .3      *     Bit 2    (unused but set in V3?)|
|      .3      *         3    The legendary "Tandy" bit (see note)|
|  2   1           Release number (word)|
| 10   1   *       Flags 2:|
|      .3            Bit 4    Set in the Amiga version of The Lurking Horror|
|                               so presumably to do with sound effects?|
|      .?  ?   *        10    Possibly set by interpreter to indicate an error|
|                               with the printer during transcription|
| 12   2           Serial code (six characters of ASCII)|
|      3           Serial number (ASCII for the compilation date in|
|                                 the form YYMMDD)|
| 38   6       *   8 bytes of ASCII: the player's user-name on Infocom's|
|                    own mainframe, useful to identify which person played|
|                    a particular saved-game|
\endlines\smallskip\hrule\endinsert

1. In Versions 1 to 3, bits 0 and 7 of `Flags 1' are unused.  In later
Versions, bits 0, 6 and 7 are unused.  In `Flags 2', bits 9 and 11-15 are
unused.  Infocom used up almost the whole header: only the bytes at |$32|
and |$33| are unused in any Version, and those are now allocated for
standard interpreters to give their Revision numbers.

2. Some early Infocom games were sold by the Tandy Corporation, who
seem to have been sensitive souls.  `Zork I' pretends not to have sequels
if it finds the Tandy bit set.  And to quote Paul David Doherty:
\quote
  In `The Witness', the Tandy Flag can be set while playing the game,
  by typing |$DB| and then |$TA|.  If it is set, some of the prose will be
  less offensive. For example, ``private dicks" become ``private eyes",
  ``bastards" are only ``idiots", and all references to ``slanteyes" and
  ``necrophilia" are removed.
\endquote
We live in an age of censorship.

3. For comment on interpreter numbers, see \S 11. Infocom's own interpreters
were generally rewritten for each of versions 3 to 6.  For instance,
interpreters known to have been shipped with the Macintosh gave version
letters B, C, G, I (Version 3), E, H, I (Version 4), A, B, C (Version 5) and
finally 6.1 for Version 6.  (Version 6 interpreters seem to have version
numbers rather than letters.)  See the ``Infocom fact sheet'' for fuller
details.

\newpage

\section{C}{Resources available}

\quote
..the dead hand of the academy had yet to stifle the unbridled
enthusiasms of a small band of amateurs in Europe and America.
\poemby{Michael D. Coe}{Breaking the Maya Code}

The resources below are all available from the |if-archive| at the
anonymous FTP site |ftp.gmd.de| in Germany, maintained by Volker
Blasius.

\subtitle{Interpreters}

Six interpreters are publically available, of which two are in widespread
use:
\item{1.} |Zip|, by Mark Howell (1991-), is currently the most accurate
interpreter across Versions 1 to 5.  It is fast and has reasonably good
error reportage.
\item{2.} The |InfoTaskForce| (or |ITF|) interpreter (1987-92) is almost as
good, but slower and less accurate on some Version 5 features.  It is no
longer maintained and the final version was 4.01.  Various patches have
been made to improve ports of |ITF|: for instance, Bryan Scattergood's
Psion and Archimedes interpreter is much more accurate.
\par\noindent
The other four are obsolescent or have yet to be widely used:
\item{3.} |Pinfocom| (1992), derived from an early form of |ITF|, and
released by Paul Smith as a Version 3 (only) interpreter; final version 3.0.
\item{4.} |Zmachine| (1988-90), by Matthias Pfaller: briefly in limited
circulation (again, for Version 3 only).
\item{5.} |ZIPDebug| (1991-3), by Frank Lancaster, supporting Versions 1
to 5 and offering some debugger facilities.
\item{6.} |Zterp| (1992), by Charles M. Hannum, for Versions 3 to 5:
reputedly very fast.
\par\noindent
Currently we lack a comprehensive Version 6 interpreter.  It is hoped that
|Zip| will eventually support Version 6 as well.

\subtitle{Compilers}

Infocom's original compiler |Zilch| no longer exists: nor is any of its
language, |ZIL|, documented anywhere (though this is similar to |MDL|, which
is documented): nor is any of Infocom's source code in the public domain
(though a fragment or two by Stu Galley has been circulated a little).

Inform is the only other compiler to have existed.  It is freeware and
comes with full documentation (of which this document is a part).

\subtitle{Debugger}

An enhanced version of |Zip|, a source-level debugger for
Inform games called |Infix|, can be obtained in test form from Dilip
Sequeira.

\subtitle{Utility programs}

Mark Howell has written a toolkit of utility programs (1991-5; sometimes
called |Ztools|), which includes:
\item{1.} |Txd|, a disassembler for Versions 1 to 6.  (Uses the
same opcode names as Inform and this document, and has an option to
disassemble in Inform assembly-language syntax.)
\item{2.} |Infodump|, capable of printing the header information,
object tree (with properties and attributes), dictionary and grammar
tables of a Version 1 to 5 game.  (Also has some ability to print the
parsing tables used by the Inform parser; and decodes all but the
parsing tables for Version 6 games too.)
\item{3.} |Pix2gif|, for converting Version 6 picture data
to GIF files.
\item{4.} |Check|, for verifying story files.

\par\noindent
|Infodump| largely supersedes Mike Threepoint's vocabulary dumper
|Zorkword| (1991-2), which was important in its day (and which the
author found extremely helpful when writing Inform 1).

\subtitle{Story files}

\item{1.} Many Inform-compiled story files are publically available:
games such as `Curses', `Christminster', `Theatre', `Busted', `Balances',
`Advent', `Adventureland' and so on.
\item{2.} A few Infocom story files are public, notably two 4-in-1 sample
games (released for advertising purposes) and `Minizork' (a heavily
abbreviated form of Zork I released with a Commodore magazine).
\item{3.} Almost all Infocom's games remain commercially available in
anthologies published by Activision.  Copyright resides in them and they
should not available by FTP from any site.
\item{4.} A few other Infocom story files have existed but are neither
on sale nor released from copyright: this applies to several of the
Version 6 games, `Leather Goddesses of Phobos' and ephemera such as
beta-test versions which have somehow passed into private circulation.

\par\noindent
Most of the Infocom games exist in several different releases, and some
were written for one Version and then ported to later ones.  `Zork I', for
instance, has at least 11 releases, 2 early, 8 in Version 3
(with release numbers between 5 to 88 in chronological order) and one in
Version 5 (release 52 -- the releases go back to 1 when the version changes).

Version 1 and 2 games are extinct, though there are a few fossils
in the hands of collectors.

\subtitle{Documents}

The definitive guide to all Infocom story files known to exist, and an
indispensable reference for anyone interested in Infocom, is Paul David
Doherty's ``fact sheet'' file, which is regularly updated, concise and
precise.  This supersedes Paul Smith's ``Infocom Game Information'' file.

Stefan Jokisch has written a brief specification of Infocom-format
sound effects files.

The {\sl Inform Technical Manual} documents the format of parsing tables
used in Inform games.

Most of the contents of the original Infocom game manuals are still on
sale with the games themselves: the ``samplers'' (sample transcripts of
play) are not, but an archive of them is publically available.  So is
an interesting historical archive of magazine articles concerning
Infocom, and articles from Infocom's own publicity magazine.


\section{D}{A short history of the Z-machine}

Infocom made six main Versions of the Z-machine and several minor variant
forms.  These are recognisably similar but with labyrinthine differences,
like different archaic dialects of the same language.  (The archaeological
record stops sharply in 1989 when the civilisation in question collapsed.)

Broadly, these fall into two groups: early (Versions 1 to 3) and late
(4 to 6).  More fully:
\smallskip
\settabs\+\indent Version 1\quad&\cr
\+ Version 1 & Early Apple ][ and TRS-80 Model I games\cr
\+ Version 2 & Early Apple ][ and TRS-80 Model I games\cr
\smallskip
\+ Version 3 & ``Standard'' series games\cr
\+ Version 4 & ``Plus'' series games\cr
\+ Version 5 & ``Advanced" series games, or, as the marketing division would\cr
\+           & have it, ``Solid Gold Interactive Fiction" -- a reference to\cr
\+           & the colour (though not composition) of the boxes they came in\cr
\smallskip
\+ Version 6 & Later games with graphics, mouse support, etc.\cr
\smallskip
\noindent
Infocom called their own interpreters ZIP (versions 1 to 3), EZIP/LZIP
(V4), XZIP (V5) and YZIP (V6).  They speculated on the possibility of an
interpreter capable of running all Versions, but never published one.
\bigskip

The original purpose of the Z-machine was simply to implement as much as
possible of the mainframe game ``Zork'' on the first popular wave of home
computers.

(Apparently ``zork" was a nonsense word used at MIT for the current
uninstalled program in progress, and stuck.  Just as this document uses the
term ``Z-machine" for both the machine and its loaded program (which is also
sometimes called the ``story file''), so ZIP (Zork Implementation Program)
was used to mean either the interpreter or the object code it interpreted.
Code was written in ZIL (Zork Implementation Language), which was derived
from MDL (informally called ``muddle"), a particularly unhelpful form of
LISP.  It was then compiled by ZILCH to assembly code which was passed to
ZAP to make the ZIP.)

The Z-machine as originally constructed was surprisingly similar to that in
use today.  Version 1 (by Joel Berez and Marc Blank, in Autumn 1979)
contained essentially all of the main architecture: the header, the memory
divided into three, the variables and stack, the object tree, the
dictionary, the instruction format.  It used ``shift lock''
characters (a text compression trick which did not survive, though it was
more efficient on long sequences of capital letters or punctuation
characters than the technique which replaced it).  The first micro
interpreters were for the TRS-80 Model I (by Scott Cutler) and the Apple II
(by Bruce K. Daniels).  (A TRS-80 Model II interpreter was written but never
actually shipped.)

Version 2 was only a minor enhancement.  Abbreviations (used to help
text compression) appeared, but only in one 32-word bank, and the
six-digit serial number appeared in the header, though it wasn't always the
date in those days: Release 7 of `Zork II', for instance, is numbered
|UG3AU5|.  (Other bizarre serial numbers, such as |000000|, appear on fakes
or beta-test releases.)

In Version 3, the text encoding alphabets changed again, and the old ``shift
lock'' codes were dropped in favour of expanding the abbreviations bank to 96
entries.  The ``verify" opcode and checksums appeared; and a new opcode to
reprint the status line at the top of the screen was introduced.
(Previously, this had been updated only when input was taken from the
keyboard.)  The earliest Version 3 releases (`Deadline', then reissues of
`Zork I' and `II') were in March and April 1982; the last (the `Minizork', a
cassette-based Commodore-64 sample of `Zork') was in November 1987.

The idea of widespread portability finally came of age as (between 1982 and
1985) interpreters were developed for the Atari 400/800, CP/M, the IBM PC,
the TRS-80 Model III, the NEC APC, the DEC Rainbow, the Commodore 64, the TI
Professional, the DECmate, the Tandy-2000, the Kaypro II, the Osborne 1,
MS-DOS, the TI 99/4a, the Apple Macintosh, the Epson QX-10, the Apricot, the
Atari ST and the Amiga.  Infocom's middle period coincided with the bubble
in home computers, before the market collapsed to its present apparently
stable state (in which IBM and Apple share almost the entire market), and
the Z-machine's portability gave Infocom a unique advantage over its
competitors.  Also, it was an expertly marketed quality brand at a time when
standards of workmanship were very variable; and text-only games did not
seem so dull at a time when graphics were on the whole crude and slow. These
factors combined to give Infocom considerable (though never enormous)
commercial success.

By 1982, then, the Z-machine had stabilised to a clean design which was to
remain in use for six years.  It was very portable, contained everything
reasonably necessary and most of its complications were badly-needed space
optimisations.  (Although Version 3 can fit 128K of story file, the
practical limit in 1982-4 was about 110K, that being the typical disc
capacity on target machines.)  The ZAP assembler was cleverly written to
exploit these optimisations, though the Zilch compiler's code generator was
much less efficient.  (Interestingly, Infocom did not develop any generic
central library, and Infocom's authors worked fairly independently of each
other: each new game would inherit a small core of code from a previous one,
but this would make up only about 10K of code (about a third of the size of
the Inform library) and would end up being hacked about to suit the new
game.  Without a central library, Infocom games waste a fair amount of space
in duplicating code for routine operations many times over.  For this
reason, Inform games tend to squash appreciably more design into the
format.)

``Verify'' and checksum data were quickly introduced.  However, the first
serious variant on Version 3 was made in 1984 when a primitive form of
screen-splitting was invented to give `Seastalker' a sonar display.  This
design (perhaps accidentally) became the foundation for the graphics systems
of later versions.

Much later (in 1987) sound effects were added to Version 3 for `The Lurking
Horror', though by that time it was really a Version 5 feature being
passed down to the old model (and only to the Amiga interpreter in any case).
(`TLH' is contemporaneous with `Sherlock' (in Version 5), the only other game
to actually use the sound effects features.)
\medskip

During 1983-5, Infocom poured resources into an ambitious pet project of its
founders: `Cornerstone', a database which used some of the same portable
virtual machine ideas as the Z-machine.  The business market, however, was
not nearly as diverse as the home computer market: `Cornerstone' probably was
the best database available on the Atari ST, but it made no impression on
the IBM PC market.  The result was a commercial failure which compounded the
company's over-expansion problems (driving it into a merger with
Activision), though it certainly did not destroy Infocom's viability.
\medskip

By 1985, Infocom had begun to write interpreters in C for the sake of
portability (previously, a different assembly-language program had to be
maintained for every model of computer).  The main motivation to keep the
format stable was therefore largely removed: it became possible to upgrade
the Z-machine for every new game, if need be.

There were two basic pressures for change.  One was that home computers were
larger, and several fundamental restrictions (the game size being only 128K,
the number of objects only 255, the attributes only 32, the properties only
31) were beginning to bite.  The other was the drive for more gimmicks -
character graphics, flashier status lines, sound effects, different
typefaces, and so on.  The former led to logical, easy to understand
structural changes in the machine (designed by Marc Blank).  The latter, in
contrast, made a mess of the system of opcodes (designed by committee).

More does not mean better (halving the price of paper does not double the
quality of the novel).  The relieving of size restrictions only increased
design time -- or endangered the quality of the designs being produced.  The
Version 3 games have a spare, concise literary style which is absent from
the later games.  (But Inform authors have certainly found Version 3
slightly too small for comfort, and it's useful to be able to spill over its
boundaries.)

In August the first Version 4 game (`A Mind Forever Voyaging') reached
production.  Opinions vary as to whether it was brilliant or awful, but it
was certainly a departure (and could not have been written under Version 3).
In retrospect there is no doubt about `Trinity', now generally considered
the finest game written: it had previously been shelved as too ambitious
for the Version 3 format.  Still, most of the new 1985/6 games remained in
Version 3: there were still plenty of 8-bit home computers around which were
too small for Version 4 games.  Despite critical acclaim, the new games
consequently did not sell as well.  (Brian Moriarty commented that `Trinity'
``sold tolerably well. Better than we'd hoped.''  But his previous game, the
more modest `Wishbringer', had sold rather better.)

Version 5 games began to appear in September 1987 with `Beyond Zork' and
`Border Zone'.  Both of these games needed new features -- character graphics
run wild in the case of the former, and real-time keyboard interaction in
the latter.  The number of opcodes grew ever faster as a result.

Although five old games were re-released in Version 5 editions (with an
in-game hints system added, and benefiting from 9-letter word dictionaries,
but otherwise as written), the direction was all too clearly away from the
old text game into graphics: `Beyond Zork' can look like a parody of an
early mainframe maze game, for instance.  Version 6 completed the process
during something of a hiatus in 1988, after which the last few
increasingly-unrecognisable Infocom games appeared: `Zork Zero', `Shogun',
`Journey' and `Arthur'.

It would be wrong, though, to suggest that Infocom regarded text and
graphics as incompatible opposites.  Infocom had never been puritanically
opposed to graphics --

\quote We have nothing against graphics per se.  However, given the quality of
 graphics currently available on home computers, we would rather use that
 disk space for additional puzzles and richer descriptions.
\quoteby{The New Zork Times (Spring 1984)}

\noindent (and, after all, the same author wrote both `Trinity' and `Beyond
Zork').  Although the old Infocom parser was considered to have passed its
sell-by date, Version 6 did not drop textual input in favour of some inane
point-and-click interface.  Instead, an entirely new parser was devised from
scratch (``using the theory of computational linguistics'', according to a
puff by Stu Galley).

Infocom gradually ceased to exist during 1987-9 as its financial problems
grew.  But its products were increasingly regarded as an anachronism and
most of its staff had left since the middle years: if Infocom had not
finally been wound up, whether it would have continued to release text games
of the classical style is arguable.

\medskip
Two new formats, versions 7 and 8, have recently been devised to cope with
large Inform games.

\section{E}{A few statistics}

\quote
LORD DIMWIT FLATHEAD:  ``It must have two hundred thousand rooms, four
million takeable objects, and understand a vocabulary of every single word
ever spoken in every language ever invented.''
\quoteby{The New Zork Times (Winter 1984)}

To give some idea of the sizes found in typical story files, here are a few
statistics, mostly gathered by Paul David Doherty, whose ``Infocom fact
sheet" file is the definitive reference.

\medskip
(i) {\sl Length}\quad
 The shortest files are those dating from the time of the `Zork'
 trilogy, at about 85K; middle-period Version 3 games are typically 105K,
 and only the latest use the full memory map.  In Versions 4 and 5, only
 `Trinity', `A Mind Forever Voyaging' and `Beyond Zork' use the full 256K.
 `Border Zone' and `Sherlock', for instance, are about 180K.  (The author's
 short story `Balances' is about 50K, an edition of `Adventure' takes 80K,
 and `Curses' takes 256K (it's padded out to the maximum size with
 background information; the actual game comprises only about 245K).  Under
 Inform, the library occupies about 35K regardless of the size of game.)


\medskip
(ii) {\sl Code size}\quad
 `Zork I' uses only about 5500 opcodes, but the number rises
 steeply with later games; `Hollywood Hijinx' has 10355 and, e.g.
 `Moonmist' has 15900 (both these being Version 3).  Against this, `A Mind
 Forever Voyaging' has only 18700, and only `Trinity' and `Beyond Zork'
 reach 32000 or so.  (Inform games are more efficiently compiled and make
 better use of common code -- the library -- so perform much better here:
 the old Version 3, release 10 of `Curses' (128K long, and a larger game
 than any Infocom Version 3 game) has only 6720 opcodes.)

\medskip
(iii) {\sl Objects and rooms}\quad
 This varies greatly with the style of game.
 `Zork I' has 110 rooms and 60 takeable objects, but several quite
 complex games have as few as 30 rooms (the mysteries, or `Hitch-hikers').
 The average for Version 3 games is 69 rooms, 39 takeable objects.

 `A Mind Forever Voyaging' contains many rooms (178) but few objects (30).
 `Trinity', a more typical style of game, contains 134 rooms and 49
 objects: the Version 5 `Curses' has a few more of each.  Of the Version 6
 games, only `Zork Zero' scores highly here, with 215 rooms and 106
 objects.  The average for Version 4/5 games is 105 rooms and 54 objects.

 The total number of objects tends to be close to the limit of 255 in
 Version 3 games.  `Curses' contains 508.


\medskip
(iv) {\sl Dictionary}\quad  Early games such as `Zork I' know about 600 words, but
 again this rises steeply to about 1000 even in Version 3.
 Later games know 1569 (`Beyond Zork') to the record, 2120 (`Trinity').
 (This is achieved by heroic inclusion of unlikely synonyms: e.g. the
 Japanese lady with the umbrella can be called WOMAN, LADY, CRONE,
 MADAM, MADAME, MATRON, DAME or FACE with any of the adjectives
 OLD, AGED, ANCIENT, JAP, JAPANESE, ORIENTAL or YELLOW.)
 Version 6 games have smaller dictionaries.  So has `Curses', at 1364.

\section{F}{Implementing the new Versions 7 and 8}

At present, two ``modern'' formats have been created: Inform 5.5 has the
ability to compile to them, but no such games prior to 1995 exist.

These new versions exist to remove the chief restriction on version-5
games: the total memory map limit of 256K.  (Although V6 removes this
restriction, full interpretation of V6 is much harder than V5 and
the extra complexity is unnecessary for text games.  New formats thus
seem preferable to use of V6, though Inform can produce V6 too.)

Both versions are {\sl identical to V5 except} for the way packed addresses
are decoded.  Let $R_O$ be the routines offset, and $S_O$
the strings offset.  Then the byte address of packed address $P$ is presently
given by:
$$ \cases { 2P & versions 1, 2 and 3\cr
           4P & versions 4 and 5\cr
           4(P+R_O) {\rm~or~} 4(P+S_O) & version 6 routine calls/{\tt print\_paddr}\cr
} $$
and the new versions translate instead by:
$$ \cases { 4(P+R_O) {\rm~or~} 4(P+S_O) & version 7 routine calls/{\tt print\_paddr}\cr
           8P & version 8\cr} $$

The reason for two new formats is that it offers two chances to
extend existing interpreters (one of which may be much less trouble
than the other).  However, the preferred large format is V8, for
which the modification required to the |Zip| interpreter is one
single line:
insert
\beginlines
|    if (h_type == 8) { h_type=V5; story_scaler = 8; story_shift = 3; }|
\endlines
into the |configure()| routine.


\newpage
\pageno=1\titletrue

\centerline{\bigfont The Specification of the Z-Machine}
\vskip 0.3in
\centerline{\medfont and Inform assembly language}
\vskip 0.3in
\centerline{\sl Standard 0.2: 15th November 1995}
\vskip 0.5in

\immediate\closeout\conts
\sli{}{Preface}{2}
\sli{1}{The memory map}{5}
\sli{2}{Numbers and arithmetic}{7}
\sli{3}{How text is encoded and printed}{8}
\sli{4}{How instructions are encoded}{12}
\sli{5}{How routines are encoded}{16}
\sli{6}{The game state: storage and routine calls}{16}
\sli{7}{Output streams and file handling}{19}
\sli{8}{The screen model}{21}
\sli{9}{Sound effects}{28}
\sli{10}{Input streams and devices}{30}
\sli{11}{The format of the header}{33}
\sli{12}{The object table}{35}
\sli{13}{The dictionary and lexical analysis}{37}
\sli{14}{Complete table of opcodes}{38}
\sli{15}{Dictionary of opcodes}{44}
\sli{16}{Font 3 and character graphics}{58}
\sli{A}{Error messages and debugging}{64}
\sli{B}{Conventional contents of the header}{64}
\sli{C}{Resources available}{66}
\sli{D}{A short history of the Z-machine}{68}
\sli{E}{A few statistics}{71}
\sli{F}{Implementing the new Versions 7 and 8}{72}

\bigskip
\noindent This is a consultation document: it will become Standard 1.0
early in the New Year after any further comments, corrections and requests
for clarification have been dealt with.
\end

% -------------------------------------------------------------------------

% Inform test files to cut out and collect:

! -------------------------------------------------------------------------
!  Fonts.inf
! -------------------------------------------------------------------------

[ Main; ShowFonts(); quit; ];
[ ShowFonts x;
 @erase_window -1; @split_window 10;
 FontAt(1,0,0); FontAt(2,1,0); FontAt(3,0,1); FontAt(4,1,1);
 @read_char 1 0 0 x;
];
[ FontAt font bx by i j x y;
 @set_window 1; y=1+5*by; x=2+34*bx;
 @set_cursor y x; print "Font ", font;
 @set_font font j; if (j==0) print " unavailable";
 for (i=32:i<127:i++)
 {   y=i/32+1+5*by; x=i%32+2+34*bx; @set_cursor y x;
     if (j==0) print "."; else @print_char i;
 }
 @set_font 1 j; @set_window 0;
];


! -------------------------------------------------------------------------
!  Accents.inf
! -------------------------------------------------------------------------

[ Main;
 ShowAccents(1);
 ShowAccents(4);
 quit;
];
[ ShowAccents font x;
  @set_font font x;
  if (x==0) print_ret "Font ", font, " unavailable.";
  @erase_window -1;
  print "Accented characters test in font ", font, "^^";
  print "Decimal code:  character     name  plain ASCII equivalent^^";
  print "155:   @@155     a-umlaut  ae^";
  print "156:   @@156     o-unlaut  oe^";
  print "157:   @@157     u-umlaut  ue^";
  print "158:   @@158     A-umlaut  Ae^";
  print "159:   @@159     O-umlaut  Oe^";
  print "160:   @@160     U-umlaut  Ue^";
  print "161:   @@161     sz-ligature  ss^";
  print "162:   @@162     quotation mark  << or ~^";
  print "163:   @@163     quotation mark  >> or ~^";
  print "164:   @@164     e-umlaut  e^";
  print "165:   @@165     i-umlaut  i^";
  print "166:   @@166     y-umlaut  y^";
  print "167:   @@167     E-umlaut  E^";
  print "168:   @@168     I-umlaut  I^";
  print "169:   @@169     a-acute  a^";
  print "170:   @@170     e-acute  e^";
  print "171:   @@171     i-acute  i^";
  print "172:   @@172     o-acute  o^";
  print "173:   @@173     u-acute  u^";
  print "174:   @@174     y-acute  y^";
  print "175:   @@175     A-acute  A^";
  print "176:   @@176     E-acute  E^";
  print "177:   @@177     I-acute  I^";
  print "178:   @@178     O-acute  O^";
  print "179:   @@179     U-acute  U^";
  print "180:   @@180     Y-acute  Y^";
  print "181:   @@181     a-grave  a^";
  print "182:   @@182     e-grave  e^";
  print "183:   @@183     i-grave  i^";
  print "184:   @@184     o-grave  o^";
  print "185:   @@185     u-grave  u^";
  print "186:   @@186     A-grave  A^";
  print "187:   @@187     E-grave  E^";
  print "188:   @@188     I-grave  I^";
  print "189:   @@189     O-grave  O^";
  print "190:   @@190     U-grave  U^";
  print "191:   @@191     a-circumflex  a^";
  print "192:   @@192     e-circumflex  e^";
  print "193:   @@193     i-circumflex  i^";
  print "194:   @@194     o-circumflex  o^";
  print "195:   @@195     u-circumflex  u^";
  print "196:   @@196     A-circumflex  A^";
  print "197:   @@197     E-circumflex  E^";
  print "198:   @@198     I-circumflex  I^";
  print "199:   @@199     O-circumflex  O^";
  print "200:   @@200     U-circumflex  U^";
  print "201:   @@201     a-ring  a^";
  print "202:   @@202     A-ring  A^";
  print "203:   @@203     o-slash  o^";
  print "204:   @@204     O-slash  O^";
  print "205:   @@205     a-tilde  a^";
  print "206:   @@206     n-tilde  n^";
  print "207:   @@207     o-tilde  o^";
  print "208:   @@208     A-tilde  A^";
  print "209:   @@209     N-tilde  N^";
  print "210:   @@210     O-tilde  O^";
  print "211:   @@211     ae-ligature  ae^";
  print "212:   @@212     AE-ligature  AE^";
  print "213:   @@213     c-cedilla  c^";
  print "214:   @@214     C-cedilla  C^";
  print "215:   @@215     Icelandic thorn  th^";
  print "216:   @@216     Icelandic eth  th^";
  print "217:   @@217     Icelandic Thorn  Th^";
  print "218:   @@218     Icelandic Eth  Th^";
  print "219:   @@219     pound symbol  L^";
  print "^Please press SPACE.^";
  @read_char 1 0 0 x;
];


! -------------------------------------------------------------------------
!   Inputcodes.inf
! -------------------------------------------------------------------------

[ Main;
 InputCodes();
 quit;
];
[ InputCodes k;
 print "Keyboard input code testing^";
 print "(Press keys to see how they respond, and press SPACE to finish.)^^";
 for (::)
 {   @read_char 1 0 0 k;
     print k, " ";
     switch(k)
     {   ' ': return;
         10, 13: print "return";
         27: print "escape";
         32 to 126: print "character '", (char) k, "'";
         129: print "cursor up";
         130: print "cursor down";
         131: print "cursor left";
         132: print "cursor right";
         133 to 144: print "function key f", k-132;
         145 to 154: print "keypad ", k-144;
         155 to 251: print "accented character '", (char) k, "'";
         252: print "menu click";
         253: print "mouse double-click";
         254: print "mouse click (single or double)";
         default: print "error: code ", k, " should not have been returned";
     }
     new_line;
 }
];


! -------------------------------------------------------------------------
!   Colours.inf
! -------------------------------------------------------------------------

[ Main;
 Colours();
 @quit;
];
[ Colours fg bg;
 print "Colour display testing^";
 if ((1->0)&1 == 0) "Fine: the interpreter says colours are unavailable.";
 print "The interpreter says colours are available.  Let's see...^^";
 for (fg=2:fg<10:fg++)
 {   for (bg=2:bg<10:bg++)
     {   if (fg ~= bg)
         {   @set_colour fg bg;
             print (colourname) fg, " on ", (colourname) bg;
             @set_colour 1 1; new_line;
         }
     }
 }
 new_line;
 for (fg=2:fg<10:fg++)
 {   for (bg=2:bg<10:bg++) { @set_colour fg bg; print "#"; }
     @set_colour 1 1; new_line;
 }
 print "^(Default colours.) Press SPACE to clear.^";
 @read_char 1 0 0 fg;
];
[ Colourname x;
 switch(x)
 {   2: print "black";
     3: print "red";
     4: print "green";
     5: print "yellow";
     6: print "blue";
     7: print "magenta";
     8: print "cyan";
     9: print "white";
 }
];


! -------------------------------------------------------------------------
!   Header.inf
! -------------------------------------------------------------------------

[ Main;
 Header();
 @quit;
];
[ Header flag x y f;
 print "Interpreter declarations:^^";
 flag=1->0;

 print "(In Flags 1...)^";

 #IFV3;
      print "Status line unavailable?", (status) flag&16;
      print "Screen splitting available?", (status) flag&32;
      print "Default font has variable pitch?", (status) flag&64;
 #IFNOT;
      print "Colours available?", (status) flag&1;
      print "Boldface available?", (status) flag&4;
      print "Italic available?", (status) flag&8;
      print "Fixed-pitch font available?", (status) flag&16;
      print "Timed keyboard input available?", (status) flag&128;
 #ENDIF;

 #IFV5;
 print "^(In Flags 2.  The following four questions have meaningful \
        answers only if bits 3, 4, 5 and 7 of Flags 2 were set in \
        advance: to do this, alter the game file by setting byte 16 \
        to 184 and then run it again.)^";
 flag=$10->1;
      print "Pictures available?", (status) flag&8;
      print "UNDO available?", (status) flag&16;
      print "Mouse available?", (status) flag&32;
      print "Sound effects available?", (status) flag&128;
 #ENDIF;

 #IFV5;
 print "^Interpreter (machine) number ", $1e->0,
       " version ", (char) $1f->0, "^";

 print "^Screen height: ";
 x = $20->0; if (x==255) print "infinite^"; else print x, " lines^";

 print "Screen width: ";
 x = $21->0; print x, " fixed-pitch font characters^";

 print "Screen height in units: ", $24-->0, "^";
 print "Screen width in units: ", $22-->0, "^";

 print "Font height in units: ", $26->0, "^";
 print "Font width (of a '0') in units: ", $27->0, "^^";

 if ((1->0)&1 ~= 0)
 {   print "Default background colour: ", (colourname) $2c->0, "^";
     print "Default foreground colour: ", (colourname) $2d->0, "^^";
 }

 for (f=1:f<5:f++)
 {   @set_font f x;
     @set_font 1 y;
     print "Font ", f, " available?", (status) x;
 }
 #ENDIF;

 x=$32-->0;
 print "^Standard specification claimed by the interpreter: ",
       x/256, ".", x%256, "^";

 #IFV5;
 print "^^(Press SPACE to clear.)^";
 @read_char 1 0 0 x;
 #ENDIF;
];
[ Status f;
 if (f==0) "  no"; "  yes";
];
[ Colourname x;
 switch(x)
 {   2: print "black";
     3: print "red";
     4: print "green";
     5: print "yellow";
     6: print "blue";
     7: print "magenta";
     8: print "cyan";
     9: print "white";
 }
];


! -------------------------------------------------------------------------
!   Timedinput.inf
! -------------------------------------------------------------------------

[ Main;
  Timings();
  @quit;
];
Global counter;
[ Timings x;
  print "Testing timed input^^";
  print "If you press no keys, five messages should appear, one second \
         apart.  If you do press a key, the test should finish at once.^^";
  counter=0;
  @read_char 1 10 #r$Interrupt x;
  print "^Test complete.^^";
  print "Now the same test for 1/10th of a second (though probably not all \
         interpreters will be fast enough to make the interval quite that \
         brief).^^";
  counter=0;
  @read_char 1 1 #r$Interrupt x;
  print "^Test complete.^^";
  print "^Please press SPACE.^";
  @read_char 1 0 0 x;
];
[ Interrupt;
  print "  message number ", ++counter, "^";
  if (counter<5) rfalse; rtrue;
];

% -------------------------------------------------------------------------
%  End of specification file
% -------------------------------------------------------------------------