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