Commit | Line | Data |
---|---|---|
0d464c77 | 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 | |
b64fb891 | 56 | void (CALLBACK *cddavCallback)(short, short)=0; |
0d464c77 | 57 | |
58 | //////////////////////////////////////////////////////////////////////// | |
59 | // CODE AREA | |
60 | //////////////////////////////////////////////////////////////////////// | |
61 | ||
650adfd2 | 62 | void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, unsigned int cycles) |
0d464c77 | 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 | ||
eedbe278 | 185 | unsigned short CALLBACK SPUreadRegister(unsigned long reg, unsigned int cycles) |
0d464c77 | 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 | ||
650adfd2 | 255 | void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cycles) |
0d464c77 | 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 | ||
650adfd2 | 268 | void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize,unsigned int cycles) |
0d464c77 | 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 | ||
eedbe278 | 283 | void CALLBACK SPUplayADPCMchannel(xa_decode_t *xap, unsigned int cycles, int is_start) |
0d464c77 | 284 | { |
285 | } | |
286 | ||
38b8a211 | 287 | void CALLBACK SPUsetCDvol(unsigned char ll, unsigned char lr, |
288 | unsigned char rl, unsigned char rr, unsigned int cycle) | |
289 | { | |
290 | } | |
291 | ||
0d464c77 | 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 | ||
650adfd2 | 351 | void SPUasync(unsigned int cycle, unsigned int flags) |
0d464c77 | 352 | { |
353 | } | |
354 | ||
eedbe278 | 355 | int SPUplayCDDAchannel(short *pcm, int nbytes, unsigned int cycle, int is_start) |
0d464c77 | 356 | { |
983a7cfd | 357 | return -1; |
0d464c77 | 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 | ||
b64fb891 | 369 | void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(short, short)) |
0d464c77 | 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 | ||
650adfd2 | 421 | long CALLBACK SPUfreeze(unsigned long ulFreezeMode,SPUFreeze_t * pF,unsigned int cycles) |
0d464c77 | 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) | |
650adfd2 | 453 | SPUwriteRegister(0x1f801c00+i*2,regArea[i],cycles); |
0d464c77 | 454 | } |
650adfd2 | 455 | SPUwriteRegister(H_SPUon1,regArea[(H_SPUon1-0xc00)/2],cycles); |
456 | SPUwriteRegister(H_SPUon2,regArea[(H_SPUon2-0xc00)/2],cycles); | |
0d464c77 | 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 | } | |
eedbe278 PC |
545 | |
546 | void CALLBACK SPUregisterScheduleCb(void (CALLBACK *callback)(unsigned int)) | |
547 | { | |
548 | } |