SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Core/gb.c
1 #include <stdio.h>
2 #include <stdbool.h>
3 #include <stdlib.h>
4 #include <stddef.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <stdarg.h>
8 #ifndef _WIN32
9 #include <sys/select.h>
10 #include <unistd.h>
11 #endif
12 #include "random.h"
13 #include "gb.h"
14
15
16 void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes_t attributes, const char *fmt, va_list args)
17 {
18 int errno_backup = errno;
19 char *string = NULL;
20 vasprintf(&string, fmt, args);
21 if (string) {
22 if (gb->log_callback) {
23 gb->log_callback(gb, string, attributes);
24 }
25 else {
26 /* Todo: Add ANSI escape sequences for attributed text */
27 printf("%s", string);
28 }
29 }
30 free(string);
31 errno = errno_backup;
32 }
33
34 void GB_attributed_log(GB_gameboy_t *gb, GB_log_attributes_t attributes, const char *fmt, ...)
35 {
36 va_list args;
37 va_start(args, fmt);
38 GB_attributed_logv(gb, attributes, fmt, args);
39 va_end(args);
40 }
41
42 void GB_log(GB_gameboy_t *gb, const char *fmt, ...)
43 {
44 va_list args;
45 va_start(args, fmt);
46 GB_attributed_logv(gb, 0, fmt, args);
47 va_end(args);
48 }
49
50 #ifndef GB_DISABLE_DEBUGGER
51 static char *default_input_callback(GB_gameboy_t *gb)
52 {
53 char *expression = NULL;
54 size_t size = 0;
55 if (gb->debug_stopped) {
56 printf(">");
57 }
58
59 if (getline(&expression, &size, stdin) == -1) {
60 /* The user doesn't have STDIN or used ^D. We make sure the program keeps running. */
61
62 /* Some implementations may allocate expressions even on getline failure,
63 and other implementations may crash on free(NULL). Free expression if
64 it was allocated. */
65 if (expression) {
66 free(expression);
67 }
68 GB_set_async_input_callback(gb, NULL); /* Disable async input */
69 return strdup("c");
70 }
71
72 if (!expression) {
73 return strdup("");
74 }
75
76 size_t length = strlen(expression);
77 if (expression[length - 1] == '\n') {
78 expression[length - 1] = 0;
79 }
80
81 if (expression[0] == '\x03') {
82 GB_debugger_break(gb);
83 free(expression);
84 return strdup("");
85 }
86 return expression;
87 }
88
89 static char *default_async_input_callback(GB_gameboy_t *gb)
90 {
91 #ifndef _WIN32
92 fd_set set;
93 FD_ZERO(&set);
94 FD_SET(STDIN_FILENO, &set);
95 struct timeval time = {0,};
96 if (select(1, &set, NULL, NULL, &time) == 1) {
97 if (feof(stdin)) {
98 GB_set_async_input_callback(gb, NULL); /* Disable async input */
99 return NULL;
100 }
101 return default_input_callback(gb);
102 }
103 #endif
104 return NULL;
105 }
106 #endif
107
108 static void load_default_border(GB_gameboy_t *gb)
109 {
110 if (gb->has_sgb_border) return;
111
112 #define LOAD_BORDER() do { \
113 memcpy(gb->borrowed_border.map, tilemap, sizeof(tilemap));\
114 memcpy(gb->borrowed_border.palette, palette, sizeof(palette));\
115 memcpy(gb->borrowed_border.tiles, tiles, sizeof(tiles));\
116 } while (false);
117
118 #ifdef GB_BIG_ENDIAN
119 for (unsigned i = 0; i < sizeof(gb->borrowed_border.map) / 2; i++) {
120 gb->borrowed_border.map[i] = LE16(gb->borrowed_border.map[i]);
121 }
122 for (unsigned i = 0; i < sizeof(gb->borrowed_border.palette) / 2; i++) {
123 gb->borrowed_border.palette[i] = LE16(gb->borrowed_border.palette[i]);
124 }
125 #endif
126
127 if (gb->model > GB_MODEL_CGB_E) {
128 #include "graphics/agb_border.inc"
129 LOAD_BORDER();
130 }
131 else if (gb->model == GB_MODEL_MGB) {
132 #include "graphics/mgb_border.inc"
133 LOAD_BORDER();
134 if (gb->dmg_palette &&
135 gb->dmg_palette->colors[4].b > gb->dmg_palette->colors[4].r) {
136 for (unsigned i = 0; i < 7; i++) {
137 gb->borrowed_border.map[13 + 24 * 32 + i] = i + 1;
138 gb->borrowed_border.map[13 + 25 * 32 + i] = i + 8;
139 }
140 }
141 }
142 else if (GB_is_cgb(gb)) {
143 #include "graphics/cgb_border.inc"
144 LOAD_BORDER();
145 }
146 else {
147 #include "graphics/dmg_border.inc"
148 LOAD_BORDER();
149 }
150 }
151
152 size_t GB_allocation_size(void)
153 {
154 return sizeof(GB_gameboy_t);
155 }
156
157 GB_gameboy_t *GB_alloc(void)
158 {
159 GB_gameboy_t *ret = malloc(sizeof(*ret));
160 ret->magic = 0;
161 return ret;
162 }
163
164 GB_gameboy_t *GB_init(GB_gameboy_t *gb, GB_model_t model)
165 {
166 memset(gb, 0, sizeof(*gb));
167 gb->model = model;
168 if (GB_is_cgb(gb)) {
169 gb->ram = malloc(gb->ram_size = 0x1000 * 8);
170 gb->vram = malloc(gb->vram_size = 0x2000 * 2);
171 }
172 else {
173 gb->ram = malloc(gb->ram_size = 0x2000);
174 gb->vram = malloc(gb->vram_size = 0x2000);
175 }
176
177 #ifndef GB_DISABLE_DEBUGGER
178 gb->input_callback = default_input_callback;
179 gb->async_input_callback = default_async_input_callback;
180 #endif
181 gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
182 gb->clock_multiplier = 1.0;
183 gb->apu_output.max_cycles_per_sample = 0x400;
184
185 if (model & GB_MODEL_NO_SFC_BIT) {
186 /* Disable time syncing. Timing should be done by the SFC emulator. */
187 gb->turbo = true;
188 }
189
190 gb->data_bus_decay = 12;
191
192 GB_reset(gb);
193 load_default_border(gb);
194 return gb;
195 }
196
197 GB_model_t GB_get_model(GB_gameboy_t *gb)
198 {
199 return gb->model;
200 }
201
202 void GB_free(GB_gameboy_t *gb)
203 {
204 GB_ASSERT_NOT_RUNNING(gb)
205 gb->magic = 0;
206 if (gb->ram) {
207 free(gb->ram);
208 }
209 if (gb->vram) {
210 free(gb->vram);
211 }
212 if (gb->mbc_ram) {
213 free(gb->mbc_ram);
214 }
215 if (gb->rom) {
216 free(gb->rom);
217 }
218 if (gb->sgb) {
219 free(gb->sgb);
220 }
221 #ifndef GB_DISABLE_DEBUGGER
222 GB_debugger_clear_symbols(gb);
223 if (gb->breakpoints) {
224 free(gb->breakpoints);
225 }
226 if (gb->watchpoints) {
227 free(gb->watchpoints);
228 }
229 if (gb->nontrivial_jump_state) {
230 free(gb->nontrivial_jump_state);
231 }
232 if (gb->undo_state) {
233 free(gb->undo_state);
234 }
235 #endif
236 GB_rewind_reset(gb);
237 #ifndef GB_DISABLE_CHEATS
238 GB_remove_all_cheats(gb);
239 #endif
240 #ifndef GB_DISABLE_CHEAT_SEARCH
241 GB_cheat_search_reset(gb);
242 #endif
243 GB_stop_audio_recording(gb);
244 memset(gb, 0, sizeof(*gb));
245 }
246
247 void GB_dealloc(GB_gameboy_t *gb)
248 {
249 if (GB_is_inited(gb)) {
250 GB_free(gb);
251 }
252 free(gb);
253 }
254
255 int GB_load_boot_rom(GB_gameboy_t *gb, const char *path)
256 {
257 FILE *f = fopen(path, "rb");
258 if (!f) {
259 GB_log(gb, "Could not open boot ROM: %s.\n", strerror(errno));
260 return errno;
261 }
262 fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f);
263 fclose(f);
264 return 0;
265 }
266
267 void GB_load_boot_rom_from_buffer(GB_gameboy_t *gb, const unsigned char *buffer, size_t size)
268 {
269 if (size > sizeof(gb->boot_rom)) {
270 size = sizeof(gb->boot_rom);
271 }
272 memset(gb->boot_rom, 0xFF, sizeof(gb->boot_rom));
273 memcpy(gb->boot_rom, buffer, size);
274 }
275
276 void GB_borrow_sgb_border(GB_gameboy_t *gb)
277 {
278 if (GB_is_sgb(gb)) return;
279 if (gb->border_mode != GB_BORDER_ALWAYS) return;
280 if (gb->tried_loading_sgb_border) return;
281 gb->tried_loading_sgb_border = true;
282 if (!gb->rom || gb->rom[0x146] != 3) return; // Not an SGB game, nothing to borrow
283 if (!gb->boot_rom_load_callback) return; // Can't borrow a border without this callback
284 GB_gameboy_t sgb;
285 GB_init(&sgb, GB_MODEL_SGB);
286 sgb.cartridge_type = gb->cartridge_type;
287 sgb.rom = gb->rom;
288 sgb.rom_size = gb->rom_size;
289 sgb.turbo = true;
290 sgb.turbo_dont_skip = true;
291 // sgb.disable_rendering = true;
292
293 /* Load the boot ROM using the existing gb object */
294 typeof(gb->boot_rom) boot_rom_backup;
295 memcpy(boot_rom_backup, gb->boot_rom, sizeof(gb->boot_rom));
296 gb->boot_rom_load_callback(gb, GB_BOOT_ROM_SGB);
297 memcpy(sgb.boot_rom, gb->boot_rom, sizeof(gb->boot_rom));
298 memcpy(gb->boot_rom, boot_rom_backup, sizeof(gb->boot_rom));
299 sgb.sgb->intro_animation = -1;
300
301 for (unsigned i = 600; i--;) {
302 GB_run_frame(&sgb);
303 if (sgb.sgb->border_animation) {
304 gb->has_sgb_border = true;
305 memcpy(&gb->borrowed_border, &sgb.sgb->pending_border, sizeof(gb->borrowed_border));
306 gb->borrowed_border.palette[0] = sgb.sgb->effective_palettes[0];
307 break;
308 }
309 }
310
311 sgb.rom = NULL;
312 sgb.rom_size = 0;
313 GB_free(&sgb);
314 }
315
316 static size_t rounded_rom_size(size_t size)
317 {
318 size = (size + 0x3FFF) & ~0x3FFF; /* Round to bank */
319 /* And then round to a power of two */
320 while (size & (size - 1)) {
321 /* I promise this works. */
322 size |= size >> 1;
323 size++;
324 }
325 if (size < 0x8000) {
326 size = 0x8000;
327 }
328 return size;
329 }
330
331 int GB_load_rom(GB_gameboy_t *gb, const char *path)
332 {
333 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
334
335 FILE *f = fopen(path, "rb");
336 if (!f) {
337 GB_log(gb, "Could not open ROM: %s.\n", strerror(errno));
338 return errno;
339 }
340 fseek(f, 0, SEEK_END);
341 gb->rom_size = rounded_rom_size(ftell(f));
342 fseek(f, 0, SEEK_SET);
343 if (gb->rom) {
344 free(gb->rom);
345 }
346 gb->rom = malloc(gb->rom_size);
347 memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
348 fread(gb->rom, 1, gb->rom_size, f);
349 fclose(f);
350 GB_configure_cart(gb);
351 gb->tried_loading_sgb_border = false;
352 gb->has_sgb_border = false;
353 load_default_border(gb);
354 return 0;
355 }
356
357 #define GBS_ENTRY 0x61
358 #define GBS_ENTRY_SIZE 13
359
360 static void generate_gbs_entry(GB_gameboy_t *gb, uint8_t *data)
361 {
362 memcpy(data, (uint8_t[]) {
363 0xCD, // Call $XXXX
364 LE16(gb->gbs_header.init_address),
365 LE16(gb->gbs_header.init_address) >> 8,
366 0x76, // HALT
367 0x00, // NOP
368 0xAF, // XOR a
369 0xE0, // LDH [$FFXX], a
370 GB_IO_IF,
371 0xCD, // Call $XXXX
372 LE16(gb->gbs_header.play_address),
373 LE16(gb->gbs_header.play_address) >> 8,
374 0x18, // JR pc ± $XX
375 -10 // To HALT
376 }, GBS_ENTRY_SIZE);
377 }
378
379 void GB_gbs_switch_track(GB_gameboy_t *gb, uint8_t track)
380 {
381 GB_reset(gb);
382 GB_write_memory(gb, 0xFF00 + GB_IO_LCDC, GB_LCDC_ENABLE);
383 GB_write_memory(gb, 0xFF00 + GB_IO_TAC, gb->gbs_header.TAC);
384 GB_write_memory(gb, 0xFF00 + GB_IO_TMA, gb->gbs_header.TMA);
385 GB_write_memory(gb, 0xFF00 + GB_IO_NR52, 0x80);
386 GB_write_memory(gb, 0xFF00 + GB_IO_NR51, 0xFF);
387 GB_write_memory(gb, 0xFF00 + GB_IO_NR50, 0x77);
388 memset(gb->ram, 0, gb->ram_size);
389 memset(gb->hram, 0, sizeof(gb->hram));
390 memset(gb->oam, 0, sizeof(gb->oam));
391 if (gb->gbs_header.TAC || gb->gbs_header.TMA) {
392 GB_write_memory(gb, 0xFFFF, 0x04);
393 }
394 else {
395 GB_write_memory(gb, 0xFFFF, 0x01);
396 }
397 if (gb->gbs_header.TAC & 0x80) {
398 gb->cgb_double_speed = true; // Might mean double speed mode on a DMG
399 }
400 if (gb->gbs_header.load_address) {
401 gb->sp = LE16(gb->gbs_header.sp);
402 gb->pc = GBS_ENTRY;
403 }
404 else {
405 gb->pc = gb->sp = LE16(gb->gbs_header.sp - GBS_ENTRY_SIZE);
406 uint8_t entry[GBS_ENTRY_SIZE];
407 generate_gbs_entry(gb, entry);
408 for (unsigned i = 0; i < sizeof(entry); i++) {
409 GB_write_memory(gb, gb->pc + i, entry[i]);
410 }
411 }
412
413 gb->boot_rom_finished = true;
414 gb->a = track;
415 if (gb->sgb) {
416 gb->sgb->intro_animation = GB_SGB_INTRO_ANIMATION_LENGTH;
417 gb->sgb->disable_commands = true;
418 }
419 if (gb->gbs_header.TAC & 0x4) {
420 gb->interrupt_enable = 4;
421 }
422 else {
423 gb->interrupt_enable = 1;
424 }
425 }
426
427 int GB_load_gbs_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size, GB_gbs_info_t *info)
428 {
429 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
430
431 if (size < sizeof(gb->gbs_header)) {
432 GB_log(gb, "Not a valid GBS file.\n");
433 return -1;
434 }
435
436 memcpy(&gb->gbs_header, buffer, sizeof(gb->gbs_header));
437
438 if (gb->gbs_header.magic != BE32('GBS\x01') ||
439 ((LE16(gb->gbs_header.load_address) < GBS_ENTRY + GBS_ENTRY_SIZE ||
440 LE16(gb->gbs_header.load_address) >= 0x8000) &&
441 LE16(gb->gbs_header.load_address) != 0)) {
442 GB_log(gb, "Not a valid GBS file.\n");
443 return -1;
444 }
445
446 size_t data_size = size - sizeof(gb->gbs_header);
447
448 gb->rom_size = rounded_rom_size(data_size + LE16(gb->gbs_header.load_address));
449
450 if (gb->rom) {
451 free(gb->rom);
452 }
453
454 gb->rom = malloc(gb->rom_size);
455 memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
456 memcpy(gb->rom + LE16(gb->gbs_header.load_address), buffer + sizeof(gb->gbs_header), data_size);
457
458 gb->cartridge_type = &GB_cart_defs[0x11];
459 if (gb->mbc_ram) {
460 free(gb->mbc_ram);
461 gb->mbc_ram = NULL;
462 gb->mbc_ram_size = 0;
463 }
464
465 if (gb->cartridge_type->has_ram) {
466 gb->mbc_ram_size = 0x2000;
467 gb->mbc_ram = malloc(gb->mbc_ram_size);
468 memset(gb->mbc_ram, 0xFF, gb->mbc_ram_size);
469 }
470
471 bool has_interrupts = gb->gbs_header.TAC & 0x40;
472
473 if (gb->gbs_header.load_address) {
474 // Generate interrupt handlers
475 for (unsigned i = 0; i <= (has_interrupts? 0x50 : 0x38); i += 8) {
476 gb->rom[i] = 0xC3; // jp $XXXX
477 gb->rom[i + 1] = (LE16(gb->gbs_header.load_address) + i);
478 gb->rom[i + 2] = (LE16(gb->gbs_header.load_address) + i) >> 8;
479 }
480 for (unsigned i = has_interrupts? 0x58 : 0x40; i <= 0x60; i += 8) {
481 gb->rom[i] = 0xC9; // ret
482 }
483
484 // Generate entry
485 generate_gbs_entry(gb, gb->rom + GBS_ENTRY);
486 }
487
488
489 GB_gbs_switch_track(gb, gb->gbs_header.first_track - 1);
490 if (info) {
491 memset(info, 0, sizeof(*info));
492 info->first_track = gb->gbs_header.first_track - 1;
493 info->track_count = gb->gbs_header.track_count;
494 memcpy(info->title, gb->gbs_header.title, sizeof(gb->gbs_header.title));
495 memcpy(info->author, gb->gbs_header.author, sizeof(gb->gbs_header.author));
496 memcpy(info->copyright, gb->gbs_header.copyright, sizeof(gb->gbs_header.copyright));
497 }
498
499 gb->tried_loading_sgb_border = true; // Don't even attempt on GBS files
500 gb->has_sgb_border = false;
501 load_default_border(gb);
502 return 0;
503 }
504
505 int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info)
506 {
507 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
508
509 FILE *f = fopen(path, "rb");
510 if (!f) {
511 GB_log(gb, "Could not open GBS: %s.\n", strerror(errno));
512 return errno;
513 }
514 fseek(f, 0, SEEK_END);
515 size_t file_size = MIN(ftell(f), sizeof(GB_gbs_header_t) + 0x4000 * 0x100); // Cap with the maximum MBC3 ROM size + GBS header
516 fseek(f, 0, SEEK_SET);
517 uint8_t *file_data = malloc(file_size);
518 fread(file_data, 1, file_size, f);
519 fclose(f);
520
521 int r = GB_load_gbs_from_buffer(gb, file_data, file_size, info);
522 free(file_data);
523 return r;
524 }
525
526 int GB_load_isx(GB_gameboy_t *gb, const char *path)
527 {
528 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
529
530 FILE *f = fopen(path, "rb");
531 if (!f) {
532 GB_log(gb, "Could not open ISX file: %s.\n", strerror(errno));
533 return errno;
534 }
535 char magic[4];
536 #define READ(x) if (fread(&x, sizeof(x), 1, f) != 1) goto error
537 fread(magic, 1, sizeof(magic), f);
538
539
540 bool extended = *(uint32_t *)&magic == BE32('ISX ');
541
542 fseek(f, extended? 0x20 : 0, SEEK_SET);
543
544
545 uint8_t *old_rom = gb->rom;
546 uint32_t old_size = gb->rom_size;
547 gb->rom = NULL;
548 gb->rom_size = 0;
549
550 while (true) {
551 uint8_t record_type = 0;
552 if (fread(&record_type, sizeof(record_type), 1, f) != 1) break;
553 switch (record_type) {
554 case 0x01: { // Binary
555 uint16_t bank;
556 uint16_t address;
557 uint16_t length;
558 uint8_t byte;
559 READ(byte);
560 bank = byte;
561 if (byte >= 0x80) {
562 READ(byte);
563 /* TODO: This is just a guess, the docs don't elaborate on how banks > 0xFF are saved,
564 other than the fact that banks >= 80 requires two bytes to store them, and I haven't
565 encountered an ISX file for a ROM larger than 4MBs yet. */
566 bank += byte << 7;
567 }
568
569 READ(address);
570 address = LE16(address);
571 if (bank) {
572 address &= 0x3FFF;
573 }
574 else {
575 address &= 0x7FFF;
576 }
577
578 READ(length);
579 length = LE16(length);
580
581 size_t needed_size = bank * 0x4000 + address + length;
582 if (needed_size > 1024 * 1024 * 32) goto error;
583
584 if (gb->rom_size < needed_size) {
585 gb->rom = realloc(gb->rom, needed_size);
586 memset(gb->rom + gb->rom_size, 0, needed_size - gb->rom_size);
587 gb->rom_size = needed_size;
588 }
589
590 if (fread(gb->rom + (bank * 0x4000 + address), length, 1, f) != 1) goto error;
591
592 break;
593 }
594
595 case 0x11: { // Extended Binary
596 uint32_t address;
597 uint32_t length;
598
599 READ(address);
600 address = LE32(address);
601
602 READ(length);
603 length = LE32(length);
604 size_t needed_size = address + length;
605 if (needed_size > 1024 * 1024 * 32) goto error;
606
607 if (gb->rom_size < needed_size) {
608 gb->rom = realloc(gb->rom, needed_size);
609 memset(gb->rom + gb->rom_size, 0, needed_size - gb->rom_size);
610 gb->rom_size = needed_size;
611 }
612
613 if (fread(gb->rom + address, length, 1, f) != 1) goto error;
614
615 break;
616 }
617
618 case 0x04: { // Symbol
619 uint16_t count;
620 uint8_t length;
621 char name[257];
622 uint8_t flag;
623 uint8_t bank;
624 uint16_t address;
625 READ(count);
626 count = LE16(count);
627 while (count--) {
628 READ(length);
629 if (fread(name, length, 1, f) != 1) goto error;
630 name[length] = 0;
631 READ(flag); // unused
632
633 READ(bank);
634
635 READ(address);
636 address = LE16(address);
637 GB_debugger_add_symbol(gb, bank, address, name);
638 }
639 break;
640 }
641
642 case 0x14: { // Extended Binary
643 uint16_t count;
644 uint8_t length;
645 char name[257];
646 uint8_t flag;
647 uint32_t address;
648 READ(count);
649 count = LE16(count);
650 while (count--) {
651 READ(length);
652 if (fread(name, length + 1, 1, f) != 1) goto error;
653 name[length] = 0;
654 READ(flag); // unused
655
656 READ(address);
657 address = LE32(address);
658 // TODO: How to convert 32-bit addresses to Bank:Address? Needs to tell RAM and ROM apart
659 }
660 break;
661 }
662
663 default:
664 goto done;
665 }
666 }
667 done:;
668 #undef READ
669 if (gb->rom_size == 0) goto error;
670 fclose(f);
671
672 size_t needed_size = (gb->rom_size + 0x3FFF) & ~0x3FFF; /* Round to bank */
673
674 /* And then round to a power of two */
675 while (needed_size & (needed_size - 1)) {
676 /* I promise this works. */
677 needed_size |= needed_size >> 1;
678 needed_size++;
679 }
680
681 if (needed_size < 0x8000) {
682 needed_size = 0x8000;
683 }
684
685 if (gb->rom_size < needed_size) {
686 gb->rom = realloc(gb->rom, needed_size);
687 memset(gb->rom + gb->rom_size, 0, needed_size - gb->rom_size);
688 gb->rom_size = needed_size;
689 }
690
691 GB_configure_cart(gb);
692
693 // Fix a common wrong MBC error
694 if (gb->rom[0x147] == 3) { // MBC1 + RAM + Battery
695 bool needs_fix = false;
696 if (gb->rom_size >= 0x21 * 0x4000) {
697 for (unsigned i = 0x20 * 0x4000; i < 0x21 * 0x4000; i++) {
698 if (gb->rom[i]) {
699 needs_fix = true;
700 break;
701 }
702 }
703 }
704 if (!needs_fix && gb->rom_size >= 0x41 * 0x4000) {
705 for (unsigned i = 0x40 * 0x4000; i < 0x41 * 0x4000; i++) {
706 if (gb->rom[i]) {
707 needs_fix = true;
708 break;
709 }
710 }
711 }
712 if (!needs_fix && gb->rom_size >= 0x61 * 0x4000) {
713 for (unsigned i = 0x60 * 0x4000; i < 0x61 * 0x4000; i++) {
714 if (gb->rom[i]) {
715 needs_fix = true;
716 break;
717 }
718 }
719 }
720 if (needs_fix) {
721 gb->rom[0x147] = 0x10; // MBC3 + RTC + RAM + Battery
722 GB_configure_cart(gb);
723 gb->rom[0x147] = 0x3;
724 GB_log(gb, "ROM claims to use MBC1 but appears to require MBC3 or 5, assuming MBC3.\n");
725 }
726 }
727
728 // Inject a correct checksum, the official linker doesn't always fix it, which breaks the official boot ROMs
729 uint8_t original_checksum = gb->rom[0x14d];
730 gb->rom[0x14d] = 0;
731 for (unsigned addr = 0x0134; addr <= 0x014C; addr++) {
732 gb->rom[0x14d] -= gb->rom[addr] + 1;
733 }
734
735 if (original_checksum != gb->rom[0x14d]) {
736 GB_log(gb, "This ROM's header checksum has been automatically corrected\n");
737 }
738
739 if (old_rom) {
740 free(old_rom);
741 }
742
743 return 0;
744 error:
745 GB_log(gb, "Invalid or unsupported ISX file.\n");
746 if (gb->rom) {
747 free(gb->rom);
748 gb->rom = old_rom;
749 gb->rom_size = old_size;
750 }
751 fclose(f);
752 gb->tried_loading_sgb_border = false;
753 gb->has_sgb_border = false;
754 load_default_border(gb);
755 return -1;
756 }
757
758 void GB_load_rom_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size)
759 {
760 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
761
762 gb->rom_size = rounded_rom_size(size);
763 if (gb->rom) {
764 free(gb->rom);
765 }
766 gb->rom = malloc(gb->rom_size);
767 memset(gb->rom, 0xFF, gb->rom_size);
768 memcpy(gb->rom, buffer, size);
769 GB_configure_cart(gb);
770 gb->tried_loading_sgb_border = false;
771 gb->has_sgb_border = false;
772 load_default_border(gb);
773 }
774
775 typedef struct {
776 uint8_t seconds;
777 uint8_t padding1[3];
778 uint8_t minutes;
779 uint8_t padding2[3];
780 uint8_t hours;
781 uint8_t padding3[3];
782 uint8_t days;
783 uint8_t padding4[3];
784 uint8_t high;
785 uint8_t padding5[3];
786 } vba_rtc_time_t;
787
788 typedef struct __attribute__((packed)) {
789 uint32_t magic;
790 uint16_t version;
791 uint8_t mr4;
792 uint8_t reserved;
793 uint64_t last_rtc_second;
794 uint8_t rtc_data[4];
795 } tpp1_rtc_save_t;
796
797 typedef union {
798 struct __attribute__((packed)) {
799 GB_rtc_time_t rtc_real;
800 time_t last_rtc_second; /* Platform specific endianess and size */
801 } sameboy_legacy;
802 struct {
803 /* Used by VBA versions with 32-bit timestamp*/
804 vba_rtc_time_t rtc_real, rtc_latched;
805 uint32_t last_rtc_second; /* Always little endian */
806 } vba32;
807 struct {
808 /* Used by BGB and VBA versions with 64-bit timestamp*/
809 vba_rtc_time_t rtc_real, rtc_latched;
810 uint64_t last_rtc_second; /* Always little endian */
811 } vba64;
812 } rtc_save_t;
813
814 static void fill_tpp1_save_data(GB_gameboy_t *gb, tpp1_rtc_save_t *data)
815 {
816 data->magic = BE32('TPP1');
817 data->version = BE16(0x100);
818 data->mr4 = gb->tpp1_mr4;
819 data->reserved = 0;
820 data->last_rtc_second = LE64(time(NULL));
821 unrolled for (unsigned i = 4; i--;) {
822 data->rtc_data[i] = gb->rtc_real.data[i ^ 3];
823 }
824 }
825
826 int GB_save_battery_size(GB_gameboy_t *gb)
827 {
828 if (!gb->cartridge_type->has_battery) return 0; // Nothing to save.
829 if (gb->cartridge_type->mbc_type == GB_TPP1 && !(gb->rom[0x153] & 8)) return 0; // Nothing to save.
830
831 if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
832
833 if (gb->cartridge_type->mbc_type == GB_HUC3) {
834 return gb->mbc_ram_size + sizeof(GB_huc3_rtc_time_t);
835 }
836
837 if (gb->cartridge_type->mbc_type == GB_TPP1) {
838 return gb->mbc_ram_size + sizeof(tpp1_rtc_save_t);
839 }
840
841 rtc_save_t rtc_save_size;
842 return gb->mbc_ram_size + (gb->cartridge_type->has_rtc ? sizeof(rtc_save_size.vba64) : 0);
843 }
844
845 int GB_save_battery_to_buffer(GB_gameboy_t *gb, uint8_t *buffer, size_t size)
846 {
847 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
848
849 if (!gb->cartridge_type->has_battery) return 0; // Nothing to save.
850 if (gb->cartridge_type->mbc_type == GB_TPP1 && !(gb->rom[0x153] & 8)) return 0; // Nothing to save.
851 if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
852
853 if (size < GB_save_battery_size(gb)) return EIO;
854
855 memcpy(buffer, gb->mbc_ram, gb->mbc_ram_size);
856
857 if (gb->cartridge_type->mbc_type == GB_TPP1) {
858 buffer += gb->mbc_ram_size;
859 tpp1_rtc_save_t rtc_save;
860 fill_tpp1_save_data(gb, &rtc_save);
861 memcpy(buffer, &rtc_save, sizeof(rtc_save));
862 }
863 else if (gb->cartridge_type->mbc_type == GB_HUC3) {
864 buffer += gb->mbc_ram_size;
865
866 GB_huc3_rtc_time_t rtc_save = {
867 LE64(gb->last_rtc_second),
868 LE16(gb->huc3.minutes),
869 LE16(gb->huc3.days),
870 LE16(gb->huc3.alarm_minutes),
871 LE16(gb->huc3.alarm_days),
872 gb->huc3.alarm_enabled,
873 };
874 memcpy(buffer, &rtc_save, sizeof(rtc_save));
875 }
876 else if (gb->cartridge_type->has_rtc) {
877 rtc_save_t rtc_save = {{{{0,}},},};
878 rtc_save.vba64.rtc_real.seconds = gb->rtc_real.seconds;
879 rtc_save.vba64.rtc_real.minutes = gb->rtc_real.minutes;
880 rtc_save.vba64.rtc_real.hours = gb->rtc_real.hours;
881 rtc_save.vba64.rtc_real.days = gb->rtc_real.days;
882 rtc_save.vba64.rtc_real.high = gb->rtc_real.high;
883 rtc_save.vba64.rtc_latched.seconds = gb->rtc_latched.seconds;
884 rtc_save.vba64.rtc_latched.minutes = gb->rtc_latched.minutes;
885 rtc_save.vba64.rtc_latched.hours = gb->rtc_latched.hours;
886 rtc_save.vba64.rtc_latched.days = gb->rtc_latched.days;
887 rtc_save.vba64.rtc_latched.high = gb->rtc_latched.high;
888 rtc_save.vba64.last_rtc_second = LE64(time(NULL));
889 memcpy(buffer + gb->mbc_ram_size, &rtc_save.vba64, sizeof(rtc_save.vba64));
890 }
891
892 return 0;
893 }
894
895 int GB_save_battery(GB_gameboy_t *gb, const char *path)
896 {
897 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
898
899 if (!gb->cartridge_type->has_battery) return 0; // Nothing to save.
900 if (gb->cartridge_type->mbc_type == GB_TPP1 && !(gb->rom[0x153] & 8)) return 0; // Nothing to save.
901 if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
902 FILE *f = fopen(path, "wb");
903 if (!f) {
904 GB_log(gb, "Could not open battery save: %s.\n", strerror(errno));
905 return errno;
906 }
907
908 if (fwrite(gb->mbc_ram, 1, gb->mbc_ram_size, f) != gb->mbc_ram_size) {
909 fclose(f);
910 return EIO;
911 }
912 if (gb->cartridge_type->mbc_type == GB_TPP1) {
913 tpp1_rtc_save_t rtc_save;
914 fill_tpp1_save_data(gb, &rtc_save);
915
916 if (fwrite(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
917 fclose(f);
918 return EIO;
919 }
920 }
921 else if (gb->cartridge_type->mbc_type == GB_HUC3) {
922 GB_huc3_rtc_time_t rtc_save = {
923 LE64(gb->last_rtc_second),
924 LE16(gb->huc3.minutes),
925 LE16(gb->huc3.days),
926 LE16(gb->huc3.alarm_minutes),
927 LE16(gb->huc3.alarm_days),
928 gb->huc3.alarm_enabled,
929 };
930
931 if (fwrite(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
932 fclose(f);
933 return EIO;
934 }
935 }
936 else if (gb->cartridge_type->has_rtc) {
937 rtc_save_t rtc_save = {{{{0,}},},};
938 rtc_save.vba64.rtc_real.seconds = gb->rtc_real.seconds;
939 rtc_save.vba64.rtc_real.minutes = gb->rtc_real.minutes;
940 rtc_save.vba64.rtc_real.hours = gb->rtc_real.hours;
941 rtc_save.vba64.rtc_real.days = gb->rtc_real.days;
942 rtc_save.vba64.rtc_real.high = gb->rtc_real.high;
943 rtc_save.vba64.rtc_latched.seconds = gb->rtc_latched.seconds;
944 rtc_save.vba64.rtc_latched.minutes = gb->rtc_latched.minutes;
945 rtc_save.vba64.rtc_latched.hours = gb->rtc_latched.hours;
946 rtc_save.vba64.rtc_latched.days = gb->rtc_latched.days;
947 rtc_save.vba64.rtc_latched.high = gb->rtc_latched.high;
948 rtc_save.vba64.last_rtc_second = LE64(time(NULL));
949 if (fwrite(&rtc_save.vba64, 1, sizeof(rtc_save.vba64), f) != sizeof(rtc_save.vba64)) {
950 fclose(f);
951 return EIO;
952 }
953
954 }
955
956 fclose(f);
957 return 0;
958 }
959
960 static void load_tpp1_save_data(GB_gameboy_t *gb, const tpp1_rtc_save_t *data)
961 {
962 gb->last_rtc_second = LE64(data->last_rtc_second);
963 unrolled for (unsigned i = 4; i--;) {
964 gb->rtc_real.data[i ^ 3] = data->rtc_data[i];
965 }
966 }
967
968 void GB_load_battery_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size)
969 {
970 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
971
972 memcpy(gb->mbc_ram, buffer, MIN(gb->mbc_ram_size, size));
973 if (size <= gb->mbc_ram_size) {
974 goto reset_rtc;
975 }
976
977 if (gb->cartridge_type->mbc_type == GB_TPP1) {
978 tpp1_rtc_save_t rtc_save;
979 if (size - gb->mbc_ram_size < sizeof(rtc_save)) {
980 goto reset_rtc;
981 }
982 memcpy(&rtc_save, buffer + gb->mbc_ram_size, sizeof(rtc_save));
983
984 load_tpp1_save_data(gb, &rtc_save);
985
986 if (gb->last_rtc_second > time(NULL)) {
987 /* We must reset RTC here, or it will not advance. */
988 goto reset_rtc;
989 }
990 return;
991 }
992
993 if (gb->cartridge_type->mbc_type == GB_HUC3) {
994 GB_huc3_rtc_time_t rtc_save;
995 if (size - gb->mbc_ram_size < sizeof(rtc_save)) {
996 goto reset_rtc;
997 }
998 memcpy(&rtc_save, buffer + gb->mbc_ram_size, sizeof(rtc_save));
999 gb->last_rtc_second = LE64(rtc_save.last_rtc_second);
1000 gb->huc3.minutes = LE16(rtc_save.minutes);
1001 gb->huc3.days = LE16(rtc_save.days);
1002 gb->huc3.alarm_minutes = LE16(rtc_save.alarm_minutes);
1003 gb->huc3.alarm_days = LE16(rtc_save.alarm_days);
1004 gb->huc3.alarm_enabled = rtc_save.alarm_enabled;
1005 if (gb->last_rtc_second > time(NULL)) {
1006 /* We must reset RTC here, or it will not advance. */
1007 goto reset_rtc;
1008 }
1009 return;
1010 }
1011
1012 rtc_save_t rtc_save;
1013 memcpy(&rtc_save, buffer + gb->mbc_ram_size, MIN(sizeof(rtc_save), size));
1014 switch (size - gb->mbc_ram_size) {
1015 case sizeof(rtc_save.sameboy_legacy):
1016 memcpy(&gb->rtc_real, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1017 memcpy(&gb->rtc_latched, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1018 gb->last_rtc_second = rtc_save.sameboy_legacy.last_rtc_second;
1019 break;
1020
1021 case sizeof(rtc_save.vba32):
1022 gb->rtc_real.seconds = rtc_save.vba32.rtc_real.seconds;
1023 gb->rtc_real.minutes = rtc_save.vba32.rtc_real.minutes;
1024 gb->rtc_real.hours = rtc_save.vba32.rtc_real.hours;
1025 gb->rtc_real.days = rtc_save.vba32.rtc_real.days;
1026 gb->rtc_real.high = rtc_save.vba32.rtc_real.high;
1027 gb->rtc_latched.seconds = rtc_save.vba32.rtc_latched.seconds;
1028 gb->rtc_latched.minutes = rtc_save.vba32.rtc_latched.minutes;
1029 gb->rtc_latched.hours = rtc_save.vba32.rtc_latched.hours;
1030 gb->rtc_latched.days = rtc_save.vba32.rtc_latched.days;
1031 gb->rtc_latched.high = rtc_save.vba32.rtc_latched.high;
1032 gb->last_rtc_second = LE32(rtc_save.vba32.last_rtc_second);
1033 break;
1034
1035 case sizeof(rtc_save.vba64):
1036 gb->rtc_real.seconds = rtc_save.vba64.rtc_real.seconds;
1037 gb->rtc_real.minutes = rtc_save.vba64.rtc_real.minutes;
1038 gb->rtc_real.hours = rtc_save.vba64.rtc_real.hours;
1039 gb->rtc_real.days = rtc_save.vba64.rtc_real.days;
1040 gb->rtc_real.high = rtc_save.vba64.rtc_real.high;
1041 gb->rtc_latched.seconds = rtc_save.vba64.rtc_latched.seconds;
1042 gb->rtc_latched.minutes = rtc_save.vba64.rtc_latched.minutes;
1043 gb->rtc_latched.hours = rtc_save.vba64.rtc_latched.hours;
1044 gb->rtc_latched.days = rtc_save.vba64.rtc_latched.days;
1045 gb->rtc_latched.high = rtc_save.vba64.rtc_latched.high;
1046 gb->last_rtc_second = LE64(rtc_save.vba64.last_rtc_second);
1047 break;
1048
1049 default:
1050 goto reset_rtc;
1051 }
1052 if (gb->last_rtc_second > time(NULL)) {
1053 /* We must reset RTC here, or it will not advance. */
1054 goto reset_rtc;
1055 }
1056
1057 if (gb->last_rtc_second < 852076800) { /* 1/1/97. There weren't any RTC games that time,
1058 so if the value we read is lower it means it wasn't
1059 really RTC data. */
1060 goto reset_rtc;
1061 }
1062 GB_rtc_set_time(gb, time(NULL));
1063 goto exit;
1064
1065 reset_rtc:
1066 gb->last_rtc_second = time(NULL);
1067 gb->rtc_real.high |= 0x80; /* This gives the game a hint that the clock should be reset. */
1068 if (gb->cartridge_type->mbc_type == GB_HUC3) {
1069 gb->huc3.days = 0xFFFF;
1070 gb->huc3.minutes = 0xFFF;
1071 gb->huc3.alarm_enabled = false;
1072 }
1073 exit:
1074 return;
1075 }
1076
1077 /* Loading will silently stop if the format is incomplete */
1078 int GB_load_battery(GB_gameboy_t *gb, const char *path)
1079 {
1080 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1081
1082 FILE *f = fopen(path, "rb");
1083 if (!f) {
1084 return errno;
1085 }
1086
1087 if (fread(gb->mbc_ram, 1, gb->mbc_ram_size, f) != gb->mbc_ram_size) {
1088 goto reset_rtc;
1089 }
1090
1091 if (gb->cartridge_type->mbc_type == GB_TPP1) {
1092 tpp1_rtc_save_t rtc_save;
1093 if (fread(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
1094 goto reset_rtc;
1095 }
1096
1097 load_tpp1_save_data(gb, &rtc_save);
1098
1099 if (gb->last_rtc_second > time(NULL)) {
1100 /* We must reset RTC here, or it will not advance. */
1101 goto reset_rtc;
1102 }
1103 goto exit;
1104 }
1105
1106 if (gb->cartridge_type->mbc_type == GB_HUC3) {
1107 GB_huc3_rtc_time_t rtc_save;
1108 if (fread(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
1109 goto reset_rtc;
1110 }
1111 gb->last_rtc_second = LE64(rtc_save.last_rtc_second);
1112 gb->huc3.minutes = LE16(rtc_save.minutes);
1113 gb->huc3.days = LE16(rtc_save.days);
1114 gb->huc3.alarm_minutes = LE16(rtc_save.alarm_minutes);
1115 gb->huc3.alarm_days = LE16(rtc_save.alarm_days);
1116 gb->huc3.alarm_enabled = rtc_save.alarm_enabled;
1117
1118 if (gb->last_rtc_second > time(NULL)) {
1119 /* We must reset RTC here, or it will not advance. */
1120 goto reset_rtc;
1121 }
1122 goto exit;
1123 }
1124
1125 rtc_save_t rtc_save;
1126 switch (fread(&rtc_save, 1, sizeof(rtc_save), f)) {
1127 case sizeof(rtc_save.sameboy_legacy):
1128 memcpy(&gb->rtc_real, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1129 memcpy(&gb->rtc_latched, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1130 gb->last_rtc_second = rtc_save.sameboy_legacy.last_rtc_second;
1131 break;
1132
1133 case sizeof(rtc_save.vba32):
1134 gb->rtc_real.seconds = rtc_save.vba32.rtc_real.seconds;
1135 gb->rtc_real.minutes = rtc_save.vba32.rtc_real.minutes;
1136 gb->rtc_real.hours = rtc_save.vba32.rtc_real.hours;
1137 gb->rtc_real.days = rtc_save.vba32.rtc_real.days;
1138 gb->rtc_real.high = rtc_save.vba32.rtc_real.high;
1139 gb->rtc_latched.seconds = rtc_save.vba32.rtc_latched.seconds;
1140 gb->rtc_latched.minutes = rtc_save.vba32.rtc_latched.minutes;
1141 gb->rtc_latched.hours = rtc_save.vba32.rtc_latched.hours;
1142 gb->rtc_latched.days = rtc_save.vba32.rtc_latched.days;
1143 gb->rtc_latched.high = rtc_save.vba32.rtc_latched.high;
1144 gb->last_rtc_second = LE32(rtc_save.vba32.last_rtc_second);
1145 break;
1146
1147 case sizeof(rtc_save.vba64):
1148 gb->rtc_real.seconds = rtc_save.vba64.rtc_real.seconds;
1149 gb->rtc_real.minutes = rtc_save.vba64.rtc_real.minutes;
1150 gb->rtc_real.hours = rtc_save.vba64.rtc_real.hours;
1151 gb->rtc_real.days = rtc_save.vba64.rtc_real.days;
1152 gb->rtc_real.high = rtc_save.vba64.rtc_real.high;
1153 gb->rtc_latched.seconds = rtc_save.vba64.rtc_latched.seconds;
1154 gb->rtc_latched.minutes = rtc_save.vba64.rtc_latched.minutes;
1155 gb->rtc_latched.hours = rtc_save.vba64.rtc_latched.hours;
1156 gb->rtc_latched.days = rtc_save.vba64.rtc_latched.days;
1157 gb->rtc_latched.high = rtc_save.vba64.rtc_latched.high;
1158 gb->last_rtc_second = LE64(rtc_save.vba64.last_rtc_second);
1159 break;
1160
1161 default:
1162 goto reset_rtc;
1163 }
1164 if (gb->last_rtc_second > time(NULL)) {
1165 /* We must reset RTC here, or it will not advance. */
1166 goto reset_rtc;
1167 }
1168
1169 if (gb->last_rtc_second < 852076800) { /* 1/1/97. There weren't any RTC games that time,
1170 so if the value we read is lower it means it wasn't
1171 really RTC data. */
1172 goto reset_rtc;
1173 }
1174 GB_rtc_set_time(gb, time(NULL));
1175 goto exit;
1176
1177 reset_rtc:
1178 gb->last_rtc_second = time(NULL);
1179 gb->rtc_real.high |= 0x80; /* This gives the game a hint that the clock should be reset. */
1180 if (gb->cartridge_type->mbc_type == GB_HUC3) {
1181 gb->huc3.days = 0xFFFF;
1182 gb->huc3.minutes = 0xFFF;
1183 gb->huc3.alarm_enabled = false;
1184 }
1185 exit:
1186 fclose(f);
1187 return 0;
1188 }
1189
1190 unsigned GB_run(GB_gameboy_t *gb)
1191 {
1192 GB_ASSERT_NOT_RUNNING(gb)
1193 gb->vblank_just_occured = false;
1194
1195 if (unlikely(gb->sgb && gb->sgb->intro_animation < 96)) {
1196 /* On the SGB, the GB is halted after finishing the boot ROM.
1197 Then, after the boot animation is almost done, it's reset.
1198 Since the SGB HLE does not perform any header validity checks,
1199 we just halt the CPU (with hacky code) until the correct time.
1200 This ensures the Nintendo logo doesn't flash on screen, and
1201 the game does "run in background" while the animation is playing. */
1202
1203 GB_set_running_thread(gb);
1204 GB_display_run(gb, 228, true);
1205 GB_clear_running_thread(gb);
1206 gb->cycles_since_last_sync += 228;
1207 return 228;
1208 }
1209
1210 GB_debugger_run(gb);
1211 gb->cycles_since_run = 0;
1212 GB_set_running_thread(gb);
1213 GB_cpu_run(gb);
1214 GB_clear_running_thread(gb);
1215 if (unlikely(gb->vblank_just_occured)) {
1216 GB_update_faux_analog(gb);
1217 GB_debugger_handle_async_commands(gb);
1218 GB_set_running_thread(gb);
1219 GB_rewind_push(gb);
1220 GB_clear_running_thread(gb);
1221 }
1222 if (!(gb->io_registers[GB_IO_IF] & 0x10) && (gb->io_registers[GB_IO_JOYP] & 0x30) != 0x30) {
1223 gb->joyp_accessed = true;
1224 }
1225 return gb->cycles_since_run;
1226 }
1227
1228 uint64_t GB_run_frame(GB_gameboy_t *gb)
1229 {
1230 /* Configure turbo temporarily, the user wants to handle FPS capping manually. */
1231 bool old_turbo = gb->turbo;
1232 bool old_dont_skip = gb->turbo_dont_skip;
1233 double old_turbo_cap = gb->turbo_cap_multiplier;
1234 gb->turbo = true;
1235 gb->turbo_dont_skip = true;
1236 gb->turbo_cap_multiplier = 0;
1237
1238 gb->cycles_since_last_sync = 0;
1239 while (true) {
1240 GB_run(gb);
1241 if (gb->vblank_just_occured) {
1242 break;
1243 }
1244 }
1245 gb->turbo = old_turbo;
1246 gb->turbo_dont_skip = old_dont_skip;
1247 gb->turbo_cap_multiplier = old_turbo_cap;
1248 return gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */
1249 }
1250
1251 uint32_t *GB_get_pixels_output(GB_gameboy_t *gb)
1252 {
1253 return gb->screen;
1254 }
1255
1256 void GB_set_log_callback(GB_gameboy_t *gb, GB_log_callback_t callback)
1257 {
1258 if (!callback) {
1259 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1260 }
1261 gb->log_callback = callback;
1262 }
1263
1264 void GB_set_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback)
1265 {
1266 #ifndef GB_DISABLE_DEBUGGER
1267 if (!callback) {
1268 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1269 }
1270 if (gb->input_callback == default_input_callback) {
1271 gb->async_input_callback = NULL;
1272 }
1273 gb->input_callback = callback;
1274 #endif
1275 }
1276
1277 void GB_set_async_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback)
1278 {
1279 #ifndef GB_DISABLE_DEBUGGER
1280 if (!callback) {
1281 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1282 }
1283 gb->async_input_callback = callback;
1284 #endif
1285 }
1286
1287 void GB_set_execution_callback(GB_gameboy_t *gb, GB_execution_callback_t callback)
1288 {
1289 if (!callback) {
1290 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1291 }
1292 gb->execution_callback = callback;
1293 }
1294
1295 void GB_set_lcd_line_callback(GB_gameboy_t *gb, GB_lcd_line_callback_t callback)
1296 {
1297 if (!callback) {
1298 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1299 }
1300 gb->lcd_line_callback = callback;
1301 }
1302
1303 void GB_set_lcd_status_callback(GB_gameboy_t *gb, GB_lcd_status_callback_t callback)
1304 {
1305 if (!callback) {
1306 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1307 }
1308 gb->lcd_status_callback = callback;
1309 }
1310
1311 void GB_set_infrared_callback(GB_gameboy_t *gb, GB_infrared_callback_t callback)
1312 {
1313 if (!callback) {
1314 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1315 }
1316 gb->infrared_callback = callback;
1317 }
1318
1319 void GB_set_infrared_input(GB_gameboy_t *gb, bool state)
1320 {
1321 gb->infrared_input = state;
1322 }
1323
1324 void GB_set_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback)
1325 {
1326 if (!callback) {
1327 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1328 }
1329 gb->rumble_callback = callback;
1330 }
1331
1332 void GB_set_serial_transfer_bit_start_callback(GB_gameboy_t *gb, GB_serial_transfer_bit_start_callback_t callback)
1333 {
1334 if (!callback) {
1335 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1336 }
1337 gb->serial_transfer_bit_start_callback = callback;
1338 }
1339
1340 void GB_set_serial_transfer_bit_end_callback(GB_gameboy_t *gb, GB_serial_transfer_bit_end_callback_t callback)
1341 {
1342 if (!callback) {
1343 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1344 }
1345 gb->serial_transfer_bit_end_callback = callback;
1346 }
1347
1348 bool GB_serial_get_data_bit(GB_gameboy_t *gb)
1349 {
1350 if (!(gb->io_registers[GB_IO_SC] & 0x80)) {
1351 /* Disabled serial returns 0 bits */
1352 return false;
1353 }
1354
1355 if (gb->io_registers[GB_IO_SC] & 1) {
1356 /* Internal Clock */
1357 GB_log(gb, "Serial read request while using internal clock. \n");
1358 return true;
1359 }
1360 return gb->io_registers[GB_IO_SB] & 0x80;
1361 }
1362
1363 void GB_serial_set_data_bit(GB_gameboy_t *gb, bool data)
1364 {
1365 if (!(gb->io_registers[GB_IO_SC] & 0x80)) {
1366 /* Serial disabled */
1367 return;
1368 }
1369
1370 if (gb->io_registers[GB_IO_SC] & 1) {
1371 /* Internal Clock */
1372 GB_log(gb, "Serial write request while using internal clock. \n");
1373 return;
1374 }
1375
1376 gb->io_registers[GB_IO_SB] <<= 1;
1377 gb->io_registers[GB_IO_SB] |= data;
1378 gb->serial_count++;
1379 if (gb->serial_count == 8) {
1380 gb->io_registers[GB_IO_SC] &= ~0x80;
1381 gb->io_registers[GB_IO_IF] |= 8;
1382 gb->serial_count = 0;
1383 }
1384 }
1385
1386 void GB_disconnect_serial(GB_gameboy_t *gb)
1387 {
1388 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1389 gb->serial_transfer_bit_start_callback = NULL;
1390 gb->serial_transfer_bit_end_callback = NULL;
1391
1392 /* Reset any internally-emulated device. */
1393 memset(GB_GET_SECTION(gb, accessory), 0, GB_SECTION_SIZE(accessory));
1394 }
1395
1396 GB_accessory_t GB_get_built_in_accessory(GB_gameboy_t *gb)
1397 {
1398 return gb->accessory;
1399 }
1400
1401 bool GB_is_inited(GB_gameboy_t *gb)
1402 {
1403 return gb->magic == GB_state_magic();
1404 }
1405
1406 bool GB_is_cgb(const GB_gameboy_t *gb)
1407 {
1408 return gb->model >= GB_MODEL_CGB_0;
1409 }
1410
1411 bool GB_is_cgb_in_cgb_mode(GB_gameboy_t *gb)
1412 {
1413 return gb->cgb_mode;
1414 }
1415
1416 bool GB_is_sgb(GB_gameboy_t *gb)
1417 {
1418 return (gb->model & ~GB_MODEL_PAL_BIT & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB || (gb->model & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB2;
1419 }
1420
1421 bool GB_is_hle_sgb(GB_gameboy_t *gb)
1422 {
1423 return (gb->model & ~GB_MODEL_PAL_BIT) == GB_MODEL_SGB || gb->model == GB_MODEL_SGB2;
1424 }
1425
1426 void GB_set_turbo_mode(GB_gameboy_t *gb, bool on, bool no_frame_skip)
1427 {
1428 gb->turbo = on;
1429 gb->turbo_dont_skip = no_frame_skip;
1430 }
1431
1432 void GB_set_turbo_cap(GB_gameboy_t *gb, double multiplier)
1433 {
1434 gb->turbo_cap_multiplier = multiplier;
1435 }
1436
1437 void GB_set_rendering_disabled(GB_gameboy_t *gb, bool disabled)
1438 {
1439 gb->disable_rendering = disabled;
1440 }
1441
1442 void *GB_get_user_data(GB_gameboy_t *gb)
1443 {
1444 return gb->user_data;
1445 }
1446
1447 void GB_set_user_data(GB_gameboy_t *gb, void *data)
1448 {
1449 gb->user_data = data;
1450 }
1451
1452 static void reset_ram(GB_gameboy_t *gb)
1453 {
1454 switch (gb->model) {
1455 case GB_MODEL_MGB:
1456 case GB_MODEL_CGB_E:
1457 case GB_MODEL_AGB_A: /* Unverified */
1458 case GB_MODEL_GBP_A:
1459 for (unsigned i = 0; i < gb->ram_size; i++) {
1460 gb->ram[i] = GB_random();
1461 }
1462 break;
1463
1464 case GB_MODEL_DMG_B:
1465 case GB_MODEL_SGB_NTSC: /* Unverified*/
1466 case GB_MODEL_SGB_PAL: /* Unverified */
1467 case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1468 case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1469 for (unsigned i = 0; i < gb->ram_size; i++) {
1470 gb->ram[i] = GB_random();
1471 if (i & 0x100) {
1472 gb->ram[i] &= GB_random();
1473 }
1474 else {
1475 gb->ram[i] |= GB_random();
1476 }
1477 }
1478 break;
1479
1480 case GB_MODEL_SGB2:
1481 case GB_MODEL_SGB2_NO_SFC:
1482 for (unsigned i = 0; i < gb->ram_size; i++) {
1483 gb->ram[i] = 0x55;
1484 gb->ram[i] ^= GB_random() & GB_random() & GB_random();
1485 }
1486 break;
1487
1488 case GB_MODEL_CGB_0:
1489 case GB_MODEL_CGB_A:
1490 case GB_MODEL_CGB_B:
1491 case GB_MODEL_CGB_C:
1492 for (unsigned i = 0; i < gb->ram_size; i++) {
1493 if ((i & 0x808) == 0x800 || (i & 0x808) == 0x008) {
1494 gb->ram[i] = 0;
1495 }
1496 else {
1497 gb->ram[i] = GB_random() | GB_random() | GB_random() | GB_random() | GB_random();
1498 }
1499 }
1500 break;
1501 case GB_MODEL_CGB_D:
1502 for (unsigned i = 0; i < gb->ram_size; i++) {
1503 gb->ram[i] = GB_random();
1504 if (i & 0x800) {
1505 gb->ram[i] &= GB_random();
1506 }
1507 else {
1508 gb->ram[i] |= GB_random();
1509 }
1510 }
1511 break;
1512 }
1513
1514 /* HRAM */
1515 switch (gb->model) {
1516 case GB_MODEL_CGB_0:
1517 case GB_MODEL_CGB_A:
1518 case GB_MODEL_CGB_B:
1519 case GB_MODEL_CGB_C:
1520 case GB_MODEL_CGB_D:
1521 case GB_MODEL_CGB_E:
1522 case GB_MODEL_AGB_A:
1523 case GB_MODEL_GBP_A:
1524 nounroll for (unsigned i = 0; i < sizeof(gb->hram); i++) {
1525 gb->hram[i] = GB_random();
1526 }
1527 break;
1528
1529 case GB_MODEL_DMG_B:
1530 case GB_MODEL_MGB:
1531 case GB_MODEL_SGB_NTSC: /* Unverified*/
1532 case GB_MODEL_SGB_PAL: /* Unverified */
1533 case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1534 case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1535 case GB_MODEL_SGB2:
1536 case GB_MODEL_SGB2_NO_SFC:
1537 nounroll for (unsigned i = 0; i < sizeof(gb->hram); i++) {
1538 if (i & 1) {
1539 gb->hram[i] = GB_random() | GB_random() | GB_random();
1540 }
1541 else {
1542 gb->hram[i] = GB_random() & GB_random() & GB_random();
1543 }
1544 }
1545 break;
1546 }
1547
1548 /* OAM */
1549 switch (gb->model) {
1550 case GB_MODEL_CGB_0:
1551 case GB_MODEL_CGB_A:
1552 case GB_MODEL_CGB_B:
1553 case GB_MODEL_CGB_C:
1554 case GB_MODEL_CGB_D:
1555 case GB_MODEL_CGB_E:
1556 case GB_MODEL_AGB_A:
1557 case GB_MODEL_GBP_A:
1558 /* Zero'd out by boot ROM anyway */
1559 break;
1560
1561 case GB_MODEL_DMG_B:
1562 case GB_MODEL_MGB:
1563 case GB_MODEL_SGB_NTSC: /* Unverified */
1564 case GB_MODEL_SGB_PAL: /* Unverified */
1565 case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1566 case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1567 case GB_MODEL_SGB2:
1568 case GB_MODEL_SGB2_NO_SFC:
1569 for (unsigned i = 0; i < sizeof(gb->oam); i++) {
1570 if (i & 2) {
1571 gb->oam[i] = GB_random() & GB_random() & GB_random();
1572 }
1573 else {
1574 gb->oam[i] = GB_random() | GB_random() | GB_random();
1575 }
1576 }
1577 break;
1578 }
1579
1580 /* Wave RAM */
1581 switch (gb->model) {
1582 case GB_MODEL_CGB_0:
1583 case GB_MODEL_CGB_A:
1584 case GB_MODEL_CGB_B:
1585 case GB_MODEL_CGB_C:
1586 case GB_MODEL_CGB_D:
1587 case GB_MODEL_CGB_E:
1588 case GB_MODEL_AGB_A:
1589 case GB_MODEL_GBP_A:
1590 /* Initialized by CGB-A and newer, 0s in CGB-0 */
1591 break;
1592 case GB_MODEL_MGB: {
1593 nounroll for (unsigned i = 0; i < GB_IO_WAV_END - GB_IO_WAV_START; i++) {
1594 if (i & 1) {
1595 gb->io_registers[GB_IO_WAV_START + i] = GB_random() & GB_random();
1596 }
1597 else {
1598 gb->io_registers[GB_IO_WAV_START + i] = GB_random() | GB_random();
1599 }
1600 }
1601 break;
1602 }
1603 case GB_MODEL_DMG_B:
1604 case GB_MODEL_SGB_NTSC: /* Unverified*/
1605 case GB_MODEL_SGB_PAL: /* Unverified */
1606 case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1607 case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1608 case GB_MODEL_SGB2:
1609 case GB_MODEL_SGB2_NO_SFC: {
1610 nounroll for (unsigned i = 0; i < GB_IO_WAV_END - GB_IO_WAV_START; i++) {
1611 if (i & 1) {
1612 gb->io_registers[GB_IO_WAV_START + i] = GB_random() & GB_random() & GB_random();
1613 }
1614 else {
1615 gb->io_registers[GB_IO_WAV_START + i] = GB_random() | GB_random() | GB_random();
1616 }
1617 }
1618 break;
1619 }
1620 }
1621
1622 for (unsigned i = 0; i < sizeof(gb->extra_oam); i++) {
1623 gb->extra_oam[i] = GB_random();
1624 }
1625
1626 if (GB_is_cgb(gb)) {
1627 for (unsigned i = 0; i < 64; i++) {
1628 gb->background_palettes_data[i] = GB_random(); /* Doesn't really matter as the boot ROM overrides it anyway*/
1629 gb->object_palettes_data[i] = GB_random();
1630 }
1631 for (unsigned i = 0; i < 32; i++) {
1632 GB_palette_changed(gb, true, i * 2);
1633 GB_palette_changed(gb, false, i * 2);
1634 }
1635 }
1636
1637 if (!gb->cartridge_type->has_battery) {
1638 memset(gb->mbc_ram, 0xFF, gb->mbc_ram_size);
1639 }
1640 }
1641
1642 static void request_boot_rom(GB_gameboy_t *gb)
1643 {
1644 if (gb->boot_rom_load_callback) {
1645 GB_boot_rom_t type = 0;
1646 switch (gb->model) {
1647 case GB_MODEL_DMG_B:
1648 type = GB_BOOT_ROM_DMG;
1649 break;
1650 case GB_MODEL_MGB:
1651 type = GB_BOOT_ROM_MGB;
1652 break;
1653 case GB_MODEL_SGB_NTSC:
1654 case GB_MODEL_SGB_PAL:
1655 case GB_MODEL_SGB_NTSC_NO_SFC:
1656 case GB_MODEL_SGB_PAL_NO_SFC:
1657 type = GB_BOOT_ROM_SGB;
1658 break;
1659 case GB_MODEL_SGB2:
1660 case GB_MODEL_SGB2_NO_SFC:
1661 type = GB_BOOT_ROM_SGB2;
1662 break;
1663 case GB_MODEL_CGB_0:
1664 type = GB_BOOT_ROM_CGB_0;
1665 break;
1666 case GB_MODEL_CGB_A:
1667 case GB_MODEL_CGB_B:
1668 case GB_MODEL_CGB_C:
1669 case GB_MODEL_CGB_D:
1670 type = GB_BOOT_ROM_CGB;
1671 break;
1672 case GB_MODEL_CGB_E:
1673 type = GB_BOOT_ROM_CGB_E;
1674 break;
1675 case GB_MODEL_AGB_A:
1676 case GB_MODEL_GBP_A:
1677 type = GB_BOOT_ROM_AGB;
1678 break;
1679 }
1680 gb->boot_rom_load_callback(gb, type);
1681 }
1682 }
1683
1684 static void GB_reset_internal(GB_gameboy_t *gb, bool quick)
1685 {
1686 struct {
1687 uint8_t hram[sizeof(gb->hram)];
1688 uint8_t background_palettes_data[sizeof(gb->background_palettes_data)];
1689 uint8_t object_palettes_data[sizeof(gb->object_palettes_data)];
1690 uint8_t oam[sizeof(gb->oam)];
1691 uint8_t extra_oam[sizeof(gb->extra_oam)];
1692 uint8_t dma, obp0, obp1;
1693 } *preserved_state = NULL;
1694
1695 if (quick) {
1696 preserved_state = alloca(sizeof(*preserved_state));
1697 memcpy(preserved_state->hram, gb->hram, sizeof(gb->hram));
1698 memcpy(preserved_state->background_palettes_data, gb->background_palettes_data, sizeof(gb->background_palettes_data));
1699 memcpy(preserved_state->object_palettes_data, gb->object_palettes_data, sizeof(gb->object_palettes_data));
1700 memcpy(preserved_state->oam, gb->oam, sizeof(gb->oam));
1701 memcpy(preserved_state->extra_oam, gb->extra_oam, sizeof(gb->extra_oam));
1702 preserved_state->dma = gb->io_registers[GB_IO_DMA];
1703 preserved_state->obp0 = gb->io_registers[GB_IO_OBP0];
1704 preserved_state->obp1 = gb->io_registers[GB_IO_OBP1];
1705 }
1706
1707 uint32_t mbc_ram_size = gb->mbc_ram_size;
1708 GB_model_t model = gb->model;
1709 GB_update_clock_rate(gb);
1710 uint8_t rtc_section[GB_SECTION_SIZE(rtc)];
1711 memcpy(rtc_section, GB_GET_SECTION(gb, rtc), sizeof(rtc_section));
1712 memset(gb, 0, GB_SECTION_OFFSET(unsaved));
1713 memcpy(GB_GET_SECTION(gb, rtc), rtc_section, sizeof(rtc_section));
1714 gb->model = model;
1715 gb->version = STRUCT_VERSION;
1716
1717 GB_reset_mbc(gb);
1718
1719 gb->last_rtc_second = time(NULL);
1720 gb->cgb_ram_bank = 1;
1721 gb->io_registers[GB_IO_JOYP] = 0xCF;
1722 gb->mbc_ram_size = mbc_ram_size;
1723 if (GB_is_cgb(gb)) {
1724 gb->ram_size = 0x1000 * 8;
1725 gb->vram_size = 0x2000 * 2;
1726 memset(gb->vram, 0, gb->vram_size);
1727 gb->cgb_mode = true;
1728 gb->object_priority = GB_OBJECT_PRIORITY_INDEX;
1729 }
1730 else {
1731 gb->ram_size = 0x2000;
1732 gb->vram_size = 0x2000;
1733 memset(gb->vram, 0, gb->vram_size);
1734 gb->object_priority = GB_OBJECT_PRIORITY_X;
1735 GB_update_dmg_palette(gb);
1736 }
1737
1738 gb->serial_mask = 0x80;
1739 gb->io_registers[GB_IO_SC] = 0x7E;
1740 gb->accessed_oam_row = -1;
1741 gb->dma_current_dest = 0xA1;
1742
1743 if (GB_is_hle_sgb(gb)) {
1744 if (!gb->sgb) {
1745 gb->sgb = malloc(sizeof(*gb->sgb));
1746 }
1747 memset(gb->sgb, 0, sizeof(*gb->sgb));
1748 memset(gb->sgb_intro_jingle_phases, 0, sizeof(gb->sgb_intro_jingle_phases));
1749 gb->sgb_intro_sweep_phase = 0;
1750 gb->sgb_intro_sweep_previous_sample = 0;
1751 gb->sgb->intro_animation = -10;
1752
1753 gb->sgb->player_count = 1;
1754 GB_sgb_load_default_data(gb);
1755
1756 }
1757 else {
1758 if (gb->sgb) {
1759 free(gb->sgb);
1760 gb->sgb = NULL;
1761 }
1762 }
1763
1764 GB_set_internal_div_counter(gb, 8);
1765 /* TODO: AGS-101 is inverted in comparison to AGS-001 and AGB */
1766 gb->is_odd_frame = gb->model > GB_MODEL_CGB_E;
1767
1768 #ifndef GB_DISABLE_DEBUGGER
1769 if (gb->nontrivial_jump_state) {
1770 free(gb->nontrivial_jump_state);
1771 gb->nontrivial_jump_state = NULL;
1772 }
1773 #endif
1774
1775 if (!quick) {
1776 reset_ram(gb);
1777 /* These are not deterministic, but 00 (CGB) and FF (DMG) are the most common initial values by far.
1778 The retain their previous values on quick resets */
1779 gb->io_registers[GB_IO_DMA] = gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = GB_is_cgb(gb)? 0x00 : 0xFF;
1780 }
1781 else {
1782 memcpy(gb->hram, preserved_state->hram, sizeof(gb->hram));
1783 memcpy(gb->background_palettes_data, preserved_state->background_palettes_data, sizeof(gb->background_palettes_data));
1784 memcpy(gb->object_palettes_data, preserved_state->object_palettes_data, sizeof(gb->object_palettes_data));
1785 memcpy(gb->oam, preserved_state->oam, sizeof(gb->oam));
1786 memcpy(gb->extra_oam, preserved_state->extra_oam, sizeof(gb->extra_oam));
1787 gb->io_registers[GB_IO_DMA] = preserved_state->dma;
1788 gb->io_registers[GB_IO_OBP0] = preserved_state->obp0;
1789 gb->io_registers[GB_IO_OBP1] = preserved_state->obp1;
1790 }
1791 gb->apu.apu_cycles_in_2mhz = true;
1792
1793 gb->magic = GB_state_magic();
1794 request_boot_rom(gb);
1795 GB_rewind_push(gb);
1796 }
1797
1798 void GB_reset(GB_gameboy_t *gb)
1799 {
1800 GB_ASSERT_NOT_RUNNING(gb)
1801 GB_reset_internal(gb, false);
1802 }
1803
1804 void GB_quick_reset(GB_gameboy_t *gb)
1805 {
1806 GB_ASSERT_NOT_RUNNING(gb)
1807 GB_reset_internal(gb, true);
1808 }
1809
1810 void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model)
1811 {
1812 GB_ASSERT_NOT_RUNNING(gb)
1813
1814 #ifndef GB_DISABLE_CHEAT_SEARCH
1815 GB_cheat_search_reset(gb);
1816 #endif
1817
1818 gb->model = model;
1819 if (GB_is_cgb(gb)) {
1820 gb->ram = realloc(gb->ram, gb->ram_size = 0x1000 * 8);
1821 gb->vram = realloc(gb->vram, gb->vram_size = 0x2000 * 2);
1822 }
1823 else {
1824 gb->ram = realloc(gb->ram, gb->ram_size = 0x2000);
1825 gb->vram = realloc(gb->vram, gb->vram_size = 0x2000);
1826 }
1827 #ifndef GB_DISABLE_DEBUGGER
1828 if (gb->undo_state) {
1829 free(gb->undo_state);
1830 gb->undo_state = NULL;
1831 }
1832 #endif
1833 GB_rewind_reset(gb);
1834 GB_reset(gb);
1835 load_default_border(gb);
1836 }
1837
1838 void *GB_get_direct_access(GB_gameboy_t *gb, GB_direct_access_t access, size_t *size, uint16_t *bank)
1839 {
1840 /* Set size and bank to dummy pointers if not set */
1841 size_t dummy_size;
1842 uint16_t dummy_bank;
1843 if (!size) {
1844 size = &dummy_size;
1845 }
1846
1847 if (!bank) {
1848 bank = &dummy_bank;
1849 }
1850
1851
1852 switch (access) {
1853 case GB_DIRECT_ACCESS_ROM:
1854 *size = gb->rom_size;
1855 *bank = gb->mbc_rom_bank & (gb->rom_size / 0x4000 - 1);
1856 return gb->rom;
1857 case GB_DIRECT_ACCESS_ROM0:
1858 *size = gb->rom_size;
1859 *bank = gb->mbc_rom0_bank & (gb->rom_size / 0x4000 - 1);
1860 return gb->rom;
1861 case GB_DIRECT_ACCESS_RAM:
1862 *size = gb->ram_size;
1863 *bank = gb->cgb_ram_bank;
1864 return gb->ram;
1865 case GB_DIRECT_ACCESS_CART_RAM:
1866 *size = gb->mbc_ram_size;
1867 *bank = gb->mbc_ram_bank & (gb->mbc_ram_size / 0x2000 - 1);
1868 return gb->mbc_ram;
1869 case GB_DIRECT_ACCESS_VRAM:
1870 *size = gb->vram_size;
1871 *bank = gb->cgb_vram_bank;
1872 return gb->vram;
1873 case GB_DIRECT_ACCESS_HRAM:
1874 *size = sizeof(gb->hram);
1875 *bank = 0;
1876 return &gb->hram;
1877 case GB_DIRECT_ACCESS_IO:
1878 *size = sizeof(gb->io_registers);
1879 *bank = 0;
1880 return &gb->io_registers;
1881 case GB_DIRECT_ACCESS_BOOTROM:
1882 *size = GB_is_cgb(gb)? sizeof(gb->boot_rom) : 0x100;
1883 *bank = 0;
1884 return &gb->boot_rom;
1885 case GB_DIRECT_ACCESS_OAM:
1886 *size = sizeof(gb->oam);
1887 *bank = 0;
1888 return &gb->oam;
1889 case GB_DIRECT_ACCESS_BGP:
1890 *size = sizeof(gb->background_palettes_data);
1891 *bank = 0;
1892 return &gb->background_palettes_data;
1893 case GB_DIRECT_ACCESS_OBP:
1894 *size = sizeof(gb->object_palettes_data);
1895 *bank = 0;
1896 return &gb->object_palettes_data;
1897 case GB_DIRECT_ACCESS_IE:
1898 *size = sizeof(gb->interrupt_enable);
1899 *bank = 0;
1900 return &gb->interrupt_enable;
1901 default:
1902 *size = 0;
1903 *bank = 0;
1904 return NULL;
1905 }
1906 }
1907
1908 GB_registers_t *GB_get_registers(GB_gameboy_t *gb)
1909 {
1910 return (GB_registers_t *)&gb->registers;
1911 }
1912
1913 void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier)
1914 {
1915 if (multiplier != gb->clock_multiplier) {
1916 gb->clock_multiplier = multiplier;
1917 GB_update_clock_rate(gb);
1918 }
1919 }
1920
1921 uint32_t GB_get_clock_rate(GB_gameboy_t *gb)
1922 {
1923 return gb->clock_rate;
1924 }
1925
1926 uint32_t GB_get_unmultiplied_clock_rate(GB_gameboy_t *gb)
1927 {
1928 return gb->unmultiplied_clock_rate;
1929 }
1930
1931 void GB_update_clock_rate(GB_gameboy_t *gb)
1932 {
1933 if (gb->model & GB_MODEL_PAL_BIT) {
1934 gb->unmultiplied_clock_rate = SGB_PAL_FREQUENCY;
1935 }
1936 else if ((gb->model & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB) {
1937 gb->unmultiplied_clock_rate = SGB_NTSC_FREQUENCY;
1938 }
1939 else {
1940 gb->unmultiplied_clock_rate = CPU_FREQUENCY;
1941 }
1942
1943 gb->clock_rate = gb->unmultiplied_clock_rate * gb->clock_multiplier;
1944 GB_set_sample_rate(gb, gb->apu_output.sample_rate);
1945 }
1946
1947 void GB_set_border_mode(GB_gameboy_t *gb, GB_border_mode_t border_mode)
1948 {
1949 if (gb->border_mode > GB_BORDER_ALWAYS) return;
1950 gb->border_mode = border_mode;
1951 }
1952
1953 void GB_set_joyp_write_callback(GB_gameboy_t *gb, GB_joyp_write_callback_t callback)
1954 {
1955 if (!callback) {
1956 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1957 }
1958 gb->joyp_write_callback = callback;
1959 }
1960
1961 void GB_set_icd_pixel_callback(GB_gameboy_t *gb, GB_icd_pixel_callback_t callback)
1962 {
1963 if (!callback) {
1964 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1965 }
1966 gb->icd_pixel_callback = callback;
1967 }
1968
1969 void GB_set_icd_hreset_callback(GB_gameboy_t *gb, GB_icd_hreset_callback_t callback)
1970 {
1971 if (!callback) {
1972 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1973 }
1974 gb->icd_hreset_callback = callback;
1975 }
1976
1977
1978 void GB_set_icd_vreset_callback(GB_gameboy_t *gb, GB_icd_vreset_callback_t callback)
1979 {
1980 if (!callback) {
1981 GB_ASSERT_NOT_RUNNING_OTHER_THREAD(gb)
1982 }
1983 gb->icd_vreset_callback = callback;
1984 }
1985
1986 void GB_set_boot_rom_load_callback(GB_gameboy_t *gb, GB_boot_rom_load_callback_t callback)
1987 {
1988 gb->boot_rom_load_callback = callback;
1989 request_boot_rom(gb);
1990 }
1991
1992 unsigned GB_time_to_alarm(GB_gameboy_t *gb)
1993 {
1994 if (gb->cartridge_type->mbc_type != GB_HUC3) return 0;
1995 if (!gb->huc3.alarm_enabled) return 0;
1996 if (!(gb->huc3.alarm_days & 0x2000)) return 0;
1997 unsigned current_time = (gb->huc3.days & 0x1FFF) * 24 * 60 * 60 + gb->huc3.minutes * 60 + (time(NULL) % 60);
1998 unsigned alarm_time = (gb->huc3.alarm_days & 0x1FFF) * 24 * 60 * 60 + gb->huc3.alarm_minutes * 60;
1999 if (current_time > alarm_time) return 0;
2000 return alarm_time - current_time;
2001 }
2002
2003 bool GB_rom_supports_alarms(GB_gameboy_t *gb)
2004 {
2005 return gb->cartridge_type->mbc_type == GB_HUC3;
2006 }
2007
2008 bool GB_has_accelerometer(GB_gameboy_t *gb)
2009 {
2010 return gb->cartridge_type->mbc_type == GB_MBC7;
2011 }
2012
2013 void GB_set_accelerometer_values(GB_gameboy_t *gb, double x, double y)
2014 {
2015 gb->accelerometer_x = x;
2016 gb->accelerometer_y = y;
2017 }
2018
2019 void GB_set_open_bus_decay_time(GB_gameboy_t *gb, uint32_t decay)
2020 {
2021 gb->data_bus_decay = decay;
2022 }
2023
2024 void GB_get_rom_title(GB_gameboy_t *gb, char *title)
2025 {
2026 memset(title, 0, 17);
2027 if (gb->rom_size >= 0x4000) {
2028 for (unsigned i = 0; i < 0x10; i++) {
2029 if (gb->rom[0x134 + i] < 0x20 || gb->rom[0x134 + i] >= 0x80) break;
2030 title[i] = gb->rom[0x134 + i];
2031 }
2032 }
2033 }
2034
2035 bool GB_get_battery_dirty(GB_gameboy_t *gb)
2036 {
2037 if (GB_save_battery_size(gb) == 0) return false;
2038 return gb->battery_dirty;
2039 }
2040
2041 void GB_clear_battery_dirty(GB_gameboy_t *gb)
2042 {
2043 gb->battery_dirty = false;
2044 }
2045
2046 uint32_t GB_get_rom_crc32(GB_gameboy_t *gb)
2047 {
2048 static const uint32_t table[] = {
2049 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
2050 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
2051 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
2052 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
2053 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
2054 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
2055 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
2056 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
2057 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
2058 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
2059 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
2060 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
2061 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
2062 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
2063 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
2064 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
2065 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
2066 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
2067 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
2068 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
2069 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
2070 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
2071 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
2072 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
2073 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
2074 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
2075 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
2076 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
2077 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
2078 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
2079 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
2080 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
2081 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
2082 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
2083 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
2084 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
2085 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
2086 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
2087 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
2088 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
2089 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
2090 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
2091 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
2092 };
2093
2094 const uint8_t *byte = gb->rom;
2095 uint32_t size = gb->rom_size;
2096 uint32_t ret = 0xFFFFFFFF;
2097 while (size--) {
2098 ret = table[(ret ^ *byte++) & 0xFF] ^ (ret >> 8);
2099 }
2100 return ~ret;
2101 }
2102
2103
2104 #ifdef GB_CONTEXT_SAFETY
2105 void *GB_get_thread_id(void)
2106 {
2107 // POSIX requires errno to be thread local, making errno's address unique per thread
2108 return &errno;
2109 }
2110
2111 void GB_set_running_thread(GB_gameboy_t *gb)
2112 {
2113 GB_ASSERT_NOT_RUNNING(gb)
2114 gb->running_thread_id = GB_get_thread_id();
2115 }
2116
2117 void GB_clear_running_thread(GB_gameboy_t *gb)
2118 {
2119 assert(gb->running_thread_id == GB_get_thread_id());
2120 gb->running_thread_id = NULL;
2121 }
2122 #endif
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.