mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-24 15:12:23 +01:00
byuu says: Small WIP, just fixes the timings for GSU multiply. However, the actual product may still be wrong when CLSR and MS0 are both set. Since I wasn't 'corrupting' the value in said case before, then this behavior can only be better than before. Turned the (cache,memory)_access_timing into functions that compute the values; and pulled "clockspeed" into GSU. Also, I'm thinking it might be kind of pointless to have clockspeed at all. Supposedly even the Mario Chip can run at 21.48MHz anyway. Enforcing 10.74MHz mode seems kind of silly. If we change it to just be a "default value for CLSR", then we can just inline the memory access tests without the need for the access_timing functions (literally just clsr?2:1 then) Slight compilation bug: go to processor/gsu/registers.hpp:33 and add reg16_t() = default; I missed it due to a partial recompile. Too lazy to upload another WIP just for that. Probably not worth doing much SuperFX testing just yet, as it looks like they're doing some other tests at the moment on NESdev.
282 lines
12 KiB
C++
282 lines
12 KiB
C++
#ifdef SUPERFX_CPP
|
|
|
|
//TODO: this belongs in processor/gsu
|
|
|
|
auto SuperFX::disassemble_opcode(char* output) -> void {
|
|
*output = 0;
|
|
|
|
if(!regs.sfr.alt2) {
|
|
if(!regs.sfr.alt1) {
|
|
disassemble_alt0(output);
|
|
} else {
|
|
disassemble_alt1(output);
|
|
}
|
|
} else {
|
|
if(!regs.sfr.alt1) {
|
|
disassemble_alt2(output);
|
|
} else {
|
|
disassemble_alt3(output);
|
|
}
|
|
}
|
|
|
|
unsigned length = strlen(output);
|
|
while(length++ < 20) strcat(output, " ");
|
|
}
|
|
|
|
#define case4(id) \
|
|
case id+ 0: case id+ 1: case id+ 2: case id+ 3
|
|
#define case6(id) \
|
|
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5
|
|
#define case12(id) \
|
|
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \
|
|
case id+ 8: case id+ 9: case id+10: case id+11
|
|
#define case15(id) \
|
|
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \
|
|
case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14
|
|
#define case16(id) \
|
|
case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \
|
|
case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14: case id+15
|
|
|
|
#define op0 regs.pipeline
|
|
#define op1 bus_read((regs.pbr << 16) + regs.r[15] + 0)
|
|
#define op2 bus_read((regs.pbr << 16) + regs.r[15] + 1)
|
|
|
|
auto SuperFX::disassemble_alt0(char* output) -> void {
|
|
char t[256] = "";
|
|
switch(op0) {
|
|
case (0x00): sprintf(t, "stop"); break;
|
|
case (0x01): sprintf(t, "nop"); break;
|
|
case (0x02): sprintf(t, "cache"); break;
|
|
case (0x03): sprintf(t, "lsr"); break;
|
|
case (0x04): sprintf(t, "rol"); break;
|
|
case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break;
|
|
case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break;
|
|
case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break;
|
|
case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break;
|
|
case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break;
|
|
case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break;
|
|
case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break;
|
|
case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break;
|
|
case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break;
|
|
case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break;
|
|
case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break;
|
|
case16(0x10): sprintf(t, "to r%u", op0 & 15); break;
|
|
case16(0x20): sprintf(t, "with r%u", op0 & 15); break;
|
|
case12(0x30): sprintf(t, "stw (r%u)", op0 & 15); break;
|
|
case (0x3c): sprintf(t, "loop"); break;
|
|
case (0x3d): sprintf(t, "alt1"); break;
|
|
case (0x3e): sprintf(t, "alt2"); break;
|
|
case (0x3f): sprintf(t, "alt3"); break;
|
|
case12(0x40): sprintf(t, "ldw (r%u)", op0 & 15); break;
|
|
case (0x4c): sprintf(t, "plot"); break;
|
|
case (0x4d): sprintf(t, "swap"); break;
|
|
case (0x4e): sprintf(t, "color"); break;
|
|
case (0x4f): sprintf(t, "not"); break;
|
|
case16(0x50): sprintf(t, "add r%u", op0 & 15); break;
|
|
case16(0x60): sprintf(t, "sub r%u", op0 & 15); break;
|
|
case (0x70): sprintf(t, "merge"); break;
|
|
case15(0x71): sprintf(t, "and r%u", op0 & 15); break;
|
|
case16(0x80): sprintf(t, "mult r%u", op0 & 15); break;
|
|
case (0x90): sprintf(t, "sbk"); break;
|
|
case4 (0x91): sprintf(t, "link #%u", op0 & 15); break;
|
|
case (0x95): sprintf(t, "sex"); break;
|
|
case (0x96): sprintf(t, "asr"); break;
|
|
case (0x97): sprintf(t, "ror"); break;
|
|
case6 (0x98): sprintf(t, "jmp r%u", op0 & 15); break;
|
|
case (0x9e): sprintf(t, "lob"); break;
|
|
case (0x9f): sprintf(t, "fmult"); break;
|
|
case16(0xa0): sprintf(t, "ibt r%u,#$%.2x", op0 & 15, op1); break;
|
|
case16(0xb0): sprintf(t, "from r%u", op0 & 15); break;
|
|
case (0xc0): sprintf(t, "hib"); break;
|
|
case15(0xc1): sprintf(t, "or r%u", op0 & 15); break;
|
|
case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break;
|
|
case (0xdf): sprintf(t, "getc"); break;
|
|
case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break;
|
|
case (0xef): sprintf(t, "getb"); break;
|
|
case16(0xf0): sprintf(t, "iwt r%u,#$%.2x%.2x", op0 & 15, op2, op1); break;
|
|
}
|
|
strcat(output, t);
|
|
}
|
|
|
|
auto SuperFX::disassemble_alt1(char* output) -> void {
|
|
char t[256] = "";
|
|
switch(op0) {
|
|
case (0x00): sprintf(t, "stop"); break;
|
|
case (0x01): sprintf(t, "nop"); break;
|
|
case (0x02): sprintf(t, "cache"); break;
|
|
case (0x03): sprintf(t, "lsr"); break;
|
|
case (0x04): sprintf(t, "rol"); break;
|
|
case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break;
|
|
case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break;
|
|
case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break;
|
|
case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break;
|
|
case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break;
|
|
case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break;
|
|
case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break;
|
|
case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break;
|
|
case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break;
|
|
case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break;
|
|
case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break;
|
|
case16(0x10): sprintf(t, "to r%u", op0 & 15); break;
|
|
case16(0x20): sprintf(t, "with r%u", op0 & 15); break;
|
|
case12(0x30): sprintf(t, "stb (r%u)", op0 & 15); break;
|
|
case (0x3c): sprintf(t, "loop"); break;
|
|
case (0x3d): sprintf(t, "alt1"); break;
|
|
case (0x3e): sprintf(t, "alt2"); break;
|
|
case (0x3f): sprintf(t, "alt3"); break;
|
|
case12(0x40): sprintf(t, "ldb (r%u)", op0 & 15); break;
|
|
case (0x4c): sprintf(t, "rpix"); break;
|
|
case (0x4d): sprintf(t, "swap"); break;
|
|
case (0x4e): sprintf(t, "cmode"); break;
|
|
case (0x4f): sprintf(t, "not"); break;
|
|
case16(0x50): sprintf(t, "adc r%u", op0 & 15); break;
|
|
case16(0x60): sprintf(t, "sbc r%u", op0 & 15); break;
|
|
case (0x70): sprintf(t, "merge"); break;
|
|
case15(0x71): sprintf(t, "bic r%u", op0 & 15); break;
|
|
case16(0x80): sprintf(t, "umult r%u", op0 & 15); break;
|
|
case (0x90): sprintf(t, "sbk"); break;
|
|
case4 (0x91): sprintf(t, "link #%u", op0 & 15); break;
|
|
case (0x95): sprintf(t, "sex"); break;
|
|
case (0x96): sprintf(t, "div2"); break;
|
|
case (0x97): sprintf(t, "ror"); break;
|
|
case6 (0x98): sprintf(t, "ljmp r%u", op0 & 15); break;
|
|
case (0x9e): sprintf(t, "lob"); break;
|
|
case (0x9f): sprintf(t, "lmult"); break;
|
|
case16(0xa0): sprintf(t, "lms r%u,(#$%.4x)", op0 & 15, op1 << 1); break;
|
|
case16(0xb0): sprintf(t, "from r%u", op0 & 15); break;
|
|
case (0xc0): sprintf(t, "hib"); break;
|
|
case15(0xc1): sprintf(t, "xor r%u", op0 & 15); break;
|
|
case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break;
|
|
case (0xdf): sprintf(t, "getc"); break;
|
|
case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break;
|
|
case (0xef): sprintf(t, "getbh"); break;
|
|
case16(0xf0): sprintf(t, "lm r%u", op0 & 15); break;
|
|
}
|
|
strcat(output, t);
|
|
}
|
|
|
|
auto SuperFX::disassemble_alt2(char* output) -> void {
|
|
char t[256] = "";
|
|
switch(op0) {
|
|
case (0x00): sprintf(t, "stop"); break;
|
|
case (0x01): sprintf(t, "nop"); break;
|
|
case (0x02): sprintf(t, "cache"); break;
|
|
case (0x03): sprintf(t, "lsr"); break;
|
|
case (0x04): sprintf(t, "rol"); break;
|
|
case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break;
|
|
case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break;
|
|
case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break;
|
|
case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break;
|
|
case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break;
|
|
case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break;
|
|
case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break;
|
|
case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break;
|
|
case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break;
|
|
case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break;
|
|
case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break;
|
|
case16(0x10): sprintf(t, "to r%u", op0 & 15); break;
|
|
case16(0x20): sprintf(t, "with r%u", op0 & 15); break;
|
|
case12(0x30): sprintf(t, "stw (r%u)", op0 & 15); break;
|
|
case (0x3c): sprintf(t, "loop"); break;
|
|
case (0x3d): sprintf(t, "alt1"); break;
|
|
case (0x3e): sprintf(t, "alt2"); break;
|
|
case (0x3f): sprintf(t, "alt3"); break;
|
|
case12(0x40): sprintf(t, "ldw (r%u)", op0 & 15); break;
|
|
case (0x4c): sprintf(t, "plot"); break;
|
|
case (0x4d): sprintf(t, "swap"); break;
|
|
case (0x4e): sprintf(t, "color"); break;
|
|
case (0x4f): sprintf(t, "not"); break;
|
|
case16(0x50): sprintf(t, "add #%u", op0 & 15); break;
|
|
case16(0x60): sprintf(t, "sub #%u", op0 & 15); break;
|
|
case (0x70): sprintf(t, "merge"); break;
|
|
case15(0x71): sprintf(t, "and #%u", op0 & 15); break;
|
|
case16(0x80): sprintf(t, "mult #%u", op0 & 15); break;
|
|
case (0x90): sprintf(t, "sbk"); break;
|
|
case4 (0x91): sprintf(t, "link #%u", op0 & 15); break;
|
|
case (0x95): sprintf(t, "sex"); break;
|
|
case (0x96): sprintf(t, "asr"); break;
|
|
case (0x97): sprintf(t, "ror"); break;
|
|
case6 (0x98): sprintf(t, "jmp r%u", op0 & 15); break;
|
|
case (0x9e): sprintf(t, "lob"); break;
|
|
case (0x9f): sprintf(t, "fmult"); break;
|
|
case16(0xa0): sprintf(t, "sms r%u,(#$%.4x)", op0 & 15, op1 << 1); break;
|
|
case16(0xb0): sprintf(t, "from r%u", op0 & 15); break;
|
|
case (0xc0): sprintf(t, "hib"); break;
|
|
case15(0xc1): sprintf(t, "or #%u", op0 & 15); break;
|
|
case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break;
|
|
case (0xdf): sprintf(t, "ramb"); break;
|
|
case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break;
|
|
case (0xef): sprintf(t, "getbl"); break;
|
|
case16(0xf0): sprintf(t, "sm r%u", op0 & 15); break;
|
|
}
|
|
strcat(output, t);
|
|
}
|
|
|
|
auto SuperFX::disassemble_alt3(char* output) -> void {
|
|
char t[256] = "";
|
|
switch(op0) {
|
|
case (0x00): sprintf(t, "stop"); break;
|
|
case (0x01): sprintf(t, "nop"); break;
|
|
case (0x02): sprintf(t, "cache"); break;
|
|
case (0x03): sprintf(t, "lsr"); break;
|
|
case (0x04): sprintf(t, "rol"); break;
|
|
case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break;
|
|
case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break;
|
|
case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break;
|
|
case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break;
|
|
case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break;
|
|
case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break;
|
|
case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break;
|
|
case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break;
|
|
case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break;
|
|
case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break;
|
|
case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break;
|
|
case16(0x10): sprintf(t, "to r%u", op0 & 15); break;
|
|
case16(0x20): sprintf(t, "with r%u", op0 & 15); break;
|
|
case12(0x30): sprintf(t, "stb (r%u)", op0 & 15); break;
|
|
case (0x3c): sprintf(t, "loop"); break;
|
|
case (0x3d): sprintf(t, "alt1"); break;
|
|
case (0x3e): sprintf(t, "alt2"); break;
|
|
case (0x3f): sprintf(t, "alt3"); break;
|
|
case12(0x40): sprintf(t, "ldb (r%u)", op0 & 15); break;
|
|
case (0x4c): sprintf(t, "rpix"); break;
|
|
case (0x4d): sprintf(t, "swap"); break;
|
|
case (0x4e): sprintf(t, "cmode"); break;
|
|
case (0x4f): sprintf(t, "not"); break;
|
|
case16(0x50): sprintf(t, "adc #%u", op0 & 15); break;
|
|
case16(0x60): sprintf(t, "cmp r%u", op0 & 15); break;
|
|
case (0x70): sprintf(t, "merge"); break;
|
|
case15(0x71): sprintf(t, "bic #%u", op0 & 15); break;
|
|
case16(0x80): sprintf(t, "umult #%u", op0 & 15); break;
|
|
case (0x90): sprintf(t, "sbk"); break;
|
|
case4 (0x91): sprintf(t, "link #%u", op0 & 15); break;
|
|
case (0x95): sprintf(t, "sex"); break;
|
|
case (0x96): sprintf(t, "div2"); break;
|
|
case (0x97): sprintf(t, "ror"); break;
|
|
case6 (0x98): sprintf(t, "ljmp r%u", op0 & 15); break;
|
|
case (0x9e): sprintf(t, "lob"); break;
|
|
case (0x9f): sprintf(t, "lmult"); break;
|
|
case16(0xa0): sprintf(t, "lms r%u", op0 & 15); break;
|
|
case16(0xb0): sprintf(t, "from r%u", op0 & 15); break;
|
|
case (0xc0): sprintf(t, "hib"); break;
|
|
case15(0xc1): sprintf(t, "xor #%u", op0 & 15); break;
|
|
case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break;
|
|
case (0xdf): sprintf(t, "romb"); break;
|
|
case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break;
|
|
case (0xef): sprintf(t, "getbs"); break;
|
|
case16(0xf0): sprintf(t, "lm r%u", op0 & 15); break;
|
|
}
|
|
strcat(output, t);
|
|
}
|
|
|
|
#undef case4
|
|
#undef case6
|
|
#undef case12
|
|
#undef case15
|
|
#undef case16
|
|
#undef op0
|
|
#undef op1
|
|
#undef op2
|
|
|
|
#endif
|