From 969ec470e4e37ab229d7fc8e9b2c5b9df0fd3b62 Mon Sep 17 00:00:00 2001 From: Chris Moeller Date: Sun, 27 Oct 2013 05:42:03 -0700 Subject: [PATCH] Implemented the SMP disassembler, for debugging purposes --- Frameworks/GME/GME.xcodeproj/project.pbxproj | 4 + Frameworks/GME/gme/Spc_Emu.cpp | 10 +- .../higan/processor/spc700/disassembler.cpp | 325 ++++++++++++++++++ .../GME/gme/higan/processor/spc700/spc700.cpp | 5 + .../GME/gme/higan/processor/spc700/spc700.hpp | 15 + Frameworks/GME/gme/higan/smp/memory.cpp | 6 + Frameworks/GME/gme/higan/smp/smp.hpp | 2 + 7 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 Frameworks/GME/gme/higan/processor/spc700/disassembler.cpp diff --git a/Frameworks/GME/GME.xcodeproj/project.pbxproj b/Frameworks/GME/GME.xcodeproj/project.pbxproj index ea3e84b2b..fffbe172a 100644 --- a/Frameworks/GME/GME.xcodeproj/project.pbxproj +++ b/Frameworks/GME/GME.xcodeproj/project.pbxproj @@ -1255,6 +1255,8 @@ 1DEB91AE08733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LIBRARY = "libc++"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1285,6 +1287,8 @@ 1DEB91AF08733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LIBRARY = "libc++"; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; diff --git a/Frameworks/GME/gme/Spc_Emu.cpp b/Frameworks/GME/gme/Spc_Emu.cpp index abe59015f..dd193b9c6 100644 --- a/Frameworks/GME/gme/Spc_Emu.cpp +++ b/Frameworks/GME/gme/Spc_Emu.cpp @@ -376,10 +376,14 @@ blargg_err_t Spc_Emu::start_track_( int track ) smp.regs.s = header.sp; memcpy( smp.apuram, ptr, 0x10000 ); - - static const uint8_t regs_to_copy[] = { 0xF1, 0xF2, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC }; - for (auto n : regs_to_copy) smp.op_buswrite( n, ptr[ n ] ); + memset( smp.apuram + 0xF4, 0, 4 ); memcpy( smp.sfm_last, ptr + 0xF4, 4 ); + + static const uint8_t regs_to_copy[][2] = { {0xFC,0xFF}, {0xFB,0xFF}, {0xFA,0xFF}, {0xF9,0xFF}, {0xF8,0xFF}, {0xF2,0xFF}, {0xF1,0x87} }; + for (auto n : regs_to_copy) smp.op_buswrite( n[0], ptr[ n[0] ] & n[1] ); + smp.timer0.stage3_ticks = ptr[ 0xFD ] & 0x0F; + smp.timer1.stage3_ticks = ptr[ 0xFE ] & 0x0F; + smp.timer2.stage3_ticks = ptr[ 0xFF ] & 0x0F; ptr += 0x10000; smp.dsp.spc_dsp.load( ptr ); diff --git a/Frameworks/GME/gme/higan/processor/spc700/disassembler.cpp b/Frameworks/GME/gme/higan/processor/spc700/disassembler.cpp new file mode 100644 index 000000000..9866a3d76 --- /dev/null +++ b/Frameworks/GME/gme/higan/processor/spc700/disassembler.cpp @@ -0,0 +1,325 @@ +template std::string hex(uintmax_t value) { + std::string buffer; + buffer.resize(sizeof(uintmax_t) * 2); + + unsigned size = 0; + do { + unsigned n = value & 15; + buffer[size++] = n < 10 ? '0' + n : 'a' + n - 10; + value >>= 4; + } while(size < precision); + buffer.resize(precision); + const unsigned size_half = precision / 2; + for (unsigned i = 0; i < size_half; ++i) { + char temp = buffer[i]; + buffer[i] = buffer[size - i - 1]; + buffer[size - i - 1] = temp; + } + + return buffer; +} + +std::string SPC700::disassemble_opcode(uint16_t addr) { + auto read = [&](uint16_t addr) -> uint8_t { + return disassembler_read(addr); + }; + + auto relative = [&](unsigned length, int8_t offset) -> uint16_t { + uint16_t pc = addr + length; + return pc + offset; + }; + + auto a = [&] { return hex<4>((read(addr + 1) << 0) + (read(addr + 2) << 8)); }; + auto b = [&](unsigned n) { return hex<2>(read(addr + 1 + n)); }; + auto r = [&](unsigned r, unsigned n = 0) { return hex<4>(addr + r + (int8_t)read(addr + 1 + n)); }; + auto dp = [&](unsigned n) { return hex<3>((regs.p.p << 8) + read(addr + 1 + n)); }; + auto ab = [&] { + unsigned n = (read(addr + 1) << 0) + (read(addr + 2) << 8); + return hex<4>(n & 0x1fff) + ":" + hex<1>(n >> 13); + }; + + auto mnemonic = [&]() -> std::string { + switch(read(addr)) { + case 0x00: return "nop"; + case 0x01: return "jst $ffde"; + case 0x02: return (std::string)"set $" + dp(0) + ":0"; + case 0x03: return (std::string)"bbs $" + dp(0) + ":0=$" + r(+3, 1); + case 0x04: return (std::string)"ora $" + dp(0); + case 0x05: return (std::string)"ora $" + a(); + case 0x06: return "ora (x)"; + case 0x07: return (std::string)"ora ($" + dp(0) + ",x)"; + case 0x08: return (std::string)"ora #$" + b(0); + case 0x09: return (std::string)"orr $" + dp(1) + "=$" + dp(0); + case 0x0a: return (std::string)"orc $" + ab(); + case 0x0b: return (std::string)"asl $" + dp(0); + case 0x0c: return (std::string)"asl $" + a(); + case 0x0d: return "php"; + case 0x0e: return (std::string)"tsb $" + a(); + case 0x0f: return "brk"; + case 0x10: return (std::string)"bpl $" + r(+2); + case 0x11: return "jst $ffdc"; + case 0x12: return (std::string)"clr $" + dp(0) + ":0"; + case 0x13: return (std::string)"bbc $" + dp(0) + ":0=$" + r(+3, 1); + case 0x14: return (std::string)"ora $" + dp(0) + ",x"; + case 0x15: return (std::string)"ora $" + a() + ",x"; + case 0x16: return (std::string)"ora $" + a() + ",y"; + case 0x17: return (std::string)"ora ($" + dp(0) + "),y"; + case 0x18: return (std::string)"orr $" + dp(1) + "=#$" + b(0); + case 0x19: return "orr (x)=(y)"; + case 0x1a: return (std::string)"dew $" + dp(0); + case 0x1b: return (std::string)"asl $" + dp(0) + ",x"; + case 0x1c: return "asl"; + case 0x1d: return "dex"; + case 0x1e: return (std::string)"cpx $" + a(); + case 0x1f: return (std::string)"jmp ($" + a() + ",x)"; + case 0x20: return "clp"; + case 0x21: return "jst $ffda"; + case 0x22: return (std::string)"set $" + dp(0) + ":1"; + case 0x23: return (std::string)"bbs $" + dp(0) + ":1=$" + r(+3, 1); + case 0x24: return (std::string)"and $" + dp(0); + case 0x25: return (std::string)"and $" + a(); + case 0x26: return "and (x)"; + case 0x27: return (std::string)"and ($" + dp(0) + ",x)"; + case 0x29: return (std::string)"and $" + dp(1) + "=$" + dp(0); + case 0x2a: return (std::string)"orc !$" + ab(); + case 0x2b: return (std::string)"rol $" + dp(0); + case 0x2c: return (std::string)"rol $" + a(); + case 0x2d: return "pha"; + case 0x2e: return (std::string)"bne $" + dp(0) + "=$" + r(+3, 1); + case 0x28: return (std::string)"and #$" + b(0); + case 0x2f: return (std::string)"bra $" + r(+2); + case 0x30: return (std::string)"bmi $" + r(+2); + case 0x31: return "jst $ffd8"; + case 0x32: return (std::string)"clr $" + dp(0) + ":1"; + case 0x33: return (std::string)"bbc $" + dp(0) + ":1=$" + r(+3, 1); + case 0x34: return (std::string)"and $" + dp(0) + ",x"; + case 0x35: return (std::string)"and $" + a() + ",x"; + case 0x36: return (std::string)"and $" + a() + ",y"; + case 0x37: return (std::string)"and ($" + dp(0) + "),y"; + case 0x38: return (std::string)"and $" + dp(1) + "=#$" + b(0); + case 0x39: return "and (x)=(y)"; + case 0x3a: return (std::string)"inw $" + dp(0); + case 0x3b: return (std::string)"rol $" + dp(0) + ",x"; + case 0x3c: return "rol"; + case 0x3d: return "inx"; + case 0x3e: return (std::string)"cpx $" + dp(0); + case 0x3f: return (std::string)"jsr $" + a(); + case 0x40: return "sep"; + case 0x41: return "jst $ffd6"; + case 0x42: return (std::string)"set $" + dp(0) + ":2"; + case 0x43: return (std::string)"bbs $" + dp(0) + ":2=$" + r(+3, 1); + case 0x44: return (std::string)"eor $" + dp(0); + case 0x45: return (std::string)"eor $" + a(); + case 0x46: return "eor (x)"; + case 0x47: return (std::string)"eor ($" + dp(0) + ",x)"; + case 0x48: return (std::string)"eor #$" + b(0); + case 0x49: return (std::string)"eor $" + dp(1) + "=$" + dp(0); + case 0x4a: return (std::string)"and $" + ab(); + case 0x4b: return (std::string)"lsr $" + dp(0); + case 0x4c: return (std::string)"lsr $" + a(); + case 0x4d: return "phx"; + case 0x4e: return (std::string)"trb $" + a(); + case 0x4f: return (std::string)"jsp $ff" + b(0); + case 0x50: return (std::string)"bvc $" + r(+2); + case 0x51: return "jst $ffd4"; + case 0x52: return (std::string)"clr $" + dp(0) + ":2"; + case 0x53: return (std::string)"bbc $" + dp(0) + ":2=$" + r(+3, 1); + case 0x54: return (std::string)"eor $" + dp(0) + ",x"; + case 0x55: return (std::string)"eor $" + a() + ",x"; + case 0x56: return (std::string)"eor $" + a() + ",y"; + case 0x57: return (std::string)"eor ($" + dp(0) + "),y"; + case 0x58: return (std::string)"eor $" + dp(1) + "=#$" + b(0); + case 0x59: return "eor (x)=(y)"; + case 0x5a: return (std::string)"cpw $" + a(); + case 0x5b: return (std::string)"lsr $" + dp(0) + ",x"; + case 0x5c: return "lsr"; + case 0x5d: return "tax"; + case 0x5e: return (std::string)"cpy $" + a(); + case 0x5f: return (std::string)"jmp $" + a(); + case 0x60: return "clc"; + case 0x61: return "jst $ffd2"; + case 0x62: return (std::string)"set $" + dp(0) + ":3"; + case 0x63: return (std::string)"bbs $" + dp(0) + ":3=$" + r(+3, 1); + case 0x64: return (std::string)"cmp $" + dp(0); + case 0x65: return (std::string)"cmp $" + a(); + case 0x66: return "cmp (x)"; + case 0x67: return (std::string)"cmp ($" + dp(0) + ",x)"; + case 0x68: return (std::string)"cmp #$" + b(0); + case 0x69: return (std::string)"cmp $" + dp(1) + "=$" + dp(0); + case 0x6a: return (std::string)"and !$" + ab(); + case 0x6b: return (std::string)"ror $" + dp(0); + case 0x6c: return (std::string)"ror $" + a(); + case 0x6d: return "phy"; + case 0x6e: return (std::string)"bne --$" + dp(0) + "=$" + r(+3, 1); + case 0x6f: return "rts"; + case 0x70: return (std::string)"bvs $" + r(+2); + case 0x71: return "jst $ffd0"; + case 0x72: return (std::string)"clr $" + dp(0) + ":3"; + case 0x73: return (std::string)"bbc $" + dp(0) + ":3=$" + r(+3, 1); + case 0x74: return (std::string)"cmp $" + dp(0) + ",x"; + case 0x75: return (std::string)"cmp $" + a() + ",x"; + case 0x76: return (std::string)"cmp $" + a() + ",y"; + case 0x77: return (std::string)"cmp ($" + dp(0) + "),y"; + case 0x78: return (std::string)"cmp $" + dp(1) + "=#$" + b(0); + case 0x79: return "cmp (x)=(y)"; + case 0x7a: return (std::string)"adw $" + a(); + case 0x7b: return (std::string)"ror $" + dp(0) + ",x"; + case 0x7c: return "ror"; + case 0x7d: return "txa"; + case 0x7e: return (std::string)"cpy $" + dp(0); + case 0x7f: return "rti"; + case 0x80: return "sec"; + case 0x81: return "jst $ffce"; + case 0x82: return (std::string)"set $" + dp(0) + ":4"; + case 0x83: return (std::string)"bbs $" + dp(0) + ":4=$" + r(+3, 1); + case 0x84: return (std::string)"adc $" + dp(0); + case 0x85: return (std::string)"adc $" + a(); + case 0x86: return "adc (x)"; + case 0x87: return (std::string)"adc ($" + dp(0) + ",x)"; + case 0x88: return (std::string)"adc #$" + b(0); + case 0x89: return (std::string)"adc $" + dp(1) + "=$" + dp(0); + case 0x8a: return (std::string)"eor $" + ab(); + case 0x8b: return (std::string)"dec $" + dp(0); + case 0x8c: return (std::string)"dec $" + a(); + case 0x8d: return (std::string)"ldy #$" + b(0); + case 0x8e: return "plp"; + case 0x8f: return (std::string)"str $" + dp(1) + "=#$" + b(0); + case 0x90: return (std::string)"bcc $" + r(+2); + case 0x91: return "jst $ffcc"; + case 0x92: return (std::string)"clr $" + dp(0) + ":4"; + case 0x93: return (std::string)"bbc $" + dp(0) + ":4=$" + r(+3, 1); + case 0x94: return (std::string)"adc $" + dp(0) + ",x"; + case 0x95: return (std::string)"adc $" + a() + ",x"; + case 0x96: return (std::string)"adc $" + a() + ",y"; + case 0x97: return (std::string)"adc ($" +dp(0) + "),y"; + case 0x98: return (std::string)"adc $" + dp(1) + "=#$" + b(0); + case 0x99: return "adc (x)=(y)"; + case 0x9a: return (std::string)"sbw $" + a(); + case 0x9b: return (std::string)"dec $" + dp(0) + ",x"; + case 0x9c: return "dec"; + case 0x9d: return "tsx"; + case 0x9e: return "div"; + case 0x9f: return "xcn"; + case 0xa0: return "sei"; + case 0xa1: return "jst $ffca"; + case 0xa2: return (std::string)"set $" + dp(0) + ":5"; + case 0xa3: return (std::string)"bbs $" + dp(0) + ":5=$" + r(+3, 1); + case 0xa4: return (std::string)"sbc $" + dp(0); + case 0xa5: return (std::string)"sbc $" + a(); + case 0xa6: return "sbc (x)"; + case 0xa7: return (std::string)"sbc ($" + dp(0) + ",x)"; + case 0xa8: return (std::string)"sbc #$" + b(0); + case 0xa9: return (std::string)"sbc $" + dp(1) + "=$" + dp(0); + case 0xaa: return (std::string)"ldc $" + ab(); + case 0xab: return (std::string)"inc $" + dp(0); + case 0xac: return (std::string)"inc $" + a(); + case 0xad: return (std::string)"cpy #$" + b(0); + case 0xae: return "pla"; + case 0xaf: return "sta (x++)"; + case 0xb0: return (std::string)"bcs $" + r(+2); + case 0xb1: return "jst $ffc8"; + case 0xb2: return (std::string)"clr $" + dp(0) + ":5"; + case 0xb3: return (std::string)"bbc $" + dp(0) + ":5=$" + r(+3, 1); + case 0xb4: return (std::string)"sbc $" + dp(0) + ",x"; + case 0xb5: return (std::string)"sbc $" + a() + ",x"; + case 0xb6: return (std::string)"sbc $" + a() + ",y"; + case 0xb7: return (std::string)"sbc ($" + dp(0) + "),y"; + case 0xb8: return (std::string)"sbc $" + dp(1) + "=#$" + b(0); + case 0xb9: return "sbc (x)=(y)"; + case 0xba: return (std::string)"ldw $" + dp(0); + case 0xbb: return (std::string)"inc $" + dp(0) + ",x"; + case 0xbc: return "inc"; + case 0xbd: return "txs"; + case 0xbe: return "das"; + case 0xbf: return "lda (x++)"; + case 0xc0: return "cli"; + case 0xc1: return "jst $ffc6"; + case 0xc2: return (std::string)"set $" + dp(0) + ":6"; + case 0xc3: return (std::string)"bbs $" + dp(0) + ":6=$" + r(+3, 1); + case 0xc4: return (std::string)"sta $" + dp(0); + case 0xc5: return (std::string)"sta $" + a(); + case 0xc6: return "sta (x)"; + case 0xc7: return (std::string)"sta ($" + dp(0) + ",x)"; + case 0xc8: return (std::string)"cpx #$" + b(0); + case 0xc9: return (std::string)"stx $" + a(); + case 0xca: return (std::string)"stc $" + ab(); + case 0xcb: return (std::string)"sty $" + dp(0); + case 0xcc: return (std::string)"sty $" + a(); + case 0xcd: return (std::string)"ldx #$" + b(0); + case 0xce: return "plx"; + case 0xcf: return "mul"; + case 0xd0: return (std::string)"bne $" + r(+2); + case 0xd1: return "jst $ffc4"; + case 0xd2: return (std::string)"clr $" + dp(0) + ":6"; + case 0xd3: return (std::string)"bbc $" + dp(0) + ":6=$" + r(+3, 1); + case 0xd4: return (std::string)"sta $" + dp(0) + ",x"; + case 0xd5: return (std::string)"sta $" + a() + ",x"; + case 0xd6: return (std::string)"sta $" + a() + ",y"; + case 0xd7: return (std::string)"sta ($" + dp(0) + "),y"; + case 0xd8: return (std::string)"stx $" + dp(0); + case 0xd9: return (std::string)"stx $" + dp(0) + ",y"; + case 0xda: return (std::string)"stw $" + dp(0); + case 0xdb: return (std::string)"sty $" + dp(0) + ",x"; + case 0xdc: return "dey"; + case 0xdd: return "tya"; + case 0xde: return (std::string)"bne $" + dp(0) + ",x=$" + r(+3, 1); + case 0xdf: return "daa"; + case 0xe0: return "clv"; + case 0xe1: return "jst $ffc2"; + case 0xe2: return (std::string)"set $" + dp(0) + ":7"; + case 0xe3: return (std::string)"bbs $" + dp(0) + ":7=$" + r(+3, 1); + case 0xe4: return (std::string)"lda $" + dp(0); + case 0xe5: return (std::string)"lda $" + a(); + case 0xe6: return "lda (x)"; + case 0xe7: return (std::string)"lda ($" + dp(0) + ",x)"; + case 0xe8: return (std::string)"lda #$" + b(0); + case 0xe9: return (std::string)"ldx $" + a(); + case 0xea: return (std::string)"not $" + ab(); + case 0xeb: return (std::string)"ldy $" + dp(0); + case 0xec: return (std::string)"ldy $" + a(); + case 0xed: return "cmc"; + case 0xee: return "ply"; + case 0xef: return "wai"; + case 0xf0: return (std::string)"beq $" + r(+2); + case 0xf1: return "jst $ffc0"; + case 0xf2: return (std::string)"clr $" + dp(0) + ":7"; + case 0xf3: return (std::string)"bbc $" + dp(0) + ":7=$" + r(+3, 1); + case 0xf4: return (std::string)"lda $" + dp(0) + ",x"; + case 0xf5: return (std::string)"lda $" + a() + ",x"; + case 0xf6: return (std::string)"lda $" + a() + ",y"; + case 0xf7: return (std::string)"lda ($" + dp(0) + "),y"; + case 0xf8: return (std::string)"ldx $" + dp(0); + case 0xf9: return (std::string)"ldx $" + dp(0) + ",y"; + case 0xfa: return (std::string)"str $" + dp(1) + "=$" + dp(0); + case 0xfb: return (std::string)"ldy $" + dp(0) + ",x"; + case 0xfc: return "iny"; + case 0xfd: return "tay"; + case 0xfe: return (std::string)"bne --y=$" + r(+2); + case 0xff: return "stp"; + } + throw; + }; + + std::string output = (std::string)".." + hex<4>(addr) + " " + mnemonic(); + + unsigned length = output.length(); + while(length++ < 30) output.append(" "); + + output += + "YA:" + hex<4>(regs.ya) + + " A:" + hex<2>(regs.a) + + " X:" + hex<2>(regs.x) + + " Y:" + hex<2>(regs.y) + + " S:" + hex<2>(regs.s) + + " " + + (regs.p.n ? "N" : "n") + + (regs.p.v ? "V" : "v") + + (regs.p.p ? "P" : "p") + + (regs.p.b ? "B" : "b") + + (regs.p.h ? "H" : "h") + + (regs.p.i ? "I" : "i") + + (regs.p.z ? "Z" : "z") + + (regs.p.c ? "C" : "c"); + + return output; +} diff --git a/Frameworks/GME/gme/higan/processor/spc700/spc700.cpp b/Frameworks/GME/gme/higan/processor/spc700/spc700.cpp index 0324c30d1..ed68d02a6 100755 --- a/Frameworks/GME/gme/higan/processor/spc700/spc700.cpp +++ b/Frameworks/GME/gme/higan/processor/spc700/spc700.cpp @@ -4,8 +4,13 @@ namespace Processor { #include "algorithms.cpp" #include "instructions.cpp" +#include "disassembler.cpp" void SPC700::op_step() { +#if 0 + std::string disasm = disassemble_opcode(regs.pc) + "\n"; + fputs(disasm.c_str(), f); +#endif switch(opcode = op_readpc()) { case 0x00: return op_nop(); case 0x01: return op_jst(); diff --git a/Frameworks/GME/gme/higan/processor/spc700/spc700.hpp b/Frameworks/GME/gme/higan/processor/spc700/spc700.hpp index c8b231c26..88641a248 100755 --- a/Frameworks/GME/gme/higan/processor/spc700/spc700.hpp +++ b/Frameworks/GME/gme/higan/processor/spc700/spc700.hpp @@ -2,14 +2,27 @@ #define PROCESSOR_SPC700_HPP #include +#include +#include +#if 0 +#include +#endif namespace Processor { struct SPC700 { +#if 0 + FILE *f; + SPC700() { f = fopen("/tmp/spc_disasm", "w"); } + ~SPC700() { fclose(f); } +#endif + virtual void op_io() = 0; virtual uint8_t op_read(uint16_t addr) = 0; virtual void op_write(uint16_t addr, uint8_t data) = 0; void op_step(); + + virtual uint8_t disassembler_read(uint16_t addr) = 0; #include "registers.hpp" #include "memory.hpp" @@ -17,6 +30,8 @@ struct SPC700 { regs_t regs; word_t dp, sp, rd, wr, bit, ya; uint8_t opcode; + + std::string disassemble_opcode(uint16_t addr); protected: uint8_t op_adc(uint8_t, uint8_t); diff --git a/Frameworks/GME/gme/higan/smp/memory.cpp b/Frameworks/GME/gme/higan/smp/memory.cpp index d3836b543..d390834d5 100755 --- a/Frameworks/GME/gme/higan/smp/memory.cpp +++ b/Frameworks/GME/gme/higan/smp/memory.cpp @@ -191,4 +191,10 @@ void SMP::op_write(uint16_t addr, uint8_t data) { cycle_edge(); } +uint8_t SMP::disassembler_read(uint16_t addr) { + if((addr & 0xfff0) == 0x00f0) return 0x00; + if((addr & 0xffc0) == 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; + return apuram[addr]; +} + #endif diff --git a/Frameworks/GME/gme/higan/smp/smp.hpp b/Frameworks/GME/gme/higan/smp/smp.hpp index 6aee02723..6c3a6f899 100755 --- a/Frameworks/GME/gme/higan/smp/smp.hpp +++ b/Frameworks/GME/gme/higan/smp/smp.hpp @@ -89,6 +89,8 @@ public: void op_io(); uint8_t op_read(uint16_t addr); void op_write(uint16_t addr, uint8_t data); + + uint8_t disassembler_read(uint16_t addr); //timing.cpp template