mappers updated to 0.98.16
[fceu.git] / boards / mmc3.c
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
30 uint8 MMC3_cmd;
31 uint8 *WRAM;
32 uint8 *CHRRAM;
33 uint32 CHRRAMSize;
34 uint8 EXPREGS[8];    /* For bootleg games, mostly. */
35
36 static uint8 A000B,A001B;
37 static uint8 DRegBuf[8];
38
39 #undef IRQCount
40 #undef IRQLatch
41 #undef IRQa
42 uint8 IRQCount,IRQLatch,IRQa;
43 uint8 IRQReload;
44
45 static 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
58 static int mmc3opts=0;
59 static int wrams;
60 static int isRevB=1;
61
62 void (*pwrap)(uint32 A, uint8 V);
63 void (*cwrap)(uint32 A, uint8 V);
64 void (*mwrap)(uint8 V);
65
66 void GenMMC3Power(void);
67 void FixMMC3PRG(int V);
68 void FixMMC3CHR(int V);
69
70 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
71
72 // ----------------------------------------------------------------------
73 // ------------------------- Generic MM3 Code ---------------------------
74 // ----------------------------------------------------------------------
75
76 void 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
92 void 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
107 void 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
124 DECLFW(MMC3_CMDWrite)
125 {
126 // FCEU_printf("%04x:%04x\n",A,V);
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;
173        Write_IRQFM(0x4017,0x40);
174        break;
175  }
176 }
177
178 DECLFW(MMC3_IRQWrite)
179 {
180 // FCEU_printf("%04x:%04x\n",A,V);
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
190 static void ClockMMC3Counter(void)
191 {
192  int count = IRQCount;
193  if(!count || IRQReload)
194  {
195     IRQCount = IRQLatch;
196     IRQReload = 0;
197  }
198  else
199     IRQCount--;
200  if((count|isRevB) && !IRQCount)
201  {
202     if(IRQa)
203     {
204        X6502_IRQBegin(FCEU_IQEXT);
205     }
206  }
207 }
208
209 static void MMC3_hb(void)
210 {
211  ClockMMC3Counter();
212 }
213
214 static void MMC3_hb_KickMasterHack(void)
215 {
216  if(scanline==238) ClockMMC3Counter();
217  ClockMMC3Counter();
218 }
219
220 static void MMC3_hb_PALStarWarsHack(void)
221 {
222  if(scanline==240) ClockMMC3Counter();
223  ClockMMC3Counter();
224 }
225
226 void GenMMC3Restore(int version)
227 {
228  if(mwrap) mwrap(A000B&1);
229  FixMMC3PRG(MMC3_cmd);
230  FixMMC3CHR(MMC3_cmd);
231 }
232
233 static void GENCWRAP(uint32 A, uint8 V)
234 {
235  if(!UNIFchrrama) setchr1(A,V);
236 }
237
238 static void GENPWRAP(uint32 A, uint8 V)
239 {
240  setprg8(A,V&0x3F);
241 }
242
243 static void GENMWRAP(uint8 V)
244 {
245  A000B=V;
246  setmirror(V^1);
247 }
248
249 static void GENNOMWRAP(uint8 V)
250 {
251  A000B=V;
252 }
253
254 static DECLFW(MBWRAM)
255 {
256   WRAM[A-0x6000]=V;
257 }
258
259 static DECLFR(MAWRAM)
260 {
261  return(WRAM[A-0x6000]);
262 }
263
264 static DECLFW(MBWRAMMMC6)
265 {
266  WRAM[A&0x3ff]=V;
267 }
268
269 static DECLFR(MAWRAMMMC6)
270 {
271  return(WRAM[A&0x3ff]);
272 }
273
274 void GenMMC3Power(void)
275 {
276  if(UNIFchrrama) setchr8(0);
277
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);
290   }
291   else
292   {
293    FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
294    SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
295    SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
296   }
297   if(!(mmc3opts&2))
298      FCEU_dwmemset(WRAM,0,wrams);
299  }
300  MMC3RegReset();
301  if(CHRRAM)
302   FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
303 }
304
305 static void GenMMC3Close(void)
306 {
307  if(CHRRAM)
308     FCEU_gfree(CHRRAM);
309  if(WRAM)
310     FCEU_gfree(WRAM);
311  CHRRAM=WRAM=NULL;
312 }
313
314 //static uint16 _a12;
315 //static void FP_FASTAPASS(1) MMC3_PPU(uint32 A)
316 //{
317 //  if(A&0x2000)return;
318 //  if((!_a12)&&(A&0x1000))
319 //    ClockMMC3Counter();
320 //  _a12=A&0x1000;
321 //}
322
323 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
324 {
325  pwrap=GENPWRAP;
326  cwrap=GENCWRAP;
327  mwrap=GENMWRAP;
328
329  wrams=wram<<10;
330
331  PRGmask8[0]&=(prg>>13)-1;
332  CHRmask1[0]&=(chr>>10)-1;
333  CHRmask2[0]&=(chr>>11)-1;
334
335  if(wram)
336  {
337   mmc3opts|=1;
338   WRAM=(uint8*)FCEU_gmalloc(wrams);
339   AddExState(WRAM, wrams, 0, "WRAM");
340  }
341
342  if(battery)
343  {
344   mmc3opts|=2;
345   info->SaveGame[0]=WRAM;
346   info->SaveGameLen[0]=wrams;
347  }
348
349 // if(!chr) // duplicated CHR RAM set up
350 // {
351 //  CHRRAM=(uint8*)FCEU_gmalloc(8192);
352 //  CHRRAMSize=8192;
353 //  SetupCartCHRMapping(0, CHRRAM, 8192, 1);
354 //  AddExState(CHRRAM, 8192, 0, "CHRR");
355 // }
356
357  AddExState(MMC3_StateRegs, ~0, 0, 0);
358
359  info->Power=GenMMC3Power;
360  info->Reset=MMC3RegReset;
361  info->Close=GenMMC3Close;
362
363  if(info->CRC32 == 0x5104833e)        // Kick Master
364   GameHBIRQHook = MMC3_hb_KickMasterHack;
365  else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
366   GameHBIRQHook = MMC3_hb_KickMasterHack;
367  else if(info->CRC32 == 0xfcd772eb)    // PAL Star Wars, similar problem as Kick Master.
368   GameHBIRQHook = MMC3_hb_PALStarWarsHack;
369  else
370  GameHBIRQHook=MMC3_hb;
371 // PPU_hook=MMC3_PPU;
372  GameStateRestore=GenMMC3Restore;
373 }
374
375 // ----------------------------------------------------------------------
376 // -------------------------- MMC3 Based Code ---------------------------
377 // ----------------------------------------------------------------------
378
379 // ---------------------------- Mapper 4 --------------------------------
380
381 static int hackm4=0;/* For Karnov, maybe others.  BLAH.  Stupid iNES format.*/
382
383 static void M4Power(void)
384 {
385  GenMMC3Power();
386  A000B=(hackm4^1)&1;
387  setmirror(hackm4);
388 }
389
390 void Mapper4_Init(CartInfo *info)
391 {
392  int ws=8;
393
394  if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
395  {
396   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");
397   ws=0;
398  }
399  GenMMC3_Init(info,512,256,ws,info->battery);
400  info->Power=M4Power;
401  hackm4=info->mirror;
402 }
403
404 // ---------------------------- Mapper 12 -------------------------------
405
406 static void M12CW(uint32 A, uint8 V)
407 {
408  setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
409 }
410
411 static DECLFW(M12Write)
412 {
413  EXPREGS[0]=V&0x01;
414  EXPREGS[1]=(V&0x10)>>4;
415 }
416
417 static void M12Power(void)
418 {
419  EXPREGS[0]=EXPREGS[1]=0;
420  GenMMC3Power();
421  SetWriteHandler(0x4100,0x5FFF,M12Write);
422 }
423
424 void Mapper12_Init(CartInfo *info)
425 {
426  GenMMC3_Init(info, 512, 256, 8, info->battery);
427  cwrap=M12CW;
428  info->Power=M12Power;
429  AddExState(EXPREGS, 2, 0, "EXPR");
430 }
431
432 // ---------------------------- Mapper 37 -------------------------------
433
434 static void M37PW(uint32 A, uint8 V)
435 {
436   if(EXPREGS[0]!=2)
437     V&=0x7;
438   else
439     V&=0xF;
440   V|=EXPREGS[0]<<3;
441   setprg8(A,V);
442 }
443
444 static void M37CW(uint32 A, uint8 V)
445 {
446   uint32 NV=V;
447   NV&=0x7F;
448   NV|=EXPREGS[0]<<6;
449   setchr1(A,NV);
450 }
451
452 static DECLFW(M37Write)
453 {
454   EXPREGS[0]=(V&6)>>1;
455   FixMMC3PRG(MMC3_cmd);
456   FixMMC3CHR(MMC3_cmd);
457 }
458
459 static void M37Reset(void)
460 {
461   EXPREGS[0]=0;
462   MMC3RegReset();
463 }
464
465 static void M37Power(void)
466 {
467   EXPREGS[0]=0;
468   GenMMC3Power();
469   SetWriteHandler(0x6000,0x7FFF,M37Write);
470 }
471
472 void Mapper37_Init(CartInfo *info)
473 {
474   GenMMC3_Init(info, 512, 256, 8, info->battery);
475   pwrap=M37PW;
476   cwrap=M37CW;
477   info->Power=M37Power;
478   info->Reset=M37Reset;
479   AddExState(EXPREGS, 1, 0, "EXPR");
480 }
481
482 // ---------------------------- Mapper 44 -------------------------------
483
484 static void M44PW(uint32 A, uint8 V)
485 {
486  uint32 NV=V;
487  if(EXPREGS[0]>=6) NV&=0x1F;
488  else NV&=0x0F;
489  NV|=EXPREGS[0]<<4;
490  setprg8(A,NV);
491 }
492
493 static void M44CW(uint32 A, uint8 V)
494 {
495  uint32 NV=V;
496  if(EXPREGS[0]<6) NV&=0x7F;
497  NV|=EXPREGS[0]<<7;
498  setchr1(A,NV);
499 }
500
501 static DECLFW(M44Write)
502 {
503  if(A&1)
504  {
505   EXPREGS[0]=V&7;
506   FixMMC3PRG(MMC3_cmd);
507   FixMMC3CHR(MMC3_cmd);
508  }
509  else
510   MMC3_CMDWrite(A,V);
511 }
512
513 static void M44Power(void)
514 {
515  EXPREGS[0]=0;
516  GenMMC3Power();
517  SetWriteHandler(0xA000,0xBFFF,M44Write);
518 }
519
520 void Mapper44_Init(CartInfo *info)
521 {
522  GenMMC3_Init(info, 512, 256, 8, info->battery);
523  cwrap=M44CW;
524  pwrap=M44PW;
525  info->Power=M44Power;
526  AddExState(EXPREGS, 1, 0, "EXPR");
527 }
528
529 // ---------------------------- Mapper 45 -------------------------------
530
531 static void M45CW(uint32 A, uint8 V)
532 {
533  if(!UNIFchrrama)
534  {
535    uint32 NV=V;
536    if(EXPREGS[2]&8)
537       NV&=(1<<((EXPREGS[2]&7)+1))-1;
538 //   else
539 //      NV&=0;
540    NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
541    setchr1(A,NV);
542  }
543 }
544
545 static void M45PW(uint32 A, uint8 V)
546 {
547  V&=(EXPREGS[3]&0x3F)^0x3F;
548  V|=EXPREGS[1];
549  setprg8(A,V);
550 }
551
552 static DECLFW(M45Write)
553 {
554  if(EXPREGS[3]&0x40)
555  {
556   WRAM[A-0x6000]=V;
557   return;
558  }
559  EXPREGS[EXPREGS[4]]=V;
560  EXPREGS[4]=(EXPREGS[4]+1)&3;
561  if(!EXPREGS[4]) 
562  {
563    FCEU_printf("CHROR %02x, PRGOR %02x, CHRAND %02x, PRGAND %02x\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3]);
564    FCEU_printf("CHR0 %03x, CHR1 %03x, PRG0 %03x, PRG1 %03x\n",
565                (0x00&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
566                (0xFF&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
567                (0x00&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]),
568                (0xFF&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]));
569  }
570  FixMMC3PRG(MMC3_cmd);
571  FixMMC3CHR(MMC3_cmd);
572 }
573
574 static void M45Reset(void)
575 {
576  EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
577  MMC3RegReset();
578 }
579
580 static void M45Power(void)
581 {
582  setchr8(0);
583  GenMMC3Power();
584  SetWriteHandler(0x6000,0x7FFF,M45Write);
585 }
586
587 void Mapper45_Init(CartInfo *info)
588 {
589  GenMMC3_Init(info, 512, 256, 8, info->battery);
590  cwrap=M45CW;
591  pwrap=M45PW;
592  info->Reset=M45Reset;
593  info->Power=M45Power;
594  AddExState(EXPREGS, 5, 0, "EXPR");
595 }
596
597 // ---------------------------- Mapper 47 -------------------------------
598
599 static void M47PW(uint32 A, uint8 V)
600 {
601  V&=0xF;
602  V|=EXPREGS[0]<<4;
603  setprg8(A,V);
604 }
605
606 static void M47CW(uint32 A, uint8 V)
607 {
608  uint32 NV=V;
609  NV&=0x7F;
610  NV|=EXPREGS[0]<<7;
611  setchr1(A,NV);
612 }
613
614 static DECLFW(M47Write)
615 {
616  EXPREGS[0]=V&1;
617  FixMMC3PRG(MMC3_cmd);
618  FixMMC3CHR(MMC3_cmd);
619 }
620
621 static void M47Power(void)
622 {
623  EXPREGS[0]=0;
624  GenMMC3Power();
625  SetWriteHandler(0x6000,0x7FFF,M47Write);
626 // SetReadHandler(0x6000,0x7FFF,0);
627 }
628
629 void Mapper47_Init(CartInfo *info)
630 {
631  GenMMC3_Init(info, 512, 256, 8, info->battery);
632  pwrap=M47PW;
633  cwrap=M47CW;
634  info->Power=M47Power;
635  AddExState(EXPREGS, 1, 0, "EXPR");
636 }
637
638 // ---------------------------- Mapper 49 -------------------------------
639
640 static void M49PW(uint32 A, uint8 V)
641 {
642  if(EXPREGS[0]&1)
643  {
644   V&=0xF;
645   V|=(EXPREGS[0]&0xC0)>>2;
646   setprg8(A,V);
647  }
648  else
649   setprg32(0x8000,(EXPREGS[0]>>4)&3);
650 }
651
652 static void M49CW(uint32 A, uint8 V)
653 {
654  uint32 NV=V;
655  NV&=0x7F;
656  NV|=(EXPREGS[0]&0xC0)<<1;
657  setchr1(A,NV);
658 }
659
660 static DECLFW(M49Write)
661 {
662  if(A001B&0x80)
663  {
664   EXPREGS[0]=V;
665   FixMMC3PRG(MMC3_cmd);
666   FixMMC3CHR(MMC3_cmd);
667  }
668 }
669
670 static void M49Reset(void)
671 {
672  EXPREGS[0]=0;
673  MMC3RegReset();
674 }
675
676 static void M49Power(void)
677 {
678  M49Reset();
679  GenMMC3Power();
680  SetWriteHandler(0x6000,0x7FFF,M49Write);
681  SetReadHandler(0x6000,0x7FFF,0);
682 }
683
684 void Mapper49_Init(CartInfo *info)
685 {
686  GenMMC3_Init(info, 512, 256, 0, 0);
687  cwrap=M49CW;
688  pwrap=M49PW;
689  info->Reset=M49Reset;
690  info->Power=M49Power;
691  AddExState(EXPREGS, 1, 0, "EXPR");
692 }
693
694 // ---------------------------- Mapper 52 -------------------------------
695
696 static void M52PW(uint32 A, uint8 V)
697 {
698  uint32 NV=V;
699  NV&=0x1F^((EXPREGS[0]&8)<<1);
700  NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
701  setprg8(A,NV);
702 }
703
704 static void M52CW(uint32 A, uint8 V)
705 {
706  uint32 NV=V;
707  NV&=0xFF^((EXPREGS[0]&0x40)<<1);
708  NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
709  setchr1(A,NV);
710 }
711
712 static DECLFW(M52Write)
713 {
714  if(EXPREGS[1])
715  {
716   WRAM[A-0x6000]=V;
717   return;
718  }
719  EXPREGS[1]=1;
720  EXPREGS[0]=V;
721  FixMMC3PRG(MMC3_cmd);
722  FixMMC3CHR(MMC3_cmd);
723 }
724
725 static void M52Reset(void)
726 {
727  EXPREGS[0]=EXPREGS[1]=0;
728  MMC3RegReset();
729 }
730
731 static void M52Power(void)
732 {
733  M52Reset();
734  GenMMC3Power();
735  SetWriteHandler(0x6000,0x7FFF,M52Write);
736 }
737
738 void Mapper52_Init(CartInfo *info)
739 {
740  GenMMC3_Init(info, 512, 256, 8, info->battery);
741  cwrap=M52CW;
742  pwrap=M52PW;
743  info->Reset=M52Reset;
744  info->Power=M52Power;
745  AddExState(EXPREGS, 2, 0, "EXPR");
746 }
747
748 // ---------------------------- Mapper 74 -------------------------------
749
750 static void M74CW(uint32 A, uint8 V)
751 {
752   if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
753     setchr1r(0x10,A,V);
754   else
755     setchr1r(0,A,V);
756 }
757
758 void Mapper74_Init(CartInfo *info)
759 {
760  GenMMC3_Init(info, 512, 256, 8, info->battery);
761  cwrap=M74CW;
762  CHRRAMSize=2048;
763  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
764  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
765  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
766 }
767
768 // ---------------------------- Mapper 114 ------------------------------
769
770 static uint8 cmdin;
771 uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
772
773 static void M114PWRAP(uint32 A, uint8 V)
774 {
775   if(EXPREGS[0]&0x80)
776   {
777     setprg16(0x8000,EXPREGS[0]&0xF);
778     setprg16(0xC000,EXPREGS[0]&0xF);
779   }
780   else
781     setprg8(A,V&0x3F);
782 }
783
784 static DECLFW(M114Write)
785 {
786  if(A==0xE003)
787  {
788   IRQa=1;
789   IRQLatch=V;
790   IRQReload=1;
791  }
792  else if(A==0xE002)
793  {
794   IRQa=0;
795   X6502_IRQEnd(FCEU_IQEXT);
796  }
797  else switch(A&0xE000)
798  {
799   case 0x8000: setmirror((V&1)^1); break;
800   case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
801   case 0xC000: if(!cmdin) break;
802                MMC3_CMDWrite(0x8001,V);
803                cmdin=0;
804                break;
805  }
806 }
807
808 static DECLFW(M114ExWrite)
809 {
810   if(A<=0x7FFF)
811   {
812    EXPREGS[0]=V;
813    FixMMC3PRG(MMC3_cmd);
814   }
815 }
816
817 static void M114Power(void)
818 {
819  GenMMC3Power();
820  SetWriteHandler(0x8000,0xFFFF,M114Write);
821  SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
822 }
823
824 static void M114Reset(void)
825 {
826  EXPREGS[0]=0;
827  MMC3RegReset();
828 }
829
830 void Mapper114_Init(CartInfo *info)
831 {
832  GenMMC3_Init(info, 256, 256, 0, 0);
833  pwrap=M114PWRAP;
834  info->Power=M114Power;
835  info->Reset=M114Reset;
836  AddExState(EXPREGS, 1, 0, "EXPR");
837  AddExState(&cmdin, 1, 0, "CMDIN");
838 }
839
840 // ---------------------------- Mapper 115 ------------------------------
841
842 static void M115PW(uint32 A, uint8 V)
843 {
844   if(EXPREGS[0]&0x80)
845     setprg32(0x8000,(EXPREGS[0]&7)>>1);
846   else
847     setprg8(A,V);
848 }
849
850 static void M115CW(uint32 A, uint8 V)
851 {
852   setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
853 }
854
855 static DECLFW(M115Write)
856 {
857  if(A==0x6000)
858     EXPREGS[0]=V;
859  else if(A==0x6001)
860     EXPREGS[1]=V;
861  FixMMC3PRG(MMC3_cmd);
862 }
863
864 static void M115Power(void)
865 {
866  GenMMC3Power();
867  SetWriteHandler(0x4100,0x7FFF,M115Write);
868  SetReadHandler(0x4100,0x7FFF,0);
869 }
870
871 void Mapper115_Init(CartInfo *info)
872 {
873  GenMMC3_Init(info, 128, 512, 0, 0);
874  cwrap=M115CW;
875  pwrap=M115PW;
876  info->Power=M115Power;
877  AddExState(EXPREGS, 2, 0, "EXPR");
878 }
879
880 // ---------------------------- Mapper 116 ------------------------------
881
882 static void M116CW(uint32 A, uint8 V)
883 {
884 // setchr1(A,V|((EXPREGS[0]&0x4)<<6));
885  if(EXPREGS[0]&2)
886     setchr8r(0x10,0);
887  else
888     setchr1(A,V);
889 }
890
891 static DECLFW(M116Write)
892 {
893  EXPREGS[0]=V;
894  FixMMC3CHR(MMC3_cmd);
895 }
896
897 static void M116Power(void)
898 {
899  GenMMC3Power();
900  SetWriteHandler(0x4100,0x4100,M116Write);
901 }
902
903 void Mapper116_Init(CartInfo *info)
904 {
905  GenMMC3_Init(info, 128, 512, 0, 0);
906  cwrap=M116CW;
907  info->Power=M116Power;
908  CHRRAM = (uint8*)FCEU_gmalloc(8192);
909  SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
910  AddExState(EXPREGS, 4, 0, "EXPR");
911 }
912
913 // ---------------------------- Mapper 118 ------------------------------
914
915 static uint8 PPUCHRBus;
916 static uint8 TKSMIR[8];
917
918 static void FP_FASTAPASS(1) TKSPPU(uint32 A)
919 {
920  A&=0x1FFF;
921  A>>=10;
922  PPUCHRBus=A;
923  setmirror(MI_0+TKSMIR[A]);
924 }
925
926 static void TKSWRAP(uint32 A, uint8 V)
927 {
928  TKSMIR[A>>10]=V>>7;
929  setchr1(A,V&0x7F);
930  if(PPUCHRBus==(A>>10))
931     setmirror(MI_0+(V>>7));
932 }
933
934 void Mapper118_Init(CartInfo *info)
935 {
936  GenMMC3_Init(info, 512, 256, 8, info->battery);
937  cwrap=TKSWRAP;
938  mwrap=GENNOMWRAP;
939  PPU_hook=TKSPPU;
940  AddExState(&PPUCHRBus, 1, 0, "PPUC");
941 }
942
943 // ---------------------------- Mapper 119 ------------------------------
944
945 static void TQWRAP(uint32 A, uint8 V)
946 {
947  setchr1r((V&0x40)>>2,A,V&0x3F);
948 }
949
950 void Mapper119_Init(CartInfo *info)
951 {
952  GenMMC3_Init(info, 512, 64, 0, 0);
953  cwrap=TQWRAP;
954  CHRRAMSize=8192;
955  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
956  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
957 }
958
959 // ---------------------------- Mapper 165 ------------------------------
960
961 static void M165CW(uint32 A, uint8 V)
962 {
963  if(V==0)
964     setchr4r(0x10,A,0);
965  else
966     setchr4(A,V>>2);
967 }
968
969 static void M165PPUFD(void)
970 {
971  if(EXPREGS[0]==0xFD)
972  {
973   M165CW(0x0000,DRegBuf[0]);
974   M165CW(0x1000,DRegBuf[2]);
975  }
976 }
977
978 static void M165PPUFE(void)
979 {
980  if(EXPREGS[0]==0xFE)
981  {
982   M165CW(0x0000,DRegBuf[1]);
983   M165CW(0x1000,DRegBuf[4]);
984  }
985 }
986
987 static void M165CWM(uint32 A, uint8 V)
988 {
989  if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2))
990    M165PPUFD();
991  if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4))
992    M165PPUFE();
993 }
994
995 static void FP_FASTAPASS(1) M165PPU(uint32 A)
996 {
997  if((A&0x1FF0)==0x1FD0)
998  {
999   EXPREGS[0]=0xFD;
1000   M165PPUFD();
1001  } else if((A&0x1FF0)==0x1FE0)
1002  {
1003   EXPREGS[0]=0xFE;
1004   M165PPUFE();
1005  }
1006 }
1007
1008 static void M165Power(void)
1009 {
1010  EXPREGS[0]=0xFD;
1011  GenMMC3Power();
1012 }
1013
1014 void Mapper165_Init(CartInfo *info)
1015 {
1016  GenMMC3_Init(info, 512, 128, 8, info->battery);
1017  cwrap=M165CWM;
1018  PPU_hook=M165PPU;
1019  info->Power=M165Power;
1020  CHRRAMSize = 4096;
1021  CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
1022  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1023  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1024  AddExState(EXPREGS, 4, 0, "EXPR");
1025 }
1026
1027 // ---------------------------- Mapper 182 ------------------------------
1028 // Ã²Ã Ã¡Ã«Ã¨Ã¶Ã  Ã¯Ã¥Ã°Ã¬Ã³Ã²Ã Ã¶Ã¨ Ã Ã­Ã Ã«Ã®Ã£Ã¨Ã·Ã­Ã  114 Ã¬Ã Ã¯Ã¯Ã¥Ã°Ã³, Ã°Ã¥Ã£Ã¨Ã±Ã²Ã°Ã» Ã¬Ã Ã¯Ã¯Ã¥Ã°Ã  Ã£Ã®Ã°Ã Ã§Ã¤Ã® Ã±Ã«Ã®Ã¦Ã­Ã¥Ã¥,
1029 // Ã·Ã¥Ã¬ Ã¨Ã±Ã¯Ã®Ã«Ã¼Ã§Ã³Ã¾Ã²Ã±Ã¿ Ã§Ã¤Ã¥Ã±Ã¼, ÃµÃ®Ã²Ã¿ Ã¢Ã±Ã¥ Ã¯Ã°Ã¥ÃªÃ°Ã Ã±Ã­Ã® Ã°Ã Ã¡Ã®Ã²Ã Ã¥Ã².
1030
1031 //static uint8 m182_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
1032 static DECLFW(M182Write)
1033 {
1034  switch(A&0xF003)
1035  {
1036   case 0x8001: setmirror((V&1)^1); break;
1037   case 0xA000: MMC3_CMDWrite(0x8000,m114_perm[V&7]); break;
1038   case 0xC000: MMC3_CMDWrite(0x8001,V); break;
1039   case 0xE003: if(V)
1040                {
1041                  IRQLatch=V;
1042                  IRQReload=1;
1043                  IRQa=1;
1044                }
1045                X6502_IRQEnd(FCEU_IQEXT);
1046                break;
1047  }
1048 }
1049
1050 static void M182Power(void)
1051 {
1052  GenMMC3Power();
1053  SetWriteHandler(0x8000,0xFFFF,M182Write);
1054 }
1055
1056 void Mapper182_Init(CartInfo *info)
1057 {
1058  GenMMC3_Init(info, 256, 256, 0, 0);
1059  info->Power=M182Power;
1060 }
1061
1062 // ---------------------------- Mapper 191 ------------------------------
1063
1064 static void M191CW(uint32 A, uint8 V)
1065 {
1066   setchr1r((V&0x80)>>3,A,V);
1067 }
1068
1069 void Mapper191_Init(CartInfo *info)
1070 {
1071  GenMMC3_Init(info, 256, 256, 8, info->battery);
1072  cwrap=M191CW;
1073  CHRRAMSize=2048;
1074  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1075  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1076  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1077 }
1078
1079 // ---------------------------- Mapper 192 -------------------------------
1080
1081 static void M192CW(uint32 A, uint8 V)
1082 {
1083   if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese),
1084     setchr1r(0x10,A,V);
1085   else
1086     setchr1r(0,A,V);
1087 }
1088
1089 void Mapper192_Init(CartInfo *info)
1090 {
1091  GenMMC3_Init(info, 512, 256, 8, info->battery);
1092  cwrap=M192CW;
1093  CHRRAMSize=4096;
1094  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1095  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1096  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1097 }
1098
1099 // ---------------------------- Mapper 194 -------------------------------
1100
1101 static void M194CW(uint32 A, uint8 V)
1102 {
1103   if(V<=1) //Dai-2-Ji - Super Robot Taisen (As).nes
1104     setchr1r(0x10,A,V);
1105   else
1106     setchr1r(0,A,V);
1107 }
1108
1109 void Mapper194_Init(CartInfo *info)
1110 {
1111  GenMMC3_Init(info, 512, 256, 8, info->battery);
1112  cwrap=M194CW;
1113  CHRRAMSize=2048;
1114  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1115  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1116  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1117 }
1118
1119 // ---------------------------- Mapper 198 -------------------------------
1120
1121 static uint8 *wramtw;
1122 static uint16 wramsize;
1123 static void M198CW(uint32 A, uint8 V)
1124 {
1125   if(V<=3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)
1126     setchr1r(0x10,A,V);
1127   else
1128     setchr1r(0,A,V);
1129 }
1130
1131 static void M198Power(void)
1132 {
1133  GenMMC3Power();
1134  setprg4r(0x10,0x5000,0);
1135  SetWriteHandler(0x5000,0x5fff,CartBW);
1136  SetReadHandler(0x5000,0x5fff,CartBR);
1137 }
1138
1139 static void M198Close(void)
1140 {
1141   if(wramtw)
1142     FCEU_gfree(wramtw);
1143   wramtw=NULL;
1144 }
1145
1146 void Mapper198_Init(CartInfo *info)
1147 {
1148  GenMMC3_Init(info, 512, 256, 8, info->battery);
1149  cwrap=M198CW;
1150  info->Power=M198Power;
1151  info->Close=M198Close;
1152  CHRRAMSize=4096;
1153  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1154  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1155  wramsize=4096;
1156  wramtw=(uint8*)FCEU_gmalloc(wramsize);
1157  SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
1158  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1159  AddExState(wramtw, wramsize, 0, "WRAMTW");
1160 }
1161
1162 // ---------------------------- Mapper 199 -------------------------------
1163
1164 static uint8 *wramtw;
1165 static uint16 wramsize;
1166 static void M199PW(uint32 A, uint8 V)
1167 {
1168   if(V>=0x50)
1169     setprg8(A,V&0x4F);
1170   else
1171     setprg8(A,V);
1172 }
1173
1174 void Mapper199_Init(CartInfo *info)
1175 {
1176  GenMMC3_Init(info, 1024, 256, 8, info->battery);
1177  pwrap=M199PW;
1178  info->Power=M198Power;
1179  info->Close=M198Close;
1180  wramsize=4096;
1181  wramtw=(uint8*)FCEU_gmalloc(wramsize);
1182  SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
1183  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1184  AddExState(wramtw, wramsize, 0, "WRAMTW");
1185 }
1186
1187 // ---------------------------- Mapper 205 ------------------------------
1188
1189 static void M205PW(uint32 A, uint8 V)
1190 {
1191  if(EXPREGS[0]&2)
1192     setprg8(A,(V&0x0f)|((EXPREGS[0]&3)<<4));
1193  else
1194     setprg8(A,(V&0x1f)|((EXPREGS[0]&3)<<4));
1195 }
1196
1197 static void M205CW(uint32 A, uint8 V)
1198 {
1199  setchr1(A,V|((EXPREGS[0]&3)<<7));
1200 }
1201
1202 static DECLFW(M205Write)
1203 {
1204  if((A&0x6800)==0x6800) EXPREGS[0]= V;
1205  FixMMC3PRG(MMC3_cmd);
1206  FixMMC3CHR(MMC3_cmd);
1207 }
1208
1209 static void M205Reset(void)
1210 {
1211  EXPREGS[0]=0;
1212  MMC3RegReset();
1213 }
1214
1215 static void M205Power(void)
1216 {
1217  GenMMC3Power();
1218  SetWriteHandler(0x4020,0x7FFF,M205Write);
1219 }
1220
1221 void Mapper205_Init(CartInfo *info)
1222 {
1223  GenMMC3_Init(info, 512, 256, 8, 0);
1224  pwrap=M205PW;
1225  cwrap=M205CW;
1226  info->Power=M205Power;
1227  info->Reset=M205Reset;
1228  AddExState(EXPREGS, 1, 0, "EXPR");
1229 }
1230
1231 // ---------------------------- Mapper 215 ------------------------------
1232
1233 static uint8 m215_perm[8] = {0, 2, 5, 3, 6, 1, 7, 4};
1234
1235 static void M215CW(uint32 A, uint8 V)
1236 {
1237  if(EXPREGS[1]&0x04)
1238    setchr1(A,V|0x100);
1239  else
1240    setchr1(A,(V&0x7F)|((EXPREGS[1]&0x10)<<3));
1241 }
1242
1243 static void M215PW(uint32 A, uint8 V)
1244 {
1245  if(EXPREGS[0]&0x80)
1246  {
1247    setprg16(0x8000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
1248    setprg16(0xC000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
1249  }
1250  else if(EXPREGS[1]&0x08)
1251         setprg8(A,(V&0x1F)|0x20);
1252       else
1253         setprg8(A,(V&0x0F)|(EXPREGS[1]&0x10));
1254 }
1255
1256 static DECLFW(M215Write)
1257 {
1258  if(!(EXPREGS[2]))
1259  {
1260   if(A >= 0xc000)
1261    MMC3_IRQWrite(A,V);
1262   else
1263    MMC3_CMDWrite(A,V);
1264  }
1265  else switch(A&0xE001)
1266  {
1267   case 0xC001: IRQLatch=V; break;
1268   case 0xA001: IRQReload=1; break;
1269   case 0xE001: IRQa=1; break;
1270   case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
1271   case 0xC000: setmirror(((V|(V>>7))&1)^1); break;
1272   case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m215_perm[V&7])); cmdin=1; break;
1273   case 0x8001: if(!cmdin) break;
1274                MMC3_CMDWrite(0x8001,V);
1275                cmdin=0;
1276                break;
1277  }
1278 }
1279
1280 static DECLFW(M215ExWrite)
1281 {
1282  switch(A)
1283  {
1284   case 0x5000:
1285        EXPREGS[0]=V;
1286        FixMMC3PRG(MMC3_cmd);
1287        break;
1288   case 0x5001:
1289        EXPREGS[1]=V;
1290        FixMMC3CHR(MMC3_cmd);
1291        break;
1292   case 0x5007:
1293        EXPREGS[2]=V;
1294        MMC3RegReset();
1295        break;
1296  }
1297 }
1298
1299 static void M215Power(void)
1300 {
1301  EXPREGS[0]=0;
1302  EXPREGS[1]=0xFF;
1303  EXPREGS[2]=4;
1304  GenMMC3Power();
1305  SetWriteHandler(0x8000,0xFFFF,M215Write);
1306  SetWriteHandler(0x5000,0x7FFF,M215ExWrite);
1307 }
1308
1309 void Mapper215_Init(CartInfo *info)
1310 {
1311  GenMMC3_Init(info, 256, 256, 0, 0);
1312  cwrap=M215CW;
1313  pwrap=M215PW;
1314  info->Power=M215Power;
1315  AddExState(EXPREGS, 3, 0, "EXPR");
1316  AddExState(&cmdin, 1, 0, "CMDIN");
1317 }
1318
1319 // ---------------------------- Mapper 217 ------------------------------
1320
1321 static uint8 m217_perm[8] = {0, 6, 3, 7, 5, 2, 4, 1};
1322
1323 static void M217CW(uint32 A, uint8 V)
1324 {
1325  if(EXPREGS[1]&0x08)
1326    setchr1(A,V|((EXPREGS[1]&3)<<8));
1327  else
1328    setchr1(A,(V&0x7F)|((EXPREGS[1]&3)<<8)|((EXPREGS[1]&0x10)<<3));
1329 }
1330
1331 static void M217PW(uint32 A, uint8 V)
1332 {
1333  if(EXPREGS[0]&0x80)
1334  {
1335    setprg16(0x8000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
1336    setprg16(0xC000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
1337  }
1338  else if(EXPREGS[1]&0x08)
1339         setprg8(A,(V&0x1F)|((EXPREGS[1]&3)<<5));
1340       else
1341         setprg8(A,(V&0x0F)|((EXPREGS[1]&3)<<5)|(EXPREGS[1]&0x10));
1342 }
1343
1344 static DECLFW(M217Write)
1345 {
1346  if(!EXPREGS[2])
1347  {
1348   if(A >= 0xc000)
1349     MMC3_IRQWrite(A, V);
1350   else
1351     MMC3_CMDWrite(A,V);
1352  }
1353  else switch(A&0xE001)
1354  {
1355    case 0x8000: IRQCount=V; break;
1356    case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
1357    case 0xC001: IRQa=1; break;
1358    case 0xA001: setmirror((V&1)^1); break;
1359    case 0x8001: MMC3_CMDWrite(0x8000,(V&0xC0)|(m217_perm[V&7])); cmdin=1; break;
1360    case 0xA000: if(!cmdin) break;
1361                 MMC3_CMDWrite(0x8001,V);
1362                 cmdin=0;
1363                 break;
1364  }
1365 }
1366
1367 static DECLFW(M217ExWrite)
1368 {
1369  switch(A)
1370  {
1371   case 0x5000:
1372        EXPREGS[0]=V;
1373        FixMMC3PRG(MMC3_cmd);
1374        break;
1375   case 0x5001:
1376        EXPREGS[1]=V;
1377        FixMMC3PRG(MMC3_cmd);
1378        break;
1379   case 0x5007:
1380        EXPREGS[2]=V;
1381        break;
1382  }
1383 }
1384
1385 static void M217Power(void)
1386 {
1387  EXPREGS[0]=0;
1388  EXPREGS[1]=0xFF;
1389  EXPREGS[2]=3;
1390  GenMMC3Power();
1391  SetWriteHandler(0x8000,0xFFFF,M217Write);
1392  SetWriteHandler(0x5000,0x7FFF,M217ExWrite);
1393 }
1394
1395 void Mapper217_Init(CartInfo *info)
1396 {
1397  GenMMC3_Init(info, 256, 256, 0, 0);
1398  cwrap=M217CW;
1399  pwrap=M217PW;
1400  info->Power=M217Power;
1401  AddExState(EXPREGS, 3, 0, "EXPR");
1402  AddExState(&cmdin, 1, 0, "CMDIN");
1403 }
1404
1405 // ---------------------------- Mapper 245 ------------------------------
1406
1407 static void M245CW(uint32 A, uint8 V)
1408 {
1409  setchr1(A,V&7);
1410  EXPREGS[0]=V;
1411  FixMMC3PRG(MMC3_cmd);
1412 }
1413
1414 static void M245PW(uint32 A, uint8 V)
1415 {
1416  setprg8(A,(V&0x3F)|((EXPREGS[0]&2)<<5));
1417 }
1418
1419 static void M245Power(void)
1420 {
1421  EXPREGS[0]=0;
1422  GenMMC3Power();
1423 }
1424
1425 void Mapper245_Init(CartInfo *info)
1426 {
1427  GenMMC3_Init(info, 512, 256, 8, info->battery);
1428  cwrap=M245CW;
1429  pwrap=M245PW;
1430  info->Power=M245Power;
1431  AddExState(EXPREGS, 1, 0, "EXPR");
1432 }
1433
1434 // ---------------------------- Mapper 249 ------------------------------
1435
1436 static void M249PW(uint32 A, uint8 V)
1437 {
1438  if(EXPREGS[0]&0x2)
1439  {
1440   if(V<0x20)
1441    V=(V&1)|((V>>3)&2)|((V>>1)&4)|((V<<2)&8)|((V<<2)&0x10);
1442   else
1443   {
1444    V-=0x20;
1445    V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1446   }
1447  }
1448  setprg8(A,V);
1449 }
1450
1451 static void M249CW(uint32 A, uint8 V)
1452 {
1453  if(EXPREGS[0]&0x2)
1454     V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1455  setchr1(A,V);
1456 }
1457
1458 static DECLFW(M249Write)
1459 {
1460  EXPREGS[0]=V;
1461  FixMMC3PRG(MMC3_cmd);
1462  FixMMC3CHR(MMC3_cmd);
1463 }
1464
1465 static void M249Power(void)
1466 {
1467  EXPREGS[0]=0;
1468  GenMMC3Power();
1469  SetWriteHandler(0x5000,0x5000,M249Write);
1470 }
1471
1472 void Mapper249_Init(CartInfo *info)
1473 {
1474  GenMMC3_Init(info, 512, 256, 8, info->battery);
1475  cwrap=M249CW;
1476  pwrap=M249PW;
1477  info->Power=M249Power;
1478  AddExState(EXPREGS, 1, 0, "EXPR");
1479 }
1480
1481 // ---------------------------- Mapper 250 ------------------------------
1482
1483 static DECLFW(M250Write)
1484 {
1485  MMC3_CMDWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1486 }
1487
1488 static DECLFW(M250IRQWrite)
1489 {
1490  MMC3_IRQWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1491 }
1492
1493 static void M250_Power(void)
1494 {
1495  GenMMC3Power();
1496  SetWriteHandler(0x8000,0xBFFF,M250Write);
1497  SetWriteHandler(0xC000,0xFFFF,M250IRQWrite);
1498 }
1499
1500 void Mapper250_Init(CartInfo *info)
1501 {
1502  GenMMC3_Init(info, 512, 256, 8, info->battery);
1503  info->Power=M250_Power;
1504 }
1505
1506 // ---------------------------- Mapper 254 ------------------------------
1507
1508 static DECLFR(MR254WRAM)
1509 {
1510   if(EXPREGS[0])
1511     return WRAM[A-0x6000];
1512   else
1513     return WRAM[A-0x6000]^EXPREGS[1];
1514 }
1515
1516 static DECLFW(M254Write)
1517 {
1518  switch (A) {
1519   case 0x8000: EXPREGS[0]=0xff;
1520                break;
1521   case 0xA001: EXPREGS[1]=V;
1522  }
1523  MMC3_CMDWrite(A,V);
1524 }
1525
1526 static void M254_Power(void)
1527 {
1528  GenMMC3Power();
1529  SetWriteHandler(0x8000,0xBFFF,M254Write);
1530  SetReadHandler(0x6000,0x7FFF,MR254WRAM);
1531 }
1532
1533 void Mapper254_Init(CartInfo *info)
1534 {
1535  GenMMC3_Init(info, 128, 128, 8, info->battery);
1536  info->Power=M254_Power;
1537  AddExState(EXPREGS, 2, 0, "EXPR");
1538 }
1539
1540 // ---------------------------- UNIF Boards -----------------------------
1541
1542 void TEROM_Init(CartInfo *info)
1543 {
1544  GenMMC3_Init(info, 32, 32, 0, 0);
1545 }
1546
1547 void TFROM_Init(CartInfo *info)
1548 {
1549  GenMMC3_Init(info, 512, 64, 0, 0);
1550 }
1551
1552 void TGROM_Init(CartInfo *info)
1553 {
1554  GenMMC3_Init(info, 512, 0, 0, 0);
1555 }
1556
1557 void TKROM_Init(CartInfo *info)
1558 {
1559  GenMMC3_Init(info, 512, 256, 8, info->battery);
1560 }
1561
1562 void TLROM_Init(CartInfo *info)
1563 {
1564  GenMMC3_Init(info, 512, 256, 0, 0);
1565 }
1566
1567 void TSROM_Init(CartInfo *info)
1568 {
1569  GenMMC3_Init(info, 512, 256, 8, 0);
1570 }
1571
1572 void TLSROM_Init(CartInfo *info)
1573 {
1574  GenMMC3_Init(info, 512, 256, 8, 0);
1575  cwrap=TKSWRAP;
1576  mwrap=GENNOMWRAP;
1577  PPU_hook=TKSPPU;
1578  AddExState(&PPUCHRBus, 1, 0, "PPUC");
1579 }
1580
1581 void TKSROM_Init(CartInfo *info)
1582 {
1583  GenMMC3_Init(info, 512, 256, 8, info->battery);
1584  cwrap=TKSWRAP;
1585  mwrap=GENNOMWRAP;
1586  PPU_hook=TKSPPU;
1587  AddExState(&PPUCHRBus, 1, 0, "PPUC");
1588 }
1589
1590 void TQROM_Init(CartInfo *info)
1591 {
1592  GenMMC3_Init(info, 512, 64, 0, 0);
1593  cwrap=TQWRAP;
1594  CHRRAMSize=8192;
1595  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1596  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1597 }
1598
1599 void HKROM_Init(CartInfo *info)
1600 {
1601  GenMMC3_Init(info, 512, 512, 1, info->battery);
1602 }