~ubuntu-branches/ubuntu/vivid/inform/vivid

« back to all changes in this revision

Viewing changes to html/section33.html

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2008-05-26 22:09:44 UTC
  • mfrom: (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526220944-ba7phz0d1k4vo7wx
Tags: 6.31.1+dfsg-1
* Remove a considerable number of files from the package
  due to unacceptable licensing terms.
* Repair library symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<HTML><HEAD><TITLE>Section 33: Descending into assembly language</TITLE></HEAD>
2
 
<BODY BGCOLOR="#FFFFFF">
3
 
<TABLE></SMALL>
4
 
<TR><TD><TD><P>
5
 
<TR><TD Valign="top"><A HREF="contents.html">Contents</A><BR><A HREF="section32.html">Back</A><BR><A HREF="chapterA.html">Forward</A><TD bgcolor="#F5DEB3"><BLOCKQUOTE><H3>33. Descending into assembly language</H3></BLOCKQUOTE><TR><TD><TD>
6
 
<P>
7
 
 
8
 
<P><TR><TD Valign="top"><IMG SRC="icons/dddbend.gif" ALT="/\/\/\"><TD bgcolor="#EEEEEE"><SMALL> Some dirty tricks require bypassing all of Inform's higher levels
9
 
to program the Z-machine directly with assembly language.  There is an
10
 
element of danger in this, in that some combinations of unusual opcodes
11
 
might look ugly on some incomplete or wrongly-written interpreters:
12
 
so if you're doing anything complicated, test it as widely as possible.
13
 
</SMALL>
14
 
<TR><TD><TD><P>
15
 
 
16
 
<P><TR><TD><TD bgcolor="#EEEEEE"><SMALL>
17
 
The best-researched and most reliable interpreters available by far are Mark
18
 
Howell's Zip and Stefan Jokisch's Frotz: they are also faster than their
19
 
only serious rival, the InfoTaskForce, a historically important work which
20
 
is fairly thorough (and should give little trouble in practice) but which was
21
 
written when the format was a little less well understood.  In some ports,
22
 
ITF gets rarer screen effects wrong, and it lacks an "undo'' feature, so the
23
 
Inform "undo'' verb won't work under ITF.
24
 
(The other two publically-available interpreters are pinfocom and zterp,
25
 
but these are unable to run Advanced games.  In the last resort, sometimes it's
26
 
possible to use one of Infocom's own supplied interpreters with a different game
27
 
from that it came with; but only sometimes, as they may have inconvenient
28
 
filenames 'wired into them'.)
29
 
<P>
30
 
 
31
 
Interpreters conforming to the Z-Machine Standard, usually but not always
32
 
derived from Frotz or Zip, are reliable and widely available.
33
 
But remember that one source of unportability is inevitable.
34
 
Your game may be running on a screen which is anything from a
35
 
64 characters by 9 pocket organiser LCD display, up to a 132 by 48 window
36
 
on a 21-inch monitor.
37
 
<P>
38
 
 
39
 
Anyone wanting to really push the outer limits (say, by implementing
40
 
Space Invaders or NetHack) will need to refer to <I> The Z-Machine
41
 
Standards Document</I>.  This is much more detailed (the
42
 
definition of <TT>aread</TT> alone runs for two pages) and covers the whole range
43
 
of assembly language.  However, this section does document all those features
44
 
which can't be better obtained with higher-level code.
45
 
<P>
46
 
 
47
 
Lines of assembly language must begin with an <TT>@</TT> character and then the
48
 
name of the "opcode'' (i.e., assembly language statement).  A number of
49
 
arguments, or "operands'' follow (how many depends on the opcode): these
50
 
may be any Inform constants, local or global variables or the stack pointer <TT>sp</TT>,
51
 
but may not be compound expressions.  <TT>sp</TT> does not behave like a variable:
52
 
writing a value to it pushes that value onto the stack, whereas reading
53
 
the value of it (for instance, by giving it as an operand) pulls the top
54
 
value off the stack.  Don't use <TT>sp</TT> unless you have to.  After the operands,
55
 
some opcodes require a variable (or <TT>sp</TT>) to write a result into.
56
 
The opcodes documented in this section are as follows:
57
 
<PRE>
58
 
@split_window    lines
59
 
@set_window      window
60
 
@set_cursor      line column
61
 
@buffer_mode     flag
62
 
@erase_window    window
63
 
@set_colour      foreground background
64
 
@aread           text parse time function &#60;result&#62;
65
 
@read_char       1 time function &#60;result&#62;
66
 
@tokenise        text parse dictionary
67
 
@encode_text     ascii-text length from coded-text
68
 
@output_stream   number table
69
 
@input_stream    number
70
 
@catch           &#60;result&#62;
71
 
@throw           value stack-frame
72
 
@save            buffer length filename &#60;result&#62;
73
 
@restore         buffer length filename &#60;result&#62;
74
 
</PRE>
75
 
<P>
76
 
 
77
 
 
78
 
<PRE>
79
 
@split_window    lines
80
 
</PRE>
81
 
 
82
 
Splits off an upper-level window of the given number of lines
83
 
in height from the main screen.  This upper window usually holds the
84
 
status line and can be resized at any time: nothing visible happens
85
 
until the window is printed to.  Warning: make the upper window
86
 
tall enough to include all the lines you want to write to it, as it
87
 
should not be allowed to scroll.
88
 
<PRE>
89
 
@set_window      window
90
 
</PRE>
91
 
 
92
 
The text part of the screen (the lower window) is "window 0'',
93
 
the status line (the upper one) is window 1; this opcode selects
94
 
which one text is to be printed into.  Each window has a "cursor
95
 
position'' at which text is being printed, though it can only
96
 
be set for the upper window.  Printing on the upper window
97
 
overlies printing on the lower, is always done in a fixed-pitch font
98
 
and does not appear in a printed transcript of the game.
99
 
Note that before printing to the upper window, it is wise
100
 
to use <TT>@buffer_mode</TT> to turn off word-breaking.
101
 
<PRE>
102
 
@set_cursor      line column
103
 
</PRE>
104
 
 
105
 
Places the cursor inside the upper window,
106
 
where $(1,1)$ is the top left character.
107
 
<PRE>
108
 
@buffer_mode     flag
109
 
</PRE>
110
 
 
111
 
 
112
 
This turns on (<TT>flag=1</TT>) or off (<TT>flag=0</TT>) word-breaking for the
113
 
current window (that is, the practice of printing new-lines only
114
 
at the ends of words, so that text is neatly formatted).  It is
115
 
wise to turn off word-breaking while printing to the upper window.
116
 
<PRE>
117
 
@erase_window    window
118
 
</PRE>
119
 
 
120
 
This opcode is unfortunately incorrectly implemented
121
 
on some interpreters and so it can't safely be used to erase
122
 
individual windows.  However, it can be used with <TT>window=-1</TT>,
123
 
and then clears the entire screen.  Don't do this in
124
 
reverse video mode, as a bad interpreter may (incorrectly) wipe the
125
 
entire screen in reversed colours.
126
 
<PRE>
127
 
@set_colour      foreground background
128
 
</PRE>
129
 
 
130
 
If coloured text is available, set text to be
131
 
foreground-against-background.  The colour numbers are borrowed
132
 
from the IBM PC:
133
 
<PRE>
134
 
2 = black,  3 = red,      4 = green,  5 = yellow,
135
 
6 = blue,   7 = magenta,  8 = cyan,   9 = white
136
 
0 = the current setting,  1 = the default.
137
 
</PRE>
138
 
 
139
 
On many machines coloured text is not available: the opcode will
140
 
then do nothing.
141
 
<PRE>
142
 
@aread           text parse time function &#60;result&#62;
143
 
</PRE>
144
 
 
145
 
The keyboard can be read in remarkably flexible ways.  This opcode
146
 
reads a line of text from the keyboard, writing it into the <TT>text</TT>
147
 
string array and 'tokenising' it into a word stream, with
148
 
details stored in the <TT>parse</TT> string array (unless this is zero,
149
 
in which case no tokenisation happens).  (See the end of <A HREF="section27.html">Section 27</A> for
150
 
the format of <TT>text</TT> and <TT>parse</TT>.)
151
 
While it is doing this, it calls <TT>function(time)</TT>
152
 
every <TT>time</TT> tenths of a second while the user is thinking:
153
 
the process ends if ever this function returns true.
154
 
<TT>&#60;result&#62;</TT> is to be a variable, but the value
155
 
written in it is only meaningful if you're using a "terminating
156
 
characters table''.  Thus (by <TT>Replace</TT>ing the <TT>Keyboard</TT>
157
 
routine in the library files) you could, say, move around all the characters every
158
 
ten seconds of real time.
159
 
Warning: not every interpreter supports this real-time feature, and
160
 
most of those that do count in seconds instead of tenths of seconds.
161
 
<P>
162
 
 
163
 
 
164
 
<PRE>
165
 
@read_char       1 time function &#60;result&#62;
166
 
</PRE>
167
 
 
168
 
results in the ASCII value of a single keypress.  Once again, the <TT>function</TT> is
169
 
called every <TT>time</TT> tenths of a second and may stop this process early.
170
 
Function keys return
171
 
special values from 129 onwards, in the order: cursor up, down, left, right,
172
 
function key f1, ..., f12, keypad digit 0, ..., 9.
173
 
The first operand must be 1 (used by Infocom as a device number to identify
174
 
the keyboard).
175
 
<PRE>
176
 
@tokenise        text parse dictionary
177
 
</PRE>
178
 
 
179
 
This takes the text in the <TT>text</TT> buffer (in the format produced by <TT>aread</TT>)
180
 
and tokenises it (i.e. breaks it up into words, finds their addresses in the
181
 
dictionary) into the <TT>parse</TT> buffer in the usual way but using the given
182
 
<TT>dictionary</TT> instead of the game's usual one.  (See the <I> Z-Machine Standards
183
 
Document</I> for the dictionary format.)
184
 
