1 /* glulxe.h: Glulxe header file.
2 Designed by Andrew Plotkin <erkyrath@eblong.com>
3 http://eblong.com/zarf/glulx/index.html
9 /* We define our own TRUE and FALSE and NULL, because ANSI
10 is a strange world. */
21 /* You may have to edit the definition of glui16 to make sure it's really a
22 16-bit unsigned integer type, and glsi16 to make sure it's really a
23 16-bit signed integer type. If they're not, horrible things will happen. */
24 typedef unsigned short glui16;
25 typedef signed short glsi16;
27 /* Uncomment this definition to turn on memory-address checking. In
28 this mode, all reads and writes to main memory will be checked to
29 ensure they're in range. This is slower, but prevents malformed
30 game files from crashing the interpreter. */
31 /* #define VERIFY_MEMORY_ACCESS (1) */
33 /* Uncomment this definition to turn on Glulx VM profiling. In this
34 mode, all function calls are timed, and the timing information is
35 written to a data file called "profile-raw". */
36 /* #define VM_PROFILING (1) */
38 /* Some macros to read and write integers to memory, always in big-endian
41 ( (glui32)(((unsigned char *)(ptr))[0] << 24) \
42 | (glui32)(((unsigned char *)(ptr))[1] << 16) \
43 | (glui32)(((unsigned char *)(ptr))[2] << 8) \
44 | (glui32)(((unsigned char *)(ptr))[3]))
46 ( (glui16)(((unsigned char *)(ptr))[0] << 8) \
47 | (glui16)(((unsigned char *)(ptr))[1]))
49 ((unsigned char)(((unsigned char *)(ptr))[0]))
51 #define Write4(ptr, vl) \
52 (((ptr)[0] = (unsigned char)(((glui32)(vl)) >> 24)), \
53 ((ptr)[1] = (unsigned char)(((glui32)(vl)) >> 16)), \
54 ((ptr)[2] = (unsigned char)(((glui32)(vl)) >> 8)), \
55 ((ptr)[3] = (unsigned char)(((glui32)(vl)))))
56 #define Write2(ptr, vl) \
57 (((ptr)[0] = (unsigned char)(((glui32)(vl)) >> 8)), \
58 ((ptr)[1] = (unsigned char)(((glui32)(vl)))))
59 #define Write1(ptr, vl) \
60 (((unsigned char *)(ptr))[0] = (vl))
62 #if VERIFY_MEMORY_ACCESS
63 #define Verify(adr, ln) verify_address(adr, ln)
65 #define Verify(adr, ln) (0)
66 #endif /* VERIFY_MEMORY_ACCESS */
68 #define Mem1(adr) (Verify(adr, 1), Read1(memmap+(adr)))
69 #define Mem2(adr) (Verify(adr, 2), Read2(memmap+(adr)))
70 #define Mem4(adr) (Verify(adr, 4), Read4(memmap+(adr)))
71 #define MemW1(adr, vl) (Verify(adr, 1), Write1(memmap+(adr), (vl)))
72 #define MemW2(adr, vl) (Verify(adr, 2), Write2(memmap+(adr), (vl)))
73 #define MemW4(adr, vl) (Verify(adr, 4), Write4(memmap+(adr), (vl)))
75 /* Macros to access values on the stack. These *must* be used
76 with proper alignment! (That is, Stk4 and StkW4 must take
77 addresses which are multiples of four, etc.) If the alignment
78 rules are not followed, the program will see performance
79 degradation or even crashes, depending on the machine CPU. */
82 (*((unsigned char *)(stack+(adr))))
84 (*((glui16 *)(stack+(adr))))
86 (*((glui32 *)(stack+(adr))))
88 #define StkW1(adr, vl) \
89 (*((unsigned char *)(stack+(adr))) = (unsigned char)(vl))
90 #define StkW2(adr, vl) \
91 (*((glui16 *)(stack+(adr))) = (glui16)(vl))
92 #define StkW4(adr, vl) \
93 (*((glui32 *)(stack+(adr))) = (glui32)(vl))
95 /* Some useful structures. */
98 Represents the list of operands to an instruction being executed.
99 (Yes, it's somewhat misnamed. Sorry.) We assume, for the indefinite
100 moment, that no opcode has more than 8 operands, and no opcode
101 has two "store" operands.
103 typedef struct instruction_struct {
109 Represents the operand structure of an opcode.
111 typedef struct operandlist_struct {
112 int num_ops; /* Number of operands for this opcode */
113 int arg_size; /* Usually 4, but can be 1 or 2 */
114 int *formlist; /* Array of values, either modeform_Load or modeform_Store */
116 #define modeform_Load (1)
117 #define modeform_Store (2)
119 /* Some useful globals */
121 extern strid_t gamefile;
122 extern glui32 gamefile_start, gamefile_len;
123 extern char *init_err, *init_err2;
125 extern unsigned char *memmap;
126 extern unsigned char *stack;
128 extern glui32 ramstart;
129 extern glui32 endgamefile;
130 extern glui32 origendmem;
131 extern glui32 stacksize;
132 extern glui32 startfuncaddr;
133 extern glui32 checksum;
134 extern glui32 stackptr;
135 extern glui32 frameptr;
137 extern glui32 origstringtable;
138 extern glui32 stringtable;
139 extern glui32 valstackbase;
140 extern glui32 localsbase;
141 extern glui32 endmem;
142 extern glui32 protectstart, protectend;
144 extern void (*stream_char_handler)(unsigned char ch);
145 extern void (*stream_unichar_handler)(glui32 ch);
148 extern void fatal_error_handler(char *str, char *arg, int useval, glsi32 val);
149 extern void nonfatal_warning_handler(char *str, char *arg, int useval, glsi32 val);
150 #define fatal_error(s) (fatal_error_handler((s), NULL, FALSE, 0))
151 #define fatal_error_2(s1, s2) (fatal_error_handler((s1), (s2), FALSE, 0))
152 #define fatal_error_i(s, v) (fatal_error_handler((s), NULL, TRUE, (v)))
153 #define nonfatal_warning(s) (nonfatal_warning_handler((s), NULL, FALSE, 0))
154 #define nonfatal_warning_2(s1, s2) (nonfatal_warning_handler((s1), (s2), FALSE, 0))
155 #define nonfatal_warning_i(s, v) (nonfatal_warning_handler((s), NULL, TRUE, (v)))
158 extern int is_gamefile_valid(void);
159 extern int locate_gamefile(int isblorb);
162 extern void setup_vm(void);
163 extern void finalize_vm(void);
164 extern void vm_restart(void);
165 extern glui32 change_memsize(glui32 newlen, int internal);
166 extern glui32 *pop_arguments(glui32 count, glui32 addr);
167 extern void verify_address(glui32 addr, glui32 count);
170 extern void execute_loop(void);
173 extern operandlist_t *fast_operandlist[0x80];
174 extern void init_operands(void);
175 extern operandlist_t *lookup_operandlist(glui32 opcode);
176 extern void parse_operands(instruction_t *inst, operandlist_t *oplist);
177 extern void store_operand(glui32 desttype, glui32 destaddr, glui32 storeval);
178 extern void store_operand_s(glui32 desttype, glui32 destaddr, glui32 storeval);
179 extern void store_operand_b(glui32 desttype, glui32 destaddr, glui32 storeval);
182 extern void enter_function(glui32 addr, glui32 argc, glui32 *argv);
183 extern void leave_function(void);
184 extern void push_callstub(glui32 desttype, glui32 destaddr);
185 extern void pop_callstub(glui32 returnvalue);
186 extern glui32 pop_callstub_string(int *bitnum);
189 extern void stream_num(glsi32 val, int inmiddle, int charnum);
190 extern void stream_string(glui32 addr, int inmiddle, int bitnum);
191 extern glui32 stream_get_table(void);
192 extern void stream_set_table(glui32 addr);
193 extern void stream_get_iosys(glui32 *mode, glui32 *rock);
194 extern void stream_set_iosys(glui32 mode, glui32 rock);
195 extern char *make_temp_string(glui32 addr);
196 extern glui32 *make_temp_ustring(glui32 addr);
197 extern void free_temp_string(char *str);
198 extern void free_temp_ustring(glui32 *str);
201 extern void heap_clear(void);
202 extern int heap_is_active(void);
203 extern glui32 heap_get_start(void);
204 extern glui32 heap_alloc(glui32 len);
205 extern void heap_free(glui32 addr);
206 extern int heap_get_summary(glui32 *valcount, glui32 **summary);
207 extern int heap_apply_summary(glui32 valcount, glui32 *summary);
208 extern void heap_sanity_check(void);
211 extern int init_serial(void);
212 extern glui32 perform_save(strid_t str);
213 extern glui32 perform_restore(strid_t str);
214 extern glui32 perform_saveundo(void);
215 extern glui32 perform_restoreundo(void);
216 extern glui32 perform_verify(void);
219 extern glui32 linear_search(glui32 key, glui32 keysize,
220 glui32 start, glui32 structsize, glui32 numstructs,
221 glui32 keyoffset, glui32 options);
222 extern glui32 binary_search(glui32 key, glui32 keysize,
223 glui32 start, glui32 structsize, glui32 numstructs,
224 glui32 keyoffset, glui32 options);
225 extern glui32 linked_search(glui32 key, glui32 keysize,
226 glui32 start, glui32 keyoffset, glui32 nextoffset,
230 extern void *glulx_malloc(glui32 len);
231 extern void *glulx_realloc(void *ptr, glui32 len);
232 extern void glulx_free(void *ptr);
233 extern void glulx_setrandom(glui32 seed);
234 extern glui32 glulx_random(void);
235 extern void glulx_sort(void *addr, int count, int size,
236 int (*comparefunc)(void *p1, void *p2));
239 extern glui32 do_gestalt(glui32 val, glui32 val2);
242 extern int init_dispatch(void);
243 extern glui32 perform_glk(glui32 funcnum, glui32 numargs, glui32 *arglist);
244 extern strid_t find_stream_by_id(glui32 objid);
247 extern int init_profile(void);
249 extern glui32 profile_opcount;
250 #define profile_tick() (profile_opcount++)
251 extern void profile_in(glui32 addr, int accel);
252 extern void profile_out(void);
253 extern void profile_fail(char *reason);
254 extern void profile_quit(void);
255 #else /* VM_PROFILING */
256 #define profile_tick() (0)
257 #define profile_in(addr, accel) (0)
258 #define profile_out() (0)
259 #define profile_fail(reason) (0)
260 #define profile_quit() (0)
261 #endif /* VM_PROFILING */
264 typedef glui32 (*acceleration_func)(glui32 argc, glui32 *argv);
265 extern void init_accel(void);
266 extern acceleration_func accel_find_func(glui32 index);
267 extern acceleration_func accel_get_func(glui32 addr);
268 extern void accel_set_func(glui32 index, glui32 addr);
269 extern void accel_set_param(glui32 index, glui32 val);
271 #endif /* _GLULXE_H */