cdrom: change pause timing again
[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 void CALLBACK SPUsetCDvol(unsigned char ll, unsigned char lr,
288   unsigned char rl, unsigned char rr, unsigned int cycle)
289 {
290 }
291
292 ////////////////////////////////////////////////////////////////////////
293
294 ////////////////////////////////////////////////////////////////////////
295 // INIT/EXIT STUFF
296 ////////////////////////////////////////////////////////////////////////
297
298 long CALLBACK SPUinit(void)
299 {
300  spuMemC=(unsigned char *)spuMem;                      // just small setup
301  return 0;
302 }
303
304 ////////////////////////////////////////////////////////////////////////
305
306 int bSPUIsOpen=0;
307
308 long CALLBACK SPUopen(void)
309 {
310  if(bSPUIsOpen) return 0;
311
312  bSPUIsOpen=1;
313
314  //if(pConfigFile) ReadConfigFile(pConfigFile);
315
316  return PSE_SPU_ERR_SUCCESS;        
317 }
318
319 ////////////////////////////////////////////////////////////////////////
320
321 void SPUsetConfigFile(char * pCfg)
322 {
323  pConfigFile=pCfg;
324 }
325
326 ////////////////////////////////////////////////////////////////////////
327
328 long CALLBACK SPUclose(void)
329 {
330  if(!bSPUIsOpen) return 0;
331  bSPUIsOpen=0;
332  return 0;
333 }
334
335 ////////////////////////////////////////////////////////////////////////
336
337 long CALLBACK SPUshutdown(void)
338 {
339  return 0;
340 }
341
342 ////////////////////////////////////////////////////////////////////////
343 // MISC STUFF
344 ////////////////////////////////////////////////////////////////////////
345
346 long CALLBACK SPUtest(void)
347 {
348  return 0;
349 }
350
351 void SPUasync(unsigned int cycle, unsigned int flags)
352 {
353 }
354
355 int SPUplayCDDAchannel(short *pcm, int nbytes)
356 {
357  return -1;
358 }
359
360 ////////////////////////////////////////////////////////////////////////
361 // this functions will be called once, 
362 // passes a callback that should be called on SPU-IRQ
363
364 void CALLBACK SPUregisterCallback(void (CALLBACK *callback)(void))
365 {
366  irqCallback = callback;
367 }
368
369 void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(short, short))
370 {
371  cddavCallback = CDDAVcallback;
372 }
373
374 ////////////////////////////////////////////////////////////////////////\r
375
376 char * CALLBACK PSEgetLibName(void)
377 {
378  return libraryName;
379 }
380
381 ////////////////////////////////////////////////////////////////////////
382
383 unsigned long CALLBACK PSEgetLibType(void)
384 {
385  return  PSE_LT_SPU;
386 }
387
388 ////////////////////////////////////////////////////////////////////////\r
389
390 unsigned long CALLBACK PSEgetLibVersion(void)\r
391 {
392  return version<<16|revision<<8|build;
393 }
394
395
396 char * SPUgetLibInfos(void)
397 {
398  return libraryInfo;
399 }
400
401 ////////////////////////////////////////////////////////////////////////\r
402
403 typedef struct\r
404 {
405  char          szSPUName[8];
406  unsigned long ulFreezeVersion;
407  unsigned long ulFreezeSize;
408  unsigned char cSPUPort[0x200];
409  unsigned char cSPURam[0x80000];
410  xa_decode_t   xaS;     
411 } SPUFreeze_t;
412
413 typedef struct
414 {
415  unsigned long Future[256];
416
417 } SPUNULLFreeze_t;
418
419 ////////////////////////////////////////////////////////////////////////\r
420
421 long CALLBACK SPUfreeze(unsigned long ulFreezeMode,SPUFreeze_t * pF,unsigned int cycles)
422 {
423  int i;
424
425  if(!pF) return 0;
426
427  if(ulFreezeMode)
428   {
429    if(ulFreezeMode==1)
430     memset(pF,0,sizeof(SPUFreeze_t)+sizeof(SPUNULLFreeze_t));
431
432    strcpy(pF->szSPUName,"PBNUL");
433    pF->ulFreezeVersion=1;
434    pF->ulFreezeSize=sizeof(SPUFreeze_t)+sizeof(SPUNULLFreeze_t);
435
436    if(ulFreezeMode==2) return 1;
437
438    memcpy(pF->cSPURam,spuMem,0x80000);
439    memcpy(pF->cSPUPort,regArea,0x200);
440    // dummy:
441    memset(&pF->xaS,0,sizeof(xa_decode_t));
442    return 1;
443   }
444
445  if(ulFreezeMode!=0) return 0;
446
447  memcpy(spuMem,pF->cSPURam,0x80000);
448  memcpy(regArea,pF->cSPUPort,0x200);
449
450  for(i=0;i<0x100;i++)
451   {
452    if(i!=H_SPUon1-0xc00 && i!=H_SPUon2-0xc00)
453     SPUwriteRegister(0x1f801c00+i*2,regArea[i],cycles);
454   }
455  SPUwriteRegister(H_SPUon1,regArea[(H_SPUon1-0xc00)/2],cycles);
456  SPUwriteRegister(H_SPUon2,regArea[(H_SPUon2-0xc00)/2],cycles);
457
458  return 1;
459 }
460
461
462 //////////////////////////////////////////////////////////////////////// 
463 //////////////////////////////////////////////////////////////////////// 
464 //////////////////////////////////////////////////////////////////////// 
465 // UNUSED WINDOWS FUNCS... YOU SHOULDN'T USE THEM IN LINUX
466
467 long CALLBACK SPUconfigure(void)
468 {
469  return 0;
470 }
471
472 void CALLBACK SPUabout(void)
473 {
474 }
475
476 //////////////////////////////////////////////////////////////////////// 
477 //////////////////////////////////////////////////////////////////////// 
478 //////////////////////////////////////////////////////////////////////// 
479 // OLD PSEMU 1 FUNCS... YOU SHOULDN'T USE THEM
480
481 unsigned short CALLBACK SPUgetOne(unsigned long val) 
482
483  if(spuAddr!=0xffffffff) 
484   { 
485    return SPUreadDMA(); 
486   } 
487  if(val>=512*1024) val=512*1024-1; 
488  return spuMem[val>>1]; 
489
490  
491 void CALLBACK SPUputOne(unsigned long val,unsigned short data) 
492
493  if(spuAddr!=0xffffffff) 
494   { 
495    SPUwriteDMA(data); 
496    return; 
497   } 
498  if(val>=512*1024) val=512*1024-1; 
499  spuMem[val>>1] = data; 
500
501  
502 void CALLBACK SPUplaySample(unsigned char ch) 
503
504
505  
506 void CALLBACK SPUsetAddr(unsigned char ch, unsigned short waddr) 
507
508  //s_chan[ch].pStart=spuMemC+((unsigned long) waddr<<3); 
509
510  
511 void CALLBACK SPUsetPitch(unsigned char ch, unsigned short pitch) 
512
513  //SetPitch(ch,pitch); 
514
515  
516 void CALLBACK SPUsetVolumeL(unsigned char ch, short vol) 
517
518  //SetVolumeL(ch,vol); 
519
520  
521 void CALLBACK SPUsetVolumeR(unsigned char ch, short vol) 
522
523  //SetVolumeR(ch,vol); 
524 }                
525  
526 void CALLBACK SPUstartChannels1(unsigned short channels) 
527
528  //SoundOn(0,16,channels); 
529
530  
531 void CALLBACK SPUstartChannels2(unsigned short channels) 
532
533  //SoundOn(16,24,channels); 
534
535  
536 void CALLBACK SPUstopChannels1(unsigned short channels) 
537
538  //SoundOff(0,16,channels); 
539
540  
541 void CALLBACK SPUstopChannels2(unsigned short channels) 
542
543  //SoundOff(16,24,channels); 
544