1 #include "rockmacros.h"
11 /* From http://www.semis.demon.co.uk/Gameboy/Gbspec.txt (4/17/2007)
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
29 static const int mbc_table
[256] =
46 MBC_MBC3
| MBC_BAT
| MBC_RTC
,
47 MBC_MBC3
| MBC_BAT
| MBC_RTC
,
63 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,
66 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,
71 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,
76 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,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 static const unsigned short romsize_table
[56] =
86 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! */
96 /* Ram size should be no larger then 16 banks 1Mbit */
97 static const unsigned char ramsize_table
[5] =
102 static const char *romfile
;
103 static char sramfile
[500];
104 static char rtcfile
[500];
105 static char saveprefix
[500];
107 static int forcebatt
, nobatt
;
110 static int memfill
= -1, memrand
= -1;
112 static void initmem(void *mem
, int size
)
117 srand(memrand
? memrand
: -6 ); /* time(0)); */
118 while(size
--) *(p
++) = rand();
120 else if (memfill
>= 0)
121 memset(p
, memfill
, size
);
124 static byte
*loadfile(int fd
, int *len
)
129 *len
=lseek(fd
,0,SEEK_END
);
130 d
=malloc((*len
)*sizeof(char)+64);
133 die("Not enough memory");
136 lseek(fd
,0,SEEK_SET
);
138 c
= read(fd
, d
, *len
);
143 static int rom_load(void)
146 byte c
, *data
, *header
;
149 fd
= open(romfile
, O_RDONLY
);
153 die("cannot open rom file %s", romfile
);
157 data
= loadfile(fd
, &len
);
161 die("Not Enough Memory");
164 header
= data
; /* no zip. = decompress(data, &len); */
166 memcpy(rom
.name
, header
+0x0134, 16);
167 if (rom
.name
[14] & 0x80) rom
.name
[14] = 0;
168 if (rom
.name
[15] & 0x80) rom
.name
[15] = 0;
172 mbc
.type
= mbc_table
[c
]&(MBC_MBC1
|MBC_MBC2
|MBC_MBC3
|MBC_MBC5
|MBC_RUMBLE
|MBC_HUC1
|MBC_HUC3
);
173 mbc
.batt
= ((mbc_table
[c
]&MBC_BAT
) && !nobatt
) || forcebatt
;
174 rtc
.batt
= mbc_table
[c
]&MBC_RTC
;
176 if(header
[0x0148]<10 || (header
[0x0148]>51 && header
[0x0148]<55))
177 mbc
.romsize
= romsize_table
[header
[0x0148]];
180 die("unknown ROM size %02X\n", header
[0x0148]);
185 mbc
.ramsize
= ramsize_table
[header
[0x0149]];
188 die("unknown SRAM size %02X\n", header
[0x0149]);
192 rlen
= 16384 * mbc
.romsize
;
193 rom
.bank
= (void *) data
; /* realloc(data, rlen); */
194 if (rlen
> len
) memset(rom
.bank
[0]+len
, 0xff, rlen
- len
);
196 /* This is the size of the ram on the cartridge
197 * See http://www.semis.demon.co.uk/Gameboy/Gbspec.txt
198 * for a full description. (8192*number of banks)
200 ram
.sbank
= malloc(8192 * mbc
.ramsize
);
201 if(ram
.sbank
==0 && mbc
.ramsize
!=0)
203 die("Not enough Memory");
207 /* ram.ibank = malloc(4096*8); */
209 initmem(ram
.sbank
, 8192 * mbc
.ramsize
);
210 initmem(ram
.ibank
, 4096 * 8);
216 hw
.cgb
= ((c
== 0x80) || (c
== 0xc0)) && !forcedmg
;
221 static int sram_load(void)
226 if (!mbc
.batt
|| !*sramfile
) return -1;
228 /* Consider sram loaded at this point, even if file doesn't exist */
231 fd
= open(sramfile
, O_RDONLY
);
232 snprintf(meow
,499,"Opening %s %d",sramfile
,fd
);
233 rb
->splash(HZ
*2, meow
);
235 snprintf(meow
,499,"Loading savedata from %s",sramfile
);
236 rb
->splash(HZ
*2, meow
);
237 read(fd
,ram
.sbank
, 8192*mbc
.ramsize
);
244 static int sram_save(void)
249 /* If we crash before we ever loaded sram, DO NOT SAVE! */
250 if (!mbc
.batt
|| !ram
.loaded
|| !mbc
.ramsize
)
252 fd
= open(sramfile
, O_WRONLY
|O_CREAT
|O_TRUNC
);
254 snprintf(meow
,499,"Saving savedata to %s",sramfile
);
255 rb
->splash(HZ
*2, meow
);
256 write(fd
,ram
.sbank
, 8192*mbc
.ramsize
);
262 static void rtc_save(void)
265 if (!rtc
.batt
) return;
266 if ((fd
= open(rtcfile
, O_WRONLY
|O_CREAT
|O_TRUNC
))<0) return;
267 rtc_save_internal(fd
);
271 static void rtc_load(void)
274 if (!rtc
.batt
) return;
275 if ((fd
= open(rtcfile
, O_RDONLY
))<0) return;
276 rtc_load_internal(fd
);
284 /* IDEA - if error, write emergency savestate..? */
287 void loader_init(const char *s
)
292 rb
->splash(HZ
/2, rom
.name
);
294 snprintf(saveprefix
, 499, "%s/%s", savedir
, rom
.name
);
296 strcpy(sramfile
, saveprefix
);
297 strcat(sramfile
, ".sav");
299 strcpy(rtcfile
, saveprefix
);
300 strcat(rtcfile
, ".rtc");