aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--plugins/spunull/register.h121
-rw-r--r--plugins/spunull/spunull.c538
-rw-r--r--plugins/spunull/xa.h22
4 files changed, 684 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 37d1311..88972b6 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 0000000..52128b7
--- /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 0000000..be798c5
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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<iSize;i++)
+ {
+ spuMem[spuAddr>>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<iSize;i++)
+ {
+ *pusPSXMem++=spuMem[spuAddr>>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 0000000..cd38f96
--- /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;
+
+
+