updated bords/mappers/stuff to 0.98.15, lots of them got broken, asmcore support...
[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=0;
31 uint8 *WRAM=0;
32 uint8 *CHRRAM=0;
33 uint32 CHRRAMSize=0;
34 uint8 EXPREGS[8]={0,0,0,0,0,0,0,0};    /* For bootleg games, mostly. */
35
36 static uint8 A000B=0,A001B=0;
37 static uint8 DRegBuf[8]={0,0,0,0,0,0,0,0};
38
39 #undef IRQCount
40 #undef IRQLatch
41 #undef IRQa
42 uint8 IRQCount=0,IRQLatch=0,IRQa=0;
43 uint8 IRQReload=0;
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=0;
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
106 void MMC3RegReset(void)
107 {
108  IRQCount=IRQLatch=IRQa=MMC3_cmd=0;
109
110  DRegBuf[0]=0;
111  DRegBuf[1]=2;
112  DRegBuf[2]=4;
113  DRegBuf[3]=5;
114  DRegBuf[4]=6;
115  DRegBuf[5]=7;
116  DRegBuf[6]=0;
117  DRegBuf[7]=1;
118
119  FixMMC3PRG(0);
120  FixMMC3CHR(0);
121 }
122
123 DECLFW(MMC3_CMDWrite)
124 {
125  switch(A&0xE001)
126  {
127   case 0x8000:
128        if((V&0x40) != (MMC3_cmd&0x40))
129           FixMMC3PRG(V);
130        if((V&0x80) != (MMC3_cmd&0x80))
131           FixMMC3CHR(V);
132        MMC3_cmd = V;
133        break;
134   case 0x8001:
135        {
136         int cbase=(MMC3_cmd&0x80)<<5;
137         DRegBuf[MMC3_cmd&0x7]=V;
138         switch(MMC3_cmd&0x07)
139         {
140          case 0: cwrap((cbase^0x000),V&(~1));
141                  cwrap((cbase^0x400),V|1);
142                  break;
143          case 1: cwrap((cbase^0x800),V&(~1));
144                  cwrap((cbase^0xC00),V|1);
145                  break;
146          case 2: cwrap(cbase^0x1000,V);
147                  break;
148          case 3: cwrap(cbase^0x1400,V);
149                  break;
150          case 4: cwrap(cbase^0x1800,V);
151                  break;
152          case 5: cwrap(cbase^0x1C00,V);
153                  break;
154          case 6:
155                  if(MMC3_cmd&0x40)
156                     pwrap(0xC000,V);
157                  else
158                     pwrap(0x8000,V);
159                  break;
160          case 7:
161                  pwrap(0xA000,V);
162                  break;
163         }
164        }
165        break;
166   case 0xA000:
167        if(mwrap) mwrap(V&1);
168        break;
169   case 0xA001:
170        A001B=V;
171        break;
172  }
173 }
174
175 DECLFW(MMC3_IRQWrite)
176 {
177  switch(A&0xE001)
178  {
179   case 0xC000:IRQLatch=V;break;
180   case 0xC001:IRQReload=1;break;
181   case 0xE000:X6502_IRQEnd(FCEU_IQEXT);IRQa=0;break;
182   case 0xE001:IRQa=1;break;
183  }
184 }
185
186 static void ClockMMC3Counter(void)
187 {
188  int count = IRQCount;
189  if(!count || IRQReload)
190  {
191     IRQCount = IRQLatch;
192     IRQReload = 0;
193  }
194  else
195     IRQCount--;
196  if(count && !IRQCount)
197  {
198     if(IRQa)
199     {
200        X6502_IRQBegin(FCEU_IQEXT);
201     }
202  }
203 }
204
205 static void MMC3_hb(void)
206 {
207  ClockMMC3Counter();
208 }
209
210 static void MMC3_hb_KickMasterHack(void)
211 {
212  if(scanline==238) ClockMMC3Counter();
213  ClockMMC3Counter();
214 }
215
216 static void MMC3_hb_PALStarWarsHack(void)
217 {
218  if(scanline==240) ClockMMC3Counter();
219  ClockMMC3Counter();
220 }
221
222 static void genmmc3restore(int version)
223 {
224  if(mwrap) mwrap(A000B&1);
225  FixMMC3PRG(MMC3_cmd);
226  FixMMC3CHR(MMC3_cmd);
227 }
228
229 static void GENCWRAP(uint32 A, uint8 V)
230 {
231  setchr1(A,V);
232 }
233
234 static void GENPWRAP(uint32 A, uint8 V)
235 {
236  setprg8(A,V&0x3F);
237 }
238
239 static void GENMWRAP(uint8 V)
240 {
241  A000B=V;
242  setmirror(V^1);
243 }
244
245 static void GENNOMWRAP(uint8 V)
246 {
247  A000B=V;
248 }
249
250 static DECLFW(MBWRAM)
251 {
252   WRAM[A-0x6000]=V;
253 }
254
255 static DECLFR(MAWRAM)
256 {
257  return(WRAM[A-0x6000]);
258 }
259
260 static DECLFW(MBWRAMMMC6)
261 {
262  WRAM[A&0x3ff]=V;
263 }
264
265 static DECLFR(MAWRAMMMC6)
266 {
267  return(WRAM[A&0x3ff]);
268 }
269
270 void GenMMC3Power(void)
271 {
272  SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
273  SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
274  SetReadHandler(0x8000,0xFFFF,CartBR);
275  A001B=A000B=0;
276  setmirror(1);
277  if(mmc3opts&1)
278  {
279   if(wrams==1024)
280   {
281    FCEU_CheatAddRAM(1,0x7000,WRAM);
282    SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
283    SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
284   }
285   else
286   {
287    FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
288    SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
289    SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
290   }
291   if(!(mmc3opts&2))
292      FCEU_dwmemset(WRAM,0,wrams);
293  }
294  MMC3RegReset();
295  if(CHRRAM)
296   FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
297 }
298
299 static void GenMMC3Close(void)
300 {
301  if(CHRRAM)
302     FCEU_gfree(CHRRAM);
303  if(WRAM)
304     FCEU_gfree(WRAM);
305  CHRRAM=WRAM=NULL;
306 }
307
308 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
309 {
310 pwrap=GENPWRAP;
311  cwrap=GENCWRAP;
312  mwrap=GENMWRAP;
313
314  wrams=wram<<10;
315
316  PRGmask8[0]&=(prg>>13)-1;
317  CHRmask1[0]&=(chr>>10)-1;
318  CHRmask2[0]&=(chr>>11)-1;
319
320  if(wram)
321  {
322   mmc3opts|=1;
323   WRAM=(uint8*)FCEU_gmalloc(wrams);
324   AddExState(WRAM, wrams, 0, "WRAM");
325  }
326
327  if(battery)
328  {
329   mmc3opts|=2;
330   info->SaveGame[0]=WRAM;
331   info->SaveGameLen[0]=wrams;
332  }
333
334  if(!chr)
335  {
336   CHRRAM=(uint8*)FCEU_gmalloc(8192);
337   CHRRAMSize=8192;
338   SetupCartCHRMapping(0, CHRRAM, 8192, 1);
339   AddExState(CHRRAM, 8192, 0, "CHRR");
340  }
341
342  AddExState(MMC3_StateRegs, ~0, 0, 0);
343
344  info->Power=GenMMC3Power;
345  info->Reset=MMC3RegReset;
346  info->Close=GenMMC3Close;
347
348  if(info->CRC32 == 0x5104833e)        // Kick Master
349   GameHBIRQHook = MMC3_hb_KickMasterHack;
350  else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
351   GameHBIRQHook = MMC3_hb_KickMasterHack;
352  else if(info->CRC32 == 0xfcd772eb)    // PAL Star Wars, similar problem as Kick Master.
353   GameHBIRQHook = MMC3_hb_PALStarWarsHack;
354  else
355   GameHBIRQHook=MMC3_hb;
356  GameStateRestore=genmmc3restore;
357 }
358
359 // ----------------------------------------------------------------------
360 // -------------------------- MMC3 Based Code ---------------------------
361 // ----------------------------------------------------------------------
362
363 // ---------------------------- Mapper 4 --------------------------------
364
365 static int hackm4=0;/* For Karnov, maybe others.  BLAH.  Stupid iNES format.*/
366
367 static void M4Power(void)
368 {
369  GenMMC3Power();
370  A000B=(hackm4^1)&1;
371  setmirror(hackm4);
372 }
373
374 void Mapper4_Init(CartInfo *info)
375 {
376  int ws=8;
377
378  if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
379  {
380   FCEU_printf("Low-G-Man can not work normally in the iNES format.\nThis game has been recognized by its CRC32 value, and the appropriate changes will be made so it will run.\nIf you wish to hack this game, you should use the UNIF format for your hack.\n\n");
381   ws=0;
382  }
383  GenMMC3_Init(info,512,256,ws,info->battery);
384  info->Power=M4Power;
385  hackm4=info->mirror;
386 }
387
388 // ---------------------------- Mapper 12 -------------------------------
389
390 static void M12CW(uint32 A, uint8 V)
391 {
392  setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
393 }
394
395 static DECLFW(M12Write)
396 {
397  EXPREGS[0]=V&0x01;
398  EXPREGS[1]=(V&0x10)>>4;
399 }
400
401 static void M12Power(void)
402 {
403  EXPREGS[0]=EXPREGS[1]=0;
404  GenMMC3Power();
405  SetWriteHandler(0x4100,0x5FFF,M12Write);
406 }
407
408 void Mapper12_Init(CartInfo *info)
409 {
410  GenMMC3_Init(info, 512, 256, 8, info->battery);
411  cwrap=M12CW;
412  info->Power=M12Power;
413  AddExState(EXPREGS, 2, 0, "EXPR");
414 }
415
416 // ---------------------------- Mapper 44 -------------------------------
417
418 static void M44PW(uint32 A, uint8 V)
419 {
420  uint32 NV=V;
421  if(EXPREGS[0]>=6) NV&=0x1F;
422  else NV&=0x0F;
423  NV|=EXPREGS[0]<<4;
424  setprg8(A,NV);
425 }
426
427 static void M44CW(uint32 A, uint8 V)
428 {
429  uint32 NV=V;
430  if(EXPREGS[0]<6) NV&=0x7F;
431  NV|=EXPREGS[0]<<7;
432  setchr1(A,NV);
433 }
434
435 static DECLFW(M44Write)
436 {
437  if(A&1)
438  {
439   EXPREGS[0]=V&7;
440   FixMMC3PRG(MMC3_cmd);
441   FixMMC3CHR(MMC3_cmd);
442  }
443  else
444   MMC3_CMDWrite(A,V);
445 }
446
447 static void M44Power(void)
448 {
449  EXPREGS[0]=0;
450  GenMMC3Power();
451  SetWriteHandler(0xA000,0xBFFF,M44Write);
452 }
453
454 void Mapper44_Init(CartInfo *info)
455 {
456  GenMMC3_Init(info, 512, 256, 8, info->battery);
457  cwrap=M44CW;
458  pwrap=M44PW;
459  info->Power=M44Power;
460  AddExState(EXPREGS, 1, 0, "EXPR");
461 }
462
463 // ---------------------------- Mapper 45 -------------------------------
464
465 static void M45CW(uint32 A, uint8 V)
466 {
467  uint32 NV=V;
468  if(EXPREGS[2]&8)
469     NV&=(1<<((EXPREGS[2]&7)+1))-1;
470  else
471     NV&=0;
472  NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
473                     // &0x10(not 0xf0) is valid given the original
474                     // description of mapper 45 by kevtris,
475                     // but this fixes Super 8 in 1.
476  setchr1(A,NV);
477 }
478
479 static void M45PW(uint32 A, uint8 V)
480 {
481  V&=(EXPREGS[3]&0x3F)^0x3F;
482  V|=EXPREGS[1];
483  setprg8(A,V);
484 }
485
486 static DECLFW(M45Write)
487 {
488  if(EXPREGS[3]&0x40)
489  {
490   WRAM[A-0x6000]=V;
491   return;
492  }
493  EXPREGS[EXPREGS[4]]=V;
494  EXPREGS[4]=(EXPREGS[4]+1)&3;
495 // FCEU_printf("write 0=%04x 1=%04x 2=%04x 3=%04x (%04x:%04x)\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3],A,V);
496  FixMMC3PRG(MMC3_cmd);
497  FixMMC3CHR(MMC3_cmd);
498 }
499
500 static void M45Reset(void)
501 {
502  FCEU_dwmemset(EXPREGS,0,5);
503  MMC3RegReset();
504 }
505
506 static void M45Power(void)
507 {
508  M45Reset();
509  GenMMC3Power();
510  SetWriteHandler(0x6000,0x7FFF,M45Write);
511 }
512
513 void Mapper45_Init(CartInfo *info)
514 {
515  GenMMC3_Init(info, 512, 256, 8, info->battery);
516  cwrap=M45CW;
517  pwrap=M45PW;
518  info->Reset=M45Reset;
519  info->Power=M45Power;
520  AddExState(EXPREGS, 5, 0, "EXPR");
521 }
522
523 // ---------------------------- Mapper 47 -------------------------------
524
525 static void M47PW(uint32 A, uint8 V)
526 {
527  V&=0xF;
528  V|=EXPREGS[0]<<4;
529  setprg8(A,V);
530 }
531
532 static void M47CW(uint32 A, uint8 V)
533 {
534  uint32 NV=V;
535  NV&=0x7F;
536  NV|=EXPREGS[0]<<7;
537  setchr1(A,NV);
538 }
539
540 static DECLFW(M47Write)
541 {
542  EXPREGS[0]=V&1;
543  FixMMC3PRG(MMC3_cmd);
544  FixMMC3CHR(MMC3_cmd);
545 }
546
547 static void M47Power(void)
548 {
549  EXPREGS[0]=0;
550  GenMMC3Power();
551  SetWriteHandler(0x6000,0x7FFF,M47Write);
552  SetReadHandler(0x6000,0x7FFF,0);
553 }
554
555 void Mapper47_Init(CartInfo *info)
556 {
557  GenMMC3_Init(info, 512, 256, 8, info->battery);
558  pwrap=M47PW;
559  cwrap=M47CW;
560  info->Power=M47Power;
561  AddExState(EXPREGS, 1, 0, "EXPR");
562 }
563
564 // ---------------------------- Mapper 49 -------------------------------
565
566 static void M49PW(uint32 A, uint8 V)
567 {
568  if(EXPREGS[0]&1)
569  {
570   V&=0xF;
571   V|=(EXPREGS[0]&0xC0)>>2;
572   setprg8(A,V);
573  }
574  else
575   setprg32(0x8000,(EXPREGS[0]>>4)&3);
576 }
577
578 static void M49CW(uint32 A, uint8 V)
579 {
580  uint32 NV=V;
581  NV&=0x7F;
582  NV|=(EXPREGS[0]&0xC0)<<1;
583  setchr1(A,NV);
584 }
585
586 static DECLFW(M49Write)
587 {
588  if(A001B&0x80)
589  {
590   EXPREGS[0]=V;
591   FixMMC3PRG(MMC3_cmd);
592   FixMMC3CHR(MMC3_cmd);
593  }
594 }
595
596 static void M49Reset(void)
597 {
598  EXPREGS[0]=0;
599  MMC3RegReset();
600 }
601
602 static void M49Power(void)
603 {
604  M49Reset();
605  GenMMC3Power();
606  SetWriteHandler(0x6000,0x7FFF,M49Write);
607  SetReadHandler(0x6000,0x7FFF,0);
608 }
609
610 void Mapper49_Init(CartInfo *info)
611 {
612  GenMMC3_Init(info, 512, 256, 0, 0);
613  cwrap=M49CW;
614  pwrap=M49PW;
615  info->Reset=M49Reset;
616  info->Power=M49Power;
617  AddExState(EXPREGS, 1, 0, "EXPR");
618 }
619
620 // ---------------------------- Mapper 52 -------------------------------
621
622 static void M52PW(uint32 A, uint8 V)
623 {
624  uint32 NV=V;
625  NV&=0x1F^((EXPREGS[0]&8)<<1);
626  NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
627  setprg8(A,NV);
628 }
629
630 static void M52CW(uint32 A, uint8 V)
631 {
632  uint32 NV=V;
633  NV&=0xFF^((EXPREGS[0]&0x40)<<1);
634  NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
635  setchr1(A,NV);
636 }
637
638 static DECLFW(M52Write)
639 {
640  if(EXPREGS[1])
641  {
642   WRAM[A-0x6000]=V;
643   return;
644  }
645  EXPREGS[1]=1;
646  EXPREGS[0]=V;
647  FixMMC3PRG(MMC3_cmd);
648  FixMMC3CHR(MMC3_cmd);
649 }
650
651 static void M52Reset(void)
652 {
653  EXPREGS[0]=EXPREGS[1]=0;
654  MMC3RegReset();
655 }
656
657 static void M52Power(void)
658 {
659  M52Reset();
660  GenMMC3Power();
661  SetWriteHandler(0x6000,0x7FFF,M52Write);
662 }
663
664 void Mapper52_Init(CartInfo *info)
665 {
666  GenMMC3_Init(info, 512, 256, 8, info->battery);
667  cwrap=M52CW;
668  pwrap=M52PW;
669  info->Reset=M52Reset;
670  info->Power=M52Power;
671  AddExState(EXPREGS, 2, 0, "EXPR");
672 }
673
674 // ---------------------------- Mapper 74 -------------------------------
675
676 static void M74CW(uint32 A, uint8 V)
677 {
678 //  FCEU_printf("%04x:%04x\n",A,V);
679 //  if((V==0)||(V==1)) //Dai-2-Ji - Super Robot Taisen (As).nes
680   if((V==0)||(V==1)||(V==2)||(V==3)) //Ying Lie Qun Xia Zhuan (Chinese).nes, 4096 CHR RAM
681 //  if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes
682 //  if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese).nes, 4096 CHR RAM
683      setchr1r(0x10,A,V);
684   else
685      setchr1r(0x0,A,V);
686 }
687
688 void Mapper74_Init(CartInfo *info)
689 {
690  GenMMC3_Init(info, 512, 256, 8, info->battery);
691  cwrap=M74CW;
692 // CHRRAMSize=2048;
693  CHRRAMSize=4096;
694  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
695  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
696  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
697 }
698
699 // ---------------------------- Mapper 114 ------------------------------
700
701 static uint8 cmdin;
702 uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
703
704 static void M114PWRAP(uint32 A, uint8 V)
705 {
706   if(EXPREGS[0]&0x80)
707   {
708     setprg16(0x8000,EXPREGS[0]&0xF);
709     setprg16(0xC000,EXPREGS[0]&0xF);
710   }
711   else
712     setprg8(A,V&0x3F);
713 }
714
715 static DECLFW(M114Write)
716 {
717  if(A==0xE003)
718  {
719   IRQa=1;
720   IRQCount=V;
721  }
722  else if(A==0xE002)
723  {
724   IRQa=0;
725   X6502_IRQEnd(FCEU_IQEXT);
726  }
727  else switch(A&0xE000)
728  {
729   case 0x8000: setmirror((V&1)^1); break;
730   case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
731   case 0xC000: if(!cmdin) break;
732                MMC3_CMDWrite(0x8001,V);
733                cmdin=0;
734                break;
735  }
736 }
737
738 static DECLFW(M114ExWrite)
739 {
740   if(A<=0x7FFF)
741   {
742    EXPREGS[0]=V;
743    FixMMC3PRG(MMC3_cmd);
744   }
745 }
746
747 static void M114Power(void)
748 {
749  GenMMC3Power();
750  SetWriteHandler(0x8000,0xFFFF,M114Write);
751  SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
752 }
753
754 static void M114Reset(void)
755 {
756  EXPREGS[0]=0;
757  MMC3RegReset();
758 }
759
760 void Mapper114_Init(CartInfo *info)
761 {
762  GenMMC3_Init(info, 256, 256, 0, 0);
763  pwrap=M114PWRAP;
764  info->Power=M114Power;
765  info->Reset=M114Reset;
766  AddExState(EXPREGS, 1, 0, "EXPR");
767  AddExState(&cmdin, 1, 0, "CMDIN");
768 }
769
770 // ---------------------------- Mapper 115 ------------------------------
771
772 static void M115PW(uint32 A, uint8 V)
773 {
774  setprg8(A,V);
775  if(EXPREGS[0]&0x80)
776     setprg16(0x8000,EXPREGS[0]&7);
777 }
778
779 static void M115CW(uint32 A, uint8 V)
780 {
781  setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
782 }
783
784 static DECLFW(M115Write)
785 {
786  if(A==0x6000)
787     EXPREGS[0]=V;
788  else if(A==0x6001)
789     EXPREGS[1]=V;
790  FixMMC3PRG(MMC3_cmd);
791 }
792
793 static void M115Power(void)
794 {
795  GenMMC3Power();
796  SetWriteHandler(0x4100,0x7FFF,M115Write);
797  SetReadHandler(0x4100,0x7FFF,0);
798 }
799
800 void Mapper115_Init(CartInfo *info)
801 {
802  GenMMC3_Init(info, 128, 512, 0, 0);
803  cwrap=M115CW;
804  pwrap=M115PW;
805  info->Power=M115Power;
806  AddExState(EXPREGS, 2, 0, "EXPR");
807 }
808
809 // ---------------------------- Mapper 116 ------------------------------
810
811 static void M116CW(uint32 A, uint8 V)
812 {
813  setchr1(A,V|((EXPREGS[0]&0x4)<<6));
814 }
815
816 static DECLFW(M116Write)
817 {
818  EXPREGS[0]=V;
819  FixMMC3PRG(MMC3_cmd);
820  FixMMC3CHR(MMC3_cmd);
821 }
822
823 static void M116Power(void)
824 {
825  GenMMC3Power();
826  SetWriteHandler(0x4100,0x4100,M116Write);
827 }
828
829 void Mapper116_Init(CartInfo *info)
830 {
831  GenMMC3_Init(info, 128, 512, 0, 0);
832  cwrap=M116CW;
833  info->Power=M116Power;
834  AddExState(EXPREGS, 4, 0, "EXPR");
835 }
836
837 // ---------------------------- Mapper 118 ------------------------------
838
839 static uint8 PPUCHRBus;
840 static uint8 TKSMIR[8];
841
842 static void FP_FASTAPASS(1) TKSPPU(uint32 A)
843 {
844  A&=0x1FFF;
845  A>>=10;
846  PPUCHRBus=A;
847  setmirror(MI_0+TKSMIR[A]);
848 }
849
850 static void TKSWRAP(uint32 A, uint8 V)
851 {
852  TKSMIR[A>>10]=V>>7;
853  setchr1(A,V&0x7F);
854  if(PPUCHRBus==(A>>10))
855     setmirror(MI_0+(V>>7));
856 }
857
858 void Mapper118_Init(CartInfo *info)
859 {
860  GenMMC3_Init(info, 512, 256, 8, info->battery);
861  cwrap=TKSWRAP;
862  mwrap=GENNOMWRAP;
863  PPU_hook=TKSPPU;
864  AddExState(&PPUCHRBus, 1, 0, "PPUC");
865 }
866
867 // ---------------------------- Mapper 119 ------------------------------
868
869 static void TQWRAP(uint32 A, uint8 V)
870 {
871  setchr1r((V&0x40)>>2,A,V&0x3F);
872 }
873
874 void Mapper119_Init(CartInfo *info)
875 {
876  GenMMC3_Init(info, 512, 64, 0, 0);
877  cwrap=TQWRAP;
878  CHRRAMSize=8192;
879  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
880  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
881 }
882
883 // ---------------------------- Mapper 191 ------------------------------
884
885 static void M191CW(uint32 A, uint8 V)
886 {
887   setchr1r((V&0x80)>>3,A,V);
888 }
889
890 void Mapper191_Init(CartInfo *info)
891 {
892  GenMMC3_Init(info, 256, 256, 8, info->battery);
893  cwrap=M191CW;
894  CHRRAMSize=2048;
895  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
896  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
897  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
898 }
899
900 // ---------------------------- Mapper 165 ------------------------------
901
902 static void M165CW(uint32 A, uint8 V)
903 {
904  if(V==0)
905     setchr4r(0x10,A,0);
906  else
907     setchr4(A,V>>2);
908 }
909
910 static void M165PPUFD(void)
911 {
912  if(EXPREGS[0]==0xFD)
913  {
914   M165CW(0x0000,DRegBuf[0]);
915   M165CW(0x1000,DRegBuf[2]);
916  }
917 }
918
919 static void M165PPUFE(void)
920 {
921  if(EXPREGS[0]==0xFE)
922  {
923   M165CW(0x0000,DRegBuf[1]);
924   M165CW(0x1000,DRegBuf[4]);
925  }
926 }
927
928 static void M165CWM(uint32 A, uint8 V)
929 {
930  if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2)) M165PPUFD();
931  if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4)) M165PPUFE();
932 }
933
934 static void FP_FASTAPASS(1) M165PPU(uint32 A)
935 {
936  if((A&0x1FF0)==0x1FD0)
937  {
938   EXPREGS[0]=0xFD;
939   M165PPUFD();
940  } else if((A&0x1FF0)==0x1FE0)
941  {
942   EXPREGS[0]=0xFE;
943   M165PPUFE();
944  }
945 }
946
947 static void M165Power(void)
948 {
949  EXPREGS[0]=0xFD;
950  GenMMC3Power();
951 }
952
953 void Mapper165_Init(CartInfo *info)
954 {
955  GenMMC3_Init(info, 512, 128, 8, info->battery);
956  cwrap=M165CWM;
957  PPU_hook=M165PPU;
958  info->Power=M165Power;
959  CHRRAMSize = 4096;
960  CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
961  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
962  AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
963  AddExState(EXPREGS, 4, 0, "EXPR");
964 }
965
966 // ---------------------------- Mapper 182 ------------------------------
967 // Ã²Ã Ã¡Ã«Ã¨Ã¶Ã  Ã¯Ã¥Ã°Ã¬Ã³Ã²Ã Ã¶Ã¨ Ã Ã­Ã Ã«Ã®Ã£Ã¨Ã·Ã­Ã  114 Ã¬Ã Ã¯Ã¯Ã¥Ã°Ã³, Ã°Ã¥Ã£Ã¨Ã±Ã²Ã°Ã» Ã¬Ã Ã¯Ã¯Ã¥Ã°Ã  Ã£Ã®Ã°Ã Ã§Ã¤Ã® Ã±Ã«Ã®Ã¦Ã­Ã¥Ã¥,
968 // Ã·Ã¥Ã¬ Ã¨Ã±Ã¯Ã®Ã«Ã¼Ã§Ã³Ã¾Ã²Ã±Ã¿ Ã§Ã¤Ã¥Ã±Ã¼, ÃµÃ®Ã²Ã¿ Ã¢Ã±Ã¥ Ã¯Ã°Ã¥ÃªÃ°Ã Ã±Ã­Ã® Ã°Ã Ã¡Ã®Ã²Ã Ã¥Ã².
969
970 //static uint8 m182_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
971 static DECLFW(M182Write)
972 {
973  switch(A&0xF003)
974  {
975   case 0x8001: setmirror((V&1)^1); break;
976   case 0xA000: MMC3_CMDWrite(0x8000,m114_perm[V&7]); break;
977   case 0xC000: MMC3_CMDWrite(0x8001,V); break;
978   case 0xE003: IRQCount=V; IRQa=1; X6502_IRQEnd(FCEU_IQEXT); break;
979  }
980 }
981
982 static void M182Power(void)
983 {
984  GenMMC3Power();
985  SetWriteHandler(0x8000,0xFFFF,M182Write);
986 }
987
988 void Mapper182_Init(CartInfo *info)
989 {
990  GenMMC3_Init(info, 256, 256, 0, 0);
991  info->Power=M182Power;
992 }
993
994 // ---------------------------- Mapper 205 ------------------------------
995
996 static void M205PW(uint32 A, uint8 V)
997 {
998  if(EXPREGS[0]&2)
999     setprg8(A,(V&0x0f)|((EXPREGS[0]&3)<<4));
1000  else
1001     setprg8(A,(V&0x1f)|((EXPREGS[0]&3)<<4));
1002 }
1003
1004 static void M205CW(uint32 A, uint8 V)
1005 {
1006  setchr1(A,V|((EXPREGS[0]&3)*128));
1007 }
1008
1009 static DECLFW(M205Write)
1010 {
1011  if((A&0x6800)==0x6800) EXPREGS[0]= V;
1012  FixMMC3PRG(MMC3_cmd);
1013  FixMMC3CHR(MMC3_cmd);
1014 }
1015
1016 static void M205Reset(void)
1017 {
1018  EXPREGS[0]=0;
1019  MMC3RegReset();
1020 }
1021
1022 static void M205Power(void)
1023 {
1024  GenMMC3Power();
1025  SetWriteHandler(0x4020,0x7FFF,M205Write);
1026 }
1027
1028 void Mapper205_Init(CartInfo *info)
1029 {
1030  GenMMC3_Init(info, 512, 256, 8, 0);
1031  pwrap=M205PW;
1032  cwrap=M205CW;
1033  info->Power=M205Power;
1034  info->Reset=M205Reset;
1035  AddExState(EXPREGS, 1, 0, "EXPR");
1036 }
1037
1038 // ---------------------------- Mapper 215 ------------------------------
1039
1040 static uint8 m215_perm[8] = {0, 2, 5, 3, 6, 1, 7, 4};
1041
1042 static void M215CW(uint32 A, uint8 V)
1043 {
1044  if(EXPREGS[1]&0x04)
1045    setchr1(A,V|0x100);
1046  else
1047    setchr1(A,(V&0x7F)|((EXPREGS[1]&0x10)<<3));
1048 }
1049
1050 static void M215PW(uint32 A, uint8 V)
1051 {
1052  if(EXPREGS[0]&0x80)
1053  {
1054    setprg16(0x8000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
1055    setprg16(0xC000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
1056  }
1057  else if(EXPREGS[1]&0x08)
1058         setprg8(A,(V&0x1F)|0x20);
1059       else
1060         setprg8(A,(V&0x0F)|(EXPREGS[1]&0x10));
1061 }
1062
1063 static DECLFW(M215Write)
1064 {
1065  if(!(EXPREGS[2]))
1066  {
1067   if(A >= 0xc000)
1068    MMC3_IRQWrite(A,V);
1069   else
1070    MMC3_CMDWrite(A,V);
1071  }
1072  else switch(A&0xE001)
1073  {
1074   case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
1075   case 0xE001: IRQCount=V; break;
1076   case 0xC001: IRQa=1; break;
1077   case 0xC000: setmirror(((V|(V>>7))&1)^1); break;
1078   case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m215_perm[V&7])); cmdin=1; break;
1079   case 0x8001: if(!cmdin) break;
1080                MMC3_CMDWrite(0x8001,V);
1081                cmdin=0;
1082                break;
1083  }
1084 }
1085
1086 static DECLFW(M215ExWrite)
1087 {
1088  switch(A)
1089  {
1090   case 0x5000:
1091        EXPREGS[0]=V;
1092        FixMMC3PRG(MMC3_cmd);
1093        break;
1094   case 0x5001:
1095        EXPREGS[1]=V;
1096        FixMMC3CHR(MMC3_cmd);
1097        break;
1098   case 0x5007:
1099        EXPREGS[2]=V;
1100        MMC3RegReset();
1101        break;
1102  }
1103 }
1104
1105 static void M215Power(void)
1106 {
1107  EXPREGS[0]=0;
1108  EXPREGS[1]=0xFF;
1109  EXPREGS[2]=4;
1110  GenMMC3Power();
1111  SetWriteHandler(0x8000,0xFFFF,M215Write);
1112  SetWriteHandler(0x5000,0x7FFF,M215ExWrite);
1113 }
1114
1115 void Mapper215_Init(CartInfo *info)
1116 {
1117  GenMMC3_Init(info, 256, 256, 0, 0);
1118  cwrap=M215CW;
1119  pwrap=M215PW;
1120  info->Power=M215Power;
1121  AddExState(EXPREGS, 3, 0, "EXPR");
1122  AddExState(&cmdin, 1, 0, "CMDIN");
1123 }
1124
1125 // ---------------------------- Mapper 217 ------------------------------
1126
1127 static uint8 m217_perm[8] = {0, 6, 3, 7, 5, 2, 4, 1};
1128
1129 static void M217CW(uint32 A, uint8 V)
1130 {
1131  if(EXPREGS[1]&0x08)
1132    setchr1(A,V|((EXPREGS[1]&3)<<8));
1133  else
1134    setchr1(A,(V&0x7F)|((EXPREGS[1]&3)<<8)|((EXPREGS[1]&0x10)<<3));
1135 }
1136
1137 static void M217PW(uint32 A, uint8 V)
1138 {
1139  if(EXPREGS[0]&0x80)
1140  {
1141    setprg16(0x8000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
1142    setprg16(0xC000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
1143  }
1144  else if(EXPREGS[1]&0x08)
1145         setprg8(A,(V&0x1F)|((EXPREGS[1]&3)<<5));
1146       else
1147         setprg8(A,(V&0x0F)|((EXPREGS[1]&3)<<5)|(EXPREGS[1]&0x10));
1148 }
1149
1150 static DECLFW(M217Write)
1151 {
1152  if(!EXPREGS[2])
1153  {
1154   if(A >= 0xc000)
1155    MMC3_IRQWrite(A, V);
1156   else
1157    MMC3_CMDWrite(A,V);
1158  }
1159  else switch(A&0xE001)
1160  {
1161   case 0x8000: IRQCount=V; break;
1162   case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
1163   case 0xC001: IRQa=1; break;
1164   case 0xA001: setmirror((V&1)^1); break;
1165   case 0x8001: MMC3_CMDWrite(0x8000,(V&0xC0)|(m217_perm[V&7])); cmdin=1; break;
1166   case 0xA000: if(!cmdin) break;
1167                MMC3_CMDWrite(0x8001,V);
1168                cmdin=0;
1169                break;
1170  }
1171 }
1172
1173 static DECLFW(M217ExWrite)
1174 {
1175  switch(A)
1176  {
1177   case 0x5000:
1178        EXPREGS[0]=V;
1179        FixMMC3PRG(MMC3_cmd);
1180        break;
1181   case 0x5001:
1182        EXPREGS[1]=V;
1183        FixMMC3PRG(MMC3_cmd);
1184        break;
1185   case 0x5007:
1186        EXPREGS[2]=V;
1187        break;
1188  }
1189 }
1190
1191 static void M217Power(void)
1192 {
1193  EXPREGS[0]=0;
1194  EXPREGS[1]=0xFF;
1195  EXPREGS[2]=3;
1196  GenMMC3Power();
1197  SetWriteHandler(0x8000,0xFFFF,M217Write);
1198  SetWriteHandler(0x5000,0x7FFF,M217ExWrite);
1199 }
1200
1201 void Mapper217_Init(CartInfo *info)
1202 {
1203  GenMMC3_Init(info, 256, 256, 0, 0);
1204  cwrap=M217CW;
1205  pwrap=M217PW;
1206  info->Power=M217Power;
1207  AddExState(EXPREGS, 3, 0, "EXPR");
1208  AddExState(&cmdin, 1, 0, "CMDIN");
1209 }
1210
1211 // ---------------------------- Mapper 245 ------------------------------
1212
1213 static void M245CW(uint32 A, uint8 V)
1214 {
1215  setchr1(A,V&7);
1216  EXPREGS[0]=V;
1217  FixMMC3PRG(MMC3_cmd);
1218 }
1219
1220 static void M245PW(uint32 A, uint8 V)
1221 {
1222  setprg8(A,(V&0x3F)|((EXPREGS[0]&2)<<5));
1223 }
1224
1225 static void M245Power(void)
1226 {
1227  EXPREGS[0]=0;
1228  GenMMC3Power();
1229 }
1230
1231 void Mapper245_Init(CartInfo *info)
1232 {
1233  GenMMC3_Init(info, 512, 256, 8, info->battery);
1234  cwrap=M245CW;
1235  pwrap=M245PW;
1236  info->Power=M245Power;
1237  AddExState(EXPREGS, 1, 0, "EXPR");
1238 }
1239
1240 // ---------------------------- Mapper 249 ------------------------------
1241
1242 static void M249PW(uint32 A, uint8 V)
1243 {
1244  if(EXPREGS[0]&0x2)
1245  {
1246   if(V<0x20)
1247    V=(V&1)|((V>>3)&2)|((V>>1)&4)|((V<<2)&8)|((V<<2)&0x10);
1248   else
1249   {
1250    V-=0x20;
1251    V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1252   }
1253  }
1254  setprg8(A,V);
1255 }
1256
1257 static void M249CW(uint32 A, uint8 V)
1258 {
1259  if(EXPREGS[0]&0x2)
1260     V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
1261  setchr1(A,V);
1262 }
1263
1264 static DECLFW(M249Write)
1265 {
1266  EXPREGS[0]=V;
1267  FixMMC3PRG(MMC3_cmd);
1268  FixMMC3CHR(MMC3_cmd);
1269 }
1270
1271 static void M249Power(void)
1272 {
1273  EXPREGS[0]=0;
1274  GenMMC3Power();
1275  SetWriteHandler(0x5000,0x5000,M249Write);
1276 }
1277
1278 void Mapper249_Init(CartInfo *info)
1279 {
1280  GenMMC3_Init(info, 512, 256, 8, info->battery);
1281  cwrap=M249CW;
1282  pwrap=M249PW;
1283  info->Power=M249Power;
1284  AddExState(EXPREGS, 1, 0, "EXPR");
1285 }
1286
1287 // ---------------------------- Mapper 250 ------------------------------
1288
1289 static DECLFW(M250Write)
1290 {
1291  MMC3_CMDWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1292 }
1293
1294 static DECLFW(M250IRQWrite)
1295 {
1296  MMC3_IRQWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
1297 }
1298
1299 static void M250_Power(void)
1300 {
1301  GenMMC3Power();
1302  SetWriteHandler(0x8000,0xBFFF,M250Write);
1303  SetWriteHandler(0xC000,0xFFFF,M250IRQWrite);
1304 }
1305
1306 void Mapper250_Init(CartInfo *info)
1307 {
1308  GenMMC3_Init(info, 512, 256, 8, info->battery);
1309  info->Power=M250_Power;
1310 }
1311
1312 // ---------------------------- Mapper 254 ------------------------------
1313
1314 static DECLFR(MR254WRAM)
1315 {
1316   if(EXPREGS[0])
1317     return WRAM[A-0x6000];
1318   else
1319     return WRAM[A-0x6000]^EXPREGS[1];
1320 }
1321
1322 static DECLFW(M254Write)
1323 {
1324  switch (A) {
1325   case 0x8000: EXPREGS[0]=0xff;
1326                break;
1327   case 0xA001: EXPREGS[1]=V;
1328  }
1329  MMC3_CMDWrite(A,V);
1330 }
1331
1332 static void M254_Power(void)
1333 {
1334  GenMMC3Power();
1335  SetWriteHandler(0x8000,0xBFFF,M254Write);
1336  SetReadHandler(0x6000,0x7FFF,MR254WRAM);
1337 }
1338
1339 void Mapper254_Init(CartInfo *info)
1340 {
1341  GenMMC3_Init(info, 128, 128, 8, info->battery);
1342  info->Power=M254_Power;
1343  AddExState(EXPREGS, 2, 0, "EXPR");
1344 }
1345
1346 // ---------------------------- UNIF Boards -----------------------------
1347
1348 void TEROM_Init(CartInfo *info)
1349 {
1350  GenMMC3_Init(info, 32, 32, 0, 0);
1351 }
1352
1353 void TFROM_Init(CartInfo *info)
1354 {
1355  GenMMC3_Init(info, 512, 64, 0, 0);
1356 }
1357
1358 void TGROM_Init(CartInfo *info)
1359 {
1360  GenMMC3_Init(info, 512, 0, 0, 0);
1361 }
1362
1363 void TKROM_Init(CartInfo *info)
1364 {
1365  GenMMC3_Init(info, 512, 256, 8, info->battery);
1366 }
1367
1368 void TLROM_Init(CartInfo *info)
1369 {
1370  GenMMC3_Init(info, 512, 256, 0, 0);
1371 }
1372
1373 void TSROM_Init(CartInfo *info)
1374 {
1375  GenMMC3_Init(info, 512, 256, 8, 0);
1376 }
1377
1378 void TLSROM_Init(CartInfo *info)
1379 {
1380  GenMMC3_Init(info, 512, 256, 8, 0);
1381  cwrap=TKSWRAP;
1382  mwrap=GENNOMWRAP;
1383  PPU_hook=TKSPPU;
1384  AddExState(&PPUCHRBus, 1, 0, "PPUC");
1385 }
1386
1387 void TKSROM_Init(CartInfo *info)
1388 {
1389  GenMMC3_Init(info, 512, 256, 8, info->battery);
1390  cwrap=TKSWRAP;
1391  mwrap=GENNOMWRAP;
1392  PPU_hook=TKSPPU;
1393  AddExState(&PPUCHRBus, 1, 0, "PPUC");
1394 }
1395
1396 void TQROM_Init(CartInfo *info)
1397 {
1398  GenMMC3_Init(info, 512, 64, 0, 0);
1399  cwrap=TQWRAP;
1400  CHRRAMSize=8192;
1401  CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
1402  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1403 }
1404
1405 void HKROM_Init(CartInfo *info)
1406 {
1407  GenMMC3_Init(info, 512, 512, 1, info->battery);
1408 }