SayoriOS 0.3.3

rom.c
1 #include "lib/stdio.h"
2 #include "rom.h"
3
4 unsigned char *bytes;
5 unsigned int mapper;
6
7 static long rom_size;
8
9 static char *carts[] = {
10 [0x00] = "ROM ONLY",
11 [0x01] = "MBC1",
12 [0x02] = "MBC1+RAM",
13 [0x03] = "MBC1+RAM+BATTERY",
14 [0x05] = "MBC2",
15 [0x06] = "MBC2+BATTERY",
16 [0x08] = "ROM+RAM",
17 [0x09] = "ROM+RAM+BATTERY",
18 [0x0B] = "MMM01",
19 [0x0C] = "MMM01+RAM",
20 [0x0D] = "MMM01+RAM+BATTERY",
21 [0x0F] = "MBC3+TIMER+BATTERY",
22 [0x10] = "MBC3+TIMER+RAM+BATTERY",
23 [0x11] = "MBC3",
24 [0x12] = "MBC3+RAM",
25 [0x13] = "MBC3+RAM+BATTERY",
26 [0x15] = "MBC4",
27 [0x16] = "MBC4+RAM",
28 [0x17] = "MBC4+RAM+BATTERY",
29 [0x19] = "MBC5",
30 [0x1A] = "MBC5+RAM",
31 [0x1B] = "MBC5+RAM+BATTERY",
32 [0x1C] = "MBC5+RUMBLE",
33 [0x1D] = "MBC5+RUMBLE+RAM",
34 [0x1E] = "MBC5+RUMBLE+RAM+BATTERY",
35 [0xFC] = "POCKET CAMERA",
36 [0xFD] = "BANDAI TAMA5",
37 [0xFE] = "HuC3",
38 [0xFF] = "HuC1+RAM+BATTERY",
39 };
40
41 static char *banks[] = {
42 " 32KiB",
43 " 64KiB",
44 "128KiB",
45 "256KiB",
46 "512KiB",
47 " 1MiB",
48 " 2MiB",
49 " 4MiB",
50 /* 0x52 */
51 "1.1MiB",
52 "1.2MiB",
53 "1.5MiB",
54 "Unknown"
55 };
56
57 static const int bank_sizes[] = {
58 32*1024,
59 64*1024,
60 128*1024,
61 256*1024,
62 512*1024,
63 1024*1024,
64 2048*1024,
65 4096*1024,
66 1152*1024,
67 1280*1024,
68 1536*1024
69 };
70
71 static char *rams[] = {
72 "None",
73 " 2KiB",
74 " 8KiB",
75 " 32KiB",
76 "Unknown"
77 };
78
79 static char *regions[] = {
80 "Japan",
81 "Non-Japan",
82 "Unknown"
83 };
84
85 static unsigned char header[] = {
86 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B,
87 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D,
88 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E,
89 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99,
90 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC,
91 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E
92 };
93
94 static int rom_init(unsigned char *rombytes, size_t filesize)
95 {
96 char buf[17] = {0};
97 int type, bank_index, ram, region, version, i, pass;
98 unsigned char checksum = 0;
99
100 if(memcmp((const char*)&rombytes[0x104], (const char*)header, sizeof(header)) != 0)
101 return 0;
102
103 memcpy(buf, &rombytes[0x134], 16);
104 buf[16] = '\0';
105 printf("Rom title: %s\n", buf);
106
107 type = (int)rombytes[0x147];
108
109 printf("Cartridge type: %s (%02X)\n", carts[type], type);
110
111 bank_index = rombytes[0x148];
112 /* Adjust for the gap in the bank indicies */
113 if(bank_index >= 0x52 && bank_index <= 0x54)
114 bank_index -= 74;
115 else if(bank_index > 7)
116 bank_index = 11;
117
118 if(bank_index >= 10)
119 {
120 printf("Illegal ROM size in header\n");
121 return 0;
122 }
123
124 printf("Rom size: %s\n", banks[bank_index]);
125
126 rom_size = bank_sizes[bank_index];
127
128 if(rom_size < filesize)
129 {
130 printf("File not big enough for ROM size.\n");
131 return 0;
132 }
133
134 ram = rombytes[0x149];
135 if(ram > 3)
136 ram = 4;
137
138 printf("RAM size: %s\n", rams[ram]);
139
140 region = rombytes[0x14A];
141 if(region > 2)
142 region = 2;
143 printf("Region: %s\n", regions[region]);
144
145 version = rombytes[0x14C];
146 printf("Version: %02X\n", version);
147
148 for(i = 0x134; i <= 0x14C; i++)
149 checksum = checksum - rombytes[i] - 1;
150
151 pass = rombytes[0x14D] == checksum;
152
153 printf("Checksum: %s (%02X)\n", pass ? "OK" : "FAIL", checksum);
154 if(!pass)
155 return 0;
156
157 bytes = rombytes;
158
159 switch(type)
160 {
161 case 0x00:
162 case 0x08:
163 case 0x09:
164 mapper = NROM;
165 break;
166 case 0x01:
167 case 0x02:
168 case 0x03:
169 mapper = MBC1;
170 break;
171 case 0x05:
172 case 0x06:
173 mapper = MBC2;
174 break;
175 case 0x0B:
176 case 0x0C:
177 mapper = MMM01;
178 break;
179 case 0x0F:
180 case 0x10:
181 case 0x11:
182 case 0x12:
183 case 0x13:
184 mapper = MBC3;
185 break;
186 case 0x15:
187 case 0x16:
188 case 0x17:
189 mapper = MBC4;
190 break;
191 case 0x19:
192 case 0x1A:
193 case 0x1B:
194 case 0x1C:
195 case 0x1D:
196 case 0x1E:
197 mapper = MBC5;
198 break;
199 }
200
201 return 1;
202 }
203
204 unsigned int rom_get_mapper(void)
205 {
206 return mapper;
207 }
208
209 int rom_load(const char *filename) {
210 FILE* f;
211 unsigned char *bytes = NULL;
212 size_t rom_size = 0;
213
214 f = fopen(filename, "r");
215
216 if(!f)
217 return 0;
218
219 rom_size = fsize(f);
220
221 bytes = malloc(rom_size);
222
223 if(!bytes)
224 return 0;
225
226 fread(f, rom_size, 1, bytes);
227
228 return rom_init(bytes, rom_size);
229 }
230
231 unsigned char *rom_getbytes(void)
232 {
233 return bytes;
234 }
235
236 int rom_bank_valid(int bank)
237 {
238 if(bank * 0x4000 > rom_size)
239 return 0;
240 return 1;
241 }
filesize
size_t filesize(const char *Path)
[FileIO] Возвращает размер указанного файла
Definition: fileio.c:67
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
memcmp
int32_t memcmp(const char *s1, const char *s2, size_t n)
Сравнение массивов
Definition: string.c:305
fopen
FILE * fopen(const char *filename, const char *_mode)
Открывает файл
Definition: stdio.c:166
fsize
int fsize(FILE *stream)
Получение размера файла в байтах
Definition: stdio.c:227
fread
int fread(FILE *stream, size_t count, size_t size, void *buffer)
Чтение файла
Definition: stdio.c:250
FILE
Структура файла. Требуется для работы с VFS.
Definition: stdio.h:21