jevsnes.git / third-party / rust / jgenesis / backend / gb-core / src / sm83 / disassemble.rs
1pub fn instruction_str(opcode: u8) -> String {
2    match opcode {
3        0x00 => "NOP".into(),
4        0x01 => "LD BC, u16".into(),
5        0x02 => "LD (BC), A".into(),
6        0x03 => "INC BC".into(),
7        0x04 => "INC B".into(),
8        0x05 => "DEC B".into(),
9        0x06 => "LD B, u8".into(),
10        0x07 => "RLCA".into(),
11        0x08 => "LD (u16), SP".into(),
12        0x09 => "ADD HL, BC".into(),
13        0x0A => "LD A, (BC)".into(),
14        0x0B => "DEC BC".into(),
15        0x0C => "INC C".into(),
16        0x0D => "DEC C".into(),
17        0x0E => "LD C, u8".into(),
18        0x0F => "RRCA".into(),
19        0x10 => "STOP".into(),
20        0x11 => "LD DE, u16".into(),
21        0x12 => "LD (DE), A".into(),
22        0x13 => "INC DE".into(),
23        0x14 => "INC D".into(),
24        0x15 => "DEC D".into(),
25        0x16 => "LD D, u8".into(),
26        0x17 => "RLA".into(),
27        0x18 => "JR i8".into(),
28        0x19 => "ADD HL, DE".into(),
29        0x1A => "LD A, (DE)".into(),
30        0x1B => "DEC DE".into(),
31        0x1C => "INC E".into(),
32        0x1D => "DEC E".into(),
33        0x1E => "LD E, u8".into(),
34        0x1F => "RRA".into(),
35        0x20 => "JR NZ, i8".into(),
36        0x21 => "LD HL, u16".into(),
37        0x22 => "LD (HL+), A".into(),
38        0x23 => "INC HL".into(),
39        0x24 => "INC H".into(),
40        0x25 => "DEC H".into(),
41        0x26 => "LD H, u8".into(),
42        0x27 => "DAA".into(),
43        0x28 => "JR Z, i8".into(),
44        0x29 => "ADD HL, HL".into(),
45        0x2A => "LD A, (HL+)".into(),
46        0x2B => "DEC HL".into(),
47        0x2C => "INC L".into(),
48        0x2D => "DEC L".into(),
49        0x2E => "LD L, u8".into(),
50        0x2F => "CPL".into(),
51        0x30 => "JR NC, i8".into(),
52        0x31 => "LD SP, u16".into(),
53        0x32 => "LD (HL-), A".into(),
54        0x33 => "INC SP".into(),
55        0x34 => "INC (HL)".into(),
56        0x35 => "DEC (HL)".into(),
57        0x36 => "LD (HL), u8".into(),
58        0x37 => "SCF".into(),
59        0x38 => "JR C, i8".into(),
60        0x39 => "ADD HL, SP".into(),
61        0x3A => "LD A, (HL-)".into(),
62        0x3B => "DEC SP".into(),
63        0x3C => "INC A".into(),
64        0x3D => "DEC A".into(),
65        0x3E => "LD A, u8".into(),
66        0x3F => "CCF".into(),
67        0x40..=0x7F => {
68            if opcode == 0x76 {
69                "HALT".into()
70            } else {
71                let r = register_bits_to_str(opcode >> 3);
72                let rp = register_bits_to_str(opcode);
73                format!("LD {r}, {rp}")
74            }
75        }
76        0x80..=0x87 => format!("ADD A, {}", register_bits_to_str(opcode)),
77        0x88..=0x8F => format!("ADC A, {}", register_bits_to_str(opcode)),
78        0x90..=0x97 => format!("SUB A, {}", register_bits_to_str(opcode)),
79        0x98..=0x9F => format!("SBC A, {}", register_bits_to_str(opcode)),
80        0xA0..=0xA7 => format!("AND A, {}", register_bits_to_str(opcode)),
81        0xA8..=0xAF => format!("XOR A, {}", register_bits_to_str(opcode)),
82        0xB0..=0xB7 => format!("OR A, {}", register_bits_to_str(opcode)),
83        0xB8..=0xBF => format!("CP A, {}", register_bits_to_str(opcode)),
84        0xC0 => "RET NZ".into(),
85        0xC1 => "POP BC".into(),
86        0xC2 => "JP NZ, u16".into(),
87        0xC3 => "JP u16".into(),
88        0xC4 => "CALL NZ, u16".into(),
89        0xC5 => "PUSH BC".into(),
90        0xC6 => "ADD A, u8".into(),
91        0xC7 => "RST $00".into(),
92        0xC8 => "RET Z".into(),
93        0xC9 => "RET".into(),
94        0xCA => "JP Z, u16".into(),
95        0xCB => "(CB prefix)".into(),
96        0xCC => "CALL Z, u16".into(),
97        0xCD => "CALL u16".into(),
98        0xCE => "ADC A, u8".into(),
99        0xCF => "RST $08".into(),
100        0xD0 => "RET NC".into(),
101        0xD1 => "POP DE".into(),
102        0xD2 => "JP NC, u16".into(),
103        0xD4 => "CALL NC, u16".into(),
104        0xD5 => "PUSH DE".into(),
105        0xD6 => "SUB A, u8".into(),
106        0xD7 => "RST $10".into(),
107        0xD8 => "RET C".into(),
108        0xD9 => "RETI".into(),
109        0xDA => "JP C, u16".into(),
110        0xDC => "CALL C, u16".into(),
111        0xDE => "SBC A, u8".into(),
112        0xDF => "RST $18".into(),
113        0xE0 => "LDH (u8), A".into(),
114        0xE1 => "POP HL".into(),
115        0xE2 => "LD ($FF00+C), A".into(),
116        0xE5 => "PUSH HL".into(),
117        0xE6 => "AND A, u8".into(),
118        0xE7 => "RST $20".into(),
119        0xE8 => "ADD SP, i8".into(),
120        0xE9 => "JP HL".into(),
121        0xEA => "LD (u16), A".into(),
122        0xEE => "XOR A, u8".into(),
123        0xEF => "RST $28".into(),
124        0xF0 => "LDH A, (u8)".into(),
125        0xF1 => "POP AF".into(),
126        0xF2 => "LD A, ($FF00+C)".into(),
127        0xF3 => "DI".into(),
128        0xF5 => "PUSH AF".into(),
129        0xF6 => "OR A, u8".into(),
130        0xF7 => "RST $30".into(),
131        0xF8 => "LD HL, SP+i8".into(),
132        0xF9 => "LD SP, HL".into(),
133        0xFA => "LD A, (u16)".into(),
134        0xFB => "EI".into(),
135        0xFE => "CP A, u8".into(),
136        0xFF => "RST $38".into(),
137        _ => "(invalid opcode)".into(),
138    }
139}
140
141fn register_bits_to_str(register_bits: u8) -> &'static str {
142    match register_bits & 0x7 {
143        0x0 => "B",
144        0x1 => "C",
145        0x2 => "D",
146        0x3 => "E",
147        0x4 => "H",
148        0x5 => "L",
149        0x6 => "(HL)",
150        0x7 => "A",
151        _ => unreachable!("value & 0x7 is always <= 0x7"),
152    }
153}
154
155pub fn cb_instruction_str(opcode: u8) -> String {
156    match opcode {
157        0x00..=0x07 => format!("RLC {}", register_bits_to_str(opcode)),
158        0x08..=0x0F => format!("RRC {}", register_bits_to_str(opcode)),
159        0x10..=0x17 => format!("RL {}", register_bits_to_str(opcode)),
160        0x18..=0x1F => format!("RR {}", register_bits_to_str(opcode)),
161        0x20..=0x27 => format!("SLA {}", register_bits_to_str(opcode)),
162        0x28..=0x2F => format!("SRA {}", register_bits_to_str(opcode)),
163        0x30..=0x37 => format!("SWAP {}", register_bits_to_str(opcode)),
164        0x38..=0x3F => format!("SRL {}", register_bits_to_str(opcode)),
165        0x40..=0x7F => format!("BIT {}, {}", (opcode >> 3) & 7, register_bits_to_str(opcode)),
166        0x80..=0xBF => format!("RES {}, {}", (opcode >> 3) & 7, register_bits_to_str(opcode)),
167        0xC0..=0xFF => format!("SET {}, {}", (opcode >> 3) & 7, register_bits_to_str(opcode)),
168    }
169}