o add missing files

This commit is contained in:
David Voswinkel
2009-05-12 22:20:41 +02:00
parent 8e877d38d4
commit 09198f5099
149 changed files with 43548 additions and 0 deletions

3
tools/bsnes/cpu/core/bpp.sh Executable file
View File

@@ -0,0 +1,3 @@
clear
bpp opcode_functions.cpp opcode_functions.bpp
bpp opcode_headers.hpp opcode_headers.bpp

51
tools/bsnes/cpu/core/core.cpp Executable file
View File

@@ -0,0 +1,51 @@
#include <../base.hpp>
#define CPUCORE_CPP
namespace SNES {
#include "opcode_algorithms.cpp"
#include "opcode_functions.cpp"
#include "opcode_tables.cpp"
#include "disasm/disasm.cpp"
//immediate, 2-cycle opcodes with I/O cycle will become bus read
//when an IRQ is to be triggered immediately after opcode completion.
//this affects the following opcodes:
// clc, cld, cli, clv, sec, sed, sei,
// tax, tay, txa, txy, tya, tyx,
// tcd, tcs, tdc, tsc, tsx, txs,
// inc, inx, iny, dec, dex, dey,
// asl, lsr, rol, ror, nop, xce.
alwaysinline void CPUcore::op_io_irq() {
if(interrupt_pending()) {
//modify I/O cycle to bus read cycle, do not increment PC
op_read(regs.pc.d);
} else {
op_io();
}
}
alwaysinline void CPUcore::op_io_cond2() {
if(regs.d.l != 0x00) {
op_io();
}
}
alwaysinline void CPUcore::op_io_cond4(uint16 x, uint16 y) {
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
op_io();
}
}
alwaysinline void CPUcore::op_io_cond6(uint16 addr) {
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
op_io();
}
}
CPUcore::CPUcore() {
initialize_opcode_table();
}
};

79
tools/bsnes/cpu/core/core.hpp Executable file
View File

@@ -0,0 +1,79 @@
class CPUcore {
public:
#include "registers.hpp"
#include "memory.hpp"
#include "opcode_headers.hpp"
#include "disasm/disasm.hpp"
regs_t regs;
reg24_t aa, rd;
uint8_t sp, dp;
virtual void op_io() = 0;
virtual uint8_t op_read(uint32_t addr) = 0;
virtual void op_write(uint32_t addr, uint8_t data) = 0;
virtual void last_cycle() = 0;
virtual bool interrupt_pending() = 0;
void op_io_irq();
void op_io_cond2();
void op_io_cond4(uint16 x, uint16 y);
void op_io_cond6(uint16 addr);
void op_adc_b();
void op_adc_w();
void op_and_b();
void op_and_w();
void op_bit_b();
void op_bit_w();
void op_cmp_b();
void op_cmp_w();
void op_cpx_b();
void op_cpx_w();
void op_cpy_b();
void op_cpy_w();
void op_eor_b();
void op_eor_w();
void op_lda_b();
void op_lda_w();
void op_ldx_b();
void op_ldx_w();
void op_ldy_b();
void op_ldy_w();
void op_ora_b();
void op_ora_w();
void op_sbc_b();
void op_sbc_w();
void op_inc_b();
void op_inc_w();
void op_dec_b();
void op_dec_w();
void op_asl_b();
void op_asl_w();
void op_lsr_b();
void op_lsr_w();
void op_rol_b();
void op_rol_w();
void op_ror_b();
void op_ror_w();
void op_trb_b();
void op_trb_w();
void op_tsb_b();
void op_tsb_w();
void (CPUcore::**opcode_table)();
void (CPUcore::*op_table[256 * 5])();
void initialize_opcode_table();
void update_table();
enum {
table_EM = 0, // 8-bit accumulator, 8-bit index (emulation mode)
table_MX = 256, // 8-bit accumulator, 8-bit index
table_Mx = 512, // 8-bit accumulator, 16-bit index
table_mX = 768, //16-bit accumulator, 8-bit index
table_mx = 1024, //16-bit accumulator, 16-bit index
};
CPUcore();
};

View File

