SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Core/sm83_cpu.c
1 #include <stdio.h>
2 #include <stdbool.h>
3 #include <assert.h>
4 #include "gb.h"
5
6
7 typedef void opcode_t(GB_gameboy_t *gb, uint8_t opcode);
8
9 typedef enum {
10 /* Default behavior. If the CPU writes while another component reads, it reads the old value */
11 GB_CONFLICT_READ_OLD,
12 /* If the CPU writes while another component reads, it reads the new value */
13 GB_CONFLICT_READ_NEW,
14 /* If the CPU and another component write at the same time, the CPU's value "wins" */
15 GB_CONFLICT_WRITE_CPU,
16 /* Register specific values */
17 GB_CONFLICT_STAT_CGB,
18 GB_CONFLICT_STAT_DMG,
19 GB_CONFLICT_PALETTE_DMG,
20 GB_CONFLICT_PALETTE_CGB,
21 GB_CONFLICT_DMG_LCDC,
22 GB_CONFLICT_SGB_LCDC,
23 GB_CONFLICT_WX_DMG,
24 GB_CONFLICT_LCDC_CGB,
25 GB_CONFLICT_LCDC_CGB_DOUBLE,
26 GB_CONFLICT_STAT_CGB_DOUBLE,
27 GB_CONFLICT_NR10_CGB_DOUBLE,
28 GB_CONFLICT_SCX_DMG_AND_CGB_DOUBLE,
29 } conflict_t;
30
31 static const conflict_t cgb_conflict_map[0x80] = {
32 [GB_IO_LCDC] = GB_CONFLICT_LCDC_CGB,
33 [GB_IO_IF] = GB_CONFLICT_WRITE_CPU,
34 [GB_IO_LYC] = GB_CONFLICT_WRITE_CPU,
35 [GB_IO_WY] = GB_CONFLICT_READ_OLD,
36 [GB_IO_STAT] = GB_CONFLICT_STAT_CGB,
37 [GB_IO_BGP] = GB_CONFLICT_PALETTE_CGB,
38 [GB_IO_OBP0] = GB_CONFLICT_PALETTE_CGB,
39 [GB_IO_OBP1] = GB_CONFLICT_PALETTE_CGB,
40 [GB_IO_SCX] = GB_CONFLICT_READ_OLD,
41 [GB_IO_WX] = GB_CONFLICT_WRITE_CPU,
42 };
43
44 static const conflict_t cgb_double_conflict_map[0x80] = {
45 [GB_IO_LCDC] = GB_CONFLICT_LCDC_CGB_DOUBLE,
46 [GB_IO_IF] = GB_CONFLICT_WRITE_CPU,
47 [GB_IO_LYC] = GB_CONFLICT_READ_OLD,
48 [GB_IO_WY] = GB_CONFLICT_READ_OLD,
49 [GB_IO_STAT] = GB_CONFLICT_STAT_CGB_DOUBLE,
50 [GB_IO_NR10] = GB_CONFLICT_NR10_CGB_DOUBLE,
51 [GB_IO_SCX] = GB_CONFLICT_SCX_DMG_AND_CGB_DOUBLE,
52 [GB_IO_WX] = GB_CONFLICT_READ_OLD,
53 };
54
55 /* Todo: verify on an MGB */
56 static const conflict_t dmg_conflict_map[0x80] = {
57 [GB_IO_IF] = GB_CONFLICT_WRITE_CPU,
58 [GB_IO_LYC] = GB_CONFLICT_READ_OLD,
59 [GB_IO_LCDC] = GB_CONFLICT_DMG_LCDC,
60 [GB_IO_SCY] = GB_CONFLICT_READ_NEW,
61 [GB_IO_STAT] = GB_CONFLICT_STAT_DMG,
62 [GB_IO_BGP] = GB_CONFLICT_PALETTE_DMG,
63 [GB_IO_OBP0] = GB_CONFLICT_PALETTE_DMG,
64 [GB_IO_OBP1] = GB_CONFLICT_PALETTE_DMG,
65 [GB_IO_WY] = GB_CONFLICT_READ_OLD,
66 [GB_IO_WX] = GB_CONFLICT_WX_DMG,
67 [GB_IO_SCX] = GB_CONFLICT_SCX_DMG_AND_CGB_DOUBLE,
68 };
69
70 /* Todo: Verify on an SGB1 */
71 static const conflict_t sgb_conflict_map[0x80] = {
72 [GB_IO_IF] = GB_CONFLICT_WRITE_CPU,
73 [GB_IO_LYC] = GB_CONFLICT_READ_OLD,
74 [GB_IO_LCDC] = GB_CONFLICT_SGB_LCDC,
75 [GB_IO_SCY] = GB_CONFLICT_READ_NEW,
76 [GB_IO_STAT] = GB_CONFLICT_STAT_DMG,
77 [GB_IO_BGP] = GB_CONFLICT_READ_NEW,
78 [GB_IO_OBP0] = GB_CONFLICT_READ_NEW,
79 [GB_IO_OBP1] = GB_CONFLICT_READ_NEW,
80 [GB_IO_WY] = GB_CONFLICT_READ_OLD,
81 [GB_IO_WX] = GB_CONFLICT_WX_DMG,
82 [GB_IO_SCX] = GB_CONFLICT_SCX_DMG_AND_CGB_DOUBLE,
83 };
84
85 static uint8_t cycle_read(GB_gameboy_t *gb, uint16_t addr)
86 {
87 if (gb->pending_cycles) {
88 GB_advance_cycles(gb, gb->pending_cycles);
89 }
90 gb->address_bus = addr;
91 uint8_t ret = GB_read_memory(gb, addr);
92 gb->pending_cycles = 4;
93 return ret;
94 }
95
96 /* A special case for IF during ISR, returns the old value of IF. */
97 /* TODO: Verify the timing, it might be wrong in cases where, in the same M cycle, IF
98 is both read be the CPU, modified by the ISR, and modified by an actual interrupt.
99 If this timing proves incorrect, the ISR emulation must be updated so IF reads are
100 timed correctly. */
101 /* TODO: Does this affect the address bus? Verify. */
102 static uint8_t cycle_write_if(GB_gameboy_t *gb, uint8_t value)
103 {
104 assert(gb->pending_cycles);
105 GB_advance_cycles(gb, gb->pending_cycles);
106 gb->address_bus = 0xFF00 + GB_IO_IF;
107 uint8_t old = (gb->io_registers[GB_IO_IF]) & 0x1F;
108 GB_write_memory(gb, 0xFF00 + GB_IO_IF, value);
109 gb->pending_cycles = 4;
110 return old;
111 }
112
113 static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
114 {
115 assert(gb->pending_cycles);
116 conflict_t conflict = GB_CONFLICT_READ_OLD;
117 if ((addr & 0xFF80) == 0xFF00) {
118 const conflict_t *map = NULL;
119 if (GB_is_cgb(gb)) {
120 map = gb->cgb_double_speed? cgb_double_conflict_map : cgb_conflict_map;
121 }
122 else if (GB_is_sgb(gb)) {
123 map = sgb_conflict_map;
124 }
125 else {
126 map = dmg_conflict_map;
127 }
128 conflict = map[addr & 0x7F];
129 }
130 switch (conflict) {
131 case GB_CONFLICT_READ_OLD:
132 GB_advance_cycles(gb, gb->pending_cycles);
133 GB_write_memory(gb, addr, value);
134 gb->pending_cycles = 4;
135 break;
136
137 case GB_CONFLICT_READ_NEW:
138 GB_advance_cycles(gb, gb->pending_cycles - 1);
139 GB_write_memory(gb, addr, value);
140 gb->pending_cycles = 5;
141 break;
142
143 case GB_CONFLICT_WRITE_CPU:
144 GB_advance_cycles(gb, gb->pending_cycles + 1);
145 GB_write_memory(gb, addr, value);
146 gb->pending_cycles = 3;
147 break;
148
149 /* The DMG STAT-write bug is basically the STAT register being read as FF for a single T-cycle */
150 case GB_CONFLICT_STAT_DMG:
151 GB_advance_cycles(gb, gb->pending_cycles);
152 GB_display_sync(gb);
153 /* State 7 is the edge between HBlank and OAM mode, and it behaves a bit weird.
154 The OAM interrupt seems to be blocked by HBlank interrupts in that case, despite
155 the timing not making much sense for that.
156 This is a hack to simulate this effect */
157 if (gb->display_state == 7 && (gb->io_registers[GB_IO_STAT] & 0x28) == 0x08) {
158 GB_write_memory(gb, addr, ~0x20);
159 }
160 else {
161 GB_write_memory(gb, addr, 0xFF);
162 }
163 GB_advance_cycles(gb, 1);
164 GB_write_memory(gb, addr, value);
165 gb->pending_cycles = 3;
166 break;
167
168 case GB_CONFLICT_STAT_CGB: {
169 /* Todo: Verify this with SCX adjustments */
170 /* The LYC bit behaves differently */
171 uint8_t old_value = gb->io_registers[GB_IO_STAT];
172 GB_advance_cycles(gb, gb->pending_cycles);
173 GB_write_memory(gb, addr, (old_value & 0x40) | (value & ~0x40));
174 GB_advance_cycles(gb, 1);
175 GB_write_memory(gb, addr, value);
176 gb->pending_cycles = 3;
177 break;
178 }
179
180 case GB_CONFLICT_STAT_CGB_DOUBLE: {
181 uint8_t old_value = gb->io_registers[GB_IO_STAT];
182 GB_advance_cycles(gb, gb->pending_cycles);
183 GB_write_memory(gb, addr, (value & ~8) | (old_value & 8));
184 GB_advance_cycles(gb, 1);
185 GB_write_memory(gb, addr, value);
186 gb->pending_cycles = 3;
187 break;
188 }
189
190 /* There is some "time travel" going on with these two values, as it appears
191 that there's some off-by-1-T-cycle timing issue in the PPU implementation.
192
193 This is should be accurate for every measureable scenario, though. */
194
195 case GB_CONFLICT_PALETTE_DMG: {
196 GB_advance_cycles(gb, gb->pending_cycles - 2);
197 uint8_t old_value = GB_read_memory(gb, addr);
198 GB_write_memory(gb, addr, value | old_value);
199 GB_advance_cycles(gb, 1);
200 GB_write_memory(gb, addr, value);
201 gb->pending_cycles = 5;
202 break;
203 }
204
205 case GB_CONFLICT_PALETTE_CGB: {
206 if (gb->model >= GB_MODEL_CGB_D) {
207 GB_advance_cycles(gb, gb->pending_cycles - 2);
208 GB_write_memory(gb, addr, value);
209 gb->pending_cycles = 6;
210 }
211 else {
212 GB_advance_cycles(gb, gb->pending_cycles - 1);
213 GB_write_memory(gb, addr, value);
214 gb->pending_cycles = 5;
215 }
216 break;
217 }
218
219 case GB_CONFLICT_DMG_LCDC: {
220 /* Similar to the palette registers, these interact directly with the LCD, so they appear to be affected by
221 it. Both my DMG (B, blob) and Game Boy Light behave this way though.
222
223 Additionally, LCDC.1 is very nasty because it is read both by the FIFO when popping pixels, and the
224 object-fetching state machine, and both behave differently when it comes to access conflicts. Hacks ahead.
225 */
226
227 uint8_t old_value = GB_read_memory(gb, addr);
228 GB_advance_cycles(gb, gb->pending_cycles - 2);
229 GB_display_sync(gb);
230 if (gb->model != GB_MODEL_MGB && gb->position_in_line == 0 && !(value & GB_LCDC_OBJ_EN)) {
231 old_value &= ~GB_LCDC_OBJ_EN;
232 }
233 else if (gb->during_object_fetch && !(value & GB_LCDC_OBJ_EN)) {
234 old_value &= ~GB_LCDC_OBJ_EN;
235 }
236
237 GB_write_memory(gb, addr, old_value | (value & GB_LCDC_BG_EN));
238 GB_advance_cycles(gb, 1);
239 GB_write_memory(gb, addr, value);
240
241 if ((old_value & GB_LCDC_WIN_ENABLE) && !(value & GB_LCDC_WIN_ENABLE) && gb->window_is_being_fetched) {
242 gb->disable_window_pixel_insertion_glitch = true;
243 }
244 gb->pending_cycles = 5;
245 break;
246 }
247
248 case GB_CONFLICT_SGB_LCDC: {
249 /* Simplified version of the above */
250
251 uint8_t old_value = GB_read_memory(gb, addr);
252 GB_advance_cycles(gb, gb->pending_cycles - 2);
253 /* Hack to force aborting object fetch */
254 GB_write_memory(gb, addr, value);
255 GB_write_memory(gb, addr, old_value);
256 GB_advance_cycles(gb, 1);
257 GB_write_memory(gb, addr, value);
258 gb->pending_cycles = 5;
259 break;
260 }
261
262 case GB_CONFLICT_WX_DMG:
263 GB_advance_cycles(gb, gb->pending_cycles);
264 GB_write_memory(gb, addr, value);
265 gb->wx_just_changed = true;
266 GB_advance_cycles(gb, 1);
267 gb->wx_just_changed = false;
268 gb->pending_cycles = 3;
269 break;
270
271 case GB_CONFLICT_LCDC_CGB: {
272 uint8_t old = gb->io_registers[GB_IO_LCDC];
273 if ((~value & old) & GB_LCDC_TILE_SEL) {
274 GB_advance_cycles(gb, gb->pending_cycles);
275 GB_write_memory(gb, addr, value);
276 gb->tile_sel_glitch = true;
277 GB_advance_cycles(gb, 1);
278 gb->tile_sel_glitch = false;
279 gb->pending_cycles = 3;
280 }
281 else {
282 GB_advance_cycles(gb, gb->pending_cycles);
283 GB_write_memory(gb, addr, value);
284 gb->pending_cycles = 4;
285 }
286 break;
287 }
288 case GB_CONFLICT_LCDC_CGB_DOUBLE: {
289 uint8_t old = gb->io_registers[GB_IO_LCDC];
290 // TODO: Verify for CGB ≤ C for BG_EN and OBJ_EN.
291 GB_advance_cycles(gb, gb->pending_cycles - 2);
292 GB_write_memory(gb, addr, (value & ~(GB_LCDC_BG_EN | GB_LCDC_ENABLE)) | (old & (GB_LCDC_BG_EN | GB_LCDC_ENABLE)));
293 // TODO: This condition is different from single speed mode. Why? What about odd modes?
294 gb->tile_sel_glitch = ((value ^ old) & GB_LCDC_TILE_SEL);
295 GB_advance_cycles(gb, 2);
296 gb->tile_sel_glitch = false;
297 GB_write_memory(gb, addr, value);
298 gb->pending_cycles = 4;
299 break;
300 }
301
302 case GB_CONFLICT_SCX_DMG_AND_CGB_DOUBLE:
303 GB_advance_cycles(gb, gb->pending_cycles - 2);
304 GB_write_memory(gb, addr, value);
305 gb->pending_cycles = 6;
306 break;
307
308 case GB_CONFLICT_NR10_CGB_DOUBLE: {
309 GB_advance_cycles(gb, gb->pending_cycles - 1);
310 gb->apu_output.square_sweep_disable_stepping = gb->model <= GB_MODEL_CGB_C && (value & 7) == 0;
311 GB_advance_cycles(gb, 1);
312 gb->apu_output.square_sweep_disable_stepping = false;
313 GB_write_memory(gb, addr, value);
314 gb->pending_cycles = 4;
315 break;
316 }
317 }
318 gb->address_bus = addr;
319 }
320
321 static void cycle_no_access(GB_gameboy_t *gb)
322 {
323 gb->pending_cycles += 4;
324 }
325
326 static void cycle_oam_bug(GB_gameboy_t *gb, uint8_t register_id)
327 {
328 if (gb->pending_cycles) {
329 GB_advance_cycles(gb, gb->pending_cycles);
330 }
331 gb->address_bus = gb->registers[register_id];
332 GB_trigger_oam_bug(gb, gb->registers[register_id]); /* Todo: test T-cycle timing */
333 gb->pending_cycles = 4;
334 }
335
336 static void flush_pending_cycles(GB_gameboy_t *gb)
337 {
338 if (gb->pending_cycles) {
339 GB_advance_cycles(gb, gb->pending_cycles);
340 }
341 gb->pending_cycles = 0;
342 }
343
344 /* Todo: test if multi-byte opcodes trigger the OAM bug correctly */
345
346 static void ill(GB_gameboy_t *gb, uint8_t opcode)
347 {
348 GB_log(gb, "Illegal Opcode. Halting.\n");
349 gb->interrupt_enable = 0;
350 gb->halted = true;
351 }
352
353 static void nop(GB_gameboy_t *gb, uint8_t opcode)
354 {
355 }
356
357 static void enter_stop_mode(GB_gameboy_t *gb)
358 {
359 GB_write_memory(gb, 0xFF00 + GB_IO_DIV, 0);
360 if (!gb->ime) { // TODO: I don't trust this if,
361 gb->div_cycles = -4; // Emulate the CPU-side DIV-reset signal being held
362 }
363 gb->stopped = true;
364 gb->allow_hdma_on_wake = (gb->io_registers[GB_IO_STAT] & 3);
365 gb->oam_ppu_blocked = !gb->oam_read_blocked;
366 gb->vram_ppu_blocked = !gb->vram_read_blocked;
367 gb->cgb_palettes_ppu_blocked = !gb->cgb_palettes_blocked;
368 }
369
370 static void leave_stop_mode(GB_gameboy_t *gb)
371 {
372 gb->stopped = false;
373 if (gb->hdma_on_hblank && (gb->io_registers[GB_IO_STAT] & 3) == 0 && gb->allow_hdma_on_wake) {
374 gb->hdma_on = true;
375 }
376 // TODO: verify this
377 gb->dma_cycles = 4;
378 GB_dma_run(gb);
379 gb->oam_ppu_blocked = false;
380 gb->vram_ppu_blocked = false;
381 gb->cgb_palettes_ppu_blocked = false;
382 }
383
384 /* TODO: Speed switch timing needs far more tests. Double to single is wrong to avoid odd mode. */
385 static void stop(GB_gameboy_t *gb, uint8_t opcode)
386 {
387 flush_pending_cycles(gb);
388 GB_read_memory(gb, gb->pc); // Timing is completely unverified, and only affects STOP triggering the OAM bug
389 if ((gb->io_registers[GB_IO_JOYP] & 0x30) != 0x30) {
390 gb->joyp_accessed = true;
391 }
392 bool exit_by_joyp = ((gb->io_registers[GB_IO_JOYP] & 0xF) != 0xF);
393 bool speed_switch = (gb->io_registers[GB_IO_KEY1] & 0x1) && !exit_by_joyp;
394 bool immediate_exit = speed_switch || exit_by_joyp;
395 bool interrupt_pending = (gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F);
396 // When entering with IF&IE, the 2nd byte of STOP is actually executed
397 if (!exit_by_joyp) {
398 if (!immediate_exit) {
399 GB_dma_run(gb);
400 }
401 enter_stop_mode(gb);
402 }
403
404 if (!interrupt_pending) {
405 cycle_read(gb, gb->pc++);
406 }
407
408 /* Todo: speed switching takes 2 extra T-cycles (so 2 PPU ticks in single->double and 1 PPU tick in double->single) */
409 if (speed_switch) {
410 flush_pending_cycles(gb);
411
412 if (gb->io_registers[GB_IO_LCDC] & GB_LCDC_ENABLE && gb->cgb_double_speed) {
413 GB_log(gb, "ROM triggered a PPU odd mode, which is currently not supported. Reverting to even-mode.\n");
414 if (gb->double_speed_alignment & 7) {
415 gb->speed_switch_freeze = 2;
416 }
417 }
418 if (gb->apu.global_enable && gb->cgb_double_speed) {
419 GB_log(gb, "ROM triggered an APU odd mode, which is currently not tested.\n");
420 }
421 if (gb->cartridge_type->mbc_type == GB_CAMERA && (gb->camera_registers[GB_CAMERA_SHOOT_AND_1D_FLAGS] & 1) && !gb->cgb_double_speed) {
422 GB_log(gb, "ROM entered double speed mode with a camera cartridge, this could damage a real cartridge's camera.\n");
423 }
424
425 if (gb->cgb_double_speed) {
426 gb->cgb_double_speed = false;
427 }
428 else {
429 gb->speed_switch_countdown = 6;
430 gb->speed_switch_freeze = 1;
431 }
432
433 if (!interrupt_pending) {
434 gb->speed_switch_halt_countdown = 0x20008;
435 gb->speed_switch_freeze = 5;
436 }
437
438 gb->io_registers[GB_IO_KEY1] = 0;
439 }
440
441 if (immediate_exit) {
442 leave_stop_mode(gb);
443 if (!interrupt_pending) {
444 GB_dma_run(gb);
445 gb->halted = true;
446 gb->just_halted = true;
447 gb->allow_hdma_on_wake = (gb->io_registers[GB_IO_STAT] & 3);
448 }
449 else {
450 gb->speed_switch_halt_countdown = 0;
451 }
452 }
453 }
454
455 /* Operand naming conventions for functions:
456 r = 8-bit register
457 lr = low 8-bit register
458 hr = high 8-bit register
459 rr = 16-bit register
460 d8 = 8-bit imm
461 d16 = 16-bit imm
462 d.. = [..]
463 cc = condition code (z, nz, c, nc)
464 */
465
466 static void ld_rr_d16(GB_gameboy_t *gb, uint8_t opcode)
467 {
468 uint8_t register_id;
469 uint16_t value;
470 register_id = (opcode >> 4) + 1;
471 value = cycle_read(gb, gb->pc++);
472 value |= cycle_read(gb, gb->pc++) << 8;
473 gb->registers[register_id] = value;
474 }
475
476 static void ld_drr_a(GB_gameboy_t *gb, uint8_t opcode)
477 {
478 uint8_t register_id;
479 register_id = (opcode >> 4) + 1;
480 cycle_write(gb, gb->registers[register_id], gb->af >> 8);
481 }
482
483 static void inc_rr(GB_gameboy_t *gb, uint8_t opcode)
484 {
485 uint8_t register_id = (opcode >> 4) + 1;
486 cycle_oam_bug(gb, register_id);
487 gb->registers[register_id]++;
488 }
489
490 static void inc_hr(GB_gameboy_t *gb, uint8_t opcode)
491 {
492 uint8_t register_id;
493 register_id = ((opcode >> 4) + 1) & 0x03;
494 gb->registers[register_id] += 0x100;
495 gb->af &= ~(GB_SUBTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
496
497 if ((gb->registers[register_id] & 0x0F00) == 0) {
498 gb->af |= GB_HALF_CARRY_FLAG;
499 }
500
501 if ((gb->registers[register_id] & 0xFF00) == 0) {
502 gb->af |= GB_ZERO_FLAG;
503 }
504 }
505 static void dec_hr(GB_gameboy_t *gb, uint8_t opcode)
506 {
507 uint8_t register_id;
508 register_id = ((opcode >> 4) + 1) & 0x03;
509 gb->registers[register_id] -= 0x100;
510 gb->af &= ~(GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
511 gb->af |= GB_SUBTRACT_FLAG;
512
513 if ((gb->registers[register_id] & 0x0F00) == 0xF00) {
514 gb->af |= GB_HALF_CARRY_FLAG;
515 }
516
517 if ((gb->registers[register_id] & 0xFF00) == 0) {
518 gb->af |= GB_ZERO_FLAG;
519 }
520 }
521
522 static void ld_hr_d8(GB_gameboy_t *gb, uint8_t opcode)
523 {
524 uint8_t register_id;
525 register_id = ((opcode >> 4) + 1) & 0x03;
526 gb->registers[register_id] &= 0xFF;
527 gb->registers[register_id] |= cycle_read(gb, gb->pc++) << 8;
528 }
529
530 static void rlca(GB_gameboy_t *gb, uint8_t opcode)
531 {
532 bool carry = (gb->af & 0x8000) != 0;
533
534 gb->af = (gb->af & 0xFF00) << 1;
535 if (carry) {
536 gb->af |= GB_CARRY_FLAG | 0x0100;
537 }
538 }
539
540 static void rla(GB_gameboy_t *gb, uint8_t opcode)
541 {
542 bool bit7 = (gb->af & 0x8000) != 0;
543 bool carry = (gb->af & GB_CARRY_FLAG) != 0;
544
545 gb->af = (gb->af & 0xFF00) << 1;
546 if (carry) {
547 gb->af |= 0x0100;
548 }
549 if (bit7) {
550 gb->af |= GB_CARRY_FLAG;
551 }
552 }
553
554 static void ld_da16_sp(GB_gameboy_t *gb, uint8_t opcode)
555 {
556 /* Todo: Verify order is correct */
557 uint16_t addr;
558 addr = cycle_read(gb, gb->pc++);
559 addr |= cycle_read(gb, gb->pc++) << 8;
560 cycle_write(gb, addr, gb->sp & 0xFF);
561 cycle_write(gb, addr + 1, gb->sp >> 8);
562 }
563
564 static void add_hl_rr(GB_gameboy_t *gb, uint8_t opcode)
565 {
566 uint16_t hl = gb->hl;
567 uint16_t rr;
568 uint8_t register_id;
569 cycle_no_access(gb);
570 register_id = (opcode >> 4) + 1;
571 rr = gb->registers[register_id];
572 gb->hl = hl + rr;
573 gb->af &= ~(GB_SUBTRACT_FLAG | GB_CARRY_FLAG | GB_HALF_CARRY_FLAG);
574
575 /* The meaning of the Half Carry flag is really hard to track -_- */
576 if (((hl & 0xFFF) + (rr & 0xFFF)) & 0x1000) {
577 gb->af |= GB_HALF_CARRY_FLAG;
578 }
579
580 if ( ((unsigned) hl + (unsigned) rr) & 0x10000) {
581 gb->af |= GB_CARRY_FLAG;
582 }
583 }
584
585 static void ld_a_drr(GB_gameboy_t *gb, uint8_t opcode)
586 {
587 uint8_t register_id;
588 register_id = (opcode >> 4) + 1;
589 gb->af &= 0xFF;
590 gb->af |= cycle_read(gb, gb->registers[register_id]) << 8;
591 }
592
593 static void dec_rr(GB_gameboy_t *gb, uint8_t opcode)
594 {
595 uint8_t register_id = (opcode >> 4) + 1;
596 cycle_oam_bug(gb, register_id);
597 gb->registers[register_id]--;
598 }
599
600 static void inc_lr(GB_gameboy_t *gb, uint8_t opcode)
601 {
602 uint8_t register_id;
603 uint8_t value;
604 register_id = (opcode >> 4) + 1;
605
606 value = (gb->registers[register_id] & 0xFF) + 1;
607 gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value;
608
609 gb->af &= ~(GB_SUBTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
610
611 if ((gb->registers[register_id] & 0x0F) == 0) {
612 gb->af |= GB_HALF_CARRY_FLAG;
613 }
614
615 if ((gb->registers[register_id] & 0xFF) == 0) {
616 gb->af |= GB_ZERO_FLAG;
617 }
618 }
619 static void dec_lr(GB_gameboy_t *gb, uint8_t opcode)
620 {
621 uint8_t register_id;
622 uint8_t value;
623 register_id = (opcode >> 4) + 1;
624
625 value = (gb->registers[register_id] & 0xFF) - 1;
626 gb->registers[register_id] = (gb->registers[register_id] & 0xFF00) | value;
627
628 gb->af &= ~(GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
629 gb->af |= GB_SUBTRACT_FLAG;
630
631 if ((gb->registers[register_id] & 0x0F) == 0xF) {
632 gb->af |= GB_HALF_CARRY_FLAG;
633 }
634
635 if ((gb->registers[register_id] & 0xFF) == 0) {
636 gb->af |= GB_ZERO_FLAG;
637 }
638 }
639
640 static void ld_lr_d8(GB_gameboy_t *gb, uint8_t opcode)
641 {
642 uint8_t register_id;
643 register_id = (opcode >> 4) + 1;
644 gb->registers[register_id] &= 0xFF00;
645 gb->registers[register_id] |= cycle_read(gb, gb->pc++);
646 }
647
648 static void rrca(GB_gameboy_t *gb, uint8_t opcode)
649 {
650 bool carry = (gb->af & 0x100) != 0;
651
652 gb->af = (gb->af >> 1) & 0xFF00;
653 if (carry) {
654 gb->af |= GB_CARRY_FLAG | 0x8000;
655 }
656 }
657
658 static void rra(GB_gameboy_t *gb, uint8_t opcode)
659 {
660 bool bit1 = (gb->af & 0x0100) != 0;
661 bool carry = (gb->af & GB_CARRY_FLAG) != 0;
662
663 gb->af = (gb->af >> 1) & 0xFF00;
664 if (carry) {
665 gb->af |= 0x8000;
666 }
667 if (bit1) {
668 gb->af |= GB_CARRY_FLAG;
669 }
670 }
671
672 static void jr_r8(GB_gameboy_t *gb, uint8_t opcode)
673 {
674 int8_t offset = (int8_t)cycle_read(gb, gb->pc++);
675 cycle_oam_bug(gb, GB_REGISTER_PC);
676 gb->pc += offset;
677 }
678
679 static bool condition_code(GB_gameboy_t *gb, uint8_t opcode)
680 {
681 switch ((opcode >> 3) & 0x3) {
682 case 0:
683 return !(gb->af & GB_ZERO_FLAG);
684 case 1:
685 return (gb->af & GB_ZERO_FLAG);
686 case 2:
687 return !(gb->af & GB_CARRY_FLAG);
688 case 3:
689 return (gb->af & GB_CARRY_FLAG);
690 nodefault;
691 }
692
693 return false;
694 }
695
696 static void jr_cc_r8(GB_gameboy_t *gb, uint8_t opcode)
697 {
698 int8_t offset = cycle_read(gb, gb->pc++);
699 if (condition_code(gb, opcode)) {
700 gb->pc += offset;
701 cycle_oam_bug(gb, GB_REGISTER_PC);
702 }
703 }
704
705 static void daa(GB_gameboy_t *gb, uint8_t opcode)
706 {
707 int16_t result = gb->af >> 8;
708
709 gb->af &= ~(0xFF00 | GB_ZERO_FLAG);
710
711 if (gb->af & GB_SUBTRACT_FLAG) {
712 if (gb->af & GB_HALF_CARRY_FLAG) {
713 result = (result - 0x06) & 0xFF;
714 }
715
716 if (gb->af & GB_CARRY_FLAG) {
717 result -= 0x60;
718 }
719 }
720 else {
721 if ((gb->af & GB_HALF_CARRY_FLAG) || (result & 0x0F) > 0x09) {
722 result += 0x06;
723 }
724
725 if ((gb->af & GB_CARRY_FLAG) || result > 0x9F) {
726 result += 0x60;
727 }
728 }
729
730 if ((result & 0xFF) == 0) {
731 gb->af |= GB_ZERO_FLAG;
732 }
733
734 if ((result & 0x100) == 0x100) {
735 gb->af |= GB_CARRY_FLAG;
736 }
737
738 gb->af &= ~GB_HALF_CARRY_FLAG;
739 gb->af |= result << 8;
740 }
741
742 static void cpl(GB_gameboy_t *gb, uint8_t opcode)
743 {
744 gb->af ^= 0xFF00;
745 gb->af |= GB_HALF_CARRY_FLAG | GB_SUBTRACT_FLAG;
746 }
747
748 static void scf(GB_gameboy_t *gb, uint8_t opcode)
749 {
750 gb->af |= GB_CARRY_FLAG;
751 gb->af &= ~(GB_HALF_CARRY_FLAG | GB_SUBTRACT_FLAG);
752 }
753
754 static void ccf(GB_gameboy_t *gb, uint8_t opcode)
755 {
756 gb->af ^= GB_CARRY_FLAG;
757 gb->af &= ~(GB_HALF_CARRY_FLAG | GB_SUBTRACT_FLAG);
758 }
759
760 static void ld_dhli_a(GB_gameboy_t *gb, uint8_t opcode)
761 {
762 cycle_write(gb, gb->hl++, gb->af >> 8);
763 }
764
765 static void ld_dhld_a(GB_gameboy_t *gb, uint8_t opcode)
766 {
767 cycle_write(gb, gb->hl--, gb->af >> 8);
768 }
769
770 static void ld_a_dhli(GB_gameboy_t *gb, uint8_t opcode)
771 {
772 gb->af &= 0xFF;
773 gb->af |= cycle_read(gb, gb->hl++) << 8;
774 }
775
776 static void ld_a_dhld(GB_gameboy_t *gb, uint8_t opcode)
777 {
778 gb->af &= 0xFF;
779 gb->af |= cycle_read(gb, gb->hl--) << 8;
780 }
781
782 static void inc_dhl(GB_gameboy_t *gb, uint8_t opcode)
783 {
784 uint8_t value;
785 value = cycle_read(gb, gb->hl) + 1;
786 cycle_write(gb, gb->hl, value);
787
788 gb->af &= ~(GB_SUBTRACT_FLAG | GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
789 if ((value & 0x0F) == 0) {
790 gb->af |= GB_HALF_CARRY_FLAG;
791 }
792
793 if ((value & 0xFF) == 0) {
794 gb->af |= GB_ZERO_FLAG;
795 }
796 }
797
798 static void dec_dhl(GB_gameboy_t *gb, uint8_t opcode)
799 {
800 uint8_t value;
801 value = cycle_read(gb, gb->hl) - 1;
802 cycle_write(gb, gb->hl, value);
803
804 gb->af &= ~( GB_ZERO_FLAG | GB_HALF_CARRY_FLAG);
805 gb->af |= GB_SUBTRACT_FLAG;
806 if ((value & 0x0F) == 0x0F) {
807 gb->af |= GB_HALF_CARRY_FLAG;
808 }
809
810 if ((value & 0xFF) == 0) {
811 gb->af |= GB_ZERO_FLAG;
812 }
813 }
814
815 static void ld_dhl_d8(GB_gameboy_t *gb, uint8_t opcode)
816 {
817 uint8_t data = cycle_read(gb, gb->pc++);
818 cycle_write(gb, gb->hl, data);
819 }
820
821 static uint8_t get_src_value(GB_gameboy_t *gb, uint8_t opcode)
822 {
823 uint8_t src_register_id;
824 uint8_t src_low;
825 src_register_id = ((opcode >> 1) + 1) & 3;
826 src_low = opcode & 1;
827 if (src_register_id == GB_REGISTER_AF) {
828 if (src_low) {
829 return gb->af >> 8;
830 }
831 return cycle_read(gb, gb->hl);
832 }
833 if (src_low) {
834 return gb->registers[src_register_id] & 0xFF;
835 }
836 return gb->registers[src_register_id] >> 8;
837 }
838
839 static void set_src_value(GB_gameboy_t *gb, uint8_t opcode, uint8_t value)
840 {
841 uint8_t src_register_id;
842 uint8_t src_low;
843 src_register_id = ((opcode >> 1) + 1) & 3;
844 src_low = opcode & 1;
845
846 if (src_register_id == GB_REGISTER_AF) {
847 if (src_low) {
848 gb->af &= 0xFF;
849 gb->af |= value << 8;
850 }
851 else {
852 cycle_write(gb, gb->hl, value);
853 }
854 }
855 else {
856 if (src_low) {
857 gb->registers[src_register_id] &= 0xFF00;
858 gb->registers[src_register_id] |= value;
859 }
860 else {
861 gb->registers[src_register_id] &= 0xFF;
862 gb->registers[src_register_id] |= value << 8;
863 }
864 }
865 }
866
867 /* The LD r,r instruction is extremely common and extremely simple. Decoding this opcode at runtime is a significent
868 performance hit, so we generate functions for every ld x,y couple (including [hl]) at compile time using macros. */
869
870 /* Todo: It's probably wise to do the same to all opcodes. */
871
872 #define LD_X_Y(x, y) \
873 static void ld_##x##_##y(GB_gameboy_t *gb, uint8_t opcode) \
874 { \
875 gb->x = gb->y;\
876 }
877
878 #define LD_X_DHL(x) \
879 static void ld_##x##_##dhl(GB_gameboy_t *gb, uint8_t opcode) \
880 { \
881 gb->x = cycle_read(gb, gb->hl); \
882 }
883
884 #define LD_DHL_Y(y) \
885 static void ld_##dhl##_##y(GB_gameboy_t *gb, uint8_t opcode) \
886 { \
887 cycle_write(gb, gb->hl, gb->y); \
888 }
889
890 LD_X_Y(b,c) LD_X_Y(b,d) LD_X_Y(b,e) LD_X_Y(b,h) LD_X_Y(b,l) LD_X_DHL(b) LD_X_Y(b,a)
891 LD_X_Y(c,b) LD_X_Y(c,d) LD_X_Y(c,e) LD_X_Y(c,h) LD_X_Y(c,l) LD_X_DHL(c) LD_X_Y(c,a)
892 LD_X_Y(d,b) LD_X_Y(d,c) LD_X_Y(d,e) LD_X_Y(d,h) LD_X_Y(d,l) LD_X_DHL(d) LD_X_Y(d,a)
893 LD_X_Y(e,b) LD_X_Y(e,c) LD_X_Y(e,d) LD_X_Y(e,h) LD_X_Y(e,l) LD_X_DHL(e) LD_X_Y(e,a)
894 LD_X_Y(h,b) LD_X_Y(h,c) LD_X_Y(h,d) LD_X_Y(h,e) LD_X_Y(h,l) LD_X_DHL(h) LD_X_Y(h,a)
895 LD_X_Y(l,b) LD_X_Y(l,c) LD_X_Y(l,d) LD_X_Y(l,e) LD_X_Y(l,h) LD_X_DHL(l) LD_X_Y(l,a)
896 LD_DHL_Y(b) LD_DHL_Y(c) LD_DHL_Y(d) LD_DHL_Y(e) LD_DHL_Y(h) LD_DHL_Y(l) LD_DHL_Y(a)
897 LD_X_Y(a,b) LD_X_Y(a,c) LD_X_Y(a,d) LD_X_Y(a,e) LD_X_Y(a,h) LD_X_Y(a,l) LD_X_DHL(a)
898
899 // fire the debugger if software breakpoints are enabled
900 static void ld_b_b(GB_gameboy_t *gb, uint8_t opcode)
901 {
902 #ifndef GB_DISABLE_DEBUGGER
903 if (gb->has_software_breakpoints) {
904 GB_debugger_break(gb);
905 }
906 #endif
907 }
908
909 static void add_a_r(GB_gameboy_t *gb, uint8_t opcode)
910 {
911 uint8_t value, a;
912 value = get_src_value(gb, opcode);
913 a = gb->af >> 8;
914 gb->af = (a + value) << 8;
915 if ((uint8_t)(a + value) == 0) {
916 gb->af |= GB_ZERO_FLAG;
917 }
918 if ((a & 0xF) + (value & 0xF) > 0x0F) {
919 gb->af |= GB_HALF_CARRY_FLAG;
920 }
921 if (((unsigned) a) + ((unsigned) value) > 0xFF) {
922 gb->af |= GB_CARRY_FLAG;
923 }
924 }
925
926 static void adc_a_r(GB_gameboy_t *gb, uint8_t opcode)
927 {
928 uint8_t value, a, carry;
929 value = get_src_value(gb, opcode);
930 a = gb->af >> 8;
931 carry = (gb->af & GB_CARRY_FLAG) != 0;
932 gb->af = (a + value + carry) << 8;
933
934 if ((uint8_t)(a + value + carry) == 0) {
935 gb->af |= GB_ZERO_FLAG;
936 }
937 if ((a & 0xF) + (value & 0xF) + carry > 0x0F) {
938 gb->af |= GB_HALF_CARRY_FLAG;
939 }
940 if (((unsigned) a) + ((unsigned) value) + carry > 0xFF) {
941 gb->af |= GB_CARRY_FLAG;
942 }
943 }
944
945 static void sub_a_r(GB_gameboy_t *gb, uint8_t opcode)
946 {
947 uint8_t value, a;
948 value = get_src_value(gb, opcode);
949 a = gb->af >> 8;
950 gb->af = ((a - value) << 8) | GB_SUBTRACT_FLAG;
951 if (a == value) {
952 gb->af |= GB_ZERO_FLAG;
953 }
954 if ((a & 0xF) < (value & 0xF)) {
955 gb->af |= GB_HALF_CARRY_FLAG;
956 }
957 if (a < value) {
958 gb->af |= GB_CARRY_FLAG;
959 }
960 }
961
962 static void sbc_a_r(GB_gameboy_t *gb, uint8_t opcode)
963 {
964 uint8_t value, a, carry;
965 value = get_src_value(gb, opcode);
966 a = gb->af >> 8;
967 carry = (gb->af & GB_CARRY_FLAG) != 0;
968 gb->af = (((uint8_t)(a - value - carry)) << 8) | GB_SUBTRACT_FLAG;
969
970 if ((uint8_t) (a - value - carry) == 0) {
971 gb->af |= GB_ZERO_FLAG;
972 }
973 if ((a & 0xF) < (value & 0xF) + carry) {
974 gb->af |= GB_HALF_CARRY_FLAG;
975 }
976 if (((unsigned) a) - ((unsigned) value) - carry > 0xFF) {
977 gb->af |= GB_CARRY_FLAG;
978 }
979 }
980
981 static void and_a_r(GB_gameboy_t *gb, uint8_t opcode)
982 {
983 uint8_t value, a;
984 value = get_src_value(gb, opcode);
985 a = gb->af >> 8;
986 gb->af = ((a & value) << 8) | GB_HALF_CARRY_FLAG;
987 if ((a & value) == 0) {
988 gb->af |= GB_ZERO_FLAG;
989 }
990 }
991
992 static void xor_a_r(GB_gameboy_t *gb, uint8_t opcode)
993 {
994 uint8_t value, a;
995 value = get_src_value(gb, opcode);
996 a = gb->af >> 8;
997 gb->af = (a ^ value) << 8;
998 if ((a ^ value) == 0) {
999 gb->af |= GB_ZERO_FLAG;
1000 }
1001 }
1002
1003 static void or_a_r(GB_gameboy_t *gb, uint8_t opcode)
1004 {
1005 uint8_t value, a;
1006 value = get_src_value(gb, opcode);
1007 a = gb->af >> 8;
1008 gb->af = (a | value) << 8;
1009 if ((a | value) == 0) {
1010 gb->af |= GB_ZERO_FLAG;
1011 }
1012 }
1013
1014 static void cp_a_r(GB_gameboy_t *gb, uint8_t opcode)
1015 {
1016 uint8_t value, a;
1017 value = get_src_value(gb, opcode);
1018 a = gb->af >> 8;
1019 gb->af &= 0xFF00;
1020 gb->af |= GB_SUBTRACT_FLAG;
1021 if (a == value) {
1022 gb->af |= GB_ZERO_FLAG;
1023 }
1024 if ((a & 0xF) < (value & 0xF)) {
1025 gb->af |= GB_HALF_CARRY_FLAG;
1026 }
1027 if (a < value) {
1028 gb->af |= GB_CARRY_FLAG;
1029 }
1030 }
1031
1032 static void halt(GB_gameboy_t *gb, uint8_t opcode)
1033 {
1034 cycle_read(gb, gb->pc);
1035 assert(gb->pending_cycles == 4);
1036 gb->pending_cycles = 0;
1037
1038 /* Despite what some online documentations say, the HALT bug also happens on a CGB, in both CGB and DMG modes. */
1039 if (((gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F) != 0)) {
1040 if (gb->ime) {
1041 gb->halted = false;
1042 gb->pc--;
1043 }
1044 else {
1045 gb->halted = false;
1046 gb->halt_bug = true;
1047 }
1048 }
1049 else {
1050 gb->halted = true;
1051 gb->allow_hdma_on_wake = (gb->io_registers[GB_IO_STAT] & 3);
1052 }
1053 gb->just_halted = true;
1054 }
1055
1056 static void pop_rr(GB_gameboy_t *gb, uint8_t opcode)
1057 {
1058 uint8_t register_id;
1059 register_id = ((opcode >> 4) + 1) & 3;
1060 gb->registers[register_id] = cycle_read(gb, gb->sp++);
1061 gb->registers[register_id] |= cycle_read(gb, gb->sp++) << 8;
1062 gb->af &= 0xFFF0; // Make sure we don't set impossible flags on F! See Blargg's PUSH AF test.
1063 }
1064
1065 static void jp_cc_a16(GB_gameboy_t *gb, uint8_t opcode)
1066 {
1067 uint16_t addr = cycle_read(gb, gb->pc++);
1068 addr |= (cycle_read(gb, gb->pc++) << 8);
1069 if (condition_code(gb, opcode)) {
1070 cycle_no_access(gb);
1071 gb->pc = addr;
1072 }
1073 }
1074
1075 static void jp_a16(GB_gameboy_t *gb, uint8_t opcode)
1076 {
1077 uint16_t addr = cycle_read(gb, gb->pc);
1078 addr |= (cycle_read(gb, gb->pc + 1) << 8);
1079 cycle_no_access(gb);
1080 gb->pc = addr;
1081
1082 }
1083
1084 static void call_cc_a16(GB_gameboy_t *gb, uint8_t opcode)
1085 {
1086 uint16_t call_addr = gb->pc - 1;
1087 uint16_t addr = cycle_read(gb, gb->pc++);
1088 addr |= (cycle_read(gb, gb->pc++) << 8);
1089 if (condition_code(gb, opcode)) {
1090 cycle_oam_bug(gb, GB_REGISTER_SP);
1091 cycle_write(gb, --gb->sp, (gb->pc) >> 8);
1092 cycle_write(gb, --gb->sp, (gb->pc) & 0xFF);
1093 gb->pc = addr;
1094
1095 GB_debugger_call_hook(gb, call_addr);
1096 }
1097 }
1098
1099 static void push_rr(GB_gameboy_t *gb, uint8_t opcode)
1100 {
1101 uint8_t register_id;
1102 cycle_oam_bug(gb, GB_REGISTER_SP);
1103 register_id = ((opcode >> 4) + 1) & 3;
1104 cycle_write(gb, --gb->sp, (gb->registers[register_id]) >> 8);
1105 cycle_write(gb, --gb->sp, (gb->registers[register_id]) & 0xFF);
1106 }
1107
1108 static void add_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1109 {
1110 uint8_t value, a;
1111 value = cycle_read(gb, gb->pc++);
1112 a = gb->af >> 8;
1113 gb->af = (a + value) << 8;
1114 if ((uint8_t) (a + value) == 0) {
1115 gb->af |= GB_ZERO_FLAG;
1116 }
1117 if ((a & 0xF) + (value & 0xF) > 0x0F) {
1118 gb->af |= GB_HALF_CARRY_FLAG;
1119 }
1120 if (((unsigned) a) + ((unsigned) value) > 0xFF) {
1121 gb->af |= GB_CARRY_FLAG;
1122 }
1123 }
1124
1125 static void adc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1126 {
1127 uint8_t value, a, carry;
1128 value = cycle_read(gb, gb->pc++);
1129 a = gb->af >> 8;
1130 carry = (gb->af & GB_CARRY_FLAG) != 0;
1131 gb->af = (a + value + carry) << 8;
1132
1133 if (gb->af == 0) {
1134 gb->af |= GB_ZERO_FLAG;
1135 }
1136 if ((a & 0xF) + (value & 0xF) + carry > 0x0F) {
1137 gb->af |= GB_HALF_CARRY_FLAG;
1138 }
1139 if (((unsigned) a) + ((unsigned) value) + carry > 0xFF) {
1140 gb->af |= GB_CARRY_FLAG;
1141 }
1142 }
1143
1144 static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1145 {
1146 uint8_t value, a;
1147 value = cycle_read(gb, gb->pc++);
1148 a = gb->af >> 8;
1149 gb->af = ((a - value) << 8) | GB_SUBTRACT_FLAG;
1150 if (a == value) {
1151 gb->af |= GB_ZERO_FLAG;
1152 }
1153 if ((a & 0xF) < (value & 0xF)) {
1154 gb->af |= GB_HALF_CARRY_FLAG;
1155 }
1156 if (a < value) {
1157 gb->af |= GB_CARRY_FLAG;
1158 }
1159 }
1160
1161 static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1162 {
1163 uint8_t value, a, carry;
1164 value = cycle_read(gb, gb->pc++);
1165 a = gb->af >> 8;
1166 carry = (gb->af & GB_CARRY_FLAG) != 0;
1167 gb->af = ((a - value - carry) << 8) | GB_SUBTRACT_FLAG;
1168
1169 if ((uint8_t) (a - value - carry) == 0) {
1170 gb->af |= GB_ZERO_FLAG;
1171 }
1172 if ((a & 0xF) < (value & 0xF) + carry) {
1173 gb->af |= GB_HALF_CARRY_FLAG;
1174 }
1175 if (((unsigned) a) - ((unsigned) value) - carry > 0xFF) {
1176 gb->af |= GB_CARRY_FLAG;
1177 }
1178 }
1179
1180 static void and_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1181 {
1182 uint8_t value, a;
1183 value = cycle_read(gb, gb->pc++);
1184 a = gb->af >> 8;
1185 gb->af = ((a & value) << 8) | GB_HALF_CARRY_FLAG;
1186 if ((a & value) == 0) {
1187 gb->af |= GB_ZERO_FLAG;
1188 }
1189 }
1190
1191 static void xor_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1192 {
1193 uint8_t value, a;
1194 value = cycle_read(gb, gb->pc++);
1195 a = gb->af >> 8;
1196 gb->af = (a ^ value) << 8;
1197 if ((a ^ value) == 0) {
1198 gb->af |= GB_ZERO_FLAG;
1199 }
1200 }
1201
1202 static void or_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1203 {
1204 uint8_t value, a;
1205 value = cycle_read(gb, gb->pc++);
1206 a = gb->af >> 8;
1207 gb->af = (a | value) << 8;
1208 if ((a | value) == 0) {
1209 gb->af |= GB_ZERO_FLAG;
1210 }
1211 }
1212
1213 static void cp_a_d8(GB_gameboy_t *gb, uint8_t opcode)
1214 {
1215 uint8_t value, a;
1216 value = cycle_read(gb, gb->pc++);
1217 a = gb->af >> 8;
1218 gb->af &= 0xFF00;
1219 gb->af |= GB_SUBTRACT_FLAG;
1220 if (a == value) {
1221 gb->af |= GB_ZERO_FLAG;
1222 }
1223 if ((a & 0xF) < (value & 0xF)) {
1224 gb->af |= GB_HALF_CARRY_FLAG;
1225 }
1226 if (a < value) {
1227 gb->af |= GB_CARRY_FLAG;
1228 }
1229 }
1230
1231 static void rst(GB_gameboy_t *gb, uint8_t opcode)
1232 {
1233 uint16_t call_addr = gb->pc - 1;
1234 cycle_oam_bug(gb, GB_REGISTER_SP);
1235 cycle_write(gb, --gb->sp, (gb->pc) >> 8);
1236 cycle_write(gb, --gb->sp, (gb->pc) & 0xFF);
1237 gb->pc = opcode ^ 0xC7;
1238 GB_debugger_call_hook(gb, call_addr);
1239 }
1240
1241 static void ret(GB_gameboy_t *gb, uint8_t opcode)
1242 {
1243 GB_debugger_ret_hook(gb);
1244 gb->pc = cycle_read(gb, gb->sp++);
1245 gb->pc |= cycle_read(gb, gb->sp++) << 8;
1246 cycle_no_access(gb);
1247 }
1248
1249 static void reti(GB_gameboy_t *gb, uint8_t opcode)
1250 {
1251 ret(gb, opcode);
1252 gb->ime = true;
1253 }
1254
1255 static void ret_cc(GB_gameboy_t *gb, uint8_t opcode)
1256 {
1257 if (condition_code(gb, opcode)) {
1258 cycle_no_access(gb);
1259 ret(gb, opcode);
1260 }
1261 else {
1262 cycle_no_access(gb);
1263 }
1264 }
1265
1266 static void call_a16(GB_gameboy_t *gb, uint8_t opcode)
1267 {
1268 uint16_t call_addr = gb->pc - 1;
1269 uint16_t addr = cycle_read(gb, gb->pc++);
1270 addr |= (cycle_read(gb, gb->pc++) << 8);
1271 cycle_oam_bug(gb, GB_REGISTER_SP);
1272 cycle_write(gb, --gb->sp, (gb->pc) >> 8);
1273 cycle_write(gb, --gb->sp, (gb->pc) & 0xFF);
1274 gb->pc = addr;
1275 GB_debugger_call_hook(gb, call_addr);
1276 }
1277
1278 static void ld_da8_a(GB_gameboy_t *gb, uint8_t opcode)
1279 {
1280 uint8_t temp = cycle_read(gb, gb->pc++);
1281 cycle_write(gb, 0xFF00 + temp, gb->af >> 8);
1282 }
1283
1284 static void ld_a_da8(GB_gameboy_t *gb, uint8_t opcode)
1285 {
1286 gb->af &= 0xFF;
1287 uint8_t temp = cycle_read(gb, gb->pc++);
1288 gb->af |= cycle_read(gb, 0xFF00 + temp) << 8;
1289 }
1290
1291 static void ld_dc_a(GB_gameboy_t *gb, uint8_t opcode)
1292 {
1293 cycle_write(gb, 0xFF00 + (gb->bc & 0xFF), gb->af >> 8);
1294 }
1295
1296 static void ld_a_dc(GB_gameboy_t *gb, uint8_t opcode)
1297 {
1298 gb->af &= 0xFF;
1299 gb->af |= cycle_read(gb, 0xFF00 + (gb->bc & 0xFF)) << 8;
1300 }
1301
1302 static void add_sp_r8(GB_gameboy_t *gb, uint8_t opcode)
1303 {
1304 int16_t offset;
1305 uint16_t sp = gb->sp;
1306 offset = (int8_t) cycle_read(gb, gb->pc++);
1307 cycle_no_access(gb);
1308 cycle_no_access(gb);
1309 gb->sp += offset;
1310
1311 gb->af &= 0xFF00;
1312
1313 /* A new instruction, a new meaning for Half Carry! */
1314 if ((sp & 0xF) + (offset & 0xF) > 0xF) {
1315 gb->af |= GB_HALF_CARRY_FLAG;
1316 }
1317
1318 if ((sp & 0xFF) + (offset & 0xFF) > 0xFF) {
1319 gb->af |= GB_CARRY_FLAG;
1320 }
1321 }
1322
1323 static void jp_hl(GB_gameboy_t *gb, uint8_t opcode)
1324 {
1325 gb->pc = gb->hl;
1326 }
1327
1328 static void ld_da16_a(GB_gameboy_t *gb, uint8_t opcode)
1329 {
1330 uint16_t addr;
1331 addr = cycle_read(gb, gb->pc++);
1332 addr |= cycle_read(gb, gb->pc++) << 8;
1333 cycle_write(gb, addr, gb->af >> 8);
1334 }
1335
1336 static void ld_a_da16(GB_gameboy_t *gb, uint8_t opcode)
1337 {
1338 uint16_t addr;
1339 gb->af &= 0xFF;
1340 addr = cycle_read(gb, gb->pc++);
1341 addr |= cycle_read(gb, gb->pc++) << 8;
1342 gb->af |= cycle_read(gb, addr) << 8;
1343 }
1344
1345 static void di(GB_gameboy_t *gb, uint8_t opcode)
1346 {
1347 /* DI is NOT delayed, not even on a CGB. Mooneye's di_timing-GS test fails on a CGB
1348 for different reasons. */
1349 gb->ime = false;
1350 }
1351
1352 static void ei(GB_gameboy_t *gb, uint8_t opcode)
1353 {
1354 /* ei is actually "disable interrupts for one instruction, then enable them". */
1355 if (!gb->ime && !gb->ime_toggle) {
1356 gb->ime_toggle = true;
1357 }
1358 }
1359
1360 static void ld_hl_sp_r8(GB_gameboy_t *gb, uint8_t opcode)
1361 {
1362 int16_t offset;
1363 gb->af &= 0xFF00;
1364 offset = (int8_t) cycle_read(gb, gb->pc++);
1365 cycle_no_access(gb);
1366 gb->hl = gb->sp + offset;
1367
1368 if ((gb->sp & 0xF) + (offset & 0xF) > 0xF) {
1369 gb->af |= GB_HALF_CARRY_FLAG;
1370 }
1371
1372 if ((gb->sp & 0xFF) + (offset & 0xFF) > 0xFF) {
1373 gb->af |= GB_CARRY_FLAG;
1374 }
1375 }
1376
1377 static void ld_sp_hl(GB_gameboy_t *gb, uint8_t opcode)
1378 {
1379 gb->sp = gb->hl;
1380 cycle_oam_bug(gb, GB_REGISTER_HL);
1381 }
1382
1383 static void rlc_r(GB_gameboy_t *gb, uint8_t opcode)
1384 {
1385 bool carry;
1386 uint8_t value;
1387 value = get_src_value(gb, opcode);
1388 carry = (value & 0x80) != 0;
1389 gb->af &= 0xFF00;
1390 set_src_value(gb, opcode, (value << 1) | carry);
1391 if (carry) {
1392 gb->af |= GB_CARRY_FLAG;
1393 }
1394 if (value == 0) {
1395 gb->af |= GB_ZERO_FLAG;
1396 }
1397 }
1398
1399 static void rrc_r(GB_gameboy_t *gb, uint8_t opcode)
1400 {
1401 bool carry;
1402 uint8_t value;
1403 value = get_src_value(gb, opcode);
1404 carry = (value & 0x01) != 0;
1405 gb->af &= 0xFF00;
1406 value = (value >> 1) | (carry << 7);
1407 set_src_value(gb, opcode, value);
1408 if (carry) {
1409 gb->af |= GB_CARRY_FLAG;
1410 }
1411 if (value == 0) {
1412 gb->af |= GB_ZERO_FLAG;
1413 }
1414 }
1415
1416 static void rl_r(GB_gameboy_t *gb, uint8_t opcode)
1417 {
1418 bool carry;
1419 uint8_t value;
1420 bool bit7;
1421 value = get_src_value(gb, opcode);
1422 carry = (gb->af & GB_CARRY_FLAG) != 0;
1423 bit7 = (value & 0x80) != 0;
1424
1425 gb->af &= 0xFF00;
1426 value = (value << 1) | carry;
1427 set_src_value(gb, opcode, value);
1428 if (bit7) {
1429 gb->af |= GB_CARRY_FLAG;
1430 }
1431 if (value == 0) {
1432 gb->af |= GB_ZERO_FLAG;
1433 }
1434 }
1435
1436 static void rr_r(GB_gameboy_t *gb, uint8_t opcode)
1437 {
1438 bool carry;
1439 uint8_t value;
1440 bool bit1;
1441
1442 value = get_src_value(gb, opcode);
1443 carry = (gb->af & GB_CARRY_FLAG) != 0;
1444 bit1 = (value & 0x1) != 0;
1445
1446 gb->af &= 0xFF00;
1447 value = (value >> 1) | (carry << 7);
1448 set_src_value(gb, opcode, value);
1449 if (bit1) {
1450 gb->af |= GB_CARRY_FLAG;
1451 }
1452 if (value == 0) {
1453 gb->af |= GB_ZERO_FLAG;
1454 }
1455 }
1456
1457 static void sla_r(GB_gameboy_t *gb, uint8_t opcode)
1458 {
1459 uint8_t value;
1460 bool carry;
1461 value = get_src_value(gb, opcode);
1462 carry = (value & 0x80) != 0;
1463 gb->af &= 0xFF00;
1464 set_src_value(gb, opcode, (value << 1));
1465 if (carry) {
1466 gb->af |= GB_CARRY_FLAG;
1467 }
1468 if ((value & 0x7F) == 0) {
1469 gb->af |= GB_ZERO_FLAG;
1470 }
1471 }
1472
1473 static void sra_r(GB_gameboy_t *gb, uint8_t opcode)
1474 {
1475 uint8_t bit7;
1476 uint8_t value;
1477 value = get_src_value(gb, opcode);
1478 bit7 = value & 0x80;
1479 gb->af &= 0xFF00;
1480 if (value & 1) {
1481 gb->af |= GB_CARRY_FLAG;
1482 }
1483 value = (value >> 1) | bit7;
1484 set_src_value(gb, opcode, value);
1485 if (value == 0) {
1486 gb->af |= GB_ZERO_FLAG;
1487 }
1488 }
1489
1490 static void srl_r(GB_gameboy_t *gb, uint8_t opcode)
1491 {
1492 uint8_t value;
1493 value = get_src_value(gb, opcode);
1494 gb->af &= 0xFF00;
1495 set_src_value(gb, opcode, (value >> 1));
1496 if (value & 1) {
1497 gb->af |= GB_CARRY_FLAG;
1498 }
1499 if (!(value >> 1)) {
1500 gb->af |= GB_ZERO_FLAG;
1501 }
1502 }
1503
1504 static void swap_r(GB_gameboy_t *gb, uint8_t opcode)
1505 {
1506 uint8_t value;
1507 value = get_src_value(gb, opcode);
1508 gb->af &= 0xFF00;
1509 set_src_value(gb, opcode, (value >> 4) | (value << 4));
1510 if (!value) {
1511 gb->af |= GB_ZERO_FLAG;
1512 }
1513 }
1514
1515 static void bit_r(GB_gameboy_t *gb, uint8_t opcode)
1516 {
1517 uint8_t value;
1518 uint8_t bit;
1519 value = get_src_value(gb, opcode);
1520 bit = 1 << ((opcode >> 3) & 7);
1521 if ((opcode & 0xC0) == 0x40) { /* Bit */
1522 gb->af &= 0xFF00 | GB_CARRY_FLAG;
1523 gb->af |= GB_HALF_CARRY_FLAG;
1524 if (!(bit & value)) {
1525 gb->af |= GB_ZERO_FLAG;
1526 }
1527 }
1528 else if ((opcode & 0xC0) == 0x80) { /* res */
1529 set_src_value(gb, opcode, value & ~bit);
1530 }
1531 else if ((opcode & 0xC0) == 0xC0) { /* set */
1532 set_src_value(gb, opcode, value | bit);
1533 }
1534 }
1535
1536 static void cb_prefix(GB_gameboy_t *gb, uint8_t opcode)
1537 {
1538 opcode = cycle_read(gb, gb->pc++);
1539 switch (opcode >> 3) {
1540 case 0:
1541 rlc_r(gb, opcode);
1542 break;
1543 case 1:
1544 rrc_r(gb, opcode);
1545 break;
1546 case 2:
1547 rl_r(gb, opcode);
1548 break;
1549 case 3:
1550 rr_r(gb, opcode);
1551 break;
1552 case 4:
1553 sla_r(gb, opcode);
1554 break;
1555 case 5:
1556 sra_r(gb, opcode);
1557 break;
1558 case 6:
1559 swap_r(gb, opcode);
1560 break;
1561 case 7:
1562 srl_r(gb, opcode);
1563 break;
1564 default:
1565 bit_r(gb, opcode);
1566 break;
1567 }
1568 }
1569
1570 static opcode_t *opcodes[256] = {
1571 /* X0 X1 X2 X3 X4 X5 X6 X7 */
1572 /* X8 X9 Xa Xb Xc Xd Xe Xf */
1573 nop, ld_rr_d16, ld_drr_a, inc_rr, inc_hr, dec_hr, ld_hr_d8, rlca, /* 0X */
1574 ld_da16_sp, add_hl_rr, ld_a_drr, dec_rr, inc_lr, dec_lr, ld_lr_d8, rrca,
1575 stop, ld_rr_d16, ld_drr_a, inc_rr, inc_hr, dec_hr, ld_hr_d8, rla, /* 1X */
1576 jr_r8, add_hl_rr, ld_a_drr, dec_rr, inc_lr, dec_lr, ld_lr_d8, rra,
1577 jr_cc_r8, ld_rr_d16, ld_dhli_a, inc_rr, inc_hr, dec_hr, ld_hr_d8, daa, /* 2X */
1578 jr_cc_r8, add_hl_rr, ld_a_dhli, dec_rr, inc_lr, dec_lr, ld_lr_d8, cpl,
1579 jr_cc_r8, ld_rr_d16, ld_dhld_a, inc_rr, inc_dhl, dec_dhl, ld_dhl_d8, scf, /* 3X */
1580 jr_cc_r8, add_hl_rr, ld_a_dhld, dec_rr, inc_hr, dec_hr, ld_hr_d8, ccf,
1581 ld_b_b, ld_b_c, ld_b_d, ld_b_e, ld_b_h, ld_b_l, ld_b_dhl, ld_b_a, /* 4X */
1582 ld_c_b, nop, ld_c_d, ld_c_e, ld_c_h, ld_c_l, ld_c_dhl, ld_c_a,
1583 ld_d_b, ld_d_c, nop, ld_d_e, ld_d_h, ld_d_l, ld_d_dhl, ld_d_a, /* 5X */
1584 ld_e_b, ld_e_c, ld_e_d, nop, ld_e_h, ld_e_l, ld_e_dhl, ld_e_a,
1585 ld_h_b, ld_h_c, ld_h_d, ld_h_e, nop, ld_h_l, ld_h_dhl, ld_h_a, /* 6X */
1586 ld_l_b, ld_l_c, ld_l_d, ld_l_e, ld_l_h, nop, ld_l_dhl, ld_l_a,
1587 ld_dhl_b, ld_dhl_c, ld_dhl_d, ld_dhl_e, ld_dhl_h, ld_dhl_l, halt, ld_dhl_a, /* 7X */
1588 ld_a_b, ld_a_c, ld_a_d, ld_a_e, ld_a_h, ld_a_l, ld_a_dhl, nop,
1589 add_a_r, add_a_r, add_a_r, add_a_r, add_a_r, add_a_r, add_a_r, add_a_r, /* 8X */
1590 adc_a_r, adc_a_r, adc_a_r, adc_a_r, adc_a_r, adc_a_r, adc_a_r, adc_a_r,
1591 sub_a_r, sub_a_r, sub_a_r, sub_a_r, sub_a_r, sub_a_r, sub_a_r, sub_a_r, /* 9X */
1592 sbc_a_r, sbc_a_r, sbc_a_r, sbc_a_r, sbc_a_r, sbc_a_r, sbc_a_r, sbc_a_r,
1593 and_a_r, and_a_r, and_a_r, and_a_r, and_a_r, and_a_r, and_a_r, and_a_r, /* aX */
1594 xor_a_r, xor_a_r, xor_a_r, xor_a_r, xor_a_r, xor_a_r, xor_a_r, xor_a_r,
1595 or_a_r, or_a_r, or_a_r, or_a_r, or_a_r, or_a_r, or_a_r, or_a_r, /* bX */
1596 cp_a_r, cp_a_r, cp_a_r, cp_a_r, cp_a_r, cp_a_r, cp_a_r, cp_a_r,
1597 ret_cc, pop_rr, jp_cc_a16, jp_a16, call_cc_a16,push_rr, add_a_d8, rst, /* cX */
1598 ret_cc, ret, jp_cc_a16, cb_prefix, call_cc_a16,call_a16, adc_a_d8, rst,
1599 ret_cc, pop_rr, jp_cc_a16, ill, call_cc_a16,push_rr, sub_a_d8, rst, /* dX */
1600 ret_cc, reti, jp_cc_a16, ill, call_cc_a16,ill, sbc_a_d8, rst,
1601 ld_da8_a, pop_rr, ld_dc_a, ill, ill, push_rr, and_a_d8, rst, /* eX */
1602 add_sp_r8, jp_hl, ld_da16_a, ill, ill, ill, xor_a_d8, rst,
1603 ld_a_da8, pop_rr, ld_a_dc, di, ill, push_rr, or_a_d8, rst, /* fX */
1604 ld_hl_sp_r8,ld_sp_hl, ld_a_da16, ei, ill, ill, cp_a_d8, rst,
1605 };
1606 void GB_cpu_run(GB_gameboy_t *gb)
1607 {
1608 if (unlikely(gb->stopped)) {
1609 GB_timing_sync(gb);
1610 GB_advance_cycles(gb, 4);
1611 if ((gb->io_registers[GB_IO_JOYP] & 0x30) != 0x30) {
1612 gb->joyp_accessed = true;
1613 }
1614 if ((gb->io_registers[GB_IO_JOYP] & 0xF) != 0xF) {
1615 leave_stop_mode(gb);
1616 GB_advance_cycles(gb, 8);
1617 }
1618 return;
1619 }
1620
1621 if ((gb->interrupt_enable & 0x10) && (gb->ime || gb->halted)) {
1622 GB_timing_sync(gb);
1623 }
1624
1625 if (gb->halted && !GB_is_cgb(gb) && !gb->just_halted) {
1626 GB_advance_cycles(gb, 2);
1627 }
1628
1629 uint8_t interrupt_queue = gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F;
1630
1631 if (gb->halted) {
1632 GB_advance_cycles(gb, (GB_is_cgb(gb) || gb->just_halted) ? 4 : 2);
1633 }
1634 gb->just_halted = false;
1635
1636 bool effective_ime = gb->ime;
1637 if (gb->ime_toggle) {
1638 gb->ime = !gb->ime;
1639 gb->ime_toggle = false;
1640 }
1641
1642 /* Wake up from HALT mode without calling interrupt code. */
1643 if (gb->halted && !effective_ime && interrupt_queue) {
1644 gb->halted = false;
1645 if (gb->hdma_on_hblank && (gb->io_registers[GB_IO_STAT] & 3) == 0 && gb->allow_hdma_on_wake) {
1646 gb->hdma_on = true;
1647 }
1648 gb->dma_cycles = 4;
1649 GB_dma_run(gb);
1650 gb->speed_switch_halt_countdown = 0;
1651 }
1652
1653 /* Call interrupt */
1654 else if (unlikely(effective_ime && interrupt_queue)) {
1655 gb->halted = false;
1656 if (gb->hdma_on_hblank && (gb->io_registers[GB_IO_STAT] & 3) == 0 && gb->allow_hdma_on_wake) {
1657 gb->hdma_on = true;
1658 }
1659 // TODO: verify the timing!
1660 gb->dma_cycles = 4;
1661 GB_dma_run(gb);
1662 gb->speed_switch_halt_countdown = 0;
1663 uint16_t call_addr = gb->pc;
1664
1665 cycle_read(gb, gb->pc++);
1666 cycle_oam_bug(gb, GB_REGISTER_PC);
1667 gb->pc--;
1668 GB_trigger_oam_bug(gb, gb->sp); /* Todo: test T-cycle timing */
1669 cycle_no_access(gb);
1670
1671 cycle_write(gb, --gb->sp, (gb->pc) >> 8);
1672 interrupt_queue = gb->interrupt_enable;
1673
1674 if (gb->sp == GB_IO_IF + 0xFF00 + 1) {
1675 gb->sp--;
1676 interrupt_queue &= cycle_write_if(gb, (gb->pc) & 0xFF);
1677 }
1678 else {
1679 cycle_write(gb, --gb->sp, (gb->pc) & 0xFF);
1680 interrupt_queue &= (gb->io_registers[GB_IO_IF]) & 0x1F;
1681 }
1682
1683 if (interrupt_queue) {
1684 uint8_t interrupt_bit = 0;
1685 while (!(interrupt_queue & 1)) {
1686 interrupt_queue >>= 1;
1687 interrupt_bit++;
1688 }
1689 assert(gb->pending_cycles > 2);
1690 gb->pending_cycles -= 2;
1691 flush_pending_cycles(gb);
1692 gb->pending_cycles = 2;
1693 gb->io_registers[GB_IO_IF] &= ~(1 << interrupt_bit);
1694 gb->pc = interrupt_bit * 8 + 0x40;
1695 }
1696 else {
1697 gb->pc = 0;
1698 }
1699 gb->ime = false;
1700 GB_debugger_call_hook(gb, call_addr);
1701 }
1702 /* Run mode */
1703 else if (!gb->halted) {
1704 uint8_t opcode = cycle_read(gb, gb->pc++);
1705 if (unlikely(gb->hdma_on)) {
1706 GB_hdma_run(gb);
1707 }
1708 if (unlikely(gb->execution_callback)) {
1709 gb->execution_callback(gb, gb->pc - 1, opcode);
1710 }
1711 if (unlikely(gb->halt_bug)) {
1712 gb->pc--;
1713 gb->halt_bug = false;
1714 }
1715 opcodes[opcode](gb, opcode);
1716 }
1717
1718 flush_pending_cycles(gb);
1719 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.