Update to v078r03 release.

byuu says:

I apparently wasted two days writing that SMP core for nothing.  I had
a perfectly well-written and well-tested core in bsnes v045.  The old
opcode.b files that were a cycle-based markup language.

So I took that core, and wrote new parsers to generate both opcode-based
(one switch) and cycle-based (two switch) cores. Throw in a
little #define magic around CYCLE_ACCURATE, and it is compile-time
toggleable.

EWJ2's bug was due to not resetting the timer variables, and Bahamut
Lagoon's was due to dividing timer frequencies by 3, but failing to
remove the 0->1 transition phase (should have done the latter and
divided by two.)

Anyway, all fixed up.
This commit is contained in:
Tim Allen 2011-05-05 21:37:46 +10:00
parent 67e6a6e742
commit 7ffaeb2ac1
31 changed files with 8551 additions and 1013 deletions

View File

@ -1,7 +1,7 @@
include nall/Makefile
snes := snes
gameboy := gameboy
profile := performance
profile := accuracy
ui := ui
# debugger

View File

@ -1,4 +1,4 @@
uint8 SMP::fn_adc(uint8 x, uint8 y) {
uint8 SMP::op_adc(uint8 x, uint8 y) {
int r = x + y + regs.p.c;
regs.p.n = r & 0x80;
regs.p.v = ~(x ^ y) & (x ^ r) & 0x80;
@ -8,23 +8,23 @@ uint8 SMP::fn_adc(uint8 x, uint8 y) {
return r;
}
uint16 SMP::fn_addw(uint16 x, uint16 y) {
uint16 SMP::op_addw(uint16 x, uint16 y) {
uint16 r;
regs.p.c = 0;
r = fn_adc(x, y);
r |= fn_adc(x >> 8, y >> 8) << 8;
r = op_adc(x, y);
r |= op_adc(x >> 8, y >> 8) << 8;
regs.p.z = r == 0;
return r;
}
uint8 SMP::fn_and(uint8 x, uint8 y) {
uint8 SMP::op_and(uint8 x, uint8 y) {
x &= y;
regs.p.n = x & 0x80;
regs.p.z = x == 0;
return x;
}
uint8 SMP::fn_cmp(uint8 x, uint8 y) {
uint8 SMP::op_cmp(uint8 x, uint8 y) {
int r = x - y;
regs.p.n = r & 0x80;
regs.p.z = (uint8)r == 0;
@ -32,7 +32,7 @@ uint8 SMP::fn_cmp(uint8 x, uint8 y) {
return x;
}
uint16 SMP::fn_cmpw(uint16 x, uint16 y) {
uint16 SMP::op_cmpw(uint16 x, uint16 y) {
int r = x - y;
regs.p.n = r & 0x8000;
regs.p.z = (uint16)r == 0;
@ -40,21 +40,21 @@ uint16 SMP::fn_cmpw(uint16 x, uint16 y) {
return x;
}
uint8 SMP::fn_eor(uint8 x, uint8 y) {
uint8 SMP::op_eor(uint8 x, uint8 y) {
x ^= y;
regs.p.n = x & 0x80;
regs.p.z = x == 0;
return x;
}
uint8 SMP::fn_or(uint8 x, uint8 y) {
uint8 SMP::op_or(uint8 x, uint8 y) {
x |= y;
regs.p.n = x & 0x80;
regs.p.z = x == 0;
return x;
}
uint8 SMP::fn_sbc(uint8 x, uint8 y) {
uint8 SMP::op_sbc(uint8 x, uint8 y) {
int r = x - y - !regs.p.c;
regs.p.n = r & 0x80;
regs.p.v = (x ^ y) & (x ^ r) & 0x80;
@ -64,30 +64,30 @@ uint8 SMP::fn_sbc(uint8 x, uint8 y) {
return r;
}
uint16 SMP::fn_subw(uint16 x, uint16 y) {
uint16 SMP::op_subw(uint16 x, uint16 y) {
uint16 r;
regs.p.c = 1;
r = fn_sbc(x, y);
r |= fn_sbc(x >> 8, y >> 8) << 8;
r = op_sbc(x, y);
r |= op_sbc(x >> 8, y >> 8) << 8;
regs.p.z = r == 0;
return r;
}
uint8 SMP::fn_inc(uint8 x) {
uint8 SMP::op_inc(uint8 x) {
x++;
regs.p.n = x & 0x80;
regs.p.z = x == 0;
return x;
}
uint8 SMP::fn_dec(uint8 x) {
uint8 SMP::op_dec(uint8 x) {
x--;
regs.p.n = x & 0x80;
regs.p.z = x == 0;
return x;
}
uint8 SMP::fn_asl(uint8 x) {
uint8 SMP::op_asl(uint8 x) {
regs.p.c = x & 0x80;
x <<= 1;
regs.p.n = x & 0x80;
@ -95,7 +95,7 @@ uint8 SMP::fn_asl(uint8 x) {
return x;
}
uint8 SMP::fn_lsr(uint8 x) {
uint8 SMP::op_lsr(uint8 x) {
regs.p.c = x & 0x01;
x >>= 1;
regs.p.n = x & 0x80;
@ -103,7 +103,7 @@ uint8 SMP::fn_lsr(uint8 x) {
return x;
}
uint8 SMP::fn_rol(uint8 x) {
uint8 SMP::op_rol(uint8 x) {
unsigned carry = (unsigned)regs.p.c;
regs.p.c = x & 0x80;
x = (x << 1) | carry;
@ -112,7 +112,7 @@ uint8 SMP::fn_rol(uint8 x) {
return x;
}
uint8 SMP::fn_ror(uint8 x) {
uint8 SMP::op_ror(uint8 x) {
unsigned carry = (unsigned)regs.p.c << 7;
regs.p.c = x & 0x01;
x = carry | (x >> 1);

View File

@ -1,881 +1,71 @@
void SMP::tick() {
timer0.tick(1);
timer1.tick(1);
timer2.tick(1);
clock += cycle_step_cpu;
dsp.clock -= 24;
synchronize_dsp();
}
void SMP::op_io() {
#if defined(CYCLE_ACCURATE)
tick();
#endif
}
uint8 SMP::op_read(uint16 addr) {
#if defined(CYCLE_ACCURATE)
tick();
#endif
if((addr & 0xfff0) == 0x00f0) return mmio_read(addr);
if((addr & 0xffc0) == 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f];
return apuram[addr];
}
void SMP::op_write(uint16 addr, uint8 data) {
#if defined(CYCLE_ACCURATE)
tick();
#endif
if((addr & 0xfff0) == 0x00f0) mmio_write(addr, data);
apuram[addr] = data; //all writes go to RAM, even MMIO writes
}
//TODO:
//* untaken conditional branches should subtract from opcode's cycle overhead
//* non-cycle accurate untaken conditional branches should subtract from opcode's cycle overhead
void SMP::op_step() {
#define op_readpc() op_read(regs.pc++)
#define op_readdp(addr) op_read((regs.p.p << 8) + addr)
#define op_writedp(addr, data) op_write((regs.p.p << 8) + addr, data)
//#define op_readsp() op_read(0x0100 | ++regs.sp)
//#define op_writesp(data) op_write(0x0100 | regs.sp--, data)
#define op_readsp() stackram[++regs.sp]
#define op_writesp(data) stackram[regs.sp--] = data
#define op_readaddr(addr) op_read(addr)
#define op_writeaddr(addr, data) op_write(addr, data)
#define op_readstack() op_read(0x0100 | ++regs.sp)
#define op_writestack(data) op_write(0x0100 | regs.sp--, data)
static unsigned rd, wr, dp, sp, ya, bit;
#if defined(CYCLE_ACCURATE)
if(opcode_cycle == 0) {
opcode_number = op_readpc();
opcode_cycle++;
} else switch(opcode_number) {
#include "core/opcycle_misc.cpp"
#include "core/opcycle_mov.cpp"
#include "core/opcycle_pc.cpp"
#include "core/opcycle_read.cpp"
#include "core/opcycle_rmw.cpp"
}
#else
unsigned opcode = op_readpc();
switch(opcode) {
case 0x00: //nop
op_io();
break;
case 0xef: //sleep
case 0xff: //stop
regs.pc--;
break;
//
// batch
//
case 0x01: case 0x11: case 0x21: case 0x31: case 0x41: case 0x51: case 0x61: case 0x71:
case 0x81: case 0x91: case 0xa1: case 0xb1: case 0xc1: case 0xd1: case 0xe1: case 0xf1: //tcall vector
dp = 0xffde - ((opcode >> 4) << 1);
rd = op_read(dp + 0) << 0;
rd |= op_read(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writesp(regs.pc >> 8);
op_writesp(regs.pc >> 0);
regs.pc = rd;
break;
case 0x02: case 0x22: case 0x42: case 0x62: case 0x82: case 0xa2: case 0xc2: case 0xe2: //setB $dp
dp = op_readpc();
rd = op_readdp(dp) | (1 << (opcode >> 5));
op_writedp(dp, rd);
break;
case 0x12: case 0x32: case 0x52: case 0x72: case 0x92: case 0xb2: case 0xd2: case 0xf2: //clrB $dp
dp = op_readpc();
rd = op_readdp(dp) &~ (1 << (opcode >> 5));
op_writedp(dp, rd);
break;
case 0x03: case 0x23: case 0x43: case 0x63: case 0x83: case 0xa3: case 0xc3: case 0xe3: //bbsB $dp,$rr
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & (1 << (opcode >> 5))) == 0) break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
case 0x13: case 0x33: case 0x53: case 0x73: case 0x93: case 0xb3: case 0xd3: case 0xf3: //bbcB $dp,$rr
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & (1 << (opcode >> 5))) != 0) break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
case 0x20: op_io(); regs.p.p = 0; break; //clrp
case 0x40: op_io(); regs.p.p = 1; break; //setp
case 0x60: op_io(); regs.p.c = 0; break; //clrc
case 0x80: op_io(); regs.p.c = 1; break; //setc
case 0xe0: op_io(); regs.p.v = 0; break; //clrv
//
case 0xa0: op_io(); op_io(); regs.p.i = 1; break; //ei
case 0xc0: op_io(); op_io(); regs.p.i = 0; break; //di
//
case 0xed: op_io(); op_io(); regs.p.c = !regs.p.c; break; //notc
//
// jump
//
#define OP_BRANCH_IF(condition) \
rd = op_readpc(); \
if((condition) == false) break; \
op_io(); \
op_io(); \
regs.pc += (int8)rd; \
break;
case 0x10: OP_BRANCH_IF(regs.p.n == 0); //bpl $rr
case 0x30: OP_BRANCH_IF(regs.p.n == 1); //bmi $rr
case 0x50: OP_BRANCH_IF(regs.p.v == 0); //bvc $rr
case 0x70: OP_BRANCH_IF(regs.p.v == 1); //bvs $rr
case 0x90: OP_BRANCH_IF(regs.p.c == 0); //bcc $rr
case 0xb0: OP_BRANCH_IF(regs.p.c == 1); //bcs $rr
case 0xd0: OP_BRANCH_IF(regs.p.z == 0); //bne $rr
case 0xf0: OP_BRANCH_IF(regs.p.z == 1); //beq $rr
case 0x0f: //brk
rd = op_read(0xffde) << 0;
rd |= op_read(0xffdf) << 8;
op_io();
op_io();
op_writesp(regs.pc >> 8);
op_writesp(regs.pc >> 0);
op_writesp(regs.p);
regs.pc = rd;
regs.p.b = 1;
regs.p.i = 0;
break;
case 0x1f: //jmp ($aaaa,x)
dp = op_readpc() << 0;
dp |= op_readpc() << 8;
op_io();
dp += regs.x;
rd = op_read(dp + 0) << 0;
rd |= op_read(dp + 1) << 8;
regs.pc = rd;
break;
case 0x2f: //bra $rr
rd = op_readpc();
op_io();
op_io();
regs.pc += (int8)rd;
break;
case 0x3f: //call $addr
rd = op_readpc() << 0;
rd |= op_readpc() << 8;
op_io();
op_io();
op_io();
op_writesp(regs.pc >> 8);
op_writesp(regs.pc >> 0);
regs.pc = rd;
break;
case 0x4f: //pcall $ff00+$dp
rd = op_readpc();
op_io();
op_io();
op_writesp(regs.pc >> 8);
op_writesp(regs.pc >> 0);
regs.pc = 0xff00 | rd;
break;
case 0x5f: //jmp $addr
rd = op_readpc() << 0;
rd |= op_readpc() << 8;
regs.pc = rd;
break;
case 0x6f: //ret
rd = op_readsp() << 0;
rd |= op_readsp() << 8;
op_io();
op_io();
regs.pc = rd;
break;
case 0x7f: //reti
regs.p = op_readsp();
rd = op_readsp() << 0;
rd |= op_readsp() << 8;
op_io();
op_io();
regs.pc = rd;
break;
case 0x2e: //cbne $dp,$rr
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if(regs.a == sp) break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
case 0x6e: //dbnz $dp,$rr
dp = op_readpc();
wr = op_readdp(dp);
op_writedp(dp, --wr);
rd = op_readpc();
if(wr == 0) break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
case 0xde: //cbne $dp+x,$rr
dp = op_readpc();
op_io();
sp = op_readdp(dp + regs.x);
rd = op_readpc();
op_io();
if(regs.a == sp) break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
case 0xfe: //dbz y,$rr
rd = op_readpc();
op_io();
regs.y--;
op_io();
if(regs.y == 0) break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
//
// stack
//
#define OP_PUSH_REG(source) \
op_io(); \
op_io(); \
op_writesp(source); \
break;
case 0x0d: OP_PUSH_REG(regs.p); //push p
case 0x2d: OP_PUSH_REG(regs.a); //push a
case 0x4d: OP_PUSH_REG(regs.x); //push x
case 0x6d: OP_PUSH_REG(regs.y); //push y
#define OP_POP_REG(target) \
op_io(); \
op_io(); \
target = op_readsp(); \
break;
case 0x8e: OP_POP_REG(regs.p); //pop p
case 0xae: OP_POP_REG(regs.a); //pop a
case 0xce: OP_POP_REG(regs.x); //pop x
case 0xee: OP_POP_REG(regs.y); //pop y
//
// ALU
//
case 0x9e: //div ya,x
op_io(); op_io(); op_io(); op_io();
op_io(); op_io(); op_io(); op_io();
op_io(); op_io(); op_io();
ya = regs.ya;
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
case 0xcf: //mul ya
op_io(); op_io(); op_io(); op_io();
op_io(); op_io(); op_io(); op_io();
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
regs.p.n = (regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
//
// read
//
#define OP_READ_REG_DP(func, target) \
dp = op_readpc(); \
rd = op_readdp(dp); \
target = func(target, rd); \
break;
case 0x04: OP_READ_REG_DP(fn_or, regs.a); //or a,$dp
case 0x24: OP_READ_REG_DP(fn_and, regs.a); //and a,$dp
case 0x44: OP_READ_REG_DP(fn_eor, regs.a); //eor a,$dp
case 0x64: OP_READ_REG_DP(fn_cmp, regs.a); //cmp a,$dp
case 0x84: OP_READ_REG_DP(fn_adc, regs.a); //adc a,$dp
case 0xa4: OP_READ_REG_DP(fn_sbc, regs.a); //sbc a,$dp
//
case 0x3e: OP_READ_REG_DP(fn_cmp, regs.x); //cmp x,$dp
case 0x7e: OP_READ_REG_DP(fn_cmp, regs.y); //cmp y,$dp
#define OP_READ_REG_ADDR(func, target) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
rd = op_read(dp); \
target = func(target, rd); \
break;
case 0x05: OP_READ_REG_ADDR(fn_or, regs.a); //or a,$addr
case 0x25: OP_READ_REG_ADDR(fn_and, regs.a); //and a,$addr
case 0x45: OP_READ_REG_ADDR(fn_eor, regs.a); //eor a,$addr
case 0x65: OP_READ_REG_ADDR(fn_cmp, regs.a); //cmp a,$addr
case 0x85: OP_READ_REG_ADDR(fn_adc, regs.a); //adc a,$addr
case 0xa5: OP_READ_REG_ADDR(fn_sbc, regs.a); //sbc a,$addr
//
case 0x1e: OP_READ_REG_ADDR(fn_cmp, regs.x); //cmp x,$addr
case 0x5e: OP_READ_REG_ADDR(fn_cmp, regs.y); //cmp y,$addr
#define OP_READ_A_IX(func) \
op_io(); \
rd = op_readdp(regs.x); \
regs.a = func(regs.a, rd); \
break;
case 0x06: OP_READ_A_IX(fn_or ); //or a,(x)
case 0x26: OP_READ_A_IX(fn_and); //and a,(x)
case 0x46: OP_READ_A_IX(fn_eor); //eor a,(x)
case 0x66: OP_READ_A_IX(fn_cmp); //cmp a,(x)
case 0x86: OP_READ_A_IX(fn_adc); //adc a,(x)
case 0xa6: OP_READ_A_IX(fn_sbc); //sbc a,(x)
#define OP_READ_A_IDPX(func) \
dp = op_readpc() + regs.x; \
op_io(); \
sp = op_readdp(dp + 0) << 0; \
sp |= op_readdp(dp + 1) << 8; \
rd = op_read(sp); \
regs.a = func(regs.a, rd); \
break;
case 0x07: OP_READ_A_IDPX(fn_or ); //or a,($dp+x)
case 0x27: OP_READ_A_IDPX(fn_and); //and a,($dp+x)
case 0x47: OP_READ_A_IDPX(fn_eor); //eor a,($dp+x)
case 0x67: OP_READ_A_IDPX(fn_cmp); //cmp a,($dp+x)
case 0x87: OP_READ_A_IDPX(fn_adc); //adc a,($dp+x)
case 0xa7: OP_READ_A_IDPX(fn_sbc); //sbc a,($dp+x)
#define OP_READ_REG_CONST(func, target) \
rd = op_readpc(); \
target = func(target, rd); \
break;
case 0x08: OP_READ_REG_CONST(fn_or, regs.a); //or a,#$ss
case 0x28: OP_READ_REG_CONST(fn_and, regs.a); //and a,#$ss
case 0x48: OP_READ_REG_CONST(fn_eor, regs.a); //eor a,#$ss
case 0x68: OP_READ_REG_CONST(fn_cmp, regs.a); //cmp a,#$ss
case 0x88: OP_READ_REG_CONST(fn_adc, regs.a); //adc a,#$ss
case 0xa8: OP_READ_REG_CONST(fn_sbc, regs.a); //sbc a,#$ss
//
case 0xad: OP_READ_REG_CONST(fn_cmp, regs.y); //cmp y,#$ss
case 0xc8: OP_READ_REG_CONST(fn_cmp, regs.x); //cmp x,#$ss
#define OP_READ_DP_DP(func) \
sp = op_readpc(); \
rd = op_readdp(sp); \
dp = op_readpc(); \
wr = op_readdp(dp); \
wr = func(wr, rd);
case 0x09: OP_READ_DP_DP(fn_or ); op_writedp(dp, wr); break; //or $dp,$dp
case 0x29: OP_READ_DP_DP(fn_and); op_writedp(dp, wr); break; //and $dp,$dp
case 0x49: OP_READ_DP_DP(fn_eor); op_writedp(dp, wr); break; //eor $dp,$dp
case 0x69: OP_READ_DP_DP(fn_cmp); op_io(); break; //cmp $dp,$dp
case 0x89: OP_READ_DP_DP(fn_adc); op_writedp(dp, wr); break; //adc $dp,$dp
case 0xa9: OP_READ_DP_DP(fn_sbc); op_writedp(dp, wr); break; //sbc $dp,$dp
#define OP_READ_A_DPX(func) \
dp = op_readpc(); \
op_io(); \
rd = op_readdp(dp + regs.x); \
regs.a = func(regs.a, rd); \
break;
case 0x14: OP_READ_A_DPX(fn_or ); //or a,$dp+x
case 0x34: OP_READ_A_DPX(fn_and); //and a,$dp+x
case 0x54: OP_READ_A_DPX(fn_eor); //eor a,$dp+x
case 0x74: OP_READ_A_DPX(fn_cmp); //cmp a,$dp+x
case 0x94: OP_READ_A_DPX(fn_adc); //adc a,$dp+x
case 0xb4: OP_READ_A_DPX(fn_sbc); //sbc a,$dp+x
#define OP_READ_A_ADDRR(func, source) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
op_io(); \
rd = op_read(dp + source); \
regs.a = func(regs.a, rd); \
break;
case 0x15: OP_READ_A_ADDRR(fn_or , regs.x); //or a,$dp+x
case 0x16: OP_READ_A_ADDRR(fn_or , regs.y); //or a,$dp+y
case 0x35: OP_READ_A_ADDRR(fn_and, regs.x); //and a,$dp+x
case 0x36: OP_READ_A_ADDRR(fn_and, regs.y); //and a,$dp+y
case 0x55: OP_READ_A_ADDRR(fn_eor, regs.x); //eor a,$dp+x
case 0x56: OP_READ_A_ADDRR(fn_eor, regs.y); //eor a,$dp+y
case 0x75: OP_READ_A_ADDRR(fn_cmp, regs.x); //cmp a,$dp+x
case 0x76: OP_READ_A_ADDRR(fn_cmp, regs.y); //cmp a,$dp+y
case 0x95: OP_READ_A_ADDRR(fn_adc, regs.x); //adc a,$dp+x
case 0x96: OP_READ_A_ADDRR(fn_adc, regs.y); //adc a,$dp+y
case 0xb5: OP_READ_A_ADDRR(fn_sbc, regs.x); //sbc a,$dp+x
case 0xb6: OP_READ_A_ADDRR(fn_sbc, regs.y); //sbc a,$dp+y
#define OP_READ_A_IDPY(func) \
dp = op_readpc(); \
op_io(); \
sp = op_readdp(dp + 0) << 0; \
sp |= op_readdp(dp + 1) << 8; \
rd = op_read(sp + regs.y); \
regs.a = func(regs.a, rd); \
break;
case 0x17: OP_READ_A_IDPY(fn_or ); //or a,($dp)+y
case 0x37: OP_READ_A_IDPY(fn_and); //and a,($dp)+y
case 0x57: OP_READ_A_IDPY(fn_eor); //eor a,($dp)+y
case 0x77: OP_READ_A_IDPY(fn_cmp); //cmp a,($dp)+y
case 0x97: OP_READ_A_IDPY(fn_adc); //adc a,($dp)+y
case 0xb7: OP_READ_A_IDPY(fn_sbc); //sbc a,($dp)+y
#define OP_READ_DP_CONST(func) \
rd = op_readpc(); \
dp = op_readpc(); \
wr = op_readdp(dp); \
wr = func(wr, rd);
case 0x18: OP_READ_DP_CONST(fn_or ); op_writedp(dp, wr); break; //or $dp,#$ss
case 0x38: OP_READ_DP_CONST(fn_and); op_writedp(dp, wr); break; //and $dp,#$ss
case 0x58: OP_READ_DP_CONST(fn_eor); op_writedp(dp, wr); break; //eor $dp,#$ss
case 0x78: OP_READ_DP_CONST(fn_cmp); op_io(); break; //cmp $dp,#$ss
case 0x98: OP_READ_DP_CONST(fn_adc); op_writedp(dp, wr); break; //adc $dp,#$ss
case 0xb8: OP_READ_DP_CONST(fn_sbc); op_writedp(dp, wr); break; //sbc $dp,#$ss
#define OP_READ_IX_IY(func) \
op_io(); \
rd = op_readdp(regs.y); \
wr = op_readdp(regs.x); \
wr = func(wr, rd);
case 0x19: OP_READ_IX_IY(fn_or ); op_writedp(regs.x, wr); break; //or (x),(y)
case 0x39: OP_READ_IX_IY(fn_and); op_writedp(regs.x, wr); break; //and (x),(y)
case 0x59: OP_READ_IX_IY(fn_eor); op_writedp(regs.x, wr); break; //eor (x),(y)
case 0x79: OP_READ_IX_IY(fn_cmp); op_io(); break; //cmp (x),(y)
case 0x99: OP_READ_IX_IY(fn_adc); op_writedp(regs.x, wr); break; //adc (x),(y)
case 0xb9: OP_READ_IX_IY(fn_sbc); op_writedp(regs.x, wr); break; //sbc (x),(y)
#define OP_READ_YA_DP(func) \
dp = op_readpc(); \
rd = op_readdp(dp + 0) << 0; \
op_io(); \
rd |= op_readdp(dp + 1) << 8; \
regs.ya = func(regs.ya, rd); \
break;
case 0x7a: OP_READ_YA_DP(fn_addw); //addw $dp
case 0x9a: OP_READ_YA_DP(fn_subw); //subw $dp
//
// move
//
#define OP_MOV_REG_REG(target, source) \
op_io(); \
target = source; \
regs.p.n = (target & 0x80); \
regs.p.z = (target == 0); \
break;
case 0x5d: OP_MOV_REG_REG(regs.x, regs.a ); //mov x,a
case 0x7d: OP_MOV_REG_REG(regs.a, regs.x ); //mov a,x
case 0x9d: OP_MOV_REG_REG(regs.x, regs.sp); //mov x,sp
case 0xdd: OP_MOV_REG_REG(regs.a, regs.y ); //mov a,y
case 0xfd: OP_MOV_REG_REG(regs.y, regs.a ); //mov y,a
#define OP_MOV_REG_CONST(target) \
target = op_readpc(); \
regs.p.n = (target & 0x80); \
regs.p.z = (target == 0); \
break;
case 0x8d: OP_MOV_REG_CONST(regs.y); //mov y,#$ss
case 0xcd: OP_MOV_REG_CONST(regs.x); //mov x,#$ss
case 0xe8: OP_MOV_REG_CONST(regs.a); //mov a,#$ss
#define OP_MOV_DP_REG(source) \
dp = op_readpc(); \
op_readdp(dp); \
op_writedp(dp, source); \
break;
case 0xc4: OP_MOV_DP_REG(regs.a); //mov $dp,a
case 0xcb: OP_MOV_DP_REG(regs.y); //mov $dp,y
case 0xd8: OP_MOV_DP_REG(regs.x); //mov $dp,x
#define OP_MOV_ADDR_REG(source) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
op_read(dp); \
op_write(dp, source); \
break;
case 0xc5: OP_MOV_ADDR_REG(regs.a); //mov $addr,a
case 0xc9: OP_MOV_ADDR_REG(regs.x); //mov $addr,x
case 0xcc: OP_MOV_ADDR_REG(regs.y); //mov $addr,y
#define OP_MOV_DPR_REG(target, source) \
dp = op_readpc(); \
op_io(); \
dp += source; \
op_readdp(dp); \
op_writedp(dp, target); \
break;
case 0xd4: OP_MOV_DPR_REG(regs.a, regs.x); //mov $dp+a,x
case 0xd9: OP_MOV_DPR_REG(regs.x, regs.y); //mov $dp+x,y
case 0xdb: OP_MOV_DPR_REG(regs.y, regs.x); //mov $dp+y,x
#define OP_MOV_ADDRR_A(source) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
op_io(); \
dp += source; \
op_read(dp); \
op_write(dp, regs.a); \
break;
case 0xd5: OP_MOV_ADDRR_A(regs.x); //mov $addr+x,a
case 0xd6: OP_MOV_ADDRR_A(regs.y); //mov $addr+y,a
#define OP_MOV_REG_DP(target) \
sp = op_readpc(); \
target = op_readdp(sp); \
regs.p.n = (target & 0x80); \
regs.p.z = (target == 0); \
break;
case 0xe4: OP_MOV_REG_DP(regs.a); //mov a,$dp
case 0xeb: OP_MOV_REG_DP(regs.y); //mov y,$dp
case 0xf8: OP_MOV_REG_DP(regs.x); //mov x,$dp
#define OP_MOV_REG_ADDR(target) \
sp = op_readpc() << 0; \
sp |= op_readpc() << 8; \
target = op_read(sp); \
regs.p.n = (target & 0x80); \
regs.p.z = (target == 0); \
break;
case 0xe5: OP_MOV_REG_ADDR(regs.a); //mov a,$addr
case 0xe9: OP_MOV_REG_ADDR(regs.x); //mov x,$addr
case 0xec: OP_MOV_REG_ADDR(regs.y); //mov y,$addr
case 0xe6: //mov a,(x)
op_io();
regs.a = op_readdp(regs.x);
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
#define OP_MOV_REG_DPR(target, source) \
sp = op_readpc(); \
op_io(); \
target = op_readdp(sp + source); \
regs.p.n = (target & 0x80); \
regs.p.z = (target == 0); \
break;
case 0xf4: OP_MOV_REG_DPR(regs.a, regs.x); //mov a,$dp+x
case 0xf9: OP_MOV_REG_DPR(regs.x, regs.y); //mov x,$dp+y
case 0xfb: OP_MOV_REG_DPR(regs.y, regs.x); //mov y,$dp+x
#define OP_MOV_A_ADDRR(source) \
sp = op_readpc() << 0; \
sp |= op_readpc() << 8; \
op_io(); \
regs.a = op_read(sp + source); \
regs.p.n = (regs.a & 0x80); \
regs.p.z = (regs.a == 0); \
break;
case 0xf5: OP_MOV_A_ADDRR(regs.x); //mov a,$addr+x
case 0xf6: OP_MOV_A_ADDRR(regs.y); //mov a,$addr+y
case 0x8f: //mov $dp,#$ss
rd = op_readpc();
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, rd);
break;
case 0xaf: //mov (x)+,a
op_io();
op_io();
op_writedp(regs.x++, regs.a);
break;
case 0xba: //movw ya,$dp
sp = op_readpc();
regs.a = op_readdp(sp + 0);
op_io();
regs.y = op_readdp(sp + 1);
regs.p.n = (regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
break;
case 0xbd: //mov sp,x
op_io();
regs.sp = regs.x;
break;
case 0xbf: //mov a,(x)+
op_io();
regs.a = op_readdp(regs.x++);
op_io();
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
case 0xc6: //mov (x),a
op_io();
op_readdp(regs.x);
op_writedp(regs.x, regs.a);
break;
case 0xc7: //mov ($dp+x),a
sp = op_readpc();
op_io();
sp += regs.x;
dp = op_readdp(sp + 0) << 0;
dp |= op_readdp(sp + 1) << 8;
op_read(dp);
op_write(dp, regs.a);
break;
case 0xd7: //mov ($dp)+y,a
sp = op_readpc();
dp = op_readdp(sp + 0) << 0;
dp |= op_readdp(sp + 1) << 8;
op_io();
dp += regs.y;
op_read(dp);
op_write(dp, regs.a);
break;
case 0xda: //movw $dp,ya
dp = op_readpc();
op_readdp(dp);
op_writedp(dp + 0, regs.a);
op_writedp(dp + 1, regs.y);
break;
case 0xe7: //mov a,($dp+x)
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp + 0) << 0;
sp |= op_readdp(dp + 1) << 8;
regs.a = op_read(sp);
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
case 0xf7: //mov a,($dp)+y
dp = op_readpc();
op_io();
sp = op_readdp(dp + 0) << 0;
sp |= op_readdp(dp + 1) << 8;
regs.a = op_read(sp + regs.y);
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
case 0xfa: //mov $dp,$dp
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
op_writedp(dp, rd);
break;
//
// read/modify/write
//
#define OP_ADJUST_DP(func) \
dp = op_readpc(); \
rd = op_readdp(dp); \
rd = func(rd); \
op_writedp(dp, rd); \
break;
case 0x0b: OP_ADJUST_DP(fn_asl); //asl $dp
case 0x2b: OP_ADJUST_DP(fn_rol); //rol $dp
case 0x4b: OP_ADJUST_DP(fn_lsr); //lsr $dp
case 0x6b: OP_ADJUST_DP(fn_ror); //ror $dp
case 0x8b: OP_ADJUST_DP(fn_dec); //dec $dp
case 0xab: OP_ADJUST_DP(fn_inc); //inc $dp
#define OP_ADJUST_ADDR(func) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
rd = op_read(dp); \
rd = func(rd); \
op_write(dp, rd); \
break;
case 0x0c: OP_ADJUST_ADDR(fn_asl); //asl $addr
case 0x2c: OP_ADJUST_ADDR(fn_rol); //rol $addr
case 0x4c: OP_ADJUST_ADDR(fn_lsr); //lsr $addr
case 0x6c: OP_ADJUST_ADDR(fn_ror); //ror $addr
case 0x8c: OP_ADJUST_ADDR(fn_dec); //dec $addr
case 0xac: OP_ADJUST_ADDR(fn_inc); //inc $addr
#define OP_ADJUSTW_DP(adjust) \
dp = op_readpc(); \
rd = op_readdp(dp) << 0; \
rd += adjust; \
op_writedp(dp++, rd); \
rd += op_readdp(dp) << 8; \
op_writedp(dp, rd >> 8); \
regs.p.n = (rd & 0x8000); \
regs.p.z = (rd == 0); \
break;
case 0x1a: OP_ADJUSTW_DP(-1); //decw $dp
case 0x3a: OP_ADJUSTW_DP(+1); //incw $dp
#define OP_ADJUST_DPX(func) \
dp = op_readpc(); \
op_io(); \
rd = op_readdp(dp + regs.x); \
rd = func(rd); \
op_writedp(dp + regs.x, rd); \
break;
case 0x1b: OP_ADJUST_DPX(fn_asl); //asl $dp+x
case 0x3b: OP_ADJUST_DPX(fn_rol); //rol $dp+x
case 0x5b: OP_ADJUST_DPX(fn_lsr); //lsr $dp+x
case 0x7b: OP_ADJUST_DPX(fn_ror); //ror $dp+x
case 0x9b: OP_ADJUST_DPX(fn_dec); //dec $dp+x
case 0xbb: OP_ADJUST_DPX(fn_inc); //inc $dp+x
#define OP_ADJUST_REG(func, target) \
op_io(); \
target = func(target); \
break;
case 0x1c: OP_ADJUST_REG(fn_asl, regs.a); //asl a
case 0x3c: OP_ADJUST_REG(fn_rol, regs.a); //rol a
case 0x5c: OP_ADJUST_REG(fn_lsr, regs.a); //lsr a
case 0x7c: OP_ADJUST_REG(fn_ror, regs.a); //ror a
case 0x9c: OP_ADJUST_REG(fn_dec, regs.a); //dec a
case 0xbc: OP_ADJUST_REG(fn_inc, regs.a); //inc a
case 0x1d: OP_ADJUST_REG(fn_dec, regs.x); //dec x
case 0x3d: OP_ADJUST_REG(fn_inc, regs.x); //inc x
case 0xdc: OP_ADJUST_REG(fn_dec, regs.y); //dec y
case 0xfc: OP_ADJUST_REG(fn_inc, regs.y); //inc y
//
// bit manipulation
//
#define OP_OR1_BIT(op) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
bit = dp >> 13; \
dp &= 0x1fff; \
rd = op_read(dp); \
op_io(); \
regs.p.c = regs.p.c = ((bool)(rd & (1 << bit)) ^ op); \
break;
case 0x0a: OP_OR1_BIT(0); //or1 c,$addr:bit
case 0x2a: OP_OR1_BIT(1); //or1 c,!$addr:bit
#define OP_AND1_BIT(op) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
bit = dp >> 13; \
dp &= 0x1fff; \
rd = op_read(dp); \
regs.p.c = regs.p.c & ((bool)(rd & (1 << bit)) ^ op); \
break;
case 0x4a: OP_AND1_BIT(0); //and1 c,$addr:bit
case 0x6a: OP_AND1_BIT(1); //and1 c,!$addr:bit
case 0x8a: //eor1 c,$addr:bit
dp = op_readpc() << 0;
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(dp);
op_io();
regs.p.c = regs.p.c ^ (bool)(rd & (1 << bit));
break;
case 0xaa: //mov1 c,$addr:bit
sp = op_readpc() << 0;
sp |= op_readpc() << 8;
bit = sp >> 13;
sp &= 0x1fff;
rd = op_read(sp);
regs.p.c = (rd & (1 << bit));
break;
case 0xca: //mov1 $addr:bit,c
dp = op_readpc() << 0;
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(dp);
regs.p.c ? rd |= (1 << bit) : rd &=~ (1 << bit);
op_io();
op_write(dp, rd);
break;
case 0xea: //not1 c,$addr:bit
dp = op_readpc() << 0;
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(dp);
rd ^= 1 << bit;
op_write(dp, rd);
break;
//
// miscellaneous
//
#define OP_TADJUST_ADDR(mathop) \
dp = op_readpc() << 0; \
dp |= op_readpc() << 8; \
rd = op_read(dp); \
regs.p.n = ((regs.a - rd) & 0x80); \
regs.p.z = ((regs.a - rd) == 0); \
op_read(dp); \
op_write(dp, rd mathop regs.a); \
break;
case 0x0e: OP_TADJUST_ADDR(| ); //tset $addr,a
case 0x4e: OP_TADJUST_ADDR(&~); //tclr $addr,a
case 0x5a: //cmpw ya,$dp
dp = op_readpc();
rd = op_readdp(dp + 0) << 0;
rd |= op_readdp(dp + 1) << 8;
fn_cmpw(regs.ya, rd);
break;
case 0x9f: //xcn a
op_io(); op_io(); op_io(); op_io();
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
case 0xbe: //das
op_io();
op_io();
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
case 0xdf: //daa
op_io();
op_io();
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = (regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
#include "core/op_misc.cpp"
#include "core/op_mov.cpp"
#include "core/op_pc.cpp"
#include "core/op_read.cpp"
#include "core/op_rmw.cpp"
}
timer0.tick(cycle_count_table[opcode]);
@ -885,6 +75,8 @@ void SMP::op_step() {
clock += cycle_table_cpu[opcode];
dsp.clock -= cycle_table_dsp[opcode];
synchronize_dsp();
#endif
}
const unsigned SMP::cycle_count_table[256] = {

View File

@ -1,3 +1,4 @@
void tick();
alwaysinline void op_io();
debugvirtual alwaysinline uint8 op_read(uint16 addr);
debugvirtual alwaysinline void op_write(uint16 addr, uint8 data);
@ -5,19 +6,20 @@ debugvirtual alwaysinline void op_step();
static const unsigned cycle_count_table[256];
uint64 cycle_table_cpu[256];
unsigned cycle_table_dsp[256];
uint64 cycle_step_cpu;
uint8 fn_adc (uint8 x, uint8 y);
uint16 fn_addw(uint16 x, uint16 y);
uint8 fn_and (uint8 x, uint8 y);
uint8 fn_cmp (uint8 x, uint8 y);
uint16 fn_cmpw(uint16 x, uint16 y);
uint8 fn_eor (uint8 x, uint8 y);
uint8 fn_inc (uint8 x);
uint8 fn_dec (uint8 x);
uint8 fn_or (uint8 x, uint8 y);
uint8 fn_sbc (uint8 x, uint8 y);
uint16 fn_subw(uint16 x, uint16 y);
uint8 fn_asl (uint8 x);
uint8 fn_lsr (uint8 x);
uint8 fn_rol (uint8 x);
uint8 fn_ror (uint8 x);
uint8 op_adc (uint8 x, uint8 y);
uint16 op_addw(uint16 x, uint16 y);
uint8 op_and (uint8 x, uint8 y);
uint8 op_cmp (uint8 x, uint8 y);
uint16 op_cmpw(uint16 x, uint16 y);
uint8 op_eor (uint8 x, uint8 y);
uint8 op_inc (uint8 x);
uint8 op_dec (uint8 x);
uint8 op_or (uint8 x, uint8 y);
uint8 op_sbc (uint8 x, uint8 y);
uint16 op_subw(uint16 x, uint16 y);
uint8 op_asl (uint8 x);
uint8 op_lsr (uint8 x);
uint8 op_rol (uint8 x);
uint8 op_ror (uint8 x);

1
bsnes/snes/alt/smp/core/cc.sh Executable file
View File

@ -0,0 +1 @@
g++-4.5 -std=gnu++0x -I../../../.. -o generate generate.cpp

BIN
bsnes/snes/alt/smp/core/generate Executable file

Binary file not shown.

View File

@ -0,0 +1,154 @@
#include <nall/file.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
using namespace nall;
static bool cycle_accurate;
struct opcode_t {
string name;
lstring args;
unsigned opcode;
};
void generate(const char *sourceFilename, const char *targetFilename) {
file fp;
fp.open(targetFilename, file::mode::write);
string filedata;
filedata.readfile(sourceFilename);
filedata.replace("\r", "");
lstring block;
block.split("\n\n", filedata);
foreach(data, block) {
lstring lines;
lines.split("\n", data);
linear_vector<opcode_t> array;
unsigned sourceStart = 0;
foreach(line, lines, currentLine) {
line.transform("()", "``");
lstring part;
part.split("`", line);
lstring arguments;
arguments.split(", ", part[1]);
opcode_t opcode;
opcode.name = part[0];
opcode.args = arguments;
opcode.opcode = hex(arguments[0]);
array.append(opcode);
line.rtrim<1>(",");
if(line.endswith(" {")) {
line.rtrim<1>("{ ");
sourceStart = currentLine + 1;
break;
}
}
if(cycle_accurate == false) {
foreach(opcode, array) {
fp.print("case 0x", hex<2>(opcode.opcode), ": {\n");
for(unsigned n = sourceStart; n < lines.size(); n++) {
if(lines[n] == "}") break;
string output;
if(lines[n].beginswith(" ")) {
output = lines[n];
} else {
lstring part;
part.split<1>(":", lines[n]);
output = { " ", part[1] };
}
output.replace("$1", opcode.args[1]);
output.replace("$2", opcode.args[2]);
output.replace("$3", opcode.args[3]);
output.replace("$4", opcode.args[4]);
output.replace("$5", opcode.args[5]);
output.replace("$6", opcode.args[6]);
output.replace("$7", opcode.args[7]);
output.replace("$8", opcode.args[8]);
output.replace("end;", "break;");
fp.print(output, "\n");
}
fp.print(" break;\n");
fp.print("}\n\n");
}
} else {
foreach(opcode, array) {
fp.print("case 0x", hex<2>(opcode.opcode), ": {\n");
fp.print(" switch(opcode_cycle++) {\n");
for(unsigned n = sourceStart; n < lines.size(); n++) {
if(lines[n] == "}") break;
bool nextLineEndsCycle = false;
if(lines[n + 1] == "}") nextLineEndsCycle = true;
if(lines[n + 1].beginswith(" ") == false) nextLineEndsCycle = true;
string output;
if(lines[n].beginswith(" ")) {
output = { " ", lines[n] };
} else {
lstring part;
part.split<1>(":", lines[n]);
fp.print(" case ", (unsigned)decimal(part[0]), ":\n");
output = { " ", part[1] };
}
output.replace("$1", opcode.args[1]);
output.replace("$2", opcode.args[2]);
output.replace("$3", opcode.args[3]);
output.replace("$4", opcode.args[4]);
output.replace("$5", opcode.args[5]);
output.replace("$6", opcode.args[6]);
output.replace("$7", opcode.args[7]);
output.replace("$8", opcode.args[8]);
output.replace("end;", "{ opcode_cycle = 0; break; }");
fp.print(output, "\n");
if(nextLineEndsCycle) {
if(lines[n + 1].beginswith("}")) {
fp.print(" opcode_cycle = 0;\n");
}
fp.print(" break;\n");
}
}
fp.print(" }\n");
fp.print(" break;\n");
fp.print("}\n\n");
}
}
}
fp.close();
}
int main() {
cycle_accurate = false;
generate("op_misc.b", "op_misc.cpp");
generate("op_mov.b", "op_mov.cpp" );
generate("op_pc.b", "op_pc.cpp" );
generate("op_read.b", "op_read.cpp");
generate("op_rmw.b", "op_rmw.cpp" );
cycle_accurate = true;
generate("op_misc.b", "opcycle_misc.cpp");
generate("op_mov.b", "opcycle_mov.cpp" );
generate("op_pc.b", "opcycle_pc.cpp" );
generate("op_read.b", "opcycle_read.cpp");
generate("op_rmw.b", "opcycle_rmw.cpp" );
return 0;
}

163
bsnes/snes/alt/smp/core/op_misc.b Executable file
View File

@ -0,0 +1,163 @@
nop(0x00) {
1:op_io();
}
sleep(0xef),
stop(0xff) {
1:op_io();
2:op_io();
regs.pc--;
}
xcn(0x9f) {
1:op_io();
2:op_io();
3:op_io();
4:op_io();
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
daa(0xdf) {
1:op_io();
2:op_io();
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
das(0xbe) {
1:op_io();
2:op_io();
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
clrc(0x60, regs.p.c = 0),
clrp(0x20, regs.p.p = 0),
setc(0x80, regs.p.c = 1),
setp(0x40, regs.p.p = 1) {
1:op_io();
$1;
}
clrv(0xe0) {
1:op_io();
regs.p.v = 0;
regs.p.h = 0;
}
notc(0xed) {
1:op_io();
2:op_io();
regs.p.c = !regs.p.c;
}
ei(0xa0, 1),
di(0xc0, 0) {
1:op_io();
2:op_io();
regs.p.i = $1;
}
set0_dp(0x02, rd |= 0x01),
clr0_dp(0x12, rd &= ~0x01),
set1_dp(0x22, rd |= 0x02),
clr1_dp(0x32, rd &= ~0x02),
set2_dp(0x42, rd |= 0x04),
clr2_dp(0x52, rd &= ~0x04),
set3_dp(0x62, rd |= 0x08),
clr3_dp(0x72, rd &= ~0x08),
set4_dp(0x82, rd |= 0x10),
clr4_dp(0x92, rd &= ~0x10),
set5_dp(0xa2, rd |= 0x20),
clr5_dp(0xb2, rd &= ~0x20),
set6_dp(0xc2, rd |= 0x40),
clr6_dp(0xd2, rd &= ~0x40),
set7_dp(0xe2, rd |= 0x80),
clr7_dp(0xf2, rd &= ~0x80) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:$1;
op_writedp(dp, rd);
}
push_a(0x2d, a),
push_x(0x4d, x),
push_y(0x6d, y),
push_p(0x0d, p) {
1:op_io();
2:op_io();
3:op_writestack(regs.$1);
}
pop_a(0xae, a),
pop_x(0xce, x),
pop_y(0xee, y),
pop_p(0x8e, p) {
1:op_io();
2:op_io();
3:regs.$1 = op_readstack();
}
mul_ya(0xcf) {
1:op_io();
2:op_io();
3:op_io();
4:op_io();
5:op_io();
6:op_io();
7:op_io();
8:op_io();
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
}
div_ya_x(0x9e) {
1:op_io();
2:op_io();
3:op_io();
4:op_io();
5:op_io();
6:op_io();
7:op_io();
8:op_io();
9:op_io();
10:op_io();
11:op_io();
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the S-SMP in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}

View File

@ -0,0 +1,346 @@
case 0x00: {
op_io();
break;
}
case 0xef: {
op_io();
op_io();
regs.pc--;
break;
}
case 0xff: {
op_io();
op_io();
regs.pc--;
break;
}
case 0x9f: {
op_io();
op_io();
op_io();
op_io();
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xdf: {
op_io();
op_io();
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xbe: {
op_io();
op_io();
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0x60: {
op_io();
regs.p.c = 0;
break;
}
case 0x20: {
op_io();
regs.p.p = 0;
break;
}
case 0x80: {
op_io();
regs.p.c = 1;
break;
}
case 0x40: {
op_io();
regs.p.p = 1;
break;
}
case 0xe0: {
op_io();
regs.p.v = 0;
regs.p.h = 0;
break;
}
case 0xed: {
op_io();
op_io();
regs.p.c = !regs.p.c;
break;
}
case 0xa0: {
op_io();
op_io();
regs.p.i = 1;
break;
}
case 0xc0: {
op_io();
op_io();
regs.p.i = 0;
break;
}
case 0x02: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x01;
op_writedp(dp, rd);
break;
}
case 0x12: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x01;
op_writedp(dp, rd);
break;
}
case 0x22: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x02;
op_writedp(dp, rd);
break;
}
case 0x32: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x02;
op_writedp(dp, rd);
break;
}
case 0x42: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x04;
op_writedp(dp, rd);
break;
}
case 0x52: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x04;
op_writedp(dp, rd);
break;
}
case 0x62: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x08;
op_writedp(dp, rd);
break;
}
case 0x72: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x08;
op_writedp(dp, rd);
break;
}
case 0x82: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x10;
op_writedp(dp, rd);
break;
}
case 0x92: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x10;
op_writedp(dp, rd);
break;
}
case 0xa2: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x20;
op_writedp(dp, rd);
break;
}
case 0xb2: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x20;
op_writedp(dp, rd);
break;
}
case 0xc2: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x40;
op_writedp(dp, rd);
break;
}
case 0xd2: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x40;
op_writedp(dp, rd);
break;
}
case 0xe2: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x80;
op_writedp(dp, rd);
break;
}
case 0xf2: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x80;
op_writedp(dp, rd);
break;
}
case 0x2d: {
op_io();
op_io();
op_writestack(regs.a);
break;
}
case 0x4d: {
op_io();
op_io();
op_writestack(regs.x);
break;
}
case 0x6d: {
op_io();
op_io();
op_writestack(regs.y);
break;
}
case 0x0d: {
op_io();
op_io();
op_writestack(regs.p);
break;
}
case 0xae: {
op_io();
op_io();
regs.a = op_readstack();
break;
}
case 0xce: {
op_io();
op_io();
regs.x = op_readstack();
break;
}
case 0xee: {
op_io();
op_io();
regs.y = op_readstack();
break;
}
case 0x8e: {
op_io();
op_io();
regs.p = op_readstack();
break;
}
case 0xcf: {
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
}
case 0x9e: {
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the S-SMP in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}

217
bsnes/snes/alt/smp/core/op_mov.b Executable file
View File

@ -0,0 +1,217 @@
mov_a_x(0x7d, a, x),
mov_a_y(0xdd, a, y),
mov_x_a(0x5d, x, a),
mov_y_a(0xfd, y, a),
mov_x_sp(0x9d, x, sp) {
1:op_io();
regs.$1 = regs.$2;
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_sp_x(0xbd, sp, x) {
1:op_io();
regs.$1 = regs.$2;
}
mov_a_const(0xe8, a),
mov_x_const(0xcd, x),
mov_y_const(0x8d, y) {
1:regs.$1 = op_readpc();
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_ix(0xe6) {
1:op_io();
2:regs.a = op_readdp(regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_ixinc(0xbf) {
1:op_io();
2:regs.a = op_readdp(regs.x++);
3:op_io();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_dp(0xe4, a),
mov_x_dp(0xf8, x),
mov_y_dp(0xeb, y) {
1:sp = op_readpc();
2:regs.$1 = op_readdp(sp);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_dpx(0xf4, a, x),
mov_x_dpy(0xf9, x, y),
mov_y_dpx(0xfb, y, x) {
1:sp = op_readpc();
2:op_io();
3:regs.$1 = op_readdp(sp + regs.$2);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_addr(0xe5, a),
mov_x_addr(0xe9, x),
mov_y_addr(0xec, y) {
1:sp = op_readpc();
2:sp |= op_readpc() << 8;
3:regs.$1 = op_readaddr(sp);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_addrx(0xf5, x),
mov_a_addry(0xf6, y) {
1:sp = op_readpc();
2:sp |= op_readpc() << 8;
3:op_io();
4:regs.a = op_readaddr(sp + regs.$1);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_idpx(0xe7) {
1:dp = op_readpc() + regs.x;
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_idpy(0xf7) {
1:dp = op_readpc();
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_dp_dp(0xfa) {
1:sp = op_readpc();
2:rd = op_readdp(sp);
3:dp = op_readpc();
4:op_writedp(dp, rd);
}
mov_dp_const(0x8f) {
1:rd = op_readpc();
2:dp = op_readpc();
3:op_readdp(dp);
4:op_writedp(dp, rd);
}
mov_ix_a(0xc6) {
1:op_io();
2:op_readdp(regs.x);
3:op_writedp(regs.x, regs.a);
}
mov_ixinc_a(0xaf) {
1:op_io();
2:op_io();
3:op_writedp(regs.x++, regs.a);
}
mov_dp_a(0xc4, a),
mov_dp_x(0xd8, x),
mov_dp_y(0xcb, y) {
1:dp = op_readpc();
2:op_readdp(dp);
3:op_writedp(dp, regs.$1);
}
mov_dpx_a(0xd4, x, a),
mov_dpy_x(0xd9, y, x),
mov_dpx_y(0xdb, x, y) {
1:dp = op_readpc();
2:op_io();
dp += regs.$1;
3:op_readdp(dp);
4:op_writedp(dp, regs.$2);
}
mov_addr_a(0xc5, a),
mov_addr_x(0xc9, x),
mov_addr_y(0xcc, y) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_readaddr(dp);
4:op_writeaddr(dp, regs.$1);
}
mov_addrx_a(0xd5, x),
mov_addry_a(0xd6, y) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_io();
dp += regs.$1;
4:op_readaddr(dp);
5:op_writeaddr(dp, regs.a);
}
mov_idpx_a(0xc7) {
1:sp = op_readpc();
2:op_io();
sp += regs.x;
3:dp = op_readdp(sp);
4:dp |= op_readdp(sp + 1) << 8;
5:op_readaddr(dp);
6:op_writeaddr(dp, regs.a);
}
mov_idpy_a(0xd7) {
1:sp = op_readpc();
2:dp = op_readdp(sp);
3:dp |= op_readdp(sp + 1) << 8;
4:op_io();
dp += regs.y;
5:op_readaddr(dp);
6:op_writeaddr(dp, regs.a);
}
movw_ya_dp(0xba) {
1:sp = op_readpc();
2:regs.a = op_readdp(sp);
3:op_io();
4:regs.y = op_readdp(sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
}
movw_dp_ya(0xda) {
1:dp = op_readpc();
2:op_readdp(dp);
3:op_writedp(dp, regs.a);
4:op_writedp(dp + 1, regs.y);
}
mov1_c_bit(0xaa) {
1:sp = op_readpc();
2:sp |= op_readpc() << 8;
3:bit = sp >> 13;
sp &= 0x1fff;
rd = op_readaddr(sp);
regs.p.c = !!(rd & (1 << bit));
}
mov1_bit_c(0xca) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
4:op_io();
5:op_writeaddr(dp, rd);
}

View File

@ -0,0 +1,389 @@
case 0x7d: {
op_io();
regs.a = regs.x;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xdd: {
op_io();
regs.a = regs.y;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0x5d: {
op_io();
regs.x = regs.a;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
break;
}
case 0xfd: {
op_io();
regs.y = regs.a;
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
}
case 0x9d: {
op_io();
regs.x = regs.sp;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
break;
}
case 0xbd: {
op_io();
regs.sp = regs.x;
break;
}
case 0xe8: {
regs.a = op_readpc();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xcd: {
regs.x = op_readpc();
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
break;
}
case 0x8d: {
regs.y = op_readpc();
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
}
case 0xe6: {
op_io();
regs.a = op_readdp(regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xbf: {
op_io();
regs.a = op_readdp(regs.x++);
op_io();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xe4: {
sp = op_readpc();
regs.a = op_readdp(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xf8: {
sp = op_readpc();
regs.x = op_readdp(sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
break;
}
case 0xeb: {
sp = op_readpc();
regs.y = op_readdp(sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
}
case 0xf4: {
sp = op_readpc();
op_io();
regs.a = op_readdp(sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xf9: {
sp = op_readpc();
op_io();
regs.x = op_readdp(sp + regs.y);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
break;
}
case 0xfb: {
sp = op_readpc();
op_io();
regs.y = op_readdp(sp + regs.x);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
}
case 0xe5: {
sp = op_readpc();
sp |= op_readpc() << 8;
regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xe9: {
sp = op_readpc();
sp |= op_readpc() << 8;
regs.x = op_readaddr(sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
break;
}
case 0xec: {
sp = op_readpc();
sp |= op_readpc() << 8;
regs.y = op_readaddr(sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
break;
}
case 0xf5: {
sp = op_readpc();
sp |= op_readpc() << 8;
op_io();
regs.a = op_readaddr(sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xf6: {
sp = op_readpc();
sp |= op_readpc() << 8;
op_io();
regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xe7: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xf7: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
break;
}
case 0xfa: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
op_writedp(dp, rd);
break;
}
case 0x8f: {
rd = op_readpc();
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, rd);
break;
}
case 0xc6: {
op_io();
op_readdp(regs.x);
op_writedp(regs.x, regs.a);
break;
}
case 0xaf: {
op_io();
op_io();
op_writedp(regs.x++, regs.a);
break;
}
case 0xc4: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.a);
break;
}
case 0xd8: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.x);
break;
}
case 0xcb: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.y);
break;
}
case 0xd4: {
dp = op_readpc();
op_io();
dp += regs.x;
op_readdp(dp);
op_writedp(dp, regs.a);
break;
}
case 0xd9: {
dp = op_readpc();
op_io();
dp += regs.y;
op_readdp(dp);
op_writedp(dp, regs.x);
break;
}
case 0xdb: {
dp = op_readpc();
op_io();
dp += regs.x;
op_readdp(dp);
op_writedp(dp, regs.y);
break;
}
case 0xc5: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
break;
}
case 0xc9: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.x);
break;
}
case 0xcc: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.y);
break;
}
case 0xd5: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
dp += regs.x;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
break;
}
case 0xd6: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
dp += regs.y;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
break;
}
case 0xc7: {
sp = op_readpc();
op_io();
sp += regs.x;
dp = op_readdp(sp);
dp |= op_readdp(sp + 1) << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
break;
}
case 0xd7: {
sp = op_readpc();
dp = op_readdp(sp);
dp |= op_readdp(sp + 1) << 8;
op_io();
dp += regs.y;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
break;
}
case 0xba: {
sp = op_readpc();
regs.a = op_readdp(sp);
op_io();
regs.y = op_readdp(sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
break;
}
case 0xda: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.a);
op_writedp(dp + 1, regs.y);
break;
}
case 0xaa: {
sp = op_readpc();
sp |= op_readpc() << 8;
bit = sp >> 13;
sp &= 0x1fff;
rd = op_readaddr(sp);
regs.p.c = !!(rd & (1 << bit));
break;
}
case 0xca: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
op_io();
op_writeaddr(dp, rd);
break;
}

179
bsnes/snes/alt/smp/core/op_pc.b Executable file
View File

@ -0,0 +1,179 @@
bra(0x2f, 0),
beq(0xf0, !regs.p.z),
bne(0xd0, regs.p.z),
bcs(0xb0, !regs.p.c),
bcc(0x90, regs.p.c),
bvs(0x70, !regs.p.v),
bvc(0x50, regs.p.v),
bmi(0x30, !regs.p.n),
bpl(0x10, regs.p.n) {
1:rd = op_readpc();
if($1)end;
2:op_io();
3:op_io();
regs.pc += (int8)rd;
}
bbs0(0x03, 0x01, !=),
bbc0(0x13, 0x01, ==),
bbs1(0x23, 0x02, !=),
bbc1(0x33, 0x02, ==),
bbs2(0x43, 0x04, !=),
bbc2(0x53, 0x04, ==),
bbs3(0x63, 0x08, !=),
bbc3(0x73, 0x08, ==),
bbs4(0x83, 0x10, !=),
bbc4(0x93, 0x10, ==),
bbs5(0xa3, 0x20, !=),
bbc5(0xb3, 0x20, ==),
bbs6(0xc3, 0x40, !=),
bbc6(0xd3, 0x40, ==),
bbs7(0xe3, 0x80, !=),
bbc7(0xf3, 0x80, ==) {
1:dp = op_readpc();
2:sp = op_readdp(dp);
3:rd = op_readpc();
4:op_io();
if((sp & $1) $2 $1)end;
5:op_io();
6:op_io();
regs.pc += (int8)rd;
}
cbne_dp(0x2e) {
1:dp = op_readpc();
2:sp = op_readdp(dp);
3:rd = op_readpc();
4:op_io();
if(regs.a == sp)end;
5:op_io();
6:op_io();
regs.pc += (int8)rd;
}
cbne_dpx(0xde) {
1:dp = op_readpc();
2:op_io();
3:sp = op_readdp(dp + regs.x);
4:rd = op_readpc();
5:op_io();
if(regs.a == sp)end;
6:op_io();
7:op_io();
regs.pc += (int8)rd;
}
dbnz_dp(0x6e) {
1:dp = op_readpc();
2:wr = op_readdp(dp);
3:op_writedp(dp, --wr);
4:rd = op_readpc();
if(wr == 0x00)end;
5:op_io();
6:op_io();
regs.pc += (int8)rd;
}
dbnz_y(0xfe) {
1:rd = op_readpc();
2:op_io();
regs.y--;
3:op_io();
if(regs.y == 0x00)end;
4:op_io();
5:op_io();
regs.pc += (int8)rd;
}
jmp_addr(0x5f) {
1:rd = op_readpc();
2:rd |= op_readpc() << 8;
regs.pc = rd;
}
jmp_iaddrx(0x1f) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_io();
dp += regs.x;
4:rd = op_readaddr(dp);
5:rd |= op_readaddr(dp + 1) << 8;
regs.pc = rd;
}
call(0x3f) {
1:rd = op_readpc();
2:rd |= op_readpc() << 8;
3:op_io();
4:op_io();
5:op_io();
6:op_writestack(regs.pc >> 8);
7:op_writestack(regs.pc);
regs.pc = rd;
}
pcall(0x4f) {
1:rd = op_readpc();
2:op_io();
3:op_io();
4:op_writestack(regs.pc >> 8);
5:op_writestack(regs.pc);
regs.pc = 0xff00 | rd;
}
tcall_0(0x01, 0),
tcall_1(0x11, 1),
tcall_2(0x21, 2),
tcall_3(0x31, 3),
tcall_4(0x41, 4),
tcall_5(0x51, 5),
tcall_6(0x61, 6),
tcall_7(0x71, 7),
tcall_8(0x81, 8),
tcall_9(0x91, 9),
tcall_10(0xa1, 10),
tcall_11(0xb1, 11),
tcall_12(0xc1, 12),
tcall_13(0xd1, 13),
tcall_14(0xe1, 14),
tcall_15(0xf1, 15) {
1:dp = 0xffde - ($1 << 1);
rd = op_readaddr(dp);
2:rd |= op_readaddr(dp + 1) << 8;
3:op_io();
4:op_io();
5:op_io();
6:op_writestack(regs.pc >> 8);
7:op_writestack(regs.pc);
regs.pc = rd;
}
brk(0x0f) {
1:rd = op_readaddr(0xffde);
2:rd |= op_readaddr(0xffdf) << 8;
3:op_io();
4:op_io();
5:op_writestack(regs.pc >> 8);
6:op_writestack(regs.pc);
7:op_writestack(regs.p);
regs.pc = rd;
regs.p.b = 1;
regs.p.i = 0;
}
ret(0x6f) {
1:rd = op_readstack();
2:rd |= op_readstack() << 8;
3:op_io();
4:op_io();
regs.pc = rd;
}
reti(0x7f) {
1:regs.p = op_readstack();
2:rd = op_readstack();
3:rd |= op_readstack() << 8;
4:op_io();
5:op_io();
regs.pc = rd;
}

603
bsnes/snes/alt/smp/core/op_pc.cpp Executable file
View File

@ -0,0 +1,603 @@
case 0x2f: {
rd = op_readpc();
if(0)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xf0: {
rd = op_readpc();
if(!regs.p.z)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xd0: {
rd = op_readpc();
if(regs.p.z)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xb0: {
rd = op_readpc();
if(!regs.p.c)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x90: {
rd = op_readpc();
if(regs.p.c)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x70: {
rd = op_readpc();
if(!regs.p.v)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x50: {
rd = op_readpc();
if(regs.p.v)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x30: {
rd = op_readpc();
if(!regs.p.n)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x10: {
rd = op_readpc();
if(regs.p.n)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x03: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x01) != 0x01)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x13: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x01) == 0x01)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x23: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x02) != 0x02)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x33: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x02) == 0x02)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x43: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x04) != 0x04)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x53: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x04) == 0x04)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x63: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x08) != 0x08)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x73: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x08) == 0x08)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x83: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x10) != 0x10)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x93: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x10) == 0x10)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xa3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x20) != 0x20)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xb3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x20) == 0x20)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xc3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x40) != 0x40)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xd3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x40) == 0x40)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xe3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x80) != 0x80)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xf3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x80) == 0x80)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x2e: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if(regs.a == sp)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xde: {
dp = op_readpc();
op_io();
sp = op_readdp(dp + regs.x);
rd = op_readpc();
op_io();
if(regs.a == sp)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x6e: {
dp = op_readpc();
wr = op_readdp(dp);
op_writedp(dp, --wr);
rd = op_readpc();
if(wr == 0x00)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0xfe: {
rd = op_readpc();
op_io();
regs.y--;
op_io();
if(regs.y == 0x00)break;
op_io();
op_io();
regs.pc += (int8)rd;
break;
}
case 0x5f: {
rd = op_readpc();
rd |= op_readpc() << 8;
regs.pc = rd;
break;
}
case 0x1f: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
dp += regs.x;
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
regs.pc = rd;
break;
}
case 0x3f: {
rd = op_readpc();
rd |= op_readpc() << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x4f: {
rd = op_readpc();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = 0xff00 | rd;
break;
}
case 0x01: {
dp = 0xffde - (0 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x11: {
dp = 0xffde - (1 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x21: {
dp = 0xffde - (2 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x31: {
dp = 0xffde - (3 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x41: {
dp = 0xffde - (4 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x51: {
dp = 0xffde - (5 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x61: {
dp = 0xffde - (6 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x71: {
dp = 0xffde - (7 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x81: {
dp = 0xffde - (8 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x91: {
dp = 0xffde - (9 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0xa1: {
dp = 0xffde - (10 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0xb1: {
dp = 0xffde - (11 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0xc1: {
dp = 0xffde - (12 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0xd1: {
dp = 0xffde - (13 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0xe1: {
dp = 0xffde - (14 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0xf1: {
dp = 0xffde - (15 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
break;
}
case 0x0f: {
rd = op_readaddr(0xffde);
rd |= op_readaddr(0xffdf) << 8;
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
op_writestack(regs.p);
regs.pc = rd;
regs.p.b = 1;
regs.p.i = 0;
break;
}
case 0x6f: {
rd = op_readstack();
rd |= op_readstack() << 8;
op_io();
op_io();
regs.pc = rd;
break;
}
case 0x7f: {
regs.p = op_readstack();
rd = op_readstack();
rd |= op_readstack() << 8;
op_io();
op_io();
regs.pc = rd;
break;
}

205
bsnes/snes/alt/smp/core/op_read.b Executable file
View File

@ -0,0 +1,205 @@
adc_a_const(0x88, adc, a),
and_a_const(0x28, and, a),
cmp_a_const(0x68, cmp, a),
cmp_x_const(0xc8, cmp, x),
cmp_y_const(0xad, cmp, y),
eor_a_const(0x48, eor, a),
or_a_const(0x08, or, a),
sbc_a_const(0xa8, sbc, a) {
1:rd = op_readpc();
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_ix(0x86, adc),
and_a_ix(0x26, and),
cmp_a_ix(0x66, cmp),
eor_a_ix(0x46, eor),
or_a_ix(0x06, or),
sbc_a_ix(0xa6, sbc) {
1:op_io();
2:rd = op_readdp(regs.x);
regs.a = op_$1(regs.a, rd);
}
adc_a_dp(0x84, adc, a),
and_a_dp(0x24, and, a),
cmp_a_dp(0x64, cmp, a),
cmp_x_dp(0x3e, cmp, x),
cmp_y_dp(0x7e, cmp, y),
eor_a_dp(0x44, eor, a),
or_a_dp(0x04, or, a),
sbc_a_dp(0xa4, sbc, a) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_dpx(0x94, adc),
and_a_dpx(0x34, and),
cmp_a_dpx(0x74, cmp),
eor_a_dpx(0x54, eor),
or_a_dpx(0x14, or),
sbc_a_dpx(0xb4, sbc) {
1:dp = op_readpc();
2:op_io();
3:rd = op_readdp(dp + regs.x);
regs.a = op_$1(regs.a, rd);
}
adc_a_addr(0x85, adc, a),
and_a_addr(0x25, and, a),
cmp_a_addr(0x65, cmp, a),
cmp_x_addr(0x1e, cmp, x),
cmp_y_addr(0x5e, cmp, y),
eor_a_addr(0x45, eor, a),
or_a_addr(0x05, or, a),
sbc_a_addr(0xa5, sbc, a) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:rd = op_readaddr(dp);
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_addrx(0x95, adc, x),
adc_a_addry(0x96, adc, y),
and_a_addrx(0x35, and, x),
and_a_addry(0x36, and, y),
cmp_a_addrx(0x75, cmp, x),
cmp_a_addry(0x76, cmp, y),
eor_a_addrx(0x55, eor, x),
eor_a_addry(0x56, eor, y),
or_a_addrx(0x15, or, x),
or_a_addry(0x16, or, y),
sbc_a_addrx(0xb5, sbc, x),
sbc_a_addry(0xb6, sbc, y) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_io();
4:rd = op_readaddr(dp + regs.$2);
regs.a = op_$1(regs.a, rd);
}
adc_a_idpx(0x87, adc),
and_a_idpx(0x27, and),
cmp_a_idpx(0x67, cmp),
eor_a_idpx(0x47, eor),
or_a_idpx(0x07, or),
sbc_a_idpx(0xa7, sbc) {
1:dp = op_readpc() + regs.x;
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:rd = op_readaddr(sp);
regs.a = op_$1(regs.a, rd);
}
adc_a_idpy(0x97, adc),
and_a_idpy(0x37, and),
cmp_a_idpy(0x77, cmp),
eor_a_idpy(0x57, eor),
or_a_idpy(0x17, or),
sbc_a_idpy(0xb7, sbc) {
1:dp = op_readpc();
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:rd = op_readaddr(sp + regs.y);
regs.a = op_$1(regs.a, rd);
}
adc_ix_iy(0x99, adc, 1),
and_ix_iy(0x39, and, 1),
cmp_ix_iy(0x79, cmp, 0),
eor_ix_iy(0x59, eor, 1),
or_ix_iy(0x19, or, 1),
sbc_ix_iy(0xb9, sbc, 1) {
1:op_io();
2:rd = op_readdp(regs.y);
3:wr = op_readdp(regs.x);
wr = op_$1(wr, rd);
4:($2) ? op_writedp(regs.x, wr) : op_io();
}
adc_dp_dp(0x89, adc, 1),
and_dp_dp(0x29, and, 1),
cmp_dp_dp(0x69, cmp, 0),
eor_dp_dp(0x49, eor, 1),
or_dp_dp(0x09, or, 1),
sbc_dp_dp(0xa9, sbc, 1) {
1:sp = op_readpc();
2:rd = op_readdp(sp);
3:dp = op_readpc();
4:wr = op_readdp(dp);
5:wr = op_$1(wr, rd);
($2) ? op_writedp(dp, wr) : op_io();
}
adc_dp_const(0x98, adc, 1),
and_dp_const(0x38, and, 1),
cmp_dp_const(0x78, cmp, 0),
eor_dp_const(0x58, eor, 1),
or_dp_const(0x18, or, 1),
sbc_dp_const(0xb8, sbc, 1) {
1:rd = op_readpc();
2:dp = op_readpc();
3:wr = op_readdp(dp);
4:wr = op_$1(wr, rd);
($2) ? op_writedp(dp, wr) : op_io();
}
addw_ya_dp(0x7a, addw),
subw_ya_dp(0x9a, subw) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:op_io();
4:rd |= op_readdp(dp + 1) << 8;
regs.ya = op_$1(regs.ya, rd);
}
cmpw_ya_dp(0x5a) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:rd |= op_readdp(dp + 1) << 8;
op_cmpw(regs.ya, rd);
}
and1_bit(0x4a, !!),
and1_notbit(0x6a, !) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
regs.p.c = regs.p.c & $1(rd & (1 << bit));
}
eor1_bit(0x8a) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
4:op_io();
regs.p.c = regs.p.c ^ !!(rd & (1 << bit));
}
not1_bit(0xea) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
rd ^= (1 << bit);
4:op_writeaddr(dp, rd);
}
or1_bit(0x0a, !!),
or1_notbit(0x2a, !) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
4:op_io();
regs.p.c = regs.p.c | $1(rd & (1 << bit));
}

View File

@ -0,0 +1,744 @@
case 0x88: {
rd = op_readpc();
regs.a = op_adc(regs.a, rd);
break;
}
case 0x28: {
rd = op_readpc();
regs.a = op_and(regs.a, rd);
break;
}
case 0x68: {
rd = op_readpc();
regs.a = op_cmp(regs.a, rd);
break;
}
case 0xc8: {
rd = op_readpc();
regs.x = op_cmp(regs.x, rd);
break;
}
case 0xad: {
rd = op_readpc();
regs.y = op_cmp(regs.y, rd);
break;
}
case 0x48: {
rd = op_readpc();
regs.a = op_eor(regs.a, rd);
break;
}
case 0x08: {
rd = op_readpc();
regs.a = op_or(regs.a, rd);
break;
}
case 0xa8: {
rd = op_readpc();
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x86: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x26: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_and(regs.a, rd);
break;
}
case 0x66: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x46: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x06: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_or(regs.a, rd);
break;
}
case 0xa6: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x84: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x24: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_and(regs.a, rd);
break;
}
case 0x64: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x3e: {
dp = op_readpc();
rd = op_readdp(dp);
regs.x = op_cmp(regs.x, rd);
break;
}
case 0x7e: {
dp = op_readpc();
rd = op_readdp(dp);
regs.y = op_cmp(regs.y, rd);
break;
}
case 0x44: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x04: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_or(regs.a, rd);
break;
}
case 0xa4: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x94: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x34: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_and(regs.a, rd);
break;
}
case 0x74: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x54: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x14: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_or(regs.a, rd);
break;
}
case 0xb4: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x85: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x25: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_and(regs.a, rd);
break;
}
case 0x65: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x1e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.x = op_cmp(regs.x, rd);
break;
}
case 0x5e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.y = op_cmp(regs.y, rd);
break;
}
case 0x45: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x05: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_or(regs.a, rd);
break;
}
case 0xa5: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x95: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x96: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x35: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_and(regs.a, rd);
break;
}
case 0x36: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_and(regs.a, rd);
break;
}
case 0x75: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x76: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x55: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x56: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x15: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_or(regs.a, rd);
break;
}
case 0x16: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_or(regs.a, rd);
break;
}
case 0xb5: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0xb6: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x87: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x27: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_and(regs.a, rd);
break;
}
case 0x67: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x47: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x07: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_or(regs.a, rd);
break;
}
case 0xa7: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x97: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_adc(regs.a, rd);
break;
}
case 0x37: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_and(regs.a, rd);
break;
}
case 0x77: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_cmp(regs.a, rd);
break;
}
case 0x57: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_eor(regs.a, rd);
break;
}
case 0x17: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_or(regs.a, rd);
break;
}
case 0xb7: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_sbc(regs.a, rd);
break;
}
case 0x99: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_adc(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
break;
}
case 0x39: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_and(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
break;
}
case 0x79: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_cmp(wr, rd);
(0) ? op_writedp(regs.x, wr) : op_io();
break;
}
case 0x59: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_eor(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
break;
}
case 0x19: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_or(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
break;
}
case 0xb9: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_sbc(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
break;
}
case 0x89: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_adc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x29: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_and(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x69: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_cmp(wr, rd);
(0) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x49: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_eor(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x09: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_or(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0xa9: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_sbc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x98: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_adc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x38: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_and(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x78: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_cmp(wr, rd);
(0) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x58: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_eor(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x18: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_or(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0xb8: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_sbc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
break;
}
case 0x7a: {
dp = op_readpc();
rd = op_readdp(dp);
op_io();
rd |= op_readdp(dp + 1) << 8;
regs.ya = op_addw(regs.ya, rd);
break;
}
case 0x9a: {
dp = op_readpc();
rd = op_readdp(dp);
op_io();
rd |= op_readdp(dp + 1) << 8;
regs.ya = op_subw(regs.ya, rd);
break;
}
case 0x5a: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= op_readdp(dp + 1) << 8;
op_cmpw(regs.ya, rd);
break;
}
case 0x4a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
regs.p.c = regs.p.c & !!(rd & (1 << bit));
break;
}
case 0x6a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
regs.p.c = regs.p.c & !(rd & (1 << bit));
break;
}
case 0x8a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
op_io();
regs.p.c = regs.p.c ^ !!(rd & (1 << bit));
break;
}
case 0xea: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
rd ^= (1 << bit);
op_writeaddr(dp, rd);
break;
}
case 0x0a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
op_io();
regs.p.c = regs.p.c | !!(rd & (1 << bit));
break;
}
case 0x2a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
op_io();
regs.p.c = regs.p.c | !(rd & (1 << bit));
break;
}

View File

@ -0,0 +1,74 @@
inc_a(0xbc, inc, a),
inc_x(0x3d, inc, x),
inc_y(0xfc, inc, y),
dec_a(0x9c, dec, a),
dec_x(0x1d, dec, x),
dec_y(0xdc, dec, y),
asl_a(0x1c, asl, a),
lsr_a(0x5c, lsr, a),
rol_a(0x3c, rol, a),
ror_a(0x7c, ror, a) {
1:op_io();
regs.$2 = op_$1(regs.$2);
}
inc_dp(0xab, inc),
dec_dp(0x8b, dec),
asl_dp(0x0b, asl),
lsr_dp(0x4b, lsr),
rol_dp(0x2b, rol),
ror_dp(0x6b, ror) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:rd = op_$1(rd);
op_writedp(dp, rd);
}
inc_dpx(0xbb, inc),
dec_dpx(0x9b, dec),
asl_dpx(0x1b, asl),
lsr_dpx(0x5b, lsr),
rol_dpx(0x3b, rol),
ror_dpx(0x7b, ror) {
1:dp = op_readpc();
2:op_io();
3:rd = op_readdp(dp + regs.x);
4:rd = op_$1(rd);
op_writedp(dp + regs.x, rd);
}
inc_addr(0xac, inc),
dec_addr(0x8c, dec),
asl_addr(0x0c, asl),
lsr_addr(0x4c, lsr),
rol_addr(0x2c, rol),
ror_addr(0x6c, ror) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:rd = op_readaddr(dp);
4:rd = op_$1(rd);
op_writeaddr(dp, rd);
}
tset_addr_a(0x0e, |),
tclr_addr_a(0x4e, &~) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
4:op_readaddr(dp);
5:op_writeaddr(dp, rd $1 regs.a);
}
incw_dp(0x3a, ++),
decw_dp(0x1a, --) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
rd$1;
3:op_writedp(dp++, rd);
4:rd += op_readdp(dp) << 8;
5:op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
}

