c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator |
2 | * |
3 | * Copyright notice for this file: |
d97315ac |
4 | * Copyright (C) 2002 Xodnizel |
c62d2810 |
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 |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | #include "mapinc.h" |
d97315ac |
22 | |
c62d2810 |
23 | static void AYSound(int Count); |
d97315ac |
24 | //static void AYSoundHQ(void); |
c62d2810 |
25 | static void DoAYSQ(int x); |
d97315ac |
26 | //static void DoAYSQHQ(int x); |
c62d2810 |
27 | |
28 | #define sunselect mapbyte1[0] |
29 | #define sungah mapbyte1[1] |
d97315ac |
30 | static uint8 sunindex; |
c62d2810 |
31 | |
d97315ac |
32 | static DECLFW(SUN5BWRAM) |
c62d2810 |
33 | { |
34 | if((sungah&0xC0)==0xC0) |
35 | (WRAM-0x6000)[A]=V; |
36 | } |
37 | |
d97315ac |
38 | static DECLFR(SUN5AWRAM) |
c62d2810 |
39 | { |
40 | if((sungah&0xC0)==0x40) |
c0bf6f9f |
41 | return X.DB; |
c62d2810 |
42 | return CartBR(A); |
43 | } |
44 | |
d97315ac |
45 | static DECLFW(Mapper69_SWL) |
c62d2810 |
46 | { |
47 | sunindex=V%14; |
48 | } |
d97315ac |
49 | |
50 | static DECLFW(Mapper69_SWH) |
c62d2810 |
51 | { |
d97315ac |
52 | int x; |
c62d2810 |
53 | GameExpSound.Fill=AYSound; |
d97315ac |
54 | GameExpSound.HiFill=0;//AYSoundHQ; |
55 | if(FSettings.SndRate); |
c62d2810 |
56 | switch(sunindex) |
57 | { |
58 | case 0: |
59 | case 1: |
d97315ac |
60 | case 8:/*if(FSettings.soundq>=1) DoAYSQHQ(0); else*/ DoAYSQ(0);break; |
c62d2810 |
61 | case 2: |
62 | case 3: |
d97315ac |
63 | case 9:/*if(FSettings.soundq>=1) DoAYSQHQ(1); else*/ DoAYSQ(1);break; |
c62d2810 |
64 | case 4: |
65 | case 5: |
d97315ac |
66 | case 10:/*if(FSettings.soundq>=1) DoAYSQHQ(2); else*/ DoAYSQ(2);break; |
67 | case 7: |
68 | for(x=0;x<2;x++) |
69 | /*if(FSettings.soundq>=1) DoAYSQHQ(x); else*/ DoAYSQ(x); |
70 | break; |
c62d2810 |
71 | } |
c0bf6f9f |
72 | MapperExRAM[sunindex]=V; |
c62d2810 |
73 | } |
74 | |
d97315ac |
75 | static DECLFW(Mapper69_write) |
c62d2810 |
76 | { |
77 | switch(A&0xE000) |
78 | { |
79 | case 0x8000:sunselect=V;break; |
80 | case 0xa000: |
81 | sunselect&=0xF; |
82 | if(sunselect<=7) |
83 | VROM_BANK1(sunselect<<10,V); |
84 | else |
85 | switch(sunselect&0x0f) |
86 | { |
87 | case 8: |
88 | sungah=V; |
89 | if(V&0x40) |
90 | { |
91 | if(V&0x80) // Select WRAM |
92 | setprg8r(0x10,0x6000,0); |
93 | } |
94 | else |
95 | setprg8(0x6000,V); |
96 | break; |
d97315ac |
97 | case 9:ROM_BANK8(0x8000,V);break; |
98 | case 0xa:ROM_BANK8(0xa000,V);break; |
99 | case 0xb:ROM_BANK8(0xc000,V);break; |
c62d2810 |
100 | case 0xc: |
101 | switch(V&3) |
102 | { |
103 | case 0:MIRROR_SET2(1);break; |
104 | case 1:MIRROR_SET2(0);break; |
105 | case 2:onemir(0);break; |
106 | case 3:onemir(1);break; |
107 | } |
108 | break; |
d97315ac |
109 | case 0xd:IRQa=V;X6502_IRQEnd(FCEU_IQEXT);break; |
110 | case 0xe:IRQCount&=0xFF00;IRQCount|=V;X6502_IRQEnd(FCEU_IQEXT);break; |
111 | case 0xf:IRQCount&=0x00FF;IRQCount|=V<<8;X6502_IRQEnd(FCEU_IQEXT);break; |
c62d2810 |
112 | } |
113 | break; |
114 | } |
115 | } |
116 | |
d97315ac |
117 | static int32 vcount[3]; |
118 | static int32 dcount[3]; |
119 | static int CAYBC[3]; |
120 | |
c62d2810 |
121 | static void DoAYSQ(int x) |
122 | { |
d97315ac |
123 | int32 freq=((MapperExRAM[x<<1]|((MapperExRAM[(x<<1)+1]&15)<<8))+1)<<(4+17); |
124 | int32 amp=(MapperExRAM[0x8+x]&15)<<2; |
c62d2810 |
125 | int32 start,end; |
d97315ac |
126 | int V; |
127 | |
128 | amp+=amp>>1; |
c62d2810 |
129 | |
c0bf6f9f |
130 | start=CAYBC[x]; |
4fdfab07 |
131 | end=(SOUNDTS<<16)/soundtsinc; |
c62d2810 |
132 | if(end<=start) return; |
133 | CAYBC[x]=end; |
134 | |
d97315ac |
135 | if(amp) |
136 | if(!(MapperExRAM[0x7]&(1<<x))) |
137 | for(V=start;V<end;V++) |
c62d2810 |
138 | { |
d97315ac |
139 | if(dcount[x]) |
140 | Wave[V>>4]+=amp; |
141 | vcount[x]-=nesincsize; |
142 | while(vcount[x]<=0) |
143 | { |
144 | dcount[x]^=1; |
145 | vcount[x]+=freq; |
c62d2810 |
146 | } |
d97315ac |
147 | } |
c62d2810 |
148 | } |
c62d2810 |
149 | |
d97315ac |
150 | #if 0 |
151 | static void DoAYSQHQ(int x) |
152 | { |
153 | int32 V; |
154 | int32 freq=((MapperExRAM[x<<1]|((MapperExRAM[(x<<1)+1]&15)<<8))+1)<<4; |
155 | int32 amp=(MapperExRAM[0x8+x]&15)<<6; |
c62d2810 |
156 | |
d97315ac |
157 | amp+=amp>>1; |
c62d2810 |
158 | |
d97315ac |
159 | if(!(MapperExRAM[0x7]&(1<<x))) |
160 | { |
161 | for(V=CAYBC[x];V<SOUNDTS;V++) |
162 | { |
163 | if(dcount[x]) |
164 | WaveHi[V]+=amp; |
165 | vcount[x]--; |
166 | if(vcount[x]<=0) |
167 | { |
168 | dcount[x]^=1; |
169 | vcount[x]=freq; |
170 | } |
171 | } |
172 | } |
173 | CAYBC[x]=SOUNDTS; |
c62d2810 |
174 | } |
d97315ac |
175 | #endif |
176 | |
c62d2810 |
177 | static void AYSound(int Count) |
178 | { |
179 | int x; |
180 | DoAYSQ(0); |
181 | DoAYSQ(1); |
182 | DoAYSQ(2); |
d97315ac |
183 | for(x=0;x<3;x++) |
c62d2810 |
184 | CAYBC[x]=Count; |
185 | } |
186 | |
d97315ac |
187 | #if 0 |
188 | static void AYSoundHQ(void) |
189 | { |
190 | DoAYSQHQ(0); |
191 | DoAYSQHQ(1); |
192 | DoAYSQHQ(2); |
193 | } |
194 | #endif |
195 | |
196 | static void AYHiSync(int32 ts) |
197 | { |
198 | int x; |
199 | |
200 | for(x=0;x<3;x++) |
201 | CAYBC[x]=ts; |
202 | } |
203 | |
c62d2810 |
204 | static void FP_FASTAPASS(1) SunIRQHook(int a) |
205 | { |
206 | if(IRQa) |
207 | { |
208 | IRQCount-=a; |
209 | if(IRQCount<=0) |
d97315ac |
210 | {X6502_IRQBegin(FCEU_IQEXT);IRQa=0;IRQCount=0xFFFF;} |
c62d2810 |
211 | } |
212 | } |
213 | |
214 | void Mapper69_StateRestore(int version) |
215 | { |
d97315ac |
216 | if(mapbyte1[1]&0x40) |
c62d2810 |
217 | { |
d97315ac |
218 | if(mapbyte1[1]&0x80) // Select WRAM |
219 | setprg8r(0x10,0x6000,0); |
c62d2810 |
220 | } |
221 | else |
d97315ac |
222 | setprg8(0x6000,mapbyte1[1]); |
c62d2810 |
223 | } |
224 | |
d97315ac |
225 | void Mapper69_ESI(void) |
c62d2810 |
226 | { |
d97315ac |
227 | GameExpSound.RChange=Mapper69_ESI; |
228 | GameExpSound.HiSync=AYHiSync; |
229 | memset(dcount,0,sizeof(dcount)); |
230 | memset(vcount,0,sizeof(vcount)); |
231 | memset(CAYBC,0,sizeof(CAYBC)); |
c62d2810 |
232 | } |
233 | |
d97315ac |
234 | void NSFAY_Init(void) |
c62d2810 |
235 | { |
d97315ac |
236 | sunindex=0; |
237 | SetWriteHandler(0xc000,0xdfff,Mapper69_SWL); |
238 | SetWriteHandler(0xe000,0xffff,Mapper69_SWH); |
239 | Mapper69_ESI(); |
c62d2810 |
240 | } |
241 | |
242 | void Mapper69_init(void) |
243 | { |
d97315ac |
244 | sunindex=0; |
245 | |
c62d2810 |
246 | SetupCartPRGMapping(0x10,WRAM,8192,1); |
247 | |
248 | SetWriteHandler(0x8000,0xbfff,Mapper69_write); |
d97315ac |
249 | SetWriteHandler(0xc000,0xdfff,Mapper69_SWL); |
250 | SetWriteHandler(0xe000,0xffff,Mapper69_SWH); |
c62d2810 |
251 | SetWriteHandler(0x6000,0x7fff,SUN5BWRAM); |
252 | SetReadHandler(0x6000,0x7fff,SUN5AWRAM); |
253 | Mapper69_ESI(); |
254 | MapIRQHook=SunIRQHook; |
255 | MapStateRestore=Mapper69_StateRestore; |
c62d2810 |
256 | } |
257 | |