1 /* Nitfol - z-machine interpreter using Glk for output.
2 Copyright (C) 1999 Evin Robertson
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
18 The author can be reached at nitfol@deja.com
22 static void op_nop(void) { ; }
24 static void op_XXX(void)
26 zbyte ins = HIBYTE(oldPC);
27 n_show_error(E_INSTR, "illegal instruction", ins);
32 /* offsets in opcodetable for various types */
33 #define OFFSET_0OP 0x00
34 #define OFFSET_1OP 0x10
35 #define OFFSET_2OP 0x20
36 #define OFFSET_VAR 0x40
37 #define OFFSET_EXT 0x60
38 #define OFFSET_END 0x80
40 typedef void (*op_func)(void);
44 op_func opcodetable[] = {
46 op_rtrue, op_rfalse, op_print, op_print_ret,
47 op_nop, op_save4, op_restore4, op_restart,
48 op_ret_popped, op_catch, op_quit, op_new_line,
49 op_show_status, op_verify, op_XXX, op_piracy,
51 op_jz, op_get_sibling, op_get_child, op_get_parent,
52 op_get_prop_len, op_inc, op_dec, op_print_addr,
53 op_call_s, op_remove_obj, op_print_obj, op_ret,
54 op_jump, op_print_paddr, op_load, op_call_n,
56 op_XXX, op_je, op_jl, op_jg,
57 op_dec_chk, op_inc_chk, op_jin, op_test,
58 op_or, op_and, op_test_attr, op_set_attr,
59 op_clear_attr, op_store, op_insert_obj, op_loadw,
60 op_loadb, op_get_prop, op_get_prop_addr, op_get_next_prop,
61 op_add, op_sub, op_mul, op_div,
62 op_mod, op_call_s, op_call_n, op_set_colour,
63 op_throw, op_XXX, op_XXX, op_XXX,
65 op_call_s, op_storew, op_storeb, op_put_prop,
66 op_aread, op_print_char, op_print_num, op_random,
67 op_push, op_pull, op_split_window, op_set_window,
68 op_call_s, op_erase_window, op_erase_line, op_set_cursor,
69 op_get_cursor, op_set_text_style,op_buffer_mode, op_output_stream,
70 op_input_stream, op_sound_effect, op_read_char, op_scan_table,
71 op_not, op_call_n, op_call_n, op_tokenise,
72 op_encode_text, op_copy_table, op_print_table, op_check_arg_count,
74 op_save5, op_restore5, op_log_shift, op_art_shift,
75 op_set_font, op_draw_picture, op_picture_data, op_erase_picture,
76 op_set_margins, op_save_undo, op_restore_undo, op_print_unicode,
77 op_check_unicode, op_XXX, op_XXX, op_XXX,
78 op_move_window, op_window_size, op_window_style, op_get_wind_prop,
79 op_scroll_window, op_pop_stack, op_read_mouse, op_mouse_window,
80 op_push_stack, op_put_wind_prop, op_print_form, op_make_menu,
81 op_picture_table, op_XXX, op_XXX, op_XXX
86 opcodeinfo opcodelist[] = {
88 { "rtrue", v1, vM, 0, 0, opNONE, 0 },
89 { "rfalse", v1, vM, 0, 0, opNONE, 0 },
90 { "print", v1, vM, 0, 0, opTEXTINLINE, 0 },
91 { "print_ret", v1, vM, 0, 0, opTEXTINLINE, 0 },
92 { "nop", v1, vM, 0, 0, opNONE, 0 },
93 { "save", v4, v4, 0, 0, opSTORES, 0 },
94 { "restore", v4, v4, 0, 0, opSTORES, 0 },
95 { "restart", v1, vM, 0, 0, opNONE, 0 },
96 { "ret_popped", v1, vM, 0, 0, opNONE, 0 },
97 { "catch", v5, vM, 0, 0, opSTORES, 0 },
98 { "quit", v1, vM, 0, 0, opNONE, 0 },
99 { "new_line", v1, vM, 0, 0, opNONE, 0 },
100 { "show_status", v3, v3, 0, 0, opNONE, 0 },
101 { "verify", v3, vM, 0, 0, opBRANCHES, 0 },
102 { "extended", v5, vM, 0, 0, opNONE, 0 },
103 { "piracy", v5, vM, 0, 0, opBRANCHES, 0 },
105 { "jz", v1, vM, 1, 1, opBRANCHES, 0 },
106 { "get_sibling", v1, vM, 1, 1, opSTORES | opBRANCHES, 0 },
107 { "get_child", v1, vM, 1, 1, opSTORES | opBRANCHES, 0 },
108 { "get_parent", v1, vM, 1, 1, opSTORES, 0 },
109 { "get_prop_len", v1, vM, 1, 1, opSTORES, 0 },
110 { "inc", v1, vM, 1, 1, opNONE, 0 },
111 { "dec", v1, vM, 1, 1, opNONE, 0 },
112 { "print_addr", v1, vM, 1, 1, opNONE, 0 },
113 { "call_1s", v4, vM, 1, 1, opSTORES, 0 },
114 { "remove_obj", v1, vM, 1, 1, opNONE, 0 },
115 { "print_obj", v1, vM, 1, 1, opNONE, 0 },
116 { "ret", v1, vM, 1, 1, opNONE, 0 },
117 { "jump", v1, vM, 1, 1, opJUMPS, 0 },
118 { "print_paddr", v1, vM, 1, 1, opNONE, 0 },
119 { "load", v1, vM, 1, 1, opSTORES, 0 },
120 { "call_1n", v5, vM, 1, 1, opNONE, 0 },
122 { "XXX", v1, vM, 0, 8, opNONE, 0 },
123 { "je", v1, vM, 1, 4, opBRANCHES, 0 },
124 { "jl", v1, vM, 2, 2, opBRANCHES, 0 },
125 { "jg", v1, vM, 2, 2, opBRANCHES, 0 },
126 { "dec_chk", v1, vM, 2, 2, opBRANCHES, 0 },
127 { "inc_chk", v1, vM, 2, 2, opBRANCHES, 0 },
128 { "jin", v1, vM, 2, 2, opBRANCHES, 0 },
129 { "test", v1, vM, 2, 2, opBRANCHES, 0 },
130 { "or", v1, vM, 2, 2, opNONE, 0 },
131 { "and", v1, vM, 2, 2, opNONE, 0 },
132 { "test_attr", v1, vM, 2, 2, opBRANCHES, 0 },
133 { "set_attr", v1, vM, 2, 2, opNONE, 0 },
134 { "clear_attr", v1, vM, 2, 2, opNONE, 0 },
135 { "store", v1, vM, 2, 2, opNONE, 0 },
136 { "insert_obj", v1, vM, 2, 2, opNONE, 0 },
137 { "loadw", v1, vM, 2, 2, opSTORES, 0 },
138 { "loadb", v1, vM, 2, 2, opSTORES, 0 },
139 { "get_prop", v1, vM, 2, 2, opSTORES, 0 },
140 { "get_prop_addr", v1, vM, 2, 2, opSTORES, 0 },
141 { "get_next_prop", v1, vM, 2, 2, opSTORES, 0 },
142 { "add", v1, vM, 2, 2, opSTORES, 0 },
143 { "sub", v1, vM, 2, 2, opSTORES, 0 },
144 { "mul", v1, vM, 2, 2, opSTORES, 0 },
145 { "div", v1, vM, 2, 2, opSTORES, 0 },
146 { "mod", v1, vM, 2, 2, opSTORES, 0 },
147 { "call_2s", v4, vM, 2, 2, opSTORES, 0 },
148 { "call_2n", v5, vM, 2, 2, opNONE, 0 },
149 { "set_colour", v5, vM, 2, 2, opNONE, 0 },
150 { "throw", v5, vM, 2, 2, opNONE, 0 },
151 { "XXX", v1, vM, 0, 8, opNONE, 0 },
152 { "XXX", v1, vM, 0, 8, opNONE, 0 },
153 { "XXX", v1, vM, 0, 8, opNONE, 0 },
155 { "call_vs", v1, vM, 1, 4, opSTORES, 0 },
156 { "storew", v1, vM, 3, 3, opNONE, 0 },
157 { "storeb", v1, vM, 3, 3, opNONE, 0 },
158 { "put_prop", v1, vM, 3, 3, opNONE, 0 },
159 { "aread", v5, vM, 0, 4, opSTORES, 0 },
160 { "print_char", v1, vM, 1, 1, opNONE, 0 },
161 { "print_num", v1, vM, 1, 1, opNONE, 0 },
162 { "random", v1, vM, 1, 1, opSTORES, 0 },
163 { "push", v1, vM, 1, 1, opNONE, 0 },
164 { "pull", v1, vM, 1, 1, opNONE, 0 },
165 { "split_window", v3, vM, 1, 1, opNONE, 0 },
166 { "set_window", v3, vM, 1, 1, opNONE, 0 },
167 { "call_vs2", v4, vM, 1, 8, opSTORES, 0 },
168 { "erase_window", v4, vM, 1, 1, opNONE, 0 },
169 { "erase_line", v4, vM, 1, 1, opNONE, 0 },
170 { "set_cursor", v4, vM, 2, 2, opNONE, 0 },
171 { "get_cursor", v4, vM, 1, 1, opNONE, 0 },
172 { "set_text_style", v4, vM, 1, 1, opNONE, 0 },
173 { "buffer_mode", v4, vM, 1, 1, opNONE, 0 },
174 { "output_stream", v5, vM, 1, 2, opNONE, 0 },
175 { "input_stream", v3, vM, 1, 1, opNONE, 0 },
176 { "sound_effect", v3, vM, 4, 4, opNONE, 0 },
177 { "read_char", v4, vM, 1, 3, opSTORES, 0 },
178 { "scan_table", v4, vM, 4, 4, opSTORES | opBRANCHES, 0 },
179 { "not", v5, vM, 1, 1, opSTORES, 0 },
180 { "call_vn", v5, vM, 1, 4, opNONE, 0 },
181 { "call_vn2", v5, vM, 1, 8, opNONE, 0 },
182 { "tokenise", v5, vM, 4, 4, opNONE, 0 },
183 { "encode_text", v5, vM, 4, 4, opNONE, 0 },
184 { "copy_table", v5, vM, 3, 3, opNONE, 0 },
185 { "print_table", v5, vM, 4, 4, opNONE, 0 },
186 { "check_arg_count", v5, vM, 1, 1, opBRANCHES, 0 },
188 { "save", v5, vM, 0, 3, opSTORES, 0 },
189 { "restore", v5, vM, 0, 3, opSTORES, 0 },
190 { "log_shift", v5, vM, 2, 2, opSTORES, 0 },
191 { "art_shift", v5, vM, 2, 2, opSTORES, 0 },
192 { "set_font", v5, vM, 1, 1, opSTORES, 0 },
193 { "draw_picture", v6, vM, 3, 3, opNONE, 0 },
194 { "picture_data", v6, vM, 2, 2, opBRANCHES, 0 },
195 { "erase_picture", v6, vM, 3, 3, opNONE, 0 },
196 { "set_margins", v6, vM, 3, 3, opNONE, 0 },
197 { "save_undo", v5, vM, 0, 0, opSTORES, 0 },
198 { "restore_undo", v5, vM, 0, 0, opSTORES, 0 },
199 { "print_unicode", v5, vM, 1, 1, opNONE, 0 },
200 { "check_unicode", v5, vM, 1, 1, opSTORES, 0 },
201 { "XXX", v1, vM, 0, 8, opNONE, 0 },
202 { "XXX", v1, vM, 0, 8, opNONE, 0 },
203 { "XXX", v1, vM, 0, 8, opNONE, 0 },
204 { "move_window", v6, vM, 3, 3, opNONE, 0 },
205 { "window_size", v6, vM, 3, 3, opNONE, 0 },
206 { "window_style", v6, vM, 2, 3, opNONE, 0 },
207 { "get_wind_prop", v6, vM, 2, 2, opSTORES, 0 },
208 { "scroll_window", v6, vM, 2, 2, opNONE, 0 },
209 { "pop_stack", v6, vM, 1, 2, opNONE, 0 },
210 { "read_mouse", v6, vM, 1, 1, opNONE, 0 },
211 { "mouse_window", v6, vM, 1, 1, opNONE, 0 },
212 { "push_stack", v6, vM, 1, 2, opBRANCHES, 0 },
213 { "put_wind_prop", v6, vM, 3, 3, opNONE, 0 },
214 { "print_form", v6, vM, 1, 1, opNONE, 0 },
215 { "make_menu", v6, vM, 2, 2, opBRANCHES, 0 },
216 { "picture_table", v6, vM, 1, 1, opNONE, 0 },
217 { "XXX", v1, vM, 0, 8, opNONE, 0 },
218 { "XXX", v1, vM, 0, 8, opNONE, 0 },
219 { "XXX", v1, vM, 0, 8, opNONE, 0 },