From 0d464c772e9a22e02818c309b79f8cc724ebb891 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 6 Dec 2010 01:30:37 +0200 Subject: [PATCH] add Pete's null SPU plugin --- Makefile | 3 + plugins/spunull/register.h | 121 +++++++++ plugins/spunull/spunull.c | 538 +++++++++++++++++++++++++++++++++++++ plugins/spunull/xa.h | 22 ++ 4 files changed, 684 insertions(+) create mode 100644 plugins/spunull/register.h create mode 100644 plugins/spunull/spunull.c create mode 100644 plugins/spunull/xa.h diff --git a/Makefile b/Makefile index 37d13118..88972b6e 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,9 @@ OBJS += frontend/linux/fbdev.o $(TARGET): $(OBJS) $(CC) -o $@ $^ $(LDFLAGS) -Wl,-Map=$@.map +spunull.so: plugins/spunull/spunull.c + $(CC) $(CFLAGS) -shared -fPIC -o $@ $^ + clean: $(RM) $(TARGET) $(OBJS) diff --git a/plugins/spunull/register.h b/plugins/spunull/register.h new file mode 100644 index 00000000..52128b76 --- /dev/null +++ b/plugins/spunull/register.h @@ -0,0 +1,121 @@ +#define H_SPUirqAddr 0x0da4 +#define H_SPUaddr 0x0da6 +#define H_SPUdata 0x0da8 +#define H_SPUctrl 0x0daa +#define H_SPUstat 0x0dae +#define H_SPUon1 0x0d88 +#define H_SPUon2 0x0d8a +#define H_SPUoff1 0x0d8c +#define H_SPUoff2 0x0d8e +#define H_FMod1 0x0d90 +#define H_FMod2 0x0d92 +#define H_Noise1 0x0d94 +#define H_Noise2 0x0d96 +#define H_RVBon1 0x0d98 +#define H_RVBon2 0x0d9a +#define H_SPUIsOn1 0x0d9c +#define H_SPUIsOn2 0x0d9e +#define H_CDLeft 0x0db0 +#define H_CDRight 0x0db2 +#define H_Reverb 0x0dc0 + +#define H_SPUPitch0 0x0c04 +#define H_SPUPitch1 0x0c14 +#define H_SPUPitch2 0x0c24 +#define H_SPUPitch3 0x0c34 +#define H_SPUPitch4 0x0c44 +#define H_SPUPitch5 0x0c54 +#define H_SPUPitch6 0x0c64 +#define H_SPUPitch7 0x0c74 +#define H_SPUPitch8 0x0c84 +#define H_SPUPitch9 0x0c94 +#define H_SPUPitch10 0x0ca4 +#define H_SPUPitch11 0x0cb4 +#define H_SPUPitch12 0x0cc4 +#define H_SPUPitch13 0x0cd4 +#define H_SPUPitch14 0x0ce4 +#define H_SPUPitch15 0x0cf4 +#define H_SPUPitch16 0x0d04 +#define H_SPUPitch17 0x0d14 +#define H_SPUPitch18 0x0d24 +#define H_SPUPitch19 0x0d34 +#define H_SPUPitch20 0x0d44 +#define H_SPUPitch21 0x0d54 +#define H_SPUPitch22 0x0d64 +#define H_SPUPitch23 0x0d74 + +#define H_SPUStartAdr0 0x0c06 +#define H_SPUStartAdr1 0x0c16 +#define H_SPUStartAdr2 0x0c26 +#define H_SPUStartAdr3 0x0c36 +#define H_SPUStartAdr4 0x0c46 +#define H_SPUStartAdr5 0x0c56 +#define H_SPUStartAdr6 0x0c66 +#define H_SPUStartAdr7 0x0c76 +#define H_SPUStartAdr8 0x0c86 +#define H_SPUStartAdr9 0x0c96 +#define H_SPUStartAdr10 0x0ca6 +#define H_SPUStartAdr11 0x0cb6 +#define H_SPUStartAdr12 0x0cc6 +#define H_SPUStartAdr13 0x0cd6 +#define H_SPUStartAdr14 0x0ce6 +#define H_SPUStartAdr15 0x0cf6 +#define H_SPUStartAdr16 0x0d06 +#define H_SPUStartAdr17 0x0d16 +#define H_SPUStartAdr18 0x0d26 +#define H_SPUStartAdr19 0x0d36 +#define H_SPUStartAdr20 0x0d46 +#define H_SPUStartAdr21 0x0d56 +#define H_SPUStartAdr22 0x0d66 +#define H_SPUStartAdr23 0x0d76 + +#define H_SPULoopAdr0 0x0c0e +#define H_SPULoopAdr1 0x0c1e +#define H_SPULoopAdr2 0x0c2e +#define H_SPULoopAdr3 0x0c3e +#define H_SPULoopAdr4 0x0c4e +#define H_SPULoopAdr5 0x0c5e +#define H_SPULoopAdr6 0x0c6e +#define H_SPULoopAdr7 0x0c7e +#define H_SPULoopAdr8 0x0c8e +#define H_SPULoopAdr9 0x0c9e +#define H_SPULoopAdr10 0x0cae +#define H_SPULoopAdr11 0x0cbe +#define H_SPULoopAdr12 0x0cce +#define H_SPULoopAdr13 0x0cde +#define H_SPULoopAdr14 0x0cee +#define H_SPULoopAdr15 0x0cfe +#define H_SPULoopAdr16 0x0d0e +#define H_SPULoopAdr17 0x0d1e +#define H_SPULoopAdr18 0x0d2e +#define H_SPULoopAdr19 0x0d3e +#define H_SPULoopAdr20 0x0d4e +#define H_SPULoopAdr21 0x0d5e +#define H_SPULoopAdr22 0x0d6e +#define H_SPULoopAdr23 0x0d7e + +#define H_SPU_ADSRLevel0 0x0c08 +#define H_SPU_ADSRLevel1 0x0c18 +#define H_SPU_ADSRLevel2 0x0c28 +#define H_SPU_ADSRLevel3 0x0c38 +#define H_SPU_ADSRLevel4 0x0c48 +#define H_SPU_ADSRLevel5 0x0c58 +#define H_SPU_ADSRLevel6 0x0c68 +#define H_SPU_ADSRLevel7 0x0c78 +#define H_SPU_ADSRLevel8 0x0c88 +#define H_SPU_ADSRLevel9 0x0c98 +#define H_SPU_ADSRLevel10 0x0ca8 +#define H_SPU_ADSRLevel11 0x0cb8 +#define H_SPU_ADSRLevel12 0x0cc8 +#define H_SPU_ADSRLevel13 0x0cd8 +#define H_SPU_ADSRLevel14 0x0ce8 +#define H_SPU_ADSRLevel15 0x0cf8 +#define H_SPU_ADSRLevel16 0x0d08 +#define H_SPU_ADSRLevel17 0x0d18 +#define H_SPU_ADSRLevel18 0x0d28 +#define H_SPU_ADSRLevel19 0x0d38 +#define H_SPU_ADSRLevel20 0x0d48 +#define H_SPU_ADSRLevel21 0x0d58 +#define H_SPU_ADSRLevel22 0x0d68 +#define H_SPU_ADSRLevel23 0x0d78 + diff --git a/plugins/spunull/spunull.c b/plugins/spunull/spunull.c new file mode 100644 index 00000000..be798c5c --- /dev/null +++ b/plugins/spunull/spunull.c @@ -0,0 +1,538 @@ +///////////////////////////////////////////////////////// + +#define PSE_LT_SPU 4 +#define PSE_SPU_ERR_SUCCESS 0 +#define PSE_SPU_ERR -60 +#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR -1 +#define PSE_SPU_ERR_INIT PSE_SPU_ERR -2 + +///////////////////////////////////////////////////////// +// main emu calls: +// 0. Get type/name/version +// 1. Init +// 2. SetCallbacks +// 3. SetConfigFile +// 4. Open +// 5. Dma/register/xa calls... +// 6. Close +// 7. Shutdown +///////////////////////////////////////////////////////// + +#include +#include +#include +#include "xa.h" +#include "register.h" +// some ms windows compatibility define +#undef CALLBACK +#define CALLBACK + +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// + +const unsigned char version = 1; +const unsigned char revision = 1; +const unsigned char build = 1; +static char * libraryName = "Pete's Null Audio Driver"; +static char * libraryInfo = "Pete's Null Audio Driver V1.1\nCoded by Pete Bernert\n"; + +//////////////////////////////////////////////////////////////////////// + +unsigned short regArea[10000]; // psx buffer +unsigned short spuMem[256*1024]; +unsigned char * spuMemC; +unsigned char * pSpuIrq=0; + +unsigned short spuCtrl, spuStat, spuIrq=0; // some vars to store psx reg infos +unsigned long spuAddr=0xffffffff; // address into spu mem +char * pConfigFile=0; + +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// + +void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq +void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0; + +//////////////////////////////////////////////////////////////////////// +// CODE AREA +//////////////////////////////////////////////////////////////////////// + +void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val) +{ + unsigned long r=reg&0xfff; + regArea[(r-0xc00)>>1] = val; + + if(r>=0x0c00 && r<0x0d80) + { + //int ch=(r>>4)-0xc0; + switch(r&0x0f) + { + //------------------------------------------------// l volume + case 0: + //SetVolumeL(ch,val); + return; + //------------------------------------------------// r volume + case 2: + //SetVolumeR(ch,val); + return; + //------------------------------------------------// pitch + case 4: + //SetPitch(ch,val); + return; + //------------------------------------------------// start + case 6: + //s_chan[ch].pStart=spuMemC+((unsigned long) val<<3); + return; + //------------------------------------------------// adsr level + case 8: + return; + //------------------------------------------------// adsr rate + case 10: + return; + //------------------------------------------------// adsr volume + case 12: + return; + //------------------------------------------------// loop adr + case 14: + return; + //------------------------------------------------// + } + return; + } + + switch(r) + { + //-------------------------------------------------// + case H_SPUaddr: + spuAddr = (unsigned long) val<<3; + return; + //-------------------------------------------------// + case H_SPUdata: + spuMem[spuAddr>>1] = val; + spuAddr+=2; + if(spuAddr>0x7ffff) spuAddr=0; + return; + //-------------------------------------------------// + case H_SPUctrl: + spuCtrl=val; + return; + //-------------------------------------------------// + case H_SPUstat: + spuStat=val & 0xf800; + return; + //-------------------------------------------------// + case H_SPUirqAddr: + spuIrq = val; + pSpuIrq=spuMemC+((unsigned long) val<<3); + return; + //-------------------------------------------------// + case H_SPUon1: + //SoundOn(0,16,val); + return; + //-------------------------------------------------// + case H_SPUon2: + //SoundOn(16,24,val); + return; + //-------------------------------------------------// + case H_SPUoff1: + //SoundOff(0,16,val); + return; + //-------------------------------------------------// + case H_SPUoff2: + //SoundOff(16,24,val); + return; + //-------------------------------------------------// + case H_CDLeft: + if(cddavCallback) cddavCallback(0,val); + return; + case H_CDRight: + if(cddavCallback) cddavCallback(1,val); + return; + //-------------------------------------------------// + case H_FMod1: + //FModOn(0,16,val); + return; + //-------------------------------------------------// + case H_FMod2: + //FModOn(16,24,val); + return; + //-------------------------------------------------// + case H_Noise1: + //NoiseOn(0,16,val); + return; + //-------------------------------------------------// + case H_Noise2: + //NoiseOn(16,24,val); + return; + //-------------------------------------------------// + case H_RVBon1: + //ReverbOn(0,16,val); + return; + //-------------------------------------------------// + case H_RVBon2: + //ReverbOn(16,24,val); + return; + //-------------------------------------------------// + case H_Reverb: + return; + } +} + +//////////////////////////////////////////////////////////////////////// + +unsigned short CALLBACK SPUreadRegister(unsigned long reg) +{ + unsigned long r=reg&0xfff; + + if(r>=0x0c00 && r<0x0d80) + { + switch(r&0x0f) + { + case 12: // adsr vol + { + //int ch=(r>>4)-0xc0; + static unsigned short adsr_dummy_vol=0; + adsr_dummy_vol=!adsr_dummy_vol; + return adsr_dummy_vol; + } + + case 14: // return curr loop adr + { + //int ch=(r>>4)-0xc0; + return 0; + } + } + } + + switch(r) + { + case H_SPUctrl: + return spuCtrl; + + case H_SPUstat: + return spuStat; + + case H_SPUaddr: + return (unsigned short)(spuAddr>>3); + + case H_SPUdata: + { + unsigned short s=spuMem[spuAddr>>1]; + spuAddr+=2; + if(spuAddr>0x7ffff) spuAddr=0; + return s; + } + + case H_SPUirqAddr: + return spuIrq; + } + return regArea[(r-0xc00)>>1]; +} + +//////////////////////////////////////////////////////////////////////// + +unsigned short CALLBACK SPUreadDMA(void) +{ + unsigned short s=spuMem[spuAddr>>1]; + spuAddr+=2; + if(spuAddr>0x7ffff) spuAddr=0; + return s; +} + +//////////////////////////////////////////////////////////////////////// + +void CALLBACK SPUwriteDMA(unsigned short val) +{ + spuMem[spuAddr>>1] = val; // spu addr got by writeregister + spuAddr+=2; // inc spu addr + if(spuAddr>0x7ffff) spuAddr=0; // wrap +} + +//////////////////////////////////////////////////////////////////////// + +void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize) +{ + int i; + for(i=0;i>1] = *pusPSXMem++; // spu addr got by writeregister + spuAddr+=2; // inc spu addr + if(spuAddr>0x7ffff) spuAddr=0; // wrap + } +} + +//////////////////////////////////////////////////////////////////////// + +void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize) +{ + int i; + for(i=0;i>1]; // spu addr got by writeregister + spuAddr+=2; // inc spu addr + if(spuAddr>0x7ffff) spuAddr=0; // wrap + } +} + +//////////////////////////////////////////////////////////////////////// +// XA AUDIO +//////////////////////////////////////////////////////////////////////// + +void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap) +{ +} + +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +// INIT/EXIT STUFF +//////////////////////////////////////////////////////////////////////// + +long CALLBACK SPUinit(void) +{ + spuMemC=(unsigned char *)spuMem; // just small setup + return 0; +} + +//////////////////////////////////////////////////////////////////////// + +int bSPUIsOpen=0; + +long CALLBACK SPUopen(void) +{ + if(bSPUIsOpen) return 0; + + bSPUIsOpen=1; + + //if(pConfigFile) ReadConfigFile(pConfigFile); + + return PSE_SPU_ERR_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////// + +void SPUsetConfigFile(char * pCfg) +{ + pConfigFile=pCfg; +} + +//////////////////////////////////////////////////////////////////////// + +long CALLBACK SPUclose(void) +{ + if(!bSPUIsOpen) return 0; + bSPUIsOpen=0; + return 0; +} + +//////////////////////////////////////////////////////////////////////// + +long CALLBACK SPUshutdown(void) +{ + return 0; +} + +//////////////////////////////////////////////////////////////////////// +// MISC STUFF +//////////////////////////////////////////////////////////////////////// + +long CALLBACK SPUtest(void) +{ + return 0; +} + +void SPUasync(unsigned int cycle) +{ +} + +void SPUplayCDDAchannel(short *pcm, int nbytes) +{ +} + +//////////////////////////////////////////////////////////////////////// +// this functions will be called once, +// passes a callback that should be called on SPU-IRQ + +void CALLBACK SPUregisterCallback(void (CALLBACK *callback)(void)) +{ + irqCallback = callback; +} + +void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned short,unsigned short)) +{ + cddavCallback = CDDAVcallback; +} + +//////////////////////////////////////////////////////////////////////// + +char * CALLBACK PSEgetLibName(void) +{ + return libraryName; +} + +//////////////////////////////////////////////////////////////////////// + +unsigned long CALLBACK PSEgetLibType(void) +{ + return PSE_LT_SPU; +} + +//////////////////////////////////////////////////////////////////////// + +unsigned long CALLBACK PSEgetLibVersion(void) +{ + return version<<16|revision<<8|build; +} + + +char * SPUgetLibInfos(void) +{ + return libraryInfo; +} + +//////////////////////////////////////////////////////////////////////// + +typedef struct +{ + char szSPUName[8]; + unsigned long ulFreezeVersion; + unsigned long ulFreezeSize; + unsigned char cSPUPort[0x200]; + unsigned char cSPURam[0x80000]; + xa_decode_t xaS; +} SPUFreeze_t; + +typedef struct +{ + unsigned long Future[256]; + +} SPUNULLFreeze_t; + +//////////////////////////////////////////////////////////////////////// + +long CALLBACK SPUfreeze(unsigned long ulFreezeMode,SPUFreeze_t * pF) +{ + int i; + + if(!pF) return 0; + + if(ulFreezeMode) + { + if(ulFreezeMode==1) + memset(pF,0,sizeof(SPUFreeze_t)+sizeof(SPUNULLFreeze_t)); + + strcpy(pF->szSPUName,"PBNUL"); + pF->ulFreezeVersion=1; + pF->ulFreezeSize=sizeof(SPUFreeze_t)+sizeof(SPUNULLFreeze_t); + + if(ulFreezeMode==2) return 1; + + memcpy(pF->cSPURam,spuMem,0x80000); + memcpy(pF->cSPUPort,regArea,0x200); + // dummy: + memset(&pF->xaS,0,sizeof(xa_decode_t)); + return 1; + } + + if(ulFreezeMode!=0) return 0; + + memcpy(spuMem,pF->cSPURam,0x80000); + memcpy(regArea,pF->cSPUPort,0x200); + + for(i=0;i<0x100;i++) + { + if(i!=H_SPUon1-0xc00 && i!=H_SPUon2-0xc00) + SPUwriteRegister(0x1f801c00+i*2,regArea[i]); + } + SPUwriteRegister(H_SPUon1,regArea[(H_SPUon1-0xc00)/2]); + SPUwriteRegister(H_SPUon2,regArea[(H_SPUon2-0xc00)/2]); + + return 1; +} + + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +// UNUSED WINDOWS FUNCS... YOU SHOULDN'T USE THEM IN LINUX + +long CALLBACK SPUconfigure(void) +{ + return 0; +} + +void CALLBACK SPUabout(void) +{ +} + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +// OLD PSEMU 1 FUNCS... YOU SHOULDN'T USE THEM + +unsigned short CALLBACK SPUgetOne(unsigned long val) +{ + if(spuAddr!=0xffffffff) + { + return SPUreadDMA(); + } + if(val>=512*1024) val=512*1024-1; + return spuMem[val>>1]; +} + +void CALLBACK SPUputOne(unsigned long val,unsigned short data) +{ + if(spuAddr!=0xffffffff) + { + SPUwriteDMA(data); + return; + } + if(val>=512*1024) val=512*1024-1; + spuMem[val>>1] = data; +} + +void CALLBACK SPUplaySample(unsigned char ch) +{ +} + +void CALLBACK SPUsetAddr(unsigned char ch, unsigned short waddr) +{ + //s_chan[ch].pStart=spuMemC+((unsigned long) waddr<<3); +} + +void CALLBACK SPUsetPitch(unsigned char ch, unsigned short pitch) +{ + //SetPitch(ch,pitch); +} + +void CALLBACK SPUsetVolumeL(unsigned char ch, short vol) +{ + //SetVolumeL(ch,vol); +} + +void CALLBACK SPUsetVolumeR(unsigned char ch, short vol) +{ + //SetVolumeR(ch,vol); +} + +void CALLBACK SPUstartChannels1(unsigned short channels) +{ + //SoundOn(0,16,channels); +} + +void CALLBACK SPUstartChannels2(unsigned short channels) +{ + //SoundOn(16,24,channels); +} + +void CALLBACK SPUstopChannels1(unsigned short channels) +{ + //SoundOff(0,16,channels); +} + +void CALLBACK SPUstopChannels2(unsigned short channels) +{ + //SoundOff(16,24,channels); +} diff --git a/plugins/spunull/xa.h b/plugins/spunull/xa.h new file mode 100644 index 00000000..cd38f96c --- /dev/null +++ b/plugins/spunull/xa.h @@ -0,0 +1,22 @@ +//============================================ +//=== Audio XA decoding +//=== Kazzuya +//============================================ + +typedef struct +{ + long y0, y1; +} ADPCM_Decode_t; + +typedef struct +{ + int freq; + int nbits; + int stereo; + int nsamples; + ADPCM_Decode_t left, right; + short pcm[16384]; +} xa_decode_t; + + + -- 2.39.2