1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 1998 BERO
5 * Copyright (C) 2003 Xodnizel
6 * Mapper 12 code Copyright (C) 2003 CaH4e3
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.
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.
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
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
34 uint8 EXPREGS[8]={0,0,0,0,0,0,0,0}; /* For bootleg games, mostly. */
36 static uint8 A000B=0,A001B=0;
37 static uint8 DRegBuf[8]={0,0,0,0,0,0,0,0};
42 uint8 IRQCount=0,IRQLatch=0,IRQa=0;
45 static SFORMAT MMC3_StateRegs[]=
48 {&MMC3_cmd, 1, "CMD"},
51 {&IRQReload, 1, "IRQR"},
52 {&IRQCount, 1, "IRQC"},
53 {&IRQLatch, 1, "IRQL"},
58 static int mmc3opts=0;
61 void (*pwrap)(uint32 A, uint8 V);
62 void (*cwrap)(uint32 A, uint8 V);
63 void (*mwrap)(uint8 V);
65 void GenMMC3Power(void);
66 void FixMMC3PRG(int V);
67 void FixMMC3CHR(int V);
69 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
71 // ----------------------------------------------------------------------
72 // ------------------------- Generic MM3 Code ---------------------------
73 // ----------------------------------------------------------------------
75 void FixMMC3PRG(int V)
79 pwrap(0xC000,DRegBuf[6]);
84 pwrap(0x8000,DRegBuf[6]);
87 pwrap(0xA000,DRegBuf[7]);
91 void FixMMC3CHR(int V)
93 int cbase=(V&0x80)<<5;
95 cwrap((cbase^0x000),DRegBuf[0]&(~1));
96 cwrap((cbase^0x400),DRegBuf[0]|1);
97 cwrap((cbase^0x800),DRegBuf[1]&(~1));
98 cwrap((cbase^0xC00),DRegBuf[1]|1);
100 cwrap(cbase^0x1000,DRegBuf[2]);
101 cwrap(cbase^0x1400,DRegBuf[3]);
102 cwrap(cbase^0x1800,DRegBuf[4]);
103 cwrap(cbase^0x1c00,DRegBuf[5]);
106 void MMC3RegReset(void)
108 IRQCount=IRQLatch=IRQa=MMC3_cmd=0;
123 DECLFW(MMC3_CMDWrite)
128 if((V&0x40) != (MMC3_cmd&0x40))
130 if((V&0x80) != (MMC3_cmd&0x80))
136 int cbase=(MMC3_cmd&0x80)<<5;
137 DRegBuf[MMC3_cmd&0x7]=V;
138 switch(MMC3_cmd&0x07)
140 case 0: cwrap((cbase^0x000),V&(~1));
141 cwrap((cbase^0x400),V|1);
143 case 1: cwrap((cbase^0x800),V&(~1));
144 cwrap((cbase^0xC00),V|1);
146 case 2: cwrap(cbase^0x1000,V);
148 case 3: cwrap(cbase^0x1400,V);
150 case 4: cwrap(cbase^0x1800,V);
152 case 5: cwrap(cbase^0x1C00,V);
167 if(mwrap) mwrap(V&1);
175 DECLFW(MMC3_IRQWrite)
179 case 0xC000:IRQLatch=V;break;
180 case 0xC001:IRQReload=1;break;
181 case 0xE000:X6502_IRQEnd(FCEU_IQEXT);IRQa=0;break;
182 case 0xE001:IRQa=1;break;
186 static void ClockMMC3Counter(void)
188 int count = IRQCount;
189 if(!count || IRQReload)
196 if(count && !IRQCount)
200 X6502_IRQBegin(FCEU_IQEXT);
205 static void MMC3_hb(void)
210 static void MMC3_hb_KickMasterHack(void)
212 if(scanline==238) ClockMMC3Counter();
216 static void MMC3_hb_PALStarWarsHack(void)
218 if(scanline==240) ClockMMC3Counter();
222 static void genmmc3restore(int version)
224 if(mwrap) mwrap(A000B&1);
225 FixMMC3PRG(MMC3_cmd);
226 FixMMC3CHR(MMC3_cmd);
229 static void GENCWRAP(uint32 A, uint8 V)
234 static void GENPWRAP(uint32 A, uint8 V)
239 static void GENMWRAP(uint8 V)
245 static void GENNOMWRAP(uint8 V)
250 static DECLFW(MBWRAM)
255 static DECLFR(MAWRAM)
257 return(WRAM[A-0x6000]);
260 static DECLFW(MBWRAMMMC6)
265 static DECLFR(MAWRAMMMC6)
267 return(WRAM[A&0x3ff]);
270 void GenMMC3Power(void)
272 SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
273 SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
274 SetReadHandler(0x8000,0xFFFF,CartBR);
281 FCEU_CheatAddRAM(1,0x7000,WRAM);
282 SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
283 SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
287 FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
288 SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
289 SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
292 FCEU_dwmemset(WRAM,0,wrams);
296 FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
299 static void GenMMC3Close(void)
308 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
316 PRGmask8[0]&=(prg>>13)-1;
317 CHRmask1[0]&=(chr>>10)-1;
318 CHRmask2[0]&=(chr>>11)-1;
323 WRAM=(uint8*)FCEU_gmalloc(wrams);
324 AddExState(WRAM, wrams, 0, "WRAM");
330 info->SaveGame[0]=WRAM;
331 info->SaveGameLen[0]=wrams;
336 CHRRAM=(uint8*)FCEU_gmalloc(8192);
338 SetupCartCHRMapping(0, CHRRAM, 8192, 1);
339 AddExState(CHRRAM, 8192, 0, "CHRR");
342 AddExState(MMC3_StateRegs, ~0, 0, 0);
344 info->Power=GenMMC3Power;
345 info->Reset=MMC3RegReset;
346 info->Close=GenMMC3Close;
348 if(info->CRC32 == 0x5104833e) // Kick Master
349 GameHBIRQHook = MMC3_hb_KickMasterHack;
350 else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
351 GameHBIRQHook = MMC3_hb_KickMasterHack;
352 else if(info->CRC32 == 0xfcd772eb) // PAL Star Wars, similar problem as Kick Master.
353 GameHBIRQHook = MMC3_hb_PALStarWarsHack;
355 GameHBIRQHook=MMC3_hb;
356 GameStateRestore=genmmc3restore;
359 // ----------------------------------------------------------------------
360 // -------------------------- MMC3 Based Code ---------------------------
361 // ----------------------------------------------------------------------
363 // ---------------------------- Mapper 4 --------------------------------
365 static int hackm4=0;/* For Karnov, maybe others. BLAH. Stupid iNES format.*/
367 static void M4Power(void)
374 void Mapper4_Init(CartInfo *info)
378 if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
380 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");
383 GenMMC3_Init(info,512,256,ws,info->battery);
388 // ---------------------------- Mapper 12 -------------------------------
390 static void M12CW(uint32 A, uint8 V)
392 setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
395 static DECLFW(M12Write)
398 EXPREGS[1]=(V&0x10)>>4;
401 static void M12Power(void)
403 EXPREGS[0]=EXPREGS[1]=0;
405 SetWriteHandler(0x4100,0x5FFF,M12Write);
408 void Mapper12_Init(CartInfo *info)
410 GenMMC3_Init(info, 512, 256, 8, info->battery);
412 info->Power=M12Power;
413 AddExState(EXPREGS, 2, 0, "EXPR");
416 // ---------------------------- Mapper 44 -------------------------------
418 static void M44PW(uint32 A, uint8 V)
421 if(EXPREGS[0]>=6) NV&=0x1F;
427 static void M44CW(uint32 A, uint8 V)
430 if(EXPREGS[0]<6) NV&=0x7F;
435 static DECLFW(M44Write)
440 FixMMC3PRG(MMC3_cmd);
441 FixMMC3CHR(MMC3_cmd);
447 static void M44Power(void)
451 SetWriteHandler(0xA000,0xBFFF,M44Write);
454 void Mapper44_Init(CartInfo *info)
456 GenMMC3_Init(info, 512, 256, 8, info->battery);
459 info->Power=M44Power;
460 AddExState(EXPREGS, 1, 0, "EXPR");
463 // ---------------------------- Mapper 45 -------------------------------
465 static void M45CW(uint32 A, uint8 V)
469 NV&=(1<<((EXPREGS[2]&7)+1))-1;
472 NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
473 // &0x10(not 0xf0) is valid given the original
474 // description of mapper 45 by kevtris,
475 // but this fixes Super 8 in 1.
479 static void M45PW(uint32 A, uint8 V)
481 V&=(EXPREGS[3]&0x3F)^0x3F;
486 static DECLFW(M45Write)
493 EXPREGS[EXPREGS[4]]=V;
494 EXPREGS[4]=(EXPREGS[4]+1)&3;
495 // FCEU_printf("write 0=%04x 1=%04x 2=%04x 3=%04x (%04x:%04x)\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3],A,V);
496 FixMMC3PRG(MMC3_cmd);
497 FixMMC3CHR(MMC3_cmd);
500 static void M45Reset(void)
502 FCEU_dwmemset(EXPREGS,0,5);
506 static void M45Power(void)
510 SetWriteHandler(0x6000,0x7FFF,M45Write);
513 void Mapper45_Init(CartInfo *info)
515 GenMMC3_Init(info, 512, 256, 8, info->battery);
518 info->Reset=M45Reset;
519 info->Power=M45Power;
520 AddExState(EXPREGS, 5, 0, "EXPR");
523 // ---------------------------- Mapper 47 -------------------------------
525 static void M47PW(uint32 A, uint8 V)
532 static void M47CW(uint32 A, uint8 V)
540 static DECLFW(M47Write)
543 FixMMC3PRG(MMC3_cmd);
544 FixMMC3CHR(MMC3_cmd);
547 static void M47Power(void)
551 SetWriteHandler(0x6000,0x7FFF,M47Write);
552 SetReadHandler(0x6000,0x7FFF,0);
555 void Mapper47_Init(CartInfo *info)
557 GenMMC3_Init(info, 512, 256, 8, info->battery);
560 info->Power=M47Power;
561 AddExState(EXPREGS, 1, 0, "EXPR");
564 // ---------------------------- Mapper 49 -------------------------------
566 static void M49PW(uint32 A, uint8 V)
571 V|=(EXPREGS[0]&0xC0)>>2;
575 setprg32(0x8000,(EXPREGS[0]>>4)&3);
578 static void M49CW(uint32 A, uint8 V)
582 NV|=(EXPREGS[0]&0xC0)<<1;
586 static DECLFW(M49Write)
591 FixMMC3PRG(MMC3_cmd);
592 FixMMC3CHR(MMC3_cmd);
596 static void M49Reset(void)
602 static void M49Power(void)
606 SetWriteHandler(0x6000,0x7FFF,M49Write);
607 SetReadHandler(0x6000,0x7FFF,0);
610 void Mapper49_Init(CartInfo *info)
612 GenMMC3_Init(info, 512, 256, 0, 0);
615 info->Reset=M49Reset;
616 info->Power=M49Power;
617 AddExState(EXPREGS, 1, 0, "EXPR");
620 // ---------------------------- Mapper 52 -------------------------------
622 static void M52PW(uint32 A, uint8 V)
625 NV&=0x1F^((EXPREGS[0]&8)<<1);
626 NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
630 static void M52CW(uint32 A, uint8 V)
633 NV&=0xFF^((EXPREGS[0]&0x40)<<1);
634 NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
638 static DECLFW(M52Write)
647 FixMMC3PRG(MMC3_cmd);
648 FixMMC3CHR(MMC3_cmd);
651 static void M52Reset(void)
653 EXPREGS[0]=EXPREGS[1]=0;
657 static void M52Power(void)
661 SetWriteHandler(0x6000,0x7FFF,M52Write);
664 void Mapper52_Init(CartInfo *info)
666 GenMMC3_Init(info, 512, 256, 8, info->battery);
669 info->Reset=M52Reset;
670 info->Power=M52Power;
671 AddExState(EXPREGS, 2, 0, "EXPR");
674 // ---------------------------- Mapper 74 -------------------------------
676 static void M74CW(uint32 A, uint8 V)
678 // FCEU_printf("%04x:%04x\n",A,V);
679 // if((V==0)||(V==1)) //Dai-2-Ji - Super Robot Taisen (As).nes
680 if((V==0)||(V==1)||(V==2)||(V==3)) //Ying Lie Qun Xia Zhuan (Chinese).nes, 4096 CHR RAM
681 // if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes
682 // if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese).nes, 4096 CHR RAM
688 void Mapper74_Init(CartInfo *info)
690 GenMMC3_Init(info, 512, 256, 8, info->battery);
694 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
695 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
696 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
699 // ---------------------------- Mapper 114 ------------------------------
702 uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
704 static void M114PWRAP(uint32 A, uint8 V)
708 setprg16(0x8000,EXPREGS[0]&0xF);
709 setprg16(0xC000,EXPREGS[0]&0xF);
715 static DECLFW(M114Write)
725 X6502_IRQEnd(FCEU_IQEXT);
727 else switch(A&0xE000)
729 case 0x8000: setmirror((V&1)^1); break;
730 case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
731 case 0xC000: if(!cmdin) break;
732 MMC3_CMDWrite(0x8001,V);
738 static DECLFW(M114ExWrite)
743 FixMMC3PRG(MMC3_cmd);
747 static void M114Power(void)
750 SetWriteHandler(0x8000,0xFFFF,M114Write);
751 SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
754 static void M114Reset(void)
760 void Mapper114_Init(CartInfo *info)
762 GenMMC3_Init(info, 256, 256, 0, 0);
764 info->Power=M114Power;
765 info->Reset=M114Reset;
766 AddExState(EXPREGS, 1, 0, "EXPR");
767 AddExState(&cmdin, 1, 0, "CMDIN");
770 // ---------------------------- Mapper 115 ------------------------------
772 static void M115PW(uint32 A, uint8 V)
776 setprg16(0x8000,EXPREGS[0]&7);
779 static void M115CW(uint32 A, uint8 V)
781 setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
784 static DECLFW(M115Write)
790 FixMMC3PRG(MMC3_cmd);
793 static void M115Power(void)
796 SetWriteHandler(0x4100,0x7FFF,M115Write);
797 SetReadHandler(0x4100,0x7FFF,0);
800 void Mapper115_Init(CartInfo *info)
802 GenMMC3_Init(info, 128, 512, 0, 0);
805 info->Power=M115Power;
806 AddExState(EXPREGS, 2, 0, "EXPR");
809 // ---------------------------- Mapper 116 ------------------------------
811 static void M116CW(uint32 A, uint8 V)
813 setchr1(A,V|((EXPREGS[0]&0x4)<<6));
816 static DECLFW(M116Write)
819 FixMMC3PRG(MMC3_cmd);
820 FixMMC3CHR(MMC3_cmd);
823 static void M116Power(void)
826 SetWriteHandler(0x4100,0x4100,M116Write);
829 void Mapper116_Init(CartInfo *info)
831 GenMMC3_Init(info, 128, 512, 0, 0);
833 info->Power=M116Power;
834 AddExState(EXPREGS, 4, 0, "EXPR");
837 // ---------------------------- Mapper 118 ------------------------------
839 static uint8 PPUCHRBus;
840 static uint8 TKSMIR[8];
842 static void FP_FASTAPASS(1) TKSPPU(uint32 A)
847 setmirror(MI_0+TKSMIR[A]);
850 static void TKSWRAP(uint32 A, uint8 V)
854 if(PPUCHRBus==(A>>10))
855 setmirror(MI_0+(V>>7));
858 void Mapper118_Init(CartInfo *info)
860 GenMMC3_Init(info, 512, 256, 8, info->battery);
864 AddExState(&PPUCHRBus, 1, 0, "PPUC");
867 // ---------------------------- Mapper 119 ------------------------------
869 static void TQWRAP(uint32 A, uint8 V)
871 setchr1r((V&0x40)>>2,A,V&0x3F);
874 void Mapper119_Init(CartInfo *info)
876 GenMMC3_Init(info, 512, 64, 0, 0);
879 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
880 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
883 // ---------------------------- Mapper 191 ------------------------------
885 static void M191CW(uint32 A, uint8 V)
887 setchr1r((V&0x80)>>3,A,V);
890 void Mapper191_Init(CartInfo *info)
892 GenMMC3_Init(info, 256, 256, 8, info->battery);
895 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
896 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
897 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
900 // ---------------------------- Mapper 165 ------------------------------
902 static void M165CW(uint32 A, uint8 V)
910 static void M165PPUFD(void)
914 M165CW(0x0000,DRegBuf[0]);
915 M165CW(0x1000,DRegBuf[2]);
919 static void M165PPUFE(void)
923 M165CW(0x0000,DRegBuf[1]);
924 M165CW(0x1000,DRegBuf[4]);
928 static void M165CWM(uint32 A, uint8 V)
930 if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2)) M165PPUFD();
931 if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4)) M165PPUFE();
934 static void FP_FASTAPASS(1) M165PPU(uint32 A)
936 if((A&0x1FF0)==0x1FD0)
940 } else if((A&0x1FF0)==0x1FE0)
947 static void M165Power(void)
953 void Mapper165_Init(CartInfo *info)
955 GenMMC3_Init(info, 512, 128, 8, info->battery);
958 info->Power=M165Power;
960 CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
961 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
962 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
963 AddExState(EXPREGS, 4, 0, "EXPR");
966 // ---------------------------- Mapper 182 ------------------------------
967 // òà áëèöà ïåðìóòà öè à Ãà ëîãè÷Ãà 114 ìà ïïåðó, ðåãèñòðû ìà ïïåðà ãîðà çäî ñëîæÃåå,
968 // ÷åì èñïîëüçóþòñÿ çäåñü, õîòÿ âñå ïðåêðà ñÃî ðà áîòà åò.
970 //static uint8 m182_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
971 static DECLFW(M182Write)
975 case 0x8001: setmirror((V&1)^1); break;
976 case 0xA000: MMC3_CMDWrite(0x8000,m114_perm[V&7]); break;
977 case 0xC000: MMC3_CMDWrite(0x8001,V); break;
978 case 0xE003: IRQCount=V; IRQa=1; X6502_IRQEnd(FCEU_IQEXT); break;
982 static void M182Power(void)
985 SetWriteHandler(0x8000,0xFFFF,M182Write);
988 void Mapper182_Init(CartInfo *info)
990 GenMMC3_Init(info, 256, 256, 0, 0);
991 info->Power=M182Power;
994 // ---------------------------- Mapper 205 ------------------------------
996 static void M205PW(uint32 A, uint8 V)
999 setprg8(A,(V&0x0f)|((EXPREGS[0]&3)<<4));
1001 setprg8(A,(V&0x1f)|((EXPREGS[0]&3)<<4));
1004 static void M205CW(uint32 A, uint8 V)
1006 setchr1(A,V|((EXPREGS[0]&3)*128));
1009 static DECLFW(M205Write)
1011 if((A&0x6800)==0x6800) EXPREGS[0]= V;
1012 FixMMC3PRG(MMC3_cmd);
1013 FixMMC3CHR(MMC3_cmd);
1016 static void M205Reset(void)
1022 static void M205Power(void)
1025 SetWriteHandler(0x4020,0x7FFF,M205Write);
1028 void Mapper205_Init(CartInfo *info)
1030 GenMMC3_Init(info, 512, 256, 8, 0);
1033 info->Power=M205Power;
1034 info->Reset=M205Reset;
1035 AddExState(EXPREGS, 1, 0, "EXPR");
1038 // ---------------------------- Mapper 215 ------------------------------
1040 static uint8 m215_perm[8] = {0, 2, 5, 3, 6, 1, 7, 4};
1042 static void M215CW(uint32 A, uint8 V)
1047 setchr1(A,(V&0x7F)|((EXPREGS[1]&0x10)<<3));
1050 static void M215PW(uint32 A, uint8 V)
1054 setprg16(0x8000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
1055 setprg16(0xC000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
1057 else if(EXPREGS[1]&0x08)
1058 setprg8(A,(V&0x1F)|0x20);
1060 setprg8(A,(V&0x0F)|(EXPREGS[1]&0x10));
1063 static DECLFW(M215Write)
1072 else switch(A&0xE001)
1074 case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
1075 case 0xE001: IRQCount=V; break;
1076 case 0xC001: IRQa=1; break;
1077 case 0xC000: setmirror(((V|(V>>7))&1)^1); break;
1078 case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m215_perm[V&7])); cmdin=1; break;
1079 case 0x8001: if(!cmdin) break;
1080 MMC3_CMDWrite(0x8001,V);
1086 static DECLFW(M215ExWrite)
1092 FixMMC3PRG(MMC3_cmd);
1096 FixMMC3CHR(MMC3_cmd);
1105 static void M215Power(void)
1111 SetWriteHandler(0x8000,0xFFFF,M215Write);
1112 SetWriteHandler(0x5000,0x7FFF,M215ExWrite);
1115 void Mapper215_Init(CartInfo *info)
1117 GenMMC3_Init(info, 256, 256, 0, 0);
1120 info->Power=M215Power;
1121 AddExState(EXPREGS, 3, 0, "EXPR");
1122 AddExState(&cmdin, 1, 0, "CMDIN");
1125 // ---------------------------- Mapper 217 ------------------------------
1127 static uint8 m217_perm[8] = {0, 6, 3, 7, 5, 2, 4, 1};
1129 static void M217CW(uint32 A, uint8 V)
1132 setchr1(A,V|((EXPREGS[1]&3)<<8));
1134 setchr1(A,(V&0x7F)|((EXPREGS[1]&3)<<8)|((EXPREGS[1]&0x10)<<3));
1137 static void M217PW(uint32 A, uint8 V)
1141 setprg16(0x8000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
1142 setprg16(0xC000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
1144 else if(EXPREGS[1]&0x08)
1145 setprg8(A,(V&0x1F)|((EXPREGS[1]&3)<<5));
1147 setprg8(A,(V&0x0F)|((EXPREGS[1]&3)<<5)|(EXPREGS[1]&0x10));
1150 static DECLFW(M217Write)
1155 MMC3_IRQWrite(A, V);
1159 else switch(A&0xE001)
1161 case 0x8000: IRQCount=V; break;
1162 case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
1163 case 0xC001: IRQa=1; break;
1164 case 0xA001: setmirror((V&1)^1); break;
1165 case 0x8001: MMC3_CMDWrite(0x8000,(V&0xC0)|(m217_perm[V&7])); cmdin=1; break;
1166 case 0xA000: if(!cmdin) break;
1167 MMC3_CMDWrite(0x8001,V);
1173 static DECLFW(M217ExWrite)
1179 FixMMC3PRG(MMC3_cmd);
1183 FixMMC3PRG(MMC3_cmd);
1191 static void M217Power(void)
1197 SetWriteHandler(0x8000,0xFFFF,M217Write);
1198 SetWriteHandler(0x5000,0x7FFF,M217ExWrite);
1201 void Mapper217_Init(CartInfo *info)
1203 GenMMC3_Init(info, 256, 256, 0, 0);
1206 info->Power=M217Power;
1207 AddExState(EXPREGS, 3, 0, "EXPR");
1208 AddExState(&cmdin, 1, 0, "CMDIN");
1211 // ---------------------------- Mapper 245 ------------------------------
1213 static void M245CW(uint32 A, uint8 V)
1217 FixMMC3PRG(MMC3_cmd);
1220 static void M245PW(uint32 A, uint8 V)
1222 setprg8(A,(V&0x3F)|((EXPREGS[0]&2)<<5));
1225 static void M245Power(void)
1231 void Mapper245_Init(CartInfo *info)
1233 GenMMC3_Init(info, 512, 256, 8, info->battery);
1236 info->Power=M245Power;
1237 AddExState(EXPREGS, 1, 0, "EXPR");
1240 // ---------------------------- Mapper 249 ------------------------------
1242 static void M249PW(uint32 A, uint8 V)
1247 V=(V&1)|((V>>3)&2)|((V>>1)&4)|((V<<2)&8)|((V<<2)&0x10);
1251 V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1257 static void M249CW(uint32 A, uint8 V)
1260 V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1264 static DECLFW(M249Write)
1267 FixMMC3PRG(MMC3_cmd);
1268 FixMMC3CHR(MMC3_cmd);
1271 static void M249Power(void)
1275 SetWriteHandler(0x5000,0x5000,M249Write);
1278 void Mapper249_Init(CartInfo *info)
1280 GenMMC3_Init(info, 512, 256, 8, info->battery);
1283 info->Power=M249Power;
1284 AddExState(EXPREGS, 1, 0, "EXPR");
1287 // ---------------------------- Mapper 250 ------------------------------
1289 static DECLFW(M250Write)
1291 MMC3_CMDWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1294 static DECLFW(M250IRQWrite)
1296 MMC3_IRQWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1299 static void M250_Power(void)
1302 SetWriteHandler(0x8000,0xBFFF,M250Write);
1303 SetWriteHandler(0xC000,0xFFFF,M250IRQWrite);
1306 void Mapper250_Init(CartInfo *info)
1308 GenMMC3_Init(info, 512, 256, 8, info->battery);
1309 info->Power=M250_Power;
1312 // ---------------------------- Mapper 254 ------------------------------
1314 static DECLFR(MR254WRAM)
1317 return WRAM[A-0x6000];
1319 return WRAM[A-0x6000]^EXPREGS[1];
1322 static DECLFW(M254Write)
1325 case 0x8000: EXPREGS[0]=0xff;
1327 case 0xA001: EXPREGS[1]=V;
1332 static void M254_Power(void)
1335 SetWriteHandler(0x8000,0xBFFF,M254Write);
1336 SetReadHandler(0x6000,0x7FFF,MR254WRAM);
1339 void Mapper254_Init(CartInfo *info)
1341 GenMMC3_Init(info, 128, 128, 8, info->battery);
1342 info->Power=M254_Power;
1343 AddExState(EXPREGS, 2, 0, "EXPR");
1346 // ---------------------------- UNIF Boards -----------------------------
1348 void TEROM_Init(CartInfo *info)
1350 GenMMC3_Init(info, 32, 32, 0, 0);
1353 void TFROM_Init(CartInfo *info)
1355 GenMMC3_Init(info, 512, 64, 0, 0);
1358 void TGROM_Init(CartInfo *info)
1360 GenMMC3_Init(info, 512, 0, 0, 0);
1363 void TKROM_Init(CartInfo *info)
1365 GenMMC3_Init(info, 512, 256, 8, info->battery);
1368 void TLROM_Init(CartInfo *info)
1370 GenMMC3_Init(info, 512, 256, 0, 0);
1373 void TSROM_Init(CartInfo *info)
1375 GenMMC3_Init(info, 512, 256, 8, 0);
1378 void TLSROM_Init(CartInfo *info)
1380 GenMMC3_Init(info, 512, 256, 8, 0);
1384 AddExState(&PPUCHRBus, 1, 0, "PPUC");
1387 void TKSROM_Init(CartInfo *info)
1389 GenMMC3_Init(info, 512, 256, 8, info->battery);
1393 AddExState(&PPUCHRBus, 1, 0, "PPUC");
1396 void TQROM_Init(CartInfo *info)
1398 GenMMC3_Init(info, 512, 64, 0, 0);
1401 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1402 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1405 void HKROM_Init(CartInfo *info)
1407 GenMMC3_Init(info, 512, 512, 1, info->battery);