@@ -78,19 +78,25 @@ uint32 genieaddr[3];
7878
7979CartInfo *currCartInfo;
8080
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) {
8286 uint32 AB = A >> 11 ;
8387 int x;
8488
8589 if (p)
8690 for (x = (s >> 1 ) - 1 ; x >= 0 ; x--) {
8791 PRGIsRAM[AB + x] = ram;
8892 Page[AB + x] = p - A;
93+ PRGBankMapping[AB + x] = bank;
8994 }
9095 else
9196 for (x = (s >> 1 ) - 1 ; x >= 0 ; x--) {
9297 PRGIsRAM[AB + x] = 0 ;
9398 Page[AB + x] = 0 ;
99+ PRGBankMapping[AB + x] = bank;
94100 }
95101}
96102
@@ -104,6 +110,7 @@ void ResetCartMapping(void) {
104110 Page[x] = nothing - x * 2048 ;
105111 PRGptr[x] = CHRptr[x] = 0 ;
106112 PRGsize[x] = CHRsize[x] = 0 ;
113+ PRGBankMapping[x] = -1 ;
107114 }
108115 for (x = 0 ; x < 8 ; x++) {
109116 MMC5SPRVPage[x] = MMC5BGVPage[x] = VPageR[x] = nothing - 0x400 * x;
@@ -140,6 +147,12 @@ void SetupCartCHRMapping(int chip, uint8 *p, uint32 size, int ram) {
140147 CHRram[chip] = ram;
141148}
142149
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+
143156DECLFR (CartBR) {
144157 return Page[A >> 11 ][A];
145158}
@@ -157,9 +170,20 @@ DECLFR(CartBROB) {
157170 return Page[A >> 11 ][A];
158171}
159172
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+
160183void setprg2r (int r, uint32 A, uint32 V) {
161184 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);
163187}
164188
165189void setprg2 (uint32 A, uint32 V) {
@@ -168,22 +192,24 @@ void setprg2(uint32 A, uint32 V) {
168192
169193void setprg4r (int r, uint32 A, uint32 V) {
170194 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);
172197}
173198
174199void setprg4 (uint32 A, uint32 V) {
175200 setprg4r (0 , A, V);
176201}
177202
178203void setprg8r (int r, uint32 A, uint32 V) {
204+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 13 ) + (V & PRGmask8[r])) : -1 ;
179205 if (PRGsize[r] >= 8192 ) {
180206 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 );
182208 } else {
183209 uint32 VA = V << 2 ;
184210 int x;
185211 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 );
187213 }
188214}
189215
@@ -192,15 +218,16 @@ void setprg8(uint32 A, uint32 V) {
192218}
193219
194220void setprg16r (int r, uint32 A, uint32 V) {
221+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 14 ) + (V & PRGmask16[r])) : -1 ;
195222 if (PRGsize[r] >= 16384 ) {
196223 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 );
198225 } else {
199226 uint32 VA = V << 3 ;
200227 int x;
201228
202229 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 );
204231 }
205232}
206233
@@ -209,15 +236,16 @@ void setprg16(uint32 A, uint32 V) {
209236}
210237
211238void setprg32r (int r, uint32 A, uint32 V) {
239+ int bank = PRGptr[r] ? (PRGOffset (r) / (1 << 15 ) + (V & PRGmask32[r])) : -1 ;
212240 if (PRGsize[r] >= 32768 ) {
213241 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 );
215243 } else {
216244 uint32 VA = V << 4 ;
217245 int x;
218246
219247 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 );
221249 }
222250}
223251
0 commit comments