<PRE>
185
 
@encode_text     ascii-text length from coded-text
186
 
</PRE>
187
 
 
188
 
Translates an ASCII word to the internal (Z-encoded) text format
189
 
suitable for use in a <TT>@tokenise</TT> dictionary.  The text begins at
190
 
<TT>from</TT> in the <TT>ascii-text</TT> and is <TT>length</TT> characters long, which
191
 
should contain the right length value (though in fact the interpreter
192
 
translates the word as far as a 0 terminator).  The result is 6 bytes
193
 
long and usually represents between 1 and 9 letters.
194
 
<PRE>
195
 
@output_stream   number table
196
 
</PRE>
197
 
 
198
 
Text can be output to a variety of different 'streams',
199
 
possibly simultaneously.  If <TT>number</TT> is 0 this does nothing.
200
 
$+n$ switches stream <I>n</I> on, $-n$ switches it off.
201
 
The output streams are: 1 (the screen),
202
 
2 (the game transcript), 3 (memory) and 4 (script of
203
 
player's commands).  The <TT>table</TT> can be omitted except for stream
204
 
3, when it's a <TT>table</TT> array holding the text printed; printing
205
 
to this stream is never word-broken, whatever the state of
206
 
<TT>@buffer_mode</TT>.
207
 
<PRE>
208
 
@input_stream    number
209
 
</PRE>
210
 
 
211
 
Switches the 'input stream' (the source of the player's commands).
212
 
0 is the keyboard, and 1 a command file (the idea is that a list of
213
 
commands produced by <TT>output_stream 4</TT> can be fed back in again).
214
 
<PRE>
215
 
@catch           &#60;result&#62;
216
 
</PRE>
217
 
 
218
 
The opposite of <TT>throw</TT>, <TT>catch</TT> preserves the "stack frame'' of the
219
 
current routine: meaning, roughly, the current position of which routine
220
 
is being run and which ones have called it so far.
221
 
<PRE>
222
 
@throw           value stack-frame
223
 
</PRE>
224
 
 
225
 
This causes the program to execute a return with <TT>value</TT>,
226
 
but as if it were returning from the routine which was running
227
 
when the <TT>stack-frame</TT> was caught (see <TT>catch</TT>).  Any routines
228
 
which were called in the mean time and haven't returned yet
229
 
(because each one called the next) are forgotten about.
230
 
This is useful to get the program out of large recursive tangles
231
 
in a hurry.
232
 
<PRE>
233
 
@save            buffer length filename &#60;result&#62;
234
 
</PRE>
235
 
 
236
 
Saves the byte array <TT>buffer</TT> (of size <TT>length</TT>) to a file,
237
 
whose (default) name is given in the <TT>filename</TT> (a <TT>string</TT>
238
 
array).  Afterwards, <TT>result</TT> holds 1 on success, 0 on failure.
239
 
<P>
240
 
 
241
 
 
242
 
<PRE>
243
 
@restore          buffer length filename &#60;result&#62;
244
 
</PRE>
245
 
 
246
 
Loads in the byte array <TT>buffer</TT> (of size <TT>length</TT>) from a file,
247
 
whose (default) name is given in the <TT>filename</TT> (a <TT>string</TT>
248
 
array).  Afterwards, <TT>result</TT> holds the number of bytes successfully
249
 
read.
250
 
<P>
251
 
 
252
 
<P><TR><TD Valign="top"><IMG SRC="icons/warning.gif" ALT="!!"><TD><B>WARNING:</B><BR>  
253
 
Some of these features may not work well on obsolete interpreters
254
 
which do not adhere to the Z-Machine Standard.  Standard
255
 
interpreters are widely available, but if seriously worried
256
 
you can test whether your game is running on a good interpreter:
257
 
<PRE>
258
 
    if (standard_interpreter == 0)
259
 
    {   print "This game must be played on an interpreter obeying the
260
 
               Z-Machine Standard.^";
261
 
        @quit;
262
 
    }
263
 
</PRE>
264
 
 
265
 
<P>
266
 
 
267
 
<P><TR><TD Valign="top"><IMG SRC="icons/exercise.gif" ALT="??"><TD bgcolor="#FBB9AC"><A NAME="ex90"><B>EXERCISE 90:</B><BR>(link to <A HREF="answers2/answer90.html">the answer</A>)<TR><TD><TD>  In a role-playing game campaign, you might want several
268
 
scenarios, each implemented as a separate Inform game.  How could
269
 
the character from one be saved and loaded into another?
270
 
 
271
 
 
272
 
<P>
273
 
 
274
 
<P><TR><TD Valign="top"><IMG SRC="icons/dexercise.gif" ALT="??/\"><TD bgcolor="#FBB9AC"><A NAME="ex91"><B>EXERCISE 91:</B><BR>(link to <A HREF="answers2/answer91.html">the answer</A>)<TR><TD><TD>  Design a title page for 'Ruins', displaying
275
 
a more or less apposite quotation and waiting for a key to be
276
 
pressed.
277
 
<P>
278
 
 
279
 
<P><TR><TD Valign="top"><IMG SRC="icons/dexercise.gif" ALT="??/\"><TD bgcolor="#FBB9AC"><A NAME="ex92"><B>EXERCISE 92:</B><BR>(link to <A HREF="answers2/answer92.html">the answer</A>)<TR><TD><TD>  Change the status line so that it has the usual
280
 
score/moves appearance except when a variable <TT>invisible_status</TT>
281
 
is set, when it's invisible.
282
 
 
283
 
<P>
284
 
 
285
 
<P><TR><TD Valign="top"><IMG SRC="icons/dexercise.gif" ALT="??/\"><TD bgcolor="#FBB9AC"><A NAME="ex93"><B>EXERCISE 93:</B><BR>(link to <A HREF="answers2/answer93.html">the answer</A>)<TR><TD><TD>  Alter the 'Advent' example game to display the number
286
 
of treasures found instead of the score and turns on the status
287
 
line.
288
 
<P>
289
 
 
290
 
<P><TR><TD Valign="top"><IMG SRC="icons/dexercise.gif" ALT="??/\"><TD bgcolor="#FBB9AC"><A NAME="ex94"><B>EXERCISE 94:</B><BR>(link to <A HREF="answers2/answer94.html">the answer</A>)<TR><TD><TD>  (From code by Joachim Baumann.)  Put a compass rose
291
 
on the status line, displaying the directions in which the room can be
292
 
left.
293
 
<P>
294
 
 
295
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex95"><B>EXERCISE 95:</B><BR>(link to <A HREF="answers2/answer95.html">the answer</A>)<TR><TD><TD> (Cf.
296
 
 'Trinity'.)
297
 
Make the status line consist only of the name of the current
298
 
location, centred in the top line of the
299
 
screen.
300
 
<P>
301
 
 
302
 
<P><TR><TD Valign="top"><IMG SRC="icons/ddexercise.gif" ALT="??/\/\"><TD bgcolor="#FBB9AC"><A NAME="ex96"><B>EXERCISE 96:</B><BR>(link to <A HREF="answers2/answer96.html">the answer</A>)<TR><TD><TD> Implement an Inform version of the standard 'C'
303
 
routine <TT>printf</TT>, taking the form
304
 
<PRE>
305
 
    printf(format, arg1, ...)
306
 
</PRE>
307
 
 
308
 
to print out the format string but with escape sequences like
309
 
<TT>%d</TT> replaced by the arguments (printed in various ways).  For
310
 
example,
311
 
<PRE>
312
 
    printf("The score is %e out of %e.", score, MAX_SCORE);
313
 
</PRE>
314
 
 
315
 
should print something like "The score is five out of ten.''
316
 
<P>
317
 
 
318
 
<P><TR><TD Valign="top"><IMG SRC="icons/refs.gif" ALT="*"><TD bgcolor="#EEEEEE"><B>REFERENCES:</B><BR><SMALL>  The assembly-language connoisseur will appreciate 'Freefall'
319
 
by Andrew Plotkin and 'Robots' by
320
 
Torbjorn Andersson
321
 
although the present lack of on-line hints make these difficult games
322
 
to win.
323
 
</TABLE>
324
 
<HR><A HREF="contents.html">Contents</A> / <A HREF="section32.html">Back</A> / <A HREF="chapterA.html">Forward</A> <BR>
325
 
<A HREF="chapter1.html">Chapter I</A> / <A HREF="chapter2.html">Chapter II</A> / <A HREF="chapter3.html">Chapter III</A> / <A HREF="chapter4.html">Chapter IV</A> / <A HREF="chapter5.html">Chapter V</A> / <A HREF="chapter6.html">Chapter VI</A> / <A HREF="chapterA.html">Appendix</A><HR><SMALL><I>Mechanically translated to HTML from third edition as revised 16 May 1997. Copyright &#169; Graham Nelson 1993, 1994, 1995, 1996, 1997: all rights reserved.</I></SMALL></BODY></HTML>