Merge pull request #569 from gameblabla/gte_stalling_libretro
[pcsx_rearmed.git] / plugins / spunull / spunull.c
1 /////////////////////////////////////////////////////////
2
3 #define PSE_LT_SPU                  4
4 #define PSE_SPU_ERR_SUCCESS         0
5 #define PSE_SPU_ERR                 -60
6 #define PSE_SPU_ERR_NOTCONFIGURED   PSE_SPU_ERR -1
7 #define PSE_SPU_ERR_INIT            PSE_SPU_ERR -2
8
9 /////////////////////////////////////////////////////////
10 // main emu calls:
11 // 0. Get type/name/version
12 // 1. Init
13 // 2. SetCallbacks
14 // 3. SetConfigFile
15 // 4. Open
16 // 5. Dma/register/xa calls...
17 // 6. Close
18 // 7. Shutdown
19 /////////////////////////////////////////////////////////
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "xa.h"
25 #include "register.h"
26 // some ms windows compatibility define
27 #undef CALLBACK
28 #define CALLBACK
29
30 ////////////////////////////////////////////////////////////////////////
31
32 ////////////////////////////////////////////////////////////////////////
33
34 const unsigned char version  = 1;
35 const unsigned char revision = 1;
36 const unsigned char build    = 1;
37 static char * libraryName    = "Pete's Null Audio Driver";
38 static char * libraryInfo    = "Pete's Null Audio Driver V1.1\nCoded by Pete Bernert\n"; 
39
40 ////////////////////////////////////////////////////////////////////////
41
42 unsigned short  regArea[10000];                        // psx buffer
43 unsigned short  spuMem[256*1024];
44 unsigned char * spuMemC;
45 unsigned char * pSpuIrq=0;
46
47 unsigned short spuCtrl, spuStat, spuIrq=0;             // some vars to store psx reg infos
48 unsigned long  spuAddr=0xffffffff;                     // address into spu mem
49 char *         pConfigFile=0;
50
51 ////////////////////////////////////////////////////////////////////////
52
53 ////////////////////////////////////////////////////////////////////////
54
55 void (CALLBACK *irqCallback)(void)=0;                   // func of main emu, called on spu irq
56 void (CALLBACK *cddavCallback)(short, short)=0;
57
58 ////////////////////////////////////////////////////////////////////////
59 // CODE AREA
60 ////////////////////////////////////////////////////////////////////////
61
62 void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, unsigned int cycles)
63 {
64  unsigned long r=reg&0xfff;
65  regArea[(r-0xc00)>>1] = val;
66
67  if(r>=0x0c00 && r<0x0d80)
68   {
69    //int ch=(r>>4)-0xc0;
70    switch(r&0x0f)
71     {
72      //------------------------------------------------// l volume
73      case 0:                    
74        //SetVolumeL(ch,val);
75        return;
76      //------------------------------------------------// r volume
77      case 2:                                           
78        //SetVolumeR(ch,val);
79        return;
80      //------------------------------------------------// pitch
81      case 4:                                           
82        //SetPitch(ch,val);
83        return;
84      //------------------------------------------------// start
85      case 6:
86        //s_chan[ch].pStart=spuMemC+((unsigned long) val<<3);
87        return;
88      //------------------------------------------------// adsr level 
89      case 8:
90        return;
91      //------------------------------------------------// adsr rate 
92      case 10:
93       return;
94      //------------------------------------------------// adsr volume
95      case 12:
96        return;
97      //------------------------------------------------// loop adr
98      case 14:                                          
99        return;
100      //------------------------------------------------//
101     }
102    return;
103   }
104
105  switch(r)
106    {
107     //-------------------------------------------------//
108     case H_SPUaddr:
109         spuAddr = (unsigned long) val<<3;
110         return;
111     //-------------------------------------------------//
112     case H_SPUdata:
113         spuMem[spuAddr>>1] = val;
114         spuAddr+=2;
115         if(spuAddr>0x7ffff) spuAddr=0;
116         return;
117     //-------------------------------------------------//
118     case H_SPUctrl:
119         spuCtrl=val;
120         return;
121     //-------------------------------------------------//
122     case H_SPUstat:
123         spuStat=val & 0xf800;
124         return;
125     //-------------------------------------------------//
126     case H_SPUirqAddr:
127         spuIrq = val;
128         pSpuIrq=spuMemC+((unsigned long) val<<3);
129         return;
130     //-------------------------------------------------//
131     case H_SPUon1:
132         //SoundOn(0,16,val);
133         return;
134     //-------------------------------------------------//
135     case H_SPUon2:
136         //SoundOn(16,24,val);
137         return;
138     //-------------------------------------------------//
139     case H_SPUoff1:
140         //SoundOff(0,16,val);
141         return;
142     //-------------------------------------------------//
143     case H_SPUoff2:
144         //SoundOff(16,24,val);
145         return;
146     //-------------------------------------------------//
147     case H_CDLeft:
148         if(cddavCallback) cddavCallback(0,val);
149         return;
150     case H_CDRight:
151         if(cddavCallback) cddavCallback(1,val);
152         return;
153     //-------------------------------------------------//
154     case H_FMod1:
155         //FModOn(0,16,val);
156         return;
157     //-------------------------------------------------//
158     case H_FMod2:
159         //FModOn(16,24,val);
160         return;
161     //-------------------------------------------------//
162     case H_Noise1:
163         //NoiseOn(0,16,val);
164         return;
165     //-------------------------------------------------//
166     case H_Noise2:
167         //NoiseOn(16,24,val);
168         return;
169     //-------------------------------------------------//
170     case H_RVBon1:
171         //ReverbOn(0,16,val);
172         return;
173     //-------------------------------------------------//
174     case H_RVBon2:
175         //ReverbOn(16,24,val);
176         return;
177     //-------------------------------------------------//
178     case H_Reverb:
179         return;
180    }
181 }
182
183 ////////////////////////////////////////////////////////////////////////\r
184
185 unsigned short CALLBACK SPUreadRegister(unsigned long reg)
186 {
187  unsigned long r=reg&0xfff;
188
189  if(r>=0x0c00 && r<0x0d80)
190   {
191    switch(r&0x0f)
192     {
193      case 12:                                          // adsr vol
194       {
195        //int ch=(r>>4)-0xc0;
196        static unsigned short adsr_dummy_vol=0;
197        adsr_dummy_vol=!adsr_dummy_vol;
198        return adsr_dummy_vol;
199       }
200
201      case 14:                                          // return curr loop adr
202       {
203        //int ch=(r>>4)-0xc0;        
204        return 0;
205       }
206     }
207   }
208
209  switch(r)
210   {
211     case H_SPUctrl:
212         return spuCtrl;
213
214     case H_SPUstat:
215         return spuStat;
216         
217     case H_SPUaddr:
218         return (unsigned short)(spuAddr>>3);
219
220     case H_SPUdata:
221       {
222        unsigned short s=spuMem[spuAddr>>1];
223        spuAddr+=2;
224        if(spuAddr>0x7ffff) spuAddr=0;
225        return s;
226       }
227
228     case H_SPUirqAddr:
229         return spuIrq;
230   }
231  return regArea[(r-0xc00)>>1];
232 }
233  
234 ////////////////////////////////////////////////////////////////////////
235
236 unsigned short CALLBACK SPUreadDMA(void)
237 {
238  unsigned short s=spuMem[spuAddr>>1];
239  spuAddr+=2;
240  if(spuAddr>0x7ffff) spuAddr=0;
241  return s;
242 }
243
244 ////////////////////////////////////////////////////////////////////////
245
246 void CALLBACK SPUwriteDMA(unsigned short val)
247 {
248  spuMem[spuAddr>>1] = val;                             // spu addr got by writeregister\r
249  spuAddr+=2;                                           // inc spu addr
250  if(spuAddr>0x7ffff) spuAddr=0;                        // wrap
251 }
252
253 ////////////////////////////////////////////////////////////////////////
254
255 void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cycles)
256 {
257  int i;
258  for(i=0;i<iSize;i++)
259   {
260    spuMem[spuAddr>>1] = *pusPSXMem++;                  // spu addr got by writeregister\r
261    spuAddr+=2;                                         // inc spu addr
262    if(spuAddr>0x7ffff) spuAddr=0;                      // wrap
263   }
264 }
265
266 ////////////////////////////////////////////////////////////////////////
267
268 void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cycles)
269 {
270  int i;
271  for(i=0;i<iSize;i++)
272   {
273    *pusPSXMem++=spuMem[spuAddr>>1];                    // spu addr got by writeregister
274    spuAddr+=2;                                         // inc spu addr
275    if(spuAddr>0x7ffff) spuAddr=0;                      // wrap
276   }
277 }
278
279 ////////////////////////////////////////////////////////////////////////
280 // XA AUDIO
281 ////////////////////////////////////////////////////////////////////////
282
283 void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap)
284 {
285 }
286
287 ////////////////////////////////////////////////////////////////////////
288
289 ////////////////////////////////////////////////////////////////////////
290 // INIT/EXIT STUFF
291 ////////////////////////////////////////////////////////////////////////
292
293 long CALLBACK SPUinit(void)
294 {
295  spuMemC=(unsigned char *)spuMem;                      // just small setup
296  return 0;
297 }
298
299 ////////////////////////////////////////////////////////////////////////
300
301 int bSPUIsOpen=0;
302
303 long CALLBACK SPUopen(void)
304 {
305  if(bSPUIsOpen) return 0;
306
307  bSPUIsOpen=1;
308
309  //if(pConfigFile) ReadConfigFile(pConfigFile);
310
311  return PSE_SPU_ERR_SUCCESS;        
312 }
313
314 ////////////////////////////////////////////////////////////////////////
315
316 void SPUsetConfigFile(char * pCfg)
317 {
318  pConfigFile=pCfg;
319 }
320
321 ////////////////////////////////////////////////////////////////////////
322
323 long CALLBACK SPUclose(void)
324 {
325  if(!bSPUIsOpen) return 0;
326  bSPUIsOpen=0;
327  return 0;
328 }
329
330 ////////////////////////////////////////////////////////////////////////
331
332 long CALLBACK SPUshutdown(void)
333 {
334  return 0;
335 }
336
337 ////////////////////////////////////////////////////////////////////////
338 // MISC STUFF
339 ////////////////////////////////////////////////////////////////////////
340
341 long CALLBACK SPUtest(void)
342 {
343  return 0;
344 }
345
346 void SPUasync(unsigned int cycle, unsigned int flags)
347 {
348 }
349
350 int SPUplayCDDAchannel(short *pcm, int nbytes)
351 {
352  return -1;
353 }
354
355 ////////////////////////////////////////////////////////////////////////
356 // this functions will be called once, 
357 // passes a callback that should be called on SPU-IRQ
358
359 void CALLBACK SPUregisterCallback(void (CALLBACK *callback)(void))
360 {
361  irqCallback = callback;
362 }
363
364 void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(short, short))
365 {
366  cddavCallback = CDDAVcallback;
367 }
368
369 ////////////////////////////////////////////////////////////////////////\r
370
371 char * CALLBACK PSEgetLibName(void)
372 {
373  return libraryName;
374 }
375
376 ////////////////////////////////////////////////////////////////////////
377
378 unsigned long CALLBACK PSEgetLibType(void)
379 {
380  return  PSE_LT_SPU;
381 }
382
383 ////////////////////////////////////////////////////////////////////////\r
384
385 unsigned long CALLBACK PSEgetLibVersion(void)\r
386 {
387  return version<<16|revision<<8|build;
388 }
389
390
391 char * SPUgetLibInfos(void)
392 {
393  return libraryInfo;
394 }
395
396 ////////////////////////////////////////////////////////////////////////\r
397
398 typedef struct\r
399 {
400  char          szSPUName[8];
401  unsigned long ulFreezeVersion;
402  unsigned long ulFreezeSize;
403  unsigned char cSPUPort[0x200];
404  unsigned char cSPURam[0x80000];
405  xa_decode_t   xaS;     
406 } SPUFreeze_t;
407
408 typedef struct
409 {
410  unsigned long Future[256];
411
412 } SPUNULLFreeze_t;
413
414 ////////////////////////////////////////////////////////////////////////\r
415
416 long CALLBACK SPUfreeze(unsigned long ulFreezeMode,SPUFreeze_t * pF,unsigned int cycles)
417 {
418  int i;
419
420  if(!pF) return 0;
421
422  if(ulFreezeMode)
423   {
424    if(ulFreezeMode==1)
425     memset(pF,0,sizeof(SPUFreeze_t)+sizeof(SPUNULLFreeze_t));
426
427    strcpy(pF->szSPUName,"PBNUL");
428    pF->ulFreezeVersion=1;
429    pF->ulFreezeSize=sizeof(SPUFreeze_t)+sizeof(SPUNULLFreeze_t);
430
431    if(ulFreezeMode==2) return 1;
432
433    memcpy(pF->cSPURam,spuMem,0x80000);
434    memcpy(pF->cSPUPort,regArea,0x200);
435    // dummy:
436    memset(&pF->xaS,0,sizeof(xa_decode_t));
437    return 1;
438   }
439
440  if(ulFreezeMode!=0) return 0;
441
442  memcpy(spuMem,pF->cSPURam,0x80000);
443  memcpy(regArea,pF->cSPUPort,0x200);
444
445  for(i=0;i<0x100;i++)
446   {
447    if(i!=H_SPUon1-0xc00 && i!=H_SPUon2-0xc00)
448     SPUwriteRegister(0x1f801c00+i*2,regArea[i],cycles);
449   }
450  SPUwriteRegister(H_SPUon1,regArea[(H_SPUon1-0xc00)/2],cycles);
451  SPUwriteRegister(H_SPUon2,regArea[(H_SPUon2-0xc00)/2],cycles);
452
453  return 1;
454 }
455
456
457 //////////////////////////////////////////////////////////////////////// 
458 //////////////////////////////////////////////////////////////////////// 
459 //////////////////////////////////////////////////////////////////////// 
460 // UNUSED WINDOWS FUNCS... YOU SHOULDN'T USE THEM IN LINUX
461
462 long CALLBACK SPUconfigure(void)
463 {
464  return 0;
465 }
466
467 void CALLBACK SPUabout(void)
468 {
469 }
470
471 //////////////////////////////////////////////////////////////////////// 
472 //////////////////////////////////////////////////////////////////////// 
473 //////////////////////////////////////////////////////////////////////// 
474 // OLD PSEMU 1 FUNCS... YOU SHOULDN'T USE THEM
475
476 unsigned short CALLBACK SPUgetOne(unsigned long val) 
477
478  if(spuAddr!=0xffffffff) 
479   { 
480    return SPUreadDMA(); 
481   } 
482  if(val>=512*1024) val=512*1024-1; 
483  return spuMem[val>>1]; 
484
485  
486 void CALLBACK SPUputOne(unsigned long val,unsigned short data) 
487
488  if(spuAddr!=0xffffffff) 
489   { 
490    SPUwriteDMA(data); 
491    return; 
492   } 
493  if(val>=512*1024) val=512*1024-1; 
494  spuMem[val>>1] = data; 
495
496  
497 void CALLBACK SPUplaySample(unsigned char ch) 
498
499
500  
501 void CALLBACK SPUsetAddr(unsigned char ch, unsigned short waddr) 
502
503  //s_chan[ch].pStart=spuMemC+((unsigned long) waddr<<3); 
504
505  
506 void CALLBACK SPUsetPitch(unsigned char ch, unsigned short pitch) 
507
508  //SetPitch(ch,pitch); 
509
510  
511 void CALLBACK SPUsetVolumeL(unsigned char ch, short vol) 
512
513  //SetVolumeL(ch,vol); 
514
515  
516 void CALLBACK SPUsetVolumeR(unsigned char ch, short vol) 
517
518  //SetVolumeR(ch,vol); 
519 }                
520  
521 void CALLBACK SPUstartChannels1(unsigned short channels) 
522
523  //SoundOn(0,16,channels); 
524
525  
526 void CALLBACK SPUstartChannels2(unsigned short channels) 
527
528  //SoundOn(16,24,channels); 
529
530  
531 void CALLBACK SPUstopChannels1(unsigned short channels) 
532
533  //SoundOff(0,16,channels); 
534
535  
536 void CALLBACK SPUstopChannels2(unsigned short channels) 
537
538  //SoundOff(16,24,channels); 
539