1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * 22 * Based on the original sources 23 * Faery Tale II -- The Halls of the Dead 24 * (c) 1993-1996 The Wyrmkeep Entertainment Co. 25 */ 26 27 #ifndef SAGA2_CODE_H 28 #define SAGA2_CODE_H 29 30 namespace Saga2 { 31 32 // types of operations for code generation 33 // note that the macros listed below depend on the ordering of this 34 // table to determine things like unary-op, binary-op, etc. 35 36 enum op_types { 37 op_undefined = 0, 38 39 // internal operations 40 41 op_nextblock, // continue execution at next block 42 op_dup, // duplicate 16-bit value on stack 43 op_drop, // drop 16-bit value on stack 44 45 // primary values 46 47 op_zero, // push a zero on the stack 48 op_one, // push a one on the stack 49 op_constint, // constant integer 50 op_constid, // constant id reference 51 op_strlit, // string literal 52 op_sym, // symbol address 53 op_symref, // symbol contents 54 op_classref, // reference to "this" 55 op_deref, // dereference of an ID 56 57 // references within this module 58 59 op_getflag, // read from flag bit (mode) 60 op_getbyte, // read from byte field (mode) 61 op_getint, // read from integer field (mode) 62 op_getstr, // read from string field (mode) 63 op_getid, // read from id field (mode) 64 65 op_putflag, // put to flag bit (mode) 66 op_putbyte, // put to byte field (mode) 67 op_putint, // put to integer field (mode) 68 op_putstr, // put to string field (mode) 69 op_putid, // put to id field (mode) 70 71 op_pea, // push effective address onto stack 72 73 // 'void' versions consume their arguments 74 75 op_putflag_v, // put to flag bit (mode) 76 op_putbyte_v, // put to byte field (mode) 77 op_putint_v, // put to integer field (mode) 78 op_putstr_v, // put to string field (mode) 79 op_putid_v, // put to id field (mode) 80 81 // function call 82 83 op_call_near, // call function in same segment 84 op_call_far, // call function in other segment 85 op_ccall, // call C function 86 op_ccall_v, // call C function (void) 87 op_call_member, // call member function 88 op_call_member_v, // call member function (void) 89 90 op_enter, // enter a function 91 op_return, // return from function 92 op_return_v, // return nothing from function 93 94 // branches 95 96 op_jmp, 97 op_jmp_true_v, // test arg and consume 98 op_jmp_false_v, // test arg and consume 99 op_jmp_true, // test arg and don't consume 100 op_jmp_false, // test arg and don't consume 101 op_jmp_switch, // switch statement (integer) 102 op_jmp_strswitch, // switch statement (string) 103 op_jmp_random, // random jump 104 105 // unary operators 106 107 op_negate, 108 op_not, 109 op_compl, 110 111 op_inc_v, // increment, don't push 112 op_dec_v, // decrement, don't push 113 op_postinc, 114 op_postdec, 115 116 // arithmetic 117 118 op_add, 119 op_sub, 120 op_mul, 121 op_div, 122 op_mod, 123 124 // conditional 125 126 op_conditional, 127 op_comma, 128 129 // comparison 130 131 op_eq, 132 op_ne, 133 op_gt, 134 op_lt, 135 op_ge, 136 op_le, 137 138 // string comparison 139 140 op_str_eq, 141 op_str_ne, 142 op_str_gt, 143 op_str_lt, 144 op_str_ge, 145 op_str_le, 146 147 // shift 148 149 op_rsh, 150 op_lsh, 151 152 // bitwise 153 154 op_and, 155 op_or, 156 op_xor, 157 158 // logical 159 160 op_land, 161 op_lor, 162 op_lxor, 163 164 // string functions 165 166 op_strcat, // string concatenation 167 op_strformat, // string formatting 168 169 // assignment operators -- none of these are actually compiled into 170 // code (they become get/put type operations) 171 172 op_assign, 173 // none of these are even used currently... 174 op_asplus, 175 op_asminus, 176 op_astimes, 177 op_asdiv, 178 op_asmod, 179 op_asrshift, 180 op_aslshift, 181 op_asand, 182 op_asor, 183 184 // Special ops 185 186 op_speak, 187 op_dialog_begin, 188 op_dialog_end, 189 op_reply, 190 op_animate, 191 192 // New opcodes 193 194 op_jmp_seedrandom, // seeded random jump 195 op_symref_x, // get the export number of the symbol 196 197 op_last /* about 90 so far */ 198 }; 199 200 // addressing modes for get and put 201 202 enum addr_types { 203 204 // Offset reference to the thread structure 205 206 addr_thread = 0, 207 208 // Offset reference to the stack 209 210 addr_stack, 211 212 // Implicit reference to the currently executing segment 213 214 addr_near, 215 216 // Implicit reference to data segment 217 218 addr_data, 219 220 // This addressing mode references any external segment 221 // using a 16-bit segment number and a 16-bit segment offset 222 // which immediately follow the instruction. 223 224 addr_far, 225 226 // This addressing mode is used for segment-array addressing 227 // it's a 16-bit segment followed by a 16-bit object number, 228 // followed by a (byte or bit) offset within the object 229 230 addr_array, 231 232 // This addressing mode uses a 16-bit segment number 233 // and a 16-bit offset which have been put on the stack. 234 235 // addr_indirect, // use SEG:offset on stack 236 // addr_indirect_index, // use SEG:index:offset on stack 237 238 // This addressing mode is used for dereferencing objects. 239 // It consists of an _embedded_ address for retrieving the 240 // object number, followed by a 16-bit segment number for 241 // the dereferenced objects, followed by a 16-bit index 242 // into the dereferenced object. 243 244 // REM: We also need a "far deref" for computing the 245 // dereferenced object's segment number. 246 247 addr_deref, 248 249 // Addressing mode used for class member functions. It 250 // specified that the address is relative to whatever 251 // object the 1st argument is referrring to. 252 253 addr_this // relative to arg 1 254 }; 255 256 #define IS_CONST(x) ((x) >= op_constint && (x) <= op_conststr) 257 #define IS_ADDRESS(x) ((x) == op_sym) 258 #define IS_UNOP(x) ((x) >= op_negate && (x) <= op_postdec) 259 260 #define IS_BINOP(x) ((x) >= op_add && (x) <= op_strcat) 261 #define IS_ASOP(x) ((x) >= op_assign && (x) <= op_asor) 262 263 // #define IS_UNOP2(x) ((x) == op_getarray || (x) == op_putarray) 264 // #define CONST(op) ((op) >= op_constflag && (op) <= op_conststr) 265 266 // Flags for special statements 267 268 #define SPEAKF_NOANIMATE (1<<0) // speaker should animate 269 #define SPEAKF_ASYNC (1<<1) // async speech. 270 271 #define REPLYF_ONCE (1<<0) // 'once' flag 272 #define REPLYF_SUMMARY (1<<1) // response is only a summary 273 #define REPLYF_CONDITION (1<<2) // response has a condition 274 275 #define ANIMATEF_REPEAT (1<<0) 276 277 // BasicBlock describes a block of generated code 278 279 #ifdef COMPILE_H 280 281 typedef struct _BasicBlock { 282 struct _BasicBlock *next; // pointer to next block 283 284 short label; // label for this block 285 286 struct _BasicBlock *from[2], // where we could have come from 287 *jumpto, // where to go if jump 288 *fallto; // where to go if fall through 289 290 struct _Statement *first_st, // statement list for this bblock 291 *last_st; // it's a circular list 292 293 ENode *test_expr; // test expression for jump 294 char in_flags, // flags for entering this block 295 jump_type; // where to go after this block 296 297 uint16 start_offset, // offset in module of this block 298 jump_offset; // offset of module of jump at end 299 300 int16 source_file, // source line of statement 301 source_line; // source file of statement 302 } BasicBlock; 303 304 // Various flags for the block 305 306 #define BBLOCK_CLABEL (1<<0) /* bblock begins with a 'C' label */ 307 #define BBLOCK_INTLABEL (1<<1) /* bblock begins with internal label */ 308 #define BBLOCK_FIRST (1<<2) /* first bblock in the function */ 309 #define BBLOCK_MANY (1<<3) /* many guys jump to here */ 310 #define BBLOCK_CASE (1<<4) /* case stmts might not have 'from' ptr */ 311 312 // Jump types 313 314 enum jump_types { 315 jump_never = 0, /* never jump */ 316 jump_false, /* jump on expression if false */ 317 jump_true, /* jump on expression if true */ 318 jump_always, /* jump always */ 319 jump_cjump, /* 'c' goto stm, jumpto is a label # */ 320 jump_return, /* block ends with a 'return' statement */ 321 jump_switch, /* jumps to lots of places */ 322 }; 323 #endif 324 /* 325 // Module describes all the code associated with a particular 326 // compilation unit. 327 328 struct Module { 329 uint16 exportCount, // number of symbols exported 330 importCount; // number of symbols imported 331 uint16 exportOffset, // start of export table 332 importOffset; // start of import table 333 334 // Q: Should ModuleName be somewhere else, like in the main program? 335 336 uint16 staticSize; // size of static data 337 uint16 stringOffset; // unused in this version 338 // int16 moduleName; // offset to name of module 339 340 // Followed by list of exports 341 // Followed by list of imports 342 // Followed by symbol names, each NULL-terminated 343 // Followed by actual code blocks 344 345 }; 346 347 // Exports: Each Export contains the offset to find the name of 348 // the object. After that is the offset to find the object itself. 349 350 // The first Export is always the module entry point 351 352 struct ModuleExport { // an exported symbol 353 uint16 symbolOffset, // offset in module of symbol name 354 objectOffset; // where to find object 355 }; 356 357 // Imports: Each Import contains the offset to find the name of 358 // the object. After that is a blank pointer, which will be filled 359 // in with the real address of the object. When addressing the 360 // imported object, the code in this module will refer to this 361 // ModuleImport entry, and indirectly locate the referenced object. 362 363 struct ModuleImport { // a module xref 364 uint16 symbolOffset; // where, from here, to find name 365 void *objectPointer; // NULL pointer, filled in on load 366 }; 367 */ 368 369 } // end of namespace Saga2 370 371 #endif 372