X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=mappers%2F24and26.c;h=71fb1393b60b0f9d827f74c586aef662e6d3a14c;hb=5bd16b94320afa9dfba4985f5d69c2d84bae4c33;hp=575e5e63884418332bffc4cd842698923d623ad1;hpb=c62d28102c77e19c291c78bf6bf7f0a81abd54b9;p=fceu.git diff --git a/mappers/24and26.c b/mappers/24and26.c index 575e5e6..71fb139 100644 --- a/mappers/24and26.c +++ b/mappers/24and26.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell + * Copyright (C) 2002 Xodnizel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,15 +16,16 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * VRC-6 + * */ #include "mapinc.h" +static void (*sfun[3])(void); + #define vrctemp mapbyte1[0] -#define regb000 mapbyte3[0] -#define regb001 mapbyte3[1] -#define regb002 mapbyte3[2] -#define exchstat mapbyte4[0] #define VPSG2 mapbyte3 #define VPSG mapbyte2 @@ -33,78 +34,73 @@ static void DoSQV2(void); static void DoSawV(void); static int swaparoo; -static int32 inc; -static DECLFW(VRC6PSGW90) -{ - DoSQV1();VPSG[0]=V; -} -static DECLFW(VRC6PSGW91) -{ - DoSQV1();VPSG[2]=V; -} -static DECLFW(VRC6PSGW92) -{ - DoSQV1();VPSG[3]=V; -} -static DECLFW(VRC6PSGWA0) -{ - DoSQV2();VPSG[4]=V; -} -static DECLFW(VRC6PSGWA1) -{ - DoSQV2();VPSG[6]=V; -} -static DECLFW(VRC6PSGWA2) -{ - DoSQV2();VPSG[7]=V; -} -static DECLFW(VRC6PSGWB0) -{ - DoSawV();VPSG2[0]=V; -} -static DECLFW(VRC6PSGWB1) -{ - DoSawV();VPSG2[1]=V; -} -static DECLFW(VRC6PSGWB2) -{ - DoSawV();VPSG2[2]=V; -} static int acount=0; static void FP_FASTAPASS(1) KonamiIRQHook(int a) { - #define LCYCS 114 + #define LCYCS 341 +// #define LCYCS ((227*2)+1) if(IRQa) { - acount+=a; + acount+=a*3; if(acount>=LCYCS) { doagainbub:acount-=LCYCS;IRQCount++; - if(IRQCount==0x100) {TriggerIRQ();IRQCount=IRQLatch;} + if(IRQCount==0x100) + { + X6502_IRQBegin(FCEU_IQEXT); + IRQCount=IRQLatch; + } if(acount>=LCYCS) goto doagainbub; } } } -DECLFW(Mapper24_write) +static DECLFW(VRC6SW) { - if(swaparoo) - A=(A&0xFFFC)|((A>>1)&1)|((A<<1)&2); + A&=0xF003; + if(A>=0x9000 && A<=0x9002) + { + VPSG[A&3]=V; + if(sfun[0]) sfun[0](); + } + else if(A>=0xa000 && A<=0xa002) + { + VPSG[4|(A&3)]=V; + if(sfun[1]) sfun[1](); + } + else if(A>=0xb000 && A<=0xb002) + { + VPSG2[A&3]=V; + if(sfun[2]) sfun[2](); + } + +} +static DECLFW(Mapper24_write) +{ + if(swaparoo) + A=(A&0xFFFC)|((A>>1)&1)|((A<<1)&2); + if(A>=0x9000 && A<=0xb002) + { + VRC6SW(A,V); + return; + } + A&=0xF003; +// if(A>=0xF000) printf("%d, %d, $%04x:$%02x\n",scanline,timestamp,A,V); switch(A&0xF003) - { + { case 0x8000:ROM_BANK16(0x8000,V);break; case 0xB003: - switch(V&0xF) - { - case 0x0:MIRROR_SET2(1);break; - case 0x4:MIRROR_SET2(0);break; - case 0x8:onemir(0);break; - case 0xC:onemir(1);break; - } - break; + switch(V&0xF) + { + case 0x0:MIRROR_SET2(1);break; + case 0x4:MIRROR_SET2(0);break; + case 0x8:onemir(0);break; + case 0xC:onemir(1);break; + } + break; case 0xC000:ROM_BANK8(0xC000,V);break; case 0xD000:VROM_BANK1(0x0000,V);break; case 0xD001:VROM_BANK1(0x0400,V);break; @@ -114,113 +110,73 @@ DECLFW(Mapper24_write) case 0xE001:VROM_BANK1(0x1400,V);break; case 0xE002:VROM_BANK1(0x1800,V);break; case 0xE003:VROM_BANK1(0x1c00,V);break; - case 0xF000:IRQLatch=V;break; + case 0xF000:IRQLatch=V; + //acount=0; + break; case 0xF001:IRQa=V&2; vrctemp=V&1; - if(V&2) {IRQCount=IRQLatch;} - //acount=0; + if(V&2) + { + IRQCount=IRQLatch; + acount=0; + } + X6502_IRQEnd(FCEU_IQEXT); break; - case 0xf002:IRQa=vrctemp;break; + case 0xf002:IRQa=vrctemp; + X6502_IRQEnd(FCEU_IQEXT);break; case 0xF003:break; } } -static int CVBC[3]={0,0,0}; -static int32 vcount[2]; +static int32 CVBC[3]; +static int32 vcount[3]; +static int32 dcount[2]; -static void DoSQV1(void) +static INLINE void DoSQV(int x) { - uint8 amp; - int32 freq; - int V; - int32 start,end; - - start=CVBC[0]; - end=(timestamp<<16)/soundtsinc; - if(end<=start) return; - CVBC[0]=end; - - if(VPSG[0x3]&0x80) + int32 V; + int32 amp=(((VPSG[x<<2]&15)<<8)*6/8)>>4; + int32 start,end; + + start=CVBC[x]; + end=(SOUNDTS<<16)/soundtsinc; + if(end<=start) return; + CVBC[x]=end; + + if(VPSG[(x<<2)|0x2]&0x80) + { + if(VPSG[x<<2]&0x80) + { + for(V=start;V>4]+=amp; + } + else + { + int32 thresh=(VPSG[x<<2]>>4)&7; + int32 freq=((VPSG[(x<<2)|0x1]|((VPSG[(x<<2)|0x2]&15)<<8))+1)<<17; + for(V=start;Vthresh) /* Greater than, not >=. Important. */ + Wave[V>>4]+=amp; + vcount[x]-=nesincsize; + while(vcount[x]<=0) /* Should only be <0 in a few circumstances. */ { - amp=(VPSG[0]&15)<<4; - if(VPSG[0]&0x80) - { - for(V=start;V>4]+=amp; - } - else - { - unsigned long dcycs; - freq=(((VPSG[0x2]|((VPSG[0x3]&15)<<8))+1)); - inc=(long double)((unsigned long)((FSettings.SndRate OVERSAMPLE)<<12))/((long double)PSG_base/freq); - switch(VPSG[0]&0x70) - { - default: - case 0x00:dcycs=inc>>4;break; - case 0x10:dcycs=inc>>3;break; - case 0x20:dcycs=(inc*3)>>4;break; - case 0x30:dcycs=inc>>2;break; - case 0x40:dcycs=(inc*5)>>4;break; - case 0x50:dcycs=(inc*6)>>4;break; - case 0x60:dcycs=(inc*7)>>4;break; - case 0x70:dcycs=inc>>1;break; - } - for(V=start;V>4]+=amp; - vcount[0]+=0x1000; - if(vcount[0]>=inc) vcount[0]-=inc; - } - } + vcount[x]+=freq; + dcount[x]=(dcount[x]+1)&15; } + } + } + } } -static void DoSQV2(void) -{ - uint8 amp; - int32 freq; - int V; - int32 start,end; - start=CVBC[1]; - end=(timestamp<<16)/soundtsinc; - if(end<=start) return; - CVBC[1]=end; +static void DoSQV1(void) +{ + DoSQV(0); +} - if(VPSG[0x7]&0x80) - { - amp=(VPSG[4]&15)<<4; - if(VPSG[4]&0x80) - { - for(V=start;V>4]+=amp; - } - else - { - unsigned long dcycs; - freq=(((VPSG[0x6]|((VPSG[0x7]&15)<<8))+1)); - inc=(long double)((unsigned long)((FSettings.SndRate OVERSAMPLE)<<12))/((long double)PSG_base/freq); - switch(VPSG[4]&0x70) - { - default: - case 0x00:dcycs=inc>>4;break; - case 0x10:dcycs=inc>>3;break; - case 0x20:dcycs=(inc*3)>>4;break; - case 0x30:dcycs=inc>>2;break; - case 0x40:dcycs=(inc*5)>>4;break; - case 0x50:dcycs=(inc*6)>>4;break; - case 0x60:dcycs=(inc*7)>>4;break; - case 0x70:dcycs=inc>>1;break; - } - for(V=start;V>4]+=amp; - vcount[1]+=0x1000; - if(vcount[1]>=inc) vcount[1]-=inc; - } - } - } +static void DoSQV2(void) +{ + DoSQV(1); } static void DoSawV(void) @@ -229,13 +185,13 @@ static void DoSawV(void) int32 start,end; start=CVBC[2]; - end=(timestamp<<16)/soundtsinc; + end=(SOUNDTS<<16)/soundtsinc; if(end<=start) return; CVBC[2]=end; if(VPSG2[2]&0x80) { - static int64 saw1phaseacc=0; + static int32 saw1phaseacc=0; uint32 freq3; static uint8 b3=0; static int32 phaseacc=0; @@ -245,13 +201,13 @@ static void DoSawV(void) for(V=start;V>3)&0x1f)<<4); + duff=(((phaseacc>>3)&0x1f)<<4)*6/8; } Wave[V>>4]+=duff; } } } -void VRC6Sound(int Count) +static INLINE void DoSQVHQ(int x) { - int x; + int32 V; + int32 amp=((VPSG[x<<2]&15)<<8)*6/8; - DoSQV1(); - DoSQV2(); - DoSawV(); - for(x=0;x<3;x++) - CVBC[x]=Count; + if(VPSG[(x<<2)|0x2]&0x80) + { + if(VPSG[x<<2]&0x80) + { + for(V=CVBC[x];V>4)&7; + for(V=CVBC[x];Vthresh) /* Greater than, not >=. Important. */ + WaveHi[V]+=amp; + vcount[x]--; + if(vcount[x]<=0) /* Should only be <0 in a few circumstances. */ + { + vcount[x]=(VPSG[(x<<2)|0x1]|((VPSG[(x<<2)|0x2]&15)<<8))+1; + dcount[x]=(dcount[x]+1)&15; + } + } + } + } + CVBC[x]=SOUNDTS; } -static int satype=0; +static void DoSQV1HQ(void) +{ + DoSQVHQ(0); +} -void VRC6SoundC(void) +static void DoSQV2HQ(void) { - int x; + DoSQVHQ(1); +} - if(FSettings.SndRate) - VRC6_ESI(satype); - else +static void DoSawVHQ(void) +{ + static uint8 b3=0; + static int32 phaseacc=0; + int32 V; + + if(VPSG2[2]&0x80) + { + for(V=CVBC[2];V>3)&0x1f)<<8)*6/8; + vcount[2]--; + if(vcount[2]<=0) { - SetWriteHandler(0x9000+x,0x9002+x,0); - SetWriteHandler(0xa000+x,0xa002+x,0); - SetWriteHandler(0xb000+x,0xb002+x,0); + vcount[2]=(VPSG2[1]+((VPSG2[2]&15)<<8)+1)<<1; + phaseacc+=VPSG2[0]&0x3f; + b3++; + if(b3==7) + { + b3=0; + phaseacc=0; + } + } } + } + CVBC[2]=SOUNDTS; } -void VRC6_ESI(int t) + +void VRC6Sound(int Count) { - int x; + int x; - satype=t; + DoSQV1(); + DoSQV2(); + DoSawV(); + for(x=0;x<3;x++) + CVBC[x]=Count; +} - GameExpSound.RChange=VRC6SoundC; +void VRC6SoundHQ(void) +{ + DoSQV1HQ(); + DoSQV2HQ(); + DoSawVHQ(); +} + +void VRC6SyncHQ(int32 ts) +{ + int x; + for(x=0;x<3;x++) CVBC[x]=ts; +} + +static void VRC6_ESI(void) +{ + GameExpSound.RChange=VRC6_ESI; GameExpSound.Fill=VRC6Sound; + GameExpSound.HiFill=VRC6SoundHQ; + GameExpSound.HiSync=VRC6SyncHQ; + + memset(CVBC,0,sizeof(CVBC)); + memset(vcount,0,sizeof(vcount)); + memset(dcount,0,sizeof(dcount)); if(FSettings.SndRate) - for(x=000;x<0x1000;x+=4) + { + if(FSettings.soundq>=1) + { + sfun[0]=DoSQV1HQ; + sfun[1]=DoSQV2HQ; + sfun[2]=DoSawVHQ; + } + else { - uint32 a; - - a=0x9000+x; - SetWriteHandler(a,a,VRC6PSGW90); - SetWriteHandler(a+(1^t),a+(1^t),VRC6PSGW91); - SetWriteHandler(a+(2^t),a+(2^t),VRC6PSGW92); - - a=0xa000+x; - SetWriteHandler(a,a,VRC6PSGWA0); - SetWriteHandler(a+(1^t),a+(1^t),VRC6PSGWA1); - SetWriteHandler(a+(2^t),a+(2^t),VRC6PSGWA2); - - a=0xb000+x; - SetWriteHandler(a,a,VRC6PSGWB0); - SetWriteHandler(a+(1^t),a+(1^t),VRC6PSGWB1); - SetWriteHandler(a+(2^t),a+(2^t),VRC6PSGWB2); + sfun[0]=DoSQV1; + sfun[1]=DoSQV2; + sfun[2]=DoSawV; } + } + else + memset(sfun,0,sizeof(sfun)); } void Mapper24_init(void) { SetWriteHandler(0x8000,0xffff,Mapper24_write); - if(FSettings.SndRate) - VRC6_ESI(0); - GameExpSound.RChange=VRC6SoundC; + VRC6_ESI(); MapIRQHook=KonamiIRQHook; - swaparoo=0; + swaparoo=0; } void Mapper26_init(void) { SetWriteHandler(0x8000,0xffff,Mapper24_write); - if(FSettings.SndRate) - VRC6_ESI(3); - GameExpSound.RChange=VRC6SoundC; + VRC6_ESI(); MapIRQHook=KonamiIRQHook; - swaparoo=1; + swaparoo=1; } +void NSFVRC6_Init(void) +{ + VRC6_ESI(); + SetWriteHandler(0x8000,0xbfff,VRC6SW); +}