bsnes/processor/upd96050/disassembler.cpp

193 lines
6.5 KiB
C++

auto uPD96050::disassemble(uint14 ip) -> string {
string output = {hex(ip, 4L), " "};
uint24 opcode = programROM[ip];
uint2 type = opcode >> 22;
if(type == 0 || type == 1) { //OP,RT
uint2 pselect = opcode >> 20;
uint4 alu = opcode >> 16;
uint1 asl = opcode >> 15;
uint2 dpl = opcode >> 13;
uint4 dphm = opcode >> 9;
uint1 rpdcr = opcode >> 8;
uint4 src = opcode >> 4;
uint4 dst = opcode >> 0;
switch(alu) {
case 0: output.append("nop "); break;
case 1: output.append("or "); break;
case 2: output.append("and "); break;
case 3: output.append("xor "); break;
case 4: output.append("sub "); break;
case 5: output.append("add "); break;
case 6: output.append("sbb "); break;
case 7: output.append("adc "); break;
case 8: output.append("dec "); break;
case 9: output.append("inc "); break;
case 10: output.append("cmp "); break;
case 11: output.append("shr1 "); break;
case 12: output.append("shl1 "); break;
case 13: output.append("shl2 "); break;
case 14: output.append("shl4 "); break;
case 15: output.append("xchg "); break;
}
if(alu < 8) {
switch(pselect) {
case 0: output.append("ram,"); break;
case 1: output.append("idb,"); break;
case 2: output.append("m," ); break;
case 3: output.append("n," ); break;
}
}
switch(asl) {
case 0: output.append("a"); break;
case 1: output.append("b"); break;
}
output.append("\n mov ");
switch(src) {
case 0: output.append("trb," ); break;
case 1: output.append("a," ); break;
case 2: output.append("b," ); break;
case 3: output.append("tr," ); break;
case 4: output.append("dp," ); break;
case 5: output.append("rp," ); break;
case 6: output.append("ro," ); break;
case 7: output.append("sgn," ); break;
case 8: output.append("dr," ); break;
case 9: output.append("drnf,"); break;
case 10: output.append("sr," ); break;
case 11: output.append("sim," ); break;
case 12: output.append("sil," ); break;
case 13: output.append("k," ); break;
case 14: output.append("l," ); break;
case 15: output.append("mem," ); break;
}
switch(dst) {
case 0: output.append("non"); break;
case 1: output.append("a" ); break;
case 2: output.append("b" ); break;
case 3: output.append("tr" ); break;
case 4: output.append("dp" ); break;
case 5: output.append("rp" ); break;
case 6: output.append("dr" ); break;
case 7: output.append("sr" ); break;
case 8: output.append("sol"); break;
case 9: output.append("som"); break;
case 10: output.append("k" ); break;
case 11: output.append("klr"); break;
case 12: output.append("klm"); break;
case 13: output.append("l" ); break;
case 14: output.append("trb"); break;
case 15: output.append("mem"); break;
}
if(dpl) {
switch(dpl) {
case 0: output.append("\n dpnop"); break;
case 1: output.append("\n dpinc"); break;
case 2: output.append("\n dpdec"); break;
case 3: output.append("\n dpclr"); break;
}
}
if(dphm) {
output.append("\n m", hex(dphm, 1L));
}
if(rpdcr == 1) {
output.append("\n rpdec");
}
if(type == 1) {
output.append("\n ret");
}
}
if(type == 2) { //JP
uint9 brch = opcode >> 13;
uint11 na = opcode >> 2;
uint8 bank = opcode >> 0;
uint14 jp = (regs.pc & 0x2000) | (bank << 11) | (na << 0);
switch(brch) {
case 0x000: output.append("jmpso "); jp = 0; break;
case 0x080: output.append("jnca "); break;
case 0x082: output.append("jca "); break;
case 0x084: output.append("jncb "); break;
case 0x086: output.append("jcb "); break;
case 0x088: output.append("jnza "); break;
case 0x08a: output.append("jza "); break;
case 0x08c: output.append("jnzb "); break;
case 0x08e: output.append("jzb "); break;
case 0x090: output.append("jnova0 "); break;
case 0x092: output.append("jova0 "); break;
case 0x094: output.append("jnovb0 "); break;
case 0x096: output.append("jovb0 "); break;
case 0x098: output.append("jnova1 "); break;
case 0x09a: output.append("jova1 "); break;
case 0x09c: output.append("jnovb1 "); break;
case 0x09e: output.append("jovb1 "); break;
case 0x0a0: output.append("jnsa0 "); break;
case 0x0a2: output.append("jsa0 "); break;
case 0x0a4: output.append("jnsb0 "); break;
case 0x0a6: output.append("jsb0 "); break;
case 0x0a8: output.append("jnsa1 "); break;
case 0x0aa: output.append("jsa1 "); break;
case 0x0ac: output.append("jnsb1 "); break;
case 0x0ae: output.append("jsb1 "); break;
case 0x0b0: output.append("jdpl0 "); break;
case 0x0b1: output.append("jdpln0 "); break;
case 0x0b2: output.append("jdplf "); break;
case 0x0b3: output.append("jdplnf "); break;
case 0x0b4: output.append("jnsiak "); break;
case 0x0b6: output.append("jsiak "); break;
case 0x0b8: output.append("jnsoak "); break;
case 0x0ba: output.append("jsoak "); break;
case 0x0bc: output.append("jnrqm "); break;
case 0x0be: output.append("jrqm "); break;
case 0x100: output.append("ljmp "); jp &= ~0x2000; break;
case 0x101: output.append("hjmp "); jp |= 0x2000; break;
case 0x140: output.append("lcall "); jp &= ~0x2000; break;
case 0x141: output.append("hcall "); jp |= 0x2000; break;
default: output.append("?????? "); break;
}
output.append("$", hex(jp, 4L));
}
if(type == 3) { //LD
output.append("ld ");
uint16 id = opcode >> 6;
uint4 dst = opcode >> 0;
output.append("$", hex(id, 4L), ",");
switch(dst) {
case 0: output.append("non"); break;
case 1: output.append("a" ); break;
case 2: output.append("b" ); break;
case 3: output.append("tr" ); break;
case 4: output.append("dp" ); break;
case 5: output.append("rp" ); break;
case 6: output.append("dr" ); break;
case 7: output.append("sr" ); break;
case 8: output.append("sol"); break;
case 9: output.append("som"); break;
case 10: output.append("k" ); break;
case 11: output.append("klr"); break;
case 12: output.append("klm"); break;
case 13: output.append("l" ); break;
case 14: output.append("trb"); break;
case 15: output.append("mem"); break;
}
}
return output;
}