View File

@ -0,0 +1,262 @@
case 0xbc: {
op_io();
regs.a = op_inc(regs.a);
break;
}
case 0x3d: {
op_io();
regs.x = op_inc(regs.x);
break;
}
case 0xfc: {
op_io();
regs.y = op_inc(regs.y);
break;
}
case 0x9c: {
op_io();
regs.a = op_dec(regs.a);
break;
}
case 0x1d: {
op_io();
regs.x = op_dec(regs.x);
break;
}
case 0xdc: {
op_io();
regs.y = op_dec(regs.y);
break;
}
case 0x1c: {
op_io();
regs.a = op_asl(regs.a);
break;
}
case 0x5c: {
op_io();
regs.a = op_lsr(regs.a);
break;
}
case 0x3c: {
op_io();
regs.a = op_rol(regs.a);
break;
}
case 0x7c: {
op_io();
regs.a = op_ror(regs.a);
break;
}
case 0xab: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_inc(rd);
op_writedp(dp, rd);
break;
}
case 0x8b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_dec(rd);
op_writedp(dp, rd);
break;
}
case 0x0b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_asl(rd);
op_writedp(dp, rd);
break;
}
case 0x4b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_lsr(rd);
op_writedp(dp, rd);
break;
}
case 0x2b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_rol(rd);
op_writedp(dp, rd);
break;
}
case 0x6b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_ror(rd);
op_writedp(dp, rd);
break;
}
case 0xbb: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_inc(rd);
op_writedp(dp + regs.x, rd);
break;
}
case 0x9b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_dec(rd);
op_writedp(dp + regs.x, rd);
break;
}
case 0x1b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_asl(rd);
op_writedp(dp + regs.x, rd);
break;
}
case 0x5b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_lsr(rd);
op_writedp(dp + regs.x, rd);
break;
}
case 0x3b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_rol(rd);
op_writedp(dp + regs.x, rd);
break;
}
case 0x7b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_ror(rd);
op_writedp(dp + regs.x, rd);
break;
}
case 0xac: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_inc(rd);
op_writeaddr(dp, rd);
break;
}
case 0x8c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_dec(rd);
op_writeaddr(dp, rd);
break;
}
case 0x0c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_asl(rd);
op_writeaddr(dp, rd);
break;
}
case 0x4c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_lsr(rd);
op_writeaddr(dp, rd);
break;
}
case 0x2c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_rol(rd);
op_writeaddr(dp, rd);
break;
}
case 0x6c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_ror(rd);
op_writeaddr(dp, rd);
break;
}
case 0x0e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
op_readaddr(dp);
op_writeaddr(dp, rd | regs.a);
break;
}
case 0x4e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
op_readaddr(dp);
op_writeaddr(dp, rd &~ regs.a);
break;
}
case 0x3a: {
dp = op_readpc();
rd = op_readdp(dp);
rd++;
op_writedp(dp++, rd);
rd += op_readdp(dp) << 8;
op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
break;
}
case 0x1a: {
dp = op_readpc();
rd = op_readdp(dp);
rd--;
op_writedp(dp++, rd);
rd += op_readdp(dp) << 8;
op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
break;
}

