d97315ac |
1 | /* FCE Ultra - NES/Famicom Emulator |
2 | * |
3 | * Copyright notice for this file: |
4 | * Copyright (C) 2002 Xodnizel |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
43725da7 |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
d97315ac |
19 | */ |
20 | |
21 | #include "mapinc.h" |
22 | |
23 | static uint8 cmd,mir,rmode,IRQmode; |
24 | static uint8 DRegs[11]; |
25 | static uint8 IRQCount,IRQa,IRQLatch; |
26 | |
27 | static SFORMAT Rambo_StateRegs[]={ |
e2d0dd92 |
28 | {&cmd, 1, "CMD"}, |
29 | {&mir, 1, "MIR"}, |
30 | {&rmode, 1, "RMOD"}, |
31 | {&IRQmode, 1, "IRQM"}, |
32 | {&IRQCount, 1, "IRQC"}, |
33 | {&IRQa, 1, "IRQA"}, |
34 | {&IRQLatch, 1, "IRQL"}, |
35 | {DRegs, 11, "DREG"}, |
36 | {0} |
d97315ac |
37 | }; |
38 | |
43725da7 |
39 | static void FP_FASTAPASS(2) (*setchr1wrap)(unsigned int A, unsigned int V); |
386f5371 |
40 | //static int nomirror; |
d97315ac |
41 | |
43725da7 |
42 | static void FP_FASTAPASS(1) RAMBO1_IRQHook(int a) |
d97315ac |
43 | { |
e2d0dd92 |
44 | static int smallcount; |
45 | if(!IRQmode) return; |
d97315ac |
46 | |
e2d0dd92 |
47 | smallcount+=a; |
48 | while(smallcount>=4) |
49 | { |
50 | smallcount-=4; |
51 | IRQCount--; |
52 | if(IRQCount==0xFF) |
d97315ac |
53 | if(IRQa) X6502_IRQBegin(FCEU_IQEXT); |
e2d0dd92 |
54 | } |
d97315ac |
55 | } |
56 | |
57 | static void RAMBO1_hb(void) |
58 | { |
e2d0dd92 |
59 | if(IRQmode) return; |
d97315ac |
60 | if(scanline==240) return; /* hmm. Maybe that should be an mmc3-only call in fce.c. */ |
e2d0dd92 |
61 | rmode=0; |
62 | IRQCount--; |
63 | if(IRQCount==0xFF) |
64 | { |
65 | if(IRQa) |
66 | { |
67 | rmode = 1; |
68 | X6502_IRQBegin(FCEU_IQEXT); |
69 | } |
70 | } |
d97315ac |
71 | } |
72 | |
73 | static void Synco(void) |
74 | { |
e2d0dd92 |
75 | int x; |
76 | |
77 | if(cmd&0x20) |
78 | { |
79 | setchr1wrap(0x0000,DRegs[0]); |
80 | setchr1wrap(0x0800,DRegs[1]); |
81 | setchr1wrap(0x0400,DRegs[8]); |
82 | setchr1wrap(0x0c00,DRegs[9]); |
83 | } |
84 | else |
85 | { |
86 | setchr1wrap(0x0000,(DRegs[0]&0xFE)); |
87 | setchr1wrap(0x0400,(DRegs[0]&0xFE)|1); |
88 | setchr1wrap(0x0800,(DRegs[1]&0xFE)); |
89 | setchr1wrap(0x0C00,(DRegs[1]&0xFE)|1); |
90 | } |
91 | |
92 | for(x=0;x<4;x++) |
93 | setchr1wrap(0x1000+x*0x400,DRegs[2+x]); |
94 | |
95 | setprg8(0x8000,DRegs[6]); |
96 | setprg8(0xA000,DRegs[7]); |
97 | |
98 | setprg8(0xC000,DRegs[10]); |
d97315ac |
99 | } |
100 | |
101 | |
102 | static DECLFW(RAMBO1_write) |
103 | { |
e2d0dd92 |
104 | switch(A&0xF001) |
d97315ac |
105 | { |
106 | case 0xa000: mir=V&1; |
386f5371 |
107 | // if(!nomirror) |
d97315ac |
108 | setmirror(mir^1); |
109 | break; |
110 | case 0x8000: cmd = V; |
111 | break; |
112 | case 0x8001: if((cmd&0xF)<10) |
e2d0dd92 |
113 | DRegs[cmd&0xF]=V; |
114 | else if((cmd&0xF)==0xF) |
115 | DRegs[10]=V; |
116 | Synco(); |
117 | break; |
d97315ac |
118 | case 0xc000: IRQLatch=V; |
119 | if(rmode==1) |
120 | IRQCount=IRQLatch; |
121 | break; |
122 | case 0xc001: rmode=1; |
e2d0dd92 |
123 | IRQCount=IRQLatch; |
124 | IRQmode=V&1; |
125 | break; |
d97315ac |
126 | case 0xE000: IRQa=0; |
127 | X6502_IRQEnd(FCEU_IQEXT); |
128 | if(rmode==1) |
129 | IRQCount=IRQLatch; |
130 | break; |
131 | case 0xE001: IRQa=1; |
132 | if(rmode==1) |
133 | IRQCount=IRQLatch; |
e2d0dd92 |
134 | break; |
d97315ac |
135 | } |
136 | } |
137 | |
138 | static void RAMBO1_Restore(int version) |
139 | { |
e2d0dd92 |
140 | Synco(); |
386f5371 |
141 | // if(!nomirror) |
e2d0dd92 |
142 | setmirror(mir^1); |
d97315ac |
143 | } |
144 | |
145 | static void RAMBO1_init(void) |
146 | { |
e2d0dd92 |
147 | int x; |
148 | for(x=0;x<11;x++) |
149 | DRegs[x]=~0; |
d97315ac |
150 | cmd=mir=0; |
386f5371 |
151 | // if(!nomirror) |
e2d0dd92 |
152 | setmirror(1); |
153 | Synco(); |
154 | GameHBIRQHook=RAMBO1_hb; |
155 | MapIRQHook=RAMBO1_IRQHook; |
156 | GameStateRestore=RAMBO1_Restore; |
157 | SetWriteHandler(0x8000,0xffff,RAMBO1_write); |
158 | AddExState(Rambo_StateRegs, ~0, 0, 0); |
d97315ac |
159 | } |
160 | |
43725da7 |
161 | static void FP_FASTAPASS(2) CHRWrap(unsigned int A, unsigned int V) |
d97315ac |
162 | { |
e2d0dd92 |
163 | setchr1(A,V); |
d97315ac |
164 | } |
165 | |
166 | void Mapper64_init(void) |
167 | { |
e2d0dd92 |
168 | setchr1wrap=CHRWrap; |
386f5371 |
169 | // nomirror=0; |
e2d0dd92 |
170 | RAMBO1_init(); |
d97315ac |
171 | } |
386f5371 |
172 | /* |
d97315ac |
173 | static int MirCache[8]; |
174 | static unsigned int PPUCHRBus; |
175 | |
43725da7 |
176 | static void FP_FASTAPASS(2) MirWrap(unsigned int A, unsigned int V) |
d97315ac |
177 | { |
e2d0dd92 |
178 | MirCache[A>>10]=(V>>7)&1; |
179 | if(PPUCHRBus==(A>>10)) |
180 | setmirror(MI_0+((V>>7)&1)); |
181 | setchr1(A,V); |
d97315ac |
182 | } |
183 | |
43725da7 |
184 | static void FP_FASTAPASS(1) MirrorFear(uint32 A) |
d97315ac |
185 | { |
e2d0dd92 |
186 | A&=0x1FFF; |
187 | A>>=10; |
188 | PPUCHRBus=A; |
189 | setmirror(MI_0+MirCache[A]); |
d97315ac |
190 | } |
191 | |
192 | void Mapper158_init(void) |
193 | { |
e2d0dd92 |
194 | setchr1wrap=MirWrap; |
195 | PPU_hook=MirrorFear; |
196 | nomirror=1; |
197 | RAMBO1_init(); |
d97315ac |
198 | } |
386f5371 |
199 | */ |