#ifdef SUPERFX_CPP //TODO: this belongs in processor/gsu void SuperFX::disassemble_opcode(char* output) { *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) void SuperFX::disassemble_alt0(char* output) { 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); } void SuperFX::disassemble_alt1(char* output) { 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); } void SuperFX::disassemble_alt2(char* output) { 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); } void SuperFX::disassemble_alt3(char* output) { 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