compat hacks for this old version of fceu
[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,165,205,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 DRegBuf[8];
35 uint8 EXPREGS[8];    /* For bootleg games, mostly. */
36 uint8 A000B,A001B;
37 int mmc3opts=0;
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 wrams;
59 static int isRevB=1;
60
61 void (*pwrap)(uint32 A, uint8 V);
62 void (*cwrap)(uint32 A, uint8 V);
63 void (*mwrap)(uint8 V);
64
65 void GenMMC3Power(void);
66 void FixMMC3PRG(int V);
67 void FixMMC3CHR(int V);
68
69 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
70
71 // ----------------------------------------------------------------------
72 // ------------------------- Generic MM3 Code ---------------------------
73 // ----------------------------------------------------------------------
74
75 void FixMMC3PRG(int V)
76 {
77  if(V&0x40)
78  {
79   pwrap(0xC000,DRegBuf[6]);
80   pwrap(0x8000,~1);
81  }
82  else
83  {
84   pwrap(0x8000,DRegBuf[6]);
85   pwrap(0xC000,~1);
86  }
87  pwrap(0xA000,DRegBuf[7]);
88  pwrap(0xE000,~0);
89 }
90
91 void FixMMC3CHR(int V)
92 {
93  int cbase=(V&0x80)<<5;
94
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);
99
100  cwrap(cbase^0x1000,DRegBuf[2]);
101  cwrap(cbase^0x1400,DRegBuf[3]);
102  cwrap(cbase^0x1800,DRegBuf[4]);
103  cwrap(cbase^0x1c00,DRegBuf[5]);
104
105  if(mwrap) mwrap(A000B);
106 }
107
108 void MMC3RegReset(void)
109 {
110  IRQCount=IRQLatch=IRQa=MMC3_cmd=0;
111
112  DRegBuf[0]=0;
113  DRegBuf[1]=2;
114  DRegBuf[2]=4;
115  DRegBuf[3]=5;
116  DRegBuf[4]=6;
117  DRegBuf[5]=7;
118  DRegBuf[6]=0;
119  DRegBuf[7]=1;
120
121  FixMMC3PRG(0);
122  FixMMC3CHR(0);
123 }
124
125 DECLFW(MMC3_CMDWrite)
126 {
127 // FCEU_printf("bs %04x %02x\n",A,V);
128  switch(A&0xE001)
129  {
130   case 0x8000:
131        if((V&0x40) != (MMC3_cmd&0x40))
132           FixMMC3PRG(V);
133        if((V&0x80) != (MMC3_cmd&0x80))
134           FixMMC3CHR(V);
135        MMC3_cmd = V;
136        break;
137   case 0x8001:
138        {
139         int cbase=(MMC3_cmd&0x80)<<5;
140         DRegBuf[MMC3_cmd&0x7]=V;
141         switch(MMC3_cmd&0x07)
142         {
143          case 0: cwrap((cbase^0x000),V&(~1));
144                  cwrap((cbase^0x400),V|1);
145                  break;
146          case 1: cwrap((cbase^0x800),V&(~1));
147                  cwrap((cbase^0xC00),V|1);
148                  break;
149          case 2: cwrap(cbase^0x1000,V);
150                  break;
151          case 3: cwrap(cbase^0x1400,V);
152                  break;
153          case 4: cwrap(cbase^0x1800,V);
154                  break;
155          case 5: cwrap(cbase^0x1C00,V);
156                  break;
157          case 6:
158                  if(MMC3_cmd&0x40)
159                     pwrap(0xC000,V);
160                  else
161                     pwrap(0x8000,V);
162                  break;
163          case 7:
164                  pwrap(0xA000,V);
165                  break;
166         }
167        }
168        break;
169   case 0xA000:
170        if(mwrap) mwrap(V);
171        break;
172   case 0xA001:
173        A001B=V;
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  FixMMC3PRG(MMC3_cmd);
229  FixMMC3CHR(MMC3_cmd);
230 }
231
232 static void GENCWRAP(uint32 A, uint8 V)
233 {
234    setchr1(A,V);    // Business Wars NEEDS THIS for 8K CHR-RAM
235 }
236
237 static void GENPWRAP(uint32 A, uint8 V)
238 {
239  setprg8(A,V&0x7F); // [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken
240 }
241
242 static void GENMWRAP(uint8 V)
243 {
244  A000B=V;
245  setmirror((V&1)^1);
246 }
247
248 static void GENNOMWRAP(uint8 V)
249 {
250  A000B=V;
251 }
252
253 static DECLFW(MBWRAMMMC6)
254 {
255  WRAM[A&0x3ff]=V;
256 }
257
258 static DECLFR(MAWRAMMMC6)
259 {
260  return(WRAM[A&0x3ff]);
261 }
262
263 void GenMMC3Power(void)
264 {
265  if(UNIFchrrama) setchr8(0);
266
267  SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
268  SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
269  SetReadHandler(0x8000,0xFFFF,CartBR);
270  A001B=A000B=0;
271  setmirror(1);
272  if(mmc3opts&1)
273  {
274   if(wrams==1024)
275   {
276    FCEU_CheatAddRAM(1,0x7000,WRAM);
277    SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
278    SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
279 #ifdef ASM_6502
280    // asm code needs pages to be set again..
281    Page[14]=WRAM-0x7000;
282    Page[15]=WRAM-0x7800;
283 #endif
284   }
285   else
286   {
287    FCEU_CheatAddRAM((wrams&0x1fff)>>10,0x6000,WRAM);
288    SetWriteHandler(0x6000,0x6000 + ((wrams - 1) & 0x1fff),CartBW);
289    SetReadHandler(0x6000,0x6000 + ((wrams - 1) & 0x1fff),CartBR);
290    setprg8r(0x10,0x6000,0);
291   }
292   if(!(mmc3opts&2))
293      FCEU_dwmemset(WRAM,0,wrams);
294  }
295  MMC3RegReset();
296  if(CHRRAM)
297    FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
298 }
299
300 static void GenMMC3Close(void)
301 {
302  if(CHRRAM)
303     FCEU_gfree(CHRRAM);
304  if(WRAM)
305     FCEU_gfree(WRAM);
306  CHRRAM=WRAM=NULL;
307 }
308
309 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
310 {
311  pwrap=GENPWRAP;
312  cwrap=GENCWRAP;
313  mwrap=GENMWRAP;
314
315  wrams=wram<<10;
316
317  PRGmask8[0]&=(prg>>13)-1;
318  CHRmask1[0]&=(chr>>10)-1;
319  CHRmask2[0]&=(chr>>11)-1;
320
321  if(wram)
322  {
323   mmc3opts|=1;
324   WRAM=(uint8*)FCEU_gmalloc(wrams);
325   SetupCartPRGMapping(0x10,WRAM,wrams,1);
326   AddExState(WRAM, wrams, 0, "MRAM");
327  }
328
329  if(battery)
330  {
331   mmc3opts|=2;
332   info->SaveGame[0]=WRAM;
333   info->SaveGameLen[0]=wrams;
334  }
335
336  AddExState(MMC3_StateRegs, ~0, 0, 0);
337
338  info->Power=GenMMC3Power;
339  info->Reset=MMC3RegReset;
340  info->Close=GenMMC3Close;
341
342  if(info->CRC32 == 0x5104833e)        // Kick Master
343   GameHBIRQHook = MMC3_hb_KickMasterHack;
344  else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
345   GameHBIRQHook = MMC3_hb_KickMasterHack;
346  else if(info->CRC32 == 0xfcd772eb)    // PAL Star Wars, similar problem as Kick Master.
347   GameHBIRQHook = MMC3_hb_PALStarWarsHack;
348  else
349   GameHBIRQHook=MMC3_hb;
350  GameStateRestore=GenMMC3Restore;
351 }
352
353 // ----------------------------------------------------------------------
354 // -------------------------- MMC3 Based Code ---------------------------
355 // ----------------------------------------------------------------------
356
357 // ---------------------------- Mapper 4 --------------------------------
358
359 static int hackm4=0;/* For Karnov, maybe others.  BLAH.  Stupid iNES format.*/
360
361 static void M4Power(void)
362 {
363  GenMMC3Power();
364  A000B=(hackm4^1)&1;
365  setmirror(hackm4);
366 }
367
368 void Mapper4_Init(CartInfo *info)
369 {
370  int ws=8;
371
372  if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
373  {
374   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");
375   ws=0;
376  }
377  GenMMC3_Init(info,512,256,ws,info->battery);
378  info->Power=M4Power;
379  hackm4=info->mirror;
380 }
381
382 // ---------------------------- Mapper 12 -------------------------------
383
384 static void M12CW(uint32 A, uint8 V)
385 {
386  setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
387 }
388
389 static DECLFW(M12Write)
390 {
391  EXPREGS[0]=V&0x01;
392  EXPREGS[1]=(V&0x10)>>4;
393 }
394
395 static void M12Power(void)
396 {
397  EXPREGS[0]=EXPREGS[1]=0;
398  GenMMC3Power();
399  SetWriteHandler(0x4100,0x5FFF,M12Write);
400 }
401
402 void Mapper12_Init(CartInfo *info)
403 {
404  GenMMC3_Init(info, 512, 256, 8, info->battery);
405  cwrap=M12CW;
406  info->Power=M12Power;
407  AddExState(EXPREGS, 2, 0, "EXPR");
408 }
409
410 // ---------------------------- Mapper 37 -------------------------------
411
412 static void M37PW(uint32 A, uint8 V)
413 {
414   if(EXPREGS[0]!=2)
415     V&=0x7;
416   else
417     V&=0xF;
418   V|=EXPREGS[0]<<3;
419   setprg8(A,V);
420 }
421
422 static void M37CW(uint32 A, uint8 V)
423 {
424   uint32 NV=V;
425   NV&=0x7F;
426   NV|=EXPREGS[0]<<6;
427   setchr1(A,NV);
428 }
429
430 static DECLFW(M37Write)
431 {
432   EXPREGS[0]=(V&6)>>1;
433   FixMMC3PRG(MMC3_cmd);
434   FixMMC3CHR(MMC3_cmd);
435 }
436
437 static void M37Reset(void)
438 {
439   EXPREGS[0]=0;
440   MMC3RegReset();
441 }
442
443 static void M37Power(void)
444 {
445   EXPREGS[0]=0;
446   GenMMC3Power();
447   SetWriteHandler(0x6000,0x7FFF,M37Write);
448 }
449
450 void Mapper37_Init(CartInfo *info)
451 {
452   GenMMC3_Init(info, 512, 256, 8, info->battery);
453   pwrap=M37PW;
454   cwrap=M37CW;
455   info->Power=M37Power;
456   info->Reset=M37Reset;
457   AddExState(EXPREGS, 1, 0, "EXPR");
458 }
459
460 // ---------------------------- Mapper 44 -------------------------------
461
462 static void M44PW(uint32 A, uint8 V)
463 {
464  uint32 NV=V;
465  if(EXPREGS[0]>=6) NV&=0x1F;
466  else NV&=0x0F;
467  NV|=EXPREGS[0]<<4;
468  setprg8(A,NV);
469 }
470
471 static void M44CW(uint32 A, uint8 V)
472 {
473  uint32 NV=V;
474  if(EXPREGS[0]<6) NV&=0x7F;
475  NV|=EXPREGS[0]<<7;
476  setchr1(A,NV);
477 }
478
479 static DECLFW(M44Write)
480 {
481  if(A&1)
482  {
483   EXPREGS[0]=V&7;
484   FixMMC3PRG(MMC3_cmd);
485   FixMMC3CHR(MMC3_cmd);
486  }
487  else
488   MMC3_CMDWrite(A,V);
489 }
490
491 static void M44Power(void)
492 {
493  EXPREGS[0]=0;
494  GenMMC3Power();
495  SetWriteHandler(0xA000,0xBFFF,M44Write);
496 }
497
498 void Mapper44_Init(CartInfo *info)
499 {
500  GenMMC3_Init(info, 512, 256, 8, info->battery);
501  cwrap=M44CW;
502  pwrap=M44PW;
503  info->Power=M44Power;
504  AddExState(EXPREGS, 1, 0, "EXPR");
505 }
506
507 // ---------------------------- Mapper 45 -------------------------------
508
509 static void M45CW(uint32 A, uint8 V)
510 {
511  if(!UNIFchrrama)
512  {
513    uint32 NV=V;
514    if(EXPREGS[2]&8)
515       NV&=(1<<((EXPREGS[2]&7)+1))-1;
516    else
517       if(EXPREGS[2])
518          NV&=0; // hack ;( don't know exactly how it should be
519    NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
520    setchr1(A,NV);
521  }
522 }
523
524 static void M45PW(uint32 A, uint8 V)
525 {
526  V&=(EXPREGS[3]&0x3F)^0x3F;
527  V|=EXPREGS[1];
528  setprg8(A,V);
529 }
530
531 static DECLFW(M45Write)
532 {
533  if(EXPREGS[3]&0x40)
534  {
535   WRAM[A-0x6000]=V;
536   return;
537  }
538  EXPREGS[EXPREGS[4]]=V;
539  EXPREGS[4]=(EXPREGS[4]+1)&3;
540 // if(!EXPREGS[4])
541 // {
542 //   FCEU_printf("CHROR %02x, PRGOR %02x, CHRAND %02x, PRGAND %02x\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3]);
543 //   FCEU_printf("CHR0 %03x, CHR1 %03x, PRG0 %03x, PRG1 %03x\n",
544 //               (0x00&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
545 //               (0xFF&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
546 //               (0x00&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]),
547 //               (0xFF&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]));
548 // }
549  FixMMC3PRG(MMC3_cmd);
550  FixMMC3CHR(MMC3_cmd);
551 }
552
553 static DECLFR(M45Read)
554 {
555   uint32 addr = 1<<(EXPREGS[5]+4);
556   if(A&(addr|(addr-1)))
557     return X.DB | 1;
558   else
559     return X.DB;
560 }
561
562 static void M45Reset(void)
563 {
564  EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
565  EXPREGS[5]++;
566  EXPREGS[5] &= 7;
567  MMC3RegReset();
568 }
569
570 static void M45Power(void)
571 {
572  setchr8(0);
573  GenMMC3Power();
574  EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=EXPREGS[5]=0;
575  SetWriteHandler(0x5000,0x7FFF,M45Write);
576  SetReadHandler(0x5000,0x5FFF,M45Read);
577 }
578
579 void Mapper45_Init(CartInfo *info)
580 {
581  GenMMC3_Init(info, 512, 256, 8, info->battery);
582  cwrap=M45CW;
583  pwrap=M45PW;
584  info->Reset=M45Reset;
585  info->Power=M45Power;
586  AddExState(EXPREGS, 5, 0, "EXPR");
587 }
588
589 // ---------------------------- Mapper 47 -------------------------------
590
591 static void M47PW(uint32 A, uint8 V)
592 {
593  V&=0xF;
594  V|=EXPREGS[0]<<4;
595  setprg8(A,V);
596 }
597
598 static void M47CW(uint32 A, uint8 V)
599 {
600  uint32 NV=V;
601  NV&=0x7F;
602  NV|=EXPREGS[0]<<7;
603  setchr1(A,NV);
604 }
605
606 static DECLFW(M47Write)
607 {
608  EXPREGS[0]=V&1;
609  FixMMC3PRG(MMC3_cmd);
610  FixMMC3CHR(MMC3_cmd);
611 }
612
613 static void M47Power(void)
614 {
615  EXPREGS[0]=0;
616  GenMMC3Power();
617  SetWriteHandler(0x6000,0x7FFF,M47Write);
618 // SetReadHandler(0x6000,0x7FFF,0);
619 }
620
621 void Mapper47_Init(CartInfo *info)
622 {
623  GenMMC3_Init(info, 512, 256, 8, 0);
624  pwrap=M47PW;
625  cwrap=M47CW;
626  info->Power=M47Power;
627  AddExState(EXPREGS, 1, 0, "EXPR");
628 }
629
630 // ---------------------------- Mapper 49 -------------------------------
631
632 static void M49PW(uint32 A, uint8 V)
633 {
634  if(EXPREGS[0]&1)
635  {
636   V&=0xF;
637   V|=(EXPREGS[0]&0xC0)>>2;
638   setprg8(A,V);
639  }
640  else
641   setprg32(0x8000,(EXPREGS[0]>>4)&3);
642 }
643
644 static void M49CW(uint32 A, uint8 V)
645 {
646  uint32 NV=V;
647  NV&=0x7F;
648  NV|=(EXPREGS[0]&0xC0)<<1;
649  setchr1(A,NV);
650 }
651
652 static DECLFW(M49Write)
653 {
654  if(A001B&0x80)
655  {
656   EXPREGS[0]=V;
657   FixMMC3PRG(MMC3_cmd);
658   FixMMC3CHR(MMC3_cmd);
659  }
660 }
661
662 static void M49Reset(void)
663 {
664  EXPREGS[0]=0;
665  MMC3RegReset();
666 }
667
668 static void M49Power(void)
669 {
670  M49Reset();
671  GenMMC3Power();
672  SetWriteHandler(0x6000,0x7FFF,M49Write);
673  SetReadHandler(0x6000,0x7FFF,0);
674 }
675
676 void Mapper49_Init(CartInfo *info)
677 {
678  GenMMC3_Init(info, 512, 256, 0, 0);
679  cwrap=M49CW;
680  pwrap=M49PW;
681  info->Reset=M49Reset;
682  info->Power=M49Power;
683  AddExState(EXPREGS, 1, 0, "EXPR");
684 }
685
686 // ---------------------------- Mapper 52 -------------------------------
687 static void M52PW(uint32 A, uint8 V)
688 {
689  uint32 mask = 0x1F^((EXPREGS[0]&8)<<1);
690  uint32 bank = ((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
691  setprg8(A, bank|(V & mask));
692 }
693
694 static void M52CW(uint32 A, uint8 V)
695 {
696  uint32 mask = 0xFF^((EXPREGS[0]&0x40)<<1);
697 // uint32 bank = (((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
698  uint32 bank = (((EXPREGS[0]>>4)&2)|(EXPREGS[0]&4)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7; // actually 256K CHR banks index bits is inverted!
699  setchr1(A, bank|(V & mask));
700 }
701
702 static DECLFW(M52Write)
703 {
704  if(EXPREGS[1])
705  {
706   WRAM[A-0x6000]=V;
707   return;
708  }
709  EXPREGS[1]=V&0x80;
710  EXPREGS[0]=V;
711  FixMMC3PRG(MMC3_cmd);
712  FixMMC3CHR(MMC3_cmd);
713 }
714
715 static void M52Reset(void)
716 {
717  EXPREGS[0]=EXPREGS[1]=0;
718  MMC3RegReset();
719 }
720
721 static void M52Power(void)
722 {
723  M52Reset();
724  GenMMC3Power();
725  SetWriteHandler(0x6000,0x7FFF,M52Write);
726 }
727
728 void Mapper52_Init(CartInfo *info)
729 {
730  GenMMC3_Init(info, 256, 256, 8, info->battery);
731  cwrap=M52CW;
732  pwrap=M52PW;
733  info->Reset=M52Reset;
734  info->Power=M52Power;
735  AddExState(EXPREGS, 2, 0, "EXPR");
736 }
737
738 // ---------------------------- Mapper 74 -------------------------------
739
740 static void M74CW(uint32 A, uint8 V)
741 {
742   if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
743     setchr1r(0x10,A,V);
744   else
745     setchr1r(0,A,V);
746 }
747
748 void Mapper74_Init(CartInfo *info)
749 {
750  GenMMC3_Init(info, 512, 256, 8, info->battery);
751  cwrap=M74CW;
752  CHRRAMSize=2048;
753  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
754  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
755  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
756 }
757
758 // ---------------------------- Mapper 114 ------------------------------
759
760 static uint8 cmdin;
761 uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
762
763 static void M114PWRAP(uint32 A, uint8 V)
764 {
765   if(EXPREGS[0]&0x80)
766   {
767 //    FCEU_printf("8000-C000:%02X\n",EXPREGS[0]&0xF);
768     setprg16(0x8000,EXPREGS[0]&0xF);
769     setprg16(0xC000,EXPREGS[0]&0xF);
770   }
771   else {
772 //    FCEU_printf("%04X:%02X\n",A,V&0x3F);
773     setprg8(A,V&0x3F);
774   }
775 }
776
777 static DECLFW(M114Write)
778 {
779   switch(A&0xE001)
780   {
781    case 0x8001: MMC3_CMDWrite(0xA000,V); break;
782    case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
783    case 0xC000: if(!cmdin) break; MMC3_CMDWrite(0x8001,V); cmdin=0; break;
784    case 0xA001: IRQLatch=V; break;
785    case 0xC001: IRQReload=1; break;
786    case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
787    case 0xE001: IRQa=1; break;
788   }
789 }
790
791 static DECLFW(M114ExWrite)
792 {
793   if(A<=0x7FFF)
794   {
795     EXPREGS[0]=V;
796     FixMMC3PRG(MMC3_cmd);
797   }
798 }
799
800 static void M114Power(void)
801 {
802   GenMMC3Power();
803   SetWriteHandler(0x8000,0xFFFF,M114Write);
804   SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
805 }
806
807 static void M114Reset(void)
808 {
809   EXPREGS[0]=0;
810   MMC3RegReset();
811 }
812
813 void Mapper114_Init(CartInfo *info)
814 {
815   isRevB=0;
816   GenMMC3_Init(info, 256, 256, 0, 0);
817   pwrap=M114PWRAP;
818   info->Power=M114Power;
819   info->Reset=M114Reset;
820   AddExState(EXPREGS, 1, 0, "EXPR");
821   AddExState(&cmdin, 1, 0, "CMDI");
822 }
823
824 // ---------------------------- Mapper 115 KN-658 board ------------------------------
825
826 static void M115PW(uint32 A, uint8 V)
827 {
828   if(EXPREGS[0]&0x80)
829     setprg32(0x8000,(EXPREGS[0]&7)>>1);
830   else
831     setprg8(A,V);
832 }
833
834 static void M115CW(uint32 A, uint8 V)
835 {
836   setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
837 }
838
839 static DECLFW(M115Write)
840 {
841 // FCEU_printf("%04x:%04x\n",A,V);
842  if(A==0x5080) EXPREGS[2]=V;
843  if(A==0x6000)
844     EXPREGS[0]=V;
845  else if(A==0x6001)
846     EXPREGS[1]=V;
847  FixMMC3PRG(MMC3_cmd);
848 }
849
850 static DECLFR(M115Read)
851 {
852  return EXPREGS[2];
853 }
854
855 static void M115Power(void)
856 {
857  GenMMC3Power();
858  SetWriteHandler(0x4100,0x7FFF,M115Write);
859  SetReadHandler(0x5000,0x5FFF,M115Read);
860 }
861
862 void Mapper115_Init(CartInfo *info)
863 {
864  GenMMC3_Init(info, 128, 512, 0, 0);
865  cwrap=M115CW;
866  pwrap=M115PW;
867  info->Power=M115Power;
868  AddExState(EXPREGS, 2, 0, "EXPR");
869 }
870
871 // ---------------------------- Mapper 118 ------------------------------
872
873 static uint8 PPUCHRBus;
874 static uint8 TKSMIR[8];
875
876 static void FP_FASTAPASS(1) TKSPPU(uint32 A)
877 {
878  A&=0x1FFF;
879  A>>=10;
880  PPUCHRBus=A;
881  setmirror(MI_0+TKSMIR[A]);
882 }
883
884 static void TKSWRAP(uint32 A, uint8 V)
885 {
886  TKSMIR[A>>10]=V>>7;
887  setchr1(A,V&0x7F);
888  if(PPUCHRBus==(A>>10))
889     setmirror(MI_0+(V>>7));
890 }
891
892 // ---------------------------- Mapper 119 ------------------------------
893
894 static void TQWRAP(uint32 A, uint8 V)
895 {
896  setchr1r((V&0x40)>>2,A,V&0x3F);
897 }
898
899 void Mapper119_Init(CartInfo *info)
900 {
901  GenMMC3_Init(info, 512, 64, 0, 0);
902  cwrap=TQWRAP;
903  CHRRAMSize=8192;
904  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
905  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
906 }
907
908 // ---------------------------- Mapper 134 ------------------------------
909
910 static void M134PW(uint32 A, uint8 V)
911 {
912   setprg8(A,(V&0x1F)|((EXPREGS[0]&2)<<4));
913 }
914
915 static void M134CW(uint32 A, uint8 V)
916 {
917   setchr1(A,(V&0xFF)|((EXPREGS[0]&0x20)<<3));
918 }
919
920 static DECLFW(M134Write)
921 {
922   EXPREGS[0]=V;
923   FixMMC3CHR(MMC3_cmd);
924   FixMMC3PRG(MMC3_cmd);
925 }
926
927 static void M134Power(void)
928 {
929  EXPREGS[0]=0;
930  GenMMC3Power();
931  SetWriteHandler(0x6001,0x6001,M134Write);
932 }
933
934 static void M134Reset(void)
935 {
936  EXPREGS[0]=0;
937  MMC3RegReset();
938 }
939
940 void Mapper134_Init(CartInfo *info)
941 {
942  GenMMC3_Init(info, 256, 256, 0, 0);
943  pwrap=M134PW;
944  cwrap=M134CW;
945  info->Power=M134Power;
946  info->Reset=M134Reset;
947  AddExState(EXPREGS, 4, 0, "EXPR");
948 }
949
950 // ---------------------------- Mapper 165 ------------------------------
951
952 static void M165CW(uint32 A, uint8 V)
953 {
954  if(V==0)
955     setchr4r(0x10,A,0);
956  else
957     setchr4(A,V>>2);
958 }
959
960 static void M165PPUFD(void)
961 {
962  if(EXPREGS[0]==0xFD)
963  {
964   M165CW(0x0000,DRegBuf[0]);
965   M165CW(0x1000,DRegBuf[2]);
966  }
967 }
968
969 static void M165PPUFE(void)
970 {
971  if(EXPREGS[0]==0xFE)
972  {
973   M165CW(0x0000,DRegBuf[1]);
974   M165CW(0x1000,DRegBuf[4]);
975  }
976 }
977
978 static void M165CWM(uint32 A, uint8 V)
979 {
980  if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2))
981    M165PPUFD();
982  if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4))
983    M165PPUFE();
984 }
985
986 static void FP_FASTAPASS(1) M165PPU(uint32 A)
987 {
988  if((A&0x1FF0)==0x1FD0)
989  {
990   EXPREGS[0]=0xFD;
991   M165PPUFD();
992  } else if((A&0x1FF0)==0x1FE0)
993  {
994   EXPREGS[0]=0xFE;
995   M165PPUFE();
996  }
997 }
998
999 static void M165Power(void)
1000 {
1001  EXPREGS[0]=0xFD;
1002  GenMMC3Power();
1003 }
1004
1005 void Mapper165_Init(CartInfo *info)
1006 {
1007  GenMMC3_Init(info, 512, 128, 8, info->battery);
1008  cwrap=M165CWM;
1009  PPU_hook=M165PPU;
1010  info->Power=M165Power;
1011  CHRRAMSize = 4096;
1012  CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
1013  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1014  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1015  AddExState(EXPREGS, 4, 0, "EXPR");
1016 }
1017
1018 // ---------------------------- Mapper 191 ------------------------------
1019
1020 static void M191CW(uint32 A, uint8 V)
1021 {
1022   setchr1r((V&0x80)>>3,A,V);
1023 }
1024
1025 void Mapper191_Init(CartInfo *info)
1026 {
1027  GenMMC3_Init(info, 256, 256, 8, info->battery);
1028  cwrap=M191CW;
1029  CHRRAMSize=2048;
1030  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1031  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1032  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1033 }
1034
1035 // ---------------------------- Mapper 192 -------------------------------
1036
1037 static void M192CW(uint32 A, uint8 V)
1038 {
1039   if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese),
1040     setchr1r(0x10,A,V);
1041   else
1042     setchr1r(0,A,V);
1043 }
1044
1045 void Mapper192_Init(CartInfo *info)
1046 {
1047  GenMMC3_Init(info, 512, 256, 8, info->battery);
1048  cwrap=M192CW;
1049  CHRRAMSize=4096;
1050  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1051  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1052  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1053 }
1054
1055 // ---------------------------- Mapper 194 -------------------------------
1056
1057 static void M194CW(uint32 A, uint8 V)
1058 {
1059   if(V<=1) //Dai-2-Ji - Super Robot Taisen (As).nes
1060     setchr1r(0x10,A,V);
1061   else
1062     setchr1r(0,A,V);
1063 }
1064
1065 void Mapper194_Init(CartInfo *info)
1066 {
1067  GenMMC3_Init(info, 512, 256, 8, info->battery);
1068  cwrap=M194CW;
1069  CHRRAMSize=2048;
1070  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1071  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1072  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1073 }
1074
1075 // ---------------------------- Mapper 195 -------------------------------
1076 static uint8 *wramtw;
1077 static uint16 wramsize;
1078
1079 static void M195CW(uint32 A, uint8 V)
1080 {
1081   if(V<=3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)
1082     setchr1r(0x10,A,V);
1083   else
1084     setchr1r(0,A,V);
1085 }
1086
1087 static void M195Power(void)
1088 {
1089  GenMMC3Power();
1090  setprg4r(0x10,0x5000,0);
1091  SetWriteHandler(0x5000,0x5fff,CartBW);
1092  SetReadHandler(0x5000,0x5fff,CartBR);
1093 }
1094
1095 static void M195Close(void)
1096 {
1097   if(wramtw)
1098     FCEU_gfree(wramtw);
1099   wramtw=NULL;
1100 }
1101
1102 void Mapper195_Init(CartInfo *info)
1103 {
1104  GenMMC3_Init(info, 512, 256, 8, info->battery);
1105  cwrap=M195CW;
1106  info->Power=M195Power;
1107  info->Close=M195Close;
1108  CHRRAMSize=4096;
1109  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1110  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1111  wramsize=4096;
1112  wramtw=(uint8*)FCEU_gmalloc(wramsize);
1113  SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
1114  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1115  AddExState(wramtw, wramsize, 0, "TRAM");
1116 }
1117
1118 // ---------------------------- Mapper 196 -------------------------------
1119 // MMC3 board with optional command address line connection, allows to
1120 // make three-four different wirings to IRQ address lines and separately to
1121 // CMD address line, Mali Boss additionally check if wiring are correct for
1122 // game
1123
1124 static void M196PW(uint32 A, uint8 V)
1125 {
1126   if(EXPREGS[0]) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
1127     setprg32(0x8000,EXPREGS[1]);
1128   else
1129     setprg8(A,V);
1130 }
1131
1132 static DECLFW(Mapper196Write)
1133 {
1134   if(A >= 0xC000) {
1135    A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1);
1136    MMC3_IRQWrite(A,V);
1137   }
1138   else {
1139    A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1)|((A>>1)&1);
1140    MMC3_CMDWrite(A,V);
1141   }
1142 }
1143
1144 static DECLFW(Mapper196WriteLo)
1145 {
1146   EXPREGS[0]=1;
1147   EXPREGS[1]=(V&0xf)|(V>>4);
1148   FixMMC3PRG(MMC3_cmd);
1149 }
1150
1151 static void Mapper196Power(void)
1152 {
1153   GenMMC3Power();
1154   EXPREGS[0] = EXPREGS[1] = 0;
1155   SetWriteHandler(0x6000,0x6FFF,Mapper196WriteLo);
1156   SetWriteHandler(0x8000,0xFFFF,Mapper196Write);
1157 }
1158
1159 void Mapper196_Init(CartInfo *info)
1160 {
1161   GenMMC3_Init(info, 128, 128, 0, 0);
1162   pwrap=M196PW;
1163   info->Power=Mapper196Power;
1164 }
1165
1166 // ---------------------------- Mapper 197 -------------------------------
1167
1168 static void M197CW(uint32 A, uint8 V)
1169 {
1170   if(A==0x0000)
1171     setchr4(0x0000,V>>1);
1172   else if(A==0x1000)
1173     setchr2(0x1000,V);
1174   else if(A==0x1400)
1175     setchr2(0x1800,V);
1176 }
1177
1178 void Mapper197_Init(CartInfo *info)
1179 {
1180  GenMMC3_Init(info, 128, 512, 8, 0);
1181  cwrap=M197CW;
1182 }
1183
1184 // ---------------------------- Mapper 198 -------------------------------
1185
1186 static void M198PW(uint32 A, uint8 V)
1187 {
1188   if(V>=0x50) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
1189     setprg8(A,V&0x4F);
1190   else
1191     setprg8(A,V);
1192 }
1193
1194 void Mapper198_Init(CartInfo *info)
1195 {
1196  GenMMC3_Init(info, 1024, 256, 8, info->battery);
1197  pwrap=M198PW;
1198  info->Power=M195Power;
1199  info->Close=M195Close;
1200  wramsize=4096;
1201  wramtw=(uint8*)FCEU_gmalloc(wramsize);
1202  SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
1203  AddExState(wramtw, wramsize, 0, "TRAM");
1204 }
1205
1206 // ---------------------------- Mapper 205 ------------------------------
1207 // GN-45 BOARD
1208
1209 static void M205PW(uint32 A, uint8 V)
1210 {
1211 // GN-30A - íà÷àëüíàÿ ìàñêà äîëæíà áûòü 1F + àïïàðàòíûé ïåðåêëþ÷àòåëü íà øèíå àäðåñà
1212  setprg8(A,(V&0x0f)|EXPREGS[0]);
1213 }
1214
1215 static void M205CW(uint32 A, uint8 V)
1216 {
1217 // GN-30A - íà÷àëüíàÿ ìàñêà äîëæíà áûòü FF
1218  setchr1(A,(V&0x7F)|(EXPREGS[0]<<3));
1219 }
1220
1221 static DECLFW(M205Write)
1222 {
1223  if(EXPREGS[2] == 0) {
1224    EXPREGS[0] = A & 0x30;
1225    EXPREGS[2] = A & 0x80;
1226    FixMMC3PRG(MMC3_cmd);
1227    FixMMC3CHR(MMC3_cmd);
1228  }
1229  else
1230    CartBW(A,V);
1231 }
1232
1233 static void M205Reset(void)
1234 {
1235  EXPREGS[0]=EXPREGS[2]=0;
1236  MMC3RegReset();
1237 }
1238
1239 static void M205Power(void)
1240 {
1241  GenMMC3Power();
1242  SetWriteHandler(0x6000,0x6fff,M205Write);
1243 }
1244
1245 void Mapper205_Init(CartInfo *info)
1246 {
1247  GenMMC3_Init(info, 256, 256, 8, 0);
1248  pwrap=M205PW;
1249  cwrap=M205CW;
1250  info->Power=M205Power;
1251  info->Reset=M205Reset;
1252  AddExState(EXPREGS, 1, 0, "EXPR");
1253 }
1254
1255 // ---------------------------- Mapper 245 ------------------------------
1256
1257 static void M245CW(uint32 A, uint8 V)
1258 {
1259  if(!UNIFchrrama) // Yong Zhe Dou E Long - Dragon Quest VI (As).nes NEEDS THIS for RAM cart
1260   setchr1(A,V&7);
1261  EXPREGS[0]=V;
1262  FixMMC3PRG(MMC3_cmd);
1263 }
1264
1265 static void M245PW(uint32 A, uint8 V)
1266 {
1267  setprg8(A,(V&0x3F)|((EXPREGS[0]&2)<<5));
1268 }
1269
1270 static void M245Power(void)
1271 {
1272  EXPREGS[0]=0;
1273  GenMMC3Power();
1274 }
1275
1276 void Mapper245_Init(CartInfo *info)
1277 {
1278  GenMMC3_Init(info, 512, 256, 8, info->battery);
1279  cwrap=M245CW;
1280  pwrap=M245PW;
1281  info->Power=M245Power;
1282  AddExState(EXPREGS, 1, 0, "EXPR");
1283 }
1284
1285 // ---------------------------- Mapper 249 ------------------------------
1286
1287 static void M249PW(uint32 A, uint8 V)
1288 {
1289  if(EXPREGS[0]&0x2)
1290  {
1291   if(V<0x20)
1292    V=(V&1)|((V>>3)&2)|((V>>1)&4)|((V<<2)&8)|((V<<2)&0x10);
1293   else
1294   {
1295    V-=0x20;
1296    V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1297   }
1298  }
1299  setprg8(A,V);
1300 }
1301
1302 static void M249CW(uint32 A, uint8 V)
1303 {
1304  if(EXPREGS[0]&0x2)
1305     V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1306  setchr1(A,V);
1307 }
1308
1309 static DECLFW(M249Write)
1310 {
1311  EXPREGS[0]=V;
1312  FixMMC3PRG(MMC3_cmd);
1313  FixMMC3CHR(MMC3_cmd);
1314 }
1315
1316 static void M249Power(void)
1317 {
1318  EXPREGS[0]=0;
1319  GenMMC3Power();
1320  SetWriteHandler(0x5000,0x5000,M249Write);
1321 }
1322
1323 void Mapper249_Init(CartInfo *info)
1324 {
1325  GenMMC3_Init(info, 512, 256, 8, info->battery);
1326  cwrap=M249CW;
1327  pwrap=M249PW;
1328  info->Power=M249Power;
1329  AddExState(EXPREGS, 1, 0, "EXPR");
1330 }
1331
1332 // ---------------------------- Mapper 250 ------------------------------
1333
1334 static DECLFW(M250Write)
1335 {
1336  MMC3_CMDWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1337 }
1338
1339 static DECLFW(M250IRQWrite)
1340 {
1341  MMC3_IRQWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1342 }
1343
1344 static void M250_Power(void)
1345 {
1346  GenMMC3Power();
1347  SetWriteHandler(0x8000,0xBFFF,M250Write);
1348  SetWriteHandler(0xC000,0xFFFF,M250IRQWrite);
1349 }
1350
1351 void Mapper250_Init(CartInfo *info)
1352 {
1353  GenMMC3_Init(info, 512, 256, 8, info->battery);
1354  info->Power=M250_Power;
1355 }
1356
1357 // ---------------------------- Mapper 254 ------------------------------
1358
1359 static DECLFR(MR254WRAM)
1360 {
1361   if(EXPREGS[0])
1362     return WRAM[A-0x6000];
1363   else
1364     return WRAM[A-0x6000]^EXPREGS[1];
1365 }
1366
1367 static DECLFW(M254Write)
1368 {
1369  switch (A) {
1370   case 0x8000: EXPREGS[0]=0xff;
1371                break;
1372   case 0xA001: EXPREGS[1]=V;
1373  }
1374  MMC3_CMDWrite(A,V);
1375 }
1376
1377 static void M254_Power(void)
1378 {
1379  GenMMC3Power();
1380  SetWriteHandler(0x8000,0xBFFF,M254Write);
1381  SetReadHandler(0x6000,0x7FFF,MR254WRAM);
1382 #ifdef ASM_6502
1383  // hrrr.. can't handle those evil xors here..
1384  Page[12]=Page[13]=Page[14]=Page[15]=WRAM-0x6000;
1385 #endif
1386 }
1387
1388 void Mapper254_Init(CartInfo *info)
1389 {
1390  GenMMC3_Init(info, 128, 128, 8, info->battery);
1391  info->Power=M254_Power;
1392  AddExState(EXPREGS, 2, 0, "EXPR");
1393 }
1394
1395 // ---------------------------- UNIF Boards -----------------------------
1396
1397 void TBROM_Init(CartInfo *info)
1398 {
1399  GenMMC3_Init(info, 64, 64, 0, 0);
1400 }
1401
1402 void TEROM_Init(CartInfo *info)
1403 {
1404  GenMMC3_Init(info, 32, 32, 0, 0);
1405 }
1406
1407 void TFROM_Init(CartInfo *info)
1408 {
1409  GenMMC3_Init(info, 512, 64, 0, 0);
1410 }
1411
1412 void TGROM_Init(CartInfo *info)
1413 {
1414  GenMMC3_Init(info, 512, 0, 0, 0);
1415 }
1416
1417 void TKROM_Init(CartInfo *info)
1418 {
1419  GenMMC3_Init(info, 512, 256, 8, info->battery);
1420 }
1421
1422 void TLROM_Init(CartInfo *info)
1423 {
1424  GenMMC3_Init(info, 512, 256, 0, 0);
1425 }
1426
1427 void TSROM_Init(CartInfo *info)
1428 {
1429  GenMMC3_Init(info, 512, 256, 8, 0);
1430 }
1431
1432 void TLSROM_Init(CartInfo *info)
1433 {
1434  GenMMC3_Init(info, 512, 256, 8, 0);
1435  cwrap=TKSWRAP;
1436  mwrap=GENNOMWRAP;
1437  PPU_hook=TKSPPU;
1438  AddExState(&PPUCHRBus, 1, 0, "PPUC");
1439 }
1440
1441 void TKSROM_Init(CartInfo *info)
1442 {
1443  GenMMC3_Init(info, 512, 256, 8, info->battery);
1444  cwrap=TKSWRAP;
1445  mwrap=GENNOMWRAP;
1446  PPU_hook=TKSPPU;
1447  AddExState(&PPUCHRBus, 1, 0, "PPUC");
1448 }
1449
1450 void TQROM_Init(CartInfo *info)
1451 {
1452  GenMMC3_Init(info, 512, 64, 0, 0);
1453  cwrap=TQWRAP;
1454  CHRRAMSize=8192;
1455  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1456  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1457 }
1458
1459 void HKROM_Init(CartInfo *info)
1460 {
1461  GenMMC3_Init(info, 512, 512, 1, info->battery);
1462 }