Page[] mappings in mapper code, X.DB update for games with no controls
[fceu.git] / boards / mmc3.c
CommitLineData
d97315ac 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 1998 BERO
5 * Copyright (C) 2003 Xodnizel
6 * Mapper 12 code Copyright (C) 2003 CaH4e3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23/* Code for emulating iNES mappers 4,12,44,45,47,49,52,74,114,115,116,118,
24 119,148,165,205,214,215,245,249,250,254
25*/
26
27#include "mapinc.h"
28#include "mmc3.h"
29
e2d0dd92 30uint8 MMC3_cmd;
31uint8 *WRAM;
32uint8 *CHRRAM;
33uint32 CHRRAMSize;
34uint8 EXPREGS[8]; /* For bootleg games, mostly. */
d97315ac 35
e2d0dd92 36static uint8 A000B,A001B;
37static uint8 DRegBuf[8];
d97315ac 38
39#undef IRQCount
40#undef IRQLatch
41#undef IRQa
e2d0dd92 42uint8 IRQCount,IRQLatch,IRQa;
43uint8 IRQReload;
d97315ac 44
45static SFORMAT MMC3_StateRegs[]=
46{
47 {DRegBuf, 8, "REGS"},
48 {&MMC3_cmd, 1, "CMD"},
49 {&A000B, 1, "A000"},
50 {&A001B, 1, "A001"},
51 {&IRQReload, 1, "IRQR"},
52 {&IRQCount, 1, "IRQC"},
53 {&IRQLatch, 1, "IRQL"},
54 {&IRQa, 1, "IRQA"},
55 {0}
56};
57
58static int mmc3opts=0;
e2d0dd92 59static int wrams;
60static int isRevB=1;
d97315ac 61
62void (*pwrap)(uint32 A, uint8 V);
63void (*cwrap)(uint32 A, uint8 V);
64void (*mwrap)(uint8 V);
65
66void GenMMC3Power(void);
67void FixMMC3PRG(int V);
68void FixMMC3CHR(int V);
69
70void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
71
72// ----------------------------------------------------------------------
73// ------------------------- Generic MM3 Code ---------------------------
74// ----------------------------------------------------------------------
75
76void FixMMC3PRG(int V)
77{
78 if(V&0x40)
79 {
80 pwrap(0xC000,DRegBuf[6]);
81 pwrap(0x8000,~1);
82 }
83 else
84 {
85 pwrap(0x8000,DRegBuf[6]);
86 pwrap(0xC000,~1);
87 }
88 pwrap(0xA000,DRegBuf[7]);
89 pwrap(0xE000,~0);
90}
91
92void FixMMC3CHR(int V)
93{
94 int cbase=(V&0x80)<<5;
95
96 cwrap((cbase^0x000),DRegBuf[0]&(~1));
97 cwrap((cbase^0x400),DRegBuf[0]|1);
98 cwrap((cbase^0x800),DRegBuf[1]&(~1));
99 cwrap((cbase^0xC00),DRegBuf[1]|1);
100
101 cwrap(cbase^0x1000,DRegBuf[2]);
102 cwrap(cbase^0x1400,DRegBuf[3]);
103 cwrap(cbase^0x1800,DRegBuf[4]);
104 cwrap(cbase^0x1c00,DRegBuf[5]);
105}
106
107void MMC3RegReset(void)
108{
109 IRQCount=IRQLatch=IRQa=MMC3_cmd=0;
110
111 DRegBuf[0]=0;
112 DRegBuf[1]=2;
113 DRegBuf[2]=4;
114 DRegBuf[3]=5;
115 DRegBuf[4]=6;
116 DRegBuf[5]=7;
117 DRegBuf[6]=0;
118 DRegBuf[7]=1;
119
120 FixMMC3PRG(0);
121 FixMMC3CHR(0);
122}
123
124DECLFW(MMC3_CMDWrite)
125{
e2d0dd92 126// FCEU_printf("%04x:%04x\n",A,V);
d97315ac 127 switch(A&0xE001)
128 {
129 case 0x8000:
130 if((V&0x40) != (MMC3_cmd&0x40))
131 FixMMC3PRG(V);
132 if((V&0x80) != (MMC3_cmd&0x80))
133 FixMMC3CHR(V);
134 MMC3_cmd = V;
135 break;
136 case 0x8001:
137 {
138 int cbase=(MMC3_cmd&0x80)<<5;
139 DRegBuf[MMC3_cmd&0x7]=V;
140 switch(MMC3_cmd&0x07)
141 {
142 case 0: cwrap((cbase^0x000),V&(~1));
143 cwrap((cbase^0x400),V|1);
144 break;
145 case 1: cwrap((cbase^0x800),V&(~1));
146 cwrap((cbase^0xC00),V|1);
147 break;
148 case 2: cwrap(cbase^0x1000,V);
149 break;
150 case 3: cwrap(cbase^0x1400,V);
151 break;
152 case 4: cwrap(cbase^0x1800,V);
153 break;
154 case 5: cwrap(cbase^0x1C00,V);
155 break;
156 case 6:
157 if(MMC3_cmd&0x40)
158 pwrap(0xC000,V);
159 else
160 pwrap(0x8000,V);
161 break;
162 case 7:
163 pwrap(0xA000,V);
164 break;
165 }
166 }
167 break;
168 case 0xA000:
169 if(mwrap) mwrap(V&1);
170 break;
171 case 0xA001:
172 A001B=V;
e2d0dd92 173 Write_IRQFM(0x4017,0x40);
d97315ac 174 break;
175 }
176}
177
178DECLFW(MMC3_IRQWrite)
179{
e2d0dd92 180// FCEU_printf("%04x:%04x\n",A,V);
d97315ac 181 switch(A&0xE001)
182 {
183 case 0xC000:IRQLatch=V;break;
184 case 0xC001:IRQReload=1;break;
185 case 0xE000:X6502_IRQEnd(FCEU_IQEXT);IRQa=0;break;
186 case 0xE001:IRQa=1;break;
187 }
188}
189
190static void ClockMMC3Counter(void)
191{
192 int count = IRQCount;
193 if(!count || IRQReload)
194 {
195 IRQCount = IRQLatch;
196 IRQReload = 0;
197 }
198 else
199 IRQCount--;
e2d0dd92 200 if((count|isRevB) && !IRQCount)
d97315ac 201 {
202 if(IRQa)
203 {
204 X6502_IRQBegin(FCEU_IQEXT);
205 }
206 }
207}
208
209static void MMC3_hb(void)
210{
211 ClockMMC3Counter();
212}
213
214static void MMC3_hb_KickMasterHack(void)
215{
216 if(scanline==238) ClockMMC3Counter();
217 ClockMMC3Counter();
218}
219
220static void MMC3_hb_PALStarWarsHack(void)
221{
222 if(scanline==240) ClockMMC3Counter();
223 ClockMMC3Counter();
224}
225
e2d0dd92 226void GenMMC3Restore(int version)
d97315ac 227{
228 if(mwrap) mwrap(A000B&1);
229 FixMMC3PRG(MMC3_cmd);
230 FixMMC3CHR(MMC3_cmd);
231}
232
233static void GENCWRAP(uint32 A, uint8 V)
234{
e2d0dd92 235 if(!UNIFchrrama) setchr1(A,V);
d97315ac 236}
237
238static void GENPWRAP(uint32 A, uint8 V)
239{
240 setprg8(A,V&0x3F);
241}
242
243static void GENMWRAP(uint8 V)
244{
245 A000B=V;
246 setmirror(V^1);
247}
248
249static void GENNOMWRAP(uint8 V)
250{
251 A000B=V;
252}
253
254static DECLFW(MBWRAM)
255{
256 WRAM[A-0x6000]=V;
257}
258
259static DECLFR(MAWRAM)
260{
261 return(WRAM[A-0x6000]);
262}
263
264static DECLFW(MBWRAMMMC6)
265{
266 WRAM[A&0x3ff]=V;
267}
268
269static DECLFR(MAWRAMMMC6)
270{
271 return(WRAM[A&0x3ff]);
272}
273
274void GenMMC3Power(void)
275{
e2d0dd92 276 if(UNIFchrrama) setchr8(0);
277
d97315ac 278 SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
279 SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
280 SetReadHandler(0x8000,0xFFFF,CartBR);
281 A001B=A000B=0;
282 setmirror(1);
283 if(mmc3opts&1)
284 {
285 if(wrams==1024)
286 {
287 FCEU_CheatAddRAM(1,0x7000,WRAM);
288 SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
289 SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
e7f52878 290#ifdef ASM_6502
291 // asm code needs pages to be set again..
292 Page[14]=Page[15]=WRAM-0x7000;
293#endif
d97315ac 294 }
295 else
296 {
297 FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
298 SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
299 SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
e7f52878 300#ifdef ASM_6502
301 {
302 int addr;
303 for (addr=0x6000; addr < 0x6000+wrams-0x7ff; addr += 0x800)
304 {
305 Page[addr>>11]=WRAM - 0x6000;
306 }
307 }
308#endif
d97315ac 309 }
310 if(!(mmc3opts&2))
311 FCEU_dwmemset(WRAM,0,wrams);
312 }
313 MMC3RegReset();
314 if(CHRRAM)
315 FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
316}
317
318static void GenMMC3Close(void)
319{
320 if(CHRRAM)
321 FCEU_gfree(CHRRAM);
322 if(WRAM)
323 FCEU_gfree(WRAM);
324 CHRRAM=WRAM=NULL;
325}
326
e2d0dd92 327//static uint16 _a12;
328//static void FP_FASTAPASS(1) MMC3_PPU(uint32 A)
329//{
330// if(A&0x2000)return;
331// if((!_a12)&&(A&0x1000))
332// ClockMMC3Counter();
333// _a12=A&0x1000;
334//}
335
d97315ac 336void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
337{
e2d0dd92 338 pwrap=GENPWRAP;
d97315ac 339 cwrap=GENCWRAP;
340 mwrap=GENMWRAP;
341
342 wrams=wram<<10;
343
344 PRGmask8[0]&=(prg>>13)-1;
345 CHRmask1[0]&=(chr>>10)-1;
346 CHRmask2[0]&=(chr>>11)-1;
347
348 if(wram)
349 {
350 mmc3opts|=1;
351 WRAM=(uint8*)FCEU_gmalloc(wrams);
352 AddExState(WRAM, wrams, 0, "WRAM");
353 }
354
355 if(battery)
356 {
357 mmc3opts|=2;
358 info->SaveGame[0]=WRAM;
359 info->SaveGameLen[0]=wrams;
360 }
361
e2d0dd92 362// if(!chr) // duplicated CHR RAM set up
363// {
364// CHRRAM=(uint8*)FCEU_gmalloc(8192);
365// CHRRAMSize=8192;
366// SetupCartCHRMapping(0, CHRRAM, 8192, 1);
367// AddExState(CHRRAM, 8192, 0, "CHRR");
368// }
d97315ac 369
370 AddExState(MMC3_StateRegs, ~0, 0, 0);
371
372 info->Power=GenMMC3Power;
373 info->Reset=MMC3RegReset;
374 info->Close=GenMMC3Close;
375
376 if(info->CRC32 == 0x5104833e) // Kick Master
377 GameHBIRQHook = MMC3_hb_KickMasterHack;
378 else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
379 GameHBIRQHook = MMC3_hb_KickMasterHack;
380 else if(info->CRC32 == 0xfcd772eb) // PAL Star Wars, similar problem as Kick Master.
381 GameHBIRQHook = MMC3_hb_PALStarWarsHack;
382 else
e2d0dd92 383 GameHBIRQHook=MMC3_hb;
384// PPU_hook=MMC3_PPU;
385 GameStateRestore=GenMMC3Restore;
d97315ac 386}
387
388// ----------------------------------------------------------------------
389// -------------------------- MMC3 Based Code ---------------------------
390// ----------------------------------------------------------------------
391
392// ---------------------------- Mapper 4 --------------------------------
393
394static int hackm4=0;/* For Karnov, maybe others. BLAH. Stupid iNES format.*/
395
396static void M4Power(void)
397{
398 GenMMC3Power();
399 A000B=(hackm4^1)&1;
400 setmirror(hackm4);
401}
402
403void Mapper4_Init(CartInfo *info)
404{
405 int ws=8;
406
407 if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
408 {
409 FCEU_printf("Low-G-Man can not work normally in the iNES format.\nThis game has been recognized by its CRC32 value, and the appropriate changes will be made so it will run.\nIf you wish to hack this game, you should use the UNIF format for your hack.\n\n");
410 ws=0;
411 }
412 GenMMC3_Init(info,512,256,ws,info->battery);
413 info->Power=M4Power;
414 hackm4=info->mirror;
415}
416
417// ---------------------------- Mapper 12 -------------------------------
418
419static void M12CW(uint32 A, uint8 V)
420{
421 setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
422}
423
424static DECLFW(M12Write)
425{
426 EXPREGS[0]=V&0x01;
427 EXPREGS[1]=(V&0x10)>>4;
428}
429
430static void M12Power(void)
431{
432 EXPREGS[0]=EXPREGS[1]=0;
433 GenMMC3Power();
434 SetWriteHandler(0x4100,0x5FFF,M12Write);
435}
436
437void Mapper12_Init(CartInfo *info)
438{
439 GenMMC3_Init(info, 512, 256, 8, info->battery);
440 cwrap=M12CW;
441 info->Power=M12Power;
442 AddExState(EXPREGS, 2, 0, "EXPR");
443}
444
e2d0dd92 445// ---------------------------- Mapper 37 -------------------------------
446
447static void M37PW(uint32 A, uint8 V)
448{
449 if(EXPREGS[0]!=2)
450 V&=0x7;
451 else
452 V&=0xF;
453 V|=EXPREGS[0]<<3;
454 setprg8(A,V);
455}
456
457static void M37CW(uint32 A, uint8 V)
458{
459 uint32 NV=V;
460 NV&=0x7F;
461 NV|=EXPREGS[0]<<6;
462 setchr1(A,NV);
463}
464
465static DECLFW(M37Write)
466{
467 EXPREGS[0]=(V&6)>>1;
468 FixMMC3PRG(MMC3_cmd);
469 FixMMC3CHR(MMC3_cmd);
470}
471
472static void M37Reset(void)
473{
474 EXPREGS[0]=0;
475 MMC3RegReset();
476}
477
478static void M37Power(void)
479{
480 EXPREGS[0]=0;
481 GenMMC3Power();
482 SetWriteHandler(0x6000,0x7FFF,M37Write);
483}
484
485void Mapper37_Init(CartInfo *info)
486{
487 GenMMC3_Init(info, 512, 256, 8, info->battery);
488 pwrap=M37PW;
489 cwrap=M37CW;
490 info->Power=M37Power;
491 info->Reset=M37Reset;
492 AddExState(EXPREGS, 1, 0, "EXPR");
493}
494
d97315ac 495// ---------------------------- Mapper 44 -------------------------------
496
497static void M44PW(uint32 A, uint8 V)
498{
499 uint32 NV=V;
500 if(EXPREGS[0]>=6) NV&=0x1F;
501 else NV&=0x0F;
502 NV|=EXPREGS[0]<<4;
503 setprg8(A,NV);
504}
505
506static void M44CW(uint32 A, uint8 V)
507{
508 uint32 NV=V;
509 if(EXPREGS[0]<6) NV&=0x7F;
510 NV|=EXPREGS[0]<<7;
511 setchr1(A,NV);
512}
513
514static DECLFW(M44Write)
515{
516 if(A&1)
517 {
518 EXPREGS[0]=V&7;
519 FixMMC3PRG(MMC3_cmd);
520 FixMMC3CHR(MMC3_cmd);
521 }
522 else
523 MMC3_CMDWrite(A,V);
524}
525
526static void M44Power(void)
527{
528 EXPREGS[0]=0;
529 GenMMC3Power();
530 SetWriteHandler(0xA000,0xBFFF,M44Write);
531}
532
533void Mapper44_Init(CartInfo *info)
534{
535 GenMMC3_Init(info, 512, 256, 8, info->battery);
536 cwrap=M44CW;
537 pwrap=M44PW;
538 info->Power=M44Power;
539 AddExState(EXPREGS, 1, 0, "EXPR");
540}
541
542// ---------------------------- Mapper 45 -------------------------------
543
544static void M45CW(uint32 A, uint8 V)
545{
e2d0dd92 546 if(!UNIFchrrama)
547 {
548 uint32 NV=V;
549 if(EXPREGS[2]&8)
550 NV&=(1<<((EXPREGS[2]&7)+1))-1;
551// else
552// NV&=0;
553 NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
554 setchr1(A,NV);
555 }
d97315ac 556}
557
558static void M45PW(uint32 A, uint8 V)
559{
560 V&=(EXPREGS[3]&0x3F)^0x3F;
561 V|=EXPREGS[1];
562 setprg8(A,V);
563}
564
565static DECLFW(M45Write)
566{
567 if(EXPREGS[3]&0x40)
568 {
569 WRAM[A-0x6000]=V;
570 return;
571 }
572 EXPREGS[EXPREGS[4]]=V;
573 EXPREGS[4]=(EXPREGS[4]+1)&3;
e7f52878 574 if(!EXPREGS[4])
e2d0dd92 575 {
576 FCEU_printf("CHROR %02x, PRGOR %02x, CHRAND %02x, PRGAND %02x\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3]);
577 FCEU_printf("CHR0 %03x, CHR1 %03x, PRG0 %03x, PRG1 %03x\n",
578 (0x00&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
579 (0xFF&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
580 (0x00&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]),
581 (0xFF&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]));
582 }
d97315ac 583 FixMMC3PRG(MMC3_cmd);
584 FixMMC3CHR(MMC3_cmd);
585}
586
587static void M45Reset(void)
588{
e2d0dd92 589 EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
d97315ac 590 MMC3RegReset();
591}
592
593static void M45Power(void)
594{
e2d0dd92 595 setchr8(0);
d97315ac 596 GenMMC3Power();
597 SetWriteHandler(0x6000,0x7FFF,M45Write);
598}
599
600void Mapper45_Init(CartInfo *info)
601{
602 GenMMC3_Init(info, 512, 256, 8, info->battery);
603 cwrap=M45CW;
604 pwrap=M45PW;
605 info->Reset=M45Reset;
606 info->Power=M45Power;
607 AddExState(EXPREGS, 5, 0, "EXPR");
608}
609
610// ---------------------------- Mapper 47 -------------------------------
611
612static void M47PW(uint32 A, uint8 V)
613{
614 V&=0xF;
615 V|=EXPREGS[0]<<4;
616 setprg8(A,V);
617}
618
619static void M47CW(uint32 A, uint8 V)
620{
621 uint32 NV=V;
622 NV&=0x7F;
623 NV|=EXPREGS[0]<<7;
624 setchr1(A,NV);
625}
626
627static DECLFW(M47Write)
628{
629 EXPREGS[0]=V&1;
630 FixMMC3PRG(MMC3_cmd);
631 FixMMC3CHR(MMC3_cmd);
632}
633
634static void M47Power(void)
635{
636 EXPREGS[0]=0;
637 GenMMC3Power();
638 SetWriteHandler(0x6000,0x7FFF,M47Write);
e2d0dd92 639// SetReadHandler(0x6000,0x7FFF,0);
d97315ac 640}
641
642void Mapper47_Init(CartInfo *info)
643{
644 GenMMC3_Init(info, 512, 256, 8, info->battery);
645 pwrap=M47PW;
646 cwrap=M47CW;
647 info->Power=M47Power;
648 AddExState(EXPREGS, 1, 0, "EXPR");
649}
650
651// ---------------------------- Mapper 49 -------------------------------
652
653static void M49PW(uint32 A, uint8 V)
654{
655 if(EXPREGS[0]&1)
656 {
657 V&=0xF;
658 V|=(EXPREGS[0]&0xC0)>>2;
659 setprg8(A,V);
660 }
661 else
662 setprg32(0x8000,(EXPREGS[0]>>4)&3);
663}
664
665static void M49CW(uint32 A, uint8 V)
666{
667 uint32 NV=V;
668 NV&=0x7F;
669 NV|=(EXPREGS[0]&0xC0)<<1;
670 setchr1(A,NV);
671}
672
673static DECLFW(M49Write)
674{
675 if(A001B&0x80)
676 {
677 EXPREGS[0]=V;
678 FixMMC3PRG(MMC3_cmd);
679 FixMMC3CHR(MMC3_cmd);
680 }
681}
682
683static void M49Reset(void)
684{
685 EXPREGS[0]=0;
686 MMC3RegReset();
687}
688
689static void M49Power(void)
690{
691 M49Reset();
692 GenMMC3Power();
693 SetWriteHandler(0x6000,0x7FFF,M49Write);
694 SetReadHandler(0x6000,0x7FFF,0);
695}
696
697void Mapper49_Init(CartInfo *info)
698{
699 GenMMC3_Init(info, 512, 256, 0, 0);
700 cwrap=M49CW;
701 pwrap=M49PW;
702 info->Reset=M49Reset;
703 info->Power=M49Power;
704 AddExState(EXPREGS, 1, 0, "EXPR");
705}
706
707// ---------------------------- Mapper 52 -------------------------------
708
709static void M52PW(uint32 A, uint8 V)
710{
711 uint32 NV=V;
712 NV&=0x1F^((EXPREGS[0]&8)<<1);
713 NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
714 setprg8(A,NV);
715}
716
717static void M52CW(uint32 A, uint8 V)
718{
719 uint32 NV=V;
720 NV&=0xFF^((EXPREGS[0]&0x40)<<1);
721 NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
722 setchr1(A,NV);
723}
724
725static DECLFW(M52Write)
726{
727 if(EXPREGS[1])
728 {
729 WRAM[A-0x6000]=V;
730 return;
731 }
732 EXPREGS[1]=1;
733 EXPREGS[0]=V;
734 FixMMC3PRG(MMC3_cmd);
735 FixMMC3CHR(MMC3_cmd);
736}
737
738static void M52Reset(void)
739{
740 EXPREGS[0]=EXPREGS[1]=0;
741 MMC3RegReset();
742}
743
744static void M52Power(void)
745{
746 M52Reset();
747 GenMMC3Power();
748 SetWriteHandler(0x6000,0x7FFF,M52Write);
749}
750
751void Mapper52_Init(CartInfo *info)
752{
753 GenMMC3_Init(info, 512, 256, 8, info->battery);
754 cwrap=M52CW;
755 pwrap=M52PW;
756 info->Reset=M52Reset;
757 info->Power=M52Power;
758 AddExState(EXPREGS, 2, 0, "EXPR");
759}
760
761// ---------------------------- Mapper 74 -------------------------------
762
763static void M74CW(uint32 A, uint8 V)
764{
e2d0dd92 765 if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
766 setchr1r(0x10,A,V);
d97315ac 767 else
e2d0dd92 768 setchr1r(0,A,V);
d97315ac 769}
770
771void Mapper74_Init(CartInfo *info)
772{
773 GenMMC3_Init(info, 512, 256, 8, info->battery);
774 cwrap=M74CW;
e2d0dd92 775 CHRRAMSize=2048;
d97315ac 776 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
777 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
778 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
779}
780
781// ---------------------------- Mapper 114 ------------------------------
782
783static uint8 cmdin;
784uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
785
786static void M114PWRAP(uint32 A, uint8 V)
787{
788 if(EXPREGS[0]&0x80)
789 {
790 setprg16(0x8000,EXPREGS[0]&0xF);
791 setprg16(0xC000,EXPREGS[0]&0xF);
792 }
793 else
794 setprg8(A,V&0x3F);
795}
796
797static DECLFW(M114Write)
798{
799 if(A==0xE003)
800 {
801 IRQa=1;
e2d0dd92 802 IRQLatch=V;
803 IRQReload=1;
d97315ac 804 }
805 else if(A==0xE002)
806 {
807 IRQa=0;
808 X6502_IRQEnd(FCEU_IQEXT);
809 }
810 else switch(A&0xE000)
811 {
812 case 0x8000: setmirror((V&1)^1); break;
813 case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
814 case 0xC000: if(!cmdin) break;
815 MMC3_CMDWrite(0x8001,V);
816 cmdin=0;
817 break;
818 }
819}
820
821static DECLFW(M114ExWrite)
822{
823 if(A<=0x7FFF)
824 {
825 EXPREGS[0]=V;
826 FixMMC3PRG(MMC3_cmd);
827 }
828}
829
830static void M114Power(void)
831{
832 GenMMC3Power();
833 SetWriteHandler(0x8000,0xFFFF,M114Write);
834 SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
835}
836
837static void M114Reset(void)
838{
839 EXPREGS[0]=0;
840 MMC3RegReset();
841}
842
843void Mapper114_Init(CartInfo *info)
844{
845 GenMMC3_Init(info, 256, 256, 0, 0);
846 pwrap=M114PWRAP;
847 info->Power=M114Power;
848 info->Reset=M114Reset;
849 AddExState(EXPREGS, 1, 0, "EXPR");
850 AddExState(&cmdin, 1, 0, "CMDIN");
851}
852
853// ---------------------------- Mapper 115 ------------------------------
854
855static void M115PW(uint32 A, uint8 V)
856{
e2d0dd92 857 if(EXPREGS[0]&0x80)
858 setprg32(0x8000,(EXPREGS[0]&7)>>1);
859 else
860 setprg8(A,V);
d97315ac 861}
862
863static void M115CW(uint32 A, uint8 V)
864{
e2d0dd92 865 setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
d97315ac 866}
867
868static DECLFW(M115Write)
869{
870 if(A==0x6000)
871 EXPREGS[0]=V;
872 else if(A==0x6001)
873 EXPREGS[1]=V;
874 FixMMC3PRG(MMC3_cmd);
875}
876
877static void M115Power(void)
878{
879 GenMMC3Power();
880 SetWriteHandler(0x4100,0x7FFF,M115Write);
881 SetReadHandler(0x4100,0x7FFF,0);
882}
883
884void Mapper115_Init(CartInfo *info)
885{
886 GenMMC3_Init(info, 128, 512, 0, 0);
887 cwrap=M115CW;
888 pwrap=M115PW;
889 info->Power=M115Power;
890 AddExState(EXPREGS, 2, 0, "EXPR");
891}
892
893// ---------------------------- Mapper 116 ------------------------------
894
895static void M116CW(uint32 A, uint8 V)
896{
e2d0dd92 897// setchr1(A,V|((EXPREGS[0]&0x4)<<6));
898 if(EXPREGS[0]&2)
899 setchr8r(0x10,0);
900 else
901 setchr1(A,V);
d97315ac 902}
903
904static DECLFW(M116Write)
905{
906 EXPREGS[0]=V;
d97315ac 907 FixMMC3CHR(MMC3_cmd);
908}
909
910static void M116Power(void)
911{
912 GenMMC3Power();
913 SetWriteHandler(0x4100,0x4100,M116Write);
914}
915
916void Mapper116_Init(CartInfo *info)
917{
918 GenMMC3_Init(info, 128, 512, 0, 0);
919 cwrap=M116CW;
920 info->Power=M116Power;
e2d0dd92 921 CHRRAM = (uint8*)FCEU_gmalloc(8192);
922 SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
d97315ac 923 AddExState(EXPREGS, 4, 0, "EXPR");
924}
925
926// ---------------------------- Mapper 118 ------------------------------
927
928static uint8 PPUCHRBus;
929static uint8 TKSMIR[8];
930
931static void FP_FASTAPASS(1) TKSPPU(uint32 A)
932{
933 A&=0x1FFF;
934 A>>=10;
935 PPUCHRBus=A;
936 setmirror(MI_0+TKSMIR[A]);
937}
938
939static void TKSWRAP(uint32 A, uint8 V)
940{
941 TKSMIR[A>>10]=V>>7;
942 setchr1(A,V&0x7F);
943 if(PPUCHRBus==(A>>10))
944 setmirror(MI_0+(V>>7));
945}
946
947void Mapper118_Init(CartInfo *info)
948{
949 GenMMC3_Init(info, 512, 256, 8, info->battery);
950 cwrap=TKSWRAP;
951 mwrap=GENNOMWRAP;
952 PPU_hook=TKSPPU;
953 AddExState(&PPUCHRBus, 1, 0, "PPUC");
954}
955
956// ---------------------------- Mapper 119 ------------------------------
957
958static void TQWRAP(uint32 A, uint8 V)
959{
960 setchr1r((V&0x40)>>2,A,V&0x3F);
961}
962
963void Mapper119_Init(CartInfo *info)
964{
965 GenMMC3_Init(info, 512, 64, 0, 0);
966 cwrap=TQWRAP;
967 CHRRAMSize=8192;
968 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
969 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
970}
971
d97315ac 972// ---------------------------- Mapper 165 ------------------------------
973
974static void M165CW(uint32 A, uint8 V)
975{
976 if(V==0)
977 setchr4r(0x10,A,0);
978 else
979 setchr4(A,V>>2);
980}
981
982static void M165PPUFD(void)
983{
984 if(EXPREGS[0]==0xFD)
985 {
986 M165CW(0x0000,DRegBuf[0]);
987 M165CW(0x1000,DRegBuf[2]);
988 }
989}
990
991static void M165PPUFE(void)
992{
993 if(EXPREGS[0]==0xFE)
994 {
995 M165CW(0x0000,DRegBuf[1]);
996 M165CW(0x1000,DRegBuf[4]);
997 }
998}
999
1000static void M165CWM(uint32 A, uint8 V)
1001{
e2d0dd92 1002 if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2))
1003 M165PPUFD();
1004 if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4))
1005 M165PPUFE();
d97315ac 1006}
1007
1008static void FP_FASTAPASS(1) M165PPU(uint32 A)
1009{
1010 if((A&0x1FF0)==0x1FD0)
1011 {
1012 EXPREGS[0]=0xFD;
1013 M165PPUFD();
1014 } else if((A&0x1FF0)==0x1FE0)
1015 {
1016 EXPREGS[0]=0xFE;
1017 M165PPUFE();
1018 }
1019}
1020
1021static void M165Power(void)
1022{
1023 EXPREGS[0]=0xFD;
1024 GenMMC3Power();
1025}
1026
1027void Mapper165_Init(CartInfo *info)
1028{
1029 GenMMC3_Init(info, 512, 128, 8, info->battery);
1030 cwrap=M165CWM;
1031 PPU_hook=M165PPU;
1032 info->Power=M165Power;
1033 CHRRAMSize = 4096;
1034 CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
1035 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1036 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1037 AddExState(EXPREGS, 4, 0, "EXPR");
1038}
1039
1040// ---------------------------- Mapper 182 ------------------------------
1041