src/lr35902/decoder.c (view raw)
1/* Copyright (c) 2013-2017 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/lr35902/decoder.h>
7
8#include <mgba/internal/lr35902/emitter-lr35902.h>
9#include <mgba/internal/lr35902/lr35902.h>
10
11typedef size_t (*LR35902Decoder)(uint8_t opcode, struct LR35902InstructionInfo* info);
12
13#define DEFINE_DECODER_LR35902(NAME, BODY) \
14 static size_t _LR35902Decode ## NAME (uint8_t opcode, struct LR35902InstructionInfo* info) { \
15 UNUSED(opcode); \
16 info->mnemonic = LR35902_MN_RST; \
17 BODY; \
18 return 0; \
19 }
20
21DEFINE_DECODER_LR35902(NOP, info->mnemonic = LR35902_MN_NOP;)
22
23#define DEFINE_LD_DECODER_LR35902_NOHL(NAME) \
24 DEFINE_DECODER_LR35902(LD ## NAME ## _A, \
25 info->mnemonic = LR35902_MN_LD; \
26 info->op1.reg = LR35902_REG_ ## NAME; \
27 info->op2.reg = LR35902_REG_A) \
28 DEFINE_DECODER_LR35902(LD ## NAME ## _B, \
29 info->mnemonic = LR35902_MN_LD; \
30 info->op1.reg = LR35902_REG_ ## NAME; \
31 info->op2.reg = LR35902_REG_B) \
32 DEFINE_DECODER_LR35902(LD ## NAME ## _C, \
33 info->mnemonic = LR35902_MN_LD; \
34 info->op1.reg = LR35902_REG_ ## NAME; \
35 info->op2.reg = LR35902_REG_C) \
36 DEFINE_DECODER_LR35902(LD ## NAME ## _D, \
37 info->mnemonic = LR35902_MN_LD; \
38 info->op1.reg = LR35902_REG_ ## NAME; \
39 info->op2.reg = LR35902_REG_D) \
40 DEFINE_DECODER_LR35902(LD ## NAME ## _E, \
41 info->mnemonic = LR35902_MN_LD; \
42 info->op1.reg = LR35902_REG_ ## NAME; \
43 info->op2.reg = LR35902_REG_E) \
44 DEFINE_DECODER_LR35902(LD ## NAME ## _H, \
45 info->mnemonic = LR35902_MN_LD; \
46 info->op1.reg = LR35902_REG_ ## NAME; \
47 info->op2.reg = LR35902_REG_H) \
48 DEFINE_DECODER_LR35902(LD ## NAME ## _L, \
49 info->mnemonic = LR35902_MN_LD; \
50 info->op1.reg = LR35902_REG_ ## NAME; \
51 info->op2.reg = LR35902_REG_L)
52
53#define DEFINE_LD_DECODER_LR35902_MEM(NAME, REG) \
54 DEFINE_DECODER_LR35902(LD ## NAME ## _ ## REG, info->mnemonic = LR35902_MN_LD; \
55 info->op1.reg = LR35902_REG_ ## NAME; \
56 info->op2.reg = LR35902_REG_ ## REG; \
57 info->op2.flags = LR35902_OP_FLAG_MEMORY;)
58
59#define DEFINE_LD_DECODER_LR35902_MEM_2(NAME, REG) \
60 DEFINE_DECODER_LR35902(LD ## REG ## _ ## NAME, info->mnemonic = LR35902_MN_LD; \
61 info->op1.reg = LR35902_REG_ ## REG; \
62 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
63 info->op2.reg = LR35902_REG_ ## NAME;)
64
65#define DEFINE_LD_DECODER_LR35902(NAME) \
66 DEFINE_LD_DECODER_LR35902_MEM(NAME, HL) \
67 DEFINE_LD_DECODER_LR35902_MEM_2(NAME, HL) \
68 DEFINE_DECODER_LR35902(LD ## NAME ## _, info->mnemonic = LR35902_MN_LD; \
69 info->op1.reg = LR35902_REG_ ## NAME; \
70 return 1;) \
71 DEFINE_LD_DECODER_LR35902_NOHL(NAME)
72
73#define DEFINE_LD_2_DECODER_LR35902(NAME) \
74 DEFINE_DECODER_LR35902(LD ## NAME, info->mnemonic = LR35902_MN_LD; \
75 info->op1.reg = LR35902_REG_ ## NAME; \
76 return 2;)
77
78DEFINE_LD_DECODER_LR35902(B);
79DEFINE_LD_DECODER_LR35902(C);
80DEFINE_LD_DECODER_LR35902(D);
81DEFINE_LD_DECODER_LR35902(E);
82DEFINE_LD_DECODER_LR35902(H);
83DEFINE_LD_DECODER_LR35902(L);
84DEFINE_LD_DECODER_LR35902(A);
85DEFINE_LD_DECODER_LR35902_MEM(A, BC);
86DEFINE_LD_DECODER_LR35902_MEM(A, DE);
87
88DEFINE_LD_2_DECODER_LR35902(BC);
89DEFINE_LD_2_DECODER_LR35902(DE);
90DEFINE_LD_2_DECODER_LR35902(HL);
91DEFINE_LD_2_DECODER_LR35902(SP);
92
93DEFINE_DECODER_LR35902(LDHL_, \
94 info->mnemonic = LR35902_MN_LD; \
95 info->op1.reg = LR35902_REG_HL; \
96 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
97 return 1;)
98
99DEFINE_DECODER_LR35902(LDHL_SP, \
100 info->mnemonic = LR35902_MN_LD; \
101 info->op1.reg = LR35902_REG_HL; \
102 info->op2.reg = LR35902_REG_SP; \
103 return 1;)
104
105DEFINE_DECODER_LR35902(LDSP_HL, \
106 info->mnemonic = LR35902_MN_LD; \
107 info->op1.reg = LR35902_REG_SP; \
108 info->op2.reg = LR35902_REG_HL;)
109
110DEFINE_DECODER_LR35902(LDAIOC, \
111 info->mnemonic = LR35902_MN_LD; \
112 info->op1.reg = LR35902_REG_A; \
113 info->op2.reg = LR35902_REG_C; \
114 info->op2.immediate = 0xFF00; \
115 info->op2.flags = LR35902_OP_FLAG_MEMORY;)
116
117DEFINE_DECODER_LR35902(LDIOCA, \
118 info->mnemonic = LR35902_MN_LD; \
119 info->op1.reg = LR35902_REG_C; \
120 info->op1.immediate = 0xFF00; \
121 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
122 info->op2.reg = LR35902_REG_A;)
123
124DEFINE_DECODER_LR35902(LDAIO, \
125 info->mnemonic = LR35902_MN_LD; \
126 info->op1.reg = LR35902_REG_A; \
127 info->op2.immediate = 0xFF00; \
128 info->op2.flags = LR35902_OP_FLAG_MEMORY; \
129 return 1;)
130
131DEFINE_DECODER_LR35902(LDIOA, \
132 info->mnemonic = LR35902_MN_LD; \
133 info->op1.immediate = 0xFF00; \
134 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
135 info->op2.reg = LR35902_REG_A; \
136 return 1;)
137
138#define DEFINE_ALU_DECODER_LR35902_NOHL(NAME) \
139 DEFINE_DECODER_LR35902(NAME ## A, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A) \
140 DEFINE_DECODER_LR35902(NAME ## B, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_B) \
141 DEFINE_DECODER_LR35902(NAME ## C, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_C) \
142 DEFINE_DECODER_LR35902(NAME ## D, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_D) \
143 DEFINE_DECODER_LR35902(NAME ## E, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_E) \
144 DEFINE_DECODER_LR35902(NAME ## H, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_H) \
145 DEFINE_DECODER_LR35902(NAME ## L, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_L)
146
147#define DEFINE_ALU_DECODER_LR35902_MEM(NAME, REG) \
148 DEFINE_DECODER_LR35902(NAME ## REG, info->mnemonic = LR35902_MN_ ## NAME; \
149 info->op1.reg = LR35902_REG_HL; \
150 info->op1.flags = LR35902_OP_FLAG_MEMORY;)
151
152#define DEFINE_ALU_DECODER_LR35902(NAME) \
153 DEFINE_ALU_DECODER_LR35902_MEM(NAME, HL) \
154 DEFINE_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME; \
155 info->op1.reg = LR35902_REG_A; \
156 info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
157 return 1;) \
158 DEFINE_ALU_DECODER_LR35902_NOHL(NAME)
159
160DEFINE_ALU_DECODER_LR35902_NOHL(INC);
161DEFINE_ALU_DECODER_LR35902_NOHL(DEC);
162DEFINE_ALU_DECODER_LR35902(AND);
163DEFINE_ALU_DECODER_LR35902(XOR);
164DEFINE_ALU_DECODER_LR35902(OR);
165DEFINE_ALU_DECODER_LR35902(CP);
166DEFINE_ALU_DECODER_LR35902(ADD);
167DEFINE_ALU_DECODER_LR35902(ADC);
168DEFINE_ALU_DECODER_LR35902(SUB);
169DEFINE_ALU_DECODER_LR35902(SBC);
170
171#define DEFINE_ALU_DECODER_LR35902_ADD_HL(REG) \
172 DEFINE_DECODER_LR35902(ADDHL_ ## REG, info->mnemonic = LR35902_MN_ADD; \
173 info->op1.reg = LR35902_REG_HL; \
174 info->op2.reg = LR35902_REG_ ## REG;)
175
176DEFINE_ALU_DECODER_LR35902_ADD_HL(BC)
177DEFINE_ALU_DECODER_LR35902_ADD_HL(DE)
178DEFINE_ALU_DECODER_LR35902_ADD_HL(HL)
179DEFINE_ALU_DECODER_LR35902_ADD_HL(SP)
180
181DEFINE_DECODER_LR35902(ADDSP, info->mnemonic = LR35902_MN_ADD; \
182 info->op1.reg = LR35902_REG_SP; \
183 return 1;)
184
185#define DEFINE_CONDITIONAL_DECODER_LR35902(NAME) \
186 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(, 0) \
187 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, LR35902_COND_C) \
188 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Z, LR35902_COND_Z) \
189 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NC, LR35902_COND_NC) \
190 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NZ, LR35902_COND_NZ)
191
192#define DEFINE_JP_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
193 DEFINE_DECODER_LR35902(JP ## CONDITION_NAME, \
194 info->mnemonic = LR35902_MN_JP; \
195 info->condition = CONDITION; \
196 return 2;)
197
198#define DEFINE_JR_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
199 DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \
200 info->mnemonic = LR35902_MN_JR; \
201 info->condition = CONDITION; \
202 info->op1.flags = LR35902_OP_FLAG_RELATIVE; \
203 return 1;)
204
205#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
206 DEFINE_DECODER_LR35902(CALL ## CONDITION_NAME, \
207 info->mnemonic = LR35902_MN_CALL; \
208 info->condition = CONDITION; \
209 return 2;)
210
211#define DEFINE_RET_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
212 DEFINE_DECODER_LR35902(RET ## CONDITION_NAME, \
213 info->mnemonic = LR35902_MN_RET; \
214 info->condition = CONDITION;)
215
216DEFINE_CONDITIONAL_DECODER_LR35902(JP);
217DEFINE_CONDITIONAL_DECODER_LR35902(JR);
218DEFINE_CONDITIONAL_DECODER_LR35902(CALL);
219DEFINE_CONDITIONAL_DECODER_LR35902(RET);
220
221DEFINE_DECODER_LR35902(JPHL, \
222 info->mnemonic = LR35902_MN_JP; \
223 info->op1.reg = LR35902_REG_HL)
224
225DEFINE_DECODER_LR35902(RETI, info->mnemonic = LR35902_MN_RETI)
226
227DEFINE_DECODER_LR35902(LDBC_A, \
228 info->mnemonic = LR35902_MN_LD; \
229 info->op1.reg = LR35902_REG_BC; \
230 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
231 info->op2.reg = LR35902_REG_A;)
232
233DEFINE_DECODER_LR35902(LDDE_A, \
234 info->mnemonic = LR35902_MN_LD; \
235 info->op1.reg = LR35902_REG_DE; \
236 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
237 info->op2.reg = LR35902_REG_A;)
238
239DEFINE_DECODER_LR35902(LDIA, \
240 info->mnemonic = LR35902_MN_LD; \
241 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
242 info->op2.reg = LR35902_REG_A; \
243 return 2;)
244
245DEFINE_DECODER_LR35902(LDAI, \
246 info->mnemonic = LR35902_MN_LD; \
247 info->op1.reg = LR35902_REG_A; \
248 info->op2.flags = LR35902_OP_FLAG_MEMORY; \
249 return 2;)
250
251DEFINE_DECODER_LR35902(LDISP, \
252 info->mnemonic = LR35902_MN_LD; \
253 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
254 info->op2.reg = LR35902_REG_SP; \
255 return 2;)
256
257DEFINE_DECODER_LR35902(LDIHLA, \
258 info->mnemonic = LR35902_MN_LD; \
259 info->op1.reg = LR35902_REG_HL; \
260 info->op1.flags = LR35902_OP_FLAG_INCREMENT | LR35902_OP_FLAG_MEMORY; \
261 info->op2.reg = LR35902_REG_A;)
262
263DEFINE_DECODER_LR35902(LDDHLA, \
264 info->mnemonic = LR35902_MN_LD; \
265 info->op1.reg = LR35902_REG_HL; \
266 info->op1.flags = LR35902_OP_FLAG_DECREMENT | LR35902_OP_FLAG_MEMORY; \
267 info->op2.reg = LR35902_REG_A;)
268
269DEFINE_DECODER_LR35902(LDA_IHL, \
270 info->mnemonic = LR35902_MN_LD; \
271 info->op1.reg = LR35902_REG_A; \
272 info->op2.reg = LR35902_REG_HL; \
273 info->op2.flags = LR35902_OP_FLAG_INCREMENT | LR35902_OP_FLAG_MEMORY;)
274
275DEFINE_DECODER_LR35902(LDA_DHL, \
276 info->mnemonic = LR35902_MN_LD; \
277 info->op1.reg = LR35902_REG_A; \
278 info->op2.reg = LR35902_REG_HL; \
279 info->op2.flags = LR35902_OP_FLAG_DECREMENT | LR35902_OP_FLAG_MEMORY;)
280
281#define DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(REG) \
282 DEFINE_DECODER_LR35902(INC ## REG, info->mnemonic = LR35902_MN_INC; info->op1.reg = LR35902_REG_ ## REG) \
283 DEFINE_DECODER_LR35902(DEC ## REG, info->mnemonic = LR35902_MN_DEC; info->op1.reg = LR35902_REG_ ## REG)
284
285DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(BC);
286DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(DE);
287DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(HL);
288DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(SP);
289
290DEFINE_DECODER_LR35902(INC_HL,
291 info->mnemonic = LR35902_MN_INC;
292 info->op1.reg = LR35902_REG_HL;
293 info->op1.flags = LR35902_OP_FLAG_MEMORY;)
294
295DEFINE_DECODER_LR35902(DEC_HL,
296 info->mnemonic = LR35902_MN_DEC;
297 info->op1.reg = LR35902_REG_HL;
298 info->op1.flags = LR35902_OP_FLAG_MEMORY;)
299
300DEFINE_DECODER_LR35902(SCF, info->mnemonic = LR35902_MN_SCF)
301DEFINE_DECODER_LR35902(CCF, info->mnemonic = LR35902_MN_CCF)
302DEFINE_DECODER_LR35902(CPL_, info->mnemonic = LR35902_MN_CPL)
303DEFINE_DECODER_LR35902(DAA, info->mnemonic = LR35902_MN_DAA)
304
305#define DEFINE_POPPUSH_DECODER_LR35902(REG) \
306 DEFINE_DECODER_LR35902(POP ## REG, \
307 info->mnemonic = LR35902_MN_POP; \
308 info->op1.reg = LR35902_REG_ ## REG;) \
309 DEFINE_DECODER_LR35902(PUSH ## REG, \
310 info->mnemonic = LR35902_MN_PUSH; \
311 info->op1.reg = LR35902_REG_ ## REG;) \
312
313DEFINE_POPPUSH_DECODER_LR35902(BC);
314DEFINE_POPPUSH_DECODER_LR35902(DE);
315DEFINE_POPPUSH_DECODER_LR35902(HL);
316DEFINE_POPPUSH_DECODER_LR35902(AF);
317
318#define DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, OP) \
319 DEFINE_DECODER_LR35902(NAME ## B, info->OP.reg = LR35902_REG_B; BODY) \
320 DEFINE_DECODER_LR35902(NAME ## C, info->OP.reg = LR35902_REG_C; BODY) \
321 DEFINE_DECODER_LR35902(NAME ## D, info->OP.reg = LR35902_REG_D; BODY) \
322 DEFINE_DECODER_LR35902(NAME ## E, info->OP.reg = LR35902_REG_E; BODY) \
323 DEFINE_DECODER_LR35902(NAME ## H, info->OP.reg = LR35902_REG_H; BODY) \
324 DEFINE_DECODER_LR35902(NAME ## L, info->OP.reg = LR35902_REG_L; BODY) \
325 DEFINE_DECODER_LR35902(NAME ## HL, info->OP.reg = LR35902_REG_HL; info->OP.flags = LR35902_OP_FLAG_MEMORY; BODY) \
326 DEFINE_DECODER_LR35902(NAME ## A, info->OP.reg = LR35902_REG_A; BODY)
327
328#define DEFINE_CB_2_DECODER_LR35902(NAME, BODY) \
329 DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op2)
330
331#define DEFINE_CB_1_DECODER_LR35902(NAME, BODY) \
332 DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op1)
333
334#define DEFINE_CB_DECODER_LR35902(NAME, BODY) \
335 DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op1.immediate = 0; BODY) \
336 DEFINE_CB_2_DECODER_LR35902(NAME ## 1, info->op1.immediate = 1; BODY) \
337 DEFINE_CB_2_DECODER_LR35902(NAME ## 2, info->op1.immediate = 2; BODY) \
338 DEFINE_CB_2_DECODER_LR35902(NAME ## 3, info->op1.immediate = 3; BODY) \
339 DEFINE_CB_2_DECODER_LR35902(NAME ## 4, info->op1.immediate = 4; BODY) \
340 DEFINE_CB_2_DECODER_LR35902(NAME ## 5, info->op1.immediate = 5; BODY) \
341 DEFINE_CB_2_DECODER_LR35902(NAME ## 6, info->op1.immediate = 6; BODY) \
342 DEFINE_CB_2_DECODER_LR35902(NAME ## 7, info->op1.immediate = 7; BODY)
343
344DEFINE_CB_DECODER_LR35902(BIT, info->mnemonic = LR35902_MN_BIT)
345DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES)
346DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET)
347
348#define DEFINE_CB_X_DECODER_LR35902(NAME) \
349 DEFINE_CB_1_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \
350 DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; \
351 info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
352 info->op1.reg = LR35902_REG_A;)
353
354DEFINE_CB_X_DECODER_LR35902(RL)
355DEFINE_CB_X_DECODER_LR35902(RLC)
356DEFINE_CB_X_DECODER_LR35902(RR)
357DEFINE_CB_X_DECODER_LR35902(RRC)
358DEFINE_CB_1_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA)
359DEFINE_CB_1_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA)
360DEFINE_CB_1_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL)
361DEFINE_CB_1_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP)
362
363DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI)
364DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI)
365DEFINE_DECODER_LR35902(HALT, info->mnemonic = LR35902_MN_HALT)
366DEFINE_DECODER_LR35902(ILL, info->mnemonic = LR35902_MN_ILL)
367DEFINE_DECODER_LR35902(STOP, info->mnemonic = LR35902_MN_STOP; return 1)
368
369#define DEFINE_RST_DECODER_LR35902(VEC) \
370 DEFINE_DECODER_LR35902(RST ## VEC, info->op1.immediate = 0x ## VEC;)
371
372DEFINE_RST_DECODER_LR35902(00);
373DEFINE_RST_DECODER_LR35902(08);
374DEFINE_RST_DECODER_LR35902(10);
375DEFINE_RST_DECODER_LR35902(18);
376DEFINE_RST_DECODER_LR35902(20);
377DEFINE_RST_DECODER_LR35902(28);
378DEFINE_RST_DECODER_LR35902(30);
379DEFINE_RST_DECODER_LR35902(38);
380
381DEFINE_DECODER_LR35902(CB, return 1)
382
383const LR35902Decoder _lr35902DecoderTable[0x100] = {
384 DECLARE_LR35902_EMITTER_BLOCK(_LR35902Decode)
385};
386
387const LR35902Decoder _lr35902CBDecoderTable[0x100] = {
388 DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Decode)
389};
390
391size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info) {
392 if (info->opcodeSize == sizeof(info->opcode)) {
393 return 0;
394 }
395 info->opcode[info->opcodeSize] = opcode;
396 LR35902Decoder decoder;
397 switch (info->opcodeSize) {
398 case 0:
399 decoder = _lr35902DecoderTable[opcode];
400 break;
401 case 1:
402 if (info->opcode[0] == 0xCB) {
403 decoder = _lr35902CBDecoderTable[opcode];
404 break;
405 }
406 // Fall through
407 case 2:
408 ++info->opcodeSize;
409 if (info->op1.reg) {
410 info->op2.immediate |= opcode << ((info->opcodeSize - 2) * 8);
411 } else {
412 info->op1.immediate |= opcode << ((info->opcodeSize - 2) * 8);
413 }
414 return 0;
415 }
416 ++info->opcodeSize;
417 return decoder(opcode, info);
418}
419
420#define ADVANCE(AMOUNT) \
421 if (AMOUNT >= blen) { \
422 buffer[blen - 1] = '\0'; \
423 return total; \
424 } \
425 total += AMOUNT; \
426 buffer += AMOUNT; \
427 blen -= AMOUNT;
428
429static const char* _lr35902Conditions[] = {
430 NULL,
431 "c",
432 "z",
433 "nc",
434 "nz",
435};
436
437static const char* _lr35902Registers[] = {
438 "",
439 "b",
440 "c",
441 "d",
442 "e",
443 "h",
444 "l",
445 "a",
446 "f",
447 "bc",
448 "de",
449 "hl",
450 "af",
451 "sp",
452 "pc",
453};
454
455static const char* _lr35902MnemonicStrings[] = {
456 "--",
457 "adc",
458 "add",
459 "and",
460 "bit",
461 "call",
462 "ccf",
463 "cp",
464 "cpl",
465 "daa",
466 "dec",
467 "di",
468 "ei",
469 "halt",
470 "inc",
471 "jp",
472 "jr",
473 "ld",
474 "nop",
475 "or",
476 "pop",
477 "push",
478 "res",
479 "ret",
480 "reti",
481 "rl",
482 "rlc",
483 "rr",
484 "rrc",
485 "rst",
486 "sbc",
487 "scf",
488 "set",
489 "sla",
490 "sra",
491 "srl",
492 "stop",
493 "sub",
494 "swap",
495 "xor",
496
497 "ill"
498};
499
500
501static int _decodeOperand(struct LR35902Operand op, uint16_t pc, char* buffer, int blen) {
502 int total = 0;
503 if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
504 return 0;
505 }
506
507 if (op.flags & LR35902_OP_FLAG_MEMORY) {
508 strncpy(buffer, "[", blen - 1);
509 ADVANCE(1);
510 }
511 if (op.reg) {
512 int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
513 ADVANCE(written);
514 } else {
515 int written;
516 if (op.flags & LR35902_OP_FLAG_RELATIVE) {
517 written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate);
518 } else {
519 written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
520 }
521 ADVANCE(written);
522 if (op.reg) {
523 strncpy(buffer, "+", blen - 1);
524 ADVANCE(1);
525 }
526 }
527 if (op.flags & LR35902_OP_FLAG_INCREMENT) {
528 strncpy(buffer, "+", blen - 1);
529 ADVANCE(1);
530 }
531 if (op.flags & LR35902_OP_FLAG_DECREMENT) {
532 strncpy(buffer, "-", blen - 1);
533 ADVANCE(1);
534 }
535 if (op.flags & LR35902_OP_FLAG_MEMORY) {
536 strncpy(buffer, "]", blen - 1);
537 ADVANCE(1);
538 }
539 return total;
540}
541
542int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen) {
543 const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
544 int written;
545 int total = 0;
546 const char* cond = _lr35902Conditions[info->condition];
547
548 written = snprintf(buffer, blen - 1, "%s ", mnemonic);
549 ADVANCE(written);
550
551 if (cond) {
552 written = snprintf(buffer, blen - 1, "%s", cond);
553 ADVANCE(written);
554
555 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
556 strncpy(buffer, ", ", blen - 1);
557 ADVANCE(2);
558 }
559 }
560
561 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
562 written = _decodeOperand(info->op1, pc, buffer, blen);
563 ADVANCE(written);
564 }
565
566 if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
567 if (written) {
568 strncpy(buffer, ", ", blen - 1);
569 ADVANCE(2);
570 }
571 written = _decodeOperand(info->op2, pc, buffer, blen);
572 ADVANCE(written);
573 }
574
575 buffer[blen - 1] = '\0';
576 return total;
577}