098 video fix, 098 sound integrated
[fceu.git] / boards / mmc3.c
CommitLineData
d97315ac 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
e2d0dd92 30uint8 MMC3_cmd;
31uint8 *WRAM;
32uint8 *CHRRAM;
33uint32 CHRRAMSize;
34uint8 EXPREGS[8]; /* For bootleg games, mostly. */
d97315ac 35
e2d0dd92 36static uint8 A000B,A001B;
37static uint8 DRegBuf[8];
d97315ac 38
39#undef IRQCount
40#undef IRQLatch
41#undef IRQa
e2d0dd92 42uint8 IRQCount,IRQLatch,IRQa;
43uint8 IRQReload;
d97315ac 44
45static 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
58static int mmc3opts=0;
e2d0dd92 59static int wrams;
60static int isRevB=1;
d97315ac 61
62void (*pwrap)(uint32 A, uint8 V);
63void (*cwrap)(uint32 A, uint8 V);
64void (*mwrap)(uint8 V);
65
66void GenMMC3Power(void);
67void FixMMC3PRG(int V);
68void FixMMC3CHR(int V);
69
70void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
71
72// ----------------------------------------------------------------------
73// ------------------------- Generic MM3 Code ---------------------------
74// ----------------------------------------------------------------------
75
76void FixMMC3PRG(int V)
77{
78 if(V&0x40)
79 {
80 pwrap(0xC000,DRegBuf[6]);
81 pwrap(0x8000,~1);
82 }
83 else
84 {
85 pwrap(0x8000,DRegBuf[6]);
86 pwrap(0xC000,~1);
87 }
88 pwrap(0xA000,DRegBuf[7]);
89 pwrap(0xE000,~0);
90}
91
92void FixMMC3CHR(int V)
93{
94 int cbase=(V&0x80)<<5;
95
96 cwrap((cbase^0x000),DRegBuf[0]&(~1));
97 cwrap((cbase^0x400),DRegBuf[0]|1);
98 cwrap((cbase^0x800),DRegBuf[1]&(~1));
99 cwrap((cbase^0xC00),DRegBuf[1]|1);
100
101 cwrap(cbase^0x1000,DRegBuf[2]);
102 cwrap(cbase^0x1400,DRegBuf[3]);
103 cwrap(cbase^0x1800,DRegBuf[4]);
104 cwrap(cbase^0x1c00,DRegBuf[5]);
105}
106
107void MMC3RegReset(void)
108{
109 IRQCount=IRQLatch=IRQa=MMC3_cmd=0;
110
111 DRegBuf[0]=0;
112 DRegBuf[1]=2;
113 DRegBuf[2]=4;
114 DRegBuf[3]=5;
115 DRegBuf[4]=6;
116 DRegBuf[5]=7;
117 DRegBuf[6]=0;
118 DRegBuf[7]=1;
119
120 FixMMC3PRG(0);
121 FixMMC3CHR(0);
122}
123
124DECLFW(MMC3_CMDWrite)
125{
e2d0dd92 126// FCEU_printf("%04x:%04x\n",A,V);
d97315ac 127 switch(A&0xE001)
128 {
129 case 0x8000:
130 if((V&0x40) != (MMC3_cmd&0x40))
131 FixMMC3PRG(V);
132 if((V&0x80) != (MMC3_cmd&0x80))
133 FixMMC3CHR(V);
134 MMC3_cmd = V;
135 break;
136 case 0x8001:
137 {
138 int cbase=(MMC3_cmd&0x80)<<5;
139 DRegBuf[MMC3_cmd&0x7]=V;
140 switch(MMC3_cmd&0x07)
141 {
142 case 0: cwrap((cbase^0x000),V&(~1));
143 cwrap((cbase^0x400),V|1);
144 break;
145 case 1: cwrap((cbase^0x800),V&(~1));
146 cwrap((cbase^0xC00),V|1);
147 break;
148 case 2: cwrap(cbase^0x1000,V);
149 break;
150 case 3: cwrap(cbase^0x1400,V);
151 break;
152 case 4: cwrap(cbase^0x1800,V);
153 break;
154 case 5: cwrap(cbase^0x1C00,V);
155 break;
156 case 6:
157 if(MMC3_cmd&0x40)
158 pwrap(0xC000,V);
159 else
160 pwrap(0x8000,V);
161 break;
162 case 7:
163 pwrap(0xA000,V);
164 break;
165 }
166 }
167 break;
168 case 0xA000:
169 if(mwrap) mwrap(V&1);
170 break;
171 case 0xA001:
172 A001B=V;
a384bf44 173 //Write_IRQFM(0x4017,0x40);
174 {
175 writefunc f = GetWriteHandler(0x4017);
176 f(0x4017,0x40);
177 }
d97315ac 178 break;
179 }
180}
181
182DECLFW(MMC3_IRQWrite)
183{
e2d0dd92 184// FCEU_printf("%04x:%04x\n",A,V);
d97315ac 185 switch(A&0xE001)
186 {
187 case 0xC000:IRQLatch=V;break;
188 case 0xC001:IRQReload=1;break;
189 case 0xE000:X6502_IRQEnd(FCEU_IQEXT);IRQa=0;break;
190 case 0xE001:IRQa=1;break;
191 }
192}
193
194static void ClockMMC3Counter(void)
195{
196 int count = IRQCount;
197 if(!count || IRQReload)
198 {
199 IRQCount = IRQLatch;
200 IRQReload = 0;
201 }
202 else
203 IRQCount--;
e2d0dd92 204 if((count|isRevB) && !IRQCount)
d97315ac 205 {
206 if(IRQa)
207 {
208 X6502_IRQBegin(FCEU_IQEXT);
209 }
210 }
211}
212
213static void MMC3_hb(void)
214{
215 ClockMMC3Counter();
216}
217
218static void MMC3_hb_KickMasterHack(void)
219{
220 if(scanline==238) ClockMMC3Counter();
221 ClockMMC3Counter();
222}
223
224static void MMC3_hb_PALStarWarsHack(void)
225{
226 if(scanline==240) ClockMMC3Counter();
227 ClockMMC3Counter();
228}
229
e2d0dd92 230void GenMMC3Restore(int version)
d97315ac 231{
232 if(mwrap) mwrap(A000B&1);
233 FixMMC3PRG(MMC3_cmd);
234 FixMMC3CHR(MMC3_cmd);
235}
236
237static void GENCWRAP(uint32 A, uint8 V)
238{
e2d0dd92 239 if(!UNIFchrrama) setchr1(A,V);
d97315ac 240}
241
242static void GENPWRAP(uint32 A, uint8 V)
243{
244 setprg8(A,V&0x3F);
245}
246
247static void GENMWRAP(uint8 V)
248{
249 A000B=V;
250 setmirror(V^1);
251}
252
253static void GENNOMWRAP(uint8 V)
254{
255 A000B=V;
256}
257
258static DECLFW(MBWRAM)
259{
260 WRAM[A-0x6000]=V;
261}
262
263static DECLFR(MAWRAM)
264{
265 return(WRAM[A-0x6000]);
266}
267
268static DECLFW(MBWRAMMMC6)
269{
270 WRAM[A&0x3ff]=V;
271}
272
273static DECLFR(MAWRAMMMC6)
274{
275 return(WRAM[A&0x3ff]);
276}
277
278void GenMMC3Power(void)
279{
e2d0dd92 280 if(UNIFchrrama) setchr8(0);
281
d97315ac 282 SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
283 SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
284 SetReadHandler(0x8000,0xFFFF,CartBR);
285 A001B=A000B=0;
286 setmirror(1);
287 if(mmc3opts&1)
288 {
289 if(wrams==1024)
290 {
291 FCEU_CheatAddRAM(1,0x7000,WRAM);
292 SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
293 SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
e7f52878 294#ifdef ASM_6502
295 // asm code needs pages to be set again..
296 Page[14]=Page[15]=WRAM-0x7000;
297#endif
d97315ac 298 }
299 else
300 {
301 FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
302 SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
303 SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
e7f52878 304#ifdef ASM_6502
305 {
306 int addr;
307 for (addr=0x6000; addr < 0x6000+wrams-0x7ff; addr += 0x800)
308 {
309 Page[addr>>11]=WRAM - 0x6000;
310 }
311 }
312#endif
d97315ac 313 }
314 if(!(mmc3opts&2))
315 FCEU_dwmemset(WRAM,0,wrams);
316 }
317 MMC3RegReset();
318 if(CHRRAM)
319 FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
320}
321
322static void GenMMC3Close(void)
323{
324 if(CHRRAM)
325 FCEU_gfree(CHRRAM);
326 if(WRAM)
327 FCEU_gfree(WRAM);
328 CHRRAM=WRAM=NULL;
329}
330
e2d0dd92 331//static uint16 _a12;
332//static void FP_FASTAPASS(1) MMC3_PPU(uint32 A)
333//{
334// if(A&0x2000)return;
335// if((!_a12)&&(A&0x1000))
336// ClockMMC3Counter();
337// _a12=A&0x1000;
338//}
339
d97315ac 340void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
341{
e2d0dd92 342 pwrap=GENPWRAP;
d97315ac 343 cwrap=GENCWRAP;
344 mwrap=GENMWRAP;
345
346 wrams=wram<<10;
347
348 PRGmask8[0]&=(prg>>13)-1;
349 CHRmask1[0]&=(chr>>10)-1;
350 CHRmask2[0]&=(chr>>11)-1;
351
352 if(wram)
353 {
354 mmc3opts|=1;
355 WRAM=(uint8*)FCEU_gmalloc(wrams);
356 AddExState(WRAM, wrams, 0, "WRAM");
357 }
358
359 if(battery)
360 {
361 mmc3opts|=2;
362 info->SaveGame[0]=WRAM;
363 info->SaveGameLen[0]=wrams;
364 }
365
e2d0dd92 366// if(!chr) // duplicated CHR RAM set up
367// {
368// CHRRAM=(uint8*)FCEU_gmalloc(8192);
369// CHRRAMSize=8192;
370// SetupCartCHRMapping(0, CHRRAM, 8192, 1);
371// AddExState(CHRRAM, 8192, 0, "CHRR");
372// }
d97315ac 373
374 AddExState(MMC3_StateRegs, ~0, 0, 0);
375
376 info->Power=GenMMC3Power;
377 info->Reset=MMC3RegReset;
378 info->Close=GenMMC3Close;
379
380 if(info->CRC32 == 0x5104833e) // Kick Master
381 GameHBIRQHook = MMC3_hb_KickMasterHack;
382 else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
383 GameHBIRQHook = MMC3_hb_KickMasterHack;
384 else if(info->CRC32 == 0xfcd772eb) // PAL Star Wars, similar problem as Kick Master.
385 GameHBIRQHook = MMC3_hb_PALStarWarsHack;
386 else
e2d0dd92 387 GameHBIRQHook=MMC3_hb;
388// PPU_hook=MMC3_PPU;
389 GameStateRestore=GenMMC3Restore;
d97315ac 390}
391
392// ----------------------------------------------------------------------
393// -------------------------- MMC3 Based Code ---------------------------
394// ----------------------------------------------------------------------
395
396// ---------------------------- Mapper 4 --------------------------------
397
398static int hackm4=0;/* For Karnov, maybe others. BLAH. Stupid iNES format.*/
399
400static void M4Power(void)
401{
402 GenMMC3Power();
403 A000B=(hackm4^1)&1;
404 setmirror(hackm4);
405}
406
407void Mapper4_Init(CartInfo *info)
408{
409 int ws=8;
410
411 if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
412 {
413 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");
414 ws=0;
415 }
416 GenMMC3_Init(info,512,256,ws,info->battery);
417 info->Power=M4Power;
418 hackm4=info->mirror;
419}
420
421// ---------------------------- Mapper 12 -------------------------------
422
423static void M12CW(uint32 A, uint8 V)
424{
425 setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
426}
427
428static DECLFW(M12Write)
429{
430 EXPREGS[0]=V&0x01;
431 EXPREGS[1]=(V&0x10)>>4;
432}
433
434static void M12Power(void)
435{
436 EXPREGS[0]=EXPREGS[1]=0;
437 GenMMC3Power();
438 SetWriteHandler(0x4100,0x5FFF,M12Write);
439}
440
441void Mapper12_Init(CartInfo *info)
442{
443 GenMMC3_Init(info, 512, 256, 8, info->battery);
444 cwrap=M12CW;
445 info->Power=M12Power;
446 AddExState(EXPREGS, 2, 0, "EXPR");
447}
448
e2d0dd92 449// ---------------------------- Mapper 37 -------------------------------
450
451static void M37PW(uint32 A, uint8 V)
452{
453 if(EXPREGS[0]!=2)
454 V&=0x7;
455 else
456 V&=0xF;
457 V|=EXPREGS[0]<<3;
458 setprg8(A,V);
459}
460
461static void M37CW(uint32 A, uint8 V)
462{
463 uint32 NV=V;
464 NV&=0x7F;
465 NV|=EXPREGS[0]<<6;
466 setchr1(A,NV);
467}
468
469static DECLFW(M37Write)
470{
471 EXPREGS[0]=(V&6)>>1;
472 FixMMC3PRG(MMC3_cmd);
473 FixMMC3CHR(MMC3_cmd);
474}
475
476static void M37Reset(void)
477{
478 EXPREGS[0]=0;
479 MMC3RegReset();
480}
481
482static void M37Power(void)
483{
484 EXPREGS[0]=0;
485 GenMMC3Power();
486 SetWriteHandler(0x6000,0x7FFF,M37Write);
487}
488
489void Mapper37_Init(CartInfo *info)
490{
491 GenMMC3_Init(info, 512, 256, 8, info->battery);
492 pwrap=M37PW;
493 cwrap=M37CW;
494 info->Power=M37Power;
495 info->Reset=M37Reset;
496 AddExState(EXPREGS, 1, 0, "EXPR");
497}
498
d97315ac 499// ---------------------------- Mapper 44 -------------------------------
500
501static void M44PW(uint32 A, uint8 V)
502{
503 uint32 NV=V;
504 if(EXPREGS[0]>=6) NV&=0x1F;
505 else NV&=0x0F;
506 NV|=EXPREGS[0]<<4;
507 setprg8(A,NV);
508}
509
510static void M44CW(uint32 A, uint8 V)
511{
512 uint32 NV=V;
513 if(EXPREGS[0]<6) NV&=0x7F;
514 NV|=EXPREGS[0]<<7;
515 setchr1(A,NV);
516}
517
518static DECLFW(M44Write)
519{
520 if(A&1)
521 {
522 EXPREGS[0]=V&7;
523 FixMMC3PRG(MMC3_cmd);
524 FixMMC3CHR(MMC3_cmd);
525 }
526 else
527 MMC3_CMDWrite(A,V);
528}
529
530static void M44Power(void)
531{
532 EXPREGS[0]=0;
533 GenMMC3Power();
534 SetWriteHandler(0xA000,0xBFFF,M44Write);
535}
536
537void Mapper44_Init(CartInfo *info)
538{
539 GenMMC3_Init(info, 512, 256, 8, info->battery);
540 cwrap=M44CW;
541 pwrap=M44PW;
542 info->Power=M44Power;
543 AddExState(EXPREGS, 1, 0, "EXPR");
544}
545
546// ---------------------------- Mapper 45 -------------------------------
547
548static void M45CW(uint32 A, uint8 V)
549{
e2d0dd92 550 if(!UNIFchrrama)
551 {
552 uint32 NV=V;
553 if(EXPREGS[2]&8)
554 NV&=(1<<((EXPREGS[2]&7)+1))-1;
555// else
556// NV&=0;
557 NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
558 setchr1(A,NV);
559 }
d97315ac 560}
561
562static void M45PW(uint32 A, uint8 V)
563{
564 V&=(EXPREGS[3]&0x3F)^0x3F;
565 V|=EXPREGS[1];
566 setprg8(A,V);
567}
568
569static DECLFW(M45Write)
570{
571 if(EXPREGS[3]&0x40)
572 {
573 WRAM[A-0x6000]=V;
574 return;
575 }
576 EXPREGS[EXPREGS[4]]=V;
577 EXPREGS[4]=(EXPREGS[4]+1)&3;
e7f52878 578 if(!EXPREGS[4])
e2d0dd92 579 {
580 FCEU_printf("CHROR %02x, PRGOR %02x, CHRAND %02x, PRGAND %02x\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3]);
581 FCEU_printf("CHR0 %03x, CHR1 %03x, PRG0 %03x, PRG1 %03x\n",
582 (0x00&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
583 (0xFF&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
584 (0x00&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]),
585 (0xFF&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]));
586 }
d97315ac 587 FixMMC3PRG(MMC3_cmd);
588 FixMMC3CHR(MMC3_cmd);
589}
590
591static void M45Reset(void)
592{
e2d0dd92 593 EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
d97315ac 594 MMC3RegReset();
595}
596
597static void M45Power(void)
598{
e2d0dd92 599 setchr8(0);
d97315ac 600 GenMMC3Power();
601 SetWriteHandler(0x6000,0x7FFF,M45Write);
602}
603
604void Mapper45_Init(CartInfo *info)
605{
606 GenMMC3_Init(info, 512, 256, 8, info->battery);
607 cwrap=M45CW;
608 pwrap=M45PW;
609 info->Reset=M45Reset;
610 info->Power=M45Power;
611 AddExState(EXPREGS, 5, 0, "EXPR");
612}
613
614// ---------------------------- Mapper 47 -------------------------------
615
616static void M47PW(uint32 A, uint8 V)
617{
618 V&=0xF;
619 V|=EXPREGS[0]<<4;
620 setprg8(A,V);
621}
622
623static void M47CW(uint32 A, uint8 V)
624{
625 uint32 NV=V;
626 NV&=0x7F;
627 NV|=EXPREGS[0]<<7;
628 setchr1(A,NV);
629}
630
631static DECLFW(M47Write)
632{
633 EXPREGS[0]=V&1;
634 FixMMC3PRG(MMC3_cmd);
635 FixMMC3CHR(MMC3_cmd);
636}
637
638static void M47Power(void)
639{
640 EXPREGS[0]=0;
641 GenMMC3Power();
642 SetWriteHandler(0x6000,0x7FFF,M47Write);
e2d0dd92 643// SetReadHandler(0x6000,0x7FFF,0);
d97315ac 644}
645
646void Mapper47_Init(CartInfo *info)
647{
648 GenMMC3_Init(info, 512, 256, 8, info->battery);
649 pwrap=M47PW;
650 cwrap=M47CW;
651 info->Power=M47Power;
652 AddExState(EXPREGS, 1, 0, "EXPR");
653}
654
655// ---------------------------- Mapper 49 -------------------------------
656
657static void M49PW(uint32 A, uint8 V)
658{
659 if(EXPREGS[0]&1)
660 {
661 V&=0xF;
662 V|=(EXPREGS[0]&0xC0)>>2;
663 setprg8(A,V);
664 }
665 else
666 setprg32(0x8000,(EXPREGS[0]>>4)&3);
667}
668
669static void M49CW(uint32 A, uint8 V)
670{
671 uint32 NV=V;
672 NV&=0x7F;
673 NV|=(EXPREGS[0]&0xC0)<<1;
674 setchr1(A,NV);
675}
676
677static DECLFW(M49Write)
678{
679 if(A001B&0x80)
680 {
681 EXPREGS[0]=V;
682 FixMMC3PRG(MMC3_cmd);
683 FixMMC3CHR(MMC3_cmd);
684 }
685}
686
687static void M49Reset(void)
688{
689 EXPREGS[0]=0;
690 MMC3RegReset();
691}
692
693static void M49Power(void)
694{
695 M49Reset();
696 GenMMC3Power();
697 SetWriteHandler(0x6000,0x7FFF,M49Write);
698 SetReadHandler(0x6000,0x7FFF,0);
699}
700
701void Mapper49_Init(CartInfo *info)
702{
703 GenMMC3_Init(info, 512, 256, 0, 0);
704 cwrap=M49CW;
705 pwrap=M49PW;
706 info->Reset=M49Reset;
707 info->Power=M49Power;
708 AddExState(EXPREGS, 1, 0, "EXPR");
709}
710
711// ---------------------------- Mapper 52 -------------------------------
712
713static void M52PW(uint32 A, uint8 V)
714{
715 uint32 NV=V;
716 NV&=0x1F^((EXPREGS[0]&8)<<1);
717 NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
718 setprg8(A,NV);
719}
720
721static void M52CW(uint32 A, uint8 V)
722{
723 uint32 NV=V;
724 NV&=0xFF^((EXPREGS[0]&0x40)<<1);
725 NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
726 setchr1(A,NV);
727}
728
729static DECLFW(M52Write)
730{
731 if(EXPREGS[1])
732 {
733 WRAM[A-0x6000]=V;
734 return;
735 }
736 EXPREGS[1]=1;
737 EXPREGS[0]=V;
738 FixMMC3PRG(MMC3_cmd);
739 FixMMC3CHR(MMC3_cmd);
740}
741
742static void M52Reset(void)
743{
744 EXPREGS[0]=EXPREGS[1]=0;
745 MMC3RegReset();
746}
747
748static void M52Power(void)
749{
750 M52Reset();
751 GenMMC3Power();
752 SetWriteHandler(0x6000,0x7FFF,M52Write);
753}
754
755void Mapper52_Init(CartInfo *info)
756{
757 GenMMC3_Init(info, 512, 256, 8, info->battery);
758 cwrap=M52CW;
759 pwrap=M52PW;
760 info->Reset=M52Reset;
761 info->Power=M52Power;
762 AddExState(EXPREGS, 2, 0, "EXPR");
763}
764
765// ---------------------------- Mapper 74 -------------------------------
766
767static void M74CW(uint32 A, uint8 V)
768{
e2d0dd92 769 if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
770 setchr1r(0x10,A,V);
d97315ac 771 else
e2d0dd92 772 setchr1r(0,A,V);
d97315ac 773}
774
775void Mapper74_Init(CartInfo *info)
776{
777 GenMMC3_Init(info, 512, 256, 8, info->battery);
778 cwrap=M74CW;
e2d0dd92 779 CHRRAMSize=2048;
d97315ac 780 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
781 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
782 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
783}
784
785// ---------------------------- Mapper 114 ------------------------------
786
787static uint8 cmdin;
788uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
789
790static void M114PWRAP(uint32 A, uint8 V)
791{
792 if(EXPREGS[0]&0x80)
793 {
794 setprg16(0x8000,EXPREGS[0]&0xF);
795 setprg16(0xC000,EXPREGS[0]&0xF);
796 }
797 else
798 setprg8(A,V&0x3F);
799}
800
801static DECLFW(M114Write)
802{
803 if(A==0xE003)
804 {
805 IRQa=1;
e2d0dd92 806 IRQLatch=V;
807 IRQReload=1;
d97315ac 808 }
809 else if(A==0xE002)
810 {
811 IRQa=0;
812 X6502_IRQEnd(FCEU_IQEXT);
813 }
814 else switch(A&0xE000)
815 {
816 case 0x8000: setmirror((V&1)^1); break;
817 case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
818 case 0xC000: if(!cmdin) break;
819 MMC3_CMDWrite(0x8001,V);
820 cmdin=0;
821 break;
822 }
823}
824
825static DECLFW(M114ExWrite)
826{
827 if(A<=0x7FFF)
828 {
829 EXPREGS[0]=V;
830 FixMMC3PRG(MMC3_cmd);
831 }
832}
833
834static void M114Power(void)
835{
836 GenMMC3Power();
837 SetWriteHandler(0x8000,0xFFFF,M114Write);
838 SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
839}
840
841static void M114Reset(void)
842{
843 EXPREGS[0]=0;
844 MMC3RegReset();
845}
846
847void Mapper114_Init(CartInfo *info)
848{
849 GenMMC3_Init(info, 256, 256, 0, 0);
850 pwrap=M114PWRAP;
851 info->Power=M114Power;
852 info->Reset=M114Reset;
853 AddExState(EXPREGS, 1, 0, "EXPR");
854 AddExState(&cmdin, 1, 0, "CMDIN");
855}
856
857// ---------------------------- Mapper 115 ------------------------------
858
859static void M115PW(uint32 A, uint8 V)
860{
e2d0dd92 861 if(EXPREGS[0]&0x80)
862 setprg32(0x8000,(EXPREGS[0]&7)>>1);
863 else
864 setprg8(A,V);
d97315ac 865}
866
867static void M115CW(uint32 A, uint8 V)
868{
e2d0dd92 869 setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
d97315ac 870}
871
872static DECLFW(M115Write)
873{
874 if(A==0x6000)
875 EXPREGS[0]=V;
876 else if(A==0x6001)
877 EXPREGS[1]=V;
878 FixMMC3PRG(MMC3_cmd);
879}
880
881static void M115Power(void)
882{
883 GenMMC3Power();
884 SetWriteHandler(0x4100,0x7FFF,M115Write);
885 SetReadHandler(0x4100,0x7FFF,0);
886}
887
888void Mapper115_Init(CartInfo *info)
889{
890 GenMMC3_Init(info, 128, 512, 0, 0);
891 cwrap=M115CW;
892 pwrap=M115PW;
893 info->Power=M115Power;
894 AddExState(EXPREGS, 2, 0, "EXPR");
895}
896
897// ---------------------------- Mapper 116 ------------------------------
898
899static void M116CW(uint32 A, uint8 V)
900{
e2d0dd92 901// setchr1(A,V|((EXPREGS[0]&0x4)<<6));
902 if(EXPREGS[0]&2)
903 setchr8r(0x10,0);
904 else
905 setchr1(A,V);
d97315ac 906}
907
908static DECLFW(M116Write)
909{
910 EXPREGS[0]=V;
d97315ac 911 FixMMC3CHR(MMC3_cmd);
912}
913
914static void M116Power(void)
915{
916 GenMMC3Power();
917 SetWriteHandler(0x4100,0x4100,M116Write);
918}
919
920void Mapper116_Init(CartInfo *info)
921{
922 GenMMC3_Init(info, 128, 512, 0, 0);
923 cwrap=M116CW;
924 info->Power=M116Power;
e2d0dd92 925 CHRRAM = (uint8*)FCEU_gmalloc(8192);
926 SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
d97315ac 927 AddExState(EXPREGS, 4, 0, "EXPR");
928}
929
930// ---------------------------- Mapper 118 ------------------------------
931
932static uint8 PPUCHRBus;
933static uint8 TKSMIR[8];
934
935static void FP_FASTAPASS(1) TKSPPU(uint32 A)
936{
937 A&=0x1FFF;
938 A>>=10;
939 PPUCHRBus=A;
940 setmirror(MI_0+TKSMIR[A]);
941}
942
943static void TKSWRAP(uint32 A, uint8 V)
944{
945 TKSMIR[A>>10]=V>>7;
946 setchr1(A,V&0x7F);
947 if(PPUCHRBus==(A>>10))
948 setmirror(MI_0+(V>>7));
949}
950
951void Mapper118_Init(CartInfo *info)
952{
953 GenMMC3_Init(info, 512, 256, 8, info->battery);
954 cwrap=TKSWRAP;
955 mwrap=GENNOMWRAP;
956 PPU_hook=TKSPPU;
957 AddExState(&PPUCHRBus, 1, 0, "PPUC");
958}
959
960// ---------------------------- Mapper 119 ------------------------------
961
962static void TQWRAP(uint32 A, uint8 V)
963{
964 setchr1r((V&0x40)>>2,A,V&0x3F);
965}
966
967void Mapper119_Init(CartInfo *info)
968{
969 GenMMC3_Init(info, 512, 64, 0, 0);
970 cwrap=TQWRAP;
971 CHRRAMSize=8192;
972 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
973 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
974}
975
d97315ac 976// ---------------------------- Mapper 165 ------------------------------
977
978static void M165CW(uint32 A, uint8 V)
979{
980 if(V==0)
981 setchr4r(0x10,A,0);
982 else
983 setchr4(A,V>>2);
984}
985
986static void M165PPUFD(void)
987{
988 if(EXPREGS[0]==0xFD)
989 {
990 M165CW(0x0000,DRegBuf[0]);
991 M165CW(0x1000,DRegBuf[2]);
992 }
993}
994
995static void M165PPUFE(void)
996{
997 if(EXPREGS[0]==0xFE)
998 {
999 M165CW(0x0000,DRegBuf[1]);
1000 M165CW(0x1000,DRegBuf[4]);
1001 }
1002}
1003
1004static void M165CWM(uint32 A, uint8 V)
1005{
e2d0dd92 1006 if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2))
1007 M165PPUFD();
1008 if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4))
1009 M165PPUFE();
d97315ac 1010}
1011
1012static void FP_FASTAPASS(1) M165PPU(uint32 A)
1013{
1014 if((A&0x1FF0)==0x1FD0)
1015 {
1016 EXPREGS[0]=0xFD;
1017 M165PPUFD();
1018 } else if((A&0x1FF0)==0x1FE0)
1019 {
1020 EXPREGS[0]=0xFE;
1021 M165PPUFE();
1022 }
1023}
1024
1025static void M165Power(void)
1026{
1027 EXPREGS[0]=0xFD;
1028 GenMMC3Power();
1029}
1030
1031void Mapper165_Init(CartInfo *info)
1032{
1033 GenMMC3_Init(info, 512, 128, 8, info->battery);
1034 cwrap=M165CWM;
1035 PPU_hook=M165PPU;
1036 info->Power=M165Power;
1037 CHRRAMSize = 4096;
1038 CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
1039 SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
1040 AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
1041 AddExState(EXPREGS, 4, 0, "EXPR");
1042}
1043
1044// ---------------------------- Mapper 182 ------------------------------
1045