diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 15761d2b..12776c67 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -9,7 +9,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "098.14"; + static const string Version = "098.15"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/gb/cartridge/huc3/huc3.cpp b/higan/gb/cartridge/huc3/huc3.cpp index b087f033..82c294c6 100644 --- a/higan/gb/cartridge/huc3/huc3.cpp +++ b/higan/gb/cartridge/huc3/huc3.cpp @@ -9,7 +9,7 @@ auto Cartridge::HuC3::mmio_read(uint16 addr) -> uint8 { if((addr & 0xe000) == 0xa000) { //$a000-bfff if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff)); - return 0xff; + return 0x01; //does not return open collection } return 0xff; diff --git a/higan/processor/r65816/switch.cpp b/higan/processor/r65816/switch.cpp index 2934a7c6..a76eef64 100644 --- a/higan/processor/r65816/switch.cpp +++ b/higan/processor/r65816/switch.cpp @@ -14,9 +14,9 @@ auto R65816::instruction() -> void { #define opXII(n, o, i, j) case n: return r.p.x ? op_##o##_b(i, j) : op_##o##_w(i, j); switch(readPC()) { - opAI (0x00, interrupt, r.e ? 0xffe6 : 0xfffe) + opAI (0x00, interrupt, r.e ? 0xfffe : 0xffe6) //emulation mode lacks BRK vector; uses IRQ vector instead opMF (0x01, read_idpx, ora) - opAI (0x02, interrupt, r.e ? 0xffe4 : 0xfff4) + opAI (0x02, interrupt, r.e ? 0xfff4 : 0xffe4) opMF (0x03, read_sr, ora) opMF (0x04, adjust_dp, tsb) opMF (0x05, read_dp, ora) diff --git a/higan/processor/spc700/disassembler.cpp b/higan/processor/spc700/disassembler.cpp index f158d5a4..0440bec1 100644 --- a/higan/processor/spc700/disassembler.cpp +++ b/higan/processor/spc700/disassembler.cpp @@ -1,6 +1,6 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string { auto read = [&](uint16 addr) -> uint8 { - return disassembler_read(addr); + return disassemblerRead(addr); }; auto relative = [&](uint length, int8 offset) -> uint16 { diff --git a/higan/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp index f0f7776d..a5a8b88f 100644 --- a/higan/processor/spc700/instructions.cpp +++ b/higan/processor/spc700/instructions.cpp @@ -1,162 +1,149 @@ #define call (this->*op) -template uint8> -auto SPC700::op_adjust(uint8_t& r) -> void { - op_io(); +auto SPC700::op_adjust(fps op, uint8_t& r) -> void { + io(); r = call(r); } -template uint8> -auto SPC700::op_adjust_addr() -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); +auto SPC700::op_adjust_addr(fps op) -> void { + dp.l = readPC(); + dp.h = readPC(); + rd = read(dp); rd = call(rd); - op_write(dp, rd); + write(dp, rd); } -template uint8> -auto SPC700::op_adjust_dp() -> void { - dp = op_readpc(); - rd = op_readdp(dp); +auto SPC700::op_adjust_dp(fps op) -> void { + dp = readPC(); + rd = readDP(dp); rd = call(rd); - op_writedp(dp, rd); + writeDP(dp, rd); } auto SPC700::op_adjust_dpw(int n) -> void { - dp = op_readpc(); - rd.w = op_readdp(dp) + n; - op_writedp(dp++, rd.l); - rd.h += op_readdp(dp); - op_writedp(dp++, rd.h); + dp = readPC(); + rd.w = readDP(dp) + n; + writeDP(dp++, rd.l); + rd.h += readDP(dp); + writeDP(dp++, rd.h); regs.p.n = rd & 0x8000; regs.p.z = rd == 0; } -template uint8> -auto SPC700::op_adjust_dpx() -> void { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); +auto SPC700::op_adjust_dpx(fps op) -> void { + dp = readPC(); + io(); + rd = readDP(dp + regs.x); rd = call(rd); - op_writedp(dp + regs.x, rd); + writeDP(dp + regs.x, rd); } auto SPC700::op_branch(bool condition) -> void { - rd = op_readpc(); - if(condition == false) return; - op_io(); - op_io(); + rd = readPC(); + if(!condition) return; + io(); + io(); regs.pc += (int8)rd; } auto SPC700::op_branch_bit() -> void { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); + dp = readPC(); + sp = readDP(dp); + rd = readPC(); + io(); if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return; - op_io(); - op_io(); + io(); + io(); regs.pc += (int8)rd; } auto SPC700::op_pull(uint8_t& r) -> void { - op_io(); - op_io(); - r = op_readsp(); + io(); + io(); + r = readSP(); } auto SPC700::op_push(uint8 r) -> void { - op_io(); - op_io(); - op_writesp(r); + io(); + io(); + writeSP(r); } -template uint8> -auto SPC700::op_read_addr(uint8_t& r) -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); +auto SPC700::op_read_addr(fpb op, uint8_t& r) -> void { + dp.l = readPC(); + dp.h = readPC(); + rd = read(dp); r = call(r, rd); } -template uint8> -auto SPC700::op_read_addri(uint8_t& r) -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); - rd = op_read(dp + r); +auto SPC700::op_read_addri(fpb op, uint8_t& r) -> void { + dp.l = readPC(); + dp.h = readPC(); + io(); + rd = read(dp + r); regs.a = call(regs.a, rd); } -template uint8> -auto SPC700::op_read_const(uint8_t& r) -> void { - rd = op_readpc(); +auto SPC700::op_read_const(fpb op, uint8_t& r) -> void { + rd = readPC(); r = call(r, rd); } -template uint8> -auto SPC700::op_read_dp(uint8_t& r) -> void { - dp = op_readpc(); - rd = op_readdp(dp); +auto SPC700::op_read_dp(fpb op, uint8_t& r) -> void { + dp = readPC(); + rd = readDP(dp); r = call(r, rd); } -template uint8> -auto SPC700::op_read_dpi(uint8_t& r, uint8_t& i) -> void { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + i); +auto SPC700::op_read_dpi(fpb op, uint8_t& r, uint8_t& i) -> void { + dp = readPC(); + io(); + rd = readDP(dp + i); r = call(r, rd); } -template uint16> -auto SPC700::op_read_dpw() -> void { - dp = op_readpc(); - rd.l = op_readdp(dp++); - if(op != &SPC700::op_cpw) op_io(); - rd.h = op_readdp(dp++); +auto SPC700::op_read_dpw(fpw op) -> void { + dp = readPC(); + rd.l = readDP(dp++); + if(op != &SPC700::op_cpw) io(); + rd.h = readDP(dp++); regs.ya = call(regs.ya, rd); } -template uint8> -auto SPC700::op_read_idpx() -> void { - dp = op_readpc() + regs.x; - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp); +auto SPC700::op_read_idpx(fpb op) -> void { + dp = readPC() + regs.x; + io(); + sp.l = readDP(dp++); + sp.h = readDP(dp++); + rd = read(sp); regs.a = call(regs.a, rd); } -template uint8> -auto SPC700::op_read_idpy() -> void { - dp = op_readpc(); - op_io(); - sp.l = op_readdp(dp++); - sp.h = op_readdp(dp++); - rd = op_read(sp + regs.y); +auto SPC700::op_read_idpy(fpb op) -> void { + dp = readPC(); + io(); + sp.l = readDP(dp++); + sp.h = readDP(dp++); + rd = read(sp + regs.y); regs.a = call(regs.a, rd); } -template uint8> -auto SPC700::op_read_ix() -> void { - op_io(); - rd = op_readdp(regs.x); +auto SPC700::op_read_ix(fpb op) -> void { + io(); + rd = readDP(regs.x); regs.a = call(regs.a, rd); } auto SPC700::op_set_addr_bit() -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); + dp.l = readPC(); + dp.h = readPC(); bit = dp >> 13; dp &= 0x1fff; - rd = op_read(dp); + rd = read(dp); switch(opcode >> 5) { case 0: //orc addr:bit case 1: //orc !addr:bit - op_io(); + io(); regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); break; case 2: //and addr:bit @@ -164,48 +151,48 @@ auto SPC700::op_set_addr_bit() -> void { regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); break; case 4: //eor addr:bit - op_io(); + io(); regs.p.c ^= (bool)(rd & (1 << bit)); break; case 5: //ldc addr:bit regs.p.c = (rd & (1 << bit)); break; case 6: //stc addr:bit - op_io(); + io(); rd = (rd & ~(1 << bit)) | (regs.p.c << bit); - op_write(dp, rd); + write(dp, rd); break; case 7: //not addr:bit rd ^= 1 << bit; - op_write(dp, rd); + write(dp, rd); break; } } auto SPC700::op_set_bit() -> void { - dp = op_readpc(); - rd = op_readdp(dp) & ~(1 << (opcode >> 5)); - op_writedp(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); + dp = readPC(); + rd = readDP(dp) & ~(1 << (opcode >> 5)); + writeDP(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); } auto SPC700::op_set_flag(bool& flag, bool data) -> void { - op_io(); - if(&flag == ®s.p.i) op_io(); + io(); + if(&flag == ®s.p.i) io(); flag = data; } auto SPC700::op_test_addr(bool set) -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - rd = op_read(dp); + dp.l = readPC(); + dp.h = readPC(); + rd = read(dp); regs.p.n = (regs.a - rd) & 0x80; regs.p.z = (regs.a - rd) == 0; - op_read(dp); - op_write(dp, set ? rd | regs.a : rd & ~regs.a); + read(dp); + write(dp, set ? rd | regs.a : rd & ~regs.a); } auto SPC700::op_transfer(uint8_t& from, uint8_t& to) -> void { - op_io(); + io(); to = from; if(&to == ®s.s) return; regs.p.n = (to & 0x80); @@ -213,136 +200,133 @@ auto SPC700::op_transfer(uint8_t& from, uint8_t& to) -> void { } auto SPC700::op_write_addr(uint8_t& r) -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_read(dp); - op_write(dp, r); + dp.l = readPC(); + dp.h = readPC(); + read(dp); + write(dp, r); } auto SPC700::op_write_addri(uint8_t& i) -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); + dp.l = readPC(); + dp.h = readPC(); + io(); dp += i; - op_read(dp); - op_write(dp, regs.a); + read(dp); + write(dp, regs.a); } auto SPC700::op_write_dp(uint8_t& r) -> void { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, r); + dp = readPC(); + readDP(dp); + writeDP(dp, r); } auto SPC700::op_write_dpi(uint8_t& r, uint8_t& i) -> void { - dp = op_readpc() + i; - op_io(); - op_readdp(dp); - op_writedp(dp, r); + dp = readPC() + i; + io(); + readDP(dp); + writeDP(dp, r); } -template uint8> -auto SPC700::op_write_dp_const() -> void { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); +auto SPC700::op_write_dp_const(fpb op) -> void { + rd = readPC(); + dp = readPC(); + wr = readDP(dp); wr = call(wr, rd); - op != &SPC700::op_cmp ? op_writedp(dp, wr) : op_io(); + op != &SPC700::op_cmp ? writeDP(dp, wr) : io(); } -template uint8> -auto SPC700::op_write_dp_dp() -> void { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - if(op != &SPC700::op_st) wr = op_readdp(dp); +auto SPC700::op_write_dp_dp(fpb op) -> void { + sp = readPC(); + rd = readDP(sp); + dp = readPC(); + if(op != &SPC700::op_st) wr = readDP(dp); wr = call(wr, rd); - op != &SPC700::op_cmp ? op_writedp(dp, wr) : op_io(); + op != &SPC700::op_cmp ? writeDP(dp, wr) : io(); } -template uint8> -auto SPC700::op_write_ix_iy() -> void { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); +auto SPC700::op_write_ix_iy(fpb op) -> void { + io(); + rd = readDP(regs.y); + wr = readDP(regs.x); wr = call(wr, rd); - op != &SPC700::op_cmp ? op_writedp(regs.x, wr) : op_io(); + op != &SPC700::op_cmp ? writeDP(regs.x, wr) : io(); } // auto SPC700::op_bne_dp() -> void { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); + dp = readPC(); + sp = readDP(dp); + rd = readPC(); + io(); if(regs.a == sp) return; - op_io(); - op_io(); + io(); + io(); regs.pc += (int8)rd; } auto SPC700::op_bne_dpdec() -> void { - dp = op_readpc(); - wr = op_readdp(dp); - op_writedp(dp, --wr); - rd = op_readpc(); + dp = readPC(); + wr = readDP(dp); + writeDP(dp, --wr); + rd = readPC(); if(wr == 0) return; - op_io(); - op_io(); + io(); + io(); regs.pc += (int8)rd; } auto SPC700::op_bne_dpx() -> void { - dp = op_readpc(); - op_io(); - sp = op_readdp(dp + regs.x); - rd = op_readpc(); - op_io(); + dp = readPC(); + io(); + sp = readDP(dp + regs.x); + rd = readPC(); + io(); if(regs.a == sp) return; - op_io(); - op_io(); + io(); + io(); regs.pc += (int8)rd; } auto SPC700::op_bne_ydec() -> void { - rd = op_readpc(); - op_io(); - op_io(); + rd = readPC(); + io(); + io(); if(--regs.y == 0) return; - op_io(); - op_io(); + io(); + io(); regs.pc += (int8)rd; } auto SPC700::op_brk() -> void { - rd.l = op_read(0xffde); - rd.h = op_read(0xffdf); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); - op_writesp(regs.p); + rd.l = read(0xffde); + rd.h = read(0xffdf); + io(); + io(); + writeSP(regs.pc.h); + writeSP(regs.pc.l); + writeSP(regs.p); regs.pc = rd; regs.p.b = 1; regs.p.i = 0; } auto SPC700::op_clv() -> void { - op_io(); + io(); regs.p.v = 0; regs.p.h = 0; } auto SPC700::op_cmc() -> void { - op_io(); - op_io(); + io(); + io(); regs.p.c = !regs.p.c; } auto SPC700::op_daa() -> void { - op_io(); - op_io(); + io(); + io(); if(regs.p.c || (regs.a) > 0x99) { regs.a += 0x60; regs.p.c = 1; @@ -355,8 +339,8 @@ auto SPC700::op_daa() -> void { } auto SPC700::op_das() -> void { - op_io(); - op_io(); + io(); + io(); if(!regs.p.c || (regs.a) > 0x99) { regs.a -= 0x60; regs.p.c = 0; @@ -369,17 +353,17 @@ auto SPC700::op_das() -> void { } auto SPC700::op_div_ya_x() -> void { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); ya = regs.ya; //overflow set if quotient >= 256 regs.p.v = (regs.y >= regs.x); @@ -400,70 +384,70 @@ auto SPC700::op_div_ya_x() -> void { } auto SPC700::op_jmp_addr() -> void { - rd.l = op_readpc(); - rd.h = op_readpc(); + rd.l = readPC(); + rd.h = readPC(); regs.pc = rd; } auto SPC700::op_jmp_iaddrx() -> void { - dp.l = op_readpc(); - dp.h = op_readpc(); - op_io(); + dp.l = readPC(); + dp.h = readPC(); + io(); dp += regs.x; - rd.l = op_read(dp++); - rd.h = op_read(dp++); + rd.l = read(dp++); + rd.h = read(dp++); regs.pc = rd; } auto SPC700::op_jsp_dp() -> void { - rd = op_readpc(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); + rd = readPC(); + io(); + io(); + writeSP(regs.pc.h); + writeSP(regs.pc.l); regs.pc = 0xff00 | rd; } auto SPC700::op_jsr_addr() -> void { - rd.l = op_readpc(); - rd.h = op_readpc(); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); + rd.l = readPC(); + rd.h = readPC(); + io(); + io(); + io(); + writeSP(regs.pc.h); + writeSP(regs.pc.l); regs.pc = rd; } auto SPC700::op_jst() -> void { dp = 0xffde - ((opcode >> 4) << 1); - rd.l = op_read(dp++); - rd.h = op_read(dp++); - op_io(); - op_io(); - op_io(); - op_writesp(regs.pc.h); - op_writesp(regs.pc.l); + rd.l = read(dp++); + rd.h = read(dp++); + io(); + io(); + io(); + writeSP(regs.pc.h); + writeSP(regs.pc.l); regs.pc = rd; } auto SPC700::op_lda_ixinc() -> void { - op_io(); - regs.a = op_readdp(regs.x++); - op_io(); + io(); + regs.a = readDP(regs.x++); + io(); regs.p.n = regs.a & 0x80; regs.p.z = regs.a == 0; } auto SPC700::op_mul_ya() -> void { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); + io(); ya = regs.y * regs.a; regs.a = ya; regs.y = ya >> 8; @@ -473,82 +457,82 @@ auto SPC700::op_mul_ya() -> void { } auto SPC700::op_nop() -> void { - op_io(); + io(); } auto SPC700::op_plp() -> void { - op_io(); - op_io(); - regs.p = op_readsp(); + io(); + io(); + regs.p = readSP(); } auto SPC700::op_rti() -> void { - regs.p = op_readsp(); - rd.l = op_readsp(); - rd.h = op_readsp(); - op_io(); - op_io(); + regs.p = readSP(); + rd.l = readSP(); + rd.h = readSP(); + io(); + io(); regs.pc = rd; } auto SPC700::op_rts() -> void { - rd.l = op_readsp(); - rd.h = op_readsp(); - op_io(); - op_io(); + rd.l = readSP(); + rd.h = readSP(); + io(); + io(); regs.pc = rd; } auto SPC700::op_sta_idpx() -> void { - sp = op_readpc() + regs.x; - op_io(); - dp.l = op_readdp(sp++); - dp.h = op_readdp(sp++); - op_read(dp); - op_write(dp, regs.a); + sp = readPC() + regs.x; + io(); + dp.l = readDP(sp++); + dp.h = readDP(sp++); + read(dp); + write(dp, regs.a); } auto SPC700::op_sta_idpy() -> void { - sp = op_readpc(); - dp.l = op_readdp(sp++); - dp.h = op_readdp(sp++); - op_io(); + sp = readPC(); + dp.l = readDP(sp++); + dp.h = readDP(sp++); + io(); dp += regs.y; - op_read(dp); - op_write(dp, regs.a); + read(dp); + write(dp, regs.a); } auto SPC700::op_sta_ix() -> void { - op_io(); - op_readdp(regs.x); - op_writedp(regs.x, regs.a); + io(); + readDP(regs.x); + writeDP(regs.x, regs.a); } auto SPC700::op_sta_ixinc() -> void { - op_io(); - op_io(); - op_writedp(regs.x++, regs.a); + io(); + io(); + writeDP(regs.x++, regs.a); } auto SPC700::op_stw_dp() -> void { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp++, regs.a); - op_writedp(dp++, regs.y); + dp = readPC(); + readDP(dp); + writeDP(dp++, regs.a); + writeDP(dp++, regs.y); } auto SPC700::op_wait() -> void { while(true) { - op_io(); - op_io(); + io(); + io(); } } auto SPC700::op_xcn() -> void { - op_io(); - op_io(); - op_io(); - op_io(); + io(); + io(); + io(); + io(); regs.a = (regs.a >> 4) | (regs.a << 4); regs.p.n = regs.a & 0x80; regs.p.z = regs.a == 0; diff --git a/higan/processor/spc700/memory.hpp b/higan/processor/spc700/memory.hpp index 03b70240..94c28b94 100644 --- a/higan/processor/spc700/memory.hpp +++ b/higan/processor/spc700/memory.hpp @@ -1,19 +1,19 @@ -alwaysinline auto op_readpc() -> uint8 { - return op_read(regs.pc++); +alwaysinline auto readPC() -> uint8 { + return read(regs.pc++); } -alwaysinline auto op_readsp() -> uint8 { - return op_read(0x0100 | ++regs.s); +alwaysinline auto readSP() -> uint8 { + return read(0x0100 | ++regs.s); } -alwaysinline auto op_writesp(uint8 data) -> void { - return op_write(0x0100 | regs.s--, data); +alwaysinline auto writeSP(uint8 data) -> void { + return write(0x0100 | regs.s--, data); } -alwaysinline auto op_readdp(uint8 addr) -> uint8 { - return op_read((regs.p.p << 8) + addr); +alwaysinline auto readDP(uint8 addr) -> uint8 { + return read(regs.p.p << 8 | addr); } -alwaysinline auto op_writedp(uint8 addr, uint8 data) -> void { - return op_write((regs.p.p << 8) + addr, data); +alwaysinline auto writeDP(uint8 addr, uint8 data) -> void { + return write(regs.p.p << 8 | addr, data); } diff --git a/higan/processor/spc700/spc700.cpp b/higan/processor/spc700/spc700.cpp index e129b568..8c5d8b37 100644 --- a/higan/processor/spc700/spc700.cpp +++ b/higan/processor/spc700/spc700.cpp @@ -8,265 +8,273 @@ namespace Processor { #include "disassembler.cpp" #include "serialization.cpp" -auto SPC700::op_step() -> void { - switch(opcode = op_readpc()) { - case 0x00: return op_nop(); - case 0x01: return op_jst(); - case 0x02: return op_set_bit(); - case 0x03: return op_branch_bit(); - case 0x04: return op_read_dp<&SPC700::op_or>(regs.a); - case 0x05: return op_read_addr<&SPC700::op_or>(regs.a); - case 0x06: return op_read_ix<&SPC700::op_or>(); - case 0x07: return op_read_idpx<&SPC700::op_or>(); - case 0x08: return op_read_const<&SPC700::op_or>(regs.a); - case 0x09: return op_write_dp_dp<&SPC700::op_or>(); - case 0x0a: return op_set_addr_bit(); - case 0x0b: return op_adjust_dp<&SPC700::op_asl>(); - case 0x0c: return op_adjust_addr<&SPC700::op_asl>(); - case 0x0d: return op_push(regs.p); - case 0x0e: return op_test_addr(1); - case 0x0f: return op_brk(); - case 0x10: return op_branch(regs.p.n == 0); - case 0x11: return op_jst(); - case 0x12: return op_set_bit(); - case 0x13: return op_branch_bit(); - case 0x14: return op_read_dpi<&SPC700::op_or>(regs.a, regs.x); - case 0x15: return op_read_addri<&SPC700::op_or>(regs.x); - case 0x16: return op_read_addri<&SPC700::op_or>(regs.y); - case 0x17: return op_read_idpy<&SPC700::op_or>(); - case 0x18: return op_write_dp_const<&SPC700::op_or>(); - case 0x19: return op_write_ix_iy<&SPC700::op_or>(); - case 0x1a: return op_adjust_dpw(-1); - case 0x1b: return op_adjust_dpx<&SPC700::op_asl>(); - case 0x1c: return op_adjust<&SPC700::op_asl>(regs.a); - case 0x1d: return op_adjust<&SPC700::op_dec>(regs.x); - case 0x1e: return op_read_addr<&SPC700::op_cmp>(regs.x); - case 0x1f: return op_jmp_iaddrx(); - case 0x20: return op_set_flag(regs.p.p, 0); - case 0x21: return op_jst(); - case 0x22: return op_set_bit(); - case 0x23: return op_branch_bit(); - case 0x24: return op_read_dp<&SPC700::op_and>(regs.a); - case 0x25: return op_read_addr<&SPC700::op_and>(regs.a); - case 0x26: return op_read_ix<&SPC700::op_and>(); - case 0x27: return op_read_idpx<&SPC700::op_and>(); - case 0x28: return op_read_const<&SPC700::op_and>(regs.a); - case 0x29: return op_write_dp_dp<&SPC700::op_and>(); - case 0x2a: return op_set_addr_bit(); - case 0x2b: return op_adjust_dp<&SPC700::op_rol>(); - case 0x2c: return op_adjust_addr<&SPC700::op_rol>(); - case 0x2d: return op_push(regs.a); - case 0x2e: return op_bne_dp(); - case 0x2f: return op_branch(true); - case 0x30: return op_branch(regs.p.n == 1); - case 0x31: return op_jst(); - case 0x32: return op_set_bit(); - case 0x33: return op_branch_bit(); - case 0x34: return op_read_dpi<&SPC700::op_and>(regs.a, regs.x); - case 0x35: return op_read_addri<&SPC700::op_and>(regs.x); - case 0x36: return op_read_addri<&SPC700::op_and>(regs.y); - case 0x37: return op_read_idpy<&SPC700::op_and>(); - case 0x38: return op_write_dp_const<&SPC700::op_and>(); - case 0x39: return op_write_ix_iy<&SPC700::op_and>(); - case 0x3a: return op_adjust_dpw(+1); - case 0x3b: return op_adjust_dpx<&SPC700::op_rol>(); - case 0x3c: return op_adjust<&SPC700::op_rol>(regs.a); - case 0x3d: return op_adjust<&SPC700::op_inc>(regs.x); - case 0x3e: return op_read_dp<&SPC700::op_cmp>(regs.x); - case 0x3f: return op_jsr_addr(); - case 0x40: return op_set_flag(regs.p.p, 1); - case 0x41: return op_jst(); - case 0x42: return op_set_bit(); - case 0x43: return op_branch_bit(); - case 0x44: return op_read_dp<&SPC700::op_eor>(regs.a); - case 0x45: return op_read_addr<&SPC700::op_eor>(regs.a); - case 0x46: return op_read_ix<&SPC700::op_eor>(); - case 0x47: return op_read_idpx<&SPC700::op_eor>(); - case 0x48: return op_read_const<&SPC700::op_eor>(regs.a); - case 0x49: return op_write_dp_dp<&SPC700::op_eor>(); - case 0x4a: return op_set_addr_bit(); - case 0x4b: return op_adjust_dp<&SPC700::op_lsr>(); - case 0x4c: return op_adjust_addr<&SPC700::op_lsr>(); - case 0x4d: return op_push(regs.x); - case 0x4e: return op_test_addr(0); - case 0x4f: return op_jsp_dp(); - case 0x50: return op_branch(regs.p.v == 0); - case 0x51: return op_jst(); - case 0x52: return op_set_bit(); - case 0x53: return op_branch_bit(); - case 0x54: return op_read_dpi<&SPC700::op_eor>(regs.a, regs.x); - case 0x55: return op_read_addri<&SPC700::op_eor>(regs.x); - case 0x56: return op_read_addri<&SPC700::op_eor>(regs.y); - case 0x57: return op_read_idpy<&SPC700::op_eor>(); - case 0x58: return op_write_dp_const<&SPC700::op_eor>(); - case 0x59: return op_write_ix_iy<&SPC700::op_eor>(); - case 0x5a: return op_read_dpw<&SPC700::op_cpw>(); - case 0x5b: return op_adjust_dpx<&SPC700::op_lsr>(); - case 0x5c: return op_adjust<&SPC700::op_lsr>(regs.a); - case 0x5d: return op_transfer(regs.a, regs.x); - case 0x5e: return op_read_addr<&SPC700::op_cmp>(regs.y); - case 0x5f: return op_jmp_addr(); - case 0x60: return op_set_flag(regs.p.c, 0); - case 0x61: return op_jst(); - case 0x62: return op_set_bit(); - case 0x63: return op_branch_bit(); - case 0x64: return op_read_dp<&SPC700::op_cmp>(regs.a); - case 0x65: return op_read_addr<&SPC700::op_cmp>(regs.a); - case 0x66: return op_read_ix<&SPC700::op_cmp>(); - case 0x67: return op_read_idpx<&SPC700::op_cmp>(); - case 0x68: return op_read_const<&SPC700::op_cmp>(regs.a); - case 0x69: return op_write_dp_dp<&SPC700::op_cmp>(); - case 0x6a: return op_set_addr_bit(); - case 0x6b: return op_adjust_dp<&SPC700::op_ror>(); - case 0x6c: return op_adjust_addr<&SPC700::op_ror>(); - case 0x6d: return op_push(regs.y); - case 0x6e: return op_bne_dpdec(); - case 0x6f: return op_rts(); - case 0x70: return op_branch(regs.p.v == 1); - case 0x71: return op_jst(); - case 0x72: return op_set_bit(); - case 0x73: return op_branch_bit(); - case 0x74: return op_read_dpi<&SPC700::op_cmp>(regs.a, regs.x); - case 0x75: return op_read_addri<&SPC700::op_cmp>(regs.x); - case 0x76: return op_read_addri<&SPC700::op_cmp>(regs.y); - case 0x77: return op_read_idpy<&SPC700::op_cmp>(); - case 0x78: return op_write_dp_const<&SPC700::op_cmp>(); - case 0x79: return op_write_ix_iy<&SPC700::op_cmp>(); - case 0x7a: return op_read_dpw<&SPC700::op_adw>(); - case 0x7b: return op_adjust_dpx<&SPC700::op_ror>(); - case 0x7c: return op_adjust<&SPC700::op_ror>(regs.a); - case 0x7d: return op_transfer(regs.x, regs.a); - case 0x7e: return op_read_dp<&SPC700::op_cmp>(regs.y); - case 0x7f: return op_rti(); - case 0x80: return op_set_flag(regs.p.c, 1); - case 0x81: return op_jst(); - case 0x82: return op_set_bit(); - case 0x83: return op_branch_bit(); - case 0x84: return op_read_dp<&SPC700::op_adc>(regs.a); - case 0x85: return op_read_addr<&SPC700::op_adc>(regs.a); - case 0x86: return op_read_ix<&SPC700::op_adc>(); - case 0x87: return op_read_idpx<&SPC700::op_adc>(); - case 0x88: return op_read_const<&SPC700::op_adc>(regs.a); - case 0x89: return op_write_dp_dp<&SPC700::op_adc>(); - case 0x8a: return op_set_addr_bit(); - case 0x8b: return op_adjust_dp<&SPC700::op_dec>(); - case 0x8c: return op_adjust_addr<&SPC700::op_dec>(); - case 0x8d: return op_read_const<&SPC700::op_ld>(regs.y); - case 0x8e: return op_plp(); - case 0x8f: return op_write_dp_const<&SPC700::op_st>(); - case 0x90: return op_branch(regs.p.c == 0); - case 0x91: return op_jst(); - case 0x92: return op_set_bit(); - case 0x93: return op_branch_bit(); - case 0x94: return op_read_dpi<&SPC700::op_adc>(regs.a, regs.x); - case 0x95: return op_read_addri<&SPC700::op_adc>(regs.x); - case 0x96: return op_read_addri<&SPC700::op_adc>(regs.y); - case 0x97: return op_read_idpy<&SPC700::op_adc>(); - case 0x98: return op_write_dp_const<&SPC700::op_adc>(); - case 0x99: return op_write_ix_iy<&SPC700::op_adc>(); - case 0x9a: return op_read_dpw<&SPC700::op_sbw>(); - case 0x9b: return op_adjust_dpx<&SPC700::op_dec>(); - case 0x9c: return op_adjust<&SPC700::op_dec>(regs.a); - case 0x9d: return op_transfer(regs.s, regs.x); - case 0x9e: return op_div_ya_x(); - case 0x9f: return op_xcn(); - case 0xa0: return op_set_flag(regs.p.i, 1); - case 0xa1: return op_jst(); - case 0xa2: return op_set_bit(); - case 0xa3: return op_branch_bit(); - case 0xa4: return op_read_dp<&SPC700::op_sbc>(regs.a); - case 0xa5: return op_read_addr<&SPC700::op_sbc>(regs.a); - case 0xa6: return op_read_ix<&SPC700::op_sbc>(); - case 0xa7: return op_read_idpx<&SPC700::op_sbc>(); - case 0xa8: return op_read_const<&SPC700::op_sbc>(regs.a); - case 0xa9: return op_write_dp_dp<&SPC700::op_sbc>(); - case 0xaa: return op_set_addr_bit(); - case 0xab: return op_adjust_dp<&SPC700::op_inc>(); - case 0xac: return op_adjust_addr<&SPC700::op_inc>(); - case 0xad: return op_read_const<&SPC700::op_cmp>(regs.y); - case 0xae: return op_pull(regs.a); - case 0xaf: return op_sta_ixinc(); - case 0xb0: return op_branch(regs.p.c == 1); - case 0xb1: return op_jst(); - case 0xb2: return op_set_bit(); - case 0xb3: return op_branch_bit(); - case 0xb4: return op_read_dpi<&SPC700::op_sbc>(regs.a, regs.x); - case 0xb5: return op_read_addri<&SPC700::op_sbc>(regs.x); - case 0xb6: return op_read_addri<&SPC700::op_sbc>(regs.y); - case 0xb7: return op_read_idpy<&SPC700::op_sbc>(); - case 0xb8: return op_write_dp_const<&SPC700::op_sbc>(); - case 0xb9: return op_write_ix_iy<&SPC700::op_sbc>(); - case 0xba: return op_read_dpw<&SPC700::op_ldw>(); - case 0xbb: return op_adjust_dpx<&SPC700::op_inc>(); - case 0xbc: return op_adjust<&SPC700::op_inc>(regs.a); - case 0xbd: return op_transfer(regs.x, regs.s); - case 0xbe: return op_das(); - case 0xbf: return op_lda_ixinc(); - case 0xc0: return op_set_flag(regs.p.i, 0); - case 0xc1: return op_jst(); - case 0xc2: return op_set_bit(); - case 0xc3: return op_branch_bit(); - case 0xc4: return op_write_dp(regs.a); - case 0xc5: return op_write_addr(regs.a); - case 0xc6: return op_sta_ix(); - case 0xc7: return op_sta_idpx(); - case 0xc8: return op_read_const<&SPC700::op_cmp>(regs.x); - case 0xc9: return op_write_addr(regs.x); - case 0xca: return op_set_addr_bit(); - case 0xcb: return op_write_dp(regs.y); - case 0xcc: return op_write_addr(regs.y); - case 0xcd: return op_read_const<&SPC700::op_ld>(regs.x); - case 0xce: return op_pull(regs.x); - case 0xcf: return op_mul_ya(); - case 0xd0: return op_branch(regs.p.z == 0); - case 0xd1: return op_jst(); - case 0xd2: return op_set_bit(); - case 0xd3: return op_branch_bit(); - case 0xd4: return op_write_dpi(regs.a, regs.x); - case 0xd5: return op_write_addri(regs.x); - case 0xd6: return op_write_addri(regs.y); - case 0xd7: return op_sta_idpy(); - case 0xd8: return op_write_dp(regs.x); - case 0xd9: return op_write_dpi(regs.x, regs.y); - case 0xda: return op_stw_dp(); - case 0xdb: return op_write_dpi(regs.y, regs.x); - case 0xdc: return op_adjust<&SPC700::op_dec>(regs.y); - case 0xdd: return op_transfer(regs.y, regs.a); - case 0xde: return op_bne_dpx(); - case 0xdf: return op_daa(); - case 0xe0: return op_clv(); - case 0xe1: return op_jst(); - case 0xe2: return op_set_bit(); - case 0xe3: return op_branch_bit(); - case 0xe4: return op_read_dp<&SPC700::op_ld>(regs.a); - case 0xe5: return op_read_addr<&SPC700::op_ld>(regs.a); - case 0xe6: return op_read_ix<&SPC700::op_ld>(); - case 0xe7: return op_read_idpx<&SPC700::op_ld>(); - case 0xe8: return op_read_const<&SPC700::op_ld>(regs.a); - case 0xe9: return op_read_addr<&SPC700::op_ld>(regs.x); - case 0xea: return op_set_addr_bit(); - case 0xeb: return op_read_dp<&SPC700::op_ld>(regs.y); - case 0xec: return op_read_addr<&SPC700::op_ld>(regs.y); - case 0xed: return op_cmc(); - case 0xee: return op_pull(regs.y); - case 0xef: return op_wait(); - case 0xf0: return op_branch(regs.p.z == 1); - case 0xf1: return op_jst(); - case 0xf2: return op_set_bit(); - case 0xf3: return op_branch_bit(); - case 0xf4: return op_read_dpi<&SPC700::op_ld>(regs.a, regs.x); - case 0xf5: return op_read_addri<&SPC700::op_ld>(regs.x); - case 0xf6: return op_read_addri<&SPC700::op_ld>(regs.y); - case 0xf7: return op_read_idpy<&SPC700::op_ld>(); - case 0xf8: return op_read_dp<&SPC700::op_ld>(regs.x); - case 0xf9: return op_read_dpi<&SPC700::op_ld>(regs.x, regs.y); - case 0xfa: return op_write_dp_dp<&SPC700::op_st>(); - case 0xfb: return op_read_dpi<&SPC700::op_ld>(regs.y, regs.x); - case 0xfc: return op_adjust<&SPC700::op_inc>(regs.y); - case 0xfd: return op_transfer(regs.a, regs.y); - case 0xfe: return op_bne_ydec(); - case 0xff: return op_wait(); +#define op(id, name, ...) case id: return op_##name(__VA_ARGS__); +#define ol(id, name, fp) case id: return op_##name(&SPC700::op_##fp); +#define of(id, name, fp, ...) case id: return op_##name(&SPC700::op_##fp, __VA_ARGS__); + +auto SPC700::instruction() -> void { + switch(opcode = readPC()) { + op(0x00, nop) + op(0x01, jst) + op(0x02, set_bit); + op(0x03, branch_bit); + of(0x04, read_dp, or, regs.a) + of(0x05, read_addr, or, regs.a) + ol(0x06, read_ix, or); + ol(0x07, read_idpx, or) + of(0x08, read_const, or, regs.a) + ol(0x09, write_dp_dp, or) + op(0x0a, set_addr_bit) + ol(0x0b, adjust_dp, asl) + ol(0x0c, adjust_addr, asl) + op(0x0d, push, regs.p) + op(0x0e, test_addr, 1) + op(0x0f, brk) + op(0x10, branch, regs.p.n == 0) + op(0x11, jst) + op(0x12, set_bit) + op(0x13, branch_bit); + of(0x14, read_dpi, or, regs.a, regs.x) + of(0x15, read_addri, or, regs.x) + of(0x16, read_addri, or, regs.y) + ol(0x17, read_idpy, or) + ol(0x18, write_dp_const, or) + ol(0x19, write_ix_iy, or) + op(0x1a, adjust_dpw, -1) + ol(0x1b, adjust_dpx, asl) + of(0x1c, adjust, asl, regs.a) + of(0x1d, adjust, dec, regs.x) + of(0x1e, read_addr, cmp, regs.x) + op(0x1f, jmp_iaddrx) + op(0x20, set_flag, regs.p.p, 0) + op(0x21, jst) + op(0x22, set_bit) + op(0x23, branch_bit) + of(0x24, read_dp, and, regs.a) + of(0x25, read_addr, and, regs.a) + ol(0x26, read_ix, and) + ol(0x27, read_idpx, and) + of(0x28, read_const, and, regs.a) + ol(0x29, write_dp_dp, and) + op(0x2a, set_addr_bit) + ol(0x2b, adjust_dp, rol) + ol(0x2c, adjust_addr, rol) + op(0x2d, push, regs.a) + op(0x2e, bne_dp) + op(0x2f, branch, true) + op(0x30, branch, regs.p.n == 1) + op(0x31, jst) + op(0x32, set_bit) + op(0x33, branch_bit) + of(0x34, read_dpi, and, regs.a, regs.x) + of(0x35, read_addri, and, regs.x) + of(0x36, read_addri, and, regs.y) + ol(0x37, read_idpy, and) + ol(0x38, write_dp_const, and) + ol(0x39, write_ix_iy, and) + op(0x3a, adjust_dpw, +1) + ol(0x3b, adjust_dpx, rol) + of(0x3c, adjust, rol, regs.a) + of(0x3d, adjust, inc, regs.x) + of(0x3e, read_dp, cmp, regs.x) + op(0x3f, jsr_addr) + op(0x40, set_flag, regs.p.p, 1) + op(0x41, jst) + op(0x42, set_bit) + op(0x43, branch_bit) + of(0x44, read_dp, eor, regs.a) + of(0x45, read_addr, eor, regs.a) + ol(0x46, read_ix, eor) + ol(0x47, read_idpx, eor) + of(0x48, read_const, eor, regs.a) + ol(0x49, write_dp_dp, eor) + op(0x4a, set_addr_bit) + ol(0x4b, adjust_dp, lsr) + ol(0x4c, adjust_addr, lsr) + op(0x4d, push, regs.x) + op(0x4e, test_addr, 0) + op(0x4f, jsp_dp) + op(0x50, branch, regs.p.v == 0) + op(0x51, jst) + op(0x52, set_bit) + op(0x53, branch_bit) + of(0x54, read_dpi, eor, regs.a, regs.x) + of(0x55, read_addri, eor, regs.x) + of(0x56, read_addri, eor, regs.y) + ol(0x57, read_idpy, eor) + ol(0x58, write_dp_const, eor) + ol(0x59, write_ix_iy, eor) + ol(0x5a, read_dpw, cpw) + ol(0x5b, adjust_dpx, lsr) + of(0x5c, adjust, lsr, regs.a) + op(0x5d, transfer, regs.a, regs.x) + of(0x5e, read_addr, cmp, regs.y) + op(0x5f, jmp_addr) + op(0x60, set_flag, regs.p.c, 0) + op(0x61, jst) + op(0x62, set_bit) + op(0x63, branch_bit) + of(0x64, read_dp, cmp, regs.a) + of(0x65, read_addr, cmp, regs.a) + ol(0x66, read_ix, cmp) + ol(0x67, read_idpx, cmp) + of(0x68, read_const, cmp, regs.a) + ol(0x69, write_dp_dp, cmp) + op(0x6a, set_addr_bit) + ol(0x6b, adjust_dp, ror) + ol(0x6c, adjust_addr, ror) + op(0x6d, push, regs.y) + op(0x6e, bne_dpdec) + op(0x6f, rts) + op(0x70, branch, regs.p.v == 1) + op(0x71, jst) + op(0x72, set_bit) + op(0x73, branch_bit) + of(0x74, read_dpi, cmp, regs.a, regs.x) + of(0x75, read_addri, cmp, regs.x) + of(0x76, read_addri, cmp, regs.y) + ol(0x77, read_idpy, cmp) + ol(0x78, write_dp_const, cmp) + ol(0x79, write_ix_iy, cmp) + ol(0x7a, read_dpw, adw) + ol(0x7b, adjust_dpx, ror) + of(0x7c, adjust, ror, regs.a) + op(0x7d, transfer, regs.x, regs.a) + of(0x7e, read_dp, cmp, regs.y) + op(0x7f, rti) + op(0x80, set_flag, regs.p.c, 1) + op(0x81, jst) + op(0x82, set_bit) + op(0x83, branch_bit) + of(0x84, read_dp, adc, regs.a) + of(0x85, read_addr, adc, regs.a) + ol(0x86, read_ix, adc) + ol(0x87, read_idpx, adc) + of(0x88, read_const, adc, regs.a) + ol(0x89, write_dp_dp, adc) + op(0x8a, set_addr_bit) + ol(0x8b, adjust_dp, dec) + ol(0x8c, adjust_addr, dec) + of(0x8d, read_const, ld, regs.y) + op(0x8e, plp) + ol(0x8f, write_dp_const, st) + op(0x90, branch, regs.p.c == 0) + op(0x91, jst) + op(0x92, set_bit) + op(0x93, branch_bit) + of(0x94, read_dpi, adc, regs.a, regs.x) + of(0x95, read_addri, adc, regs.x) + of(0x96, read_addri, adc, regs.y) + ol(0x97, read_idpy, adc) + ol(0x98, write_dp_const, adc) + ol(0x99, write_ix_iy, adc) + ol(0x9a, read_dpw, sbw) + ol(0x9b, adjust_dpx, dec) + of(0x9c, adjust, dec, regs.a) + op(0x9d, transfer, regs.s, regs.x) + op(0x9e, div_ya_x) + op(0x9f, xcn) + op(0xa0, set_flag, regs.p.i, 1) + op(0xa1, jst) + op(0xa2, set_bit) + op(0xa3, branch_bit) + of(0xa4, read_dp, sbc, regs.a) + of(0xa5, read_addr, sbc, regs.a) + ol(0xa6, read_ix, sbc) + ol(0xa7, read_idpx, sbc) + of(0xa8, read_const, sbc, regs.a) + ol(0xa9, write_dp_dp, sbc) + op(0xaa, set_addr_bit) + ol(0xab, adjust_dp, inc) + ol(0xac, adjust_addr, inc) + of(0xad, read_const, cmp, regs.y) + op(0xae, pull, regs.a) + op(0xaf, sta_ixinc) + op(0xb0, branch, regs.p.c == 1) + op(0xb1, jst) + op(0xb2, set_bit) + op(0xb3, branch_bit) + of(0xb4, read_dpi, sbc, regs.a, regs.x) + of(0xb5, read_addri, sbc, regs.x) + of(0xb6, read_addri, sbc, regs.y) + ol(0xb7, read_idpy, sbc) + ol(0xb8, write_dp_const, sbc) + ol(0xb9, write_ix_iy, sbc) + ol(0xba, read_dpw, ldw) + ol(0xbb, adjust_dpx, inc) + of(0xbc, adjust, inc, regs.a) + op(0xbd, transfer, regs.x, regs.s) + op(0xbe, das) + op(0xbf, lda_ixinc) + op(0xc0, set_flag, regs.p.i, 0) + op(0xc1, jst) + op(0xc2, set_bit) + op(0xc3, branch_bit) + op(0xc4, write_dp, regs.a) + op(0xc5, write_addr, regs.a) + op(0xc6, sta_ix) + op(0xc7, sta_idpx) + of(0xc8, read_const, cmp, regs.x) + op(0xc9, write_addr, regs.x) + op(0xca, set_addr_bit) + op(0xcb, write_dp, regs.y) + op(0xcc, write_addr, regs.y) + of(0xcd, read_const, ld, regs.x) + op(0xce, pull, regs.x) + op(0xcf, mul_ya) + op(0xd0, branch, regs.p.z == 0) + op(0xd1, jst) + op(0xd2, set_bit) + op(0xd3, branch_bit) + op(0xd4, write_dpi, regs.a, regs.x) + op(0xd5, write_addri, regs.x) + op(0xd6, write_addri, regs.y) + op(0xd7, sta_idpy) + op(0xd8, write_dp, regs.x) + op(0xd9, write_dpi, regs.x, regs.y) + op(0xda, stw_dp) + op(0xdb, write_dpi, regs.y, regs.x) + of(0xdc, adjust, dec, regs.y) + op(0xdd, transfer, regs.y, regs.a) + op(0xde, bne_dpx) + op(0xdf, daa) + op(0xe0, clv) + op(0xe1, jst) + op(0xe2, set_bit) + op(0xe3, branch_bit) + of(0xe4, read_dp, ld, regs.a) + of(0xe5, read_addr, ld, regs.a) + ol(0xe6, read_ix, ld) + ol(0xe7, read_idpx, ld) + of(0xe8, read_const, ld, regs.a) + of(0xe9, read_addr, ld, regs.x) + op(0xea, set_addr_bit) + of(0xeb, read_dp, ld, regs.y) + of(0xec, read_addr, ld, regs.y) + op(0xed, cmc) + op(0xee, pull, regs.y) + op(0xef, wait) + op(0xf0, branch, regs.p.z == 1) + op(0xf1, jst) + op(0xf2, set_bit) + op(0xf3, branch_bit) + of(0xf4, read_dpi, ld, regs.a, regs.x) + of(0xf5, read_addri, ld, regs.x) + of(0xf6, read_addri, ld, regs.y) + ol(0xf7, read_idpy, ld) + of(0xf8, read_dp, ld, regs.x) + of(0xf9, read_dpi, ld, regs.x, regs.y) + ol(0xfa, write_dp_dp, st) + of(0xfb, read_dpi, ld, regs.y, regs.x) + of(0xfc, adjust, inc, regs.y) + op(0xfd, transfer, regs.a, regs.y) + op(0xfe, bne_ydec) + op(0xff, wait) } } +#undef op +#undef ol +#undef of + } diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index 94c50747..c59f73e9 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -3,12 +3,12 @@ namespace Processor { struct SPC700 { - virtual auto op_io() -> void = 0; - virtual auto op_read(uint16 addr) -> uint8 = 0; - virtual auto op_write(uint16 addr, uint8 data) -> void = 0; - virtual auto disassembler_read(uint16 addr) -> uint8 = 0; + virtual auto io() -> void = 0; + virtual auto read(uint16 addr) -> uint8 = 0; + virtual auto write(uint16 addr, uint8 data) -> void = 0; + virtual auto disassemblerRead(uint16 addr) -> uint8 = 0; - auto op_step() -> void; + auto instruction() -> void; auto serialize(serializer&) -> void; @@ -22,6 +22,10 @@ struct SPC700 { uint8 opcode; protected: + using fps = auto (SPC700::*)(uint8) -> uint8; + using fpb = auto (SPC700::*)(uint8, uint8) -> uint8; + using fpw = auto (SPC700::*)(uint16, uint16) -> uint16; + auto op_adc(uint8, uint8) -> uint8; auto op_and(uint8, uint8) -> uint8; auto op_asl(uint8) -> uint8; @@ -41,24 +45,24 @@ protected: auto op_ldw(uint16, uint16) -> uint16; auto op_sbw(uint16, uint16) -> uint16; - template uint8> auto op_adjust(uint8_t&) -> void; - template uint8> auto op_adjust_addr() -> void; - template uint8> auto op_adjust_dp() -> void; + auto op_adjust(fps, uint8_t&) -> void; + auto op_adjust_addr(fps) -> void; + auto op_adjust_dp(fps) -> void; auto op_adjust_dpw(int) -> void; - template uint8> auto op_adjust_dpx() -> void; + auto op_adjust_dpx(fps) -> void; auto op_branch(bool) -> void; auto op_branch_bit() -> void; auto op_pull(uint8_t&) -> void; auto op_push(uint8) -> void; - template uint8> auto op_read_addr(uint8_t&) -> void; - template uint8> auto op_read_addri(uint8_t&) -> void; - template uint8> auto op_read_const(uint8_t&) -> void; - template uint8> auto op_read_dp(uint8_t&) -> void; - template uint8> auto op_read_dpi(uint8_t&, uint8_t&) -> void; - template uint16> auto op_read_dpw() -> void; - template uint8> auto op_read_idpx() -> void; - template uint8> auto op_read_idpy() -> void; - template uint8> auto op_read_ix() -> void; + auto op_read_addr(fpb, uint8_t&) -> void; + auto op_read_addri(fpb, uint8_t&) -> void; + auto op_read_const(fpb, uint8_t&) -> void; + auto op_read_dp(fpb, uint8_t&) -> void; + auto op_read_dpi(fpb, uint8_t&, uint8_t&) -> void; + auto op_read_dpw(fpw) -> void; + auto op_read_idpx(fpb) -> void; + auto op_read_idpy(fpb) -> void; + auto op_read_ix(fpb) -> void; auto op_set_addr_bit() -> void; auto op_set_bit() -> void; auto op_set_flag(bool&, bool) -> void; @@ -68,9 +72,9 @@ protected: auto op_write_addri(uint8_t&) -> void; auto op_write_dp(uint8_t&) -> void; auto op_write_dpi(uint8_t&, uint8_t&) -> void; - template uint8> auto op_write_dp_const() -> void; - template uint8> auto op_write_dp_dp() -> void; - template uint8> auto op_write_ix_iy() -> void; + auto op_write_dp_const(fpb) -> void; + auto op_write_dp_dp(fpb) -> void; + auto op_write_ix_iy(fpb) -> void; auto op_bne_dp() -> void; auto op_bne_dpdec() -> void; diff --git a/higan/sfc/smp/memory.cpp b/higan/sfc/smp/memory.cpp index 63a36f50..64659841 100644 --- a/higan/sfc/smp/memory.cpp +++ b/higan/sfc/smp/memory.cpp @@ -173,12 +173,12 @@ auto SMP::busWrite(uint16 addr, uint8 data) -> void { ramWrite(addr, data); //all writes, even to MMIO registers, appear on bus } -auto SMP::op_io() -> void { +auto SMP::io() -> void { addClocks(24); cycleEdge(); } -auto SMP::op_read(uint16 addr) -> uint8 { +auto SMP::read(uint16 addr) -> uint8 { addClocks(12); uint8 data = busRead(addr); addClocks(12); @@ -187,14 +187,14 @@ auto SMP::op_read(uint16 addr) -> uint8 { return data; } -auto SMP::op_write(uint16 addr, uint8 data) -> void { +auto SMP::write(uint16 addr, uint8 data) -> void { addClocks(24); busWrite(addr, data); cycleEdge(); debugger.op_write(addr, data); } -auto SMP::disassembler_read(uint16 addr) -> uint8 { +auto SMP::disassemblerRead(uint16 addr) -> uint8 { if((addr & 0xfff0) == 0x00f0) return 0x00; if((addr & 0xffc0) == 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; return apuram[addr]; diff --git a/higan/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp index ba561e88..ae10b1d4 100644 --- a/higan/sfc/smp/smp.cpp +++ b/higan/sfc/smp/smp.cpp @@ -27,7 +27,7 @@ auto SMP::Enter() -> void { auto SMP::main() -> void { debugger.op_exec(regs.pc); - op_step(); + instruction(); } auto SMP::power() -> void { diff --git a/higan/sfc/smp/smp.hpp b/higan/sfc/smp/smp.hpp index c362fdf1..0741ea71 100644 --- a/higan/sfc/smp/smp.hpp +++ b/higan/sfc/smp/smp.hpp @@ -46,9 +46,9 @@ privileged: static auto Enter() -> void; struct Debugger { - hook op_exec; - hook op_read; - hook op_write; + hook void> op_exec; + hook void> op_read; + hook void> op_write; } debugger; //memory.cpp @@ -58,14 +58,14 @@ privileged: auto busRead(uint16 addr) -> uint8; auto busWrite(uint16 addr, uint8 data) -> void; - auto op_io() -> void; - auto op_read(uint16 addr) -> uint8; - auto op_write(uint16 addr, uint8 data) -> void; + auto io() -> void override; + auto read(uint16 addr) -> uint8 override; + auto write(uint16 addr, uint8 data) -> void override; - auto disassembler_read(uint16 addr) -> uint8; + auto disassemblerRead(uint16 addr) -> uint8 override; //timing.cpp - template + template struct Timer { uint8 stage0; uint8 stage1; diff --git a/nall/dsp/iir/biquad.hpp b/nall/dsp/iir/biquad.hpp index b73dcb57..7a3ce0ec 100644 --- a/nall/dsp/iir/biquad.hpp +++ b/nall/dsp/iir/biquad.hpp @@ -147,7 +147,7 @@ auto Biquad::process(double in) -> double { //compute Q values for N-order butterworth filtering auto Biquad::butterworth(uint order, uint phase) -> double { - return -0.5 / cos(Math::Pi / 2.0 * (1.0 + (1.0 + (2.0 * phase + 1.0) / order))); + return -0.5 / cos(Math::Pi * (phase + order + 0.5) / order); } }}}