-
Notifications
You must be signed in to change notification settings - Fork 4
/
sect15.html
1533 lines (1254 loc) · 62.5 KB
/
sect15.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<title>The Z-Machine Standards Document</title>
<link rel="stylesheet" type="text/css" href="zspec.css">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
<body>
<img class="icon" src="images/icon15.gif" alt="">
<hr>
<h1 id="dict">15. Dictionary of opcodes</h1>
<blockquote>
<p>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.</p>
<p>Philip Vellacott</p>
</blockquote>
<hr>
<p class="dictindex">
<a href="#add">A</a> /
<a href="#buffer_mode">B</a> /
<a href="#call">C</a> /
<a href="#dec">D</a> /
<a href="#encode_text">E</a> /
<a href="#get_child">F</a> /
<a href="#get_child">G</a> /
<a href="#inc">H</a> /
<a href="#inc">I</a> /
<a href="#je">J</a> /
<a href="#load">K</a> /
<a href="#load">L</a> /
<a href="#make_menu">M</a> /
<a href="#new_line">N</a> /
<a href="#or">O</a> /
<a href="#picture_data">P</a> /
<a href="#quit">Q</a> /
<a href="#random">R</a> /
<a href="#save">S</a> /
<a href="#test">T</a> /
<a href="#verify">U</a> /
<a href="#verify">V</a> /
<a href="#window_size">W</a> /
<a href="#window_style">X</a> /
<a href="#window_style">Y</a> /
<a href="#window_style">Z</a>
</p>
<hr>
<h2 id="15.1">15.1</h2>
<p>The dictionary below is alphabetical and includes entries on every
opcode listed in the table in <strong>§</strong> 14, as well as brief
notes on a few opcodes once thought to exist but now disproved.
</p>
<h2 id="15.2">15.2</h2>
<p>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.
</p>
<h2 id="15.3">15.3</h2>
<p>In all cases below where one operand is supposed to be in
a particular range, behaviour is undefined if it is not. For instance
an interpreter complies with the Standard even if it crashes when an
illegal object number (including 0) is given for an object operand.
However, see <strong>§</strong> A for guidelines on detecting and dealing with errors.
</p>
<hr>
<h2 id="add">add</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:20 14 add a b -> (result)</strong></p>
<p>Signed 16-bit addition.</p>
<hr>
<h2 id="and">and</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:9 9 and a b -> (result)</strong></p>
<p>Bitwise AND.</p>
<hr>
<h2 id="aread">aread</h2>
<p>This is the Inform name for the keyboard-reading opcode
under Version 5 and later. (Inform calls the same opcode <strong>sread</strong>
under Versions 3 and 4.) See <strong>read</strong> for the specification.
</p>
<hr>
<h2 id="art_shift">art_shift</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:3 3 5/- art_shift number places -> (result)</strong></p>
<p>Does an arithmetic shift of <strong>number</strong> 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 <strong>log_shift</strong>.)
</p>
<p>The "places" operand must be in the range -15 to +15, otherwise behaviour
is undefined.
</p>
<hr>
<h2 id="buffer_mode">buffer_mode</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:242 12 4 buffer_mode flag</strong></p>
<p>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.
</p>
<p>In Version 6, this opcode is redundant (the "buffering" window
attribute can be set instead). It is used twice in each of Infocom's
Version 6 story files, in the <strong>$verify</strong> routine. <strong>Frotz</strong> responds by
setting the current window's "buffering" attribute, while Infocom's
own interpreters respond by doing nothing. This standard leaves the
result of <strong>buffer_mode</strong> undefined in Version 6.
</p>
<hr>
<h2 id="call">call</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:224 0 1 call routine ...up to 3 args... -> (result)</strong></p>
<p>The only call instruction in Version 3, Inform reads this as
<strong>call_vs</strong> 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.)
</p>
<hr>
<h2 id="call_1n">call_1n</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:143 F 5 call_1n routine</strong></p>
<p>Executes <strong>routine()</strong> and throws away result.</p>
<hr>
<h2 id="call_1s">call_1s</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:136 8 4 call_1s routine -> (result)</strong></p>
<p>Stores <strong>routine()</strong>.</p>
<hr>
<h2 id="call_2n">call_2n</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:26 1A 5 call_2n routine arg1</strong></p>
<p>Executes <strong>routine(arg1)</strong> and throws away result.</p>
<hr>
<h2 id="call_2s">call_2s</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:25 19 4 call_2s routine arg1 -> (result)</strong></p>
<p>Stores <strong>routine(arg1)</strong>.</p>
<hr>
<h2 id="call_vn">call_vn</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:249 19 5 call_vn routine ...up to 3 args...</strong></p>
<p>Like <strong>call</strong>, but throws away result.</p>
<hr>
<h2 id="call_vs">call_vs</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:224 0 4 call_vs routine ...up to 3 args... -> (result)</strong></p>
<p>See <strong>call</strong>.</p>
<hr>
<h2 id="call_vn2">call_vn2</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:250 1A 5 call_vn2 routine ...up to 7 args...</strong></p>
<p>Call with a variable number (from 0 to 7) of arguments, then
throw away the result. This (and <strong>call_vs2</strong>) 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 <strong>$ff</strong>).
</p>
<hr>
<h2 id="call_vs2">call_vs2</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:236 C 4 call_vs2 routine ...up to 7 args... -> (result)</strong></p>
<p>See <strong>call_vn2</strong>.</p>
<hr>
<h2 id="catch">catch</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:185 9 5/6 catch -> (result)</strong></p>
<p>Opposite to <strong>throw</strong> (and occupying the same opcode that <strong>pop</strong>
used in Versions 3 and 4). <strong>catch</strong> returns the current "stack frame".
</p>
<hr>
<h2 id="check_arg_count">check_arg_count</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:255 1F 5 check_arg_count argument-number ?(label)</strong></p>
<p>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 <strong>routine(1)</strong> and <strong>routine(1,0)</strong>, which would otherwise be
impossible to tell apart.)
</p>
<hr>
<h2 id="check_unicode">check_unicode</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:12 C 5/* check_unicode char-number -> (result)</strong></p>
<p>Determines whether or not the interpreter can print, or receive from
the keyboard, the given Unicode character. Bit 0 of the result should
be set if and only if the interpreter can print the character; bit 1
if and only if the interpreter can receive it from the keyboard.
Bits 2 to 15 are undefined.
</p>
<p><strong>***</strong>
This opcode will only be present in interpreters obeying Standard
1.0 or later, so story files should check the standard number of the
interpreter before executing this opcode.
</p>
<hr>
<h2 id="clear_attr">clear_attr</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:12 C clear_attr object attribute</strong></p>
<p>Make <strong>object</strong> not have the attribute numbered <strong>attribute</strong>.</p>
<hr>
<h2 id="clear_flag">"clear_flag"</h2>
<p>A name once used for one of the not-really-present
extended Version 5 opcodes (now removed from the specification).
</p>
<hr>
<h2 id="copy_table">copy_table</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:253 1D 5 copy_table first second size</strong></p>
<p>If <strong>second</strong> is zero, then <strong>size</strong> bytes of <strong>first</strong> are zeroed.</p>
<p>Otherwise <strong>first</strong> is copied into <strong>second</strong>, its length in bytes
being the absolute value of <strong>size</strong> (i.e., <strong>size</strong> if <strong>size</strong> is positive,
<strong>-size</strong> if <strong>size</strong> is negative).
</p>
<p>The tables are allowed to overlap. If <strong>size</strong> is positive, the
interpreter must copy either forwards or backwards so as
to make sure all the original contents of <strong>first</strong> are copied to <strong>second</strong>,
and avoid corrupting data in <strong>first</strong> that has not yet been copied.
If <strong>size</strong> is negative, the interpreter must copy forwards
even if this corrupts <strong>first</strong>. ('Beyond Zork' uses this to fill an
array with spaces.)"
</p>
<p>(Version 0.2 of this document wrongly specified that if <strong>size</strong> is
positive then copying should always run backward. This results in
the player being unable to cross the river near the start of
'Journey', as the game uses <strong>copy_table</strong> to shuffle menu options,
and the menu "Downstream, Upstream, Cross, Return" is changed
to "Return, Return, Return".)
</p>
<hr>
<h2 id="dec">dec</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:134 6 dec (variable)</strong></p>
<p>Decrement variable by 1. This is signed, so 0 decrements to -1.</p>
<hr>
<h2 id="dec_chk">dec_chk</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:4 4 dec_chk (variable) value ?(label)</strong></p>
<p>Decrement variable, and branch if it is now less than the given value.</p>
<hr>
<h2 id="div">div</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:23 17 div a b -> (result)</strong></p>
<p>Signed 16-bit division. Division by zero should halt the interpreter with a suitable error message.</p>
<hr>
<h2 id="draw_picture">draw_picture</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:5 5 6 draw_picture picture-number y x</strong></p>
<p>Displays the picture with the given number. (y,x)
coordinates (of the top left of the picture) are each optional, in that
a value of zero for y or x means the cursor y or x coordinate
in the current window. It is illegal to call this with an invalid
picture number.
</p>
<hr>
<h2 id="encode_text">encode_text</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:252 1C 5 encode_text zscii-text length from coded-text</strong></p>
<p>Translates a ZSCII word to Z-encoded text format
(stored at <strong>coded-text</strong>), as if it were an entry in the dictionary.
The text begins at <strong>from</strong> in the <strong>zscii-text</strong> buffer and is <strong>length</strong>
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.)
</p>
<hr>
<h2 id="erase_line">erase_line</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:238 E 4/6 erase_line value</strong></p>
<p>Versions 4 and 5: if the value is 1, erase from the current
cursor position to the end of its line in the current window.
If the value is anything other than 1, do nothing.
</p>
<p>Version 6: if the value is 1, erase from the current
cursor position to the end of the its line in the current window.
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.
</p>
<hr>
<h2 id="erase_picture">erase_picture</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:7 7 6 erase_picture picture-number y x</strong></p>
<p>Like <strong>draw_picture</strong>, but paints the appropriate region
to the background colour for the given window. It is illegal to call this
with an invalid picture number.
</p>
<hr>
<h2 id="erase_window">erase_window</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:237 D 4 erase_window window</strong></p>
<p>Erases window with given number (to background colour);
or if -1 it unsplits the screen and clears the lot; or if -2 it
clears the screen without unsplitting it. The cursor may move if
the window number given is -1 (see <strong>§</strong> 8 for precise details).
</p>
<hr>
<h2 id="extended">"extended"</h2>
<p>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.
</p>
<hr>
<h2 id="get_child">get_child</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:130 2 get_child object -> (result) ?(label)</strong></p>
<p>Get first object contained in given object, branching if
this exists, i.e. is not <strong>nothing</strong> (i.e., is not 0).
</p>
<hr>
<h2 id="get_cursor">get_cursor</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:240 10 4/6 get_cursor array</strong></p>
<p>Puts the current cursor position (in units) into the given array, such that the y position
is put into word 0 of the array, and the x position into word 1.
(The array is not a table and has no size information in its initial entry.)
</p>
<p>In Version 6, returns the position of the cursor in the current window. In other Versions, returns
the position of the cursor in the upper window, even if the lower window is currently selected.
</p>
<hr>
<h2 id="get_next_prop">get_next_prop</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:19 13 get_next_prop object property -> (result)</strong></p>
<p>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).
</p>
<hr>
<h2 id="get_parent">get_parent</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:131 3 get_parent object -> (result)</strong></p>
<p>Get parent object (note that this has no "branch if
exists" clause).
</p>
<hr>
<h2 id="get_prop">get_prop</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:17 11 get_prop object property -> (result)</strong></p>
<p>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. If it has length 2, the first two bytes
of the property are taken as a word value. It is illegal for the
opcode to be used if the property has length greater than 2, and
the result is unspecified.
</p>
<hr>
<h2 id="get_prop_addr">get_prop_addr</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:18 12 get_prop_addr object property -> (result)</strong></p>
<p>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.
</p>
<hr>
<h2 id="get_prop_len">get_prop_len</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:132 4 get_prop_len property-address -> (result)</strong></p>
<p>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).
</p>
<p>@get_prop_len 0 must return 0. This is required by some Infocom games and
files generated by old versions of Inform.
</p>
<hr>
<h2 id="get_sibling">get_sibling</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:129 1 get_sibling object -> (result) ?(label)</strong></p>
<p>Get next object in tree, branching if this exists, i.e.
is not 0.
</p>
<hr>
<h2 id="get_wind_prop">get_wind_prop</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:19 13 6 get_wind_prop window property-number -> (result)</strong></p>
<p>Reads the given property of the given window (see
<strong>§</strong> 8).
</p>
<hr>
<h2 id="inc">inc</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:133 5 inc (variable)</strong></p>
<p>Increment variable by 1. (This is signed, so -1 increments
to 0.)
</p>
<hr>
<h2 id="inc_chk">inc_chk</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:5 5 inc_chk (variable) value ?(label)</strong></p>
<p>Increment variable, and branch if now greater than value.</p>
<hr>
<h2 id="input_stream">input_stream</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:244 14 3 input_stream number</strong></p>
<p>Selects the current input stream.</p>
<hr>
<h2 id="insert_obj">insert_obj</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:14 E insert_obj object destination</strong></p>
<p>Moves object O to become the first child of the
destination object D. (Thus, after the operation the <strong>child</strong> of D
is O, and the <strong>sibling</strong> of O is whatever was previously the
<strong>child</strong> of D.) All children of O move with it.
(Initially O can be at
any point in the object tree; it may legally have <strong>parent</strong> zero.)
</p>
<hr>
<h2 id="je">je</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:1 1 je a b c d ?(label)</strong></p>
<p>Jump if <strong>a</strong> is equal to any of the subsequent operands. je with just one operand
is not permitted.
</p>
<hr>
<h2 id="jg">jg</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:3 3 jg a b ?(label)</strong></p>
<p>Jump if <strong>a > b</strong> (using a signed 16-bit comparison).</p>
<hr>
<h2 id="jin">jin</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:6 6 jin obj1 obj2 ?(label)</strong></p>
<p>Jump if object <strong>obj1</strong> is a direct child of <strong>obj2</strong>, i.e., if
<strong>parent</strong> of <strong>ob1</strong> is <strong>obj2</strong>.
</p>
<hr>
<h2 id="jl">jl</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:2 2 jl a b ?(label)</strong></p>
<p>Jump if <strong>a < b</strong> (using a signed 16-bit comparison).</p>
<hr>
<h2 id="jump">jump</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:140 C jump ?(label)</strong></p>
<p>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 <strong>Txd</strong> disassembler is
confused by it.</p>
<p>The destination of the jump opcode is:</p>
<pre>Address after instruction + Offset - 2
</pre>
<p>This is analogous to the calculation for branch offsets.</p>
<hr>
<h2 id="jz">jz</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:128 0 jz a ?(label)</strong></p>
<p>Jump if <strong>a = 0</strong>.</p>
<hr>
<h2 id="load">load</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:142 E load (variable) -> (result)</strong></p>
<p>The value of the variable referred to by the operand
is stored in the result. (Inform doesn't use this; see the notes to
<strong>§</strong> 14.)
</p>
<hr>
<h2 id="loadb">loadb</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:16 10 loadb array byte-index -> (result)</strong></p>
<p>Stores <strong>array->byte-index</strong> (i.e., the byte at address
<strong>array+byte-index</strong>, which must lie in static or dynamic memory).
</p>
<hr>
<h2 id="loadw">loadw</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:15 F loadw array word-index -> (result)</strong></p>
<p>Stores <strong>array-->word-index</strong> (i.e., the word at address
<strong>array+2*word-index</strong>, which must lie in static or dynamic memory).
</p>
<hr>
<h2 id="log_shift">log_shift</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:2 2 5 log_shift number places -> (result)</strong></p>
<p>Does a logical shift of <strong>number</strong> by the given number of
<strong>places</strong>, shifting left (i.e. increasing) if <strong>places</strong> is positive, right
if <strong>negative</strong>. In a right shift, the sign is zeroed instead of being
shifted on. (See also <strong>art_shift</strong>.)
</p>
<p>The "places" operand must be in the range -15 to +15, otherwise behaviour
is undefined.
</p>
<hr>
<h2 id="make_menu">make_menu</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:27 1B 6 make_menu number table ?(label)</strong></p>
<p>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
a ZSCII string: the first item being a menu name, subsequent ones the
entries.
</p>
<hr>
<h2 id="mod">mod</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:24 18 mod a b -> (result)</strong></p>
<p>Remainder after signed 16-bit division. Division by zero
should halt the interpreter with a suitable error message.
</p>
<hr>
<h2 id="mouse_window">mouse_window</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:23 17 6 mouse_window window</strong></p>
<p>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.)
</p>
<hr>
<h2 id="move_window">move_window</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:16 10 6 move_window window y x</strong></p>
<p>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.
</p>
<hr>
<h2 id="mul">mul</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:22 16 mul a b -> (result)</strong></p>
<p>Signed 16-bit multiplication.</p>
<hr>
<h2 id="new_line">new_line</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:187 B new_line</strong></p>
<p>Print carriage return.</p>
<hr>
<h2 id="nop">nop</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:180 4 1/- nop</strong></p>
<p>Probably the official "no operation" instruction, which,
appropriately, was never operated (in any of the Infocom datafiles):
it may once have been a breakpoint.
</p>
<hr>
<h2 id="not">not</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:143 F 1/4 not value -> (result)</strong></p>
<p><strong><a href="sect14.html#VAR">VAR</a>:248 18 5/6 not value -> (result)</strong></p>
<p>Bitwise NOT (i.e., all 16 bits reversed). Note that in Versions
3 and 4 this is a 1OP instruction, reasonably since it has 1 operand,
but in later Versions it was moved into the extended set
to make room for <strong>call_1n</strong>.
</p>
<hr>
<h2 id="or">or</h2>
<p><strong><a href="sect14.html#2OP">2OP</a>:8 8 or a b -> (result)</strong></p>
<p>Bitwise OR.</p>
<hr>
<h2 id="output_stream">output_stream</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:243 13 3 output_stream number table</strong></p>
<p><strong> 6 output_stream number table width</strong></p>
<p>If <strong>stream</strong> 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.)
</p>
<p>When stream 3 is selected, a <strong>table</strong> 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 <strong>table+2</strong> onward.
It is not the interpreter's responsibility to worry about the length
of this table being overrun.
</p>
<p>In Version 6, a <strong>width</strong> field may optionally be given: text will then be justified as if
it were in the window with that number (if width is zero or positive) or a box -<strong>width</strong>
pixels wide (if negative). Then the table will contain not ordinary text but formatted text: see
<strong>print_form</strong>.
</p>
<hr>
<h2 id="picture_data">picture_data</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:6 6 6 picture_data picture-number array ?(label)</strong></p>
<p>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 array: the height in word 0,
the width in word 1, in pixels. (This is an array, not a "table"
with initial size information.)
</p>
<p>Otherwise, if the picture number is zero, the interpreter writes the
number of available pictures into word 0 of the array and
the release number of the picture file into word 1, and branches
if any pictures are available. (Infocom's
first Version 6 Amiga interpreter did not handle this case properly,
and early releases of 'Zork Zero' did not use it. The feature may
have been added on the MSDOS release of 'Zork Zero'.)
</p>
<p>Otherwise, nothing happens.</p>
<hr>
<h2 id="picture_table">picture_table</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:28 1C 6 picture_table table</strong></p>
<p>Given a table of picture numbers, the interpreter may if it
wishes load or unpack these pictures from disc into a cache
for convenient rapid plotting later. 'Zork Zero' makes
frequent use of this, for instance for its peggleboard
display. Moreover, it expects rapid plotting only for those
images listed in the last call to <strong>picture_table</strong>. In other words,
any images still in the cache when <strong>picture_table</strong> is called
can safely be thrown away. (The Amiga interpreter 6.14
uses a cache of size 5K and never caches any individual
image larger than 1K.)
</p>
<hr>
<h2 id="piracy">piracy</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:191 F 5/- piracy ?(label)</strong></p>
<p>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.
</p>
<hr>
<h2 id="pop">pop</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:185 9 1 pop</strong></p>
<p>Throws away the top item on the stack. (This was useful to
lose unwanted routine call results in early Versions.)
</p>
<hr>
<h2 id="pop_stack">pop_stack</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:21 15 6 pop_stack items stack</strong></p>
<p>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.
</p>
<hr>
<h2 id="print">print</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:178 2 print <literal-string></strong></p>
<p>Print the quoted (literal) Z-encoded string.</p>
<hr>
<h2 id="print_addr">print_addr</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:135 7 print_addr byte-address-of-string</strong></p>
<p>Print (Z-encoded) string at given byte address,
in dynamic or static memory.
</p>
<hr>
<h2 id="print_char">print_char</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:229 5 print_char output-character-code</strong></p>
<p>Print a ZSCII character. The operand must be a character code
defined in ZSCII for output (see <strong>§</strong> 3). In particular, it must
certainly not be negative or larger than 1023.
</p>
<hr>
<h2 id="print_form">print_form</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:26 1A 6 print_form formatted-table</strong></p>
<p>Prints a formatted table of the kind written to
output stream 3 when formatting is on. This is an elaborated version
of <strong>print_table</strong> 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.
</p>
<hr>
<h2 id="print_num">print_num</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:230 6 print_num value</strong></p>
<p>Print (signed) number in decimal.</p>
<hr>
<h2 id="print_obj">print_obj</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:138 A print_obj object</strong></p>
<p>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.
</p>
<hr>
<h2 id="print_paddr">print_paddr</h2>
<p><strong><a href="sect14.html#1OP">1OP</a>:141 D print_paddr packed-address-of-string</strong></p>
<p>Print the (Z-encoded) string at the given packed
address in high memory.
</p>
<hr>
<h2 id="print_ret">print_ret</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:179 3 print_ret <literal-string></strong></p>
<p>Print the quoted (literal) Z-encoded string, then print
a new-line and then return true (i.e., 1).
</p>
<hr>
<h2 id="print_table">print_table</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:254 1E 5 print_table zscii-text width height skip</strong></p>
<p>Print a rectangle of text on screen spreading right and down from the current cursor position,
of given <strong>width</strong> and <strong>height</strong>, from the table of ZSCII text given.
(Height is optional and defaults to 1.) If a <strong>skip</strong> 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.)
</p>
<p><strong>print_table</strong> must work in both the upper and lower windows in Version 5 games, but in the lower
window a <strong>height</strong> other than 1 is illegal and the result undefined.
</p>
<hr>
<h2 id="print_unicode">print_unicode</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:11 B 5/* print_unicode char-number</strong></p>
<p>Print a Unicode character. See <strong>§</strong> 3.8.5.4 and <strong>§</strong> 7.5 for details.
The given character code must be defined in Unicode.
</p>
<p><strong>***</strong>
This opcode will only be present in interpreters obeying Standard
1.0 or later, so story files should check the standard number of the
interpreter before executing this opcode.
</p>
<hr>
<h2 id="pull">pull</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:233 9 1 pull (variable)</strong></p>
<p><strong> 6 pull stack -> (result)</strong></p>
<p>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.
</p>
<hr>
<h2 id="push">push</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:232 8 push value</strong></p>
<p>Pushes value onto the game stack.</p>
<hr>
<h2 id="push_stack">push_stack</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:24 18 6 push_stack value stack ?(label)</strong></p>
<p>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).
</p>
<hr>
<h2 id="put_prop">put_prop</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:227 3 put_prop object property value</strong></p>
<p>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.)
As with <strong>get_prop</strong> the property length must not be more than 2:
if it is, the behaviour of the opcode is undefined.
</p>
<hr>
<h2 id="put_wind_prop">put_wind_prop</h2>
<p><strong><a href="sect14.html#EXT">EXT</a>:25 19 6 put_wind_prop window property-number value</strong></p>
<p>Writes a window property (see <strong>get_wind_prop</strong>).
This should only be used when there is no direct command (such as
<strong>move_window</strong>) to use instead, as some such operations may have
side-effects.
</p>
<hr>
<h2 id="quit">quit</h2>
<p><strong><a href="sect14.html#0OP">0OP</a>:186 A quit</strong></p>
<p>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.
</p>
<hr>
<h2 id="random">random</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:231 7 random range -> (result)</strong></p>
<p>If <strong>range</strong> is positive, returns a uniformly random number
between 1 and <strong>range</strong>. If <strong>range</strong> is negative, the random number generator
is seeded to that value and the return value is 0. Most interpreters
consider giving 0 as <strong>range</strong> illegal (because they attempt a division
with remainder by the <strong>range</strong>), 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).
</p>
<p>(Some version 3 games, such as 'Enchanter' release 29, had a debugging
verb <strong>#random</strong> such that typing, say, <strong>#random 14</strong> caused a call of
<strong>random</strong> with -14.)
</p>
<hr>
<h2 id="read">read</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:228 4 1 sread text-buffer parse-buffer</strong></p>
<p><strong> 4 sread text-buffer parse-buffer time routine</strong></p>
<p><strong> 5 aread text-buffer parse-buffer time routine -> (result)</strong></p>
<p>(Note that Inform internally names the <strong>read</strong> opcode as <strong>aread</strong>
in Versions 5 and later and <strong>sread</strong> in Versions 3 and 4.)
</p>
<p>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.
</p>
<p>In Versions 1 to 3, the status line is automatically redisplayed first.</p>
<p>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.
</p>
<p>In Versions 1 to 4, byte 0 of the <strong>text-buffer</strong> should initially contain
the maximum number of letters which can be typed (the interpreter should
not accept more than this), plus 1 (for the zero terminator). 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 <strong>string</strong> array of length n in Inform terminology.)
</p>
<p>In Versions 5 and later, byte 0 of the <strong>text-buffer</strong> 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 (reduced to lower case) 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.)
</p>
<p>Moreover, if byte 1 contains a positive value at the start of the
input, then <strong>read</strong> assumes that number of characters are left over from an
interrupted previous input, and writes the new characters after those
already there. Note that the interpreter does not redisplay the
characters left over: the game must do this, although it may choose to
redisplay any or all of the characters in uppercase. This is
unfortunate for any interpreter wanting to give input text a distinctive
appearance on-screen, but 'Beyond Zork', 'Zork Zero' and 'Shogun'
clearly require it. ("Just a tremendous pain in my butt" -- Andrew
Plotkin; "the most unfortunate feature of the Z-machine design"
-- Stefan Jokisch.)
</p>
<p>In Version 4 and later, if the operands <strong>time</strong> and <strong>routine</strong> are
supplied (and non-zero) then the routine call <strong>routine()</strong> is
made every <strong>time/10</strong> 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 <strong>routine</strong> 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. (<strong>Frotz</strong> notices
by looking to see if the cursor position is at the left-hand margin
after the interrupt routine has returned.)
</p>
<p>If input was terminated in the usual way, by the player typing a
carriage return, then a carriage return is printed (so the cursor moves
to the next line). If it was interrupted, the cursor is left at
the rightmost end of the text typed in so far.
</p>
<p>Next, lexical analysis is performed on the text (except that in Versions 5
and later, if <strong>parse-buffer</strong> is zero then this is omitted). Initially,
byte 0 of the <strong>parse-buffer</strong> 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.)
</p>
<p>The interpreter divides the text into words and looks them up in the
dictionary, as described in <strong>§</strong> 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 <strong>text-buffer</strong> of the first letter of
the word.
</p>
<p>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 interpreter must return 13).
A timed-out input returns 0.
</p>
<p>(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*59 = 238 so that 59 is the maximum number
of textual words which can be parsed into a buffer of length 240 bytes. Old
versions of the Inform 5 library commit the same error. Neither mistake
has very serious consequences.)
</p>
<p>(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.)
</p>
<p>Interpreters should display a cursor when waiting for input. See <strong>read_char</strong>.
</p>
<hr>
<h2 id="read_char">read_char</h2>
<p><strong><a href="sect14.html#VAR">VAR</a>:246 16 4 read_char 1 time routine -> (result)</strong></p>