-----------------------------------------------------------------------------
      Informal Z-machine newsletter #1                    10th December 1995
                                               (circulated by Graham Nelson)
-----------------------------------------------------------------------------

I'm trying to email this to everyone I know of who's working on or
interested in the Z-machine: however boring this "news" may be, at least it
isn't a secret, so I'm also posting a note to rec.arts.int-fiction and
uploading this text to ftp.gmd.de.  (Please would anybody who would like to
join the circulation list, or get off it again, email me.)  I hope this
addresses the concern expressed on r.a.i-f that a private mailing list,
as proposed by Marnix Klooster, might exclude people who use Inform and want
to keep an eye on what's going on.

It's likely to appear irregularly and vary in length, turning up as and when
there's anything to say.  I certainly plan another issue before standard 1.0
is published, so that 1.0 doesn't come as a nasty surprise to anyone.

I feel it would be helpful for us to keep in touch more than we're doing at
the moment.  It would be especially good to hear of current projects under
way and of progress with the various interpreters and ports; perhaps the
circulation list below might become a directory of who's working on what.

Contents: Miscellaneous news; mistakes in standard 0.2; use of read_char
 return values in Infocom story files; producing accented characters in
 Inform; the Inform linker; circulation list.

                         Miscellaneous news
                         ==================

Progress on the interpreter front has been rapid.  Kevin Bracey's Archimedes
interpreter ("Zip2000", a derivative of Zip) is playing V6 games reasonably
well, and Stefan Jokisch's "Frotz" (with a new interpreter core) is already
up to V5 in implementing standard 0.2.  (An MS-DOS release of this state is
planned.)  Bryan Scattergood's hugely enhanced ITF interpreter (for the
Psion and Archimedes) has been souped up to V8 to play "Jigsaw".

Stefan Jokisch has produced a draft list of "all known bugs in Zip", which
can be found at ftp.gmd.de.

People are actually using the accented characters in standard 0.2.  In
particular, Profesor Jose Luis Diaz de Arriba ([email protected])
from Asturias, Spain, is trying to write an Inform game in Spanish (which
involves interesting exercise in parsing, actually, as pronouns like "it"
are simply glued onto the end of words: e.g. "cogela" means "take it",
"coge" meaning "take").  He particularly asks if JZIP produces accents
according to the standard?

Small triumph for text-only games: there's somebody working through "Jigsaw"
who is both blind and deaf, and playing by braille.

The FAQ for rec.arts.int-fiction is keen to include a brief section on the
current state of the Z-machine interpreters generally available.  Please
contact Jools Arnold at the email address below (not at his personal email
address).


                       Mistakes in Standard 0.2
                       ========================

This note summarises the corrections to the current Z-machine standard which
have been pointed out so far: they're provisional and not yet acted upon.
It would be very helpful if you could spare a moment to see if (a) you
agree, (b) you think I've missed anything!

The next proper release of the standard will, I hope, at last be 1.0 (some
time in early January), but I'm keen to get as much as possible right before
then.

EXTENSIONS:

1.     New accented characters needed: the ligatures oe and OE (e.g. in French
      word "coeur" or "Oeuvres"); upside-down Spanish exclamation and
      question-marks.  I propose to add the following to the list in 3.4.4:

         Code  name              plain text form
         220:  oe-ligature       oe
         221:  OE-ligature       OE
         222:  upside-down !     !
         223:  upside-down ?     ?

      (Spanish quotation marks can be used <<like so>>, so no new characters
      are needed there.  Profesor de Arriba did ask about ordinal o and a
      (raised and underscored letters) but said they weren't very necessary,
      and since they won't be in many fonts I've left them out.)

2.     I hope to briefly specify the file format for Version 6 graphics files.
      I know too little about this at the moment.  P. Dave D. votes for
      specifying the Amiga files since they're the prettiest.  So we should
      add a brief description of the Amiga format.  If anyone would like
      to write one and send it to me...

