all repos — mgba @ aaec68ee4896fd316660088a3c2c02c7bd3b7241

mGBA Game Boy Advance Emulator

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}