all repos — mgba @ 0e3abccca29a69bc71ae053fc6740389151d8996

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_ ## 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}