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_2_DECODER_LR35902(NAME, BODY) \
318 DEFINE_DECODER_LR35902(NAME ## B, info->op2.reg = LR35902_REG_B; BODY) \
319 DEFINE_DECODER_LR35902(NAME ## C, info->op2.reg = LR35902_REG_C; BODY) \
320 DEFINE_DECODER_LR35902(NAME ## D, info->op2.reg = LR35902_REG_D; BODY) \
321 DEFINE_DECODER_LR35902(NAME ## E, info->op2.reg = LR35902_REG_E; BODY) \
322 DEFINE_DECODER_LR35902(NAME ## H, info->op2.reg = LR35902_REG_H; BODY) \
323 DEFINE_DECODER_LR35902(NAME ## L, info->op2.reg = LR35902_REG_L; BODY) \
324 DEFINE_DECODER_LR35902(NAME ## HL, info->op2.reg = LR35902_REG_HL; info->op2.flags = LR35902_OP_FLAG_MEMORY; BODY) \
325 DEFINE_DECODER_LR35902(NAME ## A, info->op2.reg = LR35902_REG_A; BODY)
326
327#define DEFINE_CB_DECODER_LR35902(NAME, BODY) \
328 DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op1.immediate = 0; BODY) \
329 DEFINE_CB_2_DECODER_LR35902(NAME ## 1, info->op1.immediate = 1; BODY) \
330 DEFINE_CB_2_DECODER_LR35902(NAME ## 2, info->op1.immediate = 2; BODY) \
331 DEFINE_CB_2_DECODER_LR35902(NAME ## 3, info->op1.immediate = 3; BODY) \
332 DEFINE_CB_2_DECODER_LR35902(NAME ## 4, info->op1.immediate = 4; BODY) \
333 DEFINE_CB_2_DECODER_LR35902(NAME ## 5, info->op1.immediate = 5; BODY) \
334 DEFINE_CB_2_DECODER_LR35902(NAME ## 6, info->op1.immediate = 6; BODY) \
335 DEFINE_CB_2_DECODER_LR35902(NAME ## 7, info->op1.immediate = 7; BODY)
336
337DEFINE_CB_DECODER_LR35902(BIT, info->mnemonic = LR35902_MN_BIT)
338DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES)
339DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET)
340
341#define DEFINE_CB_X_DECODER_LR35902(NAME) \
342 DEFINE_CB_2_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \
343 DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A)
344
345DEFINE_CB_X_DECODER_LR35902(RL)
346DEFINE_CB_X_DECODER_LR35902(RLC)
347DEFINE_CB_X_DECODER_LR35902(RR)
348DEFINE_CB_X_DECODER_LR35902(RRC)
349DEFINE_CB_2_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA)
350DEFINE_CB_2_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA)
351DEFINE_CB_2_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL)
352DEFINE_CB_2_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP)
353
354DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI)
355DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI)
356DEFINE_DECODER_LR35902(HALT, info->mnemonic = LR35902_MN_HALT)
357DEFINE_DECODER_LR35902(ILL, info->mnemonic = LR35902_MN_ILL)
358DEFINE_DECODER_LR35902(STOP, info->mnemonic = LR35902_MN_STOP; return 1)
359
360#define DEFINE_RST_DECODER_LR35902(VEC) \
361 DEFINE_DECODER_LR35902(RST ## VEC, info->op1.immediate = 0x ## VEC;)
362
363DEFINE_RST_DECODER_LR35902(00);
364DEFINE_RST_DECODER_LR35902(08);
365DEFINE_RST_DECODER_LR35902(10);
366DEFINE_RST_DECODER_LR35902(18);
367DEFINE_RST_DECODER_LR35902(20);
368DEFINE_RST_DECODER_LR35902(28);
369DEFINE_RST_DECODER_LR35902(30);
370DEFINE_RST_DECODER_LR35902(38);
371
372DEFINE_DECODER_LR35902(CB, return 1)
373
374const LR35902Decoder _lr35902DecoderTable[0x100] = {
375 DECLARE_LR35902_EMITTER_BLOCK(_LR35902Decode)
376};
377
378const LR35902Decoder _lr35902CBDecoderTable[0x100] = {
379 DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Decode)
380};
381
382size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info) {
383 if (info->opcodeSize == sizeof(info->opcode)) {
384 return 0;
385 }
386 info->opcode[info->opcodeSize] = opcode;
387 LR35902Decoder decoder;
388 switch (info->opcodeSize) {
389 case 0:
390 decoder = _lr35902DecoderTable[opcode];
391 break;
392 case 1:
393 if (info->opcode[0] == 0xCB) {
394 decoder = _lr35902CBDecoderTable[opcode];
395 break;
396 }
397 // Fall through
398 case 2:
399 ++info->opcodeSize;
400 if (info->op1.reg) {
401 info->op2.immediate |= opcode << ((info->opcodeSize - 2) * 8);
402 } else {
403 info->op1.immediate |= opcode << ((info->opcodeSize - 2) * 8);
404 }
405 return 0;
406 }
407 ++info->opcodeSize;
408 return decoder(opcode, info);
409}
410
411#define ADVANCE(AMOUNT) \
412 if (AMOUNT > blen) { \
413 buffer[blen - 1] = '\0'; \
414 return total; \
415 } \
416 total += AMOUNT; \
417 buffer += AMOUNT; \
418 blen -= AMOUNT;
419
420static const char* _lr35902Conditions[] = {
421 NULL,
422 "c",
423 "z",
424 "nc",
425 "nz",
426};
427
428static const char* _lr35902Registers[] = {
429 "",
430 "b",
431 "c",
432 "d",
433 "e",
434 "h",
435 "l",
436 "a",
437 "f",
438 "bc",
439 "de",
440 "hl",
441 "af",
442 "sp",
443 "pc",
444};
445
446static const char* _lr35902MnemonicStrings[] = {
447 "--",
448 "adc",
449 "add",
450 "and",
451 "bit",
452 "call",
453 "ccf",
454 "cp",
455 "cpl",
456 "daa",
457 "dec",
458 "di",
459 "ei",
460 "halt",
461 "inc",
462 "jp",
463 "jr",
464 "ld",
465 "nop",
466 "or",
467 "pop",
468 "push",
469 "res",
470 "ret",
471 "reti",
472 "rl",
473 "rlc",
474 "rr",
475 "rrc",
476 "rst",
477 "sbc",
478 "scf",
479 "set",
480 "sla",
481 "sra",
482 "srl",
483 "stop",
484 "sub",
485 "swap",
486 "xor",
487
488 "ill"
489};
490
491
492static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) {
493 int total = 0;
494 if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
495 return 0;
496 }
497
498 if (op.flags & LR35902_OP_FLAG_MEMORY) {
499 strncpy(buffer, "(", blen - 1);
500 ADVANCE(1);
501 }
502 if (op.reg) {
503 int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
504 ADVANCE(written);
505 } else {
506 int written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
507 ADVANCE(written);
508 if (op.reg) {
509 strncpy(buffer, "+", blen - 1);
510 ADVANCE(1);
511 }
512 }
513 if (op.flags & LR35902_OP_FLAG_INCREMENT) {
514 strncpy(buffer, "+", blen - 1);
515 ADVANCE(1);
516 }
517 if (op.flags & LR35902_OP_FLAG_DECREMENT) {
518 strncpy(buffer, "-", blen - 1);
519 ADVANCE(1);
520 }
521 if (op.flags & LR35902_OP_FLAG_MEMORY) {
522 strncpy(buffer, ")", blen - 1);
523 ADVANCE(1);
524 }
525 return total;
526}
527
528int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) {
529 const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
530 int written;
531 int total = 0;
532 const char* cond = _lr35902Conditions[info->condition];
533
534 written = snprintf(buffer, blen - 1, "%s ", mnemonic);
535 ADVANCE(written);
536
537 if (cond) {
538 written = snprintf(buffer, blen - 1, "%s", cond);
539 ADVANCE(written);
540
541 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
542 strncpy(buffer, ", ", blen - 1);
543 ADVANCE(2);
544 }
545 }
546
547 if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
548 written = _decodeOperand(info->op1, buffer, blen);
549 ADVANCE(written);
550 }
551
552 if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
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}