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" |
22 | |
23 | #define vrctemp mapbyte1[0] |
d97315ac |
24 | static uint8 indox; |
25 | |
26 | #include "emu2413.h" |
c62d2810 |
27 | |
28 | static int acount=0; |
29 | |
d97315ac |
30 | static OPLL *VRC7Sound=NULL; |
31 | static int dwave=0; |
32 | |
33 | void DoVRC7Sound(void) |
34 | { |
35 | int32 z,a; |
36 | |
37 | //if(FSettings.soundq>=1) return; |
38 | z=((SOUNDTS<<16)/soundtsinc)>>4; |
39 | a=z-dwave; |
40 | |
92764e62 |
41 | moocow(VRC7Sound, (int32 *)&Wave[dwave], a, 1); |
d97315ac |
42 | |
43 | dwave+=a; |
44 | } |
45 | |
46 | void UpdateOPLNEO(int32 *Wave, int Count) |
47 | { |
48 | moocow(VRC7Sound, Wave, Count, 4); |
49 | } |
50 | |
51 | void UpdateOPL(int Count) |
52 | { |
53 | int32 z,a; |
54 | |
55 | z=((SOUNDTS<<16)/soundtsinc)>>4; |
56 | a=z-dwave; |
57 | |
58 | if(VRC7Sound && a) |
92764e62 |
59 | moocow(VRC7Sound, (int32 *)&Wave[dwave], a, 1); |
d97315ac |
60 | |
61 | dwave=0; |
62 | } |
c62d2810 |
63 | |
64 | static INLINE void DaMirror(int V) |
65 | { |
66 | int salpo[4]={MI_V,MI_H,MI_0,MI_1}; |
67 | setmirror(salpo[V&3]); |
68 | } |
69 | |
70 | DECLFW(Mapper85_write) |
71 | { |
d97315ac |
72 | A|=(A&8)<<1; |
73 | |
74 | if(A>=0xa000 && A<=0xDFFF) |
75 | { |
76 | // printf("$%04x, $%04x\n",X.PC,A); |
77 | A&=0xF010; |
78 | { |
79 | int x=((A>>4)&1)|((A-0xA000)>>11); |
80 | mapbyte3[x]=V; |
81 | setchr1(x<<10,V); |
82 | } |
83 | } |
84 | else if(A==0x9030) |
85 | { |
86 | if(FSettings.SndRate) |
87 | { |
88 | OPLL_writeReg(VRC7Sound, indox, V); |
89 | GameExpSound.Fill=UpdateOPL; |
90 | GameExpSound.NeoFill=UpdateOPLNEO; |
91 | } |
92 | } |
93 | else switch(A&0xF010) |
c62d2810 |
94 | { |
d97315ac |
95 | case 0x8000:mapbyte2[0]=V;setprg8(0x8000,V);break; |
96 | case 0x8010:mapbyte2[1]=V;setprg8(0xa000,V);break; |
97 | case 0x9000:mapbyte2[2]=V;setprg8(0xc000,V);break; |
c62d2810 |
98 | case 0x9010:indox=V;break; |
99 | case 0xe000:mapbyte2[3]=V;DaMirror(V);break; |
100 | case 0xE010:IRQLatch=V; |
d97315ac |
101 | X6502_IRQEnd(FCEU_IQEXT); |
c62d2810 |
102 | break; |
103 | case 0xF000:IRQa=V&2; |
104 | vrctemp=V&1; |
d97315ac |
105 | if(V&2) {IRQCount=IRQLatch;} |
106 | acount=0; |
107 | X6502_IRQEnd(FCEU_IQEXT); |
c62d2810 |
108 | break; |
109 | case 0xf010:if(vrctemp) IRQa=1; |
110 | else IRQa=0; |
d97315ac |
111 | X6502_IRQEnd(FCEU_IQEXT); |
c62d2810 |
112 | break; |
113 | } |
114 | } |
115 | |
116 | static void FP_FASTAPASS(1) KonamiIRQHook(int a) |
117 | { |
d97315ac |
118 | #define ACBOO 341 |
119 | // #define ACBOO ((227*2)+1) |
c62d2810 |
120 | if(IRQa) |
121 | { |
d97315ac |
122 | acount+=a*3; |
123 | |
124 | if(acount>=ACBOO) |
c62d2810 |
125 | { |
d97315ac |
126 | doagainbub:acount-=ACBOO; |
127 | IRQCount++; |
128 | if(IRQCount&0x100) {X6502_IRQBegin(FCEU_IQEXT);IRQCount=IRQLatch;} |
129 | if(acount>=ACBOO) goto doagainbub; |
c62d2810 |
130 | } |
131 | } |
132 | } |
133 | |
134 | void Mapper85_StateRestore(int version) |
135 | { |
136 | int x; |
137 | |
d97315ac |
138 | if(version<7200) |
c62d2810 |
139 | { |
140 | for(x=0;x<8;x++) |
141 | mapbyte3[x]=CHRBankList[x]; |
142 | for(x=0;x<3;x++) |
143 | mapbyte2[x]=PRGBankList[x]; |
144 | mapbyte2[3]=(Mirroring<0x10)?Mirroring:Mirroring-0xE; |
145 | } |
146 | |
147 | for(x=0;x<8;x++) |
148 | setchr1(x*0x400,mapbyte3[x]); |
149 | for(x=0;x<3;x++) |
150 | setprg8(0x8000+x*8192,mapbyte2[x]); |
151 | DaMirror(mapbyte2[3]); |
d97315ac |
152 | //LoadOPL(); |
c62d2810 |
153 | } |
154 | |
155 | static void M85SC(void) |
156 | { |
d97315ac |
157 | if(VRC7Sound) |
158 | OPLL_set_rate(VRC7Sound, FSettings.SndRate); |
c62d2810 |
159 | } |
160 | |
d97315ac |
161 | static void M85SKill(void) |
162 | { |
163 | if(VRC7Sound) |
164 | OPLL_delete(VRC7Sound); |
165 | VRC7Sound=NULL; |
166 | } |
167 | |
168 | static void VRC7SI(void) |
169 | { |
170 | GameExpSound.RChange=M85SC; |
171 | GameExpSound.Kill=M85SKill; |
172 | |
173 | VRC7Sound=OPLL_new(3579545, FSettings.SndRate?FSettings.SndRate:44100); |
174 | OPLL_reset(VRC7Sound); |
175 | OPLL_reset(VRC7Sound); |
176 | } |
177 | |
178 | void NSFVRC7_Init(void) |
c62d2810 |
179 | { |
c62d2810 |
180 | SetWriteHandler(0x9010,0x901F,Mapper85_write); |
181 | SetWriteHandler(0x9030,0x903F,Mapper85_write); |
d97315ac |
182 | VRC7SI(); |
c62d2810 |
183 | } |
184 | |
185 | void Mapper85_init(void) |
186 | { |
187 | MapIRQHook=KonamiIRQHook; |
188 | SetWriteHandler(0x8000,0xffff,Mapper85_write); |
189 | GameStateRestore=Mapper85_StateRestore; |
c62d2810 |
190 | if(!VROM_size) |
191 | SetupCartCHRMapping(0, CHRRAM, 8192, 1); |
d97315ac |
192 | //AddExState(VRC7Instrument, 16, 0, "VC7I"); |
193 | //AddExState(VRC7Chan, sizeof(VRC7Chan), 0, "V7CH"); |
194 | VRC7SI(); |
c62d2810 |
195 | } |