View File

@ -0,0 +1,696 @@
case 0x00: {
switch(opcode_cycle++) {
case 1:
op_io();
opcode_cycle = 0;
break;
}
break;
}
case 0xef: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
regs.pc--;
opcode_cycle = 0;
break;
}
break;
}
case 0xff: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
regs.pc--;
opcode_cycle = 0;
break;
}
break;
}
case 0x9f: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_io();
break;
case 4:
op_io();
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xdf: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xbe: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0x60: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.p.c = 0;
opcode_cycle = 0;
break;
}
break;
}
case 0x20: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.p.p = 0;
opcode_cycle = 0;
break;
}
break;
}
case 0x80: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.p.c = 1;
opcode_cycle = 0;
break;
}
break;
}
case 0x40: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.p.p = 1;
opcode_cycle = 0;
break;
}
break;
}
case 0xe0: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.p.v = 0;
regs.p.h = 0;
opcode_cycle = 0;
break;
}
break;
}
case 0xed: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
regs.p.c = !regs.p.c;
opcode_cycle = 0;
break;
}
break;
}
case 0xa0: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
regs.p.i = 1;
opcode_cycle = 0;
break;
}
break;
}
case 0xc0: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
regs.p.i = 0;
opcode_cycle = 0;
break;
}
break;
}
case 0x02: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x01;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x12: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x01;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x22: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x02;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x32: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x02;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x42: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x04;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x52: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x04;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x62: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x08;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x72: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x08;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x82: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x10;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x92: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x10;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xa2: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x20;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xb2: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x20;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xc2: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x40;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xd2: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x40;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xe2: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd |= 0x80;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xf2: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd &= ~0x80;
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x2d: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_writestack(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x4d: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_writestack(regs.x);
opcode_cycle = 0;
break;
}
break;
}
case 0x6d: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_writestack(regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0x0d: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_writestack(regs.p);
opcode_cycle = 0;
break;
}
break;
}
case 0xae: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
regs.a = op_readstack();
opcode_cycle = 0;
break;
}
break;
}
case 0xce: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
regs.x = op_readstack();
opcode_cycle = 0;
break;
}
break;
}
case 0xee: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
regs.y = op_readstack();
opcode_cycle = 0;
break;
}
break;
}
case 0x8e: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
regs.p = op_readstack();
opcode_cycle = 0;
break;
}
break;
}
case 0xcf: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_io();
break;
case 4:
op_io();
break;
case 5:
op_io();
break;
case 6:
op_io();
break;
case 7:
op_io();
break;
case 8:
op_io();
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0x9e: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_io();
break;
case 4:
op_io();
break;
case 5:
op_io();
break;
case 6:
op_io();
break;
case 7:
op_io();
break;
case 8:
op_io();
break;
case 9:
op_io();
break;
case 10:
op_io();
break;
case 11:
op_io();
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the S-SMP in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}

