initial fce ultra 0.81 import
[fceu.git] / mappers / 16.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 1998 BERO
5  *  Copyright (C) 2002 Ben Parnell
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "mapinc.h"
23
24 static void FP_FASTAPASS(1) BandaiIRQHook(int a)
25 {
26   if(IRQa)
27   {
28    IRQCount-=a;
29    if(IRQCount<0)
30    {
31     X6502_IRQBegin(FCEU_IQEXT);
32     //printf("IRQ: %d, %d\n",scanline,timestamp);
33     IRQa=0;
34     IRQCount=0xFFFF;
35    }
36   }
37 }
38
39 static DECLFW(Mapper16_write)
40 {
41         A&=0xF;
42
43         if(A<=0x7)
44          VROM_BANK1(A<<10,V);
45         else if(A==0x8)
46          ROM_BANK16(0x8000,V);
47         else switch(A) {
48          case 0x9: switch(V&3) {
49                     case 0x00:MIRROR_SET2(1);break;
50                     case 0x01:MIRROR_SET2(0);break;
51                     case 0x02:onemir(0);break;
52                     case 0x03:onemir(1);break;
53                    }
54                    break;
55          case 0xA:X6502_IRQEnd(FCEU_IQEXT);
56                   IRQa=V&1;
57                   IRQCount=IRQLatch;
58                   break;
59          case 0xB:IRQLatch&=0xFF00;
60                   IRQLatch|=V;
61                   break;
62          case 0xC:IRQLatch&=0xFF;
63                   IRQLatch|=V<<8;
64                   break;
65          case 0xD: break;/* Serial EEPROM control port */
66  }
67 }
68
69 // Famicom jump 2:
70 // 0-7: Lower bit of data selects which 256KB PRG block is in use.
71 // This seems to be a hack on the developers' part, so I'll make emulation
72 // of it a hack(I think the current PRG block would depend on whatever the
73 // lowest bit of the CHR bank switching register that corresponds to the
74 // last CHR address read).
75
76 static void PRGO(void)
77 {
78  uint32 base=(mapbyte1[0]&1)<<4;
79  ROM_BANK16(0x8000,(mapbyte2[0]&0xF)|base);
80  ROM_BANK16(0xC000,base|0xF);
81 }
82
83 static DECLFW(Mapper153_write)
84 {
85         A&=0xF;
86         if(A<=0x7) 
87         {
88          mapbyte1[A&7]=V;
89          PRGO();
90         }
91         else if(A==0x8) 
92         {
93          mapbyte2[0]=V;
94          PRGO();
95         }
96         else switch(A) {
97          case 0x9: switch(V&3) {
98                     case 0x00:MIRROR_SET2(1);break;
99                     case 0x01:MIRROR_SET2(0);break;
100                     case 0x02:onemir(0);break;
101                     case 0x03:onemir(1);break;
102                    }
103                    break;
104          case 0xA:X6502_IRQEnd(FCEU_IQEXT);
105                   IRQa=V&1;
106                   IRQCount=IRQLatch;
107                   break;
108          case 0xB:IRQLatch&=0xFF00;
109                   IRQLatch|=V;
110                   break;
111          case 0xC:IRQLatch&=0xFF;
112                   IRQLatch|=V<<8;
113                   break;
114         }
115 }
116
117 void Mapper16_init(void)
118 {
119  MapIRQHook=BandaiIRQHook;
120  SetWriteHandler(0x6000,0xFFFF,Mapper16_write);
121 }
122
123 void Mapper153_init(void)
124 {
125  MapIRQHook=BandaiIRQHook;
126  SetWriteHandler(0x8000,0xFFFF,Mapper153_write);
127  /* This mapper/board seems to have WRAM at $6000-$7FFF, so I'll let the
128     main ines code take care of that memory region. */
129 }