all repos — mgba @ 0de37f30b6cd87e6e48e8c6ea213c8ed5626397c

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_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	strncpy(buffer, " ", blen - 1);
507	ADVANCE(1);
508
509	if (op.flags & LR35902_OP_FLAG_MEMORY) {
510		strncpy(buffer, "[", blen - 1);
511		ADVANCE(1);
512	}
513	if (op.reg) {
514		int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
515		ADVANCE(written);
516	} else {
517		int written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
518		ADVANCE(written);
519		if (op.reg) {
520			strncpy(buffer, "+", blen - 1);
521			ADVANCE(1);
522		}
523	}
524	if (op.flags & LR35902_OP_FLAG_INCREMENT) {
525		strncpy(buffer, "+", blen - 1);
526		ADVANCE(1);
527	}
528	if (op.flags & LR35902_OP_FLAG_DECREMENT) {
529		strncpy(buffer, "-", blen - 1);
530		ADVANCE(1);
531	}
532	if (op.flags & LR35902_OP_FLAG_MEMORY) {
533		strncpy(buffer, "]", blen - 1);
534		ADVANCE(1);
535	}
536	return total;
537}
538
539int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) {
540	const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
541	int written;
542	int total = 0;
543	const char* cond = _lr35902Conditions[info->condition];
544
545	written = snprintf(buffer, blen - 1, "%s", mnemonic);
546	ADVANCE(written);
547
548	if (cond) {
549		written = snprintf(buffer, blen - 1, " %s", cond);
550		ADVANCE(written);
551
552		if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
553			strncpy(buffer, ",", blen - 1);
554			ADVANCE(1);
555		}
556	}
557
558	if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
559		written = _decodeOperand(info->op1, buffer, blen);
560		ADVANCE(written);
561	}
562
563	if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
564		if (written) {
565			strncpy(buffer, ",", blen - 1);
566			ADVANCE(1);
567		}
568		written = _decodeOperand(info->op2, buffer, blen);
569		ADVANCE(written);
570	}
571
572	buffer[blen - 1] = '\0';
573	return total;
574}