View File

@ -0,0 +1,806 @@
case 0x7d: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = regs.x;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xdd: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = regs.y;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0x5d: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.x = regs.a;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xfd: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.y = regs.a;
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0x9d: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.x = regs.sp;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xbd: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.sp = regs.x;
opcode_cycle = 0;
break;
}
break;
}
case 0xe8: {
switch(opcode_cycle++) {
case 1:
regs.a = op_readpc();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xcd: {
switch(opcode_cycle++) {
case 1:
regs.x = op_readpc();
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0x8d: {
switch(opcode_cycle++) {
case 1:
regs.y = op_readpc();
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xe6: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
regs.a = op_readdp(regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xbf: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
regs.a = op_readdp(regs.x++);
break;
case 3:
op_io();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xe4: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
regs.a = op_readdp(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xf8: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
regs.x = op_readdp(sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xeb: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
regs.y = op_readdp(sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xf4: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
regs.a = op_readdp(sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xf9: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
regs.x = op_readdp(sp + regs.y);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xfb: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
regs.y = op_readdp(sp + regs.x);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xe5: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
sp |= op_readpc() << 8;
break;
case 3:
regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xe9: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
sp |= op_readpc() << 8;
break;
case 3:
regs.x = op_readaddr(sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xec: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
sp |= op_readpc() << 8;
break;
case 3:
regs.y = op_readaddr(sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xf5: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
sp |= op_readpc() << 8;
break;
case 3:
op_io();
break;
case 4:
regs.a = op_readaddr(sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xf6: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
sp |= op_readpc() << 8;
break;
case 3:
op_io();
break;
case 4:
regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xe7: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc() + regs.x;
break;
case 2:
op_io();
break;
case 3:
sp = op_readdp(dp);
break;
case 4:
sp |= op_readdp(dp + 1) << 8;
break;
case 5:
regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xf7: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
sp = op_readdp(dp);
break;
case 4:
sp |= op_readdp(dp + 1) << 8;
break;
case 5:
regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xfa: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
rd = op_readdp(sp);
break;
case 3:
dp = op_readpc();
break;
case 4:
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x8f: {
switch(opcode_cycle++) {
case 1:
rd = op_readpc();
break;
case 2:
dp = op_readpc();
break;
case 3:
op_readdp(dp);
break;
case 4:
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xc6: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_readdp(regs.x);
break;
case 3:
op_writedp(regs.x, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xaf: {
switch(opcode_cycle++) {
case 1:
op_io();
break;
case 2:
op_io();
break;
case 3:
op_writedp(regs.x++, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xc4: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_readdp(dp);
break;
case 3:
op_writedp(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xd8: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_readdp(dp);
break;
case 3:
op_writedp(dp, regs.x);
opcode_cycle = 0;
break;
}
break;
}
case 0xcb: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_readdp(dp);
break;
case 3:
op_writedp(dp, regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0xd4: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
dp += regs.x;
break;
case 3:
op_readdp(dp);
break;
case 4:
op_writedp(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xd9: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
dp += regs.y;
break;
case 3:
op_readdp(dp);
break;
case 4:
op_writedp(dp, regs.x);
opcode_cycle = 0;
break;
}
break;
}
case 0xdb: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
dp += regs.x;
break;
case 3:
op_readdp(dp);
break;
case 4:
op_writedp(dp, regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0xc5: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
op_readaddr(dp);
break;
case 4:
op_writeaddr(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xc9: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
op_readaddr(dp);
break;
case 4:
op_writeaddr(dp, regs.x);
opcode_cycle = 0;
break;
}
break;
}
case 0xcc: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
op_readaddr(dp);
break;
case 4:
op_writeaddr(dp, regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0xd5: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
op_io();
dp += regs.x;
break;
case 4:
op_readaddr(dp);
break;
case 5:
op_writeaddr(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xd6: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
op_io();
dp += regs.y;
break;
case 4:
op_readaddr(dp);
break;
case 5:
op_writeaddr(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xc7: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
op_io();
sp += regs.x;
break;
case 3:
dp = op_readdp(sp);
break;
case 4:
dp |= op_readdp(sp + 1) << 8;
break;
case 5:
op_readaddr(dp);
break;
case 6:
op_writeaddr(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xd7: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
dp = op_readdp(sp);
break;
case 3:
dp |= op_readdp(sp + 1) << 8;
break;
case 4:
op_io();
dp += regs.y;
break;
case 5:
op_readaddr(dp);
break;
case 6:
op_writeaddr(dp, regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xba: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
regs.a = op_readdp(sp);
break;
case 3:
op_io();
break;
case 4:
regs.y = op_readdp(sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0xda: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_readdp(dp);
break;
case 3:
op_writedp(dp, regs.a);
break;
case 4:
op_writedp(dp + 1, regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0xaa: {
switch(opcode_cycle++) {
case 1:
sp = op_readpc();
break;
case 2:
sp |= op_readpc() << 8;
break;
case 3:
bit = sp >> 13;
sp &= 0x1fff;
rd = op_readaddr(sp);
regs.p.c = !!(rd & (1 << bit));
opcode_cycle = 0;
break;
}
break;
}
case 0xca: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
break;
case 4:
op_io();
break;
case 5:
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,550 @@
case 0xbc: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = op_inc(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x3d: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.x = op_inc(regs.x);
opcode_cycle = 0;
break;
}
break;
}
case 0xfc: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.y = op_inc(regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0x9c: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = op_dec(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x1d: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.x = op_dec(regs.x);
opcode_cycle = 0;
break;
}
break;
}
case 0xdc: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.y = op_dec(regs.y);
opcode_cycle = 0;
break;
}
break;
}
case 0x1c: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = op_asl(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x5c: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = op_lsr(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x3c: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = op_rol(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x7c: {
switch(opcode_cycle++) {
case 1:
op_io();
regs.a = op_ror(regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0xab: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd = op_inc(rd);
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x8b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd = op_dec(rd);
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x0b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd = op_asl(rd);
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x4b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd = op_lsr(rd);
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x2b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd = op_rol(rd);
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x6b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
break;
case 3:
rd = op_ror(rd);
op_writedp(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xbb: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
rd = op_readdp(dp + regs.x);
break;
case 4:
rd = op_inc(rd);
op_writedp(dp + regs.x, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x9b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
rd = op_readdp(dp + regs.x);
break;
case 4:
rd = op_dec(rd);
op_writedp(dp + regs.x, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x1b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
rd = op_readdp(dp + regs.x);
break;
case 4:
rd = op_asl(rd);
op_writedp(dp + regs.x, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x5b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
rd = op_readdp(dp + regs.x);
break;
case 4:
rd = op_lsr(rd);
op_writedp(dp + regs.x, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x3b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
rd = op_readdp(dp + regs.x);
break;
case 4:
rd = op_rol(rd);
op_writedp(dp + regs.x, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x7b: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
op_io();
break;
case 3:
rd = op_readdp(dp + regs.x);
break;
case 4:
rd = op_ror(rd);
op_writedp(dp + regs.x, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0xac: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
break;
case 4:
rd = op_inc(rd);
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x8c: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
break;
case 4:
rd = op_dec(rd);
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x0c: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
break;
case 4:
rd = op_asl(rd);
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x4c: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
break;
case 4:
rd = op_lsr(rd);
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x2c: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
break;
case 4:
rd = op_rol(rd);
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x6c: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
break;
case 4:
rd = op_ror(rd);
op_writeaddr(dp, rd);
opcode_cycle = 0;
break;
}
break;
}
case 0x0e: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
break;
case 4:
op_readaddr(dp);
break;
case 5:
op_writeaddr(dp, rd | regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x4e: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
dp |= op_readpc() << 8;
break;
case 3:
rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
break;
case 4:
op_readaddr(dp);
break;
case 5:
op_writeaddr(dp, rd &~ regs.a);
opcode_cycle = 0;
break;
}
break;
}
case 0x3a: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
rd++;
break;
case 3:
op_writedp(dp++, rd);
break;
case 4:
rd += op_readdp(dp) << 8;
break;
case 5:
op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
opcode_cycle = 0;
break;
}
break;
}
case 0x1a: {
switch(opcode_cycle++) {
case 1:
dp = op_readpc();
break;
case 2:
rd = op_readdp(dp);
rd--;
break;
case 3:
op_writedp(dp++, rd);
break;
case 4:
rd += op_readdp(dp) << 8;
break;
case 5:
op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
opcode_cycle = 0;
break;
}
break;
}

View File

@ -1,3 +1,5 @@
#define CYCLE_ACCURATE
#include <snes/snes.hpp>
#define SMP_CPP
@ -19,7 +21,7 @@ namespace SNES {
void SMP::synchronize_cpu() {
if(CPU::Threaded == true) {
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
//if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
} else {
while(clock >= 0) cpu.enter();
}
@ -27,7 +29,7 @@ void SMP::synchronize_cpu() {
void SMP::synchronize_dsp() {
if(DSP::Threaded == true) {
if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread);
//if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread);
} else {
while(dsp.clock < 0) dsp.enter();
}
@ -50,12 +52,17 @@ void SMP::power() {
cycle_table_cpu[n] = (cycle_count_table[n] * 24) * cpu.frequency;
}
cycle_step_cpu = 24 * cpu.frequency;
reset();
}
void SMP::reset() {
for(unsigned n = 0x0000; n <= 0xffff; n++) apuram[n] = 0x00;
opcode_number = 0;
opcode_cycle = 0;
regs.pc = 0xffc0;
regs.sp = 0xef;
regs.a = 0x00;
@ -63,11 +70,6 @@ void SMP::reset() {
regs.y = 0x00;
regs.p = 0x02;
//timing
status.clock_counter = 0;
status.dsp_counter = 0;
status.timer_step = 3;
//$00f1
status.iplrom_enable = true;
@ -77,6 +79,12 @@ void SMP::reset() {
//$00f8,$00f9
status.ram00f8 = 0x00;
status.ram00f9 = 0x00;
//timers
timer0.enable = timer1.enable = timer2.enable = false;
timer0.stage1_ticks = timer1.stage1_ticks = timer2.stage1_ticks = 0;
timer0.stage2_ticks = timer1.stage2_ticks = timer2.stage2_ticks = 0;
timer0.stage3_ticks = timer1.stage3_ticks = timer2.stage3_ticks = 0;
}
void SMP::serialize(serializer &s) {
@ -84,6 +92,9 @@ void SMP::serialize(serializer &s) {
s.array(apuram, 64 * 1024);
s.integer(opcode_number);
s.integer(opcode_cycle);
s.integer(regs.pc);
s.integer(regs.sp);
s.integer(regs.a);
@ -99,21 +110,35 @@ void SMP::serialize(serializer &s) {
s.integer(regs.p.z);
s.integer(regs.p.c);
s.integer(status.clock_counter);
s.integer(status.dsp_counter);
s.integer(status.timer_step);
s.integer(status.iplrom_enable);
s.integer(status.dsp_addr);
s.integer(status.ram00f8);
s.integer(status.ram00f9);
s.integer(timer0.enable);
s.integer(timer0.target);
s.integer(timer0.stage1_ticks);
s.integer(timer0.stage2_ticks);
s.integer(timer0.stage3_ticks);
s.integer(timer1.enable);
s.integer(timer1.target);
s.integer(timer1.stage1_ticks);
s.integer(timer1.stage2_ticks);
s.integer(timer1.stage3_ticks);
s.integer(timer2.enable);
s.integer(timer2.target);
s.integer(timer2.stage1_ticks);
s.integer(timer2.stage2_ticks);
s.integer(timer2.stage3_ticks);
}
SMP::SMP() {
apuram = new uint8[64 * 1024];
stackram = apuram + 0x0100;
}
SMP::~SMP() {

View File

@ -2,7 +2,6 @@ class SMP : public Processor {
public:
static const uint8 iplrom[64];
uint8 *apuram;
uint8 *stackram;
enum : bool { Threaded = false };
alwaysinline void synchronize_cpu();
@ -42,6 +41,9 @@ public:
alwaysinline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); }
};
unsigned opcode_number;
unsigned opcode_cycle;
struct Regs {
uint16 pc;
uint8 sp;
@ -54,11 +56,6 @@ public:
} regs;
struct Status {
//timing
unsigned clock_counter;
unsigned dsp_counter;
unsigned timer_step;
//$00f1
bool iplrom_enable;
@ -72,21 +69,18 @@ public:
template<unsigned frequency>
struct Timer {
unsigned stage0_ticks;
unsigned stage1_ticks;
unsigned stage2_ticks;
unsigned stage3_ticks;
bool current_line;
bool enable;
unsigned target;
uint8 target;
uint8 stage1_ticks;
uint8 stage2_ticks;
uint8 stage3_ticks;
void tick(unsigned clocks);
void synchronize();
};
Timer<64> timer0;
Timer<64> timer1;
Timer< 8> timer2;
Timer<128> timer0;
Timer<128> timer1;
Timer< 16> timer2;
};
#if defined(DEBUGGER)

View File

@ -1,28 +1,14 @@
template<unsigned timer_frequency>
void SMP::Timer<timer_frequency>::tick(unsigned clocks) {
//stage 0 increment
stage0_ticks += clocks;
if(stage0_ticks < timer_frequency) return;
stage0_ticks -= timer_frequency;
template<unsigned cycle_frequency>
void SMP::Timer<cycle_frequency>::tick(unsigned clocks) {
stage1_ticks += clocks;
if(stage1_ticks < cycle_frequency) return;
//stage 1 increment
stage1_ticks ^= 1;
synchronize();
}
template<unsigned timer_frequency>
void SMP::Timer<timer_frequency>::synchronize() {
bool new_line = stage1_ticks;
bool old_line = current_line;
current_line = new_line;
if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition
//stage 2 increment
stage1_ticks -= cycle_frequency;
if(enable == false) return;
stage2_ticks++;
if(stage2_ticks != target) return;
//stage 3 increment
stage2_ticks = 0;
stage3_ticks++;
stage3_ticks &= 15;

View File

@ -63,18 +63,18 @@ alwaysinline uint8 SMP::op_busread(uint16 addr) {
} break;
case 0xfd: { //T0OUT -- 4-bit counter value
r = t0.stage3_ticks & 15;
t0.stage3_ticks = 0;
r = timer0.stage3_ticks & 15;
timer0.stage3_ticks = 0;
} break;
case 0xfe: { //T1OUT -- 4-bit counter value
r = t1.stage3_ticks & 15;
t1.stage3_ticks = 0;
r = timer1.stage3_ticks & 15;
timer1.stage3_ticks = 0;
} break;
case 0xff: { //T2OUT -- 4-bit counter value
r = t2.stage3_ticks & 15;
t2.stage3_ticks = 0;
r = timer2.stage3_ticks & 15;
timer2.stage3_ticks = 0;
} break;
}
} else {
@ -99,9 +99,9 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed);
t0.sync_stage1();
t1.sync_stage1();
t2.sync_stage1();
timer0.sync_stage1();
timer1.sync_stage1();
timer2.sync_stage1();
} break;
case 0xf1: { //CONTROL
@ -122,23 +122,23 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
}
//0->1 transistion resets timers
if(t2.enabled == false && (data & 0x04)) {
t2.stage2_ticks = 0;
t2.stage3_ticks = 0;
if(timer2.enable == false && (data & 0x04)) {
timer2.stage2_ticks = 0;
timer2.stage3_ticks = 0;
}
t2.enabled = data & 0x04;
timer2.enable = data & 0x04;
if(t1.enabled == false && (data & 0x02)) {
t1.stage2_ticks = 0;
t1.stage3_ticks = 0;
if(timer1.enable == false && (data & 0x02)) {
timer1.stage2_ticks = 0;
timer1.stage3_ticks = 0;
}
t1.enabled = data & 0x02;
timer1.enable = data & 0x02;
if(t0.enabled == false && (data & 0x01)) {
t0.stage2_ticks = 0;
t0.stage3_ticks = 0;
if(timer0.enable == false && (data & 0x01)) {
timer0.stage2_ticks = 0;
timer0.stage3_ticks = 0;
}
t0.enabled = data & 0x01;
timer0.enable = data & 0x01;
} break;
case 0xf2: { //DSPADDR
@ -169,15 +169,15 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
} break;
case 0xfa: { //T0TARGET
t0.target = data;
timer0.target = data;
} break;
case 0xfb: { //T1TARGET
t1.target = data;
timer1.target = data;
} break;
case 0xfc: { //T2TARGET
t2.target = data;
timer2.target = data;
} break;
case 0xfd: //T0OUT

View File

@ -24,29 +24,29 @@ void SMP::serialize(serializer &s) {
s.integer(status.ram00f8);
s.integer(status.ram00f9);
s.integer(t0.stage0_ticks);
s.integer(t0.stage1_ticks);
s.integer(t0.stage2_ticks);
s.integer(t0.stage3_ticks);
s.integer(t0.current_line);
s.integer(t0.enabled);
s.integer(t0.target);
s.integer(timer0.stage0_ticks);
s.integer(timer0.stage1_ticks);
s.integer(timer0.stage2_ticks);
s.integer(timer0.stage3_ticks);
s.integer(timer0.current_line);
s.integer(timer0.enable);
s.integer(timer0.target);
s.integer(t1.stage0_ticks);
s.integer(t1.stage1_ticks);
s.integer(t1.stage2_ticks);
s.integer(t1.stage3_ticks);
s.integer(t1.current_line);
s.integer(t1.enabled);
s.integer(t1.target);
s.integer(timer1.stage0_ticks);
s.integer(timer1.stage1_ticks);
s.integer(timer1.stage2_ticks);
s.integer(timer1.stage3_ticks);
s.integer(timer1.current_line);
s.integer(timer1.enable);
s.integer(timer1.target);
s.integer(t2.stage0_ticks);
s.integer(t2.stage1_ticks);
s.integer(t2.stage2_ticks);
s.integer(t2.stage3_ticks);
s.integer(t2.current_line);
s.integer(t2.enabled);
s.integer(t2.target);
s.integer(timer2.stage0_ticks);
s.integer(timer2.stage1_ticks);
s.integer(timer2.stage2_ticks);
s.integer(timer2.stage3_ticks);
s.integer(timer2.current_line);
s.integer(timer2.enable);
s.integer(timer2.target);
}
#endif

View File

@ -54,9 +54,9 @@ void SMP::op_step() {
void SMP::power() {
//targets not initialized/changed upon reset
t0.target = 0;
t1.target = 0;
t2.target = 0;
timer0.target = 0;
timer1.target = 0;
timer2.target = 0;
reset();
}
@ -72,6 +72,10 @@ void SMP::reset() {
regs.p = 0x02;
foreach(n, apuram) n = random(0x00);
apuram[0x00f4] = 0x00;
apuram[0x00f5] = 0x00;
apuram[0x00f6] = 0x00;
apuram[0x00f7] = 0x00;
status.clock_counter = 0;
status.dsp_counter = 0;
@ -95,29 +99,29 @@ void SMP::reset() {
status.ram00f8 = 0x00;
status.ram00f9 = 0x00;
t0.stage0_ticks = 0;
t1.stage0_ticks = 0;
t2.stage0_ticks = 0;
timer0.stage0_ticks = 0;
timer1.stage0_ticks = 0;
timer2.stage0_ticks = 0;
t0.stage1_ticks = 0;
t1.stage1_ticks = 0;
t2.stage1_ticks = 0;
timer0.stage1_ticks = 0;
timer1.stage1_ticks = 0;
timer2.stage1_ticks = 0;
t0.stage2_ticks = 0;
t1.stage2_ticks = 0;
t2.stage2_ticks = 0;
timer0.stage2_ticks = 0;
timer1.stage2_ticks = 0;
timer2.stage2_ticks = 0;
t0.stage3_ticks = 0;
t1.stage3_ticks = 0;
t2.stage3_ticks = 0;
timer0.stage3_ticks = 0;
timer1.stage3_ticks = 0;
timer2.stage3_ticks = 0;
t0.current_line = 0;
t1.current_line = 0;
t2.current_line = 0;
timer0.current_line = 0;
timer1.current_line = 0;
timer2.current_line = 0;
t0.enabled = false;
t1.enabled = false;
t2.enabled = false;
timer0.enable = false;
timer1.enable = false;
timer2.enable = false;
}
SMP::SMP() {

View File

@ -10,9 +10,9 @@ void SMP::add_clocks(unsigned clocks) {
}
void SMP::cycle_edge() {
t0.tick();
t1.tick();
t2.tick();
timer0.tick();
timer1.tick();
timer2.tick();
//TEST register S-SMP speed control
//24 clocks have already been added for this cycle at this point
@ -47,7 +47,7 @@ void SMP::sSMPTimer<frequency>::sync_stage1() {
if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition
//stage 2 increment
if(enabled == false) return;
if(enable == false) return;
stage2_ticks++;
if(stage2_ticks != target) return;

View File

@ -6,16 +6,16 @@ public:
uint8 stage2_ticks;
uint8 stage3_ticks;
bool current_line;
bool enabled;
bool enable;
uint8 target;
void tick();
void sync_stage1();
};
sSMPTimer<192> t0;
sSMPTimer<192> t1;
sSMPTimer< 24> t2;
sSMPTimer<192> timer0;
sSMPTimer<192> timer1;
sSMPTimer< 24> timer2;
alwaysinline void add_clocks(unsigned clocks);
alwaysinline void cycle_edge();

View File

@ -1,8 +1,8 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "078.02";
static const unsigned SerializerVersion = 19;
static const char Version[] = "078.03";
static const unsigned SerializerVersion = 20;
}
}