void disassembler::decode_modrm(x86_insn *insn) { insn->modrm = fetch_byte(); BX_DECODE_MODRM(insn->modrm, insn->mod, insn->nnn, insn->rm); // MOVs with CRx and DRx always use register ops and ignore the mod field. if ((insn->b1 & ~3) == 0x120) insn->mod = 3; if (insn->mod == 3) { /* mod, reg, reg */ return; } /* 16 bit addressing modes. */ switch (insn->mod) { case 0: resolve_modrm = &disassembler::resolve16_mod0; if(insn->rm == 6) insn->displacement.displ16 = fetch_word(); break; case 1: /* reg, 8-bit displacement, sign extend */ resolve_modrm = &disassembler::resolve16_mod1or2; insn->displacement.displ16 = (int8) fetch_byte(); break; case 2: resolve_modrm = &disassembler::resolve16_mod1or2; insn->displacement.displ16 = fetch_word(); break; } /* switch (mod) ... */ }
static uint16_t ea_extended(struct MC6809 *cpu) { unsigned ea = fetch_byte(cpu, REG_PC) << 8; ea |= fetch_byte(cpu, REG_PC+1); REG_PC += 2; NVMA_CYCLE; return ea; }
static void take_interrupt(struct MC6809 *cpu, uint8_t mask, uint16_t vec) { REG_CC |= mask; NVMA_CYCLE; DELEGATE_SAFE_CALL1(cpu->interrupt_hook, vec); unsigned new_pc = fetch_byte(cpu, vec) << 8; new_pc |= fetch_byte(cpu, vec+1); REG_PC = new_pc; NVMA_CYCLE; }
void _ldyZp(void) { byte zaddr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); res = cpu.y = fetch_byte(zaddr); set_nz(res); cpu.pc += 2; }
/* * add with carry zero page mode */ void _adcZp(void) { byte zaddr, value; zaddr = fetch_byte((word)(cpu.pc + 1)); value = fetch_byte(zaddr); ADC(value); cpu.pc += 2; }
void _oraZpx(void) { byte zaddr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.x; res = cpu.a |= fetch_byte(zaddr); set_nz(res); cpu.pc += 2; }
void _ldxZpy(void) { byte zaddr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.y; res = cpu.x = fetch_byte(zaddr); set_nz(res); cpu.pc += 2; }
void _ldaIdy(void) { byte zaddr; word addr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); addr = fetch_word(zaddr) + cpu.y; res = cpu.a = fetch_byte(addr); set_nz(res); cpu.pc += 2; }
void _eorZp(void) { byte addr; word res; addr = fetch_byte((word)(cpu.pc + 1)); res = cpu.a ^= fetch_byte(addr); set_nz(res); cpu.pc += 2; }
void _sbcZpx(void) { byte zaddr, value; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.x; value = fetch_byte(zaddr); SBC(value); cpu.pc += 2; }
void disassembler::IbIb(const x86_insn *insn) { Bit8u ib1 = fetch_byte(); Bit8u ib2 = fetch_byte(); if (intel_mode) { dis_sprintf("0x%02x, 0x%02x", ib1, ib2); } else { dis_sprintf("$0x%02x, $0x%02x", ib2, ib1); } }
/* * add with carry indirect, y mode */ void _adcIdy(void) { byte zaddr, value; word addr; zaddr = fetch_byte((word)(cpu.pc + 1)); addr = fetch_word(zaddr) + cpu.y; value = fetch_byte(addr); ADC(value); cpu.pc += 2; }
void _sbcIdx(void) { byte zaddr, value; word addr; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.x; addr = fetch_word(zaddr); value = fetch_byte(addr); SBC(value); cpu.pc += 2; }
void _cpyZp(void) { byte zaddr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); res = cpu.y - fetch_byte(zaddr); set_carry(res < 0x100); set_nz(res); cpu.pc += 2; }
void _cmpZpx(void) { byte zaddr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.x; res = cpu.a - fetch_byte(zaddr); set_carry(res < 0x100); set_nz(res); cpu.pc += 2; }
/* * run the cpu */ void cpu_run(void) { byte i; const Instr *pi; cpu_reset(); do { /* check for pending interrupts */ if (!get_int_disable_flag() && (pending_interrupt & HANDLE_IRQ)) DO_INTERRUPT(); if (pending_interrupt & HANDLE_NMI) { pending_interrupt &= ~HANDLE_NMI; DO_NMI(); } /* fetch the next instruction */ i = fetch_byte(cpu.pc); pi = instructions[i]; if (NULL == pi) { warning("unrecognized instruction \"$%.2x\" at $%.4hx.\n", i, cpu.pc); break; } /* execute the instruction */ (*pi->fnc)(); } while (!err); }
void _decZp(void) { byte addr; word res; addr = fetch_byte((word)(cpu.pc + 1)); res = fetch_byte(addr); res = (res - 1) & 0xFF; store_byte(addr, (byte)res); set_nz(res); cpu.pc += 2; }
void _andIdx(void) { byte zaddr; word addr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.x; addr = fetch_word(zaddr); res = cpu.a &= fetch_byte(addr); set_nz(res); cpu.pc += 2; }
void _incZpx(void) { byte addr; word res; addr = fetch_byte((word)(cpu.pc + 1)); addr += cpu.x; res = fetch_byte(addr); res = (res + 1) & 0xFF; store_byte(addr, (byte)res); set_nz(res); cpu.pc += 2; }
void _bcs(void) { byte b; b = fetch_byte((word)(cpu.pc + 1)); cpu.pc += 2; if (get_carry_flag()) branch(b); }
void _cmpIdy(void) { byte zaddr; word addr; word res; zaddr = fetch_byte((word)(cpu.pc + 1)); addr = fetch_word(zaddr) + cpu.y; res = cpu.a - fetch_byte(addr); set_carry(res < 0x100); set_nz(res); cpu.pc += 2; }
void _bvs(void) { byte b; b = fetch_byte((word)(cpu.pc + 1)); cpu.pc += 2; if (get_overflow_flag()) branch(b); }
void _bpl(void) { byte b; b = fetch_byte((word)(cpu.pc + 1)); cpu.pc += 2; if (!get_neg_flag()) branch(b); }
void _bne(void) { byte b; b = fetch_byte((word)(cpu.pc + 1)); cpu.pc += 2; if (!get_zero_flag()) branch(b); }
/* * pop a value from the stack */ byte pop(void) { if (cpu.sp == STACKBEGIN) { warning("stack underflow error.\n"); err = 1; return 0; } return fetch_byte((word)(PAGEONE + ++cpu.sp)); }
void _aslZpx(void) { byte zaddr; zaddr = fetch_byte((word)(cpu.pc + 1)); ASL((word)(zaddr + cpu.x)); cpu.pc += 2; }
void _bitZp(void) { byte zaddr; zaddr = fetch_byte((word)(cpu.pc + 1)); BIT(zaddr); cpu.pc += 2; }
void _aslZp(void) { byte zaddr; zaddr = fetch_byte((word)(cpu.pc + 1)); ASL(zaddr); cpu.pc += 2; }
/* * add with carry immediate mode */ void _adcImm(void) { byte value; value = fetch_byte((word)(cpu.pc + 1)); ADC(value); cpu.pc += 2; }
void _styZpx(void) { byte zaddr; zaddr = fetch_byte((word)(cpu.pc + 1)); zaddr += cpu.x; store_byte(zaddr, cpu.y); cpu.pc += 2; }