1 #include "disassemble-gb.hpp"
2 #include "interface/disassembler.hpp"
3 #include "library/string.hpp"
4 #include "library/hex.hpp"
11 std::string
signdec(uint8_t v
, bool psign
= false);
12 std::string
signdec(uint8_t v
, bool psign
)
14 if(v
< 128) return (stringfmt() << (psign
? "+" : "") << (int)v
).str();
15 return (stringfmt() << (int)v
- 256).str();
18 uint16_t jraddr(uint16_t pc
, uint8_t lt
)
20 return pc
+ lt
+ 2 - ((lt
< 128) ? 0 : 256);
23 const char* instructions
[] = {
24 "NOP", "LD BC, %w", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,%b", "RCLA",
25 "LD (%W),SP", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,%b", "RRCA",
26 "STOP", "LD DE, %w", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,%b", "RLA",
27 "JR %R", "ADD HL,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,%b", "RRA",
28 "JR NZ,%R", "LD HL, %w", "LD (HL+),A", "INC HL", "INC H", "DEC H", "LD H,%b", "DAA",
29 "JR Z,%R", "ADD HL,HL", "LD A,(HL+)", "DEC HL", "INC L", "DEC L", "LD L,%b", "CPL",
30 "JR NC,%R", "LD SP, %w", "LD (HL-),A", "INC SP", "INC (HL)", "DEC (HL)", "LD (HL),%b", "SCF",
31 "JR Z,%R", "ADD HL,SP", "LD A,(HL-)", "DEC SP", "INC A", "DEC A", "LD A,%b", "CCF",
33 "LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,H", "LD B,L", "LD B,(HL)", "LD B,A",
34 "LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,H", "LD C,L", "LD C,(HL)", "LD C,A",
35 "LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,H", "LD D,L", "LD D,(HL)", "LD D,A",
36 "LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,H", "LD E,L", "LD E,(HL)", "LD E,A",
37 "LD H,B", "LD H,C", "LD H,D", "LD H,E", "LD H,H", "LD H,L", "LD H,(HL)", "LD H,A",
38 "LD L,B", "LD L,C", "LD L,D", "LD L,E", "LD L,H", "LD L,L", "LD L,(HL)", "LD L,A",
39 "LD (HL),B", "LD (HL),C", "LD (HL),D", "LD (HL),E", "LD (HL),H", "LD (HL),L", "HALT", "LD (HL),A",
40 "LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,H", "LD A,L", "LD A,(HL)", "LD A,A",
42 "ADD B", "ADD C", "ADD D", "ADD E", "ADD H", "ADD L", "ADD (HL)", "ADD A",
43 "ADC B", "ADC C", "ADC D", "ADC E", "ADC H", "ADC L", "ADC (HL)", "ADC A",
44 "SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB (HL)", "SUB A",
45 "SBC B", "SBC C", "SBC D", "SBC E", "SBC H", "SBC L", "SBC (HL)", "SBC A",
46 "AND B", "AND C", "AND D", "AND E", "AND H", "AND L", "AND (HL)", "AND A",
47 "XOR B", "XOR C", "XOR D", "XOR E", "XOR H", "XOR L", "XOR (HL)", "XOR A",
48 "OR B", "OR C", "OR D", "OR E", "OR H", "OR L", "OR (HL)", "OR A",
49 "CP B", "CP C", "CP D", "CP E", "CP H", "CP L", "CP (HL)", "CP A",
51 "RET NZ", "POP BC", "JP NZ,%w", "JP %w", "CALL NZ,%w", "PUSH BC", "ADD %b", "RST 0x00",
52 "RET Z", "RET", "JP Z,%w", "", "CALL Z,%w", "CALL %w", "ADC %b", "RST 0x08",
53 "RET NC", "POP DE", "JP NC,%w", "INVALID_D3", "CALL NC,%w", "PUSH DE", "SUB %b", "RST 0x10",
54 "RET C", "RETI", "JP C,%w", "INVALID_DB", "CALL C,%w", "INVALID_DD", "SBC %b", "RST 0x18",
55 "LDH (%B),A", "POP HL", "LD (C),A", "INVALID_E3", "INVALID_E4", "PUSH HL", "AND %b", "RST 0x20",
56 "ADD SP,%s", "JP (HL)", "LD (%W),A", "INVALID_EB", "INVALID_EC", "INVALID_ED", "XOR %b", "RST 0x28",
57 "LDH A, (%B)", "POP AF", "LD A,(C)", "DI", "INVALID_F4", "PUSH AF", "OR %b", "RST 0x30",
58 "LD HL,SP%S", "LD SP,HL", "LD A,(%W)", "EI", "INVALID_FC", "INVALID_FD", "CP %b", "RST 0x38",
62 std::string
disassemble_gb_opcode(uint16_t pc
, std::function
<uint8_t()> fetch
, int& addr
, uint16_t& opc
)
64 std::function
<uint16_t()> fetch2
= [&fetch
]() -> uint16_t {
70 uint8_t opcode
= fetch();
71 opc
= (uint16_t)opcode
<< 8;
74 static const char* regs
[] = {"B", "C", "D", "E", "H", "L", "(HL)", "A"};
77 uint8_t block
= opcode
>> 6;
78 uint8_t bit
= (opcode
>> 3) & 7;
79 uint8_t reg
= opcode
& 7;
83 case 0: return (stringfmt() << "RLC " << regs
[reg
]).str();
84 case 1: return (stringfmt() << "RRC " << regs
[reg
]).str();
85 case 2: return (stringfmt() << "RL " << regs
[reg
]).str();
86 case 3: return (stringfmt() << "RR " << regs
[reg
]).str();
87 case 4: return (stringfmt() << "SLA " << regs
[reg
]).str();
88 case 5: return (stringfmt() << "SRA " << regs
[reg
]).str();
89 case 6: return (stringfmt() << "SWAP " << regs
[reg
]).str();
90 case 7: return (stringfmt() << "SRL " << regs
[reg
]).str();
92 case 1: return (stringfmt() << "BIT " << (int)bit
<< "," << regs
[reg
]).str();
93 case 2: return (stringfmt() << "RES " << (int)bit
<< "," << regs
[reg
]).str();
94 case 3: return (stringfmt() << "SET " << (int)bit
<< "," << regs
[reg
]).str();
98 const char* ins
= instructions
[opcode
];
100 for(size_t i
= 0; ins
[i
]; i
++) {
106 o
<< "0x" << hex::to8(fetch());
109 o
<< "0x" << hex::to8(tmp
= fetch());
113 o
<< "0x" << hex::to16(fetch2());
116 o
<< "0x" << hex::to16(tmp
= fetch2());
120 o
<< signdec(tmp
= fetch(), false);
121 addr
= jraddr(pc
, tmp
);
124 o
<< signdec(tmp
= fetch(), false);
127 o
<< signdec(tmp
= fetch(), true);
138 struct gb_disassembler
: public disassembler
140 gb_disassembler() : disassembler("gb") {}
141 std::string
disassemble(uint64_t base
, std::function
<unsigned char()> fetchpc
)
145 return disassemble_gb_opcode(base
, fetchpc
, dummy
, dummy2
);