diff --git a/bsnes.exe b/bsnes.exe new file mode 100644 index 00000000..848cfe09 Binary files /dev/null and b/bsnes.exe differ diff --git a/demo_irqtest.smc b/demo_irqtest.smc new file mode 100644 index 00000000..384ae3c3 Binary files /dev/null and b/demo_irqtest.smc differ diff --git a/demo_nmitest.smc b/demo_nmitest.smc new file mode 100644 index 00000000..b91d4ec9 Binary files /dev/null and b/demo_nmitest.smc differ diff --git a/irq.smc b/irq.smc new file mode 100644 index 00000000..1559b6d9 Binary files /dev/null and b/irq.smc differ diff --git a/nmi.smc b/nmi.smc new file mode 100644 index 00000000..876df233 Binary files /dev/null and b/nmi.smc differ diff --git a/src/base.hpp b/src/base.hpp index 72e7caef..e27c13b6 100644 --- a/src/base.hpp +++ b/src/base.hpp @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.038" +#define BSNES_VERSION "0.038.05" #define BSNES_TITLE "bsnes v" BSNES_VERSION #define BUSCORE sBus diff --git a/src/cheat/cheat.cpp b/src/cheat/cheat.cpp index d9f838d6..2dc25281 100644 --- a/src/cheat/cheat.cpp +++ b/src/cheat/cheat.cpp @@ -74,7 +74,7 @@ bool Cheat::encode(string &str, unsigned addr, uint8 data, type_t type) { char t[16]; if(type == ProActionReplay) { - sprintf(t, "%0.6x:%0.2x", addr, data); + sprintf(t, "%.6x:%.2x", addr, data); str = t; return true; } else if(type == GameGenie) { @@ -91,7 +91,7 @@ bool Cheat::encode(string &str, unsigned addr, uint8 data, type_t type) { (!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4) | (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2) | (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0); - sprintf(t, "%0.2x%0.2x-%0.4x", data, addr >> 16, addr & 0xffff); + sprintf(t, "%.2x%.2x-%.4x", data, addr >> 16, addr & 0xffff); strtr(t, "0123456789abcdef", "df4709156bc8a23e"); str = t; return true; diff --git a/src/config/config.cpp b/src/config/config.cpp index ce4fb4d7..dab0868b 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -102,4 +102,9 @@ integral_setting SMP::ntsc_clock_rate(config(), "smp.ntsc_clock_rate", integral_setting SMP::pal_clock_rate(config(), "smp.pal_clock_rate", "PAL S-SMP clock rate (in hz)", integral_setting::decimal, 32041 * 768); +integral_setting Temp::alu_mul_delay(config(), "temp.alu_mul_delay", + "", integral_setting::decimal, 32); +integral_setting Temp::alu_div_delay(config(), "temp.alu_div_delay", + "", integral_setting::decimal, 64); + } //namespace config diff --git a/src/config/config.hpp b/src/config/config.hpp index 81b381ea..1ff13109 100644 --- a/src/config/config.hpp +++ b/src/config/config.hpp @@ -31,4 +31,8 @@ extern struct SMP { static integral_setting ntsc_clock_rate, pal_clock_rate; } smp; +extern struct Temp { + static integral_setting alu_mul_delay, alu_div_delay; +} temp; + }; diff --git a/src/cpu/cpu.hpp b/src/cpu/cpu.hpp index 825b8ab5..aa462078 100644 --- a/src/cpu/cpu.hpp +++ b/src/cpu/cpu.hpp @@ -17,7 +17,6 @@ public: regs_t regs; virtual void scanline() = 0; - virtual void frame() = 0; virtual void power() = 0; virtual void reset() = 0; diff --git a/src/cpu/dcpu.cpp b/src/cpu/dcpu.cpp index 2c3281a5..bf8942a6 100644 --- a/src/cpu/dcpu.cpp +++ b/src/cpu/dcpu.cpp @@ -2,22 +2,22 @@ uint8 CPU::dreadb(uint32 addr) { if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) { - //$[00-3f|80-bf]:[2000-5fff] - //do not read MMIO registers within debugger + //$[00-3f|80-bf]:[2000-5fff] + //do not read MMIO registers within debugger return 0x00; } return bus.read(addr); } uint16 CPU::dreadw(uint32 addr) { -uint16 r; + uint16 r; r = dreadb((addr + 0) & 0xffffff) << 0; r |= dreadb((addr + 1) & 0xffffff) << 8; return r; } uint32 CPU::dreadl(uint32 addr) { -uint32 r; + uint32 r; r = dreadb((addr + 0) & 0xffffff) << 0; r |= dreadb((addr + 1) & 0xffffff) << 8; r |= dreadb((addr + 2) & 0xffffff) << 16; @@ -25,87 +25,89 @@ uint32 r; } uint32 CPU::decode(uint8 offset_type, uint32 addr) { -uint32 r = 0; + uint32 r = 0; + switch(offset_type) { - case OPTYPE_DP: - r = (regs.d + (addr & 0xffff)) & 0xffff; - break; - case OPTYPE_DPX: - r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff; - break; - case OPTYPE_DPY: - r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff; - break; - case OPTYPE_IDP: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr); - break; - case OPTYPE_IDPX: - addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr); - break; - case OPTYPE_IDPY: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr) + regs.y; - break; - case OPTYPE_ILDP: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = dreadl(addr); - break; - case OPTYPE_ILDPY: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = dreadl(addr) + regs.y; - break; - case OPTYPE_ADDR: - r = (regs.db << 16) + (addr & 0xffff); - break; - case OPTYPE_ADDR_PC: - r = (regs.pc.b << 16) + (addr & 0xffff); - break; - case OPTYPE_ADDRX: - r = (regs.db << 16) + (addr & 0xffff) + regs.x; - break; - case OPTYPE_ADDRY: - r = (regs.db << 16) + (addr & 0xffff) + regs.y; - break; - case OPTYPE_IADDR_PC: - r = (regs.pc.b << 16) + (addr & 0xffff); - break; - case OPTYPE_IADDRX: - r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff); - break; - case OPTYPE_ILADDR: - r = addr; - break; - case OPTYPE_LONG: - r = addr; - break; - case OPTYPE_LONGX: - r = (addr + regs.x); - break; - case OPTYPE_SR: - r = (regs.s + (addr & 0xff)) & 0xffff; - break; - case OPTYPE_ISRY: - addr = (regs.s + (addr & 0xff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr) + regs.y; - break; - case OPTYPE_RELB: - r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff); - r += int8(addr); - break; - case OPTYPE_RELW: - r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff); - r += int16(addr); - break; + case OPTYPE_DP: + r = (regs.d + (addr & 0xffff)) & 0xffff; + break; + case OPTYPE_DPX: + r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff; + break; + case OPTYPE_DPY: + r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff; + break; + case OPTYPE_IDP: + addr = (regs.d + (addr & 0xffff)) & 0xffff; + r = (regs.db << 16) + dreadw(addr); + break; + case OPTYPE_IDPX: + addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff; + r = (regs.db << 16) + dreadw(addr); + break; + case OPTYPE_IDPY: + addr = (regs.d + (addr & 0xffff)) & 0xffff; + r = (regs.db << 16) + dreadw(addr) + regs.y; + break; + case OPTYPE_ILDP: + addr = (regs.d + (addr & 0xffff)) & 0xffff; + r = dreadl(addr); + break; + case OPTYPE_ILDPY: + addr = (regs.d + (addr & 0xffff)) & 0xffff; + r = dreadl(addr) + regs.y; + break; + case OPTYPE_ADDR: + r = (regs.db << 16) + (addr & 0xffff); + break; + case OPTYPE_ADDR_PC: + r = (regs.pc.b << 16) + (addr & 0xffff); + break; + case OPTYPE_ADDRX: + r = (regs.db << 16) + (addr & 0xffff) + regs.x; + break; + case OPTYPE_ADDRY: + r = (regs.db << 16) + (addr & 0xffff) + regs.y; + break; + case OPTYPE_IADDR_PC: + r = (regs.pc.b << 16) + (addr & 0xffff); + break; + case OPTYPE_IADDRX: + r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff); + break; + case OPTYPE_ILADDR: + r = addr; + break; + case OPTYPE_LONG: + r = addr; + break; + case OPTYPE_LONGX: + r = (addr + regs.x); + break; + case OPTYPE_SR: + r = (regs.s + (addr & 0xff)) & 0xffff; + break; + case OPTYPE_ISRY: + addr = (regs.s + (addr & 0xff)) & 0xffff; + r = (regs.db << 16) + dreadw(addr) + regs.y; + break; + case OPTYPE_RELB: + r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff); + r += int8(addr); + break; + case OPTYPE_RELW: + r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff); + r += int16(addr); + break; } + return(r & 0xffffff); } void CPU::disassemble_opcode(char *output) { -static reg24_t pc; -char t[256]; -char *s = output; + static reg24_t pc; + char t[256]; + char *s = output; if(in_opcode() == true) { strcpy(s, "?????? "); @@ -113,367 +115,369 @@ char *s = output; } pc.d = regs.pc.d; - sprintf(s, "%0.6x ", uint32(pc.d)); + sprintf(s, "%.6x ", (uint32)pc.d); -uint8 op = dreadb(pc.d); pc.w++; -uint8 op0 = dreadb(pc.d); pc.w++; -uint8 op1 = dreadb(pc.d); pc.w++; -uint8 op2 = dreadb(pc.d); + uint8 op = dreadb(pc.d); pc.w++; + uint8 op0 = dreadb(pc.d); pc.w++; + uint8 op1 = dreadb(pc.d); pc.w++; + uint8 op2 = dreadb(pc.d); + + #define op8 ((op0)) + #define op16 ((op0) | (op1 << 8)) + #define op24 ((op0) | (op1 << 8) | (op2 << 16)) + #define a8 (regs.e || regs.p.m) + #define x8 (regs.e || regs.p.x) -#define op8 ((op0)) -#define op16 ((op0) | (op1 << 8)) -#define op24 ((op0) | (op1 << 8) | (op2 << 16)) -#define a8 (regs.e || regs.p.m) -#define x8 (regs.e || regs.p.x) switch(op) { - case 0x00: sprintf(t, "brk #$%0.2x ", op8); break; - case 0x01: sprintf(t, "ora ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x02: sprintf(t, "cop #$%0.2x ", op8); break; - case 0x03: sprintf(t, "ora $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x04: sprintf(t, "tsb $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x05: sprintf(t, "ora $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x06: sprintf(t, "asl $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x07: sprintf(t, "ora [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x08: sprintf(t, "php "); break; - case 0x09: if(a8)sprintf(t, "ora #$%0.2x ", op8); - else sprintf(t, "ora #$%0.4x ", op16); break; - case 0x0a: sprintf(t, "asl a "); break; - case 0x0b: sprintf(t, "phd "); break; - case 0x0c: sprintf(t, "tsb $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0d: sprintf(t, "ora $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0e: sprintf(t, "asl $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0f: sprintf(t, "ora $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x10: sprintf(t, "bpl $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x11: sprintf(t, "ora ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x12: sprintf(t, "ora ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x13: sprintf(t, "ora ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x14: sprintf(t, "trb $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x15: sprintf(t, "ora $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x16: sprintf(t, "asl $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x17: sprintf(t, "ora [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x18: sprintf(t, "clc "); break; - case 0x19: sprintf(t, "ora $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x1a: sprintf(t, "inc "); break; - case 0x1b: sprintf(t, "tcs "); break; - case 0x1c: sprintf(t, "trb $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x1d: sprintf(t, "ora $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x1e: sprintf(t, "asl $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x1f: sprintf(t, "ora $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x20: sprintf(t, "jsr $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; - case 0x21: sprintf(t, "and ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x22: sprintf(t, "jsl $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x23: sprintf(t, "and $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x24: sprintf(t, "bit $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x25: sprintf(t, "and $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x26: sprintf(t, "rol $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x27: sprintf(t, "and [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x28: sprintf(t, "plp "); break; - case 0x29: if(a8)sprintf(t, "and #$%0.2x ", op8); - else sprintf(t, "and #$%0.4x ", op16); break; - case 0x2a: sprintf(t, "rol a "); break; - case 0x2b: sprintf(t, "pld "); break; - case 0x2c: sprintf(t, "bit $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2d: sprintf(t, "and $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2e: sprintf(t, "rol $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2f: sprintf(t, "and $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x30: sprintf(t, "bmi $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x31: sprintf(t, "and ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x32: sprintf(t, "and ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x33: sprintf(t, "and ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x34: sprintf(t, "bit $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x35: sprintf(t, "and $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x36: sprintf(t, "rol $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x37: sprintf(t, "and [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x38: sprintf(t, "sec "); break; - case 0x39: sprintf(t, "and $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x3a: sprintf(t, "dec "); break; - case 0x3b: sprintf(t, "tsc "); break; - case 0x3c: sprintf(t, "bit $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3d: sprintf(t, "and $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3e: sprintf(t, "rol $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3f: sprintf(t, "and $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x40: sprintf(t, "rti "); break; - case 0x41: sprintf(t, "eor ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x42: sprintf(t, "wdm "); break; - case 0x43: sprintf(t, "eor $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x44: sprintf(t, "mvp $%0.2x,$%0.2x ", op1, op8); break; - case 0x45: sprintf(t, "eor $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x46: sprintf(t, "lsr $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x47: sprintf(t, "eor [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x48: sprintf(t, "pha "); break; - case 0x49: if(a8)sprintf(t, "eor #$%0.2x ", op8); - else sprintf(t, "eor #$%0.4x ", op16); break; - case 0x4a: sprintf(t, "lsr a "); break; - case 0x4b: sprintf(t, "phk "); break; - case 0x4c: sprintf(t, "jmp $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; - case 0x4d: sprintf(t, "eor $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x4e: sprintf(t, "lsr $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x4f: sprintf(t, "eor $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x50: sprintf(t, "bvc $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x51: sprintf(t, "eor ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x52: sprintf(t, "eor ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x53: sprintf(t, "eor ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x54: sprintf(t, "mvn $%0.2x,$%0.2x ", op1, op8); break; - case 0x55: sprintf(t, "eor $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x56: sprintf(t, "lsr $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x57: sprintf(t, "eor [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x58: sprintf(t, "cli "); break; - case 0x59: sprintf(t, "eor $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x5a: sprintf(t, "phy "); break; - case 0x5b: sprintf(t, "tcd "); break; - case 0x5c: sprintf(t, "jml $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x5d: sprintf(t, "eor $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x5e: sprintf(t, "lsr $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x5f: sprintf(t, "eor $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x60: sprintf(t, "rts "); break; - case 0x61: sprintf(t, "adc ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x62: sprintf(t, "per $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x63: sprintf(t, "adc $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x64: sprintf(t, "stz $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x65: sprintf(t, "adc $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x66: sprintf(t, "ror $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x67: sprintf(t, "adc [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x68: sprintf(t, "pla "); break; - case 0x69: if(a8)sprintf(t, "adc #$%0.2x ", op8); - else sprintf(t, "adc #$%0.4x ", op16); break; - case 0x6a: sprintf(t, "ror a "); break; - case 0x6b: sprintf(t, "rtl "); break; - case 0x6c: sprintf(t, "jmp ($%0.4x) [$%0.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break; - case 0x6d: sprintf(t, "adc $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x6e: sprintf(t, "ror $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x6f: sprintf(t, "adc $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x70: sprintf(t, "bvs $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x71: sprintf(t, "adc ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x72: sprintf(t, "adc ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x73: sprintf(t, "adc ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x74: sprintf(t, "stz $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x75: sprintf(t, "adc $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x76: sprintf(t, "ror $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x77: sprintf(t, "adc [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x78: sprintf(t, "sei "); break; - case 0x79: sprintf(t, "adc $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x7a: sprintf(t, "ply "); break; - case 0x7b: sprintf(t, "tdc "); break; - case 0x7c: sprintf(t, "jmp ($%0.4x,x) [$%0.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; - case 0x7d: sprintf(t, "adc $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x7e: sprintf(t, "ror $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x7f: sprintf(t, "adc $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x80: sprintf(t, "bra $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x81: sprintf(t, "sta ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x82: sprintf(t, "brl $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break; - case 0x83: sprintf(t, "sta $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x84: sprintf(t, "sty $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x85: sprintf(t, "sta $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x86: sprintf(t, "stx $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x87: sprintf(t, "sta [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x88: sprintf(t, "dey "); break; - case 0x89: if(a8)sprintf(t, "bit #$%0.2x ", op8); - else sprintf(t, "bit #$%0.4x ", op16); break; - case 0x8a: sprintf(t, "txa "); break; - case 0x8b: sprintf(t, "phb "); break; - case 0x8c: sprintf(t, "sty $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8d: sprintf(t, "sta $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8e: sprintf(t, "stx $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8f: sprintf(t, "sta $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x90: sprintf(t, "bcc $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x91: sprintf(t, "sta ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x92: sprintf(t, "sta ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x93: sprintf(t, "sta ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x94: sprintf(t, "sty $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x95: sprintf(t, "sta $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x96: sprintf(t, "stx $%0.2x,y [$%0.6x]", op8, decode(OPTYPE_DPY, op8)); break; - case 0x97: sprintf(t, "sta [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x98: sprintf(t, "tya "); break; - case 0x99: sprintf(t, "sta $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x9a: sprintf(t, "txs "); break; - case 0x9b: sprintf(t, "txy "); break; - case 0x9c: sprintf(t, "stz $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x9d: sprintf(t, "sta $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x9e: sprintf(t, "stz $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x9f: sprintf(t, "sta $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xa0: if(x8)sprintf(t, "ldy #$%0.2x ", op8); - else sprintf(t, "ldy #$%0.4x ", op16); break; - case 0xa1: sprintf(t, "lda ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xa2: if(x8)sprintf(t, "ldx #$%0.2x ", op8); - else sprintf(t, "ldx #$%0.4x ", op16); break; - case 0xa3: sprintf(t, "lda $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xa4: sprintf(t, "ldy $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa5: sprintf(t, "lda $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa6: sprintf(t, "ldx $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa7: sprintf(t, "lda [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xa8: sprintf(t, "tay "); break; - case 0xa9: if(a8)sprintf(t, "lda #$%0.2x ", op8); - else sprintf(t, "lda #$%0.4x ", op16); break; - case 0xaa: sprintf(t, "tax "); break; - case 0xab: sprintf(t, "plb "); break; - case 0xac: sprintf(t, "ldy $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xad: sprintf(t, "lda $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xae: sprintf(t, "ldx $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xaf: sprintf(t, "lda $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xb0: sprintf(t, "bcs $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xb1: sprintf(t, "lda ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xb2: sprintf(t, "lda ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xb3: sprintf(t, "lda ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xb4: sprintf(t, "ldy $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xb5: sprintf(t, "lda $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xb6: sprintf(t, "ldx $%0.2x,y [$%0.6x]", op8, decode(OPTYPE_DPY, op8)); break; - case 0xb7: sprintf(t, "lda [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xb8: sprintf(t, "clv "); break; - case 0xb9: sprintf(t, "lda $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xba: sprintf(t, "tsx "); break; - case 0xbb: sprintf(t, "tyx "); break; - case 0xbc: sprintf(t, "ldy $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xbd: sprintf(t, "lda $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xbe: sprintf(t, "ldx $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xbf: sprintf(t, "lda $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xc0: if(x8)sprintf(t, "cpy #$%0.2x ", op8); - else sprintf(t, "cpy #$%0.4x ", op16); break; - case 0xc1: sprintf(t, "cmp ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xc2: sprintf(t, "rep #$%0.2x ", op8); break; - case 0xc3: sprintf(t, "cmp $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xc4: sprintf(t, "cpy $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc5: sprintf(t, "cmp $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc6: sprintf(t, "dec $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc7: sprintf(t, "cmp [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xc8: sprintf(t, "iny "); break; - case 0xc9: if(a8)sprintf(t, "cmp #$%0.2x ", op8); - else sprintf(t, "cmp #$%0.4x ", op16); break; - case 0xca: sprintf(t, "dex "); break; - case 0xcb: sprintf(t, "wai "); break; - case 0xcc: sprintf(t, "cpy $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xcd: sprintf(t, "cmp $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xce: sprintf(t, "dec $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xcf: sprintf(t, "cmp $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xd0: sprintf(t, "bne $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xd1: sprintf(t, "cmp ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xd2: sprintf(t, "cmp ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xd3: sprintf(t, "cmp ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xd4: sprintf(t, "pei ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xd5: sprintf(t, "cmp $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xd6: sprintf(t, "dec $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xd7: sprintf(t, "cmp [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xd8: sprintf(t, "cld "); break; - case 0xd9: sprintf(t, "cmp $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xda: sprintf(t, "phx "); break; - case 0xdb: sprintf(t, "stp "); break; - case 0xdc: sprintf(t, "jmp [$%0.4x] [$%0.6x]", op16, decode(OPTYPE_ILADDR, op16)); break; - case 0xdd: sprintf(t, "cmp $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xde: sprintf(t, "dec $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xdf: sprintf(t, "cmp $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xe0: if(x8)sprintf(t, "cpx #$%0.2x ", op8); - else sprintf(t, "cpx #$%0.4x ", op16); break; - case 0xe1: sprintf(t, "sbc ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xe2: sprintf(t, "sep #$%0.2x ", op8); break; - case 0xe3: sprintf(t, "sbc $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xe4: sprintf(t, "cpx $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe5: sprintf(t, "sbc $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe6: sprintf(t, "inc $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe7: sprintf(t, "sbc [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xe8: sprintf(t, "inx "); break; - case 0xe9: if(a8)sprintf(t, "sbc #$%0.2x ", op8); - else sprintf(t, "sbc #$%0.4x ", op16); break; - case 0xea: sprintf(t, "nop "); break; - case 0xeb: sprintf(t, "xba "); break; - case 0xec: sprintf(t, "cpx $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xed: sprintf(t, "sbc $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xee: sprintf(t, "inc $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xef: sprintf(t, "sbc $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xf0: sprintf(t, "beq $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xf1: sprintf(t, "sbc ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xf2: sprintf(t, "sbc ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xf3: sprintf(t, "sbc ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xf4: sprintf(t, "pea $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xf5: sprintf(t, "sbc $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xf6: sprintf(t, "inc $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xf7: sprintf(t, "sbc [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xf8: sprintf(t, "sed "); break; - case 0xf9: sprintf(t, "sbc $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xfa: sprintf(t, "plx "); break; - case 0xfb: sprintf(t, "xce "); break; - case 0xfc: sprintf(t, "jsr ($%0.4x,x) [$%0.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; - case 0xfd: sprintf(t, "sbc $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xfe: sprintf(t, "inc $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xff: sprintf(t, "sbc $%0.6x,x [$%0.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 -#undef op16 -#undef op24 -#undef a8 -#undef x8 + + #undef op8 + #undef op16 + #undef op24 + #undef a8 + #undef x8 strcat(s, t); strcat(s, " "); - sprintf(t, "A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x ", + sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ", regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db); strcat(s, t); if(regs.e) { sprintf(t, "%c%c%c%c%c%c%c%c", - (regs.p.n) ? 'N' : 'n', (regs.p.v) ? 'V' : 'v', - (regs.p.m) ? '1' : '0', (regs.p.x) ? 'B' : 'b', - (regs.p.d) ? 'D' : 'd', (regs.p.i) ? 'I' : 'i', - (regs.p.z) ? 'Z' : 'z', (regs.p.c) ? 'C' : 'c'); + regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v', + regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b', + regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i', + regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); } else { sprintf(t, "%c%c%c%c%c%c%c%c", - (regs.p.n) ? 'N' : 'n', (regs.p.v) ? 'V' : 'v', - (regs.p.m) ? 'M' : 'm', (regs.p.x) ? 'X' : 'x', - (regs.p.d) ? 'D' : 'd', (regs.p.i) ? 'I' : 'i', - (regs.p.z) ? 'Z' : 'z', (regs.p.c) ? 'C' : 'c'); + regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v', + regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x', + regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i', + regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); } strcat(s, t); strcat(s, " "); - sprintf(t, "V:%3d H:%4d", ppucounter.vcounter(), ppucounter.hcounter()); + sprintf(t, "V:%3d H:%4d", ppu.vcounter(), ppu.hcounter()); strcat(s, t); } -/***** - * opcode_length() retrieves the length of the next opcode - * to be executed. It is used by the debugger to step over, - * disable and proceed cpu opcodes. - * - * 5 and 6 are special cases, 5 is used for #consts based on - * the A register size, 6 for the X/Y register size. the - * rest are literal sizes. There's no need to test for - * emulation mode, as regs.p.m/regs.p.x should *always* be - * set in emulation mode. - *****/ +//opcode_length() retrieves the length of the next opcode +//to be executed. It is used by the debugger to step over, +//disable and proceed cpu opcodes. +// +//5 and 6 are special cases, 5 is used for #consts based on +//the A register size, 6 for the X/Y register size. the +//rest are literal sizes. There's no need to test for +//emulation mode, as regs.p.m/regs.p.x should *always* be +//set in emulation mode. + uint8 CPU::opcode_length() { -uint8 op, len; -static uint8 op_len_tbl[256] = { -//0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f + uint8 op, len; + static uint8 op_len_tbl[256] = { + //0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f - 2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n - 3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n + 2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n + 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n + 3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n + 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n - 1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n - 2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n - 1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n + 1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n + 2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n + 1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n + 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n - 2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n - 6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn + 2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n + 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n + 6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan + 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn + + 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn + 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn + 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen + 2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn + }; - 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn - 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen - 2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn -}; if(in_opcode() == true) { return 0; } op = dreadb(regs.pc.d); len = op_len_tbl[op]; - if(len == 5)return (regs.e || regs.p.m) ? 2 : 3; - if(len == 6)return (regs.e || regs.p.x) ? 2 : 3; + if(len == 5) return (regs.e || regs.p.m) ? 2 : 3; + if(len == 6) return (regs.e || regs.p.x) ? 2 : 3; return len; } -#endif //ifdef CPU_CPP +#endif //ifdef CPU_CPP diff --git a/src/cpu/scpu/deltaqueue.cpp b/src/cpu/scpu/deltaqueue.cpp new file mode 100644 index 00000000..6fd321e1 --- /dev/null +++ b/src/cpu/scpu/deltaqueue.cpp @@ -0,0 +1,88 @@ +#ifdef SCPU_CPP + +//delta queue scheduler is used to time multiple events with the following properties: +//O(1) test (tick) +//O(log n) insert (enqueue) +//O(log n) remove (dequeue) +// +//notes: +//implementation uses binary min-heap array; +//tick() uses 2's-complement signed math to avoid overflow errors; +//enqueue() takes relative timestamps, which are converted to absolute times internally. + +class deltaqueue { + enum { queuesize = 64 }; //maximum number of events that can be queued at the same time. + +public: + alwaysinline void tick(unsigned ticks) { + counter += ticks; + + while(heapsize) { + if((signed)(counter - heap[0].counter) < 0) break; //if(counter < heap[0].counter) break; + unsigned event = heap[0].event; + dequeue(); + cpu.queue_event(event); + } + } + + void enqueue(unsigned event, unsigned ticks) { + unsigned child = heapsize++; + + heap[child].event = event; + heap[child].counter = counter + ticks; + + while(child) { + unsigned parent = (child - 1) >> 1; + if(heap[child].counter >= heap[parent].counter) break; + swap(parent, child); + child = parent; + } + } + + void dequeue() { + heap[0].counter = heap[--heapsize].counter; + heap[0].event = heap[heapsize].event; + heap[heapsize].counter = ~0; + + unsigned parent = 0; + while(true) { + unsigned child = (parent << 1) + 1; + if(heap[child + 1].counter < heap[child].counter) child++; + if(heap[parent].counter <= heap[child].counter) break; + swap(parent, child); + parent = child; + } + } + + void reset() { + counter = 0; + heapsize = 0; + for(unsigned i = 0; i < queuesize << 1; i++) heap[i].counter = ~0; + } + + deltaqueue() { + reset(); + } + +public: + unsigned counter; + unsigned heapsize; + + struct { + unsigned counter; + unsigned event; + } heap[queuesize << 1]; + + void swap(unsigned x, unsigned y) { + unsigned counter = heap[x].counter; + unsigned event = heap[x].event; + + heap[x].counter = heap[y].counter; + heap[x].event = heap[y].event; + + heap[y].counter = counter; + heap[y].event = event; + } +}; + +#endif //ifdef SCPU_CPP diff --git a/src/cpu/scpu/dma/dma.cpp b/src/cpu/scpu/dma/dma.cpp index 9fc9125f..a5888bee 100644 --- a/src/cpu/scpu/dma/dma.cpp +++ b/src/cpu/scpu/dma/dma.cpp @@ -121,7 +121,8 @@ void sCPU::dma_run() { channel[i].dma_enabled = false; } - counter.set(counter.irq_delay, 2); + status.irq_lock = true; + delta.enqueue(EventIrqLockRelease, 2); } /***** @@ -203,7 +204,8 @@ void sCPU::hdma_run() { } } - counter.set(counter.irq_delay, 2); + status.irq_lock = true; + delta.enqueue(EventIrqLockRelease, 2); } void sCPU::hdma_init_reset() { @@ -224,7 +226,8 @@ void sCPU::hdma_init() { hdma_update(i); } - counter.set(counter.irq_delay, 2); + status.irq_lock = true; + delta.enqueue(EventIrqLockRelease, 2); } /***** diff --git a/src/cpu/scpu/mmio/mmio.cpp b/src/cpu/scpu/mmio/mmio.cpp index 1e3698cb..5fc033ad 100644 --- a/src/cpu/scpu/mmio/mmio.cpp +++ b/src/cpu/scpu/mmio/mmio.cpp @@ -91,7 +91,9 @@ void sCPU::mmio_w4202(uint8 data) { void sCPU::mmio_w4203(uint8 data) { status.mul_b = data; status.r4216 = status.mul_a * status.mul_b; -//counter.set(counter.hw_math, 48); + + status.alu_lock = true; + delta.enqueue(EventAluLockRelease, temp_.alu_mul_delay); } //WRDIVL @@ -109,7 +111,9 @@ void sCPU::mmio_w4206(uint8 data) { status.div_b = data; status.r4214 = (status.div_b) ? status.div_a / status.div_b : 0xffff; status.r4216 = (status.div_b) ? status.div_a % status.div_b : status.div_a; -//counter.set(counter.hw_math, 96); + + status.alu_lock = true; + delta.enqueue(EventAluLockRelease, temp_.alu_div_delay); } //HTIMEL @@ -190,13 +194,13 @@ uint8 sCPU::mmio_r4212() { uint16 vs = ppu.overscan() == false ? 225 : 240; //auto joypad polling - if(ppucounter.vcounter() >= vs && ppucounter.vcounter() <= (vs + 2))r |= 0x01; + if(ppu.vcounter() >= vs && ppu.vcounter() <= (vs + 2))r |= 0x01; //hblank - if(ppucounter.hcounter() <= 2 || ppucounter.hcounter() >= 1096)r |= 0x40; + if(ppu.hcounter() <= 2 || ppu.hcounter() >= 1096)r |= 0x40; //vblank - if(ppucounter.vcounter() >= vs)r |= 0x80; + if(ppu.vcounter() >= vs)r |= 0x80; return r; } @@ -208,25 +212,25 @@ uint8 sCPU::mmio_r4213() { //RDDIVL uint8 sCPU::mmio_r4214() { - if(counter.hw_math) { return 0x00; } + if(status.alu_lock) return 0; return status.r4214; } //RDDIVH uint8 sCPU::mmio_r4215() { - if(counter.hw_math) { return 0x00; } + if(status.alu_lock) return 0; return status.r4214 >> 8; } //RDMPYL uint8 sCPU::mmio_r4216() { - if(counter.hw_math) { return 0x00; } + if(status.alu_lock) return 0; return status.r4216; } //RDMPYH uint8 sCPU::mmio_r4217() { - if(counter.hw_math) { return 0x00; } + if(status.alu_lock) return 0; return status.r4216 >> 8; } diff --git a/src/cpu/scpu/scpu.cpp b/src/cpu/scpu/scpu.cpp index b5bd2329..62118eea 100644 --- a/src/cpu/scpu/scpu.cpp +++ b/src/cpu/scpu/scpu.cpp @@ -1,6 +1,9 @@ #include <../base.hpp> #define SCPU_CPP +#include "deltaqueue.cpp" +deltaqueue delta; + #include "core/core.cpp" #include "dma/dma.cpp" #include "memory/memory.cpp" @@ -35,7 +38,7 @@ void sCPU::reset() { event.wai = false; event.irq = false; - event.irq_vector = 0xfffc; //reset vector address + event.irq_vector = 0xfffc; //reset vector address mmio_reset(); dma_reset(); diff --git a/src/cpu/scpu/scpu.hpp b/src/cpu/scpu/scpu.hpp index f0f81b52..9ed4d6dd 100644 --- a/src/cpu/scpu/scpu.hpp +++ b/src/cpu/scpu/scpu.hpp @@ -12,31 +12,15 @@ public: bool wai; bool irq; uint16 irq_vector; + unsigned cycle_edge; } event; + enum DmaState { DmaInactive, DmaRun, DmaCpuSync }; + struct { - unsigned nmi_hold; - unsigned irq_hold; - - unsigned nmi_fire; - unsigned irq_fire; - unsigned irq_delay; - unsigned hw_math; - - alwaysinline void set(uint &ctr, uint clocks) { - if(clocks >= ctr) { ctr = clocks; } - } - - alwaysinline void sub(uint &ctr, uint clocks) { - if(ctr >= clocks) { - ctr -= clocks; - } else { - ctr = 0; - } - } - } counter; - - enum DMA_State { DMA_Inactive, DMA_Run, DMA_CPUsync }; + unsigned alu_mul_delay; + unsigned alu_div_delay; + } temp_; struct { //core @@ -47,34 +31,30 @@ public: unsigned line_clocks; //timing - bool dram_refreshed; - uint16 dram_refresh_position; - - bool hdmainit_triggered; - uint16 hdmainit_trigger_position; - - bool hdma_triggered; - - uint16 irq_delay; + bool irq_lock; + bool alu_lock; + unsigned dram_refresh_position; bool nmi_valid; bool nmi_line; bool nmi_transition; bool nmi_pending; + unsigned nmi_hold; uint16 virq_trigger_pos, hirq_trigger_pos; bool irq_valid; bool irq_line; bool irq_transition; bool irq_pending; + unsigned irq_hold; //dma unsigned dma_counter; unsigned dma_clocks; bool dma_pending; bool hdma_pending; - bool hdma_mode; //0 = init, 1 = run - DMA_State dma_state; + bool hdma_mode; //0 = init, 1 = run + DmaState dma_state; //mmio diff --git a/src/cpu/scpu/timing/event.cpp b/src/cpu/scpu/timing/event.cpp new file mode 100644 index 00000000..437cbfd0 --- /dev/null +++ b/src/cpu/scpu/timing/event.cpp @@ -0,0 +1,27 @@ +#ifdef SCPU_CPP + +void sCPU::queue_event(unsigned id) { + switch(id) { + case EventIrqLockRelease: { + status.irq_lock = false; + } break; + + case EventAluLockRelease: { + status.alu_lock = false; + } break; + + case EventDramRefresh: { + add_clocks(40); + } break; + + case EventHdmaInit: { + event.cycle_edge |= EventFlagHdmaInit; + } break; + + case EventHdmaRun: { + event.cycle_edge |= EventFlagHdmaRun; + } break; + } +} + +#endif //ifdef SCPU_CPP diff --git a/src/cpu/scpu/timing/irq.cpp b/src/cpu/scpu/timing/irq.cpp index f1c4d068..7830e78b 100644 --- a/src/cpu/scpu/timing/irq.cpp +++ b/src/cpu/scpu/timing/irq.cpp @@ -21,21 +21,21 @@ alwaysinline void sCPU::poll_interrupts() { uint16_t vpos, hpos; //NMI hold - if(counter.nmi_hold) { - counter.nmi_hold -= 2; - if(counter.nmi_hold == 0) { + if(status.nmi_hold) { + status.nmi_hold -= 2; + if(status.nmi_hold == 0) { if(status.nmi_enabled == true) status.nmi_transition = true; } } //NMI test - vpos = ppucounter.vcounter(2); - hpos = ppucounter.hcounter(2); + vpos = ppu.vcounter(2); + hpos = ppu.hcounter(2); bool nmi_valid = (vpos >= (!ppu.overscan() ? 225 : 240)); if(status.nmi_valid == false && nmi_valid == true) { //0->1 edge sensitive transition status.nmi_line = true; - counter.nmi_hold = 4; + status.nmi_hold = 4; } else if(status.nmi_valid == true && nmi_valid == false) { //1->0 edge sensitive transition status.nmi_line = false; @@ -43,14 +43,14 @@ alwaysinline void sCPU::poll_interrupts() { status.nmi_valid = nmi_valid; //IRQ hold - if(counter.irq_hold) counter.irq_hold -= 2; - if(status.irq_line == true && counter.irq_hold == 0) { + if(status.irq_hold) status.irq_hold -= 2; + if(status.irq_line == true && status.irq_hold == 0) { if(status.virq_enabled == true || status.hirq_enabled == true) status.irq_transition = true; } //IRQ test - vpos = ppucounter.vcounter(10); - hpos = ppucounter.hcounter(10); + vpos = ppu.vcounter(10); + hpos = ppu.hcounter(10); bool irq_valid = (status.virq_enabled == true || status.hirq_enabled == true); if(irq_valid == true) { if(status.virq_enabled == true && vpos != status.virq_trigger_pos) irq_valid = false; @@ -59,7 +59,7 @@ alwaysinline void sCPU::poll_interrupts() { if(status.irq_valid == false && irq_valid == true) { //0->1 edge sensitive transition status.irq_line = true; - counter.irq_hold = 4; + status.irq_hold = 4; } status.irq_valid = irq_valid; } @@ -88,7 +88,8 @@ void sCPU::nmitimen_update(uint8 data) { } update_interrupts(); - counter.set(counter.irq_delay, 2); + status.irq_lock = true; + delta.enqueue(EventIrqLockRelease, 2); } void sCPU::hvtime_update(uint16 addr) { @@ -97,7 +98,7 @@ void sCPU::hvtime_update(uint16 addr) { bool sCPU::rdnmi() { bool result = status.nmi_line; - if(counter.nmi_hold == 0) { + if(status.nmi_hold == 0) { status.nmi_line = false; } return result; @@ -105,7 +106,7 @@ bool sCPU::rdnmi() { bool sCPU::timeup() { bool result = status.irq_line; - if(counter.irq_hold == 0) { + if(status.irq_hold == 0) { status.irq_line = false; status.irq_transition = false; } diff --git a/src/cpu/scpu/timing/timing.cpp b/src/cpu/scpu/timing/timing.cpp index 89d2522b..c47db9a9 100644 --- a/src/cpu/scpu/timing/timing.cpp +++ b/src/cpu/scpu/timing/timing.cpp @@ -1,24 +1,18 @@ #ifdef SCPU_CPP +#include "event.cpp" #include "irq.cpp" #include "joypad.cpp" unsigned sCPU::dma_counter() { - return (status.dma_counter + ppucounter.hcounter()) & 7; + return (status.dma_counter + ppu.hcounter()) & 7; } void sCPU::add_clocks(unsigned clocks) { - if(status.dram_refreshed == false) { - if(ppucounter.hcounter() + clocks >= status.dram_refresh_position) { - status.dram_refreshed = true; - clocks += 40; - } - } - - counter.sub(counter.irq_delay, clocks); + delta.tick(clocks); unsigned ticks = clocks >> 1; while(ticks--) { - ppucounter.tick(); + ppu.tick(); snes.input.tick(); poll_interrupts(); } @@ -28,62 +22,59 @@ void sCPU::add_clocks(unsigned clocks) { void sCPU::scanline() { status.dma_counter = (status.dma_counter + status.line_clocks) & 7; - status.line_clocks = ppucounter.lineclocks(); - if(ppucounter.vcounter() == 0) frame(); + status.line_clocks = ppu.lineclocks(); + + if(ppu.vcounter() == 0) { + //hdma init triggers once every frame + delta.enqueue(EventHdmaInit, cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter()); + } //dram refresh occurs once every scanline - status.dram_refreshed = false; if(cpu_version == 2) status.dram_refresh_position = 530 + 8 - dma_counter(); + delta.enqueue(EventDramRefresh, status.dram_refresh_position); //hdma triggers once every visible scanline - status.hdma_triggered = (ppucounter.vcounter() <= (ppu.overscan() == false ? 224 : 239)) ? false : true; + if(ppu.vcounter() <= (ppu.overscan() == false ? 224 : 239)) { + delta.enqueue(EventHdmaRun, 1104); + } update_interrupts(); - if(status.auto_joypad_poll == true && ppucounter.vcounter() == (ppu.overscan() == false ? 227 : 242)) { + if(status.auto_joypad_poll == true && ppu.vcounter() == (ppu.overscan() == false ? 227 : 242)) { snes.input.poll(); run_auto_joypad_poll(); } } -void sCPU::frame() { - status.hdmainit_triggered = false; - if(cpu_version == 1) { - status.hdmainit_trigger_position = 12 + 8 - dma_counter(); - } else { - status.hdmainit_trigger_position = 12 + dma_counter(); - } -} - //used for H/DMA bus synchronization void sCPU::precycle_edge() { - if(status.dma_state == DMA_CPUsync) { + if(status.dma_state == DmaCpuSync) { add_clocks(status.clock_count - (status.dma_clocks % status.clock_count)); - status.dma_state = DMA_Inactive; + status.dma_state = DmaInactive; } } //used to test for H/DMA, which can trigger on the edge of every opcode cycle. void sCPU::cycle_edge() { - if(status.hdmainit_triggered == false) { - if(ppucounter.hcounter() >= status.hdmainit_trigger_position || ppucounter.vcounter()) { - status.hdmainit_triggered = true; - hdma_init_reset(); - if(hdma_enabled_channels()) { - status.hdma_pending = true; - status.hdma_mode = 0; - } - } - } + while(event.cycle_edge) { + switch(event.cycle_edge & -event.cycle_edge) { //switch on lowest bit (flag) set + case EventFlagHdmaInit: { + hdma_init_reset(); + if(hdma_enabled_channels()) { + status.hdma_pending = true; + status.hdma_mode = 0; + } + } break; - if(status.hdma_triggered == false) { - if(ppucounter.hcounter() >= 1104) { - status.hdma_triggered = true; - if(hdma_active_channels()) { - status.hdma_pending = true; - status.hdma_mode = 1; - } + case EventFlagHdmaRun: { + if(hdma_active_channels()) { + status.hdma_pending = true; + status.hdma_mode = 1; + } + } break; } + + event.cycle_edge &= event.cycle_edge - 1; //clear lowest bit set } //H/DMA pending && DMA inactive? @@ -94,30 +85,30 @@ void sCPU::cycle_edge() { //.. Run one bus CPU cycle //.. CPU sync - if(status.dma_state == DMA_Run) { + if(status.dma_state == DmaRun) { if(status.hdma_pending) { status.hdma_pending = false; if(hdma_enabled_channels()) { - dma_add_clocks(8 - dma_counter()); //DMA sync + dma_add_clocks(8 - dma_counter()); //DMA sync status.hdma_mode == 0 ? hdma_init() : hdma_run(); - if(!dma_enabled_channels()) status.dma_state = DMA_CPUsync; + if(!dma_enabled_channels()) status.dma_state = DmaCpuSync; } } if(status.dma_pending) { status.dma_pending = false; if(dma_enabled_channels()) { - dma_add_clocks(8 - dma_counter()); //DMA sync + dma_add_clocks(8 - dma_counter()); //DMA sync dma_run(); - status.dma_state = DMA_CPUsync; + status.dma_state = DmaCpuSync; } } } - if(status.dma_state == DMA_Inactive) { + if(status.dma_state == DmaInactive) { if(status.dma_pending || status.hdma_pending) { status.dma_clocks = 0; - status.dma_state = DMA_Run; + status.dma_state = DmaRun; } } } @@ -125,10 +116,10 @@ void sCPU::cycle_edge() { //used to test for NMI/IRQ, which can trigger on the edge of every opcode. //test one cycle early to simulate two-stage pipeline of x816 CPU. // -//status.irq_delay is used to simulate hardware delay before interrupts can +//status.irq_lock is used to simulate hardware delay before interrupts can //trigger during certain events (immediately after DMA, writes to $4200, etc) void sCPU::last_cycle() { - if(counter.irq_delay) return; + if(status.irq_lock) return; status.nmi_pending |= nmi_test(); status.irq_pending |= irq_test(); @@ -140,36 +131,29 @@ void sCPU::timing_power() { } void sCPU::timing_reset() { - counter.nmi_hold = 0; - counter.irq_hold = 0; + delta.reset(); - counter.nmi_fire = 0; - counter.irq_fire = 0; - counter.irq_delay = 0; - counter.hw_math = 0; + temp_.alu_mul_delay = config::temp.alu_mul_delay; + temp_.alu_div_delay = config::temp.alu_div_delay; status.clock_count = 0; - status.line_clocks = ppucounter.lineclocks(); + status.line_clocks = ppu.lineclocks(); - status.dram_refreshed = false; + status.irq_lock = false; + status.alu_lock = false; status.dram_refresh_position = (cpu_version == 1) ? 530 : 538; - status.hdmainit_triggered = false; - status.hdmainit_trigger_position = 0; - - status.hdma_triggered = false; - - status.irq_delay = 0; - status.nmi_valid = false; status.nmi_line = false; status.nmi_transition = false; status.nmi_pending = false; + status.nmi_hold = 0; status.irq_valid = false; status.irq_line = false; status.irq_transition = false; status.irq_pending = false; + status.irq_hold = 0; update_interrupts(); @@ -178,7 +162,9 @@ void sCPU::timing_reset() { status.dma_pending = false; status.hdma_pending = false; status.hdma_mode = 0; - status.dma_state = DMA_Inactive; + status.dma_state = DmaInactive; + + event.cycle_edge = 0; } #undef ntsc_color_burst_phase_shift_scanline diff --git a/src/cpu/scpu/timing/timing.hpp b/src/cpu/scpu/timing/timing.hpp index d0431f08..b46d2ddb 100644 --- a/src/cpu/scpu/timing/timing.hpp +++ b/src/cpu/scpu/timing/timing.hpp @@ -1,12 +1,24 @@ + enum { + EventNone, + EventIrqLockRelease, + EventAluLockRelease, + EventDramRefresh, + EventHdmaInit, + EventHdmaRun, + + //cycle edge + EventFlagHdmaInit = 1 << 0, + EventFlagHdmaRun = 1 << 1, + }; + //timing.cpp unsigned dma_counter(); void add_clocks(unsigned clocks); void scanline(); - void frame(); - void precycle_edge(); - void cycle_edge(); + alwaysinline void precycle_edge(); + alwaysinline void cycle_edge(); void last_cycle(); void timing_power(); @@ -25,3 +37,6 @@ //joypad.cpp void run_auto_joypad_poll(); + + //event.cpp + void queue_event(unsigned); //deltaqueue callback function diff --git a/src/lib/libfilter/colortable.cpp b/src/lib/libfilter/colortable.cpp index 936ab495..17b12e5e 100644 --- a/src/lib/libfilter/colortable.cpp +++ b/src/lib/libfilter/colortable.cpp @@ -1,9 +1,9 @@ Colortable colortable; void Colortable::set_format(Format format_) { format = format_; } -void Colortable::set_contrast(int32_t contrast_) { contrast = contrast_; } -void Colortable::set_brightness(int32_t brightness_) { brightness = brightness_; } -void Colortable::set_gamma(int32_t gamma_) { gamma = gamma_; } +void Colortable::set_contrast(signed contrast_) { contrast = contrast_; } +void Colortable::set_brightness(signed brightness_) { brightness = brightness_; } +void Colortable::set_gamma(signed gamma_) { gamma = gamma_; } void Colortable::enable_gamma_ramp(bool value) { gamma_ramp = value; } void Colortable::enable_sepia(bool value) { sepia = value; } @@ -11,18 +11,18 @@ void Colortable::enable_grayscale(bool value) { grayscale = value; } void Colortable::enable_invert(bool value) { invert = value; } void Colortable::update() { - int32_t l, r, g, b; - double kr = 0.2126, kb = 0.0722, kg = (1.0 - kr - kb); //luminance - uint32_t col; - for(unsigned i = 0; i < 32768; i++) { - //bgr555->rgb888 - col = ((i & 0x001f) << 19) | ((i & 0x001c) << 14) - | ((i & 0x03e0) << 6) | ((i & 0x0380) << 1) - | ((i & 0x7c00) >> 7) | ((i & 0x7000) >> 12); + double kr = 0.2126, kb = 0.0722, kg = (1.0 - kr - kb); //luminance weights - r = (col >> 16) & 0xff; - g = (col >> 8) & 0xff; - b = (col ) & 0xff; + for(unsigned i = 0; i < 32768; i++) { + unsigned color //bgr555->rgb888 conversion + = ((i & 0x001f) << 19) | ((i & 0x001c) << 14) + | ((i & 0x03e0) << 6) | ((i & 0x0380) << 1) + | ((i & 0x7c00) >> 7) | ((i & 0x7000) >> 12); + + signed l; + signed r = (color >> 16) & 0xff; + signed g = (color >> 8) & 0xff; + signed b = (color ) & 0xff; if(gamma_ramp == true) { r = gamma_ramp_table[r >> 3]; @@ -30,17 +30,31 @@ void Colortable::update() { b = gamma_ramp_table[b >> 3]; } - contrast_adjust(r); brightness_adjust(r); gamma_adjust(r); - contrast_adjust(g); brightness_adjust(g); gamma_adjust(g); - contrast_adjust(b); brightness_adjust(b); gamma_adjust(b); + if(contrast != 0) { + r = contrast_adjust(r); + g = contrast_adjust(g); + b = contrast_adjust(b); + } + + if(brightness != 0) { + r = brightness_adjust(r); + g = brightness_adjust(g); + b = brightness_adjust(b); + } + + if(gamma != 100) { + r = gamma_adjust(r); + g = gamma_adjust(g); + b = gamma_adjust(b); + } if(sepia == true) { - l = (int32_t)((double)r * kr + (double)g * kg + (double)b * kb); + l = (signed)((double)r * kr + (double)g * kg + (double)b * kb); l = max(0, min(255, l)); - r = (int32_t)((double)l * (1.0 + 0.300)); - g = (int32_t)((double)l * (1.0 - 0.055)); - b = (int32_t)((double)l * (1.0 - 0.225)); + r = (signed)((double)l * (1.0 + 0.300)); + g = (signed)((double)l * (1.0 - 0.055)); + b = (signed)((double)l * (1.0 - 0.225)); r = max(0, min(255, r)); g = max(0, min(255, g)); @@ -48,7 +62,7 @@ void Colortable::update() { } if(grayscale == true) { - l = (int32_t)((double)r * kr + (double)g * kg + (double)b * kb); + l = (signed)((double)r * kr + (double)g * kg + (double)b * kb); l = max(0, min(255, l)); r = g = b = l; } @@ -79,7 +93,7 @@ void Colortable::update() { } break; default: { - table[i] = -1U; + table[i] = ~0; } break; } } @@ -90,14 +104,17 @@ Colortable::Colortable() { contrast = 0; brightness = 0; gamma = 100; + + gamma_ramp = false; + sepia = false; + grayscale = false; + invert = false; } Colortable::~Colortable() { delete[] table; } -/* internal */ - const uint8_t Colortable::gamma_ramp_table[32] = { 0x00, 0x01, 0x03, 0x06, 0x0a, 0x0f, 0x15, 0x1c, 0x24, 0x2d, 0x37, 0x42, 0x4e, 0x5b, 0x69, 0x78, @@ -105,19 +122,17 @@ const uint8_t Colortable::gamma_ramp_table[32] = { 0xc8, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8, 0xff, }; -void Colortable::contrast_adjust(int32_t &input) { - double lmin = 0.0 - (double)contrast; - double lmax = 255.0 + (double)contrast; - int32_t result = (int32_t)(lmin + (double)input * ((lmax - lmin) / 256.0)); - input = max(0, min(255, result)); +uint8_t Colortable::contrast_adjust(uint8_t input) { + signed result = input - contrast + (2 * contrast * input + 127) / 255; + return max(0, min(255, result)); } -void Colortable::brightness_adjust(int32_t &input) { - int32_t result = input + brightness; - input = max(0, min(255, result)); +uint8_t Colortable::brightness_adjust(uint8_t input) { + signed result = input + brightness; + return max(0, min(255, result)); } -void Colortable::gamma_adjust(int32_t &input) { - int32_t result = (int32_t)(pow(((double)(input + 1) / 256.0), (double)gamma / 100.0) * 256.0); - input = max(0, min(255, result)); +uint8_t Colortable::gamma_adjust(uint8_t input) { + signed result = (signed)(pow(((double)input / 255.0), (double)gamma / 100.0) * 255.0 + 0.5); + return max(0, min(255, result)); } diff --git a/src/lib/libfilter/colortable.hpp b/src/lib/libfilter/colortable.hpp index 0fc42017..d5dd8319 100644 --- a/src/lib/libfilter/colortable.hpp +++ b/src/lib/libfilter/colortable.hpp @@ -9,9 +9,9 @@ public: const inline uint32_t operator[](uint16_t index) const { return table[index]; } void set_format(Format); - void set_contrast(int32_t); - void set_brightness(int32_t); - void set_gamma(int32_t); + void set_contrast(signed); + void set_brightness(signed); + void set_gamma(signed); void enable_gamma_ramp(bool); void enable_sepia(bool); void enable_grayscale(bool); @@ -26,9 +26,9 @@ private: uint32_t *table; Format format; - int32_t contrast; - int32_t brightness; - int32_t gamma; + signed contrast; + signed brightness; + signed gamma; bool gamma_ramp; bool sepia; @@ -36,9 +36,9 @@ private: bool invert; static const uint8_t gamma_ramp_table[32]; - void contrast_adjust(int32_t &input); - void brightness_adjust(int32_t &input); - void gamma_adjust(int32_t &input); + uint8_t contrast_adjust(uint8_t input); + uint8_t brightness_adjust(uint8_t input); + uint8_t gamma_adjust(uint8_t input); }; extern Colortable colortable; diff --git a/src/lib/nall/file.hpp b/src/lib/nall/file.hpp index 3dabc2d8..a5fc013f 100644 --- a/src/lib/nall/file.hpp +++ b/src/lib/nall/file.hpp @@ -198,7 +198,7 @@ private: buffer_offset = file_offset & ~buffer_mask; fseek(fp, buffer_offset, SEEK_SET); unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask); - if(length) fread(buffer, 1, length, fp); + if(length) unsigned unused = fread(buffer, 1, length, fp); } } @@ -209,7 +209,7 @@ private: if(buffer_dirty == false) return; //buffer unmodified since read fseek(fp, buffer_offset, SEEK_SET); unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask); - if(length) fwrite(buffer, 1, length, fp); + if(length) unsigned unused = fwrite(buffer, 1, length, fp); buffer_offset = -1; //invalidate buffer buffer_dirty = false; } diff --git a/src/lib/nall/input.hpp b/src/lib/nall/input.hpp index b358c4b1..4c147ca5 100644 --- a/src/lib/nall/input.hpp +++ b/src/lib/nall/input.hpp @@ -107,20 +107,20 @@ static const char* input_find(uint16_t key) { static char buffer[64]; for(unsigned j = 0; j < 16; j++) { - if(key == joypad<>::index(j, joypad<>::up)) { sprintf(buffer, "joypad%0.2d.up", j); return buffer; } - if(key == joypad<>::index(j, joypad<>::down)) { sprintf(buffer, "joypad%0.2d.down", j); return buffer; } - if(key == joypad<>::index(j, joypad<>::left)) { sprintf(buffer, "joypad%0.2d.left", j); return buffer; } - if(key == joypad<>::index(j, joypad<>::right)) { sprintf(buffer, "joypad%0.2d.right", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::up)) { sprintf(buffer, "joypad%.2d.up", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::down)) { sprintf(buffer, "joypad%.2d.down", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::left)) { sprintf(buffer, "joypad%.2d.left", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::right)) { sprintf(buffer, "joypad%.2d.right", j); return buffer; } if(key >= joypad<>::index(j, joypad<>::axis + 0) && key < joypad<>::index(j, joypad<>::axis + joypad<>::axes)) { - sprintf(buffer, "joypad%0.2d.axis%0.2d", j, key - joypad<>::index(j, joypad<>::axis)); + sprintf(buffer, "joypad%.2d.axis%.2d", j, key - joypad<>::index(j, joypad<>::axis)); return buffer; } if(key >= joypad<>::index(j, joypad<>::button + 0) && key < joypad<>::index(j, joypad<>::button + joypad<>::buttons)) { - sprintf(buffer, "joypad%0.2d.button%0.2d", j, key - joypad<>::index(j, joypad<>::button)); + sprintf(buffer, "joypad%.2d.button%.2d", j, key - joypad<>::index(j, joypad<>::button)); return buffer; } } diff --git a/src/lib/nall/string.hpp b/src/lib/nall/string.hpp index edca9699..46b9b575 100644 --- a/src/lib/nall/string.hpp +++ b/src/lib/nall/string.hpp @@ -69,6 +69,7 @@ public: string& operator=(const char *str); string& operator=(const string &str); string& operator<<(int num); + string& operator<<(double num); string& operator<<(const char *str); string& operator<<(const string& str); @@ -89,7 +90,7 @@ public: typedef vector lstring; -} //namespace nall +} //namespace nall size_t count(nall::lstring&); int find(nall::lstring &str, const char *key); @@ -117,4 +118,4 @@ nall::string& ltrim_once(nall::string &str, const char *key = " "); nall::string& rtrim_once(nall::string &str, const char *key = " "); nall::string& trim_once (nall::string &str, const char *key = " "); -#endif //ifndef NALL_STRING_HPP +#endif //ifndef NALL_STRING_HPP diff --git a/src/lib/nall/string/class.cpp b/src/lib/nall/string/class.cpp index 9b85f14c..efb6586f 100644 --- a/src/lib/nall/string/class.cpp +++ b/src/lib/nall/string/class.cpp @@ -68,6 +68,12 @@ string& string::operator<<(int num) { return *this; } +string& string::operator<<(double num) { + string temp(num); + strcat(*this, temp); + return *this; +} + string& string::operator<<(const char *str) { strcat(*this, str); return *this; @@ -208,13 +214,13 @@ bool fread(nall::string &str, const char *filename) { #else FILE *fp = _wfopen(nall::utf16(filename), L"rb"); #endif - if(!fp)return false; + if(!fp) return false; fseek(fp, 0, SEEK_END); size_t size = ftell(fp); rewind(fp); char *fdata = (char*)malloc(size + 1); - fread(fdata, 1, size, fp); + unsigned unused = fread(fdata, 1, size, fp); fclose(fp); fdata[size] = 0; strcpy(str, fdata); @@ -223,4 +229,4 @@ bool fread(nall::string &str, const char *filename) { return true; } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/compare.cpp b/src/lib/nall/string/compare.cpp index 72a63667..081a05d7 100644 --- a/src/lib/nall/string/compare.cpp +++ b/src/lib/nall/string/compare.cpp @@ -96,4 +96,4 @@ bool striend(const char *str, const char *key) { return true; } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/convert.cpp b/src/lib/nall/string/convert.cpp index 70551c43..51152375 100644 --- a/src/lib/nall/string/convert.cpp +++ b/src/lib/nall/string/convert.cpp @@ -24,7 +24,7 @@ char* strtr(char *dest, const char *before, const char *after) { if(!dest || !before || !after) return dest; int sl = strlen(dest), bsl = strlen(before), asl = strlen(after); - if(bsl != asl || bsl == 0) return dest; //patterns must be the same length for 1:1 replace + if(bsl != asl || bsl == 0) return dest; //patterns must be the same length for 1:1 replace for(unsigned i = 0; i < sl; i++) { for(unsigned l = 0; l < bsl; l++) { if(dest[i] == before[l]) { @@ -62,7 +62,7 @@ uintmax_t strhex(const char *str) { if(x >= '0' && x <= '9') x -= '0'; else if(x >= 'A' && x <= 'F') x -= 'A' - 10; else if(x >= 'a' && x <= 'f') x -= 'a' - 10; - else break; //stop at first invalid character + else break; //stop at first invalid character result = result * 16 + x; } @@ -83,7 +83,7 @@ intmax_t strdec(const char *str) { while(*str) { uint8_t x = *str++; if(x >= '0' && x <= '9') x -= '0'; - else break; //stop at first invalid character + else break; //stop at first invalid character result = result * 10 + x; } @@ -101,7 +101,7 @@ uintmax_t strbin(const char *str) { while(*str) { uint8_t x = *str++; if(x == '0' || x == '1') x -= '0'; - else break; //stop at first invalid character + else break; //stop at first invalid character result = result * 2 + x; } @@ -122,8 +122,8 @@ double strdouble(const char *str) { while(*str) { uint8_t x = *str++; if(x >= '0' && x <= '9') x -= '0'; - else if(x == '.') break; //break loop and read fractional part - else return (double)result_integral; //invalid value, assume no fractional part + else if(x == '.') break; //break loop and read fractional part + else return (double)result_integral; //invalid value, assume no fractional part result_integral = result_integral * 10 + x; } @@ -131,7 +131,7 @@ double strdouble(const char *str) { while(*str) { uint8_t x = *str++; if(x >= '0' && x <= '9') x -= '0'; - else break; //stop at first invalid character + else break; //stop at first invalid character result_fractional = result_fractional * 10 + x; } @@ -144,7 +144,7 @@ double strdouble(const char *str) { } size_t strhex(char *str, uintmax_t value, size_t length /* = 0 */) { - if(!length) length -= 1U; //"infinite" length + if(length == 0) length -= 1U; //"infinite" length size_t initial_length = length; //count number of digits in value @@ -153,23 +153,23 @@ size_t strhex(char *str, uintmax_t value, size_t length /* = 0 */) { while(digits_integral_ /= 16) digits_integral++; int digits = digits_integral; - if(!str) return digits + 1; //only computing required length? + if(!str) return digits + 1; //only computing required length? length = nall::min(digits, length - 1); - str += length; //seek to end of target string - *str = 0; //set null terminator + str += length; //seek to end of target string + *str = 0; //set null terminator while(length--) { uint8_t x = value % 16; value /= 16; - *--str = x < 10 ? (x + '0') : (x + 'a' - 10); //iterate backwards to write string + *--str = x < 10 ? (x + '0') : (x + 'a' - 10); //iterate backwards to write string } return nall::min(initial_length, digits + 1); } size_t strdec(char *str, intmax_t value_, size_t length /* = 0 */) { - if(!length) length = -1U; //"infinite" length + if(length == 0) length = -1U; //"infinite" length size_t initial_length = length; bool negate = value_ < 0; @@ -181,15 +181,15 @@ size_t strdec(char *str, intmax_t value_, size_t length /* = 0 */) { while(digits_integral_ /= 10) digits_integral++; int digits = (negate ? 1 : 0) + digits_integral; - if(!str) return digits + 1; //only computing required length? + if(!str) return digits + 1; //only computing required length? length = nall::min(digits, length - 1); - str += length; //seek to end of target string - *str = 0; //set null terminator + str += length; //seek to end of target string + *str = 0; //set null terminator while(length && digits_integral--) { uint8_t x = '0' + (value % 10); value /= 10; - *--str = x; //iterate backwards to write string + *--str = x; //iterate backwards to write string length--; } @@ -201,7 +201,7 @@ size_t strdec(char *str, intmax_t value_, size_t length /* = 0 */) { } size_t strbin(char *str, uintmax_t value, size_t length /* = 0 */) { - if(!length) length = -1U; //"infinite" length + if(length == 0) length = -1U; //"infinite" length size_t initial_length = length; //count number of digits in value @@ -210,79 +210,46 @@ size_t strbin(char *str, uintmax_t value, size_t length /* = 0 */) { while(digits_integral_ /= 2) digits_integral++; int digits = digits_integral; - if(!str) return digits + 1; //only computing required length? + if(!str) return digits + 1; //only computing required length? length = nall::min(digits, length - 1); - str += length; //seek to end of target string - *str = 0; //set null terminator + str += length; //seek to end of target string + *str = 0; //set null terminator while(length--) { uint8_t x = '0' + (value % 2); value /= 2; - *--str = x; //iterate backwards to write string + *--str = x; //iterate backwards to write string } return nall::min(initial_length, digits + 1); } +//using sprintf is certainly not the most ideal method to convert +//a double to a string ... but attempting to parse a double by +//hand, digit-by-digit, results in subtle rounding errors. +// +//note: length parameter is currently ignored. +//it remains for consistency and possible future support. size_t strdouble(char *str, double value, size_t length /* = 0 */) { - if(!length) length = -1U; //"infinite" length - size_t initial_length = length; + char buffer[256]; + sprintf(buffer, "%f", value); - double fractional, integral; - fractional = modf(value, &integral); - uintmax_t value_integral = (uintmax_t)integral; - uintmax_t value_fractional = 0; - - //convert fractional portion to integral number (eg 0.275 -> 275) - //six nibbles of precision, one nibble for rounding - for(int i = 0; i < 7; i++) { - fractional *= 10.0; - value_fractional = value_fractional * 10 + ((uintmax_t)fractional % 10); + //remove excess 0's in fraction (2.500000 -> 2.5) + for(char *p = buffer; *p; p++) { + if(*p == '.') { + char *p = buffer + strlen(buffer) - 1; + while(*p == '0') { + if(*(p - 1) != '.') *p = 0; //... but not for eg 1.0 -> 1. + p--; + } + break; + } } - //use seventh nibble to round fraction - value_fractional = (uintmax_t)((double)value_fractional / 10.0 + 0.5); - - //cull fractional zero nibbles (eg 275000 -> 275) - while(value_fractional && !(value_fractional % 10)) value_fractional /= 10; - - //count number of digits in integral value - int digits_integral = 1; - uintmax_t digits_integral_ = value_integral; - while(digits_integral_ /= 10) digits_integral++; - - //count number of digits in fractional value - int digits_fractional = 1; - uintmax_t digits_fractional_ = value_fractional; - while(digits_fractional_ /= 10) digits_fractional++; - - int digits = digits_integral + 1 + digits_fractional; //integral '.' fractional - if(!str) return digits + 1; //only computing required length? - - length = nall::min(digits, length - 1); - str += length; //seek to end of target string - *str = 0; //set null terminator - - while(length && digits_fractional--) { - uint8_t x = '0' + (value_fractional % 10); - value_fractional /= 10; - *--str = x; //iterate backwards to write string - length--; - } - - if(length) { - *--str = '.'; - length--; - } - - while(length-- && digits_integral--) { - uint8_t x = '0' + (value_integral % 10); - value_integral /= 10; - *--str = x; //interate backwards to write string - } - - return nall::min(initial_length, digits + 1); + length = strlen(buffer); + if(str) strcpy(str, buffer); + return length + 1; } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/match.cpp b/src/lib/nall/string/match.cpp index 7cee520e..c73df02a 100644 --- a/src/lib/nall/string/match.cpp +++ b/src/lib/nall/string/match.cpp @@ -68,4 +68,4 @@ bool match(const char *p, const char *s) { } } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/math.cpp b/src/lib/nall/string/math.cpp index bb0ac5b4..3dabde3b 100644 --- a/src/lib/nall/string/math.cpp +++ b/src/lib/nall/string/math.cpp @@ -156,4 +156,4 @@ bool strmath(const char *s, int &result) { } } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/replace.cpp b/src/lib/nall/string/replace.cpp index 9474c8b0..b29e02d9 100644 --- a/src/lib/nall/string/replace.cpp +++ b/src/lib/nall/string/replace.cpp @@ -87,4 +87,4 @@ nall::string &qreplace(nall::string &str, const char *key, const char *token) { return str; } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/split.cpp b/src/lib/nall/string/split.cpp index ebcd9b53..b68b5c13 100644 --- a/src/lib/nall/string/split.cpp +++ b/src/lib/nall/string/split.cpp @@ -48,4 +48,4 @@ void qsplit(nall::lstring &dest, const char *key, const char *src, size_t limit) strcpy(dest[split_count++], src + lp); } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/strl.cpp b/src/lib/nall/string/strl.cpp index 5710b9f2..a140fbc9 100644 --- a/src/lib/nall/string/strl.cpp +++ b/src/lib/nall/string/strl.cpp @@ -44,4 +44,4 @@ size_t strlcat(char *dest, const char *src, size_t length) { return dlength + (s - src); //return length of resulting string, sans null terminator } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/nall/string/trim.cpp b/src/lib/nall/string/trim.cpp index bef5d166..861500e4 100644 --- a/src/lib/nall/string/trim.cpp +++ b/src/lib/nall/string/trim.cpp @@ -32,4 +32,4 @@ char* trim_once(char *str, const char *key) { return ltrim_once(rtrim_once(str, key), key); } -#endif //ifdef NALL_STRING_CPP +#endif //ifdef NALL_STRING_CPP diff --git a/src/lib/ruby/audio/oss.cpp b/src/lib/ruby/audio/oss.cpp index 03a2e1f2..a16955fd 100644 --- a/src/lib/ruby/audio/oss.cpp +++ b/src/lib/ruby/audio/oss.cpp @@ -61,7 +61,7 @@ public: void sample(uint16_t sl, uint16_t sr) { uint32_t sample = sl + (sr << 16); - write(device.fd, &sample, 4); + unsigned unused = write(device.fd, &sample, 4); } bool init() { diff --git a/src/lib/ruby/input/sdl.cpp b/src/lib/ruby/input/sdl.cpp index b113e78b..b8f9642a 100644 --- a/src/lib/ruby/input/sdl.cpp +++ b/src/lib/ruby/input/sdl.cpp @@ -2,8 +2,7 @@ //SDL input driver //================ //Keyboard and mouse are controlled directly via Xlib, -//as SDL cannot capture input from windows it does not -//create itself. +//as SDL cannot capture input from windows it does not create itself. //SDL is used only to handle joysticks. #include @@ -20,14 +19,15 @@ using namespace nall; class pInputSDL { public: + #include "xlibkeys.hpp" InputSDL &self; Display *display; Window rootwindow; unsigned screenwidth, screenheight; unsigned relativex, relativey; + bool mouseacquired; Cursor InvisibleCursor; SDL_Joystick *gamepad[joypad<>::count]; - bool mouseacquired; struct { //mouse device settings @@ -111,130 +111,14 @@ public: //Keyboard //======== - #define key(n) (bool)(state[n >> 3] & (1 << (n & 7))) - { - char state[32]; - XQueryKeymap(display, state); + char state[32]; + XQueryKeymap(display, state); - table[keyboard::escape] = key(0x09); - - table[keyboard::f1 ] = key(0x43); - table[keyboard::f2 ] = key(0x44); - table[keyboard::f3 ] = key(0x45); - table[keyboard::f4 ] = key(0x46); - table[keyboard::f5 ] = key(0x47); - table[keyboard::f6 ] = key(0x48); - table[keyboard::f7 ] = key(0x49); - table[keyboard::f8 ] = key(0x4a); - table[keyboard::f9 ] = key(0x4b); - table[keyboard::f10] = key(0x4c); - table[keyboard::f11] = key(0x5f); - table[keyboard::f12] = key(0x60); - - table[keyboard::print_screen] = key(0x6f); - table[keyboard::scroll_lock ] = key(0x4e); - table[keyboard::pause ] = key(0x6e); - - table[keyboard::tilde] = key(0x31); - - table[keyboard::num_0] = key(0x0a); - table[keyboard::num_1] = key(0x0b); - table[keyboard::num_2] = key(0x0c); - table[keyboard::num_3] = key(0x0d); - table[keyboard::num_4] = key(0x0e); - table[keyboard::num_5] = key(0x0f); - table[keyboard::num_6] = key(0x10); - table[keyboard::num_7] = key(0x11); - table[keyboard::num_8] = key(0x12); - table[keyboard::num_9] = key(0x13); - - table[keyboard::dash ] = key(0x14); - table[keyboard::equal ] = key(0x15); - table[keyboard::backspace] = key(0x16); - - table[keyboard::insert ] = key(0x6a); - table[keyboard::delete_ ] = key(0x6b); - table[keyboard::home ] = key(0x61); - table[keyboard::end ] = key(0x67); - table[keyboard::page_up ] = key(0x63); - table[keyboard::page_down] = key(0x69); - - table[keyboard::a] = key(0x26); - table[keyboard::b] = key(0x38); - table[keyboard::c] = key(0x36); - table[keyboard::d] = key(0x28); - table[keyboard::e] = key(0x1a); - table[keyboard::f] = key(0x29); - table[keyboard::g] = key(0x2a); - table[keyboard::h] = key(0x2b); - table[keyboard::i] = key(0x1f); - table[keyboard::j] = key(0x2c); - table[keyboard::k] = key(0x2d); - table[keyboard::l] = key(0x2e); - table[keyboard::m] = key(0x3a); - table[keyboard::n] = key(0x39); - table[keyboard::o] = key(0x20); - table[keyboard::p] = key(0x21); - table[keyboard::q] = key(0x18); - table[keyboard::r] = key(0x1b); - table[keyboard::s] = key(0x27); - table[keyboard::t] = key(0x1c); - table[keyboard::u] = key(0x1e); - table[keyboard::v] = key(0x37); - table[keyboard::w] = key(0x19); - table[keyboard::x] = key(0x35); - table[keyboard::y] = key(0x1d); - table[keyboard::z] = key(0x34); - - table[keyboard::lbracket ] = key(0x22); - table[keyboard::rbracket ] = key(0x23); - table[keyboard::backslash ] = key(0x33); - table[keyboard::semicolon ] = key(0x2f); - table[keyboard::apostrophe] = key(0x30); - table[keyboard::comma ] = key(0x3b); - table[keyboard::period ] = key(0x3c); - table[keyboard::slash ] = key(0x3d); - - table[keyboard::pad_0] = key(0x5a); - table[keyboard::pad_1] = key(0x57); - table[keyboard::pad_2] = key(0x58); - table[keyboard::pad_3] = key(0x59); - table[keyboard::pad_4] = key(0x53); - table[keyboard::pad_5] = key(0x54); - table[keyboard::pad_6] = key(0x55); - table[keyboard::pad_7] = key(0x4f); - table[keyboard::pad_8] = key(0x50); - table[keyboard::pad_9] = key(0x51); - - table[keyboard::add ] = key(0x56); - table[keyboard::subtract] = key(0x52); - table[keyboard::multiply] = key(0x3f); - table[keyboard::divide ] = key(0x70); - table[keyboard::enter ] = key(0x6c); - - table[keyboard::num_lock ] = key(0x4d); - table[keyboard::caps_lock] = key(0x42); - - table[keyboard::up ] = key(0x62); - table[keyboard::down ] = key(0x68); - table[keyboard::left ] = key(0x64); - table[keyboard::right] = key(0x66); - - table[keyboard::tab ] = key(0x17); - table[keyboard::return_ ] = key(0x24); - table[keyboard::spacebar] = key(0x41); - - table[keyboard::lctrl ] = key(0x25); - table[keyboard::rctrl ] = key(0x6d); - table[keyboard::lalt ] = key(0x40); - table[keyboard::ralt ] = key(0x71); - table[keyboard::lshift] = key(0x32); - table[keyboard::rshift] = key(0x3e); - table[keyboard::lsuper] = key(0x73); - table[keyboard::rsuper] = key(0x74); - table[keyboard::menu ] = key(0x75); + for(unsigned i = 0; i < keyboard::limit; i++) { + uint8_t code = keycode[i]; + if(code == 0) continue; //unmapped + table[i] = (bool)(state[code >> 3] & (1 << (code & 7))); } - #undef key //===== //Mouse @@ -315,6 +199,7 @@ public: } bool init() { + init_keycodes(); SDL_InitSubSystem(SDL_INIT_JOYSTICK); SDL_JoystickEventState(SDL_IGNORE); diff --git a/src/lib/ruby/input/x.cpp b/src/lib/ruby/input/x.cpp index 5cc47d62..0555465d 100644 --- a/src/lib/ruby/input/x.cpp +++ b/src/lib/ruby/input/x.cpp @@ -3,7 +3,7 @@ #include #include #include - + namespace ruby { #include "x.hpp" @@ -12,6 +12,7 @@ class pInputX { public: InputX &self; Display *display; + #include "xlibkeys.hpp" bool cap(Input::Setting setting) { if(setting == Input::KeyboardSupport) return true; @@ -29,133 +30,20 @@ public: bool poll(int16_t *table) { memset(table, 0, input_limit * sizeof(int16_t)); - #define key(n) (bool)(state[n >> 3] & (1 << (n & 7))) char state[32]; XQueryKeymap(display, state); - table[keyboard::escape] = key(0x09); - - table[keyboard::f1 ] = key(0x43); - table[keyboard::f2 ] = key(0x44); - table[keyboard::f3 ] = key(0x45); - table[keyboard::f4 ] = key(0x46); - table[keyboard::f5 ] = key(0x47); - table[keyboard::f6 ] = key(0x48); - table[keyboard::f7 ] = key(0x49); - table[keyboard::f8 ] = key(0x4a); - table[keyboard::f9 ] = key(0x4b); - table[keyboard::f10] = key(0x4c); - table[keyboard::f11] = key(0x5f); - table[keyboard::f12] = key(0x60); - - table[keyboard::print_screen] = key(0x6f); - table[keyboard::scroll_lock ] = key(0x4e); - table[keyboard::pause ] = key(0x6e); - - table[keyboard::tilde] = key(0x31); - - table[keyboard::num_0] = key(0x0a); - table[keyboard::num_1] = key(0x0b); - table[keyboard::num_2] = key(0x0c); - table[keyboard::num_3] = key(0x0d); - table[keyboard::num_4] = key(0x0e); - table[keyboard::num_5] = key(0x0f); - table[keyboard::num_6] = key(0x10); - table[keyboard::num_7] = key(0x11); - table[keyboard::num_8] = key(0x12); - table[keyboard::num_9] = key(0x13); - - table[keyboard::dash ] = key(0x14); - table[keyboard::equal ] = key(0x15); - table[keyboard::backspace] = key(0x16); - - table[keyboard::insert ] = key(0x6a); - table[keyboard::delete_ ] = key(0x6b); - table[keyboard::home ] = key(0x61); - table[keyboard::end ] = key(0x67); - table[keyboard::page_up ] = key(0x63); - table[keyboard::page_down] = key(0x69); - - table[keyboard::a] = key(0x26); - table[keyboard::b] = key(0x38); - table[keyboard::c] = key(0x36); - table[keyboard::d] = key(0x28); - table[keyboard::e] = key(0x1a); - table[keyboard::f] = key(0x29); - table[keyboard::g] = key(0x2a); - table[keyboard::h] = key(0x2b); - table[keyboard::i] = key(0x1f); - table[keyboard::j] = key(0x2c); - table[keyboard::k] = key(0x2d); - table[keyboard::l] = key(0x2e); - table[keyboard::m] = key(0x3a); - table[keyboard::n] = key(0x39); - table[keyboard::o] = key(0x20); - table[keyboard::p] = key(0x21); - table[keyboard::q] = key(0x18); - table[keyboard::r] = key(0x1b); - table[keyboard::s] = key(0x27); - table[keyboard::t] = key(0x1c); - table[keyboard::u] = key(0x1e); - table[keyboard::v] = key(0x37); - table[keyboard::w] = key(0x19); - table[keyboard::x] = key(0x35); - table[keyboard::y] = key(0x1d); - table[keyboard::z] = key(0x34); - - table[keyboard::lbracket ] = key(0x22); - table[keyboard::rbracket ] = key(0x23); - table[keyboard::backslash ] = key(0x33); - table[keyboard::semicolon ] = key(0x2f); - table[keyboard::apostrophe] = key(0x30); - table[keyboard::comma ] = key(0x3b); - table[keyboard::period ] = key(0x3c); - table[keyboard::slash ] = key(0x3d); - - table[keyboard::pad_0] = key(0x5a); - table[keyboard::pad_1] = key(0x57); - table[keyboard::pad_2] = key(0x58); - table[keyboard::pad_3] = key(0x59); - table[keyboard::pad_4] = key(0x53); - table[keyboard::pad_5] = key(0x54); - table[keyboard::pad_6] = key(0x55); - table[keyboard::pad_7] = key(0x4f); - table[keyboard::pad_8] = key(0x50); - table[keyboard::pad_9] = key(0x51); - - table[keyboard::add ] = key(0x56); - table[keyboard::subtract] = key(0x52); - table[keyboard::multiply] = key(0x3f); - table[keyboard::divide ] = key(0x70); - table[keyboard::enter ] = key(0x6c); - - table[keyboard::num_lock ] = key(0x4d); - table[keyboard::caps_lock] = key(0x42); - - table[keyboard::up ] = key(0x62); - table[keyboard::down ] = key(0x68); - table[keyboard::left ] = key(0x64); - table[keyboard::right] = key(0x66); - - table[keyboard::tab ] = key(0x17); - table[keyboard::return_ ] = key(0x24); - table[keyboard::spacebar] = key(0x41); - - table[keyboard::lctrl ] = key(0x25); - table[keyboard::rctrl ] = key(0x6d); - table[keyboard::lalt ] = key(0x40); - table[keyboard::ralt ] = key(0x71); - table[keyboard::lshift] = key(0x32); - table[keyboard::rshift] = key(0x3e); - table[keyboard::lsuper] = key(0x73); - table[keyboard::rsuper] = key(0x74); - table[keyboard::menu ] = key(0x75); - #undef key + for(unsigned i = 0; i < keyboard::limit; i++) { + uint8_t code = keycode[i]; + if(code == 0) continue; //unmapped + table[i] = (bool)(state[code >> 3] & (1 << (code & 7))); + } return true; } bool init() { + init_keycodes(); display = XOpenDisplay(0); return true; } diff --git a/src/lib/ruby/input/xlibkeys.hpp b/src/lib/ruby/input/xlibkeys.hpp new file mode 100644 index 00000000..45813b49 --- /dev/null +++ b/src/lib/ruby/input/xlibkeys.hpp @@ -0,0 +1,138 @@ +//shared keycode lookup table + initialization routine: +//#include inside a class interface to use + +//Xlib keycodes for each key can vary between platforms, so this header file +//will lookup keycodes from static keysyms, and map them to nall/input.hpp's +//keyboard identifiers. +// +//this allows input capture routine to iterate quickly over all keycodes and +//map their states to ruby's input state table. + +uint8_t keycode[256]; + +bool init_keycodes() { + Display *display = XOpenDisplay(0); + memset(&keycode, 0, sizeof keycode); + + #define assign(x, y) keycode[x] = XKeysymToKeycode(display, y) + assign(keyboard::escape, XK_Escape); + + assign(keyboard::f1, XK_F1); + assign(keyboard::f2, XK_F2); + assign(keyboard::f3, XK_F3); + assign(keyboard::f4, XK_F4); + assign(keyboard::f5, XK_F5); + assign(keyboard::f6, XK_F6); + assign(keyboard::f7, XK_F7); + assign(keyboard::f8, XK_F8); + assign(keyboard::f9, XK_F9); + assign(keyboard::f10, XK_F10); + assign(keyboard::f11, XK_F11); + assign(keyboard::f12, XK_F12); + + //assign(keyboard::print_screen, XK_???); + assign(keyboard::scroll_lock, XK_Scroll_Lock); + assign(keyboard::pause, XK_Pause); + + assign(keyboard::tilde, XK_asciitilde); + + assign(keyboard::num_0, XK_0); + assign(keyboard::num_1, XK_1); + assign(keyboard::num_2, XK_2); + assign(keyboard::num_3, XK_3); + assign(keyboard::num_4, XK_4); + assign(keyboard::num_5, XK_5); + assign(keyboard::num_6, XK_6); + assign(keyboard::num_7, XK_7); + assign(keyboard::num_8, XK_8); + assign(keyboard::num_9, XK_9); + + assign(keyboard::dash, XK_minus); + assign(keyboard::equal, XK_equal); + assign(keyboard::backspace, XK_BackSpace); + + assign(keyboard::insert, XK_Insert); + assign(keyboard::delete_, XK_Delete); + assign(keyboard::home, XK_Home); + assign(keyboard::end, XK_End); + assign(keyboard::page_up, XK_Prior); + assign(keyboard::page_down, XK_Next); + + assign(keyboard::a, XK_A); + assign(keyboard::b, XK_B); + assign(keyboard::c, XK_C); + assign(keyboard::d, XK_D); + assign(keyboard::e, XK_E); + assign(keyboard::f, XK_F); + assign(keyboard::g, XK_G); + assign(keyboard::h, XK_H); + assign(keyboard::i, XK_I); + assign(keyboard::j, XK_J); + assign(keyboard::k, XK_K); + assign(keyboard::l, XK_L); + assign(keyboard::m, XK_M); + assign(keyboard::n, XK_N); + assign(keyboard::o, XK_O); + assign(keyboard::p, XK_P); + assign(keyboard::q, XK_Q); + assign(keyboard::r, XK_R); + assign(keyboard::s, XK_S); + assign(keyboard::t, XK_T); + assign(keyboard::u, XK_U); + assign(keyboard::v, XK_V); + assign(keyboard::w, XK_W); + assign(keyboard::x, XK_X); + assign(keyboard::y, XK_Y); + assign(keyboard::z, XK_Z); + + assign(keyboard::lbracket, XK_bracketleft); + assign(keyboard::rbracket, XK_bracketright); + assign(keyboard::backslash, XK_backslash); + assign(keyboard::semicolon, XK_semicolon); + assign(keyboard::apostrophe, XK_apostrophe); + assign(keyboard::comma, XK_comma); + assign(keyboard::period, XK_period); + assign(keyboard::slash, XK_slash); + + assign(keyboard::pad_0, XK_KP_0); + assign(keyboard::pad_1, XK_KP_1); + assign(keyboard::pad_2, XK_KP_2); + assign(keyboard::pad_3, XK_KP_3); + assign(keyboard::pad_4, XK_KP_4); + assign(keyboard::pad_5, XK_KP_5); + assign(keyboard::pad_6, XK_KP_6); + assign(keyboard::pad_7, XK_KP_7); + assign(keyboard::pad_8, XK_KP_8); + assign(keyboard::pad_9, XK_KP_9); + + assign(keyboard::add, XK_KP_Add); + assign(keyboard::subtract, XK_KP_Subtract); + assign(keyboard::multiply, XK_KP_Multiply); + assign(keyboard::divide, XK_KP_Divide); + assign(keyboard::enter, XK_KP_Enter); + + //assign(keyboard::num_lock, XK_???); + //assign(keyboard::caps_lock, XK_???); + + assign(keyboard::up, XK_Up); + assign(keyboard::down, XK_Down); + assign(keyboard::left, XK_Left); + assign(keyboard::right, XK_Right); + + assign(keyboard::tab, XK_Tab); + assign(keyboard::return_, XK_Return); + assign(keyboard::spacebar, XK_space); + + assign(keyboard::lctrl, XK_Control_L); + assign(keyboard::rctrl, XK_Control_R); + assign(keyboard::lalt, XK_Alt_L); + assign(keyboard::ralt, XK_Alt_R); + assign(keyboard::lshift, XK_Shift_L); + assign(keyboard::rshift, XK_Shift_R); + assign(keyboard::lsuper, XK_Super_L); + assign(keyboard::rsuper, XK_Super_R); + assign(keyboard::menu, XK_Menu); + #undef assign + + XCloseDisplay(display); +} diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index 10d12104..6ab44586 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -8,11 +8,11 @@ void bPPU::enter() { loop: //H = 0 (initialize) scanline(); - if(ppucounter.vcounter() == 0) frame(); + if(ivcounter() == 0) frame(); add_clocks(10); //H = 10 (OAM address reset) - if(ppucounter.vcounter() == (!overscan() ? 225 : 240)) { + if(ivcounter() == (!overscan() ? 225 : 240)) { if(regs.display_disabled == false) { regs.oam_addr = regs.oam_baseaddr << 1; regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; @@ -28,19 +28,19 @@ void bPPU::enter() { cache.oam_basesize = regs.oam_basesize; cache.oam_nameselect = regs.oam_nameselect; cache.oam_tdaddr = regs.oam_tdaddr; - add_clocks(ppucounter.ppulineclocks() - 1152); //seek to start of next scanline + add_clocks(ilineclocks() - 1152); //seek to start of next scanline goto loop; } void bPPU::add_clocks(unsigned clocks) { - ppucounter.tock(clocks); + tock(clocks); scheduler.addclocks_ppu(clocks); } void bPPU::scanline() { snes.scanline(); - line.y = ppucounter.ppuvcounter(); + line.y = ivcounter(); if(line.y == 0) { //RTO flag reset @@ -78,7 +78,7 @@ void bPPU::frame() { PPU::frame(); snes.frame(); - if(ppucounter.ppufield() == 0) { + if(ifield() == 0) { display.interlace = regs.interlace; regs.scanlines = (regs.overscan == false) ? 224 : 239; } diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index 6ef4f037..d3276e16 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -1,8 +1,8 @@ #ifdef BPPU_CPP void bPPU::latch_counters() { - regs.hcounter = ppucounter.hdot(); - regs.vcounter = ppucounter.vcounter(); + regs.hcounter = hdot(); + regs.vcounter = vcounter(); regs.counters_latched = true; } @@ -28,10 +28,10 @@ uint8 bPPU::vram_mmio_read(uint16 addr) { if(regs.display_disabled == true) { data = memory::vram[addr]; } else { - uint16 v = ppucounter.vcounter(); - uint16 h = ppucounter.hcounter(); + uint16 v = vcounter(); + uint16 h = hcounter(); uint16 ls = ((snes.region() == SNES::NTSC ? 525 : 625) >> 1) - 1; - if(interlace() && !ppucounter.field()) ls++; + if(interlace() && !field()) ls++; if(v == ls && h == 1362) { data = 0x00; @@ -55,8 +55,8 @@ void bPPU::vram_mmio_write(uint16 addr, uint8 data) { if(regs.display_disabled == true) { memory::vram[addr] = data; } else { - uint16 v = ppucounter.vcounter(); - uint16 h = ppucounter.hcounter(); + uint16 v = vcounter(); + uint16 h = hcounter(); if(v == 0) { if(h <= 4) { memory::vram[addr] = data; @@ -100,7 +100,7 @@ uint8 bPPU::oam_mmio_read(uint16 addr) { if(regs.display_disabled == true) { data = memory::oam[addr]; } else { - if(ppucounter.vcounter() < (!overscan() ? 225 : 240)) { + if(vcounter() < (!overscan() ? 225 : 240)) { data = memory::oam[0x0218]; } else { data = memory::oam[addr]; @@ -117,7 +117,7 @@ void bPPU::oam_mmio_write(uint16 addr, uint8 data) { if(regs.display_disabled == true) { memory::oam[addr] = data; } else { - if(ppucounter.vcounter() < (!overscan() ? 225 : 240)) { + if(vcounter() < (!overscan() ? 225 : 240)) { memory::oam[0x0218] = data; } else { memory::oam[addr] = data; @@ -138,8 +138,8 @@ uint8 bPPU::cgram_mmio_read(uint16 addr) { if(regs.display_disabled == true) { data = memory::cgram[addr]; } else { - uint16 v = ppucounter.vcounter(); - uint16 h = ppucounter.hcounter(); + uint16 v = vcounter(); + uint16 h = hcounter(); if(v < (!overscan() ? 225 : 240) && h >= 72 && h < 1096) { data = memory::cgram[0x01ff] & 0x7f; } else { @@ -158,8 +158,8 @@ void bPPU::cgram_mmio_write(uint16 addr, uint8 data) { if(regs.display_disabled == true) { memory::cgram[addr] = data; } else { - uint16 v = ppucounter.vcounter(); - uint16 h = ppucounter.hcounter(); + uint16 v = vcounter(); + uint16 h = hcounter(); if(v < (!overscan() ? 225 : 240) && h >= 72 && h < 1096) { memory::cgram[0x01ff] = data & 0x7f; } else { @@ -170,7 +170,7 @@ void bPPU::cgram_mmio_write(uint16 addr, uint8 data) { //INIDISP void bPPU::mmio_w2100(uint8 value) { - if(regs.display_disabled == true && ppucounter.vcounter() == (!overscan() ? 225 : 240)) { + if(regs.display_disabled == true && vcounter() == (!overscan() ? 225 : 240)) { regs.oam_addr = regs.oam_baseaddr << 1; regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; } @@ -723,7 +723,7 @@ uint8 r = 0x00; regs.latch_hcounter = 0; regs.latch_vcounter = 0; - r |= ppucounter.field() << 7; + r |= field() << 7; if(!(cpu.pio() & 0x80)) { r |= 0x40; } else if(regs.counters_latched == true) { diff --git a/src/ppu/bppu/bppu_render.hpp b/src/ppu/bppu/bppu_render.hpp index 2c67429d..5cf200bb 100644 --- a/src/ppu/bppu/bppu_render.hpp +++ b/src/ppu/bppu/bppu_render.hpp @@ -14,16 +14,16 @@ enum { COLORDEPTH_4 = 0, COLORDEPTH_16 = 1, COLORDEPTH_256 = 2 }; enum { TILE_2BIT = 0, TILE_4BIT = 1, TILE_8BIT = 2 }; struct _pixel { -//bgr555 color data for main/subscreen pixels: 0x0000 = transparent / use palette color # 0 -//needs to be bgr555 instead of palette index for direct color mode ($2130 bit 0) to work -uint16 src_main, src_sub; -//indicates source of palette # for main/subscreen (BG1-4, OAM, or back) -uint8 bg_main, bg_sub; -//color_exemption -- true when bg == OAM && palette index >= 192, disables color add/sub effects -uint8 ce_main, ce_sub; -//priority level of src_n. to set src_n, -//the priority of the pixel must be >pri_n -uint8 pri_main, pri_sub; + //bgr555 color data for main/subscreen pixels: 0x0000 = transparent / use palette color # 0 + //needs to be bgr555 instead of palette index for direct color mode ($2130 bit 0) to work + uint16 src_main, src_sub; + //indicates source of palette # for main/subscreen (BG1-4, OAM, or back) + uint8 bg_main, bg_sub; + //color_exemption -- true when bg == OAM && palette index >= 192, disables color add/sub effects + uint8 ce_main, ce_sub; + //priority level of src_n. to set src_n, + //the priority of the pixel must be >pri_n + uint8 pri_main, pri_sub; } pixel_cache[256]; uint8 *bg_tiledata[3]; diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index a30d3731..3a2b022a 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -11,14 +11,14 @@ void bPPU::update_bg_info() { bg_info[bg].mx = (bg_info[bg].th == 4) ? (width << 1) : width; bg_info[bg].my = bg_info[bg].mx; - if(regs.bg_scsize[bg] & 0x01)bg_info[bg].mx <<= 1; - if(regs.bg_scsize[bg] & 0x02)bg_info[bg].my <<= 1; + if(regs.bg_scsize[bg] & 0x01) bg_info[bg].mx <<= 1; + if(regs.bg_scsize[bg] & 0x02) bg_info[bg].my <<= 1; bg_info[bg].mx--; bg_info[bg].my--; bg_info[bg].scy = (regs.bg_scsize[bg] & 0x02) ? (32 << 5) : 0; bg_info[bg].scx = (regs.bg_scsize[bg] & 0x01) ? (32 << 5) : 0; - if(regs.bg_scsize[bg] == 3)bg_info[bg].scy <<= 1; + if(regs.bg_scsize[bg] == 3) bg_info[bg].scy <<= 1; } } @@ -90,7 +90,7 @@ void bPPU::render_line_bg(uint8 bg, uint8 color_depth, uint8 pri0_pos, uint8 pri if(hires) { hscroll <<= 1; - if(regs.interlace) y = (y << 1) + ppucounter.field(); + if(regs.interlace) y = (y << 1) + ifield(); } uint16 *mtable = mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0]; diff --git a/src/ppu/bppu/bppu_render_cache.cpp b/src/ppu/bppu/bppu_render_cache.cpp index 24e3fb36..977b4b4b 100644 --- a/src/ppu/bppu/bppu_render_cache.cpp +++ b/src/ppu/bppu/bppu_render_cache.cpp @@ -106,9 +106,11 @@ void bPPU::render_bg_tile(uint8 color_depth, uint16 tile_num) { void bPPU::flush_pixel_cache() { uint16 main = get_palette(0); - uint16 sub = (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6) ? main : regs.color_rgb; - uint32 i = 255; + uint16 sub = (regs.pseudo_hires || regs.bg_mode == 5 || regs.bg_mode == 6) + ? main + : regs.color_rgb; + unsigned i = 255; do { pixel_cache[i].src_main = main; pixel_cache[i].src_sub = sub; diff --git a/src/ppu/bppu/bppu_render_line.cpp b/src/ppu/bppu/bppu_render_line.cpp index 36aac75e..43400ba6 100644 --- a/src/ppu/bppu/bppu_render_line.cpp +++ b/src/ppu/bppu/bppu_render_line.cpp @@ -86,7 +86,7 @@ inline uint16 bPPU::get_pixel_swap(uint32 x) { inline void bPPU::render_line_output() { uint16 *ptr = (uint16*)output + (line.y * 1024) + - ((interlace() && ppucounter.field()) ? 512 : 0); + ((interlace() && ifield()) ? 512 : 0); uint16 *luma_b = light_table_b [regs.display_brightness]; uint16 *luma_gr = light_table_gr[regs.display_brightness]; uint16 curr, prev; @@ -132,7 +132,7 @@ inline void bPPU::render_line_output() { inline void bPPU::render_line_clear() { uint16 *ptr = (uint16*)output + (line.y * 1024) + - ((interlace() && ppucounter.field()) ? 512 : 0); + ((interlace() && ifield()) ? 512 : 0); uint16 width = (!regs.pseudo_hires && regs.bg_mode != 5 && regs.bg_mode != 6) ? 256 : 512; memset(ptr, 0, width * 2 * sizeof(uint16)); } diff --git a/src/ppu/bppu/bppu_render_oam.cpp b/src/ppu/bppu/bppu_render_oam.cpp index 8856d146..5394fa73 100644 --- a/src/ppu/bppu/bppu_render_oam.cpp +++ b/src/ppu/bppu/bppu_render_oam.cpp @@ -80,7 +80,7 @@ void bPPU::load_oam_tiles() { } if(regs.oam_interlace == true) { - y = (spr->vflip == false) ? (y + ppucounter.field()) : (y - ppucounter.field()); + y = (spr->vflip == false) ? (y + ifield()) : (y - ifield()); } x &= 511; diff --git a/src/ppu/counter.cpp b/src/ppu/counter.cpp index 606e3feb..a61f8b62 100644 --- a/src/ppu/counter.cpp +++ b/src/ppu/counter.cpp @@ -27,8 +27,8 @@ uint16 PPUcounter::lineclocks() { return 1364; } -uint16 PPUcounter::ppulineclocks() { - if(region() == 0 && interlace() == false && ppuvcounter() == 240 && status.field == 1) return 1360; +uint16 PPUcounter::ilineclocks() { + if(region() == 0 && interlace() == false && ivcounter() == 240 && status.field == 1) return 1360; return 1364; } diff --git a/src/ppu/counter.hpp b/src/ppu/counter.hpp index 8aced1e1..a38204a0 100644 --- a/src/ppu/counter.hpp +++ b/src/ppu/counter.hpp @@ -31,20 +31,23 @@ public: history.ppudiff -= clocks; } + //timing information relative to S-CPU alwaysinline bool field () { return status.field; } alwaysinline uint16 vcounter() { return status.vcounter; } alwaysinline uint16 hcounter() { return status.hcounter; } uint16 hdot(); uint16 lineclocks(); + //timing history information relative to S-CPU alwaysinline bool field (unsigned offset) { return history.field [(history.index - (offset >> 1)) & 2047]; } alwaysinline uint16 vcounter(unsigned offset) { return history.vcounter[(history.index - (offset >> 1)) & 2047]; } alwaysinline uint16 hcounter(unsigned offset) { return history.hcounter[(history.index - (offset >> 1)) & 2047]; } - alwaysinline bool ppufield() { return history.field [(history.index - (history.ppudiff >> 1)) & 2047]; } - alwaysinline uint16 ppuvcounter() { return history.vcounter[(history.index - (history.ppudiff >> 1)) & 2047]; } - alwaysinline uint16 ppuhcounter() { return history.hcounter[(history.index - (history.ppudiff >> 1)) & 2047]; } - uint16 ppulineclocks(); + //timing information relative to S-PPU + alwaysinline bool ifield() { return history.field [(history.index - (history.ppudiff >> 1)) & 2047]; } + alwaysinline uint16 ivcounter() { return history.vcounter[(history.index - (history.ppudiff >> 1)) & 2047]; } + alwaysinline uint16 ihcounter() { return history.hcounter[(history.index - (history.ppudiff >> 1)) & 2047]; } + uint16 ilineclocks(); void reset(); @@ -68,5 +71,3 @@ private: signed ppudiff; } history; }; - -extern PPUcounter ppucounter; diff --git a/src/ppu/ppu.cpp b/src/ppu/ppu.cpp index 2ddf84cd..01528a72 100644 --- a/src/ppu/ppu.cpp +++ b/src/ppu/ppu.cpp @@ -28,6 +28,7 @@ void PPU::power() { } void PPU::reset() { + PPUcounter::reset(); memset(output, 0, 512 * 480 * sizeof(uint16)); } diff --git a/src/ppu/ppu.hpp b/src/ppu/ppu.hpp index a899fa46..257aef16 100644 --- a/src/ppu/ppu.hpp +++ b/src/ppu/ppu.hpp @@ -1,18 +1,18 @@ -class PPU : public MMIO { +#include "counter.hpp" + +class PPU : public PPUcounter, public MMIO { public: virtual void enter() = 0; uint16 *output; - //this struct should be read-only to - //functions outside of this class struct { - bool render_output; + bool render_output; - bool frame_executed; - bool frames_updated; - uint32 frames_rendered; - uint32 frames_executed; + bool frame_executed; + bool frames_updated; + unsigned frames_rendered; + unsigned frames_executed; } status; //PPU1 version number @@ -40,5 +40,3 @@ public: PPU(); virtual ~PPU(); }; - -#include "counter.hpp" diff --git a/src/smp/dsmp.cpp b/src/smp/dsmp.cpp index e7644b5e..1cc6c009 100644 --- a/src/smp/dsmp.cpp +++ b/src/smp/dsmp.cpp @@ -5,14 +5,14 @@ bool SMP::in_opcode() { return false; } uint16 SMP::__relb(int8 offset, int op_len) { -uint16 pc = regs.pc + op_len; + uint16 pc = regs.pc + op_len; return pc + offset; } void SMP::disassemble_opcode(char *output) { -char *s, t[512]; -uint8 op, op0, op1; -uint16 opw, opdp0, opdp1; + char *s, t[512]; + uint8 op, op0, op1; + uint16 opw, opdp0, opdp1; s = output; if(in_opcode() == true) { @@ -20,7 +20,7 @@ uint16 opw, opdp0, opdp1; return; } - sprintf(s, "..%0.4x ", regs.pc); + sprintf(s, "..%.4x ", regs.pc); op = ram_read(regs.pc); op0 = ram_read(regs.pc + 1); @@ -30,281 +30,283 @@ uint16 opw, opdp0, opdp1; opdp1 = ((regs.p.p)?0x100:0x000) + op1; strcpy(t, " "); + switch(op) { - case 0x00: sprintf(t, "nop"); break; - case 0x01: sprintf(t, "tcall 0"); break; - case 0x02: sprintf(t, "set0 $%0.3x", opdp0); break; - case 0x03: sprintf(t, "bbs0 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x04: sprintf(t, "or a,$%0.3x", opdp0); break; - case 0x05: sprintf(t, "or a,$%0.4x", opw); break; - case 0x06: sprintf(t, "or a,(x)"); break; - case 0x07: sprintf(t, "or a,($%0.3x+x)", opdp0); break; - case 0x08: sprintf(t, "or a,#$%0.2x", op0); break; - case 0x09: sprintf(t, "or $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0x0a: sprintf(t, "or1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x0b: sprintf(t, "asl $%0.3x", opdp0); break; - case 0x0c: sprintf(t, "asl $%0.4x", opw); break; - case 0x0d: sprintf(t, "push p"); break; - case 0x0e: sprintf(t, "tset $%0.4x,a", opw); break; - case 0x0f: sprintf(t, "brk"); break; - case 0x10: sprintf(t, "bpl $%0.4x", __relb(op0, 2)); break; - case 0x11: sprintf(t, "tcall 1"); break; - case 0x12: sprintf(t, "clr0 $%0.3x", opdp0); break; - case 0x13: sprintf(t, "bbc0 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x14: sprintf(t, "or a,$%0.3x+x", opdp0); break; - case 0x15: sprintf(t, "or a,$%0.4x+x", opw); break; - case 0x16: sprintf(t, "or a,$%0.4x+y", opw); break; - case 0x17: sprintf(t, "or a,($%0.3x)+y", opdp0); break; - case 0x18: sprintf(t, "or $%0.3x,#$%0.2x", opdp1, op0); break; - case 0x19: sprintf(t, "or (x),(y)"); break; - case 0x1a: sprintf(t, "decw $%0.3x", opdp0); break; - case 0x1b: sprintf(t, "asl $%0.3x+x", opdp0); break; - case 0x1c: sprintf(t, "asl a"); break; - case 0x1d: sprintf(t, "dec x"); break; - case 0x1e: sprintf(t, "cmp x,$%0.4x", opw); break; - case 0x1f: sprintf(t, "jmp ($%0.4x+x)", opw); break; - case 0x20: sprintf(t, "clrp"); break; - case 0x21: sprintf(t, "tcall 2"); break; - case 0x22: sprintf(t, "set1 $%0.3x", opdp0); break; - case 0x23: sprintf(t, "bbs1 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x24: sprintf(t, "and a,$%0.3x", opdp0); break; - case 0x25: sprintf(t, "and a,$%0.4x", opw); break; - case 0x26: sprintf(t, "and a,(x)"); break; - case 0x27: sprintf(t, "and a,($%0.3x+x)", opdp0); break; - case 0x28: sprintf(t, "and a,#$%0.2x", op0); break; - case 0x29: sprintf(t, "and $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0x2a: sprintf(t, "or1 c,!$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x2b: sprintf(t, "rol $%0.3x", opdp0); break; - case 0x2c: sprintf(t, "rol $%0.4x", opw); break; - case 0x2d: sprintf(t, "push a"); break; - case 0x2e: sprintf(t, "cbne $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x2f: sprintf(t, "bra $%0.4x", __relb(op0, 2)); break; - case 0x30: sprintf(t, "bmi $%0.4x", __relb(op0, 2)); break; - case 0x31: sprintf(t, "tcall 3"); break; - case 0x32: sprintf(t, "clr1 $%0.3x", opdp0); break; - case 0x33: sprintf(t, "bbc1 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x34: sprintf(t, "and a,$%0.3x+x", opdp0); break; - case 0x35: sprintf(t, "and a,$%0.4x+x", opw); break; - case 0x36: sprintf(t, "and a,$%0.4x+y", opw); break; - case 0x37: sprintf(t, "and a,($%0.3x)+y", opdp0); break; - case 0x38: sprintf(t, "and $%0.3x,#$%0.2x", opdp1, op0); break; - case 0x39: sprintf(t, "and (x),(y)"); break; - case 0x3a: sprintf(t, "incw $%0.3x", opdp0); break; - case 0x3b: sprintf(t, "rol $%0.3x+x", opdp0); break; - case 0x3c: sprintf(t, "rol a"); break; - case 0x3d: sprintf(t, "inc x"); break; - case 0x3e: sprintf(t, "cmp x,$%0.3x", opdp0); break; - case 0x3f: sprintf(t, "call $%0.4x", opw); break; - case 0x40: sprintf(t, "setp"); break; - case 0x41: sprintf(t, "tcall 4"); break; - case 0x42: sprintf(t, "set2 $%0.3x", opdp0); break; - case 0x43: sprintf(t, "bbs2 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x44: sprintf(t, "eor a,$%0.3x", opdp0); break; - case 0x45: sprintf(t, "eor a,$%0.4x", opw); break; - case 0x46: sprintf(t, "eor a,(x)"); break; - case 0x47: sprintf(t, "eor a,($%0.3x+x)", opdp0); break; - case 0x48: sprintf(t, "eor a,#$%0.2x", op0); break; - case 0x49: sprintf(t, "eor $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0x4a: sprintf(t, "and1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x4b: sprintf(t, "lsr $%0.3x", opdp0); break; - case 0x4c: sprintf(t, "lsr $%0.4x", opw); break; - case 0x4d: sprintf(t, "push x"); break; - case 0x4e: sprintf(t, "tclr $%0.4x,a", opw); break; - case 0x4f: sprintf(t, "pcall $ff%0.2x", op0); break; - case 0x50: sprintf(t, "bvc $%0.4x", __relb(op0, 2)); break; - case 0x51: sprintf(t, "tcall 5"); break; - case 0x52: sprintf(t, "clr2 $%0.3x", opdp0); break; - case 0x53: sprintf(t, "bbc2 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x54: sprintf(t, "eor a,$%0.3x+x", opdp0); break; - case 0x55: sprintf(t, "eor a,$%0.4x+x", opw); break; - case 0x56: sprintf(t, "eor a,$%0.4x+y", opw); break; - case 0x57: sprintf(t, "eor a,($%0.3x)+y", opdp0); break; - case 0x58: sprintf(t, "eor $%0.3x,#$%0.2x", opdp1, op0); break; - case 0x59: sprintf(t, "eor (x),(y)"); break; - case 0x5a: sprintf(t, "cmpw ya,$%0.3x", opdp0); break; - case 0x5b: sprintf(t, "lsr $%0.3x+x", opdp0); break; - case 0x5c: sprintf(t, "lsr a"); break; - case 0x5d: sprintf(t, "mov x,a"); break; - case 0x5e: sprintf(t, "cmp y,$%0.4x", opw); break; - case 0x5f: sprintf(t, "jmp $%0.4x", opw); break; - case 0x60: sprintf(t, "clrc"); break; - case 0x61: sprintf(t, "tcall 6"); break; - case 0x62: sprintf(t, "set3 $%0.3x", opdp0); break; - case 0x63: sprintf(t, "bbs3 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x64: sprintf(t, "cmp a,$%0.3x", opdp0); break; - case 0x65: sprintf(t, "cmp a,$%0.4x", opw); break; - case 0x66: sprintf(t, "cmp a,(x)"); break; - case 0x67: sprintf(t, "cmp a,($%0.3x+x)", opdp0); break; - case 0x68: sprintf(t, "cmp a,#$%0.2x", op0); break; - case 0x69: sprintf(t, "cmp $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0x6a: sprintf(t, "and1 c,!$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x6b: sprintf(t, "ror $%0.3x", opdp0); break; - case 0x6c: sprintf(t, "ror $%0.4x", opw); break; - case 0x6d: sprintf(t, "push y"); break; - case 0x6e: sprintf(t, "dbnz $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x6f: sprintf(t, "ret"); break; - case 0x70: sprintf(t, "bvs $%0.4x", __relb(op0, 2)); break; - case 0x71: sprintf(t, "tcall 7"); break; - case 0x72: sprintf(t, "clr3 $%0.3x", opdp0); break; - case 0x73: sprintf(t, "bbc3 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x74: sprintf(t, "cmp a,$%0.3x+x", opdp0); break; - case 0x75: sprintf(t, "cmp a,$%0.4x+x", opw); break; - case 0x76: sprintf(t, "cmp a,$%0.4x+y", opw); break; - case 0x77: sprintf(t, "cmp a,($%0.3x)+y", opdp0); break; - case 0x78: sprintf(t, "cmp $%0.3x,#$%0.2x", opdp1, op0); break; - case 0x79: sprintf(t, "cmp (x),(y)"); break; - case 0x7a: sprintf(t, "addw ya,$%0.3x", opdp0); break; - case 0x7b: sprintf(t, "ror $%0.3x+x", opdp0); break; - case 0x7c: sprintf(t, "ror a"); break; - case 0x7d: sprintf(t, "mov a,x"); break; - case 0x7e: sprintf(t, "cmp y,$%0.3x", opdp0); break; - case 0x7f: sprintf(t, "reti"); break; - case 0x80: sprintf(t, "setc"); break; - case 0x81: sprintf(t, "tcall 8"); break; - case 0x82: sprintf(t, "set4 $%0.3x", opdp0); break; - case 0x83: sprintf(t, "bbs4 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x84: sprintf(t, "adc a,$%0.3x", opdp0); break; - case 0x85: sprintf(t, "adc a,$%0.4x", opw); break; - case 0x86: sprintf(t, "adc a,(x)"); break; - case 0x87: sprintf(t, "adc a,($%0.3x+x)", opdp0); break; - case 0x88: sprintf(t, "adc a,#$%0.2x", op0); break; - case 0x89: sprintf(t, "adc $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0x8a: sprintf(t, "eor1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x8b: sprintf(t, "dec $%0.3x", opdp0); break; - case 0x8c: sprintf(t, "dec $%0.4x", opw); break; - case 0x8d: sprintf(t, "mov y,#$%0.2x", op0); break; - case 0x8e: sprintf(t, "pop p"); break; - case 0x8f: sprintf(t, "mov $%0.3x,#$%0.2x", opdp1, op0); break; - case 0x90: sprintf(t, "bcc $%0.4x", __relb(op0, 2)); break; - case 0x91: sprintf(t, "tcall 9"); break; - case 0x92: sprintf(t, "clr4 $%0.3x", opdp0); break; - case 0x93: sprintf(t, "bbc4 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0x94: sprintf(t, "adc a,$%0.3x+x", opdp0); break; - case 0x95: sprintf(t, "adc a,$%0.4x+x", opw); break; - case 0x96: sprintf(t, "adc a,$%0.4x+y", opw); break; - case 0x97: sprintf(t, "adc a,($%0.3x)+y", opdp0); break; - case 0x98: sprintf(t, "adc $%0.3x,#$%0.2x", opdp1, op0); break; - case 0x99: sprintf(t, "adc (x),(y)"); break; - case 0x9a: sprintf(t, "subw ya,$%0.3x", opdp0); break; - case 0x9b: sprintf(t, "dec $%0.3x+x", opdp0); break; - case 0x9c: sprintf(t, "dec a"); break; - case 0x9d: sprintf(t, "mov x,sp"); break; - case 0x9e: sprintf(t, "div ya,x"); break; - case 0x9f: sprintf(t, "xcn a"); break; - case 0xa0: sprintf(t, "ei"); break; - case 0xa1: sprintf(t, "tcall 10"); break; - case 0xa2: sprintf(t, "set5 $%0.3x", opdp0); break; - case 0xa3: sprintf(t, "bbs5 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0xa4: sprintf(t, "sbc a,$%0.3x", opdp0); break; - case 0xa5: sprintf(t, "sbc a,$%0.4x", opw); break; - case 0xa6: sprintf(t, "sbc a,(x)"); break; - case 0xa7: sprintf(t, "sbc a,($%0.3x+x)", opdp0); break; - case 0xa8: sprintf(t, "sbc a,#$%0.2x", op0); break; - case 0xa9: sprintf(t, "sbc $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0xaa: sprintf(t, "mov1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0xab: sprintf(t, "inc $%0.3x", opdp0); break; - case 0xac: sprintf(t, "inc $%0.4x", opw); break; - case 0xad: sprintf(t, "cmp y,#$%0.2x", op0); break; - case 0xae: sprintf(t, "pop a"); break; - case 0xaf: sprintf(t, "mov (x)+,a"); break; - case 0xb0: sprintf(t, "bcs $%0.4x", __relb(op0, 2)); break; - case 0xb1: sprintf(t, "tcall 11"); break; - case 0xb2: sprintf(t, "clr5 $%0.3x", opdp0); break; - case 0xb3: sprintf(t, "bbc5 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0xb4: sprintf(t, "sbc a,$%0.3x+x", opdp0); break; - case 0xb5: sprintf(t, "sbc a,$%0.4x+x", opw); break; - case 0xb6: sprintf(t, "sbc a,$%0.4x+y", opw); break; - case 0xb7: sprintf(t, "sbc a,($%0.3x)+y", opdp0); break; - case 0xb8: sprintf(t, "sbc $%0.3x,#$%0.2x", opdp1, op0); break; - case 0xb9: sprintf(t, "sbc (x),(y)"); break; - case 0xba: sprintf(t, "movw ya,$%0.3x", opdp0); break; - case 0xbb: sprintf(t, "inc $%0.3x+x", opdp0); break; - case 0xbc: sprintf(t, "inc a"); break; - case 0xbd: sprintf(t, "mov sp,x"); break; - case 0xbe: sprintf(t, "das a"); break; - case 0xbf: sprintf(t, "mov a,(x)+"); break; - case 0xc0: sprintf(t, "di"); break; - case 0xc1: sprintf(t, "tcall 12"); break; - case 0xc2: sprintf(t, "set6 $%0.3x", opdp0); break; - case 0xc3: sprintf(t, "bbs6 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0xc4: sprintf(t, "mov $%0.3x,a", opdp0); break; - case 0xc5: sprintf(t, "mov $%0.4x,a", opw); break; - case 0xc6: sprintf(t, "mov (x),a"); break; - case 0xc7: sprintf(t, "mov ($%0.3x+x),a", opdp0); break; - case 0xc8: sprintf(t, "cmp x,#$%0.2x", op0); break; - case 0xc9: sprintf(t, "mov $%0.4x,x", opw); break; - case 0xca: sprintf(t, "mov1 $%0.4x:%d,c", opw & 0x1fff, opw >> 13); break; - case 0xcb: sprintf(t, "mov $%0.3x,y", opdp0); break; - case 0xcc: sprintf(t, "mov $%0.4x,y", opw); break; - case 0xcd: sprintf(t, "mov x,#$%0.2x", op0); break; - case 0xce: sprintf(t, "pop x"); break; - case 0xcf: sprintf(t, "mul ya"); break; - case 0xd0: sprintf(t, "bne $%0.4x", __relb(op0, 2)); break; - case 0xd1: sprintf(t, "tcall 13"); break; - case 0xd2: sprintf(t, "clr6 $%0.3x", opdp0); break; - case 0xd3: sprintf(t, "bbc6 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0xd4: sprintf(t, "mov $%0.3x+x,a", opdp0); break; - case 0xd5: sprintf(t, "mov $%0.4x+x,a", opw); break; - case 0xd6: sprintf(t, "mov $%0.4x+y,a", opw); break; - case 0xd7: sprintf(t, "mov ($%0.3x)+y,a", opdp0); break; - case 0xd8: sprintf(t, "mov $%0.3x,x", opdp0); break; - case 0xd9: sprintf(t, "mov $%0.3x+y,x", opdp0); break; - case 0xda: sprintf(t, "movw $%0.3x,ya", opdp0); break; - case 0xdb: sprintf(t, "mov $%0.3x+x,y", opdp0); break; - case 0xdc: sprintf(t, "dec y"); break; - case 0xdd: sprintf(t, "mov a,y"); break; - case 0xde: sprintf(t, "cbne $%0.3x+x,$%0.4x", opdp0, __relb(op1, 3));break; - case 0xdf: sprintf(t, "daa a"); break; - case 0xe0: sprintf(t, "clrv"); break; - case 0xe1: sprintf(t, "tcall 14"); break; - case 0xe2: sprintf(t, "set7 $%0.3x", opdp0); break; - case 0xe3: sprintf(t, "bbs7 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0xe4: sprintf(t, "mov a,$%0.3x", opdp0); break; - case 0xe5: sprintf(t, "mov a,$%0.4x", opw); break; - case 0xe6: sprintf(t, "mov a,(x)"); break; - case 0xe7: sprintf(t, "mov a,($%0.3x+x)", opdp0); break; - case 0xe8: sprintf(t, "mov a,#$%0.2x", op0); break; - case 0xe9: sprintf(t, "mov x,$%0.4x", opw); break; - case 0xea: sprintf(t, "not1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0xeb: sprintf(t, "mov y,$%0.3x", opdp0); break; - case 0xec: sprintf(t, "mov y,$%0.4x", opw); break; - case 0xed: sprintf(t, "notc"); break; - case 0xee: sprintf(t, "pop y"); break; - case 0xef: sprintf(t, "sleep"); break; - case 0xf0: sprintf(t, "beq $%0.4x", __relb(op0, 2)); break; - case 0xf1: sprintf(t, "tcall 15"); break; - case 0xf2: sprintf(t, "clr7 $%0.3x", opdp0); break; - case 0xf3: sprintf(t, "bbc7 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break; - case 0xf4: sprintf(t, "mov a,$%0.3x+x", opdp0); break; - case 0xf5: sprintf(t, "mov a,$%0.4x+x", opw); break; - case 0xf6: sprintf(t, "mov a,$%0.4x+y", opw); break; - case 0xf7: sprintf(t, "mov a,($%0.3x)+y", opdp0); break; - case 0xf8: sprintf(t, "mov x,$%0.3x", opdp0); break; - case 0xf9: sprintf(t, "mov x,$%0.3x+y", opdp0); break; - case 0xfa: sprintf(t, "mov $%0.3x,$%0.3x", opdp1, opdp0); break; - case 0xfb: sprintf(t, "mov y,$%0.3x+x", opdp0); break; - case 0xfc: sprintf(t, "inc y"); break; - case 0xfd: sprintf(t, "mov y,a"); break; - case 0xfe: sprintf(t, "dbnz y,$%0.4x", __relb(op0, 2)); break; - case 0xff: sprintf(t, "stop"); break; + case 0x00: sprintf(t, "nop"); break; + case 0x01: sprintf(t, "tcall 0"); break; + case 0x02: sprintf(t, "set0 $%.3x", opdp0); break; + case 0x03: sprintf(t, "bbs0 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x04: sprintf(t, "or a,$%.3x", opdp0); break; + case 0x05: sprintf(t, "or a,$%.4x", opw); break; + case 0x06: sprintf(t, "or a,(x)"); break; + case 0x07: sprintf(t, "or a,($%.3x+x)", opdp0); break; + case 0x08: sprintf(t, "or a,#$%.2x", op0); break; + case 0x09: sprintf(t, "or $%.3x,$%.3x", opdp1, opdp0); break; + case 0x0a: sprintf(t, "or1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x0b: sprintf(t, "asl $%.3x", opdp0); break; + case 0x0c: sprintf(t, "asl $%.4x", opw); break; + case 0x0d: sprintf(t, "push p"); break; + case 0x0e: sprintf(t, "tset $%.4x,a", opw); break; + case 0x0f: sprintf(t, "brk"); break; + case 0x10: sprintf(t, "bpl $%.4x", __relb(op0, 2)); break; + case 0x11: sprintf(t, "tcall 1"); break; + case 0x12: sprintf(t, "clr0 $%.3x", opdp0); break; + case 0x13: sprintf(t, "bbc0 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x14: sprintf(t, "or a,$%.3x+x", opdp0); break; + case 0x15: sprintf(t, "or a,$%.4x+x", opw); break; + case 0x16: sprintf(t, "or a,$%.4x+y", opw); break; + case 0x17: sprintf(t, "or a,($%.3x)+y", opdp0); break; + case 0x18: sprintf(t, "or $%.3x,#$%.2x", opdp1, op0); break; + case 0x19: sprintf(t, "or (x),(y)"); break; + case 0x1a: sprintf(t, "decw $%.3x", opdp0); break; + case 0x1b: sprintf(t, "asl $%.3x+x", opdp0); break; + case 0x1c: sprintf(t, "asl a"); break; + case 0x1d: sprintf(t, "dec x"); break; + case 0x1e: sprintf(t, "cmp x,$%.4x", opw); break; + case 0x1f: sprintf(t, "jmp ($%.4x+x)", opw); break; + case 0x20: sprintf(t, "clrp"); break; + case 0x21: sprintf(t, "tcall 2"); break; + case 0x22: sprintf(t, "set1 $%.3x", opdp0); break; + case 0x23: sprintf(t, "bbs1 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x24: sprintf(t, "and a,$%.3x", opdp0); break; + case 0x25: sprintf(t, "and a,$%.4x", opw); break; + case 0x26: sprintf(t, "and a,(x)"); break; + case 0x27: sprintf(t, "and a,($%.3x+x)", opdp0); break; + case 0x28: sprintf(t, "and a,#$%.2x", op0); break; + case 0x29: sprintf(t, "and $%.3x,$%.3x", opdp1, opdp0); break; + case 0x2a: sprintf(t, "or1 c,!$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x2b: sprintf(t, "rol $%.3x", opdp0); break; + case 0x2c: sprintf(t, "rol $%.4x", opw); break; + case 0x2d: sprintf(t, "push a"); break; + case 0x2e: sprintf(t, "cbne $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x2f: sprintf(t, "bra $%.4x", __relb(op0, 2)); break; + case 0x30: sprintf(t, "bmi $%.4x", __relb(op0, 2)); break; + case 0x31: sprintf(t, "tcall 3"); break; + case 0x32: sprintf(t, "clr1 $%.3x", opdp0); break; + case 0x33: sprintf(t, "bbc1 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x34: sprintf(t, "and a,$%.3x+x", opdp0); break; + case 0x35: sprintf(t, "and a,$%.4x+x", opw); break; + case 0x36: sprintf(t, "and a,$%.4x+y", opw); break; + case 0x37: sprintf(t, "and a,($%.3x)+y", opdp0); break; + case 0x38: sprintf(t, "and $%.3x,#$%.2x", opdp1, op0); break; + case 0x39: sprintf(t, "and (x),(y)"); break; + case 0x3a: sprintf(t, "incw $%.3x", opdp0); break; + case 0x3b: sprintf(t, "rol $%.3x+x", opdp0); break; + case 0x3c: sprintf(t, "rol a"); break; + case 0x3d: sprintf(t, "inc x"); break; + case 0x3e: sprintf(t, "cmp x,$%.3x", opdp0); break; + case 0x3f: sprintf(t, "call $%.4x", opw); break; + case 0x40: sprintf(t, "setp"); break; + case 0x41: sprintf(t, "tcall 4"); break; + case 0x42: sprintf(t, "set2 $%.3x", opdp0); break; + case 0x43: sprintf(t, "bbs2 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x44: sprintf(t, "eor a,$%.3x", opdp0); break; + case 0x45: sprintf(t, "eor a,$%.4x", opw); break; + case 0x46: sprintf(t, "eor a,(x)"); break; + case 0x47: sprintf(t, "eor a,($%.3x+x)", opdp0); break; + case 0x48: sprintf(t, "eor a,#$%.2x", op0); break; + case 0x49: sprintf(t, "eor $%.3x,$%.3x", opdp1, opdp0); break; + case 0x4a: sprintf(t, "and1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x4b: sprintf(t, "lsr $%.3x", opdp0); break; + case 0x4c: sprintf(t, "lsr $%.4x", opw); break; + case 0x4d: sprintf(t, "push x"); break; + case 0x4e: sprintf(t, "tclr $%.4x,a", opw); break; + case 0x4f: sprintf(t, "pcall $ff%.2x", op0); break; + case 0x50: sprintf(t, "bvc $%.4x", __relb(op0, 2)); break; + case 0x51: sprintf(t, "tcall 5"); break; + case 0x52: sprintf(t, "clr2 $%.3x", opdp0); break; + case 0x53: sprintf(t, "bbc2 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x54: sprintf(t, "eor a,$%.3x+x", opdp0); break; + case 0x55: sprintf(t, "eor a,$%.4x+x", opw); break; + case 0x56: sprintf(t, "eor a,$%.4x+y", opw); break; + case 0x57: sprintf(t, "eor a,($%.3x)+y", opdp0); break; + case 0x58: sprintf(t, "eor $%.3x,#$%.2x", opdp1, op0); break; + case 0x59: sprintf(t, "eor (x),(y)"); break; + case 0x5a: sprintf(t, "cmpw ya,$%.3x", opdp0); break; + case 0x5b: sprintf(t, "lsr $%.3x+x", opdp0); break; + case 0x5c: sprintf(t, "lsr a"); break; + case 0x5d: sprintf(t, "mov x,a"); break; + case 0x5e: sprintf(t, "cmp y,$%.4x", opw); break; + case 0x5f: sprintf(t, "jmp $%.4x", opw); break; + case 0x60: sprintf(t, "clrc"); break; + case 0x61: sprintf(t, "tcall 6"); break; + case 0x62: sprintf(t, "set3 $%.3x", opdp0); break; + case 0x63: sprintf(t, "bbs3 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x64: sprintf(t, "cmp a,$%.3x", opdp0); break; + case 0x65: sprintf(t, "cmp a,$%.4x", opw); break; + case 0x66: sprintf(t, "cmp a,(x)"); break; + case 0x67: sprintf(t, "cmp a,($%.3x+x)", opdp0); break; + case 0x68: sprintf(t, "cmp a,#$%.2x", op0); break; + case 0x69: sprintf(t, "cmp $%.3x,$%.3x", opdp1, opdp0); break; + case 0x6a: sprintf(t, "and1 c,!$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x6b: sprintf(t, "ror $%.3x", opdp0); break; + case 0x6c: sprintf(t, "ror $%.4x", opw); break; + case 0x6d: sprintf(t, "push y"); break; + case 0x6e: sprintf(t, "dbnz $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x6f: sprintf(t, "ret"); break; + case 0x70: sprintf(t, "bvs $%.4x", __relb(op0, 2)); break; + case 0x71: sprintf(t, "tcall 7"); break; + case 0x72: sprintf(t, "clr3 $%.3x", opdp0); break; + case 0x73: sprintf(t, "bbc3 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x74: sprintf(t, "cmp a,$%.3x+x", opdp0); break; + case 0x75: sprintf(t, "cmp a,$%.4x+x", opw); break; + case 0x76: sprintf(t, "cmp a,$%.4x+y", opw); break; + case 0x77: sprintf(t, "cmp a,($%.3x)+y", opdp0); break; + case 0x78: sprintf(t, "cmp $%.3x,#$%.2x", opdp1, op0); break; + case 0x79: sprintf(t, "cmp (x),(y)"); break; + case 0x7a: sprintf(t, "addw ya,$%.3x", opdp0); break; + case 0x7b: sprintf(t, "ror $%.3x+x", opdp0); break; + case 0x7c: sprintf(t, "ror a"); break; + case 0x7d: sprintf(t, "mov a,x"); break; + case 0x7e: sprintf(t, "cmp y,$%.3x", opdp0); break; + case 0x7f: sprintf(t, "reti"); break; + case 0x80: sprintf(t, "setc"); break; + case 0x81: sprintf(t, "tcall 8"); break; + case 0x82: sprintf(t, "set4 $%.3x", opdp0); break; + case 0x83: sprintf(t, "bbs4 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x84: sprintf(t, "adc a,$%.3x", opdp0); break; + case 0x85: sprintf(t, "adc a,$%.4x", opw); break; + case 0x86: sprintf(t, "adc a,(x)"); break; + case 0x87: sprintf(t, "adc a,($%.3x+x)", opdp0); break; + case 0x88: sprintf(t, "adc a,#$%.2x", op0); break; + case 0x89: sprintf(t, "adc $%.3x,$%.3x", opdp1, opdp0); break; + case 0x8a: sprintf(t, "eor1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0x8b: sprintf(t, "dec $%.3x", opdp0); break; + case 0x8c: sprintf(t, "dec $%.4x", opw); break; + case 0x8d: sprintf(t, "mov y,#$%.2x", op0); break; + case 0x8e: sprintf(t, "pop p"); break; + case 0x8f: sprintf(t, "mov $%.3x,#$%.2x", opdp1, op0); break; + case 0x90: sprintf(t, "bcc $%.4x", __relb(op0, 2)); break; + case 0x91: sprintf(t, "tcall 9"); break; + case 0x92: sprintf(t, "clr4 $%.3x", opdp0); break; + case 0x93: sprintf(t, "bbc4 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0x94: sprintf(t, "adc a,$%.3x+x", opdp0); break; + case 0x95: sprintf(t, "adc a,$%.4x+x", opw); break; + case 0x96: sprintf(t, "adc a,$%.4x+y", opw); break; + case 0x97: sprintf(t, "adc a,($%.3x)+y", opdp0); break; + case 0x98: sprintf(t, "adc $%.3x,#$%.2x", opdp1, op0); break; + case 0x99: sprintf(t, "adc (x),(y)"); break; + case 0x9a: sprintf(t, "subw ya,$%.3x", opdp0); break; + case 0x9b: sprintf(t, "dec $%.3x+x", opdp0); break; + case 0x9c: sprintf(t, "dec a"); break; + case 0x9d: sprintf(t, "mov x,sp"); break; + case 0x9e: sprintf(t, "div ya,x"); break; + case 0x9f: sprintf(t, "xcn a"); break; + case 0xa0: sprintf(t, "ei"); break; + case 0xa1: sprintf(t, "tcall 10"); break; + case 0xa2: sprintf(t, "set5 $%.3x", opdp0); break; + case 0xa3: sprintf(t, "bbs5 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xa4: sprintf(t, "sbc a,$%.3x", opdp0); break; + case 0xa5: sprintf(t, "sbc a,$%.4x", opw); break; + case 0xa6: sprintf(t, "sbc a,(x)"); break; + case 0xa7: sprintf(t, "sbc a,($%.3x+x)", opdp0); break; + case 0xa8: sprintf(t, "sbc a,#$%.2x", op0); break; + case 0xa9: sprintf(t, "sbc $%.3x,$%.3x", opdp1, opdp0); break; + case 0xaa: sprintf(t, "mov1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0xab: sprintf(t, "inc $%.3x", opdp0); break; + case 0xac: sprintf(t, "inc $%.4x", opw); break; + case 0xad: sprintf(t, "cmp y,#$%.2x", op0); break; + case 0xae: sprintf(t, "pop a"); break; + case 0xaf: sprintf(t, "mov (x)+,a"); break; + case 0xb0: sprintf(t, "bcs $%.4x", __relb(op0, 2)); break; + case 0xb1: sprintf(t, "tcall 11"); break; + case 0xb2: sprintf(t, "clr5 $%.3x", opdp0); break; + case 0xb3: sprintf(t, "bbc5 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xb4: sprintf(t, "sbc a,$%.3x+x", opdp0); break; + case 0xb5: sprintf(t, "sbc a,$%.4x+x", opw); break; + case 0xb6: sprintf(t, "sbc a,$%.4x+y", opw); break; + case 0xb7: sprintf(t, "sbc a,($%.3x)+y", opdp0); break; + case 0xb8: sprintf(t, "sbc $%.3x,#$%.2x", opdp1, op0); break; + case 0xb9: sprintf(t, "sbc (x),(y)"); break; + case 0xba: sprintf(t, "movw ya,$%.3x", opdp0); break; + case 0xbb: sprintf(t, "inc $%.3x+x", opdp0); break; + case 0xbc: sprintf(t, "inc a"); break; + case 0xbd: sprintf(t, "mov sp,x"); break; + case 0xbe: sprintf(t, "das a"); break; + case 0xbf: sprintf(t, "mov a,(x)+"); break; + case 0xc0: sprintf(t, "di"); break; + case 0xc1: sprintf(t, "tcall 12"); break; + case 0xc2: sprintf(t, "set6 $%.3x", opdp0); break; + case 0xc3: sprintf(t, "bbs6 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xc4: sprintf(t, "mov $%.3x,a", opdp0); break; + case 0xc5: sprintf(t, "mov $%.4x,a", opw); break; + case 0xc6: sprintf(t, "mov (x),a"); break; + case 0xc7: sprintf(t, "mov ($%.3x+x),a", opdp0); break; + case 0xc8: sprintf(t, "cmp x,#$%.2x", op0); break; + case 0xc9: sprintf(t, "mov $%.4x,x", opw); break; + case 0xca: sprintf(t, "mov1 $%.4x:%d,c", opw & 0x1fff, opw >> 13); break; + case 0xcb: sprintf(t, "mov $%.3x,y", opdp0); break; + case 0xcc: sprintf(t, "mov $%.4x,y", opw); break; + case 0xcd: sprintf(t, "mov x,#$%.2x", op0); break; + case 0xce: sprintf(t, "pop x"); break; + case 0xcf: sprintf(t, "mul ya"); break; + case 0xd0: sprintf(t, "bne $%.4x", __relb(op0, 2)); break; + case 0xd1: sprintf(t, "tcall 13"); break; + case 0xd2: sprintf(t, "clr6 $%.3x", opdp0); break; + case 0xd3: sprintf(t, "bbc6 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xd4: sprintf(t, "mov $%.3x+x,a", opdp0); break; + case 0xd5: sprintf(t, "mov $%.4x+x,a", opw); break; + case 0xd6: sprintf(t, "mov $%.4x+y,a", opw); break; + case 0xd7: sprintf(t, "mov ($%.3x)+y,a", opdp0); break; + case 0xd8: sprintf(t, "mov $%.3x,x", opdp0); break; + case 0xd9: sprintf(t, "mov $%.3x+y,x", opdp0); break; + case 0xda: sprintf(t, "movw $%.3x,ya", opdp0); break; + case 0xdb: sprintf(t, "mov $%.3x+x,y", opdp0); break; + case 0xdc: sprintf(t, "dec y"); break; + case 0xdd: sprintf(t, "mov a,y"); break; + case 0xde: sprintf(t, "cbne $%.3x+x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xdf: sprintf(t, "daa a"); break; + case 0xe0: sprintf(t, "clrv"); break; + case 0xe1: sprintf(t, "tcall 14"); break; + case 0xe2: sprintf(t, "set7 $%.3x", opdp0); break; + case 0xe3: sprintf(t, "bbs7 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xe4: sprintf(t, "mov a,$%.3x", opdp0); break; + case 0xe5: sprintf(t, "mov a,$%.4x", opw); break; + case 0xe6: sprintf(t, "mov a,(x)"); break; + case 0xe7: sprintf(t, "mov a,($%.3x+x)", opdp0); break; + case 0xe8: sprintf(t, "mov a,#$%.2x", op0); break; + case 0xe9: sprintf(t, "mov x,$%.4x", opw); break; + case 0xea: sprintf(t, "not1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; + case 0xeb: sprintf(t, "mov y,$%.3x", opdp0); break; + case 0xec: sprintf(t, "mov y,$%.4x", opw); break; + case 0xed: sprintf(t, "notc"); break; + case 0xee: sprintf(t, "pop y"); break; + case 0xef: sprintf(t, "sleep"); break; + case 0xf0: sprintf(t, "beq $%.4x", __relb(op0, 2)); break; + case 0xf1: sprintf(t, "tcall 15"); break; + case 0xf2: sprintf(t, "clr7 $%.3x", opdp0); break; + case 0xf3: sprintf(t, "bbc7 $%.3x,$%.4x", opdp0, __relb(op1, 3)); break; + case 0xf4: sprintf(t, "mov a,$%.3x+x", opdp0); break; + case 0xf5: sprintf(t, "mov a,$%.4x+x", opw); break; + case 0xf6: sprintf(t, "mov a,$%.4x+y", opw); break; + case 0xf7: sprintf(t, "mov a,($%.3x)+y", opdp0); break; + case 0xf8: sprintf(t, "mov x,$%.3x", opdp0); break; + case 0xf9: sprintf(t, "mov x,$%.3x+y", opdp0); break; + case 0xfa: sprintf(t, "mov $%.3x,$%.3x", opdp1, opdp0); break; + case 0xfb: sprintf(t, "mov y,$%.3x+x", opdp0); break; + case 0xfc: sprintf(t, "inc y"); break; + case 0xfd: sprintf(t, "mov y,a"); break; + case 0xfe: sprintf(t, "dbnz y,$%.4x", __relb(op0, 2)); break; + case 0xff: sprintf(t, "stop"); break; } + t[strlen(t)] = ' '; strcat(s, t); - sprintf(t, "A:%0.2x X:%0.2x Y:%0.2x SP:01%0.2x YA:%0.4x ", + sprintf(t, "A:%.2x X:%.2x Y:%.2x SP:01%.2x YA:%.4x ", regs.a, regs.x, regs.y, regs.sp, regs.ya); strcat(s, t); sprintf(t, "%c%c%c%c%c%c%c%c", - (regs.p.n) ? 'N' : 'n', - (regs.p.v) ? 'V' : 'v', - (regs.p.p) ? 'P' : 'p', - (regs.p.b) ? 'B' : 'b', - (regs.p.h) ? 'H' : 'h', - (regs.p.i) ? 'I' : 'i', - (regs.p.z) ? 'Z' : 'z', - (regs.p.c) ? 'C' : 'c'); + regs.p.n ? 'N' : 'n', + regs.p.v ? 'V' : 'v', + regs.p.p ? 'P' : 'p', + regs.p.b ? 'B' : 'b', + regs.p.h ? 'H' : 'h', + regs.p.i ? 'I' : 'i', + regs.p.z ? 'Z' : 'z', + regs.p.c ? 'C' : 'c'); strcat(s, t); } -#endif //ifdef SMP_CPP +#endif //ifdef SMP_CPP diff --git a/src/snes/input/input.hpp b/src/snes/input/input.hpp index 8fea4048..339f1745 100644 --- a/src/snes/input/input.hpp +++ b/src/snes/input/input.hpp @@ -68,8 +68,8 @@ public: alwaysinline void tick() { //only test if Super Scope or Justifier is connected if(iobit) { - if(ppucounter.vcounter() == latchy //test Y cursor position - && ppucounter.hcounter() == latchx << 2 //test X cursor position (cycles == pixels << 2) + if(ppu.vcounter() == latchy //test Y cursor position + && ppu.hcounter() == latchx << 2 //test X cursor position (cycles == pixels << 2) && latchy < (ppu.overscan() ? 240 : 225) //verify Y is not offscreen && latchx < 256 //verify X is not offscreen ) ppu.latch_counters(); diff --git a/src/snes/snes.cpp b/src/snes/snes.cpp index 1bfe6561..3d2720a0 100644 --- a/src/snes/snes.cpp +++ b/src/snes/snes.cpp @@ -1,13 +1,12 @@ #include <../base.hpp> #define SNES_CPP -SNES snes; -BUSCORE bus; -CPUCORE cpu; -SMPCORE smp; -DSPCORE dsp; -PPUCORE ppu; -PPUcounter ppucounter; +SNES snes; +BUSCORE bus; +CPUCORE cpu; +SMPCORE smp; +DSPCORE dsp; +PPUCORE ppu; BSXBase bsxbase; BSXCart bsxcart; @@ -72,7 +71,6 @@ void SNES::power() { scheduler.init(); - ppucounter.reset(); cpu.power(); smp.power(); dsp.power(); @@ -101,7 +99,7 @@ void SNES::power() { for(unsigned i = 0x4200; i <= 0x421f; i++) memory::mmio.map(i, cpu); for(unsigned i = 0x4300; i <= 0x437f; i++) memory::mmio.map(i, cpu); - if(expansion() == ExpansionBSX) { bsxbase.enable(); } + if(expansion() == ExpansionBSX) bsxbase.enable(); if(cartridge.info.bsxcart) bsxcart.enable(); if(cartridge.info.bsxflash) bsxflash.enable(); @@ -125,14 +123,13 @@ void SNES::power() { void SNES::reset() { scheduler.init(); - ppucounter.reset(); cpu.reset(); smp.reset(); dsp.reset(); ppu.reset(); bus.reset(); - if(expansion() == ExpansionBSX) { bsxbase.reset(); } + if(expansion() == ExpansionBSX) bsxbase.reset(); if(cartridge.info.bsxcart) bsxcart.reset(); if(cartridge.info.bsxflash) bsxflash.reset(); @@ -156,7 +153,7 @@ void SNES::reset() { void SNES::scanline() { video.scanline(); - if(ppucounter.vcounter() == 241) { + if(ppu.vcounter() == 241) { input.update(); video.update(); scheduler.exit(); diff --git a/src/snes/video/video.cpp b/src/snes/video/video.cpp index 1108a7e3..a88712cb 100644 --- a/src/snes/video/video.cpp +++ b/src/snes/video/video.cpp @@ -77,12 +77,12 @@ void SNES::Video::update() { } void SNES::Video::scanline() { - unsigned y = ppucounter.vcounter(); + unsigned y = ppu.vcounter(); if(y >= 240) return; unsigned width = (ppu.hires() == false ? 256 : 512); pline_width[y] = width; - iline_width[y * 2 + (int)ppucounter.field()] = width; + iline_width[y * 2 + (int)ppu.field()] = width; frame_hires |= ppu.hires(); frame_interlace |= ppu.interlace(); diff --git a/src/ui/base/main.cpp b/src/ui/base/main.cpp index e9e53b59..9986733b 100644 --- a/src/ui/base/main.cpp +++ b/src/ui/base/main.cpp @@ -205,8 +205,8 @@ void MainWindow::setup() { menu_system_sep4.create(); menu_system_exit.create(translate["{{system}}Exit"]); - //menu_system.attach(menu_system_sep4); - //menu_system.attach(menu_system_exit); + menu_system.attach(menu_system_sep4); + menu_system.attach(menu_system_exit); attach(menu_settings.create(translate["{{menu}}Settings"])); menu_settings.attach(menu_settings_videomode.create(translate["Video Mode"])); diff --git a/src/ui/config.cpp b/src/ui/config.cpp index a13938c7..e1e0ad44 100644 --- a/src/ui/config.cpp +++ b/src/ui/config.cpp @@ -43,7 +43,7 @@ integral_setting System::contrast(config(), "system.colorfilter.contrast", integral_setting System::brightness(config(), "system.colorfilter.brightness", "Brightness", integral_setting::decimal, 0); integral_setting System::gamma(config(), "system.colorfilter.gamma", - "Gamma", integral_setting::decimal, 80); + "Gamma", integral_setting::decimal, 100); struct Video { static integral_setting mode; @@ -59,6 +59,7 @@ struct Video { } fullscreen; static integral_setting aspect_ntsc_x, aspect_ntsc_y, aspect_pal_x, aspect_pal_y; static integral_setting frameskip; + static integral_setting start_in_fullscreen_mode; } video; //0 = windowed, 1 = fullscreen, 2 = exclusive (not implemented yet) @@ -107,6 +108,9 @@ integral_setting Video::aspect_pal_x (config(), "video.aspect_pal_x", "", integ integral_setting Video::aspect_pal_y (config(), "video.aspect_pal_y", "", integral_setting::decimal, 23); integral_setting Video::frameskip("video.frameskip", "Video frameskip", integral_setting::decimal, 0); +integral_setting Video::start_in_fullscreen_mode(config(), "video.start_in_fullscreen_mode", + "If true, bsnes will start in fullscreen mode, rather than windowed mode.", + integral_setting::boolean, false); struct Audio { static integral_setting output_frequency, input_frequency; diff --git a/src/ui/main.cpp b/src/ui/main.cpp index e4fe1133..ba4418da 100644 --- a/src/ui/main.cpp +++ b/src/ui/main.cpp @@ -24,27 +24,28 @@ using namespace libhiro; void get_paths(const char *image) { char temp[PATH_MAX] = ""; - realpath(image, temp); - if(strlen(temp) != 0) { - for(int i = strlen(temp) - 1; i >= 0; i--) { - if(temp[i] == '\\') temp[i] = '/'; - } + if(realpath(image, temp)) { //remove program name - for(int i = strlen(temp) - 1; i >= 0; i--) { - if(temp[i] == '/') { + for(signed i = strlen(temp) - 1; i >= 0; i--) { + if(temp[i] == '/' || temp[i] == '\\') { temp[i] = 0; break; } } + + if(strend(temp, "/") == false) strcat(temp, "/"); + config::path.base = temp; + } else { + config::path.base = ""; } - if(strend(temp, "/") == false) strcat(temp, "/"); - config::path.base = temp; - - userpath(temp); - if(strend(temp, "/") == false) strcat(temp, "/"); - config::path.user = temp; + if(userpath(temp)) { + if(strend(temp, "/") == false) strcat(temp, "/"); + config::path.user = temp; + } else { + config::path.user = ""; + } } void set_config_filenames() { diff --git a/src/ui/settings/audiosettings.cpp b/src/ui/settings/audiosettings.cpp index 0acdf3c8..347ee8f7 100644 --- a/src/ui/settings/audiosettings.cpp +++ b/src/ui/settings/audiosettings.cpp @@ -1,5 +1,5 @@ uintptr_t AudioSettingsWindow::volume_change(event_t) { - config::audio.volume = 10 + svolume.get_position(); + config::audio.volume = 25 + cvolume.get_selection() * 25; audio.set(Audio::Volume, config::audio.volume); sync_ui(); @@ -7,18 +7,19 @@ uintptr_t AudioSettingsWindow::volume_change(event_t) { } uintptr_t AudioSettingsWindow::latency_change(event_t) { - config::audio.latency = 25 + slatency.get_position() * 5; + config::audio.latency = 20 + clatency.get_selection() * 20; audio.set(Audio::Latency, config::audio.latency); sync_ui(); return true; } -uintptr_t AudioSettingsWindow::output_change(event_t) { - switch(soutput.get_position()) { +uintptr_t AudioSettingsWindow::frequency_change(event_t) { + switch(cfrequency.get_selection()) { case 0: config::audio.output_frequency = 32000; break; case 1: config::audio.output_frequency = 44100; break; default: case 2: config::audio.output_frequency = 48000; break; + case 3: config::audio.output_frequency = 96000; break; } audio.set(Audio::Frequency, config::audio.output_frequency); @@ -28,49 +29,8 @@ uintptr_t AudioSettingsWindow::output_change(event_t) { return true; } -uintptr_t AudioSettingsWindow::input_change(event_t) { - config::audio.input_frequency = sinput.get_position() + 32000 - 200; - event::update_emulation_speed(config::system.emulation_speed); - - sync_ui(); - return true; -} - -uintptr_t AudioSettingsWindow::volume_tick(event_t) { - char t[256]; - evolume.get_text(t, sizeof t); - config::audio.volume = strdec(t); - audio.set(Audio::Volume, config::audio.volume); - - sync_ui(); - return true; -} - -uintptr_t AudioSettingsWindow::latency_tick(event_t) { - char t[256]; - elatency.get_text(t, sizeof t); - config::audio.latency = strdec(t); - audio.set(Audio::Latency, config::audio.latency); - - sync_ui(); - return true; -} - -uintptr_t AudioSettingsWindow::output_tick(event_t) { - char t[256]; - eoutput.get_text(t, sizeof t); - config::audio.output_frequency = strdec(t); - audio.set(Audio::Frequency, config::audio.output_frequency); - event::update_emulation_speed(config::system.emulation_speed); - - sync_ui(); - return true; -} - -uintptr_t AudioSettingsWindow::input_tick(event_t) { - char t[256]; - einput.get_text(t, sizeof t); - config::audio.input_frequency = strdec(t); +uintptr_t AudioSettingsWindow::skew_change(event_t) { + config::audio.input_frequency = sskew.get_position() + 32000 - 200; event::update_emulation_speed(config::system.emulation_speed); sync_ui(); @@ -78,133 +38,87 @@ uintptr_t AudioSettingsWindow::input_tick(event_t) { } void AudioSettingsWindow::sync_ui() { - lvolume.set_text(string() - << translate["Volume:"] << " " - << (int)config::audio.volume << "%" - ); + cvolume.set_selection((config::audio.volume - 25) / 25); - llatency.set_text(string() - << translate["Latency:"] << " " - << (int)config::audio.latency << "ms" - ); + unsigned position; + if(config::audio.output_frequency <= 32000) position = 0; + else if(config::audio.output_frequency <= 44100) position = 1; + else if(config::audio.output_frequency <= 48000) position = 2; + else position = 3; + cfrequency.set_selection(position); - loutput.set_text(string() - << translate["Frequency:"] << " " - << (int)config::audio.output_frequency << "hz" - ); + clatency.set_selection((config::audio.latency - 20) / 20); - if(config::advanced.enable == false) { - int input_freq = config::audio.input_frequency - 32000; - string adjust; - if(input_freq > 0) adjust << "+"; - adjust << input_freq << "hz"; - linput.set_text(string() - << translate["Frequency adjust:"] << " " - << adjust - ); - } else { - linput.set_text(string() << translate["Frequency adjust:"] << " " << (int)config::audio.input_frequency << "hz"); - } - - if(config::advanced.enable == false) { - svolume.set_position(config::audio.volume - 10); - slatency.set_position((config::audio.latency - 25) / 5); - unsigned position; - if(config::audio.output_frequency <= 32000) position = 0; - else if(config::audio.output_frequency <= 44100) position = 1; - else position = 2; - soutput.set_position(position); - sinput.set_position(config::audio.input_frequency - 32000 + 200); - } else { - evolume.set_text(string() << (int)config::audio.volume); - elatency.set_text(string() << (int)config::audio.latency); - eoutput.set_text(string() << (int)config::audio.output_frequency); - einput.set_text(string() << (int)config::audio.input_frequency); - } + lskew.set_text(string() << translate["{{audio}}Frequency adjust:"] << " " << (int)config::audio.input_frequency << "hz"); + sskew.set_position(config::audio.input_frequency - 32000 + 200); } void AudioSettingsWindow::setup() { create(0, 451, 370); - lvolume.create(0, 223, 18); - svolume.create(0, 451, 30, 91); - evolume.create(0, 118, 25); - bvolume.create(0, 100, 25, translate["{{audio}}Set"]); + lvolume.create(0, 147, 18, translate["{{audio}}Volume:"]); + cvolume.create(0, 147, 25); + cvolume.add_item( "25%"); + cvolume.add_item( "50%"); + cvolume.add_item( "75%"); + cvolume.add_item("100%"); + if(config::advanced.enable == true) { + cvolume.add_item("125%"); + cvolume.add_item("150%"); + cvolume.add_item("175%"); + cvolume.add_item("200%"); + } - llatency.create(0, 223, 18); - slatency.create(0, 451, 30, 26); - elatency.create(0, 118, 25); - blatency.create(0, 100, 25, translate["{{audio}}Set"]); + lfrequency.create(0, 147, 18, translate["{{audio}}Frequency:"]); + cfrequency.create(0, 147, 25); + cfrequency.add_item("32Khz"); + cfrequency.add_item("44.1Khz"); + cfrequency.add_item("48Khz"); + if(config::advanced.enable == true) { + cfrequency.add_item("96Khz"); + } - loutput.create(0, 223, 18); - soutput.create(0, 451, 30, 3); - eoutput.create(0, 118, 25); - boutput.create(0, 100, 25, translate["{{audio}}Set"]); + llatency.create(0, 147, 18, translate["{{audio}}Latency:"]); + clatency.create(0, 147, 25); + clatency.add_item( "20ms"); + clatency.add_item( "40ms"); + clatency.add_item( "60ms"); + clatency.add_item( "80ms"); + clatency.add_item("100ms"); + clatency.add_item("120ms"); + if(config::advanced.enable == true) { + clatency.add_item("140ms"); + clatency.add_item("160ms"); + } - linput.create(0, 223, 18); - sinput.create(0, 451, 30, 401); - einput.create(0, 118, 25); - binput.create(0, 100, 25, translate["{{audio}}Set"]); + lskew.create(0, 451, 18, translate["{{audio}}Frequency adjust:"]); + sskew.create(0, 451, 30, 401); - note.create(0, 475, 54, string() + note.create(0, 451, 54, string() << translate["{{audio}}Frequency adjust is used to improve video sync timing."] << "\n" << translate["{{audio}}Lower value to clean audio output."] << "\n" << translate["{{audio}}Raise value to smooth video output."] ); unsigned y = 0; - if(config::advanced.enable == false) { - attach(lvolume, 0, y); y += 18; - attach(svolume, 0, y); y += 30; - if(audio.cap(Audio::Latency) == true) { - attach(llatency, 0, y); y += 18; - attach(slatency, 0, y); y += 30; - } - if(audio.cap(Audio::Frequency) == true) { - attach(loutput, 0, y); y += 18; - attach(soutput, 0, y); y += 30; - } - attach(linput, 0, y); y += 18; - attach(sinput, 0, y); y += 30; - } else { - attach(lvolume, 0, y); - attach(llatency, 228, y); y += 18; - attach(evolume, 0, y); - attach(bvolume, 123, y); - attach(elatency, 228, y); - attach(blatency, 351, y); y += 25 + 5; + attach(lvolume, 0, y); + attach(lfrequency, 152, y); + attach(llatency, 304, y); y += 18; - attach(loutput, 0, y); - attach(linput, 228, y); y += 18; + attach(cvolume, 0, y); + attach(cfrequency, 152, y); + attach(clatency, 304, y); y += 30; - attach(eoutput, 0, y); - attach(boutput, 123, y); - attach(einput, 228, y); - attach(binput, 351, y); y += 25 + 5; + attach(lskew, 0, y); y += 18; + attach(sskew, 0, y); y += 30; - if(audio.cap(Audio::Latency) == false) { - elatency.disable(); - blatency.disable(); - } + attach(note, 0, y); - if(audio.cap(Audio::Frequency) == false) { - eoutput.disable(); - boutput.disable(); - } - } - - attach(note, 0, y); - - svolume.on_change = bind(&AudioSettingsWindow::volume_change, this); - slatency.on_change = bind(&AudioSettingsWindow::latency_change, this); - soutput.on_change = bind(&AudioSettingsWindow::output_change, this); - sinput.on_change = bind(&AudioSettingsWindow::input_change, this); - - bvolume.on_tick = bind(&AudioSettingsWindow::volume_tick, this); - blatency.on_tick = bind(&AudioSettingsWindow::latency_tick, this); - boutput.on_tick = bind(&AudioSettingsWindow::output_tick, this); - binput.on_tick = bind(&AudioSettingsWindow::input_tick, this); + cvolume.on_change = bind(&AudioSettingsWindow::volume_change, this); + cfrequency.on_change = bind(&AudioSettingsWindow::frequency_change, this); + clatency.on_change = bind(&AudioSettingsWindow::latency_change, this); + sskew.on_change = bind(&AudioSettingsWindow::skew_change, this); sync_ui(); } diff --git a/src/ui/settings/audiosettings.hpp b/src/ui/settings/audiosettings.hpp index 740a1664..b0220fbf 100644 --- a/src/ui/settings/audiosettings.hpp +++ b/src/ui/settings/audiosettings.hpp @@ -1,36 +1,19 @@ class AudioSettingsWindow : public Window { public: - Label lvolume; - Slider svolume; - Editbox evolume; - Button bvolume; - - Label llatency; - Slider slatency; - Editbox elatency; - Button blatency; - - Label loutput; - Slider soutput; - Editbox eoutput; - Button boutput; - - Label linput; - Slider sinput; - Editbox einput; - Button binput; - - Label note; + Label lvolume; + Combobox cvolume; + Label lfrequency; + Combobox cfrequency; + Label llatency; + Combobox clatency; + Label lskew; + Slider sskew; + Label note; uintptr_t volume_change(event_t); uintptr_t latency_change(event_t); - uintptr_t output_change(event_t); - uintptr_t input_change(event_t); - - uintptr_t volume_tick(event_t); - uintptr_t latency_tick(event_t); - uintptr_t output_tick(event_t); - uintptr_t input_tick(event_t); + uintptr_t frequency_change(event_t); + uintptr_t skew_change(event_t); void sync_ui(); void setup(); diff --git a/src/ui/settings/videosettings.cpp b/src/ui/settings/videosettings.cpp index 38759ed2..633bf798 100644 --- a/src/ui/settings/videosettings.cpp +++ b/src/ui/settings/videosettings.cpp @@ -1,54 +1,57 @@ void VideoSettingsWindow::setup() { create(0, 451, 370); - lcontrast.create (0, 451, 18); - contrast.create (0, 451, 30, 192); - lbrightness.create (0, 451, 18); - brightness.create (0, 451, 30, 192); - lgamma.create (0, 451, 18); - gamma.create (0, 451, 30, 191); - gamma_ramp.create (0, 223, 18, translate["Gamma ramp"]); - sepia.create (0, 223, 18, translate["Sepia"]); - grayscale.create (0, 223, 18, translate["Grayscale"]); - invert.create (0, 223, 18, translate["Invert colors"]); - preset_optimal.create (0, 223, 25, translate["Optimal Preset"]); - preset_standard.create(0, 223, 25, translate["Standard Preset"]); + lcontrast.create (0, 451, 18); + contrast.create (0, 451, 30, 191); + lbrightness.create(0, 451, 18); + brightness.create (0, 451, 30, 191); + lgamma.create (0, 451, 18); + gamma.create (0, 451, 30, 191); + gamma_ramp.create (0, 223, 18, translate["Gamma ramp"]); + sepia.create (0, 223, 18, translate["Sepia"]); + grayscale.create (0, 223, 18, translate["Grayscale"]); + invert.create (0, 223, 18, translate["Invert colors"]); sync_ui(); - uint y = 0; - attach(lcontrast, 0, y); y += 18; - attach(contrast, 0, y); y += 30; - attach(lbrightness, 0, y); y += 18; - attach(brightness, 0, y); y += 30; - attach(lgamma, 0, y); y += 18; - attach(gamma, 0, y); y += 30; - attach(gamma_ramp, 0, y); - attach(sepia, 228, y); y += 18; - attach(grayscale, 0, y); - attach(invert, 228, y); y += 18 + 5; - attach(preset_optimal, 0, y); - attach(preset_standard, 228, y); y += 25; + unsigned y = 0; + attach(lcontrast, 0, y); y += 18; + attach(contrast, 0, y); y += 30; + attach(lbrightness, 0, y); y += 18; + attach(brightness, 0, y); y += 30; + attach(lgamma, 0, y); y += 18; + attach(gamma, 0, y); y += 30; - contrast.on_change = bind(&VideoSettingsWindow::contrast_change, this); - brightness.on_change = bind(&VideoSettingsWindow::brightness_change, this); - gamma.on_change = bind(&VideoSettingsWindow::gamma_change, this); - gamma_ramp.on_tick = bind(&VideoSettingsWindow::gammaramp_tick, this); - sepia.on_tick = bind(&VideoSettingsWindow::sepia_tick, this); - grayscale.on_tick = bind(&VideoSettingsWindow::grayscale_tick, this); - invert.on_tick = bind(&VideoSettingsWindow::invert_tick, this); - preset_optimal.on_tick = bind(&VideoSettingsWindow::optimal_tick, this); - preset_standard.on_tick = bind(&VideoSettingsWindow::standard_tick, this); + attach(gamma_ramp, 0, y); + attach(sepia, 228, y); y += 18; + attach(grayscale, 0, y); + attach(invert, 228, y); y += 18 + 5; + + contrast.on_change = bind(&VideoSettingsWindow::contrast_change, this); + brightness.on_change = bind(&VideoSettingsWindow::brightness_change, this); + gamma.on_change = bind(&VideoSettingsWindow::gamma_change, this); + gamma_ramp.on_tick = bind(&VideoSettingsWindow::gammaramp_tick, this); + sepia.on_tick = bind(&VideoSettingsWindow::sepia_tick, this); + grayscale.on_tick = bind(&VideoSettingsWindow::grayscale_tick, this); + invert.on_tick = bind(&VideoSettingsWindow::invert_tick, this); } //update all UI controls to match config file values ... void VideoSettingsWindow::sync_ui() { - ui_lock = true; //supress event messages while syncing UI elements, prevents infinite recursion - contrast.set_position(config::system.contrast + 96); - lcontrast.set_text(string() << translate["Contrast"] << ": " << (int)config::system.contrast); - brightness.set_position(config::system.brightness + 96); - lbrightness.set_text(string() << translate["Brightness"] << ": " << (int)config::system.brightness); - gamma.set_position(config::system.gamma - 10); - lgamma.set_text(string() << translate["Gamma"] << ": " << (int)config::system.gamma); //TODO: print gamma as "%0.2f" / 100.0 + contrast.set_position(config::system.contrast + 95); + lcontrast.set_text(string() + << translate["Contrast adjust"] << ": " + << ((int)config::system.contrast > 0 ? "+" : "") + << (int)config::system.contrast << "%"); + brightness.set_position(config::system.brightness + 95); + lbrightness.set_text(string() + << translate["Brightness adjust"] << ": " + << ((int)config::system.brightness > 0 ? "+" : "") + << (int)config::system.brightness << "%"); + gamma.set_position(config::system.gamma - 5); + lgamma.set_text(string() + << translate["Gamma adjust"] << ": " + << ((int)config::system.gamma > 100 ? "+" : "") + << (int)(config::system.gamma - 100) << "%"); gamma_ramp.check(config::system.gamma_ramp); sepia.check(config::system.sepia); grayscale.check(config::system.grayscale); @@ -62,36 +65,34 @@ void VideoSettingsWindow::sync_ui() { libfilter::colortable.enable_grayscale(config::system.grayscale); libfilter::colortable.enable_invert(config::system.invert); libfilter::colortable.update(); - - ui_lock = false; } uintptr_t VideoSettingsWindow::contrast_change(event_t) { - if(!ui_lock && config::system.contrast != contrast.get_position() - 96) { - config::system.contrast = contrast.get_position() - 96; + if(config::system.contrast != contrast.get_position() - 95) { + config::system.contrast = contrast.get_position() - 95; sync_ui(); } return true; } uintptr_t VideoSettingsWindow::brightness_change(event_t) { - if(!ui_lock && config::system.brightness != brightness.get_position() - 96) { - config::system.brightness = brightness.get_position() - 96; + if(config::system.brightness != brightness.get_position() - 95) { + config::system.brightness = brightness.get_position() - 95; sync_ui(); } return true; } uintptr_t VideoSettingsWindow::gamma_change(event_t) { - if(!ui_lock && config::system.gamma != gamma.get_position() + 10) { - config::system.gamma = gamma.get_position() + 10; + if(config::system.gamma != gamma.get_position() + 5) { + config::system.gamma = gamma.get_position() + 5; sync_ui(); } return true; } uintptr_t VideoSettingsWindow::gammaramp_tick(event_t) { - if(!ui_lock && config::system.gamma_ramp != gamma_ramp.checked()) { + if(config::system.gamma_ramp != gamma_ramp.checked()) { config::system.gamma_ramp = gamma_ramp.checked(); sync_ui(); } @@ -99,7 +100,7 @@ uintptr_t VideoSettingsWindow::gammaramp_tick(event_t) { } uintptr_t VideoSettingsWindow::sepia_tick(event_t) { - if(!ui_lock && config::system.sepia != sepia.checked()) { + if(config::system.sepia != sepia.checked()) { config::system.sepia = sepia.checked(); sync_ui(); } @@ -107,7 +108,7 @@ uintptr_t VideoSettingsWindow::sepia_tick(event_t) { } uintptr_t VideoSettingsWindow::grayscale_tick(event_t) { - if(!ui_lock && config::system.grayscale != grayscale.checked()) { + if(config::system.grayscale != grayscale.checked()) { config::system.grayscale = grayscale.checked(); sync_ui(); } @@ -115,37 +116,9 @@ uintptr_t VideoSettingsWindow::grayscale_tick(event_t) { } uintptr_t VideoSettingsWindow::invert_tick(event_t) { - if(!ui_lock && config::system.invert != invert.checked()) { + if(config::system.invert != invert.checked()) { config::system.invert = invert.checked(); sync_ui(); } return true; } - -uintptr_t VideoSettingsWindow::optimal_tick(event_t) { - config::system.contrast = 0; - config::system.brightness = 0; - config::system.gamma = 80; - config::system.gamma_ramp = true; - config::system.sepia = false; - config::system.grayscale = false; - config::system.invert = false; - sync_ui(); - return true; -} - -uintptr_t VideoSettingsWindow::standard_tick(event_t) { - config::system.contrast = 0; - config::system.brightness = 0; - config::system.gamma = 100; - config::system.gamma_ramp = false; - config::system.sepia = false; - config::system.grayscale = false; - config::system.invert = false; - sync_ui(); - return true; -} - -VideoSettingsWindow::VideoSettingsWindow() { - ui_lock = false; -} diff --git a/src/ui/settings/videosettings.hpp b/src/ui/settings/videosettings.hpp index 258a2b9d..b27881f0 100644 --- a/src/ui/settings/videosettings.hpp +++ b/src/ui/settings/videosettings.hpp @@ -12,13 +12,9 @@ public: Checkbox grayscale; Checkbox invert; - Button preset_optimal; - Button preset_standard; - void setup(); void sync_ui(); - bool ui_lock; uintptr_t contrast_change(event_t); uintptr_t brightness_change(event_t); uintptr_t gamma_change(event_t); @@ -26,8 +22,4 @@ public: uintptr_t sepia_tick(event_t); uintptr_t grayscale_tick(event_t); uintptr_t invert_tick(event_t); - uintptr_t optimal_tick(event_t); - uintptr_t standard_tick(event_t); - - VideoSettingsWindow(); } window_video_settings; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index 78489262..de0f6a3e 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -47,6 +47,7 @@ void ui_init() { window_advanced.setup(); window_settings.setup(); + config::video.mode = (config::video.start_in_fullscreen_mode == false) ? 0 : 1; event::update_opacity(); event::update_video_settings(); //call first time to resize main window and update menubar diff --git a/test_hdma.smc b/test_hdma.smc new file mode 100644 index 00000000..f6ad7f2f Binary files /dev/null and b/test_hdma.smc differ diff --git a/test_hdmasync.smc b/test_hdmasync.smc new file mode 100644 index 00000000..c98bb433 Binary files /dev/null and b/test_hdmasync.smc differ diff --git a/test_hdmatiming.smc b/test_hdmatiming.smc new file mode 100644 index 00000000..74ef35e2 Binary files /dev/null and b/test_hdmatiming.smc differ diff --git a/test_irq.smc b/test_irq.smc new file mode 100644 index 00000000..40c8df20 Binary files /dev/null and b/test_irq.smc differ diff --git a/test_irq4200.smc b/test_irq4200.smc new file mode 100644 index 00000000..830d1234 Binary files /dev/null and b/test_irq4200.smc differ diff --git a/test_irq4209.smc b/test_irq4209.smc new file mode 100644 index 00000000..19201d34 Binary files /dev/null and b/test_irq4209.smc differ diff --git a/test_irqb.smc b/test_irqb.smc new file mode 100644 index 00000000..c9de8575 Binary files /dev/null and b/test_irqb.smc differ diff --git a/test_nmi.smc b/test_nmi.smc new file mode 100644 index 00000000..90804d11 Binary files /dev/null and b/test_nmi.smc differ