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_INSTRUCTION_LR35902(RETI,
125 cpu->condition = true;
126 cpu->index = cpu->sp;
127 cpu->executionState = LR35902_CORE_MEMORY_LOAD;
128 cpu->irqh.setInterrupts(cpu, true);
129 cpu->instruction = _LR35902InstructionRETUpdateSPH;)
130
131DEFINE_CONDITIONAL_INSTRUCTION_LR35902(RET)
132
133#define DEFINE_AND_INSTRUCTION_LR35902(NAME, OPERAND) \
134 DEFINE_INSTRUCTION_LR35902(AND ## NAME, \
135 cpu->a &= OPERAND; \
136 cpu->f.z = !cpu->a; \
137 cpu->f.n = 0; \
138 cpu->f.c = 0; \
139 cpu->f.h = 1;)
140
141#define DEFINE_XOR_INSTRUCTION_LR35902(NAME, OPERAND) \
142 DEFINE_INSTRUCTION_LR35902(XOR ## NAME, \
143 cpu->a ^= OPERAND; \
144 cpu->f.z = !cpu->a; \
145 cpu->f.n = 0; \
146 cpu->f.c = 0; \
147 cpu->f.h = 0;)
148
149#define DEFINE_OR_INSTRUCTION_LR35902(NAME, OPERAND) \
150 DEFINE_INSTRUCTION_LR35902(OR ## NAME, \
151 cpu->a |= OPERAND; \
152 cpu->f.z = !cpu->a; \
153 cpu->f.n = 0; \
154 cpu->f.c = 0; \
155 cpu->f.h = 0;)
156
157#define DEFINE_CP_INSTRUCTION_LR35902(NAME, OPERAND) \
158 DEFINE_INSTRUCTION_LR35902(CP ## NAME, \
159 int diff = cpu->a - OPERAND; \
160 cpu->f.n = 1; \
161 cpu->f.z = !diff; \
162 cpu->f.c = diff < 0; \
163 /* TODO: Find explanation of H flag */)
164
165#define DEFINE_LDB__INSTRUCTION_LR35902(NAME, OPERAND) \
166 DEFINE_INSTRUCTION_LR35902(LDB_ ## NAME, \
167 cpu->b = OPERAND;)
168
169#define DEFINE_LDC__INSTRUCTION_LR35902(NAME, OPERAND) \
170 DEFINE_INSTRUCTION_LR35902(LDC_ ## NAME, \
171 cpu->c = OPERAND;)
172
173#define DEFINE_LDD__INSTRUCTION_LR35902(NAME, OPERAND) \
174 DEFINE_INSTRUCTION_LR35902(LDD_ ## NAME, \
175 cpu->d = OPERAND;)
176
177#define DEFINE_LDE__INSTRUCTION_LR35902(NAME, OPERAND) \
178 DEFINE_INSTRUCTION_LR35902(LDE_ ## NAME, \
179 cpu->e = OPERAND;)
180
181#define DEFINE_LDH__INSTRUCTION_LR35902(NAME, OPERAND) \
182 DEFINE_INSTRUCTION_LR35902(LDH_ ## NAME, \
183 cpu->h = OPERAND;)
184
185#define DEFINE_LDL__INSTRUCTION_LR35902(NAME, OPERAND) \
186 DEFINE_INSTRUCTION_LR35902(LDL_ ## NAME, \
187 cpu->l = OPERAND;)
188
189#define DEFINE_LDHL__INSTRUCTION_LR35902(NAME, OPERAND) \
190 DEFINE_INSTRUCTION_LR35902(LDHL_ ## NAME, \
191 cpu->bus = OPERAND; \
192 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
193 cpu->instruction = _LR35902InstructionLDHL_Bus;)
194
195#define DEFINE_LDA__INSTRUCTION_LR35902(NAME, OPERAND) \
196 DEFINE_INSTRUCTION_LR35902(LDA_ ## NAME, \
197 cpu->a = OPERAND;)
198
199#define DEFINE_ALU_INSTRUCTION_LR35902_NOHL(NAME) \
200 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(A, cpu->a); \
201 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(B, cpu->b); \
202 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(C, cpu->c); \
203 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(D, cpu->d); \
204 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(E, cpu->e); \
205 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(H, cpu->h); \
206 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(L, cpu->l);
207
208DEFINE_INSTRUCTION_LR35902(LDHL_Bus, \
209 cpu->index = LR35902ReadHL(cpu); \
210 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
211 cpu->instruction = _LR35902InstructionNOP;)
212
213DEFINE_INSTRUCTION_LR35902(LDHL_, \
214 cpu->executionState = LR35902_CORE_READ_PC; \
215 cpu->instruction = _LR35902InstructionLDHL_Bus;)
216
217#define DEFINE_ALU_INSTRUCTION_LR35902_MEM(NAME, REG) \
218 DEFINE_INSTRUCTION_LR35902(NAME ## REG, \
219 cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
220 cpu->index = LR35902Read ## REG (cpu); \
221 cpu->instruction = _LR35902Instruction ## NAME ## Bus;)
222
223#define DEFINE_ALU_INSTRUCTION_LR35902(NAME) \
224 DEFINE_ ## NAME ## _INSTRUCTION_LR35902(Bus, cpu->bus); \
225 DEFINE_ALU_INSTRUCTION_LR35902_MEM(NAME, HL) \
226 DEFINE_INSTRUCTION_LR35902(NAME, \
227 cpu->executionState = LR35902_CORE_READ_PC; \
228 cpu->instruction = _LR35902Instruction ## NAME ## Bus;) \
229 DEFINE_ALU_INSTRUCTION_LR35902_NOHL(NAME)
230
231DEFINE_ALU_INSTRUCTION_LR35902(AND);
232DEFINE_ALU_INSTRUCTION_LR35902(XOR);
233DEFINE_ALU_INSTRUCTION_LR35902(OR);
234DEFINE_ALU_INSTRUCTION_LR35902(CP);
235
236static void _LR35902InstructionLDB_Bus(struct LR35902Core*);
237static void _LR35902InstructionLDC_Bus(struct LR35902Core*);
238static void _LR35902InstructionLDD_Bus(struct LR35902Core*);
239static void _LR35902InstructionLDE_Bus(struct LR35902Core*);
240static void _LR35902InstructionLDH_Bus(struct LR35902Core*);
241static void _LR35902InstructionLDL_Bus(struct LR35902Core*);
242static void _LR35902InstructionLDHL_Bus(struct LR35902Core*);
243static void _LR35902InstructionLDA_Bus(struct LR35902Core*);
244
245#define DEFINE_ADD_INSTRUCTION_LR35902(NAME, OPERAND) \
246 DEFINE_INSTRUCTION_LR35902(ADD ## NAME, \
247 int diff = cpu->a + OPERAND; \
248 cpu->a = diff; \
249 cpu->f.n = 0; \
250 cpu->f.z = !diff; \
251 cpu->f.c = diff >= 0x100; \
252 /* TODO: Find explanation of H flag */)
253
254#define DEFINE_ADC_INSTRUCTION_LR35902(NAME, OPERAND) \
255 DEFINE_INSTRUCTION_LR35902(ADC ## NAME, \
256 int diff = cpu->a + OPERAND + cpu->f.c; \
257 cpu->a = diff; \
258 cpu->f.n = 0; \
259 cpu->f.z = !diff; \
260 cpu->f.c = diff > 0x100; \
261 /* TODO: Find explanation of H flag */)
262
263#define DEFINE_SUB_INSTRUCTION_LR35902(NAME, OPERAND) \
264 DEFINE_INSTRUCTION_LR35902(SUB ## NAME, \
265 int diff = cpu->a - OPERAND; \
266 cpu->a = diff; \
267 cpu->f.n = 1; \
268 cpu->f.z = !diff; \
269 cpu->f.c = diff < 0; \
270 /* TODO: Find explanation of H flag */)
271
272#define DEFINE_SBC_INSTRUCTION_LR35902(NAME, OPERAND) \
273 DEFINE_INSTRUCTION_LR35902(SBC ## NAME, \
274 int diff = cpu->a - OPERAND - cpu->f.c; \
275 cpu->a = diff; \
276 cpu->f.n = 1; \
277 cpu->f.z = !diff; \
278 cpu->f.c = diff < 0; \
279 /* TODO: Find explanation of H flag */)
280
281DEFINE_ALU_INSTRUCTION_LR35902(LDB_);
282DEFINE_ALU_INSTRUCTION_LR35902(LDC_);
283DEFINE_ALU_INSTRUCTION_LR35902(LDD_);
284DEFINE_ALU_INSTRUCTION_LR35902(LDE_);
285DEFINE_ALU_INSTRUCTION_LR35902(LDH_);
286DEFINE_ALU_INSTRUCTION_LR35902(LDL_);
287DEFINE_ALU_INSTRUCTION_LR35902_NOHL(LDHL_);
288DEFINE_ALU_INSTRUCTION_LR35902(LDA_);
289DEFINE_ALU_INSTRUCTION_LR35902_MEM(LDA_, BC);
290DEFINE_ALU_INSTRUCTION_LR35902_MEM(LDA_, DE);
291DEFINE_ALU_INSTRUCTION_LR35902(ADD);
292DEFINE_ALU_INSTRUCTION_LR35902(ADC);
293DEFINE_ALU_INSTRUCTION_LR35902(SUB);
294DEFINE_ALU_INSTRUCTION_LR35902(SBC);
295
296DEFINE_INSTRUCTION_LR35902(LDBCDelay, \
297 cpu->c = cpu->bus; \
298 cpu->executionState = LR35902_CORE_READ_PC; \
299 cpu->instruction = _LR35902InstructionLDB_Bus;)
300
301DEFINE_INSTRUCTION_LR35902(LDBC, \
302 cpu->executionState = LR35902_CORE_READ_PC; \
303 cpu->instruction = _LR35902InstructionLDBCDelay;)
304
305DEFINE_INSTRUCTION_LR35902(LDBC_A, \
306 cpu->index = LR35902ReadBC(cpu); \
307 cpu->bus = cpu->a; \
308 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
309 cpu->instruction = _LR35902InstructionNOP;)
310
311DEFINE_INSTRUCTION_LR35902(LDDEDelay, \
312 cpu->e = cpu->bus; \
313 cpu->executionState = LR35902_CORE_READ_PC; \
314 cpu->instruction = _LR35902InstructionLDD_Bus;)
315
316DEFINE_INSTRUCTION_LR35902(LDDE, \
317 cpu->executionState = LR35902_CORE_READ_PC; \
318 cpu->instruction = _LR35902InstructionLDDEDelay;)
319
320DEFINE_INSTRUCTION_LR35902(LDDE_A, \
321 cpu->index = LR35902ReadDE(cpu); \
322 cpu->bus = cpu->a; \
323 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
324 cpu->instruction = _LR35902InstructionNOP;)
325
326DEFINE_INSTRUCTION_LR35902(LDHLDelay, \
327 cpu->l = cpu->bus; \
328 cpu->executionState = LR35902_CORE_READ_PC; \
329 cpu->instruction = _LR35902InstructionLDH_Bus;)
330
331DEFINE_INSTRUCTION_LR35902(LDHL, \
332 cpu->executionState = LR35902_CORE_READ_PC; \
333 cpu->instruction = _LR35902InstructionLDHLDelay;)
334
335DEFINE_INSTRUCTION_LR35902(LDSPFinish, cpu->sp |= cpu->bus << 8;)
336
337DEFINE_INSTRUCTION_LR35902(LDSPDelay, \
338 cpu->sp = cpu->bus; \
339 cpu->executionState = LR35902_CORE_READ_PC; \
340 cpu->instruction = _LR35902InstructionLDSPFinish;)
341
342DEFINE_INSTRUCTION_LR35902(LDSP, \
343 cpu->executionState = LR35902_CORE_READ_PC; \
344 cpu->instruction = _LR35902InstructionLDSPDelay;)
345
346DEFINE_INSTRUCTION_LR35902(LDIHLA, \
347 cpu->index = LR35902ReadHL(cpu); \
348 LR35902WriteHL(cpu, cpu->index + 1); \
349 cpu->bus = cpu->a; \
350 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
351 cpu->instruction = _LR35902InstructionNOP;)
352
353DEFINE_INSTRUCTION_LR35902(LDDHLA, \
354 cpu->index = LR35902ReadHL(cpu); \
355 LR35902WriteHL(cpu, cpu->index - 1); \
356 cpu->bus = cpu->a; \
357 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
358 cpu->instruction = _LR35902InstructionNOP;)
359
360DEFINE_INSTRUCTION_LR35902(LDA_IHL, \
361 cpu->index = LR35902ReadHL(cpu); \
362 LR35902WriteHL(cpu, cpu->index + 1); \
363 cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
364 cpu->instruction = _LR35902InstructionLDA_Bus;)
365
366DEFINE_INSTRUCTION_LR35902(LDA_DHL, \
367 cpu->index = LR35902ReadHL(cpu); \
368 LR35902WriteHL(cpu, cpu->index - 1); \
369 cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
370 cpu->instruction = _LR35902InstructionLDA_Bus;)
371
372DEFINE_INSTRUCTION_LR35902(LDIAFinish, \
373 cpu->index |= cpu->bus << 8;
374 cpu->bus = cpu->a; \
375 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
376 cpu->instruction = _LR35902InstructionNOP;)
377
378DEFINE_INSTRUCTION_LR35902(LDIADelay, \
379 cpu->index = cpu->bus;
380 cpu->executionState = LR35902_CORE_READ_PC; \
381 cpu->instruction = _LR35902InstructionLDIAFinish;)
382
383DEFINE_INSTRUCTION_LR35902(LDIA, \
384 cpu->executionState = LR35902_CORE_READ_PC; \
385 cpu->instruction = _LR35902InstructionLDIADelay;)
386
387DEFINE_INSTRUCTION_LR35902(LDAIFinish, \
388 cpu->index |= cpu->bus << 8;
389 cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
390 cpu->instruction = _LR35902InstructionLDA_Bus;)
391
392DEFINE_INSTRUCTION_LR35902(LDAIDelay, \
393 cpu->index = cpu->bus;
394 cpu->executionState = LR35902_CORE_READ_PC; \
395 cpu->instruction = _LR35902InstructionLDAIFinish;)
396
397DEFINE_INSTRUCTION_LR35902(LDAI, \
398 cpu->executionState = LR35902_CORE_READ_PC; \
399 cpu->instruction = _LR35902InstructionLDAIDelay;)
400
401DEFINE_INSTRUCTION_LR35902(LDAIOC, \
402 cpu->index = 0xFF00 | cpu->c; \
403 cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
404 cpu->instruction = _LR35902InstructionLDA_Bus;)
405
406DEFINE_INSTRUCTION_LR35902(LDIOCA, \
407 cpu->index = 0xFF00 | cpu->c; \
408 cpu->bus = cpu->a; \
409 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
410 cpu->instruction = _LR35902InstructionNOP;)
411
412DEFINE_INSTRUCTION_LR35902(LDAIODelay, \
413 cpu->index = 0xFF00 | cpu->bus; \
414 cpu->executionState = LR35902_CORE_MEMORY_LOAD; \
415 cpu->instruction = _LR35902InstructionLDA_Bus;)
416
417DEFINE_INSTRUCTION_LR35902(LDAIO, \
418 cpu->executionState = LR35902_CORE_READ_PC; \
419 cpu->instruction = _LR35902InstructionLDAIODelay;)
420
421DEFINE_INSTRUCTION_LR35902(LDIOADelay, \
422 cpu->index = 0xFF00 | cpu->bus; \
423 cpu->bus = cpu->a; \
424 cpu->executionState = LR35902_CORE_MEMORY_STORE; \
425 cpu->instruction = _LR35902InstructionNOP;)
426
427DEFINE_INSTRUCTION_LR35902(LDIOA, \
428 cpu->executionState = LR35902_CORE_READ_PC; \
429 cpu->instruction = _LR35902InstructionLDIOADelay;)
430
431#define DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(REG) \
432 DEFINE_INSTRUCTION_LR35902(INC ## REG, \
433 uint16_t reg = LR35902Read ## REG (cpu); \
434 LR35902Write ## REG (cpu, reg + 1); \
435 cpu->executionState = LR35902_CORE_STALL;) \
436 DEFINE_INSTRUCTION_LR35902(DEC ## REG, \
437 uint16_t reg = LR35902Read ## REG (cpu); \
438 LR35902Write ## REG (cpu, reg - 1); \
439 cpu->executionState = LR35902_CORE_STALL;)
440
441DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(BC);
442DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(DE);
443DEFINE_INCDEC_WIDE_INSTRUCTION_LR35902(HL);
444
445#define DEFINE_ADD_HL_INSTRUCTION_LR35902(REG, L, H) \
446 DEFINE_INSTRUCTION_LR35902(ADDHL_ ## REG ## Finish, \
447 int diff = H + cpu->h + cpu->f.c; \
448 cpu->h = diff; \
449 cpu->f.c = diff >= 0x100; \
450 cpu->f.n = 0; \
451 /* TODO: Find explanation of H flag */) \
452 DEFINE_INSTRUCTION_LR35902(ADDHL_ ## REG, \
453 int diff = L + cpu->l; \
454 cpu->l = diff; \
455 cpu->f.c = diff >= 0x100; \
456 cpu->executionState = LR35902_CORE_OP2; \
457 cpu->instruction = _LR35902InstructionADDHL_ ## REG ## Finish;)
458
459DEFINE_ADD_HL_INSTRUCTION_LR35902(BC, cpu->c, cpu->b);
460DEFINE_ADD_HL_INSTRUCTION_LR35902(DE, cpu->e, cpu->d);
461DEFINE_ADD_HL_INSTRUCTION_LR35902(HL, cpu->l, cpu->h);
462DEFINE_ADD_HL_INSTRUCTION_LR35902(SP, (cpu->sp & 0xFF), (cpu->sp >> 8));
463
464
465#define DEFINE_INC_INSTRUCTION_LR35902(NAME, OPERAND) \
466 DEFINE_INSTRUCTION_LR35902(INC ## NAME, \
467 int diff = OPERAND + 1; \
468 OPERAND = diff; \
469 cpu->f.n = 0; \
470 cpu->f.z = !diff; \
471 /* TODO: Find explanation of H flag */)
472
473#define DEFINE_DEC_INSTRUCTION_LR35902(NAME, OPERAND) \
474 DEFINE_INSTRUCTION_LR35902(DEC ## NAME, \
475 int diff = OPERAND - 1; \
476 OPERAND = diff; \
477 cpu->f.n = 1; \
478 cpu->f.z = !diff; \
479 /* TODO: Find explanation of H flag */)
480
481DEFINE_ALU_INSTRUCTION_LR35902_NOHL(INC);
482DEFINE_ALU_INSTRUCTION_LR35902_NOHL(DEC);
483
484DEFINE_INSTRUCTION_LR35902(INC_HLDelay,
485 int diff = cpu->bus + 1;
486 cpu->bus = diff;
487 cpu->f.n = 0;
488 cpu->f.z = !diff;
489 /* TODO: Find explanation of H flag */
490 cpu->instruction = _LR35902InstructionNOP;
491 cpu->executionState = LR35902_CORE_MEMORY_STORE;)
492
493DEFINE_INSTRUCTION_LR35902(INC_HL,
494 cpu->index = LR35902ReadHL(cpu);
495 cpu->instruction = _LR35902InstructionINC_HLDelay;
496 cpu->executionState = LR35902_CORE_MEMORY_LOAD;)
497
498DEFINE_INSTRUCTION_LR35902(DEC_HLDelay,
499 int diff = cpu->bus - 1;
500 cpu->bus = diff;
501 cpu->f.n = 1;
502 cpu->f.z = !diff;
503 /* TODO: Find explanation of H flag */
504 cpu->instruction = _LR35902InstructionNOP;
505 cpu->executionState = LR35902_CORE_MEMORY_STORE;)
506
507DEFINE_INSTRUCTION_LR35902(DEC_HL,
508 cpu->index = LR35902ReadHL(cpu);
509 cpu->instruction = _LR35902InstructionDEC_HLDelay;
510 cpu->executionState = LR35902_CORE_MEMORY_LOAD;)
511
512DEFINE_INSTRUCTION_LR35902(INCSP,
513 ++cpu->sp;
514 cpu->executionState = LR35902_CORE_STALL;)
515
516DEFINE_INSTRUCTION_LR35902(DECSP,
517 --cpu->sp;
518 cpu->executionState = LR35902_CORE_STALL;)
519
520DEFINE_INSTRUCTION_LR35902(SCF,
521 cpu->f.c = 1;
522 cpu->f.h = 0;
523 cpu->f.n = 0;)
524
525DEFINE_INSTRUCTION_LR35902(CCF,
526 cpu->f.c ^= 1;
527 cpu->f.h = 0;
528 cpu->f.n = 0;)
529
530DEFINE_INSTRUCTION_LR35902(CPL_,
531 cpu->a ^= 0xFF;
532 cpu->f.h = 1;
533 cpu->f.n = 1;)
534
535#define DEFINE_POPPUSH_INSTRUCTION_LR35902(REG, HH, H, L) \
536 DEFINE_INSTRUCTION_LR35902(POP ## REG ## Delay, \
537 cpu-> L = cpu->bus; \
538 cpu->index = cpu->sp; \
539 ++cpu->sp; \
540 cpu->instruction = _LR35902InstructionLD ## HH ## _Bus; \
541 cpu->executionState = LR35902_CORE_MEMORY_LOAD;) \
542 DEFINE_INSTRUCTION_LR35902(POP ## REG, \
543 cpu->index = cpu->sp; \
544 ++cpu->sp; \
545 cpu->instruction = _LR35902InstructionPOP ## REG ## Delay; \
546 cpu->executionState = LR35902_CORE_MEMORY_LOAD;) \
547 DEFINE_INSTRUCTION_LR35902(PUSH ## REG ## Finish, \
548 cpu->executionState = LR35902_CORE_STALL;) \
549 DEFINE_INSTRUCTION_LR35902(PUSH ## REG ## Delay, \
550 --cpu->sp; \
551 cpu->index = cpu->sp; \
552 cpu->bus = cpu-> L; \
553 cpu->instruction = _LR35902InstructionPUSH ## REG ## Finish; \
554 cpu->executionState = LR35902_CORE_MEMORY_STORE;) \
555 DEFINE_INSTRUCTION_LR35902(PUSH ## REG, \
556 --cpu->sp; \
557 cpu->index = cpu->sp; \
558 cpu->bus = cpu-> H; \
559 cpu->instruction = _LR35902InstructionPUSH ## REG ## Delay; \
560 cpu->executionState = LR35902_CORE_MEMORY_STORE;)
561
562DEFINE_POPPUSH_INSTRUCTION_LR35902(BC, B, b, c);
563DEFINE_POPPUSH_INSTRUCTION_LR35902(DE, D, d, e);
564DEFINE_POPPUSH_INSTRUCTION_LR35902(HL, H, h, l);
565DEFINE_POPPUSH_INSTRUCTION_LR35902(AF, A, a, f.packed);
566
567DEFINE_INSTRUCTION_LR35902(DI, cpu->irqh.setInterrupts(cpu, false));
568DEFINE_INSTRUCTION_LR35902(EI, cpu->irqh.setInterrupts(cpu, true));
569DEFINE_INSTRUCTION_LR35902(HALT, cpu->cycles = cpu->nextEvent);
570
571DEFINE_INSTRUCTION_LR35902(STUB, cpu->irqh.hitStub(cpu));
572
573static const LR35902Instruction _lr35902CBInstructionTable[0x100] = {
574 DECLARE_LR35902_CB_EMITTER_BLOCK(_LR35902Instruction)
575};
576
577DEFINE_INSTRUCTION_LR35902(CBDelegate, _lr35902CBInstructionTable[cpu->bus](cpu))
578
579DEFINE_INSTRUCTION_LR35902(CB, \
580 cpu->executionState = LR35902_CORE_READ_PC; \
581 cpu->instruction = _LR35902InstructionCBDelegate;)
582
583const LR35902Instruction _lr35902InstructionTable[0x100] = {
584 DECLARE_LR35902_EMITTER_BLOCK(_LR35902Instruction)
585};