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 <mgba/internal/sm83/isa-sm83.h>
7 
8 #include <mgba/internal/sm83/emitter-sm83.h>
9 #include <mgba/internal/sm83/sm83.h>
10 
SM83ReadHL(struct SM83Core * cpu)11 static inline uint16_t SM83ReadHL(struct SM83Core* cpu) {
12 	return cpu->hl;
13 }
14 
SM83WriteHL(struct SM83Core * cpu,uint16_t hl)15 static inline void SM83WriteHL(struct SM83Core* cpu, uint16_t hl) {
16 	cpu->hl = hl;
17 }
18 
SM83ReadBC(struct SM83Core * cpu)19 static inline uint16_t SM83ReadBC(struct SM83Core* cpu) {
20 	return cpu->bc;
21 }
22 
SM83WriteBC(struct SM83Core * cpu,uint16_t bc)23 static inline void SM83WriteBC(struct SM83Core* cpu, uint16_t bc) {
24 	cpu->bc = bc;
25 }
26 
SM83ReadDE(struct SM83Core * cpu)27 static inline uint16_t SM83ReadDE(struct SM83Core* cpu) {
28 	return cpu->de;
29 }
30 
SM83WriteDE(struct SM83Core * cpu,uint16_t de)31 static inline void SM83WriteDE(struct SM83Core* cpu, uint16_t de) {
32 	cpu->de = de;
33 }
34 
35 #define DEFINE_INSTRUCTION_SM83(NAME, BODY) \
36 	static void _SM83Instruction ## NAME (struct SM83Core* cpu) { \
37 		UNUSED(cpu); \
38 		BODY; \
39 	}
40 
41 DEFINE_INSTRUCTION_SM83(NOP,);
42 
43 #define DEFINE_CONDITIONAL_ONLY_INSTRUCTION_SM83(NAME) \
44 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(C, cpu->f.c) \
45 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(Z, cpu->f.z) \
46 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(NC, !cpu->f.c) \
47 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(NZ, !cpu->f.z)
48 
49 #define DEFINE_CONDITIONAL_INSTRUCTION_SM83(NAME) \
50 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(, true) \
51 	DEFINE_CONDITIONAL_ONLY_INSTRUCTION_SM83(NAME)
52 
53 DEFINE_INSTRUCTION_SM83(JPFinish,
54 	if (cpu->condition) {
55 		cpu->pc = (cpu->bus << 8) | cpu->index;
56 		cpu->memory.setActiveRegion(cpu, cpu->pc);
57 		cpu->executionState = SM83_CORE_STALL;
58 	})
59 
60 DEFINE_INSTRUCTION_SM83(JPDelay,
61 	cpu->executionState = SM83_CORE_READ_PC;
62 	cpu->instruction = _SM83InstructionJPFinish;
63 	cpu->index = cpu->bus;)
64 
65 #define DEFINE_JP_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
66 	DEFINE_INSTRUCTION_SM83(JP ## CONDITION_NAME, \
67 		cpu->executionState = SM83_CORE_READ_PC; \
68 		cpu->instruction = _SM83InstructionJPDelay; \
69 		cpu->condition = CONDITION;)
70 
71 DEFINE_CONDITIONAL_INSTRUCTION_SM83(JP);
72 
73 DEFINE_INSTRUCTION_SM83(JPHL,
74 	cpu->pc = cpu->hl;
75 	cpu->memory.setActiveRegion(cpu, cpu->pc);)
76 
77 DEFINE_INSTRUCTION_SM83(JRFinish,
78 	if (cpu->condition) {
79 		cpu->pc += (int8_t) cpu->bus;
80 		cpu->memory.setActiveRegion(cpu, cpu->pc);
81 		cpu->executionState = SM83_CORE_STALL;
82 	})
83 
84 #define DEFINE_JR_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
85 	DEFINE_INSTRUCTION_SM83(JR ## CONDITION_NAME, \
86 		cpu->executionState = SM83_CORE_READ_PC; \
87 		cpu->instruction = _SM83InstructionJRFinish; \
88 		cpu->condition = CONDITION;)
89 
90 DEFINE_CONDITIONAL_INSTRUCTION_SM83(JR);
91 
92 DEFINE_INSTRUCTION_SM83(CALLUpdateSPL,
93 	--cpu->index;
94 	cpu->bus = cpu->sp;
95 	cpu->sp = cpu->index;
96 	cpu->executionState = SM83_CORE_MEMORY_STORE;
97 	cpu->instruction = _SM83InstructionNOP;)
98 
99 DEFINE_INSTRUCTION_SM83(CALLUpdateSPH,
100 	cpu->executionState = SM83_CORE_MEMORY_STORE;
101 	cpu->instruction = _SM83InstructionCALLUpdateSPL;)
102 
103 DEFINE_INSTRUCTION_SM83(CALLUpdatePCH,
104 	if (cpu->condition) {
105 		int newPc = (cpu->bus << 8) | cpu->index;
106 		cpu->bus = cpu->pc >> 8;
107 		cpu->index = cpu->sp - 1;
108 		cpu->sp = cpu->pc; // GROSS
109 		cpu->pc = newPc;
110 		cpu->memory.setActiveRegion(cpu, cpu->pc);
111 		cpu->executionState = SM83_CORE_OP2;
112 		cpu->instruction = _SM83InstructionCALLUpdateSPH;
113 	})
114 
115 DEFINE_INSTRUCTION_SM83(CALLUpdatePCL,
116 	cpu->executionState = SM83_CORE_READ_PC;
117 	cpu->index = cpu->bus;
118 	cpu->instruction = _SM83InstructionCALLUpdatePCH)
119 
120 #define DEFINE_CALL_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
121 	DEFINE_INSTRUCTION_SM83(CALL ## CONDITION_NAME, \
122 		cpu->condition = CONDITION; \
123 		cpu->executionState = SM83_CORE_READ_PC; \
124 		cpu->instruction = _SM83InstructionCALLUpdatePCL;)
125 
126 DEFINE_CONDITIONAL_INSTRUCTION_SM83(CALL)
127 
128 DEFINE_INSTRUCTION_SM83(RETFinish,
129 	cpu->sp += 2;  /* TODO: Atomic incrementing? */
130 	cpu->pc |= cpu->bus << 8;
131 	cpu->memory.setActiveRegion(cpu, cpu->pc);
132 	cpu->executionState = SM83_CORE_STALL;)
133 
134 DEFINE_INSTRUCTION_SM83(RETUpdateSPL,
135 	cpu->index = cpu->sp + 1;
136 	cpu->pc = cpu->bus;
137 	cpu->executionState = SM83_CORE_MEMORY_LOAD;
138 	cpu->instruction = _SM83InstructionRETFinish;)
139 
140 DEFINE_INSTRUCTION_SM83(RETUpdateSPH,
141 	if (cpu->condition) {
142 		cpu->index = cpu->sp;
143 		cpu->executionState = SM83_CORE_MEMORY_LOAD;
144 		cpu->instruction = _SM83InstructionRETUpdateSPL;
145 	})
146 
147 #define DEFINE_RET_INSTRUCTION_SM83(CONDITION_NAME, CONDITION) \
148 	DEFINE_INSTRUCTION_SM83(RET ## CONDITION_NAME, \
149 		cpu->condition = CONDITION; \
150 		cpu->executionState = SM83_CORE_OP2; \
151 		cpu->instruction = _SM83InstructionRETUpdateSPH;)
152 
153 DEFINE_INSTRUCTION_SM83(RET,
154 	cpu->condition = true;
155 	_SM83InstructionRETUpdateSPH(cpu);)
156 
157 DEFINE_INSTRUCTION_SM83(RETI,
158 	cpu->condition = true;
159 	cpu->irqh.setInterrupts(cpu, true);
160 	_SM83InstructionRETUpdateSPH(cpu);)
161 
162 DEFINE_CONDITIONAL_ONLY_INSTRUCTION_SM83(RET)
163 
164 #define DEFINE_AND_INSTRUCTION_SM83(NAME, OPERAND) \
165 	DEFINE_INSTRUCTION_SM83(AND ## NAME, \
166 		cpu->a &= OPERAND; \
167 		cpu->f.z = !cpu->a; \
168 		cpu->f.n = 0; \
169 		cpu->f.c = 0; \
170 		cpu->f.h = 1;)
171 
172 #define DEFINE_XOR_INSTRUCTION_SM83(NAME, OPERAND) \
173 	DEFINE_INSTRUCTION_SM83(XOR ## NAME, \
174 		cpu->a ^= OPERAND; \
175 		cpu->f.z = !cpu->a; \
176 		cpu->f.n = 0; \
177 		cpu->f.c = 0; \
178 		cpu->f.h = 0;)
179 
180 #define DEFINE_OR_INSTRUCTION_SM83(NAME, OPERAND) \
181 	DEFINE_INSTRUCTION_SM83(OR ## NAME, \
182 		cpu->a |= OPERAND; \
183 		cpu->f.z = !cpu->a; \
184 		cpu->f.n = 0; \
185 		cpu->f.c = 0; \
186 		cpu->f.h = 0;)
187 
188 #define DEFINE_CP_INSTRUCTION_SM83(NAME, OPERAND) \
189 	DEFINE_INSTRUCTION_SM83(CP ## NAME, \
190 		int diff = cpu->a - OPERAND; \
191 		cpu->f.n = 1; \
192 		cpu->f.z = !(diff & 0xFF); \
193 		cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \
194 		cpu->f.c = diff < 0;)
195 
196 #define DEFINE_LDB__INSTRUCTION_SM83(NAME, OPERAND) \
197 	DEFINE_INSTRUCTION_SM83(LDB_ ## NAME, \
198 		cpu->b = OPERAND;)
199 
200 #define DEFINE_LDC__INSTRUCTION_SM83(NAME, OPERAND) \
201 	DEFINE_INSTRUCTION_SM83(LDC_ ## NAME, \
202 		cpu->c = OPERAND;)
203 
204 #define DEFINE_LDD__INSTRUCTION_SM83(NAME, OPERAND) \
205 	DEFINE_INSTRUCTION_SM83(LDD_ ## NAME, \
206 		cpu->d = OPERAND;)
207 
208 #define DEFINE_LDE__INSTRUCTION_SM83(NAME, OPERAND) \
209 	DEFINE_INSTRUCTION_SM83(LDE_ ## NAME, \
210 		cpu->e = OPERAND;)
211 
212 #define DEFINE_LDH__INSTRUCTION_SM83(NAME, OPERAND) \
213 	DEFINE_INSTRUCTION_SM83(LDH_ ## NAME, \
214 		cpu->h = OPERAND;)
215 
216 #define DEFINE_LDL__INSTRUCTION_SM83(NAME, OPERAND) \
217 	DEFINE_INSTRUCTION_SM83(LDL_ ## NAME, \
218 		cpu->l = OPERAND;)
219 
220 #define DEFINE_LDHL__INSTRUCTION_SM83(NAME, OPERAND) \
221 	DEFINE_INSTRUCTION_SM83(LDHL_ ## NAME, \
222 		cpu->bus = OPERAND; \
223 		cpu->index = cpu->hl; \
224 		cpu->executionState = SM83_CORE_MEMORY_STORE; \
225 		cpu->instruction = _SM83InstructionNOP;)
226 
227 #define DEFINE_LDA__INSTRUCTION_SM83(NAME, OPERAND) \
228 	DEFINE_INSTRUCTION_SM83(LDA_ ## NAME, \
229 		cpu->a = OPERAND;)
230 
231 #define DEFINE_ALU_INSTRUCTION_SM83_NOHL(NAME) \
232 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(A, cpu->a); \
233 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(B, cpu->b); \
234 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(C, cpu->c); \
235 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(D, cpu->d); \
236 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(E, cpu->e); \
237 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(H, cpu->h); \
238 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(L, cpu->l);
239 
240 DEFINE_INSTRUCTION_SM83(LDHL_Bus, \
241 	cpu->index = cpu->hl; \
242 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
243 	cpu->instruction = _SM83InstructionNOP;)
244 
245 DEFINE_INSTRUCTION_SM83(LDHL_, \
246 	cpu->executionState = SM83_CORE_READ_PC; \
247 	cpu->instruction = _SM83InstructionLDHL_Bus;)
248 
249 DEFINE_INSTRUCTION_SM83(LDHL_SPDelay,
250 	int diff = (int8_t) cpu->bus;
251 	int sum = cpu->sp + diff;
252 	SM83WriteHL(cpu, sum);
253 	cpu->executionState = SM83_CORE_STALL;
254 	cpu->f.z = 0;
255 	cpu->f.n = 0;
256 	cpu->f.c = (diff & 0xFF) + (cpu->sp & 0xFF) >= 0x100;
257 	cpu->f.h = (diff & 0xF) + (cpu->sp & 0xF) >= 0x10;)
258 
259 DEFINE_INSTRUCTION_SM83(LDHL_SP,
260 	cpu->executionState = SM83_CORE_READ_PC;
261 	cpu->instruction = _SM83InstructionLDHL_SPDelay;)
262 
263 DEFINE_INSTRUCTION_SM83(LDSP_HL,
264 	cpu->sp = cpu->hl;
265 	cpu->executionState = SM83_CORE_STALL;)
266 
267 #define DEFINE_ALU_INSTRUCTION_SM83_MEM(NAME, REG) \
268 	DEFINE_INSTRUCTION_SM83(NAME ## REG, \
269 		cpu->executionState = SM83_CORE_MEMORY_LOAD; \
270 		cpu->index = SM83Read ## REG (cpu); \
271 		cpu->instruction = _SM83Instruction ## NAME ## Bus;)
272 
273 #define DEFINE_ALU_INSTRUCTION_SM83(NAME) \
274 	DEFINE_ ## NAME ## _INSTRUCTION_SM83(Bus, cpu->bus); \
275 	DEFINE_ALU_INSTRUCTION_SM83_MEM(NAME, HL) \
276 	DEFINE_INSTRUCTION_SM83(NAME, \
277 		cpu->executionState = SM83_CORE_READ_PC; \
278 		cpu->instruction = _SM83Instruction ## NAME ## Bus;) \
279 	DEFINE_ALU_INSTRUCTION_SM83_NOHL(NAME)
280 
281 DEFINE_ALU_INSTRUCTION_SM83(AND);
282 DEFINE_ALU_INSTRUCTION_SM83(XOR);
283 DEFINE_ALU_INSTRUCTION_SM83(OR);
284 DEFINE_ALU_INSTRUCTION_SM83(CP);
285 
286 static void _SM83InstructionLDB_Bus(struct SM83Core*);
287 static void _SM83InstructionLDC_Bus(struct SM83Core*);
288 static void _SM83InstructionLDD_Bus(struct SM83Core*);
289 static void _SM83InstructionLDE_Bus(struct SM83Core*);
290 static void _SM83InstructionLDH_Bus(struct SM83Core*);
291 static void _SM83InstructionLDL_Bus(struct SM83Core*);
292 static void _SM83InstructionLDHL_Bus(struct SM83Core*);
293 static void _SM83InstructionLDA_Bus(struct SM83Core*);
294 
295 #define DEFINE_ADD_INSTRUCTION_SM83(NAME, OPERAND) \
296 	DEFINE_INSTRUCTION_SM83(ADD ## NAME, \
297 		int diff = cpu->a + OPERAND; \
298 		cpu->f.n = 0; \
299 		cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) >= 0x10; \
300 		cpu->f.c = diff >= 0x100; \
301 		cpu->a = diff; \
302 		cpu->f.z = !cpu->a;)
303 
304 #define DEFINE_ADC_INSTRUCTION_SM83(NAME, OPERAND) \
305 	DEFINE_INSTRUCTION_SM83(ADC ## NAME, \
306 		int diff = cpu->a + OPERAND + cpu->f.c; \
307 		cpu->f.n = 0; \
308 		cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) + cpu->f.c >= 0x10; \
309 		cpu->f.c = diff >= 0x100; \
310 		cpu->a = diff; \
311 		cpu->f.z = !cpu->a;)
312 
313 #define DEFINE_SUB_INSTRUCTION_SM83(NAME, OPERAND) \
314 	DEFINE_INSTRUCTION_SM83(SUB ## NAME, \
315 		int diff = cpu->a - OPERAND; \
316 		cpu->f.n = 1; \
317 		cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \
318 		cpu->f.c = diff < 0; \
319 		cpu->a = diff; \
320 		cpu->f.z = !cpu->a;)
321 
322 #define DEFINE_SBC_INSTRUCTION_SM83(NAME, OPERAND) \
323 	DEFINE_INSTRUCTION_SM83(SBC ## NAME, \
324 		int diff = cpu->a - OPERAND - cpu->f.c; \
325 		cpu->f.n = 1; \
326 		cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) - cpu->f.c < 0; \
327 		cpu->f.c = diff < 0; \
328 		cpu->a = diff; \
329 		cpu->f.z = !cpu->a;)
330 
331 DEFINE_ALU_INSTRUCTION_SM83(LDB_);
332 DEFINE_ALU_INSTRUCTION_SM83(LDC_);
333 DEFINE_ALU_INSTRUCTION_SM83(LDD_);
334 DEFINE_ALU_INSTRUCTION_SM83(LDE_);
335 DEFINE_ALU_INSTRUCTION_SM83(LDH_);
336 DEFINE_ALU_INSTRUCTION_SM83(LDL_);
337 DEFINE_ALU_INSTRUCTION_SM83_NOHL(LDHL_);
338 DEFINE_ALU_INSTRUCTION_SM83(LDA_);
339 DEFINE_ALU_INSTRUCTION_SM83_MEM(LDA_, BC);
340 DEFINE_ALU_INSTRUCTION_SM83_MEM(LDA_, DE);
341 DEFINE_ALU_INSTRUCTION_SM83(ADD);
342 DEFINE_ALU_INSTRUCTION_SM83(ADC);
343 DEFINE_ALU_INSTRUCTION_SM83(SUB);
344 DEFINE_ALU_INSTRUCTION_SM83(SBC);
345 
346 DEFINE_INSTRUCTION_SM83(ADDSPFinish,
347 	cpu->sp = cpu->index;
348 	cpu->executionState = SM83_CORE_STALL;)
349 
350 DEFINE_INSTRUCTION_SM83(ADDSPDelay,
351 	int diff = (int8_t) cpu->bus;
352 	int sum = cpu->sp + diff;
353 	cpu->index = sum;
354 	cpu->executionState = SM83_CORE_OP2;
355 	cpu->instruction = _SM83InstructionADDSPFinish;
356 	cpu->f.z = 0;
357 	cpu->f.n = 0;
358 	cpu->f.c = (diff & 0xFF) + (cpu->sp & 0xFF) >= 0x100;
359 	cpu->f.h = (diff & 0xF) + (cpu->sp & 0xF) >= 0x10;)
360 
361 DEFINE_INSTRUCTION_SM83(ADDSP,
362 	cpu->executionState = SM83_CORE_READ_PC;
363 	cpu->instruction = _SM83InstructionADDSPDelay;)
364 
365 DEFINE_INSTRUCTION_SM83(LDBCDelay, \
366 	cpu->c = cpu->bus; \
367 	cpu->executionState = SM83_CORE_READ_PC; \
368 	cpu->instruction = _SM83InstructionLDB_Bus;)
369 
370 DEFINE_INSTRUCTION_SM83(LDBC, \
371 	cpu->executionState = SM83_CORE_READ_PC; \
372 	cpu->instruction = _SM83InstructionLDBCDelay;)
373 
374 DEFINE_INSTRUCTION_SM83(LDBC_A, \
375 	cpu->index = cpu->bc; \
376 	cpu->bus = cpu->a; \
377 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
378 	cpu->instruction = _SM83InstructionNOP;)
379 
380 DEFINE_INSTRUCTION_SM83(LDDEDelay, \
381 	cpu->e = cpu->bus; \
382 	cpu->executionState = SM83_CORE_READ_PC; \
383 	cpu->instruction = _SM83InstructionLDD_Bus;)
384 
385 DEFINE_INSTRUCTION_SM83(LDDE, \
386 	cpu->executionState = SM83_CORE_READ_PC; \
387 	cpu->instruction = _SM83InstructionLDDEDelay;)
388 
389 DEFINE_INSTRUCTION_SM83(LDDE_A, \
390 	cpu->index = cpu->de; \
391 	cpu->bus = cpu->a; \
392 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
393 	cpu->instruction = _SM83InstructionNOP;)
394 
395 DEFINE_INSTRUCTION_SM83(LDHLDelay, \
396 	cpu->l = cpu->bus; \
397 	cpu->executionState = SM83_CORE_READ_PC; \
398 	cpu->instruction = _SM83InstructionLDH_Bus;)
399 
400 DEFINE_INSTRUCTION_SM83(LDHL, \
401 	cpu->executionState = SM83_CORE_READ_PC; \
402 	cpu->instruction = _SM83InstructionLDHLDelay;)
403 
404 DEFINE_INSTRUCTION_SM83(LDSPFinish, cpu->sp |= cpu->bus << 8;)
405 
406 DEFINE_INSTRUCTION_SM83(LDSPDelay, \
407 	cpu->sp = cpu->bus; \
408 	cpu->executionState = SM83_CORE_READ_PC; \
409 	cpu->instruction = _SM83InstructionLDSPFinish;)
410 
411 DEFINE_INSTRUCTION_SM83(LDSP, \
412 	cpu->executionState = SM83_CORE_READ_PC; \
413 	cpu->instruction = _SM83InstructionLDSPDelay;)
414 
415 DEFINE_INSTRUCTION_SM83(LDIHLA, \
416 	cpu->index = cpu->hl; \
417 	SM83WriteHL(cpu, cpu->index + 1); \
418 	cpu->bus = cpu->a; \
419 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
420 	cpu->instruction = _SM83InstructionNOP;)
421 
422 DEFINE_INSTRUCTION_SM83(LDDHLA, \
423 	cpu->index = cpu->hl; \
424 	SM83WriteHL(cpu, cpu->index - 1); \
425 	cpu->bus = cpu->a; \
426 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
427 	cpu->instruction = _SM83InstructionNOP;)
428 
429 DEFINE_INSTRUCTION_SM83(LDA_IHL, \
430 	cpu->index = cpu->hl; \
431 	SM83WriteHL(cpu, cpu->index + 1); \
432 	cpu->executionState = SM83_CORE_MEMORY_LOAD; \
433 	cpu->instruction = _SM83InstructionLDA_Bus;)
434 
435 DEFINE_INSTRUCTION_SM83(LDA_DHL, \
436 	cpu->index = cpu->hl; \
437 	SM83WriteHL(cpu, cpu->index - 1); \
438 	cpu->executionState = SM83_CORE_MEMORY_LOAD; \
439 	cpu->instruction = _SM83InstructionLDA_Bus;)
440 
441 DEFINE_INSTRUCTION_SM83(LDIAFinish, \
442 	cpu->index |= cpu->bus << 8;
443 	cpu->bus = cpu->a; \
444 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
445 	cpu->instruction = _SM83InstructionNOP;)
446 
447 DEFINE_INSTRUCTION_SM83(LDIADelay, \
448 	cpu->index = cpu->bus;
449 	cpu->executionState = SM83_CORE_READ_PC; \
450 	cpu->instruction = _SM83InstructionLDIAFinish;)
451 
452 DEFINE_INSTRUCTION_SM83(LDIA, \
453 	cpu->executionState = SM83_CORE_READ_PC; \
454 	cpu->instruction = _SM83InstructionLDIADelay;)
455 
456 DEFINE_INSTRUCTION_SM83(LDAIFinish, \
457 	cpu->index |= cpu->bus << 8;
458 	cpu->executionState = SM83_CORE_MEMORY_LOAD; \
459 	cpu->instruction = _SM83InstructionLDA_Bus;)
460 
461 DEFINE_INSTRUCTION_SM83(LDAIDelay, \
462 	cpu->index = cpu->bus;
463 	cpu->executionState = SM83_CORE_READ_PC; \
464 	cpu->instruction = _SM83InstructionLDAIFinish;)
465 
466 DEFINE_INSTRUCTION_SM83(LDAI, \
467 	cpu->executionState = SM83_CORE_READ_PC; \
468 	cpu->instruction = _SM83InstructionLDAIDelay;)
469 
470 DEFINE_INSTRUCTION_SM83(LDAIOC, \
471 	cpu->index = 0xFF00 | cpu->c; \
472 	cpu->executionState = SM83_CORE_MEMORY_LOAD; \
473 	cpu->instruction = _SM83InstructionLDA_Bus;)
474 
475 DEFINE_INSTRUCTION_SM83(LDIOCA, \
476 	cpu->index = 0xFF00 | cpu->c; \
477 	cpu->bus = cpu->a; \
478 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
479 	cpu->instruction = _SM83InstructionNOP;)
480 
481 DEFINE_INSTRUCTION_SM83(LDAIODelay, \
482 	cpu->index = 0xFF00 | cpu->bus; \
483 	cpu->executionState = SM83_CORE_MEMORY_LOAD; \
484 	cpu->instruction = _SM83InstructionLDA_Bus;)
485 
486 DEFINE_INSTRUCTION_SM83(LDAIO, \
487 	cpu->executionState = SM83_CORE_READ_PC; \
488 	cpu->instruction = _SM83InstructionLDAIODelay;)
489 
490 DEFINE_INSTRUCTION_SM83(LDIOADelay, \
491 	cpu->index = 0xFF00 | cpu->bus; \
492 	cpu->bus = cpu->a; \
493 	cpu->executionState = SM83_CORE_MEMORY_STORE; \
494 	cpu->instruction = _SM83InstructionNOP;)
495 
496 DEFINE_INSTRUCTION_SM83(LDIOA, \
497 	cpu->executionState = SM83_CORE_READ_PC; \
498 	cpu->instruction = _SM83InstructionLDIOADelay;)
499 
500 DEFINE_INSTRUCTION_SM83(LDISPStoreH,
501 	++cpu->index;
502 	cpu->bus = cpu->sp >> 8;
503 	cpu->executionState = SM83_CORE_MEMORY_STORE;
504 	cpu->instruction = _SM83InstructionNOP;)
505 
506 DEFINE_INSTRUCTION_SM83(LDISPStoreL,
507 	cpu->index |= cpu->bus << 8;
508 	cpu->bus = cpu->sp;
509 	cpu->executionState = SM83_CORE_MEMORY_STORE;
510 	cpu->instruction = _SM83InstructionLDISPStoreH;)
511 
512 DEFINE_INSTRUCTION_SM83(LDISPReadAddr,
513 	cpu->index = cpu->bus;
514 	cpu->executionState = SM83_CORE_READ_PC;
515 	cpu->instruction = _SM83InstructionLDISPStoreL;)
516 
517 DEFINE_INSTRUCTION_SM83(LDISP,
518 	cpu->executionState = SM83_CORE_READ_PC;
519 	cpu->instruction = _SM83InstructionLDISPReadAddr;)
520 
521 #define DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(REG) \
522 	DEFINE_INSTRUCTION_SM83(INC ## REG, \
523 		uint16_t reg = SM83Read ## REG (cpu); \
524 		SM83Write ## REG (cpu, reg + 1); \
525 		cpu->executionState = SM83_CORE_STALL;) \
526 	DEFINE_INSTRUCTION_SM83(DEC ## REG, \
527 		uint16_t reg = SM83Read ## REG (cpu); \
528 		SM83Write ## REG (cpu, reg - 1); \
529 		cpu->executionState = SM83_CORE_STALL;)
530 
531 DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(BC);
532 DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(DE);
533 DEFINE_INCDEC_WIDE_INSTRUCTION_SM83(HL);
534 
535 #define DEFINE_ADD_HL_INSTRUCTION_SM83(REG, L, H) \
536 	DEFINE_INSTRUCTION_SM83(ADDHL_ ## REG ## Finish, \
537 		int diff = H + cpu->h + cpu->f.c; \
538 		cpu->f.n = 0; \
539 		cpu->f.h = (H & 0xF) + (cpu->h & 0xF) + cpu->f.c >= 0x10; \
540 		cpu->f.c = diff >= 0x100; \
541 		cpu->h = diff;) \
542 	DEFINE_INSTRUCTION_SM83(ADDHL_ ## REG, \
543 		int diff = L + cpu->l; \
544 		cpu->l = diff; \
545 		cpu->f.c = diff >= 0x100; \
546 		cpu->executionState = SM83_CORE_OP2; \
547 		cpu->instruction = _SM83InstructionADDHL_ ## REG ## Finish;)
548 
549 DEFINE_ADD_HL_INSTRUCTION_SM83(BC, cpu->c, cpu->b);
550 DEFINE_ADD_HL_INSTRUCTION_SM83(DE, cpu->e, cpu->d);
551 DEFINE_ADD_HL_INSTRUCTION_SM83(HL, cpu->l, cpu->h);
552 DEFINE_ADD_HL_INSTRUCTION_SM83(SP, (cpu->sp & 0xFF), (cpu->sp >> 8));
553 
554 
555 #define DEFINE_INC_INSTRUCTION_SM83(NAME, OPERAND) \
556 	DEFINE_INSTRUCTION_SM83(INC ## NAME, \
557 		int diff = OPERAND + 1; \
558 		cpu->f.h = (OPERAND & 0xF) == 0xF; \
559 		OPERAND = diff; \
560 		cpu->f.n = 0; \
561 		cpu->f.z = !OPERAND;)
562 
563 #define DEFINE_DEC_INSTRUCTION_SM83(NAME, OPERAND) \
564 	DEFINE_INSTRUCTION_SM83(DEC ## NAME, \
565 		int diff = OPERAND - 1; \
566 		cpu->f.h = (OPERAND & 0xF) == 0x0; \
567 		OPERAND = diff; \
568 		cpu->f.n = 1; \
569 		cpu->f.z = !OPERAND;)
570 
571 DEFINE_ALU_INSTRUCTION_SM83_NOHL(INC);
572 DEFINE_ALU_INSTRUCTION_SM83_NOHL(DEC);
573 
574 DEFINE_INSTRUCTION_SM83(INC_HLDelay,
575 	int diff = cpu->bus + 1;
576 	cpu->f.n = 0;
577 	cpu->f.h = (cpu->bus & 0xF) == 0xF;
578 	cpu->bus = diff;
579 	cpu->f.z = !cpu->bus;
580 	cpu->instruction = _SM83InstructionNOP;
581 	cpu->executionState = SM83_CORE_MEMORY_STORE;)
582 
583 DEFINE_INSTRUCTION_SM83(INC_HL,
584 	cpu->index = cpu->hl;
585 	cpu->instruction = _SM83InstructionINC_HLDelay;
586 	cpu->executionState = SM83_CORE_MEMORY_LOAD;)
587 
588 DEFINE_INSTRUCTION_SM83(DEC_HLDelay,
589 	int diff = cpu->bus - 1;
590 	cpu->f.n = 1;
591 	cpu->f.h = (cpu->bus & 0xF) == 0;
592 	cpu->bus = diff;
593 	cpu->f.z = !cpu->bus;
594 	cpu->instruction = _SM83InstructionNOP;
595 	cpu->executionState = SM83_CORE_MEMORY_STORE;)
596 
597 DEFINE_INSTRUCTION_SM83(DEC_HL,
598 	cpu->index = cpu->hl;
599 	cpu->instruction = _SM83InstructionDEC_HLDelay;
600 	cpu->executionState = SM83_CORE_MEMORY_LOAD;)
601 
602 DEFINE_INSTRUCTION_SM83(INCSP,
603 	++cpu->sp;
604 	cpu->executionState = SM83_CORE_STALL;)
605 
606 DEFINE_INSTRUCTION_SM83(DECSP,
607 	--cpu->sp;
608 	cpu->executionState = SM83_CORE_STALL;)
609 
610 DEFINE_INSTRUCTION_SM83(SCF,
611 	cpu->f.c = 1;
612 	cpu->f.h = 0;
613 	cpu->f.n = 0;)
614 
615 DEFINE_INSTRUCTION_SM83(CCF,
616 	cpu->f.c ^= 1;
617 	cpu->f.h = 0;
618 	cpu->f.n = 0;)
619 
620 DEFINE_INSTRUCTION_SM83(CPL_,
621 	cpu->a ^= 0xFF;
622 	cpu->f.h = 1;
623 	cpu->f.n = 1;)
624 
625 DEFINE_INSTRUCTION_SM83(DAA,
626 	if (cpu->f.n) {
627 		if (cpu->f.h) {
628 			cpu->a += 0xFA;
629 		}
630 		if (cpu->f.c) {
631 			cpu->a += 0xA0;
632 		}
633 	} else {
634 		int a = cpu->a;
635 		if ((cpu->a & 0xF) > 0x9 || cpu->f.h) {
636 			a += 0x6;
637 		}
638 		if ((a & 0x1F0) > 0x90 || cpu->f.c) {
639 			a += 0x60;
640 			cpu->f.c = 1;
641 		} else {
642 			cpu->f.c = 0;
643 		}
644 		cpu->a = a;
645 	}
646 	cpu->f.h = 0;
647 	cpu->f.z = !cpu->a;)
648 
649 #define DEFINE_POPPUSH_INSTRUCTION_SM83(REG, HH, H, L) \
650 	DEFINE_INSTRUCTION_SM83(POP ## REG ## Delay, \
651 		cpu-> L = cpu->bus; \
652 		cpu->f.packed &= 0xF0; \
653 		cpu->index = cpu->sp; \
654 		++cpu->sp; \
655 		cpu->instruction = _SM83InstructionLD ## HH ## _Bus; \
656 		cpu->executionState = SM83_CORE_MEMORY_LOAD;) \
657 	DEFINE_INSTRUCTION_SM83(POP ## REG, \
658 		cpu->index = cpu->sp; \
659 		++cpu->sp; \
660 		cpu->instruction = _SM83InstructionPOP ## REG ## Delay; \
661 		cpu->executionState = SM83_CORE_MEMORY_LOAD;) \
662 	DEFINE_INSTRUCTION_SM83(PUSH ## REG ## Finish, \
663 		cpu->executionState = SM83_CORE_STALL;) \
664 	DEFINE_INSTRUCTION_SM83(PUSH ## REG ## Delay, \
665 		--cpu->sp; \
666 		cpu->index = cpu->sp; \
667 		cpu->bus = cpu-> L; \
668 		cpu->instruction = _SM83InstructionPUSH ## REG ## Finish; \
669 		cpu->executionState = SM83_CORE_MEMORY_STORE;) \
670 	DEFINE_INSTRUCTION_SM83(PUSH ## REG, \
671 		--cpu->sp; \
672 		cpu->index = cpu->sp; \
673 		cpu->bus = cpu-> H; \
674 		cpu->instruction = _SM83InstructionPUSH ## REG ## Delay; \
675 		cpu->executionState = SM83_CORE_MEMORY_STORE;)
676 
677 DEFINE_POPPUSH_INSTRUCTION_SM83(BC, B, b, c);
678 DEFINE_POPPUSH_INSTRUCTION_SM83(DE, D, d, e);
679 DEFINE_POPPUSH_INSTRUCTION_SM83(HL, H, h, l);
680 DEFINE_POPPUSH_INSTRUCTION_SM83(AF, A, a, f.packed);
681 
682 #define DEFINE_CB_2_INSTRUCTION_SM83(NAME, WB, BODY) \
683 	DEFINE_INSTRUCTION_SM83(NAME ## B, uint8_t reg = cpu->b; BODY; cpu->b = reg) \
684 	DEFINE_INSTRUCTION_SM83(NAME ## C, uint8_t reg = cpu->c; BODY; cpu->c = reg) \
685 	DEFINE_INSTRUCTION_SM83(NAME ## D, uint8_t reg = cpu->d; BODY; cpu->d = reg) \
686 	DEFINE_INSTRUCTION_SM83(NAME ## E, uint8_t reg = cpu->e; BODY; cpu->e = reg) \
687 	DEFINE_INSTRUCTION_SM83(NAME ## H, uint8_t reg = cpu->h; BODY; cpu->h = reg) \
688 	DEFINE_INSTRUCTION_SM83(NAME ## L, uint8_t reg = cpu->l; BODY; cpu->l = reg) \
689 	DEFINE_INSTRUCTION_SM83(NAME ## HLDelay, \
690 		uint8_t reg = cpu->bus; \
691 		BODY; \
692 		cpu->bus = reg; \
693 		cpu->executionState = WB; \
694 		cpu->instruction = _SM83InstructionNOP;) \
695 	DEFINE_INSTRUCTION_SM83(NAME ## HL, \
696 		cpu->index = cpu->hl; \
697 		cpu->executionState = SM83_CORE_MEMORY_LOAD; \
698 		cpu->instruction = _SM83Instruction ## NAME ## HLDelay;) \
699 	DEFINE_INSTRUCTION_SM83(NAME ## A, uint8_t reg = cpu->a; BODY; cpu->a = reg)
700 
701 #define DEFINE_CB_INSTRUCTION_SM83(NAME, WB, BODY) \
702 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 0, WB, uint8_t bit = 1; BODY) \
703 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 1, WB, uint8_t bit = 2; BODY) \
704 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 2, WB, uint8_t bit = 4; BODY) \
705 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 3, WB, uint8_t bit = 8; BODY) \
706 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 4, WB, uint8_t bit = 16; BODY) \
707 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 5, WB, uint8_t bit = 32; BODY) \
708 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 6, WB, uint8_t bit = 64; BODY) \
709 	DEFINE_CB_2_INSTRUCTION_SM83(NAME ## 7, WB, uint8_t bit = 128; BODY)
710 
711 DEFINE_CB_INSTRUCTION_SM83(BIT, SM83_CORE_FETCH, cpu->f.n = 0; cpu->f.h = 1; cpu->f.z = !(reg & bit))
712 DEFINE_CB_INSTRUCTION_SM83(RES, SM83_CORE_MEMORY_STORE, reg &= ~bit)
713 DEFINE_CB_INSTRUCTION_SM83(SET, SM83_CORE_MEMORY_STORE, reg |= bit)
714 
715 #define DEFINE_CB_ALU_INSTRUCTION_SM83(NAME, BODY) \
716 	DEFINE_CB_2_INSTRUCTION_SM83(NAME, SM83_CORE_MEMORY_STORE, \
717 		BODY; \
718 		cpu->f.n = 0; \
719 		cpu->f.h = 0; \
720 		cpu->f.z = !reg;)
721 
722 DEFINE_CB_ALU_INSTRUCTION_SM83(RL, int wide = (reg << 1) | cpu->f.c; reg = wide; cpu->f.c = wide >> 8)
723 DEFINE_CB_ALU_INSTRUCTION_SM83(RLC, reg = (reg << 1) | (reg >> 7); cpu->f.c = reg & 1)
724 DEFINE_CB_ALU_INSTRUCTION_SM83(RR, int low = reg & 1; reg = (reg >> 1) | (cpu->f.c << 7); cpu->f.c = low)
725 DEFINE_CB_ALU_INSTRUCTION_SM83(RRC, int low = reg & 1; reg = (reg >> 1) | (low << 7); cpu->f.c = low)
726 DEFINE_CB_ALU_INSTRUCTION_SM83(SLA, cpu->f.c = reg >> 7; reg <<= 1)
727 DEFINE_CB_ALU_INSTRUCTION_SM83(SRA, cpu->f.c = reg & 1; reg = ((int8_t) reg) >> 1)
728 DEFINE_CB_ALU_INSTRUCTION_SM83(SRL, cpu->f.c = reg & 1; reg >>= 1)
729 DEFINE_CB_ALU_INSTRUCTION_SM83(SWAP, reg = (reg << 4) | (reg >> 4); cpu->f.c = 0)
730 
731 DEFINE_INSTRUCTION_SM83(RLA_,
732 	int wide = (cpu->a << 1) | cpu->f.c;
733 	cpu->a = wide;
734 	cpu->f.z = 0;
735 	cpu->f.h = 0;
736 	cpu->f.n = 0;
737 	cpu->f.c = wide >> 8;)
738 
739 DEFINE_INSTRUCTION_SM83(RLCA_,
740 	cpu->a = (cpu->a << 1) | (cpu->a >> 7);
741 	cpu->f.z = 0;
742 	cpu->f.h = 0;
743 	cpu->f.n = 0;
744 	cpu->f.c = cpu->a & 1;)
745 
746 DEFINE_INSTRUCTION_SM83(RRA_,
747 	int low = cpu->a & 1;
748 	cpu->a = (cpu->a >> 1) | (cpu->f.c << 7);
749 	cpu->f.z = 0;
750 	cpu->f.h = 0;
751 	cpu->f.n = 0;
752 	cpu->f.c = low;)
753 
754 DEFINE_INSTRUCTION_SM83(RRCA_,
755 	int low = cpu->a & 1;
756 	cpu->a = (cpu->a >> 1) | (low << 7);
757 	cpu->f.z = 0;
758 	cpu->f.h = 0;
759 	cpu->f.n = 0;
760 	cpu->f.c = low;)
761 
762 DEFINE_INSTRUCTION_SM83(DI, cpu->irqh.setInterrupts(cpu, false));
763 DEFINE_INSTRUCTION_SM83(EI, cpu->irqh.setInterrupts(cpu, true));
764 DEFINE_INSTRUCTION_SM83(HALT,
765 	cpu->irqh.halt(cpu);
766 	// XXX: Subtract the cycles that will be added later in the tick function
767 	cpu->cycles -= cpu->tMultiplier;);
768 
769 #define DEFINE_RST_INSTRUCTION_SM83(VEC) \
770 	DEFINE_INSTRUCTION_SM83(RST ## VEC ## UpdateSPL, \
771 		--cpu->sp; \
772 		cpu->index = cpu->sp; \
773 		cpu->bus = cpu->pc; \
774 		cpu->pc = 0x ## VEC; \
775 		cpu->memory.setActiveRegion(cpu, cpu->pc); \
776 		cpu->executionState = SM83_CORE_MEMORY_STORE; \
777 		cpu->instruction = _SM83InstructionNOP;) \
778 	DEFINE_INSTRUCTION_SM83(RST ## VEC ## UpdateSPH, \
779 		--cpu->sp;\
780 		cpu->index = cpu->sp; \
781 		cpu->bus = cpu->pc >> 8; \
782 		cpu->executionState = SM83_CORE_MEMORY_STORE; \
783 		cpu->instruction = _SM83InstructionRST ## VEC ## UpdateSPL;) \
784 	DEFINE_INSTRUCTION_SM83(RST ## VEC, \
785 		cpu->executionState = SM83_CORE_OP2; \
786 		cpu->instruction = _SM83InstructionRST ## VEC ## UpdateSPH;)
787 
788 DEFINE_RST_INSTRUCTION_SM83(00);
789 DEFINE_RST_INSTRUCTION_SM83(08);
790 DEFINE_RST_INSTRUCTION_SM83(10);
791 DEFINE_RST_INSTRUCTION_SM83(18);
792 DEFINE_RST_INSTRUCTION_SM83(20);
793 DEFINE_RST_INSTRUCTION_SM83(28);
794 DEFINE_RST_INSTRUCTION_SM83(30);
795 DEFINE_RST_INSTRUCTION_SM83(38);
796 
797 DEFINE_INSTRUCTION_SM83(ILL, cpu->irqh.hitIllegal(cpu));
798 
799 DEFINE_INSTRUCTION_SM83(STOP2, cpu->irqh.stop(cpu));
800 
801 DEFINE_INSTRUCTION_SM83(STOP, \
802 	cpu->executionState = SM83_CORE_READ_PC; \
803 	cpu->instruction = _SM83InstructionSTOP2;)
804 
805 static const SM83Instruction _sm83CBInstructionTable[0x100] = {
806 	DECLARE_SM83_CB_EMITTER_BLOCK(_SM83Instruction)
807 };
808 
809 DEFINE_INSTRUCTION_SM83(CBDelegate, _sm83CBInstructionTable[cpu->bus](cpu))
810 
811 DEFINE_INSTRUCTION_SM83(CB, \
812 	cpu->executionState = SM83_CORE_READ_PC; \
813 	cpu->instruction = _SM83InstructionCBDelegate;)
814 
815 const SM83Instruction _sm83InstructionTable[0x100] = {
816 	DECLARE_SM83_EMITTER_BLOCK(_SM83Instruction)
817 };
818