1 /*
2 Sega/Yamaha YMF292-F (SCSP = Saturn Custom Sound Processor) emulation
3 By ElSemi
4 MAME/M1 conversion and cleanup by R. Belmont
5 Additional code and bugfixes by kingshriek
6
7 This chip has 32 voices. Each voice can play a sample or be part of
8 an FM construct. Unlike traditional Yamaha FM chips, the base waveform
9 for the FM still comes from the wavetable RAM.
10
11 ChangeLog:
12 * November 25, 2003 (ES) Fixed buggy timers and envelope overflows.
13 (RB) Improved sample rates other than 44100, multiple
14 chips now works properly.
15 * December 02, 2003 (ES) Added DISDL register support, improves mix.
16 * April 28, 2004 (ES) Corrected envelope rates, added key-rate scaling,
17 added ringbuffer support.
18 * January 8, 2005 (RB) Added ability to specify region offset for RAM.
19 * January 26, 2007 (ES) Added on-board DSP capability
20 * December 16, 2007 (kingshriek) Many EG bug fixes, implemented effects mixer,
21 implemented FM.
22 */
23
24 #include <math.h>
25 #include <string.h>
26 #include "ao.h"
27 #include "cpuintrf.h"
28 #include "scsp.h"
29 #include "scspdsp.h"
30 #include "sat_hw.h"
31
32 #define ICLIP16(x) (x<-32768)?-32768:((x>32767)?32767:x)
33
34 #define SHIFT 12
35 #define FIX(v) ((UINT32) ((float) (1<<SHIFT)*(v)))
36
37
38 #define EG_SHIFT 16
39 #define FM_DELAY 0 // delay in number of slots processed before samples are written to the FM ring buffer
40
41 // include the LFO handling code
42 #include "scsplfo.c"
43
44 /*
45 SCSP features 32 programmable slots
46 that can generate FM and PCM (from ROM/RAM) sound
47 */
48
49 //SLOT PARAMETERS
50 #define KEYONEX(slot) ((slot->udata.data[0x0]>>0x0)&0x1000)
51 #define KEYONB(slot) ((slot->udata.data[0x0]>>0x0)&0x0800)
52 #define SBCTL(slot) ((slot->udata.data[0x0]>>0x9)&0x0003)
53 #define SSCTL(slot) ((slot->udata.data[0x0]>>0x7)&0x0003)
54 #define LPCTL(slot) ((slot->udata.data[0x0]>>0x5)&0x0003)
55 #define PCM8B(slot) ((slot->udata.data[0x0]>>0x0)&0x0010)
56
57 #define SA(slot) (((slot->udata.data[0x0]&0xF)<<16)|(slot->udata.data[0x1]))
58
59 #define LSA(slot) (slot->udata.data[0x2])
60
61 #define LEA(slot) (slot->udata.data[0x3])
62
63 #define D2R(slot) ((slot->udata.data[0x4]>>0xB)&0x001F)
64 #define D1R(slot) ((slot->udata.data[0x4]>>0x6)&0x001F)
65 #define EGHOLD(slot) ((slot->udata.data[0x4]>>0x0)&0x0020)
66 #define AR(slot) ((slot->udata.data[0x4]>>0x0)&0x001F)
67
68 #define LPSLNK(slot) ((slot->udata.data[0x5]>>0x0)&0x4000)
69 #define KRS(slot) ((slot->udata.data[0x5]>>0xA)&0x000F)
70 #define DL(slot) ((slot->udata.data[0x5]>>0x5)&0x001F)
71 #define RR(slot) ((slot->udata.data[0x5]>>0x0)&0x001F)
72
73 #define STWINH(slot) ((slot->udata.data[0x6]>>0x0)&0x0200)
74 #define SDIR(slot) ((slot->udata.data[0x6]>>0x0)&0x0100)
75 #define TL(slot) ((slot->udata.data[0x6]>>0x0)&0x00FF)
76
77 #define MDL(slot) ((slot->udata.data[0x7]>>0xC)&0x000F)
78 #define MDXSL(slot) ((slot->udata.data[0x7]>>0x6)&0x003F)
79 #define MDYSL(slot) ((slot->udata.data[0x7]>>0x0)&0x003F)
80
81 #define OCT(slot) ((slot->udata.data[0x8]>>0xB)&0x000F)
82 #define FNS(slot) ((slot->udata.data[0x8]>>0x0)&0x03FF)
83
84 #define LFORE(slot) ((slot->udata.data[0x9]>>0x0)&0x8000)
85 #define LFOF(slot) ((slot->udata.data[0x9]>>0xA)&0x001F)
86 #define PLFOWS(slot) ((slot->udata.data[0x9]>>0x8)&0x0003)
87 #define PLFOS(slot) ((slot->udata.data[0x9]>>0x5)&0x0007)
88 #define ALFOWS(slot) ((slot->udata.data[0x9]>>0x3)&0x0003)
89 #define ALFOS(slot) ((slot->udata.data[0x9]>>0x0)&0x0007)
90
91 #define ISEL(slot) ((slot->udata.data[0xA]>>0x3)&0x000F)
92 #define IMXL(slot) ((slot->udata.data[0xA]>>0x0)&0x0007)
93
94 #define DISDL(slot) ((slot->udata.data[0xB]>>0xD)&0x0007)
95 #define DIPAN(slot) ((slot->udata.data[0xB]>>0x8)&0x001F)
96 #define EFSDL(slot) ((slot->udata.data[0xB]>>0x5)&0x0007)
97 #define EFPAN(slot) ((slot->udata.data[0xB]>>0x0)&0x001F)
98
99 //Envelope times in ms
100 static const double ARTimes[64]={100000/*infinity*/,100000/*infinity*/,8100.0,6900.0,6000.0,4800.0,4000.0,3400.0,3000.0,2400.0,2000.0,1700.0,1500.0,
101 1200.0,1000.0,860.0,760.0,600.0,500.0,430.0,380.0,300.0,250.0,220.0,190.0,150.0,130.0,110.0,95.0,
102 76.0,63.0,55.0,47.0,38.0,31.0,27.0,24.0,19.0,15.0,13.0,12.0,9.4,7.9,6.8,6.0,4.7,3.8,3.4,3.0,2.4,
103 2.0,1.8,1.6,1.3,1.1,0.93,0.85,0.65,0.53,0.44,0.40,0.35,0.0,0.0};
104 static const double DRTimes[64]={100000/*infinity*/,100000/*infinity*/,118200.0,101300.0,88600.0,70900.0,59100.0,50700.0,44300.0,35500.0,29600.0,25300.0,22200.0,17700.0,
105 14800.0,12700.0,11100.0,8900.0,7400.0,6300.0,5500.0,4400.0,3700.0,3200.0,2800.0,2200.0,1800.0,1600.0,1400.0,1100.0,
106 920.0,790.0,690.0,550.0,460.0,390.0,340.0,270.0,230.0,200.0,170.0,140.0,110.0,98.0,85.0,68.0,57.0,49.0,43.0,34.0,
107 28.0,25.0,22.0,18.0,14.0,12.0,11.0,8.5,7.1,6.1,5.4,4.3,3.6,3.1};
108 static UINT32 FNS_Table[0x400];
109 static INT32 EG_TABLE[0x400];
110
111 typedef enum {ATTACK,DECAY1,DECAY2,RELEASE} _STATE;
112 struct _EG
113 {
114 int volume; //
115 _STATE state;
116 int step;
117 //step vals
118 int AR; //Attack
119 int D1R; //Decay1
120 int D2R; //Decay2
121 int RR; //Release
122
123 int DL; //Decay level
124 UINT8 EGHOLD;
125 UINT8 LPLINK;
126 };
127
128 struct _SLOT
129 {
130 union
131 {
132 UINT16 data[0x10]; //only 0x1a bytes used
133 UINT8 datab[0x20];
134 } udata;
135 UINT8 active; //this slot is currently playing
136 UINT8 *base; //samples base address
137 UINT32 cur_addr; //current play address (24.8)
138 UINT32 nxt_addr; //next play address
139 UINT32 step; //pitch step (24.8)
140 UINT8 Backwards; //the wave is playing backwards
141 struct _EG EG; //Envelope
142 struct _LFO PLFO; //Phase LFO
143 struct _LFO ALFO; //Amplitude LFO
144 int slot;
145 signed short Prev; //Previous sample (for interpolation)
146 };
147
148 #define MEM4B(scsp) ((scsp->udata.data[0]>>0x0)&0x0200)
149 #define DAC18B(scsp) ((scsp->udata.data[0]>>0x0)&0x0100)
150 #define MVOL(scsp) ((scsp->udata.data[0]>>0x0)&0x000F)
151 #define RBL(scsp) ((scsp->udata.data[1]>>0x7)&0x0003)
152 #define RBP(scsp) ((scsp->udata.data[1]>>0x0)&0x003F)
153 #define MOFULL(scsp) ((scsp->udata.data[2]>>0x0)&0x1000)
154 #define MOEMPTY(scsp) ((scsp->udata.data[2]>>0x0)&0x0800)
155 #define MIOVF(scsp) ((scsp->udata.data[2]>>0x0)&0x0400)
156 #define MIFULL(scsp) ((scsp->udata.data[2]>>0x0)&0x0200)
157 #define MIEMPTY(scsp) ((scsp->udata.data[2]>>0x0)&0x0100)
158
159 #define SCILV0(scsp) ((scsp->udata.data[0x24/2]>>0x0)&0xff)
160 #define SCILV1(scsp) ((scsp->udata.data[0x26/2]>>0x0)&0xff)
161 #define SCILV2(scsp) ((scsp->udata.data[0x28/2]>>0x0)&0xff)
162
163 #define SCIEX0 0
164 #define SCIEX1 1
165 #define SCIEX2 2
166 #define SCIMID 3
167 #define SCIDMA 4
168 #define SCIIRQ 5
169 #define SCITMA 6
170 #define SCITMB 7
171
172 #define USEDSP
173
174 struct m68ki_cpu_core_s;
175
176 struct _SCSP
177 {
178 union
179 {
180 UINT16 data[0x30/2];
181 UINT8 datab[0x30];
182 } udata;
183 struct _SLOT Slots[32];
184 signed short RINGBUF[64];
185 unsigned char BUFPTR;
186 #if FM_DELAY
187 signed short DELAYBUF[FM_DELAY];
188 unsigned char DELAYPTR;
189 #endif
190 unsigned char *SCSPRAM;
191 UINT32 SCSPRAM_LENGTH;
192 char Master;
193 void (*Int68kCB)(struct m68ki_cpu_core_s *cpu, int irq);
194
195 INT32 *buffertmpl, *buffertmpr;
196
197 UINT32 IrqTimA;
198 UINT32 IrqTimBC;
199 UINT32 IrqMidi;
200
201 UINT8 MidiOutW,MidiOutR;
202 UINT8 MidiStack[16];
203 UINT8 MidiW,MidiR;
204
205 int LPANTABLE[0x10000];
206 int RPANTABLE[0x10000];
207
208 int TimPris[3];
209 int TimCnt[3];
210
211 // DMA stuff
212 UINT32 scsp_dmea;
213 UINT16 scsp_drga;
214 UINT16 scsp_dtlg;
215
216 int ARTABLE[64], DRTABLE[64];
217
218 struct m68ki_cpu_core_s *cpu;
219 struct _SCSPDSP DSP;
220
221 INT16 *bufferl;
222 INT16 *bufferr;
223
224 int length;
225
226 signed short *RBUFDST; //this points to where the sample will be stored in the RingBuf
227 };
228
229 static void dma_scsp(struct _SCSP *SCSP); /*SCSP DMA transfer function*/
230 #define scsp_dgate scsp_regs[0x16/2] & 0x4000
231 #define scsp_ddir scsp_regs[0x16/2] & 0x2000
232 #define scsp_dexe scsp_regs[0x16/2] & 0x1000
233 #define dma_transfer_end ((scsp_regs[0x24/2] & 0x10)>>4)|(((scsp_regs[0x26/2] & 0x10)>>4)<<1)|(((scsp_regs[0x28/2] & 0x10)>>4)<<2)
234
235 static const float SDLT[8]={-1000000.0,-36.0,-30.0,-24.0,-18.0,-12.0,-6.0,0.0};
236
DecodeSCI(struct _SCSP * SCSP,unsigned char irq)237 static unsigned char DecodeSCI(struct _SCSP *SCSP,unsigned char irq)
238 {
239 unsigned char SCI=0;
240 unsigned char v;
241 v=(SCILV0((SCSP))&(1<<irq))?1:0;
242 SCI|=v;
243 v=(SCILV1((SCSP))&(1<<irq))?1:0;
244 SCI|=v<<1;
245 v=(SCILV2((SCSP))&(1<<irq))?1:0;
246 SCI|=v<<2;
247 return SCI;
248 }
249
ResetInterrupts(struct _SCSP * SCSP)250 static void ResetInterrupts(struct _SCSP *SCSP)
251 {
252 UINT32 reset = SCSP->udata.data[0x22/2];
253 if (reset & 0x40)
254 SCSP->Int68kCB(SCSP->cpu, -SCSP->IrqTimA);
255 if (reset & 0x180)
256 SCSP->Int68kCB(SCSP->cpu, -SCSP->IrqTimBC);
257 }
258
CheckPendingIRQ(struct _SCSP * SCSP)259 static void CheckPendingIRQ(struct _SCSP *SCSP)
260 {
261 UINT32 pend=SCSP->udata.data[0x20/2];
262 UINT32 en=SCSP->udata.data[0x1e/2];
263 if(SCSP->MidiW!=SCSP->MidiR)
264 {
265 SCSP->Int68kCB(SCSP->cpu, SCSP->IrqMidi);
266 return;
267 }
268 if(!pend)
269 return;
270 if(pend&0x40)
271 if(en&0x40)
272 {
273 SCSP->Int68kCB(SCSP->cpu, SCSP->IrqTimA);
274 return;
275 }
276 if(pend&0x80)
277 if(en&0x80)
278 {
279 SCSP->Int68kCB(SCSP->cpu, SCSP->IrqTimBC);
280 return;
281 }
282 if(pend&0x100)
283 if(en&0x100)
284 {
285 SCSP->Int68kCB(SCSP->cpu, SCSP->IrqTimBC);
286 return;
287 }
288
289 SCSP->Int68kCB(SCSP->cpu, 0);
290 }
291
Get_AR(struct _SCSP * SCSP,int base,int R)292 static int Get_AR(struct _SCSP *SCSP,int base,int R)
293 {
294 int Rate=base+(R<<1);
295 if(Rate>63) Rate=63;
296 if(Rate<0) Rate=0;
297 return SCSP->ARTABLE[Rate];
298 }
299
Get_DR(struct _SCSP * SCSP,int base,int R)300 static int Get_DR(struct _SCSP *SCSP,int base,int R)
301 {
302 int Rate=base+(R<<1);
303 if(Rate>63) Rate=63;
304 if(Rate<0) Rate=0;
305 return SCSP->DRTABLE[Rate];
306 }
307
Get_RR(struct _SCSP * SCSP,int base,int R)308 static int Get_RR(struct _SCSP *SCSP,int base,int R)
309 {
310 int Rate=base+(R<<1);
311 if(Rate>63) Rate=63;
312 if(Rate<0) Rate=0;
313 return SCSP->DRTABLE[Rate];
314 }
315
Compute_EG(struct _SCSP * SCSP,struct _SLOT * slot)316 static void Compute_EG(struct _SCSP *SCSP,struct _SLOT *slot)
317 {
318 int octave=OCT(slot);
319 int rate;
320 if(octave&8) octave=octave-16;
321 if(KRS(slot)!=0xf)
322 rate=octave+2*KRS(slot)+((FNS(slot)>>9)&1);
323 else
324 rate=0; //rate=((FNS(slot)>>9)&1);
325
326 slot->EG.volume=0x17F<<EG_SHIFT;
327 slot->EG.AR=Get_AR(SCSP,rate,AR(slot));
328 slot->EG.D1R=Get_DR(SCSP,rate,D1R(slot));
329 slot->EG.D2R=Get_DR(SCSP,rate,D2R(slot));
330 slot->EG.RR=Get_RR(SCSP,rate,RR(slot));
331 slot->EG.DL=0x1f-DL(slot);
332 slot->EG.EGHOLD=EGHOLD(slot);
333 }
334
335 static void SCSP_StopSlot(struct _SLOT *slot,int keyoff);
336
EG_Update(struct _SLOT * slot)337 static int EG_Update(struct _SLOT *slot)
338 {
339 switch(slot->EG.state)
340 {
341 case ATTACK:
342 slot->EG.volume+=slot->EG.AR;
343 if(slot->EG.volume>=(0x3ff<<EG_SHIFT))
344 {
345 if (!LPSLNK(slot))
346 {
347 slot->EG.state=DECAY1;
348 if(slot->EG.D1R>=(1024<<EG_SHIFT)) //Skip DECAY1, go directly to DECAY2
349 slot->EG.state=DECAY2;
350 }
351 slot->EG.volume=0x3ff<<EG_SHIFT;
352 }
353 if(slot->EG.EGHOLD)
354 return 0x3ff<<(SHIFT-10);
355 break;
356 case DECAY1:
357 slot->EG.volume-=slot->EG.D1R;
358 if(slot->EG.volume<=0)
359 slot->EG.volume=0;
360 if(slot->EG.volume>>(EG_SHIFT+5)<=slot->EG.DL)
361 slot->EG.state=DECAY2;
362 break;
363 case DECAY2:
364 if(D2R(slot)==0)
365 return (slot->EG.volume>>EG_SHIFT)<<(SHIFT-10);
366 slot->EG.volume-=slot->EG.D2R;
367 if(slot->EG.volume<=0)
368 slot->EG.volume=0;
369
370 break;
371 case RELEASE:
372 slot->EG.volume-=slot->EG.RR;
373 if(slot->EG.volume<=0)
374 {
375 slot->EG.volume=0;
376 SCSP_StopSlot(slot,0);
377 //slot->EG.volume=0x17F<<EG_SHIFT;
378 //slot->EG.state=ATTACK;
379 }
380 break;
381 default:
382 return 1<<SHIFT;
383 }
384 return (slot->EG.volume>>EG_SHIFT)<<(SHIFT-10);
385 }
386
SCSP_Step(struct _SLOT * slot)387 static UINT32 SCSP_Step(struct _SLOT *slot)
388 {
389 int octave=OCT(slot);
390 UINT64 Fn;
391
392 Fn=(FNS_Table[FNS(slot)]); //24.8
393 if(octave&8)
394 Fn>>=(16-octave);
395 else
396 Fn<<=octave;
397
398 return Fn/(44100);
399 }
400
401
Compute_LFO(struct _SLOT * slot)402 static void Compute_LFO(struct _SLOT *slot)
403 {
404 if(PLFOS(slot)!=0)
405 LFO_ComputeStep(&(slot->PLFO),LFOF(slot),PLFOWS(slot),PLFOS(slot),0);
406 if(ALFOS(slot)!=0)
407 LFO_ComputeStep(&(slot->ALFO),LFOF(slot),ALFOWS(slot),ALFOS(slot),1);
408 }
409
SCSP_StartSlot(struct _SCSP * SCSP,struct _SLOT * slot)410 static void SCSP_StartSlot(struct _SCSP *SCSP, struct _SLOT *slot)
411 {
412 UINT32 start_offset;
413 slot->active=1;
414 slot->Backwards=0;
415 slot->cur_addr=0; slot->nxt_addr=1<<SHIFT;
416 start_offset = PCM8B(slot) ? SA(slot) : SA(slot) & 0x7FFFE;
417 slot->base=SCSP->SCSPRAM + start_offset;
418 slot->step=SCSP_Step(slot);
419 Compute_EG(SCSP,slot);
420 slot->EG.state=ATTACK;
421 slot->EG.volume=0x17F<<EG_SHIFT;
422 slot->Prev=0;
423 Compute_LFO(slot);
424
425 // printf("StartSlot: SA %x PCM8B %x LPCTL %x ALFOS %x STWINH %x TL %x EFSDL %x\n", SA(slot), PCM8B(slot), LPCTL(slot), ALFOS(slot), STWINH(slot), TL(slot), EFSDL(slot));
426 // printf(" AR %x D1R %x D2R %x RR %x DL %x KRS %x EGHOLD %x LPSLNK %x\n", AR(slot), D1R(slot), D2R(slot), RR(slot), DL(slot), KRS(slot), EGHOLD(slot), LPSLNK(slot));
427 }
428
SCSP_StopSlot(struct _SLOT * slot,int keyoff)429 static void SCSP_StopSlot(struct _SLOT *slot,int keyoff)
430 {
431 if(keyoff /*&& slot->EG.state!=RELEASE*/)
432 {
433 slot->EG.state=RELEASE;
434 }
435 else
436 {
437 slot->active=0;
438 }
439 slot->udata.data[0]&=~0x800;
440 }
441
442 #define log_base_2(n) (log((float) n)/log((float) 2))
443
SCSP_Init(struct _SCSP * SCSP,const struct SCSPinterface * intf)444 static void SCSP_Init(struct _SCSP *SCSP, const struct SCSPinterface *intf)
445 {
446 int i=0;
447
448 SCSP->IrqTimA = SCSP->IrqTimBC = SCSP->IrqMidi = 0;
449 SCSP->MidiR=SCSP->MidiW=0;
450 SCSP->MidiOutR=SCSP->MidiOutW=0;
451
452 // get SCSP RAM
453 {
454 memset(SCSP,0,sizeof(*SCSP));
455 SCSP->cpu = intf->cpu;
456
457 if (!i)
458 {
459 SCSP->Master=1;
460 }
461 else
462 {
463 SCSP->Master=0;
464 }
465
466 if (intf->region)
467 {
468 SCSP->SCSPRAM = (unsigned char *)intf->region[0];
469 SCSP->SCSPRAM_LENGTH = 512*1024;
470 SCSP->DSP.SCSPRAM = (UINT16 *)SCSP->SCSPRAM;
471 SCSP->DSP.SCSPRAM_LENGTH = (512*1024)/2;
472 // SCSP->SCSPRAM += intf->roffset;
473 }
474 }
475
476 for(i=0;i<0x400;++i)
477 {
478 float fcent=(double) 1200.0*log_base_2((double)(((double) 1024.0+(double)i)/(double)1024.0));
479 fcent=(double) 44100.0*pow(2.0,fcent/1200.0);
480 FNS_Table[i]=(float) (1<<SHIFT) *fcent;
481 }
482
483 for(i=0;i<0x400;++i)
484 {
485 float envDB=((float)(3*(i-0x3ff)))/32.0;
486 float scale=(float)(1<<SHIFT);
487 EG_TABLE[i]=(INT32)(pow(10.0,envDB/20.0)*scale);
488 }
489
490 for(i=0;i<0x10000;++i)
491 {
492 int iTL =(i>>0x0)&0xff;
493 int iPAN=(i>>0x8)&0x1f;
494 int iSDL=(i>>0xD)&0x07;
495 float TL=1.0;
496 float SegaDB=0;
497 float fSDL=1.0;
498 float PAN=1.0;
499 float LPAN,RPAN;
500
501 if(iTL&0x01) SegaDB-=0.4;
502 if(iTL&0x02) SegaDB-=0.8;
503 if(iTL&0x04) SegaDB-=1.5;
504 if(iTL&0x08) SegaDB-=3;
505 if(iTL&0x10) SegaDB-=6;
506 if(iTL&0x20) SegaDB-=12;
507 if(iTL&0x40) SegaDB-=24;
508 if(iTL&0x80) SegaDB-=48;
509
510 TL=pow(10.0,SegaDB/20.0);
511
512 SegaDB=0;
513 if(iPAN&0x1) SegaDB-=3;
514 if(iPAN&0x2) SegaDB-=6;
515 if(iPAN&0x4) SegaDB-=12;
516 if(iPAN&0x8) SegaDB-=24;
517
518 if((iPAN&0xf)==0xf) PAN=0.0;
519 else PAN=pow(10.0,SegaDB/20.0);
520
521 if(iPAN<0x10)
522 {
523 LPAN=PAN;
524 RPAN=1.0;
525 }
526 else
527 {
528 RPAN=PAN;
529 LPAN=1.0;
530 }
531
532 if(iSDL)
533 fSDL=pow(10.0,(SDLT[iSDL])/20.0);
534 else
535 fSDL=0.0;
536
537 SCSP->LPANTABLE[i]=FIX((4.0*LPAN*TL*fSDL));
538 SCSP->RPANTABLE[i]=FIX((4.0*RPAN*TL*fSDL));
539 }
540
541 SCSP->ARTABLE[0]=SCSP->DRTABLE[0]=0; //Infinite time
542 SCSP->ARTABLE[1]=SCSP->DRTABLE[1]=0; //Infinite time
543 for(i=2;i<64;++i)
544 {
545 double t,step,scale;
546 t=ARTimes[i]; //In ms
547 if(t!=0.0)
548 {
549 step=(1023*1000.0)/((float) 44100.0f*t);
550 scale=(double) (1<<EG_SHIFT);
551 SCSP->ARTABLE[i]=(int) (step*scale);
552 }
553 else
554 SCSP->ARTABLE[i]=1024<<EG_SHIFT;
555
556 t=DRTimes[i]; //In ms
557 step=(1023*1000.0)/((float) 44100.0f*t);
558 scale=(double) (1<<EG_SHIFT);
559 SCSP->DRTABLE[i]=(int) (step*scale);
560 }
561
562 // make sure all the slots are off
563 for(i=0;i<32;++i)
564 {
565 SCSP->Slots[i].slot=i;
566 SCSP->Slots[i].active=0;
567 SCSP->Slots[i].base=NULL;
568 }
569
570 LFO_Init();
571 SCSP->buffertmpl=(signed int*) malloc(44100*sizeof(signed int));
572 SCSP->buffertmpr=(signed int*) malloc(44100*sizeof(signed int));
573 memset(SCSP->buffertmpl,0,44100*sizeof(signed int));
574 memset(SCSP->buffertmpr,0,44100*sizeof(signed int));
575
576 // no "pend"
577 SCSP[0].udata.data[0x20/2] = 0;
578 //SCSP[1].udata.data[0x20/2] = 0;
579 SCSP->TimCnt[0] = 0xffff;
580 SCSP->TimCnt[1] = 0xffff;
581 SCSP->TimCnt[2] = 0xffff;
582 }
583
SCSP_UpdateSlotReg(struct _SCSP * SCSP,int s,int r)584 static void SCSP_UpdateSlotReg(struct _SCSP *SCSP,int s,int r)
585 {
586 struct _SLOT *slot=SCSP->Slots+s;
587 int sl;
588 switch(r&0x3f)
589 {
590 case 0:
591 case 1:
592 if(KEYONEX(slot))
593 {
594 for(sl=0;sl<32;++sl)
595 {
596 struct _SLOT *s2=SCSP->Slots+sl;
597 {
598 if(KEYONB(s2) && s2->EG.state==RELEASE/*&& !s2->active*/)
599 {
600 SCSP_StartSlot(SCSP, s2);
601 }
602 if(!KEYONB(s2) /*&& s2->active*/)
603 {
604 SCSP_StopSlot(s2,1);
605 }
606 }
607 }
608 slot->udata.data[0]&=~0x1000;
609 }
610 break;
611 case 0x10:
612 case 0x11:
613 slot->step=SCSP_Step(slot);
614 break;
615 case 0xA:
616 case 0xB:
617 slot->EG.RR=Get_RR(SCSP,0,RR(slot));
618 slot->EG.DL=0x1f-DL(slot);
619 break;
620 case 0x12:
621 case 0x13:
622 Compute_LFO(slot);
623 break;
624 }
625 }
626
SCSP_UpdateReg(struct _SCSP * SCSP,int reg)627 static void SCSP_UpdateReg(struct _SCSP *SCSP, int reg)
628 {
629 switch(reg&0x3f)
630 {
631 case 0x2:
632 case 0x3:
633 {
634 unsigned int v=RBL(SCSP);
635 SCSP->DSP.RBP=RBP(SCSP);
636 if(v==0)
637 SCSP->DSP.RBL=8*1024;
638 else if(v==1)
639 SCSP->DSP.RBL=16*1024;
640 if(v==2)
641 SCSP->DSP.RBL=32*1024;
642 if(v==3)
643 SCSP->DSP.RBL=64*1024;
644 }
645 break;
646 case 0x6:
647 case 0x7:
648 SCSP_MidiIn(SCSP, 0, SCSP->udata.data[0x6/2]&0xff, 0);
649 break;
650 case 0x12:
651 case 0x13:
652 case 0x14:
653 case 0x15:
654 case 0x16:
655 case 0x17:
656 break;
657 case 0x18:
658 case 0x19:
659 if(SCSP->Master)
660 {
661 SCSP->TimPris[0]=1<<((SCSP->udata.data[0x18/2]>>8)&0x7);
662 SCSP->TimCnt[0]=(SCSP->udata.data[0x18/2]&0xff)<<8;
663 }
664 break;
665 case 0x1a:
666 case 0x1b:
667 if(SCSP->Master)
668 {
669 SCSP->TimPris[1]=1<<((SCSP->udata.data[0x1A/2]>>8)&0x7);
670 SCSP->TimCnt[1]=(SCSP->udata.data[0x1A/2]&0xff)<<8;
671 }
672 break;
673 case 0x1C:
674 case 0x1D:
675 if(SCSP->Master)
676 {
677 SCSP->TimPris[2]=1<<((SCSP->udata.data[0x1C/2]>>8)&0x7);
678 SCSP->TimCnt[2]=(SCSP->udata.data[0x1C/2]&0xff)<<8;
679 }
680 break;
681 case 0x22: //SCIRE
682 case 0x23:
683
684 if(SCSP->Master)
685 {
686 SCSP->udata.data[0x20/2]&=~SCSP->udata.data[0x22/2];
687 ResetInterrupts(SCSP);
688
689 // behavior from real hardware: if you SCIRE a timer that's expired,
690 // it'll immediately pop up again. ask Sakura Taisen on the Saturn...
691 if (SCSP->TimCnt[0] >= 0xff00)
692 {
693 SCSP->udata.data[0x20/2] |= 0x40;
694 }
695 if (SCSP->TimCnt[1] >= 0xff00)
696 {
697 SCSP->udata.data[0x20/2] |= 0x80;
698 }
699 if (SCSP->TimCnt[2] >= 0xff00)
700 {
701 SCSP->udata.data[0x20/2] |= 0x100;
702 }
703 }
704 break;
705 case 0x24:
706 case 0x25:
707 case 0x26:
708 case 0x27:
709 case 0x28:
710 case 0x29:
711 if(SCSP->Master)
712 {
713 SCSP->IrqTimA=DecodeSCI(SCSP,SCITMA);
714 SCSP->IrqTimBC=DecodeSCI(SCSP,SCITMB);
715 SCSP->IrqMidi=DecodeSCI(SCSP,SCIMID);
716 }
717 break;
718 }
719 }
720
SCSP_UpdateSlotRegR(struct _SCSP * SCSP,int slot,int reg)721 static void SCSP_UpdateSlotRegR(struct _SCSP *SCSP, int slot,int reg)
722 {
723
724 }
725
SCSP_UpdateRegR(struct _SCSP * SCSP,int reg)726 static void SCSP_UpdateRegR(struct _SCSP *SCSP, int reg)
727 {
728 switch(reg&0x3f)
729 {
730 case 4:
731 case 5:
732 {
733 unsigned short v=SCSP->udata.data[0x5/2];
734 v&=0xff00;
735 v|=SCSP->MidiStack[SCSP->MidiR];
736 SCSP->Int68kCB(SCSP->cpu, 0); // cancel the IRQ
737 if(SCSP->MidiR!=SCSP->MidiW)
738 {
739 ++SCSP->MidiR;
740 SCSP->MidiR&=15;
741 }
742 SCSP->udata.data[0x5/2]=v;
743 }
744 break;
745 case 8:
746 case 9:
747 {
748 unsigned char slot=SCSP->udata.data[0x8/2]>>11;
749 unsigned int CA=SCSP->Slots[slot&0x1f].cur_addr>>(SHIFT+12);
750 SCSP->udata.data[0x8/2]&=~(0x780);
751 SCSP->udata.data[0x8/2]|=CA<<7;
752 }
753 break;
754 }
755 }
756
SCSP_w16(struct _SCSP * SCSP,unsigned int addr,unsigned short val)757 static void SCSP_w16(struct _SCSP *SCSP,unsigned int addr,unsigned short val)
758 {
759 addr&=0xffff;
760 if(addr<0x400)
761 {
762 int slot=addr/0x20;
763 addr&=0x1f;
764 *((unsigned short *) (SCSP->Slots[slot].udata.datab+(addr))) = val;
765 SCSP_UpdateSlotReg(SCSP,slot,addr&0x1f);
766 }
767 else if(addr<0x600)
768 {
769 if (addr < 0x430)
770 {
771 *((unsigned short *) (SCSP->udata.datab+((addr&0x3f)))) = val;
772 SCSP_UpdateReg(SCSP, addr&0x3f);
773 }
774 }
775 else if(addr<0x700)
776 SCSP->RINGBUF[(addr-0x600)/2]=val;
777 else
778 {
779 //DSP
780 if(addr<0x780) //COEF
781 *((unsigned short *) (SCSP->DSP.COEF+(addr-0x700)/2))=val;
782 else if(addr<0x800)
783 *((unsigned short *) (SCSP->DSP.MADRS+(addr-0x780)/2))=val;
784 else if(addr<0xC00)
785 *((unsigned short *) (SCSP->DSP.MPRO+(addr-0x800)/2))=val;
786
787 if(addr==0xBF0)
788 {
789 // printf("DSP start\n");
790 SCSPDSP_Start(&SCSP->DSP);
791 }
792 }
793 }
794
SCSP_r16(struct _SCSP * SCSP,unsigned int addr)795 static unsigned short SCSP_r16(struct _SCSP *SCSP, unsigned int addr)
796 {
797 unsigned short v=0;
798 addr&=0xffff;
799 if(addr<0x400)
800 {
801 int slot=addr/0x20;
802 addr&=0x1f;
803 SCSP_UpdateSlotRegR(SCSP, slot,addr&0x1f);
804 v=*((unsigned short *) (SCSP->Slots[slot].udata.datab+(addr)));
805 }
806 else if(addr<0x600)
807 {
808 if (addr < 0x430)
809 {
810 SCSP_UpdateRegR(SCSP, addr&0x3f);
811 v= *((unsigned short *) (SCSP->udata.datab+((addr&0x3f))));
812 }
813 }
814 else if(addr<0x700)
815 v=SCSP->RINGBUF[(addr-0x600)/2];
816 return v;
817 }
818
819
820 #define REVSIGN(v) ((~v)+1)
821
SCSP_TimersAddTicks(struct _SCSP * SCSP,int ticks)822 void SCSP_TimersAddTicks(struct _SCSP *SCSP, int ticks)
823 {
824 if(SCSP->TimCnt[0]<=0xff00)
825 {
826 SCSP->TimCnt[0] += ticks << (8-((SCSP->udata.data[0x18/2]>>8)&0x7));
827 if (SCSP->TimCnt[0] > 0xFF00)
828 {
829 SCSP->TimCnt[0] = 0xFFFF;
830 SCSP->udata.data[0x20/2]|=0x40;
831 }
832 SCSP->udata.data[0x18/2]&=0xff00;
833 SCSP->udata.data[0x18/2]|=SCSP->TimCnt[0]>>8;
834 }
835
836 if(SCSP->TimCnt[1]<=0xff00)
837 {
838 SCSP->TimCnt[1] += ticks << (8-((SCSP->udata.data[0x1a/2]>>8)&0x7));
839 if (SCSP->TimCnt[1] > 0xFF00)
840 {
841 SCSP->TimCnt[1] = 0xFFFF;
842 SCSP->udata.data[0x20/2]|=0x80;
843 }
844 SCSP->udata.data[0x1a/2]&=0xff00;
845 SCSP->udata.data[0x1a/2]|=SCSP->TimCnt[1]>>8;
846 }
847
848 if(SCSP->TimCnt[2]<=0xff00)
849 {
850 SCSP->TimCnt[2] += ticks << (8-((SCSP->udata.data[0x1c/2]>>8)&0x7));
851 if (SCSP->TimCnt[2] > 0xFF00)
852 {
853 SCSP->TimCnt[2] = 0xFFFF;
854 SCSP->udata.data[0x20/2]|=0x100;
855 }
856 SCSP->udata.data[0x1c/2]&=0xff00;
857 SCSP->udata.data[0x1c/2]|=SCSP->TimCnt[2]>>8;
858 }
859 }
860
SCSP_UpdateSlot(struct _SCSP * SCSP,struct _SLOT * slot)861 static INLINE INT32 SCSP_UpdateSlot(struct _SCSP *SCSP, struct _SLOT *slot)
862 {
863 INT32 sample;
864 int step=slot->step;
865 UINT32 addr1,addr2,addr_select; // current and next sample addresses
866 UINT32 *addr[2] = {&addr1, &addr2}; // used for linear interpolation
867 UINT32 *slot_addr[2] = {&(slot->cur_addr), &(slot->nxt_addr)}; //
868
869 if(SSCTL(slot)!=0) //no FM or noise yet
870 return 0;
871
872 if(PLFOS(slot)!=0)
873 {
874 step=step*PLFO_Step(&(slot->PLFO));
875 step>>=SHIFT;
876 }
877
878 if(PCM8B(slot))
879 {
880 addr1=slot->cur_addr>>SHIFT;
881 addr2=slot->nxt_addr>>SHIFT;
882 }
883 else
884 {
885 addr1=(slot->cur_addr>>(SHIFT-1))&0x7fffe;
886 addr2=(slot->nxt_addr>>(SHIFT-1))&0x7fffe;
887 }
888
889 if(MDL(slot)!=0 || MDXSL(slot)!=0 || MDYSL(slot)!=0)
890 {
891 INT32 smp=(SCSP->RINGBUF[(SCSP->BUFPTR+MDXSL(slot))&63]+SCSP->RINGBUF[(SCSP->BUFPTR+MDYSL(slot))&63])/2;
892
893 smp<<=0xA; // associate cycle with 1024
894 smp>>=0x1A-MDL(slot); // ex. for MDL=0xF, sample range corresponds to +/- 64 pi (32=2^5 cycles) so shift by 11 (16-5 == 0x1A-0xF)
895 if(!PCM8B(slot)) smp<<=1;
896
897 addr1+=smp; addr2+=smp;
898 }
899
900 if(PCM8B(slot)) //8 bit signed
901 {
902 INT8 *p1=(signed char *) (SCSP->SCSPRAM+(((SA(slot)+addr1)^1)&0x7FFFF));
903 INT8 *p2=(signed char *) (SCSP->SCSPRAM+(((SA(slot)+addr2)^1)&0x7FFFF));
904 //sample=(p[0])<<8;
905 INT32 s;
906 INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
907 s=(int) (p1[0]<<8)*((1<<SHIFT)-fpart)+(int) (p2[0]<<8)*fpart;
908 sample=(s>>SHIFT);
909 }
910 else //16 bit signed (endianness?)
911 {
912 INT16 *p1=(signed short *) (SCSP->SCSPRAM+((SA(slot)+addr1)&0x7FFFE));
913 INT16 *p2=(signed short *) (SCSP->SCSPRAM+((SA(slot)+addr2)&0x7FFFE));
914 //sample=LE16(p[0]);
915 INT32 s;
916 INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
917 s=(int) LE16(p1[0])*((1<<SHIFT)-fpart)+(int) LE16(p2[0])*fpart;
918 sample=(s>>SHIFT);
919 }
920
921 if(SBCTL(slot)&0x1)
922 sample ^= 0x7FFF;
923 if(SBCTL(slot)&0x2)
924 sample = (INT16)(sample^0x8000);
925
926 if(slot->Backwards)
927 slot->cur_addr-=step;
928 else
929 slot->cur_addr+=step;
930 slot->nxt_addr=slot->cur_addr+(1<<SHIFT);
931
932 addr1=slot->cur_addr>>SHIFT;
933 addr2=slot->nxt_addr>>SHIFT;
934
935 if(addr1>=LSA(slot) && !(slot->Backwards))
936 {
937 if(LPSLNK(slot) && slot->EG.state==ATTACK)
938 slot->EG.state = DECAY1;
939 }
940
941 for (addr_select=0;addr_select<2;addr_select++)
942 {
943 INT32 rem_addr;
944 switch(LPCTL(slot))
945 {
946 case 0: //no loop
947 if(*addr[addr_select]>=LSA(slot) && *addr[addr_select]>=LEA(slot))
948 {
949 //slot->active=0;
950 SCSP_StopSlot(slot,0);
951 }
952 break;
953 case 1: //normal loop
954 if(*addr[addr_select]>=LEA(slot))
955 {
956 rem_addr = *slot_addr[addr_select] - (LEA(slot)<<SHIFT);
957 *slot_addr[addr_select]=(LSA(slot)<<SHIFT) + rem_addr;
958 }
959 break;
960 case 2: //reverse loop
961 if((*addr[addr_select]>=LSA(slot)) && !(slot->Backwards))
962 {
963 rem_addr = *slot_addr[addr_select] - (LSA(slot)<<SHIFT);
964 *slot_addr[addr_select]=(LEA(slot)<<SHIFT) - rem_addr;
965 slot->Backwards=1;
966 }
967 else if((*addr[addr_select]<LSA(slot) || (*slot_addr[addr_select]&0x80000000)) && slot->Backwards)
968 {
969 rem_addr = (LSA(slot)<<SHIFT) - *slot_addr[addr_select];
970 *slot_addr[addr_select]=(LEA(slot)<<SHIFT) - rem_addr;
971 }
972 break;
973 case 3: //ping-pong
974 if(*addr[addr_select]>=LEA(slot)) //reached end, reverse till start
975 {
976 rem_addr = *slot_addr[addr_select] - (LEA(slot)<<SHIFT);
977 *slot_addr[addr_select]=(LEA(slot)<<SHIFT) - rem_addr;
978 slot->Backwards=1;
979 }
980 else if((*addr[addr_select]<LSA(slot) || (*slot_addr[addr_select]&0x80000000)) && slot->Backwards)//reached start or negative
981 {
982 rem_addr = (LSA(slot)<<SHIFT) - *slot_addr[addr_select];
983 *slot_addr[addr_select]=(LSA(slot)<<SHIFT) + rem_addr;
984 slot->Backwards=0;
985 }
986 break;
987 }
988 }
989
990 if(ALFOS(slot)!=0)
991 {
992 sample=sample*ALFO_Step(&(slot->ALFO));
993 sample>>=SHIFT;
994 }
995
996 if(slot->EG.state==ATTACK)
997 sample=(sample*EG_Update(slot))>>SHIFT;
998 else
999 sample=(sample*EG_TABLE[EG_Update(slot)>>(SHIFT-10)])>>SHIFT;
1000
1001 if(!STWINH(slot))
1002 {
1003 unsigned short Enc=((TL(slot))<<0x0)|(0x7<<0xd);
1004 *SCSP->RBUFDST=(sample*SCSP->LPANTABLE[Enc])>>(SHIFT+1);
1005 }
1006
1007 return sample;
1008 }
1009
SCSP_DoMasterSamples(struct _SCSP * SCSP,int nsamples)1010 static void SCSP_DoMasterSamples(struct _SCSP *SCSP, int nsamples)
1011 {
1012 INT16 *bufr,*bufl;
1013 int sl, s, i;
1014
1015 bufr=SCSP->bufferr;
1016 bufl=SCSP->bufferl;
1017
1018 for(s=0;s<nsamples;++s)
1019 {
1020 INT32 smpl, smpr;
1021
1022 smpl = smpr = 0;
1023
1024 for(sl=0;sl<32;++sl)
1025 {
1026 #if FM_DELAY
1027 SCSP->RBUFDST=SCSP->DELAYBUF+SCSP->DELAYPTR;
1028 #else
1029 SCSP->RBUFDST=SCSP->RINGBUF+SCSP->BUFPTR;
1030 #endif
1031 if(SCSP->Slots[sl].active)
1032 {
1033 struct _SLOT *slot=SCSP->Slots+sl;
1034 unsigned short Enc;
1035 signed int sample;
1036
1037 sample=SCSP_UpdateSlot(SCSP, slot);
1038
1039 Enc=((TL(slot))<<0x0)|((IMXL(slot))<<0xd);
1040 SCSPDSP_SetSample(&SCSP->DSP,(sample*SCSP->LPANTABLE[Enc])>>(SHIFT-2),ISEL(slot),IMXL(slot));
1041 Enc=((TL(slot))<<0x0)|((DIPAN(slot))<<0x8)|((DISDL(slot))<<0xd);
1042 {
1043 smpl+=(sample*SCSP->LPANTABLE[Enc])>>SHIFT;
1044 smpr+=(sample*SCSP->RPANTABLE[Enc])>>SHIFT;
1045 }
1046 }
1047
1048 #if FM_DELAY
1049 SCSP->RINGBUF[(SCSP->BUFPTR+64-(FM_DELAY-1))&63] = SCSP->DELAYBUF[(SCSP->DELAYPTR+FM_DELAY-(FM_DELAY-1))%FM_DELAY];
1050 #endif
1051 ++SCSP->BUFPTR;
1052 SCSP->BUFPTR&=63;
1053 #if FM_DELAY
1054 ++SCSP->DELAYPTR;
1055 if(SCSP->DELAYPTR>FM_DELAY-1) SCSP->DELAYPTR=0;
1056 #endif
1057 }
1058
1059 SCSPDSP_Step(&SCSP->DSP);
1060
1061 for(i=0;i<16;++i)
1062 {
1063 struct _SLOT *slot=SCSP->Slots+i;
1064 if(EFSDL(slot))
1065 {
1066 unsigned short Enc=((EFPAN(slot))<<0x8)|((EFSDL(slot))<<0xd);
1067 smpl+=(SCSP->DSP.EFREG[i]*SCSP->LPANTABLE[Enc])>>SHIFT;
1068 smpr+=(SCSP->DSP.EFREG[i]*SCSP->RPANTABLE[Enc])>>SHIFT;
1069 }
1070 }
1071
1072 *bufl++ = ICLIP16(smpl>>2);
1073 *bufr++ = ICLIP16(smpr>>2);
1074
1075 SCSP_TimersAddTicks(SCSP, 1);
1076 CheckPendingIRQ(SCSP);
1077 }
1078
1079 }
1080
dma_scsp(struct _SCSP * SCSP)1081 static void dma_scsp(struct _SCSP *SCSP)
1082 {
1083 static UINT16 tmp_dma[3], *scsp_regs;
1084
1085 scsp_regs = (UINT16 *)SCSP->udata.datab;
1086
1087 printf("SCSP: DMA transfer START\n"
1088 "DMEA: %04x DRGA: %04x DTLG: %04x\n"
1089 "DGATE: %d DDIR: %d\n",SCSP->scsp_dmea,SCSP->scsp_drga,SCSP->scsp_dtlg,scsp_dgate ? 1 : 0,scsp_ddir ? 1 : 0);
1090
1091 /* Copy the dma values in a temp storage for resuming later *
1092 * (DMA *can't* overwrite his parameters). */
1093 if(!(scsp_ddir))
1094 {
1095 tmp_dma[0] = scsp_regs[0x12/2];
1096 tmp_dma[1] = scsp_regs[0x14/2];
1097 tmp_dma[2] = scsp_regs[0x16/2];
1098 }
1099
1100 if(scsp_ddir)
1101 {
1102 for(;SCSP->scsp_dtlg > 0;SCSP->scsp_dtlg-=2)
1103 {
1104 // program_write_word(SCSP->scsp_dmea, program_read_word(0x100000|SCSP->scsp_drga));
1105 SCSP->scsp_dmea+=2;
1106 SCSP->scsp_drga+=2;
1107 }
1108 }
1109 else
1110 {
1111 for(;SCSP->scsp_dtlg > 0;SCSP->scsp_dtlg-=2)
1112 {
1113 // program_write_word(0x100000|SCSP->scsp_drga,program_read_word(SCSP->scsp_dmea));
1114 SCSP->scsp_dmea+=2;
1115 SCSP->scsp_drga+=2;
1116 }
1117 }
1118
1119 /*Resume the values*/
1120 if(!(scsp_ddir))
1121 {
1122 scsp_regs[0x12/2] = tmp_dma[0];
1123 scsp_regs[0x14/2] = tmp_dma[1];
1124 scsp_regs[0x16/2] = tmp_dma[2];
1125 }
1126
1127 /*Job done,request a dma end irq*/
1128 // if(scsp_regs[0x1e/2] & 0x10)
1129 // cpunum_set_input_line(2,dma_transfer_end,HOLD_LINE);
1130 }
1131
SCSP_IRQCB(void * param)1132 int SCSP_IRQCB(void *param)
1133 {
1134 CheckPendingIRQ(param);
1135 return -1;
1136 }
1137
SCSP_Update(void * param,INT16 ** inputs,INT16 ** buf,int samples)1138 void SCSP_Update(void *param, INT16 **inputs, INT16 **buf, int samples)
1139 {
1140 struct _SCSP *SCSP = param;
1141 SCSP->bufferl = buf[0];
1142 SCSP->bufferr = buf[1];
1143 SCSP->length = samples;
1144 SCSP_DoMasterSamples(SCSP, samples);
1145 }
1146
SCSP_Start(const void * config)1147 void *SCSP_Start(const void *config)
1148 {
1149 const struct SCSPinterface *intf;
1150
1151 struct _SCSP *SCSP;
1152
1153 SCSP = malloc(sizeof(*SCSP));
1154 memset(SCSP, 0, sizeof(*SCSP));
1155
1156 intf = config;
1157
1158 // init the emulation
1159 SCSP_Init(SCSP, intf);
1160
1161 // set up the IRQ callbacks
1162 {
1163 SCSP->Int68kCB = intf->irq_callback[0];
1164
1165 // SCSP->stream = stream_create(0, 2, 44100, SCSP, SCSP_Update);
1166 }
1167
1168 return SCSP;
1169 }
1170
SCSP_Exit(void * param)1171 void SCSP_Exit (void *param) {
1172 if (param) {
1173 struct _SCSP *SCSP = param;
1174 if (SCSP->buffertmpl) {
1175 free (SCSP->buffertmpl);
1176 }
1177 if (SCSP->buffertmpr) {
1178 free (SCSP->buffertmpr);
1179 }
1180 free (param);
1181 }
1182 }
1183
1184
SCSP_set_ram_base(struct _SCSP * SCSP,int which,void * base)1185 void SCSP_set_ram_base(struct _SCSP *SCSP, int which, void *base)
1186 {
1187 if (SCSP)
1188 {
1189 SCSP->SCSPRAM = base;
1190 SCSP->DSP.SCSPRAM = base;
1191 }
1192 }
1193
1194
READ16_HANDLER(SCSP_0_r)1195 READ16_HANDLER( SCSP_0_r )
1196 {
1197 return SCSP_r16(param, offset*2);
1198 }
1199
WRITE16_HANDLER(SCSP_0_w)1200 WRITE16_HANDLER( SCSP_0_w )
1201 {
1202 struct _SCSP *SCSP = param;
1203 UINT16 tmp, *scsp_regs;
1204
1205 tmp = SCSP_r16(SCSP, offset*2);
1206 COMBINE_DATA(&tmp);
1207 SCSP_w16(SCSP,offset*2, tmp);
1208
1209 scsp_regs = (UINT16 *)SCSP->udata.datab;
1210
1211 switch(offset*2)
1212 {
1213 // check DMA
1214 case 0x412:
1215 /*DMEA [15:1]*/
1216 /*Sound memory address*/
1217 SCSP->scsp_dmea = (((scsp_regs[0x14/2] & 0xf000)>>12)*0x10000) | (scsp_regs[0x12/2] & 0xfffe);
1218 break;
1219 case 0x414:
1220 /*DMEA [19:16]*/
1221 SCSP->scsp_dmea = (((scsp_regs[0x14/2] & 0xf000)>>12)*0x10000) | (scsp_regs[0x12/2] & 0xfffe);
1222 /*DRGA [11:1]*/
1223 /*Register memory address*/
1224 SCSP->scsp_drga = scsp_regs[0x14/2] & 0x0ffe;
1225 break;
1226 case 0x416:
1227 /*DGATE[14]*/
1228 /*DDIR[13]*/
1229 /*if 0 sound_mem -> reg*/
1230 /*if 1 sound_mem <- reg*/
1231 /*DEXE[12]*/
1232 /*starting bit*/
1233 /*DTLG[11:1]*/
1234 /*size of transfer*/
1235 SCSP->scsp_dtlg = scsp_regs[0x16/2] & 0x0ffe;
1236 if(scsp_dexe)
1237 {
1238 dma_scsp(SCSP);
1239 scsp_regs[0x16/2]^=0x1000;//disable starting bit
1240 }
1241 break;
1242 //check main cpu IRQ
1243 case 0x42a:
1244 #if 0
1245 extern UINT32* stv_scu;
1246
1247 if(stv_scu && !(stv_scu[40] & 0x40) /*&& scsp_regs[0x42c/2] & 0x20*/)/*Main CPU allow sound irq*/
1248 {
1249 cpunum_set_input_line_and_vector(0, 9, HOLD_LINE , 0x46);
1250 logerror("SCSP: Main CPU interrupt\n");
1251 }
1252 #endif
1253 break;
1254 case 0x42c:
1255 break;
1256 case 0x42e:
1257 break;
1258 }
1259 }
1260
WRITE16_HANDLER(SCSP_MidiIn)1261 WRITE16_HANDLER( SCSP_MidiIn )
1262 {
1263 struct _SCSP *SCSP = param;
1264 SCSP->MidiStack[SCSP->MidiW++]=data;
1265 SCSP->MidiW &= 15;
1266 }
1267
READ16_HANDLER(SCSP_MidiOutR)1268 READ16_HANDLER( SCSP_MidiOutR )
1269 {
1270 struct _SCSP *SCSP = param;
1271 unsigned char val;
1272
1273 val=SCSP->MidiStack[SCSP->MidiR++];
1274 SCSP->MidiR&=7;
1275 return val;
1276 }
1277
1278