Path: blob/master/libsnes/bsnes/gameboy/cpu/core/disassembler.cpp
2 views
#ifdef CPU_CPP12string CPU::disassemble(uint16 pc) {3char output[80];4memset(output, ' ', sizeof output);5output[79] = 0;67string opcode = disassemble_opcode(pc);8string registers = {9" AF:", hex<4>(r[AF]),10" BC:", hex<4>(r[BC]),11" DE:", hex<4>(r[DE]),12" HL:", hex<4>(r[HL]),13" SP:", hex<4>(r[SP])14};1516memcpy(output + 0, hex<4>(pc), 4);17memcpy(output + 6, opcode, opcode.length());18memcpy(output + 23, registers, registers.length());19output[63] = 0;20return output;21}2223string CPU::disassemble_opcode(uint16 pc) {24uint8 opcode = bus.read(pc);25uint8 p0 = bus.read(pc + 1);26uint8 p1 = bus.read(pc + 2);27uint8 p2 = bus.read(pc + 3);2829switch(opcode) {30case 0x00: return { "nop" };31case 0x01: return { "ld bc,$", hex<2>(p1), hex<2>(p0) };32case 0x02: return { "ld (bc),a" };33case 0x03: return { "inc bc" };34case 0x04: return { "inc b" };35case 0x05: return { "dec b" };36case 0x06: return { "ld b,$", hex<2>(p0) };37case 0x07: return { "rlc a" };38case 0x08: return { "ld ($", hex<2>(p1), hex<2>(p0), "),sp" };39case 0x09: return { "add hl,bc" };40case 0x0a: return { "ld a,(bc)" };41case 0x0b: return { "dec bc" };42case 0x0c: return { "inc c" };43case 0x0d: return { "dec c" };44case 0x0e: return { "ld c,$", hex<2>(p0) };45case 0x0f: return { "rrc a" };46case 0x10: return { "stop" };47case 0x11: return { "ld de,$", hex<2>(p1), hex<2>(p0) };48case 0x12: return { "ld (de),a" };49case 0x13: return { "inc de" };50case 0x14: return { "inc d" };51case 0x15: return { "dec d" };52case 0x16: return { "ld d,$", hex<2>(p0) };53case 0x17: return { "rl a" };54case 0x18: return { "jr $", hex<4>(r[PC] + 2 + (int8)p0) };55case 0x19: return { "add hl,de" };56case 0x1a: return { "ld a,(de)" };57case 0x1b: return { "dec de" };58case 0x1c: return { "inc e" };59case 0x1d: return { "dec e" };60case 0x1e: return { "ld e,$", hex<2>(p0) };61case 0x1f: return { "rr a" };62case 0x20: return { "jr nz,$", hex<4>(r[PC] + 2 + (int8)p0) };63case 0x21: return { "ld hl,$", hex<2>(p1), hex<2>(p0) };64case 0x22: return { "ldi (hl),a" };65case 0x23: return { "inc hl" };66case 0x24: return { "inc h" };67case 0x25: return { "dec h" };68case 0x26: return { "ld h,$", hex<2>(p0) };69case 0x27: return { "daa" };70case 0x28: return { "jr z,$", hex<4>(r[PC] + 2 + (int8)p0) };71case 0x29: return { "add hl,hl" };72case 0x2a: return { "ldi a,(hl)" };73case 0x2b: return { "dec hl" };74case 0x2c: return { "inc l" };75case 0x2d: return { "dec l" };76case 0x2e: return { "ld l,$", hex<2>(p0) };77case 0x2f: return { "cpl" };78case 0x30: return { "jr nc,$", hex<4>(r[PC] + 2 + (int8)p0) };79case 0x31: return { "ld sp,$", hex<2>(p1), hex<2>(p0) };80case 0x32: return { "ldd (hl),a" };81case 0x33: return { "inc sp" };82case 0x34: return { "inc (hl)" };83case 0x35: return { "dec (hl)" };84case 0x36: return { "ld (hl),$", hex<2>(p0) };85case 0x37: return { "scf" };86case 0x38: return { "jr c,$", hex<4>(r[PC] + 2 + (int8)p0) };87case 0x39: return { "add hl,sp" };88case 0x3a: return { "ldd a,(hl)" };89case 0x3b: return { "dec sp" };90case 0x3c: return { "inc a" };91case 0x3d: return { "dec a" };92case 0x3e: return { "ld a,$", hex<2>(p0) };93case 0x3f: return { "ccf" };94case 0x40: return { "ld b,b" };95case 0x41: return { "ld b,c" };96case 0x42: return { "ld b,d" };97case 0x43: return { "ld b,e" };98case 0x44: return { "ld b,h" };99case 0x45: return { "ld b,l" };100case 0x46: return { "ld b,(hl)" };101case 0x47: return { "ld b,a" };102case 0x48: return { "ld c,b" };103case 0x49: return { "ld c,c" };104case 0x4a: return { "ld c,d" };105case 0x4b: return { "ld c,e" };106case 0x4c: return { "ld c,h" };107case 0x4d: return { "ld c,l" };108case 0x4e: return { "ld c,(hl)" };109case 0x4f: return { "ld c,a" };110case 0x50: return { "ld d,b" };111case 0x51: return { "ld d,c" };112case 0x52: return { "ld d,d" };113case 0x53: return { "ld d,e" };114case 0x54: return { "ld d,h" };115case 0x55: return { "ld d,l" };116case 0x56: return { "ld d,(hl)" };117case 0x57: return { "ld d,a" };118case 0x58: return { "ld e,b" };119case 0x59: return { "ld e,c" };120case 0x5a: return { "ld e,d" };121case 0x5b: return { "ld e,e" };122case 0x5c: return { "ld e,h" };123case 0x5d: return { "ld e,l" };124case 0x5e: return { "ld e,(hl)" };125case 0x5f: return { "ld e,a" };126case 0x60: return { "ld h,b" };127case 0x61: return { "ld h,c" };128case 0x62: return { "ld h,d" };129case 0x63: return { "ld h,e" };130case 0x64: return { "ld h,h" };131case 0x65: return { "ld h,l" };132case 0x66: return { "ld h,(hl)" };133case 0x67: return { "ld h,a" };134case 0x68: return { "ld l,b" };135case 0x69: return { "ld l,c" };136case 0x6a: return { "ld l,d" };137case 0x6b: return { "ld l,e" };138case 0x6c: return { "ld l,h" };139case 0x6d: return { "ld l,l" };140case 0x6e: return { "ld l,(hl)" };141case 0x6f: return { "ld l,a" };142case 0x70: return { "ld (hl),b" };143case 0x71: return { "ld (hl),c" };144case 0x72: return { "ld (hl),d" };145case 0x73: return { "ld (hl),e" };146case 0x74: return { "ld (hl),h" };147case 0x75: return { "ld (hl),l" };148case 0x76: return { "halt" };149case 0x77: return { "ld (hl),a" };150case 0x78: return { "ld a,b" };151case 0x79: return { "ld a,c" };152case 0x7a: return { "ld a,d" };153case 0x7b: return { "ld a,e" };154case 0x7c: return { "ld a,h" };155case 0x7d: return { "ld a,l" };156case 0x7e: return { "ld a,(hl)" };157case 0x7f: return { "ld a,a" };158case 0x80: return { "add a,b" };159case 0x81: return { "add a,c" };160case 0x82: return { "add a,d" };161case 0x83: return { "add a,e" };162case 0x84: return { "add a,h" };163case 0x85: return { "add a,l" };164case 0x86: return { "add a,(hl)" };165case 0x87: return { "add a,a" };166case 0x88: return { "adc a,b" };167case 0x89: return { "adc a,c" };168case 0x8a: return { "adc a,d" };169case 0x8b: return { "adc a,e" };170case 0x8c: return { "adc a,h" };171case 0x8d: return { "adc a,l" };172case 0x8e: return { "adc a,(hl)" };173case 0x8f: return { "adc a,a" };174case 0x90: return { "sub a,b" };175case 0x91: return { "sub a,c" };176case 0x92: return { "sub a,d" };177case 0x93: return { "sub a,e" };178case 0x94: return { "sub a,h" };179case 0x95: return { "sub a,l" };180case 0x96: return { "sub a,(hl)" };181case 0x97: return { "sub a,a" };182case 0x98: return { "sbc a,b" };183case 0x99: return { "sbc a,c" };184case 0x9a: return { "sbc a,d" };185case 0x9b: return { "sbc a,e" };186case 0x9c: return { "sbc a,h" };187case 0x9d: return { "sbc a,l" };188case 0x9e: return { "sbc a,(hl)" };189case 0x9f: return { "sbc a,a" };190case 0xa0: return { "and a,b" };191case 0xa1: return { "and a,c" };192case 0xa2: return { "and a,d" };193case 0xa3: return { "and a,e" };194case 0xa4: return { "and a,h" };195case 0xa5: return { "and a,l" };196case 0xa6: return { "and a,(hl)" };197case 0xa7: return { "and a,a" };198case 0xa8: return { "xor a,b" };199case 0xa9: return { "xor a,c" };200case 0xaa: return { "xor a,d" };201case 0xab: return { "xor a,e" };202case 0xac: return { "xor a,h" };203case 0xad: return { "xor a,l" };204case 0xae: return { "xor a,(hl)" };205case 0xaf: return { "xor a,a" };206case 0xb0: return { "or a,b" };207case 0xb1: return { "or a,c" };208case 0xb2: return { "or a,d" };209case 0xb3: return { "or a,e" };210case 0xb4: return { "or a,h" };211case 0xb5: return { "or a,l" };212case 0xb6: return { "or a,(hl)" };213case 0xb7: return { "or a,a" };214case 0xb8: return { "cp a,b" };215case 0xb9: return { "cp a,c" };216case 0xba: return { "cp a,d" };217case 0xbb: return { "cp a,e" };218case 0xbc: return { "cp a,h" };219case 0xbd: return { "cp a,l" };220case 0xbe: return { "cp a,(hl)" };221case 0xbf: return { "cp a,a" };222case 0xc0: return { "ret nz" };223case 0xc1: return { "pop bc" };224case 0xc2: return { "jp nz,$", hex<2>(p1), hex<2>(p0) };225case 0xc3: return { "jp $", hex<2>(p1), hex<2>(p0) };226case 0xc4: return { "call nz,$", hex<2>(p1), hex<2>(p0) };227case 0xc5: return { "push bc" };228case 0xc6: return { "add a,$", hex<2>(p0) };229case 0xc7: return { "rst $0000" };230case 0xc8: return { "ret z" };231case 0xc9: return { "ret" };232case 0xca: return { "jp z,$", hex<2>(p1), hex<2>(p0) };233case 0xcb: return disassemble_opcode_cb(pc + 1);234case 0xcc: return { "call z,$", hex<2>(p1), hex<2>(p0) };235case 0xcd: return { "call $", hex<2>(p1), hex<2>(p0) };236case 0xce: return { "adc a,$", hex<2>(p0) };237case 0xcf: return { "rst $0008" };238case 0xd0: return { "ret nc" };239case 0xd1: return { "pop de" };240case 0xd2: return { "jp nc,$", hex<2>(p1), hex<2>(p0) };241case 0xd3: return { "xx" };242case 0xd4: return { "call nc,$", hex<2>(p1), hex<2>(p0) };243case 0xd5: return { "push de" };244case 0xd6: return { "sub a,$", hex<2>(p0) };245case 0xd7: return { "rst $0010" };246case 0xd8: return { "ret c" };247case 0xd9: return { "reti" };248case 0xda: return { "jp c,$", hex<2>(p1), hex<2>(p0) };249case 0xdb: return { "xx" };250case 0xdc: return { "call c,$", hex<2>(p1), hex<2>(p0) };251case 0xdd: return { "xx" };252case 0xde: return { "sbc a,$", hex<2>(p0) };253case 0xdf: return { "rst $0018" };254case 0xe0: return { "ld ($ff", hex<2>(p0), "),a" };255case 0xe1: return { "pop hl" };256case 0xe2: return { "ld ($ff00+c),a" };257case 0xe3: return { "xx" };258case 0xe4: return { "xx" };259case 0xe5: return { "push hl" };260case 0xe6: return { "and a,$", hex<2>(p0) };261case 0xe7: return { "rst $0020" };262case 0xe8: return { "add sp,$", hex<4>((int8)p0) };263case 0xe9: return { "jp hl" };264case 0xea: return { "ld ($", hex<2>(p1), hex<2>(p0), "),a" };265case 0xeb: return { "xx" };266case 0xec: return { "xx" };267case 0xed: return { "xx" };268case 0xee: return { "xor a,$", hex<2>(p0) };269case 0xef: return { "rst $0028" };270case 0xf0: return { "ld a,($ff", hex<2>(p0), ")" };271case 0xf1: return { "pop af" };272case 0xf2: return { "ld a,($ff00+c)" };273case 0xf3: return { "di" };274case 0xf4: return { "xx" };275case 0xf5: return { "push af" };276case 0xf6: return { "or a,$", hex<2>(p0) };277case 0xf7: return { "rst $0030" };278case 0xf8: return { "ld hl,sp+$", hex<4>((int8)p0) };279case 0xf9: return { "ld sp,hl" };280case 0xfa: return { "ld a,($", hex<2>(p1), hex<2>(p0), ")" };281case 0xfb: return { "ei" };282case 0xfc: return { "xx" };283case 0xfd: return { "xx" };284case 0xfe: return { "cp a,$", hex<2>(p0) };285case 0xff: return { "rst $0038" };286}287288return "";289}290291string CPU::disassemble_opcode_cb(uint16 pc) {292uint8 opcode = bus.read(pc);293uint8 p0 = bus.read(pc + 1);294uint8 p1 = bus.read(pc + 2);295uint8 p2 = bus.read(pc + 3);296297switch(opcode) {298case 0x00: return { "rlc b" };299case 0x01: return { "rlc c" };300case 0x02: return { "rlc d" };301case 0x03: return { "rlc e" };302case 0x04: return { "rlc h" };303case 0x05: return { "rlc l" };304case 0x06: return { "rlc (hl)" };305case 0x07: return { "rlc a" };306case 0x08: return { "rrc b" };307case 0x09: return { "rrc c" };308case 0x0a: return { "rrc d" };309case 0x0b: return { "rrc e" };310case 0x0c: return { "rrc h" };311case 0x0d: return { "rrc l" };312case 0x0e: return { "rrc (hl)" };313case 0x0f: return { "rrc a" };314case 0x10: return { "rl b" };315case 0x11: return { "rl c" };316case 0x12: return { "rl d" };317case 0x13: return { "rl e" };318case 0x14: return { "rl h" };319case 0x15: return { "rl l" };320case 0x16: return { "rl (hl)" };321case 0x17: return { "rl a" };322case 0x18: return { "rr b" };323case 0x19: return { "rr c" };324case 0x1a: return { "rr d" };325case 0x1b: return { "rr e" };326case 0x1c: return { "rr h" };327case 0x1d: return { "rr l" };328case 0x1e: return { "rr (hl)" };329case 0x1f: return { "rr a" };330case 0x20: return { "sla b" };331case 0x21: return { "sla c" };332case 0x22: return { "sla d" };333case 0x23: return { "sla e" };334case 0x24: return { "sla h" };335case 0x25: return { "sla l" };336case 0x26: return { "sla (hl)" };337case 0x27: return { "sla a" };338case 0x28: return { "sra b" };339case 0x29: return { "sra c" };340case 0x2a: return { "sra d" };341case 0x2b: return { "sra e" };342case 0x2c: return { "sra h" };343case 0x2d: return { "sra l" };344case 0x2e: return { "sra (hl)" };345case 0x2f: return { "sra a" };346case 0x30: return { "swap b" };347case 0x31: return { "swap c" };348case 0x32: return { "swap d" };349case 0x33: return { "swap e" };350case 0x34: return { "swap h" };351case 0x35: return { "swap l" };352case 0x36: return { "swap (hl)" };353case 0x37: return { "swap a" };354case 0x38: return { "srl b" };355case 0x39: return { "srl c" };356case 0x3a: return { "srl d" };357case 0x3b: return { "srl e" };358case 0x3c: return { "srl h" };359case 0x3d: return { "srl l" };360case 0x3e: return { "srl (hl)" };361case 0x3f: return { "srl a" };362case 0x40: return { "bit 0,b" };363case 0x41: return { "bit 0,c" };364case 0x42: return { "bit 0,d" };365case 0x43: return { "bit 0,e" };366case 0x44: return { "bit 0,h" };367case 0x45: return { "bit 0,l" };368case 0x46: return { "bit 0,(hl)" };369case 0x47: return { "bit 0,a" };370case 0x48: return { "bit 1,b" };371case 0x49: return { "bit 1,c" };372case 0x4a: return { "bit 1,d" };373case 0x4b: return { "bit 1,e" };374case 0x4c: return { "bit 1,h" };375case 0x4d: return { "bit 1,l" };376case 0x4e: return { "bit 1,(hl)" };377case 0x4f: return { "bit 1,a" };378case 0x50: return { "bit 2,b" };379case 0x51: return { "bit 2,c" };380case 0x52: return { "bit 2,d" };381case 0x53: return { "bit 2,e" };382case 0x54: return { "bit 2,h" };383case 0x55: return { "bit 2,l" };384case 0x56: return { "bit 2,(hl)" };385case 0x57: return { "bit 2,a" };386case 0x58: return { "bit 3,b" };387case 0x59: return { "bit 3,c" };388case 0x5a: return { "bit 3,d" };389case 0x5b: return { "bit 3,e" };390case 0x5c: return { "bit 3,h" };391case 0x5d: return { "bit 3,l" };392case 0x5e: return { "bit 3,(hl)" };393case 0x5f: return { "bit 3,a" };394case 0x60: return { "bit 4,b" };395case 0x61: return { "bit 4,c" };396case 0x62: return { "bit 4,d" };397case 0x63: return { "bit 4,e" };398case 0x64: return { "bit 4,h" };399case 0x65: return { "bit 4,l" };400case 0x66: return { "bit 4,(hl)" };401case 0x67: return { "bit 4,a" };402case 0x68: return { "bit 5,b" };403case 0x69: return { "bit 5,c" };404case 0x6a: return { "bit 5,d" };405case 0x6b: return { "bit 5,e" };406case 0x6c: return { "bit 5,h" };407case 0x6d: return { "bit 5,l" };408case 0x6e: return { "bit 5,(hl)" };409case 0x6f: return { "bit 5,a" };410case 0x70: return { "bit 6,b" };411case 0x71: return { "bit 6,c" };412case 0x72: return { "bit 6,d" };413case 0x73: return { "bit 6,e" };414case 0x74: return { "bit 6,h" };415case 0x75: return { "bit 6,l" };416case 0x76: return { "bit 6,(hl)" };417case 0x77: return { "bit 6,a" };418case 0x78: return { "bit 7,b" };419case 0x79: return { "bit 7,c" };420case 0x7a: return { "bit 7,d" };421case 0x7b: return { "bit 7,e" };422case 0x7c: return { "bit 7,h" };423case 0x7d: return { "bit 7,l" };424case 0x7e: return { "bit 7,(hl)" };425case 0x7f: return { "bit 7,a" };426case 0x80: return { "res 0,b" };427case 0x81: return { "res 0,c" };428case 0x82: return { "res 0,d" };429case 0x83: return { "res 0,e" };430case 0x84: return { "res 0,h" };431case 0x85: return { "res 0,l" };432case 0x86: return { "res 0,(hl)" };433case 0x87: return { "res 0,a" };434case 0x88: return { "res 1,b" };435case 0x89: return { "res 1,c" };436case 0x8a: return { "res 1,d" };437case 0x8b: return { "res 1,e" };438case 0x8c: return { "res 1,h" };439case 0x8d: return { "res 1,l" };440case 0x8e: return { "res 1,(hl)" };441case 0x8f: return { "res 1,a" };442case 0x90: return { "res 2,b" };443case 0x91: return { "res 2,c" };444case 0x92: return { "res 2,d" };445case 0x93: return { "res 2,e" };446case 0x94: return { "res 2,h" };447case 0x95: return { "res 2,l" };448case 0x96: return { "res 2,(hl)" };449case 0x97: return { "res 2,a" };450case 0x98: return { "res 3,b" };451case 0x99: return { "res 3,c" };452case 0x9a: return { "res 3,d" };453case 0x9b: return { "res 3,e" };454case 0x9c: return { "res 3,h" };455case 0x9d: return { "res 3,l" };456case 0x9e: return { "res 3,(hl)" };457case 0x9f: return { "res 3,a" };458case 0xa0: return { "res 4,b" };459case 0xa1: return { "res 4,c" };460case 0xa2: return { "res 4,d" };461case 0xa3: return { "res 4,e" };462case 0xa4: return { "res 4,h" };463case 0xa5: return { "res 4,l" };464case 0xa6: return { "res 4,(hl)" };465case 0xa7: return { "res 4,a" };466case 0xa8: return { "res 5,b" };467case 0xa9: return { "res 5,c" };468case 0xaa: return { "res 5,d" };469case 0xab: return { "res 5,e" };470case 0xac: return { "res 5,h" };471case 0xad: return { "res 5,l" };472case 0xae: return { "res 5,(hl)" };473case 0xaf: return { "res 5,a" };474case 0xb0: return { "res 6,b" };475case 0xb1: return { "res 6,c" };476case 0xb2: return { "res 6,d" };477case 0xb3: return { "res 6,e" };478case 0xb4: return { "res 6,h" };479case 0xb5: return { "res 6,l" };480case 0xb6: return { "res 6,(hl)" };481case 0xb7: return { "res 6,a" };482case 0xb8: return { "res 7,b" };483case 0xb9: return { "res 7,c" };484case 0xba: return { "res 7,d" };485case 0xbb: return { "res 7,e" };486case 0xbc: return { "res 7,h" };487case 0xbd: return { "res 7,l" };488case 0xbe: return { "res 7,(hl)" };489case 0xbf: return { "res 7,a" };490case 0xc0: return { "set 0,b" };491case 0xc1: return { "set 0,c" };492case 0xc2: return { "set 0,d" };493case 0xc3: return { "set 0,e" };494case 0xc4: return { "set 0,h" };495case 0xc5: return { "set 0,l" };496case 0xc6: return { "set 0,(hl)" };497case 0xc7: return { "set 0,a" };498case 0xc8: return { "set 1,b" };499case 0xc9: return { "set 1,c" };500case 0xca: return { "set 1,d" };501case 0xcb: return { "set 1,e" };502case 0xcc: return { "set 1,h" };503case 0xcd: return { "set 1,l" };504case 0xce: return { "set 1,(hl)" };505case 0xcf: return { "set 1,a" };506case 0xd0: return { "set 2,b" };507case 0xd1: return { "set 2,c" };508case 0xd2: return { "set 2,d" };509case 0xd3: return { "set 2,e" };510case 0xd4: return { "set 2,h" };511case 0xd5: return { "set 2,l" };512case 0xd6: return { "set 2,(hl)" };513case 0xd7: return { "set 2,a" };514case 0xd8: return { "set 3,b" };515case 0xd9: return { "set 3,c" };516case 0xda: return { "set 3,d" };517case 0xdb: return { "set 3,e" };518case 0xdc: return { "set 3,h" };519case 0xdd: return { "set 3,l" };520case 0xde: return { "set 3,(hl)" };521case 0xdf: return { "set 3,a" };522case 0xe0: return { "set 4,b" };523case 0xe1: return { "set 4,c" };524case 0xe2: return { "set 4,d" };525case 0xe3: return { "set 4,e" };526case 0xe4: return { "set 4,h" };527case 0xe5: return { "set 4,l" };528case 0xe6: return { "set 4,(hl)" };529case 0xe7: return { "set 4,a" };530case 0xe8: return { "set 5,b" };531case 0xe9: return { "set 5,c" };532case 0xea: return { "set 5,d" };533case 0xeb: return { "set 5,e" };534case 0xec: return { "set 5,h" };535case 0xed: return { "set 5,l" };536case 0xee: return { "set 5,(hl)" };537case 0xef: return { "set 5,a" };538case 0xf0: return { "set 6,b" };539case 0xf1: return { "set 6,c" };540case 0xf2: return { "set 6,d" };541case 0xf3: return { "set 6,e" };542case 0xf4: return { "set 6,h" };543case 0xf5: return { "set 6,l" };544case 0xf6: return { "set 6,(hl)" };545case 0xf7: return { "set 6,a" };546case 0xf8: return { "set 7,b" };547case 0xf9: return { "set 7,c" };548case 0xfa: return { "set 7,d" };549case 0xfb: return { "set 7,e" };550case 0xfc: return { "set 7,h" };551case 0xfd: return { "set 7,l" };552case 0xfe: return { "set 7,(hl)" };553case 0xff: return { "set 7,a" };554}555556return "";557}558559#endif560561562