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 #ifdef GB_DISABLE_REWIND
17 #define GB_rewind_free(...)
18 #define GB_rewind_push(...)
19 #endif
20 
21 
GB_attributed_logv(GB_gameboy_t * gb,GB_log_attributes attributes,const char * fmt,va_list args)22 void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, va_list args)
23 {
24     char *string = NULL;
25     vasprintf(&string, fmt, args);
26     if (string) {
27         if (gb->log_callback) {
28             gb->log_callback(gb, string, attributes);
29         }
30         else {
31             /* Todo: Add ANSI escape sequences for attributed text */
32             printf("%s", string);
33         }
34     }
35     free(string);
36 }
37 
GB_attributed_log(GB_gameboy_t * gb,GB_log_attributes attributes,const char * fmt,...)38 void GB_attributed_log(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, ...)
39 {
40     va_list args;
41     va_start(args, fmt);
42     GB_attributed_logv(gb, attributes, fmt, args);
43     va_end(args);
44 }
45 
GB_log(GB_gameboy_t * gb,const char * fmt,...)46 void GB_log(GB_gameboy_t *gb, const char *fmt, ...)
47 {
48     va_list args;
49     va_start(args, fmt);
50     GB_attributed_logv(gb, 0, fmt, args);
51     va_end(args);
52 }
53 
54 #ifndef GB_DISABLE_DEBUGGER
default_input_callback(GB_gameboy_t * gb)55 static char *default_input_callback(GB_gameboy_t *gb)
56 {
57     char *expression = NULL;
58     size_t size = 0;
59     if (gb->debug_stopped) {
60         printf(">");
61     }
62 
63     if (getline(&expression, &size, stdin) == -1) {
64         /* The user doesn't have STDIN or used ^D. We make sure the program keeps running. */
65         GB_set_async_input_callback(gb, NULL); /* Disable async input */
66         return strdup("c");
67     }
68 
69     if (!expression) {
70         return strdup("");
71     }
72 
73     size_t length = strlen(expression);
74     if (expression[length - 1] == '\n') {
75         expression[length - 1] = 0;
76     }
77 
78     if (expression[0] == '\x03') {
79         gb->debug_stopped = true;
80         free(expression);
81         return strdup("");
82     }
83     return expression;
84 }
85 
default_async_input_callback(GB_gameboy_t * gb)86 static char *default_async_input_callback(GB_gameboy_t *gb)
87 {
88 #ifndef _WIN32
89     fd_set set;
90     FD_ZERO(&set);
91     FD_SET(STDIN_FILENO, &set);
92     struct timeval time = {0,};
93     if (select(1, &set, NULL, NULL, &time) == 1) {
94         if (feof(stdin)) {
95             GB_set_async_input_callback(gb, NULL); /* Disable async input */
96             return NULL;
97         }
98         return default_input_callback(gb);
99     }
100 #endif
101     return NULL;
102 }
103 #endif
104 
load_default_border(GB_gameboy_t * gb)105 static void load_default_border(GB_gameboy_t *gb)
106 {
107     if (gb->has_sgb_border) return;
108 
109     #define LOAD_BORDER() do { \
110         memcpy(gb->borrowed_border.map, tilemap, sizeof(tilemap));\
111         memcpy(gb->borrowed_border.palette, palette, sizeof(palette));\
112         memcpy(gb->borrowed_border.tiles, tiles, sizeof(tiles));\
113     } while (false);
114 
115 #ifdef GB_BIG_ENDIAN
116     for (unsigned i = 0; i < sizeof(gb->borrowed_border.map) / 2; i++) {
117         gb->borrowed_border.map[i] = LE16(gb->borrowed_border.map[i]);
118     }
119     for (unsigned i = 0; i < sizeof(gb->borrowed_border.palette) / 2; i++) {
120         gb->borrowed_border.palette[i] = LE16(gb->borrowed_border.palette[i]);
121     }
122 #endif
123 
124     if (gb->model == GB_MODEL_AGB) {
125         #include "graphics/agb_border.inc"
126         LOAD_BORDER();
127     }
128     else if (GB_is_cgb(gb)) {
129         #include "graphics/cgb_border.inc"
130         LOAD_BORDER();
131     }
132     else {
133         #include "graphics/dmg_border.inc"
134         LOAD_BORDER();
135     }
136 }
137 
GB_init(GB_gameboy_t * gb,GB_model_t model)138 void GB_init(GB_gameboy_t *gb, GB_model_t model)
139 {
140     memset(gb, 0, sizeof(*gb));
141     gb->model = model;
142     if (GB_is_cgb(gb)) {
143         gb->ram = malloc(gb->ram_size = 0x1000 * 8);
144         gb->vram = malloc(gb->vram_size = 0x2000 * 2);
145     }
146     else {
147         gb->ram = malloc(gb->ram_size = 0x2000);
148         gb->vram = malloc(gb->vram_size = 0x2000);
149     }
150 
151 #ifndef GB_DISABLE_DEBUGGER
152     gb->input_callback = default_input_callback;
153     gb->async_input_callback = default_async_input_callback;
154 #endif
155     gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
156     gb->clock_multiplier = 1.0;
157 
158     if (model & GB_MODEL_NO_SFC_BIT) {
159         /* Disable time syncing. Timing should be done by the SFC emulator. */
160         gb->turbo = true;
161     }
162 
163     GB_reset(gb);
164     load_default_border(gb);
165 }
166 
GB_get_model(GB_gameboy_t * gb)167 GB_model_t GB_get_model(GB_gameboy_t *gb)
168 {
169     return gb->model;
170 }
171 
GB_free(GB_gameboy_t * gb)172 void GB_free(GB_gameboy_t *gb)
173 {
174     gb->magic = 0;
175     if (gb->ram) {
176         free(gb->ram);
177     }
178     if (gb->vram) {
179         free(gb->vram);
180     }
181     if (gb->mbc_ram) {
182         free(gb->mbc_ram);
183     }
184     if (gb->rom) {
185         free(gb->rom);
186     }
187     if (gb->breakpoints) {
188         free(gb->breakpoints);
189     }
190     if (gb->sgb) {
191         free(gb->sgb);
192     }
193     if (gb->nontrivial_jump_state) {
194         free(gb->nontrivial_jump_state);
195     }
196     if (gb->undo_state) {
197         free(gb->undo_state);
198     }
199 #ifndef GB_DISABLE_DEBUGGER
200     GB_debugger_clear_symbols(gb);
201 #endif
202     GB_rewind_free(gb);
203 #ifndef GB_DISABLE_CHEATS
204     while (gb->cheats) {
205         GB_remove_cheat(gb, gb->cheats[0]);
206     }
207 #endif
208     memset(gb, 0, sizeof(*gb));
209 }
210 
GB_load_boot_rom(GB_gameboy_t * gb,const char * path)211 int GB_load_boot_rom(GB_gameboy_t *gb, const char *path)
212 {
213     FILE *f = fopen(path, "rb");
214     if (!f) {
215         GB_log(gb, "Could not open boot ROM: %s.\n", strerror(errno));
216         return errno;
217     }
218     fread(gb->boot_rom, sizeof(gb->boot_rom), 1, f);
219     fclose(f);
220     return 0;
221 }
222 
GB_load_boot_rom_from_buffer(GB_gameboy_t * gb,const unsigned char * buffer,size_t size)223 void GB_load_boot_rom_from_buffer(GB_gameboy_t *gb, const unsigned char *buffer, size_t size)
224 {
225     if (size > sizeof(gb->boot_rom)) {
226         size = sizeof(gb->boot_rom);
227     }
228     memset(gb->boot_rom, 0xFF, sizeof(gb->boot_rom));
229     memcpy(gb->boot_rom, buffer, size);
230 }
231 
GB_borrow_sgb_border(GB_gameboy_t * gb)232 void GB_borrow_sgb_border(GB_gameboy_t *gb)
233 {
234     if (GB_is_sgb(gb)) return;
235     if (gb->border_mode != GB_BORDER_ALWAYS) return;
236     if (gb->tried_loading_sgb_border) return;
237     gb->tried_loading_sgb_border = true;
238     if (gb->rom && gb->rom[0x146] != 3) return; // Not an SGB game, nothing to borrow
239     if (!gb->boot_rom_load_callback) return; // Can't borrow a border without this callback
240     GB_gameboy_t sgb;
241     GB_init(&sgb, GB_MODEL_SGB);
242     sgb.cartridge_type = gb->cartridge_type;
243     sgb.rom = gb->rom;
244     sgb.rom_size = gb->rom_size;
245     sgb.turbo = true;
246     sgb.turbo_dont_skip = true;
247     // sgb.disable_rendering = true;
248 
249     /* Load the boot ROM using the existing gb object */
250     typeof(gb->boot_rom) boot_rom_backup;
251     memcpy(boot_rom_backup, gb->boot_rom, sizeof(gb->boot_rom));
252     gb->boot_rom_load_callback(gb, GB_BOOT_ROM_SGB);
253     memcpy(sgb.boot_rom, gb->boot_rom, sizeof(gb->boot_rom));
254     memcpy(gb->boot_rom, boot_rom_backup, sizeof(gb->boot_rom));
255     sgb.sgb->intro_animation = -1;
256 
257     for (unsigned i = 600; i--;) {
258         GB_run_frame(&sgb);
259         if (sgb.sgb->border_animation) {
260             gb->has_sgb_border = true;
261             memcpy(&gb->borrowed_border, &sgb.sgb->pending_border, sizeof(gb->borrowed_border));
262             gb->borrowed_border.palette[0] = sgb.sgb->effective_palettes[0];
263             break;
264         }
265     }
266 
267     sgb.rom = NULL;
268     sgb.rom_size = 0;
269     GB_free(&sgb);
270 }
271 
GB_load_rom(GB_gameboy_t * gb,const char * path)272 int GB_load_rom(GB_gameboy_t *gb, const char *path)
273 {
274     FILE *f = fopen(path, "rb");
275     if (!f) {
276         GB_log(gb, "Could not open ROM: %s.\n", strerror(errno));
277         return errno;
278     }
279     fseek(f, 0, SEEK_END);
280     gb->rom_size = (ftell(f) + 0x3FFF) & ~0x3FFF; /* Round to bank */
281     /* And then round to a power of two */
282     while (gb->rom_size & (gb->rom_size - 1)) {
283         /* I promise this works. */
284         gb->rom_size |= gb->rom_size >> 1;
285         gb->rom_size++;
286     }
287     if (gb->rom_size < 0x8000) {
288         gb->rom_size = 0x8000;
289     }
290     fseek(f, 0, SEEK_SET);
291     if (gb->rom) {
292         free(gb->rom);
293     }
294     gb->rom = malloc(gb->rom_size);
295     memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
296     fread(gb->rom, 1, gb->rom_size, f);
297     fclose(f);
298     GB_configure_cart(gb);
299     gb->tried_loading_sgb_border = false;
300     gb->has_sgb_border = false;
301     load_default_border(gb);
302     return 0;
303 }
304 
305 #define GBS_ENTRY 0x61
306 #define GBS_ENTRY_SIZE 13
307 
generate_gbs_entry(GB_gameboy_t * gb,uint8_t * data)308 static void generate_gbs_entry(GB_gameboy_t *gb, uint8_t *data)
309 {
310     memcpy(data, (uint8_t[]) {
311         0xCD, // Call $XXXX
312         LE16(gb->gbs_header.init_address),
313         LE16(gb->gbs_header.init_address) >> 8,
314         0x76, // HALT
315         0x00, // NOP
316         0xAF, // XOR a
317         0xE0, // LDH [$FFXX], a
318         GB_IO_IF,
319         0xCD, // Call $XXXX
320         LE16(gb->gbs_header.play_address),
321         LE16(gb->gbs_header.play_address) >> 8,
322         0x18, // JR pc ± $XX
323         -10   // To HALT
324     }, GBS_ENTRY_SIZE);
325 }
326 
GB_gbs_switch_track(GB_gameboy_t * gb,uint8_t track)327 void GB_gbs_switch_track(GB_gameboy_t *gb, uint8_t track)
328 {
329     GB_reset(gb);
330     GB_write_memory(gb, 0xFF00 + GB_IO_LCDC, 0x80);
331     GB_write_memory(gb, 0xFF00 + GB_IO_TAC, gb->gbs_header.TAC);
332     GB_write_memory(gb, 0xFF00 + GB_IO_TMA, gb->gbs_header.TMA);
333     GB_write_memory(gb, 0xFF00 + GB_IO_NR52, 0x80);
334     GB_write_memory(gb, 0xFF00 + GB_IO_NR51, 0xFF);
335     GB_write_memory(gb, 0xFF00 + GB_IO_NR50, 0x77);
336     memset(gb->ram, 0, gb->ram_size);
337     memset(gb->hram, 0, sizeof(gb->hram));
338     memset(gb->oam, 0, sizeof(gb->oam));
339     if (gb->gbs_header.TAC || gb->gbs_header.TMA) {
340         GB_write_memory(gb, 0xFFFF, 0x04);
341     }
342     else {
343         GB_write_memory(gb, 0xFFFF, 0x01);
344     }
345     if (gb->gbs_header.TAC & 0x80) {
346         gb->cgb_double_speed = true; // Might mean double speed mode on a DMG
347     }
348     if (gb->gbs_header.load_address) {
349         gb->sp = LE16(gb->gbs_header.sp);
350         gb->pc = GBS_ENTRY;
351     }
352     else {
353         gb->pc = gb->sp = LE16(gb->gbs_header.sp - GBS_ENTRY_SIZE);
354         uint8_t entry[GBS_ENTRY_SIZE];
355         generate_gbs_entry(gb, entry);
356         for (unsigned i = 0; i < sizeof(entry); i++) {
357             GB_write_memory(gb, gb->pc + i, entry[i]);
358         }
359     }
360 
361     gb->boot_rom_finished = true;
362     gb->a = track;
363     if (gb->sgb) {
364         gb->sgb->intro_animation = GB_SGB_INTRO_ANIMATION_LENGTH;
365         gb->sgb->disable_commands = true;
366     }
367     if (gb->gbs_header.TAC & 0x40) {
368         gb->interrupt_enable = true;
369     }
370 }
371 
GB_load_gbs_from_buffer(GB_gameboy_t * gb,const uint8_t * buffer,size_t size,GB_gbs_info_t * info)372 int GB_load_gbs_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size, GB_gbs_info_t *info)
373 {
374     if (size < sizeof(gb->gbs_header)) {
375         GB_log(gb, "Not a valid GBS file.\n");
376         return -1;
377     }
378 
379     memcpy(&gb->gbs_header, buffer, sizeof(gb->gbs_header));
380 
381     if (gb->gbs_header.magic != BE32('GBS\x01') ||
382         ((LE16(gb->gbs_header.load_address) < GBS_ENTRY + GBS_ENTRY_SIZE ||
383         LE16(gb->gbs_header.load_address) >= 0x8000) &&
384         LE16(gb->gbs_header.load_address) != 0)) {
385         GB_log(gb, "Not a valid GBS file.\n");
386         return -1;
387     }
388 
389     size_t data_size = size - sizeof(gb->gbs_header);
390 
391     gb->rom_size = (data_size + LE16(gb->gbs_header.load_address) + 0x3FFF) & ~0x3FFF; /* Round to bank */
392     /* And then round to a power of two */
393     while (gb->rom_size & (gb->rom_size - 1)) {
394         /* I promise this works. */
395         gb->rom_size |= gb->rom_size >> 1;
396         gb->rom_size++;
397     }
398 
399     if (gb->rom_size < 0x8000) {
400         gb->rom_size = 0x8000;
401     }
402 
403     if (gb->rom) {
404         free(gb->rom);
405     }
406 
407     gb->rom = malloc(gb->rom_size);
408     memset(gb->rom, 0xFF, gb->rom_size); /* Pad with 0xFFs */
409     memcpy(gb->rom + LE16(gb->gbs_header.load_address), buffer + sizeof(gb->gbs_header), data_size);
410 
411     gb->cartridge_type = &GB_cart_defs[0x11];
412     if (gb->mbc_ram) {
413         free(gb->mbc_ram);
414         gb->mbc_ram = NULL;
415         gb->mbc_ram_size = 0;
416     }
417 
418     if (gb->cartridge_type->has_ram) {
419         gb->mbc_ram_size = 0x2000;
420         gb->mbc_ram = malloc(gb->mbc_ram_size);
421         memset(gb->mbc_ram, 0xFF, gb->mbc_ram_size);
422     }
423 
424     bool has_interrupts = gb->gbs_header.TAC & 0x40;
425 
426     if (gb->gbs_header.load_address) {
427         // Generate interrupt handlers
428         for (unsigned i = 0; i <= (has_interrupts? 0x50 : 0x38); i += 8) {
429             gb->rom[i] = 0xc3; // jp $XXXX
430             gb->rom[i + 1] = (LE16(gb->gbs_header.load_address) + i);
431             gb->rom[i + 2] = (LE16(gb->gbs_header.load_address) + i) >> 8;
432         }
433         for (unsigned i = has_interrupts? 0x58 : 0x40; i <= 0x60; i += 8) {
434             gb->rom[i] = 0xc9; // ret
435         }
436 
437         // Generate entry
438         generate_gbs_entry(gb, gb->rom + GBS_ENTRY);
439     }
440 
441 
442     GB_gbs_switch_track(gb, gb->gbs_header.first_track - 1);
443     if (info) {
444         memset(info, 0, sizeof(*info));
445         info->first_track = gb->gbs_header.first_track - 1;
446         info->track_count = gb->gbs_header.track_count;
447         memcpy(info->title, gb->gbs_header.title, sizeof(gb->gbs_header.title));
448         memcpy(info->author, gb->gbs_header.author, sizeof(gb->gbs_header.author));
449         memcpy(info->copyright, gb->gbs_header.copyright, sizeof(gb->gbs_header.copyright));
450     }
451 
452     gb->tried_loading_sgb_border = true; // Don't even attempt on GBS files
453     gb->has_sgb_border = false;
454     load_default_border(gb);
455     return 0;
456 }
457 
GB_load_gbs(GB_gameboy_t * gb,const char * path,GB_gbs_info_t * info)458 int GB_load_gbs(GB_gameboy_t *gb, const char *path, GB_gbs_info_t *info)
459 {
460     FILE *f = fopen(path, "rb");
461     if (!f) {
462         GB_log(gb, "Could not open GBS: %s.\n", strerror(errno));
463         return errno;
464     }
465     fseek(f, 0, SEEK_END);
466     size_t file_size = MIN(ftell(f), sizeof(GB_gbs_header_t) + 0x4000 * 0x100); // Cap with the maximum MBC3 ROM size + GBS header
467     fseek(f, 0, SEEK_SET);
468     uint8_t *file_data = malloc(file_size);
469     fread(file_data, 1, file_size, f);
470     fclose(f);
471 
472     int r = GB_load_gbs_from_buffer(gb, file_data, file_size, info);
473     free(file_data);
474     return r;
475 }
476 
GB_load_isx(GB_gameboy_t * gb,const char * path)477 int GB_load_isx(GB_gameboy_t *gb, const char *path)
478 {
479     FILE *f = fopen(path, "rb");
480     if (!f) {
481         GB_log(gb, "Could not open ISX file: %s.\n", strerror(errno));
482         return errno;
483     }
484     char magic[4];
485 #define READ(x) if (fread(&x, sizeof(x), 1, f) != 1) goto error
486     fread(magic, 1, sizeof(magic), f);
487 
488 #ifdef GB_BIG_ENDIAN
489     bool extended = *(uint32_t *)&magic == 'ISX ';
490 #else
491     bool extended = *(uint32_t *)&magic == __builtin_bswap32('ISX ');
492 #endif
493 
494     fseek(f, extended? 0x20 : 0, SEEK_SET);
495 
496 
497     uint8_t *old_rom = gb->rom;
498     uint32_t old_size = gb->rom_size;
499     gb->rom = NULL;
500     gb->rom_size = 0;
501 
502     while (true) {
503         uint8_t record_type = 0;
504         if (fread(&record_type, sizeof(record_type), 1, f) != 1) break;
505         switch (record_type) {
506             case 0x01: { // Binary
507                 uint16_t bank;
508                 uint16_t address;
509                 uint16_t length;
510                 uint8_t byte;
511                 READ(byte);
512                 bank = byte;
513                 if (byte >= 0x80) {
514                     READ(byte);
515                     bank |= byte << 8;
516                 }
517 
518                 READ(address);
519 #ifdef GB_BIG_ENDIAN
520                 address = __builtin_bswap16(address);
521 #endif
522                 address &= 0x3FFF;
523 
524                 READ(length);
525 #ifdef GB_BIG_ENDIAN
526                 length = __builtin_bswap16(length);
527 #endif
528 
529                 size_t needed_size = bank * 0x4000 + address + length;
530                 if (needed_size > 1024 * 1024 * 32) goto error;
531 
532                 if (gb->rom_size < needed_size) {
533                     gb->rom = realloc(gb->rom, needed_size);
534                     memset(gb->rom + gb->rom_size, 0, needed_size - gb->rom_size);
535                     gb->rom_size = needed_size;
536                 }
537 
538                 if (fread(gb->rom + (bank * 0x4000 + address), length, 1, f) != 1) goto error;
539 
540                 break;
541             }
542 
543             case 0x11: { // Extended Binary
544                 uint32_t address;
545                 uint32_t length;
546 
547                 READ(address);
548 #ifdef GB_BIG_ENDIAN
549                 address = __builtin_bswap32(address);
550 #endif
551 
552                 READ(length);
553 #ifdef GB_BIG_ENDIAN
554                 length = __builtin_bswap32(length);
555 #endif
556                 size_t needed_size = address + length;
557                 if (needed_size > 1024 * 1024 * 32) goto error;
558 
559                 if (gb->rom_size < needed_size) {
560                     gb->rom = realloc(gb->rom, needed_size);
561                     memset(gb->rom + gb->rom_size, 0, needed_size - gb->rom_size);
562                     gb->rom_size = needed_size;
563                 }
564 
565                 if (fread(gb->rom + address, length, 1, f) != 1) goto error;
566 
567                 break;
568             }
569 
570             case 0x04: { // Symbol
571                 uint16_t count;
572                 uint8_t length;
573                 char name[257];
574                 uint8_t flag;
575                 uint16_t bank;
576                 uint16_t address;
577                 uint8_t byte;
578                 READ(count);
579 #ifdef GB_BIG_ENDIAN
580                 count = __builtin_bswap16(count);
581 #endif
582                 while (count--) {
583                     READ(length);
584                     if (fread(name, length, 1, f) != 1) goto error;
585                     name[length] = 0;
586                     READ(flag); // unused
587 
588                     READ(byte);
589                     bank = byte;
590                     if (byte >= 0x80) {
591                         READ(byte);
592                         bank |= byte << 8;
593                     }
594 
595                     READ(address);
596 #ifdef GB_BIG_ENDIAN
597                     address = __builtin_bswap16(address);
598 #endif
599                     GB_debugger_add_symbol(gb, bank, address, name);
600                 }
601                 break;
602             }
603 
604             case 0x14: { // Extended Binary
605                 uint16_t count;
606                 uint8_t length;
607                 char name[257];
608                 uint8_t flag;
609                 uint32_t address;
610                 READ(count);
611 #ifdef GB_BIG_ENDIAN
612                 count = __builtin_bswap16(count);
613 #endif
614                 while (count--) {
615                     READ(length);
616                     if (fread(name, length + 1, 1, f) != 1) goto error;
617                     name[length] = 0;
618                     READ(flag); // unused
619 
620                     READ(address);
621 #ifdef GB_BIG_ENDIAN
622                     address = __builtin_bswap32(address);
623 #endif
624                     // TODO: How to convert 32-bit addresses to Bank:Address? Needs to tell RAM and ROM apart
625                 }
626                 break;
627             }
628 
629             default:
630                 goto done;
631         }
632     }
633 done:;
634 #undef READ
635     if (gb->rom_size == 0) goto error;
636 
637     size_t needed_size = (gb->rom_size + 0x3FFF) & ~0x3FFF; /* Round to bank */
638 
639     /* And then round to a power of two */
640     while (needed_size & (needed_size - 1)) {
641         /* I promise this works. */
642         needed_size |= needed_size >> 1;
643         needed_size++;
644     }
645 
646     if (needed_size < 0x8000) {
647         needed_size = 0x8000;
648     }
649 
650     if (gb->rom_size < needed_size) {
651         gb->rom = realloc(gb->rom, needed_size);
652         memset(gb->rom + gb->rom_size, 0, needed_size - gb->rom_size);
653         gb->rom_size = needed_size;
654     }
655 
656     GB_configure_cart(gb);
657 
658     // Fix a common wrong MBC error
659     if (gb->rom[0x147] == 3) { // MBC1 + RAM + Battery
660         bool needs_fix = false;
661         if (gb->rom_size >= 0x21 * 0x4000) {
662             for (unsigned i = 0x20 * 0x4000; i < 0x21 * 0x4000; i++) {
663                 if (gb->rom[i]) {
664                     needs_fix = true;
665                     break;
666                 }
667             }
668         }
669         if (!needs_fix && gb->rom_size >= 0x41 * 0x4000) {
670             for (unsigned i = 0x40 * 0x4000; i < 0x41 * 0x4000; i++) {
671                 if (gb->rom[i]) {
672                     needs_fix = true;
673                     break;
674                 }
675             }
676         }
677         if (!needs_fix && gb->rom_size >= 0x61 * 0x4000) {
678             for (unsigned i = 0x60 * 0x4000; i < 0x61 * 0x4000; i++) {
679                 if (gb->rom[i]) {
680                     needs_fix = true;
681                     break;
682                 }
683             }
684         }
685         if (needs_fix) {
686             gb->rom[0x147] = 0x10; // MBC3 + RTC + RAM + Battery
687             GB_configure_cart(gb);
688             gb->rom[0x147] = 0x3;
689             GB_log(gb, "ROM claims to use MBC1 but appears to require MBC3 or 5, assuming MBC3.\n");
690         }
691     }
692 
693     if (old_rom) {
694         free(old_rom);
695     }
696 
697     return 0;
698 error:
699     GB_log(gb, "Invalid or unsupported ISX file.\n");
700     if (gb->rom) {
701         free(gb->rom);
702         gb->rom = old_rom;
703         gb->rom_size = old_size;
704     }
705     fclose(f);
706     gb->tried_loading_sgb_border = false;
707     gb->has_sgb_border = false;
708     load_default_border(gb);
709     return -1;
710 }
711 
GB_load_rom_from_buffer(GB_gameboy_t * gb,const uint8_t * buffer,size_t size)712 void GB_load_rom_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size)
713 {
714     gb->rom_size = (size + 0x3fff) & ~0x3fff;
715     while (gb->rom_size & (gb->rom_size - 1)) {
716         gb->rom_size |= gb->rom_size >> 1;
717         gb->rom_size++;
718     }
719     if (gb->rom_size == 0) {
720         gb->rom_size = 0x8000;
721     }
722     if (gb->rom) {
723         free(gb->rom);
724     }
725     gb->rom = malloc(gb->rom_size);
726     memset(gb->rom, 0xff, gb->rom_size);
727     memcpy(gb->rom, buffer, size);
728     GB_configure_cart(gb);
729     gb->tried_loading_sgb_border = false;
730     gb->has_sgb_border = false;
731     load_default_border(gb);
732 }
733 
734 typedef struct {
735     uint8_t seconds;
736     uint8_t padding1[3];
737     uint8_t minutes;
738     uint8_t padding2[3];
739     uint8_t hours;
740     uint8_t padding3[3];
741     uint8_t days;
742     uint8_t padding4[3];
743     uint8_t high;
744     uint8_t padding5[3];
745 } GB_vba_rtc_time_t;
746 
747 typedef struct __attribute__((packed)) {
748     uint32_t magic;
749     uint16_t version;
750     uint8_t mr4;
751     uint8_t reserved;
752     uint64_t last_rtc_second;
753     uint8_t rtc_data[4];
754 } GB_tpp1_rtc_save_t;
755 
756 typedef union {
757     struct __attribute__((packed)) {
758         GB_rtc_time_t rtc_real;
759         time_t last_rtc_second; /* Platform specific endianess and size */
760     } sameboy_legacy;
761     struct {
762         /* Used by VBA versions with 32-bit timestamp*/
763         GB_vba_rtc_time_t rtc_real, rtc_latched;
764         uint32_t last_rtc_second; /* Always little endian */
765     } vba32;
766     struct {
767         /* Used by BGB and VBA versions with 64-bit timestamp*/
768         GB_vba_rtc_time_t rtc_real, rtc_latched;
769         uint64_t last_rtc_second; /* Always little endian */
770     } vba64;
771 } GB_rtc_save_t;
772 
GB_fill_tpp1_save_data(GB_gameboy_t * gb,GB_tpp1_rtc_save_t * data)773 static void GB_fill_tpp1_save_data(GB_gameboy_t *gb, GB_tpp1_rtc_save_t *data)
774 {
775     data->magic = BE32('TPP1');
776     data->version = BE16(0x100);
777     data->mr4 = gb->tpp1_mr4;
778     data->reserved = 0;
779     data->last_rtc_second = LE64(time(NULL));
780     unrolled for (unsigned i = 4; i--;) {
781         data->rtc_data[i] = gb->rtc_real.data[i ^ 3];
782     }
783 }
784 
GB_save_battery_size(GB_gameboy_t * gb)785 int GB_save_battery_size(GB_gameboy_t *gb)
786 {
787     if (!gb->cartridge_type->has_battery) return 0; // Nothing to save.
788     if (gb->cartridge_type->mbc_type == GB_TPP1 && !(gb->rom[0x153] & 8)) return 0; // Nothing to save.
789 
790     if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
791 
792     if (gb->cartridge_type->mbc_type == GB_HUC3) {
793         return gb->mbc_ram_size + sizeof(GB_huc3_rtc_time_t);
794     }
795 
796     if (gb->cartridge_type->mbc_type == GB_TPP1) {
797         return gb->mbc_ram_size + sizeof(GB_tpp1_rtc_save_t);
798     }
799 
800     GB_rtc_save_t rtc_save_size;
801     return gb->mbc_ram_size + (gb->cartridge_type->has_rtc ? sizeof(rtc_save_size.vba64) : 0);
802 }
803 
GB_save_battery_to_buffer(GB_gameboy_t * gb,uint8_t * buffer,size_t size)804 int GB_save_battery_to_buffer(GB_gameboy_t *gb, uint8_t *buffer, size_t size)
805 {
806     if (!gb->cartridge_type->has_battery) return 0; // Nothing to save.
807     if (gb->cartridge_type->mbc_type == GB_TPP1 && !(gb->rom[0x153] & 8)) return 0; // Nothing to save.
808     if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
809 
810     if (size < GB_save_battery_size(gb)) return EIO;
811 
812     memcpy(buffer, gb->mbc_ram, gb->mbc_ram_size);
813 
814     if (gb->cartridge_type->mbc_type == GB_TPP1) {
815         buffer += gb->mbc_ram_size;
816         GB_tpp1_rtc_save_t rtc_save;
817         GB_fill_tpp1_save_data(gb, &rtc_save);
818         memcpy(buffer, &rtc_save, sizeof(rtc_save));
819     }
820     else if (gb->cartridge_type->mbc_type == GB_HUC3) {
821         buffer += gb->mbc_ram_size;
822 
823 #ifdef GB_BIG_ENDIAN
824         GB_huc3_rtc_time_t rtc_save = {
825             __builtin_bswap64(gb->last_rtc_second),
826             __builtin_bswap16(gb->huc3_minutes),
827             __builtin_bswap16(gb->huc3_days),
828             __builtin_bswap16(gb->huc3_alarm_minutes),
829             __builtin_bswap16(gb->huc3_alarm_days),
830             gb->huc3_alarm_enabled,
831         };
832 #else
833         GB_huc3_rtc_time_t rtc_save = {
834             gb->last_rtc_second,
835             gb->huc3_minutes,
836             gb->huc3_days,
837             gb->huc3_alarm_minutes,
838             gb->huc3_alarm_days,
839             gb->huc3_alarm_enabled,
840         };
841 #endif
842         memcpy(buffer, &rtc_save, sizeof(rtc_save));
843     }
844     else if (gb->cartridge_type->has_rtc) {
845         GB_rtc_save_t rtc_save = {{{{0,}},},};
846         rtc_save.vba64.rtc_real.seconds = gb->rtc_real.seconds;
847         rtc_save.vba64.rtc_real.minutes = gb->rtc_real.minutes;
848         rtc_save.vba64.rtc_real.hours = gb->rtc_real.hours;
849         rtc_save.vba64.rtc_real.days = gb->rtc_real.days;
850         rtc_save.vba64.rtc_real.high = gb->rtc_real.high;
851         rtc_save.vba64.rtc_latched.seconds = gb->rtc_latched.seconds;
852         rtc_save.vba64.rtc_latched.minutes = gb->rtc_latched.minutes;
853         rtc_save.vba64.rtc_latched.hours = gb->rtc_latched.hours;
854         rtc_save.vba64.rtc_latched.days = gb->rtc_latched.days;
855         rtc_save.vba64.rtc_latched.high = gb->rtc_latched.high;
856 #ifdef GB_BIG_ENDIAN
857         rtc_save.vba64.last_rtc_second = __builtin_bswap64(time(NULL));
858 #else
859         rtc_save.vba64.last_rtc_second = time(NULL);
860 #endif
861         memcpy(buffer + gb->mbc_ram_size, &rtc_save.vba64, sizeof(rtc_save.vba64));
862     }
863 
864     errno = 0;
865     return errno;
866 }
867 
GB_save_battery(GB_gameboy_t * gb,const char * path)868 int GB_save_battery(GB_gameboy_t *gb, const char *path)
869 {
870     if (!gb->cartridge_type->has_battery) return 0; // Nothing to save.
871     if (gb->cartridge_type->mbc_type == GB_TPP1 && !(gb->rom[0x153] & 8)) return 0; // Nothing to save.
872     if (gb->mbc_ram_size == 0 && !gb->cartridge_type->has_rtc) return 0; /* Claims to have battery, but has no RAM or RTC */
873     FILE *f = fopen(path, "wb");
874     if (!f) {
875         GB_log(gb, "Could not open battery save: %s.\n", strerror(errno));
876         return errno;
877     }
878 
879     if (fwrite(gb->mbc_ram, 1, gb->mbc_ram_size, f) != gb->mbc_ram_size) {
880         fclose(f);
881         return EIO;
882     }
883     if (gb->cartridge_type->mbc_type == GB_TPP1) {
884         GB_tpp1_rtc_save_t rtc_save;
885         GB_fill_tpp1_save_data(gb, &rtc_save);
886 
887         if (fwrite(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
888             fclose(f);
889             return EIO;
890         }
891     }
892     else if (gb->cartridge_type->mbc_type == GB_HUC3) {
893 #ifdef GB_BIG_ENDIAN
894         GB_huc3_rtc_time_t rtc_save = {
895             __builtin_bswap64(gb->last_rtc_second),
896             __builtin_bswap16(gb->huc3_minutes),
897             __builtin_bswap16(gb->huc3_days),
898             __builtin_bswap16(gb->huc3_alarm_minutes),
899             __builtin_bswap16(gb->huc3_alarm_days),
900             gb->huc3_alarm_enabled,
901         };
902 #else
903         GB_huc3_rtc_time_t rtc_save = {
904             gb->last_rtc_second,
905             gb->huc3_minutes,
906             gb->huc3_days,
907             gb->huc3_alarm_minutes,
908             gb->huc3_alarm_days,
909             gb->huc3_alarm_enabled,
910         };
911 #endif
912 
913         if (fwrite(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
914             fclose(f);
915             return EIO;
916         }
917     }
918     else if (gb->cartridge_type->has_rtc) {
919         GB_rtc_save_t rtc_save = {{{{0,}},},};
920         rtc_save.vba64.rtc_real.seconds = gb->rtc_real.seconds;
921         rtc_save.vba64.rtc_real.minutes = gb->rtc_real.minutes;
922         rtc_save.vba64.rtc_real.hours = gb->rtc_real.hours;
923         rtc_save.vba64.rtc_real.days = gb->rtc_real.days;
924         rtc_save.vba64.rtc_real.high = gb->rtc_real.high;
925         rtc_save.vba64.rtc_latched.seconds = gb->rtc_latched.seconds;
926         rtc_save.vba64.rtc_latched.minutes = gb->rtc_latched.minutes;
927         rtc_save.vba64.rtc_latched.hours = gb->rtc_latched.hours;
928         rtc_save.vba64.rtc_latched.days = gb->rtc_latched.days;
929         rtc_save.vba64.rtc_latched.high = gb->rtc_latched.high;
930 #ifdef GB_BIG_ENDIAN
931         rtc_save.vba64.last_rtc_second = __builtin_bswap64(time(NULL));
932 #else
933         rtc_save.vba64.last_rtc_second = time(NULL);
934 #endif
935         if (fwrite(&rtc_save.vba64, 1, sizeof(rtc_save.vba64), f) != sizeof(rtc_save.vba64)) {
936             fclose(f);
937             return EIO;
938         }
939 
940     }
941 
942     errno = 0;
943     fclose(f);
944     return errno;
945 }
946 
GB_load_tpp1_save_data(GB_gameboy_t * gb,const GB_tpp1_rtc_save_t * data)947 static void GB_load_tpp1_save_data(GB_gameboy_t *gb, const GB_tpp1_rtc_save_t *data)
948 {
949     gb->last_rtc_second = LE64(data->last_rtc_second);
950     unrolled for (unsigned i = 4; i--;) {
951         gb->rtc_real.data[i ^ 3] = data->rtc_data[i];
952     }
953 }
954 
GB_load_battery_from_buffer(GB_gameboy_t * gb,const uint8_t * buffer,size_t size)955 void GB_load_battery_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t size)
956 {
957     memcpy(gb->mbc_ram, buffer, MIN(gb->mbc_ram_size, size));
958     if (size <= gb->mbc_ram_size) {
959         goto reset_rtc;
960     }
961 
962     if (gb->cartridge_type->mbc_type == GB_TPP1) {
963         GB_tpp1_rtc_save_t rtc_save;
964         if (size - gb->mbc_ram_size < sizeof(rtc_save)) {
965             goto reset_rtc;
966         }
967         memcpy(&rtc_save, buffer + gb->mbc_ram_size, sizeof(rtc_save));
968 
969         GB_load_tpp1_save_data(gb, &rtc_save);
970 
971         if (gb->last_rtc_second > time(NULL)) {
972             /* We must reset RTC here, or it will not advance. */
973             goto reset_rtc;
974         }
975         return;
976     }
977 
978     if (gb->cartridge_type->mbc_type == GB_HUC3) {
979         GB_huc3_rtc_time_t rtc_save;
980         if (size - gb->mbc_ram_size < sizeof(rtc_save)) {
981             goto reset_rtc;
982         }
983         memcpy(&rtc_save, buffer + gb->mbc_ram_size, sizeof(rtc_save));
984 #ifdef GB_BIG_ENDIAN
985         gb->last_rtc_second = __builtin_bswap64(rtc_save.last_rtc_second);
986         gb->huc3_minutes = __builtin_bswap16(rtc_save.minutes);
987         gb->huc3_days = __builtin_bswap16(rtc_save.days);
988         gb->huc3_alarm_minutes = __builtin_bswap16(rtc_save.alarm_minutes);
989         gb->huc3_alarm_days = __builtin_bswap16(rtc_save.alarm_days);
990         gb->huc3_alarm_enabled = rtc_save.alarm_enabled;
991 #else
992         gb->last_rtc_second = rtc_save.last_rtc_second;
993         gb->huc3_minutes = rtc_save.minutes;
994         gb->huc3_days = rtc_save.days;
995         gb->huc3_alarm_minutes = rtc_save.alarm_minutes;
996         gb->huc3_alarm_days = rtc_save.alarm_days;
997         gb->huc3_alarm_enabled = rtc_save.alarm_enabled;
998 #endif
999         if (gb->last_rtc_second > time(NULL)) {
1000             /* We must reset RTC here, or it will not advance. */
1001             goto reset_rtc;
1002         }
1003         return;
1004     }
1005 
1006     GB_rtc_save_t rtc_save;
1007     memcpy(&rtc_save, buffer + gb->mbc_ram_size, MIN(sizeof(rtc_save), size));
1008     switch (size - gb->mbc_ram_size) {
1009         case sizeof(rtc_save.sameboy_legacy):
1010             memcpy(&gb->rtc_real, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1011             memcpy(&gb->rtc_latched, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1012             gb->last_rtc_second = rtc_save.sameboy_legacy.last_rtc_second;
1013             break;
1014 
1015         case sizeof(rtc_save.vba32):
1016             gb->rtc_real.seconds = rtc_save.vba32.rtc_real.seconds;
1017             gb->rtc_real.minutes = rtc_save.vba32.rtc_real.minutes;
1018             gb->rtc_real.hours = rtc_save.vba32.rtc_real.hours;
1019             gb->rtc_real.days = rtc_save.vba32.rtc_real.days;
1020             gb->rtc_real.high = rtc_save.vba32.rtc_real.high;
1021             gb->rtc_latched.seconds = rtc_save.vba32.rtc_latched.seconds;
1022             gb->rtc_latched.minutes = rtc_save.vba32.rtc_latched.minutes;
1023             gb->rtc_latched.hours = rtc_save.vba32.rtc_latched.hours;
1024             gb->rtc_latched.days = rtc_save.vba32.rtc_latched.days;
1025             gb->rtc_latched.high = rtc_save.vba32.rtc_latched.high;
1026 #ifdef GB_BIG_ENDIAN
1027             gb->last_rtc_second = __builtin_bswap32(rtc_save.vba32.last_rtc_second);
1028 #else
1029             gb->last_rtc_second = rtc_save.vba32.last_rtc_second;
1030 #endif
1031             break;
1032 
1033         case sizeof(rtc_save.vba64):
1034             gb->rtc_real.seconds = rtc_save.vba64.rtc_real.seconds;
1035             gb->rtc_real.minutes = rtc_save.vba64.rtc_real.minutes;
1036             gb->rtc_real.hours = rtc_save.vba64.rtc_real.hours;
1037             gb->rtc_real.days = rtc_save.vba64.rtc_real.days;
1038             gb->rtc_real.high = rtc_save.vba64.rtc_real.high;
1039             gb->rtc_latched.seconds = rtc_save.vba64.rtc_latched.seconds;
1040             gb->rtc_latched.minutes = rtc_save.vba64.rtc_latched.minutes;
1041             gb->rtc_latched.hours = rtc_save.vba64.rtc_latched.hours;
1042             gb->rtc_latched.days = rtc_save.vba64.rtc_latched.days;
1043             gb->rtc_latched.high = rtc_save.vba64.rtc_latched.high;
1044 #ifdef GB_BIG_ENDIAN
1045             gb->last_rtc_second = __builtin_bswap64(rtc_save.vba64.last_rtc_second);
1046 #else
1047             gb->last_rtc_second = rtc_save.vba64.last_rtc_second;
1048 #endif
1049             break;
1050 
1051         default:
1052             goto reset_rtc;
1053     }
1054     if (gb->last_rtc_second > time(NULL)) {
1055         /* We must reset RTC here, or it will not advance. */
1056         goto reset_rtc;
1057     }
1058 
1059     if (gb->last_rtc_second < 852076800) { /* 1/1/97. There weren't any RTC games that time,
1060                                             so if the value we read is lower it means it wasn't
1061                                             really RTC data. */
1062         goto reset_rtc;
1063     }
1064     goto exit;
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     gb->huc3_days = 0xFFFF;
1069     gb->huc3_minutes = 0xFFF;
1070     gb->huc3_alarm_enabled = false;
1071 exit:
1072     return;
1073 }
1074 
1075 /* Loading will silently stop if the format is incomplete */
GB_load_battery(GB_gameboy_t * gb,const char * path)1076 void GB_load_battery(GB_gameboy_t *gb, const char *path)
1077 {
1078     FILE *f = fopen(path, "rb");
1079     if (!f) {
1080         return;
1081     }
1082 
1083     if (fread(gb->mbc_ram, 1, gb->mbc_ram_size, f) != gb->mbc_ram_size) {
1084         goto reset_rtc;
1085     }
1086 
1087     if (gb->cartridge_type->mbc_type == GB_TPP1) {
1088         GB_tpp1_rtc_save_t rtc_save;
1089         if (fread(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
1090             goto reset_rtc;
1091         }
1092 
1093         GB_load_tpp1_save_data(gb, &rtc_save);
1094 
1095         if (gb->last_rtc_second > time(NULL)) {
1096             /* We must reset RTC here, or it will not advance. */
1097             goto reset_rtc;
1098         }
1099         return;
1100     }
1101 
1102     if (gb->cartridge_type->mbc_type == GB_HUC3) {
1103         GB_huc3_rtc_time_t rtc_save;
1104         if (fread(&rtc_save, sizeof(rtc_save), 1, f) != 1) {
1105             goto reset_rtc;
1106         }
1107 #ifdef GB_BIG_ENDIAN
1108         gb->last_rtc_second = __builtin_bswap64(rtc_save.last_rtc_second);
1109         gb->huc3_minutes = __builtin_bswap16(rtc_save.minutes);
1110         gb->huc3_days = __builtin_bswap16(rtc_save.days);
1111         gb->huc3_alarm_minutes = __builtin_bswap16(rtc_save.alarm_minutes);
1112         gb->huc3_alarm_days = __builtin_bswap16(rtc_save.alarm_days);
1113         gb->huc3_alarm_enabled = rtc_save.alarm_enabled;
1114 #else
1115         gb->last_rtc_second = rtc_save.last_rtc_second;
1116         gb->huc3_minutes = rtc_save.minutes;
1117         gb->huc3_days = rtc_save.days;
1118         gb->huc3_alarm_minutes = rtc_save.alarm_minutes;
1119         gb->huc3_alarm_days = rtc_save.alarm_days;
1120         gb->huc3_alarm_enabled = rtc_save.alarm_enabled;
1121 #endif
1122         if (gb->last_rtc_second > time(NULL)) {
1123             /* We must reset RTC here, or it will not advance. */
1124             goto reset_rtc;
1125         }
1126         return;
1127     }
1128 
1129     GB_rtc_save_t rtc_save;
1130     switch (fread(&rtc_save, 1, sizeof(rtc_save), f)) {
1131         case sizeof(rtc_save.sameboy_legacy):
1132             memcpy(&gb->rtc_real, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1133             memcpy(&gb->rtc_latched, &rtc_save.sameboy_legacy.rtc_real, sizeof(gb->rtc_real));
1134             gb->last_rtc_second = rtc_save.sameboy_legacy.last_rtc_second;
1135             break;
1136 
1137         case sizeof(rtc_save.vba32):
1138             gb->rtc_real.seconds = rtc_save.vba32.rtc_real.seconds;
1139             gb->rtc_real.minutes = rtc_save.vba32.rtc_real.minutes;
1140             gb->rtc_real.hours = rtc_save.vba32.rtc_real.hours;
1141             gb->rtc_real.days = rtc_save.vba32.rtc_real.days;
1142             gb->rtc_real.high = rtc_save.vba32.rtc_real.high;
1143             gb->rtc_latched.seconds = rtc_save.vba32.rtc_latched.seconds;
1144             gb->rtc_latched.minutes = rtc_save.vba32.rtc_latched.minutes;
1145             gb->rtc_latched.hours = rtc_save.vba32.rtc_latched.hours;
1146             gb->rtc_latched.days = rtc_save.vba32.rtc_latched.days;
1147             gb->rtc_latched.high = rtc_save.vba32.rtc_latched.high;
1148 #ifdef GB_BIG_ENDIAN
1149             gb->last_rtc_second = __builtin_bswap32(rtc_save.vba32.last_rtc_second);
1150 #else
1151             gb->last_rtc_second = rtc_save.vba32.last_rtc_second;
1152 #endif
1153             break;
1154 
1155         case sizeof(rtc_save.vba64):
1156             gb->rtc_real.seconds = rtc_save.vba64.rtc_real.seconds;
1157             gb->rtc_real.minutes = rtc_save.vba64.rtc_real.minutes;
1158             gb->rtc_real.hours = rtc_save.vba64.rtc_real.hours;
1159             gb->rtc_real.days = rtc_save.vba64.rtc_real.days;
1160             gb->rtc_real.high = rtc_save.vba64.rtc_real.high;
1161             gb->rtc_latched.seconds = rtc_save.vba64.rtc_latched.seconds;
1162             gb->rtc_latched.minutes = rtc_save.vba64.rtc_latched.minutes;
1163             gb->rtc_latched.hours = rtc_save.vba64.rtc_latched.hours;
1164             gb->rtc_latched.days = rtc_save.vba64.rtc_latched.days;
1165             gb->rtc_latched.high = rtc_save.vba64.rtc_latched.high;
1166 #ifdef GB_BIG_ENDIAN
1167             gb->last_rtc_second = __builtin_bswap64(rtc_save.vba64.last_rtc_second);
1168 #else
1169             gb->last_rtc_second = rtc_save.vba64.last_rtc_second;
1170 #endif
1171             break;
1172 
1173         default:
1174             goto reset_rtc;
1175     }
1176     if (gb->last_rtc_second > time(NULL)) {
1177         /* We must reset RTC here, or it will not advance. */
1178         goto reset_rtc;
1179     }
1180 
1181     if (gb->last_rtc_second < 852076800) { /* 1/1/97. There weren't any RTC games that time,
1182                                             so if the value we read is lower it means it wasn't
1183                                             really RTC data. */
1184         goto reset_rtc;
1185     }
1186     goto exit;
1187 reset_rtc:
1188     gb->last_rtc_second = time(NULL);
1189     gb->rtc_real.high |= 0x80; /* This gives the game a hint that the clock should be reset. */
1190     gb->huc3_days = 0xFFFF;
1191     gb->huc3_minutes = 0xFFF;
1192     gb->huc3_alarm_enabled = false;
1193 exit:
1194     fclose(f);
1195     return;
1196 }
1197 
GB_run(GB_gameboy_t * gb)1198 uint8_t GB_run(GB_gameboy_t *gb)
1199 {
1200     gb->vblank_just_occured = false;
1201 
1202     if (gb->sgb && gb->sgb->intro_animation < 96) {
1203         /* On the SGB, the GB is halted after finishing the boot ROM.
1204            Then, after the boot animation is almost done, it's reset.
1205            Since the SGB HLE does not perform any header validity checks,
1206            we just halt the CPU (with hacky code) until the correct time.
1207            This ensures the Nintendo logo doesn't flash on screen, and
1208            the game does "run in background" while the animation is playing. */
1209         GB_display_run(gb, 228);
1210         gb->cycles_since_last_sync += 228;
1211         return 228;
1212     }
1213 
1214     GB_debugger_run(gb);
1215     gb->cycles_since_run = 0;
1216     GB_cpu_run(gb);
1217     if (gb->vblank_just_occured) {
1218         GB_debugger_handle_async_commands(gb);
1219         GB_rewind_push(gb);
1220     }
1221     return gb->cycles_since_run;
1222 }
1223 
GB_run_frame(GB_gameboy_t * gb)1224 uint64_t GB_run_frame(GB_gameboy_t *gb)
1225 {
1226     /* Configure turbo temporarily, the user wants to handle FPS capping manually. */
1227     bool old_turbo = gb->turbo;
1228     bool old_dont_skip = gb->turbo_dont_skip;
1229     gb->turbo = true;
1230     gb->turbo_dont_skip = true;
1231 
1232     gb->cycles_since_last_sync = 0;
1233     while (true) {
1234         GB_run(gb);
1235         if (gb->vblank_just_occured) {
1236             break;
1237         }
1238     }
1239     gb->turbo = old_turbo;
1240     gb->turbo_dont_skip = old_dont_skip;
1241     return gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */
1242 }
1243 
GB_set_pixels_output(GB_gameboy_t * gb,uint32_t * output)1244 void GB_set_pixels_output(GB_gameboy_t *gb, uint32_t *output)
1245 {
1246     gb->screen = output;
1247 }
1248 
GB_set_vblank_callback(GB_gameboy_t * gb,GB_vblank_callback_t callback)1249 void GB_set_vblank_callback(GB_gameboy_t *gb, GB_vblank_callback_t callback)
1250 {
1251     gb->vblank_callback = callback;
1252 }
1253 
GB_set_log_callback(GB_gameboy_t * gb,GB_log_callback_t callback)1254 void GB_set_log_callback(GB_gameboy_t *gb, GB_log_callback_t callback)
1255 {
1256     gb->log_callback = callback;
1257 }
1258 
GB_set_input_callback(GB_gameboy_t * gb,GB_input_callback_t callback)1259 void GB_set_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback)
1260 {
1261 #ifndef GB_DISABLE_DEBUGGER
1262     if (gb->input_callback == default_input_callback) {
1263         gb->async_input_callback = NULL;
1264     }
1265     gb->input_callback = callback;
1266 #endif
1267 }
1268 
GB_set_async_input_callback(GB_gameboy_t * gb,GB_input_callback_t callback)1269 void GB_set_async_input_callback(GB_gameboy_t *gb, GB_input_callback_t callback)
1270 {
1271 #ifndef GB_DISABLE_DEBUGGER
1272     gb->async_input_callback = callback;
1273 #endif
1274 }
1275 
1276 const GB_palette_t GB_PALETTE_GREY = {{{0x00, 0x00, 0x00}, {0x55, 0x55, 0x55}, {0xaa, 0xaa, 0xaa}, {0xff, 0xff, 0xff}, {0xff, 0xff, 0xff}}};
1277 const GB_palette_t GB_PALETTE_DMG  = {{{0x08, 0x18, 0x10}, {0x39, 0x61, 0x39}, {0x84, 0xa5, 0x63}, {0xc6, 0xde, 0x8c}, {0xd2, 0xe6, 0xa6}}};
1278 const GB_palette_t GB_PALETTE_MGB  = {{{0x07, 0x10, 0x0e}, {0x3a, 0x4c, 0x3a}, {0x81, 0x8d, 0x66}, {0xc2, 0xce, 0x93}, {0xcf, 0xda, 0xac}}};
1279 const GB_palette_t GB_PALETTE_GBL  = {{{0x0a, 0x1c, 0x15}, {0x35, 0x78, 0x62}, {0x56, 0xb4, 0x95}, {0x7f, 0xe2, 0xc3}, {0x91, 0xea, 0xd0}}};
1280 
update_dmg_palette(GB_gameboy_t * gb)1281 static void update_dmg_palette(GB_gameboy_t *gb)
1282 {
1283     const GB_palette_t *palette = gb->dmg_palette ?: &GB_PALETTE_GREY;
1284     if (gb->rgb_encode_callback && !GB_is_cgb(gb)) {
1285         gb->sprite_palettes_rgb[4] = gb->sprite_palettes_rgb[0] = gb->background_palettes_rgb[0] =
1286         gb->rgb_encode_callback(gb, palette->colors[3].r, palette->colors[3].g, palette->colors[3].b);
1287         gb->sprite_palettes_rgb[5] = gb->sprite_palettes_rgb[1] = gb->background_palettes_rgb[1] =
1288         gb->rgb_encode_callback(gb, palette->colors[2].r, palette->colors[2].g, palette->colors[2].b);
1289         gb->sprite_palettes_rgb[6] = gb->sprite_palettes_rgb[2] = gb->background_palettes_rgb[2] =
1290         gb->rgb_encode_callback(gb, palette->colors[1].r, palette->colors[1].g, palette->colors[1].b);
1291         gb->sprite_palettes_rgb[7] = gb->sprite_palettes_rgb[3] = gb->background_palettes_rgb[3] =
1292         gb->rgb_encode_callback(gb, palette->colors[0].r, palette->colors[0].g, palette->colors[0].b);
1293 
1294         // LCD off color
1295         gb->background_palettes_rgb[4] =
1296         gb->rgb_encode_callback(gb, palette->colors[4].r, palette->colors[4].g, palette->colors[4].b);
1297     }
1298 }
1299 
GB_set_palette(GB_gameboy_t * gb,const GB_palette_t * palette)1300 void GB_set_palette(GB_gameboy_t *gb, const GB_palette_t *palette)
1301 {
1302     gb->dmg_palette = palette;
1303     update_dmg_palette(gb);
1304 }
1305 
GB_set_rgb_encode_callback(GB_gameboy_t * gb,GB_rgb_encode_callback_t callback)1306 void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callback)
1307 {
1308 
1309     gb->rgb_encode_callback = callback;
1310     update_dmg_palette(gb);
1311 
1312     for (unsigned i = 0; i < 32; i++) {
1313         GB_palette_changed(gb, true, i * 2);
1314         GB_palette_changed(gb, false, i * 2);
1315     }
1316 }
1317 
GB_set_infrared_callback(GB_gameboy_t * gb,GB_infrared_callback_t callback)1318 void GB_set_infrared_callback(GB_gameboy_t *gb, GB_infrared_callback_t callback)
1319 {
1320     gb->infrared_callback = callback;
1321 }
1322 
GB_set_infrared_input(GB_gameboy_t * gb,bool state)1323 void GB_set_infrared_input(GB_gameboy_t *gb, bool state)
1324 {
1325     gb->infrared_input = state;
1326 }
1327 
GB_set_rumble_callback(GB_gameboy_t * gb,GB_rumble_callback_t callback)1328 void GB_set_rumble_callback(GB_gameboy_t *gb, GB_rumble_callback_t callback)
1329 {
1330     gb->rumble_callback = callback;
1331 }
1332 
GB_set_serial_transfer_bit_start_callback(GB_gameboy_t * gb,GB_serial_transfer_bit_start_callback_t callback)1333 void GB_set_serial_transfer_bit_start_callback(GB_gameboy_t *gb, GB_serial_transfer_bit_start_callback_t callback)
1334 {
1335     gb->serial_transfer_bit_start_callback = callback;
1336 }
1337 
GB_set_serial_transfer_bit_end_callback(GB_gameboy_t * gb,GB_serial_transfer_bit_end_callback_t callback)1338 void GB_set_serial_transfer_bit_end_callback(GB_gameboy_t *gb, GB_serial_transfer_bit_end_callback_t callback)
1339 {
1340     gb->serial_transfer_bit_end_callback = callback;
1341 }
1342 
GB_serial_get_data_bit(GB_gameboy_t * gb)1343 bool GB_serial_get_data_bit(GB_gameboy_t *gb)
1344 {
1345     if (gb->io_registers[GB_IO_SC] & 1) {
1346         /* Internal Clock */
1347         GB_log(gb, "Serial read request while using internal clock. \n");
1348         return 0xFF;
1349     }
1350     return gb->io_registers[GB_IO_SB] & 0x80;
1351 }
1352 
GB_serial_set_data_bit(GB_gameboy_t * gb,bool data)1353 void GB_serial_set_data_bit(GB_gameboy_t *gb, bool data)
1354 {
1355     if (gb->io_registers[GB_IO_SC] & 1) {
1356         /* Internal Clock */
1357         GB_log(gb, "Serial write request while using internal clock. \n");
1358         return;
1359     }
1360     gb->io_registers[GB_IO_SB] <<= 1;
1361     gb->io_registers[GB_IO_SB] |= data;
1362     gb->serial_count++;
1363     if (gb->serial_count == 8) {
1364         gb->io_registers[GB_IO_IF] |= 8;
1365         gb->serial_count = 0;
1366     }
1367 }
1368 
GB_disconnect_serial(GB_gameboy_t * gb)1369 void GB_disconnect_serial(GB_gameboy_t *gb)
1370 {
1371     gb->serial_transfer_bit_start_callback = NULL;
1372     gb->serial_transfer_bit_end_callback = NULL;
1373 
1374     /* Reset any internally-emulated device. */
1375     memset(&gb->printer, 0, sizeof(gb->printer));
1376     memset(&gb->workboy, 0, sizeof(gb->workboy));
1377 }
1378 
GB_is_inited(GB_gameboy_t * gb)1379 bool GB_is_inited(GB_gameboy_t *gb)
1380 {
1381     return gb->magic == state_magic();
1382 }
1383 
GB_is_cgb(GB_gameboy_t * gb)1384 bool GB_is_cgb(GB_gameboy_t *gb)
1385 {
1386     return (gb->model & GB_MODEL_FAMILY_MASK) == GB_MODEL_CGB_FAMILY;
1387 }
1388 
GB_is_sgb(GB_gameboy_t * gb)1389 bool GB_is_sgb(GB_gameboy_t *gb)
1390 {
1391     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;
1392 }
1393 
GB_is_hle_sgb(GB_gameboy_t * gb)1394 bool GB_is_hle_sgb(GB_gameboy_t *gb)
1395 {
1396     return (gb->model & ~GB_MODEL_PAL_BIT) == GB_MODEL_SGB || gb->model == GB_MODEL_SGB2;
1397 }
1398 
GB_set_turbo_mode(GB_gameboy_t * gb,bool on,bool no_frame_skip)1399 void GB_set_turbo_mode(GB_gameboy_t *gb, bool on, bool no_frame_skip)
1400 {
1401     gb->turbo = on;
1402     gb->turbo_dont_skip = no_frame_skip;
1403 }
1404 
GB_set_rendering_disabled(GB_gameboy_t * gb,bool disabled)1405 void GB_set_rendering_disabled(GB_gameboy_t *gb, bool disabled)
1406 {
1407     gb->disable_rendering = disabled;
1408 }
1409 
GB_get_user_data(GB_gameboy_t * gb)1410 void *GB_get_user_data(GB_gameboy_t *gb)
1411 {
1412     return gb->user_data;
1413 }
1414 
GB_set_user_data(GB_gameboy_t * gb,void * data)1415 void GB_set_user_data(GB_gameboy_t *gb, void *data)
1416 {
1417     gb->user_data = data;
1418 }
1419 
reset_ram(GB_gameboy_t * gb)1420 static void reset_ram(GB_gameboy_t *gb)
1421 {
1422     switch (gb->model) {
1423         case GB_MODEL_CGB_E:
1424         case GB_MODEL_AGB: /* Unverified */
1425             for (unsigned i = 0; i < gb->ram_size; i++) {
1426                 gb->ram[i] = GB_random();
1427             }
1428             break;
1429 
1430         case GB_MODEL_DMG_B:
1431         case GB_MODEL_SGB_NTSC: /* Unverified*/
1432         case GB_MODEL_SGB_PAL: /* Unverified */
1433         case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1434         case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1435             for (unsigned i = 0; i < gb->ram_size; i++) {
1436                 gb->ram[i] = GB_random();
1437                 if (i & 0x100) {
1438                     gb->ram[i] &= GB_random();
1439                 }
1440                 else {
1441                     gb->ram[i] |= GB_random();
1442                 }
1443             }
1444             break;
1445 
1446         case GB_MODEL_SGB2:
1447         case GB_MODEL_SGB2_NO_SFC:
1448             for (unsigned i = 0; i < gb->ram_size; i++) {
1449                 gb->ram[i] = 0x55;
1450                 gb->ram[i] ^= GB_random() & GB_random() & GB_random();
1451             }
1452             break;
1453 
1454         case GB_MODEL_CGB_C:
1455             for (unsigned i = 0; i < gb->ram_size; i++) {
1456                 if ((i & 0x808) == 0x800 || (i & 0x808) == 0x008) {
1457                     gb->ram[i] = 0;
1458                 }
1459                 else {
1460                     gb->ram[i] = GB_random() | GB_random() | GB_random() | GB_random();
1461                 }
1462             }
1463             break;
1464     }
1465 
1466     /* HRAM */
1467     switch (gb->model) {
1468         case GB_MODEL_CGB_C:
1469         // case GB_MODEL_CGB_D:
1470         case GB_MODEL_CGB_E:
1471         case GB_MODEL_AGB:
1472             for (unsigned i = 0; i < sizeof(gb->hram); i++) {
1473                 gb->hram[i] = GB_random();
1474             }
1475             break;
1476 
1477         case GB_MODEL_DMG_B:
1478         case GB_MODEL_SGB_NTSC: /* Unverified*/
1479         case GB_MODEL_SGB_PAL: /* Unverified */
1480         case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1481         case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1482         case GB_MODEL_SGB2:
1483         case GB_MODEL_SGB2_NO_SFC:
1484             for (unsigned i = 0; i < sizeof(gb->hram); i++) {
1485                 if (i & 1) {
1486                     gb->hram[i] = GB_random() | GB_random() | GB_random();
1487                 }
1488                 else {
1489                     gb->hram[i] = GB_random() & GB_random() & GB_random();
1490                 }
1491             }
1492             break;
1493     }
1494 
1495     /* OAM */
1496     switch (gb->model) {
1497         case GB_MODEL_CGB_C:
1498         case GB_MODEL_CGB_E:
1499         case GB_MODEL_AGB:
1500             /* Zero'd out by boot ROM anyway*/
1501             break;
1502 
1503         case GB_MODEL_DMG_B:
1504         case GB_MODEL_SGB_NTSC: /* Unverified */
1505         case GB_MODEL_SGB_PAL: /* Unverified */
1506         case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1507         case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1508         case GB_MODEL_SGB2:
1509         case GB_MODEL_SGB2_NO_SFC:
1510             for (unsigned i = 0; i < 8; i++) {
1511                 if (i & 2) {
1512                     gb->oam[i] = GB_random() & GB_random() & GB_random();
1513                 }
1514                 else {
1515                     gb->oam[i] = GB_random() | GB_random() | GB_random();
1516                 }
1517             }
1518             for (unsigned i = 8; i < sizeof(gb->oam); i++) {
1519                 gb->oam[i] = gb->oam[i - 8];
1520             }
1521             break;
1522     }
1523 
1524     /* Wave RAM */
1525     switch (gb->model) {
1526         case GB_MODEL_CGB_C:
1527         case GB_MODEL_CGB_E:
1528         case GB_MODEL_AGB:
1529             /* Initialized by CGB-A and newer, 0s in CGB-0*/
1530             break;
1531 
1532         case GB_MODEL_DMG_B:
1533         case GB_MODEL_SGB_NTSC: /* Unverified*/
1534         case GB_MODEL_SGB_PAL: /* Unverified */
1535         case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */
1536         case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */
1537         case GB_MODEL_SGB2:
1538         case GB_MODEL_SGB2_NO_SFC: {
1539             for (unsigned i = 0; i < GB_IO_WAV_END - GB_IO_WAV_START; i++) {
1540                 if (i & 1) {
1541                     gb->io_registers[GB_IO_WAV_START + i] = GB_random() & GB_random() & GB_random();
1542                 }
1543                 else {
1544                     gb->io_registers[GB_IO_WAV_START + i] = GB_random() | GB_random() | GB_random();
1545                 }
1546             }
1547             break;
1548         }
1549     }
1550 
1551     for (unsigned i = 0; i < sizeof(gb->extra_oam); i++) {
1552         gb->extra_oam[i] = GB_random();
1553     }
1554 
1555     if (GB_is_cgb(gb)) {
1556         for (unsigned i = 0; i < 64; i++) {
1557             gb->background_palettes_data[i] = GB_random(); /* Doesn't really matter as the boot ROM overrides it anyway*/
1558             gb->sprite_palettes_data[i] = GB_random();
1559         }
1560         for (unsigned i = 0; i < 32; i++) {
1561             GB_palette_changed(gb, true, i * 2);
1562             GB_palette_changed(gb, false, i * 2);
1563         }
1564     }
1565 }
1566 
request_boot_rom(GB_gameboy_t * gb)1567 static void request_boot_rom(GB_gameboy_t *gb)
1568 {
1569     if (gb->boot_rom_load_callback) {
1570         GB_boot_rom_t type = 0;
1571         switch (gb->model) {
1572             case GB_MODEL_DMG_B:
1573                 type = GB_BOOT_ROM_DMG;
1574                 break;
1575             case GB_MODEL_SGB_NTSC:
1576             case GB_MODEL_SGB_PAL:
1577             case GB_MODEL_SGB_NTSC_NO_SFC:
1578             case GB_MODEL_SGB_PAL_NO_SFC:
1579                 type = GB_BOOT_ROM_SGB;
1580                 break;
1581             case GB_MODEL_SGB2:
1582             case GB_MODEL_SGB2_NO_SFC:
1583                 type = GB_BOOT_ROM_SGB2;
1584                 break;
1585             case GB_MODEL_CGB_C:
1586             case GB_MODEL_CGB_E:
1587                 type = GB_BOOT_ROM_CGB;
1588                 break;
1589             case GB_MODEL_AGB:
1590                 type = GB_BOOT_ROM_AGB;
1591                 break;
1592         }
1593         gb->boot_rom_load_callback(gb, type);
1594     }
1595 }
1596 
GB_reset(GB_gameboy_t * gb)1597 void GB_reset(GB_gameboy_t *gb)
1598 {
1599     uint32_t mbc_ram_size = gb->mbc_ram_size;
1600     GB_model_t model = gb->model;
1601     uint8_t rtc_section[GB_SECTION_SIZE(rtc)];
1602     memcpy(rtc_section, GB_GET_SECTION(gb, rtc), sizeof(rtc_section));
1603     memset(gb, 0, (size_t)GB_GET_SECTION((GB_gameboy_t *) 0, unsaved));
1604     memcpy(GB_GET_SECTION(gb, rtc), rtc_section, sizeof(rtc_section));
1605     gb->model = model;
1606     gb->version = GB_STRUCT_VERSION;
1607 
1608     gb->mbc_rom_bank = 1;
1609     gb->last_rtc_second = time(NULL);
1610     gb->cgb_ram_bank = 1;
1611     gb->io_registers[GB_IO_JOYP] = 0xCF;
1612     gb->mbc_ram_size = mbc_ram_size;
1613     if (GB_is_cgb(gb)) {
1614         gb->ram_size = 0x1000 * 8;
1615         gb->vram_size = 0x2000 * 2;
1616         memset(gb->vram, 0, gb->vram_size);
1617         gb->cgb_mode = true;
1618         gb->object_priority = GB_OBJECT_PRIORITY_INDEX;
1619     }
1620     else {
1621         gb->ram_size = 0x2000;
1622         gb->vram_size = 0x2000;
1623         memset(gb->vram, 0, gb->vram_size);
1624         gb->object_priority = GB_OBJECT_PRIORITY_X;
1625 
1626         update_dmg_palette(gb);
1627     }
1628     reset_ram(gb);
1629 
1630     /* The serial interrupt always occur on the 0xF7th cycle of every 0x100 cycle since boot. */
1631     gb->serial_cycles = 0x100-0xF7;
1632     gb->io_registers[GB_IO_SC] = 0x7E;
1633 
1634     /* These are not deterministic, but 00 (CGB) and FF (DMG) are the most common initial values by far */
1635     gb->io_registers[GB_IO_DMA] = gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = GB_is_cgb(gb)? 0x00 : 0xFF;
1636 
1637     gb->accessed_oam_row = -1;
1638 
1639 
1640     if (GB_is_hle_sgb(gb)) {
1641         if (!gb->sgb) {
1642             gb->sgb = malloc(sizeof(*gb->sgb));
1643         }
1644         memset(gb->sgb, 0, sizeof(*gb->sgb));
1645         memset(gb->sgb_intro_jingle_phases, 0, sizeof(gb->sgb_intro_jingle_phases));
1646         gb->sgb_intro_sweep_phase = 0;
1647         gb->sgb_intro_sweep_previous_sample = 0;
1648         gb->sgb->intro_animation = -10;
1649 
1650         gb->sgb->player_count = 1;
1651         GB_sgb_load_default_data(gb);
1652 
1653     }
1654     else {
1655         if (gb->sgb) {
1656             free(gb->sgb);
1657             gb->sgb = NULL;
1658         }
1659     }
1660 
1661     /* Todo: Ugly, fixme, see comment in the timer state machine */
1662     gb->div_state = 3;
1663 
1664     GB_apu_update_cycles_per_sample(gb);
1665 
1666     if (gb->nontrivial_jump_state) {
1667         free(gb->nontrivial_jump_state);
1668         gb->nontrivial_jump_state = NULL;
1669     }
1670 
1671     gb->magic = state_magic();
1672     request_boot_rom(gb);
1673 }
1674 
GB_switch_model_and_reset(GB_gameboy_t * gb,GB_model_t model)1675 void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model)
1676 {
1677     gb->model = model;
1678     if (GB_is_cgb(gb)) {
1679         gb->ram = realloc(gb->ram, gb->ram_size = 0x1000 * 8);
1680         gb->vram = realloc(gb->vram, gb->vram_size = 0x2000 * 2);
1681     }
1682     else {
1683         gb->ram = realloc(gb->ram, gb->ram_size = 0x2000);
1684         gb->vram = realloc(gb->vram, gb->vram_size = 0x2000);
1685     }
1686     if (gb->undo_state) {
1687         free(gb->undo_state);
1688         gb->undo_state = NULL;
1689     }
1690     GB_rewind_free(gb);
1691     GB_reset(gb);
1692     load_default_border(gb);
1693 }
1694 
GB_get_direct_access(GB_gameboy_t * gb,GB_direct_access_t access,size_t * size,uint16_t * bank)1695 void *GB_get_direct_access(GB_gameboy_t *gb, GB_direct_access_t access, size_t *size, uint16_t *bank)
1696 {
1697     /* Set size and bank to dummy pointers if not set */
1698     size_t dummy_size;
1699     uint16_t dummy_bank;
1700     if (!size) {
1701         size = &dummy_size;
1702     }
1703 
1704     if (!bank) {
1705         bank = &dummy_bank;
1706     }
1707 
1708 
1709     switch (access) {
1710         case GB_DIRECT_ACCESS_ROM:
1711             *size = gb->rom_size;
1712             *bank = gb->mbc_rom_bank;
1713             return gb->rom;
1714         case GB_DIRECT_ACCESS_RAM:
1715             *size = gb->ram_size;
1716             *bank = gb->cgb_ram_bank;
1717             return gb->ram;
1718         case GB_DIRECT_ACCESS_CART_RAM:
1719             *size = gb->mbc_ram_size;
1720             *bank = gb->mbc_ram_bank;
1721             return gb->mbc_ram;
1722         case GB_DIRECT_ACCESS_VRAM:
1723             *size = gb->vram_size;
1724             *bank = gb->cgb_vram_bank;
1725             return gb->vram;
1726         case GB_DIRECT_ACCESS_HRAM:
1727             *size = sizeof(gb->hram);
1728             *bank = 0;
1729             return &gb->hram;
1730         case GB_DIRECT_ACCESS_IO:
1731             *size = sizeof(gb->io_registers);
1732             *bank = 0;
1733             return &gb->io_registers;
1734         case GB_DIRECT_ACCESS_BOOTROM:
1735             *size = GB_is_cgb(gb)? sizeof(gb->boot_rom) : 0x100;
1736             *bank = 0;
1737             return &gb->boot_rom;
1738         case GB_DIRECT_ACCESS_OAM:
1739             *size = sizeof(gb->oam);
1740             *bank = 0;
1741             return &gb->oam;
1742         case GB_DIRECT_ACCESS_BGP:
1743             *size = sizeof(gb->background_palettes_data);
1744             *bank = 0;
1745             return &gb->background_palettes_data;
1746         case GB_DIRECT_ACCESS_OBP:
1747             *size = sizeof(gb->sprite_palettes_data);
1748             *bank = 0;
1749             return &gb->sprite_palettes_data;
1750         case GB_DIRECT_ACCESS_IE:
1751             *size = sizeof(gb->interrupt_enable);
1752             *bank = 0;
1753             return &gb->interrupt_enable;
1754         default:
1755             *size = 0;
1756             *bank = 0;
1757             return NULL;
1758     }
1759 }
1760 
GB_set_clock_multiplier(GB_gameboy_t * gb,double multiplier)1761 void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier)
1762 {
1763     gb->clock_multiplier = multiplier;
1764     GB_apu_update_cycles_per_sample(gb);
1765 }
1766 
GB_get_clock_rate(GB_gameboy_t * gb)1767 uint32_t GB_get_clock_rate(GB_gameboy_t *gb)
1768 {
1769     return GB_get_unmultiplied_clock_rate(gb) * gb->clock_multiplier;
1770 }
1771 
1772 
GB_get_unmultiplied_clock_rate(GB_gameboy_t * gb)1773 uint32_t GB_get_unmultiplied_clock_rate(GB_gameboy_t *gb)
1774 {
1775     if (gb->model & GB_MODEL_PAL_BIT) {
1776         return SGB_PAL_FREQUENCY;
1777     }
1778     if ((gb->model & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB) {
1779         return SGB_NTSC_FREQUENCY;
1780     }
1781     return CPU_FREQUENCY;
1782 }
GB_set_border_mode(GB_gameboy_t * gb,GB_border_mode_t border_mode)1783 void GB_set_border_mode(GB_gameboy_t *gb, GB_border_mode_t border_mode)
1784 {
1785     if (gb->border_mode > GB_BORDER_ALWAYS) return;
1786     gb->border_mode = border_mode;
1787 }
1788 
GB_get_screen_width(GB_gameboy_t * gb)1789 unsigned GB_get_screen_width(GB_gameboy_t *gb)
1790 {
1791     switch (gb->border_mode) {
1792         default:
1793         case GB_BORDER_SGB:
1794             return GB_is_hle_sgb(gb)? 256 : 160;
1795         case GB_BORDER_NEVER:
1796             return 160;
1797         case GB_BORDER_ALWAYS:
1798             return 256;
1799     }
1800 }
1801 
GB_get_screen_height(GB_gameboy_t * gb)1802 unsigned GB_get_screen_height(GB_gameboy_t *gb)
1803 {
1804     switch (gb->border_mode) {
1805         default:
1806         case GB_BORDER_SGB:
1807             return GB_is_hle_sgb(gb)? 224 : 144;
1808         case GB_BORDER_NEVER:
1809             return 144;
1810         case GB_BORDER_ALWAYS:
1811             return 224;
1812     }
1813 }
1814 
GB_get_player_count(GB_gameboy_t * gb)1815 unsigned GB_get_player_count(GB_gameboy_t *gb)
1816 {
1817     return GB_is_hle_sgb(gb)? gb->sgb->player_count : 1;
1818 }
1819 
GB_set_update_input_hint_callback(GB_gameboy_t * gb,GB_update_input_hint_callback_t callback)1820 void GB_set_update_input_hint_callback(GB_gameboy_t *gb, GB_update_input_hint_callback_t callback)
1821 {
1822     gb->update_input_hint_callback = callback;
1823 }
1824 
GB_get_usual_frame_rate(GB_gameboy_t * gb)1825 double GB_get_usual_frame_rate(GB_gameboy_t *gb)
1826 {
1827     return GB_get_clock_rate(gb) / (double)LCDC_PERIOD;
1828 }
1829 
GB_set_joyp_write_callback(GB_gameboy_t * gb,GB_joyp_write_callback_t callback)1830 void GB_set_joyp_write_callback(GB_gameboy_t *gb, GB_joyp_write_callback_t callback)
1831 {
1832     gb->joyp_write_callback = callback;
1833 }
1834 
GB_set_icd_pixel_callback(GB_gameboy_t * gb,GB_icd_pixel_callback_t callback)1835 void GB_set_icd_pixel_callback(GB_gameboy_t *gb, GB_icd_pixel_callback_t callback)
1836 {
1837     gb->icd_pixel_callback = callback;
1838 }
1839 
GB_set_icd_hreset_callback(GB_gameboy_t * gb,GB_icd_hreset_callback_t callback)1840 void GB_set_icd_hreset_callback(GB_gameboy_t *gb, GB_icd_hreset_callback_t callback)
1841 {
1842     gb->icd_hreset_callback = callback;
1843 }
1844 
1845 
GB_set_icd_vreset_callback(GB_gameboy_t * gb,GB_icd_vreset_callback_t callback)1846 void GB_set_icd_vreset_callback(GB_gameboy_t *gb, GB_icd_vreset_callback_t callback)
1847 {
1848     gb->icd_vreset_callback = callback;
1849 }
1850 
GB_set_boot_rom_load_callback(GB_gameboy_t * gb,GB_boot_rom_load_callback_t callback)1851 void GB_set_boot_rom_load_callback(GB_gameboy_t *gb, GB_boot_rom_load_callback_t callback)
1852 {
1853     gb->boot_rom_load_callback = callback;
1854     request_boot_rom(gb);
1855 }
1856 
GB_time_to_alarm(GB_gameboy_t * gb)1857 unsigned GB_time_to_alarm(GB_gameboy_t *gb)
1858 {
1859     if (gb->cartridge_type->mbc_type != GB_HUC3) return 0;
1860     if (!gb->huc3_alarm_enabled) return 0;
1861     if (!(gb->huc3_alarm_days & 0x2000)) return 0;
1862     unsigned current_time = (gb->huc3_days & 0x1FFF) * 24 * 60 * 60 + gb->huc3_minutes * 60 + (time(NULL) % 60);
1863     unsigned alarm_time = (gb->huc3_alarm_days & 0x1FFF) * 24 * 60 * 60 + gb->huc3_alarm_minutes * 60;
1864     if (current_time > alarm_time) return 0;
1865     return alarm_time - current_time;
1866 }
1867 
GB_set_rtc_mode(GB_gameboy_t * gb,GB_rtc_mode_t mode)1868 void GB_set_rtc_mode(GB_gameboy_t *gb, GB_rtc_mode_t mode)
1869 {
1870     if (gb->rtc_mode != mode) {
1871         gb->rtc_mode = mode;
1872         gb->rtc_cycles = 0;
1873         gb->last_rtc_second = time(NULL);
1874     }
1875 }
1876 
GB_get_rom_title(GB_gameboy_t * gb,char * title)1877 void GB_get_rom_title(GB_gameboy_t *gb, char *title)
1878 {
1879     memset(title, 0, 17);
1880     if (gb->rom_size >= 0x4000) {
1881         for (unsigned i = 0; i < 0x10; i++) {
1882             if (gb->rom[0x134 + i] < 0x20 || gb->rom[0x134 + i] >= 0x80) break;
1883             title[i] = gb->rom[0x134 + i];
1884         }
1885     }
1886 }
1887 
GB_get_rom_crc32(GB_gameboy_t * gb)1888 uint32_t GB_get_rom_crc32(GB_gameboy_t *gb)
1889 {
1890     static const uint32_t table[] = {
1891         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
1892         0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
1893         0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
1894         0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
1895         0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
1896         0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
1897         0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
1898         0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
1899         0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
1900         0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1901         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
1902         0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
1903         0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
1904         0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
1905         0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
1906         0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
1907         0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
1908         0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
1909         0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
1910         0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1911         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
1912         0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
1913         0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
1914         0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
1915         0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
1916         0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
1917         0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
1918         0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
1919         0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
1920         0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1921         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
1922         0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
1923         0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
1924         0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
1925         0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
1926         0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
1927         0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
1928         0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
1929         0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
1930         0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1931         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
1932         0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
1933         0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
1934     };
1935 
1936     const uint8_t *byte = gb->rom;
1937     uint32_t size = gb->rom_size;
1938     uint32_t ret = 0xFFFFFFFF;
1939     while (size--) {
1940         ret = table[(ret ^ *byte++) & 0xFF] ^ (ret >> 8);
1941     }
1942     return ~ret;
1943 }
1944