Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/gameboy/cartridge.hpp
2 views
1
#ifndef NALL_GAMEBOY_CARTRIDGE_HPP
2
#define NALL_GAMEBOY_CARTRIDGE_HPP
3
4
namespace nall {
5
6
class GameBoyCartridge {
7
public:
8
string markup;
9
inline GameBoyCartridge(uint8_t *data, unsigned size);
10
11
//private:
12
struct Information {
13
string mapper;
14
bool ram;
15
bool battery;
16
bool rtc;
17
bool rumble;
18
19
unsigned romsize;
20
unsigned ramsize;
21
} info;
22
};
23
24
GameBoyCartridge::GameBoyCartridge(uint8_t *romdata, unsigned romsize) {
25
markup = "";
26
if(romsize < 0x4000) return;
27
28
info.mapper = "unknown";
29
info.ram = false;
30
info.battery = false;
31
info.rtc = false;
32
info.rumble = false;
33
34
info.romsize = 0;
35
info.ramsize = 0;
36
37
unsigned base = romsize - 0x8000;
38
if(romdata[base + 0x0104] == 0xce && romdata[base + 0x0105] == 0xed
39
&& romdata[base + 0x0106] == 0x66 && romdata[base + 0x0107] == 0x66
40
&& romdata[base + 0x0108] == 0xcc && romdata[base + 0x0109] == 0x0d
41
&& romdata[base + 0x0147] >= 0x0b && romdata[base + 0x0147] <= 0x0d
42
) {
43
//MMM01 stores header at bottom of image
44
//flip this around for consistency with all other mappers
45
uint8_t header[0x8000];
46
memcpy(header, romdata + base, 0x8000);
47
memmove(romdata + 0x8000, romdata, romsize - 0x8000);
48
memcpy(romdata, header, 0x8000);
49
}
50
51
switch(romdata[0x0147]) {
52
case 0x00: info.mapper = "none"; break;
53
case 0x01: info.mapper = "MBC1"; break;
54
case 0x02: info.mapper = "MBC1"; info.ram = true; break;
55
case 0x03: info.mapper = "MBC1"; info.ram = true; info.battery = true; break;
56
case 0x05: info.mapper = "MBC2"; info.ram = true; break;
57
case 0x06: info.mapper = "MBC2"; info.ram = true; info.battery = true; break;
58
case 0x08: info.mapper = "none"; info.ram = true; break;
59
case 0x09: info.mapper = "MBC0"; info.ram = true; info.battery = true; break;
60
case 0x0b: info.mapper = "MMM01"; break;
61
case 0x0c: info.mapper = "MMM01"; info.ram = true; break;
62
case 0x0d: info.mapper = "MMM01"; info.ram = true; info.battery = true; break;
63
case 0x0f: info.mapper = "MBC3"; info.rtc = true; info.battery = true; break;
64
case 0x10: info.mapper = "MBC3"; info.rtc = true; info.ram = true; info.battery = true; break;
65
case 0x11: info.mapper = "MBC3"; break;
66
case 0x12: info.mapper = "MBC3"; info.ram = true; break;
67
case 0x13: info.mapper = "MBC3"; info.ram = true; info.battery = true; break;
68
case 0x19: info.mapper = "MBC5"; break;
69
case 0x1a: info.mapper = "MBC5"; info.ram = true; break;
70
case 0x1b: info.mapper = "MBC5"; info.ram = true; info.battery = true; break;
71
case 0x1c: info.mapper = "MBC5"; info.rumble = true; break;
72
case 0x1d: info.mapper = "MBC5"; info.rumble = true; info.ram = true; break;
73
case 0x1e: info.mapper = "MBC5"; info.rumble = true; info.ram = true; info.battery = true; break;
74
case 0xfc: break; //Pocket Camera
75
case 0xfd: break; //Bandai TAMA5
76
case 0xfe: info.mapper = "HuC3"; break;
77
case 0xff: info.mapper = "HuC1"; info.ram = true; info.battery = true; break;
78
}
79
80
switch(romdata[0x0148]) { default:
81
case 0x00: info.romsize = 2 * 16 * 1024; break;
82
case 0x01: info.romsize = 4 * 16 * 1024; break;
83
case 0x02: info.romsize = 8 * 16 * 1024; break;
84
case 0x03: info.romsize = 16 * 16 * 1024; break;
85
case 0x04: info.romsize = 32 * 16 * 1024; break;
86
case 0x05: info.romsize = 64 * 16 * 1024; break;
87
case 0x06: info.romsize = 128 * 16 * 1024; break;
88
case 0x07: info.romsize = 256 * 16 * 1024; break;
89
case 0x52: info.romsize = 72 * 16 * 1024; break;
90
case 0x53: info.romsize = 80 * 16 * 1024; break;
91
case 0x54: info.romsize = 96 * 16 * 1024; break;
92
}
93
94
switch(romdata[0x0149]) { default:
95
case 0x00: info.ramsize = 0 * 1024; break;
96
case 0x01: info.ramsize = 2 * 1024; break;
97
case 0x02: info.ramsize = 8 * 1024; break;
98
case 0x03: info.ramsize = 32 * 1024; break;
99
}
100
101
if(info.mapper == "MBC2") info.ramsize = 512; //512 x 4-bit
102
103
markup.append(
104
"<?xml version='1.0' encoding='UTF-8'?>\n",
105
"<cartridge mapper='", info.mapper, "' rtc='", info.rtc, "' rumble='", info.rumble, "'>\n",
106
" <rom size='0x", hex(romsize), "'/>\n");
107
if(info.ramsize > 0) markup.append(
108
" <ram size='0x", hex(info.ramsize), "' battery='", info.battery, "'/>\n");
109
markup.append(
110
"</cartridge>\n");
111
112
/*
113
markup.append("cartridge mapper=", info.mapper);
114
if(info.rtc) markup.append(" rtc");
115
if(info.rumble) markup.append(" rumble");
116
markup.append("\n");
117
118
markup.append("\t" "rom size=", hex(romsize), "\n"); //TODO: trust/check info.romsize?
119
120
if(info.ramsize > 0)
121
markup.append("\t" "ram size=", hex(info.ramsize), info.battery ? " non-volatile\n" : "\n");
122
*/
123
}
124
125
}
126
127
#endif
128
129