all repos — mgba @ 029638ae99d948c4a759f4446eed0e0266b3d0aa

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