diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 1256f98d..36d10282 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "102.26"; + static const string Version = "102.27"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/processor/gsu/disassembler.cpp b/higan/processor/gsu/disassembler.cpp index 75216e34..75254b4f 100644 --- a/higan/processor/gsu/disassembler.cpp +++ b/higan/processor/gsu/disassembler.cpp @@ -2,10 +2,10 @@ auto GSU::disassembleOpcode(char* output) -> void { *output = 0; switch(regs.sfr.alt2 << 1 | regs.sfr.alt1 << 0) { - case 0: disassembleAlt0(output); break; - case 1: disassembleAlt1(output); break; - case 2: disassembleAlt2(output); break; - case 3: disassembleAlt3(output); break; + case 0: disassembleALT0(output); break; + case 1: disassembleALT1(output); break; + case 2: disassembleALT2(output); break; + case 3: disassembleALT3(output); break; } uint length = strlen(output); @@ -30,7 +30,7 @@ auto GSU::disassembleOpcode(char* output) -> void { #define op1 read((regs.pbr << 16) + regs.r[15] + 0) #define op2 read((regs.pbr << 16) + regs.r[15] + 1) -auto GSU::disassembleAlt0(char* output) -> void { +auto GSU::disassembleALT0(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -87,7 +87,7 @@ auto GSU::disassembleAlt0(char* output) -> void { strcat(output, t); } -auto GSU::disassembleAlt1(char* output) -> void { +auto GSU::disassembleALT1(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -144,7 +144,7 @@ auto GSU::disassembleAlt1(char* output) -> void { strcat(output, t); } -auto GSU::disassembleAlt2(char* output) -> void { +auto GSU::disassembleALT2(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -201,7 +201,7 @@ auto GSU::disassembleAlt2(char* output) -> void { strcat(output, t); } -auto GSU::disassembleAlt3(char* output) -> void { +auto GSU::disassembleALT3(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; diff --git a/higan/processor/gsu/gsu.cpp b/higan/processor/gsu/gsu.cpp index 54ccc366..78a255c6 100644 --- a/higan/processor/gsu/gsu.cpp +++ b/higan/processor/gsu/gsu.cpp @@ -7,8 +7,8 @@ namespace Processor { +#include "instruction.cpp" #include "instructions.cpp" -#include "switch.cpp" #include "serialization.cpp" #include "disassembler.cpp" diff --git a/higan/processor/gsu/gsu.hpp b/higan/processor/gsu/gsu.hpp index a5cf7c5b..5cb258b0 100644 --- a/higan/processor/gsu/gsu.hpp +++ b/higan/processor/gsu/gsu.hpp @@ -27,46 +27,46 @@ struct GSU { auto power() -> void; //instructions.cpp - auto op_add_adc(uint n); - auto op_alt1(); - auto op_alt2(); - auto op_alt3(); - auto op_and_bic(uint n); - auto op_asr_div2(); - auto op_branch(bool c); - auto op_cache(); - auto op_color_cmode(); - auto op_dec(uint n); - auto op_fmult_lmult(); - auto op_from_moves(uint n); - auto op_getb(); - auto op_getc_ramb_romb(); - auto op_hib(); - auto op_ibt_lms_sms(uint n); - auto op_inc(uint n); - auto op_iwt_lm_sm(uint n); - auto op_jmp_ljmp(uint n); - auto op_link(uint n); - auto op_load(uint n); - auto op_lob(); - auto op_loop(); - auto op_lsr(); - auto op_merge(); - auto op_mult_umult(uint n); - auto op_nop(); - auto op_not(); - auto op_or_xor(uint n); - auto op_plot_rpix(); - auto op_rol(); - auto op_ror(); - auto op_sbk(); - auto op_sex(); - auto op_store(uint n); - auto op_stop(); - auto op_sub_sbc_cmp(uint n); - auto op_swap(); - auto op_to_move(uint n); - auto op_with(uint n); + auto instructionADD_ADC(uint n) -> void; + auto instructionALT1() -> void; + auto instructionALT2() -> void; + auto instructionALT3() -> void; + auto instructionAND_BIC(uint n) -> void; + auto instructionASR_DIV2() -> void; + auto instructionBranch(bool c) -> void; + auto instructionCACHE() -> void; + auto instructionCOLOR_CMODE() -> void; + auto instructionDEC(uint n) -> void; + auto instructionFMULT_LMULT() -> void; + auto instructionFROM_MOVES(uint n) -> void; + auto instructionGETB() -> void; + auto instructionGETC_RAMB_ROMB() -> void; + auto instructionHIB() -> void; + auto instructionIBT_LMS_SMS(uint n) -> void; + auto instructionINC(uint n) -> void; + auto instructionIWT_LM_SM(uint n) -> void; + auto instructionJMP_LJMP(uint n) -> void; + auto instructionLINK(uint n) -> void; + auto instructionLoad(uint n) -> void; + auto instructionLOB() -> void; + auto instructionLOOP() -> void; + auto instructionLSR() -> void; + auto instructionMERGE() -> void; + auto instructionMULT_UMULT(uint n) -> void; + auto instructionNOP() -> void; + auto instructionNOT() -> void; + auto instructionOR_XOR(uint n) -> void; + auto instructionPLOT_RPIX() -> void; + auto instructionROL() -> void; + auto instructionROR() -> void; + auto instructionSBK() -> void; + auto instructionSEX() -> void; + auto instructionStore(uint n) -> void; + auto instructionSTOP() -> void; + auto instructionSUB_SBC_CMP(uint n) -> void; + auto instructionSWAP() -> void; + auto instructionTO_MOVE(uint n) -> void; + auto instructionWITH(uint n) -> void; //switch.cpp auto instruction(uint8 opcode) -> void; @@ -76,10 +76,10 @@ struct GSU { //disassembler.cpp auto disassembleOpcode(char* output) -> void; - auto disassembleAlt0(char* output) -> void; - auto disassembleAlt1(char* output) -> void; - auto disassembleAlt2(char* output) -> void; - auto disassembleAlt3(char* output) -> void; + auto disassembleALT0(char* output) -> void; + auto disassembleALT1(char* output) -> void; + auto disassembleALT2(char* output) -> void; + auto disassembleALT3(char* output) -> void; }; } diff --git a/higan/processor/gsu/instruction.cpp b/higan/processor/gsu/instruction.cpp new file mode 100644 index 00000000..969e6118 --- /dev/null +++ b/higan/processor/gsu/instruction.cpp @@ -0,0 +1,94 @@ +auto GSU::instruction(uint8 opcode) -> void { + #define op(id, name, ...) \ + case id: return instruction##name(__VA_ARGS__); \ + + #define op4(id, name) \ + case id+ 0: return instruction##name((uint4)opcode); \ + case id+ 1: return instruction##name((uint4)opcode); \ + case id+ 2: return instruction##name((uint4)opcode); \ + case id+ 3: return instruction##name((uint4)opcode); \ + + #define op6(id, name) \ + op4(id, name) \ + case id+ 4: return instruction##name((uint4)opcode); \ + case id+ 5: return instruction##name((uint4)opcode); \ + + #define op12(id, name) \ + op6(id, name) \ + case id+ 6: return instruction##name((uint4)opcode); \ + case id+ 7: return instruction##name((uint4)opcode); \ + case id+ 8: return instruction##name((uint4)opcode); \ + case id+ 9: return instruction##name((uint4)opcode); \ + case id+10: return instruction##name((uint4)opcode); \ + case id+11: return instruction##name((uint4)opcode); \ + + #define op15(id, name) \ + op12(id, name) \ + case id+12: return instruction##name((uint4)opcode); \ + case id+13: return instruction##name((uint4)opcode); \ + case id+14: return instruction##name((uint4)opcode); \ + + #define op16(id, name) \ + op15(id, name) \ + case id+15: return instruction##name((uint4)opcode); \ + + switch(opcode) { + op (0x00, STOP) + op (0x01, NOP) + op (0x02, CACHE) + op (0x03, LSR) + op (0x04, ROL) + op (0x05, Branch, 1) //bra + op (0x06, Branch, (regs.sfr.s ^ regs.sfr.ov) == 0) //blt + op (0x07, Branch, (regs.sfr.s ^ regs.sfr.ov) == 1) //bge + op (0x08, Branch, regs.sfr.z == 0) //bne + op (0x09, Branch, regs.sfr.z == 1) //beq + op (0x0a, Branch, regs.sfr.s == 0) //bpl + op (0x0b, Branch, regs.sfr.s == 1) //bmi + op (0x0c, Branch, regs.sfr.cy == 0) //bcc + op (0x0d, Branch, regs.sfr.cy == 1) //bcs + op (0x0e, Branch, regs.sfr.ov == 0) //bvc + op (0x0f, Branch, regs.sfr.ov == 1) //bvs + op16(0x10, TO_MOVE) + op16(0x20, WITH) + op12(0x30, Store) + op (0x3c, LOOP) + op (0x3d, ALT1) + op (0x3e, ALT2) + op (0x3f, ALT3) + op12(0x40, Load) + op (0x4c, PLOT_RPIX) + op (0x4d, SWAP) + op (0x4e, COLOR_CMODE) + op (0x4f, NOT) + op16(0x50, ADD_ADC) + op16(0x60, SUB_SBC_CMP) + op (0x70, MERGE) + op15(0x71, AND_BIC) + op16(0x80, MULT_UMULT) + op (0x90, SBK) + op4 (0x91, LINK) + op (0x95, SEX) + op (0x96, ASR_DIV2) + op (0x97, ROR) + op6 (0x98, JMP_LJMP) + op (0x9e, LOB) + op (0x9f, FMULT_LMULT) + op16(0xa0, IBT_LMS_SMS) + op16(0xb0, FROM_MOVES) + op (0xc0, HIB) + op15(0xc1, OR_XOR) + op15(0xd0, INC) + op (0xdf, GETC_RAMB_ROMB) + op15(0xe0, DEC) + op (0xef, GETB) + op16(0xf0, IWT_LM_SM) + } + + #undef op + #undef op4 + #undef op6 + #undef op12 + #undef op15 + #undef op16 +} diff --git a/higan/processor/gsu/instructions.cpp b/higan/processor/gsu/instructions.cpp index f022641e..89d7319f 100644 --- a/higan/processor/gsu/instructions.cpp +++ b/higan/processor/gsu/instructions.cpp @@ -1,5 +1,5 @@ //$00 stop -auto GSU::op_stop() { +auto GSU::instructionSTOP() -> void { if(regs.cfgr.irq == 0) { regs.sfr.irq = 1; stop(); @@ -10,12 +10,12 @@ auto GSU::op_stop() { } //$01 nop -auto GSU::op_nop() { +auto GSU::instructionNOP() -> void { regs.reset(); } //$02 cache -auto GSU::op_cache() { +auto GSU::instructionCACHE() -> void { if(regs.cbr != (regs.r[15] & 0xfff0)) { regs.cbr = regs.r[15] & 0xfff0; flushCache(); @@ -24,7 +24,7 @@ auto GSU::op_cache() { } //$03 lsr -auto GSU::op_lsr() { +auto GSU::instructionLSR() -> void { regs.sfr.cy = (regs.sr() & 1); regs.dr() = regs.sr() >> 1; regs.sfr.s = (regs.dr() & 0x8000); @@ -33,7 +33,7 @@ auto GSU::op_lsr() { } //$04 rol -auto GSU::op_rol() { +auto GSU::instructionROL() -> void { bool carry = (regs.sr() & 0x8000); regs.dr() = (regs.sr() << 1) | regs.sfr.cy; regs.sfr.s = (regs.dr() & 0x8000); @@ -53,14 +53,14 @@ auto GSU::op_rol() { //$0d bcs e //$0e bvc e //$0f bvs e -auto GSU::op_branch(bool c) { - auto d = (int8)pipe(); - if(c) regs.r[15] += d; +auto GSU::instructionBranch(bool take) -> void { + auto displacement = (int8)pipe(); + if(take) regs.r[15] += displacement; } //$10-1f(b0) to rN //$10-1f(b1) move rN -auto GSU::op_to_move(uint n) { +auto GSU::instructionTO_MOVE(uint n) -> void { if(!regs.sfr.b) { regs.dreg = n; } else { @@ -70,7 +70,7 @@ auto GSU::op_to_move(uint n) { } //$20-2f with rN -auto GSU::op_with(uint n) { +auto GSU::instructionWITH(uint n) -> void { regs.sreg = n; regs.dreg = n; regs.sfr.b = 1; @@ -78,7 +78,7 @@ auto GSU::op_with(uint n) { //$30-3b(alt0) stw (rN) //$30-3b(alt1) stb (rN) -auto GSU::op_store(uint n) { +auto GSU::instructionStore(uint n) -> void { regs.ramaddr = regs.r[n]; writeRAMBuffer(regs.ramaddr, regs.sr()); if(!regs.sfr.alt1) writeRAMBuffer(regs.ramaddr ^ 1, regs.sr() >> 8); @@ -86,7 +86,7 @@ auto GSU::op_store(uint n) { } //$3c loop -auto GSU::op_loop() { +auto GSU::instructionLOOP() -> void { regs.r[12]--; regs.sfr.s = (regs.r[12] & 0x8000); regs.sfr.z = (regs.r[12] == 0); @@ -95,19 +95,19 @@ auto GSU::op_loop() { } //$3d alt1 -auto GSU::op_alt1() { +auto GSU::instructionALT1() -> void { regs.sfr.b = 0; regs.sfr.alt1 = 1; } //$3e alt2 -auto GSU::op_alt2() { +auto GSU::instructionALT2() -> void { regs.sfr.b = 0; regs.sfr.alt2 = 1; } //$3f alt3 -auto GSU::op_alt3() { +auto GSU::instructionALT3() -> void { regs.sfr.b = 0; regs.sfr.alt1 = 1; regs.sfr.alt2 = 1; @@ -115,7 +115,7 @@ auto GSU::op_alt3() { //$40-4b(alt0) ldw (rN) //$40-4b(alt1) ldb (rN) -auto GSU::op_load(uint n) { +auto GSU::instructionLoad(uint n) -> void { regs.ramaddr = regs.r[n]; regs.dr() = readRAMBuffer(regs.ramaddr); if(!regs.sfr.alt1) regs.dr() |= readRAMBuffer(regs.ramaddr ^ 1) << 8; @@ -124,7 +124,7 @@ auto GSU::op_load(uint n) { //$4c(alt0) plot //$4c(alt1) rpix -auto GSU::op_plot_rpix() { +auto GSU::instructionPLOT_RPIX() -> void { if(!regs.sfr.alt1) { plot(regs.r[1], regs.r[2]); regs.r[1]++; @@ -137,8 +137,8 @@ auto GSU::op_plot_rpix() { } //$4d swap -auto GSU::op_swap() { - regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8); +auto GSU::instructionSWAP() -> void { + regs.dr() = regs.sr() >> 8 | regs.sr() << 8; regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); regs.reset(); @@ -146,7 +146,7 @@ auto GSU::op_swap() { //$4e(alt0) color //$4e(alt1) cmode -auto GSU::op_color_cmode() { +auto GSU::instructionCOLOR_CMODE() -> void { if(!regs.sfr.alt1) { regs.colr = color(regs.sr()); } else { @@ -156,7 +156,7 @@ auto GSU::op_color_cmode() { } //$4f not -auto GSU::op_not() { +auto GSU::instructionNOT() -> void { regs.dr() = ~regs.sr(); regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -167,7 +167,7 @@ auto GSU::op_not() { //$50-5f(alt1) adc rN //$50-5f(alt2) add #N //$50-5f(alt3) adc #N -auto GSU::op_add_adc(uint n) { +auto GSU::instructionADD_ADC(uint n) -> void { if(!regs.sfr.alt2) n = regs.r[n]; int r = regs.sr() + n + (regs.sfr.alt1 ? regs.sfr.cy : 0); regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; @@ -182,7 +182,7 @@ auto GSU::op_add_adc(uint n) { //$60-6f(alt1) sbc rN //$60-6f(alt2) sub #N //$60-6f(alt3) cmp rN -auto GSU::op_sub_sbc_cmp(uint n) { +auto GSU::instructionSUB_SBC_CMP(uint n) -> void { if(!regs.sfr.alt2 || regs.sfr.alt1) n = regs.r[n]; int r = regs.sr() - n - (!regs.sfr.alt2 && regs.sfr.alt1 ? !regs.sfr.cy : 0); regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000; @@ -194,7 +194,7 @@ auto GSU::op_sub_sbc_cmp(uint n) { } //$70 merge -auto GSU::op_merge() { +auto GSU::instructionMERGE() -> void { regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8); regs.sfr.ov = (regs.dr() & 0xc0c0); regs.sfr.s = (regs.dr() & 0x8080); @@ -207,7 +207,7 @@ auto GSU::op_merge() { //$71-7f(alt1) bic rN //$71-7f(alt2) and #N //$71-7f(alt3) bic #N -auto GSU::op_and_bic(uint n) { +auto GSU::instructionAND_BIC(uint n) -> void { if(!regs.sfr.alt2) n = regs.r[n]; regs.dr() = regs.sr() & (regs.sfr.alt1 ? ~n : n); regs.sfr.s = (regs.dr() & 0x8000); @@ -219,7 +219,7 @@ auto GSU::op_and_bic(uint n) { //$80-8f(alt1) umult rN //$80-8f(alt2) mult #N //$80-8f(alt3) umult #N -auto GSU::op_mult_umult(uint n) { +auto GSU::instructionMULT_UMULT(uint n) -> void { if(!regs.sfr.alt2) n = regs.r[n]; regs.dr() = (!regs.sfr.alt1 ? ((int8)regs.sr() * (int8)n) : ((uint8)regs.sr() * (uint8)n)); regs.sfr.s = (regs.dr() & 0x8000); @@ -229,20 +229,20 @@ auto GSU::op_mult_umult(uint n) { } //$90 sbk -auto GSU::op_sbk() { +auto GSU::instructionSBK() -> void { writeRAMBuffer(regs.ramaddr ^ 0, regs.sr() >> 0); writeRAMBuffer(regs.ramaddr ^ 1, regs.sr() >> 8); regs.reset(); } //$91-94 link #N -auto GSU::op_link(uint n) { +auto GSU::instructionLINK(uint n) -> void { regs.r[11] = regs.r[15] + n; regs.reset(); } //$95 sex -auto GSU::op_sex() { +auto GSU::instructionSEX() -> void { regs.dr() = (int8)regs.sr(); regs.sfr.s = (regs.dr() & 0x8000); regs.sfr.z = (regs.dr() == 0); @@ -251,7 +251,7 @@ auto GSU::op_sex() { //$96(alt0) asr //$96(alt1) div2 -auto GSU::op_asr_div2() { +auto GSU::instructionASR_DIV2() -> void { regs.sfr.cy = (regs.sr() & 1); regs.dr() = ((int16)regs.sr() >> 1) + (regs.sfr.alt1 ? ((regs.sr() + 1) >> 16) : 0); regs.sfr.s = (regs.dr() & 0x8000); @@ -260,7 +260,7 @@ auto GSU::op_asr_div2() { } //$97 ror -auto GSU::op_ror() { +auto GSU::instructionROR() -> void { bool carry = (regs.sr() & 1); regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1); regs.sfr.s = (regs.dr() & 0x8000); @@ -271,7 +271,7 @@ auto GSU::op_ror() { //$98-9d(alt0) jmp rN //$98-9d(alt1) ljmp rN -auto GSU::op_jmp_ljmp(uint n) { +auto GSU::instructionJMP_LJMP(uint n) -> void { if(!regs.sfr.alt1) { regs.r[15] = regs.r[n]; } else { @@ -284,7 +284,7 @@ auto GSU::op_jmp_ljmp(uint n) { } //$9e lob -auto GSU::op_lob() { +auto GSU::instructionLOB() -> void { regs.dr() = regs.sr() & 0xff; regs.sfr.s = (regs.dr() & 0x80); regs.sfr.z = (regs.dr() == 0); @@ -293,7 +293,7 @@ auto GSU::op_lob() { //$9f(alt0) fmult //$9f(alt1) lmult -auto GSU::op_fmult_lmult() { +auto GSU::instructionFMULT_LMULT() -> void { uint32 result = (int16)regs.sr() * (int16)regs.r[6]; if(regs.sfr.alt1) regs.r[4] = result; regs.dr() = result >> 16; @@ -307,7 +307,7 @@ auto GSU::op_fmult_lmult() { //$a0-af(alt0) ibt rN,#pp //$a0-af(alt1) lms rN,(yy) //$a0-af(alt2) sms (yy),rN -auto GSU::op_ibt_lms_sms(uint n) { +auto GSU::instructionIBT_LMS_SMS(uint n) -> void { if(regs.sfr.alt1) { regs.ramaddr = pipe() << 1; uint8 lo = readRAMBuffer(regs.ramaddr ^ 0) << 0; @@ -324,7 +324,7 @@ auto GSU::op_ibt_lms_sms(uint n) { //$b0-bf(b0) from rN //$b0-bf(b1) moves rN -auto GSU::op_from_moves(uint n) { +auto GSU::instructionFROM_MOVES(uint n) -> void { if(!regs.sfr.b) { regs.sreg = n; } else { @@ -337,7 +337,7 @@ auto GSU::op_from_moves(uint n) { } //$c0 hib -auto GSU::op_hib() { +auto GSU::instructionHIB() -> void { regs.dr() = regs.sr() >> 8; regs.sfr.s = (regs.dr() & 0x80); regs.sfr.z = (regs.dr() == 0); @@ -348,7 +348,7 @@ auto GSU::op_hib() { //$c1-cf(alt1) xor rN //$c1-cf(alt2) or #N //$c1-cf(alt3) xor #N -auto GSU::op_or_xor(uint n) { +auto GSU::instructionOR_XOR(uint n) -> void { if(!regs.sfr.alt2) n = regs.r[n]; regs.dr() = (!regs.sfr.alt1 ? (regs.sr() | n) : (regs.sr() ^ n)); regs.sfr.s = (regs.dr() & 0x8000); @@ -357,7 +357,7 @@ auto GSU::op_or_xor(uint n) { } //$d0-de inc rN -auto GSU::op_inc(uint n) { +auto GSU::instructionINC(uint n) -> void { regs.r[n]++; regs.sfr.s = (regs.r[n] & 0x8000); regs.sfr.z = (regs.r[n] == 0); @@ -367,7 +367,7 @@ auto GSU::op_inc(uint n) { //$df(alt0) getc //$df(alt2) ramb //$df(alt3) romb -auto GSU::op_getc_ramb_romb() { +auto GSU::instructionGETC_RAMB_ROMB() -> void { if(!regs.sfr.alt2) { regs.colr = color(readROMBuffer()); } else if(!regs.sfr.alt1) { @@ -381,7 +381,7 @@ auto GSU::op_getc_ramb_romb() { } //$e0-ee dec rN -auto GSU::op_dec(uint n) { +auto GSU::instructionDEC(uint n) -> void { regs.r[n]--; regs.sfr.s = (regs.r[n] & 0x8000); regs.sfr.z = (regs.r[n] == 0); @@ -392,7 +392,7 @@ auto GSU::op_dec(uint n) { //$ef(alt1) getbh //$ef(alt2) getbl //$ef(alt3) getbs -auto GSU::op_getb() { +auto GSU::instructionGETB() -> void { switch(regs.sfr.alt2 << 1 | regs.sfr.alt1 << 0) { case 0: regs.dr() = readROMBuffer(); break; case 1: regs.dr() = readROMBuffer() << 8 | (uint8)regs.sr(); break; @@ -405,7 +405,7 @@ auto GSU::op_getb() { //$f0-ff(alt0) iwt rN,#xx //$f0-ff(alt1) lm rN,(xx) //$f0-ff(alt2) sm (xx),rN -auto GSU::op_iwt_lm_sm(uint n) { +auto GSU::instructionIWT_LM_SM(uint n) -> void { if(regs.sfr.alt1) { regs.ramaddr = pipe() << 0; regs.ramaddr |= pipe() << 8; diff --git a/higan/processor/gsu/switch.cpp b/higan/processor/gsu/switch.cpp deleted file mode 100644 index 7aba9a5e..00000000 --- a/higan/processor/gsu/switch.cpp +++ /dev/null @@ -1,94 +0,0 @@ -auto GSU::instruction(uint8 opcode) -> void { - #define op(id, name, ...) \ - case id: return op_##name(__VA_ARGS__); \ - - #define op4(id, name) \ - case id+ 0: return op_##name((uint4)opcode); \ - case id+ 1: return op_##name((uint4)opcode); \ - case id+ 2: return op_##name((uint4)opcode); \ - case id+ 3: return op_##name((uint4)opcode); \ - - #define op6(id, name) \ - op4(id, name) \ - case id+ 4: return op_##name((uint4)opcode); \ - case id+ 5: return op_##name((uint4)opcode); \ - - #define op12(id, name) \ - op6(id, name) \ - case id+ 6: return op_##name((uint4)opcode); \ - case id+ 7: return op_##name((uint4)opcode); \ - case id+ 8: return op_##name((uint4)opcode); \ - case id+ 9: return op_##name((uint4)opcode); \ - case id+10: return op_##name((uint4)opcode); \ - case id+11: return op_##name((uint4)opcode); \ - - #define op15(id, name) \ - op12(id, name) \ - case id+12: return op_##name((uint4)opcode); \ - case id+13: return op_##name((uint4)opcode); \ - case id+14: return op_##name((uint4)opcode); \ - - #define op16(id, name) \ - op15(id, name) \ - case id+15: return op_##name((uint4)opcode); \ - - switch(opcode) { - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, branch, 1) //bra - op (0x06, branch, (regs.sfr.s ^ regs.sfr.ov) == 0) //blt - op (0x07, branch, (regs.sfr.s ^ regs.sfr.ov) == 1) //bge - op (0x08, branch, regs.sfr.z == 0) //bne - op (0x09, branch, regs.sfr.z == 1) //beq - op (0x0a, branch, regs.sfr.s == 0) //bpl - op (0x0b, branch, regs.sfr.s == 1) //bmi - op (0x0c, branch, regs.sfr.cy == 0) //bcc - op (0x0d, branch, regs.sfr.cy == 1) //bcs - op (0x0e, branch, regs.sfr.ov == 0) //bvc - op (0x0f, branch, regs.sfr.ov == 1) //bvs - op16(0x10, to_move) - op16(0x20, with) - op12(0x30, store) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12(0x40, load) - op (0x4c, plot_rpix) - op (0x4d, swap) - op (0x4e, color_cmode) - op (0x4f, not) - op16(0x50, add_adc) - op16(0x60, sub_sbc_cmp) - op (0x70, merge) - op15(0x71, and_bic) - op16(0x80, mult_umult) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, asr_div2) - op (0x97, ror) - op6 (0x98, jmp_ljmp) - op (0x9e, lob) - op (0x9f, fmult_lmult) - op16(0xa0, ibt_lms_sms) - op16(0xb0, from_moves) - op (0xc0, hib) - op15(0xc1, or_xor) - op15(0xd0, inc) - op15(0xe0, dec) - op (0xdf, getc_ramb_romb) - op (0xef, getb) - op16(0xf0, iwt_lm_sm) - } - - #undef op - #undef op4 - #undef op6 - #undef op12 - #undef op15 - #undef op16 -} diff --git a/higan/processor/hg51b/hg51b.hpp b/higan/processor/hg51b/hg51b.hpp index b7118878..94c60ae8 100644 --- a/higan/processor/hg51b/hg51b.hpp +++ b/higan/processor/hg51b/hg51b.hpp @@ -25,8 +25,8 @@ protected: auto instruction() -> void; //registers.cpp - auto regRead(uint8 addr) const -> uint24; - auto regWrite(uint8 addr, uint24 data) -> void; + auto registerRead(uint8 addr) const -> uint24; + auto registerWrite(uint8 addr, uint24 data) -> void; struct Registers { bool halt; diff --git a/higan/processor/hg51b/instructions.cpp b/higan/processor/hg51b/instructions.cpp index 96ae8cc5..58e0d0f8 100644 --- a/higan/processor/hg51b/instructions.cpp +++ b/higan/processor/hg51b/instructions.cpp @@ -34,7 +34,7 @@ auto HG51B::sa() -> uint { //Register-or-Immediate: most opcodes can load from a register or immediate auto HG51B::ri() -> uint { if(opcode & 0x0400) return opcode & 0xff; - return regRead(opcode & 0xff); + return registerRead(opcode & 0xff); } //New-PC: determine jump target address; opcode.d9 = long jump flag (1 = yes) @@ -306,7 +306,7 @@ auto HG51B::instruction() -> void { else if((opcode & 0xff00) == 0xe000) { //1110 0000 .... .... //st r,a - regWrite(opcode & 0xff, regs.a); + registerWrite(opcode & 0xff, regs.a); } else if((opcode & 0xfb00) == 0xe800) { @@ -333,10 +333,10 @@ auto HG51B::instruction() -> void { else if((opcode & 0xff00) == 0xf000) { //1111 0000 .... .... //swap a,r - uint24 source = regRead(opcode & 0xff); + uint24 source = registerRead(opcode & 0xff); uint24 target = regs.a; regs.a = source; - regWrite(opcode & 0xff, target); + registerWrite(opcode & 0xff, target); } else if((opcode & 0xffff) == 0xfc00) { diff --git a/higan/processor/hg51b/registers.cpp b/higan/processor/hg51b/registers.cpp index 4038efe5..2a3ae5d5 100644 --- a/higan/processor/hg51b/registers.cpp +++ b/higan/processor/hg51b/registers.cpp @@ -1,4 +1,4 @@ -auto HG51B::regRead(uint8 addr) const -> uint24 { +auto HG51B::registerRead(uint8 addr) const -> uint24 { switch(addr) { case 0x00: return regs.a; case 0x01: return regs.acch; @@ -44,7 +44,7 @@ auto HG51B::regRead(uint8 addr) const -> uint24 { return 0x000000; } -auto HG51B::regWrite(uint8 addr, uint24 data) -> void { +auto HG51B::registerWrite(uint8 addr, uint24 data) -> void { switch(addr) { case 0x00: regs.a = data; return; case 0x01: regs.acch = data; return; diff --git a/higan/processor/lr35902/disassembler.cpp b/higan/processor/lr35902/disassembler.cpp index 8cc962f8..36c77fee 100644 --- a/higan/processor/lr35902/disassembler.cpp +++ b/higan/processor/lr35902/disassembler.cpp @@ -26,262 +26,262 @@ auto LR35902::disassembleOpcode(uint16 pc) -> string { uint8 p2 = debuggerRead(pc + 3); switch(opcode) { - case 0x00: return { "nop" }; - case 0x01: return { "ld bc,$", hex(p1, 2L), hex(p0, 2L) }; - case 0x02: return { "ld (bc),a" }; - case 0x03: return { "inc bc" }; - case 0x04: return { "inc b" }; - case 0x05: return { "dec b" }; - case 0x06: return { "ld b,$", hex(p0, 2L) }; - case 0x07: return { "rlc a" }; - case 0x08: return { "ld ($", hex(p1, 2L), hex(p0, 2L), "),sp" }; - case 0x09: return { "add hl,bc" }; - case 0x0a: return { "ld a,(bc)" }; - case 0x0b: return { "dec bc" }; - case 0x0c: return { "inc c" }; - case 0x0d: return { "dec c" }; - case 0x0e: return { "ld c,$", hex(p0, 2L) }; - case 0x0f: return { "rrc a" }; - case 0x10: return { "stop" }; - case 0x11: return { "ld de,$", hex(p1, 2L), hex(p0, 2L) }; - case 0x12: return { "ld (de),a" }; - case 0x13: return { "inc de" }; - case 0x14: return { "inc d" }; - case 0x15: return { "dec d" }; - case 0x16: return { "ld d,$", hex(p0, 2L) }; - case 0x17: return { "rl a" }; - case 0x18: return { "jr $", hex(r[PC] + 2 + (int8)p0, 4L) }; - case 0x19: return { "add hl,de" }; - case 0x1a: return { "ld a,(de)" }; - case 0x1b: return { "dec de" }; - case 0x1c: return { "inc e" }; - case 0x1d: return { "dec e" }; - case 0x1e: return { "ld e,$", hex(p0, 2L) }; - case 0x1f: return { "rr a" }; - case 0x20: return { "jr nz,$", hex(r[PC] + 2 + (int8)p0, 4L) }; - case 0x21: return { "ld hl,$", hex(p1, 2L), hex(p0, 2L) }; - case 0x22: return { "ldi (hl),a" }; - case 0x23: return { "inc hl" }; - case 0x24: return { "inc h" }; - case 0x25: return { "dec h" }; - case 0x26: return { "ld h,$", hex(p0, 2L) }; - case 0x27: return { "daa" }; - case 0x28: return { "jr z,$", hex(r[PC] + 2 + (int8)p0, 4L) }; - case 0x29: return { "add hl,hl" }; - case 0x2a: return { "ldi a,(hl)" }; - case 0x2b: return { "dec hl" }; - case 0x2c: return { "inc l" }; - case 0x2d: return { "dec l" }; - case 0x2e: return { "ld l,$", hex(p0, 2L) }; - case 0x2f: return { "cpl" }; - case 0x30: return { "jr nc,$", hex(r[PC] + 2 + (int8)p0, 4L) }; - case 0x31: return { "ld sp,$", hex(p1, 2L), hex(p0, 2L) }; - case 0x32: return { "ldd (hl),a" }; - case 0x33: return { "inc sp" }; - case 0x34: return { "inc (hl)" }; - case 0x35: return { "dec (hl)" }; - case 0x36: return { "ld (hl),$", hex(p0, 2L) }; - case 0x37: return { "scf" }; - case 0x38: return { "jr c,$", hex(r[PC] + 2 + (int8)p0, 4L) }; - case 0x39: return { "add hl,sp" }; - case 0x3a: return { "ldd a,(hl)" }; - case 0x3b: return { "dec sp" }; - case 0x3c: return { "inc a" }; - case 0x3d: return { "dec a" }; - case 0x3e: return { "ld a,$", hex(p0, 2L) }; - case 0x3f: return { "ccf" }; - case 0x40: return { "ld b,b" }; - case 0x41: return { "ld b,c" }; - case 0x42: return { "ld b,d" }; - case 0x43: return { "ld b,e" }; - case 0x44: return { "ld b,h" }; - case 0x45: return { "ld b,l" }; - case 0x46: return { "ld b,(hl)" }; - case 0x47: return { "ld b,a" }; - case 0x48: return { "ld c,b" }; - case 0x49: return { "ld c,c" }; - case 0x4a: return { "ld c,d" }; - case 0x4b: return { "ld c,e" }; - case 0x4c: return { "ld c,h" }; - case 0x4d: return { "ld c,l" }; - case 0x4e: return { "ld c,(hl)" }; - case 0x4f: return { "ld c,a" }; - case 0x50: return { "ld d,b" }; - case 0x51: return { "ld d,c" }; - case 0x52: return { "ld d,d" }; - case 0x53: return { "ld d,e" }; - case 0x54: return { "ld d,h" }; - case 0x55: return { "ld d,l" }; - case 0x56: return { "ld d,(hl)" }; - case 0x57: return { "ld d,a" }; - case 0x58: return { "ld e,b" }; - case 0x59: return { "ld e,c" }; - case 0x5a: return { "ld e,d" }; - case 0x5b: return { "ld e,e" }; - case 0x5c: return { "ld e,h" }; - case 0x5d: return { "ld e,l" }; - case 0x5e: return { "ld e,(hl)" }; - case 0x5f: return { "ld e,a" }; - case 0x60: return { "ld h,b" }; - case 0x61: return { "ld h,c" }; - case 0x62: return { "ld h,d" }; - case 0x63: return { "ld h,e" }; - case 0x64: return { "ld h,h" }; - case 0x65: return { "ld h,l" }; - case 0x66: return { "ld h,(hl)" }; - case 0x67: return { "ld h,a" }; - case 0x68: return { "ld l,b" }; - case 0x69: return { "ld l,c" }; - case 0x6a: return { "ld l,d" }; - case 0x6b: return { "ld l,e" }; - case 0x6c: return { "ld l,h" }; - case 0x6d: return { "ld l,l" }; - case 0x6e: return { "ld l,(hl)" }; - case 0x6f: return { "ld l,a" }; - case 0x70: return { "ld (hl),b" }; - case 0x71: return { "ld (hl),c" }; - case 0x72: return { "ld (hl),d" }; - case 0x73: return { "ld (hl),e" }; - case 0x74: return { "ld (hl),h" }; - case 0x75: return { "ld (hl),l" }; - case 0x76: return { "halt" }; - case 0x77: return { "ld (hl),a" }; - case 0x78: return { "ld a,b" }; - case 0x79: return { "ld a,c" }; - case 0x7a: return { "ld a,d" }; - case 0x7b: return { "ld a,e" }; - case 0x7c: return { "ld a,h" }; - case 0x7d: return { "ld a,l" }; - case 0x7e: return { "ld a,(hl)" }; - case 0x7f: return { "ld a,a" }; - case 0x80: return { "add a,b" }; - case 0x81: return { "add a,c" }; - case 0x82: return { "add a,d" }; - case 0x83: return { "add a,e" }; - case 0x84: return { "add a,h" }; - case 0x85: return { "add a,l" }; - case 0x86: return { "add a,(hl)" }; - case 0x87: return { "add a,a" }; - case 0x88: return { "adc a,b" }; - case 0x89: return { "adc a,c" }; - case 0x8a: return { "adc a,d" }; - case 0x8b: return { "adc a,e" }; - case 0x8c: return { "adc a,h" }; - case 0x8d: return { "adc a,l" }; - case 0x8e: return { "adc a,(hl)" }; - case 0x8f: return { "adc a,a" }; - case 0x90: return { "sub a,b" }; - case 0x91: return { "sub a,c" }; - case 0x92: return { "sub a,d" }; - case 0x93: return { "sub a,e" }; - case 0x94: return { "sub a,h" }; - case 0x95: return { "sub a,l" }; - case 0x96: return { "sub a,(hl)" }; - case 0x97: return { "sub a,a" }; - case 0x98: return { "sbc a,b" }; - case 0x99: return { "sbc a,c" }; - case 0x9a: return { "sbc a,d" }; - case 0x9b: return { "sbc a,e" }; - case 0x9c: return { "sbc a,h" }; - case 0x9d: return { "sbc a,l" }; - case 0x9e: return { "sbc a,(hl)" }; - case 0x9f: return { "sbc a,a" }; - case 0xa0: return { "and a,b" }; - case 0xa1: return { "and a,c" }; - case 0xa2: return { "and a,d" }; - case 0xa3: return { "and a,e" }; - case 0xa4: return { "and a,h" }; - case 0xa5: return { "and a,l" }; - case 0xa6: return { "and a,(hl)" }; - case 0xa7: return { "and a,a" }; - case 0xa8: return { "xor a,b" }; - case 0xa9: return { "xor a,c" }; - case 0xaa: return { "xor a,d" }; - case 0xab: return { "xor a,e" }; - case 0xac: return { "xor a,h" }; - case 0xad: return { "xor a,l" }; - case 0xae: return { "xor a,(hl)" }; - case 0xaf: return { "xor a,a" }; - case 0xb0: return { "or a,b" }; - case 0xb1: return { "or a,c" }; - case 0xb2: return { "or a,d" }; - case 0xb3: return { "or a,e" }; - case 0xb4: return { "or a,h" }; - case 0xb5: return { "or a,l" }; - case 0xb6: return { "or a,(hl)" }; - case 0xb7: return { "or a,a" }; - case 0xb8: return { "cp a,b" }; - case 0xb9: return { "cp a,c" }; - case 0xba: return { "cp a,d" }; - case 0xbb: return { "cp a,e" }; - case 0xbc: return { "cp a,h" }; - case 0xbd: return { "cp a,l" }; - case 0xbe: return { "cp a,(hl)" }; - case 0xbf: return { "cp a,a" }; - case 0xc0: return { "ret nz" }; - case 0xc1: return { "pop bc" }; - case 0xc2: return { "jp nz,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xc3: return { "jp $", hex(p1, 2L), hex(p0, 2L) }; - case 0xc4: return { "call nz,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xc5: return { "push bc" }; - case 0xc6: return { "add a,$", hex(p0, 2L) }; - case 0xc7: return { "rst $0000" }; - case 0xc8: return { "ret z" }; - case 0xc9: return { "ret" }; - case 0xca: return { "jp z,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xcb: return disassembleOpcodeCB(pc + 1); - case 0xcc: return { "call z,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xcd: return { "call $", hex(p1, 2L), hex(p0, 2L) }; - case 0xce: return { "adc a,$", hex(p0, 2L) }; - case 0xcf: return { "rst $0008" }; - case 0xd0: return { "ret nc" }; - case 0xd1: return { "pop de" }; - case 0xd2: return { "jp nc,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xd3: return { "xx" }; - case 0xd4: return { "call nc,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xd5: return { "push de" }; - case 0xd6: return { "sub a,$", hex(p0, 2L) }; - case 0xd7: return { "rst $0010" }; - case 0xd8: return { "ret c" }; - case 0xd9: return { "reti" }; - case 0xda: return { "jp c,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xdb: return { "xx" }; - case 0xdc: return { "call c,$", hex(p1, 2L), hex(p0, 2L) }; - case 0xdd: return { "xx" }; - case 0xde: return { "sbc a,$", hex(p0, 2L) }; - case 0xdf: return { "rst $0018" }; - case 0xe0: return { "ld ($ff", hex(p0, 2L), "),a" }; - case 0xe1: return { "pop hl" }; - case 0xe2: return { "ld ($ff00+c),a" }; - case 0xe3: return { "xx" }; - case 0xe4: return { "xx" }; - case 0xe5: return { "push hl" }; - case 0xe6: return { "and a,$", hex(p0, 2L) }; - case 0xe7: return { "rst $0020" }; - case 0xe8: return { "add sp,$", hex((int8)p0, 4L) }; - case 0xe9: return { "jp hl" }; - case 0xea: return { "ld ($", hex(p1, 2L), hex(p0, 2L), "),a" }; - case 0xeb: return { "xx" }; - case 0xec: return { "xx" }; - case 0xed: return { "xx" }; - case 0xee: return { "xor a,$", hex(p0, 2L) }; - case 0xef: return { "rst $0028" }; - case 0xf0: return { "ld a,($ff", hex(p0, 2L), ")" }; - case 0xf1: return { "pop af" }; - case 0xf2: return { "ld a,($ff00+c)" }; - case 0xf3: return { "di" }; - case 0xf4: return { "xx" }; - case 0xf5: return { "push af" }; - case 0xf6: return { "or a,$", hex(p0, 2L) }; - case 0xf7: return { "rst $0030" }; - case 0xf8: return { "ld hl,sp+$", hex((int8)p0, 4L) }; - case 0xf9: return { "ld sp,hl" }; - case 0xfa: return { "ld a,($", hex(p1, 2L), hex(p0, 2L), ")" }; - case 0xfb: return { "ei" }; - case 0xfc: return { "xx" }; - case 0xfd: return { "xx" }; - case 0xfe: return { "cp a,$", hex(p0, 2L) }; - case 0xff: return { "rst $0038" }; + case 0x00: return { "nop" }; + case 0x01: return { "ld bc,$", hex(p1, 2L), hex(p0, 2L) }; + case 0x02: return { "ld (bc),a" }; + case 0x03: return { "inc bc" }; + case 0x04: return { "inc b" }; + case 0x05: return { "dec b" }; + case 0x06: return { "ld b,$", hex(p0, 2L) }; + case 0x07: return { "rlc a" }; + case 0x08: return { "ld ($", hex(p1, 2L), hex(p0, 2L), "),sp" }; + case 0x09: return { "add hl,bc" }; + case 0x0a: return { "ld a,(bc)" }; + case 0x0b: return { "dec bc" }; + case 0x0c: return { "inc c" }; + case 0x0d: return { "dec c" }; + case 0x0e: return { "ld c,$", hex(p0, 2L) }; + case 0x0f: return { "rrc a" }; + case 0x10: return { "stop" }; + case 0x11: return { "ld de,$", hex(p1, 2L), hex(p0, 2L) }; + case 0x12: return { "ld (de),a" }; + case 0x13: return { "inc de" }; + case 0x14: return { "inc d" }; + case 0x15: return { "dec d" }; + case 0x16: return { "ld d,$", hex(p0, 2L) }; + case 0x17: return { "rl a" }; + case 0x18: return { "jr $", hex(r[PC] + 2 + (int8)p0, 4L) }; + case 0x19: return { "add hl,de" }; + case 0x1a: return { "ld a,(de)" }; + case 0x1b: return { "dec de" }; + case 0x1c: return { "inc e" }; + case 0x1d: return { "dec e" }; + case 0x1e: return { "ld e,$", hex(p0, 2L) }; + case 0x1f: return { "rr a" }; + case 0x20: return { "jr nz,$", hex(r[PC] + 2 + (int8)p0, 4L) }; + case 0x21: return { "ld hl,$", hex(p1, 2L), hex(p0, 2L) }; + case 0x22: return { "ldi (hl),a" }; + case 0x23: return { "inc hl" }; + case 0x24: return { "inc h" }; + case 0x25: return { "dec h" }; + case 0x26: return { "ld h,$", hex(p0, 2L) }; + case 0x27: return { "daa" }; + case 0x28: return { "jr z,$", hex(r[PC] + 2 + (int8)p0, 4L) }; + case 0x29: return { "add hl,hl" }; + case 0x2a: return { "ldi a,(hl)" }; + case 0x2b: return { "dec hl" }; + case 0x2c: return { "inc l" }; + case 0x2d: return { "dec l" }; + case 0x2e: return { "ld l,$", hex(p0, 2L) }; + case 0x2f: return { "cpl" }; + case 0x30: return { "jr nc,$", hex(r[PC] + 2 + (int8)p0, 4L) }; + case 0x31: return { "ld sp,$", hex(p1, 2L), hex(p0, 2L) }; + case 0x32: return { "ldd (hl),a" }; + case 0x33: return { "inc sp" }; + case 0x34: return { "inc (hl)" }; + case 0x35: return { "dec (hl)" }; + case 0x36: return { "ld (hl),$", hex(p0, 2L) }; + case 0x37: return { "scf" }; + case 0x38: return { "jr c,$", hex(r[PC] + 2 + (int8)p0, 4L) }; + case 0x39: return { "add hl,sp" }; + case 0x3a: return { "ldd a,(hl)" }; + case 0x3b: return { "dec sp" }; + case 0x3c: return { "inc a" }; + case 0x3d: return { "dec a" }; + case 0x3e: return { "ld a,$", hex(p0, 2L) }; + case 0x3f: return { "ccf" }; + case 0x40: return { "ld b,b" }; + case 0x41: return { "ld b,c" }; + case 0x42: return { "ld b,d" }; + case 0x43: return { "ld b,e" }; + case 0x44: return { "ld b,h" }; + case 0x45: return { "ld b,l" }; + case 0x46: return { "ld b,(hl)" }; + case 0x47: return { "ld b,a" }; + case 0x48: return { "ld c,b" }; + case 0x49: return { "ld c,c" }; + case 0x4a: return { "ld c,d" }; + case 0x4b: return { "ld c,e" }; + case 0x4c: return { "ld c,h" }; + case 0x4d: return { "ld c,l" }; + case 0x4e: return { "ld c,(hl)" }; + case 0x4f: return { "ld c,a" }; + case 0x50: return { "ld d,b" }; + case 0x51: return { "ld d,c" }; + case 0x52: return { "ld d,d" }; + case 0x53: return { "ld d,e" }; + case 0x54: return { "ld d,h" }; + case 0x55: return { "ld d,l" }; + case 0x56: return { "ld d,(hl)" }; + case 0x57: return { "ld d,a" }; + case 0x58: return { "ld e,b" }; + case 0x59: return { "ld e,c" }; + case 0x5a: return { "ld e,d" }; + case 0x5b: return { "ld e,e" }; + case 0x5c: return { "ld e,h" }; + case 0x5d: return { "ld e,l" }; + case 0x5e: return { "ld e,(hl)" }; + case 0x5f: return { "ld e,a" }; + case 0x60: return { "ld h,b" }; + case 0x61: return { "ld h,c" }; + case 0x62: return { "ld h,d" }; + case 0x63: return { "ld h,e" }; + case 0x64: return { "ld h,h" }; + case 0x65: return { "ld h,l" }; + case 0x66: return { "ld h,(hl)" }; + case 0x67: return { "ld h,a" }; + case 0x68: return { "ld l,b" }; + case 0x69: return { "ld l,c" }; + case 0x6a: return { "ld l,d" }; + case 0x6b: return { "ld l,e" }; + case 0x6c: return { "ld l,h" }; + case 0x6d: return { "ld l,l" }; + case 0x6e: return { "ld l,(hl)" }; + case 0x6f: return { "ld l,a" }; + case 0x70: return { "ld (hl),b" }; + case 0x71: return { "ld (hl),c" }; + case 0x72: return { "ld (hl),d" }; + case 0x73: return { "ld (hl),e" }; + case 0x74: return { "ld (hl),h" }; + case 0x75: return { "ld (hl),l" }; + case 0x76: return { "halt" }; + case 0x77: return { "ld (hl),a" }; + case 0x78: return { "ld a,b" }; + case 0x79: return { "ld a,c" }; + case 0x7a: return { "ld a,d" }; + case 0x7b: return { "ld a,e" }; + case 0x7c: return { "ld a,h" }; + case 0x7d: return { "ld a,l" }; + case 0x7e: return { "ld a,(hl)" }; + case 0x7f: return { "ld a,a" }; + case 0x80: return { "add a,b" }; + case 0x81: return { "add a,c" }; + case 0x82: return { "add a,d" }; + case 0x83: return { "add a,e" }; + case 0x84: return { "add a,h" }; + case 0x85: return { "add a,l" }; + case 0x86: return { "add a,(hl)" }; + case 0x87: return { "add a,a" }; + case 0x88: return { "adc a,b" }; + case 0x89: return { "adc a,c" }; + case 0x8a: return { "adc a,d" }; + case 0x8b: return { "adc a,e" }; + case 0x8c: return { "adc a,h" }; + case 0x8d: return { "adc a,l" }; + case 0x8e: return { "adc a,(hl)" }; + case 0x8f: return { "adc a,a" }; + case 0x90: return { "sub a,b" }; + case 0x91: return { "sub a,c" }; + case 0x92: return { "sub a,d" }; + case 0x93: return { "sub a,e" }; + case 0x94: return { "sub a,h" }; + case 0x95: return { "sub a,l" }; + case 0x96: return { "sub a,(hl)" }; + case 0x97: return { "sub a,a" }; + case 0x98: return { "sbc a,b" }; + case 0x99: return { "sbc a,c" }; + case 0x9a: return { "sbc a,d" }; + case 0x9b: return { "sbc a,e" }; + case 0x9c: return { "sbc a,h" }; + case 0x9d: return { "sbc a,l" }; + case 0x9e: return { "sbc a,(hl)" }; + case 0x9f: return { "sbc a,a" }; + case 0xa0: return { "and a,b" }; + case 0xa1: return { "and a,c" }; + case 0xa2: return { "and a,d" }; + case 0xa3: return { "and a,e" }; + case 0xa4: return { "and a,h" }; + case 0xa5: return { "and a,l" }; + case 0xa6: return { "and a,(hl)" }; + case 0xa7: return { "and a,a" }; + case 0xa8: return { "xor a,b" }; + case 0xa9: return { "xor a,c" }; + case 0xaa: return { "xor a,d" }; + case 0xab: return { "xor a,e" }; + case 0xac: return { "xor a,h" }; + case 0xad: return { "xor a,l" }; + case 0xae: return { "xor a,(hl)" }; + case 0xaf: return { "xor a,a" }; + case 0xb0: return { "or a,b" }; + case 0xb1: return { "or a,c" }; + case 0xb2: return { "or a,d" }; + case 0xb3: return { "or a,e" }; + case 0xb4: return { "or a,h" }; + case 0xb5: return { "or a,l" }; + case 0xb6: return { "or a,(hl)" }; + case 0xb7: return { "or a,a" }; + case 0xb8: return { "cp a,b" }; + case 0xb9: return { "cp a,c" }; + case 0xba: return { "cp a,d" }; + case 0xbb: return { "cp a,e" }; + case 0xbc: return { "cp a,h" }; + case 0xbd: return { "cp a,l" }; + case 0xbe: return { "cp a,(hl)" }; + case 0xbf: return { "cp a,a" }; + case 0xc0: return { "ret nz" }; + case 0xc1: return { "pop bc" }; + case 0xc2: return { "jp nz,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xc3: return { "jp $", hex(p1, 2L), hex(p0, 2L) }; + case 0xc4: return { "call nz,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xc5: return { "push bc" }; + case 0xc6: return { "add a,$", hex(p0, 2L) }; + case 0xc7: return { "rst $0000" }; + case 0xc8: return { "ret z" }; + case 0xc9: return { "ret" }; + case 0xca: return { "jp z,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xcb: return disassembleOpcodeCB(pc + 1); + case 0xcc: return { "call z,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xcd: return { "call $", hex(p1, 2L), hex(p0, 2L) }; + case 0xce: return { "adc a,$", hex(p0, 2L) }; + case 0xcf: return { "rst $0008" }; + case 0xd0: return { "ret nc" }; + case 0xd1: return { "pop de" }; + case 0xd2: return { "jp nc,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xd3: return { "xx" }; + case 0xd4: return { "call nc,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xd5: return { "push de" }; + case 0xd6: return { "sub a,$", hex(p0, 2L) }; + case 0xd7: return { "rst $0010" }; + case 0xd8: return { "ret c" }; + case 0xd9: return { "reti" }; + case 0xda: return { "jp c,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xdb: return { "xx" }; + case 0xdc: return { "call c,$", hex(p1, 2L), hex(p0, 2L) }; + case 0xdd: return { "xx" }; + case 0xde: return { "sbc a,$", hex(p0, 2L) }; + case 0xdf: return { "rst $0018" }; + case 0xe0: return { "ld ($ff", hex(p0, 2L), "),a" }; + case 0xe1: return { "pop hl" }; + case 0xe2: return { "ld ($ff00+c),a" }; + case 0xe3: return { "xx" }; + case 0xe4: return { "xx" }; + case 0xe5: return { "push hl" }; + case 0xe6: return { "and a,$", hex(p0, 2L) }; + case 0xe7: return { "rst $0020" }; + case 0xe8: return { "add sp,$", hex((int8)p0, 4L) }; + case 0xe9: return { "jp hl" }; + case 0xea: return { "ld ($", hex(p1, 2L), hex(p0, 2L), "),a" }; + case 0xeb: return { "xx" }; + case 0xec: return { "xx" }; + case 0xed: return { "xx" }; + case 0xee: return { "xor a,$", hex(p0, 2L) }; + case 0xef: return { "rst $0028" }; + case 0xf0: return { "ld a,($ff", hex(p0, 2L), ")" }; + case 0xf1: return { "pop af" }; + case 0xf2: return { "ld a,($ff00+c)" }; + case 0xf3: return { "di" }; + case 0xf4: return { "xx" }; + case 0xf5: return { "push af" }; + case 0xf6: return { "or a,$", hex(p0, 2L) }; + case 0xf7: return { "rst $0030" }; + case 0xf8: return { "ld hl,sp+$", hex((int8)p0, 4L) }; + case 0xf9: return { "ld sp,hl" }; + case 0xfa: return { "ld a,($", hex(p1, 2L), hex(p0, 2L), ")" }; + case 0xfb: return { "ei" }; + case 0xfc: return { "xx" }; + case 0xfd: return { "xx" }; + case 0xfe: return { "cp a,$", hex(p0, 2L) }; + case 0xff: return { "rst $0038" }; } return ""; @@ -294,262 +294,262 @@ auto LR35902::disassembleOpcodeCB(uint16 pc) -> string { uint8 p2 = debuggerRead(pc + 3); switch(opcode) { - case 0x00: return { "rlc b" }; - case 0x01: return { "rlc c" }; - case 0x02: return { "rlc d" }; - case 0x03: return { "rlc e" }; - case 0x04: return { "rlc h" }; - case 0x05: return { "rlc l" }; - case 0x06: return { "rlc (hl)" }; - case 0x07: return { "rlc a" }; - case 0x08: return { "rrc b" }; - case 0x09: return { "rrc c" }; - case 0x0a: return { "rrc d" }; - case 0x0b: return { "rrc e" }; - case 0x0c: return { "rrc h" }; - case 0x0d: return { "rrc l" }; - case 0x0e: return { "rrc (hl)" }; - case 0x0f: return { "rrc a" }; - case 0x10: return { "rl b" }; - case 0x11: return { "rl c" }; - case 0x12: return { "rl d" }; - case 0x13: return { "rl e" }; - case 0x14: return { "rl h" }; - case 0x15: return { "rl l" }; - case 0x16: return { "rl (hl)" }; - case 0x17: return { "rl a" }; - case 0x18: return { "rr b" }; - case 0x19: return { "rr c" }; - case 0x1a: return { "rr d" }; - case 0x1b: return { "rr e" }; - case 0x1c: return { "rr h" }; - case 0x1d: return { "rr l" }; - case 0x1e: return { "rr (hl)" }; - case 0x1f: return { "rr a" }; - case 0x20: return { "sla b" }; - case 0x21: return { "sla c" }; - case 0x22: return { "sla d" }; - case 0x23: return { "sla e" }; - case 0x24: return { "sla h" }; - case 0x25: return { "sla l" }; - case 0x26: return { "sla (hl)" }; - case 0x27: return { "sla a" }; - case 0x28: return { "sra b" }; - case 0x29: return { "sra c" }; - case 0x2a: return { "sra d" }; - case 0x2b: return { "sra e" }; - case 0x2c: return { "sra h" }; - case 0x2d: return { "sra l" }; - case 0x2e: return { "sra (hl)" }; - case 0x2f: return { "sra a" }; - case 0x30: return { "swap b" }; - case 0x31: return { "swap c" }; - case 0x32: return { "swap d" }; - case 0x33: return { "swap e" }; - case 0x34: return { "swap h" }; - case 0x35: return { "swap l" }; - case 0x36: return { "swap (hl)" }; - case 0x37: return { "swap a" }; - case 0x38: return { "srl b" }; - case 0x39: return { "srl c" }; - case 0x3a: return { "srl d" }; - case 0x3b: return { "srl e" }; - case 0x3c: return { "srl h" }; - case 0x3d: return { "srl l" }; - case 0x3e: return { "srl (hl)" }; - case 0x3f: return { "srl a" }; - case 0x40: return { "bit 0,b" }; - case 0x41: return { "bit 0,c" }; - case 0x42: return { "bit 0,d" }; - case 0x43: return { "bit 0,e" }; - case 0x44: return { "bit 0,h" }; - case 0x45: return { "bit 0,l" }; - case 0x46: return { "bit 0,(hl)" }; - case 0x47: return { "bit 0,a" }; - case 0x48: return { "bit 1,b" }; - case 0x49: return { "bit 1,c" }; - case 0x4a: return { "bit 1,d" }; - case 0x4b: return { "bit 1,e" }; - case 0x4c: return { "bit 1,h" }; - case 0x4d: return { "bit 1,l" }; - case 0x4e: return { "bit 1,(hl)" }; - case 0x4f: return { "bit 1,a" }; - case 0x50: return { "bit 2,b" }; - case 0x51: return { "bit 2,c" }; - case 0x52: return { "bit 2,d" }; - case 0x53: return { "bit 2,e" }; - case 0x54: return { "bit 2,h" }; - case 0x55: return { "bit 2,l" }; - case 0x56: return { "bit 2,(hl)" }; - case 0x57: return { "bit 2,a" }; - case 0x58: return { "bit 3,b" }; - case 0x59: return { "bit 3,c" }; - case 0x5a: return { "bit 3,d" }; - case 0x5b: return { "bit 3,e" }; - case 0x5c: return { "bit 3,h" }; - case 0x5d: return { "bit 3,l" }; - case 0x5e: return { "bit 3,(hl)" }; - case 0x5f: return { "bit 3,a" }; - case 0x60: return { "bit 4,b" }; - case 0x61: return { "bit 4,c" }; - case 0x62: return { "bit 4,d" }; - case 0x63: return { "bit 4,e" }; - case 0x64: return { "bit 4,h" }; - case 0x65: return { "bit 4,l" }; - case 0x66: return { "bit 4,(hl)" }; - case 0x67: return { "bit 4,a" }; - case 0x68: return { "bit 5,b" }; - case 0x69: return { "bit 5,c" }; - case 0x6a: return { "bit 5,d" }; - case 0x6b: return { "bit 5,e" }; - case 0x6c: return { "bit 5,h" }; - case 0x6d: return { "bit 5,l" }; - case 0x6e: return { "bit 5,(hl)" }; - case 0x6f: return { "bit 5,a" }; - case 0x70: return { "bit 6,b" }; - case 0x71: return { "bit 6,c" }; - case 0x72: return { "bit 6,d" }; - case 0x73: return { "bit 6,e" }; - case 0x74: return { "bit 6,h" }; - case 0x75: return { "bit 6,l" }; - case 0x76: return { "bit 6,(hl)" }; - case 0x77: return { "bit 6,a" }; - case 0x78: return { "bit 7,b" }; - case 0x79: return { "bit 7,c" }; - case 0x7a: return { "bit 7,d" }; - case 0x7b: return { "bit 7,e" }; - case 0x7c: return { "bit 7,h" }; - case 0x7d: return { "bit 7,l" }; - case 0x7e: return { "bit 7,(hl)" }; - case 0x7f: return { "bit 7,a" }; - case 0x80: return { "res 0,b" }; - case 0x81: return { "res 0,c" }; - case 0x82: return { "res 0,d" }; - case 0x83: return { "res 0,e" }; - case 0x84: return { "res 0,h" }; - case 0x85: return { "res 0,l" }; - case 0x86: return { "res 0,(hl)" }; - case 0x87: return { "res 0,a" }; - case 0x88: return { "res 1,b" }; - case 0x89: return { "res 1,c" }; - case 0x8a: return { "res 1,d" }; - case 0x8b: return { "res 1,e" }; - case 0x8c: return { "res 1,h" }; - case 0x8d: return { "res 1,l" }; - case 0x8e: return { "res 1,(hl)" }; - case 0x8f: return { "res 1,a" }; - case 0x90: return { "res 2,b" }; - case 0x91: return { "res 2,c" }; - case 0x92: return { "res 2,d" }; - case 0x93: return { "res 2,e" }; - case 0x94: return { "res 2,h" }; - case 0x95: return { "res 2,l" }; - case 0x96: return { "res 2,(hl)" }; - case 0x97: return { "res 2,a" }; - case 0x98: return { "res 3,b" }; - case 0x99: return { "res 3,c" }; - case 0x9a: return { "res 3,d" }; - case 0x9b: return { "res 3,e" }; - case 0x9c: return { "res 3,h" }; - case 0x9d: return { "res 3,l" }; - case 0x9e: return { "res 3,(hl)" }; - case 0x9f: return { "res 3,a" }; - case 0xa0: return { "res 4,b" }; - case 0xa1: return { "res 4,c" }; - case 0xa2: return { "res 4,d" }; - case 0xa3: return { "res 4,e" }; - case 0xa4: return { "res 4,h" }; - case 0xa5: return { "res 4,l" }; - case 0xa6: return { "res 4,(hl)" }; - case 0xa7: return { "res 4,a" }; - case 0xa8: return { "res 5,b" }; - case 0xa9: return { "res 5,c" }; - case 0xaa: return { "res 5,d" }; - case 0xab: return { "res 5,e" }; - case 0xac: return { "res 5,h" }; - case 0xad: return { "res 5,l" }; - case 0xae: return { "res 5,(hl)" }; - case 0xaf: return { "res 5,a" }; - case 0xb0: return { "res 6,b" }; - case 0xb1: return { "res 6,c" }; - case 0xb2: return { "res 6,d" }; - case 0xb3: return { "res 6,e" }; - case 0xb4: return { "res 6,h" }; - case 0xb5: return { "res 6,l" }; - case 0xb6: return { "res 6,(hl)" }; - case 0xb7: return { "res 6,a" }; - case 0xb8: return { "res 7,b" }; - case 0xb9: return { "res 7,c" }; - case 0xba: return { "res 7,d" }; - case 0xbb: return { "res 7,e" }; - case 0xbc: return { "res 7,h" }; - case 0xbd: return { "res 7,l" }; - case 0xbe: return { "res 7,(hl)" }; - case 0xbf: return { "res 7,a" }; - case 0xc0: return { "set 0,b" }; - case 0xc1: return { "set 0,c" }; - case 0xc2: return { "set 0,d" }; - case 0xc3: return { "set 0,e" }; - case 0xc4: return { "set 0,h" }; - case 0xc5: return { "set 0,l" }; - case 0xc6: return { "set 0,(hl)" }; - case 0xc7: return { "set 0,a" }; - case 0xc8: return { "set 1,b" }; - case 0xc9: return { "set 1,c" }; - case 0xca: return { "set 1,d" }; - case 0xcb: return { "set 1,e" }; - case 0xcc: return { "set 1,h" }; - case 0xcd: return { "set 1,l" }; - case 0xce: return { "set 1,(hl)" }; - case 0xcf: return { "set 1,a" }; - case 0xd0: return { "set 2,b" }; - case 0xd1: return { "set 2,c" }; - case 0xd2: return { "set 2,d" }; - case 0xd3: return { "set 2,e" }; - case 0xd4: return { "set 2,h" }; - case 0xd5: return { "set 2,l" }; - case 0xd6: return { "set 2,(hl)" }; - case 0xd7: return { "set 2,a" }; - case 0xd8: return { "set 3,b" }; - case 0xd9: return { "set 3,c" }; - case 0xda: return { "set 3,d" }; - case 0xdb: return { "set 3,e" }; - case 0xdc: return { "set 3,h" }; - case 0xdd: return { "set 3,l" }; - case 0xde: return { "set 3,(hl)" }; - case 0xdf: return { "set 3,a" }; - case 0xe0: return { "set 4,b" }; - case 0xe1: return { "set 4,c" }; - case 0xe2: return { "set 4,d" }; - case 0xe3: return { "set 4,e" }; - case 0xe4: return { "set 4,h" }; - case 0xe5: return { "set 4,l" }; - case 0xe6: return { "set 4,(hl)" }; - case 0xe7: return { "set 4,a" }; - case 0xe8: return { "set 5,b" }; - case 0xe9: return { "set 5,c" }; - case 0xea: return { "set 5,d" }; - case 0xeb: return { "set 5,e" }; - case 0xec: return { "set 5,h" }; - case 0xed: return { "set 5,l" }; - case 0xee: return { "set 5,(hl)" }; - case 0xef: return { "set 5,a" }; - case 0xf0: return { "set 6,b" }; - case 0xf1: return { "set 6,c" }; - case 0xf2: return { "set 6,d" }; - case 0xf3: return { "set 6,e" }; - case 0xf4: return { "set 6,h" }; - case 0xf5: return { "set 6,l" }; - case 0xf6: return { "set 6,(hl)" }; - case 0xf7: return { "set 6,a" }; - case 0xf8: return { "set 7,b" }; - case 0xf9: return { "set 7,c" }; - case 0xfa: return { "set 7,d" }; - case 0xfb: return { "set 7,e" }; - case 0xfc: return { "set 7,h" }; - case 0xfd: return { "set 7,l" }; - case 0xfe: return { "set 7,(hl)" }; - case 0xff: return { "set 7,a" }; + case 0x00: return { "rlc b" }; + case 0x01: return { "rlc c" }; + case 0x02: return { "rlc d" }; + case 0x03: return { "rlc e" }; + case 0x04: return { "rlc h" }; + case 0x05: return { "rlc l" }; + case 0x06: return { "rlc (hl)" }; + case 0x07: return { "rlc a" }; + case 0x08: return { "rrc b" }; + case 0x09: return { "rrc c" }; + case 0x0a: return { "rrc d" }; + case 0x0b: return { "rrc e" }; + case 0x0c: return { "rrc h" }; + case 0x0d: return { "rrc l" }; + case 0x0e: return { "rrc (hl)" }; + case 0x0f: return { "rrc a" }; + case 0x10: return { "rl b" }; + case 0x11: return { "rl c" }; + case 0x12: return { "rl d" }; + case 0x13: return { "rl e" }; + case 0x14: return { "rl h" }; + case 0x15: return { "rl l" }; + case 0x16: return { "rl (hl)" }; + case 0x17: return { "rl a" }; + case 0x18: return { "rr b" }; + case 0x19: return { "rr c" }; + case 0x1a: return { "rr d" }; + case 0x1b: return { "rr e" }; + case 0x1c: return { "rr h" }; + case 0x1d: return { "rr l" }; + case 0x1e: return { "rr (hl)" }; + case 0x1f: return { "rr a" }; + case 0x20: return { "sla b" }; + case 0x21: return { "sla c" }; + case 0x22: return { "sla d" }; + case 0x23: return { "sla e" }; + case 0x24: return { "sla h" }; + case 0x25: return { "sla l" }; + case 0x26: return { "sla (hl)" }; + case 0x27: return { "sla a" }; + case 0x28: return { "sra b" }; + case 0x29: return { "sra c" }; + case 0x2a: return { "sra d" }; + case 0x2b: return { "sra e" }; + case 0x2c: return { "sra h" }; + case 0x2d: return { "sra l" }; + case 0x2e: return { "sra (hl)" }; + case 0x2f: return { "sra a" }; + case 0x30: return { "swap b" }; + case 0x31: return { "swap c" }; + case 0x32: return { "swap d" }; + case 0x33: return { "swap e" }; + case 0x34: return { "swap h" }; + case 0x35: return { "swap l" }; + case 0x36: return { "swap (hl)" }; + case 0x37: return { "swap a" }; + case 0x38: return { "srl b" }; + case 0x39: return { "srl c" }; + case 0x3a: return { "srl d" }; + case 0x3b: return { "srl e" }; + case 0x3c: return { "srl h" }; + case 0x3d: return { "srl l" }; + case 0x3e: return { "srl (hl)" }; + case 0x3f: return { "srl a" }; + case 0x40: return { "bit 0,b" }; + case 0x41: return { "bit 0,c" }; + case 0x42: return { "bit 0,d" }; + case 0x43: return { "bit 0,e" }; + case 0x44: return { "bit 0,h" }; + case 0x45: return { "bit 0,l" }; + case 0x46: return { "bit 0,(hl)" }; + case 0x47: return { "bit 0,a" }; + case 0x48: return { "bit 1,b" }; + case 0x49: return { "bit 1,c" }; + case 0x4a: return { "bit 1,d" }; + case 0x4b: return { "bit 1,e" }; + case 0x4c: return { "bit 1,h" }; + case 0x4d: return { "bit 1,l" }; + case 0x4e: return { "bit 1,(hl)" }; + case 0x4f: return { "bit 1,a" }; + case 0x50: return { "bit 2,b" }; + case 0x51: return { "bit 2,c" }; + case 0x52: return { "bit 2,d" }; + case 0x53: return { "bit 2,e" }; + case 0x54: return { "bit 2,h" }; + case 0x55: return { "bit 2,l" }; + case 0x56: return { "bit 2,(hl)" }; + case 0x57: return { "bit 2,a" }; + case 0x58: return { "bit 3,b" }; + case 0x59: return { "bit 3,c" }; + case 0x5a: return { "bit 3,d" }; + case 0x5b: return { "bit 3,e" }; + case 0x5c: return { "bit 3,h" }; + case 0x5d: return { "bit 3,l" }; + case 0x5e: return { "bit 3,(hl)" }; + case 0x5f: return { "bit 3,a" }; + case 0x60: return { "bit 4,b" }; + case 0x61: return { "bit 4,c" }; + case 0x62: return { "bit 4,d" }; + case 0x63: return { "bit 4,e" }; + case 0x64: return { "bit 4,h" }; + case 0x65: return { "bit 4,l" }; + case 0x66: return { "bit 4,(hl)" }; + case 0x67: return { "bit 4,a" }; + case 0x68: return { "bit 5,b" }; + case 0x69: return { "bit 5,c" }; + case 0x6a: return { "bit 5,d" }; + case 0x6b: return { "bit 5,e" }; + case 0x6c: return { "bit 5,h" }; + case 0x6d: return { "bit 5,l" }; + case 0x6e: return { "bit 5,(hl)" }; + case 0x6f: return { "bit 5,a" }; + case 0x70: return { "bit 6,b" }; + case 0x71: return { "bit 6,c" }; + case 0x72: return { "bit 6,d" }; + case 0x73: return { "bit 6,e" }; + case 0x74: return { "bit 6,h" }; + case 0x75: return { "bit 6,l" }; + case 0x76: return { "bit 6,(hl)" }; + case 0x77: return { "bit 6,a" }; + case 0x78: return { "bit 7,b" }; + case 0x79: return { "bit 7,c" }; + case 0x7a: return { "bit 7,d" }; + case 0x7b: return { "bit 7,e" }; + case 0x7c: return { "bit 7,h" }; + case 0x7d: return { "bit 7,l" }; + case 0x7e: return { "bit 7,(hl)" }; + case 0x7f: return { "bit 7,a" }; + case 0x80: return { "res 0,b" }; + case 0x81: return { "res 0,c" }; + case 0x82: return { "res 0,d" }; + case 0x83: return { "res 0,e" }; + case 0x84: return { "res 0,h" }; + case 0x85: return { "res 0,l" }; + case 0x86: return { "res 0,(hl)" }; + case 0x87: return { "res 0,a" }; + case 0x88: return { "res 1,b" }; + case 0x89: return { "res 1,c" }; + case 0x8a: return { "res 1,d" }; + case 0x8b: return { "res 1,e" }; + case 0x8c: return { "res 1,h" }; + case 0x8d: return { "res 1,l" }; + case 0x8e: return { "res 1,(hl)" }; + case 0x8f: return { "res 1,a" }; + case 0x90: return { "res 2,b" }; + case 0x91: return { "res 2,c" }; + case 0x92: return { "res 2,d" }; + case 0x93: return { "res 2,e" }; + case 0x94: return { "res 2,h" }; + case 0x95: return { "res 2,l" }; + case 0x96: return { "res 2,(hl)" }; + case 0x97: return { "res 2,a" }; + case 0x98: return { "res 3,b" }; + case 0x99: return { "res 3,c" }; + case 0x9a: return { "res 3,d" }; + case 0x9b: return { "res 3,e" }; + case 0x9c: return { "res 3,h" }; + case 0x9d: return { "res 3,l" }; + case 0x9e: return { "res 3,(hl)" }; + case 0x9f: return { "res 3,a" }; + case 0xa0: return { "res 4,b" }; + case 0xa1: return { "res 4,c" }; + case 0xa2: return { "res 4,d" }; + case 0xa3: return { "res 4,e" }; + case 0xa4: return { "res 4,h" }; + case 0xa5: return { "res 4,l" }; + case 0xa6: return { "res 4,(hl)" }; + case 0xa7: return { "res 4,a" }; + case 0xa8: return { "res 5,b" }; + case 0xa9: return { "res 5,c" }; + case 0xaa: return { "res 5,d" }; + case 0xab: return { "res 5,e" }; + case 0xac: return { "res 5,h" }; + case 0xad: return { "res 5,l" }; + case 0xae: return { "res 5,(hl)" }; + case 0xaf: return { "res 5,a" }; + case 0xb0: return { "res 6,b" }; + case 0xb1: return { "res 6,c" }; + case 0xb2: return { "res 6,d" }; + case 0xb3: return { "res 6,e" }; + case 0xb4: return { "res 6,h" }; + case 0xb5: return { "res 6,l" }; + case 0xb6: return { "res 6,(hl)" }; + case 0xb7: return { "res 6,a" }; + case 0xb8: return { "res 7,b" }; + case 0xb9: return { "res 7,c" }; + case 0xba: return { "res 7,d" }; + case 0xbb: return { "res 7,e" }; + case 0xbc: return { "res 7,h" }; + case 0xbd: return { "res 7,l" }; + case 0xbe: return { "res 7,(hl)" }; + case 0xbf: return { "res 7,a" }; + case 0xc0: return { "set 0,b" }; + case 0xc1: return { "set 0,c" }; + case 0xc2: return { "set 0,d" }; + case 0xc3: return { "set 0,e" }; + case 0xc4: return { "set 0,h" }; + case 0xc5: return { "set 0,l" }; + case 0xc6: return { "set 0,(hl)" }; + case 0xc7: return { "set 0,a" }; + case 0xc8: return { "set 1,b" }; + case 0xc9: return { "set 1,c" }; + case 0xca: return { "set 1,d" }; + case 0xcb: return { "set 1,e" }; + case 0xcc: return { "set 1,h" }; + case 0xcd: return { "set 1,l" }; + case 0xce: return { "set 1,(hl)" }; + case 0xcf: return { "set 1,a" }; + case 0xd0: return { "set 2,b" }; + case 0xd1: return { "set 2,c" }; + case 0xd2: return { "set 2,d" }; + case 0xd3: return { "set 2,e" }; + case 0xd4: return { "set 2,h" }; + case 0xd5: return { "set 2,l" }; + case 0xd6: return { "set 2,(hl)" }; + case 0xd7: return { "set 2,a" }; + case 0xd8: return { "set 3,b" }; + case 0xd9: return { "set 3,c" }; + case 0xda: return { "set 3,d" }; + case 0xdb: return { "set 3,e" }; + case 0xdc: return { "set 3,h" }; + case 0xdd: return { "set 3,l" }; + case 0xde: return { "set 3,(hl)" }; + case 0xdf: return { "set 3,a" }; + case 0xe0: return { "set 4,b" }; + case 0xe1: return { "set 4,c" }; + case 0xe2: return { "set 4,d" }; + case 0xe3: return { "set 4,e" }; + case 0xe4: return { "set 4,h" }; + case 0xe5: return { "set 4,l" }; + case 0xe6: return { "set 4,(hl)" }; + case 0xe7: return { "set 4,a" }; + case 0xe8: return { "set 5,b" }; + case 0xe9: return { "set 5,c" }; + case 0xea: return { "set 5,d" }; + case 0xeb: return { "set 5,e" }; + case 0xec: return { "set 5,h" }; + case 0xed: return { "set 5,l" }; + case 0xee: return { "set 5,(hl)" }; + case 0xef: return { "set 5,a" }; + case 0xf0: return { "set 6,b" }; + case 0xf1: return { "set 6,c" }; + case 0xf2: return { "set 6,d" }; + case 0xf3: return { "set 6,e" }; + case 0xf4: return { "set 6,h" }; + case 0xf5: return { "set 6,l" }; + case 0xf6: return { "set 6,(hl)" }; + case 0xf7: return { "set 6,a" }; + case 0xf8: return { "set 7,b" }; + case 0xf9: return { "set 7,c" }; + case 0xfa: return { "set 7,d" }; + case 0xfb: return { "set 7,e" }; + case 0xfc: return { "set 7,h" }; + case 0xfd: return { "set 7,l" }; + case 0xfe: return { "set 7,(hl)" }; + case 0xff: return { "set 7,a" }; } return ""; diff --git a/higan/processor/lr35902/instruction.cpp b/higan/processor/lr35902/instruction.cpp new file mode 100644 index 00000000..7856eedf --- /dev/null +++ b/higan/processor/lr35902/instruction.cpp @@ -0,0 +1,531 @@ +auto LR35902::interrupt(uint16 vector) -> void { + io(); + io(); + io(); + r.ime = 0; + write(--r[SP], r[PC] >> 8); + write(--r[SP], r[PC] >> 0); + r[PC] = vector; +} + +auto LR35902::instruction() -> void { + switch(auto opcode = read(r[PC]++)) { + case 0x00: return op_nop(); + case 0x01: return op_ld_rr_nn(BC); + case 0x02: return op_ld_rr_a(BC); + case 0x03: return op_inc_rr(BC); + case 0x04: return op_inc_r(B); + case 0x05: return op_dec_r(B); + case 0x06: return op_ld_r_n(B); + case 0x07: return op_rlca(); + case 0x08: return op_ld_nn_sp(); + case 0x09: return op_add_hl_rr(BC); + case 0x0a: return op_ld_a_rr(BC); + case 0x0b: return op_dec_rr(BC); + case 0x0c: return op_inc_r(C); + case 0x0d: return op_dec_r(C); + case 0x0e: return op_ld_r_n(C); + case 0x0f: return op_rrca(); + case 0x10: return op_stop(); + case 0x11: return op_ld_rr_nn(DE); + case 0x12: return op_ld_rr_a(DE); + case 0x13: return op_inc_rr(DE); + case 0x14: return op_inc_r(D); + case 0x15: return op_dec_r(D); + case 0x16: return op_ld_r_n(D); + case 0x17: return op_rla(); + case 0x18: return op_jr_n(); + case 0x19: return op_add_hl_rr(DE); + case 0x1a: return op_ld_a_rr(DE); + case 0x1b: return op_dec_rr(DE); + case 0x1c: return op_inc_r(E); + case 0x1d: return op_dec_r(E); + case 0x1e: return op_ld_r_n(E); + case 0x1f: return op_rra(); + case 0x20: return op_jr_f_n(ZF, 0); + case 0x21: return op_ld_rr_nn(HL); + case 0x22: return op_ldi_hl_a(); + case 0x23: return op_inc_rr(HL); + case 0x24: return op_inc_r(H); + case 0x25: return op_dec_r(H); + case 0x26: return op_ld_r_n(H); + case 0x27: return op_daa(); + case 0x28: return op_jr_f_n(ZF, 1); + case 0x29: return op_add_hl_rr(HL); + case 0x2a: return op_ldi_a_hl(); + case 0x2b: return op_dec_rr(HL); + case 0x2c: return op_inc_r(L); + case 0x2d: return op_dec_r(L); + case 0x2e: return op_ld_r_n(L); + case 0x2f: return op_cpl(); + case 0x30: return op_jr_f_n(CF, 0); + case 0x31: return op_ld_rr_nn(SP); + case 0x32: return op_ldd_hl_a(); + case 0x33: return op_inc_rr(SP); + case 0x34: return op_inc_hl(); + case 0x35: return op_dec_hl(); + case 0x36: return op_ld_hl_n(); + case 0x37: return op_scf(); + case 0x38: return op_jr_f_n(CF, 1); + case 0x39: return op_add_hl_rr(SP); + case 0x3a: return op_ldd_a_hl(); + case 0x3b: return op_dec_rr(SP); + case 0x3c: return op_inc_r(A); + case 0x3d: return op_dec_r(A); + case 0x3e: return op_ld_r_n(A); + case 0x3f: return op_ccf(); + case 0x40: return op_ld_r_r(B, B); + case 0x41: return op_ld_r_r(B, C); + case 0x42: return op_ld_r_r(B, D); + case 0x43: return op_ld_r_r(B, E); + case 0x44: return op_ld_r_r(B, H); + case 0x45: return op_ld_r_r(B, L); + case 0x46: return op_ld_r_hl(B); + case 0x47: return op_ld_r_r(B, A); + case 0x48: return op_ld_r_r(C, B); + case 0x49: return op_ld_r_r(C, C); + case 0x4a: return op_ld_r_r(C, D); + case 0x4b: return op_ld_r_r(C, E); + case 0x4c: return op_ld_r_r(C, H); + case 0x4d: return op_ld_r_r(C, L); + case 0x4e: return op_ld_r_hl(C); + case 0x4f: return op_ld_r_r(C, A); + case 0x50: return op_ld_r_r(D, B); + case 0x51: return op_ld_r_r(D, C); + case 0x52: return op_ld_r_r(D, D); + case 0x53: return op_ld_r_r(D, E); + case 0x54: return op_ld_r_r(D, H); + case 0x55: return op_ld_r_r(D, L); + case 0x56: return op_ld_r_hl(D); + case 0x57: return op_ld_r_r(D, A); + case 0x58: return op_ld_r_r(E, B); + case 0x59: return op_ld_r_r(E, C); + case 0x5a: return op_ld_r_r(E, D); + case 0x5b: return op_ld_r_r(E, E); + case 0x5c: return op_ld_r_r(E, H); + case 0x5d: return op_ld_r_r(E, L); + case 0x5e: return op_ld_r_hl(E); + case 0x5f: return op_ld_r_r(E, A); + case 0x60: return op_ld_r_r(H, B); + case 0x61: return op_ld_r_r(H, C); + case 0x62: return op_ld_r_r(H, D); + case 0x63: return op_ld_r_r(H, E); + case 0x64: return op_ld_r_r(H, H); + case 0x65: return op_ld_r_r(H, L); + case 0x66: return op_ld_r_hl(H); + case 0x67: return op_ld_r_r(H, A); + case 0x68: return op_ld_r_r(L, B); + case 0x69: return op_ld_r_r(L, C); + case 0x6a: return op_ld_r_r(L, D); + case 0x6b: return op_ld_r_r(L, E); + case 0x6c: return op_ld_r_r(L, H); + case 0x6d: return op_ld_r_r(L, L); + case 0x6e: return op_ld_r_hl(L); + case 0x6f: return op_ld_r_r(L, A); + case 0x70: return op_ld_hl_r(B); + case 0x71: return op_ld_hl_r(C); + case 0x72: return op_ld_hl_r(D); + case 0x73: return op_ld_hl_r(E); + case 0x74: return op_ld_hl_r(H); + case 0x75: return op_ld_hl_r(L); + case 0x76: return op_halt(); + case 0x77: return op_ld_hl_r(A); + case 0x78: return op_ld_r_r(A, B); + case 0x79: return op_ld_r_r(A, C); + case 0x7a: return op_ld_r_r(A, D); + case 0x7b: return op_ld_r_r(A, E); + case 0x7c: return op_ld_r_r(A, H); + case 0x7d: return op_ld_r_r(A, L); + case 0x7e: return op_ld_r_hl(A); + case 0x7f: return op_ld_r_r(A, A); + case 0x80: return op_add_a_r(B); + case 0x81: return op_add_a_r(C); + case 0x82: return op_add_a_r(D); + case 0x83: return op_add_a_r(E); + case 0x84: return op_add_a_r(H); + case 0x85: return op_add_a_r(L); + case 0x86: return op_add_a_hl(); + case 0x87: return op_add_a_r(A); + case 0x88: return op_adc_a_r(B); + case 0x89: return op_adc_a_r(C); + case 0x8a: return op_adc_a_r(D); + case 0x8b: return op_adc_a_r(E); + case 0x8c: return op_adc_a_r(H); + case 0x8d: return op_adc_a_r(L); + case 0x8e: return op_adc_a_hl(); + case 0x8f: return op_adc_a_r(A); + case 0x90: return op_sub_a_r(B); + case 0x91: return op_sub_a_r(C); + case 0x92: return op_sub_a_r(D); + case 0x93: return op_sub_a_r(E); + case 0x94: return op_sub_a_r(H); + case 0x95: return op_sub_a_r(L); + case 0x96: return op_sub_a_hl(); + case 0x97: return op_sub_a_r(A); + case 0x98: return op_sbc_a_r(B); + case 0x99: return op_sbc_a_r(C); + case 0x9a: return op_sbc_a_r(D); + case 0x9b: return op_sbc_a_r(E); + case 0x9c: return op_sbc_a_r(H); + case 0x9d: return op_sbc_a_r(L); + case 0x9e: return op_sbc_a_hl(); + case 0x9f: return op_sbc_a_r(A); + case 0xa0: return op_and_a_r(B); + case 0xa1: return op_and_a_r(C); + case 0xa2: return op_and_a_r(D); + case 0xa3: return op_and_a_r(E); + case 0xa4: return op_and_a_r(H); + case 0xa5: return op_and_a_r(L); + case 0xa6: return op_and_a_hl(); + case 0xa7: return op_and_a_r(A); + case 0xa8: return op_xor_a_r(B); + case 0xa9: return op_xor_a_r(C); + case 0xaa: return op_xor_a_r(D); + case 0xab: return op_xor_a_r(E); + case 0xac: return op_xor_a_r(H); + case 0xad: return op_xor_a_r(L); + case 0xae: return op_xor_a_hl(); + case 0xaf: return op_xor_a_r(A); + case 0xb0: return op_or_a_r(B); + case 0xb1: return op_or_a_r(C); + case 0xb2: return op_or_a_r(D); + case 0xb3: return op_or_a_r(E); + case 0xb4: return op_or_a_r(H); + case 0xb5: return op_or_a_r(L); + case 0xb6: return op_or_a_hl(); + case 0xb7: return op_or_a_r(A); + case 0xb8: return op_cp_a_r(B); + case 0xb9: return op_cp_a_r(C); + case 0xba: return op_cp_a_r(D); + case 0xbb: return op_cp_a_r(E); + case 0xbc: return op_cp_a_r(H); + case 0xbd: return op_cp_a_r(L); + case 0xbe: return op_cp_a_hl(); + case 0xbf: return op_cp_a_r(A); + case 0xc0: return op_ret_f(ZF, 0); + case 0xc1: return op_pop_rr(BC); + case 0xc2: return op_jp_f_nn(ZF, 0); + case 0xc3: return op_jp_nn(); + case 0xc4: return op_call_f_nn(ZF, 0); + case 0xc5: return op_push_rr(BC); + case 0xc6: return op_add_a_n(); + case 0xc7: return op_rst_n(0x00); + case 0xc8: return op_ret_f(ZF, 1); + case 0xc9: return op_ret(); + case 0xca: return op_jp_f_nn(ZF, 1); + case 0xcb: return op_cb(); + case 0xcc: return op_call_f_nn(ZF, 1); + case 0xcd: return op_call_nn(); + case 0xce: return op_adc_a_n(); + case 0xcf: return op_rst_n(0x08); + case 0xd0: return op_ret_f(CF, 0); + case 0xd1: return op_pop_rr(DE); + case 0xd2: return op_jp_f_nn(CF, 0); + case 0xd3: return op_xx(); + case 0xd4: return op_call_f_nn(CF, 0); + case 0xd5: return op_push_rr(DE); + case 0xd6: return op_sub_a_n(); + case 0xd7: return op_rst_n(0x10); + case 0xd8: return op_ret_f(CF, 1); + case 0xd9: return op_reti(); + case 0xda: return op_jp_f_nn(CF, 1); + case 0xdb: return op_xx(); + case 0xdc: return op_call_f_nn(CF, 1); + case 0xdd: return op_xx(); + case 0xde: return op_sbc_a_n(); + case 0xdf: return op_rst_n(0x18); + case 0xe0: return op_ld_ffn_a(); + case 0xe1: return op_pop_rr(HL); + case 0xe2: return op_ld_ffc_a(); + case 0xe3: return op_xx(); + case 0xe4: return op_xx(); + case 0xe5: return op_push_rr(HL); + case 0xe6: return op_and_a_n(); + case 0xe7: return op_rst_n(0x20); + case 0xe8: return op_add_sp_n(); + case 0xe9: return op_jp_hl(); + case 0xea: return op_ld_nn_a(); + case 0xeb: return op_xx(); + case 0xec: return op_xx(); + case 0xed: return op_xx(); + case 0xee: return op_xor_a_n(); + case 0xef: return op_rst_n(0x28); + case 0xf0: return op_ld_a_ffn(); + case 0xf1: return op_pop_rr(AF); + case 0xf2: return op_ld_a_ffc(); + case 0xf3: return op_di(); + case 0xf4: return op_xx(); + case 0xf5: return op_push_rr(AF); + case 0xf6: return op_or_a_n(); + case 0xf7: return op_rst_n(0x30); + case 0xf8: return op_ld_hl_sp_n(); + case 0xf9: return op_ld_sp_hl(); + case 0xfa: return op_ld_a_nn(); + case 0xfb: return op_ei(); + case 0xfc: return op_xx(); + case 0xfd: return op_xx(); + case 0xfe: return op_cp_a_n(); + case 0xff: return op_rst_n(0x38); + } +} + +auto LR35902::instructionCB() -> void { + switch(auto opcode = read(r[PC]++)) { + case 0x00: return op_rlc_r(B); + case 0x01: return op_rlc_r(C); + case 0x02: return op_rlc_r(D); + case 0x03: return op_rlc_r(E); + case 0x04: return op_rlc_r(H); + case 0x05: return op_rlc_r(L); + case 0x06: return op_rlc_hl(); + case 0x07: return op_rlc_r(A); + case 0x08: return op_rrc_r(B); + case 0x09: return op_rrc_r(C); + case 0x0a: return op_rrc_r(D); + case 0x0b: return op_rrc_r(E); + case 0x0c: return op_rrc_r(H); + case 0x0d: return op_rrc_r(L); + case 0x0e: return op_rrc_hl(); + case 0x0f: return op_rrc_r(A); + case 0x10: return op_rl_r(B); + case 0x11: return op_rl_r(C); + case 0x12: return op_rl_r(D); + case 0x13: return op_rl_r(E); + case 0x14: return op_rl_r(H); + case 0x15: return op_rl_r(L); + case 0x16: return op_rl_hl(); + case 0x17: return op_rl_r(A); + case 0x18: return op_rr_r(B); + case 0x19: return op_rr_r(C); + case 0x1a: return op_rr_r(D); + case 0x1b: return op_rr_r(E); + case 0x1c: return op_rr_r(H); + case 0x1d: return op_rr_r(L); + case 0x1e: return op_rr_hl(); + case 0x1f: return op_rr_r(A); + case 0x20: return op_sla_r(B); + case 0x21: return op_sla_r(C); + case 0x22: return op_sla_r(D); + case 0x23: return op_sla_r(E); + case 0x24: return op_sla_r(H); + case 0x25: return op_sla_r(L); + case 0x26: return op_sla_hl(); + case 0x27: return op_sla_r(A); + case 0x28: return op_sra_r(B); + case 0x29: return op_sra_r(C); + case 0x2a: return op_sra_r(D); + case 0x2b: return op_sra_r(E); + case 0x2c: return op_sra_r(H); + case 0x2d: return op_sra_r(L); + case 0x2e: return op_sra_hl(); + case 0x2f: return op_sra_r(A); + case 0x30: return op_swap_r(B); + case 0x31: return op_swap_r(C); + case 0x32: return op_swap_r(D); + case 0x33: return op_swap_r(E); + case 0x34: return op_swap_r(H); + case 0x35: return op_swap_r(L); + case 0x36: return op_swap_hl(); + case 0x37: return op_swap_r(A); + case 0x38: return op_srl_r(B); + case 0x39: return op_srl_r(C); + case 0x3a: return op_srl_r(D); + case 0x3b: return op_srl_r(E); + case 0x3c: return op_srl_r(H); + case 0x3d: return op_srl_r(L); + case 0x3e: return op_srl_hl(); + case 0x3f: return op_srl_r(A); + case 0x40: return op_bit_n_r(0, B); + case 0x41: return op_bit_n_r(0, C); + case 0x42: return op_bit_n_r(0, D); + case 0x43: return op_bit_n_r(0, E); + case 0x44: return op_bit_n_r(0, H); + case 0x45: return op_bit_n_r(0, L); + case 0x46: return op_bit_n_hl(0); + case 0x47: return op_bit_n_r(0, A); + case 0x48: return op_bit_n_r(1, B); + case 0x49: return op_bit_n_r(1, C); + case 0x4a: return op_bit_n_r(1, D); + case 0x4b: return op_bit_n_r(1, E); + case 0x4c: return op_bit_n_r(1, H); + case 0x4d: return op_bit_n_r(1, L); + case 0x4e: return op_bit_n_hl(1); + case 0x4f: return op_bit_n_r(1, A); + case 0x50: return op_bit_n_r(2, B); + case 0x51: return op_bit_n_r(2, C); + case 0x52: return op_bit_n_r(2, D); + case 0x53: return op_bit_n_r(2, E); + case 0x54: return op_bit_n_r(2, H); + case 0x55: return op_bit_n_r(2, L); + case 0x56: return op_bit_n_hl(2); + case 0x57: return op_bit_n_r(2, A); + case 0x58: return op_bit_n_r(3, B); + case 0x59: return op_bit_n_r(3, C); + case 0x5a: return op_bit_n_r(3, D); + case 0x5b: return op_bit_n_r(3, E); + case 0x5c: return op_bit_n_r(3, H); + case 0x5d: return op_bit_n_r(3, L); + case 0x5e: return op_bit_n_hl(3); + case 0x5f: return op_bit_n_r(3, A); + case 0x60: return op_bit_n_r(4, B); + case 0x61: return op_bit_n_r(4, C); + case 0x62: return op_bit_n_r(4, D); + case 0x63: return op_bit_n_r(4, E); + case 0x64: return op_bit_n_r(4, H); + case 0x65: return op_bit_n_r(4, L); + case 0x66: return op_bit_n_hl(4); + case 0x67: return op_bit_n_r(4, A); + case 0x68: return op_bit_n_r(5, B); + case 0x69: return op_bit_n_r(5, C); + case 0x6a: return op_bit_n_r(5, D); + case 0x6b: return op_bit_n_r(5, E); + case 0x6c: return op_bit_n_r(5, H); + case 0x6d: return op_bit_n_r(5, L); + case 0x6e: return op_bit_n_hl(5); + case 0x6f: return op_bit_n_r(5, A); + case 0x70: return op_bit_n_r(6, B); + case 0x71: return op_bit_n_r(6, C); + case 0x72: return op_bit_n_r(6, D); + case 0x73: return op_bit_n_r(6, E); + case 0x74: return op_bit_n_r(6, H); + case 0x75: return op_bit_n_r(6, L); + case 0x76: return op_bit_n_hl(6); + case 0x77: return op_bit_n_r(6, A); + case 0x78: return op_bit_n_r(7, B); + case 0x79: return op_bit_n_r(7, C); + case 0x7a: return op_bit_n_r(7, D); + case 0x7b: return op_bit_n_r(7, E); + case 0x7c: return op_bit_n_r(7, H); + case 0x7d: return op_bit_n_r(7, L); + case 0x7e: return op_bit_n_hl(7); + case 0x7f: return op_bit_n_r(7, A); + case 0x80: return op_res_n_r(0, B); + case 0x81: return op_res_n_r(0, C); + case 0x82: return op_res_n_r(0, D); + case 0x83: return op_res_n_r(0, E); + case 0x84: return op_res_n_r(0, H); + case 0x85: return op_res_n_r(0, L); + case 0x86: return op_res_n_hl(0); + case 0x87: return op_res_n_r(0, A); + case 0x88: return op_res_n_r(1, B); + case 0x89: return op_res_n_r(1, C); + case 0x8a: return op_res_n_r(1, D); + case 0x8b: return op_res_n_r(1, E); + case 0x8c: return op_res_n_r(1, H); + case 0x8d: return op_res_n_r(1, L); + case 0x8e: return op_res_n_hl(1); + case 0x8f: return op_res_n_r(1, A); + case 0x90: return op_res_n_r(2, B); + case 0x91: return op_res_n_r(2, C); + case 0x92: return op_res_n_r(2, D); + case 0x93: return op_res_n_r(2, E); + case 0x94: return op_res_n_r(2, H); + case 0x95: return op_res_n_r(2, L); + case 0x96: return op_res_n_hl(2); + case 0x97: return op_res_n_r(2, A); + case 0x98: return op_res_n_r(3, B); + case 0x99: return op_res_n_r(3, C); + case 0x9a: return op_res_n_r(3, D); + case 0x9b: return op_res_n_r(3, E); + case 0x9c: return op_res_n_r(3, H); + case 0x9d: return op_res_n_r(3, L); + case 0x9e: return op_res_n_hl(3); + case 0x9f: return op_res_n_r(3, A); + case 0xa0: return op_res_n_r(4, B); + case 0xa1: return op_res_n_r(4, C); + case 0xa2: return op_res_n_r(4, D); + case 0xa3: return op_res_n_r(4, E); + case 0xa4: return op_res_n_r(4, H); + case 0xa5: return op_res_n_r(4, L); + case 0xa6: return op_res_n_hl(4); + case 0xa7: return op_res_n_r(4, A); + case 0xa8: return op_res_n_r(5, B); + case 0xa9: return op_res_n_r(5, C); + case 0xaa: return op_res_n_r(5, D); + case 0xab: return op_res_n_r(5, E); + case 0xac: return op_res_n_r(5, H); + case 0xad: return op_res_n_r(5, L); + case 0xae: return op_res_n_hl(5); + case 0xaf: return op_res_n_r(5, A); + case 0xb0: return op_res_n_r(6, B); + case 0xb1: return op_res_n_r(6, C); + case 0xb2: return op_res_n_r(6, D); + case 0xb3: return op_res_n_r(6, E); + case 0xb4: return op_res_n_r(6, H); + case 0xb5: return op_res_n_r(6, L); + case 0xb6: return op_res_n_hl(6); + case 0xb7: return op_res_n_r(6, A); + case 0xb8: return op_res_n_r(7, B); + case 0xb9: return op_res_n_r(7, C); + case 0xba: return op_res_n_r(7, D); + case 0xbb: return op_res_n_r(7, E); + case 0xbc: return op_res_n_r(7, H); + case 0xbd: return op_res_n_r(7, L); + case 0xbe: return op_res_n_hl(7); + case 0xbf: return op_res_n_r(7, A); + case 0xc0: return op_set_n_r(0, B); + case 0xc1: return op_set_n_r(0, C); + case 0xc2: return op_set_n_r(0, D); + case 0xc3: return op_set_n_r(0, E); + case 0xc4: return op_set_n_r(0, H); + case 0xc5: return op_set_n_r(0, L); + case 0xc6: return op_set_n_hl(0); + case 0xc7: return op_set_n_r(0, A); + case 0xc8: return op_set_n_r(1, B); + case 0xc9: return op_set_n_r(1, C); + case 0xca: return op_set_n_r(1, D); + case 0xcb: return op_set_n_r(1, E); + case 0xcc: return op_set_n_r(1, H); + case 0xcd: return op_set_n_r(1, L); + case 0xce: return op_set_n_hl(1); + case 0xcf: return op_set_n_r(1, A); + case 0xd0: return op_set_n_r(2, B); + case 0xd1: return op_set_n_r(2, C); + case 0xd2: return op_set_n_r(2, D); + case 0xd3: return op_set_n_r(2, E); + case 0xd4: return op_set_n_r(2, H); + case 0xd5: return op_set_n_r(2, L); + case 0xd6: return op_set_n_hl(2); + case 0xd7: return op_set_n_r(2, A); + case 0xd8: return op_set_n_r(3, B); + case 0xd9: return op_set_n_r(3, C); + case 0xda: return op_set_n_r(3, D); + case 0xdb: return op_set_n_r(3, E); + case 0xdc: return op_set_n_r(3, H); + case 0xdd: return op_set_n_r(3, L); + case 0xde: return op_set_n_hl(3); + case 0xdf: return op_set_n_r(3, A); + case 0xe0: return op_set_n_r(4, B); + case 0xe1: return op_set_n_r(4, C); + case 0xe2: return op_set_n_r(4, D); + case 0xe3: return op_set_n_r(4, E); + case 0xe4: return op_set_n_r(4, H); + case 0xe5: return op_set_n_r(4, L); + case 0xe6: return op_set_n_hl(4); + case 0xe7: return op_set_n_r(4, A); + case 0xe8: return op_set_n_r(5, B); + case 0xe9: return op_set_n_r(5, C); + case 0xea: return op_set_n_r(5, D); + case 0xeb: return op_set_n_r(5, E); + case 0xec: return op_set_n_r(5, H); + case 0xed: return op_set_n_r(5, L); + case 0xee: return op_set_n_hl(5); + case 0xef: return op_set_n_r(5, A); + case 0xf0: return op_set_n_r(6, B); + case 0xf1: return op_set_n_r(6, C); + case 0xf2: return op_set_n_r(6, D); + case 0xf3: return op_set_n_r(6, E); + case 0xf4: return op_set_n_r(6, H); + case 0xf5: return op_set_n_r(6, L); + case 0xf6: return op_set_n_hl(6); + case 0xf7: return op_set_n_r(6, A); + case 0xf8: return op_set_n_r(7, B); + case 0xf9: return op_set_n_r(7, C); + case 0xfa: return op_set_n_r(7, D); + case 0xfb: return op_set_n_r(7, E); + case 0xfc: return op_set_n_r(7, H); + case 0xfd: return op_set_n_r(7, L); + case 0xfe: return op_set_n_hl(7); + case 0xff: return op_set_n_r(7, A); + } +} diff --git a/higan/processor/lr35902/lr35902.cpp b/higan/processor/lr35902/lr35902.cpp index 969a4235..b26bccba 100644 --- a/higan/processor/lr35902/lr35902.cpp +++ b/higan/processor/lr35902/lr35902.cpp @@ -4,8 +4,9 @@ namespace Processor { #include "instructions.cpp" -#include "disassembler.cpp" +#include "instruction.cpp" #include "serialization.cpp" +#include "disassembler.cpp" auto LR35902::power() -> void { r.halt = false; @@ -14,536 +15,4 @@ auto LR35902::power() -> void { r.ime = false; } -auto LR35902::interrupt(uint16 vector) -> void { - io(); - io(); - io(); - r.ime = 0; - write(--r[SP], r[PC] >> 8); - write(--r[SP], r[PC] >> 0); - r[PC] = vector; -} - -auto LR35902::instruction() -> void { - switch(auto opcode = read(r[PC]++)) { - case 0x00: return op_nop(); - case 0x01: return op_ld_rr_nn(BC); - case 0x02: return op_ld_rr_a(BC); - case 0x03: return op_inc_rr(BC); - case 0x04: return op_inc_r(B); - case 0x05: return op_dec_r(B); - case 0x06: return op_ld_r_n(B); - case 0x07: return op_rlca(); - case 0x08: return op_ld_nn_sp(); - case 0x09: return op_add_hl_rr(BC); - case 0x0a: return op_ld_a_rr(BC); - case 0x0b: return op_dec_rr(BC); - case 0x0c: return op_inc_r(C); - case 0x0d: return op_dec_r(C); - case 0x0e: return op_ld_r_n(C); - case 0x0f: return op_rrca(); - case 0x10: return op_stop(); - case 0x11: return op_ld_rr_nn(DE); - case 0x12: return op_ld_rr_a(DE); - case 0x13: return op_inc_rr(DE); - case 0x14: return op_inc_r(D); - case 0x15: return op_dec_r(D); - case 0x16: return op_ld_r_n(D); - case 0x17: return op_rla(); - case 0x18: return op_jr_n(); - case 0x19: return op_add_hl_rr(DE); - case 0x1a: return op_ld_a_rr(DE); - case 0x1b: return op_dec_rr(DE); - case 0x1c: return op_inc_r(E); - case 0x1d: return op_dec_r(E); - case 0x1e: return op_ld_r_n(E); - case 0x1f: return op_rra(); - case 0x20: return op_jr_f_n(ZF, 0); - case 0x21: return op_ld_rr_nn(HL); - case 0x22: return op_ldi_hl_a(); - case 0x23: return op_inc_rr(HL); - case 0x24: return op_inc_r(H); - case 0x25: return op_dec_r(H); - case 0x26: return op_ld_r_n(H); - case 0x27: return op_daa(); - case 0x28: return op_jr_f_n(ZF, 1); - case 0x29: return op_add_hl_rr(HL); - case 0x2a: return op_ldi_a_hl(); - case 0x2b: return op_dec_rr(HL); - case 0x2c: return op_inc_r(L); - case 0x2d: return op_dec_r(L); - case 0x2e: return op_ld_r_n(L); - case 0x2f: return op_cpl(); - case 0x30: return op_jr_f_n(CF, 0); - case 0x31: return op_ld_rr_nn(SP); - case 0x32: return op_ldd_hl_a(); - case 0x33: return op_inc_rr(SP); - case 0x34: return op_inc_hl(); - case 0x35: return op_dec_hl(); - case 0x36: return op_ld_hl_n(); - case 0x37: return op_scf(); - case 0x38: return op_jr_f_n(CF, 1); - case 0x39: return op_add_hl_rr(SP); - case 0x3a: return op_ldd_a_hl(); - case 0x3b: return op_dec_rr(SP); - case 0x3c: return op_inc_r(A); - case 0x3d: return op_dec_r(A); - case 0x3e: return op_ld_r_n(A); - case 0x3f: return op_ccf(); - case 0x40: return op_ld_r_r(B, B); - case 0x41: return op_ld_r_r(B, C); - case 0x42: return op_ld_r_r(B, D); - case 0x43: return op_ld_r_r(B, E); - case 0x44: return op_ld_r_r(B, H); - case 0x45: return op_ld_r_r(B, L); - case 0x46: return op_ld_r_hl(B); - case 0x47: return op_ld_r_r(B, A); - case 0x48: return op_ld_r_r(C, B); - case 0x49: return op_ld_r_r(C, C); - case 0x4a: return op_ld_r_r(C, D); - case 0x4b: return op_ld_r_r(C, E); - case 0x4c: return op_ld_r_r(C, H); - case 0x4d: return op_ld_r_r(C, L); - case 0x4e: return op_ld_r_hl(C); - case 0x4f: return op_ld_r_r(C, A); - case 0x50: return op_ld_r_r(D, B); - case 0x51: return op_ld_r_r(D, C); - case 0x52: return op_ld_r_r(D, D); - case 0x53: return op_ld_r_r(D, E); - case 0x54: return op_ld_r_r(D, H); - case 0x55: return op_ld_r_r(D, L); - case 0x56: return op_ld_r_hl(D); - case 0x57: return op_ld_r_r(D, A); - case 0x58: return op_ld_r_r(E, B); - case 0x59: return op_ld_r_r(E, C); - case 0x5a: return op_ld_r_r(E, D); - case 0x5b: return op_ld_r_r(E, E); - case 0x5c: return op_ld_r_r(E, H); - case 0x5d: return op_ld_r_r(E, L); - case 0x5e: return op_ld_r_hl(E); - case 0x5f: return op_ld_r_r(E, A); - case 0x60: return op_ld_r_r(H, B); - case 0x61: return op_ld_r_r(H, C); - case 0x62: return op_ld_r_r(H, D); - case 0x63: return op_ld_r_r(H, E); - case 0x64: return op_ld_r_r(H, H); - case 0x65: return op_ld_r_r(H, L); - case 0x66: return op_ld_r_hl(H); - case 0x67: return op_ld_r_r(H, A); - case 0x68: return op_ld_r_r(L, B); - case 0x69: return op_ld_r_r(L, C); - case 0x6a: return op_ld_r_r(L, D); - case 0x6b: return op_ld_r_r(L, E); - case 0x6c: return op_ld_r_r(L, H); - case 0x6d: return op_ld_r_r(L, L); - case 0x6e: return op_ld_r_hl(L); - case 0x6f: return op_ld_r_r(L, A); - case 0x70: return op_ld_hl_r(B); - case 0x71: return op_ld_hl_r(C); - case 0x72: return op_ld_hl_r(D); - case 0x73: return op_ld_hl_r(E); - case 0x74: return op_ld_hl_r(H); - case 0x75: return op_ld_hl_r(L); - case 0x76: return op_halt(); - case 0x77: return op_ld_hl_r(A); - case 0x78: return op_ld_r_r(A, B); - case 0x79: return op_ld_r_r(A, C); - case 0x7a: return op_ld_r_r(A, D); - case 0x7b: return op_ld_r_r(A, E); - case 0x7c: return op_ld_r_r(A, H); - case 0x7d: return op_ld_r_r(A, L); - case 0x7e: return op_ld_r_hl(A); - case 0x7f: return op_ld_r_r(A, A); - case 0x80: return op_add_a_r(B); - case 0x81: return op_add_a_r(C); - case 0x82: return op_add_a_r(D); - case 0x83: return op_add_a_r(E); - case 0x84: return op_add_a_r(H); - case 0x85: return op_add_a_r(L); - case 0x86: return op_add_a_hl(); - case 0x87: return op_add_a_r(A); - case 0x88: return op_adc_a_r(B); - case 0x89: return op_adc_a_r(C); - case 0x8a: return op_adc_a_r(D); - case 0x8b: return op_adc_a_r(E); - case 0x8c: return op_adc_a_r(H); - case 0x8d: return op_adc_a_r(L); - case 0x8e: return op_adc_a_hl(); - case 0x8f: return op_adc_a_r(A); - case 0x90: return op_sub_a_r(B); - case 0x91: return op_sub_a_r(C); - case 0x92: return op_sub_a_r(D); - case 0x93: return op_sub_a_r(E); - case 0x94: return op_sub_a_r(H); - case 0x95: return op_sub_a_r(L); - case 0x96: return op_sub_a_hl(); - case 0x97: return op_sub_a_r(A); - case 0x98: return op_sbc_a_r(B); - case 0x99: return op_sbc_a_r(C); - case 0x9a: return op_sbc_a_r(D); - case 0x9b: return op_sbc_a_r(E); - case 0x9c: return op_sbc_a_r(H); - case 0x9d: return op_sbc_a_r(L); - case 0x9e: return op_sbc_a_hl(); - case 0x9f: return op_sbc_a_r(A); - case 0xa0: return op_and_a_r(B); - case 0xa1: return op_and_a_r(C); - case 0xa2: return op_and_a_r(D); - case 0xa3: return op_and_a_r(E); - case 0xa4: return op_and_a_r(H); - case 0xa5: return op_and_a_r(L); - case 0xa6: return op_and_a_hl(); - case 0xa7: return op_and_a_r(A); - case 0xa8: return op_xor_a_r(B); - case 0xa9: return op_xor_a_r(C); - case 0xaa: return op_xor_a_r(D); - case 0xab: return op_xor_a_r(E); - case 0xac: return op_xor_a_r(H); - case 0xad: return op_xor_a_r(L); - case 0xae: return op_xor_a_hl(); - case 0xaf: return op_xor_a_r(A); - case 0xb0: return op_or_a_r(B); - case 0xb1: return op_or_a_r(C); - case 0xb2: return op_or_a_r(D); - case 0xb3: return op_or_a_r(E); - case 0xb4: return op_or_a_r(H); - case 0xb5: return op_or_a_r(L); - case 0xb6: return op_or_a_hl(); - case 0xb7: return op_or_a_r(A); - case 0xb8: return op_cp_a_r(B); - case 0xb9: return op_cp_a_r(C); - case 0xba: return op_cp_a_r(D); - case 0xbb: return op_cp_a_r(E); - case 0xbc: return op_cp_a_r(H); - case 0xbd: return op_cp_a_r(L); - case 0xbe: return op_cp_a_hl(); - case 0xbf: return op_cp_a_r(A); - case 0xc0: return op_ret_f(ZF, 0); - case 0xc1: return op_pop_rr(BC); - case 0xc2: return op_jp_f_nn(ZF, 0); - case 0xc3: return op_jp_nn(); - case 0xc4: return op_call_f_nn(ZF, 0); - case 0xc5: return op_push_rr(BC); - case 0xc6: return op_add_a_n(); - case 0xc7: return op_rst_n(0x00); - case 0xc8: return op_ret_f(ZF, 1); - case 0xc9: return op_ret(); - case 0xca: return op_jp_f_nn(ZF, 1); - case 0xcb: return op_cb(); - case 0xcc: return op_call_f_nn(ZF, 1); - case 0xcd: return op_call_nn(); - case 0xce: return op_adc_a_n(); - case 0xcf: return op_rst_n(0x08); - case 0xd0: return op_ret_f(CF, 0); - case 0xd1: return op_pop_rr(DE); - case 0xd2: return op_jp_f_nn(CF, 0); - case 0xd3: return op_xx(); - case 0xd4: return op_call_f_nn(CF, 0); - case 0xd5: return op_push_rr(DE); - case 0xd6: return op_sub_a_n(); - case 0xd7: return op_rst_n(0x10); - case 0xd8: return op_ret_f(CF, 1); - case 0xd9: return op_reti(); - case 0xda: return op_jp_f_nn(CF, 1); - case 0xdb: return op_xx(); - case 0xdc: return op_call_f_nn(CF, 1); - case 0xdd: return op_xx(); - case 0xde: return op_sbc_a_n(); - case 0xdf: return op_rst_n(0x18); - case 0xe0: return op_ld_ffn_a(); - case 0xe1: return op_pop_rr(HL); - case 0xe2: return op_ld_ffc_a(); - case 0xe3: return op_xx(); - case 0xe4: return op_xx(); - case 0xe5: return op_push_rr(HL); - case 0xe6: return op_and_a_n(); - case 0xe7: return op_rst_n(0x20); - case 0xe8: return op_add_sp_n(); - case 0xe9: return op_jp_hl(); - case 0xea: return op_ld_nn_a(); - case 0xeb: return op_xx(); - case 0xec: return op_xx(); - case 0xed: return op_xx(); - case 0xee: return op_xor_a_n(); - case 0xef: return op_rst_n(0x28); - case 0xf0: return op_ld_a_ffn(); - case 0xf1: return op_pop_rr(AF); - case 0xf2: return op_ld_a_ffc(); - case 0xf3: return op_di(); - case 0xf4: return op_xx(); - case 0xf5: return op_push_rr(AF); - case 0xf6: return op_or_a_n(); - case 0xf7: return op_rst_n(0x30); - case 0xf8: return op_ld_hl_sp_n(); - case 0xf9: return op_ld_sp_hl(); - case 0xfa: return op_ld_a_nn(); - case 0xfb: return op_ei(); - case 0xfc: return op_xx(); - case 0xfd: return op_xx(); - case 0xfe: return op_cp_a_n(); - case 0xff: return op_rst_n(0x38); - } -} - -auto LR35902::instructionCB() -> void { - switch(auto opcode = read(r[PC]++)) { - case 0x00: return op_rlc_r(B); - case 0x01: return op_rlc_r(C); - case 0x02: return op_rlc_r(D); - case 0x03: return op_rlc_r(E); - case 0x04: return op_rlc_r(H); - case 0x05: return op_rlc_r(L); - case 0x06: return op_rlc_hl(); - case 0x07: return op_rlc_r(A); - case 0x08: return op_rrc_r(B); - case 0x09: return op_rrc_r(C); - case 0x0a: return op_rrc_r(D); - case 0x0b: return op_rrc_r(E); - case 0x0c: return op_rrc_r(H); - case 0x0d: return op_rrc_r(L); - case 0x0e: return op_rrc_hl(); - case 0x0f: return op_rrc_r(A); - case 0x10: return op_rl_r(B); - case 0x11: return op_rl_r(C); - case 0x12: return op_rl_r(D); - case 0x13: return op_rl_r(E); - case 0x14: return op_rl_r(H); - case 0x15: return op_rl_r(L); - case 0x16: return op_rl_hl(); - case 0x17: return op_rl_r(A); - case 0x18: return op_rr_r(B); - case 0x19: return op_rr_r(C); - case 0x1a: return op_rr_r(D); - case 0x1b: return op_rr_r(E); - case 0x1c: return op_rr_r(H); - case 0x1d: return op_rr_r(L); - case 0x1e: return op_rr_hl(); - case 0x1f: return op_rr_r(A); - case 0x20: return op_sla_r(B); - case 0x21: return op_sla_r(C); - case 0x22: return op_sla_r(D); - case 0x23: return op_sla_r(E); - case 0x24: return op_sla_r(H); - case 0x25: return op_sla_r(L); - case 0x26: return op_sla_hl(); - case 0x27: return op_sla_r(A); - case 0x28: return op_sra_r(B); - case 0x29: return op_sra_r(C); - case 0x2a: return op_sra_r(D); - case 0x2b: return op_sra_r(E); - case 0x2c: return op_sra_r(H); - case 0x2d: return op_sra_r(L); - case 0x2e: return op_sra_hl(); - case 0x2f: return op_sra_r(A); - case 0x30: return op_swap_r(B); - case 0x31: return op_swap_r(C); - case 0x32: return op_swap_r(D); - case 0x33: return op_swap_r(E); - case 0x34: return op_swap_r(H); - case 0x35: return op_swap_r(L); - case 0x36: return op_swap_hl(); - case 0x37: return op_swap_r(A); - case 0x38: return op_srl_r(B); - case 0x39: return op_srl_r(C); - case 0x3a: return op_srl_r(D); - case 0x3b: return op_srl_r(E); - case 0x3c: return op_srl_r(H); - case 0x3d: return op_srl_r(L); - case 0x3e: return op_srl_hl(); - case 0x3f: return op_srl_r(A); - case 0x40: return op_bit_n_r(0, B); - case 0x41: return op_bit_n_r(0, C); - case 0x42: return op_bit_n_r(0, D); - case 0x43: return op_bit_n_r(0, E); - case 0x44: return op_bit_n_r(0, H); - case 0x45: return op_bit_n_r(0, L); - case 0x46: return op_bit_n_hl(0); - case 0x47: return op_bit_n_r(0, A); - case 0x48: return op_bit_n_r(1, B); - case 0x49: return op_bit_n_r(1, C); - case 0x4a: return op_bit_n_r(1, D); - case 0x4b: return op_bit_n_r(1, E); - case 0x4c: return op_bit_n_r(1, H); - case 0x4d: return op_bit_n_r(1, L); - case 0x4e: return op_bit_n_hl(1); - case 0x4f: return op_bit_n_r(1, A); - case 0x50: return op_bit_n_r(2, B); - case 0x51: return op_bit_n_r(2, C); - case 0x52: return op_bit_n_r(2, D); - case 0x53: return op_bit_n_r(2, E); - case 0x54: return op_bit_n_r(2, H); - case 0x55: return op_bit_n_r(2, L); - case 0x56: return op_bit_n_hl(2); - case 0x57: return op_bit_n_r(2, A); - case 0x58: return op_bit_n_r(3, B); - case 0x59: return op_bit_n_r(3, C); - case 0x5a: return op_bit_n_r(3, D); - case 0x5b: return op_bit_n_r(3, E); - case 0x5c: return op_bit_n_r(3, H); - case 0x5d: return op_bit_n_r(3, L); - case 0x5e: return op_bit_n_hl(3); - case 0x5f: return op_bit_n_r(3, A); - case 0x60: return op_bit_n_r(4, B); - case 0x61: return op_bit_n_r(4, C); - case 0x62: return op_bit_n_r(4, D); - case 0x63: return op_bit_n_r(4, E); - case 0x64: return op_bit_n_r(4, H); - case 0x65: return op_bit_n_r(4, L); - case 0x66: return op_bit_n_hl(4); - case 0x67: return op_bit_n_r(4, A); - case 0x68: return op_bit_n_r(5, B); - case 0x69: return op_bit_n_r(5, C); - case 0x6a: return op_bit_n_r(5, D); - case 0x6b: return op_bit_n_r(5, E); - case 0x6c: return op_bit_n_r(5, H); - case 0x6d: return op_bit_n_r(5, L); - case 0x6e: return op_bit_n_hl(5); - case 0x6f: return op_bit_n_r(5, A); - case 0x70: return op_bit_n_r(6, B); - case 0x71: return op_bit_n_r(6, C); - case 0x72: return op_bit_n_r(6, D); - case 0x73: return op_bit_n_r(6, E); - case 0x74: return op_bit_n_r(6, H); - case 0x75: return op_bit_n_r(6, L); - case 0x76: return op_bit_n_hl(6); - case 0x77: return op_bit_n_r(6, A); - case 0x78: return op_bit_n_r(7, B); - case 0x79: return op_bit_n_r(7, C); - case 0x7a: return op_bit_n_r(7, D); - case 0x7b: return op_bit_n_r(7, E); - case 0x7c: return op_bit_n_r(7, H); - case 0x7d: return op_bit_n_r(7, L); - case 0x7e: return op_bit_n_hl(7); - case 0x7f: return op_bit_n_r(7, A); - case 0x80: return op_res_n_r(0, B); - case 0x81: return op_res_n_r(0, C); - case 0x82: return op_res_n_r(0, D); - case 0x83: return op_res_n_r(0, E); - case 0x84: return op_res_n_r(0, H); - case 0x85: return op_res_n_r(0, L); - case 0x86: return op_res_n_hl(0); - case 0x87: return op_res_n_r(0, A); - case 0x88: return op_res_n_r(1, B); - case 0x89: return op_res_n_r(1, C); - case 0x8a: return op_res_n_r(1, D); - case 0x8b: return op_res_n_r(1, E); - case 0x8c: return op_res_n_r(1, H); - case 0x8d: return op_res_n_r(1, L); - case 0x8e: return op_res_n_hl(1); - case 0x8f: return op_res_n_r(1, A); - case 0x90: return op_res_n_r(2, B); - case 0x91: return op_res_n_r(2, C); - case 0x92: return op_res_n_r(2, D); - case 0x93: return op_res_n_r(2, E); - case 0x94: return op_res_n_r(2, H); - case 0x95: return op_res_n_r(2, L); - case 0x96: return op_res_n_hl(2); - case 0x97: return op_res_n_r(2, A); - case 0x98: return op_res_n_r(3, B); - case 0x99: return op_res_n_r(3, C); - case 0x9a: return op_res_n_r(3, D); - case 0x9b: return op_res_n_r(3, E); - case 0x9c: return op_res_n_r(3, H); - case 0x9d: return op_res_n_r(3, L); - case 0x9e: return op_res_n_hl(3); - case 0x9f: return op_res_n_r(3, A); - case 0xa0: return op_res_n_r(4, B); - case 0xa1: return op_res_n_r(4, C); - case 0xa2: return op_res_n_r(4, D); - case 0xa3: return op_res_n_r(4, E); - case 0xa4: return op_res_n_r(4, H); - case 0xa5: return op_res_n_r(4, L); - case 0xa6: return op_res_n_hl(4); - case 0xa7: return op_res_n_r(4, A); - case 0xa8: return op_res_n_r(5, B); - case 0xa9: return op_res_n_r(5, C); - case 0xaa: return op_res_n_r(5, D); - case 0xab: return op_res_n_r(5, E); - case 0xac: return op_res_n_r(5, H); - case 0xad: return op_res_n_r(5, L); - case 0xae: return op_res_n_hl(5); - case 0xaf: return op_res_n_r(5, A); - case 0xb0: return op_res_n_r(6, B); - case 0xb1: return op_res_n_r(6, C); - case 0xb2: return op_res_n_r(6, D); - case 0xb3: return op_res_n_r(6, E); - case 0xb4: return op_res_n_r(6, H); - case 0xb5: return op_res_n_r(6, L); - case 0xb6: return op_res_n_hl(6); - case 0xb7: return op_res_n_r(6, A); - case 0xb8: return op_res_n_r(7, B); - case 0xb9: return op_res_n_r(7, C); - case 0xba: return op_res_n_r(7, D); - case 0xbb: return op_res_n_r(7, E); - case 0xbc: return op_res_n_r(7, H); - case 0xbd: return op_res_n_r(7, L); - case 0xbe: return op_res_n_hl(7); - case 0xbf: return op_res_n_r(7, A); - case 0xc0: return op_set_n_r(0, B); - case 0xc1: return op_set_n_r(0, C); - case 0xc2: return op_set_n_r(0, D); - case 0xc3: return op_set_n_r(0, E); - case 0xc4: return op_set_n_r(0, H); - case 0xc5: return op_set_n_r(0, L); - case 0xc6: return op_set_n_hl(0); - case 0xc7: return op_set_n_r(0, A); - case 0xc8: return op_set_n_r(1, B); - case 0xc9: return op_set_n_r(1, C); - case 0xca: return op_set_n_r(1, D); - case 0xcb: return op_set_n_r(1, E); - case 0xcc: return op_set_n_r(1, H); - case 0xcd: return op_set_n_r(1, L); - case 0xce: return op_set_n_hl(1); - case 0xcf: return op_set_n_r(1, A); - case 0xd0: return op_set_n_r(2, B); - case 0xd1: return op_set_n_r(2, C); - case 0xd2: return op_set_n_r(2, D); - case 0xd3: return op_set_n_r(2, E); - case 0xd4: return op_set_n_r(2, H); - case 0xd5: return op_set_n_r(2, L); - case 0xd6: return op_set_n_hl(2); - case 0xd7: return op_set_n_r(2, A); - case 0xd8: return op_set_n_r(3, B); - case 0xd9: return op_set_n_r(3, C); - case 0xda: return op_set_n_r(3, D); - case 0xdb: return op_set_n_r(3, E); - case 0xdc: return op_set_n_r(3, H); - case 0xdd: return op_set_n_r(3, L); - case 0xde: return op_set_n_hl(3); - case 0xdf: return op_set_n_r(3, A); - case 0xe0: return op_set_n_r(4, B); - case 0xe1: return op_set_n_r(4, C); - case 0xe2: return op_set_n_r(4, D); - case 0xe3: return op_set_n_r(4, E); - case 0xe4: return op_set_n_r(4, H); - case 0xe5: return op_set_n_r(4, L); - case 0xe6: return op_set_n_hl(4); - case 0xe7: return op_set_n_r(4, A); - case 0xe8: return op_set_n_r(5, B); - case 0xe9: return op_set_n_r(5, C); - case 0xea: return op_set_n_r(5, D); - case 0xeb: return op_set_n_r(5, E); - case 0xec: return op_set_n_r(5, H); - case 0xed: return op_set_n_r(5, L); - case 0xee: return op_set_n_hl(5); - case 0xef: return op_set_n_r(5, A); - case 0xf0: return op_set_n_r(6, B); - case 0xf1: return op_set_n_r(6, C); - case 0xf2: return op_set_n_r(6, D); - case 0xf3: return op_set_n_r(6, E); - case 0xf4: return op_set_n_r(6, H); - case 0xf5: return op_set_n_r(6, L); - case 0xf6: return op_set_n_hl(6); - case 0xf7: return op_set_n_r(6, A); - case 0xf8: return op_set_n_r(7, B); - case 0xf9: return op_set_n_r(7, C); - case 0xfa: return op_set_n_r(7, D); - case 0xfb: return op_set_n_r(7, E); - case 0xfc: return op_set_n_r(7, H); - case 0xfd: return op_set_n_r(7, L); - case 0xfe: return op_set_n_hl(7); - case 0xff: return op_set_n_r(7, A); - } -} - } diff --git a/higan/processor/lr35902/lr35902.hpp b/higan/processor/lr35902/lr35902.hpp index a52740fa..9edd2af7 100644 --- a/higan/processor/lr35902/lr35902.hpp +++ b/higan/processor/lr35902/lr35902.hpp @@ -11,11 +11,15 @@ struct LR35902 { virtual auto stop() -> bool = 0; virtual auto debuggerRead(uint16 addr) -> uint8 { return 0; } + //lr35902.cpp auto power() -> void; + + //instruction.cpp auto interrupt(uint16 vector) -> void; auto instruction() -> void; auto instructionCB() -> void; + //serialization.cpp auto serialize(serializer&) -> void; #include "registers.hpp" diff --git a/higan/processor/spc700/disassembler.cpp b/higan/processor/spc700/disassembler.cpp index e5405fe3..1251cb75 100644 --- a/higan/processor/spc700/disassembler.cpp +++ b/higan/processor/spc700/disassembler.cpp @@ -59,13 +59,13 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string { case 0x25: return { "and $", a() }; case 0x26: return { "and (x)" }; case 0x27: return { "and ($", dp(0), ",x)" }; + case 0x28: return { "and #$", b(0) }; case 0x29: return { "and $", dp(1), "=$", dp(0) }; case 0x2a: return { "orc !$", ab() }; case 0x2b: return { "rol $", dp(0) }; case 0x2c: return { "rol $", a() }; case 0x2d: return { "pha" }; case 0x2e: return { "bne $", dp(0), "=$", rel(+3, 1) }; - case 0x28: return { "and #$", b(0) }; case 0x2f: return { "bra $", rel(+2) }; case 0x30: return { "bmi $", rel(+2) }; case 0x31: return { "jst $ffd8" }; diff --git a/higan/processor/spc700/instruction.cpp b/higan/processor/spc700/instruction.cpp index eabb1ea7..22e280b7 100644 --- a/higan/processor/spc700/instruction.cpp +++ b/higan/processor/spc700/instruction.cpp @@ -2,7 +2,7 @@ #define fp(name) &SPC700::algorithm##name auto SPC700::instruction() -> void { - switch(opcode = fetch()) { + switch(fetch()) { op(0x00, NOP) op(0x01, JST, 0) op(0x02, SET, 0) @@ -13,7 +13,7 @@ auto SPC700::instruction() -> void { op(0x07, IndirectPageXRead, fp(OR)) op(0x08, ImmediateRead, fp(OR), A) op(0x09, DirectPageWriteDirectPage, fp(OR)) - op(0x0a, AbsoluteModifyBit) + op(0x0a, AbsoluteModifyBit, 0) op(0x0b, DirectPageModify, fp(ASL)) op(0x0c, AbsoluteModify, fp(ASL)) op(0x0d, Push, P) @@ -45,7 +45,7 @@ auto SPC700::instruction() -> void { op(0x27, IndirectPageXRead, fp(AND)) op(0x28, ImmediateRead, fp(AND), A) op(0x29, DirectPageWriteDirectPage, fp(AND)) - op(0x2a, AbsoluteModifyBit) + op(0x2a, AbsoluteModifyBit, 1) op(0x2b, DirectPageModify, fp(ROL)) op(0x2c, AbsoluteModify, fp(ROL)) op(0x2d, Push, A) @@ -77,7 +77,7 @@ auto SPC700::instruction() -> void { op(0x47, IndirectPageXRead, fp(EOR)) op(0x48, ImmediateRead, fp(EOR), A) op(0x49, DirectPageWriteDirectPage, fp(EOR)) - op(0x4a, AbsoluteModifyBit) + op(0x4a, AbsoluteModifyBit, 2) op(0x4b, DirectPageModify, fp(LSR)) op(0x4c, AbsoluteModify, fp(LSR)) op(0x4d, Push, X) @@ -109,7 +109,7 @@ auto SPC700::instruction() -> void { op(0x67, IndirectPageXRead, fp(CMP)) op(0x68, ImmediateRead, fp(CMP), A) op(0x69, DirectPageWriteDirectPage, fp(CMP)) - op(0x6a, AbsoluteModifyBit) + op(0x6a, AbsoluteModifyBit, 3) op(0x6b, DirectPageModify, fp(ROR)) op(0x6c, AbsoluteModify, fp(ROR)) op(0x6d, Push, Y) @@ -141,7 +141,7 @@ auto SPC700::instruction() -> void { op(0x87, IndirectPageXRead, fp(ADC)) op(0x88, ImmediateRead, fp(ADC), A) op(0x89, DirectPageWriteDirectPage, fp(ADC)) - op(0x8a, AbsoluteModifyBit) + op(0x8a, AbsoluteModifyBit, 4) op(0x8b, DirectPageModify, fp(DEC)) op(0x8c, AbsoluteModify, fp(DEC)) op(0x8d, ImmediateRead, fp(LD), Y) @@ -173,7 +173,7 @@ auto SPC700::instruction() -> void { op(0xa7, IndirectPageXRead, fp(SBC)) op(0xa8, ImmediateRead, fp(SBC), A) op(0xa9, DirectPageWriteDirectPage, fp(SBC)) - op(0xaa, AbsoluteModifyBit) + op(0xaa, AbsoluteModifyBit, 5) op(0xab, DirectPageModify, fp(INC)) op(0xac, AbsoluteModify, fp(INC)) op(0xad, ImmediateRead, fp(CMP), Y) @@ -205,7 +205,7 @@ auto SPC700::instruction() -> void { op(0xc7, STAIndirectPageX) op(0xc8, ImmediateRead, fp(CMP), X) op(0xc9, AbsoluteWrite, X) - op(0xca, AbsoluteModifyBit) + op(0xca, AbsoluteModifyBit, 6) op(0xcb, DirectPageWrite, Y) op(0xcc, AbsoluteWrite, Y) op(0xcd, ImmediateRead, fp(LD), X) @@ -237,7 +237,7 @@ auto SPC700::instruction() -> void { op(0xe7, IndirectPageXRead, fp(LD)) op(0xe8, ImmediateRead, fp(LD), A) op(0xe9, AbsoluteRead, fp(LD), X) - op(0xea, AbsoluteModifyBit) + op(0xea, AbsoluteModifyBit, 7) op(0xeb, DirectPageRead, fp(LD), Y) op(0xec, AbsoluteRead, fp(LD), Y) op(0xed, CMC) diff --git a/higan/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp index a30eb725..f591f1e4 100644 --- a/higan/processor/spc700/instructions.cpp +++ b/higan/processor/spc700/instructions.cpp @@ -1,5 +1,3 @@ -#define alu (this->*op) - auto SPC700::instructionImpliedModify(fps op, uint8& target) -> void { idle(); target = alu(target); @@ -81,76 +79,81 @@ auto SPC700::instructionDirectPageRead(fpb op, uint8& target) -> void { target = alu(target, data); } -auto SPC700::instructionDirectPageIndexedRead(fpb op, uint8& data, uint8& index) -> void { - dp = fetch(); +auto SPC700::instructionDirectPageIndexedRead(fpb op, uint8& target, uint8& index) -> void { + uint8 direct = fetch(); idle(); - rd = load(dp + index); - data = alu(data, rd); + uint8 data = load(direct + index); + target = alu(target, data); } auto SPC700::instructionDirectPageReadWord(fpw op) -> void { - dp = fetch(); - rd.l = load(dp++); + uint8 direct = fetch(); + uint16 data = load(direct++); if(op != &SPC700::algorithmCPW) idle(); - rd.h = load(dp++); - YA = alu(YA, rd); + data |= load(direct++) << 8; + YA = alu(YA, data); } auto SPC700::instructionIndirectPageXRead(fpb op) -> void { - dp = fetch() + X; + uint8 direct = fetch() + X; idle(); - sp.l = load(dp++); - sp.h = load(dp++); - rd = read(sp); - A = alu(A, rd); + uint16 absolute = load(direct++); + absolute |= load(direct++) << 8; + uint8 data = read(absolute); + A = alu(A, data); } auto SPC700::instructionIndirectPageYRead(fpb op) -> void { - dp = fetch(); + uint8 direct = fetch(); idle(); - sp.l = load(dp++); - sp.h = load(dp++); - rd = read(sp + Y); - A = alu(A, rd); + uint16 absolute = load(direct++); + absolute |= load(direct++) << 8; + uint8 data = read(absolute + Y); + A = alu(A, data); } auto SPC700::instructionIndirectXRead(fpb op) -> void { idle(); - rd = load(X); - A = alu(A, rd); + uint8 data = load(X); + A = alu(A, data); } -auto SPC700::instructionAbsoluteModifyBit() -> void { - dp.l = fetch(); - dp.h = fetch(); - bit = dp >> 13; - dp &= 0x1fff; - rd = read(dp); - switch(opcode >> 5) { +auto SPC700::instructionAbsoluteModifyBit(uint3 mode) -> void { + uint16 absolute = fetch(); + absolute |= fetch() << 8; + uint3 bit = absolute >> 13; + absolute &= 0x1fff; + uint8 data = read(absolute); + switch(mode) { case 0: //orc addr:bit + idle(); + CF |= data.bit(bit); + break; case 1: //orc !addr:bit idle(); - CF |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); + CF |= !data.bit(bit); break; case 2: //and addr:bit + CF &= data.bit(bit); + break; case 3: //and !addr:bit - CF &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20); + CF &= !data.bit(bit); break; case 4: //eor addr:bit idle(); - CF ^= (bool)(rd & (1 << bit)); + CF ^= data.bit(bit); break; case 5: //ldc addr:bit - CF = (rd & (1 << bit)); + CF = data.bit(bit); break; case 6: //stc addr:bit idle(); - rd = (rd & ~(1 << bit)) | (CF << bit); - write(dp, rd); + data.bit(bit) = CF; + write(absolute, data); break; case 7: //not addr:bit - rd ^= 1 << bit; - write(dp, rd); + data.bit(bit) ^= 1; + write(absolute, data); break; } } @@ -176,136 +179,137 @@ auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void { } auto SPC700::instructionAbsoluteWrite(uint8& data) -> void { - dp.l = fetch(); - dp.h = fetch(); - read(dp); - write(dp, data); + uint16 absolute = fetch(); + absolute |= fetch() << 8; + read(absolute); + write(absolute, data); } auto SPC700::instructionAbsoluteIndexedWrite(uint8& index) -> void { - dp.l = fetch(); - dp.h = fetch(); + uint16 absolute = fetch(); + absolute |= fetch() << 8; idle(); - dp += index; - read(dp); - write(dp, A); + absolute += index; + read(absolute); + write(absolute, A); } auto SPC700::instructionDirectPageWrite(uint8& data) -> void { - dp = fetch(); - load(dp); - store(dp, data); + uint8 direct = fetch(); + load(direct); + store(direct, data); } auto SPC700::instructionDirectPageIndexedWrite(uint8& data, uint8& index) -> void { - dp = fetch() + index; + uint8 direct = fetch() + index; idle(); - load(dp); - store(dp, data); + load(direct); + store(direct, data); } auto SPC700::instructionDirectPageWriteImmediate(fpb op) -> void { - rd = fetch(); - dp = fetch(); - wr = load(dp); - wr = alu(wr, rd); - op != &SPC700::algorithmCMP ? store(dp, wr) : idle(); + uint8 immediate = fetch(); + uint8 direct = fetch(); + uint8 data = load(direct); + data = alu(data, immediate); + op != &SPC700::algorithmCMP ? store(direct, data) : idle(); } auto SPC700::instructionDirectPageWriteDirectPage(fpb op) -> void { - sp = fetch(); - rd = load(sp); - dp = fetch(); - if(op != &SPC700::algorithmST) wr = load(dp); - wr = alu(wr, rd); - op != &SPC700::algorithmCMP ? store(dp, wr) : idle(); + uint8 source = fetch(); + uint8 rhs = load(source); + uint8 target = fetch(); + uint8 lhs; + if(op != &SPC700::algorithmST) lhs = load(target); + lhs = alu(lhs, rhs); + op != &SPC700::algorithmCMP ? store(target, lhs) : idle(); } auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void { idle(); - rd = load(Y); - wr = load(X); - wr = alu(wr, rd); - op != &SPC700::algorithmCMP ? store(X, wr) : idle(); + uint8 rhs = load(Y); + uint8 lhs = load(X); + lhs = alu(lhs, rhs); + op != &SPC700::algorithmCMP ? store(X, lhs) : idle(); } // auto SPC700::instructionBBC(uint3 bit) -> void { - dp = fetch(); - uint8 data = load(dp); - rd = fetch(); + uint8 direct = fetch(); + uint8 data = load(direct); + uint8 displacement = fetch(); idle(); if(data.bit(bit) == 1) return; idle(); idle(); - PC += (int8)rd; + PC += (int8)displacement; } auto SPC700::instructionBBS(uint3 bit) -> void { - dp = fetch(); - uint8 data = load(dp); - rd = fetch(); + uint8 direct = fetch(); + uint8 data = load(direct); + uint8 displacement = fetch(); idle(); if(data.bit(bit) == 0) return; idle(); idle(); - PC += (int8)rd; + PC += (int8)displacement; } auto SPC700::instructionBNEDirectPage() -> void { - dp = fetch(); - sp = load(dp); - rd = fetch(); + uint8 direct = fetch(); + uint8 data = load(direct); + uint8 displacement = fetch(); idle(); - if(A == sp) return; + if(A == data) return; idle(); idle(); - PC += (int8)rd; + PC += (int8)displacement; } auto SPC700::instructionBNEDirectPageDecrement() -> void { - dp = fetch(); - wr = load(dp); - store(dp, --wr); - rd = fetch(); - if(wr == 0) return; + uint8 direct = fetch(); + uint8 data = load(direct); + store(direct, --data); + uint8 displacement = fetch(); + if(data == 0) return; idle(); idle(); - PC += (int8)rd; + PC += (int8)displacement; } auto SPC700::instructionBNEDirectPageX() -> void { - dp = fetch(); + uint8 direct = fetch(); idle(); - sp = load(dp + X); - rd = fetch(); + uint8 data = load(direct + X); + uint8 displacement = fetch(); idle(); - if(A == sp) return; + if(A == data) return; idle(); idle(); - PC += (int8)rd; + PC += (int8)displacement; } auto SPC700::instructionBNEYDecrement() -> void { - rd = fetch(); + uint8 displacement = fetch(); idle(); idle(); if(--Y == 0) return; idle(); idle(); - PC += (int8)rd; + PC += (int8)displacement; } auto SPC700::instructionBRK() -> void { - rd.l = read(0xffde); - rd.h = read(0xffdf); + uint16 absolute = read(0xffde); + absolute |= read(0xffdf) << 8; idle(); idle(); push(PC >> 8); push(PC >> 0); push(P); - PC = rd; + PC = absolute; IF = 0; BF = 1; } @@ -389,51 +393,51 @@ auto SPC700::instructionDIV() -> void { } auto SPC700::instructionJMPAbsolute() -> void { - rd.l = fetch(); - rd.h = fetch(); - PC = rd; + uint16 absolute = fetch(); + absolute |= fetch() << 8; + PC = absolute; } auto SPC700::instructionJMPIndirectAbsoluteX() -> void { - dp.l = fetch(); - dp.h = fetch(); + uint16 absolute = fetch(); + absolute |= fetch() << 8; idle(); - dp += X; - rd.l = read(dp++); - rd.h = read(dp++); - PC = rd; + absolute += X; + uint16 pc = read(absolute++); + pc |= read(absolute++) << 8; + PC = pc; } auto SPC700::instructionJSPDirectPage() -> void { - rd = fetch(); + uint8 direct = fetch(); idle(); idle(); push(PC >> 8); push(PC >> 0); - PC = 0xff00 | rd; + PC = 0xff00 | direct; } auto SPC700::instructionJSRAbsolute() -> void { - rd.l = fetch(); - rd.h = fetch(); + uint16 absolute = fetch(); + absolute |= fetch() << 8; idle(); idle(); idle(); push(PC >> 8); push(PC >> 0); - PC = rd; + PC = absolute; } auto SPC700::instructionJST(uint4 vector) -> void { - dp = 0xffde - (vector << 1); - rd.l = read(dp++); - rd.h = read(dp++); + uint16 absolute = 0xffde - (vector << 1); + uint16 pc = read(absolute++); + pc |= read(absolute++) << 8; idle(); idle(); idle(); push(PC >> 8); push(PC >> 0); - PC = rd; + PC = pc; } auto SPC700::instructionLDAIndirectXIncrement() -> void { @@ -473,19 +477,19 @@ auto SPC700::instructionPLP() -> void { auto SPC700::instructionRTI() -> void { P = pull(); - rd.l = pull(); - rd.h = pull(); + uint16 absolute = pull(); + absolute |= pull() << 8; idle(); idle(); - PC = rd; + PC = absolute; } auto SPC700::instructionRTS() -> void { - rd.l = pull(); - rd.h = pull(); + uint16 absolute = pull(); + absolute |= pull() << 8; idle(); idle(); - PC = rd; + PC = absolute; } auto SPC700::instructionSET(uint3 bit) -> void { @@ -496,22 +500,22 @@ auto SPC700::instructionSET(uint3 bit) -> void { } auto SPC700::instructionSTAIndirectPageX() -> void { - sp = fetch() + X; + uint8 direct = fetch() + X; idle(); - dp.l = load(sp++); - dp.h = load(sp++); - read(dp); - write(dp, A); + uint16 absolute = load(direct++); + absolute |= load(direct++) << 8; + read(absolute); + write(absolute, A); } auto SPC700::instructionSTAIndirectPageY() -> void { - sp = fetch(); - dp.l = load(sp++); - dp.h = load(sp++); + uint8 direct = fetch(); + uint16 absolute = load(direct++); + absolute |= load(direct++) << 8; idle(); - dp += Y; - read(dp); - write(dp, A); + absolute += Y; + read(absolute); + write(absolute, A); } auto SPC700::instructionSTAIndirectX() -> void { @@ -527,41 +531,43 @@ auto SPC700::instructionSTAIndirectXIncrement() -> void { } auto SPC700::instructionSTP() -> void { - while(true) { + r.stp = true; + while(r.stp && !synchronizing()) { idle(); idle(); } } auto SPC700::instructionSTWDirectPage() -> void { - dp = fetch(); - load(dp); - store(dp++, A); - store(dp++, Y); + uint8 direct = fetch(); + load(direct); + store(direct++, A); + store(direct++, Y); } auto SPC700::instructionTRBAbsolute() -> void { - dp.l = fetch(); - dp.h = fetch(); - rd = read(dp); - ZF = (A - rd) == 0; - NF = (A - rd) & 0x80; - read(dp); - write(dp, rd & ~A); + uint16 absolute = fetch(); + absolute |= fetch() << 8; + uint8 data = read(absolute); + ZF = (A - data) == 0; + NF = (A - data) & 0x80; + read(absolute); + write(absolute, data & ~A); } auto SPC700::instructionTSBAbsolute() -> void { - dp.l = fetch(); - dp.h = fetch(); - rd = read(dp); - ZF = (A - rd) == 0; - NF = (A - rd) & 0x80; - read(dp); - write(dp, rd | A); + uint16 absolute = fetch(); + absolute |= fetch() << 8; + uint8 data = read(absolute); + ZF = (A - data) == 0; + NF = (A - data) & 0x80; + read(absolute); + write(absolute, data | A); } auto SPC700::instructionWAI() -> void { - while(true) { + r.wai = true; + while(r.wai && !synchronizing()) { idle(); idle(); } @@ -576,5 +582,3 @@ auto SPC700::instructionXCN() -> void { ZF = A == 0; NF = A & 0x80; } - -#undef alu diff --git a/higan/processor/spc700/serialization.cpp b/higan/processor/spc700/serialization.cpp index 0e90b928..5ae8f32f 100644 --- a/higan/processor/spc700/serialization.cpp +++ b/higan/processor/spc700/serialization.cpp @@ -12,10 +12,6 @@ auto SPC700::serialize(serializer& s) -> void { s.integer(r.p.v); s.integer(r.p.n); - s.integer(opcode); - s.integer(dp.w); - s.integer(sp.w); - s.integer(rd.w); - s.integer(wr.w); - s.integer(bit.w); + s.integer(r.wai); + s.integer(r.stp); } diff --git a/higan/processor/spc700/spc700.cpp b/higan/processor/spc700/spc700.cpp index 93f14fca..15c1f54c 100644 --- a/higan/processor/spc700/spc700.cpp +++ b/higan/processor/spc700/spc700.cpp @@ -20,6 +20,8 @@ namespace Processor { #define VF r.p.v #define NF r.p.n +#define alu (this->*op) + #include "memory.cpp" #include "algorithms.cpp" #include "instructions.cpp" @@ -44,12 +46,17 @@ namespace Processor { #undef VF #undef NF +#undef alu + auto SPC700::power() -> void { r.pc.w = 0x0000; r.ya.w = 0x0000; r.x = 0x00; r.s = 0xef; r.p = 0x02; + + r.wai = false; + r.stp = false; } } diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index c930abe1..e2106e38 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -6,7 +6,9 @@ struct SPC700 { virtual auto idle() -> void = 0; virtual auto read(uint16 addr) -> uint8 = 0; virtual auto write(uint16 addr, uint8 data) -> void = 0; - virtual auto readDisassembler(uint16 addr) -> uint8 = 0; + virtual auto synchronizing() const -> bool = 0; + + virtual auto readDisassembler(uint16 addr) -> uint8 { return 0; } //spc700.cpp auto power() -> void; @@ -63,7 +65,7 @@ struct SPC700 { auto instructionIndirectPageXRead(fpb) -> void; auto instructionIndirectPageYRead(fpb) -> void; auto instructionIndirectXRead(fpb) -> void; - auto instructionAbsoluteModifyBit() -> void; + auto instructionAbsoluteModifyBit(uint3) -> void; auto instructionFlagClear(bool&) -> void; auto instructionFlagSet(bool&) -> void; auto instructionTransfer(uint8&, uint8&) -> void; @@ -152,34 +154,10 @@ struct SPC700 { } pc, ya; uint8 x, s; Flags p; + + bool wai = false; + bool stp = false; } r; - - struct Register { - union { - uint16_t w = 0; - NaturalBitField l; - NaturalBitField h; - }; - - inline operator uint() const { return w; } - inline auto operator=(const Register& value) { w = value.w; } - - inline auto operator++(int) { uint value = w++; return value; } - inline auto operator--(int) { uint value = w--; return value; } - - inline auto& operator++() { return ++w, *this; } - inline auto& operator--() { return --w, *this; } - - inline auto& operator =(uint value) { return w = value, *this; } - inline auto& operator&=(uint value) { return w &= value, *this; } - inline auto& operator|=(uint value) { return w |= value, *this; } - inline auto& operator^=(uint value) { return w ^= value, *this; } - inline auto& operator+=(uint value) { return w += value, *this; } - inline auto& operator-=(uint value) { return w -= value, *this; } - }; - - Register dp, sp, rd, wr, bit; - uint8 opcode; }; } diff --git a/higan/processor/z80/algorithms.cpp b/higan/processor/z80/algorithms.cpp new file mode 100644 index 00000000..73c32a93 --- /dev/null +++ b/higan/processor/z80/algorithms.cpp @@ -0,0 +1,252 @@ +auto Z80::ADD(uint8 x, uint8 y, bool c) -> uint8 { + uint9 z = x + y + c; + + CF = z.bit(8); + NF = 0; + VF = uint8(~(x ^ y) & (x ^ z)).bit(7); + XF = z.bit(3); + HF = uint8(x ^ y ^ z).bit(4); + YF = z.bit(5); + ZF = uint8(z) == 0; + SF = z.bit(7); + + return z; +} + +auto Z80::AND(uint8 x, uint8 y) -> uint8 { + uint8 z = x & y; + + CF = 0; + NF = 0; + PF = parity(z); + XF = z.bit(3); + HF = 1; + YF = z.bit(5); + ZF = z == 0; + SF = z.bit(7); + + return z; +} + +auto Z80::BIT(uint3 bit, uint8 x) -> uint8 { + uint8 z = x & 1 << bit; + + NF = 0; + PF = parity(z); + XF = z.bit(3); + HF = 1; + YF = z.bit(5); + ZF = z == 0; + SF = z.bit(7); + + return x; +} + +auto Z80::DEC(uint8 x) -> uint8 { + uint8 z = x - 1; + + NF = 1; + VF = z == 0x7f; + XF = z.bit(3); + HF = z.bits(0,3) == 0x0f; + YF = z.bit(5); + ZF = z == 0; + SF = z.bit(7); + + return z; +} + +auto Z80::INC(uint8 x) -> uint8 { + uint8 z = x + 1; + + NF = 0; + VF = z == 0x80; + XF = z.bit(3); + HF = z.bits(0,3) == 0x00; + YF = z.bit(5); + ZF = z == 0; + SF = z.bit(7); + + return z; +} + +auto Z80::OR(uint8 x, uint8 y) -> uint8 { + uint8 z = x | y; + + CF = 0; + NF = 0; + PF = parity(z); + XF = z.bit(3); + HF = 0; + YF = z.bit(5); + ZF = z == 0; + SF = z.bit(7); + + return z; +} + +auto Z80::RES(uint3 bit, uint8 x) -> uint8 { + x &= ~(1 << bit); + return x; +} + +auto Z80::RL(uint8 x) -> uint8 { + bool c = x.bit(7); + x = x << 1 | CF; + + CF = c; + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::RLC(uint8 x) -> uint8 { + x = x << 1 | x >> 7; + + CF = x.bit(0); + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::RR(uint8 x) -> uint8 { + bool c = x.bit(0); + x = x >> 1 | CF << 7; + + CF = c; + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::RRC(uint8 x) -> uint8 { + x = x >> 1 | x << 7; + + CF = x.bit(7); + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::SET(uint3 bit, uint8 x) -> uint8 { + x |= (1 << bit); + return x; +} + +auto Z80::SLA(uint8 x) -> uint8 { + bool c = x.bit(7); + x = x << 1; + + CF = c; + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::SLL(uint8 x) -> uint8 { + bool c = x.bit(7); + x = x << 1 | 1; + + CF = c; + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::SRA(uint8 x) -> uint8 { + bool c = x.bit(0); + x = (int8)x >> 1; + + CF = c; + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::SRL(uint8 x) -> uint8 { + bool c = x.bit(0); + x = x >> 1; + + CF = c; + NF = 0; + PF = parity(x); + XF = x.bit(3); + HF = 0; + YF = x.bit(5); + ZF = x == 0; + SF = x.bit(7); + + return x; +} + +auto Z80::SUB(uint8 x, uint8 y, bool c) -> uint8 { + uint9 z = x - y - c; + + CF = z.bit(8); + NF = 1; + VF = uint8((x ^ y) & (x ^ z)).bit(7); + XF = z.bit(3); + HF = uint8(x ^ y ^ z).bit(4); + YF = z.bit(5); + ZF = uint8(z) == 0; + SF = z.bit(7); + + return z; +} + +auto Z80::XOR(uint8 x, uint8 y) -> uint8 { + uint8 z = x ^ y; + + CF = 0; + NF = 0; + PF = parity(z); + XF = z.bit(3); + HF = 0; + YF = z.bit(5); + ZF = z == 0; + SF = z.bit(7); + + return z; +} diff --git a/higan/processor/z80/instructions.cpp b/higan/processor/z80/instructions.cpp index 8f834fde..2a24487d 100644 --- a/higan/processor/z80/instructions.cpp +++ b/higan/processor/z80/instructions.cpp @@ -10,261 +10,6 @@ // nn = operand-word // r = register -auto Z80::ADD(uint8 x, uint8 y, bool c) -> uint8 { - uint9 z = x + y + c; - - CF = z.bit(8); - NF = 0; - VF = uint8(~(x ^ y) & (x ^ z)).bit(7); - XF = z.bit(3); - HF = uint8(x ^ y ^ z).bit(4); - YF = z.bit(5); - ZF = uint8(z) == 0; - SF = z.bit(7); - - return z; -} - -auto Z80::AND(uint8 x, uint8 y) -> uint8 { - uint8 z = x & y; - - CF = 0; - NF = 0; - PF = parity(z); - XF = z.bit(3); - HF = 1; - YF = z.bit(5); - ZF = z == 0; - SF = z.bit(7); - - return z; -} - -auto Z80::BIT(uint3 bit, uint8 x) -> uint8 { - uint8 z = x & 1 << bit; - - NF = 0; - PF = parity(z); - XF = z.bit(3); - HF = 1; - YF = z.bit(5); - ZF = z == 0; - SF = z.bit(7); - - return x; -} - -auto Z80::DEC(uint8 x) -> uint8 { - uint8 z = x - 1; - - NF = 1; - VF = z == 0x7f; - XF = z.bit(3); - HF = z.bits(0,3) == 0x0f; - YF = z.bit(5); - ZF = z == 0; - SF = z.bit(7); - - return z; -} - -auto Z80::INC(uint8 x) -> uint8 { - uint8 z = x + 1; - - NF = 0; - VF = z == 0x80; - XF = z.bit(3); - HF = z.bits(0,3) == 0x00; - YF = z.bit(5); - ZF = z == 0; - SF = z.bit(7); - - return z; -} - -auto Z80::OR(uint8 x, uint8 y) -> uint8 { - uint8 z = x | y; - - CF = 0; - NF = 0; - PF = parity(z); - XF = z.bit(3); - HF = 0; - YF = z.bit(5); - ZF = z == 0; - SF = z.bit(7); - - return z; -} - -auto Z80::RES(uint3 bit, uint8 x) -> uint8 { - x &= ~(1 << bit); - return x; -} - -auto Z80::RL(uint8 x) -> uint8 { - bool c = x.bit(7); - x = x << 1 | CF; - - CF = c; - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::RLC(uint8 x) -> uint8 { - x = x << 1 | x >> 7; - - CF = x.bit(0); - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::RR(uint8 x) -> uint8 { - bool c = x.bit(0); - x = x >> 1 | CF << 7; - - CF = c; - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::RRC(uint8 x) -> uint8 { - x = x >> 1 | x << 7; - - CF = x.bit(7); - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::SET(uint3 bit, uint8 x) -> uint8 { - x |= (1 << bit); - return x; -} - -auto Z80::SLA(uint8 x) -> uint8 { - bool c = x.bit(7); - x = x << 1; - - CF = c; - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::SLL(uint8 x) -> uint8 { - bool c = x.bit(7); - x = x << 1 | 1; - - CF = c; - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::SRA(uint8 x) -> uint8 { - bool c = x.bit(0); - x = (int8)x >> 1; - - CF = c; - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::SRL(uint8 x) -> uint8 { - bool c = x.bit(0); - x = x >> 1; - - CF = c; - NF = 0; - PF = parity(x); - XF = x.bit(3); - HF = 0; - YF = x.bit(5); - ZF = x == 0; - SF = x.bit(7); - - return x; -} - -auto Z80::SUB(uint8 x, uint8 y, bool c) -> uint8 { - uint9 z = x - y - c; - - CF = z.bit(8); - NF = 1; - VF = uint8((x ^ y) & (x ^ z)).bit(7); - XF = z.bit(3); - HF = uint8(x ^ y ^ z).bit(4); - YF = z.bit(5); - ZF = uint8(z) == 0; - SF = z.bit(7); - - return z; -} - -auto Z80::XOR(uint8 x, uint8 y) -> uint8 { - uint8 z = x ^ y; - - CF = 0; - NF = 0; - PF = parity(z); - XF = z.bit(3); - HF = 0; - YF = z.bit(5); - ZF = z == 0; - SF = z.bit(7); - - return z; -} - -// - auto Z80::instructionADC_a_irr(uint16& x) -> void { A = ADD(A, read(displace(x)), CF); } diff --git a/higan/processor/z80/z80.cpp b/higan/processor/z80/z80.cpp index 25ca4532..bcfbb359 100644 --- a/higan/processor/z80/z80.cpp +++ b/higan/processor/z80/z80.cpp @@ -7,6 +7,7 @@ namespace Processor { #include "registers.cpp" #include "memory.cpp" #include "instruction.cpp" +#include "algorithms.cpp" #include "instructions.cpp" #include "serialization.cpp" diff --git a/higan/processor/z80/z80.hpp b/higan/processor/z80/z80.hpp index e51a6e80..b6627c7a 100644 --- a/higan/processor/z80/z80.hpp +++ b/higan/processor/z80/z80.hpp @@ -55,7 +55,7 @@ struct Z80 { auto instructionCBd(uint16 addr, uint8 code) -> void; auto instructionED(uint8 code) -> void; - //instructions.cpp + //algorithms.cpp auto ADD(uint8, uint8, bool = false) -> uint8; auto AND(uint8, uint8) -> uint8; auto BIT(uint3, uint8) -> uint8; @@ -75,6 +75,7 @@ struct Z80 { auto SUB(uint8, uint8, bool = false) -> uint8; auto XOR(uint8, uint8) -> uint8; + //instructions.cpp auto instructionADC_a_irr(uint16&) -> void; auto instructionADC_a_n() -> void; auto instructionADC_a_r(uint8&) -> void; diff --git a/higan/sfc/dsp/dsp.cpp b/higan/sfc/dsp/dsp.cpp index 379aac17..6bbea19f 100644 --- a/higan/sfc/dsp/dsp.cpp +++ b/higan/sfc/dsp/dsp.cpp @@ -246,15 +246,10 @@ auto DSP::power() -> void { voice[n].vidx = n * 0x10; } - for(auto r : range(0x80)) { - REG(r) = random(0x00); - } - - for(auto v : range(8)) { - REG(v * 0x10 + ENVX) = 0; - REG(v * 0x10 + OUTX) = 0; - } - + //note: memory is pseudo-random at startup; but internal state is less so + //exact differences are unknown. need to separate memory from internal state + for(auto r : range(0x80)) REG(r) = 0x00; + REG(ENDX) = random(0x00); REG(FLG) = 0xe0; } diff --git a/higan/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp index 9ea8c1ac..eda23318 100644 --- a/higan/sfc/smp/smp.cpp +++ b/higan/sfc/smp/smp.cpp @@ -8,11 +8,17 @@ SMP smp; #include "timing.cpp" #include "serialization.cpp" +auto SMP::synchronizing() const -> bool { + return scheduler.synchronizing(); +} + auto SMP::Enter() -> void { while(true) scheduler.synchronize(), smp.main(); } auto SMP::main() -> void { + if(r.wai) return instructionWAI(); + if(r.stp) return instructionSTP(); instruction(); } diff --git a/higan/sfc/smp/smp.hpp b/higan/sfc/smp/smp.hpp index c6b70dd5..ecb9eeff 100644 --- a/higan/sfc/smp/smp.hpp +++ b/higan/sfc/smp/smp.hpp @@ -1,6 +1,9 @@ //Sony CXP1100Q-1 struct SMP : Processor::SPC700, Thread { + //smp.cpp + auto synchronizing() const -> bool override; + auto readPort(uint2 port) const -> uint8; auto writePort(uint2 port, uint8 data) -> void; @@ -8,6 +11,7 @@ struct SMP : Processor::SPC700, Thread { auto load(Markup::Node) -> bool; auto power() -> void; + //serialization.cpp auto serialize(serializer&) -> void; uint8 iplrom[64];