updated bords/mappers/stuff to 0.98.15, lots of them got broken, asmcore support...
[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
30uint8 MMC3_cmd=0;
31uint8 *WRAM=0;
32uint8 *CHRRAM=0;
33uint32 CHRRAMSize=0;
34uint8 EXPREGS[8]={0,0,0,0,0,0,0,0}; /* For bootleg games, mostly. */
35
36static uint8 A000B=0,A001B=0;
37static uint8 DRegBuf[8]={0,0,0,0,0,0,0,0};
38
39#undef IRQCount
40#undef IRQLatch
41#undef IRQa
42uint8 IRQCount=0,IRQLatch=0,IRQa=0;
43uint8 IRQReload=0;
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;
59static int wrams=0;
60
61void (*pwrap)(uint32 A, uint8 V);
62void (*cwrap)(uint32 A, uint8 V);
63void (*mwrap)(uint8 V);
64
65void GenMMC3Power(void);
66void FixMMC3PRG(int V);
67void FixMMC3CHR(int V);
68
69void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
70
71// ----------------------------------------------------------------------
72// ------------------------- Generic MM3 Code ---------------------------
73// ----------------------------------------------------------------------
74
75void 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
91void 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
106void 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
123DECLFW(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
175DECLFW(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
186static 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
205static void MMC3_hb(void)
206{
207 ClockMMC3Counter();
208}
209
210static void MMC3_hb_KickMasterHack(void)
211{
212 if(scanline==238) ClockMMC3Counter();
213 ClockMMC3Counter();
214}
215
216static void MMC3_hb_PALStarWarsHack(void)
217{
218 if(scanline==240) ClockMMC3Counter();
219 ClockMMC3Counter();
220}
221
222static void genmmc3restore(int version)
223{
224 if(mwrap) mwrap(A000B&1);
225 FixMMC3PRG(MMC3_cmd);
226 FixMMC3CHR(MMC3_cmd);
227}
228
229static void GENCWRAP(uint32 A, uint8 V)
230{
231 setchr1(A,V);
232}
233
234static void GENPWRAP(uint32 A, uint8 V)
235{
236 setprg8(A,V&0x3F);
237}
238
239static void GENMWRAP(uint8 V)
240{
241 A000B=V;
242 setmirror(V^1);
243}
244
245static void GENNOMWRAP(uint8 V)
246{
247 A000B=V;
248}
249
250static DECLFW(MBWRAM)
251{
252 WRAM[A-0x6000]=V;
253}
254
255static DECLFR(MAWRAM)
256{
257 return(WRAM[A-0x6000]);
258}
259
260static DECLFW(MBWRAMMMC6)
261{
262 WRAM[A&0x3ff]=V;
263}
264
265static DECLFR(MAWRAMMMC6)
266{
267 return(WRAM[A&0x3ff]);
268}
269
270void 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
299static void GenMMC3Close(void)
300{
301 if(CHRRAM)
302 FCEU_gfree(CHRRAM);
303 if(WRAM)
304 FCEU_gfree(WRAM);
305 CHRRAM=WRAM=NULL;
306}
307
308void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
309{
310pwrap=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
365static int hackm4=0;/* For Karnov, maybe others. BLAH. Stupid iNES format.*/
366
367static void M4Power(void)
368{
369 GenMMC3Power();
370 A000B=(hackm4^1)&1;
371 setmirror(hackm4);
372}
373
374void 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
390static void M12CW(uint32 A, uint8 V)
391{
392 setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
393}
394
395static DECLFW(M12Write)
396{
397 EXPREGS[0]=V&0x01;
398 EXPREGS[1]=(V&0x10)>>4;
399}
400
401static void M12Power(void)
402{
403 EXPREGS[0]=EXPREGS[1]=0;
404 GenMMC3Power();
405 SetWriteHandler(0x4100,0x5FFF,M12Write);
406}
407
408void 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
418static 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
427static 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
435static 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
447static void M44Power(void)
448{
449 EXPREGS[0]=0;
450 GenMMC3Power();
451 SetWriteHandler(0xA000,0xBFFF,M44Write);
452}
453
454void 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
465static 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
479static void M45PW(uint32 A, uint8 V)
480{
481 V&=(EXPREGS[3]&0x3F)^0x3F;
482 V|=EXPREGS[1];
483 setprg8(A,V);
484}
485
486static 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
500static void M45Reset(void)
501{
502 FCEU_dwmemset(EXPREGS,0,5);
503 MMC3RegReset();
504}
505
506static void M45Power(void)
507{
508 M45Reset();
509 GenMMC3Power();
510 SetWriteHandler(0x6000,0x7FFF,M45Write);
511}
512
513void 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
525static void M47PW(uint32 A, uint8 V)
526{
527 V&=0xF;
528 V|=EXPREGS[0]<<4;
529 setprg8(A,V);
530}
531
532static 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
540static DECLFW(M47Write)
541{
542 EXPREGS[0]=V&1;
543 FixMMC3PRG(MMC3_cmd);
544 FixMMC3CHR(MMC3_cmd);
545}
546
547static void M47Power(void)
548{
549 EXPREGS[0]=0;
550 GenMMC3Power();
551 SetWriteHandler(0x6000,0x7FFF,M47Write);
552 SetReadHandler(0x6000,0x7FFF,0);
553}
554
555void 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
566static 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
578static 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
586static DECLFW(M49Write)
587{
588 if(A001B&0x80)
589 {
590 EXPREGS[0]=V;
591 FixMMC3PRG(MMC3_cmd);
592 FixMMC3CHR(MMC3_cmd);
593 }
594}
595
596static void M49Reset(void)
597{
598 EXPREGS[0]=0;
599 MMC3RegReset();
600}
601
602static void M49Power(void)
603{
604 M49Reset();
605 GenMMC3Power();
606 SetWriteHandler(0x6000,0x7FFF,M49Write);
607 SetReadHandler(0x6000,0x7FFF,0);
608}
609
610void 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
622static 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
630static 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
638static 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
651static void M52Reset(void)
652{
653 EXPREGS[0]=EXPREGS[1]=0;
654 MMC3RegReset();
655}
656
657static void M52Power(void)
658{
659 M52Reset();
660 GenMMC3Power();
661 SetWriteHandler(0x6000,0x7FFF,M52Write);
662}
663
664void 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
676static 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
688void 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
701static uint8 cmdin;
702uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
703
704static 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
715static 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
738static DECLFW(M114ExWrite)
739{
740 if(A<=0x7FFF)
741 {
742 EXPREGS[0]=V;
743 FixMMC3PRG(MMC3_cmd);
744 }
745}
746
747static void M114Power(void)
748{
749 GenMMC3Power();
750 SetWriteHandler(0x8000,0xFFFF,M114Write);
751 SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
752}
753
754static void M114Reset(void)
755{
756 EXPREGS[0]=0;
757 MMC3RegReset();
758}
759
760void 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
772static void M115PW(uint32 A, uint8 V)
773{
774 setprg8(A,V);
775 if(EXPREGS[0]&0x80)
776 setprg16(0x8000,EXPREGS[0]&7);
777}
778
779static void M115CW(uint32 A, uint8 V)
780{
781 setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
782}
783
784static 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
793static void M115Power(void)
794{
795 GenMMC3Power();
796 SetWriteHandler(0x4100,0x7FFF,M115Write);
797 SetReadHandler(0x4100,0x7FFF,0);
798}
799
800void 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
811static void M116CW(uint32 A, uint8 V)
812{
813 setchr1(A,V|((EXPREGS[0]&0x4)<<6));
814}
815
816static DECLFW(M116Write)
817{
818 EXPREGS[0]=V;
819 FixMMC3PRG(MMC3_cmd);
820 FixMMC3CHR(MMC3_cmd);
821}
822
823static void M116Power(void)
824{
825 GenMMC3Power();
826 SetWriteHandler(0x4100,0x4100,M116Write);
827}
828
829void 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
839static uint8 PPUCHRBus;
840static uint8 TKSMIR[8];
841
842static 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
850static 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
858void 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
869static void TQWRAP(uint32 A, uint8 V)
870{
871 setchr1r((V&0x40)>>2,A,V&0x3F);
872}
873
874void 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
885static void M191CW(uint32 A, uint8 V)
886{
887 setchr1r((V&0x80)>>3,A,V);
888}
889
890void 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
902static 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
910static void M165PPUFD(void)
911{
912 if(EXPREGS[0]==0xFD)
913 {
914 M165CW(0x0000,DRegBuf[0]);
915 M165CW(0x1000,DRegBuf[2]);
916 }
917}
918
919static void M165PPUFE(void)
920{
921 if(EXPREGS[0]==0xFE)
922 {
923 M165CW(0x0000,DRegBuf[1]);
924 M165CW(0x1000,DRegBuf[4]);
925 }
926}
927
928static 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
934static 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
947static void M165Power(void)
948{
949 EXPREGS[0]=0xFD;
950 GenMMC3Power();
951}
952
953void 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