3.     Remarks to sections 7 and 10: I remarked that it would be good to
      write time-out information and unusual character terminations to
      command script files, to allow for really thorough testing, but that
      this was "formidably" difficult.  Perhaps it's not so bad.  Stefan J.
      suggests the following style:

          take lamp                        ordinary command
          turn it on.[154]                 command, full stop, then keypad 9
                                           (which might abbreviate for NE)
          look unde[0]                     timed out input
          look under the rock              the same input continuing
          [254][10][6]                     mouse-click at (10,6)

      with accented characters also appearing like [220].  So I propose to
      specify that command script files do encode timeouts and terminating
      characters after all.  Any objections?

COMMENTS:

      It's been suggested that non-breaking space and breaking-hyphen be
      added to the standard output codes.  I'm not really convinced this is
      worth the effort involved: any other views?

      Stefan J. has an interesting conjecture to account for the presence
      of both a new font and a text style for fixed-pitch text (which on the
      face of it is redundant).  He suggests that fixed-pitch style should
      use the ordinary font's letters, but simply pitch them a fixed distance
      apart (I suppose it would have to be an Em-width), as Infocom's V6
      interpreters do; whereas font 4 should genuinely be a Courier-type font.
      I don't want to specify this behaviour, but I suppose it might make a
      nice option on an interpreter.

      I will slightly clarify the definition of "standard" -- somebody asked
      me if standard meant that source code had to be available for users to
      make extensions to (for example) the ASCII set; the answer is "no".
      Providing such a facility in some way (not necessarily by making the
      source available) is only suggested, not required.

      It's been pointed out that Border Zone has a rather strangely striped
      upper window when a hint answer is being displayed.  I think this is a
      "feature" of BZ, though, not the result of a mistake in the standard.

      Infocom's own interpreters are not compliant with 0.2.  Partly this
      is because they obviously miss off recent changes to the Z-machine,
      partly because Inform 5.5 does not get all the header bits correct
      according to a strict reading of the Infocom story file design.
      (For instance, I5.5 doesn't set the "I want to use UNDO" bit, even
      though it does want this; likewise for the "colours" bit in Flags 2.
      This means Infocom's own interpreters won't allow "undo" when playing
      an Inform game, and won't display the Jigsaw jigsaw in colour.)
      Inform 6 will get the header bits right (no, really) but the
      standard is written so as to make Inform 5.5 games playable.


CORRECTIONS:

1.1.4: The maximum size of a V6 file is 512K, not 576K (though only because
      of the "length" field in the header).

1.2.3: The V6 packed address translation formula is disastrously wrong.
      (Inform 5.5 is wrong about this too and generates inaccurate files
      as a result.  Inform 6 will be better!)  The formula should be

      $$ B = \cases { 2P & Versions 1, 2 and 3\cr
                      4P & Versions 4 and 5\cr
                      4P + 8R_O & Versions 6 and 7, for routine calls\cr
                      4P + 8S_O & Versions 6 and 7, for {\tt print\_paddr}\cr
                      8P & Version 8\cr
      } $$

      (rather than 4P+4R_0 and 4P+4S_O respectively for versions 6 and 7).
      (Thus I am also respecifying Version 7 in line with this: I don't
      think this will cause trouble since nobody is actually using V7
      at present anyway.)

3.4.4: The << and >> are the wrong way round.  Code 162 should mean >> and
      code 163 should mean <<.

6.1.3: Insert "and the stack is emptied".  (Properly speaking, the stack isn't
      restored from the initial state of the story file because it doesn't
      live in the story file.)

7.1.2.2.1: Reword this, replacing "Any character 10 codes printed should
      be converted to 13." with "(A game may |print_char| 13 but should never
      |print_char| 10; in any case, it could more sensibly use
      |new_line|.  So there is no need to convert code 10 to 13.)"

7.2.2: Claimed that text buffering in V3-5 was only active on the lower
      window.  This is true in V3 and V5, but not V4.  (As 8.7.2.5, indeed,
      said all along.)

8.1.3.1: Perhaps I am pushing my luck asking for font changes to be possible
      mid-word (Infocom's own games change font at word breaks but not inside
      them): however, I want this feature to make it possible for authors
      to hack up new accented characters or symbols.  So I'm proposing to
      keep this clause.

8.3.1: For "the colour under the mouse arrow", read "the colour under the
      cursor".

8.6.1.1.1, dictionary: In Version 3, you can't turn off text buffering for
      the upper window, as this seems to imply; and selecting the upper
      window automatically clears it (this is the only way of clearing the
      upper window).

8.7.2, 8.8.3.2, dictionary: reading the cursor position cannot be expected
      to produce an accurate answer when there is text buffered up which may
      become a long wrappable word.  What should we do about this?  Should
      we (a) specify that the answer is undefined, or (b) specify that the
      act of reading the cursor position ought to flush any buffered text onto
      the screen and then give the accurate answer?

8.8.3.2, 8.8.3.2.6: Zork Zero's demonstration mode sets the line count to
      -999 to stop [MORE] from ever appearing, which would prevent it from
      timing out and restarting the demo if it feels it has been abandoned
      by a shopper who has passed on.  I propose to specify this as legal,
      which means rewording 8.8.3.2 as well.

8.8.3.2.2.1: insert such a clause to explain when adjusting the margins takes
      effect during a call to a newline interrupt routine.  If such a routine
      alters the left margin, no effect takes place until the succeeding
      line, while altering the right margin takes effect on this line.
      That is, the interpreter does the following on a new-line:

         move to the new line and put the cursor at the current margin;
         call the interrupt routine, if necessary, but take no further action.

8.8.3.3: Window 0 should default to have attributes 2, 3 and 4 on (scrolling,
      copy to printer transcript, buffering).

8.8.4.1: Reword this to remove ambiguity: some people think this means that
      window 1 is fitted into the present window 0, but actually it's meant
      to mean that windows 0 and 1 are tiled onto the whole physical screen.

8.8.5.3.2: To clarify: erase_window -2 clears the entire screen to the current
      background colour (rather than performing an erase_window for all 8
      windows in turn).

Section 9:  This section needs rewording to make clear that bleeps are treated
      differently from other sound effects.  Many games (e.g. Beyond Zork)
      bleep but don't have a sound effects file; and:
          games not setting the sound bit can still bleep;
          bleeps can't be prepared, stopped or finished with;
          bleeps can only be played at one volume;
          bleeps don't need to run as a background task;
          bleeps don't stop other sound effects which are playing in the
              background.

Remarks to section 9: Unfortunately "The Lurking Horror" uses sound_effect
      in slightly more complicated ways, thanks in part to sloppy coding.
      In particular

          sound_effect 4 8
          sound_effect 4095 2 15

      can both occur but both are thought to be bugs.

          sound_effect n 3
          sound_effect 0 3

      are each used to stop the current sound effect (n being its number).
      More unhappily, TLH also assumes that the interpreter is as slow
      as the old Amiga one was: it fires off several sound effects in one
      game round, assuming there will be time for it to play most of each
      while it goes through its machinations.  To simulate this,
      sound_effect must be rewritten to pause sometimes:

          if a new sound effect is begun while there is still one
              playing which was started since the last keyboard input,
          then wait until that earlier one finishes one cycle before
              replacing it with the new sound effect.


10.7:  In the light of the read_char research detailed below, the new
      definition of the input character set is:

      \nsp{7} For input purposes the character set is as follows:
      \orm\beginstt
       0-12      ----
       13        New-line   (ends input of a command)
       14-26     ----
       27        Escape key code
       28-31     ----
       32-126    Standard ASCII           (see 3.4.3)
       127       Delete key code
       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 passed to the game. Note that an
      interpreter should return 13 and not 10 as ``new-line'' (contrary to the
      advice in Standard 0.2).  (10 would work on every known game except
      `Bureaucracy', which would be unplayable; this also requires 127 to be
      typeable.)

11.1:  The header entry for "interpreter version" says that an ASCII
      character is expected (conventionally an upper case letter).  In V6,
      the version code is just a number and has no ASCII significance.

13.6.3: |sread| should be |read| (only a typo).

14.1:  The save opcode had the wrong syntax for Version 4.  Standard 0.2 says
      |       *   0OP:181  5  1  save            <label>|
      |                       5  [illegal]|
      with EXT:256 taking over in V5:
      |   *       EXT:256  0  5  save            table bytes name <result>|
      However, Version 4 uses a cross between the two forms, so the 0OP:181
      entry should read:
      |       *   0OP:181  5  1  save            <label>|
      |                       4  save            <result>|
      |                       5  [illegal]|
      where "result" means what it means in V5.  Likewise, 0OP:182 should read
      |       *   0OP:182  6  1  restore         <label>|
      |                       4  restore         <result>|
      |                       5  [illegal]|

14.1:  The |scan_table| opcode had the incomplete grammar line
      |   *    *  VAR:247 17  4  scan_table      x table len|
      which should read
      |   *    *  VAR:247 17  4  scan_table      x table len form <result>|
      (likewise in the dictionary entry).

14.1:  I'd like to finally add details of which opcodes are used in V6.  My
      present belief is that EXT:261 to EXT:264 and EXT:272 to EXT:284 are
      all used by existing Infocom files (though "print_form" only by Arthur,
      "read_mouse" only by Journey, "make_menu" only by Journey and then only
      if the machine number is 3).  The following, I believe, are never used:

          catch / throw
          nop
          piracy

      Are the following used?

          pull stack <result>
          erase_line pixels
          set_cursor l c w
          get_cursor table
          output_stream n t w (i.e., in its full form)
          not
          art_shift

      I'd be grateful if V6 hackers out there could let me know.

15.3:  The remarks this makes about interpreter error-checking belong in
      Appendix A.

dictionary: |erase_line| should ignore its one operand in versions 4 and 5.
      (The opcode is never used in any V4 or V5 game, we aren't sure what
      the operand was meant to be, and I can't think of anything very useful
      to do with it: so here's the least effort solution.)

dictionary: does anyone know if |get_cursor| should write its data to
      words 1 and 2 of a "table" array where word 0 is the extent of the
      array (presumably 2), or if it writes to words 0 and 1 of the "table"?
      I would guess the former and there may be no evidence either way,
      but any information would be welcomed.

dictionary: |picture_data|: to "Otherwise, if the picture number is zero,
      the interpreter writes the highest legal picture number into the first
      word of the table" add "and the release number of the picture file
      into the second word".  (Zork Zero expects this.)

dictionary: Kevin B. reports that implementing "picture_table" in the way
      suggested in 0.2 as "only a conjecture" seems to work well.  He suggests
      that if one has to decompress pictures and then plot them, then it's
      good enough to cache decompressed images only for pictures listed in
      the last call to picture_table.  (I.e., with other pictures it's
      acceptable to decompress all over again each time they are printed.)
      At any rate, I'm going to remove the "only a conjecture" caveat, as
      experience seems to have confirmed it.

dictionary: the enormous |read| entry needs a short extension to make clear
      where the cursor ends up: a new-line is printed if input was terminated
      by ENTER, whereas the cursor stays at the end of the text entered so far
      if input was terminated by anything else.

dictionary: similarly, to make clear that |read| can take place in any window.

dictionary: the |save| entry missed some of the syntax lines out.  (Typo.)

App A: It's not a trivial issue to check non-existent locals, so I'll reword
      this.

App F: Needs correction in line with 1.2.3.


        Use of read_char return values in Infocom story files
        =====================================================

This note details all uses except: (i) press-any-key-to-continue, and (ii)
press-y-or-n.  With minor variations there is a common "hints" routine to
the Version 5 re-releases and releases; and also in the V4 Nord'n'Bert.

Version 4
=========
Trinity  None.
-------

Bureaucracy
-----------
The form-reading code (200e4):
(i) must have 13 (not 10) for RETURN;
(ii) accepts either ^ (94) or 14 (old ASCII for cursor-up) to go back;
(iii) accepts either 127 or 8 (delete or backspace) as delete.
Otherwise it uses plain ASCII.

A joke at 30095 asks for input apparently normally but accepts only one
character before interrupting the reader.  The input code is echoed to
screen with print_char.

Nord 'n' Bert
-------------
The action routine for "garble" (bff4) reads in a line of text, garbling E
into C and N into P: text can be terminated by a 10 or a 13.

Interestingly, while garbling it seems to think it might get codes with top
bit set (i.e., codes plus $80), which it treats identically.

Hints routine: expects return codes N, n, Q, q, P, p; 10 or 13 for return;
but now top bit set codes are not recognised.

A Mind Forever Voyaging
-----------------------
Is similarly written to possibly expect codes with top bit set; there is a
yes-no routine at 12ad0 and routine 2b6bc (for opening and closing "files")
expects E, C, N, O, P, R, e, c, n, o, p or r.

Version 5
=========
Beyond Zork
-----------
The routine at 11198 reads a character using read_char, converting \ to
"cursor up" (129) and / to "cursor down" (130).  It's used in four places.
In each case, there is a limited set of values which the game will allow
the player to type, and the game will beep and retry if a different value
is given.

(i) At 18a68: legal values 10 or 13 for RETURN, 129 or 130.
(ii) At 18db2: as (i), except that (redundantly) the ASCII / and \
are also recognised as 129 and 130.
(iii) At 18ee6: as (i), except that cursor left and right (131 and 132)
are also legal.
(iv) At 3ae3d: as (i).

The attribute-choosing routine at 3b4cc reads 10 or 13 for return, 32 for
space.

Border Zone
-----------
Hints routine at 35bc, as for Nord'n'Bert above.
The chapter-choosing routine at 21da4 reads for 1, 2, 3, R or r.

Sherlock
--------
Hints routine at ccc0, as for Nord'n'Bert above (except for some quite funny
jokes).
At end of play (11348), a menu for Quit/Restart/Restore/Hints/Undo is
offered: using read_char and expecting only codes 1 to 5.

German Zork I
-------------
Only uses the standard hints routine, but a print_ret has been inserted into
the code to say no hints are available (in English).  (Conjecturally, the
hints had not been translated yet.)

Version 5 re-releases   Seem to use only the standard hints routine.
---------------------

Version 6   Based on a quick survey by Stefan, the V6 games seem to present
=========   no further difficulties: i.e., behave much as the Standard says.

Conclusions:

1. Every Infocom file in V4 and 5 allows 10 or 13 as equivalent codes for
  RETURN, except for Bureaucracy, which only allows 13.  Therefore 13 should
  be the standard.

2. Bureaucracy also needs either 127 or 8 to be "delete".  I propose 127 as
  the standard (since 8 is properly "backspace").

3. Otherwise no existing file needs any other "control characters" in the
  range 1 to 31, so Standard 0.2 is otherwise accurate.


                 Producing accented characters in Inform
                 =======================================

 This note, which I posted to rec.arts.int-fiction a while back, describes
a small patch to Inform allowing accented characters to be conveniently
compiled in text.  It will end up as a feature of Inform 6, but since the
release of I6 is not imminent (see below) here is a standby measure.

 They are produced by an @ string escape.  Most accents are written as
@, followed by an accent marker, then the letter on which the accent appears:

     @^   put a circumflex on the next letter: a,e,i,o,u,A,E,I,O or U
     @'   put an acute on the next letter: a,e,i,o,u,y,A,E,I,O,U or Y
     @`   put a grave on the next letter: a,e,i,o,u,A,E,I,O or U
     @:   put an umlaut on the next letter: a,e,i,o,u,A,E,I,O or U
     @c   put a cedilla on the next letter: c or C
     @~   put a tilde on the next letter: a,n,o,A,N or O
     @\   put a slash on the next letter: o or O
     @o   put a ring on the next letter: a or A

There are then a few others:

     @ss  German sz
     @<<  quote marks
     @>>
     @ae  ligatures
     @AE
     @th, @et, @Th, @Et  Icelandic accents
     @LL  pound sign

For instance,

 print "@AEsop en fran@ccais, mon @'el@`eve: @`a votre sant@'e.";
 print "Na@:ive readers of the New Yorker will re@:elect Mr Clinton.";
 print "K@:arl Gau@ss first proved the Fundamental Theorem of Algebra.";

(This syntax is similar to that used by TeX.)

                    -------------------------------------

 The patch is to zcode.c.  Add the following declaration before the
translate_text routine:

static char *accents =
  ":a:o:u:A:O:Uss<<>>:e:i:y:E:I'a'e'i'o'u'y'A'E'I'O'U'Y`a`e`i`o`u`A`E`I`O`U\
^a^e^i^o^u^A^E^I^O^UoaoA/o/O~a~n~o~A~N~OaeAEcccCthetThEtLL";

(to follow Standard 0.2), or, better,

static char *accents =
  ":a:o:u:A:O:Uss>><<:e:i:y:E:I'a'e'i'o'u'y'A'E'I'O'U'Y`a`e`i`o`u`A`E`I`O`U\
^a^e^i^o^u^A^E^I^O^UoaoA/o/O~a~n~o~A~N~OaeAEcccCthetThEtLLoeOE!!??";

(correcting the <<,>> mistake in 0.2, and adding the new accents proposed
above)

And, after the block

       ...
               if ((value!=-1)&&(value2!=-1))
               {   i++; i++;
                   write_z_char(1); write_z_char(value*10+value2);
               }
           }

in translate_text, append

           else
           {   value=0;
               for (j=0;accents[j]!=0;j=j+2)
               {   if ((accents[j]==text[i+1])&&(accents[j+1]==text[i+2]))
                       value = j/2 + 155;
               }
               if (value==0)
               {   char uac[4];
                   uac[0]='@'; uac[1]=text[i+1]; uac[2]=text[i+2]; uac[3]=0;
                   error_named("Unknown accented character", uac);
               }
               i+=2;
               write_z_char(5); write_z_char(6);
               write_z_char(value/32); write_z_char(value%32);
           }

(Please also increment the Inform version number if you are making this
patch.)

                           The Inform linker
                           =================

Inform 6 is progressing in that its new feature, a linker, is working well
enough for everyday use (though there are still bugs to remove and a few
annoying restrictions).  It works as follows: games compiled -M are compiled
as "modules", which can be embedded into any Inform game using a new "Link"
directive (exactly as if they were source code files being inserted using
"Include").  The format of a "module" file is very similar to that of a
story file.  In the header, though, we have the following differences:

      Byte   Contents

      0      64 + V  (where V is the version number)
      6,7    scaled address of "link data" table
      56,57  the number of objects
      58,59  byte address of object table
      60,61  byte address of properties table
      62,63  scaled address of static strings

(A module can't exceed 64K in length.)  The link data table is a morass of
detail, but the rest could be readable by Txd, Infodump, etc., very easily.


-----------------------------------------------------------------------------
                           Circulation list
                           ================

[email protected]                 Adam Thornton            historian
[email protected]                         Bob Newell    avuncle, PC Informer
[email protected]                             Bryan Scattergood        author of
                                                Psion and Arch ITF-based int
[email protected]                    Torbj|rn Andersson
[email protected]                       David Kinder      interested in V6
[email protected]                    David Rose       maintainer of Zip
[email protected]                 (David Rose)
[email protected]                  (David Rose)
[email protected]                          Andrew Plotkin  author of Freefall
[email protected]                       (Andrew Plotkin)
[email protected]            Bjorn Gustavsson         author of
                                             Scott Adams-to-Inform converter
[email protected]                   Gareth Rees       Inform home page
[email protected]              Mark Howell     author of Zip, Txd
[email protected]                   Paul David Doherty (Dave)    guru,
                                                   collector of story files,
                                                author of Infocom fact sheet
[email protected]                           John Holder         author of JZIP
[email protected]  Stefan Jokisch    author of Frotz,
                                             maintainer of Txd and Infodump,
                                                      author of Zip bug list
[email protected]            Kevin Bracey     author of Zip2000
[email protected]             Marnix Klooster          author of
                                                    another exposition of ZM
[email protected]           Bob Manson       working on V6 Zip
[email protected]                         Matt Ackeret       Apple II hacker
[email protected]                           Martin Frost            working on
                                                    faster Amiga interpreter
[email protected]                        Graham Nelson     author of Inform
[email protected]                      Robert Pelak    Macintosh Informer
[email protected]                  Julian Arnold (Jools)   FAQ-keeper
[email protected]               Sverker Wiberg          TeX hacker
[email protected]                         Ronald Tjoelker         working on
                                                          V6 Mac interpreter
-----------------------------------------------------------------------------