blob: bdccb2e7e1a843988111d3db88d2619e51ffee7d [file] [log] [blame]
Jens Arnold384de102005-03-02 23:49:38 +00001#include "rockmacros.h"
2#include "defs.h"
3#include "regs.h"
4#include "mem.h"
5#include "hw.h"
Jens Arnoldd2456b42005-07-03 14:05:12 +00006#include "lcd-gb.h"
7#include "rtc-gb.h"
Jens Arnold384de102005-03-02 23:49:38 +00008#include "save.h"
9#include "sound.h"
10
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000011/* From http://www.semis.demon.co.uk/Gameboy/Gbspec.txt (4/17/2007)
12 * Cartridge type:
13 * 0 - ROM ONLY 12 - ROM+MBC3+RAM
14 * 1 - ROM+MBC1 13 - ROM+MBC3+RAM+BATT
15 * 2 - ROM+MBC1+RAM 19 - ROM+MBC5
16 * 3 - ROM+MBC1+RAM+BATT 1A - ROM+MBC5+RAM
17 * 5 - ROM+MBC2 1B - ROM+MBC5+RAM+BATT
18 * 6 - ROM+MBC2+BATTERY 1C - ROM+MBC5+RUMBLE
19 * 8 - ROM+RAM 1D - ROM+MBC5+RUMBLE+SRAM
20 * 9 - ROM+RAM+BATTERY 1E - ROM+MBC5+RUMBLE+SRAM+BATT
21 * B - ROM+MMM01 1F - Pocket Camera
22 * C - ROM+MMM01+SRAM FD - Bandai TAMA5
23 * D - ROM+MMM01+SRAM+BATT FE - Hudson HuC-3
24 * F - ROM+MBC3+TIMER+BATT FF - Hudson HuC-1
25 * 10 - ROM+MBC3+TIMER+RAM+BATT
26 * 11 - ROM+MBC3
27 */
Jens Arnold384de102005-03-02 23:49:38 +000028
29static int mbc_table[256] =
30{
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000031 MBC_NONE,
32 MBC_MBC1,
33 MBC_MBC1,
34 MBC_MBC1 | MBC_BAT,
35 0,
36 MBC_MBC2,
37 MBC_MBC2 | MBC_BAT,
38 0,
39 0,
40 MBC_BAT,
41 0,
42 0,
43 0,
44 MBC_BAT,
45 0,
46 MBC_MBC3 | MBC_BAT | MBC_RTC,
47 MBC_MBC3 | MBC_BAT | MBC_RTC,
48 MBC_MBC3,
49 MBC_MBC3,
50 MBC_MBC3 | MBC_BAT,
51 0,
52 0,
53 0,
54 0,
55 0,
56 MBC_MBC5,
57 MBC_MBC5,
58 MBC_MBC5 | MBC_BAT,
59 MBC_RUMBLE,
60 MBC_RUMBLE,
61 MBC_RUMBLE | MBC_BAT,
62 0,
Tom Ross2882b262007-02-06 21:41:08 +000063 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jens Arnold384de102005-03-02 23:49:38 +000065
Tom Ross2882b262007-02-06 21:41:08 +000066 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jens Arnold384de102005-03-02 23:49:38 +000070
Tom Ross2882b262007-02-06 21:41:08 +000071 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jens Arnold384de102005-03-02 23:49:38 +000075
Tom Ross2882b262007-02-06 21:41:08 +000076 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000079 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 MBC_HUC3,
81 MBC_HUC1
Jens Arnold384de102005-03-02 23:49:38 +000082};
83
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000084static unsigned short romsize_table[56] =
Jens Arnold384de102005-03-02 23:49:38 +000085{
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000086 2, 4, 8, 16, 32, 64, 128, 256,
87 512, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 128, 128, 128, 0
93 /* 0, 0, 0, 0, 72, 80, 96 -- actual values but bad to use these! */
Jens Arnold384de102005-03-02 23:49:38 +000094};
95
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000096/* Ram size should be no larger then 16 banks 1Mbit */
97static unsigned char ramsize_table[5] =
Jens Arnold384de102005-03-02 23:49:38 +000098{
Karl Kurbjunc3dcc872007-04-18 07:41:31 +000099 0, 1, 1, 4, 16
Jens Arnold384de102005-03-02 23:49:38 +0000100};
101
Jens Arnold384de102005-03-02 23:49:38 +0000102static char *romfile;
103static char sramfile[500];
104static char rtcfile[500];
105static char saveprefix[500];
106
Jens Arnold384de102005-03-02 23:49:38 +0000107static int saveslot;
108
109static int forcebatt, nobatt;
Tom Ross2882b262007-02-06 21:41:08 +0000110static int forcedmg;
Jens Arnold384de102005-03-02 23:49:38 +0000111
112static int memfill = -1, memrand = -1;
113
Jens Arnold384de102005-03-02 23:49:38 +0000114static void initmem(void *mem, int size)
115{
Tom Ross2882b262007-02-06 21:41:08 +0000116 char *p = mem;
117 if (memrand >= 0)
118 {
119 srand(memrand ? memrand : -6 ); /* time(0)); */
120 while(size--) *(p++) = rand();
121 }
122 else if (memfill >= 0)
123 memset(p, memfill, size);
Jens Arnold384de102005-03-02 23:49:38 +0000124}
125
126static byte *loadfile(int fd, int *len)
127{
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000128 int c;
129 byte *d;
130
131 *len=lseek(fd,0,SEEK_END);
132 d=malloc((*len)*sizeof(char)+64);
133 if(d==0)
Tom Ross2882b262007-02-06 21:41:08 +0000134 {
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000135 die("Not enough memory");
136 return 0;
Tom Ross2882b262007-02-06 21:41:08 +0000137 }
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000138 lseek(fd,0,SEEK_SET);
139
140 c = read(fd, d, *len);
141
Tom Ross2882b262007-02-06 21:41:08 +0000142 return d;
Jens Arnold384de102005-03-02 23:49:38 +0000143}
144
Jens Arnold384de102005-03-02 23:49:38 +0000145int rom_load(void)
146{
Tom Ross2882b262007-02-06 21:41:08 +0000147 int fd;
148 byte c, *data, *header;
149 int len = 0, rlen;
Jens Arnold384de102005-03-02 23:49:38 +0000150
Tom Ross2882b262007-02-06 21:41:08 +0000151 fd = open(romfile, O_RDONLY);
152
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000153 if (fd<0)
154 {
155 die("cannot open rom file %s", romfile);
Tom Ross2882b262007-02-06 21:41:08 +0000156 return 1;
157 }
Jens Arnold384de102005-03-02 23:49:38 +0000158
Tom Ross2882b262007-02-06 21:41:08 +0000159 data = loadfile(fd, &len);
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000160 close(fd);
161 if(data==0)
162 {
163 die("Not Enough Memory");
164 return 1;
165 }
Tom Ross2882b262007-02-06 21:41:08 +0000166 header = data; /* no zip. = decompress(data, &len); */
167
168 memcpy(rom.name, header+0x0134, 16);
169 if (rom.name[14] & 0x80) rom.name[14] = 0;
170 if (rom.name[15] & 0x80) rom.name[15] = 0;
171 rom.name[16] = 0;
Jens Arnold384de102005-03-02 23:49:38 +0000172
Tom Ross2882b262007-02-06 21:41:08 +0000173 c = header[0x0147];
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000174 mbc.type = mbc_table[c]&(MBC_MBC1|MBC_MBC2|MBC_MBC3|MBC_MBC5|MBC_RUMBLE|MBC_HUC1|MBC_HUC3);
175 mbc.batt = ((mbc_table[c]&MBC_BAT) && !nobatt) || forcebatt;
176 rtc.batt = mbc_table[c]&MBC_RTC;
Jens Arnold384de102005-03-02 23:49:38 +0000177
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000178 if(header[0x0148]<10 || (header[0x0148]>51 && header[0x0148]<55))
179 mbc.romsize = romsize_table[header[0x0148]];
180 else
181 {
Tom Ross2882b262007-02-06 21:41:08 +0000182 die("unknown ROM size %02X\n", header[0x0148]);
183 return 1;
184 }
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000185
186 if(header[0x0149]<5)
187 mbc.ramsize = ramsize_table[header[0x0149]];
188 else
189 {
Tom Ross2882b262007-02-06 21:41:08 +0000190 die("unknown SRAM size %02X\n", header[0x0149]);
191 return 1;
192 }
Jens Arnold384de102005-03-02 23:49:38 +0000193
Tom Ross2882b262007-02-06 21:41:08 +0000194 rlen = 16384 * mbc.romsize;
195 rom.bank = (void *) data; /* realloc(data, rlen); */
196 if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len);
Jens Arnold384de102005-03-02 23:49:38 +0000197
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000198 /* This is the size of the ram on the cartridge
199 * See http://www.semis.demon.co.uk/Gameboy/Gbspec.txt
200 * for a full description. (8192*number of banks)
201 */
Tom Ross2882b262007-02-06 21:41:08 +0000202 ram.sbank = malloc(8192 * mbc.ramsize);
Karl Kurbjunc3dcc872007-04-18 07:41:31 +0000203 if(ram.sbank==0 && mbc.ramsize!=0)
204 {
205 die("Not enough Memory");
206 return 1;
207 }
208
Tom Ross2882b262007-02-06 21:41:08 +0000209 /* ram.ibank = malloc(4096*8); */
Jens Arnold384de102005-03-02 23:49:38 +0000210
Tom Ross2882b262007-02-06 21:41:08 +0000211 initmem(ram.sbank, 8192 * mbc.ramsize);
212 initmem(ram.ibank, 4096 * 8);
Jens Arnold384de102005-03-02 23:49:38 +0000213
Tom Ross2882b262007-02-06 21:41:08 +0000214 mbc.rombank = 1;
215 mbc.rambank = 0;
Jens Arnold384de102005-03-02 23:49:38 +0000216
Tom Ross2882b262007-02-06 21:41:08 +0000217 c = header[0x0143];
Jens Arnold384de102005-03-02 23:49:38 +0000218 hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg;
Jens Arnold384de102005-03-02 23:49:38 +0000219
Tom Ross2882b262007-02-06 21:41:08 +0000220 return 0;
Jens Arnold384de102005-03-02 23:49:38 +0000221}
222
223int sram_load(void)
224{
Tom Ross2882b262007-02-06 21:41:08 +0000225 int fd;
226 char meow[500];
Jens Arnold384de102005-03-02 23:49:38 +0000227
Michael Sevakisb0a1ed12007-09-09 02:49:24 +0000228 if (!mbc.batt || !*sramfile) return -1;
Jens Arnold384de102005-03-02 23:49:38 +0000229
Tom Ross2882b262007-02-06 21:41:08 +0000230 /* Consider sram loaded at this point, even if file doesn't exist */
231 ram.loaded = 1;
Jens Arnold384de102005-03-02 23:49:38 +0000232
Tom Ross2882b262007-02-06 21:41:08 +0000233 fd = open(sramfile, O_RDONLY);
Jens Arnold384de102005-03-02 23:49:38 +0000234 snprintf(meow,499,"Opening %s %d",sramfile,fd);
Jens Arnold4d6374c2007-03-16 21:56:08 +0000235 rb->splash(HZ*2, meow);
Tom Ross2882b262007-02-06 21:41:08 +0000236 if (fd<0) return -1;
Jens Arnold384de102005-03-02 23:49:38 +0000237 snprintf(meow,499,"Loading savedata from %s",sramfile);
Jens Arnold4d6374c2007-03-16 21:56:08 +0000238 rb->splash(HZ*2, meow);
Tom Ross2882b262007-02-06 21:41:08 +0000239 read(fd,ram.sbank, 8192*mbc.ramsize);
240 close(fd);
241
242 return 0;
Jens Arnold384de102005-03-02 23:49:38 +0000243}
244
245
246int sram_save(void)
247{
Tom Ross2882b262007-02-06 21:41:08 +0000248 int fd;
249 char meow[500];
Jens Arnold384de102005-03-02 23:49:38 +0000250
Tom Ross2882b262007-02-06 21:41:08 +0000251 /* If we crash before we ever loaded sram, DO NOT SAVE! */
Michael Sevakisb0a1ed12007-09-09 02:49:24 +0000252 if (!mbc.batt || !ram.loaded || !mbc.ramsize)
Tom Ross2882b262007-02-06 21:41:08 +0000253 return -1;
254 fd = open(sramfile, O_WRONLY|O_CREAT|O_TRUNC);
255 if (fd<0) return -1;
256 snprintf(meow,499,"Saving savedata to %s",sramfile);
Jens Arnold4d6374c2007-03-16 21:56:08 +0000257 rb->splash(HZ*2, meow);
Tom Ross2882b262007-02-06 21:41:08 +0000258 write(fd,ram.sbank, 8192*mbc.ramsize);
259 close(fd);
260
261 return 0;
Jens Arnold384de102005-03-02 23:49:38 +0000262}
263
264
265void state_save(int n)
266{
Tom Ross2882b262007-02-06 21:41:08 +0000267 int fd;
268 char name[500];
Jens Arnold384de102005-03-02 23:49:38 +0000269
Tom Ross2882b262007-02-06 21:41:08 +0000270 if (n < 0) n = saveslot;
271 if (n < 0) n = 0;
272 snprintf(name, 499,"%s.%03d", saveprefix, n);
Jens Arnold384de102005-03-02 23:49:38 +0000273
Tom Ross2882b262007-02-06 21:41:08 +0000274 if ((fd = open(name, O_WRONLY|O_CREAT|O_TRUNC)>=0))
275 {
276 savestate(fd);
277 close(fd);
278 }
Jens Arnold384de102005-03-02 23:49:38 +0000279}
280
281
282void state_load(int n)
283{
Tom Ross2882b262007-02-06 21:41:08 +0000284 int fd;
285 char name[500];
Jens Arnold384de102005-03-02 23:49:38 +0000286
Tom Ross2882b262007-02-06 21:41:08 +0000287 if (n < 0) n = saveslot;
288 if (n < 0) n = 0;
289 snprintf(name, 499, "%s.%03d", saveprefix, n);
Jens Arnold384de102005-03-02 23:49:38 +0000290
Tom Ross2882b262007-02-06 21:41:08 +0000291 if ((fd = open(name, O_RDONLY)>=0))
292 {
293 loadstate(fd);
294 close(fd);
295 vram_dirty();
296 pal_dirty();
297 sound_dirty();
298 mem_updatemap();
299 }
Jens Arnold384de102005-03-02 23:49:38 +0000300}
301
302void rtc_save(void)
303{
Tom Ross2882b262007-02-06 21:41:08 +0000304 int fd;
305 if (!rtc.batt) return;
306 if ((fd = open(rtcfile, O_WRONLY|O_CREAT|O_TRUNC))<0) return;
307 rtc_save_internal(fd);
308 close(fd);
Jens Arnold384de102005-03-02 23:49:38 +0000309}
310
311void rtc_load(void)
312{
Tom Ross2882b262007-02-06 21:41:08 +0000313 int fd;
314 if (!rtc.batt) return;
315 if ((fd = open(rtcfile, O_RDONLY))<0) return;
316 rtc_load_internal(fd);
317 close(fd);
Jens Arnold384de102005-03-02 23:49:38 +0000318}
319
320
321void loader_unload(void)
322{
Tom Ross2882b262007-02-06 21:41:08 +0000323 sram_save();
324 /* if (romfile) free(romfile);
325 if (sramfile) free(sramfile);
326 if (saveprefix) free(saveprefix);
327 if (rom.bank) free(rom.bank);
328 if (ram.sbank) free(ram.sbank); */
329 romfile = 0;
330 rom.bank = 0;
331 ram.sbank = 0;
332 mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0;
Jens Arnold384de102005-03-02 23:49:38 +0000333}
334
Jens Arnold384de102005-03-02 23:49:38 +0000335void cleanup(void)
336{
Tom Ross2882b262007-02-06 21:41:08 +0000337 sram_save();
338 rtc_save();
339 /* IDEA - if error, write emergency savestate..? */
Jens Arnold384de102005-03-02 23:49:38 +0000340}
341
342void loader_init(char *s)
343{
Tom Ross2882b262007-02-06 21:41:08 +0000344 romfile = s;
345 if(rom_load())
346 return;
Jens Arnold4d6374c2007-03-16 21:56:08 +0000347 rb->splash(HZ/2, rom.name);
Tom Ross2882b262007-02-06 21:41:08 +0000348
349 snprintf(saveprefix, 499, "%s/%s", savedir, rom.name);
Jens Arnold384de102005-03-02 23:49:38 +0000350
Tom Ross2882b262007-02-06 21:41:08 +0000351 strcpy(sramfile, saveprefix);
352 strcat(sramfile, ".sav");
Jens Arnold384de102005-03-02 23:49:38 +0000353
Tom Ross2882b262007-02-06 21:41:08 +0000354 strcpy(rtcfile, saveprefix);
355 strcat(rtcfile, ".rtc");
356
357 sram_load();
358 rtc_load();
Jens Arnold384de102005-03-02 23:49:38 +0000359}