4
* Main interpreter loop
10
static int halt = FALSE;
26
zword_t specifier, operand[8];
27
int maxoperands, count, extended, i;
29
interpreter_status = 1;
31
/* Loop until HALT instruction executed */
33
for (interpreter_state = RUN; interpreter_state == RUN && halt == FALSE; ) {
35
/* Load opcode and set operand count */
37
opcode = read_code_byte ();
38
if (h_type > V4 && opcode == 0xbe) {
39
opcode = read_code_byte ();
45
/* Multiple operand instructions */
47
if ((opcode < 0x80 || opcode > 0xc0) || extended == TRUE) {
49
/* Two operand class, load both operands */
51
if (opcode < 0x80 && extended == FALSE) {
52
operand[count++] = load_operand ((opcode & 0x40) ? 2 : 1);
53
operand[count++] = load_operand ((opcode & 0x20) ? 2 : 1);
57
/* Variable operand class, load operand specifier */
60
if (opcode == 0x2c || opcode == 0x3a) { /* Extended CALL instruction */
61
specifier = read_code_word ();
64
specifier = read_code_byte ();
70
for (i = (maxoperands - 1) * 2; i >= 0; i -= 2)
71
if (((specifier >> i) & 0x03) != 3)
72
operand[count++] = load_operand ((specifier >> i) & 0x03);
78
switch ((char) opcode) {
80
/* Extended operand instructions */
82
case 0x00: save (count, operand); break;
83
case 0x01: restore (count, operand); break;
84
case 0x02: shift (operand[0], operand[1]); break;
85
case 0x03: arith_shift (operand[0], operand[1]); break;
86
case 0x04: set_font_attribute (operand[0]); break;
88
case 0x09: undo_save (); break;
89
case 0x0a: undo_restore (); break;
91
default: fatal ("Illegal operation");
94
switch ((char) opcode) {
96
/* Two or multiple operand instructions */
98
case 0x01: compare_je (count, operand); break;
99
case 0x02: compare_jl (operand[0], operand[1]); break;
100
case 0x03: compare_jg (operand[0], operand[1]); break;
101
case 0x04: decrement_check (operand[0], operand[1]); break;
102
case 0x05: increment_check (operand[0], operand[1]); break;
103
case 0x06: compare_parent_object (operand[0], operand[1]); break;
104
case 0x07: test (operand[0], operand[1]); break;
105
case 0x08: or (operand[0], operand[1]); break;
106
case 0x09: and (operand[0], operand[1]); break;
107
case 0x0a: test_attr (operand[0], operand[1]); break;
108
case 0x0b: set_attr (operand[0], operand[1]); break;
109
case 0x0c: clear_attr (operand[0], operand[1]); break;
110
case 0x0d: store_variable (operand[0], operand[1]); break;
111
case 0x0e: insert_object (operand[0], operand[1]); break;
112
case 0x0f: load_word (operand[0], operand[1]); break;
113
case 0x10: load_byte (operand[0], operand[1]); break;
114
case 0x11: load_property (operand[0], operand[1]); break;
115
case 0x12: load_property_address (operand[0], operand[1]); break;
116
case 0x13: load_next_property (operand[0], operand[1]); break;
117
case 0x14: add (operand[0], operand[1]); break;
118
case 0x15: subtract (operand[0], operand[1]); break;
119
case 0x16: multiply (operand[0], operand[1]); break;
120
case 0x17: divide (operand[0], operand[1]); break;
121
case 0x18: remainder (operand[0], operand[1]); break;
122
case 0x19: call (count, operand, FUNCTION); break;
123
case 0x1a: call (count, operand, PROCEDURE); break;
124
case 0x1b: set_colour_attribute (operand[0], operand[1]); break;
125
case 0x1c: unwind (operand[0], operand[1]); break;
127
/* Multiple operand instructions */
129
case 0x20: call (count, operand, FUNCTION); break;
130
case 0x21: store_word (operand[0], operand[1], operand[2]); break;
131
case 0x22: store_byte (operand[0], operand[1], operand[2]); break;
132
case 0x23: store_property (operand[0], operand[1], operand[2]); break;
133
case 0x24: read_line (count, operand); break;
134
case 0x25: print_character (operand[0]); break;
135
case 0x26: print_number (operand[0]); break;
136
case 0x27: ziprandom (operand[0]); break;
137
case 0x28: push_var (operand[0]); break;
138
case 0x29: pop_var (operand[0]); break;
139
case 0x2a: set_status_size (operand[0]); break;
140
case 0x2b: select_window (operand[0]); break;
141
case 0x2c: call (count, operand, FUNCTION); break;
142
case 0x2d: erase_window (operand[0]); break;
143
case 0x2e: erase_line (operand[0]); break;
144
case 0x2f: set_cursor_position (operand[0], operand[1]); break;
146
case 0x31: set_video_attribute (operand[0]); break;
147
case 0x32: set_format_mode (operand[0]); break;
148
case 0x33: set_print_modes (operand[0], operand[1]); break;
149
case 0x34: open_playback (operand[0]); break;
150
case 0x35: sound (count, operand); break;
151
case 0x36: read_character (count, operand); break;
152
case 0x37: scan_data (count, operand); break;
153
case 0x38: not (operand[0]); break;
154
case 0x39: call (count, operand, PROCEDURE); break;
155
case 0x3a: call (count, operand, PROCEDURE); break;
156
case 0x3b: tokenise (count, operand); break;
157
case 0x3c: encode (operand[0], operand[1], operand[2], operand[3]); break;
158
case 0x3d: move_data (operand[0], operand[1], operand[2]); break;
159
case 0x3e: print_window (count, operand); break;
160
case 0x3f: check_argument (operand[0]); break;
162
default: fatal ("Illegal operation");
166
/* Single operand class, load operand and execute instruction */
169
operand[0] = load_operand ((opcode >> 4) & 0x03);
170
switch ((char) opcode & 0x0f) {
171
case 0x00: compare_zero (operand[0]); break;
172
case 0x01: load_next_object (operand[0]); break;
173
case 0x02: load_child_object (operand[0]); break;
174
case 0x03: load_parent_object (operand[0]); break;
175
case 0x04: load_property_length (operand[0]); break;
176
case 0x05: increment (operand[0]); break;
177
case 0x06: decrement (operand[0]); break;
178
case 0x07: print_offset (operand[0]); break;
179
case 0x08: call (1, operand, FUNCTION); break;
180
case 0x09: remove_object (operand[0]); break;
181
case 0x0a: print_object (operand[0]); break;
182
case 0x0b: ret (operand[0]); break;
183
case 0x0c: jump (operand[0]); break;
184
case 0x0d: print_address (operand[0]); break;
185
case 0x0e: load (operand[0]); break;
188
call (1, operand, PROCEDURE);
195
/* Zero operand class, execute instruction */
197
switch ((char) opcode & 0x0f) {
198
case 0x00: ret (TRUE); break;
199
case 0x01: ret (FALSE); break;
200
case 0x02: print_literal (); break;
201
case 0x03: println_return (); break;
203
case 0x05: save (count, operand); break;
204
case 0x06: restore (count, operand); break;
205
case 0x07: restart (); break;
206
case 0x08: ret (stack[sp++]); break;
207
case 0x09: get_fp (); break;
208
case 0x0a: halt = TRUE; break;
209
case 0x0b: new_line (); break;
210
case 0x0c: display_status_line (); break;
211
case 0x0d: verify (); break;
213
case 0x0f: conditional_jump (TRUE); break;
215
default: fatal ("Illegal operation");
221
return (interpreter_status);