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_A; \
70 info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
71 return 1;) \
72 DEFINE_LD_DECODER_LR35902_NOHL(NAME)
73
74#define DEFINE_LD_2_DECODER_LR35902(NAME) \
75 DEFINE_DECODER_LR35902(LD ## NAME, info->mnemonic = LR35902_MN_LD; \
76 info->op1.reg = LR35902_REG_ ## NAME; \
77 return 2;)
78
79DEFINE_LD_DECODER_LR35902(B);
80DEFINE_LD_DECODER_LR35902(C);
81DEFINE_LD_DECODER_LR35902(D);
82DEFINE_LD_DECODER_LR35902(E);
83DEFINE_LD_DECODER_LR35902(H);
84DEFINE_LD_DECODER_LR35902(L);
85DEFINE_LD_DECODER_LR35902(A);
86DEFINE_LD_DECODER_LR35902_MEM(A, BC);
87DEFINE_LD_DECODER_LR35902_MEM(A, DE);
88
89DEFINE_LD_2_DECODER_LR35902(BC);
90DEFINE_LD_2_DECODER_LR35902(DE);
91DEFINE_LD_2_DECODER_LR35902(HL);
92DEFINE_LD_2_DECODER_LR35902(SP);
93
94DEFINE_DECODER_LR35902(LDHL_, \
95 info->mnemonic = LR35902_MN_LD; \
96 info->op1.reg = LR35902_REG_HL; \
97 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
98 return 1;)
99
100DEFINE_DECODER_LR35902(LDHL_SP, \
101 info->mnemonic = LR35902_MN_LD; \
102 info->op1.reg = LR35902_REG_HL; \
103 info->op2.reg = LR35902_REG_SP; \
104 return 1;)
105
106DEFINE_DECODER_LR35902(LDSP_HL, \
107 info->mnemonic = LR35902_MN_LD; \
108 info->op1.reg = LR35902_REG_SP; \
109 info->op2.reg = LR35902_REG_HL;)
110
111DEFINE_DECODER_LR35902(LDAIOC, \
112 info->mnemonic = LR35902_MN_LD; \
113 info->op1.reg = LR35902_REG_A; \
114 info->op2.reg = LR35902_REG_C; \
115 info->op2.immediate = 0xFF00; \
116 info->op2.flags = LR35902_OP_FLAG_MEMORY;)
117
118DEFINE_DECODER_LR35902(LDIOCA, \
119 info->mnemonic = LR35902_MN_LD; \
120 info->op1.reg = LR35902_REG_C; \
121 info->op1.immediate = 0xFF00; \
122 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
123 info->op2.reg = LR35902_REG_A;)
124
125DEFINE_DECODER_LR35902(LDAIO, \
126 info->mnemonic = LR35902_MN_LD; \
127 info->op1.reg = LR35902_REG_A; \
128 info->op2.immediate = 0xFF00; \
129 info->op2.flags = LR35902_OP_FLAG_MEMORY; \
130 return 1;)
131
132DEFINE_DECODER_LR35902(LDIOA, \
133 info->mnemonic = LR35902_MN_LD; \
134 info->op1.immediate = 0xFF00; \
135 info->op1.flags = LR35902_OP_FLAG_MEMORY; \
136 info->op2.reg = LR35902_REG_A; \
137 return 1;)
138
139#define DEFINE_ALU_DECODER_LR35902_NOHL(NAME) \
140 DEFINE_DECODER_LR35902(NAME ## A, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A) \
141 DEFINE_DECODER_LR35902(NAME ## B, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_B) \
142 DEFINE_DECODER_LR35902(NAME ## C, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_C) \
143 DEFINE_DECODER_LR35902(NAME ## D, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_D) \
144 DEFINE_DECODER_LR35902(NAME ## E, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_E) \
145 DEFINE_DECODER_LR35902(NAME ## H, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_H) \
146 DEFINE_DECODER_LR35902(NAME ## L, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_L)
147
148#define DEFINE_ALU_DECODER_LR35902_MEM(NAME, REG) \
149 DEFINE_DECODER_LR35902(NAME ## REG, info->mnemonic = LR35902_MN_ ## NAME; \
150 info->op1.reg = LR35902_REG_HL; \
151 info->op1.flags = LR35902_OP_FLAG_MEMORY;)
152
153#define DEFINE_ALU_DECODER_LR35902(NAME) \
154 DEFINE_ALU_DECODER_LR35902_MEM(NAME, HL) \
155 DEFINE_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME; \
156 info->op1.reg = LR35902_REG_A; \
157 info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \
158 return 1;) \
159 DEFINE_ALU_DECODER_LR35902_NOHL(NAME)
160
161DEFINE_ALU_DECODER_LR35902_NOHL(INC);
162DEFINE_ALU_DECODER_LR35902_NOHL(DEC);
163DEFINE_ALU_DECODER_LR35902(AND);
164DEFINE_ALU_DECODER_LR35902(XOR);
165DEFINE_ALU_DECODER_LR35902(OR);
166DEFINE_ALU_DECODER_LR35902(CP);
167DEFINE_ALU_DECODER_LR35902(ADD);
168DEFINE_ALU_DECODER_LR35902(ADC);
169DEFINE_ALU_DECODER_LR35902(SUB);
170DEFINE_ALU_DECODER_LR35902(SBC);
171
172#define DEFINE_ALU_DECODER_LR35902_ADD_HL(REG) \
173 DEFINE_DECODER_LR35902(ADDHL_ ## REG, info->mnemonic = LR35902_MN_ADD; \
174 info->op1.reg = LR35902_REG_HL; \
175 info->op2.reg = LR35902_REG_ ## REG;)
176
177DEFINE_ALU_DECODER_LR35902_ADD_HL(BC)
178DEFINE_ALU_DECODER_LR35902_ADD_HL(DE)
179DEFINE_ALU_DECODER_LR35902_ADD_HL(HL)
180DEFINE_ALU_DECODER_LR35902_ADD_HL(SP)
181
182DEFINE_DECODER_LR35902(ADDSP, info->mnemonic = LR35902_MN_ADD; \
183 info->op1.reg = LR35902_REG_SP; \
184 return 1;)
185
186#define DEFINE_CONDITIONAL_DECODER_LR35902(NAME) \
187 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(, 0) \
188 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, LR35902_COND_C) \
189 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Z, LR35902_COND_Z) \
190 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NC, LR35902_COND_NC) \
191 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NZ, LR35902_COND_NZ)
192
193#define DEFINE_JP_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
194 DEFINE_DECODER_LR35902(JP ## CONDITION_NAME, \
195 info->mnemonic = LR35902_MN_JP; \
196 info->condition = CONDITION; \
197 return 2;)
198
199#define DEFINE_JR_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
200 DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \
201 info->mnemonic = LR35902_MN_JR; \
202 info->condition = CONDITION; \
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_2_DECODER_LR35902(NAME, BODY) \
319 DEFINE_DECODER_LR35902(NAME ## B, info->op1.reg = LR35902_REG_B; BODY) \
320 DEFINE_DECODER_LR35902(NAME ## C, info->op1.reg = LR35902_REG_C; BODY) \
321 DEFINE_DECODER_LR35902(NAME ## D, info->op1.reg = LR35902_REG_D; BODY) \
322 DEFINE_DECODER_LR35902(NAME ## E, info->op1.reg = LR35902_REG_E; BODY) \
323 DEFINE_DECODER_LR35902(NAME ## H, info->op1.reg = LR35902_REG_H; BODY) \
324 DEFINE_DECODER_LR35902(NAME ## L, info->op1.reg = LR35902_REG_L; BODY) \
325 DEFINE_DECODER_LR35902(NAME ## HL, info->op1.reg = LR35902_REG_HL; BODY) \
326 DEFINE_DECODER_LR35902(NAME ## A, info->op1.reg = LR35902_REG_A; BODY)
327
328#define DEFINE_CB_DECODER_LR35902(NAME, BODY) \
329 DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op2.immediate = 1; BODY) \
330 DEFINE_CB_2_DECODER_LR35902(NAME ## 1, info->op2.immediate = 2; BODY) \
331 DEFINE_CB_2_DECODER_LR35902(NAME ## 2, info->op2.immediate = 4; BODY) \
332 DEFINE_CB_2_DECODER_LR35902(NAME ## 3, info->op2.immediate = 8; BODY) \
333 DEFINE_CB_2_DECODER_LR35902(NAME ## 4, info->op2.immediate = 16; BODY) \
334 DEFINE_CB_2_DECODER_LR35902(NAME ## 5, info->op2.immediate = 32; BODY) \
335 DEFINE_CB_2_DECODER_LR35902(NAME ## 6, info->op2.immediate = 64; BODY) \
336 DEFINE_CB_2_DECODER_LR35902(NAME ## 7, info->op2.immediate = 128; BODY)
337
338DEFINE_CB_DECODER_LR35902(BIT, info->mnemonic = LR35902_MN_BIT)
339DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES)
340DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET)
341
342#define DEFINE_CB_X_DECODER_LR35902(NAME) \
343 DEFINE_CB_2_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \
344 DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A)
345
346DEFINE_CB_X_DECODER_LR35902(RL)
347DEFINE_CB_X_DECODER_LR35902(RLC)
348DEFINE_CB_X_DECODER_LR35902(RR)
349DEFINE_CB_X_DECODER_LR35902(RRC)
350DEFINE_CB_2_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA)
351DEFINE_CB_2_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA)
352DEFINE_CB_2_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL)
353DEFINE_CB_2_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP)
354
355DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI)
356DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI)
357DEFINE_DECODER_LR35902(HALT, info->mnemonic = LR35902_MN_HALT)
358DEFINE_DECODER_LR35902(ILL, info->mnemonic = LR35902_MN_ILL)
359DEFINE_DECODER_LR35902(STOP, info->mnemonic = LR35902_MN_STOP; return 1)
360
361#define DEFINE_RST_DECODER_LR35902(VEC) \
362 DEFINE_DECODER_LR35902(RST ## VEC, info->op1.immediate = 0x ## VEC;)
363
364DEFINE_RST_DECODER_LR35902(00);
365DEFINE_RST_DECODER_LR35902(08);
366DEFINE_RST_DECODER_LR35902(10);
367DEFINE_RST_DECODER_LR35902(18);
368DEFINE_RST_DECODER_LR35902(20);
369DEFINE_RST_DECODER_LR35902(28);
370DEFINE_RST_DECODER_LR35902(30);
371DEFINE_RST_DECODER_LR35902(38);
372
373DEFINE_DECODER_LR35902(CB, return 1)
374
375const LR35902Decoder _lr35902DecoderTable[0x100] = {
376 DECLARE_LR35902_EMITTER_BLOCK(_LR35902Decode)
377};
378
379const LR35902Decoder _lr35902CBDecoderTable[0x100] = {
380 DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Decode)
381};
382
383size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info) {
384 if (info->opcodeSize == sizeof(info->opcode)) {
385 return 0;
386 }
387 info->opcode[info->opcodeSize] = opcode;
388 LR35902Decoder decoder;
389 switch (info->opcodeSize) {
390 case 0:
391 decoder = _lr35902DecoderTable[opcode];
392 break;
393 case 1:
394 if (info->opcode[0] == 0xCB) {
395 decoder = _lr35902CBDecoderTable[opcode];
396 break;
397 }
398 // Fall through
399 case 2:
400 ++info->opcodeSize;
401 if (info->op1.reg) {
402 info->op2.immediate |= opcode << ((info->opcodeSize - 2) * 8);
403 } else {
404 info->op1.immediate |= opcode << ((info->opcodeSize - 2) * 8);
405 }
406 return 0;
407 }
408 ++info->opcodeSize;
409 return decoder(opcode, info);
410}
411
412#define ADVANCE(AMOUNT) \
413 if (AMOUNT > blen) { \
414 buffer[blen - 1] = '\0'; \
415 return total; \
416 } \
417 total += AMOUNT; \
418 buffer += AMOUNT; \
419 blen -= AMOUNT;
420
421static const char* _lr35902Conditions[] = {
422 NULL,
423 "c",
424 "z",
425 "nc",
426 "nz",
427};
428
429static const char* _lr35902Registers[] = {
430 "",
431 "b",
432 "c",
433 "d",
434 "e",
435 "h",
436 "l",
437 "a",
438 "f",
439 "bc",
440 "de",
441 "hl",
442 "af",
443 "sp",
444 "pc",
445};
446
447static const char* _lr35902MnemonicStrings[] = {
448 "--",
449 "adc",
450 "add",
451 "and",
452 "bit",
453 "call",
454 "ccf",
455 "cp",
456 "cpl",
457 "daa",
458 "dec",
459 "di",
460 "ei",
461 "halt",
462 "inc",
463 "jp",
464 "jr",
465 "ld",
466 "nop",
467 "or",
468 "pop",
469 "push",
470 "res",
471 "ret",
472 "reti",
473 "rl",
474 "rlc",
475 "rr",
476 "rrc",
477 "rst",
478 "sbc",
479 "scf",
480 "set",
481 "sla",
482 "sra",
483 "srl",
484 "stop",
485 "sub",
486 "swap",
487 "xor",
488
489 "ill"
490};
491
492
493static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) {
494 int total = 0;
495 if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
496 return 0;
497 }
498
499 if (op.flags & LR35902_OP_FLAG_MEMORY) {
500 strncpy(buffer, "(", blen - 1);
501 ADVANCE(1);
502 }
503 if (op.immediate) {
504 int written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
505 ADVANCE(written);
506 if (op.reg) {
507 strncpy(buffer, "+", blen - 1);
508 ADVANCE(1);
509 }
510 }
511 if (op.reg) {
512 int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
513 ADVANCE(written);
514 }
515 if (op.flags & LR35902_OP_FLAG_INCREMENT) {
516 strncpy(buffer, "+", blen - 1);
517 ADVANCE(1);
518 }
519 if (op.flags & LR35902_OP_FLAG_DECREMENT) {
520 strncpy(buffer, "-", blen - 1);
521 ADVANCE(1);
522 }
523 if (op.flags & LR35902_OP_FLAG_MEMORY) {
524 strncpy(buffer, ")", blen - 1);
525 ADVANCE(1);
526 }
527 return total;
528}
529
530int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) {
531 const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
532 int written;
533 int total = 0;
534 const char* cond = _lr35902Conditions[info->condition];
535
536 written = snprintf(buffer, blen - 1, "%s ", mnemonic);
537 ADVANCE(written);
538
539 if (cond) {
540 written = snprintf(buffer, blen - 1, "%s", cond);
541 ADVANCE(written);
542
543 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
544 strncpy(buffer, ", ", blen - 1);
545 ADVANCE(2);
546 }
547 }
548
549 written = _decodeOperand(info->op1, buffer, blen);
550 ADVANCE(written);
551
552 if (info->op2.reg || info->op2.immediate) {
553 if (written) {
554 strncpy(buffer, ", ", blen - 1);
555 ADVANCE(2);
556 }
557 written = _decodeOperand(info->op2, buffer, blen);
558 ADVANCE(written);
559 }
560
561 buffer[blen - 1] = '\0';
562 return total;
563}