I thought it would be useful to have a list of all mistakes in the specification of the Z-machine. Any feedback is welcomed. I hope this list helps to finally settle on a standard 1.0. Now that we have two public interpreters running V6 games (Zip2000 and Frotz), most open questions can be answered. Speaking of V6, recent work revealed a number of differences between Amiga and DOS story files and interpreters; these are covered by the following list. We can expect a few more oddities in Macintosh and Apple II files. -- Stefan Jokisch (jokisch@ls7.informatik.uni-dortmund.de) A list of corrections and comments on standard 0.2 -------------------------------------------------- *** Part I: The first newsletter *** >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... It turned out that Amiga graphics are identical to MCGA graphics. It seems sensible to use the *.MG1 files as nobody has analyzed the Amiga format yet. Still no volunteers to specify the *.MG1 format? Besides, some screen filling Amiga pictures (e.g. the game screen in "Zork Zero") have been divided into separate MCGA pictures (e.g. left border, right border and status bar in "Zork Zero"). Interpreters running Amiga story files with MCGA pictures must take care of these differences, i.e. they must substitute several DOS pictures for one Amiga picture. The situation is even worse with DOS story files. Some of them consider the interpreter number before they paint one or several pictures, some of them do not. The easiest way is to use interpreter number 6 (MS-DOS) and to run DOS story files only. Otherwise the interpreter should be prepared for both cases. I still have to take a closer look at the Macintosh files. My first impression is that they resemble the Amiga versions -- except for "Zork Zero" which crashes horribly. >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.) For the sake of simplicity, I suggest to turn off buffering in the upper window like most public Z-code interpreters do. >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. But then it should be marked as an extension (***). >8.3.1: For "the colour under the mouse arrow", read "the colour under the > cursor". The "colour under the cursor" leads to a question. To my knowledge this is a _V6_ feature that is useful to write text on top of pictures like the status bar in "Zork Zero". At the same time pictures use colours beyond the Z-machine colour scheme. In this case it is unclear which value should be stored in the window property "colour". (Frotz uses values greater than 15; Infocom's DOS interpreter uses the value 0 and stores the colour elsewhere.) >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). My fault: split_window, not set_window, erases the upper window in V3. And to repeat myself: One should turn off buffering in the upper window although this is likely to contradict the original specification. >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? V6 hacker's motto: "When in doubt, flush the buffer." >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. This is only true when the interpreter number is 6 (MS-DOS). All other systems should call the interrupt routine _before_ they move the cursor. Presumably, this is a bug in Infocom's DOS interpreter. The DOS version of "Zork Zero" checks the interpreter number before it sets a countdown of either x or x-1. Other versions of "Zork Zero" do not work properly for MS-DOS. The newsletter is also wrong for DOS: Increasing the width of the left margin has immediate effect, whereas decreasing takes effect on the following line. >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. To simplify: Short syntax "sound_effect 1" or "sound_effect 2" is for bleeps, the longer syntax is for samples. >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- ---- In "Bureaucracy" both code 8 and 127 will delete the letter to the left of the cursor. I never understood why this means we have to define code 127 as delete and why we must not define code 8 as backspace. >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 > 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. Yes, print_form is only used by "Arthur." The same game also calls "output_stream n t w". w is always 0. "Journey" uses read_mouse to read the menu selection after a menu click has been reported. Therefor we can say that both make_menu and read_mouse were used only on the Macintosh. catch and throw are used by the V6 parser, I think. "pull stack " is the only way to read values from a user stack, so it is used by the V6 LALR(1) parser. "erase_line pixels" is used (both pixels == 1 and <> 1). "set_cursor l c w" is also used, although w is usually -3. get_cursor table is used. Alternatively, the cursor position is often read through get_wind_prop. not is used exactly once by each V6 file. nop, piracy and art_shift were never used. >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.) Public and original V5 interpreters expect "erase_line 1". It should do nothing in all other cases. V6 behaves as specified. >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. The latter is correct. >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.) It is the "number of pictures" instead of the "highest legal picture number". The DOS version of "Zork Zero" shows the release number on the screen, other versions of "Zork Zero" do not. The Amiga interpreter cannot handle "picture_info 0" properly. *** Part II: The Specification of the Z-machine *** (Corrections not covered by the newsletter.) >\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. Division and remainder-after-division are signed. >\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. Infocom's own interpreters never convert tab to space. >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.) No longer true for Inform 6. >\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. In my opinion the interpreter should also preserve the value of the fixed font bit. We could say that the entire flags 2 registers should be preserved. This is what Infocom's own interpreters do. >\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. Same as above. >\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''.) I withdraw all my earlier attempts to precisely define the process of word wrapping. Maybe we should leave it this way. >\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. Now that I changed my mind, I would like to replace this with the earlier rule: no buffering in the upper window. >\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). The optional operands were introduced in V6. >\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. Is there any chance we could replace "the current font" with "the fixed width font"? This would make life easier. Furthermore, it is |$26| and |$27| for V6, but |$27| and |$26| for V5 ("Journey" vs. "Beyond Zork"). >\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. No Infocom interpreter (public or original) returns 0 when a font is unavailable. We should either drop this clause, mark it as an extension, or warn the reader that only standard interpreters will return the correct value. >\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. This will only work for MS-DOS (interpreter number 6). See the remarks on chapter 16 far below. >\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. In the good old days this limit was only 23 characters. >\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.) The original Amiga V6 interpreter had to work with 16 colours. 14 colours were reserved for pictures, the remaining two were used as text background and foreground. Changing the colours in window 0 actually changed the palette entries, i.e. it had effect on the entire screen. Changing the colours in other windows usually had no effect at all. The one exception is colour -1. This would actually change the colour to the pixel under the cursor (instead of changing the palette entries for text background or foreground). This is probably the most serious hardware dependency in V6. Story files usually check the interpreter number and use the set_colour opcode appropriately. For instance, a game might set the reverse text style when the interpreter number is 2 (Amiga), but it might swap foreground and background colours otherwise. >\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.) Colour -1 is a V6 feature. There is an additional colour for DOS V6 interpreters: 10 = grey Even more colours for Amiga V6 interpreters: 10 = light grey 11 = medium grey 12 = dark grey DOS colour 10 is darker than Amiga colour 10. >\sp{3.2} If the interpreter cannot produce colours, it should clear >bit 0 of `Flags 1' in the header. This flag should not be set in the story file itself, so there is no need to clear it. It might be a better idea to clear bit 6 of flags 2. >\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. V1 to V4 games calculate in character grid positions. V6 games use screen units (which can be character grid positions or pixels or anything in between depending in the font height and width). V5 is unclear: split_window always uses lines, but get_cursor and set_cursor can use either character grid positions or screen units. This is what Infocom's DOS V5 interpreter does: When the graphics bit is clear, the font size is set to 1x1 such that there is no difference between character grid positions and screen units. Otherwise the standard PC text mode is replaced with a graphic mode and the font size is set to 8x8. This is what the games do: Most games use character grid positions. 'Beyond Zork' has the graphic bit set and uses screen units. The German 'Zork 1' does not set the graphic bit, but it contains some half-baked support for screen units. To print at character grid position (x,y) the cursor is placed at (font width * x,font height * y) instead of (font width * (x - 1) + 1,font height * (y - 1) + 1) which would have been the correct formula used by 'Beyond Zork'. A V5 interpreter can do the following: - Always set the font size to 1x1. - Behave like Infocom's DOS V5 interpreter. - Use screen units only if the graphics bit is set; add a fix for "German Zork 1". Zip uses the first, Frotz the last strategy. At the moment I prefer the simpler Zip solution. >\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. Same as above. >\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. It should also select window 0. The screen must be cleared to the background colour of window 0. >\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. Contrary to my earlier remarks, this is correct. Infocom's DOS interpreter does not implement it properly, but still it is correct. >\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|). V6 games often change the line count to force or suppress MORE prompts. >\sp{8.3.2.6} The interpreter may use the line count to see when it >should print ``[MORE]''. Should use it, see above. >\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. Window 0 is not selected. >\sp{8.5.3.1} Erasing window number -1 erases the entire screen >and unsplits windows 0 and 1 (see above). This time window 0 is selected. See above. >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.) Nowadays they are called Ztools. >\sp{1.1} In Version 6, the interpreter should set bit 5 of `Flags 1' >if it can provide sound effects. All V5 and V6 interpreter set this bit, most of which do not support sound. This is not a sound flag. >\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. The game may, but need not finish with any effect. The games usually "finish with" only when the player turns sound off; and Interpreters usually keep only one sample in memory. Question: Does the sample number really matter when the effect is "stop sound" (== 3) or "finish with" (== 4)? >\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. They should be updated whenever a mouse click is reported to the game, I believe. >\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. ...see the |read| opcode. >| 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?| Probably not a sound flag, see above. >| .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| I suggest to mark this "Rst" as well, see above. >| .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| Strangely enough, Macintosh "Zork Zero" does not set this bit. (This is the one story file that crashes Frotz horribly.) This flag also seems to have a slightly different meaning in V5, see the character grid/pixel discussion above. >| .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.)| It would probably not hurt to clear bit 6. >| 26 5 * * Font height in units| >| 27 5 * * Font width in units (defined as width of a '0')| Reverse this order for V5, see above. >\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. Not true. "AMFV" uses "output_stream 2/-2", but expects the interpreter to set and clear the transscription bit. >\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.) V6 games depend heavily on the interpreter number, too. >\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|. Sometimes they are $$11. >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.) See above. >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. See above. >\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. ...see the |read| opcode. >The Infocom games do contain words whose initial >character is not a letter (words such as ``\#record''). This has changed with Inform 6, I think. >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.) This has changed, too. >| * EXT:256 0 5 save table bytes name | >| * EXT:257 1 5 restore table bytes name | The syntax is actually * EXT:256 0 5 save table | * EXT:256 0 6 save table bytes name | * EXT:257 1 5 restore table | * EXT:257 1 6 restore table bytes name | >| * EXT:260 4 5 set_font font window | The parameter window is optional. It was introduced in V6 and it is not used by any existing game. The correct syntax is * EXT:260 4 5 set_font font | * EXT:260 4 6 set_font font window | Now that we have extended the set_font opcode in several ways (font changes in the middle of the word, return 0 when a font is unavailable) it has become difficult to implement this opcode; mostly because it connects the program layer which handles word wrapping with a different layer that handles the screen and its windows. What about dropping the optional parameter altogether? >\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. Out of curiousity: What were these opcodes supposed to do? >\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. Does anybody know what this opcode does in V6? >\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. When size is positive, copy_table behaves like memcpy: the data will be copied properly even if both areas overlap. >\block{div}|2OP:23 17 div a b | > \continue > Unsigned 16-bit division. Division by zero > should halt the interpreter with a suitable error message. Signed division, see above. >\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. "erase_line 1" clears the line in both V5 and V6. Arguments other than 1 should only be used in V6, see above. >\block{get\_prop}|2OP:17 11 get_prop object property | > \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.) Almost every interpreter will react strangely. This should be illegal. >\block{mod}|2OP:24 18 mod a b | > \continue > Remainder after unsigned 16-bit division. Division by zero > should halt the interpreter with a suitable error message. Signed remainder, see above. >\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.) Strange idea to restrict the mouse arrow movements to a window which has zero height by default. But since all V6 games call "mouse_window -1" at the start, this is probably correct. What happens when the window is moved or re-sized? Are mouse coordinates given relative to the top left corner of the screen or the mouse window? Finally, the use of mouse_window in "Arthur" (the only game to call mouse_window with an argument other than -1) makes me think that "erase_window -1" lifts any restrictions, but this is only a vague guess. Does anybody have further information? >\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'.) This should be optional: An interpreter may, but need not load the pictures into a cache. >\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. I do not think this last bit of information is worth telling. To be honest, I am the source of this information. But this was at the time when I argued against code 0 as a legal output code. In general, the behaviour of Infocom's own interpreters shows so many oddities and bugs that it is no use listing them all. >\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. Similar to get_prop, this opcode should not be applied to properties longer than two bytes. >\block{restore}|0OP:182 6 1 restore