merge mapper code from FCEUX
[fceu.git] / boards / 253.c
CommitLineData
386f5371 1/* FCE Ultra - NES/Famicom Emulator\r
2 *\r
3 * Copyright notice for this file:\r
4 * Copyright (C) 2009 CaH4e3\r
5 *\r
6 * This program is free software; you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation; either version 2 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * This program is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with this program; if not, write to the Free Software\r
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
19 */\r
20\r
21#include "mapinc.h"\r
22\r
23static uint8 chrlo[8], chrhi[8], prg[2], mirr, vlock;\r
24static int32 IRQa, IRQCount, IRQLatch, IRQClock; \r
25static uint8 *WRAM=NULL;\r
26static uint32 WRAMSIZE;\r
27static uint8 *CHRRAM=NULL;\r
28static uint32 CHRRAMSIZE;\r
29\r
30static SFORMAT StateRegs[]=\r
31{\r
32 {chrlo, 8, "CHRLO"},\r
33 {chrhi, 8, "CHRHI"},\r
34 {prg, 2, "PRGR"},\r
35 {&mirr, 1, "MIRR"},\r
36 {&vlock, 1, "VLOCK"},\r
37 {&IRQa, 4, "IRQA"},\r
38 {&IRQCount, 4, "IRQC"},\r
39 {&IRQLatch, 4, "IRQL"},\r
40 {&IRQClock, 4, "IRQK"},\r
41 {0}\r
42};\r
43\r
44static void Sync(void)\r
45{\r
46 uint8 i;\r
47 setprg8r(0x10,0x6000,0);\r
48 setprg8(0x8000,prg[0]);\r
49 setprg8(0xa000,prg[1]);\r
50 setprg8(0xc000,~1);\r
51 setprg8(0xe000,~0);\r
52 for(i=0; i<8; i++)\r
53 {\r
54 uint32 chr = chrlo[i]|(chrhi[i]<<8);\r
55 if(chrlo[i]==0xc8)\r
56 {\r
57 vlock = 0;\r
58 continue;\r
59 }\r
60 else if(chrlo[i]==0x88)\r
61 {\r
62 vlock = 1;\r
63 continue;\r
64 }\r
65 if(((chrlo[i]==4)||(chrlo[i]==5))&&!vlock)\r
66 setchr1r(0x10,i<<10,chr&1);\r
67 else\r
68 setchr1(i<<10,chr);\r
69 }\r
70 switch(mirr)\r
71 {\r
72 case 0: setmirror(MI_V); break;\r
73 case 1: setmirror(MI_H); break;\r
74 case 2: setmirror(MI_0); break;\r
75 case 3: setmirror(MI_1); break;\r
76 }\r
77}\r
78\r
79static DECLFW(M253Write)\r
80{\r
81 if((A>=0xB000)&&(A<=0xE00C))\r
82 {\r
83 uint8 ind=((((A&8)|(A>>8))>>3)+2)&7;\r
84 uint8 sar=A&4;\r
85 chrlo[ind]=(chrlo[ind]&(0xF0>>sar))|((V&0x0F)<<sar);\r
86 if(A&4)\r
87 chrhi[ind]=V>>4;\r
88 Sync();\r
89 }\r
90 else\r
91 switch(A)\r
92 {\r
93 case 0x8010: prg[0]=V; Sync(); break;\r
94 case 0xA010: prg[1]=V; Sync(); break;\r
95 case 0x9400: mirr=V&3; Sync(); break;\r
96 case 0xF000: IRQLatch = (IRQLatch & 0xF0) | (V & 0x0F); break;\r
97 case 0xF004: IRQLatch = (IRQLatch & 0x0F) | (V << 4); break;\r
98 case 0xF008:\r
99 IRQa = V&3;\r
100 if(IRQa&2)\r
101 {\r
102 IRQCount = IRQLatch;\r
103 IRQClock = 0;\r
104 }\r
105 X6502_IRQEnd(FCEU_IQEXT);\r
106 break;\r
107 }\r
108}\r
109\r
110static void M253Power(void)\r
111{\r
112 Sync();\r
113 SetReadHandler(0x6000,0x7FFF,CartBR);\r
114 SetWriteHandler(0x6000,0x7FFF,CartBW);\r
115 SetReadHandler(0x8000,0xFFFF,CartBR);\r
116 SetWriteHandler(0x8000,0xFFFF,M253Write);\r
117}\r
118\r
119static void M253Close(void)\r
120{\r
121 if(WRAM)\r
122 FCEU_gfree(WRAM);\r
123 if(CHRRAM)\r
124 FCEU_gfree(CHRRAM);\r
125 WRAM=CHRRAM=NULL;\r
126}\r
127\r
128static void M253IRQ(int cycles)\r
129{\r
130 if(IRQa&2) \r
131 {\r
132 if((IRQClock+=cycles)>=0x72) \r
133 {\r
134 IRQClock -= 0x72;\r
135 if(IRQCount==0xFF) \r
136 {\r
137 IRQCount = IRQLatch;\r
138 IRQa = IRQa|((IRQa&1)<<1);\r
139 X6502_IRQBegin(FCEU_IQEXT);\r
140 }\r
141 else \r
142 IRQCount++;\r
143 }\r
144 }\r
145}\r
146\r
147static void StateRestore(int version)\r
148{\r
149 Sync();\r
150}\r
151\r
152void Mapper253_Init(CartInfo *info)\r
153{\r
154 info->Power=M253Power;\r
155 info->Close=M253Close;\r
156 MapIRQHook=M253IRQ;\r
157 GameStateRestore=StateRestore;\r
158\r
159 CHRRAMSIZE=4096;\r
160 CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSIZE);\r
161 SetupCartCHRMapping(0x10,CHRRAM,CHRRAMSIZE,1);\r
162 AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM");\r
163\r
164 WRAMSIZE=8192;\r
165 WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);\r
166 SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);\r
167 AddExState(WRAM, WRAMSIZE, 0, "WRAM");\r
168 if(info->battery)\r
169 {\r
170 info->SaveGame[0]=WRAM;\r
171 info->SaveGameLen[0]=WRAMSIZE;\r
172 }\r
173\r
174 AddExState(&StateRegs, ~0, 0, 0);\r
175}\r