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
This commit is contained in:
Tim Allen 2012-05-14 23:32:55 +10:00
parent 73ebe093b8
commit a1e4c67a05
26 changed files with 873 additions and 774 deletions

View File

@ -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";
}

View File

@ -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) {}
};

View File

@ -76,7 +76,7 @@ void Interface::cheatSet(const lstring &list) {
cheat.synchronize();
}
void Interface::updatePalette() {
void Interface::paletteUpdate() {
video.generate_palette();
}

View File

@ -33,7 +33,7 @@ struct Interface : Emulator::Interface {
void cheatSet(const lstring&);
void updatePalette();
void paletteUpdate();
Interface();

View File

@ -99,7 +99,7 @@ void Interface::cheatSet(const lstring &list) {
cheat.synchronize();
}
void Interface::updatePalette() {
void Interface::paletteUpdate() {
video.generate_palette();
}

View File

@ -45,7 +45,7 @@ struct Interface : Emulator::Interface {
void cheatSet(const lstring&);
void updatePalette();
void paletteUpdate();
Interface();

View File

@ -79,7 +79,7 @@ bool Interface::unserialize(serializer &s) {
return system.unserialize(s);
}
void Interface::updatePalette() {
void Interface::paletteUpdate() {
video.generate_palette();
}

View File

@ -32,7 +32,7 @@ struct Interface : Emulator::Interface {
serializer serialize();
bool unserialize(serializer&);
void updatePalette();
void paletteUpdate();
Interface();

View File

@ -158,26 +158,11 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
else if(has_spc7110) {
markup.append(
" <rom>\n"
" <map mode='shadow' address='00-0f:8000-ffff'/>\n"
" <map mode='shadow' address='80-bf:8000-ffff'/>\n"
" <map mode='linear' address='c0-cf:0000-ffff'/>\n"
" </rom>\n"
" <spc7110>\n"
" <ram size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='00:6000-7fff'/>\n"
" <map mode='linear' address='30:6000-7fff'/>\n"
" </ram>\n"
" <mmio>\n"
" <map address='00-3f:4800-483f'/>\n"
" <map address='80-bf:4800-483f'/>\n"
" </mmio>\n"
" <mcu>\n"
" <map address='d0-ff:0000-ffff' offset='0x100000' size='0x", hex(size - 0x100000), "'/>\n"
" </mcu>\n"
" <dcu>\n"
" <map address='50:0000-ffff'/>\n"
" </dcu>\n"
);
if(has_spc7110rtc) markup.append(
" <rtc>\n"
@ -186,6 +171,22 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" </rtc>\n"
);
markup.append(
" <dcu>\n"
" <map address='50:0000-ffff'/>\n"
" </dcu>\n"
" <mcu>\n"
" <rom>\n"
" <program offset='0x000000' size='0x100000'/>\n"
" <data offset='0x100000' size='", hex(rom_size - 0x100000), "'/>\n"
" <map address='00-0f:8000-ffff'/>\n"
" <map address='80-bf:8000-ffff'/>\n"
" <map address='c0-cf:0000-ffff'/>\n"
" </rom>\n"
" <ram size='0x", hex(ram_size), "'>\n"
" <map address='00-3f:6000-7fff'/>\n"
" <map address='80-bf:6000-7fff'/>\n"
" </ram>\n"
" </mcu>\n"
" </spc7110>\n"
);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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()])();
}

View File

@ -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();

View File

@ -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> device;
};

View File

@ -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]);

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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(" ", "");

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;