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 return 1;)
203
204#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
205 DEFINE_DECODER_LR35902(CALL ## CONDITION_NAME, \
206 info->mnemonic = LR35902_MN_CALL; \
207 info->condition = CONDITION; \
208 return 2;)
209
210#define DEFINE_RET_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
211 DEFINE_DECODER_LR35902(RET ## CONDITION_NAME, \
212 info->mnemonic = LR35902_MN_RET; \
213 info->condition = CONDITION;)
214
215DEFINE_CONDITIONAL_DECODER_LR35902(JP);
216DEFINE_CONDITIONAL_DECODER_LR35902(JR);
217DEFINE_CONDITIONAL_DECODER_LR35902(CALL);
218DEFINE_CONDITIONAL_DECODER_LR35902(RET);
219
220DEFINE_DECODER_LR35902(JPHL, \
221 info->mnemonic = LR35902_MN_JP; \
222 info->op1.reg = LR35902_REG_HL)
223
224DEFINE_DECODER_LR35902(RETI, info->mnemonic = LR35902_MN_RETI)
225
226DEFINE_DECODER_LR35902(LDBC_A, \
227 info->mnemonic = LR35902_MN_LD; \
228 info->op1.reg = LR35902_REG_BC; \
229 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
230 info->op2.reg = LR35902_REG_A;)
231
232DEFINE_DECODER_LR35902(LDDE_A, \
233 info->mnemonic = LR35902_MN_LD; \
234 info->op1.reg = LR35902_REG_DE; \
235 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
236 info->op2.reg = LR35902_REG_A;)
237
238DEFINE_DECODER_LR35902(LDIA, \
239 info->mnemonic = LR35902_MN_LD; \
240 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
241 info->op2.reg = LR35902_REG_A; \
242 return 2;)
243
244DEFINE_DECODER_LR35902(LDAI, \
245 info->mnemonic = LR35902_MN_LD; \
246 info->op1.reg = LR35902_REG_A; \
247 info->op2.flags = LR35902_OP_FLAG_MEMORY; \
248 return 2;)
249
250DEFINE_DECODER_LR35902(LDISP, \
251 info->mnemonic = LR35902_MN_LD; \
252 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
253 info->op2.reg = LR35902_REG_SP; \
254 return 2;)
255
256DEFINE_DECODER_LR35902(LDIHLA, \
257 info->mnemonic = LR35902_MN_LD; \
258 info->op1.reg = LR35902_REG_HL; \
259 info->op1.flags = LR35902_OP_FLAG_INCREMENT | LR35902_OP_FLAG_MEMORY; \
260 info->op2.reg = LR35902_REG_A;)
261
262DEFINE_DECODER_LR35902(LDDHLA, \
263 info->mnemonic = LR35902_MN_LD; \
264 info->op1.reg = LR35902_REG_HL; \
265 info->op1.flags = LR35902_OP_FLAG_DECREMENT | LR35902_OP_FLAG_MEMORY; \
266 info->op2.reg = LR35902_REG_A;)
267
268DEFINE_DECODER_LR35902(LDA_IHL, \
269 info->mnemonic = LR35902_MN_LD; \
270 info->op1.reg = LR35902_REG_A; \
271 info->op2.reg = LR35902_REG_HL; \
272 info->op2.flags = LR35902_OP_FLAG_INCREMENT | LR35902_OP_FLAG_MEMORY;)
273
274DEFINE_DECODER_LR35902(LDA_DHL, \
275 info->mnemonic = LR35902_MN_LD; \
276 info->op1.reg = LR35902_REG_A; \
277 info->op2.reg = LR35902_REG_HL; \
278 info->op2.flags = LR35902_OP_FLAG_DECREMENT | LR35902_OP_FLAG_MEMORY;)
279
280#define DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(REG) \
281 DEFINE_DECODER_LR35902(INC ## REG, info->mnemonic = LR35902_MN_INC; info->op1.reg = LR35902_REG_ ## REG) \
282 DEFINE_DECODER_LR35902(DEC ## REG, info->mnemonic = LR35902_MN_DEC; info->op1.reg = LR35902_REG_ ## REG)
283
284DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(BC);
285DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(DE);
286DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(HL);
287DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(SP);
288
289DEFINE_DECODER_LR35902(INC_HL,
290 info->mnemonic = LR35902_MN_INC;
291 info->op1.reg = LR35902_REG_HL;
292 info->op1.flags = LR35902_OP_FLAG_MEMORY;)
293
294DEFINE_DECODER_LR35902(DEC_HL,
295 info->mnemonic = LR35902_MN_DEC;
296 info->op1.reg = LR35902_REG_HL;
297 info->op1.flags = LR35902_OP_FLAG_MEMORY;)
298
299DEFINE_DECODER_LR35902(SCF, info->mnemonic = LR35902_MN_SCF)
300DEFINE_DECODER_LR35902(CCF, info->mnemonic = LR35902_MN_CCF)
301DEFINE_DECODER_LR35902(CPL_, info->mnemonic = LR35902_MN_CPL)
302DEFINE_DECODER_LR35902(DAA, info->mnemonic = LR35902_MN_DAA)
303
304#define DEFINE_POPPUSH_DECODER_LR35902(REG) \
305 DEFINE_DECODER_LR35902(POP ## REG, \
306 info->mnemonic = LR35902_MN_POP; \
307 info->op1.reg = LR35902_REG_ ## REG;) \
308 DEFINE_DECODER_LR35902(PUSH ## REG, \
309 info->mnemonic = LR35902_MN_PUSH; \
310 info->op1.reg = LR35902_REG_ ## REG;) \
311
312DEFINE_POPPUSH_DECODER_LR35902(BC);
313DEFINE_POPPUSH_DECODER_LR35902(DE);
314DEFINE_POPPUSH_DECODER_LR35902(HL);
315DEFINE_POPPUSH_DECODER_LR35902(AF);
316
317#define DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, OP) \
318 DEFINE_DECODER_LR35902(NAME ## B, info->OP.reg = LR35902_REG_B; BODY) \
319 DEFINE_DECODER_LR35902(NAME ## C, info->OP.reg = LR35902_REG_C; BODY) \
320 DEFINE_DECODER_LR35902(NAME ## D, info->OP.reg = LR35902_REG_D; BODY) \
321 DEFINE_DECODER_LR35902(NAME ## E, info->OP.reg = LR35902_REG_E; BODY) \
322 DEFINE_DECODER_LR35902(NAME ## H, info->OP.reg = LR35902_REG_H; BODY) \
323 DEFINE_DECODER_LR35902(NAME ## L, info->OP.reg = LR35902_REG_L; BODY) \
324 DEFINE_DECODER_LR35902(NAME ## HL, info->OP.reg = LR35902_REG_HL; info->OP.flags = LR35902_OP_FLAG_MEMORY; BODY) \
325 DEFINE_DECODER_LR35902(NAME ## A, info->OP.reg = LR35902_REG_A; BODY)
326
327#define DEFINE_CB_2_DECODER_LR35902(NAME, BODY) \
328 DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op2)
329
330#define DEFINE_CB_1_DECODER_LR35902(NAME, BODY) \
331 DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op1)
332
333#define DEFINE_CB_DECODER_LR35902(NAME, BODY) \
334 DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op1.immediate = 0; BODY) \
335 DEFINE_CB_2_DECODER_LR35902(NAME ## 1, info->op1.immediate = 1; BODY) \
336 DEFINE_CB_2_DECODER_LR35902(NAME ## 2, info->op1.immediate = 2; BODY) \
337 DEFINE_CB_2_DECODER_LR35902(NAME ## 3, info->op1.immediate = 3; BODY) \
338 DEFINE_CB_2_DECODER_LR35902(NAME ## 4, info->op1.immediate = 4; BODY) \
339 DEFINE_CB_2_DECODER_LR35902(NAME ## 5, info->op1.immediate = 5; BODY) \
340 DEFINE_CB_2_DECODER_LR35902(NAME ## 6, info->op1.immediate = 6; BODY) \
341 DEFINE_CB_2_DECODER_LR35902(NAME ## 7, info->op1.immediate = 7; BODY)
342
343DEFINE_CB_DECODER_LR35902(BIT, info->mnemonic = LR35902_MN_BIT)
344DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES)
345DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET)
346
347#define DEFINE_CB_X_DECODER_LR35902(NAME) \
348 DEFINE_CB_1_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \
349 DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; \
350 info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
351 info->op1.reg = LR35902_REG_A;)
352
353DEFINE_CB_X_DECODER_LR35902(RL)
354DEFINE_CB_X_DECODER_LR35902(RLC)
355DEFINE_CB_X_DECODER_LR35902(RR)
356DEFINE_CB_X_DECODER_LR35902(RRC)
357DEFINE_CB_1_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA)
358DEFINE_CB_1_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA)
359DEFINE_CB_1_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL)
360DEFINE_CB_1_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP)
361
362DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI)
363DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI)
364DEFINE_DECODER_LR35902(HALT, info->mnemonic = LR35902_MN_HALT)
365DEFINE_DECODER_LR35902(ILL, info->mnemonic = LR35902_MN_ILL)
366DEFINE_DECODER_LR35902(STOP, info->mnemonic = LR35902_MN_STOP; return 1)
367
368#define DEFINE_RST_DECODER_LR35902(VEC) \
369 DEFINE_DECODER_LR35902(RST ## VEC, info->op1.immediate = 0x ## VEC;)
370
371DEFINE_RST_DECODER_LR35902(00);
372DEFINE_RST_DECODER_LR35902(08);
373DEFINE_RST_DECODER_LR35902(10);
374DEFINE_RST_DECODER_LR35902(18);
375DEFINE_RST_DECODER_LR35902(20);
376DEFINE_RST_DECODER_LR35902(28);
377DEFINE_RST_DECODER_LR35902(30);
378DEFINE_RST_DECODER_LR35902(38);
379
380DEFINE_DECODER_LR35902(CB, return 1)
381
382const LR35902Decoder _lr35902DecoderTable[0x100] = {
383 DECLARE_LR35902_EMITTER_BLOCK(_LR35902Decode)
384};
385
386const LR35902Decoder _lr35902CBDecoderTable[0x100] = {
387 DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Decode)
388};
389
390size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info) {
391 if (info->opcodeSize == sizeof(info->opcode)) {
392 return 0;
393 }
394 info->opcode[info->opcodeSize] = opcode;
395 LR35902Decoder decoder;
396 switch (info->opcodeSize) {
397 case 0:
398 decoder = _lr35902DecoderTable[opcode];
399 break;
400 case 1:
401 if (info->opcode[0] == 0xCB) {
402 decoder = _lr35902CBDecoderTable[opcode];
403 break;
404 }
405 // Fall through
406 case 2:
407 ++info->opcodeSize;
408 if (info->op1.reg) {
409 info->op2.immediate |= opcode << ((info->opcodeSize - 2) * 8);
410 } else {
411 info->op1.immediate |= opcode << ((info->opcodeSize - 2) * 8);
412 }
413 return 0;
414 }
415 ++info->opcodeSize;
416 return decoder(opcode, info);
417}
418
419#define ADVANCE(AMOUNT) \
420 if (AMOUNT >= blen) { \
421 buffer[blen - 1] = '\0'; \
422 return total; \
423 } \
424 total += AMOUNT; \
425 buffer += AMOUNT; \
426 blen -= AMOUNT;
427
428static const char* _lr35902Conditions[] = {
429 NULL,
430 "c",
431 "z",
432 "nc",
433 "nz",
434};
435
436static const char* _lr35902Registers[] = {
437 "",
438 "b",
439 "c",
440 "d",
441 "e",
442 "h",
443 "l",
444 "a",
445 "f",
446 "bc",
447 "de",
448 "hl",
449 "af",
450 "sp",
451 "pc",
452};
453
454static const char* _lr35902MnemonicStrings[] = {
455 "--",
456 "adc",
457 "add",
458 "and",
459 "bit",
460 "call",
461 "ccf",
462 "cp",
463 "cpl",
464 "daa",
465 "dec",
466 "di",
467 "ei",
468 "halt",
469 "inc",
470 "jp",
471 "jr",
472 "ld",
473 "nop",
474 "or",
475 "pop",
476 "push",
477 "res",
478 "ret",
479 "reti",
480 "rl",
481 "rlc",
482 "rr",
483 "rrc",
484 "rst",
485 "sbc",
486 "scf",
487 "set",
488 "sla",
489 "sra",
490 "srl",
491 "stop",
492 "sub",
493 "swap",
494 "xor",
495
496 "ill"
497};
498
499
500static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) {
501 int total = 0;
502 if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
503 return 0;
504 }
505
506 if (op.flags & LR35902_OP_FLAG_MEMORY) {
507 strncpy(buffer, "[", blen - 1);
508 ADVANCE(1);
509 }
510 if (op.reg) {
511 int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
512 ADVANCE(written);
513 } else {
514 int written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
515 ADVANCE(written);
516 if (op.reg) {
517 strncpy(buffer, "+", blen - 1);
518 ADVANCE(1);
519 }
520 }
521 if (op.flags & LR35902_OP_FLAG_INCREMENT) {
522 strncpy(buffer, "+", blen - 1);
523 ADVANCE(1);
524 }
525 if (op.flags & LR35902_OP_FLAG_DECREMENT) {
526 strncpy(buffer, "-", blen - 1);
527 ADVANCE(1);
528 }
529 if (op.flags & LR35902_OP_FLAG_MEMORY) {
530 strncpy(buffer, "]", blen - 1);
531 ADVANCE(1);
532 }
533 return total;
534}
535
536int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) {
537 const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
538 int written;
539 int total = 0;
540 const char* cond = _lr35902Conditions[info->condition];
541
542 written = snprintf(buffer, blen - 1, "%s ", mnemonic);
543 ADVANCE(written);
544
545 if (cond) {
546 written = snprintf(buffer, blen - 1, "%s", cond);
547 ADVANCE(written);
548
549 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
550 strncpy(buffer, ", ", blen - 1);
551 ADVANCE(2);
552 }
553 }
554
555 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
556 written = _decodeOperand(info->op1, buffer, blen);
557 ADVANCE(written);
558 }
559
560 if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
561 if (written) {
562 strncpy(buffer, ", ", blen - 1);
563 ADVANCE(2);
564 }
565 written = _decodeOperand(info->op2, buffer, blen);
566 ADVANCE(written);
567 }
568
569 buffer[blen - 1] = '\0';
570 return total;
571}