static inline Tl_var *decode_dest(void *ptr) { if ((prep_frame == NULL) || ((ta_table[current_line].f != assign_i) && (ta_table[current_line].f != assign_d) && (ta_table[current_line].f != assign_str))) return decode_var(ptr, stack_top(frame_stack)); return decode_var(ptr, prep_frame); }
gint wr_varval(gint x, gptr vb) { gint y; // do the first test without loop y=vb[decode_var(x)]; if (y==UNASSIGNED) { return x; } else if (!isvar(y)) { return y; } else { // if variable is assigned to a variable, loop for (;;) { x=y; y=vb[decode_var(x)]; if (y==UNASSIGNED) { return x; } else if (!isvar(y)) { return y; } } } }
static inline Tl_var *decode_op1(void *ptr) { i_func f = ta_table[current_line].f; if ((f != call_function) && (f != prepare_frame)) return decode_var(ptr, stack_top(frame_stack)); if (f == call_function) prep_var.u = ((Tglobal_sym_tab_node*)ptr)->func_start; else if (f == prepare_frame) prep_var.u = ((Tglobal_sym_tab_node*)ptr)->var_count; return &prep_var; }
/* This nifty trick is from Frotz. */ static void zextended(void) { uint8_t opnumber = BYTE(pc++); decode_var(BYTE(pc++)); /* §14.2.1 * The exception for 0x80–0x83 is for the Zoom extensions. * Standard 1.1 implicitly updates §14.2.1 to recommend ignoring * opcodes in the range EXT:30 to EXT:255, due to the fact that * @buffer_screen is EXT:29. */ if(opnumber > 0x1d && (opnumber < 0x80 || opnumber > 0x83)) return; op_call(EXT, opnumber); }
void process_instructions(void) { if(njumps <= ++ilevel) { jumps = realloc(jumps, ++njumps * sizeof *jumps); if(jumps == NULL) die("unable to allocate memory for jump buffer"); } switch(setjmp(jumps[ilevel])) { case 1: /* Normal break from interrupt. */ return; case 2: /* Special break: a restart was requested. */ { /* §6.1.3: Flags2 is preserved on a restart. */ uint16_t flags2 = WORD(0x10); process_story(); STORE_WORD(0x10, flags2); } break; } while(1) { uint8_t opcode; #if defined(ZTERP_GLK) && defined(ZTERP_GLK_TICK) glk_tick(); #endif ZPC(pc); opcode = BYTE(pc++); /* long 2OP */ if(opcode < 0x80) { znargs = 2; if(opcode & 0x40) zargs[0] = variable(BYTE(pc++)); else zargs[0] = BYTE(pc++); if(opcode & 0x20) zargs[1] = variable(BYTE(pc++)); else zargs[1] = BYTE(pc++); op_call(TWO, opcode & 0x1f); } /* short 1OP */ else if(opcode < 0xb0) { znargs = 1; if(opcode < 0x90) /* large constant */ { zargs[0] = WORD(pc); pc += 2; } else if(opcode < 0xa0) /* small constant */ { zargs[0] = BYTE(pc++); } else /* variable */ { zargs[0] = variable(BYTE(pc++)); } op_call(ONE, opcode & 0x0f); } /* short 0OP (plus EXT) */ else if(opcode < 0xc0) { znargs = 0; op_call(ZERO, opcode & 0x0f); } /* variable 2OP */ else if(opcode < 0xe0) { znargs = 0; decode_var(BYTE(pc++)); op_call(TWO, opcode & 0x1f); } /* Double variable VAR */ else if(opcode == 0xec || opcode == 0xfa) { uint8_t types1, types2; znargs = 0; types1 = BYTE(pc++); types2 = BYTE(pc++); decode_var(types1); decode_var(types2); op_call(VAR, opcode & 0x1f); } /* variable VAR */ else { znargs = 0; read_pc = pc - 1; decode_var(BYTE(pc++)); op_call(VAR, opcode & 0x1f); } } }
void setvar(gint x, gint y, gptr vb, gptr vstk, gint* vc) { vb[decode_var(x)]=y; vstk[*vc]=(gint)(vb+decode_var(x)); // pointer arithmetic (gint ptr) (*vc)++; }
static inline Tl_var *decode_op2(void *ptr) { return decode_var(ptr, stack_top(frame_stack)); }