// perform wrapping and output static void op_enc_perform(op_enc_t* enc) { io_t wrap = 0; io_t dif = 0; if (enc->wrap) { // wrapping... // if value needs wrapping, output the applied difference while (enc->val > enc->max) { dif = op_sub(enc->min, enc->max); wrap = op_add(wrap, dif); enc->val = op_add(enc->val, dif); } while (enc->val < enc->min) { dif = op_sub(enc->max, enc->min); wrap = op_add(wrap, dif); enc->val = op_add(enc->val, dif); } } else { // saturating... if (enc->val > enc->max) { enc->val = enc->max; dif = 1; // force wrap output } if (enc->val < enc->min) { enc->val = enc->min; dif = -1; // force wrap output } } // output the value net_activate(enc->outs[0], enc->val, enc); // output the wrap amount if (dif != 0) { net_activate(enc->outs[1], wrap, enc); } }
// wrap and output void op_accum_wrap_out(op_accum_t* accum) { io_t wrap = 0; io_t dif = 0; if (accum->wrap) { // wrapping... // if value needs wrapping, output the applied difference while (accum->val > accum->max) { dif = op_sub(accum->min, accum->max) - 1; wrap = op_add(wrap, dif); accum->val = op_add(accum->val, dif); } while (accum->val < accum->min) { dif = op_sub(accum->max, accum->min) + 1; wrap = op_add(wrap, dif); accum->val = op_add(accum->val, dif); } } else { // saturating... if (accum->val > accum->max) { wrap = dif = op_sub(accum->val, accum->max); accum->val = accum->max; } if (accum->val < accum->min) { wrap = dif = op_sub(accum->val , accum->min); accum->val = accum->min; } } // output the value net_activate(accum->outs[0], accum->val, accum); // output the wrap amount if (dif != 0) { net_activate(accum->outs[1], wrap, accum); } }
void muste_pol(int argc,char *argv[]) { // RS REM int i; char *t; // RS ADD Variable init mtx=0; n_row_comments=0; roots_eps=EPS; roots_max_iter=MAX_ITER; s_init(argv[1]); if (g<2) { sur_print("\nIncomplete POL operation!"); WAIT; return; } // RS ADD strcpy(xx,word[1]); p=strchr(xx,'='); if (p==NULL) { sur_print("\n= missing in POL operation!"); WAIT; return; } *p++=EOS; if (g>2) { if (strncmp(p,"LAG(",4)==0) { op_lag(p); return; } // 16.8.2006 } q=strchr(p,'*'); if (q!=NULL) { op_mult(); return; } q=strchr(p,'/'); if (q!=NULL) { op_div(); return; } q=strchr(p,'+'); if (q!=NULL) { op_add(); return; } q=strchr(p,'-'); if (q!=NULL) { op_sub(); return; } q=strchr(p,'('); if (q!=NULL) { *q++=EOS; t=strchr(q,')'); if (t==NULL) { sur_print("\n) is missing!"); WAIT; return; } *t=EOS; muste_strupr(p); if (strncmp(p,"PROD",4)==0) { op_product(); return; } if (strncmp(p,"ROOT",4)==0) { op_roots(); return; } if (strncmp(p,"DER",3)==0) { op_der(); return; } op_value(); /* POL V=P(X) */ } }
int executeInstruction(struct Instruction *instr, struct FunctionContext *func, struct RuntimeContext *ctx) { switch (instr->opcode) { case PUSH: op_push(instr, func); break; case ADD: op_add(instr, func); break; case SUB: op_sub(instr, func); break; case MUL: op_mul(instr, func); break; case DIV: op_div(instr, func); break; case LCALL: op_lcall(instr, func, ctx); break; case IJMP: op_ijmp(instr, func); break; case RARG: op_rarg(instr, func); break; case MKARR: op_mkarr(instr, func, ctx); break; case SETELEM: op_setelem(instr, func, ctx); break; case GETELEM: op_getelem(instr, func, ctx); break; case SETVAR: op_setvar(instr, func); break; case GETVAR: op_getvar(instr, func); break; case JLE: op_jle(instr, func); break; case RET: op_ret(instr, func); return 0; } if (instr->opcode != IJMP) { if (func->next +1 <= func->opCount) func->next++; } return 1; }
/** * Runs the instruction at the program counters position in memory. */ void vm_exec() { cycles++; Instruction* op = mem_load_instr(pcounter); print_instr(op); switch(op->op) { case OP_NAP: break; case OP_ADD: op_add(op); break; case OP_SUB: op_sub(op); break; case OP_EXP: op_exp(op); break; case OP_SIN: op_sin(op); break; case OP_COS: op_cos(op); break; case OP_TAN: op_tan(op); break; case OP_LW: op_lw(op); break; case OP_SW: op_sw(op); break; case OP_SB: op_sb(op); break; case OP_J: op_j(op); return; // Jump case OP_JR: op_jr(op); return; case OP_JAL: op_jal(op); return; case OP_JZ: op_jz(op); return; case OP_JNZ: op_jnz(op); return; case OP_JEQ: op_jeq(op); return; case OP_JNQ: op_jnq(op); return; case OP_PUSH: op_push(op); break; case OP_POP: op_pop(op); break; case OP_PRTI: op_prti(op); break; case OP_EXIT: vm_exit(op->k); return; /* Unsupported operation */ default: printf("Error: Invalid operation at %d\n", pcounter); print_instr(op); vm_exit(-1); return; } pcounter = pcounter + 8; }
void StackInterpreter::processOpCode(const OpCode& oc) { ++opcount_; //handle push data by itself, doesn't play well with switch if (oc.opcode_ == 0) { op_0(); return; } if (oc.opcode_ <= 75) { stack_.push_back(oc.dataRef_); return; } if (oc.opcode_ < 79) { //op push data stack_.push_back(oc.dataRef_); return; } if (oc.opcode_ == OP_1NEGATE) { op_1negate(); return; } if (oc.opcode_ <= 96 && oc.opcode_ >= 81) { //op_1 - op_16 uint8_t val = oc.opcode_ - 80; stack_.push_back(move(intToRawBinary(val))); return; } //If we got this far this op code is not push data. If this is the input //script, set the flag as per P2SH parsing rules (only push data in inputs) if (outputScriptRef_.getSize() == 0) onlyPushDataInInput_ = false; switch (oc.opcode_) { case OP_NOP: break; case OP_IF: { BinaryRefReader brr(oc.dataRef_); op_if(brr, false); break; } case OP_NOTIF: { op_not(); BinaryRefReader brr(oc.dataRef_); op_if(brr, false); break; } case OP_ELSE: //processed by opening if statement throw ScriptException("a wild else appears"); case OP_ENDIF: //processed by opening if statement throw ScriptException("a wild endif appears"); case OP_VERIFY: op_verify(); break; case OP_TOALTSTACK: op_toaltstack(); break; case OP_FROMALTSTACK: op_fromaltstack(); break; case OP_IFDUP: op_ifdup(); break; case OP_2DROP: { stack_.pop_back(); stack_.pop_back(); break; } case OP_2DUP: op_2dup(); break; case OP_3DUP: op_3dup(); break; case OP_2OVER: op_2over(); break; case OP_DEPTH: op_depth(); break; case OP_DROP: stack_.pop_back(); break; case OP_DUP: op_dup(); break; case OP_NIP: op_nip(); break; case OP_OVER: op_over(); break; case OP_PICK: op_pick(); break; case OP_ROLL: op_roll(); break; case OP_ROT: op_rot(); break; case OP_SWAP: op_swap(); break; case OP_TUCK: op_tuck(); break; case OP_SIZE: op_size(); break; case OP_EQUAL: { op_equal(); if (onlyPushDataInInput_ && p2shScript_.getSize() != 0) { //check the op_equal result op_verify(); if (!isValid_) break; if (flags_ & SCRIPT_VERIFY_SEGWIT) if (p2shScript_.getSize() == 22 || p2shScript_.getSize() == 34) { auto versionByte = p2shScript_.getPtr(); if (*versionByte <= 16) { processSW(p2shScript_); return; } } processScript(p2shScript_, true); } break; } case OP_EQUALVERIFY: { op_equal(); op_verify(); break; } case OP_1ADD: op_1add(); break; case OP_1SUB: op_1sub(); break; case OP_NEGATE: op_negate(); break; case OP_ABS: op_abs(); break; case OP_NOT: op_not(); break; case OP_0NOTEQUAL: op_0notequal(); break; case OP_ADD: op_add(); break; case OP_SUB: op_sub(); break; case OP_BOOLAND: op_booland(); break; case OP_BOOLOR: op_boolor(); break; case OP_NUMEQUAL: op_numequal(); break; case OP_NUMEQUALVERIFY: { op_numequal(); op_verify(); break; } case OP_NUMNOTEQUAL: op_numnotequal(); break; case OP_LESSTHAN: op_lessthan(); break; case OP_GREATERTHAN: op_greaterthan(); break; case OP_LESSTHANOREQUAL: op_lessthanorequal(); break; case OP_GREATERTHANOREQUAL: op_greaterthanorequal(); break; case OP_MIN: op_min(); break; case OP_MAX: op_max(); break; case OP_WITHIN: op_within(); break; case OP_RIPEMD160: op_ripemd160(); break; case OP_SHA256: { //save the script if this output is a possible p2sh if (flags_ & SCRIPT_VERIFY_P2SH_SHA256) if (opcount_ == 1 && onlyPushDataInInput_) p2shScript_ = stack_back(); op_sha256(); break; } case OP_HASH160: { //save the script if this output is a possible p2sh if (flags_ & SCRIPT_VERIFY_P2SH) if (opcount_ == 1 && onlyPushDataInInput_) p2shScript_ = stack_back(); op_hash160(); break; } case OP_HASH256: op_hash256(); break; case OP_CODESEPARATOR: { opcount_ = 0; if (outputScriptRef_.getSize() != 0) txStubPtr_->setLastOpCodeSeparator(inputIndex_, oc.offset_); break; } case OP_CHECKSIG: op_checksig(); break; case OP_CHECKSIGVERIFY: { op_checksig(); op_verify(); break; } case OP_CHECKMULTISIG: op_checkmultisig(); break; case OP_CHECKMULTISIGVERIFY: { op_checkmultisig(); op_verify(); } case OP_NOP1: break; case OP_NOP2: { if (!(flags_ & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) break; // not enabled; treat as a NOP //CLTV mechanics throw ScriptException("OP_CLTV not supported"); } case OP_NOP3: { if (!(flags_ & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) break; // not enabled; treat as a NOP //CSV mechanics throw ScriptException("OP_CSV not supported"); } case OP_NOP4: break; case OP_NOP5: break; case OP_NOP6: break; case OP_NOP7: break; case OP_NOP8: break; case OP_NOP9: break; case OP_NOP10: break; default: { stringstream ss; ss << "unknown opcode: " << (unsigned)oc.opcode_; throw runtime_error(ss.str()); } } }
void flt_mod (mval *u, mval *v, mval *q) { int exp; int4 z, x; mval w; /* temporary mval for division result */ mval y; /* temporary mval for extended precision promotion to prevent modifying caller's data */ mval *u_orig; /* original (caller's) value of u */ error_def(ERR_DIVZERO); u_orig = u; MV_FORCE_NUM(u); MV_FORCE_NUM(v); if ((v->mvtype & MV_INT) != 0 && v->m[1] == 0) rts_error(VARLSTCNT(1) ERR_DIVZERO); if ((u->mvtype & MV_INT & v->mvtype) != 0) { /* Both are INT's; use shortcut. */ q->mvtype = MV_NM | MV_INT; eb_int_mod(u->m[1], v->m[1], q->m); return; } else if ((u->mvtype & MV_INT) != 0) { /* u is INT; promote to extended precision for compatibility with v. */ y = *u; promote(&y); /* y will be normalized, but not in canonical form */ u = &y; /* this is why we need u_orig */ } else if ((v->mvtype & MV_INT) != 0) { /* v is INT; promote to extended precision for compatibility with u. */ y = *v; promote(&y); v = &y; } /* At this point, both u and v are in extended precision format. */ /* Set w = floor(u/v). */ op_div (u, v, &w); if ((w.mvtype & MV_INT) != 0) promote(&w); exp = w.e; if (exp <= MV_XBIAS) { /* Magnitude of w, floor(u/v), is < 1. */ if (u->sgn != v->sgn && w.m[1] != 0 && exp >= EXPLO) { /* Signs differ (=> floor(u/v) < 0) and (w != 0) and (no underflow) => floor(u/v) == -1 */ w.sgn = 1; w.e = MV_XBIAS + 1; w.m[1] = MANT_LO; w.m[0] = 0; } else { /* Signs same (=> floor(u/v) >= 0) or (w == 0) or (underflow) => floor(u/v) == 0 */ *q = *u_orig; /* u - floor(u/v)*v == u - 0*v == u */ return; } } else if (exp < EXP_IDX_BIAL) { z = ten_pwr[EXP_IDX_BIAL - exp]; x = (w.m[1]/z)*z; if (u->sgn != v->sgn && (w.m[1] != x || w.m[0] != 0)) { w.m[0] = 0; w.m[1] = x + z; if (w.m[1] >= MANT_HI) { w.m[0] = w.m[0]/10 + (w.m[1]%10)*MANT_LO; w.m[1] /= 10; w.e++; } } else { w.m[0] = 0; w.m[1] = x; } } else if (exp < EXP_IDX_BIAQ) { z = ten_pwr[EXP_IDX_BIAQ - exp]; x = (w.m[0]/z)*z; if (u->sgn != v->sgn && w.m[0] != x) { w.m[0] = x + z; if (w.m[0] >= MANT_HI) { w.m[0] -= MANT_HI; w.m[1]++; } } else { w.m[0] = x; } } op_mul (&w, v, &w); /* w = w*v = floor(u/v)*v */ op_sub (u_orig, &w, q); /* q = u - w = u - floor(u/v)*v */ }
void Step() { Opcodes OP = (Opcodes)Fetch8(); //printf("%08X:%08X\n", Registers[sp], Registers[pc]); switch (OP) { case O_NOP: op_nop(); break; case O_MOV: op_mov(); break; case O_ADD: op_add(); break; case O_SUB: op_sub(); break; case O_MUL: op_mul(); break; case O_DIV: op_div(); break; case O_LI: op_li(); break; case O_MOVF: op_movf(); break; case O_ADDF: op_addf(); break; case O_SUBF: op_subf(); break; case O_MULF: op_mulf(); break; case O_DIVF: op_divf(); break; case O_LIF: op_lif(); break; case O_XOR: op_xor(); break; case O_AND: op_and(); break; case O_MOD: op_mod(); break; case O_OR: op_or(); break; case O_NOT: op_not(); break; case O_SHR: op_shr(); break; case O_SHL: op_shl(); break; case O_PUSH: op_push(); break; case O_POP: op_pop(); break; case O_STB: op_stb(); break; case O_LDB: op_ldb(); break; case O_STH: op_sth(); break; case O_LDH: op_ldh(); break; case O_STW: op_stw(); break; case O_LDW: op_ldw(); break; case O_LDF: op_ldf(); break; case O_STF: op_stf(); break; case O_CMP: op_cmp(); break; case O_B: op_b(0); break; case O_BC: op_b(1); break; case O_BEQ: op_bcond(ctr0_eq); break; case O_BNE: op_bcond(ctr0_ne); break; case O_BGT: op_bcond(ctr0_gt); break; case O_BLT: op_bcond(ctr0_lt); break; case O_BTC: op_btc(); break; case O_INC: op_inc(); break; case O_DEC: op_dec(); break; default: Error("Error: Unknown Opcode PC = %d OP = %08X\n", Registers[pc], OP); } Ticks++; }
void doop(Mips * emu, uint32_t op) { switch(op & 0xfc000000) { case 0x8000000: op_j(emu,op); return; case 0xc000000: op_jal(emu,op); return; case 0x10000000: op_beq(emu,op); return; case 0x14000000: op_bne(emu,op); return; case 0x18000000: op_blez(emu,op); return; case 0x1c000000: op_bgtz(emu,op); return; case 0x20000000: op_addi(emu,op); return; case 0x24000000: op_addiu(emu,op); return; case 0x28000000: op_slti(emu,op); return; case 0x2c000000: op_sltiu(emu,op); return; case 0x30000000: op_andi(emu,op); return; case 0x34000000: op_ori(emu,op); return; case 0x38000000: op_xori(emu,op); return; case 0x3c000000: op_lui(emu,op); return; case 0x50000000: op_beql(emu,op); return; case 0x54000000: op_bnel(emu,op); return; case 0x58000000: op_blezl(emu,op); return; case 0x80000000: op_lb(emu,op); return; case 0x84000000: op_lh(emu,op); return; case 0x88000000: op_lwl(emu,op); return; case 0x8c000000: op_lw(emu,op); return; case 0x90000000: op_lbu(emu,op); return; case 0x94000000: op_lhu(emu,op); return; case 0x98000000: op_lwr(emu,op); return; case 0xa0000000: op_sb(emu,op); return; case 0xa4000000: op_sh(emu,op); return; case 0xa8000000: op_swl(emu,op); return; case 0xac000000: op_sw(emu,op); return; case 0xb8000000: op_swr(emu,op); return; case 0xbc000000: op_cache(emu,op); return; case 0xc0000000: op_ll(emu,op); return; case 0xcc000000: op_pref(emu,op); return; case 0xe0000000: op_sc(emu,op); return; } switch(op & 0xfc00003f) { case 0x0: op_sll(emu,op); return; case 0x2: op_srl(emu,op); return; case 0x3: op_sra(emu,op); return; case 0x4: op_sllv(emu,op); return; case 0x6: op_srlv(emu,op); return; case 0x7: op_srav(emu,op); return; case 0x8: op_jr(emu,op); return; case 0x9: op_jalr(emu,op); return; case 0xc: op_syscall(emu,op); return; case 0xf: op_sync(emu,op); return; case 0x10: op_mfhi(emu,op); return; case 0x11: op_mthi(emu,op); return; case 0x12: op_mflo(emu,op); return; case 0x13: op_mtlo(emu,op); return; case 0x18: op_mult(emu,op); return; case 0x19: op_multu(emu,op); return; case 0x1a: op_div(emu,op); return; case 0x1b: op_divu(emu,op); return; case 0x20: op_add(emu,op); return; case 0x21: op_addu(emu,op); return; case 0x22: op_sub(emu,op); return; case 0x23: op_subu(emu,op); return; case 0x24: op_and(emu,op); return; case 0x25: op_or(emu,op); return; case 0x26: op_xor(emu,op); return; case 0x27: op_nor(emu,op); return; case 0x2a: op_slt(emu,op); return; case 0x2b: op_sltu(emu,op); return; case 0x2d: op_addu(emu,op); //daddu return; case 0x36: op_tne(emu,op); return; } switch(op & 0xfc1f0000) { case 0x4000000: op_bltz(emu,op); return; case 0x4010000: op_bgez(emu,op); return; case 0x4020000: op_bltzl(emu,op); return; case 0x4030000: op_bgezl(emu,op); return; case 0x4100000: op_bltzal(emu,op); return; case 0x4110000: op_bgezal(emu,op); return; case 0x5c000000: op_bgtzl(emu,op); return; } switch(op & 0xffffffff) { case 0x42000002: op_tlbwi(emu,op); return; case 0x42000006: op_tlbwr(emu,op); return; case 0x42000008: op_tlbp(emu,op); return; case 0x42000018: op_eret(emu,op); return; } switch(op & 0xfc0007ff) { case 0xa: op_movz(emu,op); return; case 0xb: op_movn(emu,op); return; case 0x70000002: op_mul(emu,op); return; } switch(op & 0xffe00000) { case 0x40000000: op_mfc0(emu,op); return; case 0x40800000: op_mtc0(emu,op); return; } switch(op & 0xfe00003f) { case 0x42000020: op_wait(emu,op); return; } // printf("unhandled opcode at %x -> %x\n",emu->pc,op); setExceptionCode(emu,EXC_RI); emu->exceptionOccured = 1; return; }
static void mc6809_run(struct MC6809 *cpu) { do { _Bool nmi_active = cpu->nmi && ((cpu->cycle - cpu->nmi_cycle) <= (UINT_MAX/2)); _Bool firq_active = cpu->firq && ((cpu->cycle - cpu->firq_cycle) <= (UINT_MAX/2)); _Bool irq_active = cpu->irq && ((cpu->cycle - cpu->irq_cycle) <= (UINT_MAX/2)); // Prevent overflow if (firq_active) cpu->firq_cycle = cpu->cycle; if (irq_active) cpu->irq_cycle = cpu->cycle; switch (cpu->state) { case mc6809_state_reset: REG_DP = 0; REG_CC |= (CC_F | CC_I); cpu->nmi = 0; cpu->nmi_armed = 0; cpu->state = mc6809_state_reset_check_halt; // fall through case mc6809_state_reset_check_halt: if (cpu->halt) { NVMA_CYCLE; continue; } REG_PC = fetch_byte(cpu, MC6809_INT_VEC_RESET) << 8; REG_PC |= fetch_byte(cpu, MC6809_INT_VEC_RESET + 1); NVMA_CYCLE; cpu->state = mc6809_state_label_a; continue; // done_instruction case for backwards-compatibility case mc6809_state_done_instruction: case mc6809_state_label_a: if (cpu->halt) { NVMA_CYCLE; continue; } cpu->state = mc6809_state_label_b; // fall through case mc6809_state_label_b: if (cpu->nmi_armed && nmi_active) { peek_byte(cpu, REG_PC); peek_byte(cpu, REG_PC); stack_irq_registers(cpu, 1); cpu->state = mc6809_state_dispatch_irq; continue; } if (!(REG_CC & CC_F) && firq_active) { peek_byte(cpu, REG_PC); peek_byte(cpu, REG_PC); stack_irq_registers(cpu, 0); cpu->state = mc6809_state_dispatch_irq; continue; } if (!(REG_CC & CC_I) && irq_active) { peek_byte(cpu, REG_PC); peek_byte(cpu, REG_PC); stack_irq_registers(cpu, 1); cpu->state = mc6809_state_dispatch_irq; continue; } cpu->state = mc6809_state_next_instruction; // Instruction fetch hook called here so that machine // can be stopped beforehand. DELEGATE_SAFE_CALL0(cpu->instruction_hook); continue; case mc6809_state_dispatch_irq: if (cpu->nmi_armed && nmi_active) { cpu->nmi = 0; REG_CC |= (CC_F | CC_I); take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_NMI); cpu->state = mc6809_state_label_a; continue; } if (!(REG_CC & CC_F) && firq_active) { REG_CC |= (CC_F | CC_I); take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_FIRQ); cpu->state = mc6809_state_label_a; continue; } if (!(REG_CC & CC_I) && irq_active) { REG_CC |= CC_I; take_interrupt(cpu, CC_I, MC6809_INT_VEC_IRQ); cpu->state = mc6809_state_label_a; continue; } cpu->state = mc6809_state_cwai_check_halt; continue; case mc6809_state_cwai_check_halt: NVMA_CYCLE; if (cpu->halt) { continue; } cpu->state = mc6809_state_dispatch_irq; continue; case mc6809_state_sync: if (nmi_active || firq_active || irq_active) { NVMA_CYCLE; NVMA_CYCLE; instruction_posthook(cpu); cpu->state = mc6809_state_label_b; continue; } NVMA_CYCLE; if (cpu->halt) cpu->state = mc6809_state_sync_check_halt; continue; case mc6809_state_sync_check_halt: NVMA_CYCLE; if (!cpu->halt) { cpu->state = mc6809_state_sync; } continue; case mc6809_state_next_instruction: { unsigned op; // Fetch op-code and process op = byte_immediate(cpu); switch (op) { // 0x00 - 0x0f direct mode ops // 0x40 - 0x4f inherent A register ops // 0x50 - 0x5f inherent B register ops // 0x60 - 0x6f indexed mode ops // 0x70 - 0x7f extended mode ops case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0f: case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4f: case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5f: case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6f: case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7f: { uint16_t ea; unsigned tmp1; switch ((op >> 4) & 0xf) { case 0x0: ea = ea_direct(cpu); tmp1 = fetch_byte(cpu, ea); break; case 0x4: ea = 0; tmp1 = RREG_A; break; case 0x5: ea = 0; tmp1 = RREG_B; break; case 0x6: ea = ea_indexed(cpu); tmp1 = fetch_byte(cpu, ea); break; case 0x7: ea = ea_extended(cpu); tmp1 = fetch_byte(cpu, ea); break; default: ea = tmp1 = 0; break; } switch (op & 0xf) { case 0x1: // NEG illegal case 0x0: tmp1 = op_neg(cpu, tmp1); break; // NEG, NEGA, NEGB case 0x2: tmp1 = op_negcom(cpu, tmp1); break; // NEGCOM illegal case 0x3: tmp1 = op_com(cpu, tmp1); break; // COM, COMA, COMB case 0x5: // LSR illegal case 0x4: tmp1 = op_lsr(cpu, tmp1); break; // LSR, LSRA, LSRB case 0x6: tmp1 = op_ror(cpu, tmp1); break; // ROR, RORA, RORB case 0x7: tmp1 = op_asr(cpu, tmp1); break; // ASR, ASRA, ASRB case 0x8: tmp1 = op_asl(cpu, tmp1); break; // ASL, ASLA, ASLB case 0x9: tmp1 = op_rol(cpu, tmp1); break; // ROL, ROLA, ROLB case 0xb: // DEC illegal case 0xa: tmp1 = op_dec(cpu, tmp1); break; // DEC, DECA, DECB case 0xc: tmp1 = op_inc(cpu, tmp1); break; // INC, INCA, INCB case 0xd: tmp1 = op_tst(cpu, tmp1); break; // TST, TSTA, TSTB case 0xf: tmp1 = op_clr(cpu, tmp1); break; // CLR, CLRA, CLRB default: break; } switch (op & 0xf) { case 0xd: // TST NVMA_CYCLE; NVMA_CYCLE; break; default: // the rest need storing switch ((op >> 4) & 0xf) { default: case 0x0: case 0x6: case 0x7: NVMA_CYCLE; store_byte(cpu, ea, tmp1); break; case 0x4: WREG_A = tmp1; peek_byte(cpu, REG_PC); break; case 0x5: WREG_B = tmp1; peek_byte(cpu, REG_PC); break; } } } break; // 0x0e JMP direct // 0x6e JMP indexed // 0x7e JMP extended case 0x0e: case 0x6e: case 0x7e: { unsigned ea; switch ((op >> 4) & 0xf) { case 0x0: ea = ea_direct(cpu); break; case 0x6: ea = ea_indexed(cpu); break; case 0x7: ea = ea_extended(cpu); break; default: ea = 0; break; } REG_PC = ea; } break; // 0x10 Page 2 case 0x10: cpu->state = mc6809_state_instruction_page_2; continue; // 0x11 Page 3 case 0x11: cpu->state = mc6809_state_instruction_page_3; continue; // 0x12 NOP inherent case 0x12: peek_byte(cpu, REG_PC); break; // 0x13 SYNC inherent case 0x13: peek_byte(cpu, REG_PC); cpu->state = mc6809_state_sync; continue; // 0x14, 0x15 HCF? (illegal) case 0x14: case 0x15: cpu->state = mc6809_state_hcf; goto done_instruction; // 0x16 LBRA relative case 0x16: { uint16_t ea; ea = long_relative(cpu); REG_PC += ea; NVMA_CYCLE; NVMA_CYCLE; } break; // 0x17 LBSR relative case 0x17: { uint16_t ea; ea = long_relative(cpu); ea += REG_PC; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; push_word(cpu, ®_S, REG_PC); REG_PC = ea; } break; // 0x18 Shift CC with mask inherent (illegal) case 0x18: REG_CC = (REG_CC << 1) & (CC_H | CC_Z); NVMA_CYCLE; peek_byte(cpu, REG_PC); break; // 0x19 DAA inherent case 0x19: { unsigned tmp = 0; if ((RREG_A&0x0f) >= 0x0a || REG_CC & CC_H) tmp |= 0x06; if (RREG_A >= 0x90 && (RREG_A&0x0f) >= 0x0a) tmp |= 0x60; if (RREG_A >= 0xa0 || REG_CC & CC_C) tmp |= 0x60; tmp += RREG_A; WREG_A = tmp; // CC.C NOT cleared, only set if appropriate CLR_NZV; SET_NZC8(tmp); peek_byte(cpu, REG_PC); } break; // 0x1a ORCC immediate case 0x1a: { unsigned data; data = byte_immediate(cpu); REG_CC |= data; peek_byte(cpu, REG_PC); } break; // 0x1b NOP inherent (illegal) case 0x1b: peek_byte(cpu, REG_PC); break; // 0x1c ANDCC immediate case 0x1c: { unsigned data; data = byte_immediate(cpu); REG_CC &= data; peek_byte(cpu, REG_PC); } break; // 0x1d SEX inherent case 0x1d: WREG_A = (RREG_B & 0x80) ? 0xff : 0; CLR_NZ; SET_NZ16(REG_D); peek_byte(cpu, REG_PC); break; // 0x1e EXG immediate case 0x1e: { unsigned postbyte; uint16_t tmp1, tmp2; postbyte = byte_immediate(cpu); switch (postbyte >> 4) { case 0x0: tmp1 = REG_D; break; case 0x1: tmp1 = REG_X; break; case 0x2: tmp1 = REG_Y; break; case 0x3: tmp1 = REG_U; break; case 0x4: tmp1 = REG_S; break; case 0x5: tmp1 = REG_PC; break; case 0x8: tmp1 = RREG_A | 0xff00; break; case 0x9: tmp1 = RREG_B | 0xff00; break; // TODO: verify this behaviour case 0xa: tmp1 = (REG_CC << 8) | REG_CC; break; case 0xb: tmp1 = (REG_DP << 8) | REG_DP; break; default: tmp1 = 0xffff; break; } switch (postbyte & 0xf) { case 0x0: tmp2 = REG_D; REG_D = tmp1; break; case 0x1: tmp2 = REG_X; REG_X = tmp1; break; case 0x2: tmp2 = REG_Y; REG_Y = tmp1; break; case 0x3: tmp2 = REG_U; REG_U = tmp1; break; case 0x4: tmp2 = REG_S; REG_S = tmp1; break; case 0x5: tmp2 = REG_PC; REG_PC = tmp1; break; case 0x8: tmp2 = RREG_A | 0xff00; WREG_A = tmp1; break; case 0x9: tmp2 = RREG_B | 0xff00; WREG_B = tmp1; break; // TODO: verify this behaviour case 0xa: tmp2 = (REG_CC << 8) | REG_CC; REG_CC = tmp1; break; case 0xb: tmp2 = (REG_DP << 8) | REG_DP; REG_DP = tmp1; break; default: tmp2 = 0xffff; break; } switch (postbyte >> 4) { case 0x0: REG_D = tmp2; break; case 0x1: REG_X = tmp2; break; case 0x2: REG_Y = tmp2; break; case 0x3: REG_U = tmp2; break; case 0x4: REG_S = tmp2; break; case 0x5: REG_PC = tmp2; break; case 0x8: WREG_A = tmp2; break; case 0x9: WREG_B = tmp2; break; case 0xa: REG_CC = tmp2; break; case 0xb: REG_DP = tmp2; break; default: break; } NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; } break; // 0x1f TFR immediate case 0x1f: { unsigned postbyte; uint16_t tmp1; postbyte = byte_immediate(cpu); switch (postbyte >> 4) { case 0x0: tmp1 = REG_D; break; case 0x1: tmp1 = REG_X; break; case 0x2: tmp1 = REG_Y; break; case 0x3: tmp1 = REG_U; break; case 0x4: tmp1 = REG_S; break; case 0x5: tmp1 = REG_PC; break; case 0x8: tmp1 = RREG_A | 0xff00; break; case 0x9: tmp1 = RREG_B | 0xff00; break; // TODO: verify this behaviour case 0xa: tmp1 = (REG_CC << 8) | REG_CC; break; case 0xb: tmp1 = (REG_DP << 8) | REG_DP; break; default: tmp1 = 0xffff; break; } switch (postbyte & 0xf) { case 0x0: REG_D = tmp1; break; case 0x1: REG_X = tmp1; break; case 0x2: REG_Y = tmp1; break; case 0x3: REG_U = tmp1; break; case 0x4: REG_S = tmp1; break; case 0x5: REG_PC = tmp1; break; case 0x8: WREG_A = tmp1; break; case 0x9: WREG_B = tmp1; break; case 0xa: REG_CC = tmp1; break; case 0xb: REG_DP = tmp1; break; default: break; } NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; } break; // 0x20 - 0x2f short branches case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: { unsigned tmp = sex8(byte_immediate(cpu)); NVMA_CYCLE; if (branch_condition(cpu, op)) REG_PC += tmp; } break; // 0x30 LEAX indexed case 0x30: REG_X = ea_indexed(cpu); CLR_Z; SET_Z(REG_X); NVMA_CYCLE; break; // 0x31 LEAY indexed case 0x31: REG_Y = ea_indexed(cpu); CLR_Z; SET_Z(REG_Y); NVMA_CYCLE; break; // 0x32 LEAS indexed case 0x32: REG_S = ea_indexed(cpu); NVMA_CYCLE; cpu->nmi_armed = 1; // XXX: Really? break; // 0x33 LEAU indexed case 0x33: REG_U = ea_indexed(cpu); NVMA_CYCLE; break; // 0x34 PSHS immediate case 0x34: psh(cpu, ®_S, REG_U); break; // 0x35 PULS immediate case 0x35: pul(cpu, ®_S, ®_U); break; // 0x36 PSHU immediate case 0x36: psh(cpu, ®_U, REG_S); break; // 0x37 PULU immediate case 0x37: pul(cpu, ®_U, ®_S); break; // 0x38 ANDCC immediate (illegal) case 0x38: { unsigned data; data = byte_immediate(cpu); REG_CC &= data; peek_byte(cpu, REG_PC); /* Differs from legal 0x1c version by * taking one more cycle: */ NVMA_CYCLE; } break; // 0x39 RTS inherent case 0x39: peek_byte(cpu, REG_PC); REG_PC = pull_word(cpu, ®_S); NVMA_CYCLE; break; // 0x3a ABX inherent case 0x3a: REG_X += RREG_B; peek_byte(cpu, REG_PC); NVMA_CYCLE; break; // 0x3b RTI inherent case 0x3b: peek_byte(cpu, REG_PC); REG_CC = pull_byte(cpu, ®_S); if (REG_CC & CC_E) { WREG_A = pull_byte(cpu, ®_S); WREG_B = pull_byte(cpu, ®_S); REG_DP = pull_byte(cpu, ®_S); REG_X = pull_word(cpu, ®_S); REG_Y = pull_word(cpu, ®_S); REG_U = pull_word(cpu, ®_S); REG_PC = pull_word(cpu, ®_S); } else { REG_PC = pull_word(cpu, ®_S); } cpu->nmi_armed = 1; peek_byte(cpu, REG_S); break; // 0x3c CWAI immediate case 0x3c: { unsigned data; data = byte_immediate(cpu); REG_CC &= data; peek_byte(cpu, REG_PC); NVMA_CYCLE; stack_irq_registers(cpu, 1); NVMA_CYCLE; cpu->state = mc6809_state_dispatch_irq; goto done_instruction; } break; // 0x3d MUL inherent case 0x3d: { unsigned tmp = RREG_A * RREG_B; REG_D = tmp; CLR_ZC; SET_Z(tmp); if (tmp & 0x80) REG_CC |= CC_C; peek_byte(cpu, REG_PC); NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; } break; // 0x3e RESET (illegal) case 0x3e: peek_byte(cpu, REG_PC); push_irq_registers(cpu); instruction_posthook(cpu); take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_RESET); cpu->state = mc6809_state_label_a; continue; // 0x3f SWI inherent case 0x3f: peek_byte(cpu, REG_PC); stack_irq_registers(cpu, 1); instruction_posthook(cpu); take_interrupt(cpu, CC_F|CC_I, MC6809_INT_VEC_SWI); cpu->state = mc6809_state_label_a; continue; // 0x80 - 0xbf A register arithmetic ops // 0xc0 - 0xff B register arithmetic ops case 0x80: case 0x81: case 0x82: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x90: case 0x91: case 0x92: case 0x94: case 0x95: case 0x96: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0xa0: case 0xa1: case 0xa2: case 0xa4: case 0xa5: case 0xa6: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xb0: case 0xb1: case 0xb2: case 0xb4: case 0xb5: case 0xb6: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xc0: case 0xc1: case 0xc2: case 0xc4: case 0xc5: case 0xc6: case 0xc7: case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xd0: case 0xd1: case 0xd2: case 0xd4: case 0xd5: case 0xd6: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe5: case 0xe6: case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xf0: case 0xf1: case 0xf2: case 0xf4: case 0xf5: case 0xf6: case 0xf8: case 0xf9: case 0xfa: case 0xfb: { unsigned tmp1, tmp2; tmp1 = !(op & 0x40) ? RREG_A : RREG_B; switch ((op >> 4) & 3) { case 0: tmp2 = byte_immediate(cpu); break; case 1: tmp2 = byte_direct(cpu); break; case 2: tmp2 = byte_indexed(cpu); break; case 3: tmp2 = byte_extended(cpu); break; default: tmp2 = 0; break; } switch (op & 0xf) { case 0x0: tmp1 = op_sub(cpu, tmp1, tmp2); break; // SUBA, SUBB case 0x1: (void)op_sub(cpu, tmp1, tmp2); break; // CMPA, CMPB case 0x2: tmp1 = op_sbc(cpu, tmp1, tmp2); break; // SBCA, SBCB case 0x4: tmp1 = op_and(cpu, tmp1, tmp2); break; // ANDA, ANDB case 0x5: (void)op_and(cpu, tmp1, tmp2); break; // BITA, BITB case 0x6: tmp1 = op_ld(cpu, 0, tmp2); break; // LDA, LDB case 0x7: tmp1 = op_discard(cpu, tmp1, tmp2); break; // illegal case 0x8: tmp1 = op_eor(cpu, tmp1, tmp2); break; // EORA, EORB case 0x9: tmp1 = op_adc(cpu, tmp1, tmp2); break; // ADCA, ADCB case 0xa: tmp1 = op_or(cpu, tmp1, tmp2); break; // ORA, ORB case 0xb: tmp1 = op_add(cpu, tmp1, tmp2); break; // ADDA, ADDB default: break; } if (!(op & 0x40)) { WREG_A = tmp1; } else { WREG_B = tmp1; } } break; // 0x83, 0x93, 0xa3, 0xb3 SUBD // 0x8c, 0x9c, 0xac, 0xbc CMPX // 0xc3, 0xd3, 0xe3, 0xf3 ADDD case 0x83: case 0x93: case 0xa3: case 0xb3: case 0x8c: case 0x9c: case 0xac: case 0xbc: case 0xc3: case 0xd3: case 0xe3: case 0xf3: { unsigned tmp1, tmp2; tmp1 = !(op & 0x08) ? REG_D : REG_X; switch ((op >> 4) & 3) { case 0: tmp2 = word_immediate(cpu); break; case 1: tmp2 = word_direct(cpu); break; case 2: tmp2 = word_indexed(cpu); break; case 3: tmp2 = word_extended(cpu); break; default: tmp2 = 0; break; } switch (op & 0x4f) { case 0x03: tmp1 = op_sub16(cpu, tmp1, tmp2); break; // SUBD case 0x0c: (void)op_sub16(cpu, tmp1, tmp2); break; // CMPX case 0x43: tmp1 = op_add16(cpu, tmp1, tmp2); break; // ADDD default: break; } NVMA_CYCLE; if (!(op & 0x08)) { REG_D = tmp1; } } break; // 0x8d BSR // 0x9d, 0xad, 0xbd JSR case 0x8d: case 0x9d: case 0xad: case 0xbd: { unsigned ea; switch ((op >> 4) & 3) { case 0: ea = short_relative(cpu); ea += REG_PC; NVMA_CYCLE; NVMA_CYCLE; NVMA_CYCLE; break; case 1: ea = ea_direct(cpu); peek_byte(cpu, ea); NVMA_CYCLE; break; case 2: ea = ea_indexed(cpu); peek_byte(cpu, ea); NVMA_CYCLE; break; case 3: ea = ea_extended(cpu); peek_byte(cpu, ea); NVMA_CYCLE; break; default: ea = 0; break; } push_word(cpu, ®_S, REG_PC); REG_PC = ea; } break; // 0x8e, 0x9e, 0xae, 0xbe LDX // 0xcc, 0xdc, 0xec, 0xfc LDD // 0xce, 0xde, 0xee, 0xfe LDU case 0x8e: case 0x9e: case 0xae: case 0xbe: case 0xcc: case 0xdc: case 0xec: case 0xfc: case 0xce: case 0xde: case 0xee: case 0xfe: { unsigned tmp1, tmp2; switch ((op >> 4) & 3) { case 0: tmp2 = word_immediate(cpu); break; case 1: tmp2 = word_direct(cpu); break; case 2: tmp2 = word_indexed(cpu); break; case 3: tmp2 = word_extended(cpu); break; default: tmp2 = 0; break; } tmp1 = op_ld16(cpu, 0, tmp2); switch (op & 0x42) { case 0x02: REG_X = tmp1; break; case 0x40: REG_D = tmp1; break; case 0x42: REG_U = tmp1; break; default: break; } } break; // 0x97, 0xa7, 0xb7 STA // 0xd7, 0xe7, 0xf7 STB case 0x97: case 0xa7: case 0xb7: case 0xd7: case 0xe7: case 0xf7: { uint16_t ea; uint8_t tmp1; tmp1 = !(op & 0x40) ? RREG_A : RREG_B; switch ((op >> 4) & 3) { case 1: ea = ea_direct(cpu); break; case 2: ea = ea_indexed(cpu); break; case 3: ea = ea_extended(cpu); break; default: ea = 0; break; } store_byte(cpu, ea, tmp1); CLR_NZV; SET_NZ8(tmp1); } break; // 0x9f, 0xaf, 0xbf STX // 0xdd, 0xed, 0xfd STD // 0xdf, 0xef, 0xff STU case 0x9f: case 0xaf: case 0xbf: case 0xdd: case 0xed: case 0xfd: case 0xdf: case 0xef: case 0xff: { uint16_t ea, tmp1; switch (op & 0x42) { case 0x02: tmp1 = REG_X; break; case 0x40: tmp1 = REG_D; break; case 0x42: tmp1 = REG_U; break; default: tmp1 = 0; break; } switch ((op >> 4) & 3) { case 1: ea = ea_direct(cpu); break; case 2: ea = ea_indexed(cpu); break; case 3: ea = ea_extended(cpu); break; default: ea = 0; break; } CLR_NZV; SET_NZ16(tmp1); store_byte(cpu, ea, tmp1 >> 8); store_byte(cpu, ea+1, tmp1); } break; // 0x8f STX immediate (illegal) // 0xcf STU immediate (illegal) // Illegal instruction only part working case 0x8f: case 0xcf: { unsigned tmp1; tmp1 = !(op & 0x40) ? REG_X : REG_U; (void)fetch_byte(cpu, REG_PC); REG_PC++; store_byte(cpu, REG_PC, tmp1); REG_PC++; CLR_NZV; REG_CC |= CC_N; } break; // 0xcd HCF? (illegal) case 0xcd: cpu->state = mc6809_state_hcf; goto done_instruction; // Illegal instruction default: NVMA_CYCLE; break; } cpu->state = mc6809_state_label_a; goto done_instruction; } case mc6809_state_instruction_page_2: { unsigned op; op = byte_immediate(cpu); switch (op) { // 0x10, 0x11 Page 2 case 0x10: case 0x11: cpu->state = mc6809_state_instruction_page_2; continue; // 0x1020 - 0x102f long branches case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: { unsigned tmp = word_immediate(cpu); if (branch_condition(cpu, op)) { REG_PC += tmp; NVMA_CYCLE; } NVMA_CYCLE; } break; // 0x103f SWI2 inherent case 0x3f: peek_byte(cpu, REG_PC); stack_irq_registers(cpu, 1); instruction_posthook(cpu); take_interrupt(cpu, 0, MC6809_INT_VEC_SWI2); cpu->state = mc6809_state_label_a; continue; // 0x1083, 0x1093, 0x10a3, 0x10b3 CMPD // 0x108c, 0x109c, 0x10ac, 0x10bc CMPY case 0x83: case 0x93: case 0xa3: case 0xb3: case 0x8c: case 0x9c: case 0xac: case 0xbc: { unsigned tmp1, tmp2; tmp1 = !(op & 0x08) ? REG_D : REG_Y; switch ((op >> 4) & 3) { case 0: tmp2 = word_immediate(cpu); break; case 1: tmp2 = word_direct(cpu); break; case 2: tmp2 = word_indexed(cpu); break; case 3: tmp2 = word_extended(cpu); break; default: tmp2 = 0; break; } (void)op_sub16(cpu, tmp1, tmp2); NVMA_CYCLE; } break; // 0x108e, 0x109e, 0x10ae, 0x10be LDY // 0x10ce, 0x10de, 0x10ee, 0x10fe LDS case 0x8e: case 0x9e: case 0xae: case 0xbe: case 0xce: case 0xde: case 0xee: case 0xfe: { unsigned tmp1, tmp2; switch ((op >> 4) & 3) { case 0: tmp2 = word_immediate(cpu); break; case 1: tmp2 = word_direct(cpu); break; case 2: tmp2 = word_indexed(cpu); break; case 3: tmp2 = word_extended(cpu); break; default: tmp2 = 0; break; } tmp1 = op_ld16(cpu, 0, tmp2); if (!(op & 0x40)) { REG_Y = tmp1; } else { REG_S = tmp1; cpu->nmi_armed = 1; } } break; // 0x109f, 0x10af, 0x10bf STY // 0x10df, 0x10ef, 0x10ff STS case 0x9f: case 0xaf: case 0xbf: case 0xdf: case 0xef: case 0xff: { unsigned ea, tmp1; tmp1 = !(op & 0x40) ? REG_Y : REG_S; switch ((op >> 4) & 3) { case 1: ea = ea_direct(cpu); break; case 2: ea = ea_indexed(cpu); break; case 3: ea = ea_extended(cpu); break; default: ea = 0; break; } CLR_NZV; SET_NZ16(tmp1); store_byte(cpu, ea, tmp1 >> 8); store_byte(cpu, ea+1, tmp1); } break; // Illegal instruction default: NVMA_CYCLE; break; } cpu->state = mc6809_state_label_a; goto done_instruction; } case mc6809_state_instruction_page_3: { unsigned op; op = byte_immediate(cpu); switch (op) { // 0x10, 0x11 Page 3 case 0x10: case 0x11: cpu->state = mc6809_state_instruction_page_3; continue; // 0x113F SWI3 inherent case 0x3f: peek_byte(cpu, REG_PC); stack_irq_registers(cpu, 1); instruction_posthook(cpu); take_interrupt(cpu, 0, MC6809_INT_VEC_SWI3); cpu->state = mc6809_state_label_a; continue; // 0x1183, 0x1193, 0x11a3, 0x11b3 CMPU // 0x118c, 0x119c, 0x11ac, 0x11bc CMPS case 0x83: case 0x93: case 0xa3: case 0xb3: case 0x8c: case 0x9c: case 0xac: case 0xbc: { unsigned tmp1, tmp2; tmp1 = !(op & 0x08) ? REG_U : REG_S; switch ((op >> 4) & 3) { case 0: tmp2 = word_immediate(cpu); break; case 1: tmp2 = word_direct(cpu); break; case 2: tmp2 = word_indexed(cpu); break; case 3: tmp2 = word_extended(cpu); break; default: tmp2 = 0; break; } (void)op_sub16(cpu, tmp1, tmp2); NVMA_CYCLE; } break; // Illegal instruction default: NVMA_CYCLE; break; } cpu->state = mc6809_state_label_a; goto done_instruction; } // Certain illegal instructions cause the CPU to lock up: case mc6809_state_hcf: NVMA_CYCLE; continue; } done_instruction: instruction_posthook(cpu); continue; } while (cpu->running); }