@@ -78,19 +78,25 @@ uint32 genieaddr[3];
78
78
79
79
CartInfo *currCartInfo;
80
80
81
- static INLINE void setpageptr (int s, uint32 A, uint8 *p, int ram) {
81
+ // Reverse mapping of the address space back to bank numbers.
82
+ // Split into 2 KiB pages, like `Page`.
83
+ int PRGBankMapping[32 ];
84
+
85
+ static INLINE void setpageptr (int s, uint32 A, uint8 *p, int ram, int bank) {
82
86
uint32 AB = A >> 11 ;
83
87
int x;
84
88
85
89
if (p)
86
90
for (x = (s >> 1 ) - 1 ; x >= 0 ; x--) {
87
91
PRGIsRAM[AB + x] = ram;
88
92
Page[AB + x] = p - A;
93
+ PRGBankMapping[AB + x] = bank;
89
94
}
90
95
else
91
96
for (x = (s >> 1 ) - 1 ; x >= 0 ; x--) {
92
97
PRGIsRAM[AB + x] = 0 ;
93
98
Page[AB + x] = 0 ;
99
+ PRGBankMapping[AB + x] = bank;
94
100
}
95
101
}
96
102
@@ -104,6 +110,7 @@ void ResetCartMapping(void) {
104
110
Page[x] = nothing - x * 2048 ;
105
111
PRGptr[x] = CHRptr[x] = 0 ;
106
112
PRGsize[x] = CHRsize[x] = 0 ;
113
+ PRGBankMapping[x] = -1 ;
107
114
}
108
115
for (x = 0 ; x < 8 ; x++) {
109
116
MMC5SPRVPage[x] = MMC5BGVPage[x] = VPageR[x] = nothing - 0x400 * x;
@@ -140,6 +147,12 @@ void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram) {
140
147
CHRram[chip] = ram;
141
148
}
142
149
150
+ // Get the mapper-specific bank number for the given CPU address.
151
+ // Returns -1 when the page has not been mapped.
152
+ int GetPRGBank (uint16 address) {
153
+ return PRGBankMapping[address >> 11 ];
154
+ }
155
+
143
156
DECLFR (CartBR) {
144
157
return Page[A >> 11 ][A];
145
158
}
@@ -157,9 +170,20 @@ DECLFR(CartBROB) {
157
170
return Page[A >> 11 ][A];
158
171
}
159
172
173
+ // Get the cumulative size of PRG chips.
174
+ // I.e. the ROM file offset (without iNES header).
175
+ static uint32 PRGOffset (int chip) {
176
+ uint32 bank = 0 ;
177
+ for (int i = 0 ; i < chip; i ++) {
178
+ bank += PRGsize[i];
179
+ }
180
+ return bank;
181
+ }
182
+
160
183
void setprg2r (int r, uint32 A, uint32 V) {
161
184
V &= PRGmask2[r];
162
- setpageptr (2 , A, PRGptr[r] ? (&PRGptr[r][V << 11 ]) : 0 , PRGram[r]);
185
+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 11 ) + V) : -1 ;
186
+ setpageptr (2 , A, PRGptr[r] ? (&PRGptr[r][V << 11 ]) : 0 , PRGram[r], bank);
163
187
}
164
188
165
189
void setprg2 (uint32 A, uint32 V) {
@@ -168,22 +192,24 @@ void setprg2(uint32 A, uint32 V) {
168
192
169
193
void setprg4r (int r, uint32 A, uint32 V) {
170
194
V &= PRGmask4[r];
171
- setpageptr (4 , A, PRGptr[r] ? (&PRGptr[r][V << 12 ]) : 0 , PRGram[r]);
195
+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 12 ) + V) : -1 ;
196
+ setpageptr (4 , A, PRGptr[r] ? (&PRGptr[r][V << 12 ]) : 0 , PRGram[r], bank);
172
197
}
173
198
174
199
void setprg4 (uint32 A, uint32 V) {
175
200
setprg4r (0 , A, V);
176
201
}
177
202
178
203
void setprg8r (int r, uint32 A, uint32 V) {
204
+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 13 ) + (V & PRGmask8[r])) : -1 ;
179
205
if (PRGsize[r] >= 8192 ) {
180
206
V &= PRGmask8[r];
181
- setpageptr (8 , A, PRGptr[r] ? (&PRGptr[r][V << 13 ]) : 0 , PRGram[r]);
207
+ setpageptr (8 , A, PRGptr[r] ? (&PRGptr[r][V << 13 ]) : 0 , PRGram[r], bank );
182
208
} else {
183
209
uint32 VA = V << 2 ;
184
210
int x;
185
211
for (x = 0 ; x < 4 ; x++)
186
- setpageptr (2 , A + (x << 11 ), PRGptr[r] ? (&PRGptr[r][((VA + x) & PRGmask2[r]) << 11 ]) : 0 , PRGram[r]);
212
+ setpageptr (2 , A + (x << 11 ), PRGptr[r] ? (&PRGptr[r][((VA + x) & PRGmask2[r]) << 11 ]) : 0 , PRGram[r], bank );
187
213
}
188
214
}
189
215
@@ -192,15 +218,16 @@ void setprg8(uint32 A, uint32 V) {
192
218
}
193
219
194
220
void setprg16r (int r, uint32 A, uint32 V) {
221
+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 14 ) + (V & PRGmask16[r])) : -1 ;
195
222
if (PRGsize[r] >= 16384 ) {
196
223
V &= PRGmask16[r];
197
- setpageptr (16 , A, PRGptr[r] ? (&PRGptr[r][V << 14 ]) : 0 , PRGram[r]);
224
+ setpageptr (16 , A, PRGptr[r] ? (&PRGptr[r][V << 14 ]) : 0 , PRGram[r], bank );
198
225
} else {
199
226
uint32 VA = V << 3 ;
200
227
int x;
201
228
202
229
for (x = 0 ; x < 8 ; x++)
203
- setpageptr (2 , A + (x << 11 ), PRGptr[r] ? (&PRGptr[r][((VA + x) & PRGmask2[r]) << 11 ]) : 0 , PRGram[r]);
230
+ setpageptr (2 , A + (x << 11 ), PRGptr[r] ? (&PRGptr[r][((VA + x) & PRGmask2[r]) << 11 ]) : 0 , PRGram[r], bank );
204
231
}
205
232
}
206
233
@@ -209,15 +236,16 @@ void setprg16(uint32 A, uint32 V) {
209
236
}
210
237
211
238
void setprg32r (int r, uint32 A, uint32 V) {
239
+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 15 ) + (V & PRGmask32[r])) : -1 ;
212
240
if (PRGsize[r] >= 32768 ) {
213
241
V &= PRGmask32[r];
214
- setpageptr (32 , A, PRGptr[r] ? (&PRGptr[r][V << 15 ]) : 0 , PRGram[r]);
242
+ setpageptr (32 , A, PRGptr[r] ? (&PRGptr[r][V << 15 ]) : 0 , PRGram[r], bank );
215
243
} else {
216
244
uint32 VA = V << 4 ;
217
245
int x;
218
246
219
247
for (x = 0 ; x < 16 ; x++)
220
- setpageptr (2 , A + (x << 11 ), PRGptr[r] ? (&PRGptr[r][((VA + x) & PRGmask2[r]) << 11 ]) : 0 , PRGram[r]);
248
+ setpageptr (2 , A + (x << 11 ), PRGptr[r] ? (&PRGptr[r][((VA + x) & PRGmask2[r]) << 11 ]) : 0 , PRGram[r], bank );
221
249
}
222
250
}
223
251
0 commit comments