1
/* FCE Ultra - NES/Famicom Emulator
3
* Copyright notice for this file:
4
* Copyright (C) 2002 Xodnizel
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.
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.
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
23
static void (*sfun[3])(void);
25
#define vrctemp mapbyte1[0]
26
#define VPSG2 mapbyte3
29
static void DoSQV1(void);
30
static void DoSQV2(void);
31
static void DoSawV(void);
37
static void KonamiIRQHook(int a)
40
// #define LCYCS ((227*2)+1)
46
doagainbub:acount-=LCYCS;IRQCount++;
49
X6502_IRQBegin(FCEU_IQEXT);
52
if(acount>=LCYCS) goto doagainbub;
60
if(A>=0x9000 && A<=0x9002)
63
if(sfun[0]) sfun[0]();
65
else if(A>=0xa000 && A<=0xa002)
68
if(sfun[1]) sfun[1]();
70
else if(A>=0xb000 && A<=0xb002)
73
if(sfun[2]) sfun[2]();
78
static DECLFW(Mapper24_write)
81
A=(A&0xFFFC)|((A>>1)&1)|((A<<1)&2);
82
if(A>=0x9000 && A<=0xb002)
88
// if(A>=0xF000) printf("%d, %d, $%04x:$%02x\n",scanline,timestamp,A,V);
91
case 0x8000:ROM_BANK16(0x8000,V);break;
95
case 0x0:MIRROR_SET2(1);break;
96
case 0x4:MIRROR_SET2(0);break;
97
case 0x8:onemir(0);break;
98
case 0xC:onemir(1);break;
101
case 0xC000:ROM_BANK8(0xC000,V);break;
102
case 0xD000:VROM_BANK1(0x0000,V);break;
103
case 0xD001:VROM_BANK1(0x0400,V);break;
104
case 0xD002:VROM_BANK1(0x0800,V);break;
105
case 0xD003:VROM_BANK1(0x0c00,V);break;
106
case 0xE000:VROM_BANK1(0x1000,V);break;
107
case 0xE001:VROM_BANK1(0x1400,V);break;
108
case 0xE002:VROM_BANK1(0x1800,V);break;
109
case 0xE003:VROM_BANK1(0x1c00,V);break;
110
case 0xF000:IRQLatch=V;
113
case 0xF001:IRQa=V&2;
120
X6502_IRQEnd(FCEU_IQEXT);
122
case 0xf002:IRQa=vrctemp;
123
X6502_IRQEnd(FCEU_IQEXT);break;
128
static int32 CVBC[3];
129
static int32 vcount[3];
130
static int32 dcount[2];
132
static INLINE void DoSQV(int x)
135
int32 amp=(((VPSG[x<<2]&15)<<8)*6/8)>>4;
139
end=(SOUNDTS<<16)/soundtsinc;
140
if(end<=start) return;
143
if(VPSG[(x<<2)|0x2]&0x80)
147
for(V=start;V<end;V++)
152
int32 thresh=(VPSG[x<<2]>>4)&7;
153
int32 freq=((VPSG[(x<<2)|0x1]|((VPSG[(x<<2)|0x2]&15)<<8))+1)<<17;
154
for(V=start;V<end;V++)
156
if(dcount[x]>thresh) /* Greater than, not >=. Important. */
158
vcount[x]-=nesincsize;
159
while(vcount[x]<=0) /* Should only be <0 in a few circumstances. */
162
dcount[x]=(dcount[x]+1)&15;
169
static void DoSQV1(void)
174
static void DoSQV2(void)
179
static void DoSawV(void)
185
end=(SOUNDTS<<16)/soundtsinc;
186
if(end<=start) return;
191
static int32 saw1phaseacc=0;
194
static int32 phaseacc=0;
195
static uint32 duff=0;
197
freq3=(VPSG2[1]+((VPSG2[2]&15)<<8)+1);
199
for(V=start;V<end;V++)
201
saw1phaseacc-=nesincsize;
209
phaseacc+=VPSG2[0]&0x3f;
218
duff=(((phaseacc>>3)&0x1f)<<4)*6/8;
225
static INLINE void DoSQVHQ(int x)
227
uint32 V; //mbg merge 7/17/06 made uint
228
int32 amp=((VPSG[x<<2]&15)<<8)*6/8;
230
if(VPSG[(x<<2)|0x2]&0x80)
234
for(V=CVBC[x];V<SOUNDTS;V++)
239
int32 thresh=(VPSG[x<<2]>>4)&7;
240
for(V=CVBC[x];V<SOUNDTS;V++)
242
if(dcount[x]>thresh) /* Greater than, not >=. Important. */
245
if(vcount[x]<=0) /* Should only be <0 in a few circumstances. */
247
vcount[x]=(VPSG[(x<<2)|0x1]|((VPSG[(x<<2)|0x2]&15)<<8))+1;
248
dcount[x]=(dcount[x]+1)&15;
256
static void DoSQV1HQ(void)
261
static void DoSQV2HQ(void)
266
static void DoSawVHQ(void)
269
static int32 phaseacc=0;
270
uint32 V; //mbg merge 7/17/06 made uint32
274
for(V=CVBC[2];V<SOUNDTS;V++)
276
WaveHi[V]+=(((phaseacc>>3)&0x1f)<<8)*6/8;
280
vcount[2]=(VPSG2[1]+((VPSG2[2]&15)<<8)+1)<<1;
281
phaseacc+=VPSG2[0]&0x3f;
296
void VRC6Sound(int Count)
307
void VRC6SoundHQ(void)
314
void VRC6SyncHQ(int32 ts)
317
for(x=0;x<3;x++) CVBC[x]=ts;
320
static void VRC6_ESI(void)
322
GameExpSound.RChange=VRC6_ESI;
323
GameExpSound.Fill=VRC6Sound;
324
GameExpSound.HiFill=VRC6SoundHQ;
325
GameExpSound.HiSync=VRC6SyncHQ;
327
memset(CVBC,0,sizeof(CVBC));
328
memset(vcount,0,sizeof(vcount));
329
memset(dcount,0,sizeof(dcount));
330
if(FSettings.SndRate)
332
if(FSettings.soundq>=1)
346
memset(sfun,0,sizeof(sfun));
349
void Mapper24_init(void)
351
SetWriteHandler(0x8000,0xffff,Mapper24_write);
353
MapIRQHook=KonamiIRQHook;
357
void Mapper26_init(void)
359
SetWriteHandler(0x8000,0xffff,Mapper24_write);
361
MapIRQHook=KonamiIRQHook;
365
void NSFVRC6_Init(void)
368
SetWriteHandler(0x8000,0xbfff,VRC6SW);