fix crash when specifying --source on command line
[rofl0r-gnuboy.git] / loader.c
blobfb8b4a8ca9eff790bc60ff8eac2b4e2e2604ec20
1 #undef _POSIX_C_SOURCE
2 #define _POSIX_C_SOURCE 200809L
3 #undef _GNU_SOURCE
4 #define _GNU_SOURCE
5 #include <string.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <ctype.h>
11 #include <time.h>
13 #include "defs.h"
14 #include "loader.h"
15 #include "regs.h"
16 #include "mem.h"
17 #include "hw.h"
18 #include "rtc.h"
19 #include "rc.h"
20 #include "lcd.h"
21 #include "inflate.h"
22 #include "miniz.h"
23 #define XZ_USE_CRC64
24 #include "xz/xz.h"
25 #include "save.h"
26 #include "sound.h"
27 #include "sys.h"
29 static int mbc_table[256] =
31 0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3,
32 3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1
52 static int rtc_table[256] =
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
55 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 static int batt_table[256] =
61 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
62 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
66 static int romsize_table[256] =
68 2, 4, 8, 16, 32, 64, 128, 256, 512,
69 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 128, 128, 128
79 /* 0, 0, 72, 80, 96 -- actual values but bad to use these! */
82 static int ramsize_table[256] =
84 1, 1, 1, 4, 16,
85 4 /* FIXME - what value should this be?! */
89 static char *bootroms[2];
90 static char *romfile;
91 static char *sramfile;
92 static char *rtcfile;
93 static char *saveprefix;
95 static char *savename;
96 static char *savedir;
98 static int saveslot;
100 static int forcebatt, nobatt;
101 static int forcedmg, gbamode;
103 static int memfill = -1, memrand = -1;
106 static void initmem(void *mem, int size)
108 char *p = mem;
109 if (memrand >= 0)
111 srand(memrand ? memrand : time(0));
112 while(size--) *(p++) = rand();
114 else if (memfill >= 0)
115 memset(p, memfill, size);
118 static byte *loadfile(FILE *f, int *len)
120 int c, l = 0, p = 0;
121 byte *d = 0, buf[4096];
123 for(;;)
125 c = fread(buf, 1, sizeof buf, f);
126 if (c <= 0) break;
127 l += c;
128 d = realloc(d, l);
129 if (!d) return 0;
130 memcpy(d+p, buf, c);
131 p += c;
133 *len = l;
134 return d;
137 static byte *inf_buf;
138 static int inf_pos, inf_len;
139 static char* loader_error;
141 char* loader_get_error(void)
143 return loader_error;
146 void loader_set_error(char *fmt, ...)
148 char buf[1024];
149 va_list ap;
150 va_start(ap, fmt);
151 vsnprintf(buf, sizeof buf, fmt, ap);
152 va_end(ap);
153 loader_error = strdup(buf);
156 static int inflate_callback(byte b)
158 if (inf_pos >= inf_len)
160 inf_len += 512;
161 inf_buf = realloc(inf_buf, inf_len);
162 if (!inf_buf) {
163 loader_set_error("out of memory inflating file @ %d bytes\n", inf_pos);
164 return -1;
167 inf_buf[inf_pos++] = b;
168 return 0;
171 typedef int (*unzip_or_inflate_func) (const unsigned char *data, long *p, int (* callback) (unsigned char d));
173 static byte *gunzip_or_inflate(byte *data, int *len, unsigned offset,
174 unzip_or_inflate_func func)
176 long pos = 0;
177 inf_buf = 0;
178 inf_pos = inf_len = 0;
179 if (func(data+offset, &pos, inflate_callback) < 0)
180 return data;
181 free(data);
182 *len = inf_pos;
183 return inf_buf;
186 static byte *gunzip(byte *data, int *len) {
187 return gunzip_or_inflate(data, len, 0, unzip);
190 /* primitive pkzip decompressor. it can only decompress the first
191 file in a zip archive. */
192 static byte *pkunzip(byte *data, int *len) {
193 unsigned short fnl, el, comp;
194 unsigned int st;
195 void *new;
196 size_t newlen;
197 int oldlen = *len;
198 if (*len < 128) return data;
199 memcpy(&comp, data+8, 2);
200 comp = LIL(comp);
201 if(comp != 0 && comp != 8) return data;
202 memcpy(&fnl, data+26, 2);
203 memcpy(&el, data+28, 2);
204 fnl = LIL(fnl);
205 el = LIL(el);
206 st = 30 + fnl + el;
207 if(*len < st) return data;
208 if(comp == 0) {
209 inf_buf = realloc(NULL, *len - st);
210 memcpy(inf_buf, data+st, *len - st);
211 free(data);
212 inf_len = *len = *len - st;
213 return inf_buf;
215 *len -= st;
216 newlen = 0;
217 new = tinfl_decompress_mem_to_heap(data+st, *len, &newlen, 0);
218 if(new) {
219 *len = newlen;
220 free(data);
221 return new;
223 *len = oldlen;
224 return data;
227 static int write_dec(byte *data, int len) {
228 int i;
229 for(i=0; i < len; i++)
230 if(inflate_callback(data[i])) return -1;
231 return 0;
234 static int unxz(byte *data, int len) {
235 struct xz_buf b;
236 struct xz_dec *s;
237 enum xz_ret ret;
238 unsigned char out[4096];
241 * Support up to 64 MiB dictionary. The actually needed memory
242 * is allocated once the headers have been parsed.
244 s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
245 if(!s) goto err;
247 b.in = data;
248 b.in_pos = 0;
249 b.in_size = len;
250 b.out = out;
251 b.out_pos = 0;
252 b.out_size = sizeof(out);
254 while (1) {
255 ret = xz_dec_run(s, &b);
256 if(b.out_pos == sizeof(out)) {
257 if(write_dec(out, sizeof(out))) goto err;
258 b.out_pos = 0;
261 if(ret == XZ_OK) continue;
263 if(write_dec(out, b.out_pos)) goto err;
265 if(ret == XZ_STREAM_END) {
266 xz_dec_end(s);
267 return 0;
269 goto err;
272 err:
273 xz_dec_end(s);
274 return -1;
277 static byte *do_unxz(byte *data, int *len) {
278 xz_crc32_init();
279 xz_crc64_init();
280 inf_buf = 0;
281 inf_pos = inf_len = 0;
282 if (unxz(data, *len) < 0)
283 return data;
284 free(data);
285 *len = inf_pos;
286 return inf_buf;
289 static byte *decompress(byte *data, int *len)
291 if (data[0] == 0x1f && data[1] == 0x8b)
292 return gunzip(data, len);
293 if (data[0] == 0xFD && !memcmp(data+1, "7zXZ", 4))
294 return do_unxz(data, len);
295 if (data[0] == 'P' && !memcmp(data+1, "K\03\04", 3))
296 return pkunzip(data, len);
297 return data;
300 static FILE* rom_loadfile(char *fn, byte** data, int *len) {
301 FILE *f;
302 if (strcmp(fn, "-")) f = fopen(fn, "rb");
303 else f = stdin;
304 if (!f) {
305 err:
306 loader_set_error("cannot open rom file: %s\n", fn);
307 return f;
309 *data = loadfile(f, len);
310 if (!*data) {
311 fclose(f);
312 f = 0;
313 goto err;
315 *data = decompress(*data, len);
316 return f;
319 int bootrom_load() {
320 byte *data;
321 int len;
322 FILE *f;
323 REG(RI_BOOT) = 0xff;
324 if (!bootroms[hw.cgb] || !bootroms[hw.cgb][0]) return 0;
325 f = rom_loadfile(bootroms[hw.cgb], &data, &len);
326 if(!f) return -1;
327 bootrom.bank = realloc(data, 16384);
328 memset(bootrom.bank[0]+len, 0xff, 16384-len);
329 memcpy(bootrom.bank[0]+0x100, rom.bank[0]+0x100, 0x100);
330 fclose(f);
331 REG(RI_BOOT) = 0xfe;
332 return 0;
335 /* memory allocation breakdown:
336 loadfile returns local buffer retrieved via realloc()
337 it's called only by rom_loadfile.
338 rom_loadfile is called by bootrom_load and rom_load.
339 bootrom_load is called once per romfile load via loader_init from
340 load_rom_and_rc, and mem ends up in bootrom.bank, loader_unload() frees it.
341 rom_load is called by rom_load_simple and loader_init().
342 rom_load_simple is only called by rominfo in main.c, which we can ignore.
343 the mem allocated by loadfile thru loader_init/rom_load ends up in
344 rom.bank, which is freed in loader_unload(), just like the malloc'd
345 rom.sbank.
346 where it gets complicated is when rom_loadfile uncompresses data.
347 the allocation returned by loadfile is passed to decompress().
348 if it fails, it returns the original loadfile allocation, on success
349 it returns a pointer to inf_buf which contains the uncompressed data.
352 int rom_load()
354 FILE *f;
355 byte c, *data, *header;
356 int len = 0, rlen;
357 f = rom_loadfile(romfile, &data, &len);
358 if(!f) return -1;
359 header = data;
361 memcpy(rom.name, header+0x0134, 16);
362 if (rom.name[14] & 0x80) rom.name[14] = 0;
363 if (rom.name[15] & 0x80) rom.name[15] = 0;
364 rom.name[16] = 0;
366 c = header[0x0147];
367 mbc.type = mbc_table[c];
368 mbc.batt = (batt_table[c] && !nobatt) || forcebatt;
369 rtc.batt = rtc_table[c];
370 mbc.romsize = romsize_table[header[0x0148]];
371 mbc.ramsize = ramsize_table[header[0x0149]];
373 if (!mbc.romsize) {
374 loader_set_error("unknown ROM size %02X\n", header[0x0148]);
375 return -1;
377 if (!mbc.ramsize) {
378 loader_set_error("unknown SRAM size %02X\n", header[0x0149]);
379 return -1;
382 rlen = 16384 * mbc.romsize;
384 c = header[0x0143];
386 /* from this point on, we may no longer access data and header */
387 rom.bank = realloc(data, rlen);
388 if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len);
390 ram.sbank = malloc(8192 * mbc.ramsize);
392 initmem(ram.sbank, 8192 * mbc.ramsize);
393 initmem(ram.ibank, 4096 * 8);
395 mbc.rombank = 1;
396 mbc.rambank = 0;
398 hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg;
399 hw.gba = (hw.cgb && gbamode);
401 if (strcmp(romfile, "-")) fclose(f);
403 return 0;
406 int rom_load_simple(char *fn) {
407 romfile = fn;
408 return rom_load();
411 int sram_load()
413 FILE *f;
415 if (!mbc.batt || !sramfile || !*sramfile) return -1;
417 /* Consider sram loaded at this point, even if file doesn't exist */
418 ram.loaded = 1;
420 f = fopen(sramfile, "rb");
421 if (!f) return -1;
422 fread(ram.sbank, 8192, mbc.ramsize, f);
423 fclose(f);
425 return 0;
429 int sram_save()
431 FILE *f;
433 /* If we crash before we ever loaded sram, DO NOT SAVE! */
434 if (!mbc.batt || !sramfile || !ram.loaded || !mbc.ramsize)
435 return -1;
437 f = fopen(sramfile, "wb");
438 if (!f) return -1;
439 fwrite(ram.sbank, 8192, mbc.ramsize, f);
440 fclose(f);
442 return 0;
446 void state_save(int n)
448 FILE *f;
449 char *name;
451 if (n < 0) n = saveslot;
452 if (n < 0) n = 0;
453 name = malloc(strlen(saveprefix) + 5);
454 sprintf(name, "%s.%03d", saveprefix, n);
456 if ((f = fopen(name, "wb")))
458 savestate(f);
459 fclose(f);
461 free(name);
465 void state_load(int n)
467 FILE *f;
468 char *name;
470 if (n < 0) n = saveslot;
471 if (n < 0) n = 0;
472 name = malloc(strlen(saveprefix) + 5);
473 sprintf(name, "%s.%03d", saveprefix, n);
475 if ((f = fopen(name, "rb")))
477 loadstate(f);
478 fclose(f);
479 vram_dirty();
480 pal_dirty();
481 sound_dirty();
482 mem_updatemap();
484 free(name);
487 void rtc_save()
489 FILE *f;
490 if (!rtc.batt) return;
491 if (!(f = fopen(rtcfile, "wb"))) return;
492 rtc_save_internal(f);
493 fclose(f);
496 void rtc_load()
498 FILE *f;
499 if (!rtc.batt) return;
500 if (!(f = fopen(rtcfile, "r"))) return;
501 rtc_load_internal(f);
502 fclose(f);
505 #define FREENULL(X) do { free(X); X = 0; } while(0)
506 void loader_unload()
508 sram_save();
509 if (romfile) FREENULL(romfile);
510 if (sramfile) FREENULL(sramfile);
511 if (saveprefix) FREENULL(saveprefix);
512 if (rom.bank) FREENULL(rom.bank);
513 if (ram.sbank) FREENULL(ram.sbank);
514 if (bootrom.bank) FREENULL(bootrom.bank);
515 mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0;
518 static char *base(char *s)
520 char *p;
521 p = strrchr(s, '/');
522 if (p) return p+1;
523 return s;
526 static char *ldup(char *s)
528 int i;
529 char *n, *p;
530 p = n = malloc(strlen(s));
531 for (i = 0; s[i]; i++) if (isalnum(s[i])) *(p++) = tolower(s[i]);
532 *p = 0;
533 return n;
536 static void cleanup()
538 sram_save();
539 rtc_save();
540 /* IDEA - if error, write emergency savestate..? */
543 int loader_init(char *s)
545 char *name, *p;
547 sys_checkdir(savedir, 1); /* needs to be writable */
549 romfile = s;
550 if(rom_load()) return -1;
551 bootrom_load();
552 vid_settitle(rom.name);
553 if (savename && *savename)
555 if (savename[0] == '-' && savename[1] == 0)
556 name = ldup(rom.name);
557 else name = strdup(savename);
559 else if (romfile && *base(romfile) && strcmp(romfile, "-"))
561 name = strdup(base(romfile));
562 p = strchr(name, '.');
563 if (p) *p = 0;
565 else name = ldup(rom.name);
567 saveprefix = malloc(strlen(savedir) + strlen(name) + 2);
568 sprintf(saveprefix, "%s/%s", savedir, name);
570 sramfile = malloc(strlen(saveprefix) + 5);
571 strcpy(sramfile, saveprefix);
572 strcat(sramfile, ".sav");
574 rtcfile = malloc(strlen(saveprefix) + 5);
575 strcpy(rtcfile, saveprefix);
576 strcat(rtcfile, ".rtc");
578 sram_load();
579 rtc_load();
581 atexit(cleanup);
582 return 0;
585 rcvar_t loader_exports[] =
587 RCV_STRING("bootrom_dmg", &bootroms[0], "bootrom for DMG games"),
588 RCV_STRING("bootrom_cgb", &bootroms[1], "bootrom for CGB games"),
589 RCV_STRING("savedir", &savedir, "save directory"),
590 RCV_STRING("savename", &savename, "base filename for saves"),
591 RCV_INT("saveslot", &saveslot, "which savestate slot to use"),
592 RCV_BOOL("forcebatt", &forcebatt, "save SRAM even on carts w/o battery"),
593 RCV_BOOL("nobatt", &nobatt, "never save SRAM"),
594 RCV_BOOL("forcedmg", &forcedmg, "force DMG mode for CGB carts"),
595 RCV_BOOL("gbamode", &gbamode, "simulate cart being used on a GBA"),
596 RCV_INT("memfill", &memfill, ""),
597 RCV_INT("memrand", &memrand, ""),
598 RCV_END