@@ -0,0 +1,479 @@
uint8 CPUcore::dreadb(uint32 addr) {
if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) {
//$[00-3f|80-bf]:[2000-5fff]
//do not read MMIO registers within debugger
return 0x00;
}
return bus.read(addr);
}
uint16 CPUcore::dreadw(uint32 addr) {
uint16 r;
r = dreadb((addr + 0) & 0xffffff) << 0;
r |= dreadb((addr + 1) & 0xffffff) << 8;
return r;
}
uint32 CPUcore::dreadl(uint32 addr) {
uint32 r;
r = dreadb((addr + 0) & 0xffffff) << 0;
r |= dreadb((addr + 1) & 0xffffff) << 8;
r |= dreadb((addr + 2) & 0xffffff) << 16;
return r;
}
uint32 CPUcore::decode(uint8 offset_type, uint32 addr) {
uint32 r = 0;
switch(offset_type) {
case OPTYPE_DP:
r = (regs.d + (addr & 0xffff)) & 0xffff;
break;
case OPTYPE_DPX:
r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
break;
case OPTYPE_DPY:
r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
break;
case OPTYPE_IDP:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
r = (regs.db << 16) + dreadw(addr);
break;
case OPTYPE_IDPX:
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
r = (regs.db << 16) + dreadw(addr);
break;
case OPTYPE_IDPY:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
r = (regs.db << 16) + dreadw(addr) + regs.y;
break;
case OPTYPE_ILDP:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
r = dreadl(addr);
break;
case OPTYPE_ILDPY:
addr = (regs.d + (addr & 0xffff)) & 0xffff;
r = dreadl(addr) + regs.y;
break;
case OPTYPE_ADDR:
r = (regs.db << 16) + (addr & 0xffff);
break;
case OPTYPE_ADDR_PC:
r = (regs.pc.b << 16) + (addr & 0xffff);
break;
case OPTYPE_ADDRX:
r = (regs.db << 16) + (addr & 0xffff) + regs.x;
break;
case OPTYPE_ADDRY:
r = (regs.db << 16) + (addr & 0xffff) + regs.y;
break;
case OPTYPE_IADDR_PC:
r = (regs.pc.b << 16) + (addr & 0xffff);
break;
case OPTYPE_IADDRX:
r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff);
break;
case OPTYPE_ILADDR:
r = addr;
break;
case OPTYPE_LONG:
r = addr;
break;
case OPTYPE_LONGX:
r = (addr + regs.x);
break;
case OPTYPE_SR:
r = (regs.s + (addr & 0xff)) & 0xffff;
break;
case OPTYPE_ISRY:
addr = (regs.s + (addr & 0xff)) & 0xffff;
r = (regs.db << 16) + dreadw(addr) + regs.y;
break;
case OPTYPE_RELB:
r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff);
r += int8(addr);
break;
case OPTYPE_RELW:
r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff);
r += int16(addr);
break;
}
return(r & 0xffffff);
}
void CPUcore::disassemble_opcode(char *output) {
static reg24_t pc;
char t[256];
char *s = output;
if(false /* in_opcode() == true */) {
strcpy(s, "?????? <CPU within opcode>");
return;
}
pc.d = regs.pc.d;
sprintf(s, "%.6x ", (uint32)pc.d);
uint8 op = dreadb(pc.d); pc.w++;
uint8 op0 = dreadb(pc.d); pc.w++;
uint8 op1 = dreadb(pc.d); pc.w++;
uint8 op2 = dreadb(pc.d);
#define op8 ((op0))
#define op16 ((op0) | (op1 << 8))
#define op24 ((op0) | (op1 << 8) | (op2 << 16))
#define a8 (regs.e || regs.p.m)
#define x8 (regs.e || regs.p.x)
switch(op) {
case 0x00: sprintf(t, "brk #$%.2x ", op8); break;
case 0x01: sprintf(t, "ora ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0x02: sprintf(t, "cop #$%.2x ", op8); break;
case 0x03: sprintf(t, "ora $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0x04: sprintf(t, "tsb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x05: sprintf(t, "ora $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x06: sprintf(t, "asl $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x07: sprintf(t, "ora [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0x08: sprintf(t, "php "); break;
case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8);
else sprintf(t, "ora #$%.4x ", op16); break;
case 0x0a: sprintf(t, "asl a "); break;
case 0x0b: sprintf(t, "phd "); break;
case 0x0c: sprintf(t, "tsb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x0d: sprintf(t, "ora $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x0e: sprintf(t, "asl $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x0f: sprintf(t, "ora $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x10: sprintf(t, "bpl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0x11: sprintf(t, "ora ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0x12: sprintf(t, "ora ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0x13: sprintf(t, "ora ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0x14: sprintf(t, "trb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x15: sprintf(t, "ora $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x16: sprintf(t, "asl $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x17: sprintf(t, "ora [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0x18: sprintf(t, "clc "); break;
case 0x19: sprintf(t, "ora $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0x1a: sprintf(t, "inc "); break;
case 0x1b: sprintf(t, "tcs "); break;
case 0x1c: sprintf(t, "trb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x1d: sprintf(t, "ora $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x1e: sprintf(t, "asl $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x1f: sprintf(t, "ora $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0x20: sprintf(t, "jsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
case 0x21: sprintf(t, "and ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0x22: sprintf(t, "jsl $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x23: sprintf(t, "and $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0x24: sprintf(t, "bit $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x25: sprintf(t, "and $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x26: sprintf(t, "rol $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x27: sprintf(t, "and [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0x28: sprintf(t, "plp "); break;
case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8);
else sprintf(t, "and #$%.4x ", op16); break;
case 0x2a: sprintf(t, "rol a "); break;
case 0x2b: sprintf(t, "pld "); break;
case 0x2c: sprintf(t, "bit $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x2d: sprintf(t, "and $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x2e: sprintf(t, "rol $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x2f: sprintf(t, "and $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x30: sprintf(t, "bmi $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0x31: sprintf(t, "and ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0x32: sprintf(t, "and ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0x33: sprintf(t, "and ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0x34: sprintf(t, "bit $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x35: sprintf(t, "and $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x36: sprintf(t, "rol $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x37: sprintf(t, "and [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0x38: sprintf(t, "sec "); break;
case 0x39: sprintf(t, "and $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0x3a: sprintf(t, "dec "); break;
case 0x3b: sprintf(t, "tsc "); break;
case 0x3c: sprintf(t, "bit $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x3d: sprintf(t, "and $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x3e: sprintf(t, "rol $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x3f: sprintf(t, "and $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0x40: sprintf(t, "rti "); break;
case 0x41: sprintf(t, "eor ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0x42: sprintf(t, "wdm "); break;
case 0x43: sprintf(t, "eor $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break;
case 0x45: sprintf(t, "eor $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x46: sprintf(t, "lsr $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x47: sprintf(t, "eor [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0x48: sprintf(t, "pha "); break;
case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8);
else sprintf(t, "eor #$%.4x ", op16); break;
case 0x4a: sprintf(t, "lsr a "); break;
case 0x4b: sprintf(t, "phk "); break;
case 0x4c: sprintf(t, "jmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
case 0x4d: sprintf(t, "eor $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x4e: sprintf(t, "lsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x4f: sprintf(t, "eor $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x50: sprintf(t, "bvc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0x51: sprintf(t, "eor ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0x52: sprintf(t, "eor ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0x53: sprintf(t, "eor ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break;
case 0x55: sprintf(t, "eor $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x56: sprintf(t, "lsr $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x57: sprintf(t, "eor [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0x58: sprintf(t, "cli "); break;
case 0x59: sprintf(t, "eor $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0x5a: sprintf(t, "phy "); break;
case 0x5b: sprintf(t, "tcd "); break;
case 0x5c: sprintf(t, "jml $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x5d: sprintf(t, "eor $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x5e: sprintf(t, "lsr $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x5f: sprintf(t, "eor $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0x60: sprintf(t, "rts "); break;
case 0x61: sprintf(t, "adc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0x62: sprintf(t, "per $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x63: sprintf(t, "adc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0x64: sprintf(t, "stz $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x65: sprintf(t, "adc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x66: sprintf(t, "ror $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x67: sprintf(t, "adc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0x68: sprintf(t, "pla "); break;
case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8);
else sprintf(t, "adc #$%.4x ", op16); break;
case 0x6a: sprintf(t, "ror a "); break;
case 0x6b: sprintf(t, "rtl "); break;
case 0x6c: sprintf(t, "jmp ($%.4x) [$%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break;
case 0x6d: sprintf(t, "adc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x6e: sprintf(t, "ror $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x6f: sprintf(t, "adc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x70: sprintf(t, "bvs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0x71: sprintf(t, "adc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0x72: sprintf(t, "adc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0x73: sprintf(t, "adc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0x74: sprintf(t, "stz $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x75: sprintf(t, "adc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x76: sprintf(t, "ror $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x77: sprintf(t, "adc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0x78: sprintf(t, "sei "); break;
case 0x79: sprintf(t, "adc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0x7a: sprintf(t, "ply "); break;
case 0x7b: sprintf(t, "tdc "); break;
case 0x7c: sprintf(t, "jmp ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
case 0x7d: sprintf(t, "adc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x7e: sprintf(t, "ror $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x7f: sprintf(t, "adc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0x80: sprintf(t, "bra $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0x81: sprintf(t, "sta ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0x82: sprintf(t, "brl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
case 0x83: sprintf(t, "sta $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0x84: sprintf(t, "sty $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x85: sprintf(t, "sta $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x86: sprintf(t, "stx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0x87: sprintf(t, "sta [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0x88: sprintf(t, "dey "); break;
case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8);
else sprintf(t, "bit #$%.4x ", op16); break;
case 0x8a: sprintf(t, "txa "); break;
case 0x8b: sprintf(t, "phb "); break;
case 0x8c: sprintf(t, "sty $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x8d: sprintf(t, "sta $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x8e: sprintf(t, "stx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x8f: sprintf(t, "sta $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0x90: sprintf(t, "bcc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0x91: sprintf(t, "sta ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0x92: sprintf(t, "sta ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0x93: sprintf(t, "sta ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0x94: sprintf(t, "sty $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x95: sprintf(t, "sta $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0x96: sprintf(t, "stx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
case 0x97: sprintf(t, "sta [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0x98: sprintf(t, "tya "); break;
case 0x99: sprintf(t, "sta $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0x9a: sprintf(t, "txs "); break;
case 0x9b: sprintf(t, "txy "); break;
case 0x9c: sprintf(t, "stz $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0x9d: sprintf(t, "sta $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x9e: sprintf(t, "stz $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0x9f: sprintf(t, "sta $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8);
else sprintf(t, "ldy #$%.4x ", op16); break;
case 0xa1: sprintf(t, "lda ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8);
else sprintf(t, "ldx #$%.4x ", op16); break;
case 0xa3: sprintf(t, "lda $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0xa4: sprintf(t, "ldy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xa5: sprintf(t, "lda $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xa6: sprintf(t, "ldx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xa7: sprintf(t, "lda [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0xa8: sprintf(t, "tay "); break;
case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8);
else sprintf(t, "lda #$%.4x ", op16); break;
case 0xaa: sprintf(t, "tax "); break;
case 0xab: sprintf(t, "plb "); break;
case 0xac: sprintf(t, "ldy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xad: sprintf(t, "lda $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xae: sprintf(t, "ldx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xaf: sprintf(t, "lda $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0xb0: sprintf(t, "bcs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0xb1: sprintf(t, "lda ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0xb2: sprintf(t, "lda ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0xb3: sprintf(t, "lda ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0xb4: sprintf(t, "ldy $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0xb5: sprintf(t, "lda $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0xb6: sprintf(t, "ldx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
case 0xb7: sprintf(t, "lda [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0xb8: sprintf(t, "clv "); break;
case 0xb9: sprintf(t, "lda $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0xba: sprintf(t, "tsx "); break;
case 0xbb: sprintf(t, "tyx "); break;
case 0xbc: sprintf(t, "ldy $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0xbd: sprintf(t, "lda $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0xbe: sprintf(t, "ldx $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0xbf: sprintf(t, "lda $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8);
else sprintf(t, "cpy #$%.4x ", op16); break;
case 0xc1: sprintf(t, "cmp ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0xc2: sprintf(t, "rep #$%.2x ", op8); break;
case 0xc3: sprintf(t, "cmp $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0xc4: sprintf(t, "cpy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xc5: sprintf(t, "cmp $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xc6: sprintf(t, "dec $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xc7: sprintf(t, "cmp [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0xc8: sprintf(t, "iny "); break;
case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8);
else sprintf(t, "cmp #$%.4x ", op16); break;
case 0xca: sprintf(t, "dex "); break;
case 0xcb: sprintf(t, "wai "); break;
case 0xcc: sprintf(t, "cpy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xcd: sprintf(t, "cmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xce: sprintf(t, "dec $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xcf: sprintf(t, "cmp $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0xd0: sprintf(t, "bne $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0xd1: sprintf(t, "cmp ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0xd2: sprintf(t, "cmp ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0xd3: sprintf(t, "cmp ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0xd4: sprintf(t, "pei ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0xd5: sprintf(t, "cmp $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0xd6: sprintf(t, "dec $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0xd7: sprintf(t, "cmp [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0xd8: sprintf(t, "cld "); break;
case 0xd9: sprintf(t, "cmp $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0xda: sprintf(t, "phx "); break;
case 0xdb: sprintf(t, "stp "); break;
case 0xdc: sprintf(t, "jmp [$%.4x] [$%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break;
case 0xdd: sprintf(t, "cmp $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0xde: sprintf(t, "dec $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0xdf: sprintf(t, "cmp $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8);
else sprintf(t, "cpx #$%.4x ", op16); break;
case 0xe1: sprintf(t, "sbc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
case 0xe2: sprintf(t, "sep #$%.2x ", op8); break;
case 0xe3: sprintf(t, "sbc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
case 0xe4: sprintf(t, "cpx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xe5: sprintf(t, "sbc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xe6: sprintf(t, "inc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
case 0xe7: sprintf(t, "sbc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
case 0xe8: sprintf(t, "inx "); break;
case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8);
else sprintf(t, "sbc #$%.4x ", op16); break;
case 0xea: sprintf(t, "nop "); break;
case 0xeb: sprintf(t, "xba "); break;
case 0xec: sprintf(t, "cpx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xed: sprintf(t, "sbc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xee: sprintf(t, "inc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xef: sprintf(t, "sbc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
case 0xf0: sprintf(t, "beq $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
case 0xf1: sprintf(t, "sbc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
case 0xf2: sprintf(t, "sbc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
case 0xf3: sprintf(t, "sbc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
case 0xf4: sprintf(t, "pea $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
case 0xf5: sprintf(t, "sbc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0xf6: sprintf(t, "inc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
case 0xf7: sprintf(t, "sbc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
case 0xf8: sprintf(t, "sed "); break;
case 0xf9: sprintf(t, "sbc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
case 0xfa: sprintf(t, "plx "); break;
case 0xfb: sprintf(t, "xce "); break;
case 0xfc: sprintf(t, "jsr ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
case 0xfd: sprintf(t, "sbc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0xfe: sprintf(t, "inc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
case 0xff: sprintf(t, "sbc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
}
#undef op8
#undef op16
#undef op24
#undef a8
#undef x8
strcat(s, t);
strcat(s, " ");
sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ",
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db);
strcat(s, t);
if(regs.e) {
sprintf(t, "%c%c%c%c%c%c%c%c",
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b',
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
} else {
sprintf(t, "%c%c%c%c%c%c%c%c",
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x',
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
}
strcat(s, t);
strcat(s, " ");
sprintf(t, "V:%3d H:%4d", ppu.vcounter(), ppu.hcounter());
strcat(s, t);
}
//opcode_length() retrieves the length of the next opcode
//to be executed. It is used by the debugger to step over,
//disable and proceed cpu opcodes.
//
//5 and 6 are special cases, 5 is used for #consts based on
//the A register size, 6 for the X/Y register size. the
//rest are literal sizes. There's no need to test for
//emulation mode, as regs.p.m/regs.p.x should *always* be
//set in emulation mode.
uint8 CPUcore::opcode_length() {
uint8 op, len;
static uint8 op_len_tbl[256] = {
//0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f
2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n
3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n
1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n
2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n
1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n
2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n
6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen
2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn
};
if(false /* in_opcode() == true */) {
return 0;
}
op = dreadb(regs.pc.d);
len = op_len_tbl[op];
if(len == 5) return (regs.e || regs.p.m) ? 2 : 3;
if(len == 6) return (regs.e || regs.p.x) ? 2 : 3;
return len;
}

View File

@@ -0,0 +1,30 @@
enum {
OPTYPE_DP = 0, //dp
OPTYPE_DPX, //dp,x
OPTYPE_DPY, //dp,y
OPTYPE_IDP, //(dp)
OPTYPE_IDPX, //(dp,x)
OPTYPE_IDPY, //(dp),y
OPTYPE_ILDP, //[dp]
OPTYPE_ILDPY, //[dp],y
OPTYPE_ADDR, //addr
OPTYPE_ADDRX, //addr,x
OPTYPE_ADDRY, //addr,y
OPTYPE_IADDRX, //(addr,x)
OPTYPE_ILADDR, //[addr]
OPTYPE_LONG, //long
OPTYPE_LONGX, //long, x
OPTYPE_SR, //sr,s
OPTYPE_ISRY, //(sr,s),y
OPTYPE_ADDR_PC, //pbr:addr
OPTYPE_IADDR_PC, //pbr:(addr)
OPTYPE_RELB, //relb
OPTYPE_RELW, //relw
};
void disassemble_opcode(char *output);
uint8 dreadb(uint32 addr);
uint16 dreadw(uint32 addr);
uint32 dreadl(uint32 addr);
uint32 decode(uint8 offset_type, uint32 addr);
uint8 opcode_length();

77
tools/bsnes/cpu/core/memory.hpp Executable file
View File

@@ -0,0 +1,77 @@
alwaysinline uint8_t op_readpc() {
return op_read((regs.pc.b << 16) + regs.pc.w++);
}
alwaysinline uint8_t op_readstack() {
regs.e ? regs.s.l++ : regs.s.w++;
return op_read(regs.s.w);
}
alwaysinline uint8_t op_readstackn() {
return op_read(++regs.s.w);
}
alwaysinline uint8_t op_readaddr(uint32_t addr) {
return op_read(addr & 0xffff);
}
alwaysinline uint8_t op_readlong(uint32_t addr) {
return op_read(addr & 0xffffff);
}
alwaysinline uint8_t op_readdbr(uint32_t addr) {
return op_read(((regs.db << 16) + addr) & 0xffffff);
}
alwaysinline uint8_t op_readpbr(uint32_t addr) {
return op_read((regs.pc.b << 16) + (addr & 0xffff));
}
alwaysinline uint8_t op_readdp(uint32_t addr) {
if(regs.e && regs.d.l == 0x00) {
return op_read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff));
} else {
return op_read((regs.d + (addr & 0xffff)) & 0xffff);
}
}
alwaysinline uint8_t op_readsp(uint32_t addr) {
return op_read((regs.s + (addr & 0xffff)) & 0xffff);
}
alwaysinline void op_writestack(uint8_t data) {
op_write(regs.s.w, data);
regs.e ? regs.s.l-- : regs.s.w--;
}
alwaysinline void op_writestackn(uint8_t data) {
op_write(regs.s.w--, data);
}
alwaysinline void op_writeaddr(uint32_t addr, uint8_t data) {
op_write(addr & 0xffff, data);
}
alwaysinline void op_writelong(uint32_t addr, uint8_t data) {
op_write(addr & 0xffffff, data);
}
alwaysinline void op_writedbr(uint32_t addr, uint8_t data) {
op_write(((regs.db << 16) + addr) & 0xffffff, data);
}
alwaysinline void op_writepbr(uint32_t addr, uint8_t data) {
op_write((regs.pc.b << 16) + (addr & 0xffff), data);
}
alwaysinline void op_writedp(uint32_t addr, uint8_t data) {
if(regs.e && regs.d.l == 0x00) {
op_write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data);
} else {
op_write((regs.d + (addr & 0xffff)) & 0xffff, data);
}
}
alwaysinline void op_writesp(uint32_t addr, uint8_t data) {
op_write((regs.s + (addr & 0xffff)) & 0xffff, data);
}

View File

@@ -0,0 +1,369 @@
#ifdef CPUCORE_CPP
inline void CPUcore::op_adc_b() {
int r;
if(regs.p.d) {
uint8 n0 = (regs.a.l ) & 15;
uint8 n1 = (regs.a.l >> 4) & 15;
n0 += (rd.l & 15) + regs.p.c;
if(n0 > 9) {
n0 = (n0 - 10) & 15;
n1++;
}
n1 += ((rd.l >> 4) & 15);
if(n1 > 9) {
n1 = (n1 - 10) & 15;
regs.p.c = 1;
} else {
regs.p.c = 0;
}
r = (n1 << 4) | n0;
} else {
r = regs.a.l + rd.l + regs.p.c;
regs.p.c = r > 0xff;
}
regs.p.n = r & 0x80;
regs.p.v = ~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80;
regs.p.z = (uint8)r == 0;
regs.a.l = r;
}
inline void CPUcore::op_adc_w() {
int r;
if(regs.p.d) {
uint8 n0 = (regs.a.w ) & 15;
uint8 n1 = (regs.a.w >> 4) & 15;
uint8 n2 = (regs.a.w >> 8) & 15;
uint8 n3 = (regs.a.w >> 12) & 15;
n0 += (rd.w & 15) + regs.p.c;
if(n0 > 9) {
n0 = (n0 - 10) & 15;
n1++;
}
n1 += ((rd.w >> 4) & 15);
if(n1 > 9) {
n1 = (n1 - 10) & 15;
n2++;
}
n2 += ((rd.w >> 8) & 15);
if(n2 > 9) {
n2 = (n2 - 10) & 15;
n3++;
}
n3 += ((rd.w >> 12) & 15);
if(n3 > 9) {
n3 = (n3 - 10) & 15;
regs.p.c = 1;
} else {
regs.p.c = 0;
}
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | n0;
} else {
r = regs.a.w + rd.w + regs.p.c;
regs.p.c = r > 0xffff;
}
regs.p.n = r & 0x8000;
regs.p.v = ~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000;
regs.p.z = (uint16)r == 0;
regs.a.w = r;
}
inline void CPUcore::op_and_b() {
regs.a.l &= rd.l;
regs.p.n = regs.a.l & 0x80;
regs.p.z = regs.a.l == 0;
}
inline void CPUcore::op_and_w() {
regs.a.w &= rd.w;
regs.p.n = regs.a.w & 0x8000;
regs.p.z = regs.a.w == 0;
}
inline void CPUcore::op_bit_b() {
regs.p.n = rd.l & 0x80;
regs.p.v = rd.l & 0x40;
regs.p.z = (rd.l & regs.a.l) == 0;
}
inline void CPUcore::op_bit_w() {
regs.p.n = rd.w & 0x8000;
regs.p.v = rd.w & 0x4000;
regs.p.z = (rd.w & regs.a.w) == 0;
}
inline void CPUcore::op_cmp_b() {
int r = regs.a.l - rd.l;
regs.p.n = r & 0x80;
regs.p.z = (uint8)r == 0;
regs.p.c = r >= 0;
}
inline void CPUcore::op_cmp_w() {
int r = regs.a.w - rd.w;
regs.p.n = r & 0x8000;
regs.p.z = (uint16)r == 0;
regs.p.c = r >= 0;
}
inline void CPUcore::op_cpx_b() {
int r = regs.x.l - rd.l;
regs.p.n = r & 0x80;
regs.p.z = (uint8)r == 0;
regs.p.c = r >= 0;
}
inline void CPUcore::op_cpx_w() {
int r = regs.x.w - rd.w;
regs.p.n = r & 0x8000;
regs.p.z = (uint16)r == 0;
regs.p.c = r >= 0;
}
inline void CPUcore::op_cpy_b() {
int r = regs.y.l - rd.l;
regs.p.n = r & 0x80;
regs.p.z = (uint8)r == 0;
regs.p.c = r >= 0;
}
inline void CPUcore::op_cpy_w() {
int r = regs.y.w - rd.w;
regs.p.n = r & 0x8000;
regs.p.z = (uint16)r == 0;
regs.p.c = r >= 0;
}
inline void CPUcore::op_eor_b() {
regs.a.l ^= rd.l;
regs.p.n = regs.a.l & 0x80;
regs.p.z = regs.a.l == 0;
}
inline void CPUcore::op_eor_w() {
regs.a.w ^= rd.w;
regs.p.n = regs.a.w & 0x8000;
regs.p.z = regs.a.w == 0;
}
inline void CPUcore::op_lda_b() {
regs.a.l = rd.l;
regs.p.n = regs.a.l & 0x80;
regs.p.z = regs.a.l == 0;
}
inline void CPUcore::op_lda_w() {
regs.a.w = rd.w;
regs.p.n = regs.a.w & 0x8000;
regs.p.z = regs.a.w == 0;
}
inline void CPUcore::op_ldx_b() {
regs.x.l = rd.l;
regs.p.n = regs.x.l & 0x80;
regs.p.z = regs.x.l == 0;
}
inline void CPUcore::op_ldx_w() {
regs.x.w = rd.w;
regs.p.n = regs.x.w & 0x8000;
regs.p.z = regs.x.w == 0;
}
inline void CPUcore::op_ldy_b() {
regs.y.l = rd.l;
regs.p.n = regs.y.l & 0x80;
regs.p.z = regs.y.l == 0;
}
inline void CPUcore::op_ldy_w() {
regs.y.w = rd.w;
regs.p.n = regs.y.w & 0x8000;
regs.p.z = regs.y.w == 0;
}
inline void CPUcore::op_ora_b() {
regs.a.l |= rd.l;
regs.p.n = regs.a.l & 0x80;
regs.p.z = regs.a.l == 0;
}
inline void CPUcore::op_ora_w() {
regs.a.w |= rd.w;
regs.p.n = regs.a.w & 0x8000;
regs.p.z = regs.a.w == 0;
}
inline void CPUcore::op_sbc_b() {
int r;
if(regs.p.d) {
uint8 n0 = (regs.a.l ) & 15;
uint8 n1 = (regs.a.l >> 4) & 15;
n0 -= ((rd.l ) & 15) + !regs.p.c;
n1 -= ((rd.l >> 4) & 15);
if(n0 > 9) {
n0 += 10;
n1--;
}
if(n1 > 9) {
n1 += 10;
regs.p.c = 0;
} else {
regs.p.c = 1;
}
r = (n1 << 4) | (n0);
} else {
r = regs.a.l - rd.l - !regs.p.c;
regs.p.c = r >= 0;
}
regs.p.n = r & 0x80;
regs.p.v = (regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80;
regs.p.z = (uint8)r == 0;
regs.a.l = r;
}
inline void CPUcore::op_sbc_w() {
int r;
if(regs.p.d) {
uint8 n0 = (regs.a.w ) & 15;
uint8 n1 = (regs.a.w >> 4) & 15;
uint8 n2 = (regs.a.w >> 8) & 15;
uint8 n3 = (regs.a.w >> 12) & 15;
n0 -= ((rd.w ) & 15) + !regs.p.c;
n1 -= ((rd.w >> 4) & 15);
n2 -= ((rd.w >> 8) & 15);
n3 -= ((rd.w >> 12) & 15);
if(n0 > 9) {
n0 += 10;
n1--;
}
if(n1 > 9) {
n1 += 10;
n2--;
}
if(n2 > 9) {
n2 += 10;
n3--;
}
if(n3 > 9) {
n3 += 10;
regs.p.c = 0;
} else {
regs.p.c = 1;
}
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
} else {
r = regs.a.w - rd.w - !regs.p.c;
regs.p.c = r >= 0;
}
regs.p.n = r & 0x8000;
regs.p.v = (regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000;
regs.p.z = (uint16)r == 0;
regs.a.w = r;
}
inline void CPUcore::op_inc_b() {
rd.l++;
regs.p.n = rd.l & 0x80;
regs.p.z = rd.l == 0;
}
inline void CPUcore::op_inc_w() {
rd.w++;
regs.p.n = rd.w & 0x8000;
regs.p.z = rd.w == 0;
}
inline void CPUcore::op_dec_b() {
rd.l--;
regs.p.n = rd.l & 0x80;
regs.p.z = rd.l == 0;
}
inline void CPUcore::op_dec_w() {
rd.w--;
regs.p.n = rd.w & 0x8000;
regs.p.z = rd.w == 0;
}
inline void CPUcore::op_asl_b() {
regs.p.c = rd.l & 0x80;
rd.l <<= 1;
regs.p.n = rd.l & 0x80;
regs.p.z = rd.l == 0;
}
inline void CPUcore::op_asl_w() {
regs.p.c = rd.w & 0x8000;
rd.w <<= 1;
regs.p.n = rd.w & 0x8000;
regs.p.z = rd.w == 0;
}
inline void CPUcore::op_lsr_b() {
regs.p.c = rd.l & 1;
rd.l >>= 1;
regs.p.n = rd.l & 0x80;
regs.p.z = rd.l == 0;
}
inline void CPUcore::op_lsr_w() {
regs.p.c = rd.w & 1;
rd.w >>= 1;
regs.p.n = rd.w & 0x8000;
regs.p.z = rd.w == 0;
}
inline void CPUcore::op_rol_b() {
unsigned carry = (unsigned)regs.p.c;
regs.p.c = rd.l & 0x80;
rd.l = (rd.l << 1) | carry;
regs.p.n = rd.l & 0x80;
regs.p.z = rd.l == 0;
}
inline void CPUcore::op_rol_w() {
unsigned carry = (unsigned)regs.p.c;
regs.p.c = rd.w & 0x8000;
rd.w = (rd.w << 1) | carry;
regs.p.n = rd.w & 0x8000;
regs.p.z = rd.w == 0;
}
inline void CPUcore::op_ror_b() {
unsigned carry = (unsigned)regs.p.c << 7;
regs.p.c = rd.l & 1;
rd.l = carry | (rd.l >> 1);
regs.p.n = rd.l & 0x80;
regs.p.z = rd.l == 0;
}
inline void CPUcore::op_ror_w() {
unsigned carry = (unsigned)regs.p.c << 15;
regs.p.c = rd.w & 1;
rd.w = carry | (rd.w >> 1);
regs.p.n = rd.w & 0x8000;
regs.p.z = rd.w == 0;
}
inline void CPUcore::op_trb_b() {
regs.p.z = (rd.l & regs.a.l) == 0;
rd.l &= ~regs.a.l;
}
inline void CPUcore::op_trb_w() {
regs.p.z = (rd.w & regs.a.w) == 0;
rd.w &= ~regs.a.w;
}
inline void CPUcore::op_tsb_b() {
regs.p.z = (rd.l & regs.a.l) == 0;
rd.l |= regs.a.l;
}
inline void CPUcore::op_tsb_w() {
regs.p.z = (rd.w & regs.a.w) == 0;
rd.w |= regs.a.w;
}
#endif

View File

@@ -0,0 +1,13 @@
//opcode_functions.cpp was generated via bpp -> opcode_functions.bpp
@global class CPUcore
@global lc last_cycle();
@global wai regs.wai
@include "opcode_read.bpp"
@include "opcode_write.bpp"
@include "opcode_rmw.bpp"
@include "opcode_pc.bpp"
@include "opcode_misc.bpp"
@include "opcode_list.bpp"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,386 @@
//===============
//opcode_read.bpp
//===============
@macro op_read_const(name)
void op_{name}_const_b();
void op_{name}_const_w();
@endmacro
@macro op_read_bit_const()
void op_bit_const_b();
void op_bit_const_w();
@endmacro
@macro op_read_addr(name)
void op_{name}_addr_b();
void op_{name}_addr_w();
@endmacro
@macro op_read_addrx(name)
void op_{name}_addrx_b();
void op_{name}_addrx_w();
@endmacro
@macro op_read_addry(name)
void op_{name}_addry_b();
void op_{name}_addry_w();
@endmacro
@macro op_read_long(name)
void op_{name}_long_b();
void op_{name}_long_w();
@endmacro
@macro op_read_longx(name)
void op_{name}_longx_b();
void op_{name}_longx_w();
@endmacro
@macro op_read_dp(name)
void op_{name}_dp_b();
void op_{name}_dp_w();
@endmacro
@macro op_read_dpr(name, r)
void op_{name}_dpr_b();
void op_{name}_dpr_w();
@endmacro
@macro op_read_idp(name)
void op_{name}_idp_b();
void op_{name}_idp_w();
@endmacro
@macro op_read_idpx(name)
void op_{name}_idpx_b();
void op_{name}_idpx_w();
@endmacro
@macro op_read_idpy(name)
void op_{name}_idpy_b();
void op_{name}_idpy_w();
@endmacro
@macro op_read_ildp(name)
void op_{name}_ildp_b();
void op_{name}_ildp_w();
@endmacro
@macro op_read_ildpy(name)
void op_{name}_ildpy_b();
void op_{name}_ildpy_w();
@endmacro
@macro op_read_sr(name)
void op_{name}_sr_b();
void op_{name}_sr_w();
@endmacro
@macro op_read_isry(name)
void op_{name}_isry_b();
void op_{name}_isry_w();
@endmacro
//================
//opcode_write.bpp
//================
@macro op_store_addr(name, r)
void op_{name}_addr_b();
void op_{name}_addr_w();
@endmacro
@macro op_store_addrr(name, suffix, r, index)
void op_{name}_addr{suffix}_b();
void op_{name}_addr{suffix}_w();
@endmacro
@macro op_store_longr(name, suffix, index)
void op_{name}_long{suffix}_b();
void op_{name}_long{suffix}_w();
@endmacro
@macro op_store_dp(name, r)
void op_{name}_dp_b();
void op_{name}_dp_w();
@endmacro
@macro op_store_dpr(name, r, index)
void op_{name}_dpr_b();
void op_{name}_dpr_w();
@endmacro
@macro op_sta_idp()
void op_sta_idp_b();
void op_sta_idp_w();
@endmacro
@macro op_sta_ildp()
void op_sta_ildp_b();
void op_sta_ildp_w();
@endmacro
@macro op_sta_idpx()
void op_sta_idpx_b();
void op_sta_idpx_w();
@endmacro
@macro op_sta_idpy()
void op_sta_idpy_b();
void op_sta_idpy_w();
@endmacro
@macro op_sta_ildpy()
void op_sta_ildpy_b();
void op_sta_ildpy_w();
@endmacro
@macro op_sta_sr()
void op_sta_sr_b();
void op_sta_sr_w();
@endmacro
@macro op_sta_isry()
void op_sta_isry_b();
void op_sta_isry_w();
@endmacro
//==============
//opcode_rmw.bpp
//==============
@macro op_adjust(name, r, op)
void op_{name}_imm_b();
void op_{name}_imm_w();
@endmacro
@macro op_asl()
void op_asl_imm_b();
void op_asl_imm_w();
@endmacro
@macro op_lsr()
void op_lsr_imm_b();
void op_lsr_imm_w();
@endmacro
@macro op_rol()
void op_rol_imm_b();
void op_rol_imm_w();
@endmacro
@macro op_ror()
void op_ror_imm_b();
void op_ror_imm_w();
@endmacro
@macro op_adjust_addr(name)
void op_{name}_addr_b();
void op_{name}_addr_w();
@endmacro
@macro op_adjust_addrx(name)
void op_{name}_addrx_b();
void op_{name}_addrx_w();
@endmacro
@macro op_adjust_dp(name)
void op_{name}_dp_b();
void op_{name}_dp_w();
@endmacro
@macro op_adjust_dpx(name)
void op_{name}_dpx_b();
void op_{name}_dpx_w();
@endmacro
//=============
//opcode_pc.bpp
//=============
@macro op_branch(name, condition)
void op_{name}();
@endmacro
@macro op_bra()
void op_bra();
@endmacro
@macro op_brl()
void op_brl();
@endmacro
@macro op_jmp_addr()
void op_jmp_addr();
@endmacro
@macro op_jmp_long()
void op_jmp_long();
@endmacro
@macro op_jmp_iaddr()
void op_jmp_iaddr();
@endmacro
@macro op_jmp_iaddrx()
void op_jmp_iaddrx();
@endmacro
@macro op_jmp_iladdr()
void op_jmp_iladdr();
@endmacro
@macro op_jsr_addr()
void op_jsr_addr();
@endmacro
@macro op_jsr_long()
void op_jsr_long_e();
void op_jsr_long_n();
@endmacro
@macro op_jsr_iaddrx()
void op_jsr_iaddrx_e();
void op_jsr_iaddrx_n();
@endmacro
@macro op_rti()
void op_rti_e();
void op_rti_n();
@endmacro
@macro op_rts()
void op_rts();
@endmacro
@macro op_rtl()
void op_rtl_e();
void op_rtl_n();
@endmacro
//===============
//opcode_misc.bpp
//===============
@macro op_nop()
void op_nop();
@endmacro
@macro op_wdm()
void op_wdm();
@endmacro
@macro op_xba()
void op_xba();
@endmacro
@macro op_move(name, op)
void op_{name}_b();
void op_{name}_w();
@endmacro
@macro op_interrupt(name, vectorE, vectorN)
void op_{name}_e();
void op_{name}_n();
@endmacro
@macro op_stp()
void op_stp();
@endmacro
@macro op_wai()
void op_wai();
@endmacro
@macro op_xce()
void op_xce();
@endmacro
@macro op_flag(name, rule)
void op_{name}();
@endmacro
@macro op_pflag(name, op)
void op_{name}_e();
void op_{name}_n();
@endmacro
@macro op_transfer(name, from, to)
void op_{name}_b();
void op_{name}_w();
@endmacro
@macro op_transfer_word(name, from, to)
void op_{name}();
@endmacro
@macro op_tcs()
void op_tcs_e();
void op_tcs_n();
@endmacro
@macro op_tsc()
void op_tsc_e();
void op_tsc_n();
@endmacro
@macro op_tsx()
void op_tsx_b();
void op_tsx_w();
@endmacro
@macro op_txs()
void op_txs_e();
void op_txs_n();
@endmacro
@macro op_push(name, r)
void op_{name}_b();
void op_{name}_w();
@endmacro
@macro op_phd()
void op_phd_e();
void op_phd_n();
@endmacro
@macro op_push_byte(name, r)
void op_{name}();
@endmacro
@macro op_pull(name, r)
void op_{name}_b();
void op_{name}_w();
@endmacro
@macro op_pld()
void op_pld_e();
void op_pld_n();
@endmacro
@macro op_plb()
void op_plb();
@endmacro
@macro op_plp()
void op_plp_e();
void op_plp_n();
@endmacro
@macro op_pea()
void op_pea_e();
void op_pea_n();
@endmacro
@macro op_pei()
void op_pei_e();
void op_pei_n();
@endmacro
@macro op_per()
void op_per_e();
void op_per_n();
@endmacro
@include "opcode_list.bpp"

View File

@@ -0,0 +1,892 @@
//===============
//opcode_read.bpp
//===============
//================
//opcode_write.bpp
//================
//==============
//opcode_rmw.bpp
//==============
//=============
//opcode_pc.bpp
//=============
//===============
//opcode_misc.bpp
//===============
//===============
//opcode_read.bpp
//===============
void op_adc_const_b();
void op_adc_const_w();
void op_and_const_b();
void op_and_const_w();
void op_cmp_const_b();
void op_cmp_const_w();
void op_cpx_const_b();
void op_cpx_const_w();
void op_cpy_const_b();
void op_cpy_const_w();
void op_eor_const_b();
void op_eor_const_w();
void op_lda_const_b();
void op_lda_const_w();
void op_ldx_const_b();
void op_ldx_const_w();
void op_ldy_const_b();
void op_ldy_const_w();
void op_ora_const_b();
void op_ora_const_w();
void op_sbc_const_b();
void op_sbc_const_w();
void op_bit_const_b();
void op_bit_const_w();
void op_adc_addr_b();
void op_adc_addr_w();
void op_and_addr_b();
void op_and_addr_w();
void op_bit_addr_b();
void op_bit_addr_w();
void op_cmp_addr_b();
void op_cmp_addr_w();
void op_cpx_addr_b();
void op_cpx_addr_w();
void op_cpy_addr_b();
void op_cpy_addr_w();
void op_eor_addr_b();
void op_eor_addr_w();
void op_lda_addr_b();
void op_lda_addr_w();
void op_ldx_addr_b();
void op_ldx_addr_w();
void op_ldy_addr_b();
void op_ldy_addr_w();
void op_ora_addr_b();
void op_ora_addr_w();
void op_sbc_addr_b();
void op_sbc_addr_w();
void op_adc_addrx_b();
void op_adc_addrx_w();
void op_and_addrx_b();
void op_and_addrx_w();
void op_bit_addrx_b();
void op_bit_addrx_w();
void op_cmp_addrx_b();
void op_cmp_addrx_w();
void op_eor_addrx_b();
void op_eor_addrx_w();
void op_lda_addrx_b();
void op_lda_addrx_w();
void op_ldy_addrx_b();
void op_ldy_addrx_w();
void op_ora_addrx_b();
void op_ora_addrx_w();
void op_sbc_addrx_b();
void op_sbc_addrx_w();
void op_adc_addry_b();
void op_adc_addry_w();
void op_and_addry_b();
void op_and_addry_w();
void op_cmp_addry_b();
void op_cmp_addry_w();
void op_eor_addry_b();
void op_eor_addry_w();
void op_lda_addry_b();
void op_lda_addry_w();
void op_ldx_addry_b();
void op_ldx_addry_w();
void op_ora_addry_b();
void op_ora_addry_w();
void op_sbc_addry_b();
void op_sbc_addry_w();
void op_adc_long_b();
void op_adc_long_w();
void op_and_long_b();
void op_and_long_w();
void op_cmp_long_b();
void op_cmp_long_w();
void op_eor_long_b();
void op_eor_long_w();
void op_lda_long_b();
void op_lda_long_w();
void op_ora_long_b();
void op_ora_long_w();
void op_sbc_long_b();
void op_sbc_long_w();
void op_adc_longx_b();
void op_adc_longx_w();
void op_and_longx_b();
void op_and_longx_w();
void op_cmp_longx_b();
void op_cmp_longx_w();
void op_eor_longx_b();
void op_eor_longx_w();
void op_lda_longx_b();
void op_lda_longx_w();
void op_ora_longx_b();
void op_ora_longx_w();
void op_sbc_longx_b();
void op_sbc_longx_w();
void op_adc_dp_b();
void op_adc_dp_w();
void op_and_dp_b();
void op_and_dp_w();
void op_bit_dp_b();
void op_bit_dp_w();
void op_cmp_dp_b();
void op_cmp_dp_w();
void op_cpx_dp_b();
void op_cpx_dp_w();
void op_cpy_dp_b();
void op_cpy_dp_w();
void op_eor_dp_b();
void op_eor_dp_w();
void op_lda_dp_b();
void op_lda_dp_w();
void op_ldx_dp_b();
void op_ldx_dp_w();
void op_ldy_dp_b();
void op_ldy_dp_w();
void op_ora_dp_b();
void op_ora_dp_w();
void op_sbc_dp_b();
void op_sbc_dp_w();
void op_adc_dpr_b();
void op_adc_dpr_w();
void op_and_dpr_b();
void op_and_dpr_w();
void op_bit_dpr_b();
void op_bit_dpr_w();
void op_cmp_dpr_b();
void op_cmp_dpr_w();
void op_eor_dpr_b();
void op_eor_dpr_w();
void op_lda_dpr_b();
void op_lda_dpr_w();
void op_ldx_dpr_b();
void op_ldx_dpr_w();
void op_ldy_dpr_b();
void op_ldy_dpr_w();
void op_ora_dpr_b();
void op_ora_dpr_w();
void op_sbc_dpr_b();
void op_sbc_dpr_w();
void op_adc_idp_b();
void op_adc_idp_w();
void op_and_idp_b();
void op_and_idp_w();
void op_cmp_idp_b();
void op_cmp_idp_w();
void op_eor_idp_b();
void op_eor_idp_w();
void op_lda_idp_b();
void op_lda_idp_w();
void op_ora_idp_b();
void op_ora_idp_w();
void op_sbc_idp_b();
void op_sbc_idp_w();
void op_adc_idpx_b();
void op_adc_idpx_w();
void op_and_idpx_b();
void op_and_idpx_w();
void op_cmp_idpx_b();
void op_cmp_idpx_w();
void op_eor_idpx_b();
void op_eor_idpx_w();
void op_lda_idpx_b();
void op_lda_idpx_w();
void op_ora_idpx_b();
void op_ora_idpx_w();
void op_sbc_idpx_b();
void op_sbc_idpx_w();
void op_adc_idpy_b();
void op_adc_idpy_w();
void op_and_idpy_b();
void op_and_idpy_w();
void op_cmp_idpy_b();
void op_cmp_idpy_w();
void op_eor_idpy_b();
void op_eor_idpy_w();
void op_lda_idpy_b();
void op_lda_idpy_w();
void op_ora_idpy_b();
void op_ora_idpy_w();
void op_sbc_idpy_b();
void op_sbc_idpy_w();
void op_adc_ildp_b();
void op_adc_ildp_w();
void op_and_ildp_b();
void op_and_ildp_w();
void op_cmp_ildp_b();
void op_cmp_ildp_w();
void op_eor_ildp_b();
void op_eor_ildp_w();
void op_lda_ildp_b();
void op_lda_ildp_w();
void op_ora_ildp_b();
void op_ora_ildp_w();
void op_sbc_ildp_b();
void op_sbc_ildp_w();
void op_adc_ildpy_b();
void op_adc_ildpy_w();
void op_and_ildpy_b();
void op_and_ildpy_w();
void op_cmp_ildpy_b();
void op_cmp_ildpy_w();
void op_eor_ildpy_b();
void op_eor_ildpy_w();
void op_lda_ildpy_b();
void op_lda_ildpy_w();
void op_ora_ildpy_b();
void op_ora_ildpy_w();
void op_sbc_ildpy_b();
void op_sbc_ildpy_w();
void op_adc_sr_b();
void op_adc_sr_w();
void op_and_sr_b();
void op_and_sr_w();
void op_cmp_sr_b();
void op_cmp_sr_w();
void op_eor_sr_b();
void op_eor_sr_w();
void op_lda_sr_b();
void op_lda_sr_w();
void op_ora_sr_b();
void op_ora_sr_w();
void op_sbc_sr_b();
void op_sbc_sr_w();
void op_adc_isry_b();
void op_adc_isry_w();
void op_and_isry_b();
void op_and_isry_w();
void op_cmp_isry_b();
void op_cmp_isry_w();
void op_eor_isry_b();
void op_eor_isry_w();
void op_lda_isry_b();
void op_lda_isry_w();
void op_ora_isry_b();
void op_ora_isry_w();
void op_sbc_isry_b();
void op_sbc_isry_w();
//================
//opcode_write.bpp
//================
void op_sta_addr_b();
void op_sta_addr_w();
void op_stx_addr_b();
void op_stx_addr_w();
void op_sty_addr_b();
void op_sty_addr_w();
void op_stz_addr_b();
void op_stz_addr_w();
void op_sta_addrx_b();
void op_sta_addrx_w();
void op_sta_addry_b();
void op_sta_addry_w();
void op_stz_addrx_b();
void op_stz_addrx_w();
void op_sta_long_b();
void op_sta_long_w();
void op_sta_longx_b();
void op_sta_longx_w();
void op_sta_dp_b();
void op_sta_dp_w();
void op_stx_dp_b();
void op_stx_dp_w();
void op_sty_dp_b();
void op_sty_dp_w();
void op_stz_dp_b();
void op_stz_dp_w();
void op_sta_dpr_b();
void op_sta_dpr_w();
void op_stx_dpr_b();
void op_stx_dpr_w();
void op_sty_dpr_b();
void op_sty_dpr_w();
void op_stz_dpr_b();
void op_stz_dpr_w();
void op_sta_idp_b();
void op_sta_idp_w();
void op_sta_ildp_b();
void op_sta_ildp_w();
void op_sta_idpx_b();
void op_sta_idpx_w();
void op_sta_idpy_b();
void op_sta_idpy_w();
void op_sta_ildpy_b();
void op_sta_ildpy_w();
void op_sta_sr_b();
void op_sta_sr_w();
void op_sta_isry_b();
void op_sta_isry_w();
//==============
//opcode_rmw.bpp
//==============
void op_inc_imm_b();
void op_inc_imm_w();
void op_inx_imm_b();
void op_inx_imm_w();
void op_iny_imm_b();
void op_iny_imm_w();
void op_dec_imm_b();
void op_dec_imm_w();
void op_dex_imm_b();
void op_dex_imm_w();
void op_dey_imm_b();
void op_dey_imm_w();
void op_asl_imm_b();
void op_asl_imm_w();
void op_lsr_imm_b();
void op_lsr_imm_w();
void op_rol_imm_b();
void op_rol_imm_w();
void op_ror_imm_b();
void op_ror_imm_w();
void op_inc_addr_b();
void op_inc_addr_w();
void op_dec_addr_b();
void op_dec_addr_w();
void op_asl_addr_b();
void op_asl_addr_w();
void op_lsr_addr_b();
void op_lsr_addr_w();
void op_rol_addr_b();
void op_rol_addr_w();
void op_ror_addr_b();
void op_ror_addr_w();
void op_trb_addr_b();
void op_trb_addr_w();
void op_tsb_addr_b();
void op_tsb_addr_w();
void op_inc_addrx_b();
void op_inc_addrx_w();
void op_dec_addrx_b();
void op_dec_addrx_w();
void op_asl_addrx_b();
void op_asl_addrx_w();
void op_lsr_addrx_b();
void op_lsr_addrx_w();
void op_rol_addrx_b();
void op_rol_addrx_w();
void op_ror_addrx_b();
void op_ror_addrx_w();
void op_inc_dp_b();
void op_inc_dp_w();
void op_dec_dp_b();
void op_dec_dp_w();
void op_asl_dp_b();
void op_asl_dp_w();
void op_lsr_dp_b();
void op_lsr_dp_w();
void op_rol_dp_b();
void op_rol_dp_w();
void op_ror_dp_b();
void op_ror_dp_w();
void op_trb_dp_b();
void op_trb_dp_w();
void op_tsb_dp_b();
void op_tsb_dp_w();
void op_inc_dpx_b();
void op_inc_dpx_w();
void op_dec_dpx_b();
void op_dec_dpx_w();
void op_asl_dpx_b();
void op_asl_dpx_w();
void op_lsr_dpx_b();
void op_lsr_dpx_w();
void op_rol_dpx_b();
void op_rol_dpx_w();
void op_ror_dpx_b();
void op_ror_dpx_w();
//=============
//opcode_pc.bpp
//=============
void op_bcc();
void op_bcs();
void op_bne();
void op_beq();
void op_bpl();
void op_bmi();
void op_bvc();
void op_bvs();
void op_bra();
void op_brl();
void op_jmp_addr();
void op_jmp_long();
void op_jmp_iaddr();
void op_jmp_iaddrx();
void op_jmp_iladdr();
void op_jsr_addr();
void op_jsr_long_e();
void op_jsr_long_n();
void op_jsr_iaddrx_e();
void op_jsr_iaddrx_n();
void op_rti_e();
void op_rti_n();
void op_rts();
void op_rtl_e();
void op_rtl_n();
//===============
//opcode_misc.bpp
//===============
void op_nop();
void op_wdm();
void op_xba();
void op_mvn_b();
void op_mvn_w();
void op_mvp_b();
void op_mvp_w();
void op_brk_e();
void op_brk_n();
void op_cop_e();
void op_cop_n();
void op_stp();
void op_wai();
void op_xce();
void op_clc();
void op_cld();
void op_cli();
void op_clv();
void op_sec();
void op_sed();
void op_sei();
void op_rep_e();
void op_rep_n();
void op_sep_e();
void op_sep_n();
void op_tax_b();
void op_tax_w();
void op_tay_b();
void op_tay_w();
void op_txa_b();
void op_txa_w();
void op_txy_b();
void op_txy_w();
void op_tya_b();
void op_tya_w();
void op_tyx_b();
void op_tyx_w();
void op_tcd();
void op_tdc();
void op_tcs_e();
void op_tcs_n();
void op_tsc_e();
void op_tsc_n();
void op_tsx_b();
void op_tsx_w();
void op_txs_e();
void op_txs_n();
void op_pha_b();
void op_pha_w();
void op_phx_b();
void op_phx_w();
void op_phy_b();
void op_phy_w();
void op_phd_e();
void op_phd_n();
void op_phb();
void op_phk();
void op_php();
void op_pla_b();
void op_pla_w();
void op_plx_b();
void op_plx_w();
void op_ply_b();
void op_ply_w();
void op_pld_e();
void op_pld_n();
void op_plb();
void op_plp_e();
void op_plp_n();
void op_pea_e();
void op_pea_n();
void op_pei_e();
void op_pei_n();
void op_per_e();
void op_per_n();

View File

@@ -0,0 +1,317 @@
//===============
//opcode_read.bpp
//===============
@op_read_const(adc)
@op_read_const(and)
@op_read_const(cmp)
@op_read_const(cpx)
@op_read_const(cpy)
@op_read_const(eor)
@op_read_const(lda)
@op_read_const(ldx)
@op_read_const(ldy)
@op_read_const(ora)
@op_read_const(sbc)
@op_read_bit_const()
@op_read_addr(adc)
@op_read_addr(and)
@op_read_addr(bit)
@op_read_addr(cmp)
@op_read_addr(cpx)
@op_read_addr(cpy)
@op_read_addr(eor)
@op_read_addr(lda)
@op_read_addr(ldx)
@op_read_addr(ldy)
@op_read_addr(ora)
@op_read_addr(sbc)
@op_read_addrx(adc)
@op_read_addrx(and)
@op_read_addrx(bit)
@op_read_addrx(cmp)
@op_read_addrx(eor)
@op_read_addrx(lda)
@op_read_addrx(ldy)
@op_read_addrx(ora)
@op_read_addrx(sbc)
@op_read_addry(adc)
@op_read_addry(and)
@op_read_addry(cmp)
@op_read_addry(eor)
@op_read_addry(lda)
@op_read_addry(ldx)
@op_read_addry(ora)
@op_read_addry(sbc)
@op_read_long(adc)
@op_read_long(and)
@op_read_long(cmp)
@op_read_long(eor)
@op_read_long(lda)
@op_read_long(ora)
@op_read_long(sbc)
@op_read_longx(adc)
@op_read_longx(and)
@op_read_longx(cmp)
@op_read_longx(eor)
@op_read_longx(lda)
@op_read_longx(ora)
@op_read_longx(sbc)
@op_read_dp(adc)
@op_read_dp(and)
@op_read_dp(bit)
@op_read_dp(cmp)
@op_read_dp(cpx)
@op_read_dp(cpy)
@op_read_dp(eor)
@op_read_dp(lda)
@op_read_dp(ldx)
@op_read_dp(ldy)
@op_read_dp(ora)
@op_read_dp(sbc)
@op_read_dpr(adc, x)
@op_read_dpr(and, x)
@op_read_dpr(bit, x)
@op_read_dpr(cmp, x)
@op_read_dpr(eor, x)
@op_read_dpr(lda, x)
@op_read_dpr(ldx, y)
@op_read_dpr(ldy, x)
@op_read_dpr(ora, x)
@op_read_dpr(sbc, x)
@op_read_idp(adc)
@op_read_idp(and)
@op_read_idp(cmp)
@op_read_idp(eor)
@op_read_idp(lda)
@op_read_idp(ora)
@op_read_idp(sbc)
@op_read_idpx(adc)
@op_read_idpx(and)
@op_read_idpx(cmp)
@op_read_idpx(eor)
@op_read_idpx(lda)
@op_read_idpx(ora)
@op_read_idpx(sbc)
@op_read_idpy(adc)
@op_read_idpy(and)
@op_read_idpy(cmp)
@op_read_idpy(eor)
@op_read_idpy(lda)
@op_read_idpy(ora)
@op_read_idpy(sbc)
@op_read_ildp(adc)
@op_read_ildp(and)
@op_read_ildp(cmp)
@op_read_ildp(eor)
@op_read_ildp(lda)
@op_read_ildp(ora)
@op_read_ildp(sbc)
@op_read_ildpy(adc)
@op_read_ildpy(and)
@op_read_ildpy(cmp)
@op_read_ildpy(eor)
@op_read_ildpy(lda)
@op_read_ildpy(ora)
@op_read_ildpy(sbc)
@op_read_sr(adc)
@op_read_sr(and)
@op_read_sr(cmp)
@op_read_sr(eor)
@op_read_sr(lda)
@op_read_sr(ora)
@op_read_sr(sbc)
@op_read_isry(adc)
@op_read_isry(and)
@op_read_isry(cmp)
@op_read_isry(eor)
@op_read_isry(lda)
@op_read_isry(ora)
@op_read_isry(sbc)
//================
//opcode_write.bpp
//================
@op_store_addr(sta, regs.a.w)
@op_store_addr(stx, regs.x.w)
@op_store_addr(sty, regs.y.w)
@op_store_addr(stz, 0x0000)
@op_store_addrr(sta, x, regs.a.w, regs.x.w)
@op_store_addrr(sta, y, regs.a.w, regs.y.w)
@op_store_addrr(stz, x, 0x0000, regs.x.w)
@op_store_longr(sta, , 0x0000)
@op_store_longr(sta, x, regs.x.w)
@op_store_dp(sta, regs.a.w)
@op_store_dp(stx, regs.x.w)
@op_store_dp(sty, regs.y.w)
@op_store_dp(stz, 0x0000)
@op_store_dpr(sta, regs.a.w, x)
@op_store_dpr(stx, regs.x.w, y)
@op_store_dpr(sty, regs.y.w, x)
@op_store_dpr(stz, 0x0000, x)
@op_sta_idp()
@op_sta_ildp()
@op_sta_idpx()
@op_sta_idpy()
@op_sta_ildpy()
@op_sta_sr()
@op_sta_isry()
//==============
//opcode_rmw.bpp
//==============
@op_adjust(inc, a, ++)
@op_adjust(inx, x, ++)
@op_adjust(iny, y, ++)
@op_adjust(dec, a, --)
@op_adjust(dex, x, --)
@op_adjust(dey, y, --)
@op_asl()
@op_lsr()
@op_rol()
@op_ror()
@op_adjust_addr(inc)
@op_adjust_addr(dec)
@op_adjust_addr(asl)
@op_adjust_addr(lsr)
@op_adjust_addr(rol)
@op_adjust_addr(ror)
@op_adjust_addr(trb)
@op_adjust_addr(tsb)
@op_adjust_addrx(inc)
@op_adjust_addrx(dec)
@op_adjust_addrx(asl)
@op_adjust_addrx(lsr)
@op_adjust_addrx(rol)
@op_adjust_addrx(ror)
@op_adjust_dp(inc)
@op_adjust_dp(dec)
@op_adjust_dp(asl)
@op_adjust_dp(lsr)
@op_adjust_dp(rol)
@op_adjust_dp(ror)
@op_adjust_dp(trb)
@op_adjust_dp(tsb)
@op_adjust_dpx(inc)
@op_adjust_dpx(dec)
@op_adjust_dpx(asl)
@op_adjust_dpx(lsr)
@op_adjust_dpx(rol)
@op_adjust_dpx(ror)
//=============
//opcode_pc.bpp
//=============
@op_branch(bcc, !regs.p.c)
@op_branch(bcs, regs.p.c)
@op_branch(bne, !regs.p.z)
@op_branch(beq, regs.p.z)
@op_branch(bpl, !regs.p.n)
@op_branch(bmi, regs.p.n)
@op_branch(bvc, !regs.p.v)
@op_branch(bvs, regs.p.v)
@op_bra()
@op_brl()
@op_jmp_addr()
@op_jmp_long()
@op_jmp_iaddr()
@op_jmp_iaddrx()
@op_jmp_iladdr()
@op_jsr_addr()
@op_jsr_long()
@op_jsr_iaddrx()
@op_rti()
@op_rts()
@op_rtl()
//===============
//opcode_misc.bpp
//===============
@op_nop()
@op_wdm()
@op_xba()
@op_move(mvn, ++)
@op_move(mvp, --)
@op_interrupt(brk, 0xfffe, 0xffe6)
@op_interrupt(cop, 0xfff4, 0xffe4)
@op_stp()
@op_wai()
@op_xce()
@op_flag(clc, regs.p.c = 0)
@op_flag(cld, regs.p.d = 0)
@op_flag(cli, regs.p.i = 0)
@op_flag(clv, regs.p.v = 0)
@op_flag(sec, regs.p.c = 1)
@op_flag(sed, regs.p.d = 1)
@op_flag(sei, regs.p.i = 1)
@op_pflag(rep, &=~)
@op_pflag(sep, |=)
@op_transfer(tax, a, x)
@op_transfer(tay, a, y)
@op_transfer(txa, x, a)
@op_transfer(txy, x, y)
@op_transfer(tya, y, a)
@op_transfer(tyx, y, x)
@op_transfer_word(tcd, a, d)
@op_transfer_word(tdc, d, a)
@op_tcs()
@op_tsc()
@op_tsx()
@op_txs()
@op_push(pha, a)
@op_push(phx, x)
@op_push(phy, y)
@op_phd()
@op_push_byte(phb, regs.db)
@op_push_byte(phk, regs.pc.b)
@op_push_byte(php, regs.p)
@op_pull(pla, a)
@op_pull(plx, x)
@op_pull(ply, y)
@op_pld()
@op_plb()
@op_plp()
@op_pea()
@op_pei()
@op_per()

View File

@@ -0,0 +1,397 @@
@macro op_nop()
void {class}::op_nop() {
{lc}op_io_irq();
}
@endmacro
@macro op_wdm()
void {class}::op_wdm() {
{lc}op_readpc();
}
@endmacro
@macro op_xba()
void {class}::op_xba() {
op_io();
{lc}op_io();
regs.a.l ^= regs.a.h;
regs.a.h ^= regs.a.l;
regs.a.l ^= regs.a.h;
regs.p.n = (regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
@endmacro
@macro op_move(name, op)
void {class}::op_{name}_b() {
dp = op_readpc();
sp = op_readpc();
regs.db = dp;
rd.l = op_readlong((sp << 16) | regs.x.w);
op_writelong((dp << 16) | regs.y.w, rd.l);
op_io();
regs.x.l {op};
regs.y.l {op};
{lc}op_io();
if(regs.a.w--) regs.pc.w -= 3;
}
void {class}::op_{name}_w() {
dp = op_readpc();
sp = op_readpc();
regs.db = dp;
rd.l = op_readlong((sp << 16) | regs.x.w);
op_writelong((dp << 16) | regs.y.w, rd.l);
op_io();
regs.x.w {op};
regs.y.w {op};
{lc}op_io();
if(regs.a.w--) regs.pc.w -= 3;
}
@endmacro
@macro op_interrupt(name, vectorE, vectorN)
void {class}::op_{name}_e() {
op_readpc();
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.p);
rd.l = op_readlong({vectorE} + 0);
regs.pc.b = 0;
regs.p.i = 1;
regs.p.d = 0;
{lc}rd.h = op_readlong({vectorE} + 1);
regs.pc.w = rd.w;
}
void {class}::op_{name}_n() {
op_readpc();
op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.p);
rd.l = op_readlong({vectorN} + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
{lc}rd.h = op_readlong({vectorN} + 1);
regs.pc.w = rd.w;
}
@endmacro
@macro op_stp()
void {class}::op_stp() {
while({wai} = true) {
{lc} op_io();
}
}
@endmacro
@macro op_wai()
void {class}::op_wai() {
{wai} = true;
while({wai}) {
{lc} op_io();
}
op_io();
}
@endmacro
@macro op_xce()
void {class}::op_xce() {
{lc}op_io_irq();
bool carry = regs.p.c;
regs.p.c = regs.e;
regs.e = carry;
if(regs.e) {
regs.p |= 0x30;
regs.s.h = 0x01;
}
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
update_table();
}
@endmacro
@macro op_flag(name, rule)
void {class}::op_{name}() {
{lc}op_io_irq();
{rule};
}
@endmacro
@macro op_pflag(name, op)
void {class}::op_{name}_e() {
rd.l = op_readpc();
{lc}op_io();
regs.p {op} rd.l;
regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
update_table();
}
void {class}::op_{name}_n() {
rd.l = op_readpc();
{lc}op_io();
regs.p {op} rd.l;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
update_table();
}
@endmacro
@macro op_transfer(name, from, to)
void {class}::op_{name}_b() {
{lc}op_io_irq();
regs.{to}.l = regs.{from}.l;
regs.p.n = (regs.{to}.l & 0x80);
regs.p.z = (regs.{to}.l == 0);
}
void {class}::op_{name}_w() {
{lc}op_io_irq();
regs.{to}.w = regs.{from}.w;
regs.p.n = (regs.{to}.w & 0x8000);
regs.p.z = (regs.{to}.w == 0);
}
@endmacro
@macro op_transfer_word(name, from, to)
void {class}::op_{name}() {
{lc}op_io_irq();
regs.{to}.w = regs.{from}.w;
regs.p.n = (regs.{to}.w & 0x8000);
regs.p.z = (regs.{to}.w == 0);
}
@endmacro
@macro op_tcs()
void {class}::op_tcs_e() {
{lc}op_io_irq();
regs.s.l = regs.a.l;
}
void {class}::op_tcs_n() {
{lc}op_io_irq();
regs.s.w = regs.a.w;
}
@endmacro
@macro op_tsc()
void {class}::op_tsc_e() {
{lc}op_io_irq();
regs.a.w = regs.s.w;
regs.p.n = (regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void {class}::op_tsc_n() {
{lc}op_io_irq();
regs.a.w = regs.s.w;
regs.p.n = (regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@endmacro
@macro op_tsx()
void {class}::op_tsx_b() {
{lc}op_io_irq();
regs.x.l = regs.s.l;
regs.p.n = (regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
}
void {class}::op_tsx_w() {
{lc}op_io_irq();
regs.x.w = regs.s.w;
regs.p.n = (regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
@endmacro
@macro op_txs()
void {class}::op_txs_e() {
{lc}op_io_irq();
regs.s.l = regs.x.l;
}
void {class}::op_txs_n() {
{lc}op_io_irq();
regs.s.w = regs.x.w;
}
@endmacro
@macro op_push(name, r)
void {class}::op_{name}_b() {
op_io();
{lc}op_writestack(regs.{r}.l);
}
void {class}::op_{name}_w() {
op_io();
op_writestack(regs.{r}.h);
{lc}op_writestack(regs.{r}.l);
}
@endmacro
@macro op_phd()
void {class}::op_phd_e() {
op_io();
op_writestackn(regs.d.h);
{lc}op_writestackn(regs.d.l);
regs.s.h = 0x01;
}
void {class}::op_phd_n() {
op_io();
op_writestackn(regs.d.h);
{lc}op_writestackn(regs.d.l);
}
@endmacro
@macro op_push_byte(name, r)
void {class}::op_{name}() {
op_io();
{lc}op_writestack({r});
}
@endmacro
@macro op_pull(name, r)
void {class}::op_{name}_b() {
op_io();
op_io();
{lc}regs.{r}.l = op_readstack();
regs.p.n = (regs.{r}.l & 0x80);
regs.p.z = (regs.{r}.l == 0);
}
void {class}::op_{name}_w() {
op_io();
op_io();
regs.{r}.l = op_readstack();
{lc}regs.{r}.h = op_readstack();
regs.p.n = (regs.{r}.w & 0x8000);
regs.p.z = (regs.{r}.w == 0);
}
@endmacro
@macro op_pld()
void {class}::op_pld_e() {
op_io();
op_io();
regs.d.l = op_readstackn();
{lc}regs.d.h = op_readstackn();
regs.p.n = (regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
regs.s.h = 0x01;
}
void {class}::op_pld_n() {
op_io();
op_io();
regs.d.l = op_readstackn();
{lc}regs.d.h = op_readstackn();
regs.p.n = (regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
}
@endmacro
@macro op_plb()
void {class}::op_plb() {
op_io();
op_io();
{lc}regs.db = op_readstack();
regs.p.n = (regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
@endmacro
@macro op_plp()
void {class}::op_plp_e() {
op_io();
op_io();
{lc}regs.p = op_readstack() | 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
update_table();
}
void {class}::op_plp_n() {
op_io();
op_io();
{lc}regs.p = op_readstack();
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
update_table();
}
@endmacro
@macro op_pea()
void {class}::op_pea_e() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestackn(aa.h);
{lc}op_writestackn(aa.l);
regs.s.h = 0x01;
}
void {class}::op_pea_n() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestackn(aa.h);
{lc}op_writestackn(aa.l);
}
@endmacro
@macro op_pei()
void {class}::op_pei_e() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_writestackn(aa.h);
{lc}op_writestackn(aa.l);
regs.s.h = 0x01;
}
void {class}::op_pei_n() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_writestackn(aa.h);
{lc}op_writestackn(aa.l);
}
@endmacro
@macro op_per()
void {class}::op_per_e() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.w = regs.pc.d + (int16_t)aa.w;
op_writestackn(rd.h);
{lc}op_writestackn(rd.l);
regs.s.h = 0x01;
}
void {class}::op_per_n() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.w = regs.pc.d + (int16_t)aa.w;
op_writestackn(rd.h);
{lc}op_writestackn(rd.l);
}
@endmacro

View File

@@ -0,0 +1,205 @@
@macro op_branch(name, condition)
void {class}::op_{name}() {
if({condition} == false) {
{lc} rd.l = op_readpc();
} else {
rd.l = op_readpc();
aa.w = regs.pc.d + (int8_t)rd.l;
op_io_cond6(aa.w);
{lc} op_io();
regs.pc.w = aa.w;
}
}
@endmacro
@macro op_bra()
void {class}::op_bra() {
rd.l = op_readpc();
aa.w = regs.pc.d + (int8_t)rd.l;
op_io_cond6(aa.w);
{lc}op_io();
regs.pc.w = aa.w;
}
@endmacro
@macro op_brl()
void {class}::op_brl() {
rd.l = op_readpc();
rd.h = op_readpc();
{lc}op_io();
regs.pc.w = regs.pc.d + (int16_t)rd.w;
}
@endmacro
@macro op_jmp_addr()
void {class}::op_jmp_addr() {
rd.l = op_readpc();
{lc}rd.h = op_readpc();
regs.pc.w = rd.w;
}
@endmacro
@macro op_jmp_long()
void {class}::op_jmp_long() {
rd.l = op_readpc();
rd.h = op_readpc();
{lc}rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
}
@endmacro
@macro op_jmp_iaddr()
void {class}::op_jmp_iaddr() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readaddr(aa.w + 0);
{lc}rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
}
@endmacro
@macro op_jmp_iaddrx()
void {class}::op_jmp_iaddrx() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w + 0);
{lc}rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
@endmacro
@macro op_jmp_iladdr()
void {class}::op_jmp_iladdr() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readaddr(aa.w + 0);
rd.h = op_readaddr(aa.w + 1);
{lc}rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
}
@endmacro
@macro op_jsr_addr()
void {class}::op_jsr_addr() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
regs.pc.w--;
op_writestack(regs.pc.h);
{lc}op_writestack(regs.pc.l);
regs.pc.w = aa.w;
}
@endmacro
@macro op_jsr_long()
void {class}::op_jsr_long_e() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestackn(regs.pc.b);
op_io();
aa.b = op_readpc();
regs.pc.w--;
op_writestackn(regs.pc.h);
{lc}op_writestackn(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
regs.s.h = 0x01;
}
void {class}::op_jsr_long_n() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestackn(regs.pc.b);
op_io();
aa.b = op_readpc();
regs.pc.w--;
op_writestackn(regs.pc.h);
{lc}op_writestackn(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
}
@endmacro
@macro op_jsr_iaddrx()
void {class}::op_jsr_iaddrx_e() {
aa.l = op_readpc();
op_writestackn(regs.pc.h);
op_writestackn(regs.pc.l);
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w + 0);
{lc}rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
regs.s.h = 0x01;
}
void {class}::op_jsr_iaddrx_n() {
aa.l = op_readpc();
op_writestackn(regs.pc.h);
op_writestackn(regs.pc.l);
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w + 0);
{lc}rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
@endmacro
@macro op_rti()
void {class}::op_rti_e() {
op_io();
op_io();
regs.p = op_readstack() | 0x30;
rd.l = op_readstack();
{lc}rd.h = op_readstack();
regs.pc.w = rd.w;
}
void {class}::op_rti_n() {
op_io();
op_io();
regs.p = op_readstack();
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
rd.l = op_readstack();
rd.h = op_readstack();
{lc}rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
update_table();
}
@endmacro
@macro op_rts()
void {class}::op_rts() {
op_io();
op_io();
rd.l = op_readstack();
rd.h = op_readstack();
{lc}op_io();
regs.pc.w = ++rd.w;
}
@endmacro
@macro op_rtl()
void {class}::op_rtl_e() {
op_io();
op_io();
rd.l = op_readstackn();
rd.h = op_readstackn();
{lc}rd.b = op_readstackn();
regs.pc.b = rd.b;
regs.pc.w = ++rd.w;
regs.s.h = 0x01;
}
void {class}::op_rtl_n() {
op_io();
op_io();
rd.l = op_readstackn();
rd.h = op_readstackn();
{lc}rd.b = op_readstackn();
regs.pc.b = rd.b;
regs.pc.w = ++rd.w;
}
@endmacro

View File

@@ -0,0 +1,307 @@
@macro op_read_const(name)
void {class}::op_{name}_const_b() {
{lc}rd.l = op_readpc();
op_{name}_b();
}
void {class}::op_{name}_const_w() {
rd.l = op_readpc();
{lc}rd.h = op_readpc();
op_{name}_w();
}
@endmacro
@macro op_read_bit_const()
void {class}::op_bit_const_b() {
{lc}rd.l = op_readpc();
regs.p.z = ((rd.l & regs.a.l) == 0);
}
void {class}::op_bit_const_w() {
rd.l = op_readpc();
{lc}rd.h = op_readpc();
regs.p.z = ((rd.w & regs.a.w) == 0);
}
@endmacro
@macro op_read_addr(name)
void {class}::op_{name}_addr_b() {
aa.l = op_readpc();
aa.h = op_readpc();
{lc}rd.l = op_readdbr(aa.w);
op_{name}_b();
}
void {class}::op_{name}_addr_w() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w + 0);
{lc}rd.h = op_readdbr(aa.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_addrx(name)
void {class}::op_{name}_addrx_b() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io_cond4(aa.w, aa.w + regs.x.w);
{lc}rd.l = op_readdbr(aa.w + regs.x.w);
op_{name}_b();
}
void {class}::op_{name}_addrx_w() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io_cond4(aa.w, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w + 0);
{lc}rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_addry(name)
void {class}::op_{name}_addry_b() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io_cond4(aa.w, aa.w + regs.y.w);
{lc}rd.l = op_readdbr(aa.w + regs.y.w);
op_{name}_b();
}
void {class}::op_{name}_addry_w() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io_cond4(aa.w, aa.w + regs.y.w);
rd.l = op_readdbr(aa.w + regs.y.w + 0);
{lc}rd.h = op_readdbr(aa.w + regs.y.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_long(name)
void {class}::op_{name}_long_b() {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
{lc}rd.l = op_readlong(aa.d);
op_{name}_b();
}
void {class}::op_{name}_long_w() {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
rd.l = op_readlong(aa.d + 0);
{lc}rd.h = op_readlong(aa.d + 1);
op_{name}_w();
}
@endmacro
@macro op_read_longx(name)
void {class}::op_{name}_longx_b() {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
{lc}rd.l = op_readlong(aa.d + regs.x.w);
op_{name}_b();
}
void {class}::op_{name}_longx_w() {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
rd.l = op_readlong(aa.d + regs.x.w + 0);
{lc}rd.h = op_readlong(aa.d + regs.x.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_dp(name)
void {class}::op_{name}_dp_b() {
dp = op_readpc();
op_io_cond2();
{lc}rd.l = op_readdp(dp);
op_{name}_b();
}
void {class}::op_{name}_dp_w() {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp + 0);
{lc}rd.h = op_readdp(dp + 1);
op_{name}_w();
}
@endmacro
@macro op_read_dpr(name, r)
void {class}::op_{name}_dpr_b() {
dp = op_readpc();
op_io_cond2();
op_io();
{lc}rd.l = op_readdp(dp + regs.{r}.w);
op_{name}_b();
}
void {class}::op_{name}_dpr_w() {
dp = op_readpc();
op_io_cond2();
op_io();
{lc}rd.l = op_readdp(dp + regs.{r}.w + 0);
rd.h = op_readdp(dp + regs.{r}.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_idp(name)
void {class}::op_{name}_idp_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
{lc}rd.l = op_readdbr(aa.w);
op_{name}_b();
}
void {class}::op_{name}_idp_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
rd.l = op_readdbr(aa.w + 0);
{lc}rd.h = op_readdbr(aa.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_idpx(name)
void {class}::op_{name}_idpx_b() {
dp = op_readpc();
op_io_cond2();
op_io();
aa.l = op_readdp(dp + regs.x.w + 0);
aa.h = op_readdp(dp + regs.x.w + 1);
{lc}rd.l = op_readdbr(aa.w);
op_{name}_b();
}
void {class}::op_{name}_idpx_w() {
dp = op_readpc();
op_io_cond2();
op_io();
aa.l = op_readdp(dp + regs.x.w + 0);
aa.h = op_readdp(dp + regs.x.w + 1);
rd.l = op_readdbr(aa.w + 0);
{lc}rd.h = op_readdbr(aa.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_idpy(name)
void {class}::op_{name}_idpy_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_io_cond4(aa.w, aa.w + regs.y.w);
{lc}rd.l = op_readdbr(aa.w + regs.y.w);
op_{name}_b();
}
void {class}::op_{name}_idpy_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_io_cond4(aa.w, aa.w + regs.y.w);
rd.l = op_readdbr(aa.w + regs.y.w + 0);
{lc}rd.h = op_readdbr(aa.w + regs.y.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_ildp(name)
void {class}::op_{name}_ildp_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
{lc}rd.l = op_readlong(aa.d);
op_{name}_b();
}
void {class}::op_{name}_ildp_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
rd.l = op_readlong(aa.d + 0);
{lc}rd.h = op_readlong(aa.d + 1);
op_{name}_w();
}
@endmacro
@macro op_read_ildpy(name)
void {class}::op_{name}_ildpy_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
{lc}rd.l = op_readlong(aa.d + regs.y.w);
op_{name}_b();
}
void {class}::op_{name}_ildpy_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
rd.l = op_readlong(aa.d + regs.y.w + 0);
{lc}rd.h = op_readlong(aa.d + regs.y.w + 1);
op_{name}_w();
}
@endmacro
@macro op_read_sr(name)
void {class}::op_{name}_sr_b() {
sp = op_readpc();
op_io();
{lc}rd.l = op_readsp(sp);
op_{name}_b();
}
void {class}::op_{name}_sr_w() {
sp = op_readpc();
op_io();
rd.l = op_readsp(sp + 0);
{lc}rd.h = op_readsp(sp + 1);
op_{name}_w();
}
@endmacro
@macro op_read_isry(name)
void {class}::op_{name}_isry_b() {
sp = op_readpc();
op_io();
aa.l = op_readsp(sp + 0);
aa.h = op_readsp(sp + 1);
op_io();
{lc}rd.l = op_readdbr(aa.w + regs.y.w);
op_{name}_b();
}
void {class}::op_{name}_isry_w() {
sp = op_readpc();
op_io();
aa.l = op_readsp(sp + 0);
aa.h = op_readsp(sp + 1);
op_io();
rd.l = op_readdbr(aa.w + regs.y.w + 0);
{lc}rd.h = op_readdbr(aa.w + regs.y.w + 1);
op_{name}_w();
}
@endmacro

View File

@@ -0,0 +1,183 @@
@macro op_adjust(name, r, op)
void {class}::op_{name}_imm_b() {
{lc}op_io_irq();
regs.{r}.l {op};
regs.p.n = (regs.{r}.l & 0x80);
regs.p.z = (regs.{r}.l == 0);
}
void {class}::op_{name}_imm_w() {
{lc}op_io_irq();
regs.{r}.w {op};
regs.p.n = (regs.{r}.w & 0x8000);
regs.p.z = (regs.{r}.w == 0);
}
@endmacro
@macro op_asl()
void {class}::op_asl_imm_b() {
{lc}op_io_irq();
regs.p.c = (regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = (regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void {class}::op_asl_imm_w() {
{lc}op_io_irq();
regs.p.c = (regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.p.n = (regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@endmacro
@macro op_lsr()
void {class}::op_lsr_imm_b() {
{lc}op_io_irq();
regs.p.c = (regs.a.l & 0x01);
regs.a.l >>= 1;
regs.p.n = (regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void {class}::op_lsr_imm_w() {
{lc}op_io_irq();
regs.p.c = (regs.a.w & 0x0001);
regs.a.w >>= 1;
regs.p.n = (regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@endmacro
@macro op_rol()
void {class}::op_rol_imm_b() {
{lc}op_io_irq();
bool carry = regs.p.c;
regs.p.c = (regs.a.l & 0x80);
regs.a.l = (regs.a.l << 1) | carry;
regs.p.n = (regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void {class}::op_rol_imm_w() {
{lc}op_io_irq();
bool carry = regs.p.c;
regs.p.c = (regs.a.w & 0x8000);
regs.a.w = (regs.a.w << 1) | carry;
regs.p.n = (regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@endmacro
@macro op_ror()
void {class}::op_ror_imm_b() {
{lc}op_io_irq();
bool carry = regs.p.c;
regs.p.c = (regs.a.l & 0x01);
regs.a.l = (carry << 7) | (regs.a.l >> 1);
regs.p.n = (regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void {class}::op_ror_imm_w() {
{lc}op_io_irq();
bool carry = regs.p.c;
regs.p.c = (regs.a.w & 0x0001);
regs.a.w = (carry << 15) | (regs.a.w >> 1);
regs.p.n = (regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@endmacro
@macro op_adjust_addr(name)
void {class}::op_{name}_addr_b() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
op_io();
op_{name}_b();
{lc}op_writedbr(aa.w, rd.l);
}
void {class}::op_{name}_addr_w() {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w + 0);
rd.h = op_readdbr(aa.w + 1);
op_io();
op_{name}_w();
op_writedbr(aa.w + 1, rd.h);
{lc}op_writedbr(aa.w + 0, rd.l);
}
@endmacro
@macro op_adjust_addrx(name)
void {class}::op_{name}_addrx_b() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
op_io();
op_{name}_b();
{lc}op_writedbr(aa.w + regs.x.w, rd.l);
}
void {class}::op_{name}_addrx_w() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w + 0);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
op_{name}_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h);
{lc}op_writedbr(aa.w + regs.x.w + 0, rd.l);
}
@endmacro
@macro op_adjust_dp(name)
void {class}::op_{name}_dp_b() {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
op_io();
op_{name}_b();
{lc}op_writedp(dp, rd.l);
}
void {class}::op_{name}_dp_w() {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp + 0);
rd.h = op_readdp(dp + 1);
op_io();
op_{name}_w();
op_writedp(dp + 1, rd.h);
{lc}op_writedp(dp + 0, rd.l);
}
@endmacro
@macro op_adjust_dpx(name)
void {class}::op_{name}_dpx_b() {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
op_io();
op_{name}_b();
{lc}op_writedp(dp + regs.x.w, rd.l);
}
void {class}::op_{name}_dpx_w() {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w + 0);
rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
op_{name}_w();
op_writedp(dp + regs.x.w + 1, rd.h);
{lc}op_writedp(dp + regs.x.w + 0, rd.l);
}
@endmacro

View File

@@ -0,0 +1,141 @@
#ifdef CPUCORE_CPP
void CPUcore::initialize_opcode_table() {
//same implementation for all processor states
#define opA(id, name) \
op_table[table_EM + id] = &CPUcore::op_ ## name; \
op_table[table_MX + id] = &CPUcore::op_ ## name; \
op_table[table_Mx + id] = &CPUcore::op_ ## name; \
op_table[table_mX + id] = &CPUcore::op_ ## name; \
op_table[table_mx + id] = &CPUcore::op_ ## name;
//implementation changes based on E processor state
#define opE(id, name) \
op_table[table_EM + id] = &CPUcore::op_ ## name ## _e; \
op_table[table_MX + id] = &CPUcore::op_ ## name ## _n; \
op_table[table_Mx + id] = &CPUcore::op_ ## name ## _n; \
op_table[table_mX + id] = &CPUcore::op_ ## name ## _n; \
op_table[table_mx + id] = &CPUcore::op_ ## name ## _n; \
//implementation changes based on M processor state
#define opM(id, name) \
op_table[table_EM + id] = &CPUcore::op_ ## name ## _b; \
op_table[table_MX + id] = &CPUcore::op_ ## name ## _b; \
op_table[table_Mx + id] = &CPUcore::op_ ## name ## _b; \
op_table[table_mX + id] = &CPUcore::op_ ## name ## _w; \
op_table[table_mx + id] = &CPUcore::op_ ## name ## _w;
//implementation changes based on X processor state
#define opX(id, name) \
op_table[table_EM + id] = &CPUcore::op_ ## name ## _b; \
op_table[table_MX + id] = &CPUcore::op_ ## name ## _b; \
op_table[table_Mx + id] = &CPUcore::op_ ## name ## _w; \
op_table[table_mX + id] = &CPUcore::op_ ## name ## _b; \
op_table[table_mx + id] = &CPUcore::op_ ## name ## _w;
opE(0x00, brk) opM(0x01, ora_idpx) opE(0x02, cop) opM(0x03, ora_sr)
opM(0x04, tsb_dp) opM(0x05, ora_dp) opM(0x06, asl_dp) opM(0x07, ora_ildp)
opA(0x08, php) opM(0x09, ora_const) opM(0x0a, asl_imm) opE(0x0b, phd)
opM(0x0c, tsb_addr) opM(0x0d, ora_addr) opM(0x0e, asl_addr) opM(0x0f, ora_long)
opA(0x10, bpl) opM(0x11, ora_idpy) opM(0x12, ora_idp) opM(0x13, ora_isry)
opM(0x14, trb_dp) opM(0x15, ora_dpr) opM(0x16, asl_dpx) opM(0x17, ora_ildpy)
opA(0x18, clc) opM(0x19, ora_addry) opM(0x1a, inc_imm) opE(0x1b, tcs)
opM(0x1c, trb_addr) opM(0x1d, ora_addrx) opM(0x1e, asl_addrx) opM(0x1f, ora_longx)
opA(0x20, jsr_addr) opM(0x21, and_idpx) opE(0x22, jsr_long) opM(0x23, and_sr)
opM(0x24, bit_dp) opM(0x25, and_dp) opM(0x26, rol_dp) opM(0x27, and_ildp)
opE(0x28, plp) opM(0x29, and_const) opM(0x2a, rol_imm) opE(0x2b, pld)
opM(0x2c, bit_addr) opM(0x2d, and_addr) opM(0x2e, rol_addr) opM(0x2f, and_long)
opA(0x30, bmi) opM(0x31, and_idpy) opM(0x32, and_idp) opM(0x33, and_isry)
opM(0x34, bit_dpr) opM(0x35, and_dpr) opM(0x36, rol_dpx) opM(0x37, and_ildpy)
opA(0x38, sec) opM(0x39, and_addry) opM(0x3a, dec_imm) opE(0x3b, tsc)
opM(0x3c, bit_addrx) opM(0x3d, and_addrx) opM(0x3e, rol_addrx) opM(0x3f, and_longx)
opE(0x40, rti) opM(0x41, eor_idpx) opA(0x42, wdm) opM(0x43, eor_sr)
opX(0x44, mvp) opM(0x45, eor_dp) opM(0x46, lsr_dp) opM(0x47, eor_ildp)
opM(0x48, pha) opM(0x49, eor_const) opM(0x4a, lsr_imm) opA(0x4b, phk)
opA(0x4c, jmp_addr) opM(0x4d, eor_addr) opM(0x4e, lsr_addr) opM(0x4f, eor_long)
opA(0x50, bvc) opM(0x51, eor_idpy) opM(0x52, eor_idp) opM(0x53, eor_isry)
opX(0x54, mvn) opM(0x55, eor_dpr) opM(0x56, lsr_dpx) opM(0x57, eor_ildpy)
opA(0x58, cli) opM(0x59, eor_addry) opX(0x5a, phy) opA(0x5b, tcd)
opA(0x5c, jmp_long) opM(0x5d, eor_addrx) opM(0x5e, lsr_addrx) opM(0x5f, eor_longx)
opA(0x60, rts) opM(0x61, adc_idpx) opE(0x62, per) opM(0x63, adc_sr)
opM(0x64, stz_dp) opM(0x65, adc_dp) opM(0x66, ror_dp) opM(0x67, adc_ildp)
opM(0x68, pla) opM(0x69, adc_const) opM(0x6a, ror_imm) opE(0x6b, rtl)
opA(0x6c, jmp_iaddr) opM(0x6d, adc_addr) opM(0x6e, ror_addr) opM(0x6f, adc_long)
opA(0x70, bvs) opM(0x71, adc_idpy) opM(0x72, adc_idp) opM(0x73, adc_isry)
opM(0x74, stz_dpr) opM(0x75, adc_dpr) opM(0x76, ror_dpx) opM(0x77, adc_ildpy)
opA(0x78, sei) opM(0x79, adc_addry) opX(0x7a, ply) opA(0x7b, tdc)
opA(0x7c, jmp_iaddrx) opM(0x7d, adc_addrx) opM(0x7e, ror_addrx) opM(0x7f, adc_longx)
opA(0x80, bra) opM(0x81, sta_idpx) opA(0x82, brl) opM(0x83, sta_sr)
opX(0x84, sty_dp) opM(0x85, sta_dp) opX(0x86, stx_dp) opM(0x87, sta_ildp)
opX(0x88, dey_imm) opM(0x89, bit_const) opM(0x8a, txa) opA(0x8b, phb)
opX(0x8c, sty_addr) opM(0x8d, sta_addr) opX(0x8e, stx_addr) opM(0x8f, sta_long)
opA(0x90, bcc) opM(0x91, sta_idpy) opM(0x92, sta_idp) opM(0x93, sta_isry)
opX(0x94, sty_dpr) opM(0x95, sta_dpr) opX(0x96, stx_dpr) opM(0x97, sta_ildpy)
opM(0x98, tya) opM(0x99, sta_addry) opE(0x9a, txs) opX(0x9b, txy)
opM(0x9c, stz_addr) opM(0x9d, sta_addrx) opM(0x9e, stz_addrx) opM(0x9f, sta_longx)
opX(0xa0, ldy_const) opM(0xa1, lda_idpx) opX(0xa2, ldx_const) opM(0xa3, lda_sr)
opX(0xa4, ldy_dp) opM(0xa5, lda_dp) opX(0xa6, ldx_dp) opM(0xa7, lda_ildp)
opX(0xa8, tay) opM(0xa9, lda_const) opX(0xaa, tax) opA(0xab, plb)
opX(0xac, ldy_addr) opM(0xad, lda_addr) opX(0xae, ldx_addr) opM(0xaf, lda_long)
opA(0xb0, bcs) opM(0xb1, lda_idpy) opM(0xb2, lda_idp) opM(0xb3, lda_isry)
opX(0xb4, ldy_dpr) opM(0xb5, lda_dpr) opX(0xb6, ldx_dpr) opM(0xb7, lda_ildpy)
opA(0xb8, clv) opM(0xb9, lda_addry) opX(0xba, tsx) opX(0xbb, tyx)
opX(0xbc, ldy_addrx) opM(0xbd, lda_addrx) opX(0xbe, ldx_addry) opM(0xbf, lda_longx)
opX(0xc0, cpy_const) opM(0xc1, cmp_idpx) opE(0xc2, rep) opM(0xc3, cmp_sr)
opX(0xc4, cpy_dp) opM(0xc5, cmp_dp) opM(0xc6, dec_dp) opM(0xc7, cmp_ildp)
opX(0xc8, iny_imm) opM(0xc9, cmp_const) opX(0xca, dex_imm) opA(0xcb, wai)
opX(0xcc, cpy_addr) opM(0xcd, cmp_addr) opM(0xce, dec_addr) opM(0xcf, cmp_long)
opA(0xd0, bne) opM(0xd1, cmp_idpy) opM(0xd2, cmp_idp) opM(0xd3, cmp_isry)
opE(0xd4, pei) opM(0xd5, cmp_dpr) opM(0xd6, dec_dpx) opM(0xd7, cmp_ildpy)
opA(0xd8, cld) opM(0xd9, cmp_addry) opX(0xda, phx) opA(0xdb, stp)
opA(0xdc, jmp_iladdr) opM(0xdd, cmp_addrx) opM(0xde, dec_addrx) opM(0xdf, cmp_longx)
opX(0xe0, cpx_const) opM(0xe1, sbc_idpx) opE(0xe2, sep) opM(0xe3, sbc_sr)
opX(0xe4, cpx_dp) opM(0xe5, sbc_dp) opM(0xe6, inc_dp) opM(0xe7, sbc_ildp)
opX(0xe8, inx_imm) opM(0xe9, sbc_const) opA(0xea, nop) opA(0xeb, xba)
opX(0xec, cpx_addr) opM(0xed, sbc_addr) opM(0xee, inc_addr) opM(0xef, sbc_long)
opA(0xf0, beq) opM(0xf1, sbc_idpy) opM(0xf2, sbc_idp) opM(0xf3, sbc_isry)
opE(0xf4, pea) opM(0xf5, sbc_dpr) opM(0xf6, inc_dpx) opM(0xf7, sbc_ildpy)
opA(0xf8, sed) opM(0xf9, sbc_addry) opX(0xfa, plx) opA(0xfb, xce)
opE(0xfc, jsr_iaddrx) opM(0xfd, sbc_addrx) opM(0xfe, inc_addrx) opM(0xff, sbc_longx)
#undef opA
#undef opE
#undef opM
#undef opX
}
void CPUcore::update_table() {
if(regs.e) {
opcode_table = &op_table[table_EM];
} else if(regs.p.m) {
if(regs.p.x) {
opcode_table = &op_table[table_MX];
} else {
opcode_table = &op_table[table_Mx];
}
} else {
if(regs.p.x) {
opcode_table = &op_table[table_mX];
} else {
opcode_table = &op_table[table_mx];
}
}
}
#endif

View File

@@ -0,0 +1,219 @@
@macro op_store_addr(name, r)
void {class}::op_{name}_addr_b() {
aa.l = op_readpc();
aa.h = op_readpc();
{lc}op_writedbr(aa.w, {r});
}
void {class}::op_{name}_addr_w() {
aa.l = op_readpc();
aa.h = op_readpc();
op_writedbr(aa.w + 0, {r} >> 0);
{lc}op_writedbr(aa.w + 1, {r} >> 8);
}
@endmacro
@macro op_store_addrr(name, suffix, r, index)
void {class}::op_{name}_addr{suffix}_b() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
{lc}op_writedbr(aa.w + {index}, {r});
}
void {class}::op_{name}_addr{suffix}_w() {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
op_writedbr(aa.w + {index} + 0, {r} >> 0);
{lc}op_writedbr(aa.w + {index} + 1, {r} >> 8);
}
@endmacro
@macro op_store_longr(name, suffix, index)
void {class}::op_{name}_long{suffix}_b() {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
{lc}op_writelong(aa.d + {index}, regs.a.l);
}
void {class}::op_{name}_long{suffix}_w() {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
op_writelong(aa.d + {index} + 0, regs.a.l);
{lc}op_writelong(aa.d + {index} + 1, regs.a.h);
}
@endmacro
@macro op_store_dp(name, r)
void {class}::op_{name}_dp_b() {
dp = op_readpc();
op_io_cond2();
{lc}op_writedp(dp, {r});
}
void {class}::op_{name}_dp_w() {
dp = op_readpc();
op_io_cond2();
op_writedp(dp + 0, {r} >> 0);
{lc}op_writedp(dp + 1, {r} >> 8);
}
@endmacro
@macro op_store_dpr(name, r, index)
void {class}::op_{name}_dpr_b() {
dp = op_readpc();
op_io_cond2();
op_io();
{lc}op_writedp(dp + regs.{index}.w, {r});
}
void {class}::op_{name}_dpr_w() {
dp = op_readpc();
op_io_cond2();
op_io();
op_writedp(dp + regs.{index}.w + 0, {r} >> 0);
{lc}op_writedp(dp + regs.{index}.w + 1, {r} >> 8);
}
@endmacro
@macro op_sta_idp()
void {class}::op_sta_idp_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
{lc}op_writedbr(aa.w, regs.a.l);
}
void {class}::op_sta_idp_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_writedbr(aa.w + 0, regs.a.l);
{lc}op_writedbr(aa.w + 1, regs.a.h);
}
@endmacro
@macro op_sta_ildp()
void {class}::op_sta_ildp_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
{lc}op_writelong(aa.d, regs.a.l);
}
void {class}::op_sta_ildp_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
op_writelong(aa.d + 0, regs.a.l);
{lc}op_writelong(aa.d + 1, regs.a.h);
}
@endmacro
@macro op_sta_idpx()
void {class}::op_sta_idpx_b() {
dp = op_readpc();
op_io_cond2();
op_io();
aa.l = op_readdp(dp + regs.x.w + 0);
aa.h = op_readdp(dp + regs.x.w + 1);
{lc}op_writedbr(aa.w, regs.a.l);
}
void {class}::op_sta_idpx_w() {
dp = op_readpc();
op_io_cond2();
op_io();
aa.l = op_readdp(dp + regs.x.w + 0);
aa.h = op_readdp(dp + regs.x.w + 1);
op_writedbr(aa.w + 0, regs.a.l);
{lc}op_writedbr(aa.w + 1, regs.a.h);
}
@endmacro
@macro op_sta_idpy()
void {class}::op_sta_idpy_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_io();
{lc}op_writedbr(aa.w + regs.y.w, regs.a.l);
}
void {class}::op_sta_idpy_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
op_io();
op_writedbr(aa.w + regs.y.w + 0, regs.a.l);
{lc}op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
@endmacro
@macro op_sta_ildpy()
void {class}::op_sta_ildpy_b() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
{lc}op_writelong(aa.d + regs.y.w, regs.a.l);
}
void {class}::op_sta_ildpy_w() {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp + 0);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
op_writelong(aa.d + regs.y.w + 0, regs.a.l);
{lc}op_writelong(aa.d + regs.y.w + 1, regs.a.h);
}
@endmacro
@macro op_sta_sr()
void {class}::op_sta_sr_b() {
sp = op_readpc();
op_io();
{lc}op_writesp(sp, regs.a.l);
}
void {class}::op_sta_sr_w() {
sp = op_readpc();
op_io();
op_writesp(sp + 0, regs.a.l);
{lc}op_writesp(sp + 1, regs.a.h);
}
@endmacro
@macro op_sta_isry()
void {class}::op_sta_isry_b() {
sp = op_readpc();
op_io();
aa.l = op_readsp(sp + 0);
aa.h = op_readsp(sp + 1);
op_io();
{lc}op_writedbr(aa.w + regs.y.w, regs.a.l);
}
void {class}::op_sta_isry_w() {
sp = op_readpc();
op_io();
aa.l = op_readsp(sp + 0);
aa.h = op_readsp(sp + 1);
op_io();
op_writedbr(aa.w + regs.y.w + 0, regs.a.l);
{lc}op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
@endmacro

View File

@@ -0,0 +1,79 @@
struct flag_t {
bool n, v, m, x, d, i, z, c;
inline operator unsigned() const {
return (n << 7) + (v << 6) + (m << 5) + (x << 4)
+ (d << 3) + (i << 2) + (z << 1) + (c << 0);
}
inline unsigned operator=(uint8_t data) {
n = data & 0x80; v = data & 0x40; m = data & 0x20; x = data & 0x10;
d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01;
return data;
}
inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); }
inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); }
inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); }
flag_t() : n(0), v(0), m(0), x(0), d(0), i(0), z(0), c(0) {}
};
struct reg16_t {
union {
uint16 w;
struct { uint8 order_lsb2(l, h); };
};
inline operator unsigned() const { return w; }
inline unsigned operator = (unsigned i) { return w = i; }
inline unsigned operator |= (unsigned i) { return w |= i; }
inline unsigned operator ^= (unsigned i) { return w ^= i; }
inline unsigned operator &= (unsigned i) { return w &= i; }
inline unsigned operator <<= (unsigned i) { return w <<= i; }
inline unsigned operator >>= (unsigned i) { return w >>= i; }
inline unsigned operator += (unsigned i) { return w += i; }
inline unsigned operator -= (unsigned i) { return w -= i; }
inline unsigned operator *= (unsigned i) { return w *= i; }
inline unsigned operator /= (unsigned i) { return w /= i; }
inline unsigned operator %= (unsigned i) { return w %= i; }
reg16_t() : w(0) {}
};
struct reg24_t {
union {
uint32 d;
struct { uint16 order_lsb2(w, wh); };
struct { uint8 order_lsb4(l, h, b, bh); };
};
inline operator unsigned() const { return d; }
inline unsigned operator = (unsigned i) { return d = uclip<24>(i); }
inline unsigned operator |= (unsigned i) { return d = uclip<24>(d | i); }
inline unsigned operator ^= (unsigned i) { return d = uclip<24>(d ^ i); }
inline unsigned operator &= (unsigned i) { return d = uclip<24>(d & i); }
inline unsigned operator <<= (unsigned i) { return d = uclip<24>(d << i); }
inline unsigned operator >>= (unsigned i) { return d = uclip<24>(d >> i); }
inline unsigned operator += (unsigned i) { return d = uclip<24>(d + i); }
inline unsigned operator -= (unsigned i) { return d = uclip<24>(d - i); }
inline unsigned operator *= (unsigned i) { return d = uclip<24>(d * i); }
inline unsigned operator /= (unsigned i) { return d = uclip<24>(d / i); }
inline unsigned operator %= (unsigned i) { return d = uclip<24>(d % i); }
reg24_t() : d(0) {}
};
struct regs_t {
reg24_t pc;
reg16_t a, x, y, s, d;
flag_t p;
uint8_t db;
bool e;
bool irq; //IRQ pin (0 = low, 1 = trigger)
bool wai; //raised during wai, cleared after interrupt triggered
uint8_t mdr; //memory data register
regs_t() : db(0), e(false), irq(false), wai(false), mdr(0) {}
};