all repos — mgba @ 76c41a62ba989549d3dc75580e6dde16b8b5f9bb

mGBA Game Boy Advance Emulator

src/lr35902/isa-lr35902.c (view raw)

  1/* Copyright (c) 2013-2016 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 "isa-lr35902.h"
  7
  8#include "lr35902/emitter-lr35902.h"
  9#include "lr35902/lr35902.h"
 10
 11#define DEFINE_INSTRUCTION_LR35902(NAME, BODY) \
 12	static void _LR35902Instruction ## NAME (struct LR35902Core* cpu) { \
 13		UNUSED(cpu); \
 14		BODY; \
 15	}
 16
 17DEFINE_INSTRUCTION_LR35902(NOP,);
 18
 19#define DEFINE_CONDITIONAL_INSTRUCTION_LR35902(NAME) \
 20	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(, true) \
 21	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, cpu->f.c) \
 22	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Z, cpu->f.z) \
 23	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NC, !cpu->f.c) \
 24	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(NZ, !cpu->f.z)
 25
 26DEFINE_INSTRUCTION_LR35902(JPFinish,
 27	if (cpu->condition) {
 28		cpu->pc = (cpu->bus << 8) | cpu->index;
 29		cpu->memory.setActiveRegion(cpu, cpu->pc);
 30		cpu->executionState = LR35902_CORE_STALL;
 31	})
 32
 33DEFINE_INSTRUCTION_LR35902(JPDelay,
 34	cpu->executionState = LR35902_CORE_READ_PC;
 35	cpu->instruction = _LR35902InstructionJPFinish;
 36	cpu->index = cpu->bus;)
 37
 38#define DEFINE_JP_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
 39	DEFINE_INSTRUCTION_LR35902(JP ## CONDITION_NAME, \
 40		cpu->executionState = LR35902_CORE_READ_PC; \
 41		cpu->instruction = _LR35902InstructionJPDelay; \
 42		cpu->condition = CONDITION;)
 43
 44DEFINE_CONDITIONAL_INSTRUCTION_LR35902(JP);
 45
 46DEFINE_INSTRUCTION_LR35902(JPHL,
 47	cpu->pc = LR35902ReadHL(cpu);
 48	cpu->memory.setActiveRegion(cpu, cpu->pc);)
 49
 50DEFINE_INSTRUCTION_LR35902(JRFinish,
 51	if (cpu->condition) {
 52		cpu->pc += (int8_t) cpu->bus;
 53		cpu->memory.setActiveRegion(cpu, cpu->pc);
 54		cpu->executionState = LR35902_CORE_STALL;
 55	})
 56
 57#define DEFINE_JR_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
 58	DEFINE_INSTRUCTION_LR35902(JR ## CONDITION_NAME, \
 59		cpu->executionState = LR35902_CORE_READ_PC; \
 60		cpu->instruction = _LR35902InstructionJRFinish; \
 61		cpu->condition = CONDITION;)
 62
 63DEFINE_CONDITIONAL_INSTRUCTION_LR35902(JR);
 64
 65DEFINE_INSTRUCTION_LR35902(CALLFinish,
 66	if (cpu->condition) {
 67		cpu->pc = (cpu->bus << 8) | cpu->index;
 68		cpu->memory.setActiveRegion(cpu, cpu->pc);
 69		cpu->executionState = LR35902_CORE_STALL;
 70	})
 71
 72DEFINE_INSTRUCTION_LR35902(CALLUpdatePC,
 73	cpu->executionState = LR35902_CORE_READ_PC;
 74	cpu->index = cpu->bus;
 75	cpu->instruction = _LR35902InstructionCALLFinish;)
 76
 77DEFINE_INSTRUCTION_LR35902(CALLUpdateSPL,
 78	cpu->executionState = LR35902_CORE_READ_PC; \
 79	cpu->instruction = _LR35902InstructionCALLUpdatePC;)
 80
 81DEFINE_INSTRUCTION_LR35902(CALLUpdateSPH,
 82	cpu->index = cpu->sp + 1;
 83	cpu->bus = (cpu->pc + 2) >> 8;
 84	cpu->executionState = LR35902_CORE_MEMORY_STORE;
 85	cpu->instruction = _LR35902InstructionCALLUpdateSPL;)
 86
 87#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
 88	DEFINE_INSTRUCTION_LR35902(CALL ## CONDITION_NAME, \
 89		cpu->condition = CONDITION; \
 90		if (CONDITION) { \
 91			cpu->sp -= 2; /* TODO: Atomic incrementing? */ \
 92			cpu->index = cpu->sp; \
 93			cpu->bus = cpu->pc + 2; \
 94			cpu->executionState = LR35902_CORE_MEMORY_STORE; \
 95			cpu->instruction = _LR35902InstructionCALLUpdateSPH; \
 96		} else { \
 97			cpu->executionState = LR35902_CORE_READ_PC; \
 98			cpu->instruction = _LR35902InstructionCALLUpdatePC; \
 99		})
