diff options
author | 2007-12-17 15:19:59 +0000 | |
---|---|---|
committer | 2007-12-17 15:19:59 +0000 | |
commit | 7b77f1218624ea26dbb2efd85a19f795f5d4e02e (patch) | |
tree | 19209304095572b4fd61c2a2d6a5aa75c4e471ad /src/emu/sound/scspdsp.c | |
parent | 3da7f476068b3ffef713218ba2fc1bd5030f2c38 (diff) |
Initial checkin of MAME 0.121.mame0121
Diffstat (limited to 'src/emu/sound/scspdsp.c')
-rw-r--r-- | src/emu/sound/scspdsp.c | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/src/emu/sound/scspdsp.c b/src/emu/sound/scspdsp.c new file mode 100644 index 00000000000..9a417c47443 --- /dev/null +++ b/src/emu/sound/scspdsp.c @@ -0,0 +1,319 @@ +#include <math.h> +#include "sndintrf.h" +#include "cpuintrf.h" +#include "scsp.h" +#include "scspdsp.h" + +static UINT16 PACK(INT32 val) +{ + //cut to 16 bits + INT32 f=((UINT32 ) val)>>8; + return f; +} + +static INT32 UNPACK(UINT16 val) +{ + INT32 r=val<<8; + r<<=8; + r>>=8; + //if(r&0x00800000) + // r|=0xFF000000; + return r; +} + +void SCSPDSP_Init(struct _SCSPDSP *DSP) +{ + memset(DSP,0,sizeof(struct _SCSPDSP)); + DSP->RBL=0x8000; + DSP->Stopped=1; +} + +void SCSPDSP_Step(struct _SCSPDSP *DSP) +{ + INT32 ACC=0; //26 bit + INT32 SHIFTED=0; //24 bit + INT32 X=0; //24 bit + INT32 Y=0; //13 bit + INT32 B=0; //26 bit + INT32 INPUTS=0; //24 bit + INT32 MEMVAL=0; + INT32 FRC_REG=0; //13 bit + INT32 Y_REG=0; //24 bit + UINT32 ADDR=0; + UINT32 ADRS_REG=0; //13 bit + int step; + + if(DSP->Stopped) + return; + + memset(DSP->EFREG,0,2*16); +#if 0 + int dump=0; + FILE *f=NULL; + if(dump) + f=fopen("dsp.txt","wt"); +#endif + for(step=0;step</*128*/DSP->LastStep;++step) + { + UINT16 *IPtr=DSP->MPRO+step*4; + +// if(IPtr[0]==0 && IPtr[1]==0 && IPtr[2]==0 && IPtr[3]==0) +// break; + + UINT32 TRA=(IPtr[0]>>8)&0x7F; + UINT32 TWT=(IPtr[0]>>7)&0x01; + UINT32 TWA=(IPtr[0]>>0)&0x7F; + + UINT32 XSEL=(IPtr[1]>>15)&0x01; + UINT32 YSEL=(IPtr[1]>>13)&0x03; + UINT32 IRA=(IPtr[1]>>6)&0x3F; + UINT32 IWT=(IPtr[1]>>5)&0x01; + UINT32 IWA=(IPtr[1]>>0)&0x1F; + + UINT32 TABLE=(IPtr[2]>>15)&0x01; + UINT32 MWT=(IPtr[2]>>14)&0x01; + UINT32 MRD=(IPtr[2]>>13)&0x01; + UINT32 EWT=(IPtr[2]>>12)&0x01; + UINT32 EWA=(IPtr[2]>>8)&0x0F; + UINT32 ADRL=(IPtr[2]>>7)&0x01; + UINT32 FRCL=(IPtr[2]>>6)&0x01; + UINT32 SHIFT=(IPtr[2]>>4)&0x03; + UINT32 YRL=(IPtr[2]>>3)&0x01; + UINT32 NEGB=(IPtr[2]>>2)&0x01; + UINT32 ZERO=(IPtr[2]>>1)&0x01; + UINT32 BSEL=(IPtr[2]>>0)&0x01; + + UINT32 NOFL=(IPtr[3]>>15)&1; //???? + UINT32 COEF=(IPtr[3]>>9)&0x3f; + + UINT32 MASA=(IPtr[3]>>2)&0x1f; //??? + UINT32 ADREB=(IPtr[3]>>1)&0x1; + UINT32 NXADR=(IPtr[3]>>0)&0x1; + + INT64 v; + + //operations are done at 24 bit precision +#if 0 + if(MASA) + int a=1; + if(NOFL) + int a=1; + +// int dump=0; + + if(f) + { +#define DUMP(v) fprintf(f," " #v ": %04X",v); + + fprintf(f,"%d: ",step); + DUMP(ACC); + DUMP(SHIFTED); + DUMP(X); + DUMP(Y); + DUMP(B); + DUMP(INPUTS); + DUMP(MEMVAL); + DUMP(FRC_REG); + DUMP(Y_REG); + DUMP(ADDR); + DUMP(ADRS_REG); + fprintf(f,"\n"); + } +#endif + //INPUTS RW + assert(IRA<0x32); + if(IRA<=0x1f) + INPUTS=DSP->MEMS[IRA]; + else if(IRA<=0x2F) + INPUTS=DSP->MIXS[IRA-0x20]<<8; //MIXS is 16 bit + else if(IRA<=0x31) + INPUTS=0; + + INPUTS<<=8; + INPUTS>>=8; + //if(INPUTS&0x00800000) + // INPUTS|=0xFF000000; + + if(IWT) + { + DSP->MEMS[IWA]=MEMVAL; //MEMVAL was selected in previous MRD + if(IRA==IWA) + INPUTS=MEMVAL; + } + + //Operand sel + //B + if(!ZERO) + { + if(BSEL) + B=ACC; + else + { + B=DSP->TEMP[(TRA+DSP->DEC)&0x7F]; + B<<=8; + B>>=8; + //if(B&0x00800000) + // B|=0xFF000000; //Sign extend + } + if(NEGB) + B=0-B; + } + else + B=0; + + //X + if(XSEL) + X=INPUTS; + else + { + X=DSP->TEMP[(TRA+DSP->DEC)&0x7F]; + X<<=8; + X>>=8; + //if(X&0x00800000) + // X|=0xFF000000; + } + + //Y + if(YSEL==0) + Y=FRC_REG; + else if(YSEL==1) + Y=DSP->COEF[COEF]>>3; //COEF is 16 bits + else if(YSEL==2) + Y=(Y_REG>>11)&0x1FFF; + else if(YSEL==3) + Y=(Y_REG>>4)&0x0FFF; + + if(YRL) + Y_REG=INPUTS; + + //Shifter + if(SHIFT==0) + { + SHIFTED=ACC; + if(SHIFTED>0x007FFFFF) + SHIFTED=0x007FFFFF; + if(SHIFTED<(-0x00800000)) + SHIFTED=-0x00800000; + } + else if(SHIFT==1) + { + SHIFTED=ACC*2; + if(SHIFTED>0x007FFFFF) + SHIFTED=0x007FFFFF; + if(SHIFTED<(-0x00800000)) + SHIFTED=-0x00800000; + } + else if(SHIFT==2) + { + SHIFTED=ACC*2; + SHIFTED<<=8; + SHIFTED>>=8; + //SHIFTED&=0x00FFFFFF; + //if(SHIFTED&0x00800000) + // SHIFTED|=0xFF000000; + } + else if(SHIFT==3) + { + SHIFTED=ACC; + SHIFTED<<=8; + SHIFTED>>=8; + //SHIFTED&=0x00FFFFFF; + //if(SHIFTED&0x00800000) + // SHIFTED|=0xFF000000; + } + + //ACCUM + Y<<=19; + Y>>=19; + //if(Y&0x1000) + // Y|=0xFFFFF000; + + v=(((INT64) X*(INT64) Y)>>12); + ACC=(int) v+B; + + if(TWT) + DSP->TEMP[(TWA+DSP->DEC)&0x7F]=SHIFTED; + + if(FRCL) + { + if(SHIFT==3) + FRC_REG=SHIFTED&0x0FFF; + else + FRC_REG=(SHIFTED>>11)&0x1FFF; + } + + if(MRD || MWT) + //if(0) + { + ADDR=DSP->MADRS[MASA]; + if(!TABLE) + ADDR+=DSP->DEC; + if(ADREB) + ADDR+=ADRS_REG&0x0FFF; + if(NXADR) + ADDR++; + if(!TABLE) + ADDR&=DSP->RBL-1; + else + ADDR&=0xFFFF; + //ADDR<<=1; + //ADDR+=DSP->RBP<<13; + //MEMVAL=DSP->SCSPRAM[ADDR>>1]; + ADDR+=DSP->RBP<<12; + if (ADDR > 0x7ffff) ADDR = 0; + if(MRD && (step&1)) //memory only allowed on odd? DoA inserts NOPs on even + { + if(NOFL) + MEMVAL=DSP->SCSPRAM[ADDR]<<8; + else + MEMVAL=UNPACK(DSP->SCSPRAM[ADDR]); + } + if(MWT && (step&1)) + { + if(NOFL) + DSP->SCSPRAM[ADDR]=SHIFTED>>8; + else + DSP->SCSPRAM[ADDR]=PACK(SHIFTED); + } + } + + if(ADRL) + { + if(SHIFT==3) + ADRS_REG=(SHIFTED>>12)&0xFFF; + else + ADRS_REG=(INPUTS>>16); + } + + if(EWT) + DSP->EFREG[EWA]+=SHIFTED>>8; + + } + --DSP->DEC; + memset(DSP->MIXS,0,4*16); +// if(f) +// fclose(f); +} + +void SCSPDSP_SetSample(struct _SCSPDSP *DSP,INT32 sample,int SEL,int MXL) +{ + //DSP->MIXS[SEL]+=sample<<(MXL+1)/*7*/; + DSP->MIXS[SEL]+=sample<<7; +// if(MXL) +// int a=1; +} + +void SCSPDSP_Start(struct _SCSPDSP *DSP) +{ + int i; + DSP->Stopped=0; + for(i=127;i>=0;--i) + { + UINT16 *IPtr=DSP->MPRO+i*4; + + if(IPtr[0]!=0 || IPtr[1]!=0 || IPtr[2]!=0 || IPtr[3]!=0) + break; + } + DSP->LastStep=i+1; + +} |