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 strncpy(buffer, " ", blen - 1);
508 ADVANCE(1);
509
510 if (op.flags & LR35902_OP_FLAG_MEMORY) {
511 strncpy(buffer, "[", blen - 1);
512 ADVANCE(1);
513 }
514 if (op.reg) {
515 int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
516 ADVANCE(written);
517 } else {
518 int written;
519 if (op.flags & LR35902_OP_FLAG_RELATIVE) {
520 written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate);
521 } else {
522 written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
523 }
524 ADVANCE(written);
525 if (op.reg) {
526 strncpy(buffer, "+", blen - 1);
527 ADVANCE(1);
528 }
529 }
530 if (op.flags & LR35902_OP_FLAG_INCREMENT) {
531 strncpy(buffer, "+", blen - 1);
532 ADVANCE(1);
533 }
534 if (op.flags & LR35902_OP_FLAG_DECREMENT) {
535 strncpy(buffer, "-", blen - 1);
536 ADVANCE(1);
537 }
538 if (op.flags & LR35902_OP_FLAG_MEMORY) {
539 strncpy(buffer, "]", blen - 1);
540 ADVANCE(1);
541 }
542 return total;
543}
544
545int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen) {
546 const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
547 int written;
548 int total = 0;
549 const char* cond = _lr35902Conditions[info->condition];
550
551 written = snprintf(buffer, blen - 1, "%s", mnemonic);
552 ADVANCE(written);
553
554 if (cond) {
555 written = snprintf(buffer, blen - 1, " %s", cond);
556 ADVANCE(written);
557
558 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
559 strncpy(buffer, ",", blen - 1);
560 ADVANCE(1);
561 }
562 }
563
564 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
565 written = _decodeOperand(info->op1, pc, buffer, blen);
566 ADVANCE(written);
567 }
568
569 if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
570 if (written) {
571 strncpy(buffer, ",", blen - 1);
572 ADVANCE(1);
573 }
574 written = _decodeOperand(info->op2, pc, buffer, blen);
575 ADVANCE(written);
576 }
577
578 buffer[blen - 1] = '\0';
579 return total;
580}