093ac6a600c75b4e5dd98f4b973fce05ca274124
[projects/chimara/chimara.git] / interpreters / glulxe / glulxe.h
1 /* glulxe.h: Glulxe header file.
2     Designed by Andrew Plotkin <erkyrath@eblong.com>
3     http://eblong.com/zarf/glulx/index.html
4 */
5
6 #ifndef _GLULXE_H
7 #define _GLULXE_H
8
9 /* We define our own TRUE and FALSE and NULL, because ANSI
10    is a strange world. */
11 #ifndef TRUE
12 #define TRUE 1
13 #endif
14 #ifndef FALSE
15 #define FALSE 0
16 #endif
17 #ifndef NULL
18 #define NULL 0
19 #endif
20
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; 
26
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) */
32
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) */
37
38 /* Some macros to read and write integers to memory, always in big-endian
39    format. */
40 #define Read4(ptr)    \
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]))
45 #define Read2(ptr)    \
46   ( (glui16)(((unsigned char *)(ptr))[0] << 8)  \
47   | (glui16)(((unsigned char *)(ptr))[1]))
48 #define Read1(ptr)    \
49   ((unsigned char)(((unsigned char *)(ptr))[0]))
50
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))
61
62 #if VERIFY_MEMORY_ACCESS
63 #define Verify(adr, ln) verify_address(adr, ln)
64 #else
65 #define Verify(adr, ln) (0)
66 #endif /* VERIFY_MEMORY_ACCESS */
67
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)))
74
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. */
80
81 #define Stk1(adr)   \
82   (*((unsigned char *)(stack+(adr))))
83 #define Stk2(adr)   \
84   (*((glui16 *)(stack+(adr))))
85 #define Stk4(adr)   \
86   (*((glui32 *)(stack+(adr))))
87
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))
94
95 /* Some useful structures. */
96
97 /* instruction_t:
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.
102 */
103 typedef struct instruction_struct {
104   glui32 desttype;
105   glui32 value[8];
106 } instruction_t;
107
108 /* operandlist_t:
109    Represents the operand structure of an opcode.
110 */
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 */
115 } operandlist_t;
116 #define modeform_Load (1)
117 #define modeform_Store (2)
118
119 /* Some useful globals */
120
121 extern strid_t gamefile;
122 extern glui32 gamefile_start, gamefile_len;
123 extern char *init_err, *init_err2;
124
125 extern unsigned char *memmap;
126 extern unsigned char *stack;
127
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;
136 extern glui32 pc;
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;
143
144 extern void (*stream_char_handler)(unsigned char ch);
145 extern void (*stream_unichar_handler)(glui32 ch);
146
147 /* main.c */
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)))
156
157 /* files.c */
158 extern int is_gamefile_valid(void);
159 extern int locate_gamefile(int isblorb);
160
161 /* vm.c */
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);
168
169 /* exec.c */
170 extern void execute_loop(void);
171
172 /* operand.c */
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);
180
181 /* funcs.c */
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);
187
188 /* string.c */
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);
199
200 /* heap.c */
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);
209
210 /* serial.c */
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);
217
218 /* search.c */
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,
227   glui32 options);
228
229 /* osdepend.c */
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));
237
238 /* gestalt.c */
239 extern glui32 do_gestalt(glui32 val, glui32 val2);
240
241 /* glkop.c */
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);
245
246 /* profile.c */
247 extern int init_profile(void);
248 #if VM_PROFILING
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 */
262
263 /* accel.c */
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);
270
271 #endif /* _GLULXE_H */