From a1e4c67a059e1c845f77f6020003aebcb5c3c590 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 14 May 2012 23:32:55 +1000 Subject: [PATCH] Update to v089r02 release. (r01 was not posted to the WIP thread) byuu says: r01 changelog: - major improvements to SPC7110 MCU (memory controller unit) - revised SPC7110 memory map to reflect aforementioned improvements - added "Toggle Tracer" hotkey to target-ethos (only works for SFC so far, I plan to use this as a lightweight laevateinn for FEoEZ) r02 changelog: - quick fix: SRAM is mapped to 00-3f|80-bf:6000-7fff - quick fix: $4830.d7 is SRAM chip enable, not SRAM write enable. Reads return 0x00 when this bit is clear --- bsnes/emulator/emulator.hpp | 2 +- bsnes/emulator/interface.hpp | 5 +- bsnes/fc/interface/interface.cpp | 2 +- bsnes/fc/interface/interface.hpp | 2 +- bsnes/gb/interface/interface.cpp | 2 +- bsnes/gb/interface/interface.hpp | 2 +- bsnes/gba/interface/interface.cpp | 2 +- bsnes/gba/interface/interface.hpp | 2 +- bsnes/nall/snes/cartridge.hpp | 31 +- bsnes/processor/r65816/disassembler.cpp | 540 +++++++------- bsnes/sfc/cartridge/markup.cpp | 61 +- bsnes/sfc/chip/spc7110/decomp.cpp | 5 +- bsnes/sfc/chip/spc7110/serialization.cpp | 4 - bsnes/sfc/chip/spc7110/spc7110.cpp | 856 ++++++++++++----------- bsnes/sfc/chip/spc7110/spc7110.hpp | 28 +- bsnes/sfc/cpu/cpu.cpp | 5 + bsnes/sfc/interface/interface.cpp | 23 +- bsnes/sfc/interface/interface.hpp | 6 +- bsnes/sfc/memory/memory-inline.hpp | 18 + bsnes/sfc/memory/memory.cpp | 18 - bsnes/sfc/memory/memory.hpp | 2 +- bsnes/target-ethos/Makefile | 2 + bsnes/target-ethos/input/hotkeys.cpp | 10 + bsnes/target-ethos/settings/video.cpp | 2 +- bsnes/target-ethos/utility/utility.cpp | 14 +- bsnes/target-ethos/utility/utility.hpp | 3 + 26 files changed, 873 insertions(+), 774 deletions(-) diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index 69525b18..d9670702 100755 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "bsnes"; - static const char Version[] = "089"; + static const char Version[] = "089.02"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; } diff --git a/bsnes/emulator/interface.hpp b/bsnes/emulator/interface.hpp index 623859e3..ae880e87 100755 --- a/bsnes/emulator/interface.hpp +++ b/bsnes/emulator/interface.hpp @@ -98,7 +98,10 @@ struct Interface { virtual void cheatSet(const lstring& = lstring{}) {} //utility functions - virtual void updatePalette() {} + virtual void paletteUpdate() {} + + //debugger functions + virtual bool tracerEnable(bool) { return false; } Interface() : bind(nullptr) {} }; diff --git a/bsnes/fc/interface/interface.cpp b/bsnes/fc/interface/interface.cpp index 89b5ad5f..af9aba82 100755 --- a/bsnes/fc/interface/interface.cpp +++ b/bsnes/fc/interface/interface.cpp @@ -76,7 +76,7 @@ void Interface::cheatSet(const lstring &list) { cheat.synchronize(); } -void Interface::updatePalette() { +void Interface::paletteUpdate() { video.generate_palette(); } diff --git a/bsnes/fc/interface/interface.hpp b/bsnes/fc/interface/interface.hpp index 9af97136..d32f5d41 100755 --- a/bsnes/fc/interface/interface.hpp +++ b/bsnes/fc/interface/interface.hpp @@ -33,7 +33,7 @@ struct Interface : Emulator::Interface { void cheatSet(const lstring&); - void updatePalette(); + void paletteUpdate(); Interface(); diff --git a/bsnes/gb/interface/interface.cpp b/bsnes/gb/interface/interface.cpp index d2a8c48d..a2511cd4 100755 --- a/bsnes/gb/interface/interface.cpp +++ b/bsnes/gb/interface/interface.cpp @@ -99,7 +99,7 @@ void Interface::cheatSet(const lstring &list) { cheat.synchronize(); } -void Interface::updatePalette() { +void Interface::paletteUpdate() { video.generate_palette(); } diff --git a/bsnes/gb/interface/interface.hpp b/bsnes/gb/interface/interface.hpp index e7ceeaf0..7caff179 100755 --- a/bsnes/gb/interface/interface.hpp +++ b/bsnes/gb/interface/interface.hpp @@ -45,7 +45,7 @@ struct Interface : Emulator::Interface { void cheatSet(const lstring&); - void updatePalette(); + void paletteUpdate(); Interface(); diff --git a/bsnes/gba/interface/interface.cpp b/bsnes/gba/interface/interface.cpp index 3219718d..abbb0cdc 100755 --- a/bsnes/gba/interface/interface.cpp +++ b/bsnes/gba/interface/interface.cpp @@ -79,7 +79,7 @@ bool Interface::unserialize(serializer &s) { return system.unserialize(s); } -void Interface::updatePalette() { +void Interface::paletteUpdate() { video.generate_palette(); } diff --git a/bsnes/gba/interface/interface.hpp b/bsnes/gba/interface/interface.hpp index 2d151209..b2288c77 100755 --- a/bsnes/gba/interface/interface.hpp +++ b/bsnes/gba/interface/interface.hpp @@ -32,7 +32,7 @@ struct Interface : Emulator::Interface { serializer serialize(); bool unserialize(serializer&); - void updatePalette(); + void paletteUpdate(); Interface(); diff --git a/bsnes/nall/snes/cartridge.hpp b/bsnes/nall/snes/cartridge.hpp index 1c64c659..3577841e 100755 --- a/bsnes/nall/snes/cartridge.hpp +++ b/bsnes/nall/snes/cartridge.hpp @@ -158,26 +158,11 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size) else if(has_spc7110) { markup.append( - " \n" - " \n" - " \n" - " \n" - " \n" " \n" - " \n" - " \n" - " \n" - " \n" " \n" " \n" " \n" " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" ); if(has_spc7110rtc) markup.append( " \n" @@ -186,6 +171,22 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size) " \n" ); markup.append( + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" ); } diff --git a/bsnes/processor/r65816/disassembler.cpp b/bsnes/processor/r65816/disassembler.cpp index 9f8c4137..78e5e77d 100755 --- a/bsnes/processor/r65816/disassembler.cpp +++ b/bsnes/processor/r65816/disassembler.cpp @@ -127,274 +127,274 @@ void R65816::disassemble_opcode(char *output, uint32 addr) { #define x8 (regs.e || regs.p.x) switch(op) { - case 0x00: sprintf(t, "brk #$%.2x ", op8); break; - case 0x01: sprintf(t, "ora ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x02: sprintf(t, "cop #$%.2x ", op8); break; - case 0x03: sprintf(t, "ora $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x04: sprintf(t, "tsb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x05: sprintf(t, "ora $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x06: sprintf(t, "asl $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x07: sprintf(t, "ora [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x08: sprintf(t, "php "); break; - case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8); - else sprintf(t, "ora #$%.4x ", op16); break; - case 0x0a: sprintf(t, "asl a "); break; - case 0x0b: sprintf(t, "phd "); break; - case 0x0c: sprintf(t, "tsb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0d: sprintf(t, "ora $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0e: sprintf(t, "asl $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0f: sprintf(t, "ora $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x10: sprintf(t, "bpl $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x11: sprintf(t, "ora ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x12: sprintf(t, "ora ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x13: sprintf(t, "ora ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x14: sprintf(t, "trb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x15: sprintf(t, "ora $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x16: sprintf(t, "asl $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x17: sprintf(t, "ora [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x18: sprintf(t, "clc "); break; - case 0x19: sprintf(t, "ora $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x1a: sprintf(t, "inc "); break; - case 0x1b: sprintf(t, "tcs "); break; - case 0x1c: sprintf(t, "trb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x1d: sprintf(t, "ora $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x1e: sprintf(t, "asl $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x1f: sprintf(t, "ora $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x20: sprintf(t, "jsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; - case 0x21: sprintf(t, "and ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x22: sprintf(t, "jsl $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x23: sprintf(t, "and $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x24: sprintf(t, "bit $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x25: sprintf(t, "and $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x26: sprintf(t, "rol $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x27: sprintf(t, "and [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x28: sprintf(t, "plp "); break; - case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8); - else sprintf(t, "and #$%.4x ", op16); break; - case 0x2a: sprintf(t, "rol a "); break; - case 0x2b: sprintf(t, "pld "); break; - case 0x2c: sprintf(t, "bit $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2d: sprintf(t, "and $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2e: sprintf(t, "rol $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2f: sprintf(t, "and $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x30: sprintf(t, "bmi $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x31: sprintf(t, "and ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x32: sprintf(t, "and ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x33: sprintf(t, "and ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x34: sprintf(t, "bit $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x35: sprintf(t, "and $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x36: sprintf(t, "rol $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x37: sprintf(t, "and [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x38: sprintf(t, "sec "); break; - case 0x39: sprintf(t, "and $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x3a: sprintf(t, "dec "); break; - case 0x3b: sprintf(t, "tsc "); break; - case 0x3c: sprintf(t, "bit $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3d: sprintf(t, "and $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3e: sprintf(t, "rol $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3f: sprintf(t, "and $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x40: sprintf(t, "rti "); break; - case 0x41: sprintf(t, "eor ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x42: sprintf(t, "wdm "); break; - case 0x43: sprintf(t, "eor $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break; - case 0x45: sprintf(t, "eor $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x46: sprintf(t, "lsr $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x47: sprintf(t, "eor [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x48: sprintf(t, "pha "); break; - case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8); - else sprintf(t, "eor #$%.4x ", op16); break; - case 0x4a: sprintf(t, "lsr a "); break; - case 0x4b: sprintf(t, "phk "); break; - case 0x4c: sprintf(t, "jmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; - case 0x4d: sprintf(t, "eor $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x4e: sprintf(t, "lsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x4f: sprintf(t, "eor $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x50: sprintf(t, "bvc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x51: sprintf(t, "eor ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x52: sprintf(t, "eor ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x53: sprintf(t, "eor ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break; - case 0x55: sprintf(t, "eor $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x56: sprintf(t, "lsr $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x57: sprintf(t, "eor [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x58: sprintf(t, "cli "); break; - case 0x59: sprintf(t, "eor $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x5a: sprintf(t, "phy "); break; - case 0x5b: sprintf(t, "tcd "); break; - case 0x5c: sprintf(t, "jml $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x5d: sprintf(t, "eor $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x5e: sprintf(t, "lsr $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x5f: sprintf(t, "eor $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x60: sprintf(t, "rts "); break; - case 0x61: sprintf(t, "adc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x62: sprintf(t, "per $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x63: sprintf(t, "adc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x64: sprintf(t, "stz $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x65: sprintf(t, "adc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x66: sprintf(t, "ror $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x67: sprintf(t, "adc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x68: sprintf(t, "pla "); break; - case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8); - else sprintf(t, "adc #$%.4x ", op16); break; - case 0x6a: sprintf(t, "ror a "); break; - case 0x6b: sprintf(t, "rtl "); break; - case 0x6c: sprintf(t, "jmp ($%.4x) [%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break; - case 0x6d: sprintf(t, "adc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x6e: sprintf(t, "ror $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x6f: sprintf(t, "adc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x70: sprintf(t, "bvs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x71: sprintf(t, "adc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x72: sprintf(t, "adc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x73: sprintf(t, "adc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x74: sprintf(t, "stz $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x75: sprintf(t, "adc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x76: sprintf(t, "ror $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x77: sprintf(t, "adc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x78: sprintf(t, "sei "); break; - case 0x79: sprintf(t, "adc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x7a: sprintf(t, "ply "); break; - case 0x7b: sprintf(t, "tdc "); break; - case 0x7c: sprintf(t, "jmp ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; - case 0x7d: sprintf(t, "adc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x7e: sprintf(t, "ror $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x7f: sprintf(t, "adc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x80: sprintf(t, "bra $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x81: sprintf(t, "sta ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x82: sprintf(t, "brl $%.4x [%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break; - case 0x83: sprintf(t, "sta $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x84: sprintf(t, "sty $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x85: sprintf(t, "sta $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x86: sprintf(t, "stx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x87: sprintf(t, "sta [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x88: sprintf(t, "dey "); break; - case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8); - else sprintf(t, "bit #$%.4x ", op16); break; - case 0x8a: sprintf(t, "txa "); break; - case 0x8b: sprintf(t, "phb "); break; - case 0x8c: sprintf(t, "sty $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8d: sprintf(t, "sta $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8e: sprintf(t, "stx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8f: sprintf(t, "sta $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x90: sprintf(t, "bcc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x91: sprintf(t, "sta ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x92: sprintf(t, "sta ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x93: sprintf(t, "sta ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x94: sprintf(t, "sty $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x95: sprintf(t, "sta $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x96: sprintf(t, "stx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; - case 0x97: sprintf(t, "sta [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x98: sprintf(t, "tya "); break; - case 0x99: sprintf(t, "sta $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x9a: sprintf(t, "txs "); break; - case 0x9b: sprintf(t, "txy "); break; - case 0x9c: sprintf(t, "stz $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x9d: sprintf(t, "sta $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x9e: sprintf(t, "stz $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x9f: sprintf(t, "sta $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8); - else sprintf(t, "ldy #$%.4x ", op16); break; - case 0xa1: sprintf(t, "lda ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8); - else sprintf(t, "ldx #$%.4x ", op16); break; - case 0xa3: sprintf(t, "lda $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xa4: sprintf(t, "ldy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa5: sprintf(t, "lda $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa6: sprintf(t, "ldx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa7: sprintf(t, "lda [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xa8: sprintf(t, "tay "); break; - case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8); - else sprintf(t, "lda #$%.4x ", op16); break; - case 0xaa: sprintf(t, "tax "); break; - case 0xab: sprintf(t, "plb "); break; - case 0xac: sprintf(t, "ldy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xad: sprintf(t, "lda $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xae: sprintf(t, "ldx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xaf: sprintf(t, "lda $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xb0: sprintf(t, "bcs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xb1: sprintf(t, "lda ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xb2: sprintf(t, "lda ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xb3: sprintf(t, "lda ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xb4: sprintf(t, "ldy $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xb5: sprintf(t, "lda $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xb6: sprintf(t, "ldx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; - case 0xb7: sprintf(t, "lda [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xb8: sprintf(t, "clv "); break; - case 0xb9: sprintf(t, "lda $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xba: sprintf(t, "tsx "); break; - case 0xbb: sprintf(t, "tyx "); break; - case 0xbc: sprintf(t, "ldy $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xbd: sprintf(t, "lda $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xbe: sprintf(t, "ldx $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xbf: sprintf(t, "lda $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8); - else sprintf(t, "cpy #$%.4x ", op16); break; - case 0xc1: sprintf(t, "cmp ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xc2: sprintf(t, "rep #$%.2x ", op8); break; - case 0xc3: sprintf(t, "cmp $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xc4: sprintf(t, "cpy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc5: sprintf(t, "cmp $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc6: sprintf(t, "dec $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc7: sprintf(t, "cmp [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xc8: sprintf(t, "iny "); break; - case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8); - else sprintf(t, "cmp #$%.4x ", op16); break; - case 0xca: sprintf(t, "dex "); break; - case 0xcb: sprintf(t, "wai "); break; - case 0xcc: sprintf(t, "cpy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xcd: sprintf(t, "cmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xce: sprintf(t, "dec $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xcf: sprintf(t, "cmp $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xd0: sprintf(t, "bne $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xd1: sprintf(t, "cmp ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xd2: sprintf(t, "cmp ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xd3: sprintf(t, "cmp ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xd4: sprintf(t, "pei ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xd5: sprintf(t, "cmp $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xd6: sprintf(t, "dec $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xd7: sprintf(t, "cmp [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xd8: sprintf(t, "cld "); break; - case 0xd9: sprintf(t, "cmp $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xda: sprintf(t, "phx "); break; - case 0xdb: sprintf(t, "stp "); break; - case 0xdc: sprintf(t, "jmp [$%.4x] [%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break; - case 0xdd: sprintf(t, "cmp $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xde: sprintf(t, "dec $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xdf: sprintf(t, "cmp $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8); - else sprintf(t, "cpx #$%.4x ", op16); break; - case 0xe1: sprintf(t, "sbc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xe2: sprintf(t, "sep #$%.2x ", op8); break; - case 0xe3: sprintf(t, "sbc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xe4: sprintf(t, "cpx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe5: sprintf(t, "sbc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe6: sprintf(t, "inc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe7: sprintf(t, "sbc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xe8: sprintf(t, "inx "); break; - case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8); - else sprintf(t, "sbc #$%.4x ", op16); break; - case 0xea: sprintf(t, "nop "); break; - case 0xeb: sprintf(t, "xba "); break; - case 0xec: sprintf(t, "cpx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xed: sprintf(t, "sbc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xee: sprintf(t, "inc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xef: sprintf(t, "sbc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xf0: sprintf(t, "beq $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xf1: sprintf(t, "sbc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xf2: sprintf(t, "sbc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xf3: sprintf(t, "sbc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xf4: sprintf(t, "pea $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xf5: sprintf(t, "sbc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xf6: sprintf(t, "inc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xf7: sprintf(t, "sbc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xf8: sprintf(t, "sed "); break; - case 0xf9: sprintf(t, "sbc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xfa: sprintf(t, "plx "); break; - case 0xfb: sprintf(t, "xce "); break; - case 0xfc: sprintf(t, "jsr ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; - case 0xfd: sprintf(t, "sbc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xfe: sprintf(t, "inc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xff: sprintf(t, "sbc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0x00: sprintf(t, "brk #$%.2x ", op8); break; + case 0x01: sprintf(t, "ora ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0x02: sprintf(t, "cop #$%.2x ", op8); break; + case 0x03: sprintf(t, "ora $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0x04: sprintf(t, "tsb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x05: sprintf(t, "ora $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x06: sprintf(t, "asl $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x07: sprintf(t, "ora [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0x08: sprintf(t, "php "); break; + case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8); + else sprintf(t, "ora #$%.4x ", op16); break; + case 0x0a: sprintf(t, "asl a "); break; + case 0x0b: sprintf(t, "phd "); break; + case 0x0c: sprintf(t, "tsb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x0d: sprintf(t, "ora $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x0e: sprintf(t, "asl $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x0f: sprintf(t, "ora $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x10: sprintf(t, "bpl $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0x11: sprintf(t, "ora ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0x12: sprintf(t, "ora ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0x13: sprintf(t, "ora ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0x14: sprintf(t, "trb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x15: sprintf(t, "ora $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x16: sprintf(t, "asl $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x17: sprintf(t, "ora [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0x18: sprintf(t, "clc "); break; + case 0x19: sprintf(t, "ora $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0x1a: sprintf(t, "inc "); break; + case 0x1b: sprintf(t, "tcs "); break; + case 0x1c: sprintf(t, "trb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x1d: sprintf(t, "ora $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x1e: sprintf(t, "asl $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x1f: sprintf(t, "ora $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0x20: sprintf(t, "jsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; + case 0x21: sprintf(t, "and ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0x22: sprintf(t, "jsl $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x23: sprintf(t, "and $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0x24: sprintf(t, "bit $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x25: sprintf(t, "and $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x26: sprintf(t, "rol $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x27: sprintf(t, "and [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0x28: sprintf(t, "plp "); break; + case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8); + else sprintf(t, "and #$%.4x ", op16); break; + case 0x2a: sprintf(t, "rol a "); break; + case 0x2b: sprintf(t, "pld "); break; + case 0x2c: sprintf(t, "bit $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x2d: sprintf(t, "and $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x2e: sprintf(t, "rol $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x2f: sprintf(t, "and $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x30: sprintf(t, "bmi $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0x31: sprintf(t, "and ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0x32: sprintf(t, "and ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0x33: sprintf(t, "and ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0x34: sprintf(t, "bit $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x35: sprintf(t, "and $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x36: sprintf(t, "rol $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x37: sprintf(t, "and [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0x38: sprintf(t, "sec "); break; + case 0x39: sprintf(t, "and $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0x3a: sprintf(t, "dec "); break; + case 0x3b: sprintf(t, "tsc "); break; + case 0x3c: sprintf(t, "bit $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x3d: sprintf(t, "and $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x3e: sprintf(t, "rol $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x3f: sprintf(t, "and $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0x40: sprintf(t, "rti "); break; + case 0x41: sprintf(t, "eor ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0x42: sprintf(t, "wdm "); break; + case 0x43: sprintf(t, "eor $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break; + case 0x45: sprintf(t, "eor $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x46: sprintf(t, "lsr $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x47: sprintf(t, "eor [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0x48: sprintf(t, "pha "); break; + case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8); + else sprintf(t, "eor #$%.4x ", op16); break; + case 0x4a: sprintf(t, "lsr a "); break; + case 0x4b: sprintf(t, "phk "); break; + case 0x4c: sprintf(t, "jmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; + case 0x4d: sprintf(t, "eor $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x4e: sprintf(t, "lsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x4f: sprintf(t, "eor $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x50: sprintf(t, "bvc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0x51: sprintf(t, "eor ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0x52: sprintf(t, "eor ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0x53: sprintf(t, "eor ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break; + case 0x55: sprintf(t, "eor $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x56: sprintf(t, "lsr $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x57: sprintf(t, "eor [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0x58: sprintf(t, "cli "); break; + case 0x59: sprintf(t, "eor $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0x5a: sprintf(t, "phy "); break; + case 0x5b: sprintf(t, "tcd "); break; + case 0x5c: sprintf(t, "jml $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x5d: sprintf(t, "eor $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x5e: sprintf(t, "lsr $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x5f: sprintf(t, "eor $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0x60: sprintf(t, "rts "); break; + case 0x61: sprintf(t, "adc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0x62: sprintf(t, "per $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x63: sprintf(t, "adc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0x64: sprintf(t, "stz $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x65: sprintf(t, "adc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x66: sprintf(t, "ror $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x67: sprintf(t, "adc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0x68: sprintf(t, "pla "); break; + case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8); + else sprintf(t, "adc #$%.4x ", op16); break; + case 0x6a: sprintf(t, "ror a "); break; + case 0x6b: sprintf(t, "rtl "); break; + case 0x6c: sprintf(t, "jmp ($%.4x) [%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break; + case 0x6d: sprintf(t, "adc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x6e: sprintf(t, "ror $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x6f: sprintf(t, "adc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x70: sprintf(t, "bvs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0x71: sprintf(t, "adc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0x72: sprintf(t, "adc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0x73: sprintf(t, "adc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0x74: sprintf(t, "stz $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x75: sprintf(t, "adc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x76: sprintf(t, "ror $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x77: sprintf(t, "adc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0x78: sprintf(t, "sei "); break; + case 0x79: sprintf(t, "adc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0x7a: sprintf(t, "ply "); break; + case 0x7b: sprintf(t, "tdc "); break; + case 0x7c: sprintf(t, "jmp ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; + case 0x7d: sprintf(t, "adc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x7e: sprintf(t, "ror $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x7f: sprintf(t, "adc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0x80: sprintf(t, "bra $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0x81: sprintf(t, "sta ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0x82: sprintf(t, "brl $%.4x [%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break; + case 0x83: sprintf(t, "sta $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0x84: sprintf(t, "sty $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x85: sprintf(t, "sta $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x86: sprintf(t, "stx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0x87: sprintf(t, "sta [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0x88: sprintf(t, "dey "); break; + case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8); + else sprintf(t, "bit #$%.4x ", op16); break; + case 0x8a: sprintf(t, "txa "); break; + case 0x8b: sprintf(t, "phb "); break; + case 0x8c: sprintf(t, "sty $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x8d: sprintf(t, "sta $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x8e: sprintf(t, "stx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x8f: sprintf(t, "sta $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0x90: sprintf(t, "bcc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0x91: sprintf(t, "sta ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0x92: sprintf(t, "sta ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0x93: sprintf(t, "sta ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0x94: sprintf(t, "sty $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x95: sprintf(t, "sta $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0x96: sprintf(t, "stx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; + case 0x97: sprintf(t, "sta [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0x98: sprintf(t, "tya "); break; + case 0x99: sprintf(t, "sta $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0x9a: sprintf(t, "txs "); break; + case 0x9b: sprintf(t, "txy "); break; + case 0x9c: sprintf(t, "stz $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0x9d: sprintf(t, "sta $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x9e: sprintf(t, "stz $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0x9f: sprintf(t, "sta $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8); + else sprintf(t, "ldy #$%.4x ", op16); break; + case 0xa1: sprintf(t, "lda ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8); + else sprintf(t, "ldx #$%.4x ", op16); break; + case 0xa3: sprintf(t, "lda $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0xa4: sprintf(t, "ldy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xa5: sprintf(t, "lda $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xa6: sprintf(t, "ldx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xa7: sprintf(t, "lda [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0xa8: sprintf(t, "tay "); break; + case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8); + else sprintf(t, "lda #$%.4x ", op16); break; + case 0xaa: sprintf(t, "tax "); break; + case 0xab: sprintf(t, "plb "); break; + case 0xac: sprintf(t, "ldy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xad: sprintf(t, "lda $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xae: sprintf(t, "ldx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xaf: sprintf(t, "lda $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0xb0: sprintf(t, "bcs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0xb1: sprintf(t, "lda ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0xb2: sprintf(t, "lda ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0xb3: sprintf(t, "lda ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0xb4: sprintf(t, "ldy $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0xb5: sprintf(t, "lda $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0xb6: sprintf(t, "ldx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; + case 0xb7: sprintf(t, "lda [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0xb8: sprintf(t, "clv "); break; + case 0xb9: sprintf(t, "lda $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0xba: sprintf(t, "tsx "); break; + case 0xbb: sprintf(t, "tyx "); break; + case 0xbc: sprintf(t, "ldy $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0xbd: sprintf(t, "lda $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0xbe: sprintf(t, "ldx $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0xbf: sprintf(t, "lda $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8); + else sprintf(t, "cpy #$%.4x ", op16); break; + case 0xc1: sprintf(t, "cmp ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0xc2: sprintf(t, "rep #$%.2x ", op8); break; + case 0xc3: sprintf(t, "cmp $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0xc4: sprintf(t, "cpy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xc5: sprintf(t, "cmp $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xc6: sprintf(t, "dec $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xc7: sprintf(t, "cmp [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0xc8: sprintf(t, "iny "); break; + case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8); + else sprintf(t, "cmp #$%.4x ", op16); break; + case 0xca: sprintf(t, "dex "); break; + case 0xcb: sprintf(t, "wai "); break; + case 0xcc: sprintf(t, "cpy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xcd: sprintf(t, "cmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xce: sprintf(t, "dec $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xcf: sprintf(t, "cmp $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0xd0: sprintf(t, "bne $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0xd1: sprintf(t, "cmp ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0xd2: sprintf(t, "cmp ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0xd3: sprintf(t, "cmp ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0xd4: sprintf(t, "pei ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0xd5: sprintf(t, "cmp $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0xd6: sprintf(t, "dec $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0xd7: sprintf(t, "cmp [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0xd8: sprintf(t, "cld "); break; + case 0xd9: sprintf(t, "cmp $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0xda: sprintf(t, "phx "); break; + case 0xdb: sprintf(t, "stp "); break; + case 0xdc: sprintf(t, "jmp [$%.4x] [%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break; + case 0xdd: sprintf(t, "cmp $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0xde: sprintf(t, "dec $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0xdf: sprintf(t, "cmp $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; + case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8); + else sprintf(t, "cpx #$%.4x ", op16); break; + case 0xe1: sprintf(t, "sbc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; + case 0xe2: sprintf(t, "sep #$%.2x ", op8); break; + case 0xe3: sprintf(t, "sbc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; + case 0xe4: sprintf(t, "cpx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xe5: sprintf(t, "sbc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xe6: sprintf(t, "inc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; + case 0xe7: sprintf(t, "sbc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; + case 0xe8: sprintf(t, "inx "); break; + case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8); + else sprintf(t, "sbc #$%.4x ", op16); break; + case 0xea: sprintf(t, "nop "); break; + case 0xeb: sprintf(t, "xba "); break; + case 0xec: sprintf(t, "cpx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xed: sprintf(t, "sbc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xee: sprintf(t, "inc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xef: sprintf(t, "sbc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; + case 0xf0: sprintf(t, "beq $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; + case 0xf1: sprintf(t, "sbc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; + case 0xf2: sprintf(t, "sbc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; + case 0xf3: sprintf(t, "sbc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; + case 0xf4: sprintf(t, "pea $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; + case 0xf5: sprintf(t, "sbc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0xf6: sprintf(t, "inc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; + case 0xf7: sprintf(t, "sbc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; + case 0xf8: sprintf(t, "sed "); break; + case 0xf9: sprintf(t, "sbc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; + case 0xfa: sprintf(t, "plx "); break; + case 0xfb: sprintf(t, "xce "); break; + case 0xfc: sprintf(t, "jsr ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; + case 0xfd: sprintf(t, "sbc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0xfe: sprintf(t, "inc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; + case 0xff: sprintf(t, "sbc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; } #undef op8 @@ -424,9 +424,5 @@ void R65816::disassemble_opcode(char *output, uint32 addr) { regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); } - strcat(s, t); -//strcat(s, " "); - -//sprintf(t, "V:%3d H:%4d", cpu.vcounter(), cpu.hcounter()); strcat(s, t); } diff --git a/bsnes/sfc/cartridge/markup.cpp b/bsnes/sfc/cartridge/markup.cpp index 41429bdb..cec6d075 100755 --- a/bsnes/sfc/cartridge/markup.cpp +++ b/bsnes/sfc/cartridge/markup.cpp @@ -400,46 +400,51 @@ void Cartridge::parse_markup_spc7110(XML::Node &root) { has_spc7110 = true; has_spc7110rtc = root["rtc"].exists(); - auto &ram = root["ram"]; auto &mmio = root["mmio"]; - auto &mcu = root["mcu"]; - auto &dcu = root["dcu"]; auto &rtc = root["rtc"]; + auto &dcu = root["dcu"]; + auto &mcurom = root["mcu"]["rom"]; + auto &mcuram = root["mcu"]["ram"]; - ram_size = numeral(ram["size"].data); - for(auto &node : ram) { - if(node.name != "map") continue; - Mapping m({ &SPC7110::ram_read, &spc7110 }, { &SPC7110::ram_write, &spc7110 }); - parse_markup_map(m, node); - mapping.append(m); - } + spc7110.prom_base = numeral(mcurom["program"]["offset"].data); + spc7110.prom_size = numeral(mcurom["program"]["size"].data); + + spc7110.drom_base = numeral(mcurom["data"]["offset"].data); + spc7110.drom_size = numeral(mcurom["data"]["size"].data); + + ram_size = numeral(mcuram["size"].data); for(auto &node : mmio) { if(node.name != "map") continue; - Mapping m({ &SPC7110::mmio_read, &spc7110 }, { &SPC7110::mmio_write, &spc7110 }); - parse_markup_map(m, node); - mapping.append(m); - } - - spc7110.data_rom_offset = numeral(mcu["offset"].data); - if(spc7110.data_rom_offset == 0) spc7110.data_rom_offset = 0x100000; - for(auto &node : mcu) { - if(node.name != "map") continue; - Mapping m({ &SPC7110::mcu_read, &spc7110 }, { &SPC7110::mcu_write, &spc7110 }); - parse_markup_map(m, node); - mapping.append(m); - } - - for(auto &node : dcu) { - if(node.name != "map") continue; - Mapping m({ &SPC7110::dcu_read, &spc7110 }, { &SPC7110::dcu_write, &spc7110 }); + Mapping m({&SPC7110::mmio_read, &spc7110}, {&SPC7110::mmio_write, &spc7110}); parse_markup_map(m, node); mapping.append(m); } for(auto &node : rtc) { if(node.name != "map") continue; - Mapping m({ &SPC7110::mmio_read, &spc7110 }, { &SPC7110::mmio_write, &spc7110 }); + Mapping m({&SPC7110::mmio_read, &spc7110}, {&SPC7110::mmio_write, &spc7110}); + parse_markup_map(m, node); + mapping.append(m); + } + + for(auto &node : dcu) { + if(node.name != "map") continue; + Mapping m({&SPC7110::dcu_read, &spc7110}, {&SPC7110::dcu_write, &spc7110}); + parse_markup_map(m, node); + mapping.append(m); + } + + for(auto &node : mcurom) { + if(node.name != "map") continue; + Mapping m({&SPC7110::mcurom_read, &spc7110}, {&SPC7110::mcurom_write, &spc7110}); + parse_markup_map(m, node); + mapping.append(m); + } + + for(auto &node : mcuram) { + if(node.name != "map") continue; + Mapping m({&SPC7110::mcuram_read, &spc7110}, {&SPC7110::mcuram_write, &spc7110}); parse_markup_map(m, node); mapping.append(m); } diff --git a/bsnes/sfc/chip/spc7110/decomp.cpp b/bsnes/sfc/chip/spc7110/decomp.cpp index d6b4cce5..6ad01708 100755 --- a/bsnes/sfc/chip/spc7110/decomp.cpp +++ b/bsnes/sfc/chip/spc7110/decomp.cpp @@ -24,9 +24,8 @@ void SPC7110::Decomp::write(uint8 data) { } uint8 SPC7110::Decomp::dataread() { - unsigned size = cartridge.rom.size() - spc7110.data_rom_offset; - while(decomp_offset >= size) decomp_offset -= size; - return cartridge.rom.read(spc7110.data_rom_offset + decomp_offset++); + unsigned addr = Bus::mirror(decomp_offset++, spc7110.drom_size); + return cartridge.rom.read(spc7110.drom_base + addr); } void SPC7110::Decomp::init(unsigned mode, unsigned offset, unsigned index) { diff --git a/bsnes/sfc/chip/spc7110/serialization.cpp b/bsnes/sfc/chip/spc7110/serialization.cpp index 196d04c0..2056df25 100755 --- a/bsnes/sfc/chip/spc7110/serialization.cpp +++ b/bsnes/sfc/chip/spc7110/serialization.cpp @@ -65,10 +65,6 @@ void SPC7110::serialize(serializer &s) { s.integer(r4833); s.integer(r4834); - s.integer(dx_offset); - s.integer(ex_offset); - s.integer(fx_offset); - s.integer(r4840); s.integer(r4841); s.integer(r4842); diff --git a/bsnes/sfc/chip/spc7110/spc7110.cpp b/bsnes/sfc/chip/spc7110/spc7110.cpp index 8be35c0a..f58b948e 100755 --- a/bsnes/sfc/chip/spc7110/spc7110.cpp +++ b/bsnes/sfc/chip/spc7110/spc7110.cpp @@ -71,9 +71,9 @@ void SPC7110::reset() { r482f = 0x00; r4830 = 0x00; - mmio_write(0x4831, 0); - mmio_write(0x4832, 1); - mmio_write(0x4833, 2); + r4831 = 0x00; + r4832 = 0x01; + r4833 = 0x02; r4834 = 0x00; r4840 = 0x00; @@ -88,9 +88,8 @@ void SPC7110::reset() { } unsigned SPC7110::datarom_addr(unsigned addr) { - unsigned size = cartridge.rom.size() - data_rom_offset; - while(addr >= size) addr -= size; - return data_rom_offset + addr; + addr = Bus::mirror(addr, drom_size); + return drom_base + addr; } unsigned SPC7110::data_pointer() { return r4811 + (r4812 << 8) + (r4813 << 16); } @@ -194,145 +193,147 @@ uint8 SPC7110::mmio_read(unsigned addr) { addr &= 0xffff; switch(addr) { - //================== - //decompression unit - //================== - case 0x4800: { - uint16 counter = (r4809 + (r480a << 8)); - counter--; - r4809 = counter; - r480a = counter >> 8; - return decomp.read(); - } - case 0x4801: return r4801; - case 0x4802: return r4802; - case 0x4803: return r4803; - case 0x4804: return r4804; - case 0x4805: return r4805; - case 0x4806: return r4806; - case 0x4807: return r4807; - case 0x4808: return r4808; - case 0x4809: return r4809; - case 0x480a: return r480a; - case 0x480b: return r480b; - case 0x480c: { - uint8 status = r480c; - r480c &= 0x7f; - return status; + //================== + //decompression unit + //================== + + case 0x4800: { + uint16 counter = (r4809 + (r480a << 8)); + counter--; + r4809 = counter; + r480a = counter >> 8; + return decomp.read(); + } + case 0x4801: return r4801; + case 0x4802: return r4802; + case 0x4803: return r4803; + case 0x4804: return r4804; + case 0x4805: return r4805; + case 0x4806: return r4806; + case 0x4807: return r4807; + case 0x4808: return r4808; + case 0x4809: return r4809; + case 0x480a: return r480a; + case 0x480b: return r480b; + case 0x480c: { + uint8 status = r480c; + r480c &= 0x7f; + return status; + } + + //============== + //data port unit + //============== + + case 0x4810: { + if(r481x != 0x07) return 0x00; + + unsigned addr = data_pointer(); + unsigned adjust = data_adjust(); + if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend + + unsigned adjustaddr = addr; + if(r4818 & 2) { + adjustaddr += adjust; + set_data_adjust(adjust + 1); } - //============== - //data port unit - //============== + uint8 data = cartridge.rom.read(datarom_addr(adjustaddr)); + if(!(r4818 & 2)) { + unsigned increment = (r4818 & 1) ? data_increment() : 1; + if(r4818 & 4) increment = (int16)increment; //16-bit sign extend - case 0x4810: { - if(r481x != 0x07) return 0x00; - - unsigned addr = data_pointer(); - unsigned adjust = data_adjust(); - if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend - - unsigned adjustaddr = addr; - if(r4818 & 2) { - adjustaddr += adjust; - set_data_adjust(adjust + 1); + if((r4818 & 16) == 0) { + set_data_pointer(addr + increment); + } else { + set_data_adjust(adjust + increment); } + } - uint8 data = cartridge.rom.read(datarom_addr(adjustaddr)); - if(!(r4818 & 2)) { - unsigned increment = (r4818 & 1) ? data_increment() : 1; - if(r4818 & 4) increment = (int16)increment; //16-bit sign extend + return data; + } + case 0x4811: return r4811; + case 0x4812: return r4812; + case 0x4813: return r4813; + case 0x4814: return r4814; + case 0x4815: return r4815; + case 0x4816: return r4816; + case 0x4817: return r4817; + case 0x4818: return r4818; + case 0x481a: { + if(r481x != 0x07) return 0x00; - if((r4818 & 16) == 0) { - set_data_pointer(addr + increment); - } else { - set_data_adjust(adjust + increment); - } + unsigned addr = data_pointer(); + unsigned adjust = data_adjust(); + if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend + + uint8 data = cartridge.rom.read(datarom_addr(addr + adjust)); + if((r4818 & 0x60) == 0x60) { + if((r4818 & 16) == 0) { + set_data_pointer(addr + adjust); + } else { + set_data_adjust(adjust + adjust); } - - return data; - } - case 0x4811: return r4811; - case 0x4812: return r4812; - case 0x4813: return r4813; - case 0x4814: return r4814; - case 0x4815: return r4815; - case 0x4816: return r4816; - case 0x4817: return r4817; - case 0x4818: return r4818; - case 0x481a: { - if(r481x != 0x07) return 0x00; - - unsigned addr = data_pointer(); - unsigned adjust = data_adjust(); - if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend - - uint8 data = cartridge.rom.read(datarom_addr(addr + adjust)); - if((r4818 & 0x60) == 0x60) { - if((r4818 & 16) == 0) { - set_data_pointer(addr + adjust); - } else { - set_data_adjust(adjust + adjust); - } - } - - return data; } - //========= - //math unit - //========= + return data; + } - case 0x4820: return r4820; - case 0x4821: return r4821; - case 0x4822: return r4822; - case 0x4823: return r4823; - case 0x4824: return r4824; - case 0x4825: return r4825; - case 0x4826: return r4826; - case 0x4827: return r4827; - case 0x4828: return r4828; - case 0x4829: return r4829; - case 0x482a: return r482a; - case 0x482b: return r482b; - case 0x482c: return r482c; - case 0x482d: return r482d; - case 0x482e: return r482e; - case 0x482f: { - uint8 status = r482f; - r482f &= 0x7f; - return status; - } + //========= + //math unit + //========= - //=================== - //memory mapping unit - //=================== + case 0x4820: return r4820; + case 0x4821: return r4821; + case 0x4822: return r4822; + case 0x4823: return r4823; + case 0x4824: return r4824; + case 0x4825: return r4825; + case 0x4826: return r4826; + case 0x4827: return r4827; + case 0x4828: return r4828; + case 0x4829: return r4829; + case 0x482a: return r482a; + case 0x482b: return r482b; + case 0x482c: return r482c; + case 0x482d: return r482d; + case 0x482e: return r482e; + case 0x482f: { + uint8 status = r482f; + r482f &= 0x7f; + return status; + } - case 0x4830: return r4830; - case 0x4831: return r4831; - case 0x4832: return r4832; - case 0x4833: return r4833; - case 0x4834: return r4834; + //=================== + //memory mapping unit + //=================== - //==================== - //real-time clock unit - //==================== + case 0x4830: return r4830; + case 0x4831: return r4831; + case 0x4832: return r4832; + case 0x4833: return r4833; + case 0x4834: return r4834; - case 0x4840: return r4840; - case 0x4841: { - if(rtc_state == RTCS_Inactive || rtc_state == RTCS_ModeSelect) return 0x00; + //==================== + //real-time clock unit + //==================== + + case 0x4840: return r4840; + case 0x4841: { + if(rtc_state == RTCS_Inactive || rtc_state == RTCS_ModeSelect) return 0x00; + + r4842 = 0x80; + uint8 data = rtc[rtc_index]; + rtc_index = (rtc_index + 1) & 15; + return data; + } + case 0x4842: { + uint8 status = r4842; + r4842 &= 0x7f; + return status; + } - r4842 = 0x80; - uint8 data = rtc[rtc_index]; - rtc_index = (rtc_index + 1) & 15; - return data; - } - case 0x4842: { - uint8 status = r4842; - r4842 &= 0x7f; - return status; - } } return cpu.regs.mdr; @@ -342,312 +343,287 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) { addr &= 0xffff; switch(addr) { - //================== - //decompression unit - //================== - case 0x4801: r4801 = data; break; - case 0x4802: r4802 = data; break; - case 0x4803: r4803 = data; break; - case 0x4804: r4804 = data; break; - case 0x4805: r4805 = data; break; - case 0x4806: { - r4806 = data; + //================== + //decompression unit + //================== - unsigned table = (r4801 + (r4802 << 8) + (r4803 << 16)); - unsigned index = (r4804 << 2); - unsigned length = (r4809 + (r480a << 8)); - unsigned addr = datarom_addr(table + index); - unsigned mode = (cartridge.rom.read(addr + 0)); - unsigned offset = (cartridge.rom.read(addr + 1) << 16) - + (cartridge.rom.read(addr + 2) << 8) - + (cartridge.rom.read(addr + 3) << 0); + case 0x4801: r4801 = data; break; + case 0x4802: r4802 = data; break; + case 0x4803: r4803 = data; break; + case 0x4804: r4804 = data; break; + case 0x4805: r4805 = data; break; + case 0x4806: { + r4806 = data; - decomp.init(mode, offset, (r4805 + (r4806 << 8)) << mode); - r480c = 0x80; - } break; + unsigned table = (r4801 + (r4802 << 8) + (r4803 << 16)); + unsigned index = (r4804 << 2); + unsigned length = (r4809 + (r480a << 8)); + unsigned addr = datarom_addr(table + index); + unsigned mode = (cartridge.rom.read(addr + 0)); + unsigned offset = (cartridge.rom.read(addr + 1) << 16) + + (cartridge.rom.read(addr + 2) << 8) + + (cartridge.rom.read(addr + 3) << 0); - case 0x4807: r4807 = data; break; - case 0x4808: r4808 = data; break; - case 0x4809: r4809 = data; break; - case 0x480a: r480a = data; break; - case 0x480b: r480b = data; break; + decomp.init(mode, offset, (r4805 + (r4806 << 8)) << mode); + r480c = 0x80; + } break; - //============== - //data port unit - //============== + case 0x4807: r4807 = data; break; + case 0x4808: r4808 = data; break; + case 0x4809: r4809 = data; break; + case 0x480a: r480a = data; break; + case 0x480b: r480b = data; break; - case 0x4811: r4811 = data; r481x |= 0x01; break; - case 0x4812: r4812 = data; r481x |= 0x02; break; - case 0x4813: r4813 = data; r481x |= 0x04; break; - case 0x4814: { - r4814 = data; - r4814_latch = true; - if(!r4815_latch) break; - if(!(r4818 & 2)) break; - if(r4818 & 0x10) break; + //============== + //data port unit + //============== - if((r4818 & 0x60) == 0x20) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; //8-bit sign extend - set_data_pointer(data_pointer() + increment); - } else if((r4818 & 0x60) == 0x40) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; //16-bit sign extend - set_data_pointer(data_pointer() + increment); - } - } break; - case 0x4815: { - r4815 = data; - r4815_latch = true; - if(!r4814_latch) break; - if(!(r4818 & 2)) break; - if(r4818 & 0x10) break; + case 0x4811: r4811 = data; r481x |= 0x01; break; + case 0x4812: r4812 = data; r481x |= 0x02; break; + case 0x4813: r4813 = data; r481x |= 0x04; break; + case 0x4814: { + r4814 = data; + r4814_latch = true; + if(!r4815_latch) break; + if(!(r4818 & 2)) break; + if(r4818 & 0x10) break; - if((r4818 & 0x60) == 0x20) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; //8-bit sign extend - set_data_pointer(data_pointer() + increment); - } else if((r4818 & 0x60) == 0x40) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; //16-bit sign extend - set_data_pointer(data_pointer() + increment); - } - } break; - case 0x4816: r4816 = data; break; - case 0x4817: r4817 = data; break; - case 0x4818: { - if(r481x != 0x07) break; + if((r4818 & 0x60) == 0x20) { + unsigned increment = data_adjust() & 0xff; + if(r4818 & 8) increment = (int8)increment; //8-bit sign extend + set_data_pointer(data_pointer() + increment); + } else if((r4818 & 0x60) == 0x40) { + unsigned increment = data_adjust(); + if(r4818 & 8) increment = (int16)increment; //16-bit sign extend + set_data_pointer(data_pointer() + increment); + } + } break; + case 0x4815: { + r4815 = data; + r4815_latch = true; + if(!r4814_latch) break; + if(!(r4818 & 2)) break; + if(r4818 & 0x10) break; - r4818 = data; - r4814_latch = r4815_latch = false; - } break; + if((r4818 & 0x60) == 0x20) { + unsigned increment = data_adjust() & 0xff; + if(r4818 & 8) increment = (int8)increment; //8-bit sign extend + set_data_pointer(data_pointer() + increment); + } else if((r4818 & 0x60) == 0x40) { + unsigned increment = data_adjust(); + if(r4818 & 8) increment = (int16)increment; //16-bit sign extend + set_data_pointer(data_pointer() + increment); + } + } break; + case 0x4816: r4816 = data; break; + case 0x4817: r4817 = data; break; + case 0x4818: { + if(r481x != 0x07) break; - //========= - //math unit - //========= + r4818 = data; + r4814_latch = r4815_latch = false; + } break; - case 0x4820: r4820 = data; break; - case 0x4821: r4821 = data; break; - case 0x4822: r4822 = data; break; - case 0x4823: r4823 = data; break; - case 0x4824: r4824 = data; break; - case 0x4825: { - r4825 = data; + //========= + //math unit + //========= - if(r482e & 1) { - //signed 16-bit x 16-bit multiplication - int16 r0 = (int16)(r4824 + (r4825 << 8)); - int16 r1 = (int16)(r4820 + (r4821 << 8)); + case 0x4820: r4820 = data; break; + case 0x4821: r4821 = data; break; + case 0x4822: r4822 = data; break; + case 0x4823: r4823 = data; break; + case 0x4824: r4824 = data; break; + case 0x4825: { + r4825 = data; - signed result = r0 * r1; - r4828 = result; - r4829 = result >> 8; - r482a = result >> 16; - r482b = result >> 24; + if(r482e & 1) { + //signed 16-bit x 16-bit multiplication + int16 r0 = (int16)(r4824 + (r4825 << 8)); + int16 r1 = (int16)(r4820 + (r4821 << 8)); + + signed result = r0 * r1; + r4828 = result; + r4829 = result >> 8; + r482a = result >> 16; + r482b = result >> 24; + } else { + //unsigned 16-bit x 16-bit multiplication + uint16 r0 = (uint16)(r4824 + (r4825 << 8)); + uint16 r1 = (uint16)(r4820 + (r4821 << 8)); + + unsigned result = r0 * r1; + r4828 = result; + r4829 = result >> 8; + r482a = result >> 16; + r482b = result >> 24; + } + + r482f = 0x80; + } break; + case 0x4826: r4826 = data; break; + case 0x4827: { + r4827 = data; + + if(r482e & 1) { + //signed 32-bit x 16-bit division + int32 dividend = (int32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); + int16 divisor = (int16)(r4826 + (r4827 << 8)); + + int32 quotient; + int16 remainder; + + if(divisor) { + quotient = (int32)(dividend / divisor); + remainder = (int32)(dividend % divisor); } else { - //unsigned 16-bit x 16-bit multiplication - uint16 r0 = (uint16)(r4824 + (r4825 << 8)); - uint16 r1 = (uint16)(r4820 + (r4821 << 8)); - - unsigned result = r0 * r1; - r4828 = result; - r4829 = result >> 8; - r482a = result >> 16; - r482b = result >> 24; + //illegal division by zero + quotient = 0; + remainder = dividend & 0xffff; } - r482f = 0x80; - } break; - case 0x4826: r4826 = data; break; - case 0x4827: { - r4827 = data; + r4828 = quotient; + r4829 = quotient >> 8; + r482a = quotient >> 16; + r482b = quotient >> 24; - if(r482e & 1) { - //signed 32-bit x 16-bit division - int32 dividend = (int32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); - int16 divisor = (int16)(r4826 + (r4827 << 8)); + r482c = remainder; + r482d = remainder >> 8; + } else { + //unsigned 32-bit x 16-bit division + uint32 dividend = (uint32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); + uint16 divisor = (uint16)(r4826 + (r4827 << 8)); - int32 quotient; - int16 remainder; + uint32 quotient; + uint16 remainder; - if(divisor) { - quotient = (int32)(dividend / divisor); - remainder = (int32)(dividend % divisor); - } else { - //illegal division by zero - quotient = 0; - remainder = dividend & 0xffff; + if(divisor) { + quotient = (uint32)(dividend / divisor); + remainder = (uint16)(dividend % divisor); + } else { + //illegal division by zero + quotient = 0; + remainder = dividend & 0xffff; + } + + r4828 = quotient; + r4829 = quotient >> 8; + r482a = quotient >> 16; + r482b = quotient >> 24; + + r482c = remainder; + r482d = remainder >> 8; + } + + r482f = 0x80; + } break; + + case 0x482e: { + //reset math unit + r4820 = r4821 = r4822 = r4823 = 0; + r4824 = r4825 = r4826 = r4827 = 0; + r4828 = r4829 = r482a = r482b = 0; + r482c = r482d = 0; + + r482e = data; + } break; + + //=================== + //memory mapping unit + //=================== + + case 0x4830: r4830 = data & 0x87; break; + case 0x4831: r4831 = data & 0x07; break; + case 0x4832: r4832 = data & 0x07; break; + case 0x4833: r4833 = data & 0x07; break; + case 0x4834: r4834 = data & 0x07; break; + + //==================== + //real-time clock unit + //==================== + + case 0x4840: { + r4840 = data; + if(!(r4840 & 1)) { + //disable RTC + rtc_state = RTCS_Inactive; + update_time(); + } else { + //enable RTC + r4842 = 0x80; + rtc_state = RTCS_ModeSelect; + } + } break; + + case 0x4841: { + r4841 = data; + + switch(rtc_state) { + case RTCS_ModeSelect: { + if(data == RTCM_Linear || data == RTCM_Indexed) { + r4842 = 0x80; + rtc_state = RTCS_IndexSelect; + rtc_mode = (RTC_Mode)data; + rtc_index = 0; } + } break; - r4828 = quotient; - r4829 = quotient >> 8; - r482a = quotient >> 16; - r482b = quotient >> 24; - - r482c = remainder; - r482d = remainder >> 8; - } else { - //unsigned 32-bit x 16-bit division - uint32 dividend = (uint32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); - uint16 divisor = (uint16)(r4826 + (r4827 << 8)); - - uint32 quotient; - uint16 remainder; - - if(divisor) { - quotient = (uint32)(dividend / divisor); - remainder = (uint16)(dividend % divisor); - } else { - //illegal division by zero - quotient = 0; - remainder = dividend & 0xffff; - } - - r4828 = quotient; - r4829 = quotient >> 8; - r482a = quotient >> 16; - r482b = quotient >> 24; - - r482c = remainder; - r482d = remainder >> 8; - } - - r482f = 0x80; - } break; - - case 0x482e: { - //reset math unit - r4820 = r4821 = r4822 = r4823 = 0; - r4824 = r4825 = r4826 = r4827 = 0; - r4828 = r4829 = r482a = r482b = 0; - r482c = r482d = 0; - - r482e = data; - } break; - - //=================== - //memory mapping unit - //=================== - - case 0x4830: r4830 = data; break; - - case 0x4831: { - r4831 = data; - dx_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4832: { - r4832 = data; - ex_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4833: { - r4833 = data; - fx_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4834: r4834 = data; break; - - //==================== - //real-time clock unit - //==================== - - case 0x4840: { - r4840 = data; - if(!(r4840 & 1)) { - //disable RTC - rtc_state = RTCS_Inactive; - update_time(); - } else { - //enable RTC + case RTCS_IndexSelect: { r4842 = 0x80; - rtc_state = RTCS_ModeSelect; - } - } break; + rtc_index = data & 15; + if(rtc_mode == RTCM_Linear) rtc_state = RTCS_Write; + } break; - case 0x4841: { - r4841 = data; + case RTCS_Write: { + r4842 = 0x80; - switch(rtc_state) { - case RTCS_ModeSelect: { - if(data == RTCM_Linear || data == RTCM_Indexed) { - r4842 = 0x80; - rtc_state = RTCS_IndexSelect; - rtc_mode = (RTC_Mode)data; - rtc_index = 0; + //control register 0 + if(rtc_index == 13) { + //increment second counter + if(data & 2) update_time(+1); + + //round minute counter + if(data & 8) { + update_time(); + + unsigned second = rtc[ 0] + rtc[ 1] * 10; + //clear seconds + rtc[0] = 0; + rtc[1] = 0; + + if(second >= 30) update_time(+60); } - } break; + } - case RTCS_IndexSelect: { - r4842 = 0x80; - rtc_index = data & 15; - if(rtc_mode == RTCM_Linear) rtc_state = RTCS_Write; - } break; + //control register 2 + if(rtc_index == 15) { + //disable timer and clear second counter + if((data & 1) && !(rtc[15] & 1)) { + update_time(); - case RTCS_Write: { - r4842 = 0x80; - - //control register 0 - if(rtc_index == 13) { - //increment second counter - if(data & 2) update_time(+1); - - //round minute counter - if(data & 8) { - update_time(); - - unsigned second = rtc[ 0] + rtc[ 1] * 10; - //clear seconds - rtc[0] = 0; - rtc[1] = 0; - - if(second >= 30) update_time(+60); - } + //clear seconds + rtc[0] = 0; + rtc[1] = 0; } - //control register 2 - if(rtc_index == 15) { - //disable timer and clear second counter - if((data & 1) && !(rtc[15] & 1)) { - update_time(); - - //clear seconds - rtc[0] = 0; - rtc[1] = 0; - } - - //disable timer - if((data & 2) && !(rtc[15] & 2)) { - update_time(); - } + //disable timer + if((data & 2) && !(rtc[15] & 2)) { + update_time(); } + } + + rtc[rtc_index] = data & 15; + rtc_index = (rtc_index + 1) & 15; + } break; + } //switch(rtc_state) + } break; - rtc[rtc_index] = data & 15; - rtc_index = (rtc_index + 1) & 15; - } break; - } //switch(rtc_state) - } break; } } SPC7110::SPC7110() { } -//============ -//SPC7110::MCU -//============ - -uint8 SPC7110::mcu_read(unsigned addr) { - if(addr <= 0xdfffff) return cartridge.rom.read(dx_offset + (addr & 0x0fffff)); - if(addr <= 0xefffff) return cartridge.rom.read(ex_offset + (addr & 0x0fffff)); - if(addr <= 0xffffff) return cartridge.rom.read(fx_offset + (addr & 0x0fffff)); - return cpu.regs.mdr; -} - -void SPC7110::mcu_write(unsigned addr, uint8 data) { -} - //============ //SPC7110::DCU //============ @@ -659,16 +635,86 @@ uint8 SPC7110::dcu_read(unsigned) { void SPC7110::dcu_write(unsigned, uint8) { } -//============ -//SPC7110::RAM -//============ +//=============== +//SPC7110::MCUROM +//=============== -uint8 SPC7110::ram_read(unsigned addr) { - return cartridge.ram.read(addr & 0x1fff); +uint8 SPC7110::mcurom_read(unsigned addr) { + unsigned bank = 0; + + if((addr & 0x708000) == 0x008000 //$00-0f|80-8f:8000-ffff + || (addr & 0xf00000) == 0xc00000 // $c0-cf:0000-ffff + ) { + addr &= 0x0fffff; + if(true) { //8mbit PROM + return cartridge.rom.read(prom_base + bus.mirror(0x000000 + addr, prom_size)); + } + return mcurom_read_data(r4830 & 7, addr); + } + + if((addr & 0x708000) == 0x108000 //$10-1f|90-9f:8000-ffff + || (addr & 0xf00000) == 0xd00000 // $d0-df:0000-ffff + ) { + addr &= 0x0fffff; + if(r4834 & 4) { //16mbit PROM + return cartridge.rom.read(prom_base + bus.mirror(0x100000 + addr, prom_size)); + } + return mcurom_read_data(r4831 & 7, addr); + } + + if((addr & 0x708000) == 0x208000 //$20-2f|a0-af:8000-ffff + || (addr & 0xf00000) == 0xe00000 // $e0-ef:0000-ffff + ) { + addr &= 0x0fffff; + return mcurom_read_data(r4832 & 7, addr); + } + + if((addr & 0x708000) == 0x308000 //$30-3f|b0-bf:8000-ffff + || (addr & 0xf00000) == 0xf00000 // $f0-ff:0000-ffff + ) { + addr &= 0x0fffff; + return mcurom_read_data(r4833 & 7, addr); + } + + return cpu.regs.mdr; } -void SPC7110::ram_write(unsigned addr, uint8 data) { - if(r4830 & 0x80) cartridge.ram.write(addr & 0x1fff, data); +uint8 SPC7110::mcurom_read_data(unsigned bank, unsigned addr) { + unsigned mask = (1 << (r4834 & 3)) - 1; //8mbit, 16mbit, 32mbit, 64mbit DROM + unsigned range = 0x100000 * (1 + mask); + unsigned offset = 0x100000 * (bank & mask); + + //mirroring behavior is non-sensical. assuming a 32mbit data ROM: + //banks 4-7 with mask 0-2 returns 0x00; banks 4-7 with mask 3 mirrors banks 0-3 + if(range <= drom_size && offset >= drom_size) return 0x00; + + return cartridge.rom.read(drom_base + bus.mirror(offset + addr, drom_size)); +} + +void SPC7110::mcurom_write(unsigned addr, uint8 data) { +} + +//=============== +//SPC7110::MCURAM +//=============== + +uint8 SPC7110::mcuram_read(unsigned addr) { + //$00-3f|80-bf:6000-7fff + if(r4830 & 0x80) { + unsigned bank = (addr >> 16) & 0x3f; + addr = bus.mirror(bank * 0x2000 + (addr & 0x1fff), cartridge.ram.size()); + return cartridge.ram.read(addr); + } + return 0x00; +} + +void SPC7110::mcuram_write(unsigned addr, uint8 data) { + //$00-3f|80-bf:6000-7fff + if(r4830 & 0x80) { + unsigned bank = (addr >> 16) & 0x3f; + addr = bus.mirror(bank * 0x2000 + (addr & 0x1fff), cartridge.ram.size()); + cartridge.ram.write(addr, data); + } } } diff --git a/bsnes/sfc/chip/spc7110/spc7110.hpp b/bsnes/sfc/chip/spc7110/spc7110.hpp index 5164a326..ac0d2009 100755 --- a/bsnes/sfc/chip/spc7110/spc7110.hpp +++ b/bsnes/sfc/chip/spc7110/spc7110.hpp @@ -3,7 +3,8 @@ struct SPC7110 { uint8 rtc[20]; - unsigned data_rom_offset; + unsigned prom_base, prom_size; //program ROM + unsigned drom_base, drom_size; //data ROM void init(); void load(); @@ -25,14 +26,15 @@ struct SPC7110 { uint8 mmio_read(unsigned addr); void mmio_write(unsigned addr, uint8 data); - uint8 mcu_read(unsigned addr); - void mcu_write(unsigned addr, uint8 data); - uint8 dcu_read(unsigned); void dcu_write(unsigned, uint8); - uint8 ram_read(unsigned addr); - void ram_write(unsigned addr, uint8 data); + uint8 mcurom_read(unsigned addr); + uint8 mcurom_read_data(unsigned bank, unsigned addr); + void mcurom_write(unsigned addr, uint8 data); + + uint8 mcuram_read(unsigned addr); + void mcuram_write(unsigned addr, uint8 data); //spc7110decomp void decomp_init(); @@ -101,15 +103,11 @@ private: //=================== //memory mapping unit //=================== - uint8 r4830; //SRAM write enable - uint8 r4831; //$[d0-df]:[0000-ffff] mapping - uint8 r4832; //$[e0-ef]:[0000-ffff] mapping - uint8 r4833; //$[f0-ff]:[0000-ffff] mapping - uint8 r4834; //??? - - unsigned dx_offset; - unsigned ex_offset; - unsigned fx_offset; + uint8 r4830; //bank 0 mapping + SRAM write enable + uint8 r4831; //bank 1 mapping + uint8 r4832; //bank 2 mapping + uint8 r4833; //bank 3 mapping + uint8 r4834; //bank mapping control //==================== //real-time clock unit diff --git a/bsnes/sfc/cpu/cpu.cpp b/bsnes/sfc/cpu/cpu.cpp index d9c602d7..da28060a 100755 --- a/bsnes/sfc/cpu/cpu.cpp +++ b/bsnes/sfc/cpu/cpu.cpp @@ -86,6 +86,11 @@ void CPU::enter() { void CPU::op_step() { debugger.op_exec(regs.pc.d); + if(interface->tracer.open()) { + char text[4096]; + disassemble_opcode(text, regs.pc.d); + interface->tracer.print(text, "\n"); + } (this->*opcode_table[op_readpc()])(); } diff --git a/bsnes/sfc/interface/interface.cpp b/bsnes/sfc/interface/interface.cpp index 54eebae5..ced70901 100755 --- a/bsnes/sfc/interface/interface.cpp +++ b/bsnes/sfc/interface/interface.cpp @@ -174,6 +174,7 @@ void Interface::save(unsigned id, const stream &stream) { void Interface::unload() { cartridge.unload(); + tracerEnable(false); } void Interface::connect(unsigned port, unsigned device) { @@ -230,10 +231,30 @@ void Interface::cheatSet(const lstring &list) { cheat.synchronize(); } -void Interface::updatePalette() { +void Interface::paletteUpdate() { video.generate_palette(); } +bool Interface::tracerEnable(bool trace) { + string pathname = path(group(ID::ROM)); + + if(trace == true && !tracer.open()) { + for(unsigned n = 0; n <= 999; n++) { + string filename = {pathname, "trace-", decimal<3, '0'>(n), ".log"}; + if(file::exists(filename)) continue; + tracer.open(filename, file::mode::write); + return true; + } + } + + if(trace == false && tracer.open()) { + tracer.close(); + return true; + } + + return false; +} + Interface::Interface() { interface = this; system.init(); diff --git a/bsnes/sfc/interface/interface.hpp b/bsnes/sfc/interface/interface.hpp index be8c17be..aef7933f 100755 --- a/bsnes/sfc/interface/interface.hpp +++ b/bsnes/sfc/interface/interface.hpp @@ -53,11 +53,13 @@ struct Interface : Emulator::Interface { void cheatSet(const lstring&); - void updatePalette(); + void paletteUpdate(); + + bool tracerEnable(bool); Interface(); -private: + file tracer; vector device; }; diff --git a/bsnes/sfc/memory/memory-inline.hpp b/bsnes/sfc/memory/memory-inline.hpp index cf9e726b..b3a13c91 100755 --- a/bsnes/sfc/memory/memory-inline.hpp +++ b/bsnes/sfc/memory/memory-inline.hpp @@ -51,6 +51,24 @@ MappedRAM::MappedRAM() : data_(nullptr), size_(0), write_protect_(false) {} //Bus +unsigned Bus::mirror(unsigned addr, unsigned size) { + unsigned base = 0; + if(size) { + unsigned mask = 1 << 23; + while(addr >= size) { + while(!(addr & mask)) mask >>= 1; + addr -= mask; + if(size > mask) { + size -= mask; + base += mask; + } + mask >>= 1; + } + base += addr; + } + return base; +} + uint8 Bus::read(unsigned addr) { if(cheat.override[addr]) return cheat.read(addr); return reader[lookup[addr]](target[addr]); diff --git a/bsnes/sfc/memory/memory.cpp b/bsnes/sfc/memory/memory.cpp index ae2a4bf9..30ccd69f 100755 --- a/bsnes/sfc/memory/memory.cpp +++ b/bsnes/sfc/memory/memory.cpp @@ -5,24 +5,6 @@ namespace SuperFamicom { Bus bus; -unsigned Bus::mirror(unsigned addr, unsigned size) { - unsigned base = 0; - if(size) { - unsigned mask = 1 << 23; - while(addr >= size) { - while(!(addr & mask)) mask >>= 1; - addr -= mask; - if(size > mask) { - size -= mask; - base += mask; - } - mask >>= 1; - } - base += addr; - } - return base; -} - void Bus::map( MapMode mode, unsigned bank_lo, unsigned bank_hi, diff --git a/bsnes/sfc/memory/memory.hpp b/bsnes/sfc/memory/memory.hpp index 237e9498..c0bc7870 100755 --- a/bsnes/sfc/memory/memory.hpp +++ b/bsnes/sfc/memory/memory.hpp @@ -42,7 +42,7 @@ private: }; struct Bus { - unsigned mirror(unsigned addr, unsigned size); + alwaysinline static unsigned mirror(unsigned addr, unsigned size); alwaysinline uint8 read(unsigned addr); alwaysinline void write(unsigned addr, uint8 data); diff --git a/bsnes/target-ethos/Makefile b/bsnes/target-ethos/Makefile index cc1ca9c6..fdcf497b 100755 --- a/bsnes/target-ethos/Makefile +++ b/bsnes/target-ethos/Makefile @@ -74,6 +74,8 @@ ifeq ($(USER),root) @echo The installer needs to know your home directory to install important files. else ifeq ($(platform),x) sudo install -D -m 755 out/$(name) $(DESTDIR)$(prefix)/bin/$(name) + sudo install -D -m 644 data/$(name).png $(DESTDIR)$(prefix)/share/pixmaps/$(name).png + sudo install -D -m 644 data/$(name).desktop $(DESTDIR)$(prefix)/share/applications/$(name).desktop mkdir -p ~/.config/$(name) cp -R profile/* ~/.config/$(name) diff --git a/bsnes/target-ethos/input/hotkeys.cpp b/bsnes/target-ethos/input/hotkeys.cpp index 6781101d..982abde6 100755 --- a/bsnes/target-ethos/input/hotkeys.cpp +++ b/bsnes/target-ethos/input/hotkeys.cpp @@ -119,6 +119,16 @@ void InputManager::appendHotkeys() { }; } + { + auto hotkey = new HotkeyInput; + hotkey->name = "Toggle Tracer"; + hotkey->mapping = "None"; + + hotkey->press = [&] { + utility->tracerToggle(); + }; + } + for(auto &hotkey : hotkeyMap) { string name = {"Hotkey::", hotkey->name}; name.replace(" ", ""); diff --git a/bsnes/target-ethos/settings/video.cpp b/bsnes/target-ethos/settings/video.cpp index 73eedd67..f741fb73 100755 --- a/bsnes/target-ethos/settings/video.cpp +++ b/bsnes/target-ethos/settings/video.cpp @@ -59,5 +59,5 @@ void VideoSettings::synchronize() { overscanHorizontal.value.setText({config->video.maskOverscanHorizontal, "px"}); overscanVertical.value.setText({config->video.maskOverscanVertical, "px"}); - if(application->active) system().updatePalette(); + if(application->active) system().paletteUpdate(); } diff --git a/bsnes/target-ethos/utility/utility.cpp b/bsnes/target-ethos/utility/utility.cpp index 5ca4fb34..9346a6d4 100755 --- a/bsnes/target-ethos/utility/utility.cpp +++ b/bsnes/target-ethos/utility/utility.cpp @@ -99,7 +99,7 @@ void Utility::load() { loadMemory(); - system().updatePalette(); + system().paletteUpdate(); synchronizeDSP(); resize(); @@ -109,6 +109,7 @@ void Utility::load() { void Utility::unload() { if(application->active == nullptr) return; + if(tracerEnable) tracerToggle(); saveMemory(); system().unload(); @@ -143,6 +144,16 @@ void Utility::loadState(unsigned slot) { showMessage({"Loaded from slot ", slot}); } +void Utility::tracerToggle() { + if(application->active == nullptr) return; + tracerEnable = !tracerEnable; + bool result = system().tracerEnable(tracerEnable); + if( tracerEnable && result) return utility->showMessage("Tracer activated"); + if( tracerEnable && !result) return tracerEnable = false, utility->showMessage("Unable to activate tracer"); + if(!tracerEnable && result) return utility->showMessage("Tracer deactivated"); + if(!tracerEnable && !result) return utility->showMessage("Unable to deactivate tracer"); +} + void Utility::synchronizeDSP() { if(application->active == nullptr) return; @@ -280,5 +291,6 @@ void Utility::showMessage(const string &message) { } Utility::Utility() { + tracerEnable = false; statusTime = 0; } diff --git a/bsnes/target-ethos/utility/utility.hpp b/bsnes/target-ethos/utility/utility.hpp index 6d5cadb5..a509c936 100755 --- a/bsnes/target-ethos/utility/utility.hpp +++ b/bsnes/target-ethos/utility/utility.hpp @@ -16,6 +16,8 @@ struct Utility { void saveState(unsigned slot); void loadState(unsigned slot); + void tracerToggle(); + void synchronizeDSP(); void synchronizeRuby(); void updateShader(); @@ -32,6 +34,7 @@ struct Utility { lstring pathname; private: + bool tracerEnable; string statusText; string statusMessage; time_t statusTime;