100
101DEFINE_CONDITIONAL_INSTRUCTION_LR35902(CALL)
102
103DEFINE_INSTRUCTION_LR35902(RETUpdateSPL,
104	cpu->pc |= cpu->bus << 8;
105	cpu->sp += 2;  /* TODO: Atomic incrementing? */
106	cpu->memory.setActiveRegion(cpu, cpu->pc);
107	cpu->executionState = LR35902_CORE_STALL;)
108
109DEFINE_INSTRUCTION_LR35902(RETUpdateSPH,
110	if (cpu->condition) {
111		cpu->index = cpu->sp + 1;
112		cpu->pc = cpu->bus;
113		cpu->executionState = LR35902_CORE_MEMORY_LOAD;
114		cpu->instruction = _LR35902InstructionRETUpdateSPL;
115	})
116
117#define DEFINE_RET_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
118	DEFINE_INSTRUCTION_LR35902(RET ## CONDITION_NAME, \
119		cpu->condition = CONDITION; \
120		cpu->index = cpu->sp; \
121		cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
122		cpu->instruction = _LR35902InstructionRETUpdateSPH;)
123
124DEFINE_CONDITIONAL_INSTRUCTION_LR35902(RET)
125
126#define DEFINE_AND_INSTRUCTION_LR35902(NAME, OPERAND) \
127	DEFINE_INSTRUCTION_LR35902(AND ## NAME, \
128		cpu->a &= OPERAND; \
129		cpu->f.z = !cpu->a; \
130		cpu->f.n = 0; \
131		cpu->f.c = 0; \
132		cpu->f.h = 1;)
133
134#define DEFINE_XOR_INSTRUCTION_LR35902(NAME, OPERAND) \
135	DEFINE_INSTRUCTION_LR35902(XOR ## NAME, \
136		cpu->a ^= OPERAND; \
137		cpu->f.z = !cpu->a; \
138		cpu->f.n = 0; \
139		cpu->f.c = 0; \
140		cpu->f.h = 0;)
141
142#define DEFINE_OR_INSTRUCTION_LR35902(NAME, OPERAND) \
143	DEFINE_INSTRUCTION_LR35902(OR ## NAME, \
144		cpu->a |= OPERAND; \
145		cpu->f.z = !cpu->a; \
146		cpu->f.n = 0; \
147		cpu->f.c = 0; \
148		cpu->f.h = 0;)
149
150#define DEFINE_CP_INSTRUCTION_LR35902(NAME, OPERAND) \
151	DEFINE_INSTRUCTION_LR35902(CP ## NAME, \
152		int diff = cpu->a - OPERAND; \
153		cpu->f.n = 1; \
154		cpu->f.z = !diff; \
155		cpu->f.c = diff < 0; \
156		/* TODO: Find explanation of H flag */)
157
158#define DEFINE_LDB__INSTRUCTION_LR35902(NAME, OPERAND) \
159	DEFINE_INSTRUCTION_LR35902(LDB_ ## NAME, \
160		cpu->b = OPERAND;)
161
162#define DEFINE_LDC__INSTRUCTION_LR35902(NAME, OPERAND) \
163	DEFINE_INSTRUCTION_LR35902(LDC_ ## NAME, \
164		cpu->c = OPERAND;)
165
166#define DEFINE_LDD__INSTRUCTION_LR35902(NAME, OPERAND) \
167	DEFINE_INSTRUCTION_LR35902(LDD_ ## NAME, \
168		cpu->d = OPERAND;)
169
170#define DEFINE_LDE__INSTRUCTION_LR35902(NAME, OPERAND) \
171	DEFINE_INSTRUCTION_LR35902(LDE_ ## NAME, \
172		cpu->e = OPERAND;)
173
174#define DEFINE_LDH__INSTRUCTION_LR35902(NAME, OPERAND) \
175	DEFINE_INSTRUCTION_LR35902(LDH_ ## NAME, \
176		cpu->h = OPERAND;)
177
178#define DEFINE_LDL__INSTRUCTION_LR35902(NAME, OPERAND) \
179	DEFINE_INSTRUCTION_LR35902(LDL_ ## NAME, \
180		cpu->l = OPERAND;)
181
182#define DEFINE_LDHL__INSTRUCTION_LR35902(NAME, OPERAND) \
183	DEFINE_INSTRUCTION_LR35902(LDHL_ ## NAME, \
184		cpu->bus = OPERAND; \
185		cpu->executionState = LR35902_CORE_MEMORY_STORE; \
186		cpu->instruction = _LR35902InstructionLDHL_Bus;)
187
188#define DEFINE_LDA__INSTRUCTION_LR35902(NAME, OPERAND) \
189	DEFINE_INSTRUCTION_LR35902(LDA_ ## NAME, \
190		cpu->a = OPERAND;)
191
192#define DEFINE_ALU_INSTRUCTION_LR35902_NOHL(NAME) \
193	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(A, cpu->a); \
194	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(B, cpu->b); \
195	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, cpu->c); \
196	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(D, cpu->d); \
197	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(E, cpu->e); \
198	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(H, cpu->h); \
199	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(L, cpu->l);
200
201DEFINE_INSTRUCTION_LR35902(LDHL_Bus, \
202	cpu->index = LR35902ReadHL(cpu); \
203	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
204	cpu->instruction = _LR35902InstructionNOP;)
205
206DEFINE_INSTRUCTION_LR35902(LDHL_, \
207	cpu->executionState = LR35902_CORE_READ_PC; \
208	cpu->instruction = _LR35902InstructionLDHL_Bus;)
209
210#define DEFINE_ALU_INSTRUCTION_LR35902_MEM(NAME, REG) \
211	DEFINE_INSTRUCTION_LR35902(NAME ## REG, \
212		cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
213		cpu->index = LR35902Read ## REG (cpu); \
214		cpu->instruction = _LR35902Instruction ## NAME ## Bus;)
215
216#define DEFINE_ALU_INSTRUCTION_LR35902(NAME) \
217	DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Bus, cpu->bus); \
218	DEFINE_ALU_INSTRUCTION_LR35902_MEM(NAME, HL) \
219	DEFINE_INSTRUCTION_LR35902(NAME, \
220		cpu->executionState = LR35902_CORE_READ_PC; \
221		cpu->instruction = _LR35902Instruction ## NAME ## Bus;) \
222	DEFINE_ALU_INSTRUCTION_LR35902_NOHL(NAME)
223
224DEFINE_ALU_INSTRUCTION_LR35902(AND);
225DEFINE_ALU_INSTRUCTION_LR35902(XOR);
226DEFINE_ALU_INSTRUCTION_LR35902(OR);
227DEFINE_ALU_INSTRUCTION_LR35902(CP);
228
229static void _LR35902InstructionLDB_Bus(struct LR35902Core*);
230static void _LR35902InstructionLDC_Bus(struct LR35902Core*);
231static void _LR35902InstructionLDD_Bus(struct LR35902Core*);
232static void _LR35902InstructionLDE_Bus(struct LR35902Core*);
233static void _LR35902InstructionLDH_Bus(struct LR35902Core*);
234static void _LR35902InstructionLDL_Bus(struct LR35902Core*);
235static void _LR35902InstructionLDHL_Bus(struct LR35902Core*);
236static void _LR35902InstructionLDA_Bus(struct LR35902Core*);
237
238DEFINE_ALU_INSTRUCTION_LR35902(LDB_);
239DEFINE_ALU_INSTRUCTION_LR35902(LDC_);
240DEFINE_ALU_INSTRUCTION_LR35902(LDD_);
241DEFINE_ALU_INSTRUCTION_LR35902(LDE_);
242DEFINE_ALU_INSTRUCTION_LR35902(LDH_);
243DEFINE_ALU_INSTRUCTION_LR35902(LDL_);
244DEFINE_ALU_INSTRUCTION_LR35902_NOHL(LDHL_);
245DEFINE_ALU_INSTRUCTION_LR35902(LDA_);
246DEFINE_ALU_INSTRUCTION_LR35902_MEM(LDA_, BC);
247DEFINE_ALU_INSTRUCTION_LR35902_MEM(LDA_, DE);
248
249DEFINE_INSTRUCTION_LR35902(LDBCDelay, \
250	cpu->c = cpu->bus; \
251	cpu->executionState = LR35902_CORE_READ_PC; \
252	cpu->instruction = _LR35902InstructionLDB_Bus;)
253
254DEFINE_INSTRUCTION_LR35902(LDBC, \
255	cpu->executionState = LR35902_CORE_READ_PC; \
256	cpu->instruction = _LR35902InstructionLDBCDelay;)
257
258DEFINE_INSTRUCTION_LR35902(LDBC_A, \
259	cpu->index = LR35902ReadBC(cpu); \
260	cpu->bus = cpu->a; \
261	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
262	cpu->instruction = _LR35902InstructionNOP;)
263
264DEFINE_INSTRUCTION_LR35902(LDDEDelay, \
265	cpu->e = cpu->bus; \
266	cpu->executionState = LR35902_CORE_READ_PC; \
267	cpu->instruction = _LR35902InstructionLDD_Bus;)
268
269DEFINE_INSTRUCTION_LR35902(LDDE, \
270	cpu->executionState = LR35902_CORE_READ_PC; \
271	cpu->instruction = _LR35902InstructionLDDEDelay;)
272
273DEFINE_INSTRUCTION_LR35902(LDDE_A, \
274	cpu->index = LR35902ReadDE(cpu); \
275	cpu->bus = cpu->a; \
276	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
277	cpu->instruction = _LR35902InstructionNOP;)
278
279DEFINE_INSTRUCTION_LR35902(LDHLDelay, \
280	cpu->l = cpu->bus; \
281	cpu->executionState = LR35902_CORE_READ_PC; \
282	cpu->instruction = _LR35902InstructionLDH_Bus;)
283
284DEFINE_INSTRUCTION_LR35902(LDHL, \
285	cpu->executionState = LR35902_CORE_READ_PC; \
286	cpu->instruction = _LR35902InstructionLDHLDelay;)
287
288DEFINE_INSTRUCTION_LR35902(LDSPFinish, cpu->sp |= cpu->bus << 8;)
289
290DEFINE_INSTRUCTION_LR35902(LDSPDelay, \
291	cpu->sp = cpu->bus; \
292	cpu->executionState = LR35902_CORE_READ_PC; \
293	cpu->instruction = _LR35902InstructionLDSPFinish;)
294
295DEFINE_INSTRUCTION_LR35902(LDSP, \
296	cpu->executionState = LR35902_CORE_READ_PC; \
297	cpu->instruction = _LR35902InstructionLDSPDelay;)
298
299DEFINE_INSTRUCTION_LR35902(LDIHLA, \
300	cpu->index = LR35902ReadHL(cpu); \
301	LR35902WriteHL(cpu, cpu->index + 1); \
302	cpu->bus = cpu->a; \
303	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
304	cpu->instruction = _LR35902InstructionNOP;)
305
306DEFINE_INSTRUCTION_LR35902(LDDHLA, \
307	cpu->index = LR35902ReadHL(cpu); \
308	LR35902WriteHL(cpu, cpu->index - 1); \
309	cpu->bus = cpu->a; \
310	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
311	cpu->instruction = _LR35902InstructionNOP;)
312
313DEFINE_INSTRUCTION_LR35902(LDA_IHL, \
314	cpu->index = LR35902ReadHL(cpu); \
315	LR35902WriteHL(cpu, cpu->index + 1); \
316	cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
317	cpu->instruction = _LR35902InstructionLDA_Bus;)
318
319DEFINE_INSTRUCTION_LR35902(LDA_DHL, \
320	cpu->index = LR35902ReadHL(cpu); \
321	LR35902WriteHL(cpu, cpu->index - 1); \
322	cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
323	cpu->instruction = _LR35902InstructionLDA_Bus;)
324
325DEFINE_INSTRUCTION_LR35902(LDIAFinish, \
326	cpu->index |= cpu->bus << 8;
327	cpu->bus = cpu->a; \
328	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
329	cpu->instruction = _LR35902InstructionNOP;)
330
331DEFINE_INSTRUCTION_LR35902(LDIADelay, \
332	cpu->index = cpu->bus;
333	cpu->executionState = LR35902_CORE_READ_PC; \
334	cpu->instruction = _LR35902InstructionLDIAFinish;)
335
336DEFINE_INSTRUCTION_LR35902(LDIA, \
337	cpu->executionState = LR35902_CORE_READ_PC; \
338	cpu->instruction = _LR35902InstructionLDIADelay;)
339
340DEFINE_INSTRUCTION_LR35902(LDAIFinish, \
341	cpu->index |= cpu->bus << 8;
342	cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
343	cpu->instruction = _LR35902InstructionLDA_Bus;)
344
345DEFINE_INSTRUCTION_LR35902(LDAIDelay, \
346	cpu->index = cpu->bus;
347	cpu->executionState = LR35902_CORE_READ_PC; \
348	cpu->instruction = _LR35902InstructionLDAIFinish;)
349
350DEFINE_INSTRUCTION_LR35902(LDAI, \
351	cpu->executionState = LR35902_CORE_READ_PC; \
352	cpu->instruction = _LR35902InstructionLDAIDelay;)
353
354DEFINE_INSTRUCTION_LR35902(LDAIOC, \
355	cpu->index = 0xFF00 | cpu->c; \
356	cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
357	cpu->instruction = _LR35902InstructionLDA_Bus;)
358
359DEFINE_INSTRUCTION_LR35902(LDIOCA, \
360	cpu->index = 0xFF00 | cpu->c; \
361	cpu->bus = cpu->a; \
362	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
363	cpu->instruction = _LR35902InstructionNOP;)
364
365DEFINE_INSTRUCTION_LR35902(LDAIODelay, \
366	cpu->index = 0xFF00 | cpu->bus; \
367	cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
368	cpu->instruction = _LR35902InstructionLDA_Bus;)
369
370DEFINE_INSTRUCTION_LR35902(LDAIO, \
371	cpu->executionState = LR35902_CORE_READ_PC; \
372	cpu->instruction = _LR35902InstructionLDAIODelay;)
373
374DEFINE_INSTRUCTION_LR35902(LDIOADelay, \
375	cpu->index = 0xFF00 | cpu->bus; \
376	cpu->bus = cpu->a; \
377	cpu->executionState = LR35902_CORE_MEMORY_STORE; \
378	cpu->instruction = _LR35902InstructionNOP;)
379
380DEFINE_INSTRUCTION_LR35902(LDIOA, \
381	cpu->executionState = LR35902_CORE_READ_PC; \
382	cpu->instruction = _LR35902InstructionLDIOADelay;)
383
384#define DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(REG) \
385	DEFINE_INSTRUCTION_LR35902(INC ## REG, \
386		uint16_t reg = LR35902Read ## REG (cpu); \
387		LR35902Write ## REG (cpu, reg + 1); \
388		cpu->executionState = LR35902_CORE_STALL;) \
389	DEFINE_INSTRUCTION_LR35902(DEC ## REG, \
390		uint16_t reg = LR35902Read ## REG (cpu); \
391		LR35902Write ## REG (cpu, reg - 1); \
392		cpu->executionState = LR35902_CORE_STALL;)
393
394DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(BC);
395DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(DE);
396DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(HL);
397
398
399#define DEFINE_INC_INSTRUCTION_LR35902(NAME, OPERAND) \
400	DEFINE_INSTRUCTION_LR35902(INC ## NAME, \
401		int diff = OPERAND + 1; \
402		OPERAND = diff; \
403		cpu->f.n = 0; \
404		cpu->f.z = !diff; \
405		/* TODO: Find explanation of H flag */)
406
407#define DEFINE_DEC_INSTRUCTION_LR35902(NAME, OPERAND) \
408	DEFINE_INSTRUCTION_LR35902(DEC ## NAME, \
409		int diff = OPERAND - 1; \
410		OPERAND = diff; \
411		cpu->f.n = 1; \
412		cpu->f.z = !diff; \
413		/* TODO: Find explanation of H flag */)
414
415DEFINE_ALU_INSTRUCTION_LR35902_NOHL(INC);
416DEFINE_ALU_INSTRUCTION_LR35902_NOHL(DEC);
417
418DEFINE_INSTRUCTION_LR35902(INC_HLDelay,
419	int diff = cpu->bus + 1;
420	cpu->bus = diff;
421	cpu->f.n = 0;
422	cpu->f.z = !diff;
423	/* TODO: Find explanation of H flag */
424	cpu->instruction = _LR35902InstructionNOP;
425	cpu->executionState = LR35902_CORE_MEMORY_STORE;)
426
427DEFINE_INSTRUCTION_LR35902(INC_HL,
428	cpu->index = LR35902ReadHL(cpu);
429	cpu->instruction = _LR35902InstructionINC_HLDelay;
430	cpu->executionState = LR35902_CORE_MEMORY_LOAD;)
431
432DEFINE_INSTRUCTION_LR35902(DEC_HLDelay,
433	int diff = cpu->bus - 1;
434	cpu->bus = diff;
435	cpu->f.n = 1;
436	cpu->f.z = !diff;
437	/* TODO: Find explanation of H flag */
438	cpu->instruction = _LR35902InstructionNOP;
439	cpu->executionState = LR35902_CORE_MEMORY_STORE;)
440
441DEFINE_INSTRUCTION_LR35902(DEC_HL,
442	cpu->index = LR35902ReadHL(cpu);
443	cpu->instruction = _LR35902InstructionDEC_HLDelay;
444	cpu->executionState = LR35902_CORE_MEMORY_LOAD;)
445
446DEFINE_INSTRUCTION_LR35902(INCSP,
447	++cpu->sp;
448	cpu->executionState = LR35902_CORE_STALL;)
449
450DEFINE_INSTRUCTION_LR35902(DECSP,
451	--cpu->sp;
452	cpu->executionState = LR35902_CORE_STALL;)
453
454
455#define DEFINE_POPPUSH_INSTRUCTION_LR35902(REG, HH, H, L) \
456	DEFINE_INSTRUCTION_LR35902(POP ## REG ## Delay, \
457		cpu-> L = cpu->bus; \
458		cpu->index = cpu->sp; \
459		++cpu->sp; \
460		cpu->instruction = _LR35902InstructionLD ## HH ## _Bus; \
461		cpu->executionState = LR35902_CORE_MEMORY_LOAD;) \
462	DEFINE_INSTRUCTION_LR35902(POP ## REG, \
463		cpu->index = cpu->sp; \
464		++cpu->sp; \
465		cpu->instruction = _LR35902InstructionPOP ## REG ## Delay; \
466		cpu->executionState = LR35902_CORE_MEMORY_LOAD;) \
467	DEFINE_INSTRUCTION_LR35902(PUSH ## REG ## Finish, \
468		cpu->instruction = _LR35902InstructionNOP; \
469		cpu->executionState = LR35902_CORE_STALL;) \
470	DEFINE_INSTRUCTION_LR35902(PUSH ## REG ## Delay, \
471		--cpu->sp; \
472		cpu->index = cpu->sp; \
473		cpu->bus = cpu-> L; \
474		cpu->instruction = _LR35902InstructionPUSH ## REG ## Finish; \
475		cpu->executionState = LR35902_CORE_MEMORY_STORE;) \
476	DEFINE_INSTRUCTION_LR35902(PUSH ## REG, \
477		--cpu->sp; \
478		cpu->index = cpu->sp; \
479		cpu->bus = cpu-> H; \
480		cpu->instruction = _LR35902InstructionPUSH ## REG ## Delay; \
481		cpu->executionState = LR35902_CORE_MEMORY_STORE;)
482
483DEFINE_POPPUSH_INSTRUCTION_LR35902(BC, B, b, c);
484DEFINE_POPPUSH_INSTRUCTION_LR35902(DE, D, d, e);
485DEFINE_POPPUSH_INSTRUCTION_LR35902(HL, H, h, l);
486DEFINE_POPPUSH_INSTRUCTION_LR35902(AF, A, a, f.packed);
487
488DEFINE_INSTRUCTION_LR35902(DI, cpu->irqh.setInterrupts(cpu, false));
489DEFINE_INSTRUCTION_LR35902(EI, cpu->irqh.setInterrupts(cpu, true));
490
491DEFINE_INSTRUCTION_LR35902(STUB, cpu->irqh.hitStub(cpu));
492
493static const LR35902Instruction _lr35902CBInstructionTable[0x100] = {
494	DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Instruction)
495};
496
497DEFINE_INSTRUCTION_LR35902(CBDelegate, _lr35902CBInstructionTable[cpu->bus](cpu))
498
499DEFINE_INSTRUCTION_LR35902(CB, \
500	cpu->executionState = LR35902_CORE_READ_PC; \
501	cpu->instruction = _LR35902InstructionCBDelegate;)
502
503const LR35902Instruction _lr35902InstructionTable[0x100] = {
504	DECLARE_LR35902_EMITTER_BLOCK(_LR35902Instruction)
505};