--- /dev/null
+/* glulxe.h: Glulxe header file.
+ Designed by Andrew Plotkin <erkyrath@eblong.com>
+ http://eblong.com/zarf/glulx/index.html
+*/
+
+#ifndef _GLULXE_H
+#define _GLULXE_H
+
+/* We define our own TRUE and FALSE and NULL, because ANSI
+ is a strange world. */
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* You may have to edit the definition of glui16 to make sure it's really a
+ 16-bit unsigned integer type, and glsi16 to make sure it's really a
+ 16-bit signed integer type. If they're not, horrible things will happen. */
+typedef unsigned short glui16;
+typedef signed short glsi16;
+
+/* Uncomment this definition to turn on memory-address checking. In
+ this mode, all reads and writes to main memory will be checked to
+ ensure they're in range. This is slower, but prevents malformed
+ game files from crashing the interpreter. */
+/* #define VERIFY_MEMORY_ACCESS (1) */
+
+/* Uncomment this definition to turn on Glulx VM profiling. In this
+ mode, all function calls are timed, and the timing information is
+ written to a data file called "profile-raw". */
+/* #define VM_PROFILING (1) */
+
+/* Some macros to read and write integers to memory, always in big-endian
+ format. */
+#define Read4(ptr) \
+ ( (glui32)(((unsigned char *)(ptr))[0] << 24) \
+ | (glui32)(((unsigned char *)(ptr))[1] << 16) \
+ | (glui32)(((unsigned char *)(ptr))[2] << 8) \
+ | (glui32)(((unsigned char *)(ptr))[3]))
+#define Read2(ptr) \
+ ( (glui16)(((unsigned char *)(ptr))[0] << 8) \
+ | (glui16)(((unsigned char *)(ptr))[1]))
+#define Read1(ptr) \
+ ((unsigned char)(((unsigned char *)(ptr))[0]))
+
+#define Write4(ptr, vl) \
+ (((ptr)[0] = (unsigned char)(((glui32)(vl)) >> 24)), \
+ ((ptr)[1] = (unsigned char)(((glui32)(vl)) >> 16)), \
+ ((ptr)[2] = (unsigned char)(((glui32)(vl)) >> 8)), \
+ ((ptr)[3] = (unsigned char)(((glui32)(vl)))))
+#define Write2(ptr, vl) \
+ (((ptr)[0] = (unsigned char)(((glui32)(vl)) >> 8)), \
+ ((ptr)[1] = (unsigned char)(((glui32)(vl)))))
+#define Write1(ptr, vl) \
+ (((unsigned char *)(ptr))[0] = (vl))
+
+#if VERIFY_MEMORY_ACCESS
+#define Verify(adr, ln) verify_address(adr, ln)
+#else
+#define Verify(adr, ln) (0)
+#endif /* VERIFY_MEMORY_ACCESS */
+
+#define Mem1(adr) (Verify(adr, 1), Read1(memmap+(adr)))
+#define Mem2(adr) (Verify(adr, 2), Read2(memmap+(adr)))
+#define Mem4(adr) (Verify(adr, 4), Read4(memmap+(adr)))
+#define MemW1(adr, vl) (Verify(adr, 1), Write1(memmap+(adr), (vl)))
+#define MemW2(adr, vl) (Verify(adr, 2), Write2(memmap+(adr), (vl)))
+#define MemW4(adr, vl) (Verify(adr, 4), Write4(memmap+(adr), (vl)))
+
+/* Macros to access values on the stack. These *must* be used
+ with proper alignment! (That is, Stk4 and StkW4 must take
+ addresses which are multiples of four, etc.) If the alignment
+ rules are not followed, the program will see performance
+ degradation or even crashes, depending on the machine CPU. */
+
+#define Stk1(adr) \
+ (*((unsigned char *)(stack+(adr))))
+#define Stk2(adr) \
+ (*((glui16 *)(stack+(adr))))
+#define Stk4(adr) \
+ (*((glui32 *)(stack+(adr))))
+
+#define StkW1(adr, vl) \
+ (*((unsigned char *)(stack+(adr))) = (unsigned char)(vl))
+#define StkW2(adr, vl) \
+ (*((glui16 *)(stack+(adr))) = (glui16)(vl))
+#define StkW4(adr, vl) \
+ (*((glui32 *)(stack+(adr))) = (glui32)(vl))
+
+/* Some useful structures. */
+
+/* instruction_t:
+ Represents the list of operands to an instruction being executed.
+ (Yes, it's somewhat misnamed. Sorry.) We assume, for the indefinite
+ moment, that no opcode has more than 8 operands, and no opcode
+ has two "store" operands.
+*/
+typedef struct instruction_struct {
+ glui32 desttype;
+ glui32 value[8];
+} instruction_t;
+
+/* operandlist_t:
+ Represents the operand structure of an opcode.
+*/
+typedef struct operandlist_struct {
+ int num_ops; /* Number of operands for this opcode */
+ int arg_size; /* Usually 4, but can be 1 or 2 */
+ int *formlist; /* Array of values, either modeform_Load or modeform_Store */
+} operandlist_t;
+#define modeform_Load (1)
+#define modeform_Store (2)
+
+/* Some useful globals */
+
+extern strid_t gamefile;
+extern glui32 gamefile_start, gamefile_len;
+extern char *init_err, *init_err2;
+
+extern unsigned char *memmap;
+extern unsigned char *stack;
+
+extern glui32 ramstart;
+extern glui32 endgamefile;
+extern glui32 origendmem;
+extern glui32 stacksize;
+extern glui32 startfuncaddr;
+extern glui32 checksum;
+extern glui32 stackptr;
+extern glui32 frameptr;
+extern glui32 pc;
+extern glui32 origstringtable;
+extern glui32 stringtable;
+extern glui32 valstackbase;
+extern glui32 localsbase;
+extern glui32 endmem;
+extern glui32 protectstart, protectend;
+
+extern void (*stream_char_handler)(unsigned char ch);
+extern void (*stream_unichar_handler)(glui32 ch);
+
+/* main.c */
+extern void fatal_error_handler(char *str, char *arg, int useval, glsi32 val);
+extern void nonfatal_warning_handler(char *str, char *arg, int useval, glsi32 val);
+#define fatal_error(s) (fatal_error_handler((s), NULL, FALSE, 0))
+#define fatal_error_2(s1, s2) (fatal_error_handler((s1), (s2), FALSE, 0))
+#define fatal_error_i(s, v) (fatal_error_handler((s), NULL, TRUE, (v)))
+#define nonfatal_warning(s) (nonfatal_warning_handler((s), NULL, FALSE, 0))
+#define nonfatal_warning_2(s1, s2) (nonfatal_warning_handler((s1), (s2), FALSE, 0))
+#define nonfatal_warning_i(s, v) (nonfatal_warning_handler((s), NULL, TRUE, (v)))
+
+/* files.c */
+extern int is_gamefile_valid(void);
+extern int locate_gamefile(int isblorb);
+
+/* vm.c */
+extern void setup_vm(void);
+extern void finalize_vm(void);
+extern void vm_restart(void);
+extern glui32 change_memsize(glui32 newlen, int internal);
+extern glui32 *pop_arguments(glui32 count, glui32 addr);
+extern void verify_address(glui32 addr, glui32 count);
+
+/* exec.c */
+extern void execute_loop(void);
+
+/* operand.c */
+extern operandlist_t *fast_operandlist[0x80];
+extern void init_operands(void);
+extern operandlist_t *lookup_operandlist(glui32 opcode);
+extern void parse_operands(instruction_t *inst, operandlist_t *oplist);
+extern void store_operand(glui32 desttype, glui32 destaddr, glui32 storeval);
+extern void store_operand_s(glui32 desttype, glui32 destaddr, glui32 storeval);
+extern void store_operand_b(glui32 desttype, glui32 destaddr, glui32 storeval);
+
+/* funcs.c */
+extern void enter_function(glui32 addr, glui32 argc, glui32 *argv);
+extern void leave_function(void);
+extern void push_callstub(glui32 desttype, glui32 destaddr);
+extern void pop_callstub(glui32 returnvalue);
+extern glui32 pop_callstub_string(int *bitnum);
+
+/* string.c */
+extern void stream_num(glsi32 val, int inmiddle, int charnum);
+extern void stream_string(glui32 addr, int inmiddle, int bitnum);
+extern glui32 stream_get_table(void);
+extern void stream_set_table(glui32 addr);
+extern void stream_get_iosys(glui32 *mode, glui32 *rock);
+extern void stream_set_iosys(glui32 mode, glui32 rock);
+extern char *make_temp_string(glui32 addr);
+extern glui32 *make_temp_ustring(glui32 addr);
+extern void free_temp_string(char *str);
+extern void free_temp_ustring(glui32 *str);
+
+/* heap.c */
+extern void heap_clear(void);
+extern int heap_is_active(void);
+extern glui32 heap_get_start(void);
+extern glui32 heap_alloc(glui32 len);
+extern void heap_free(glui32 addr);
+extern int heap_get_summary(glui32 *valcount, glui32 **summary);
+extern int heap_apply_summary(glui32 valcount, glui32 *summary);
+extern void heap_sanity_check(void);
+
+/* serial.c */
+extern int init_serial(void);
+extern glui32 perform_save(strid_t str);
+extern glui32 perform_restore(strid_t str);
+extern glui32 perform_saveundo(void);
+extern glui32 perform_restoreundo(void);
+extern glui32 perform_verify(void);
+
+/* search.c */
+extern glui32 linear_search(glui32 key, glui32 keysize,
+ glui32 start, glui32 structsize, glui32 numstructs,
+ glui32 keyoffset, glui32 options);
+extern glui32 binary_search(glui32 key, glui32 keysize,
+ glui32 start, glui32 structsize, glui32 numstructs,
+ glui32 keyoffset, glui32 options);
+extern glui32 linked_search(glui32 key, glui32 keysize,
+ glui32 start, glui32 keyoffset, glui32 nextoffset,
+ glui32 options);
+
+/* osdepend.c */
+extern void *glulx_malloc(glui32 len);
+extern void *glulx_realloc(void *ptr, glui32 len);
+extern void glulx_free(void *ptr);
+extern void glulx_setrandom(glui32 seed);
+extern glui32 glulx_random(void);
+extern void glulx_sort(void *addr, int count, int size,
+ int (*comparefunc)(void *p1, void *p2));
+
+/* gestalt.c */
+extern glui32 do_gestalt(glui32 val, glui32 val2);
+
+/* glkop.c */
+extern int init_dispatch(void);
+extern glui32 perform_glk(glui32 funcnum, glui32 numargs, glui32 *arglist);
+extern strid_t find_stream_by_id(glui32 objid);
+
+/* profile.c */
+extern int init_profile(void);
+#if VM_PROFILING
+extern glui32 profile_opcount;
+#define profile_tick() (profile_opcount++)
+extern void profile_in(glui32 addr, int accel);
+extern void profile_out(void);
+extern void profile_fail(char *reason);
+extern void profile_quit(void);
+#else /* VM_PROFILING */
+#define profile_tick() (0)
+#define profile_in(addr, accel) (0)
+#define profile_out() (0)
+#define profile_fail(reason) (0)
+#define profile_quit() (0)
+#endif /* VM_PROFILING */
+
+/* accel.c */
+typedef glui32 (*acceleration_func)(glui32 argc, glui32 *argv);
+extern void init_accel(void);
+extern acceleration_func accel_find_func(glui32 index);
+extern acceleration_func accel_get_func(glui32 addr);
+extern void accel_set_func(glui32 index, glui32 addr);
+extern void accel_set_param(glui32 index, glui32 val);
+
+#endif /* _GLULXE_H */