1 /*
2 * Copyright 2004 Stephane Dallongeville
3 * Copyright 2004-2007 Theo Berkau
4 * Copyright 2006 Guillaume Duhamel
5 * Copyright 2012 Chris Lord
6 *
7 * This file is part of Yabause.
8 *
9 * Yabause is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * Yabause is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Yabause; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /*! \file scsp.c
25 \brief SCSP emulation functions.
26 */
27
28 ////////////////////////////////////////////////////////////////
29 // Custom Sound Processor
30
31 // note: model2 scsp is mapped to 0x100000~0x100ee4 of the space, but seems to
32 // have additional hw ports ($40a~$410)
33 // note: it seems that the user interrupt is used by the sound driver to reset
34 // the subsystem
35
36 //--------------------------------------------------------------
37 //
38 // Common Control Register (CCR)
39 //
40 // $+00 $+01
41 // $400 ---- --12 3333 4444 1:MEM4MB memory size 2:DAC18B dac for digital output 3:VER version number 4:MVOL
42 // $402 ---- ---1 1222 2222 1:RBL ring buffer length 2:RBP lead address
43 // $404 ---1 2345 6666 6666 1:MOFULL out fifo full 2:MOEMP empty 3:MIOVF overflow 4:MIFULL in 5:MIEMP 6:MIBUF
44 // $406 ---- ---- 1111 1111 1:MOBUF midi output data buffer
45 // $408 1111 1222 2334 4444 1:MSLC monitor slot 2:CA call address 3:SGC Slot phase 4:EG Slot envelope
46 // $40a ---- ---- ---- ----
47 // $40c ---- ---- ---- ----
48 // $40e ---- ---- ---- ----
49 // $410 ---- ---- ---- ----
50 // $412 1111 1111 1111 111- 1:DMEAL transfer start address (sound)
51 // $414 1111 2222 2222 222- 1:DMEAH transfer start address hi 2:DRGA start register address (dsp)
52 // $416 -123 4444 4444 444- 1:DGATE transfer gate 0 clear 2:DDIR direction 3:DEXE start 4:DTLG data count
53 // $418 ---- -111 2222 2222 1:TACTL timer a prescalar control 2:TIMA timer a count data
54 // $41a ---- -111 2222 2222 1:TBCTL timer b prescalar control 2:TIMB timer b count data
55 // $41c ---- -111 2222 2222 2:TCCTL timer c prescalar control 2:TIMC timer c count data
56 // $41e ---- -111 1111 1111 1:SCIEB allow sound cpu interrupt
57 // $420 ---- -111 1111 1111 1:SCIPD request sound cpu interrupt
58 // $422 ---- -111 1111 1111 1:SCIRE reset sound cpu interrupt
59 // $424 ---- ---- 1111 1111 1:SCILV0 sound cpu interrupt level bit0
60 // $426 ---- ---- 1111 1111 1:SCILV1 sound cpu interrupt level bit1
61 // $428 ---- ---- 1111 1111 1:SCILV2 sound cpu interrupt level bit2
62 // $42a ---- -111 1111 1111 1:MCIEB allow main cpu interrupt
63 // $42c ---- -111 1111 1111 1:MCIPD request main cpu interrupt
64 // $42e ---- -111 1111 1111 1:MCIRE reset main cpu interrupt
65 //
66 //--------------------------------------------------------------
67 //
68 // Individual Slot Register (ISR)
69 //
70 // $+00 $+01
71 // $00 ---1 2334 4556 7777 1:KYONEX 2:KYONB 3:SBCTL 4:SSCTL 5:LPCTL 6:PCM8B 7:SA start address
72 // $02 1111 1111 1111 1111 1:SA start address
73 // $04 1111 1111 1111 1111 1:LSA loop start address
74 // $06 1111 1111 1111 1111 1:LEA loop end address
75 // $08 1111 1222 2234 4444 1:D2R decay 2 rate 2:D1R decay 1 rate 3:EGHOLD eg hold mode 4:AR attack rate
76 // $0a -122 2233 3334 4444 1:LPSLNK loop start link 2:KRS key rate scaling 3:DL decay level 4:RR release rate
77 // $0c ---- --12 3333 3333 1:STWINH stack write inhibit 2:SDIR sound direct 3:TL total level
78 // $0e 1111 2222 2233 3333 1:MDL modulation level 2:MDXSL modulation input x 3:MDYSL modulation input y
79 // $10 -111 1-22 2222 2222 1:OCT octave 2:FNS frequency number switch
80 // $12 1222 2233 4445 5666 1:LFORE 2:LFOF 3:PLFOWS 4:PLFOS 5:ALFOWS 6:ALFOS
81 // $14 ---- ---- -111 1222 1:ISEL input select 2:OMXL input mix level
82 // $16 1112 2222 3334 4444 1:DISDL 2:DIPAN 3:EFSDL 4:EFPAN
83 //
84 //--------------------------------------------------------------
85
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <stdarg.h>
89 #include <math.h>
90
91 #include "c68k/c68k.h"
92 #include "cs2.h"
93 #include "debug.h"
94 #include "error.h"
95 #include "memory.h"
96 #include "m68kcore.h"
97 #include "scu.h"
98 #include "yabause.h"
99 #include "scsp.h"
100 #include "scspdsp.h"
101 #include "scsp_dsp_jit.h"
102 #if 0
103 #include "windows/aviout.h"
104 #endif
105
106 #ifdef PSP
107 # include "psp/common.h"
108
109 /* Macro to write a variable's value through the cache to main memory */
110 # define WRITE_THROUGH(var) (*(u32 *)((u32)&(var) | 0x40000000) = (var))
111
112 /* Macro to flush SCSP state so it can be read from the ME */
113 # define FLUSH_SCSP() sceKernelDcacheWritebackRange(&scsp, sizeof(scsp))
114
115 #else // !PSP
116 # define WRITE_THROUGH(var) /*nothing*/
117 # define FLUSH_SCSP() /*nothing*/
118 #endif
119
120 int use_new_scsp = 0;
121 int new_scsp_outbuf_pos = 0;
122 s32 new_scsp_outbuf_l[900] = { 0 };
123 s32 new_scsp_outbuf_r[900] = { 0 };
124 int new_scsp_cycles = 0;
125
126 enum EnvelopeStates
127 {
128 ATTACK,
129 DECAY1,
130 DECAY2,
131 RELEASE
132 };
133
134 //0x30 to 0x3f only
135 const u8 attack_rate_table[][4] =
136 {
137 { 4,4,4,4 },//0x30
138 { 3,4,4,4 },
139 { 3,4,3,4 },
140 { 3,3,3,4 },
141
142 { 3,3,3,3 },
143 { 2,3,3,3 },
144 { 2,3,2,3 },
145 { 2,2,2,3 },
146
147 { 2,2,2,2 },
148 { 1,2,2,2 },
149 { 1,2,1,2 },
150 { 1,1,1,2 },
151
152 { 1,1,1,1 },//0x3c
153 { 1,1,1,1 },//0x3d
154 { 1,1,1,1 },//0x3e
155 { 1,1,1,1 },//0x3f
156 };
157
158 const u8 decay_rate_table[][4] =
159 {
160 { 1,1,1,1 },//0x30
161 { 2,1,1,1 },
162 { 2,1,2,1 },
163 { 2,2,2,1 },
164
165 { 2,2,2,2 },
166 { 4,2,2,2 },
167 { 4,2,4,2 },
168 { 4,4,4,2 },
169
170 { 4,4,4,4 },
171 { 8,4,4,4 },
172 { 8,4,8,4 },
173 { 8,8,8,4 },
174
175 { 8,8,8,8 },//0x3c
176 { 8,8,8,8 },//0x3d
177 { 8,8,8,8 },//0x3e
178 { 8,8,8,8 },//0x3f
179 };
180
181 #define EFFECTIVE_RATE_END 0xffff
182
183 //effective rate step table
184 //settings 0x2 to 0x5, then repeats with bigger shifts
185 //EFFECTIVE_RATE_END represents going back to the beginning of a row since
186 //the number of steps is not the same for each setting
187 #define MAKE_TABLE(SHIFT) \
188 { 8192 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, EFFECTIVE_RATE_END,EFFECTIVE_RATE_END,EFFECTIVE_RATE_END,EFFECTIVE_RATE_END, EFFECTIVE_RATE_END }, \
189 { 8192 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, EFFECTIVE_RATE_END }, \
190 { 4096 >> SHIFT, EFFECTIVE_RATE_END,EFFECTIVE_RATE_END,EFFECTIVE_RATE_END,EFFECTIVE_RATE_END, EFFECTIVE_RATE_END,EFFECTIVE_RATE_END , EFFECTIVE_RATE_END }, \
191 { 4096 >> SHIFT, 4096 >> SHIFT, 4096 >> SHIFT, 2048 >> SHIFT, 2048 >> SHIFT, EFFECTIVE_RATE_END, EFFECTIVE_RATE_END, EFFECTIVE_RATE_END },
192
193 const u16 envelope_table[][8] =
194 {
195 MAKE_TABLE(0)
196 MAKE_TABLE(1)
197 MAKE_TABLE(2)
198 MAKE_TABLE(3)
199 MAKE_TABLE(4)
200 MAKE_TABLE(5)
201 MAKE_TABLE(6)
202 MAKE_TABLE(7)
203 MAKE_TABLE(8)
204 MAKE_TABLE(9)
205 MAKE_TABLE(10)
206 MAKE_TABLE(11)
207 MAKE_TABLE(12)
208 };
209
210 //unknown stored bits are unknown1-5
211 struct SlotRegs
212 {
213 u8 kx;
214 u8 kb;
215 u8 sbctl;
216 u8 ssctl;
217 u8 lpctl;
218 u8 pcm8b;
219 u32 sa;
220 u16 lsa;
221 u16 lea;
222 u8 d2r;
223 u8 d1r;
224 u8 hold;
225 u8 ar;
226 u8 unknown1;
227 u8 ls;
228 u8 krs;
229 u8 dl;
230 u8 rr;
231 u8 unknown2;
232 u8 si;
233 u8 sd;
234 u16 tl;
235 u8 mdl;
236 u8 mdxsl;
237 u8 mdysl;
238 u8 unknown3;
239 u8 oct;
240 u8 unknown4;
241 u16 fns;
242 u8 re;
243 u8 lfof;
244 u8 plfows;
245 u8 plfos;
246 u8 alfows;
247 u8 alfos;
248 u8 unknown5;
249 u8 isel;
250 u8 imxl;
251 u8 disdl;
252 u8 dipan;
253 u8 efsdl;
254 u8 efpan;
255 };
256
257 struct SlotState
258 {
259 u16 wave;
260 int backwards;
261 enum EnvelopeStates envelope;
262 s16 output;
263 u16 attenuation;
264 int step_count;
265 u32 sample_counter;
266 u32 envelope_steps_taken;
267 s32 waveform_phase_value;
268 s32 sample_offset;
269 u32 address_pointer;
270 u32 lfo_counter;
271 u32 lfo_pos;
272
273 int num;
274 int is_muted;
275 };
276
277 struct Slot
278 {
279 //registers
280 struct SlotRegs regs;
281
282 //internal state
283 struct SlotState state;
284 };
285
286 struct Scsp
287 {
288 u16 sound_stack[64];
289 struct Slot slots[32];
290
291 int debug_mode;
292 }new_scsp;
293
294 //samples per step through a 256 entry lfo table
295 const int lfo_step_table[0x20] = {
296 0x3fc,//0
297 0x37c,//1
298 0x2fc,//2
299 0x27c,//3
300 0x1fc,//4
301 0x1bc,//5
302 0x17c,//6
303 0x13c,//7
304 0x0fc,//8
305 0x0bc,//9
306 0x0dc,//0xa
307 0x08c,//0xb
308 0x07c,//0xc
309 0x06c,//0xd
310 0x05c,//0xe
311 0x04c,//0xf
312
313 0x03c,//0x10
314 0x034,//0x11
315 0x02c,//0x12
316 0x024,//0x13
317 0x01c,//0x14
318 0x018,//0x15
319 0x014,//0x16
320 0x010,//0x17
321 0x00c,//0x18
322 0x00a,//0x19
323 0x008,//0x1a
324 0x006,//0x1b
325 0x004,//0x1c
326 0x003,//0x1d
327 0x002,//0x1e
328 0x001,//0x1f
329 };
330
331 struct PlfoTables
332 {
333 s8 saw_table[256];
334 s8 square_table[256];
335 s8 tri_table[256];
336 s8 noise_table[256];
337 };
338
339 struct PlfoTables plfo;
340
341 struct AlfoTables
342 {
343 u8 saw_table[256];
344 u8 square_table[256];
345 u8 tri_table[256];
346 u8 noise_table[256];
347 };
348
349 struct AlfoTables alfo;
350
fill_plfo_tables()351 void fill_plfo_tables()
352 {
353 int i;
354
355 //saw
356 for (i = 0; i < 256; i++)
357 {
358 if (i < 128)
359 plfo.saw_table[i] = i;
360 else
361 plfo.saw_table[i] = -256 + i;
362 }
363
364 //square
365 for (i = 0; i < 256; i++)
366 {
367 if (i < 128)
368 plfo.square_table[i] = 127;
369 else
370 plfo.square_table[i] = -128;
371 }
372
373 //triangular
374 for (i = 0; i < 256; i++)
375 {
376 if (i < 64)
377 plfo.tri_table[i] = i * 2;
378 else if (i < 192)
379 plfo.tri_table[i] = 255 - (i * 2);
380 else
381 plfo.tri_table[i] = (i * 2) - 512;
382 }
383
384 //noise
385 for (i = 0; i < 256; i++)
386 {
387 plfo.noise_table[i] = rand() & 0xff;
388 }
389 }
390
fill_alfo_tables()391 void fill_alfo_tables()
392 {
393 int i;
394
395 //saw
396 for (i = 0; i < 256; i++)
397 {
398 alfo.saw_table[i] = i;
399 }
400
401 //square
402 for (i = 0; i < 256; i++)
403 {
404 if (i < 128)
405 alfo.square_table[i] = 0;
406 else
407 alfo.square_table[i] = 0xff;
408 }
409
410 //triangular
411 for (i = 0; i < 256; i++)
412 {
413 if (i < 128)
414 alfo.tri_table[i] = i * 2;
415 else
416 alfo.tri_table[i] = 255 - (i * 2);
417 }
418
419 //noise
420 for (i = 0; i < 256; i++)
421 {
422 alfo.noise_table[i] = rand() & 0xff;
423 }
424 }
425
426 //pg, plfo
op1(struct Slot * slot)427 void op1(struct Slot * slot)
428 {
429 u32 oct = slot->regs.oct ^ 8;
430 u32 fns = slot->regs.fns ^ 0x400;
431 u32 phase_increment = fns << oct;
432 int plfo_val = 0;
433 int plfo_shifted = 0;
434
435 if (slot->state.attenuation > 0x3bf)
436 return;
437
438 if (slot->state.lfo_counter % lfo_step_table[slot->regs.lfof] == 0)
439 {
440 slot->state.lfo_counter = 0;
441 slot->state.lfo_pos++;
442
443 if (slot->state.lfo_pos > 0xff)
444 slot->state.lfo_pos = 0;
445 }
446
447 if (slot->regs.plfows == 0)
448 plfo_val = plfo.saw_table[slot->state.lfo_pos];
449 else if (slot->regs.plfows == 1)
450 plfo_val = plfo.square_table[slot->state.lfo_pos];
451 else if (slot->regs.plfows == 2)
452 plfo_val = plfo.tri_table[slot->state.lfo_pos];
453 else if (slot->regs.plfows == 3)
454 plfo_val = plfo.noise_table[slot->state.lfo_pos];
455
456 plfo_shifted = (plfo_val << slot->regs.plfos) >> 2;
457
458 slot->state.waveform_phase_value &= (1 << 18) - 1;//18 fractional bits
459 slot->state.waveform_phase_value += (phase_increment + plfo_shifted);
460 }
461
get_slot(struct Slot * slot,int mdsl)462 int get_slot(struct Slot * slot, int mdsl)
463 {
464 return (mdsl + slot->state.num) & 0x1f;
465 }
466
467 //address pointer calculation
468 //modulation data read
op2(struct Slot * slot,struct Scsp * s)469 void op2(struct Slot * slot, struct Scsp * s)
470 {
471 s32 md_out = 0;
472 s32 sample_delta = slot->state.waveform_phase_value >> 18;
473
474 if (slot->state.attenuation > 0x3bf)
475 return;
476
477 if (slot->regs.mdl)
478 {
479 //averaging operation
480 u32 x_sel = get_slot(slot, slot->regs.mdxsl);
481 u32 y_sel = get_slot(slot, slot->regs.mdysl);
482 s16 xd = s->sound_stack[x_sel];
483 s16 yd = s->sound_stack[y_sel];
484
485 s32 zd = (xd + yd) / 2;
486
487 //modulation operation
488 u16 shift = 0xf - (slot->regs.mdl);
489 zd >>= shift;
490
491 md_out = zd;
492 }
493
494 //address pointer
495
496 if (slot->regs.lpctl == 0)//no loop
497 {
498 slot->state.sample_offset += sample_delta;
499
500 if (slot->state.sample_offset >= slot->regs.lea)
501 slot->state.attenuation = 0x3ff;
502 }
503 else if (slot->regs.lpctl == 1)//normal loop
504 {
505 slot->state.sample_offset += sample_delta;
506
507 if (slot->state.sample_offset >= slot->regs.lea)
508 slot->state.sample_offset = slot->regs.lsa;
509 }
510 else if (slot->regs.lpctl == 2)//reverse
511 {
512 if (!slot->state.backwards)
513 slot->state.sample_offset += sample_delta;
514 else
515 slot->state.sample_offset -= sample_delta;
516
517 if (!slot->state.backwards)
518 {
519 if (slot->state.sample_offset >= slot->regs.lea)
520 {
521 slot->state.sample_offset = slot->regs.lea;
522 slot->state.backwards = 1;
523 }
524 }
525 else
526 {
527 //backwards
528 if (slot->state.sample_offset <= slot->regs.lsa)
529 slot->state.sample_offset = slot->regs.lea;
530 }
531 }
532 else if (slot->regs.lpctl == 3)//ping pong
533 {
534 if(!slot->state.backwards)
535 slot->state.sample_offset += sample_delta;
536 else
537 slot->state.sample_offset -= sample_delta;
538
539 if (!slot->state.backwards)
540 {
541 if (slot->state.sample_offset >= slot->regs.lea)
542 {
543 slot->state.sample_offset = slot->regs.lea;
544 slot->state.backwards = 1;
545 }
546 }
547 else
548 {
549 if (slot->state.sample_offset <= slot->regs.lsa)
550 {
551 slot->state.sample_offset = slot->regs.lsa;
552 slot->state.backwards = 0;
553 }
554 }
555 }
556
557 if (!slot->regs.pcm8b)
558 slot->state.address_pointer = (s32)slot->regs.sa + (slot->state.sample_offset + md_out) * 2;
559 else
560 slot->state.address_pointer = (s32)slot->regs.sa + (slot->state.sample_offset + md_out);
561 }
562
563 //waveform dram read
op3(struct Slot * slot)564 void op3(struct Slot * slot)
565 {
566 u32 addr = (slot->state.address_pointer) & 0x7FFFF;
567
568 if (slot->state.attenuation > 0x3bf)
569 return;
570
571 if (!slot->regs.pcm8b)
572 slot->state.wave = c68k_word_read(addr);
573 else
574 slot->state.wave = c68k_byte_read(addr) << 8;
575
576 slot->state.output = slot->state.wave;
577 }
578
change_envelope_state(struct Slot * slot,enum EnvelopeStates new_state)579 void change_envelope_state(struct Slot * slot, enum EnvelopeStates new_state)
580 {
581 slot->state.envelope = new_state;
582 slot->state.step_count = 0;
583 }
584
need_envelope_step(int effective_rate,u32 sample_counter,struct Slot * slot)585 int need_envelope_step(int effective_rate, u32 sample_counter, struct Slot* slot)
586 {
587 if (sample_counter == 0)
588 return 0;
589
590 if (effective_rate == 0 || effective_rate == 1)
591 {
592 return 0;//never step
593 }
594 else if (effective_rate >= 0x30)
595 {
596 if ((sample_counter & 1) == 0)
597 {
598 slot->state.envelope_steps_taken++;
599 return 1;
600 }
601 else
602 return 0;
603 }
604 else
605 {
606 int pos = effective_rate - 2;
607
608 int result = 0;
609
610 int value = envelope_table[pos][slot->state.step_count];
611
612 if (sample_counter % value == 0)
613 {
614 result = 1;
615
616 slot->state.envelope_steps_taken++;
617 slot->state.step_count++;
618
619 if (envelope_table[pos][slot->state.step_count] == EFFECTIVE_RATE_END)
620 slot->state.step_count = 0;//reached the end of the array
621 }
622
623 return result;
624 }
625 return 0;
626 }
627
get_rate(struct Slot * slot,int rate)628 s32 get_rate(struct Slot * slot, int rate)
629 {
630 s32 result = 0;
631
632 if (slot->regs.krs == 0xf)
633 result = rate * 2;
634 else
635 {
636 result = (slot->regs.krs * 2) + (rate * 2) + ((slot->regs.fns >> 9) & 1);
637 result = (8 ^ slot->regs.oct) + (result - 8);
638 }
639
640 if (result <= 0)
641 return 0;
642
643 if (result >= 0x3c)
644 return 0x3c;
645
646 return result;
647 }
648
do_decay(struct Slot * slot,int rate_in)649 void do_decay(struct Slot * slot, int rate_in)
650 {
651 int rate = get_rate(slot, rate_in);
652 int sample_mod_4 = slot->state.envelope_steps_taken & 3;
653 int decay_rate;
654
655 if (rate <= 0x30)
656 decay_rate = decay_rate_table[0][sample_mod_4];
657 else
658 decay_rate = decay_rate_table[rate - 0x30][sample_mod_4];
659
660 if (need_envelope_step(rate, slot->state.sample_counter, slot))
661 {
662 if (slot->state.attenuation < 0x3bf)
663 slot->state.attenuation += decay_rate;
664 }
665 }
666
667 //interpolation
668 //eg
op4(struct Slot * slot)669 void op4(struct Slot * slot)
670 {
671 int sample_mod_4 = slot->state.envelope_steps_taken & 3;
672
673 if (slot->state.attenuation >= 0x3bf)
674 return;
675
676 if (slot->state.envelope == ATTACK)
677 {
678 int rate = get_rate(slot, slot->regs.ar);
679 int need_step = need_envelope_step(rate, slot->state.sample_counter, slot);
680
681 if (need_step)
682 {
683 int attack_rate = 0;
684
685 if (rate <= 0x30)
686 attack_rate = attack_rate_table[0][sample_mod_4];
687 else
688 attack_rate = attack_rate_table[rate - 0x30][sample_mod_4];
689
690 slot->state.attenuation -= ((slot->state.attenuation >> attack_rate)) + 1;
691
692 if (slot->state.attenuation == 0)
693 change_envelope_state(slot, DECAY1);
694 }
695 }
696 else if (slot->state.envelope == DECAY1)
697 {
698 do_decay(slot,slot->regs.d1r);
699
700 if ((slot->state.attenuation >> 5) >= slot->regs.dl)
701 change_envelope_state(slot, DECAY2);
702 }
703 else if (slot->state.envelope == DECAY2)
704 do_decay(slot, slot->regs.d2r);
705 else if (slot->state.envelope == RELEASE)
706 do_decay(slot, slot->regs.rr);
707 }
708
apply_volume(u16 tl,u16 slot_att,const s16 s)709 s16 apply_volume(u16 tl, u16 slot_att, const s16 s)
710 {
711 u32 tl_att = tl * 4;
712 u32 att_clipped = 0;
713 s32 sample_att = 0;
714 u32 shift = 0;
715
716 tl_att += slot_att;
717
718 att_clipped = tl_att;
719 att_clipped &= 0x3f;
720 att_clipped ^= 0x7f;
721 att_clipped += 1;
722
723 sample_att = s * att_clipped;
724 shift = tl_att >> 6;
725
726 sample_att = sample_att >> (shift + 7);
727
728 return sample_att;
729 }
730
731 //level 1
op5(struct Slot * slot)732 void op5(struct Slot * slot)
733 {
734 if (slot->state.attenuation > 0x3bf)
735 {
736 slot->state.output = 0;
737 return;
738 }
739 else
740 {
741 int alfo_val = 0;
742 int lfo_add = 0;
743 s16 sample = 0;
744
745 if (slot->regs.alfows == 0)
746 alfo_val = alfo.saw_table[slot->state.lfo_pos];
747 else if (slot->regs.alfows == 1)
748 alfo_val = alfo.square_table[slot->state.lfo_pos];
749 else if (slot->regs.alfows == 2)
750 alfo_val = alfo.tri_table[slot->state.lfo_pos];
751 else if (slot->regs.alfows == 3)
752 alfo_val = alfo.noise_table[slot->state.lfo_pos];
753
754 lfo_add = (((alfo_val + 1)) >> (7 - slot->regs.alfos)) << 1;
755
756 sample = apply_volume(slot->regs.tl, slot->state.attenuation + lfo_add, slot->state.output);
757 slot->state.output = sample;
758 }
759 }
760
761 //level 2
op6(struct Slot * slot)762 void op6(struct Slot * slot)
763 {
764
765 }
766
767 //sound stack write
op7(struct Slot * slot,struct Scsp * s)768 void op7(struct Slot * slot, struct Scsp*s)
769 {
770 u32 previous = s->sound_stack[slot->state.num + 32];
771 s->sound_stack[slot->state.num + 32] = slot->state.output;
772 s->sound_stack[slot->state.num] = previous;
773
774 slot->state.sample_counter++;
775 slot->state.lfo_counter++;
776 }
777
778 struct DebugInstrument
779 {
780 u32 sa;
781 int is_muted;
782 };
783
784 #define NUM_DEBUG_INSTRUMENTS 24
785
786 struct DebugInstrument debug_instruments[NUM_DEBUG_INSTRUMENTS] = { 0 };
787 int debug_instrument_pos = 0;
788
scsp_debug_search_instruments(const u32 sa,int * found,int * offset)789 void scsp_debug_search_instruments(const u32 sa, int* found, int * offset)
790 {
791 int i = 0;
792 *found = 0;
793 for (i = 0; i < NUM_DEBUG_INSTRUMENTS; i++)
794 {
795 if (debug_instruments[i].sa == sa)
796 {
797 *found = 1;
798 break;
799 }
800 }
801
802 *offset = i;
803 }
804
scsp_debug_add_instrument(u32 sa)805 void scsp_debug_add_instrument(u32 sa)
806 {
807 int i = 0, found = 0, offset = 0;
808
809 if (debug_instrument_pos >= NUM_DEBUG_INSTRUMENTS)
810 return;
811
812 scsp_debug_search_instruments(sa, &found, &offset);
813
814 //new instrument discovered
815 if (!found)
816 debug_instruments[debug_instrument_pos++].sa = sa;
817 }
818
scsp_debug_instrument_set_mute(u32 sa,int mute)819 void scsp_debug_instrument_set_mute(u32 sa, int mute)
820 {
821 int found = 0, offset = 0;
822 scsp_debug_search_instruments(sa, &found, &offset);
823
824 if (offset >= NUM_DEBUG_INSTRUMENTS)
825 return;
826
827 if (found)
828 debug_instruments[offset].is_muted = mute;
829 }
830
scsp_debug_instrument_check_is_muted(u32 sa)831 int scsp_debug_instrument_check_is_muted(u32 sa)
832 {
833 int found = 0, offset = 0;
834 scsp_debug_search_instruments(sa, &found, &offset);
835
836 if (offset >= NUM_DEBUG_INSTRUMENTS)
837 return 0;
838
839 if (found && debug_instruments[offset].is_muted)
840 return 1;
841
842 return 0;
843 }
844
scsp_debug_instrument_get_data(int i,u32 * sa,int * is_muted)845 void scsp_debug_instrument_get_data(int i, u32 * sa, int * is_muted)
846 {
847 if(i >= NUM_DEBUG_INSTRUMENTS)
848 return;
849
850 *sa = debug_instruments[i].sa;
851 *is_muted = debug_instruments[i].is_muted;
852 }
853
scsp_debug_set_mode(int mode)854 void scsp_debug_set_mode(int mode)
855 {
856 new_scsp.debug_mode = mode;
857 }
858
scsp_debug_instrument_clear()859 void scsp_debug_instrument_clear()
860 {
861 debug_instrument_pos = 0;
862 memset(debug_instruments, 0, sizeof(struct DebugInstrument) * NUM_DEBUG_INSTRUMENTS);
863 }
864
scsp_debug_get_envelope(int chan,int * env,int * state)865 void scsp_debug_get_envelope(int chan, int * env, int * state)
866 {
867 *env = new_scsp.slots[chan].state.attenuation;
868 *state = new_scsp.slots[chan].state.envelope;
869 }
870
keyon(struct Slot * slot)871 void keyon(struct Slot * slot)
872 {
873 if (slot->state.envelope == RELEASE)
874 {
875 slot->state.envelope = ATTACK;
876 slot->state.attenuation = 0x280;
877 slot->state.sample_counter = 0;
878 slot->state.step_count = 0;
879 slot->state.sample_offset = 0;
880 slot->state.envelope_steps_taken = 0;
881
882 if (new_scsp.debug_mode)
883 scsp_debug_add_instrument(slot->regs.sa);
884 }
885 //otherwise ignore
886 }
887
keyoff(struct Slot * slot)888 void keyoff(struct Slot * slot)
889 {
890 change_envelope_state(slot, RELEASE);
891 }
892
keyonex(struct Scsp * s)893 void keyonex(struct Scsp *s)
894 {
895 int channel;
896 for (channel = 0; channel < 32; channel++)
897 {
898 if (s->slots[channel].regs.kb)
899 keyon(&s->slots[channel]);
900 else
901 keyoff(&s->slots[channel]);
902 }
903 }
904
scsp_slot_write_byte(struct Scsp * s,u32 addr,u8 data)905 void scsp_slot_write_byte(struct Scsp *s, u32 addr, u8 data)
906 {
907 int slot_num = (addr >> 5) & 0x1f;
908 struct Slot * slot = &s->slots[slot_num];
909 u32 offset = (addr - (0x20 * slot_num));
910
911 switch (offset)
912 {
913 case 0:
914 slot->regs.kb = (data >> 3) & 1;//has to be done first
915
916 if ((data >> 4) & 1)//keyonex
917 keyonex(s);
918
919 slot->regs.sbctl = (data >> 1) & 3;
920 slot->regs.ssctl = (slot->regs.ssctl & 1) | ((data & 1) << 1);
921 break;
922 case 1:
923 slot->regs.ssctl = (slot->regs.ssctl & 2) | ((data >> 7) & 1);
924 slot->regs.lpctl = (data >> 5) & 3;
925 slot->regs.pcm8b = (data >> 4) & 1;
926 slot->regs.sa = (slot->regs.sa & 0xffff) | ((data & 0xf) << 16);
927 break;
928 case 2:
929 slot->regs.sa = (slot->regs.sa & 0xf00ff) | (data << 8);
930 break;
931 case 3:
932 slot->regs.sa = (slot->regs.sa & 0xfff00) | data;
933 break;
934 case 4:
935 slot->regs.lsa = (slot->regs.lsa & 0x00ff) | (data << 8);
936 break;
937 case 5:
938 slot->regs.lsa = (slot->regs.lsa & 0xff00) | data;
939 break;
940 case 6:
941 slot->regs.lea = (slot->regs.lea & 0x00ff) | (data << 8);
942 break;
943 case 7:
944 slot->regs.lea = (slot->regs.lea & 0xff00) | data;
945 break;
946 case 8:
947 slot->regs.d2r = (data >> 3) & 0x1f;
948 slot->regs.d1r = (slot->regs.d1r & 3) | ((data & 0x7) << 2);
949 break;
950 case 9:
951 slot->regs.d1r = (slot->regs.d1r & 0x1c) | ((data >> 6) & 3);
952 slot->regs.hold = (data >> 5) & 1;
953 slot->regs.ar = data & 0x1f;
954 break;
955 case 10:
956 slot->regs.unknown1 = (data >> 7) & 1;
957 slot->regs.ls = (data >> 6) & 1;
958 slot->regs.krs = (data >> 2) & 0xf;
959 slot->regs.dl = (slot->regs.dl & 0x7) | ((data & 3) << 3);
960 break;
961 case 11:
962 slot->regs.dl = (slot->regs.dl & 0x18) | ((data >> 5) & 7);
963 slot->regs.rr = data & 0x1f;
964 break;
965 case 12:
966 slot->regs.unknown2 = (data >> 2) & 3;
967 slot->regs.si = (data >> 1) & 1;
968 slot->regs.sd = data & 1;
969 break;
970 case 13:
971 slot->regs.tl = data;
972 break;
973 case 14:
974 slot->regs.mdl = (data >> 4) & 0xf;
975 slot->regs.mdxsl = (slot->regs.mdxsl & 0x3) | ((data & 0xf) << 2);
976 break;
977 case 15:
978 slot->regs.mdxsl = (slot->regs.mdxsl & 0x3C) | ((data >> 6) & 3);
979 slot->regs.mdysl = data & 0x3f;
980 break;
981 case 16:
982 slot->regs.unknown3 = (data >> 7) & 1;
983 slot->regs.oct = (data >> 3) & 0xf;
984 slot->regs.unknown4 = (data >> 2) & 1;
985 slot->regs.fns = (slot->regs.fns & 0xff) | ((data & 3) << 8);
986 break;
987 case 17:
988 slot->regs.fns = (slot->regs.fns & 0x300) | data;
989 break;
990 case 18:
991 slot->regs.re = (data >> 7) & 1;
992 slot->regs.lfof = (data >> 2) & 0x1f;
993 slot->regs.plfows = data & 3;
994 break;
995 case 19:
996 slot->regs.plfos = (data >> 5) & 7;
997 slot->regs.alfows = (data >> 3) & 3;
998 slot->regs.alfos = data & 7;
999 break;
1000 case 20:
1001 //nothing here
1002 break;
1003 case 21:
1004 slot->regs.unknown5 = (data >> 7) & 1;
1005 slot->regs.isel = (data >> 3) & 0xf;
1006 slot->regs.imxl = data & 7;
1007 break;
1008 case 22:
1009 slot->regs.disdl = (data >> 5) & 7;
1010 slot->regs.dipan = data & 0x1f;
1011 break;
1012 case 23:
1013 slot->regs.efsdl = (data >> 5) & 7;
1014 slot->regs.efpan = data & 0x1f;
1015 break;
1016 default:
1017 break;
1018 }
1019 }
1020
scsp_slot_read_byte(struct Scsp * s,u32 addr)1021 u8 scsp_slot_read_byte(struct Scsp *s, u32 addr)
1022 {
1023 int slot_num = (addr >> 5) & 0x1f;
1024 struct Slot * slot = &s->slots[slot_num];
1025 u32 offset = (addr - (0x20 * slot_num));
1026 u8 data = 0;
1027
1028 switch (offset)
1029 {
1030 case 0:
1031 data |= slot->regs.kb << 3;
1032 data |= slot->regs.sbctl << 1;
1033 data |= (slot->regs.ssctl >> 1) & 1;
1034 break;
1035 case 1:
1036 data |= (slot->regs.ssctl & 1) << 7;
1037 data |= slot->regs.lpctl << 5;
1038 data |= slot->regs.pcm8b << 4;
1039 data |= (slot->regs.sa & 0xf0000) >> 16;
1040 break;
1041 case 2:
1042 data |= (slot->regs.sa & 0xff00) >> 8;
1043 break;
1044 case 3:
1045 data |= slot->regs.sa & 0xff;
1046 break;
1047 case 4:
1048 data |= (slot->regs.lsa & 0xff00) >> 8;
1049 break;
1050 case 5:
1051 data |= slot->regs.lsa & 0xff;
1052 break;
1053 case 6:
1054 data |= (slot->regs.lea & 0xff00) >> 8;
1055 break;
1056 case 7:
1057 data |= slot->regs.lea & 0xff;
1058 break;
1059 case 8:
1060 data |= slot->regs.d2r << 3;
1061 data |= slot->regs.d1r >> 2;
1062 break;
1063 case 9:
1064 data |= slot->regs.d1r << 6;
1065 data |= slot->regs.hold << 5;
1066 data |= slot->regs.ar;
1067 break;
1068 case 10:
1069 data |= slot->regs.unknown1 << 7;
1070 data |= slot->regs.ls << 6;
1071 data |= slot->regs.krs << 2;
1072 data |= slot->regs.dl >> 3;
1073 break;
1074 case 11:
1075 data |= slot->regs.dl << 5;
1076 data |= slot->regs.rr;
1077 break;
1078 case 12:
1079 data |= slot->regs.unknown2 << 2;
1080 data |= slot->regs.si << 1;
1081 data |= slot->regs.sd;
1082 break;
1083 case 13:
1084 data |= slot->regs.tl;
1085 break;
1086 case 14:
1087 data |= slot->regs.mdl << 4;
1088 data |= slot->regs.mdxsl >> 2;
1089 break;
1090 case 15:
1091 data |= slot->regs.mdxsl << 6;
1092 data |= slot->regs.mdysl;
1093 break;
1094 case 16:
1095 data |= slot->regs.unknown3 << 7;
1096 data |= slot->regs.oct << 3;
1097 data |= slot->regs.unknown4 << 2;
1098 data |= slot->regs.fns >> 8;
1099 break;
1100 case 17:
1101 data |= slot->regs.fns;
1102 break;
1103 case 18:
1104 data |= slot->regs.re << 7;
1105 data |= slot->regs.lfof << 2;
1106 data |= slot->regs.plfows;
1107 break;
1108 case 19:
1109 data |= slot->regs.plfos << 5;
1110 data |= slot->regs.alfows << 3;
1111 data |= slot->regs.alfos;
1112 break;
1113 case 20:
1114 //nothing
1115 break;
1116 case 21:
1117 data |= slot->regs.unknown5 << 7;
1118 data |= slot->regs.isel << 3;
1119 data |= slot->regs.imxl;
1120 break;
1121 case 22:
1122 data |= slot->regs.disdl << 5;
1123 data |= slot->regs.dipan;
1124 break;
1125 case 23:
1126 data |= slot->regs.efsdl << 5;
1127 data |= slot->regs.efpan;
1128 break;
1129 }
1130
1131 return data;
1132 }
1133
scsp_slot_write_word(struct Scsp * s,u32 addr,u16 data)1134 void scsp_slot_write_word(struct Scsp *s, u32 addr, u16 data)
1135 {
1136 int slot_num = (addr >> 5) & 0x1f;
1137 struct Slot * slot = &s->slots[slot_num];
1138 u32 offset = (addr - (0x20 * slot_num));
1139
1140 switch (offset >> 1)
1141 {
1142 case 0:
1143 slot->regs.kb = (data >> 11) & 1;//has to be done before keyonex
1144
1145 if (data & (1 << 12))
1146 keyonex(s);
1147
1148 slot->regs.sbctl = (data >> 9) & 3;
1149 slot->regs.ssctl = (data >> 7) & 3;
1150 slot->regs.lpctl = (data >> 5) & 3;
1151 slot->regs.pcm8b = (data >> 4) & 1;
1152 slot->regs.sa = (slot->regs.sa & 0xffff) | ((data & 0xf) << 16);
1153 break;
1154 case 1:
1155 slot->regs.sa = (slot->regs.sa & 0xf0000) | data;
1156 break;
1157 case 2:
1158 slot->regs.lsa = data;
1159 break;
1160 case 3:
1161 slot->regs.lea = data;
1162 break;
1163 case 4:
1164 slot->regs.d2r = data >> 11;
1165 slot->regs.d1r = (data >> 6) & 0x1f;
1166 slot->regs.hold = (data >> 5) & 1;
1167 slot->regs.ar = data & 0x1f;
1168 break;
1169 case 5:
1170 slot->regs.unknown1 = (data >> 15) & 1;
1171 slot->regs.ls = (data >> 14) & 1;
1172 slot->regs.krs = (data >> 10) & 0xf;
1173 slot->regs.dl = (data >> 5) & 0x1f;
1174 slot->regs.rr = data & 0x1f;
1175 break;
1176 case 6:
1177 slot->regs.unknown2 = (data >> 10) & 3;
1178 slot->regs.si = (data >> 9) & 1;
1179 slot->regs.sd = (data >> 8) & 1;
1180 slot->regs.tl = data & 0xff;
1181 break;
1182 case 7:
1183 slot->regs.mdl = (data >> 12) & 0xf;
1184 slot->regs.mdxsl = (data >> 6) & 0x3f;
1185 slot->regs.mdysl = data & 0x3f;
1186 break;
1187 case 8:
1188 slot->regs.unknown3 = (data >> 15) & 1;
1189 slot->regs.unknown4 = (data >> 10) & 1;
1190 slot->regs.oct = (data >> 11) & 0xf;
1191 slot->regs.fns = data & 0x3ff;
1192 break;
1193 case 9:
1194 slot->regs.re = (data >> 15) & 1;
1195 slot->regs.lfof = (data >> 10) & 0x1f;
1196 slot->regs.plfows = (data >> 8) & 3;
1197 slot->regs.plfos = (data >> 5) & 7;
1198 slot->regs.alfows = (data >> 3) & 3;
1199 slot->regs.alfos = data & 7;
1200 break;
1201 case 10:
1202 slot->regs.unknown5 = (data >> 7) & 1;
1203 slot->regs.isel = (data >> 3) & 0xf;
1204 slot->regs.imxl = data & 7;
1205 break;
1206 case 11:
1207 slot->regs.disdl = (data >> 13) & 7;
1208 slot->regs.dipan = (data >> 8) & 0x1f;
1209 slot->regs.efsdl = (data >> 5) & 7;
1210 slot->regs.efpan = data & 0x1f;
1211 break;
1212 default:
1213 break;
1214 }
1215 }
1216
scsp_slot_read_word(struct Scsp * s,u32 addr)1217 u16 scsp_slot_read_word(struct Scsp *s, u32 addr)
1218 {
1219 int slot_num = (addr >> 5) & 0x1f;
1220 struct Slot * slot = &s->slots[slot_num];
1221 u32 offset = (addr - (0x20 * slot_num));
1222 u16 data = 0;
1223
1224 switch (offset >> 1)
1225 {
1226 case 0:
1227 //keyonex not stored
1228 data |= slot->regs.kb << 11;
1229 data |= slot->regs.sbctl << 9;
1230 data |= slot->regs.ssctl << 7;
1231 data |= slot->regs.lpctl << 5;
1232 data |= slot->regs.pcm8b << 4;
1233 data |= (slot->regs.sa >> 16) & 0xf;
1234 break;
1235 case 1:
1236 data = slot->regs.sa & 0xffff;
1237 break;
1238 case 2:
1239 data = slot->regs.lsa;
1240 break;
1241 case 3:
1242 data = slot->regs.lea;
1243 break;
1244 case 4:
1245 data |= slot->regs.d2r << 11;
1246 data |= slot->regs.d1r << 6;
1247 data |= slot->regs.hold << 5;
1248 data |= slot->regs.ar;
1249 break;
1250 case 5:
1251 data |= slot->regs.unknown1 << 15;
1252 data |= slot->regs.ls << 14;
1253 data |= slot->regs.krs << 10;
1254 data |= slot->regs.dl << 5;
1255 data |= slot->regs.rr;
1256 break;
1257 case 6:
1258 data |= slot->regs.unknown2 << 10;
1259 data |= slot->regs.si << 9;
1260 data |= slot->regs.sd << 8;
1261 data |= slot->regs.tl;
1262 break;
1263 case 7:
1264 data |= slot->regs.mdl << 12;
1265 data |= slot->regs.mdxsl << 6;
1266 data |= slot->regs.mdysl;
1267 break;
1268 case 8:
1269 data |= slot->regs.unknown3 << 15;
1270 data |= slot->regs.oct << 11;
1271 data |= slot->regs.unknown4 << 10;
1272 data |= slot->regs.fns;
1273 break;
1274 case 9:
1275 data |= slot->regs.re << 15;
1276 data |= slot->regs.lfof << 10;
1277 data |= slot->regs.plfows << 8;
1278 data |= slot->regs.plfos << 5;
1279 data |= slot->regs.alfows << 3;
1280 data |= slot->regs.alfos;
1281 break;
1282 case 10:
1283 data |= slot->regs.unknown5 << 7;
1284 data |= slot->regs.isel << 3;
1285 data |= slot->regs.imxl;
1286 break;
1287 case 11:
1288 data |= slot->regs.disdl << 13;
1289 data |= slot->regs.dipan << 8;
1290 data |= slot->regs.efsdl << 5;
1291 data |= slot->regs.efpan;
1292 break;
1293 }
1294 return data;
1295 }
1296
get_panning(int pan,int * pan_val_l,int * pan_val_r)1297 void get_panning(int pan, int * pan_val_l, int * pan_val_r)
1298 {
1299 if (pan & 0x10)
1300 {
1301 //negative values
1302 *pan_val_l = 0;
1303 *pan_val_r = pan & 0xf;
1304 }
1305 else
1306 {
1307 *pan_val_l = pan & 0xf;
1308 *pan_val_r = 0;
1309 }
1310 }
1311
get_sdl_shift(int sdl)1312 int get_sdl_shift(int sdl)
1313 {
1314 if (sdl == 0)
1315 return 16;//-infinity
1316 else return (7 - sdl);
1317 }
1318
generate_sample(struct Scsp * s,int rbp,int rbl,s16 * out_l,s16 * out_r,int mvol,s16 cd_in_l,s16 cd_in_r)1319 void generate_sample(struct Scsp * s, int rbp, int rbl, s16 * out_l, s16* out_r, int mvol, s16 cd_in_l, s16 cd_in_r)
1320 {
1321 int step_num = 0;
1322 int i = 0;
1323 int mvol_shift = 0;
1324
1325 //run 32 steps to generate 1 full sample (512 clock cycles at 22579200hz)
1326 //7 operations happen simultaneously on different channels due to pipelining
1327 for (step_num = 0; step_num < 32; step_num++)
1328 {
1329 int last_step = (step_num - 6) & 0x1f;
1330 int debug_muted = 0;
1331
1332 op1(&s->slots[step_num]);//phase, pitch lfo
1333 op2(&s->slots[(step_num - 1) & 0x1f],s);//address pointer, modulation data read
1334 op3(&s->slots[(step_num - 2) & 0x1f]);//waveform dram read
1335 op4(&s->slots[(step_num - 3) & 0x1f]);//interpolation, eg, amplitude lfo
1336 op5(&s->slots[(step_num - 4) & 0x1f]);//level calc 1
1337 op6(&s->slots[(step_num - 5) & 0x1f]);//level calc 2
1338 op7(&s->slots[(step_num - 6) & 0x1f],s);//sound stack write
1339
1340 if (s->debug_mode)
1341 {
1342 if (scsp_debug_instrument_check_is_muted(s->slots[last_step].regs.sa))
1343 debug_muted = 1;
1344 }
1345
1346 if (!debug_muted)
1347 {
1348 int disdl = get_sdl_shift(s->slots[last_step].regs.disdl);
1349
1350 s16 disdl_applied = (s->slots[last_step].state.output >> disdl);
1351
1352 s16 mixs_input = s->slots[last_step].state.output >>
1353 get_sdl_shift(s->slots[last_step].regs.imxl);
1354
1355 int pan_val_l = 0, pan_val_r = 0;
1356
1357 get_panning(s->slots[last_step].regs.dipan, &pan_val_l, &pan_val_r);
1358
1359 *out_l = *out_l + ((disdl_applied >> pan_val_l) >> 2);
1360 *out_r = *out_r + ((disdl_applied >> pan_val_r) >> 2);
1361
1362 dsp_inf.set_mixs(s->slots[last_step].regs.isel, mixs_input);
1363 }
1364 }
1365
1366 dsp_inf.set_rbl_rbp(rbl, rbp);
1367 dsp_inf.set_exts(cd_in_l, cd_in_r);
1368
1369 dsp_inf.exec();
1370
1371 for (i = 0; i < 18; i++)//16,17 are exts0/1
1372 {
1373 int efsdl = get_sdl_shift(s->slots[i].regs.efsdl);
1374 s16 efsdl_applied = 0;
1375
1376 int pan_val_l = 0, pan_val_r = 0;
1377 s16 panned_l = 0, panned_r = 0;
1378
1379 efsdl_applied = dsp_inf.get_effect_out(i) >> efsdl;
1380
1381 get_panning(s->slots[i].regs.efpan, &pan_val_l, &pan_val_r);
1382
1383 panned_l = (efsdl_applied >> pan_val_l) >> 2;
1384 panned_r = (efsdl_applied >> pan_val_r) >> 2;
1385
1386 *out_l = *out_l + panned_l;
1387 *out_r = *out_r + panned_r;
1388 }
1389
1390 mvol_shift = 0xf - mvol;
1391
1392 *out_l = *out_l >> mvol_shift;
1393 *out_r = *out_r >> mvol_shift;
1394 }
1395
new_scsp_reset(struct Scsp * s)1396 void new_scsp_reset(struct Scsp* s)
1397 {
1398 int slot_num;
1399 memset(s, 0, sizeof(struct Scsp));
1400
1401 for (slot_num = 0; slot_num < 32; slot_num++)
1402 {
1403 s->slots[slot_num].state.attenuation = 0x3FF;
1404 s->slots[slot_num].state.envelope = RELEASE;
1405 s->slots[slot_num].state.num = slot_num;
1406 }
1407
1408 fill_plfo_tables();
1409 fill_alfo_tables();
1410
1411 #ifdef HAVE_PLAY_JIT
1412 if (yabsys.use_scsp_dsp_jit)
1413 scsp_dsp_jit_init();
1414 else
1415 scsp_dsp_int_init();
1416 #else
1417 scsp_dsp_int_init();
1418 #endif
1419
1420 new_scsp_outbuf_pos = 0;
1421 new_scsp_cycles = 0;
1422 }
1423
scsp_set_use_new(int which)1424 void scsp_set_use_new(int which)
1425 {
1426 if (which && !use_new_scsp)
1427 new_scsp_reset(&new_scsp);
1428
1429 use_new_scsp = which;
1430 }
1431
1432 ////////////////////////////////////////////////////////////////
1433
1434 #ifndef PI
1435 #define PI 3.14159265358979323846
1436 #endif
1437
1438 #define SCSP_FREQ 44100 // SCSP frequency
1439
1440 #define SCSP_RAM_SIZE 0x080000 // SCSP RAM size
1441 #define SCSP_RAM_MASK (SCSP_RAM_SIZE - 1)
1442
1443 #define SCSP_MIDI_IN_EMP 0x01 // MIDI flags
1444 #define SCSP_MIDI_IN_FUL 0x02
1445 #define SCSP_MIDI_IN_OVF 0x04
1446 #define SCSP_MIDI_OUT_EMP 0x08
1447 #define SCSP_MIDI_OUT_FUL 0x10
1448
1449 #define SCSP_ENV_RELEASE 3 // Envelope phase
1450 #define SCSP_ENV_SUSTAIN 2
1451 #define SCSP_ENV_DECAY 1
1452 #define SCSP_ENV_ATTACK 0
1453
1454 #define SCSP_FREQ_HB 19 // Freq counter int part
1455 #define SCSP_FREQ_LB 10 // Freq counter float part
1456
1457 #define SCSP_ENV_HB 10 // Env counter int part
1458 #define SCSP_ENV_LB 10 // Env counter float part
1459
1460 #define SCSP_LFO_HB 10 // LFO counter int part
1461 #define SCSP_LFO_LB 10 // LFO counter float part
1462
1463 #define SCSP_ENV_LEN (1 << SCSP_ENV_HB) // Env table len
1464 #define SCSP_ENV_MASK (SCSP_ENV_LEN - 1) // Env table mask
1465
1466 #define SCSP_FREQ_LEN (1 << SCSP_FREQ_HB) // Freq table len
1467 #define SCSP_FREQ_MASK (SCSP_FREQ_LEN - 1) // Freq table mask
1468
1469 #define SCSP_LFO_LEN (1 << SCSP_LFO_HB) // LFO table len
1470 #define SCSP_LFO_MASK (SCSP_LFO_LEN - 1) // LFO table mask
1471
1472 #define SCSP_ENV_AS 0 // Env Attack Start
1473 #define SCSP_ENV_DS (SCSP_ENV_LEN << SCSP_ENV_LB) // Env Decay Start
1474 #define SCSP_ENV_AE (SCSP_ENV_DS - 1) // Env Attack End
1475 #define SCSP_ENV_DE (((2 * SCSP_ENV_LEN) << SCSP_ENV_LB) - 1) // Env Decay End
1476
1477 #define SCSP_ATTACK_R (u32) (8 * 44100)
1478 #define SCSP_DECAY_R (u32) (12 * SCSP_ATTACK_R)
1479
1480 ////////////////////////////////////////////////////////////////
1481
1482 typedef struct slot_t
1483 {
1484 u8 swe; // stack write enable
1485 u8 sdir; // sound direct
1486 u8 pcm8b; // PCM sound format
1487
1488 u8 sbctl; // source bit control
1489 u8 ssctl; // sound source control
1490 u8 lpctl; // loop control
1491
1492 u8 key; // KEY_ state
1493 u8 keyx; // still playing regardless the KEY_ state (hold, decay)
1494
1495 s8 *buf8; // sample buffer 8 bits
1496 s16 *buf16; // sample buffer 16 bits
1497
1498 u32 fcnt; // phase counter
1499 u32 finc; // phase step adder
1500 u32 finct; // non adjusted phase step
1501
1502 s32 ecnt; // envelope counter
1503 s32 *einc; // envelope current step adder
1504 s32 einca; // envelope step adder for attack
1505 s32 eincd; // envelope step adder for decay 1
1506 s32 eincs; // envelope step adder for decay 2
1507 s32 eincr; // envelope step adder for release
1508 s32 ecmp; // envelope compare to raise next phase
1509 u32 ecurp; // envelope current phase (attack / decay / release ...)
1510 s32 env; // envelope multiplier (at time of last update)
1511
1512 void (*enxt)(struct slot_t *); // envelope function pointer for next phase event
1513
1514 u32 lfocnt; // lfo counter
1515 s32 lfoinc; // lfo step adder
1516
1517 u32 sa; // start address
1518 u32 lsa; // loop start address
1519 u32 lea; // loop end address
1520
1521 s32 tl; // total level
1522 s32 sl; // sustain level
1523
1524 s32 ar; // attack rate
1525 s32 dr; // decay rate
1526 s32 sr; // sustain rate
1527 s32 rr; // release rate
1528
1529 s32 *arp; // attack rate table pointer
1530 s32 *drp; // decay rate table pointer
1531 s32 *srp; // sustain rate table pointer
1532 s32 *rrp; // release rate table pointer
1533
1534 u32 krs; // key rate scale
1535
1536 s32 *lfofmw; // lfo frequency modulation waveform pointer
1537 s32 *lfoemw; // lfo envelope modulation waveform pointer
1538 u8 lfofms; // lfo frequency modulation sensitivity
1539 u8 lfoems; // lfo envelope modulation sensitivity
1540 u8 fsft; // frequency shift (used for freq lfo)
1541
1542 u8 mdl; // modulation level
1543 u8 mdx; // modulation source X
1544 u8 mdy; // modulation source Y
1545
1546 u8 imxl; // input sound level
1547 u8 disll; // direct sound level left
1548 u8 dislr; // direct sound level right
1549 u8 efsll; // effect sound level left
1550 u8 efslr; // effect sound level right
1551
1552 u8 eghold; // eg type envelope hold
1553 u8 lslnk; // loop start link (start D1R when start loop adr is reached)
1554
1555 // NOTE: Previously there were u8 pads here to maintain 4-byte alignment.
1556 // There are current 22 u8's in this struct and 1 u16. This makes 24
1557 // bytes, so there are no pads at the moment.
1558 //
1559 // I'm not sure this is at all necessary either, but keeping this note
1560 // in case.
1561 } slot_t;
1562
1563 typedef struct scsp_t
1564 {
1565 u32 mem4b; // 4mbit memory
1566 u32 mvol; // master volume
1567
1568 u32 rbl; // ring buffer lenght
1569 u32 rbp; // ring buffer address (pointer)
1570
1571 u32 mslc; // monitor slot
1572 u32 ca; // call address
1573 u32 sgc; // phase
1574 u32 eg; // envelope
1575
1576 u32 dmea; // dma memory address start
1577 u32 drga; // dma register address start
1578 u32 dmfl; // dma flags (direction / gate 0 ...)
1579 u32 dmlen; // dma transfer len
1580
1581 u8 midinbuf[4]; // midi in buffer
1582 u8 midoutbuf[4]; // midi out buffer
1583 u8 midincnt; // midi in buffer size
1584 u8 midoutcnt; // midi out buffer size
1585 u8 midflag; // midi flag (empty, full, overflow ...)
1586 u8 midflag2; // midi flag 2 (here only for alignement)
1587
1588 s32 timacnt; // timer A counter
1589 u32 timasd; // timer A step diviser
1590 s32 timbcnt; // timer B counter
1591 u32 timbsd; // timer B step diviser
1592 s32 timccnt; // timer C counter
1593 u32 timcsd; // timer C step diviser
1594
1595 u32 scieb; // allow sound cpu interrupt
1596 u32 scipd; // pending sound cpu interrupt
1597
1598 u32 scilv0; // IL0 M68000 interrupt pin state
1599 u32 scilv1; // IL1 M68000 interrupt pin state
1600 u32 scilv2; // IL2 M68000 interrupt pin state
1601
1602 u32 mcieb; // allow main cpu interrupt
1603 u32 mcipd; // pending main cpu interrupt
1604
1605 u8 *scsp_ram; // scsp ram pointer
1606 void (*mintf)(void); // main cpu interupt function pointer
1607 void (*sintf)(u32); // sound cpu interrupt function pointer
1608
1609 s32 stack[32 * 2]; // two last generation slot output (SCSP STACK)
1610 slot_t slot[32]; // 32 slots
1611 } scsp_t;
1612
1613 ////////////////////////////////////////////////////////////////
1614
1615 static s32 scsp_env_table[SCSP_ENV_LEN * 2]; // envelope curve table (attack & decay)
1616
1617 static s32 scsp_lfo_sawt_e[SCSP_LFO_LEN]; // lfo sawtooth waveform for envelope
1618 static s32 scsp_lfo_squa_e[SCSP_LFO_LEN]; // lfo square waveform for envelope
1619 static s32 scsp_lfo_tri_e[SCSP_LFO_LEN]; // lfo triangle waveform for envelope
1620 static s32 scsp_lfo_noi_e[SCSP_LFO_LEN]; // lfo noise waveform for envelope
1621
1622 static s32 scsp_lfo_sawt_f[SCSP_LFO_LEN]; // lfo sawtooth waveform for frequency
1623 static s32 scsp_lfo_squa_f[SCSP_LFO_LEN]; // lfo square waveform for frequency
1624 static s32 scsp_lfo_tri_f[SCSP_LFO_LEN]; // lfo triangle waveform for frequency
1625 static s32 scsp_lfo_noi_f[SCSP_LFO_LEN]; // lfo noise waveform frequency
1626
1627 static s32 scsp_attack_rate[0x40 + 0x20]; // envelope step for attack
1628 static s32 scsp_decay_rate[0x40 + 0x20]; // envelope step for decay
1629 static s32 scsp_null_rate[0x20]; // null envelope step
1630
1631 static s32 scsp_lfo_step[32]; // directly give the lfo counter step
1632
1633 static s32 scsp_tl_table[256]; // table of values for total level attentuation
1634
1635 static u8 scsp_reg[0x1000];
1636
1637 static u8 *scsp_isr;
1638 static u8 *scsp_ccr;
1639 static u8 *scsp_dcr;
1640
1641 static s32 *scsp_bufL;
1642 static s32 *scsp_bufR;
1643 static u32 scsp_buf_len;
1644 static u32 scsp_buf_pos;
1645
1646 static scsp_t scsp; // SCSP structure
1647
1648 #define CDDA_NUM_BUFFERS 2*75
1649
1650 static union {
1651 u8 data[CDDA_NUM_BUFFERS*2352];
1652 } cddabuf;
1653 static unsigned int cdda_next_in=0; // Next sector buffer offset to receive into
1654 static u32 cdda_out_left; // Bytes of CDDA left to output
1655
1656 ////////////////////////////////////////////////////////////////
1657
1658 static void scsp_env_null_next(slot_t *slot);
1659 static void scsp_release_next(slot_t *slot);
1660 static void scsp_sustain_next(slot_t *slot);
1661 static void scsp_decay_next(slot_t *slot);
1662 static void scsp_attack_next(slot_t *slot);
1663 static void scsp_slot_update_keyon(slot_t *slot);
1664
1665 //////////////////////////////////////////////////////////////////////////////
1666
1667 static int scsp_mute_flags = 0;
1668 static int scsp_volume = 100;
1669
1670 ////////////////////////////////////////////////////////////////
1671 // Misc
1672
1673 static int
scsp_round(double val)1674 scsp_round (double val)
1675 {
1676 return (int)(val + 0.5);
1677 }
1678
1679
1680 ////////////////////////////////////////////////////////////////
1681 // Interrupts
1682
1683 static INLINE void
scsp_trigger_main_interrupt(u32 id)1684 scsp_trigger_main_interrupt (u32 id)
1685 {
1686 SCSPLOG ("scsp main interrupt accepted %.4X\n", id);
1687 scsp.mintf ();
1688 }
1689
1690 static INLINE void
scsp_trigger_sound_interrupt(u32 id)1691 scsp_trigger_sound_interrupt (u32 id)
1692 {
1693 u32 level;
1694 level = 0;
1695 if (id > 0x80) id = 0x80;
1696
1697 if (scsp.scilv0 & id) level |= 1;
1698 if (scsp.scilv1 & id) level |= 2;
1699 if (scsp.scilv2 & id) level |= 4;
1700
1701 #ifdef SCSP_DEBUG
1702 if (id == 0x8) SCSPLOG ("scsp sound interrupt accepted %.2X lev=%d\n", id, level);
1703 #endif
1704
1705 scsp.sintf (level);
1706 }
1707
1708 static void
scsp_main_interrupt(u32 id)1709 scsp_main_interrupt (u32 id)
1710 {
1711 // if (scsp.mcipd & id) return;
1712 // if (id != 0x400) SCSPLOG("scsp main interrupt %.4X\n", id);
1713
1714 scsp.mcipd |= id;
1715 WRITE_THROUGH (scsp.mcipd);
1716
1717 if (scsp.mcieb & id)
1718 scsp_trigger_main_interrupt (id);
1719 }
1720
1721 static void
scsp_sound_interrupt(u32 id)1722 scsp_sound_interrupt (u32 id)
1723 {
1724 // if (scsp.scipd & id) return;
1725
1726 // SCSPLOG ("scsp sound interrupt %.4X\n", id);
1727
1728 scsp.scipd |= id;
1729 WRITE_THROUGH (scsp.scipd);
1730
1731 if (scsp.scieb & id)
1732 scsp_trigger_sound_interrupt (id);
1733 }
1734
1735 ////////////////////////////////////////////////////////////////
1736 // Direct Memory Access
1737
1738 static void
scsp_dma(void)1739 scsp_dma (void)
1740 {
1741 if (scsp.dmfl & 0x20)
1742 {
1743 // dsp -> scsp_ram
1744 SCSPLOG ("scsp dma: scsp_ram(%08lx) <- reg(%08lx) * %08lx\n",
1745 scsp.dmea, scsp.drga, scsp.dmlen);
1746 }
1747 else
1748 {
1749 // scsp_ram -> dsp
1750 SCSPLOG ("scsp dma: scsp_ram(%08lx) -> reg(%08lx) * %08lx\n",
1751 scsp.dmea, scsp.drga, scsp.dmlen);
1752 }
1753
1754 scsp_ccr[0x16 ^ 3] &= 0xE0;
1755
1756 scsp_sound_interrupt (0x10);
1757 scsp_main_interrupt (0x10);
1758 }
1759
1760 ////////////////////////////////////////////////////////////////
1761 // Key ON/OFF event handler
1762
1763 static void
scsp_slot_keyon(slot_t * slot)1764 scsp_slot_keyon (slot_t *slot)
1765 {
1766 // key need to be released before being pressed ;)
1767 if (slot->ecurp == SCSP_ENV_RELEASE)
1768 {
1769 SCSPLOG ("key on slot %d. 68K PC = %08X slot->sa = %08X slot->lsa = %08X "
1770 "slot->lea = %08X\n", slot - &(scsp.slot[0]), M68K->GetPC(),
1771 slot->sa, slot->lsa, slot->lea >> SCSP_FREQ_LB);
1772
1773 // set buffer, loop start/end address of the slot
1774 if (slot->pcm8b)
1775 {
1776 slot->buf8 = (s8*) &(scsp.scsp_ram[slot->sa]);
1777 if ((slot->sa + (slot->lea >> SCSP_FREQ_LB)) > SCSP_RAM_MASK)
1778 slot->lea = (SCSP_RAM_MASK - slot->sa) << SCSP_FREQ_LB;
1779 }
1780 else
1781 {
1782 slot->buf16 = (s16*) &(scsp.scsp_ram[slot->sa & ~1]);
1783 if ((slot->sa + (slot->lea >> (SCSP_FREQ_LB - 1))) > SCSP_RAM_MASK)
1784 slot->lea = (SCSP_RAM_MASK - slot->sa) << (SCSP_FREQ_LB - 1);
1785 }
1786
1787 slot->fcnt = 0; // reset frequency counter
1788 slot->ecnt = SCSP_ENV_AS; // reset envelope counter (probably wrong,
1789 // should convert decay to attack?)
1790 slot->env = 0; // reset envelope
1791
1792 slot->einc = &slot->einca; // envelope counter step is attack step
1793 slot->ecurp = SCSP_ENV_ATTACK; // current envelope phase is attack
1794 slot->ecmp = SCSP_ENV_AE; // limit reach to next event (Attack End)
1795 slot->enxt = scsp_attack_next; // function pointer to next event
1796 }
1797 }
1798
1799 static void
scsp_slot_keyoff(slot_t * slot)1800 scsp_slot_keyoff (slot_t *slot)
1801 {
1802 // key need to be pressed before being released ;)
1803 if (slot->ecurp != SCSP_ENV_RELEASE)
1804 {
1805 SCSPLOG ("key off slot %d\n", slot - &(scsp.slot[0]));
1806
1807 // if we still are in attack phase at release time, convert attack to decay
1808 if (slot->ecurp == SCSP_ENV_ATTACK)
1809 slot->ecnt = SCSP_ENV_DE - slot->ecnt;
1810 slot->einc = &slot->eincr;
1811 slot->ecmp = SCSP_ENV_DE;
1812 slot->ecurp = SCSP_ENV_RELEASE;
1813 slot->enxt = scsp_release_next;
1814 }
1815 }
1816
1817 static void
scsp_slot_keyonoff(void)1818 scsp_slot_keyonoff (void)
1819 {
1820 slot_t *slot;
1821
1822 for(slot = &(scsp.slot[0]); slot < &(scsp.slot[32]); slot++)
1823 {
1824 if (slot->key)
1825 scsp_slot_keyon (slot);
1826 else
1827 scsp_slot_keyoff (slot);
1828 }
1829 }
1830
1831 /*
1832 Envelope Events Handler
1833
1834 Max EG level = 0x3FF /|\
1835 / | \
1836 / | \_____
1837 Min EG level = 0x000 __/ | | |\___
1838 A D1 D2 R
1839 */
1840
1841 static void
scsp_env_null_next(UNUSED slot_t * slot)1842 scsp_env_null_next (UNUSED slot_t *slot)
1843 {
1844 // only to prevent null call pointer...
1845 }
1846
1847 static void
scsp_release_next(slot_t * slot)1848 scsp_release_next (slot_t *slot)
1849 {
1850 // end of release happened, update to process the next phase...
1851
1852 slot->ecnt = SCSP_ENV_DE;
1853 slot->einc = NULL;
1854 slot->ecmp = SCSP_ENV_DE + 1;
1855 slot->enxt = scsp_env_null_next;
1856 }
1857
1858 static void
scsp_sustain_next(slot_t * slot)1859 scsp_sustain_next (slot_t *slot)
1860 {
1861 // end of sustain happened, update to process the next phase...
1862
1863 slot->ecnt = SCSP_ENV_DE;
1864 slot->einc = NULL;
1865 slot->ecmp = SCSP_ENV_DE + 1;
1866 slot->enxt = scsp_env_null_next;
1867 }
1868
1869 static void
scsp_decay_next(slot_t * slot)1870 scsp_decay_next (slot_t *slot)
1871 {
1872 // end of decay happened, update to process the next phase...
1873
1874 slot->ecnt = slot->sl;
1875 slot->einc = &slot->eincs;
1876 slot->ecmp = SCSP_ENV_DE;
1877 slot->ecurp = SCSP_ENV_SUSTAIN;
1878 slot->enxt = scsp_sustain_next;
1879 }
1880
1881 static void
scsp_attack_next(slot_t * slot)1882 scsp_attack_next (slot_t *slot)
1883 {
1884 // end of attack happened, update to process the next phase...
1885
1886 slot->ecnt = SCSP_ENV_DS;
1887 slot->einc = &slot->eincd;
1888 slot->ecmp = slot->sl;
1889 slot->ecurp = SCSP_ENV_DECAY;
1890 slot->enxt = scsp_decay_next;
1891 }
1892
1893 ////////////////////////////////////////////////////////////////
1894 // Slot Access
1895
1896 static void
scsp_slot_refresh_einc(slot_t * slot,u32 adsr_bitmask)1897 scsp_slot_refresh_einc (slot_t *slot, u32 adsr_bitmask)
1898 {
1899 if (slot->arp && (adsr_bitmask & 0x1))
1900 slot->einca = slot->arp[(14 - slot->fsft) >> slot->krs];
1901 if (slot->drp && (adsr_bitmask & 0x2))
1902 slot->eincd = slot->drp[(14 - slot->fsft) >> slot->krs];
1903 if (slot->srp && (adsr_bitmask & 0x4))
1904 slot->eincs = slot->srp[(14 - slot->fsft) >> slot->krs];
1905 if (slot->rrp && (adsr_bitmask & 0x8))
1906 slot->eincr = slot->rrp[(14 - slot->fsft) >> slot->krs];
1907 }
1908
1909 static void
scsp_slot_set_b(u32 s,u32 a,u8 d)1910 scsp_slot_set_b (u32 s, u32 a, u8 d)
1911 {
1912
1913 slot_t *slot = &(scsp.slot[s]);
1914
1915 SCSPLOG("slot %d : reg %.2X = %.2X\n", s, a & 0x1F, d);
1916
1917 scsp_isr[a ^ 3] = d;
1918
1919 switch (a & 0x1F)
1920 {
1921 case 0x00: // KX/KB/SBCTL/SSCTL(high bit)
1922 slot->key = (d >> 3) & 1;
1923 slot->sbctl = (d >> 1) & 3;
1924 slot->ssctl = (slot->ssctl & 1) + ((d & 1) << 1);
1925
1926 if (d & 0x10) scsp_slot_keyonoff ();
1927 return;
1928
1929 case 0x01: // SSCTL(low bit)/LPCTL/8B/SA(highest 4 bits)
1930 slot->ssctl = (slot->ssctl & 2) + ((d >> 7) & 1);
1931 slot->lpctl = (d >> 5) & 3;
1932
1933 slot->pcm8b = d & 0x10;
1934 slot->sa = (slot->sa & 0x0FFFF) + ((d & 0xF) << 16);
1935 slot->sa &= SCSP_RAM_MASK;
1936
1937 if (slot->ecnt < SCSP_ENV_DE) scsp_slot_update_keyon (slot);
1938
1939 return;
1940
1941 case 0x02: // SA(next highest byte)
1942 slot->sa = (slot->sa & 0xF00FF) + (d << 8);
1943 slot->sa &= SCSP_RAM_MASK;
1944
1945 if (slot->ecnt < SCSP_ENV_DE) scsp_slot_update_keyon (slot);
1946 return;
1947
1948 case 0x03: // SA(low byte)
1949 slot->sa = (slot->sa & 0xFFF00) + d;
1950 slot->sa &= SCSP_RAM_MASK;
1951
1952 if (slot->ecnt < SCSP_ENV_DE) scsp_slot_update_keyon (slot);
1953 return;
1954
1955 case 0x04: // LSA(high byte)
1956 slot->lsa = (slot->lsa & (0x00FF << SCSP_FREQ_LB)) +
1957 (d << (8 + SCSP_FREQ_LB));
1958 return;
1959
1960 case 0x05: // LSA(low byte)
1961 slot->lsa = (slot->lsa & (0xFF00 << SCSP_FREQ_LB)) +
1962 (d << SCSP_FREQ_LB);
1963 return;
1964
1965 case 0x06: // LEA(high byte)
1966 slot->lea = (slot->lea & (0x00FF << SCSP_FREQ_LB)) +
1967 (d << (8 + SCSP_FREQ_LB));
1968 return;
1969
1970 case 0x07: // LEA(low byte)
1971 slot->lea = (slot->lea & (0xFF00 << SCSP_FREQ_LB)) +
1972 (d << SCSP_FREQ_LB);
1973 return;
1974
1975 case 0x08: // D2R/D1R(highest 3 bits)
1976 slot->sr = (d >> 3) & 0x1F;
1977 slot->dr = (slot->dr & 0x03) + ((d & 7) << 2);
1978
1979 if (slot->sr)
1980 slot->srp = &scsp_decay_rate[slot->sr << 1];
1981 else
1982 slot->srp = &scsp_null_rate[0];
1983
1984 if (slot->dr)
1985 slot->drp = &scsp_decay_rate[slot->dr << 1];
1986 else
1987 slot->drp = &scsp_null_rate[0];
1988
1989 scsp_slot_refresh_einc (slot, 0x2 | 0x4);
1990 return;
1991
1992 case 0x09: // D1R(lowest 2 bits)/EGHOLD/AR
1993 slot->dr = (slot->dr & 0x1C) + ((d >> 6) & 3);
1994 slot->eghold = d & 0x20;
1995 slot->ar = d & 0x1F;
1996
1997 if (slot->dr)
1998 slot->drp = &scsp_decay_rate[slot->dr << 1];
1999 else
2000 slot->drp = &scsp_null_rate[0];
2001
2002 if (slot->ar)
2003 slot->arp = &scsp_attack_rate[slot->ar << 1];
2004 else
2005 slot->arp = &scsp_null_rate[0];
2006
2007 scsp_slot_refresh_einc (slot, 0x1 | 0x2);
2008 return;
2009
2010 case 0x0A: // LPSLNK/KRS/DL(highest 2 bits)
2011 slot->lslnk = d & 0x40;
2012 slot->krs = (d >> 2) & 0xF;
2013
2014 if (slot->krs == 0xF)
2015 slot->krs = 4;
2016 else
2017 slot->krs >>= 2;
2018
2019 slot->sl &= 0xE0 << SCSP_ENV_LB;
2020 slot->sl += (d & 3) << (8 + SCSP_ENV_LB);
2021 slot->sl += SCSP_ENV_DS; // adjusted for envelope compare (ecmp)
2022
2023 scsp_slot_refresh_einc (slot, 0xF);
2024 return;
2025
2026 case 0x0B: // DL(lowest 3 bits)/RR
2027 slot->sl &= 0x300 << SCSP_ENV_LB;
2028 slot->sl += (d & 0xE0) << SCSP_ENV_LB;
2029 slot->sl += SCSP_ENV_DS; // adjusted for envelope compare (ecmp)
2030 slot->rr = d & 0x1F;
2031
2032 if (slot->rr)
2033 slot->rrp = &scsp_decay_rate[slot->rr << 1];
2034 else
2035 slot->rrp = &scsp_null_rate[0];
2036
2037 scsp_slot_refresh_einc (slot, 0x8);
2038 return;
2039
2040 case 0x0C: // STWINH/SDIR
2041 slot->sdir = d & 2;
2042 slot->swe = d & 1;
2043 return;
2044
2045 case 0x0D: // TL
2046 slot->tl = scsp_tl_table[(d & 0xFF)];
2047 return;
2048
2049 case 0x0E: // MDL/MDXSL(highest 4 bits)
2050 slot->mdl = (d >> 4) & 0xF; // need to adjust for correct shift
2051 slot->mdx = (slot->mdx & 3) + ((d & 0xF) << 2);
2052 return;
2053
2054 case 0x0F: // MDXSL(lowest 2 bits)/MDYSL
2055 slot->mdx = (slot->mdx & 0x3C) + ((d >> 6) & 3);
2056 slot->mdy = d & 0x3F;
2057 return;
2058
2059 case 0x10: // OCT/FNS(highest 2 bits)
2060 if (d & 0x40)
2061 slot->fsft = 23 - ((d >> 3) & 0xF);
2062 else
2063 slot->fsft = ((d >> 3) & 7) ^ 7;
2064
2065 slot->finct = (slot->finct & 0x7F80) + ((d & 3) << (8 + 7));
2066 slot->finc = (0x20000 + slot->finct) >> slot->fsft;
2067
2068 scsp_slot_refresh_einc (slot, 0xF);
2069 return;
2070
2071 case 0x11: // FNS(low byte)
2072 slot->finct = (slot->finct & 0x18000) + (d << 7);
2073 slot->finc = (0x20000 + slot->finct) >> slot->fsft;
2074 return;
2075
2076 case 0x12: // LFORE/LFOF/PLFOWS
2077 if (d & 0x80)
2078 {
2079 slot->lfoinc = -1;
2080 return;
2081 }
2082 else if (slot->lfoinc == -1)
2083 {
2084 slot->lfocnt = 0;
2085 }
2086
2087 slot->lfoinc = scsp_lfo_step[(d >> 2) & 0x1F];
2088
2089 switch (d & 3)
2090 {
2091 case 0:
2092 slot->lfofmw = scsp_lfo_sawt_f;
2093 return;
2094
2095 case 1:
2096 slot->lfofmw = scsp_lfo_squa_f;
2097 return;
2098
2099 case 2:
2100 slot->lfofmw = scsp_lfo_tri_f;
2101 return;
2102
2103 case 3:
2104 slot->lfofmw = scsp_lfo_noi_f;
2105 return;
2106 }
2107
2108 case 0x13: // PLFOS/ALFOWS/ALFOS
2109 if ((d >> 5) & 7)
2110 slot->lfofms = ((d >> 5) & 7) + 7;
2111 else
2112 slot->lfofms = 31;
2113
2114 if (d & 7)
2115 slot->lfoems = ((d & 7) ^ 7) + 4;
2116 else
2117 slot->lfoems = 31;
2118
2119 switch ((d >> 3) & 3)
2120 {
2121 case 0:
2122 slot->lfoemw = scsp_lfo_sawt_e;
2123 return;
2124
2125 case 1:
2126 slot->lfoemw = scsp_lfo_squa_e;
2127 return;
2128
2129 case 2:
2130 slot->lfoemw = scsp_lfo_tri_e;
2131 return;
2132
2133 case 3:
2134 slot->lfoemw = scsp_lfo_noi_e;
2135 }
2136 return;
2137
2138 case 0x15: // ISEL/OMXL
2139 if (d & 7)
2140 slot->imxl = ((d & 7) ^ 7) + SCSP_ENV_HB;
2141 else
2142 slot->imxl = 31;
2143 return;
2144
2145 case 0x16: // DISDL/DIPAN
2146 if (d & 0xE0)
2147 {
2148 // adjusted for envelope calculation
2149 // some inaccuracy in panning though...
2150 slot->dislr = slot->disll = (((d >> 5) & 7) ^ 7) + SCSP_ENV_HB;
2151 if (d & 0x10)
2152 {
2153 // Panning Left
2154 if ((d & 0xF) == 0xF)
2155 slot->dislr = 31;
2156 else
2157 slot->dislr += (d >> 1) & 7;
2158 }
2159 else
2160 {
2161 // Panning Right
2162 if ((d & 0xF) == 0xF)
2163 slot->disll = 31;
2164 else
2165 slot->disll += (d >> 1) & 7;
2166 }
2167 }
2168 else
2169 {
2170 slot->dislr = slot->disll = 31; // muted
2171 }
2172 return;
2173
2174 case 0x17: // EFSDL/EFPAN
2175 if (d & 0xE0)
2176 {
2177 slot->efslr = slot->efsll = (((d >> 5) & 7) ^ 7) + SCSP_ENV_HB;
2178 if (d & 0x10)
2179 {
2180 // Panning Left
2181 if ((d & 0xF) == 0xF)
2182 slot->efslr = 31;
2183 else
2184 slot->efslr += (d >> 1) & 7;
2185 }
2186 else
2187 {
2188 // Panning Right
2189 if ((d & 0xF) == 0xF)
2190 slot->efsll = 31;
2191 else
2192 slot->efsll += (d >> 1) & 7;
2193 }
2194 }
2195 else
2196 {
2197 slot->efslr = slot->efsll = 31; // muted
2198 }
2199 return;
2200 }
2201 }
2202
2203 static void
scsp_slot_set_w(u32 s,s32 a,u16 d)2204 scsp_slot_set_w (u32 s, s32 a, u16 d)
2205 {
2206 slot_t *slot = &(scsp.slot[s]);
2207
2208 SCSPLOG ("slot %d : reg %.2X = %.4X\n", s, a & 0x1E, d);
2209
2210 *(u16 *)&scsp_isr[a ^ 2] = d;
2211
2212 switch (a & 0x1E)
2213 {
2214 case 0x00: // KYONEX/KYONB/SBCTL/SSCTL/LPCTL/PCM8B/SA(highest 4 bits)
2215 slot->key = (d >> 11) & 1;
2216 slot->sbctl = (d >> 9) & 3;
2217 slot->ssctl = (d >> 7) & 3;
2218 slot->lpctl = (d >> 5) & 3;
2219
2220 slot->pcm8b = d & 0x10;
2221 slot->sa = (slot->sa & 0x0FFFF) | ((d & 0xF) << 16);
2222 slot->sa &= SCSP_RAM_MASK;
2223
2224 if (slot->ecnt < SCSP_ENV_DE)
2225 scsp_slot_update_keyon(slot);
2226
2227 if (d & 0x1000)
2228 scsp_slot_keyonoff();
2229 return;
2230
2231 case 0x02: // SA(low word)
2232 slot->sa = (slot->sa & 0xF0000) | d;
2233 slot->sa &= SCSP_RAM_MASK;
2234
2235 if (slot->ecnt < SCSP_ENV_DE)
2236 scsp_slot_update_keyon(slot);
2237 return;
2238
2239 case 0x04: // LSA
2240 slot->lsa = d << SCSP_FREQ_LB;
2241 return;
2242
2243 case 0x06: // LEA
2244 slot->lea = d << SCSP_FREQ_LB;
2245 return;
2246
2247 case 0x08: // D2R/D1R/EGHOLD/AR
2248 slot->sr = (d >> 11) & 0x1F;
2249 slot->dr = (d >> 6) & 0x1F;
2250 slot->eghold = d & 0x20;
2251 slot->ar = d & 0x1F;
2252
2253 if (slot->sr)
2254 slot->srp = &scsp_decay_rate[slot->sr << 1];
2255 else
2256 slot->srp = &scsp_null_rate[0];
2257
2258 if (slot->dr)
2259 slot->drp = &scsp_decay_rate[slot->dr << 1];
2260 else
2261 slot->drp = &scsp_null_rate[0];
2262
2263 if (slot->ar)
2264 slot->arp = &scsp_attack_rate[slot->ar << 1];
2265 else
2266 slot->arp = &scsp_null_rate[0];
2267
2268 scsp_slot_refresh_einc (slot, 0x1 | 0x2 | 0x4);
2269 return;
2270
2271 case 0x0A: // LPSLNK/KRS/DL/RR
2272 slot->lslnk = (d >> 8) & 0x40;
2273 slot->krs = (d >> 10) & 0xF;
2274
2275 if (slot->krs == 0xF)
2276 slot->krs = 4;
2277 else
2278 slot->krs >>= 2;
2279
2280 slot->sl = ((d & 0x3E0) << SCSP_ENV_LB) + SCSP_ENV_DS; // adjusted for envelope compare (ecmp)
2281 slot->rr = d & 0x1F;
2282
2283 if (slot->rr)
2284 slot->rrp = &scsp_decay_rate[slot->rr << 1];
2285 else
2286 slot->rrp = &scsp_null_rate[0];
2287
2288 scsp_slot_refresh_einc (slot, 0xF);
2289 return;
2290
2291 case 0x0C: // STWINH/SDIR
2292 slot->sdir = (d >> 8) & 2;
2293 slot->swe = (d >> 8) & 1;
2294 slot->tl = scsp_tl_table[(d & 0xFF)];
2295 return;
2296
2297 case 0x0E: // MDL/MDXSL/MDYSL
2298 slot->mdl = (d >> 12) & 0xF; // need to adjust for correct shift
2299 slot->mdx = (d >> 6) & 0x3F;
2300 slot->mdy = d & 0x3F;
2301 return;
2302
2303 case 0x10: // OCT/FNS
2304 if (d & 0x4000)
2305 slot->fsft = 23 - ((d >> 11) & 0xF);
2306 else
2307 slot->fsft = (((d >> 11) & 7) ^ 7);
2308
2309 slot->finc = ((0x400 + (d & 0x3FF)) << 7) >> slot->fsft;
2310
2311 scsp_slot_refresh_einc (slot, 0xF);
2312 return;
2313
2314 case 0x12: // LFORE/LFOF/PLFOWS/PLFOS/ALFOWS/ALFOS
2315 if (d & 0x8000)
2316 {
2317 slot->lfoinc = -1;
2318 return;
2319 }
2320 else if (slot->lfoinc == -1)
2321 {
2322 slot->lfocnt = 0;
2323 }
2324
2325 slot->lfoinc = scsp_lfo_step[(d >> 10) & 0x1F];
2326 if ((d >> 5) & 7)
2327 slot->lfofms = ((d >> 5) & 7) + 7;
2328 else
2329 slot->lfofms = 31;
2330
2331 if (d & 7)
2332 slot->lfoems = ((d & 7) ^ 7) + 4;
2333 else
2334 slot->lfoems = 31;
2335
2336 switch ((d >> 8) & 3)
2337 {
2338 case 0:
2339 slot->lfofmw = scsp_lfo_sawt_f;
2340 break;
2341
2342 case 1:
2343 slot->lfofmw = scsp_lfo_squa_f;
2344 break;
2345
2346 case 2:
2347 slot->lfofmw = scsp_lfo_tri_f;
2348 break;
2349
2350 case 3:
2351 slot->lfofmw = scsp_lfo_noi_f;
2352 break;
2353 }
2354
2355 switch ((d >> 3) & 3)
2356 {
2357 case 0:
2358 slot->lfoemw = scsp_lfo_sawt_e;
2359 return;
2360
2361 case 1:
2362 slot->lfoemw = scsp_lfo_squa_e;
2363 return;
2364
2365 case 2:
2366 slot->lfoemw = scsp_lfo_tri_e;
2367 return;
2368
2369 case 3:
2370 slot->lfoemw = scsp_lfo_noi_e;
2371 }
2372 return;
2373
2374 case 0x14: // ISEL/OMXL
2375 if (d & 7)
2376 slot->imxl = ((d & 7) ^ 7) + SCSP_ENV_HB;
2377 else
2378 slot->imxl = 31;
2379 return;
2380
2381 case 0x16: // DISDL/DIPAN/EFSDL/EFPAN
2382 if (d & 0xE000)
2383 {
2384 // adjusted fr enveloppe calculation
2385 // some accuracy lose for panning here...
2386 slot->dislr = slot->disll = (((d >> 13) & 7) ^ 7) + SCSP_ENV_HB;
2387 if (d & 0x1000)
2388 {
2389 // Panning Left
2390 if ((d & 0xF00) == 0xF00)
2391 slot->dislr = 31;
2392 else
2393 slot->dislr += (d >> 9) & 7;
2394 }
2395 else
2396 {
2397 // Panning Right
2398 if ((d & 0xF00) == 0xF00)
2399 slot->disll = 31;
2400 else
2401 slot->disll += (d >> 9) & 7;
2402 }
2403 }
2404 else
2405 {
2406 slot->dislr = slot->disll = 31; // muted
2407 }
2408
2409 if (d & 0xE0)
2410 {
2411 slot->efslr = slot->efsll = (((d >> 5) & 7) ^ 7) + SCSP_ENV_HB;
2412 if (d & 0x10)
2413 {
2414 // Panning Left
2415 if ((d & 0xF) == 0xF)
2416 slot->efslr = 31;
2417 else
2418 slot->efslr += (d >> 1) & 7;
2419 }
2420 else
2421 {
2422 // Panning Right
2423 if ((d & 0xF) == 0xF)
2424 slot->efsll = 31;
2425 else
2426 slot->efsll += (d >> 1) & 7;
2427 }
2428 }
2429 else
2430 {
2431 slot->efslr = slot->efsll = 31; // muted
2432 }
2433 return;
2434 }
2435 }
2436
2437 static u8
scsp_slot_get_b(u32 s,u32 a)2438 scsp_slot_get_b (u32 s, u32 a)
2439 {
2440 u8 val = scsp_isr[a ^ 3];
2441
2442 // Mask out keyonx
2443 if ((a & 0x1F) == 0x00) val &= 0xEF;
2444
2445 SCSPLOG ("r_b slot %d (%.2X) : reg %.2X = %.2X\n", s, a, a & 0x1F, val);
2446
2447 return val;
2448 }
2449
scsp_slot_get_w(u32 s,u32 a)2450 static u16 scsp_slot_get_w(u32 s, u32 a)
2451 {
2452 u16 val = *(u16 *)&scsp_isr[a ^ 2];
2453
2454 if ((a & 0x1E) == 0x00) return val &= 0xEFFF;
2455
2456 SCSPLOG ("r_w slot %d (%.2X) : reg %.2X = %.4X\n", s, a, a & 0x1E, val);
2457
2458 return val;
2459 }
2460
2461 ////////////////////////////////////////////////////////////////
2462 // SCSP Access
2463
2464 static void
scsp_set_b(u32 a,u8 d)2465 scsp_set_b (u32 a, u8 d)
2466 {
2467 if ((a != 0x408) && (a != 0x41D))
2468 {
2469 SCSPLOG("scsp : reg %.2X = %.2X\n", a & 0x3F, d);
2470 }
2471
2472 scsp_ccr[a ^ 3] = d;
2473
2474 switch (a & 0x3F)
2475 {
2476 case 0x00: // MEM4MB/DAC18B
2477 scsp.mem4b = (d >> 1) & 0x1;
2478 if (scsp.mem4b)
2479 {
2480 M68K->SetFetch(0x000000, 0x080000, (pointer)SoundRam);
2481 }
2482 else
2483 {
2484 M68K->SetFetch(0x000000, 0x040000, (pointer)SoundRam);
2485 M68K->SetFetch(0x040000, 0x080000, (pointer)SoundRam);
2486 M68K->SetFetch(0x080000, 0x0C0000, (pointer)SoundRam);
2487 M68K->SetFetch(0x0C0000, 0x100000, (pointer)SoundRam);
2488 }
2489 return;
2490
2491 case 0x01: // VER/MVOL
2492 scsp.mvol = d & 0xF;
2493 return;
2494
2495 case 0x02: // RBL(high bit)
2496 scsp.rbl = (scsp.rbl & 1) + ((d & 1) << 1);
2497 return;
2498
2499 case 0x03: // RBL(low bit)/RBP
2500 scsp.rbl = (scsp.rbl & 2) + ((d >> 7) & 1);
2501 if (use_new_scsp)
2502 scsp.rbp = (d & 0x7F);
2503 else
2504 scsp.rbp = (d & 0x7F) * (4 * 1024 * 2);
2505 return;
2506
2507 case 0x07: // MOBUF
2508 scsp_midi_out_send(d);
2509 return;
2510
2511 case 0x08: // MSLC
2512 scsp.mslc = (d >> 3) & 0x1F;
2513 scsp_update_monitor ();
2514 return;
2515
2516 case 0x12: // DMEAL(high byte)
2517 scsp.dmea = (scsp.dmea & 0x700FE) + (d << 8);
2518 return;
2519
2520 case 0x13: // DMEAL(low byte)
2521 scsp.dmea = (scsp.dmea & 0x7FF00) + (d & 0xFE);
2522 return;
2523
2524 case 0x14: // DMEAH(high byte)
2525 scsp.dmea = (scsp.dmea & 0xFFFE) + ((d & 0x70) << 12);
2526 scsp.drga = (scsp.drga & 0xFE) + ((d & 0xF) << 8);
2527 return;
2528
2529 case 0x15: // DMEAH(low byte)
2530 scsp.drga = (scsp.drga & 0xF00) + (d & 0xFE);
2531 return;
2532
2533 case 0x16: // DGATE/DDIR/DEXE/DTLG(upper 4 bits)
2534 scsp.dmlen = (scsp.dmlen & 0xFE) + ((d & 0xF) << 8);
2535 if ((scsp.dmfl = d & 0xF0) & 0x10) scsp_dma ();
2536 return;
2537
2538 case 0x17: // DTLG(lower byte)
2539 scsp.dmlen = (scsp.dmlen & 0xF00) + (d & 0xFE);
2540 return;
2541
2542 case 0x18: // TACTL
2543 scsp.timasd = d & 7;
2544 return;
2545
2546 case 0x19: // TIMA
2547 scsp.timacnt = d << 8;
2548 return;
2549
2550 case 0x1A: // TBCTL
2551 scsp.timbsd = d & 7;
2552 return;
2553
2554 case 0x1B: // TIMB
2555 scsp.timbcnt = d << 8;
2556 return;
2557
2558 case 0x1C: // TCCTL
2559 scsp.timcsd = d & 7;
2560 return;
2561
2562 case 0x1D: // TIMC
2563 scsp.timccnt = d << 8;
2564 return;
2565
2566 case 0x1E: // SCIEB(high byte)
2567 {
2568 int i;
2569 scsp.scieb = (scsp.scieb & 0xFF) + (d << 8);
2570
2571 for (i = 0; i < 3; i++)
2572 {
2573 if (scsp.scieb & (1 << i) && scsp.scipd & (1 << i))
2574 scsp_trigger_sound_interrupt ((1 << (i+8)));
2575 }
2576
2577 return;
2578 }
2579 case 0x1F: // SCIEB(low byte)
2580 {
2581 int i;
2582 scsp.scieb = (scsp.scieb & 0x700) + d;
2583
2584 for (i = 0; i < 8; i++)
2585 {
2586 if (scsp.scieb & (1 << i) && scsp.scipd & (1 << i))
2587 scsp_trigger_sound_interrupt ((1 << i));
2588 }
2589 return;
2590 }
2591 case 0x21: // SCIPD(low byte)
2592 if (d & 0x20) scsp_sound_interrupt (0x20);
2593 return;
2594
2595 case 0x22: // SCIRE(high byte)
2596 scsp.scipd &= ~(d << 8);
2597 return;
2598
2599 case 0x23: // SCIRE(low byte)
2600 scsp.scipd &= ~(u32)d;
2601 return;
2602
2603 case 0x25: // SCILV0
2604 scsp.scilv0 = d;
2605 return;
2606
2607 case 0x27: // SCILV1
2608 scsp.scilv1 = d;
2609 return;
2610
2611 case 0x29: // SCILV2
2612 scsp.scilv2 = d;
2613 return;
2614
2615 case 0x2A: // MCIEB(high byte)
2616 scsp.mcieb = (scsp.mcieb & 0xFF) + (d << 8);
2617 return;
2618
2619 case 0x2B: // MCIEB(low byte)
2620 scsp.mcieb = (scsp.mcieb & 0x700) + d;
2621 return;
2622
2623 case 0x2D: // MCIPD(low byte)
2624 if (d & 0x20)
2625 scsp_main_interrupt(0x20);
2626 return;
2627
2628 case 0x2E: // MCIRE(high byte)
2629 scsp.mcipd &= ~(d << 8);
2630 return;
2631
2632 case 0x2F: // MCIRE(low byte)
2633 scsp.mcipd &= ~(u32)d;
2634 return;
2635 }
2636 }
2637
2638 static void
scsp_set_w(u32 a,u16 d)2639 scsp_set_w (u32 a, u16 d)
2640 {
2641 if ((a != 0x418) && (a != 0x41A) && (a != 0x422))
2642 {
2643 SCSPLOG("scsp : reg %.2X = %.4X\n", a & 0x3E, d);
2644 }
2645
2646 *(u16 *)&scsp_ccr[a ^ 2] = d;
2647
2648 switch (a & 0x3E)
2649 {
2650 case 0x00: // MEM4MB/DAC18B/VER/MVOL
2651 scsp.mem4b = (d >> 9) & 0x1;
2652 scsp.mvol = d & 0xF;
2653 if (scsp.mem4b)
2654 {
2655 M68K->SetFetch(0x000000, 0x080000, (pointer)SoundRam);
2656 }
2657 else
2658 {
2659 M68K->SetFetch(0x000000, 0x040000, (pointer)SoundRam);
2660 M68K->SetFetch(0x040000, 0x080000, (pointer)SoundRam);
2661 M68K->SetFetch(0x080000, 0x0C0000, (pointer)SoundRam);
2662 M68K->SetFetch(0x0C0000, 0x100000, (pointer)SoundRam);
2663 }
2664 return;
2665
2666 case 0x02: // RBL/RBP
2667 scsp.rbl = (d >> 7) & 3;
2668
2669 if (use_new_scsp)
2670 scsp.rbp = (d & 0x7F);
2671 else
2672 scsp.rbp = (d & 0x7F) * (4 * 1024 * 2);
2673
2674 return;
2675
2676 case 0x06: // MOBUF
2677 scsp_midi_out_send(d & 0xFF);
2678 return;
2679
2680 case 0x08: // MSLC
2681 scsp.mslc = (d >> 11) & 0x1F;
2682 scsp_update_monitor();
2683 return;
2684
2685 case 0x12: // DMEAL
2686 scsp.dmea = (scsp.dmea & 0x70000) + (d & 0xFFFE);
2687 return;
2688
2689 case 0x14: // DMEAH/DRGA
2690 scsp.dmea = (scsp.dmea & 0xFFFE) + ((d & 0x7000) << 4);
2691 scsp.drga = d & 0xFFE;
2692 return;
2693
2694 case 0x16: // DGATE/DDIR/DEXE/DTLG
2695 scsp.dmlen = d & 0xFFE;
2696 if ((scsp.dmfl = ((d >> 8) & 0xF0)) & 0x10) scsp_dma ();
2697 return;
2698
2699 case 0x18: // TACTL/TIMA
2700 scsp.timasd = (d >> 8) & 7;
2701 scsp.timacnt = (d & 0xFF) << 8;
2702 return;
2703
2704 case 0x1A: // TBCTL/TIMB
2705 scsp.timbsd = (d >> 8) & 7;
2706 scsp.timbcnt = (d & 0xFF) << 8;
2707 return;
2708
2709 case 0x1C: // TCCTL/TIMC
2710 scsp.timcsd = (d >> 8) & 7;
2711 scsp.timccnt = (d & 0xFF) << 8;
2712 return;
2713
2714 case 0x1E: // SCIEB
2715 {
2716 int i;
2717 scsp.scieb = d;
2718 for (i = 0; i < 11; i++)
2719 {
2720 if (scsp.scieb & (1 << i) && scsp.scipd & (1 << i))
2721 scsp_trigger_sound_interrupt ((1 << i));
2722 }
2723 return;
2724 }
2725 case 0x20: // SCIPD
2726 if (d & 0x20) scsp_sound_interrupt (0x20);
2727 return;
2728
2729 case 0x22: // SCIRE
2730 scsp.scipd &= ~d;
2731 return;
2732
2733 case 0x24: // SCILV0
2734 scsp.scilv0 = d;
2735 return;
2736
2737 case 0x26: // SCILV1
2738 scsp.scilv1 = d;
2739 return;
2740
2741 case 0x28: // SCILV2
2742 scsp.scilv2 = d;
2743 return;
2744
2745 case 0x2A: // MCIEB
2746 {
2747 int i;
2748 scsp.mcieb = d;
2749 for (i = 0; i < 11; i++)
2750 {
2751 if (scsp.mcieb & (1 << i) && scsp.mcipd & (1 << i))
2752 scsp_trigger_main_interrupt ((1 << i));
2753 }
2754 return;
2755 }
2756
2757 case 0x2C: // MCIPD
2758 if (d & 0x20) scsp_main_interrupt (0x20);
2759 return;
2760
2761 case 0x2E: // MCIRE
2762 scsp.mcipd &= ~d;
2763 return;
2764 }
2765 }
2766
2767 static u8
scsp_get_b(u32 a)2768 scsp_get_b (u32 a)
2769 {
2770 a &= 0x3F;
2771
2772 if ((a != 0x09) && (a != 0x21))
2773 {
2774 SCSPLOG("r_b scsp : reg %.2X\n", a);
2775 }
2776 // if (a == 0x09) SCSPLOG("r_b scsp 09 = %.2X\n", ((scsp.slot[scsp.mslc].fcnt >> (SCSP_FREQ_LB + 12)) & 0x1) << 7);
2777
2778 switch (a)
2779 {
2780 case 0x01: // VER/MVOL
2781 scsp_ccr[a ^ 3] &= 0x0F;
2782 break;
2783
2784 case 0x04: // Midi flags register
2785 return scsp.midflag;
2786
2787 case 0x05: // MIBUF
2788 return scsp_midi_in_read();
2789
2790 case 0x07: // MOBUF
2791 return scsp_midi_out_read();
2792
2793 case 0x08: // CA(highest 3 bits)
2794 return (scsp.ca >> 8);
2795
2796 case 0x09: // CA(lowest bit)/SGC/EG
2797 return (scsp.ca & 0xE0) | (scsp.sgc << 5) | scsp.eg;
2798
2799 case 0x1E: // SCIEB(high byte)
2800 return (scsp.scieb >> 8);
2801
2802 case 0x1F: // SCIEB(low byte)
2803 return scsp.scieb;
2804
2805 case 0x20: // SCIPD(high byte)
2806 return (scsp.scipd >> 8);
2807
2808 case 0x21: // SCIPD(low byte)
2809 return scsp.scipd;
2810
2811 case 0x2C: // MCIPD(high byte)
2812 return (scsp.mcipd >> 8);
2813
2814 case 0x2D: // MCIPD(low byte)
2815 return scsp.mcipd;
2816 }
2817
2818 return scsp_ccr[a ^ 3];
2819 }
2820
2821 static u16
scsp_get_w(u32 a)2822 scsp_get_w (u32 a)
2823 {
2824 a &= 0x3E;
2825
2826 if ((a != 0x20) && (a != 0x08))
2827 {
2828 SCSPLOG("r_w scsp : reg %.2X\n", a * 2);
2829 }
2830
2831 switch (a)
2832 {
2833 case 0x00: // MEM4MB/DAC18B/VER/MVOL
2834 *(u16 *)&scsp_ccr[a ^ 2] &= 0xFF0F;
2835 break;
2836
2837 case 0x04: // Midi flags/MIBUF
2838 {
2839 u16 d = (scsp.midflag << 8); // this needs to be done to keep midfi status before midi in read
2840 d |= scsp_midi_in_read();
2841 return d;
2842 }
2843
2844 case 0x06: // MOBUF
2845 return scsp_midi_out_read();
2846
2847 case 0x08: // CA/SGC/EG
2848 return (scsp.ca & 0x780) | (scsp.sgc << 5) | scsp.eg;
2849
2850 case 0x18: // TACTL
2851 return (scsp.timasd << 8);
2852
2853 case 0x1A: // TBCTL
2854 return (scsp.timbsd << 8);
2855
2856 case 0x1C: // TCCTL
2857 return (scsp.timcsd << 8);
2858
2859 case 0x1E: // SCIEB
2860 return scsp.scieb;
2861
2862 case 0x20: // SCIPD
2863 return scsp.scipd;
2864
2865 case 0x2C: // MCIPD
2866 return scsp.mcipd;
2867 }
2868
2869 return *(u16 *)&scsp_ccr[a ^ 2];
2870 }
2871
2872 ////////////////////////////////////////////////////////////////
2873 // Synth Slot
2874 //
2875 // SCSPLOG("outL=%.8X bufL=%.8X disll=%d\n", outL, scsp_bufL[scsp_buf_pos], slot->disll);
2876
2877 ////////////////////////////////////////////////////////////////
2878
2879 #ifdef WORDS_BIGENDIAN
2880 #define SCSP_GET_OUT_8B \
2881 out = (s32) slot->buf8[(slot->fcnt >> SCSP_FREQ_LB)];
2882 #else
2883 #define SCSP_GET_OUT_8B \
2884 out = (s32) slot->buf8[(slot->fcnt >> SCSP_FREQ_LB) ^ 1];
2885 #endif
2886
2887 #define SCSP_GET_OUT_16B \
2888 out = (s32) slot->buf16[slot->fcnt >> SCSP_FREQ_LB];
2889
2890 #define SCSP_GET_ENV \
2891 slot->env = scsp_env_table[slot->ecnt >> SCSP_ENV_LB] * slot->tl / 1024;
2892
2893 #define SCSP_GET_ENV_LFO \
2894 slot->env = (scsp_env_table[slot->ecnt >> SCSP_ENV_LB] * slot->tl / 1024) - \
2895 (slot->lfoemw[(slot->lfocnt >> SCSP_LFO_LB) & SCSP_LFO_MASK] >> \
2896 slot->lfoems);
2897
2898 #define SCSP_OUT_8B_L \
2899 if ((out) && (slot->env > 0)) \
2900 { \
2901 out *= slot->env; \
2902 scsp_bufL[scsp_buf_pos] += out >> (slot->disll - 8); \
2903 }
2904
2905 #define SCSP_OUT_8B_R \
2906 if ((out) && (slot->env > 0)) \
2907 { \
2908 out *= slot->env; \
2909 scsp_bufR[scsp_buf_pos] += out >> (slot->dislr - 8); \
2910 }
2911
2912 #define SCSP_OUT_8B_LR \
2913 if ((out) && (slot->env > 0)) \
2914 { \
2915 out *= slot->env; \
2916 scsp_bufL[scsp_buf_pos] += out >> (slot->disll - 8); \
2917 scsp_bufR[scsp_buf_pos] += out >> (slot->dislr - 8); \
2918 }
2919
2920 #define SCSP_OUT_16B_L \
2921 if ((out) && (slot->env > 0)) \
2922 { \
2923 out *= slot->env; \
2924 scsp_bufL[scsp_buf_pos] += out >> slot->disll; \
2925 }
2926
2927 #define SCSP_OUT_16B_R \
2928 if ((out) && (slot->env > 0)) \
2929 { \
2930 out *= slot->env; \
2931 scsp_bufR[scsp_buf_pos] += out >> slot->dislr; \
2932 }
2933
2934 #define SCSP_OUT_16B_LR \
2935 if ((out) && (slot->env > 0)) \
2936 { \
2937 out *= slot->env; \
2938 scsp_bufL[scsp_buf_pos] += out >> slot->disll; \
2939 scsp_bufR[scsp_buf_pos] += out >> slot->dislr; \
2940 }
2941
2942 #define SCSP_UPDATE_PHASE \
2943 if ((slot->fcnt += slot->finc) > slot->lea) \
2944 { \
2945 if (slot->lpctl) \
2946 { \
2947 slot->fcnt = slot->lsa; \
2948 } \
2949 else \
2950 { \
2951 slot->ecnt = SCSP_ENV_DE; \
2952 return; \
2953 } \
2954 }
2955
2956 #define SCSP_UPDATE_PHASE_LFO \
2957 slot->fcnt += \
2958 ((slot->lfofmw[(slot->lfocnt >> SCSP_LFO_LB) & SCSP_LFO_MASK] << \
2959 (slot->lfofms-7)) >> (slot->fsft+1)); \
2960 if ((slot->fcnt += slot->finc) > slot->lea) \
2961 { \
2962 if (slot->lpctl) \
2963 { \
2964 slot->fcnt = slot->lsa; \
2965 } \
2966 else \
2967 { \
2968 slot->ecnt = SCSP_ENV_DE; \
2969 return; \
2970 } \
2971 }
2972
2973 #define SCSP_UPDATE_ENV \
2974 if (slot->einc) slot->ecnt += *slot->einc; \
2975 if (slot->ecnt >= slot->ecmp) \
2976 { \
2977 slot->enxt(slot); \
2978 if (slot->ecnt >= SCSP_ENV_DE) return; \
2979 }
2980
2981 #define SCSP_UPDATE_LFO \
2982 slot->lfocnt += slot->lfoinc;
2983
2984 ////////////////////////////////////////////////////////////////
2985
2986 static void
scsp_slot_update_keyon(slot_t * slot)2987 scsp_slot_update_keyon (slot_t *slot)
2988 {
2989 // set buffer, loop start/end address of the slot
2990 if (slot->pcm8b)
2991 {
2992 slot->buf8 = (s8*)&(scsp.scsp_ram[slot->sa]);
2993
2994 if ((slot->sa + (slot->lea >> SCSP_FREQ_LB)) > SCSP_RAM_MASK)
2995 slot->lea = (SCSP_RAM_MASK - slot->sa) << SCSP_FREQ_LB;
2996 }
2997 else
2998 {
2999 slot->buf16 = (s16*)&(scsp.scsp_ram[slot->sa & ~1]);
3000
3001 if ((slot->sa + (slot->lea >> (SCSP_FREQ_LB - 1))) > SCSP_RAM_MASK)
3002 slot->lea = (SCSP_RAM_MASK - slot->sa) << (SCSP_FREQ_LB - 1);
3003 }
3004
3005 SCSP_UPDATE_PHASE
3006 }
3007
3008 ////////////////////////////////////////////////////////////////
3009
3010 static void
scsp_slot_update_null(slot_t * slot)3011 scsp_slot_update_null (slot_t *slot)
3012 {
3013 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3014 {
3015 SCSP_GET_ENV
3016
3017 SCSP_UPDATE_PHASE
3018 SCSP_UPDATE_ENV
3019 }
3020 }
3021
3022 ////////////////////////////////////////////////////////////////
3023 // Normal 8 bits
3024
3025 static void
scsp_slot_update_8B_L(slot_t * slot)3026 scsp_slot_update_8B_L (slot_t *slot)
3027 {
3028 s32 out;
3029
3030 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3031 {
3032 // env = [0..0x3FF] - slot->tl
3033 SCSP_GET_OUT_8B
3034 SCSP_GET_ENV
3035
3036 // don't waste time if no sound...
3037 SCSP_OUT_8B_L
3038
3039 // calculate new frequency (phase) counter and enveloppe counter
3040 SCSP_UPDATE_PHASE
3041 SCSP_UPDATE_ENV
3042 }
3043 }
3044
3045 static void
scsp_slot_update_8B_R(slot_t * slot)3046 scsp_slot_update_8B_R (slot_t *slot)
3047 {
3048 s32 out;
3049
3050 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3051 {
3052 SCSP_GET_OUT_8B
3053 SCSP_GET_ENV
3054
3055 SCSP_OUT_8B_R
3056
3057 SCSP_UPDATE_PHASE
3058 SCSP_UPDATE_ENV
3059 }
3060 }
3061
3062 static void
scsp_slot_update_8B_LR(slot_t * slot)3063 scsp_slot_update_8B_LR(slot_t *slot)
3064 {
3065 s32 out;
3066
3067 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3068 {
3069 SCSP_GET_OUT_8B
3070 SCSP_GET_ENV
3071
3072 SCSP_OUT_8B_LR
3073
3074 SCSP_UPDATE_PHASE
3075 SCSP_UPDATE_ENV
3076 }
3077 }
3078
3079 ////////////////////////////////////////////////////////////////
3080 // Envelope LFO modulation 8 bits
3081
3082 static void
scsp_slot_update_E_8B_L(slot_t * slot)3083 scsp_slot_update_E_8B_L (slot_t *slot)
3084 {
3085 s32 out;
3086
3087 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3088 {
3089 SCSP_GET_OUT_8B
3090 SCSP_GET_ENV_LFO
3091
3092 SCSP_OUT_8B_L
3093
3094 SCSP_UPDATE_PHASE
3095 SCSP_UPDATE_ENV
3096 SCSP_UPDATE_LFO
3097 }
3098 }
3099
3100 static void
scsp_slot_update_E_8B_R(slot_t * slot)3101 scsp_slot_update_E_8B_R (slot_t *slot)
3102 {
3103 s32 out;
3104
3105 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3106 {
3107 SCSP_GET_OUT_8B
3108 SCSP_GET_ENV_LFO
3109
3110 SCSP_OUT_8B_R
3111
3112 SCSP_UPDATE_PHASE
3113 SCSP_UPDATE_ENV
3114 SCSP_UPDATE_LFO
3115 }
3116 }
3117
3118 static void
scsp_slot_update_E_8B_LR(slot_t * slot)3119 scsp_slot_update_E_8B_LR (slot_t *slot)
3120 {
3121 s32 out;
3122
3123 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3124 {
3125 SCSP_GET_OUT_8B
3126 SCSP_GET_ENV_LFO
3127
3128 SCSP_OUT_8B_LR
3129
3130 SCSP_UPDATE_PHASE
3131 SCSP_UPDATE_ENV
3132 SCSP_UPDATE_LFO
3133 }
3134 }
3135
3136 ////////////////////////////////////////////////////////////////
3137 // Frequency LFO modulation 8 bits
3138
3139 static void
scsp_slot_update_F_8B_L(slot_t * slot)3140 scsp_slot_update_F_8B_L (slot_t *slot)
3141 {
3142 s32 out;
3143
3144 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3145 {
3146 SCSP_GET_OUT_8B
3147 SCSP_GET_ENV
3148
3149 SCSP_OUT_8B_L
3150
3151 SCSP_UPDATE_PHASE_LFO
3152 SCSP_UPDATE_ENV
3153 SCSP_UPDATE_LFO
3154 }
3155 }
3156
3157 static void
scsp_slot_update_F_8B_R(slot_t * slot)3158 scsp_slot_update_F_8B_R (slot_t *slot)
3159 {
3160 s32 out;
3161
3162 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3163 {
3164 SCSP_GET_OUT_8B
3165 SCSP_GET_ENV
3166
3167 SCSP_OUT_8B_R
3168
3169 SCSP_UPDATE_PHASE_LFO
3170 SCSP_UPDATE_ENV
3171 SCSP_UPDATE_LFO
3172 }
3173 }
3174
3175 static void
scsp_slot_update_F_8B_LR(slot_t * slot)3176 scsp_slot_update_F_8B_LR (slot_t *slot)
3177 {
3178 s32 out;
3179
3180 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3181 {
3182 SCSP_GET_OUT_8B
3183 SCSP_GET_ENV
3184
3185 SCSP_OUT_8B_LR
3186
3187 SCSP_UPDATE_PHASE_LFO
3188 SCSP_UPDATE_ENV
3189 SCSP_UPDATE_LFO
3190 }
3191 }
3192
3193 ////////////////////////////////////////////////////////////////
3194 // Enveloppe & Frequency LFO modulation 8 bits
3195
3196 static void
scsp_slot_update_F_E_8B_L(slot_t * slot)3197 scsp_slot_update_F_E_8B_L (slot_t *slot)
3198 {
3199 s32 out;
3200
3201 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3202 {
3203 SCSP_GET_OUT_8B
3204 SCSP_GET_ENV_LFO
3205
3206 SCSP_OUT_8B_L
3207
3208 SCSP_UPDATE_PHASE_LFO
3209 SCSP_UPDATE_ENV
3210 SCSP_UPDATE_LFO
3211 }
3212 }
3213
3214 static void
scsp_slot_update_F_E_8B_R(slot_t * slot)3215 scsp_slot_update_F_E_8B_R (slot_t *slot)
3216 {
3217 s32 out;
3218
3219 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3220 {
3221 SCSP_GET_OUT_8B
3222 SCSP_GET_ENV_LFO
3223
3224 SCSP_OUT_8B_R
3225
3226 SCSP_UPDATE_PHASE_LFO
3227 SCSP_UPDATE_ENV
3228 SCSP_UPDATE_LFO
3229 }
3230 }
3231
scsp_slot_update_F_E_8B_LR(slot_t * slot)3232 static void scsp_slot_update_F_E_8B_LR(slot_t *slot)
3233 {
3234 s32 out;
3235
3236 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3237 {
3238 SCSP_GET_OUT_8B
3239 SCSP_GET_ENV_LFO
3240
3241 SCSP_OUT_8B_LR
3242
3243 SCSP_UPDATE_PHASE_LFO
3244 SCSP_UPDATE_ENV
3245 SCSP_UPDATE_LFO
3246 }
3247 }
3248
3249 ////////////////////////////////////////////////////////////////
3250 // Normal 16 bits
3251
3252 static void
scsp_slot_update_16B_L(slot_t * slot)3253 scsp_slot_update_16B_L (slot_t *slot)
3254 {
3255 s32 out;
3256
3257 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3258 {
3259 SCSP_GET_OUT_16B
3260 SCSP_GET_ENV
3261
3262 SCSP_OUT_16B_L
3263
3264 SCSP_UPDATE_PHASE
3265 SCSP_UPDATE_ENV
3266 }
3267 }
3268
3269 static void
scsp_slot_update_16B_R(slot_t * slot)3270 scsp_slot_update_16B_R (slot_t *slot)
3271 {
3272 s32 out;
3273
3274 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3275 {
3276 SCSP_GET_OUT_16B
3277 SCSP_GET_ENV
3278
3279 SCSP_OUT_16B_R
3280
3281 SCSP_UPDATE_PHASE
3282 SCSP_UPDATE_ENV
3283 }
3284 }
3285
3286 static void
scsp_slot_update_16B_LR(slot_t * slot)3287 scsp_slot_update_16B_LR (slot_t *slot)
3288 {
3289 s32 out;
3290
3291 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3292 {
3293 SCSP_GET_OUT_16B
3294 SCSP_GET_ENV
3295
3296 SCSP_OUT_16B_LR
3297
3298 SCSP_UPDATE_PHASE
3299 SCSP_UPDATE_ENV
3300 }
3301 }
3302
3303 ////////////////////////////////////////////////////////////////
3304 // Envelope LFO modulation 16 bits
3305
3306 static void
scsp_slot_update_E_16B_L(slot_t * slot)3307 scsp_slot_update_E_16B_L (slot_t *slot)
3308 {
3309 s32 out;
3310
3311 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3312 {
3313 SCSP_GET_OUT_16B
3314 SCSP_GET_ENV_LFO
3315
3316 SCSP_OUT_16B_L
3317
3318 SCSP_UPDATE_PHASE
3319 SCSP_UPDATE_ENV
3320 SCSP_UPDATE_LFO
3321 }
3322 }
3323
3324 static void
scsp_slot_update_E_16B_R(slot_t * slot)3325 scsp_slot_update_E_16B_R (slot_t *slot)
3326 {
3327 s32 out;
3328
3329 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3330 {
3331 SCSP_GET_OUT_16B
3332 SCSP_GET_ENV_LFO
3333
3334 SCSP_OUT_16B_R
3335
3336 SCSP_UPDATE_PHASE
3337 SCSP_UPDATE_ENV
3338 SCSP_UPDATE_LFO
3339 }
3340 }
3341
3342 static void
scsp_slot_update_E_16B_LR(slot_t * slot)3343 scsp_slot_update_E_16B_LR (slot_t *slot)
3344 {
3345 s32 out;
3346
3347 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3348 {
3349 SCSP_GET_OUT_16B
3350 SCSP_GET_ENV_LFO
3351
3352 SCSP_OUT_16B_LR
3353
3354 SCSP_UPDATE_PHASE
3355 SCSP_UPDATE_ENV
3356 SCSP_UPDATE_LFO
3357 }
3358 }
3359
3360 ////////////////////////////////////////////////////////////////
3361 // Frequency LFO modulation 16 bits
3362
3363 static void
scsp_slot_update_F_16B_L(slot_t * slot)3364 scsp_slot_update_F_16B_L (slot_t *slot)
3365 {
3366 s32 out;
3367
3368 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3369 {
3370 SCSP_GET_OUT_16B
3371 SCSP_GET_ENV
3372
3373 SCSP_OUT_16B_L
3374
3375 SCSP_UPDATE_PHASE_LFO
3376 SCSP_UPDATE_ENV
3377 SCSP_UPDATE_LFO
3378 }
3379 }
3380
3381 static void
scsp_slot_update_F_16B_R(slot_t * slot)3382 scsp_slot_update_F_16B_R (slot_t *slot)
3383 {
3384 s32 out;
3385
3386 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3387 {
3388 SCSP_GET_OUT_16B
3389 SCSP_GET_ENV
3390
3391 SCSP_OUT_16B_R
3392
3393 SCSP_UPDATE_PHASE_LFO
3394 SCSP_UPDATE_ENV
3395 SCSP_UPDATE_LFO
3396 }
3397 }
3398
3399 static void
scsp_slot_update_F_16B_LR(slot_t * slot)3400 scsp_slot_update_F_16B_LR (slot_t *slot)
3401 {
3402 s32 out;
3403
3404 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3405 {
3406 SCSP_GET_OUT_16B
3407 SCSP_GET_ENV
3408
3409 SCSP_OUT_16B_LR
3410
3411 SCSP_UPDATE_PHASE_LFO
3412 SCSP_UPDATE_ENV
3413 SCSP_UPDATE_LFO
3414 }
3415 }
3416
3417 ////////////////////////////////////////////////////////////////
3418 // Envelope & Frequency LFO modulation 16 bits
3419
3420 static void
scsp_slot_update_F_E_16B_L(slot_t * slot)3421 scsp_slot_update_F_E_16B_L (slot_t *slot)
3422 {
3423 s32 out;
3424
3425 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3426 {
3427 SCSP_GET_OUT_16B
3428 SCSP_GET_ENV_LFO
3429
3430 SCSP_OUT_16B_L
3431
3432 SCSP_UPDATE_PHASE_LFO
3433 SCSP_UPDATE_ENV
3434 SCSP_UPDATE_LFO
3435 }
3436 }
3437
3438 static void
scsp_slot_update_F_E_16B_R(slot_t * slot)3439 scsp_slot_update_F_E_16B_R (slot_t *slot)
3440 {
3441 s32 out;
3442
3443 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3444 {
3445 SCSP_GET_OUT_16B
3446 SCSP_GET_ENV_LFO
3447
3448 SCSP_OUT_16B_R
3449
3450 SCSP_UPDATE_PHASE_LFO
3451 SCSP_UPDATE_ENV
3452 SCSP_UPDATE_LFO
3453 }
3454 }
3455
3456 static void
scsp_slot_update_F_E_16B_LR(slot_t * slot)3457 scsp_slot_update_F_E_16B_LR (slot_t *slot)
3458 {
3459 s32 out;
3460
3461 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3462 {
3463 SCSP_GET_OUT_16B
3464 SCSP_GET_ENV_LFO
3465
3466 SCSP_OUT_16B_LR
3467
3468 SCSP_UPDATE_PHASE_LFO
3469 SCSP_UPDATE_ENV
3470 SCSP_UPDATE_LFO
3471 }
3472 }
3473
3474 ////////////////////////////////////////////////////////////////
3475 // Update functions
3476
3477 static void (*scsp_slot_update_p[2][2][2][2][2])(slot_t *slot) =
3478 {
3479 // NO FMS
3480 { // NO EMS
3481 { // 8 BITS
3482 { // NO LEFT
3483 { // NO RIGHT
3484 scsp_slot_update_null,
3485 // RIGHT
3486 scsp_slot_update_8B_R
3487 },
3488 // LEFT
3489 { // NO RIGHT
3490 scsp_slot_update_8B_L,
3491 // RIGHT
3492 scsp_slot_update_8B_LR
3493 },
3494 },
3495 // 16 BITS
3496 { // NO LEFT
3497 { // NO RIGHT
3498 scsp_slot_update_null,
3499 // RIGHT
3500 scsp_slot_update_16B_R
3501 },
3502 // LEFT
3503 { // NO RIGHT
3504 scsp_slot_update_16B_L,
3505 // RIGHT
3506 scsp_slot_update_16B_LR
3507 },
3508 }
3509 },
3510 // EMS
3511 { // 8 BITS
3512 { // NO LEFT
3513 { // NO RIGHT
3514 scsp_slot_update_null,
3515 // RIGHT
3516 scsp_slot_update_E_8B_R
3517 },
3518 // LEFT
3519 { // NO RIGHT
3520 scsp_slot_update_E_8B_L,
3521 // RIGHT
3522 scsp_slot_update_E_8B_LR
3523 },
3524 },
3525 // 16 BITS
3526 { // NO LEFT
3527 { // NO RIGHT
3528 scsp_slot_update_null,
3529 // RIGHT
3530 scsp_slot_update_E_16B_R
3531 },
3532 // LEFT
3533 { // NO RIGHT
3534 scsp_slot_update_E_16B_L,
3535 // RIGHT
3536 scsp_slot_update_E_16B_LR
3537 },
3538 }
3539 }
3540 },
3541 // FMS
3542 { // NO EMS
3543 { // 8 BITS
3544 { // NO LEFT
3545 { // NO RIGHT
3546 scsp_slot_update_null,
3547 // RIGHT
3548 scsp_slot_update_F_8B_R
3549 },
3550 // LEFT
3551 { // NO RIGHT
3552 scsp_slot_update_F_8B_L,
3553 // RIGHT
3554 scsp_slot_update_F_8B_LR
3555 },
3556 },
3557 // 16 BITS
3558 { // NO LEFT
3559 { // NO RIGHT
3560 scsp_slot_update_null,
3561 // RIGHT
3562 scsp_slot_update_F_16B_R
3563 },
3564 // LEFT
3565 { // NO RIGHT
3566 scsp_slot_update_F_16B_L,
3567 // RIGHT
3568 scsp_slot_update_F_16B_LR
3569 },
3570 }
3571 },
3572 // EMS
3573 { // 8 BITS
3574 { // NO LEFT
3575 { // NO RIGHT
3576 scsp_slot_update_null,
3577 // RIGHT
3578 scsp_slot_update_F_E_8B_R
3579 },
3580 // LEFT
3581 { // NO RIGHT
3582 scsp_slot_update_F_E_8B_L,
3583 // RIGHT
3584 scsp_slot_update_F_E_8B_LR
3585 },
3586 },
3587 // 16 BITS
3588 { // NO LEFT
3589 { // NO RIGHT
3590 scsp_slot_update_null,
3591 // RIGHT
3592 scsp_slot_update_F_E_16B_R
3593 },
3594 // LEFT
3595 { // NO RIGHT
3596 scsp_slot_update_F_E_16B_L,
3597 // RIGHT
3598 scsp_slot_update_F_E_16B_LR
3599 },
3600 }
3601 }
3602 }
3603 };
3604
3605 void
scsp_update(s32 * bufL,s32 * bufR,u32 len)3606 scsp_update (s32 *bufL, s32 *bufR, u32 len)
3607 {
3608 slot_t *slot;
3609
3610 scsp_bufL = bufL;
3611 scsp_bufR = bufR;
3612
3613 for (slot = &(scsp.slot[0]); slot < &(scsp.slot[32]); slot++)
3614 {
3615 if (slot->ecnt >= SCSP_ENV_DE) continue; // enveloppe null...
3616
3617 if (slot->ssctl)
3618 {
3619 // Still not correct, but at least this fixes games
3620 // that rely on Call Address information
3621 scsp_buf_len = len;
3622 scsp_buf_pos = 0;
3623
3624 for (; scsp_buf_pos < scsp_buf_len; scsp_buf_pos++)
3625 {
3626 if ((slot->fcnt += slot->finc) > slot->lea)
3627 {
3628 if (slot->lpctl) slot->fcnt = slot->lsa;
3629 else
3630 {
3631 slot->ecnt = SCSP_ENV_DE;
3632 break;
3633 }
3634 }
3635 }
3636
3637 continue; // not yet supported!
3638 }
3639
3640 scsp_buf_len = len;
3641 scsp_buf_pos = 0;
3642
3643 // take effect sound volume if no direct sound volume...
3644 if ((slot->disll == 31) && (slot->dislr == 31))
3645 {
3646 slot->disll = slot->efsll;
3647 slot->dislr = slot->efslr;
3648 }
3649
3650 // SCSPLOG("update : VL=%d VR=%d CNT=%.8X STEP=%.8X\n", slot->disll, slot->dislr, slot->fcnt, slot->finc);
3651
3652 scsp_slot_update_p[(slot->lfofms == 31) ? 0 : 1]
3653 [(slot->lfoems == 31) ? 0 : 1]
3654 [(slot->pcm8b == 0) ? 1 : 0]
3655 [(slot->disll == 31) ? 0 : 1]
3656 [(slot->dislr == 31) ? 0 : 1](slot);
3657 }
3658
3659 if (cdda_out_left > 0)
3660 {
3661 if (len > cdda_out_left / 4)
3662 scsp_buf_len = cdda_out_left / 4;
3663 else
3664 scsp_buf_len = len;
3665
3666 scsp_buf_pos = 0;
3667
3668 /* May need to wrap around the buffer, so use nested loops */
3669 while (scsp_buf_pos < scsp_buf_len)
3670 {
3671 s32 temp = cdda_next_in - cdda_out_left;
3672 s32 outpos = (temp < 0) ? temp + sizeof(cddabuf.data) : temp;
3673 u8 *buf = &cddabuf.data[outpos];
3674
3675 u32 scsp_buf_target;
3676 u32 this_len = scsp_buf_len - scsp_buf_pos;
3677 if (this_len > (sizeof(cddabuf.data) - outpos) / 4)
3678 this_len = (sizeof(cddabuf.data) - outpos) / 4;
3679 scsp_buf_target = scsp_buf_pos + this_len;
3680
3681 for (; scsp_buf_pos < scsp_buf_target; scsp_buf_pos++, buf += 4)
3682 {
3683 s32 out;
3684
3685 out = (s32)(s16)((buf[1] << 8) | buf[0]);
3686
3687 if (out)
3688 scsp_bufL[scsp_buf_pos] += out;
3689
3690 out = (s32)(s16)((buf[3] << 8) | buf[2]);
3691
3692 if (out)
3693 scsp_bufR[scsp_buf_pos] += out;
3694 }
3695
3696 cdda_out_left -= this_len * 4;
3697 }
3698 }
3699 else if (Cs2Area->isaudio)
3700 {
3701 SCSPLOG("WARNING: CDDA buffer underrun\n");
3702 }
3703 }
3704
3705 void
scsp_update_monitor(void)3706 scsp_update_monitor(void)
3707 {
3708 if (use_new_scsp)
3709 {
3710 scsp.ca = new_scsp.slots[scsp.mslc].state.sample_offset >> 5;
3711 scsp.sgc = new_scsp.slots[scsp.mslc].state.envelope;
3712 scsp.eg = new_scsp.slots[scsp.mslc].state.attenuation >> 5;
3713 }
3714 else
3715 {
3716 slot_t *slot = &scsp.slot[scsp.mslc];
3717 scsp.ca = ((slot->fcnt >> (SCSP_FREQ_LB + 12)) & 0xF) << 7;
3718 scsp.sgc = slot->ecurp;
3719 scsp.eg = 0x1f - (slot->env >> (SCSP_ENV_HB - 5));
3720 }
3721 #ifdef PSP
3722 WRITE_THROUGH(scsp.ca);
3723 WRITE_THROUGH(scsp.sgc);
3724 WRITE_THROUGH(scsp.eg);
3725 #endif
3726 }
3727
3728 void
scsp_update_timer(u32 len)3729 scsp_update_timer (u32 len)
3730 {
3731 scsp.timacnt += len << (8 - scsp.timasd);
3732
3733 if (scsp.timacnt >= 0xFF00)
3734 {
3735 if (!(scsp.scipd & 0x40))
3736 scsp_sound_interrupt(0x40);
3737 if (!(scsp.mcipd & 0x40))
3738 scsp_main_interrupt(0x40);
3739 scsp.timacnt -= 0xFF00;
3740 }
3741
3742 scsp.timbcnt += len << (8 - scsp.timbsd);
3743
3744 if (scsp.timbcnt >= 0xFF00)
3745 {
3746 if (!(scsp.scipd & 0x80))
3747 scsp_sound_interrupt(0x80);
3748 if (!(scsp.mcipd & 0x80))
3749 scsp_main_interrupt(0x80);
3750 scsp.timbcnt -= 0xFF00;
3751 }
3752
3753 scsp.timccnt += len << (8 - scsp.timcsd);
3754
3755 if (scsp.timccnt >= 0xFF00)
3756 {
3757 if (!(scsp.scipd & 0x100))
3758 scsp_sound_interrupt(0x100);
3759 if (!(scsp.mcipd & 0x100))
3760 scsp_main_interrupt(0x100);
3761 scsp.timccnt -= 0xFF00;
3762 }
3763
3764 // 1F interrupt can't be accurate here...
3765 if (len)
3766 {
3767 if (!(scsp.scipd & 0x400))
3768 scsp_sound_interrupt(0x400);
3769 if (!(scsp.mcipd & 0x400))
3770 scsp_main_interrupt(0x400);
3771 }
3772 }
3773
3774 ////////////////////////////////////////////////////////////////
3775 // MIDI
3776
3777 void
scsp_midi_in_send(u8 data)3778 scsp_midi_in_send (u8 data)
3779 {
3780 if (scsp.midflag & SCSP_MIDI_IN_EMP)
3781 {
3782 scsp_sound_interrupt(0x8);
3783 scsp_main_interrupt(0x8);
3784 }
3785
3786 scsp.midflag &= ~SCSP_MIDI_IN_EMP;
3787
3788 if (scsp.midincnt > 3)
3789 {
3790 scsp.midflag |= SCSP_MIDI_IN_OVF;
3791 return;
3792 }
3793
3794 scsp.midinbuf[scsp.midincnt++] = data;
3795
3796 if (scsp.midincnt > 3) scsp.midflag |= SCSP_MIDI_IN_FUL;
3797 }
3798
3799 void
scsp_midi_out_send(u8 data)3800 scsp_midi_out_send (u8 data)
3801 {
3802 scsp.midflag &= ~SCSP_MIDI_OUT_EMP;
3803
3804 if (scsp.midoutcnt > 3) return;
3805
3806 scsp.midoutbuf[scsp.midoutcnt++] = data;
3807
3808 if (scsp.midoutcnt > 3) scsp.midflag |= SCSP_MIDI_OUT_FUL;
3809 }
3810
3811 u8
scsp_midi_in_read(void)3812 scsp_midi_in_read (void)
3813 {
3814 u8 data;
3815
3816 scsp.midflag &= ~(SCSP_MIDI_IN_OVF | SCSP_MIDI_IN_FUL);
3817
3818 if (scsp.midincnt > 0)
3819 {
3820 if (scsp.midincnt > 1)
3821 {
3822 scsp_sound_interrupt(0x8);
3823 scsp_main_interrupt(0x8);
3824 }
3825 else
3826 {
3827 scsp.midflag |= SCSP_MIDI_IN_EMP;
3828 }
3829
3830 data = scsp.midinbuf[0];
3831
3832 switch ((--scsp.midincnt) & 3)
3833 {
3834 case 1:
3835 scsp.midinbuf[0] = scsp.midinbuf[1];
3836 break;
3837
3838 case 2:
3839 scsp.midinbuf[0] = scsp.midinbuf[1];
3840 scsp.midinbuf[1] = scsp.midinbuf[2];
3841 break;
3842
3843 case 3:
3844 scsp.midinbuf[0] = scsp.midinbuf[1];
3845 scsp.midinbuf[1] = scsp.midinbuf[2];
3846 scsp.midinbuf[2] = scsp.midinbuf[3];
3847 break;
3848 }
3849
3850 return data;
3851 }
3852
3853 return 0xFF;
3854 }
3855
3856 u8
scsp_midi_out_read(void)3857 scsp_midi_out_read (void)
3858 {
3859 u8 data;
3860
3861 scsp.midflag &= ~SCSP_MIDI_OUT_FUL;
3862
3863 if (scsp.midoutcnt > 0)
3864 {
3865 if (scsp.midoutcnt == 1)
3866 {
3867 scsp.midflag |= SCSP_MIDI_OUT_EMP;
3868 scsp_sound_interrupt(0x200);
3869 scsp_main_interrupt(0x200);
3870 }
3871
3872 data = scsp.midoutbuf[0];
3873
3874 switch (--scsp.midoutcnt & 3)
3875 {
3876 case 1:
3877 scsp.midoutbuf[0] = scsp.midoutbuf[1];
3878 break;
3879
3880 case 2:
3881 scsp.midoutbuf[0] = scsp.midoutbuf[1];
3882 scsp.midoutbuf[1] = scsp.midoutbuf[2];
3883 break;
3884
3885 case 3:
3886 scsp.midoutbuf[0] = scsp.midoutbuf[1];
3887 scsp.midoutbuf[1] = scsp.midoutbuf[2];
3888 scsp.midoutbuf[2] = scsp.midoutbuf[3];
3889 break;
3890 }
3891
3892 return data;
3893 }
3894
3895 return 0xFF;
3896 }
3897
3898 ////////////////////////////////////////////////////////////////
3899 // Access
3900
3901 void FASTCALL
scsp_w_b(u32 a,u8 d)3902 scsp_w_b (u32 a, u8 d)
3903 {
3904 a &= 0xFFF;
3905
3906 if (a < 0x400)
3907 {
3908 if (use_new_scsp)
3909 scsp_slot_write_byte(&new_scsp, a, d);
3910 else
3911 scsp_slot_set_b(a >> 5, a, d);
3912 FLUSH_SCSP ();
3913 return;
3914 }
3915 else if (a < 0x600)
3916 {
3917 if (a < 0x440)
3918 {
3919 scsp_set_b (a, d);
3920 FLUSH_SCSP ();
3921 return;
3922 }
3923 }
3924 else if (a < 0x700)
3925 {
3926
3927 }
3928 else if (a < 0xee4)
3929 {
3930 a &= 0x3ff;
3931 scsp_dcr[a ^ 3] = d;
3932 return;
3933 }
3934
3935 SCSPLOG("WARNING: scsp w_b to %08lx w/ %02x\n", a, d);
3936 }
3937
3938 ////////////////////////////////////////////////////////////////
3939
3940 void FASTCALL
scsp_w_w(u32 a,u16 d)3941 scsp_w_w (u32 a, u16 d)
3942 {
3943 if (a & 1)
3944 {
3945 SCSPLOG ("ERROR: scsp w_w misaligned : %.8X\n", a);
3946 }
3947
3948 a &= 0xFFE;
3949
3950 if (a < 0x400)
3951 {
3952 if (use_new_scsp)
3953 scsp_slot_write_word(&new_scsp, a, d);
3954 else
3955 scsp_slot_set_w(a >> 5, a, d);
3956 FLUSH_SCSP ();
3957 return;
3958 }
3959 else if (a < 0x600)
3960 {
3961 if (a < 0x440)
3962 {
3963 scsp_set_w (a, d);
3964 FLUSH_SCSP ();
3965 return;
3966 }
3967 }
3968 else if (a < 0x700)
3969 {
3970
3971 }
3972 else if (a >= 0x700 && a < 0x780)
3973 {
3974 u32 address = (a - 0x700) / 2;
3975 dsp_inf.set_coef(d >> 3, address);//lower 3 bits seem to be discarded
3976 }
3977 else if (a >= 0x780 && a < 0x7A0)
3978 {
3979 u32 address = (a - 0x780) / 2;
3980 dsp_inf.set_madrs(d, address);
3981 }
3982 else if (a >= 0x7A0 && a < 0x7C0)
3983 {
3984 //madrs mirror
3985 //seems to read only (todo test)
3986 }
3987 else if (a >= 0x800 && a < 0xC00)
3988 {
3989 u32 address = (a - 0x800) / 8;
3990 u64 current_val = dsp_inf.get_mpro(address);
3991 #ifdef HAVE_PLAY_JIT
3992 scsp_dsp_jit_need_recompile();
3993 #endif
3994
3995 switch (a & 0xf)
3996 {
3997 case 0:
3998 case 8:
3999 current_val = (current_val & 0x0000ffffffffffff) | (u64)d << (u64)48;
4000 break;
4001 case 2:
4002 case 0xa:
4003 current_val = (current_val & 0xffff0000ffffffff) | (u64)d << (u64)32;
4004 break;
4005 case 4:
4006 case 0xc:
4007 current_val = (current_val & 0xffffffff0000ffff) | (u64)d << (u64)16;
4008 break;
4009 case 6:
4010 case 0xe:
4011 current_val = (current_val & 0xffffffffffff0000) | d;
4012 break;
4013 default:
4014 break;
4015 }
4016
4017 dsp_inf.set_mpro(current_val, address);
4018 }
4019 else if (a < 0xee4)
4020 {
4021 a &= 0x3ff;
4022 *(u16 *)&scsp_dcr[a ^ 2] = d;
4023 return;
4024 }
4025
4026 SCSPLOG ("WARNING: scsp w_w to %08lx w/ %04x\n", a, d);
4027 }
4028
4029 ////////////////////////////////////////////////////////////////
4030
4031 void FASTCALL
scsp_w_d(u32 a,u32 d)4032 scsp_w_d (u32 a, u32 d)
4033 {
4034 if (a & 3)
4035 {
4036 SCSPLOG ("ERROR: scsp w_d misaligned : %.8X\n", a);
4037 }
4038
4039 a &= 0xFFC;
4040
4041 if (a < 0x400)
4042 {
4043 if (use_new_scsp)
4044 {
4045 scsp_slot_write_word(&new_scsp, a + 0, d >> 16);
4046 scsp_slot_write_word(&new_scsp, a + 2, d & 0xffff);
4047 }
4048 else
4049 {
4050 scsp_slot_set_w(a >> 5, a + 0, d >> 16);
4051 scsp_slot_set_w(a >> 5, a + 2, d & 0xFFFF);
4052 }
4053 FLUSH_SCSP ();
4054 return;
4055 }
4056 else if (a < 0x600)
4057 {
4058 if (a < 0x440)
4059 {
4060 scsp_set_w (a + 0, d >> 16);
4061 scsp_set_w (a + 2, d & 0xFFFF);
4062 FLUSH_SCSP ();
4063 return;
4064 }
4065 }
4066 else if (a < 0x700)
4067 {
4068
4069 }
4070 else if (a < 0xee4)
4071 {
4072 a &= 0x3ff;
4073 *(u32 *)&scsp_dcr[a] = d;
4074 return;
4075 }
4076
4077 SCSPLOG ("WARNING: scsp w_d to %08lx w/ %08lx\n", a, d);
4078 }
4079
4080 ////////////////////////////////////////////////////////////////
4081
4082 u8 FASTCALL
scsp_r_b(u32 a)4083 scsp_r_b (u32 a)
4084 {
4085 a &= 0xFFF;
4086
4087 if (a < 0x400)
4088 {
4089 if (use_new_scsp)
4090 return scsp_slot_read_byte(&new_scsp, a);
4091 else
4092 return scsp_slot_get_b(a >> 5, a);
4093 }
4094 else if (a < 0x600)
4095 {
4096 if (a < 0x440) return scsp_get_b(a);
4097 }
4098 else if (a < 0x700)
4099 {
4100
4101 }
4102 else if (a < 0xee4)
4103 {
4104
4105 }
4106
4107 SCSPLOG("WARNING: scsp r_b to %08lx\n", a);
4108
4109 return 0;
4110 }
4111
4112 ////////////////////////////////////////////////////////////////
4113
4114 u16 FASTCALL
scsp_r_w(u32 a)4115 scsp_r_w (u32 a)
4116 {
4117 if (a & 1)
4118 {
4119 SCSPLOG ("ERROR: scsp r_w misaligned : %.8X\n", a);
4120 }
4121
4122 a &= 0xFFE;
4123
4124 if (a < 0x400)
4125 {
4126 if (use_new_scsp)
4127 return scsp_slot_read_word(&new_scsp, a);
4128 else
4129 return scsp_slot_get_w(a >> 5, a);
4130 }
4131 else if (a < 0x600)
4132 {
4133 if (a < 0x440) return scsp_get_w (a);
4134 }
4135 else if (a < 0x700)
4136 {
4137 if (use_new_scsp)
4138 {
4139 u32 addr = a - 0x600;
4140 return new_scsp.sound_stack[(addr / 2) & 0x3f];
4141 }
4142 }
4143 else if (a >= 0x700 && a < 0x780)
4144 {
4145 u32 address = (a - 0x700) / 2;
4146 return dsp_inf.get_coef(address) << 3;
4147 }
4148 else if (a >= 0x780 && a < 0x7A0)
4149 {
4150 u32 address = (a - 0x780) / 2;
4151 return dsp_inf.get_madrs(address);
4152 }
4153 else if (a >= 0x7A0 && a < 0x7C0)
4154 {
4155 //madrs mirror
4156 u32 address = (a - 0x7A0) / 2;
4157 return dsp_inf.get_madrs(address);
4158 }
4159 else if (a >= 0x800 && a < 0xC00)
4160 {
4161 u32 address = (a - 0x800) / 8;
4162 u64 value = dsp_inf.get_mpro(address);
4163 switch (a & 0xf)
4164 {
4165 case 0:
4166 case 8:
4167 return (value >> (u64)48) & 0xffff;
4168 break;
4169 case 2:
4170 case 0xa:
4171 return (value >> (u64)32) & 0xffff;
4172 break;
4173 case 4:
4174 case 0xc:
4175 return (value >> (u64)16) & 0xffff;
4176 break;
4177 case 6:
4178 case 0xe:
4179 return value & 0xffff;
4180 break;
4181 default:
4182 break;
4183 }
4184 }
4185 else if (a >= 0xE00 && a <= 0xE7F)
4186 {
4187 u32 address = (a - 0xE00) / 2;
4188 return dsp_inf.get_mems(address);
4189 }
4190 else if (a >= 0xEE0 && a <= 0xEE3)
4191 {
4192 u32 address = (a - 0xEE0) / 2;
4193 return dsp_inf.get_exts(address);
4194 }
4195 else if (a < 0xee4)
4196 {
4197
4198 }
4199
4200 SCSPLOG ("WARNING: scsp r_w to %08lx\n", a);
4201
4202 return 0;
4203 }
4204
4205 ////////////////////////////////////////////////////////////////
4206
4207 u32 FASTCALL
scsp_r_d(u32 a)4208 scsp_r_d (u32 a)
4209 {
4210 if (a & 3)
4211 {
4212 SCSPLOG ("ERROR: scsp r_d misaligned : %.8X\n", a);
4213 }
4214
4215 a &= 0xFFC;
4216
4217 if (a < 0x400)
4218 {
4219 if (use_new_scsp)
4220 return (scsp_slot_read_word(&new_scsp, a + 0) << 16) | scsp_slot_read_word(&new_scsp, a + 2);
4221 else
4222 return (scsp_slot_get_w(a >> 5, a + 0) << 16) | scsp_slot_get_w(a >> 5, a + 2);
4223 }
4224 else if (a < 0x600)
4225 {
4226 if (a < 0x440) return (scsp_get_w (a + 0) << 16) | scsp_get_w (a + 2);
4227 }
4228 else if (a < 0x700)
4229 {
4230
4231 }
4232 else if (a < 0xee4)
4233 {
4234
4235 }
4236
4237 SCSPLOG("WARNING: scsp r_d to %08lx\n", a);
4238
4239 return 0;
4240 }
4241
4242 ////////////////////////////////////////////////////////////////
4243 // Interface
4244
4245 void
scsp_shutdown(void)4246 scsp_shutdown (void)
4247 {
4248
4249 }
4250
4251 void
scsp_reset(void)4252 scsp_reset (void)
4253 {
4254 slot_t *slot;
4255
4256 memset(scsp_reg, 0, 0x1000);
4257
4258 scsp.mem4b = 0;
4259 scsp.mvol = 0;
4260 scsp.rbl = 0;
4261 scsp.rbp = 0;
4262 scsp.mslc = 0;
4263 scsp.ca = 0;
4264
4265 scsp.dmea = 0;
4266 scsp.drga = 0;
4267 scsp.dmfl = 0;
4268 scsp.dmlen = 0;
4269
4270 scsp.midincnt = 0;
4271 scsp.midoutcnt = 0;
4272 scsp.midflag = SCSP_MIDI_IN_EMP | SCSP_MIDI_OUT_EMP;
4273 scsp.midflag2 = 0;
4274
4275 scsp.timacnt = 0xFF00;
4276 scsp.timbcnt = 0xFF00;
4277 scsp.timccnt = 0xFF00;
4278 scsp.timasd = 0;
4279 scsp.timbsd = 0;
4280 scsp.timcsd = 0;
4281
4282 scsp.mcieb = 0;
4283 scsp.mcipd = 0;
4284 scsp.scieb = 0;
4285 scsp.scipd = 0;
4286 scsp.scilv0 = 0;
4287 scsp.scilv1 = 0;
4288 scsp.scilv2 = 0;
4289
4290 for(slot = &(scsp.slot[0]); slot < &(scsp.slot[32]); slot++)
4291 {
4292 memset(slot, 0, sizeof(slot_t));
4293 slot->ecnt = SCSP_ENV_DE; // slot off
4294 slot->ecurp = SCSP_ENV_RELEASE;
4295 slot->dislr = slot->disll = 31; // direct level sound off
4296 slot->efslr = slot->efsll = 31; // effect level sound off
4297
4298 // Make sure lfofmw/lfoemw have sane values
4299 slot->lfofmw = scsp_lfo_sawt_f;
4300 slot->lfoemw = scsp_lfo_sawt_e;
4301 }
4302
4303 if (use_new_scsp)
4304 new_scsp_reset(&new_scsp);
4305 else
4306 scsp_dsp_int_init();
4307 }
4308
4309 void
scsp_init(u8 * scsp_ram,void (* sint_hand)(u32),void (* mint_hand)(void))4310 scsp_init (u8 *scsp_ram, void (*sint_hand)(u32), void (*mint_hand)(void))
4311 {
4312 u32 i, j;
4313 double x;
4314
4315 scsp_shutdown ();
4316
4317 scsp_isr = &scsp_reg[0x0000];
4318 scsp_ccr = &scsp_reg[0x0400];
4319 scsp_dcr = &scsp_reg[0x0700];
4320
4321 scsp.scsp_ram = scsp_ram;
4322 scsp.sintf = sint_hand;
4323 scsp.mintf = mint_hand;
4324
4325 for (i = 0; i < SCSP_ENV_LEN; i++)
4326 {
4327 // Attack Curve (x^7 ?)
4328 x = pow (((double)(SCSP_ENV_MASK - i) / (double)SCSP_ENV_LEN), 7);
4329 x *= (double)SCSP_ENV_LEN;
4330 scsp_env_table[i] = SCSP_ENV_MASK - (s32)x;
4331
4332 // Decay curve (x = linear)
4333 x = pow (((double)i / (double)SCSP_ENV_LEN), 1);
4334 x *= (double)SCSP_ENV_LEN;
4335 scsp_env_table[i + SCSP_ENV_LEN] = SCSP_ENV_MASK - (s32)x;
4336 }
4337
4338 for (i = 0, j = 0; i < 32; i++)
4339 {
4340 j += 1 << (i >> 2);
4341
4342 // lfo freq
4343 x = (SCSP_FREQ / 256.0) / (double)j;
4344
4345 // converting lfo freq in lfo step
4346 scsp_lfo_step[31 - i] = scsp_round(x * ((double)SCSP_LFO_LEN /
4347 (double)SCSP_FREQ) *
4348 (double)(1 << SCSP_LFO_LB));
4349 }
4350
4351 // Calculate LFO (modulation) values
4352 for (i = 0; i < SCSP_LFO_LEN; i++)
4353 {
4354 // Envelope modulation
4355 scsp_lfo_sawt_e[i] = SCSP_LFO_MASK - i;
4356
4357 if (i < (SCSP_LFO_LEN / 2))
4358 scsp_lfo_squa_e[i] = SCSP_LFO_MASK;
4359 else
4360 scsp_lfo_squa_e[i] = 0;
4361
4362 if (i < (SCSP_LFO_LEN / 2))
4363 scsp_lfo_tri_e[i] = SCSP_LFO_MASK - (i * 2);
4364 else
4365 scsp_lfo_tri_e[i] = (i - (SCSP_LFO_LEN / 2)) * 2;
4366
4367 scsp_lfo_noi_e[i] = rand() & SCSP_LFO_MASK;
4368
4369 // Frequency modulation
4370 scsp_lfo_sawt_f[(i + 512) & SCSP_LFO_MASK] = i - (SCSP_LFO_LEN / 2);
4371
4372 if (i < (SCSP_LFO_LEN / 2))
4373 scsp_lfo_squa_f[i] = SCSP_LFO_MASK - (SCSP_LFO_LEN / 2) - 128;
4374 else
4375 scsp_lfo_squa_f[i] = 0 - (SCSP_LFO_LEN / 2) + 128;
4376
4377 if (i < (SCSP_LFO_LEN / 2))
4378 scsp_lfo_tri_f[(i + 768) & SCSP_LFO_MASK] = (i * 2) -
4379 (SCSP_LFO_LEN / 2);
4380 else
4381 scsp_lfo_tri_f[(i + 768) & SCSP_LFO_MASK] =
4382 (SCSP_LFO_MASK - ((i - (SCSP_LFO_LEN / 2)) * 2)) -
4383 (SCSP_LFO_LEN / 2) + 1;
4384
4385 scsp_lfo_noi_f[i] = scsp_lfo_noi_e[i] - (SCSP_LFO_LEN / 2);
4386 }
4387
4388 for(i = 0; i < 4; i++)
4389 {
4390 scsp_attack_rate[i] = 0;
4391 scsp_decay_rate[i] = 0;
4392 }
4393
4394 for(i = 0; i < 60; i++)
4395 {
4396 x = 1.0 + ((i & 3) * 0.25); // bits 0-1 : x1.00, x1.25, x1.50, x1.75
4397 x *= (double)(1 << ((i >> 2))); // bits 2-5 : shift bits (x2^0 - x2^15)
4398 x *= (double)(SCSP_ENV_LEN << SCSP_ENV_LB); // adjust for table scsp_env_table
4399
4400 scsp_attack_rate[i + 4] = scsp_round(x / (double)SCSP_ATTACK_R);
4401 scsp_decay_rate[i + 4] = scsp_round(x / (double)SCSP_DECAY_R);
4402
4403 if (scsp_attack_rate[i + 4] == 0) scsp_attack_rate[i + 4] = 1;
4404 if (scsp_decay_rate[i + 4] == 0) scsp_decay_rate[i + 4] = 1;
4405 }
4406
4407 scsp_attack_rate[63] = SCSP_ENV_AE;
4408 scsp_decay_rate[61] = scsp_decay_rate[60];
4409 scsp_decay_rate[62] = scsp_decay_rate[60];
4410 scsp_decay_rate[63] = scsp_decay_rate[60];
4411
4412 for(i = 64; i < 96; i++)
4413 {
4414 scsp_attack_rate[i] = scsp_attack_rate[63];
4415 scsp_decay_rate[i] = scsp_decay_rate[63];
4416 scsp_null_rate[i - 64] = 0;
4417 }
4418
4419 for(i = 0; i < 96; i++)
4420 {
4421 SCSPLOG ("attack rate[%d] = %.8X -> %.8X\n", i, scsp_attack_rate[i],
4422 scsp_attack_rate[i] >> SCSP_ENV_LB);
4423 SCSPLOG ("decay rate[%d] = %.8X -> %.8X\n", i, scsp_decay_rate[i],
4424 scsp_decay_rate[i] >> SCSP_ENV_LB);
4425 }
4426
4427 for(i = 0; i < 256; i++)
4428 scsp_tl_table[i] = scsp_round(pow(10, ((double)i * -0.3762) / 20) * 1024.0);
4429
4430 scsp_reset();
4431 }
4432
4433 //////////////////////////////////////////////////////////////////////////////
4434 // Yabause specific
4435 //////////////////////////////////////////////////////////////////////////////
4436
4437 u8 *SoundRam = NULL;
4438 ScspInternal *ScspInternalVars;
4439 static SoundInterface_struct *SNDCore = NULL;
4440 extern SoundInterface_struct *SNDCoreList[];
4441
4442 struct sounddata
4443 {
4444 u32 *data32;
4445 } scspchannel[2];
4446
4447 static u32 scspsoundlen; // Samples to output per frame
4448 static u32 scsplines; // Lines per frame
4449 static u32 scspsoundbufs; // Number of "scspsoundlen"-sample buffers
4450 static u32 scspsoundbufsize; // scspsoundlen * scspsoundbufs
4451 static u32 scspsoundgenpos; // Offset of next byte to generate
4452 static u32 scspsoundoutleft; // Samples not yet sent to host driver
4453
4454 static int
scsp_alloc_bufs(void)4455 scsp_alloc_bufs (void)
4456 {
4457 if (scspchannel[0].data32)
4458 free(scspchannel[0].data32);
4459 scspchannel[0].data32 = NULL;
4460 if (scspchannel[1].data32)
4461 free(scspchannel[1].data32);
4462 scspchannel[1].data32 = NULL;
4463
4464 scspchannel[0].data32 = (u32 *)calloc(scspsoundbufsize, sizeof(u32));
4465 if (scspchannel[0].data32 == NULL)
4466 return -1;
4467 scspchannel[1].data32 = (u32 *)calloc(scspsoundbufsize, sizeof(u32));
4468 if (scspchannel[1].data32 == NULL)
4469 return -1;
4470
4471 return 0;
4472 }
4473
4474 static u8 IsM68KRunning;
4475 static s32 FASTCALL (*m68kexecptr)(s32 cycles); // M68K->Exec or M68KExecBP
4476 static s32 savedcycles; // Cycles left over from the last M68KExec() call
4477
4478 //////////////////////////////////////////////////////////////////////////////
4479
4480 u32 FASTCALL
c68k_byte_read(const u32 adr)4481 c68k_byte_read (const u32 adr)
4482 {
4483 if (adr < 0x100000)
4484 return T2ReadByte(SoundRam, adr & 0x7FFFF);
4485 else
4486 return scsp_r_b(adr);
4487 }
4488
4489 //////////////////////////////////////////////////////////////////////////////
4490
4491 static void FASTCALL
c68k_byte_write(const u32 adr,u32 data)4492 c68k_byte_write (const u32 adr, u32 data)
4493 {
4494 if (adr < 0x100000)
4495 T2WriteByte(SoundRam, adr & 0x7FFFF, data);
4496 else
4497 scsp_w_b(adr, data);
4498 }
4499
4500 //////////////////////////////////////////////////////////////////////////////
4501
4502 /* exported to m68kd.c */
4503 u32 FASTCALL
c68k_word_read(const u32 adr)4504 c68k_word_read (const u32 adr)
4505 {
4506 if (adr < 0x100000)
4507 return T2ReadWord(SoundRam, adr & 0x7FFFF);
4508 else
4509 return scsp_r_w(adr);
4510 }
4511
4512 //////////////////////////////////////////////////////////////////////////////
4513
4514 static void FASTCALL
c68k_word_write(const u32 adr,u32 data)4515 c68k_word_write (const u32 adr, u32 data)
4516 {
4517 if (adr < 0x100000)
4518 T2WriteWord (SoundRam, adr & 0x7FFFF, data);
4519 else
4520 scsp_w_w (adr, data);
4521 }
4522
4523 //////////////////////////////////////////////////////////////////////////////
4524
4525 static void
c68k_interrupt_handler(u32 level)4526 c68k_interrupt_handler (u32 level)
4527 {
4528 // send interrupt to 68k
4529 M68K->SetIRQ ((s32)level);
4530 }
4531
4532 //////////////////////////////////////////////////////////////////////////////
4533
4534 static void
scu_interrupt_handler(void)4535 scu_interrupt_handler (void)
4536 {
4537 // send interrupt to scu
4538 ScuSendSoundRequest ();
4539 }
4540
4541 //////////////////////////////////////////////////////////////////////////////
4542
4543 u8 FASTCALL
ScspReadByte(u32 addr)4544 ScspReadByte (u32 addr)
4545 {
4546 return scsp_r_b(addr);
4547 }
4548
4549 //////////////////////////////////////////////////////////////////////////////
4550
4551 void FASTCALL
ScspWriteByte(u32 addr,u8 val)4552 ScspWriteByte (u32 addr, u8 val)
4553 {
4554 scsp_w_b(addr, val);
4555 }
4556
4557 //////////////////////////////////////////////////////////////////////////////
4558
4559 u16 FASTCALL
ScspReadWord(u32 addr)4560 ScspReadWord (u32 addr)
4561 {
4562 return scsp_r_w(addr);
4563 }
4564
4565 //////////////////////////////////////////////////////////////////////////////
4566
4567 void FASTCALL
ScspWriteWord(u32 addr,u16 val)4568 ScspWriteWord (u32 addr, u16 val)
4569 {
4570 scsp_w_w(addr, val);
4571 }
4572
4573 //////////////////////////////////////////////////////////////////////////////
4574
4575 u32 FASTCALL
ScspReadLong(u32 addr)4576 ScspReadLong (u32 addr)
4577 {
4578 return scsp_r_d(addr);
4579 }
4580
4581 //////////////////////////////////////////////////////////////////////////////
4582
4583 void FASTCALL
ScspWriteLong(u32 addr,u32 val)4584 ScspWriteLong (u32 addr, u32 val)
4585 {
4586 scsp_w_d(addr, val);
4587 }
4588
4589 //////////////////////////////////////////////////////////////////////////////
4590
4591 u8 FASTCALL
SoundRamReadByte(u32 addr)4592 SoundRamReadByte (u32 addr)
4593 {
4594 addr &= 0xFFFFF;
4595
4596 // If mem4b is set, mirror ram every 256k
4597 if (scsp.mem4b == 0)
4598 addr &= 0x3FFFF;
4599 else if (addr > 0x7FFFF)
4600 return 0xFF;
4601
4602 return T2ReadByte (SoundRam, addr);
4603 }
4604
4605 //////////////////////////////////////////////////////////////////////////////
4606
4607 void FASTCALL
SoundRamWriteByte(u32 addr,u8 val)4608 SoundRamWriteByte (u32 addr, u8 val)
4609 {
4610 addr &= 0xFFFFF;
4611
4612 // If mem4b is set, mirror ram every 256k
4613 if (scsp.mem4b == 0)
4614 addr &= 0x3FFFF;
4615 else if (addr > 0x7FFFF)
4616 return;
4617
4618 T2WriteByte (SoundRam, addr, val);
4619 M68K->WriteNotify (addr, 1);
4620 }
4621
4622 //////////////////////////////////////////////////////////////////////////////
4623
4624 u16 FASTCALL
SoundRamReadWord(u32 addr)4625 SoundRamReadWord (u32 addr)
4626 {
4627 addr &= 0xFFFFF;
4628
4629 if (scsp.mem4b == 0)
4630 addr &= 0x3FFFF;
4631 else if (addr > 0x7FFFF)
4632 return 0xFFFF;
4633
4634 return T2ReadWord (SoundRam, addr);
4635 }
4636
4637 //////////////////////////////////////////////////////////////////////////////
4638
4639 void FASTCALL
SoundRamWriteWord(u32 addr,u16 val)4640 SoundRamWriteWord (u32 addr, u16 val)
4641 {
4642 addr &= 0xFFFFF;
4643
4644 // If mem4b is set, mirror ram every 256k
4645 if (scsp.mem4b == 0)
4646 addr &= 0x3FFFF;
4647 else if (addr > 0x7FFFF)
4648 return;
4649
4650 T2WriteWord (SoundRam, addr, val);
4651 M68K->WriteNotify (addr, 2);
4652 }
4653
4654 //////////////////////////////////////////////////////////////////////////////
4655
4656 u32 FASTCALL
SoundRamReadLong(u32 addr)4657 SoundRamReadLong (u32 addr)
4658 {
4659 addr &= 0xFFFFF;
4660
4661 // If mem4b is set, mirror ram every 256k
4662 if (scsp.mem4b == 0)
4663 addr &= 0x3FFFF;
4664 else if (addr > 0x7FFFF)
4665 return 0xFFFFFFFF;
4666
4667 return T2ReadLong (SoundRam, addr);
4668 }
4669
4670 //////////////////////////////////////////////////////////////////////////////
4671
4672 void FASTCALL
SoundRamWriteLong(u32 addr,u32 val)4673 SoundRamWriteLong (u32 addr, u32 val)
4674 {
4675 addr &= 0xFFFFF;
4676
4677 // If mem4b is set, mirror ram every 256k
4678 if (scsp.mem4b == 0)
4679 addr &= 0x3FFFF;
4680 else if (addr > 0x7FFFF)
4681 return;
4682
4683 T2WriteLong (SoundRam, addr, val);
4684 M68K->WriteNotify (addr, 4);
4685 }
4686
4687 //////////////////////////////////////////////////////////////////////////////
4688
4689 u8 FASTCALL
Sh2ScspReadByte(SH2_struct * sh,u32 addr)4690 Sh2ScspReadByte(SH2_struct *sh, u32 addr)
4691 {
4692 return ScspReadByte(addr);
4693 }
4694
4695 //////////////////////////////////////////////////////////////////////////////
4696
4697 void FASTCALL
Sh2ScspWriteByte(SH2_struct * sh,u32 addr,u8 val)4698 Sh2ScspWriteByte(SH2_struct *sh, u32 addr, u8 val)
4699 {
4700 ScspWriteByte(addr, val);
4701 }
4702
4703 //////////////////////////////////////////////////////////////////////////////
4704
4705 u16 FASTCALL
Sh2ScspReadWord(SH2_struct * sh,u32 addr)4706 Sh2ScspReadWord(SH2_struct *sh, u32 addr)
4707 {
4708 return ScspReadWord(addr);
4709 }
4710
4711 //////////////////////////////////////////////////////////////////////////////
4712
4713 void FASTCALL
Sh2ScspWriteWord(SH2_struct * sh,u32 addr,u16 val)4714 Sh2ScspWriteWord(SH2_struct *sh, u32 addr, u16 val)
4715 {
4716 ScspWriteWord(addr, val);
4717 }
4718
4719 //////////////////////////////////////////////////////////////////////////////
4720
4721 u32 FASTCALL
Sh2ScspReadLong(SH2_struct * sh,u32 addr)4722 Sh2ScspReadLong(SH2_struct *sh, u32 addr)
4723 {
4724 return ScspReadLong(addr);
4725 }
4726
4727 //////////////////////////////////////////////////////////////////////////////
4728
4729 void FASTCALL
Sh2ScspWriteLong(SH2_struct * sh,u32 addr,u32 val)4730 Sh2ScspWriteLong(SH2_struct *sh, u32 addr, u32 val)
4731 {
4732 ScspWriteLong(addr, val);
4733 }
4734
4735 //////////////////////////////////////////////////////////////////////////////
4736
4737 u8 FASTCALL
Sh2SoundRamReadByte(SH2_struct * sh,u32 addr)4738 Sh2SoundRamReadByte(SH2_struct *sh, u32 addr)
4739 {
4740 return SoundRamReadByte(addr);
4741 }
4742
4743 //////////////////////////////////////////////////////////////////////////////
4744
4745 void FASTCALL
Sh2SoundRamWriteByte(SH2_struct * sh,u32 addr,u8 val)4746 Sh2SoundRamWriteByte(SH2_struct *sh, u32 addr, u8 val)
4747 {
4748 SoundRamWriteByte(addr, val);
4749 }
4750
4751 //////////////////////////////////////////////////////////////////////////////
4752
4753 u16 FASTCALL
Sh2SoundRamReadWord(SH2_struct * sh,u32 addr)4754 Sh2SoundRamReadWord(SH2_struct *sh, u32 addr)
4755 {
4756 return SoundRamReadWord(addr);
4757 }
4758
4759 //////////////////////////////////////////////////////////////////////////////
4760
4761 void FASTCALL
Sh2SoundRamWriteWord(SH2_struct * sh,u32 addr,u16 val)4762 Sh2SoundRamWriteWord(SH2_struct *sh, u32 addr, u16 val)
4763 {
4764 SoundRamWriteWord(addr, val);
4765 }
4766
4767 //////////////////////////////////////////////////////////////////////////////
4768
4769 u32 FASTCALL
Sh2SoundRamReadLong(SH2_struct * sh,u32 addr)4770 Sh2SoundRamReadLong(SH2_struct *sh, u32 addr)
4771 {
4772 return SoundRamReadLong(addr);
4773 }
4774
4775 //////////////////////////////////////////////////////////////////////////////
4776
4777 void FASTCALL
Sh2SoundRamWriteLong(SH2_struct * sh,u32 addr,u32 val)4778 Sh2SoundRamWriteLong(SH2_struct *sh, u32 addr, u32 val)
4779 {
4780 SoundRamWriteLong(addr, val);
4781 }
4782
4783 //////////////////////////////////////////////////////////////////////////////
4784
4785 int
ScspInit(int coreid)4786 ScspInit (int coreid)
4787 {
4788 int i;
4789
4790 if ((SoundRam = T2MemoryInit (0x80000)) == NULL)
4791 return -1;
4792
4793 if ((ScspInternalVars = (ScspInternal *)calloc(1, sizeof(ScspInternal))) == NULL)
4794 return -1;
4795
4796 if (M68K->Init () != 0)
4797 return -1;
4798
4799 M68K->SetReadB ((C68K_READ *)c68k_byte_read);
4800 M68K->SetReadW ((C68K_READ *)c68k_word_read);
4801 M68K->SetWriteB ((C68K_WRITE *)c68k_byte_write);
4802 M68K->SetWriteW ((C68K_WRITE *)c68k_word_write);
4803
4804 M68K->SetFetch (0x000000, 0x040000, (pointer)SoundRam);
4805 M68K->SetFetch (0x040000, 0x080000, (pointer)SoundRam);
4806 M68K->SetFetch (0x080000, 0x0C0000, (pointer)SoundRam);
4807 M68K->SetFetch (0x0C0000, 0x100000, (pointer)SoundRam);
4808
4809 IsM68KRunning = 0;
4810
4811 scsp_init (SoundRam, &c68k_interrupt_handler, &scu_interrupt_handler);
4812 ScspInternalVars->scsptiming1 = 0;
4813 ScspInternalVars->scsptiming2 = 0;
4814
4815 for (i = 0; i < MAX_BREAKPOINTS; i++)
4816 ScspInternalVars->codebreakpoint[i].addr = 0xFFFFFFFF;
4817 ScspInternalVars->numcodebreakpoints = 0;
4818 ScspInternalVars->BreakpointCallBack = NULL;
4819 ScspInternalVars->inbreakpoint = 0;
4820
4821 m68kexecptr = M68K->Exec;
4822
4823 // Allocate enough memory for each channel buffer(may have to change)
4824 scspsoundlen = 44100 / 60; // assume it's NTSC timing
4825 scsplines = 263;
4826 scspsoundbufs = 10; // should be enough to prevent skipping
4827 scspsoundbufsize = scspsoundlen * scspsoundbufs;
4828 if (scsp_alloc_bufs () < 0)
4829 return -1;
4830
4831 // Reset output pointers
4832 scspsoundgenpos = 0;
4833 scspsoundoutleft = 0;
4834
4835 return ScspChangeSoundCore (coreid);
4836 }
4837
4838 //////////////////////////////////////////////////////////////////////////////
4839
4840 int
ScspChangeSoundCore(int coreid)4841 ScspChangeSoundCore (int coreid)
4842 {
4843 int i;
4844
4845 // Make sure the old core is freed
4846 if (SNDCore)
4847 SNDCore->DeInit();
4848
4849 // So which core do we want?
4850 if (coreid == SNDCORE_DEFAULT)
4851 coreid = 0; // Assume we want the first one
4852
4853 // Go through core list and find the id
4854 for (i = 0; SNDCoreList[i] != NULL; i++)
4855 {
4856 if (SNDCoreList[i]->id == coreid)
4857 {
4858 // Set to current core
4859 SNDCore = SNDCoreList[i];
4860 break;
4861 }
4862 }
4863
4864 if (SNDCore == NULL)
4865 {
4866 SNDCore = &SNDDummy;
4867 return -1;
4868 }
4869
4870 if (SNDCore->Init () == -1)
4871 {
4872 // Since it failed, instead of it being fatal, we'll just use the dummy
4873 // core instead
4874
4875 // This might be helpful though.
4876 YabSetError (YAB_ERR_CANNOTINIT, (void *)SNDCore->Name);
4877
4878 SNDCore = &SNDDummy;
4879 }
4880
4881 if (SNDCore)
4882 {
4883 if (scsp_mute_flags) SNDCore->MuteAudio();
4884 else SNDCore->UnMuteAudio();
4885 SNDCore->SetVolume(scsp_volume);
4886 }
4887
4888 return 0;
4889 }
4890
4891 //////////////////////////////////////////////////////////////////////////////
4892
4893 void
ScspDeInit(void)4894 ScspDeInit (void)
4895 {
4896 if (scspchannel[0].data32)
4897 free(scspchannel[0].data32);
4898 scspchannel[0].data32 = NULL;
4899
4900 if (scspchannel[1].data32)
4901 free(scspchannel[1].data32);
4902 scspchannel[1].data32 = NULL;
4903
4904 if (SNDCore)
4905 SNDCore->DeInit();
4906 SNDCore = NULL;
4907
4908 scsp_shutdown();
4909
4910 if (SoundRam)
4911 T2MemoryDeInit (SoundRam);
4912 SoundRam = NULL;
4913 }
4914
4915 //////////////////////////////////////////////////////////////////////////////
4916
4917 void
M68KStart(void)4918 M68KStart (void)
4919 {
4920 M68K->Reset ();
4921 savedcycles = 0;
4922 IsM68KRunning = 1;
4923 }
4924
4925 //////////////////////////////////////////////////////////////////////////////
4926
4927 void
M68KStop(void)4928 M68KStop (void)
4929 {
4930 IsM68KRunning = 0;
4931 }
4932
4933 //////////////////////////////////////////////////////////////////////////////
4934
4935 void
ScspReset(void)4936 ScspReset (void)
4937 {
4938 scsp_reset();
4939 }
4940
4941 //////////////////////////////////////////////////////////////////////////////
4942
4943 int
ScspChangeVideoFormat(int type)4944 ScspChangeVideoFormat (int type)
4945 {
4946 scspsoundlen = 44100 / (type ? 50 : 60);
4947 scsplines = type ? 313 : 263;
4948 scspsoundbufsize = scspsoundlen * scspsoundbufs;
4949
4950 if (scsp_alloc_bufs () < 0)
4951 return -1;
4952
4953 SNDCore->ChangeVideoFormat (type ? 50 : 60);
4954
4955 return 0;
4956 }
4957
4958 //////////////////////////////////////////////////////////////////////////////
4959
4960 /* Process breakpoints in a separate function to avoid unnecessary register
4961 * spillage on the fast path (and to avoid too much block nesting) */
4962 #ifdef __GNUC__
4963 __attribute__((noinline))
4964 #endif
4965 static s32 FASTCALL M68KExecBP (s32 cycles);
4966
4967 void
M68KExec(s32 cycles)4968 M68KExec (s32 cycles)
4969 {
4970 s32 newcycles = savedcycles - cycles;
4971 if (LIKELY(IsM68KRunning))
4972 {
4973 if (LIKELY(newcycles < 0))
4974 {
4975 s32 cyclestoexec = -newcycles;
4976 newcycles += (*m68kexecptr)(cyclestoexec);
4977 }
4978 savedcycles = newcycles;
4979 }
4980 }
4981
new_scsp_run_sample()4982 void new_scsp_run_sample()
4983 {
4984 s32 temp = cdda_next_in - cdda_out_left;
4985 s32 outpos = (temp < 0) ? temp + sizeof(cddabuf.data) : temp;
4986 u8 *buf = &cddabuf.data[outpos];
4987
4988 s16 out_l = 0;
4989 s16 out_r = 0;
4990
4991 s16 cd_in_l = 0;
4992 s16 cd_in_r = 0;
4993
4994 if ((s32)cdda_out_left > 0)
4995 {
4996 cd_in_l = (s16)((buf[1] << 8) | buf[0]);
4997 cd_in_r = (s16)((buf[3] << 8) | buf[2]);
4998
4999 cdda_out_left -= 4;
5000 }
5001
5002 scsp_update_timer(1);
5003 generate_sample(&new_scsp, scsp.rbp, scsp.rbl, &out_l, &out_r, scsp.mvol, cd_in_l, cd_in_r);
5004
5005 if (new_scsp_outbuf_pos < 900)
5006 {
5007 new_scsp_outbuf_l[new_scsp_outbuf_pos] = out_l;
5008 new_scsp_outbuf_r[new_scsp_outbuf_pos] = out_r;
5009 }
5010 else
5011 {
5012 //buffer overrun
5013 }
5014
5015 scsp_update_monitor();
5016 new_scsp_outbuf_pos++;
5017 }
5018
new_scsp_exec(s32 cycles)5019 void new_scsp_exec(s32 cycles)
5020 {
5021 s32 cycles_temp = new_scsp_cycles - cycles;
5022 if (cycles_temp < 0)
5023 {
5024 new_scsp_run_sample();
5025 cycles_temp += 512;
5026 }
5027 new_scsp_cycles = cycles_temp;
5028 }
5029
5030 //----------------------------------------------------------------------------
5031
5032 static s32 FASTCALL
M68KExecBP(s32 cycles)5033 M68KExecBP (s32 cycles)
5034 {
5035 s32 cyclestoexec=cycles;
5036 s32 cyclesexecuted=0;
5037 int i;
5038
5039 while (cyclesexecuted < cyclestoexec)
5040 {
5041 // Make sure it isn't one of our breakpoints
5042 for (i = 0; i < ScspInternalVars->numcodebreakpoints; i++)
5043 {
5044 if ((M68K->GetPC () == ScspInternalVars->codebreakpoint[i].addr) &&
5045 ScspInternalVars->inbreakpoint == 0)
5046 {
5047 ScspInternalVars->inbreakpoint = 1;
5048 if (ScspInternalVars->BreakpointCallBack)
5049 ScspInternalVars->BreakpointCallBack (ScspInternalVars->codebreakpoint[i].addr);
5050 ScspInternalVars->inbreakpoint = 0;
5051 }
5052 }
5053
5054 // execute instructions individually
5055 cyclesexecuted += M68K->Exec(1);
5056
5057 }
5058 return cyclesexecuted;
5059 }
5060
5061 //////////////////////////////////////////////////////////////////////////////
5062
5063 void
M68KStep(void)5064 M68KStep (void)
5065 {
5066 M68K->Exec(1);
5067 }
5068
5069 //////////////////////////////////////////////////////////////////////////////
5070
5071 // Wait for background execution to finish (used on PSP)
5072 void
M68KSync(void)5073 M68KSync (void)
5074 {
5075 M68K->Sync();
5076 }
5077
5078 //////////////////////////////////////////////////////////////////////////////
5079
5080 void
ScspConvert32uto16s(s32 * srcL,s32 * srcR,s16 * dst,u32 len)5081 ScspConvert32uto16s (s32 *srcL, s32 *srcR, s16 *dst, u32 len)
5082 {
5083 u32 i;
5084
5085 for (i = 0; i < len; i++)
5086 {
5087 // Left Channel
5088 if (*srcL > 0x7FFF)
5089 *dst = 0x7FFF;
5090 else if (*srcL < -0x8000)
5091 *dst = -0x8000;
5092 else
5093 *dst = *srcL;
5094
5095 srcL++;
5096 dst++;
5097
5098 // Right Channel
5099 if (*srcR > 0x7FFF)
5100 *dst = 0x7FFF;
5101 else if (*srcR < -0x8000)
5102 *dst = -0x8000;
5103 else
5104 *dst = *srcR;
5105
5106 srcR++;
5107 dst++;
5108 }
5109 }
5110
5111 //////////////////////////////////////////////////////////////////////////////
5112
5113 void
ScspReceiveCDDA(const u8 * sector)5114 ScspReceiveCDDA (const u8 *sector)
5115 {
5116 // If buffer is half empty or less, boost timing for a bit until we've buffered a few sectors
5117 if (cdda_out_left < (sizeof(cddabuf.data) / 2))
5118 {
5119 Cs2Area->isaudio = 0;
5120 Cs2SetTiming(1);
5121 Cs2Area->isaudio = 1;
5122 }
5123 else if (cdda_out_left > (sizeof(cddabuf.data) * 3 / 4 ))
5124 Cs2SetTiming(0);
5125 else
5126 {
5127 Cs2Area->isaudio = 1;
5128 Cs2SetTiming(1);
5129 }
5130
5131 memcpy(cddabuf.data+cdda_next_in, sector, 2352);
5132 if (sizeof(cddabuf.data)-cdda_next_in <= 2352)
5133 cdda_next_in = 0;
5134 else
5135 cdda_next_in += 2352;
5136
5137 cdda_out_left += 2352;
5138
5139 if (cdda_out_left > sizeof(cddabuf.data))
5140 {
5141 SCSPLOG ("WARNING: CDDA buffer overrun\n");
5142 cdda_out_left = sizeof(cddabuf.data);
5143 }
5144 }
5145
5146 //////////////////////////////////////////////////////////////////////////////
5147
ScspReceiveMpeg(const u8 * samples,int len)5148 void ScspReceiveMpeg (const u8 *samples, int len)
5149 {
5150 memcpy(cddabuf.data+cdda_next_in, samples, len);
5151
5152 if (sizeof(cddabuf.data)-cdda_next_in <= len)
5153 cdda_next_in = 0;
5154 else
5155 cdda_next_in += len;
5156
5157 cdda_out_left += len;
5158
5159 if (cdda_out_left > sizeof(cddabuf.data))
5160 {
5161 SCSPLOG ("WARNING: CDDA buffer overrun\n");
5162 cdda_out_left = sizeof(cddabuf.data);
5163 }
5164 }
5165
5166 //////////////////////////////////////////////////////////////////////////////
5167
new_scsp_update_samples(s32 * bufL,s32 * bufR,int scspsoundlen)5168 void new_scsp_update_samples(s32 *bufL, s32 *bufR, int scspsoundlen)
5169 {
5170 int i;
5171 for (i = 0; i < new_scsp_outbuf_pos; i++)
5172 {
5173 if (i >= scspsoundlen)
5174 break;
5175
5176 bufL[i] = new_scsp_outbuf_l[i];
5177 bufR[i] = new_scsp_outbuf_r[i];
5178 }
5179
5180 new_scsp_outbuf_pos = 0;
5181 }
5182
5183 void
ScspExec()5184 ScspExec ()
5185 {
5186 u32 audiosize;
5187
5188 ScspInternalVars->scsptiming2 +=
5189 ((scspsoundlen << 16) + scsplines / 2) / scsplines;
5190 if (!use_new_scsp)
5191 scsp_update_timer (ScspInternalVars->scsptiming2 >> 16); // Pass integer part
5192 ScspInternalVars->scsptiming2 &= 0xFFFF; // Keep fractional part
5193 ScspInternalVars->scsptiming1++;
5194
5195 if (ScspInternalVars->scsptiming1 >= scsplines)
5196 {
5197 s32 *bufL, *bufR;
5198
5199 ScspInternalVars->scsptiming1 -= scsplines;
5200 ScspInternalVars->scsptiming2 = 0;
5201
5202 // Update sound buffers
5203 if (scspsoundgenpos + scspsoundlen > scspsoundbufsize)
5204 scspsoundgenpos = 0;
5205
5206 if (scspsoundoutleft + scspsoundlen > scspsoundbufsize)
5207 {
5208 u32 overrun = (scspsoundoutleft + scspsoundlen) -
5209 scspsoundbufsize;
5210 SCSPLOG("WARNING: Sound buffer overrun, %lu samples\n",
5211 (long)overrun);
5212 scspsoundoutleft -= overrun;
5213 }
5214
5215 bufL = (s32 *)&scspchannel[0].data32[scspsoundgenpos];
5216 bufR = (s32 *)&scspchannel[1].data32[scspsoundgenpos];
5217 memset(bufL, 0, sizeof(u32) * scspsoundlen);
5218 memset(bufR, 0, sizeof(u32) * scspsoundlen);
5219 if (use_new_scsp)
5220 new_scsp_update_samples(bufL, bufR, scspsoundlen);
5221 else
5222 scsp_update(bufL, bufR, scspsoundlen);
5223 scspsoundgenpos += scspsoundlen;
5224 scspsoundoutleft += scspsoundlen;
5225 }
5226
5227 while (scspsoundoutleft > 0 &&
5228 (audiosize = SNDCore->GetAudioSpace()) > 0)
5229 {
5230 s32 outstart = (s32)scspsoundgenpos - (s32)scspsoundoutleft;
5231
5232 if (outstart < 0)
5233 outstart += scspsoundbufsize;
5234 if (audiosize > scspsoundoutleft)
5235 audiosize = scspsoundoutleft;
5236 if (audiosize > scspsoundbufsize - outstart)
5237 audiosize = scspsoundbufsize - outstart;
5238
5239 SNDCore->UpdateAudio(&scspchannel[0].data32[outstart],
5240 &scspchannel[1].data32[outstart], audiosize);
5241 scspsoundoutleft -= audiosize;
5242
5243 #if 0
5244 ScspConvert32uto16s(&scspchannel[0].data32[outstart],
5245 &scspchannel[1].data32[outstart],
5246 (s16 *)stereodata16, audiosize);
5247 DRV_AviSoundUpdate(stereodata16, audiosize);
5248 #endif
5249 }
5250
5251 if (!use_new_scsp)
5252 scsp_update_monitor();
5253
5254 #ifdef USE_SCSPMIDI
5255 // Process Midi ports
5256 while (scsp.midincnt < 4)
5257 {
5258 u8 data;
5259 int isdata;
5260
5261 data = SNDCore->MidiIn(&isdata);
5262 if (!isdata)
5263 break;
5264 scsp_midi_in_send(data);
5265 }
5266
5267
5268 while (scsp.midoutcnt)
5269 {
5270 SNDCore->MidiOut(scsp_midi_out_read());
5271 }
5272
5273 #endif
5274 }
5275
5276 //////////////////////////////////////////////////////////////////////////////
5277
5278 void
M68KWriteNotify(u32 address,u32 size)5279 M68KWriteNotify (u32 address, u32 size)
5280 {
5281 M68K->WriteNotify (address, size);
5282 }
5283
5284 //////////////////////////////////////////////////////////////////////////////
5285
5286 void
M68KGetRegisters(m68kregs_struct * regs)5287 M68KGetRegisters (m68kregs_struct *regs)
5288 {
5289 int i;
5290
5291 if (regs != NULL)
5292 {
5293 for (i = 0; i < 8; i++)
5294 {
5295 regs->D[i] = M68K->GetDReg (i);
5296 regs->A[i] = M68K->GetAReg (i);
5297 }
5298
5299 regs->SR = M68K->GetSR ();
5300 regs->PC = M68K->GetPC ();
5301 }
5302 }
5303
5304 //////////////////////////////////////////////////////////////////////////////
5305
5306 void
M68KSetRegisters(m68kregs_struct * regs)5307 M68KSetRegisters (m68kregs_struct *regs)
5308 {
5309 int i;
5310
5311 if (regs != NULL)
5312 {
5313 for (i = 0; i < 8; i++)
5314 {
5315 M68K->SetDReg (i, regs->D[i]);
5316 M68K->SetAReg (i, regs->A[i]);
5317 }
5318
5319 M68K->SetSR (regs->SR);
5320 M68K->SetPC (regs->PC);
5321 }
5322 }
5323
5324 //////////////////////////////////////////////////////////////////////////////
5325
5326 void
ScspMuteAudio(int flags)5327 ScspMuteAudio (int flags)
5328 {
5329 scsp_mute_flags |= flags;
5330 if (SNDCore && scsp_mute_flags)
5331 SNDCore->MuteAudio ();
5332 }
5333
5334 //////////////////////////////////////////////////////////////////////////////
5335
5336 void
ScspUnMuteAudio(int flags)5337 ScspUnMuteAudio (int flags)
5338 {
5339 scsp_mute_flags &= ~flags;
5340 if (SNDCore && (scsp_mute_flags == 0))
5341 SNDCore->UnMuteAudio ();
5342 }
5343
5344 //////////////////////////////////////////////////////////////////////////////
5345
5346 void
ScspSetVolume(int volume)5347 ScspSetVolume (int volume)
5348 {
5349 scsp_volume = volume;
5350 if (SNDCore)
5351 SNDCore->SetVolume (volume);
5352 }
5353
5354 //////////////////////////////////////////////////////////////////////////////
5355
5356 void
M68KSetBreakpointCallBack(void (* func)(u32))5357 M68KSetBreakpointCallBack (void (*func)(u32))
5358 {
5359 ScspInternalVars->BreakpointCallBack = func;
5360 }
5361
5362 //////////////////////////////////////////////////////////////////////////////
5363
5364 int
M68KAddCodeBreakpoint(u32 addr)5365 M68KAddCodeBreakpoint (u32 addr)
5366 {
5367 int i;
5368
5369 if (ScspInternalVars->numcodebreakpoints < MAX_BREAKPOINTS)
5370 {
5371 // Make sure it isn't already on the list
5372 for (i = 0; i < ScspInternalVars->numcodebreakpoints; i++)
5373 {
5374 if (addr == ScspInternalVars->codebreakpoint[i].addr)
5375 return -1;
5376 }
5377
5378 ScspInternalVars->codebreakpoint[i].addr = addr;
5379 ScspInternalVars->numcodebreakpoints++;
5380 m68kexecptr = M68KExecBP;
5381
5382 return 0;
5383 }
5384
5385 return -1;
5386 }
5387
5388 //////////////////////////////////////////////////////////////////////////////
5389
5390 void
M68KSortCodeBreakpoints(void)5391 M68KSortCodeBreakpoints (void)
5392 {
5393 int i, i2;
5394 u32 tmp;
5395
5396 for (i = 0; i < (MAX_BREAKPOINTS - 1); i++)
5397 {
5398 for (i2 = i+1; i2 < MAX_BREAKPOINTS; i2++)
5399 {
5400 if (ScspInternalVars->codebreakpoint[i].addr == 0xFFFFFFFF &&
5401 ScspInternalVars->codebreakpoint[i2].addr != 0xFFFFFFFF)
5402 {
5403 tmp = ScspInternalVars->codebreakpoint[i].addr;
5404 ScspInternalVars->codebreakpoint[i].addr =
5405 ScspInternalVars->codebreakpoint[i2].addr;
5406 ScspInternalVars->codebreakpoint[i2].addr = tmp;
5407 }
5408 }
5409 }
5410 }
5411
5412 //////////////////////////////////////////////////////////////////////////////
5413
5414 int
M68KDelCodeBreakpoint(u32 addr)5415 M68KDelCodeBreakpoint (u32 addr)
5416 {
5417 int i;
5418 if (ScspInternalVars->numcodebreakpoints > 0)
5419 {
5420 for (i = 0; i < ScspInternalVars->numcodebreakpoints; i++)
5421 {
5422 if (ScspInternalVars->codebreakpoint[i].addr == addr)
5423 {
5424 ScspInternalVars->codebreakpoint[i].addr = 0xFFFFFFFF;
5425 M68KSortCodeBreakpoints ();
5426 ScspInternalVars->numcodebreakpoints--;
5427 if (ScspInternalVars->numcodebreakpoints == 0)
5428 m68kexecptr = M68K->Exec;
5429 return 0;
5430 }
5431 }
5432 }
5433
5434 return -1;
5435 }
5436
5437 //////////////////////////////////////////////////////////////////////////////
5438
5439 m68kcodebreakpoint_struct *
M68KGetBreakpointList()5440 M68KGetBreakpointList ()
5441 {
5442 return ScspInternalVars->codebreakpoint;
5443 }
5444
5445 //////////////////////////////////////////////////////////////////////////////
5446
5447 void
M68KClearCodeBreakpoints()5448 M68KClearCodeBreakpoints ()
5449 {
5450 int i;
5451 for (i = 0; i < MAX_BREAKPOINTS; i++)
5452 ScspInternalVars->codebreakpoint[i].addr = 0xFFFFFFFF;
5453
5454 ScspInternalVars->numcodebreakpoints = 0;
5455 }
5456
5457 //////////////////////////////////////////////////////////////////////////////
5458
5459 int
SoundSaveState(FILE * fp)5460 SoundSaveState (FILE *fp)
5461 {
5462 int i;
5463 u32 temp;
5464 int offset;
5465 u8 nextphase;
5466 IOCheck_struct check = { 0, 0 };
5467
5468 offset = StateWriteHeader (fp, "SCSP", 2);
5469
5470 // Save 68k registers first
5471 ywrite (&check, (void *)&IsM68KRunning, 1, 1, fp);
5472
5473 #ifdef IMPROVED_SAVESTATES
5474 M68K->SaveState(fp);
5475 #else
5476 for (i = 0; i < 8; i++)
5477 {
5478 temp = M68K->GetDReg (i);
5479 ywrite (&check, (void *)&temp, 4, 1, fp);
5480 }
5481
5482 for (i = 0; i < 8; i++)
5483 {
5484 temp = M68K->GetAReg (i);
5485 ywrite (&check, (void *)&temp, 4, 1, fp);
5486 }
5487
5488 temp = M68K->GetSR ();
5489 ywrite (&check, (void *)&temp, 4, 1, fp);
5490 temp = M68K->GetPC ();
5491 ywrite (&check, (void *)&temp, 4, 1, fp);
5492 #endif
5493
5494 // Now for the SCSP registers
5495 ywrite (&check, (void *)scsp_reg, 0x1000, 1, fp);
5496
5497 // Sound RAM is important
5498 ywrite (&check, (void *)SoundRam, 0x80000, 1, fp);
5499
5500 // Write slot internal variables
5501 for (i = 0; i < 32; i++)
5502 {
5503 s32 einc;
5504
5505 #ifdef IMPROVED_SAVESTATES
5506 ywrite(&check, (void *)&scsp.slot[i].swe, sizeof(u8), 1, fp);
5507 ywrite(&check, (void *)&scsp.slot[i].sdir, sizeof(u8), 1, fp);
5508 ywrite(&check, (void *)&scsp.slot[i].pcm8b, sizeof(u8), 1, fp);
5509 ywrite(&check, (void *)&scsp.slot[i].sbctl, sizeof(u8), 1, fp);
5510 ywrite(&check, (void *)&scsp.slot[i].ssctl, sizeof(u8), 1, fp);
5511 ywrite(&check, (void *)&scsp.slot[i].lpctl, sizeof(u8), 1, fp);
5512 #endif
5513 ywrite (&check, (void *)&scsp.slot[i].key, 1, 1, fp);
5514 #ifdef IMPROVED_SAVESTATES
5515 ywrite(&check, (void *)&scsp.slot[i].keyx, sizeof(u8), 1, fp);
5516 #endif
5517 //buf8,16 get regenerated on state load
5518
5519 ywrite (&check, (void *)&scsp.slot[i].fcnt, 4, 1, fp);
5520 #ifdef IMPROVED_SAVESTATES
5521 ywrite(&check, (void *)&scsp.slot[i].finc, sizeof(u32), 1, fp);
5522 ywrite(&check, (void *)&scsp.slot[i].finct, sizeof(u32), 1, fp);
5523 #endif
5524 ywrite (&check, (void *)&scsp.slot[i].ecnt, 4, 1, fp);
5525
5526 if (scsp.slot[i].einc == &scsp.slot[i].einca)
5527 einc = 0;
5528 else if (scsp.slot[i].einc == &scsp.slot[i].eincd)
5529 einc = 1;
5530 else if (scsp.slot[i].einc == &scsp.slot[i].eincs)
5531 einc = 2;
5532 else if (scsp.slot[i].einc == &scsp.slot[i].eincr)
5533 einc = 3;
5534 else
5535 einc = 4;
5536
5537 ywrite (&check, (void *)&einc, 4, 1, fp);
5538
5539 //einca,eincd,eincs,eincr
5540
5541 ywrite (&check, (void *)&scsp.slot[i].ecmp, 4, 1, fp);
5542 ywrite (&check, (void *)&scsp.slot[i].ecurp, 4, 1, fp);
5543 #ifdef IMPROVED_SAVESTATES
5544 ywrite(&check, (void *)&scsp.slot[i].env, sizeof(s32), 1, fp);
5545 #endif
5546 if (scsp.slot[i].enxt == scsp_env_null_next)
5547 nextphase = 0;
5548 else if (scsp.slot[i].enxt == scsp_release_next)
5549 nextphase = 1;
5550 else if (scsp.slot[i].enxt == scsp_sustain_next)
5551 nextphase = 2;
5552 else if (scsp.slot[i].enxt == scsp_decay_next)
5553 nextphase = 3;
5554 else if (scsp.slot[i].enxt == scsp_attack_next)
5555 nextphase = 4;
5556 ywrite (&check, (void *)&nextphase, 1, 1, fp);
5557
5558 ywrite (&check, (void *)&scsp.slot[i].lfocnt, 4, 1, fp);
5559 ywrite (&check, (void *)&scsp.slot[i].lfoinc, 4, 1, fp);
5560 #ifdef IMPROVED_SAVESTATES
5561 ywrite(&check, (void *)&scsp.slot[i].sa, sizeof(u32), 1, fp);
5562 ywrite(&check, (void *)&scsp.slot[i].lsa, sizeof(u32), 1, fp);
5563 ywrite(&check, (void *)&scsp.slot[i].lea , sizeof(u32), 1, fp);
5564
5565 ywrite(&check, (void *)&scsp.slot[i].tl, sizeof(s32), 1, fp);
5566 ywrite(&check, (void *)&scsp.slot[i].sl, sizeof(s32), 1, fp);
5567
5568 ywrite(&check, (void *)&scsp.slot[i].ar, sizeof(s32), 1, fp);
5569 ywrite(&check, (void *)&scsp.slot[i].dr, sizeof(s32), 1, fp);
5570 ywrite(&check, (void *)&scsp.slot[i].sr, sizeof(s32), 1, fp);
5571 ywrite(&check, (void *)&scsp.slot[i].rr, sizeof(s32), 1, fp);
5572
5573 //arp
5574 //drp
5575 //srp
5576 //rrp
5577
5578 ywrite(&check, (void *)&scsp.slot[i].krs, sizeof(u32), 1, fp);
5579
5580 //lfofmw
5581 //lfoemw
5582
5583 ywrite(&check, (void *)&scsp.slot[i].lfofms, sizeof(u8), 1, fp);
5584 ywrite(&check, (void *)&scsp.slot[i].lfoems, sizeof(u8), 1, fp);
5585 ywrite(&check, (void *)&scsp.slot[i].fsft, sizeof(u8), 1, fp);
5586
5587 ywrite(&check, (void *)&scsp.slot[i].mdl, sizeof(u8), 1, fp);
5588 ywrite(&check, (void *)&scsp.slot[i].mdx, sizeof(u8), 1, fp);
5589 ywrite(&check, (void *)&scsp.slot[i].mdy, sizeof(u8), 1, fp);
5590
5591 ywrite(&check, (void *)&scsp.slot[i].imxl, sizeof(u8), 1, fp);
5592 ywrite(&check, (void *)&scsp.slot[i].disll, sizeof(u8), 1, fp);
5593 ywrite(&check, (void *)&scsp.slot[i].dislr, sizeof(u8), 1, fp);
5594 ywrite(&check, (void *)&scsp.slot[i].efsll, sizeof(u8), 1, fp);
5595 ywrite(&check, (void *)&scsp.slot[i].efslr, sizeof(u8), 1, fp);
5596
5597 ywrite(&check, (void *)&scsp.slot[i].eghold, sizeof(u8), 1, fp);
5598 ywrite(&check, (void *)&scsp.slot[i].lslnk, sizeof(u8), 1, fp);
5599 #endif
5600 }
5601
5602 // Write main internal variables
5603 ywrite (&check, (void *)&scsp.mem4b, 4, 1, fp);
5604 ywrite (&check, (void *)&scsp.mvol, 4, 1, fp);
5605
5606 ywrite (&check, (void *)&scsp.rbl, 4, 1, fp);
5607 ywrite (&check, (void *)&scsp.rbp, 4, 1, fp);
5608
5609 ywrite (&check, (void *)&scsp.mslc, 4, 1, fp);
5610
5611 ywrite (&check, (void *)&scsp.dmea, 4, 1, fp);
5612 ywrite (&check, (void *)&scsp.drga, 4, 1, fp);
5613 ywrite (&check, (void *)&scsp.dmfl, 4, 1, fp);
5614 ywrite (&check, (void *)&scsp.dmlen, 4, 1, fp);
5615
5616 ywrite (&check, (void *)scsp.midinbuf, 1, 4, fp);
5617 ywrite (&check, (void *)scsp.midoutbuf, 1, 4, fp);
5618 ywrite (&check, (void *)&scsp.midincnt, 1, 1, fp);
5619 ywrite (&check, (void *)&scsp.midoutcnt, 1, 1, fp);
5620 ywrite (&check, (void *)&scsp.midflag, 1, 1, fp);
5621
5622 ywrite (&check, (void *)&scsp.timacnt, 4, 1, fp);
5623 ywrite (&check, (void *)&scsp.timasd, 4, 1, fp);
5624 ywrite (&check, (void *)&scsp.timbcnt, 4, 1, fp);
5625 ywrite (&check, (void *)&scsp.timbsd, 4, 1, fp);
5626 ywrite (&check, (void *)&scsp.timccnt, 4, 1, fp);
5627 ywrite (&check, (void *)&scsp.timcsd, 4, 1, fp);
5628
5629 ywrite (&check, (void *)&scsp.scieb, 4, 1, fp);
5630 ywrite (&check, (void *)&scsp.scipd, 4, 1, fp);
5631 ywrite (&check, (void *)&scsp.scilv0, 4, 1, fp);
5632 ywrite (&check, (void *)&scsp.scilv1, 4, 1, fp);
5633 ywrite (&check, (void *)&scsp.scilv2, 4, 1, fp);
5634 ywrite (&check, (void *)&scsp.mcieb, 4, 1, fp);
5635 ywrite (&check, (void *)&scsp.mcipd, 4, 1, fp);
5636
5637 ywrite (&check, (void *)scsp.stack, 4, 32 * 2, fp);
5638
5639 return StateFinishHeader (fp, offset);
5640 }
5641
5642 //////////////////////////////////////////////////////////////////////////////
5643
5644 int
SoundLoadState(FILE * fp,int version,int size)5645 SoundLoadState (FILE *fp, int version, int size)
5646 {
5647 int i, i2;
5648 u32 temp;
5649 u8 nextphase;
5650 IOCheck_struct check = { 0, 0 };
5651
5652 // Read 68k registers first
5653 yread (&check, (void *)&IsM68KRunning, 1, 1, fp);
5654
5655 #ifdef IMPROVED_SAVESTATES
5656 M68K->LoadState(fp);
5657 #else
5658 for (i = 0; i < 8; i++)
5659 {
5660 yread (&check, (void *)&temp, 4, 1, fp);
5661 M68K->SetDReg (i, temp);
5662 }
5663
5664 for (i = 0; i < 8; i++)
5665 {
5666 yread (&check, (void *)&temp, 4, 1, fp);
5667 M68K->SetAReg (i, temp);
5668 }
5669
5670 yread (&check, (void *)&temp, 4, 1, fp);
5671 M68K->SetSR (temp);
5672 yread (&check, (void *)&temp, 4, 1, fp);
5673 M68K->SetPC (temp);
5674 #endif
5675
5676 // Now for the SCSP registers
5677 yread (&check, (void *)scsp_reg, 0x1000, 1, fp);
5678
5679 // Lastly, sound ram
5680 yread (&check, (void *)SoundRam, 0x80000, 1, fp);
5681
5682 if (version > 1)
5683 {
5684 // Internal variables need to be regenerated
5685 for(i = 0; i < 32; i++)
5686 {
5687 for (i2 = 0; i2 < 0x20; i2+=2)
5688 scsp_slot_set_w (i, 0x1E - i2, scsp_slot_get_w (i, 0x1E - i2));
5689 }
5690
5691 scsp_set_w (0x402, scsp_get_w (0x402));
5692
5693 // Read slot internal variables
5694 for (i = 0; i < 32; i++)
5695 {
5696 s32 einc;
5697 #ifdef IMPROVED_SAVESTATES
5698 yread(&check, (void *)&scsp.slot[i].swe, sizeof(u8), 1, fp);
5699 yread(&check, (void *)&scsp.slot[i].sdir, sizeof(u8), 1, fp);
5700 yread(&check, (void *)&scsp.slot[i].pcm8b, sizeof(u8), 1, fp);
5701
5702 yread(&check, (void *)&scsp.slot[i].sbctl, sizeof(u8), 1, fp);
5703 yread(&check, (void *)&scsp.slot[i].ssctl, sizeof(u8), 1, fp);
5704 yread(&check, (void *)&scsp.slot[i].lpctl, sizeof(u8), 1, fp);
5705 #endif
5706 yread (&check, (void *)&scsp.slot[i].key, 1, 1, fp);
5707 #ifdef IMPROVED_SAVESTATES
5708 yread(&check, (void *)&scsp.slot[i].keyx, sizeof(u8), 1, fp);
5709 #endif
5710 //buf8,16 regenerated at end
5711
5712 yread (&check, (void *)&scsp.slot[i].fcnt, 4, 1, fp);
5713 #ifdef IMPROVED_SAVESTATES
5714 yread(&check, (void *)&scsp.slot[i].finc, sizeof(u32), 1, fp);
5715 yread(&check, (void *)&scsp.slot[i].finct, sizeof(u32), 1, fp);
5716 #endif
5717 yread (&check, (void *)&scsp.slot[i].ecnt, 4, 1, fp);
5718
5719 yread (&check, (void *)&einc, 4, 1, fp);
5720 switch (einc)
5721 {
5722 case 0:
5723 scsp.slot[i].einc = &scsp.slot[i].einca;
5724 break;
5725 case 1:
5726 scsp.slot[i].einc = &scsp.slot[i].eincd;
5727 break;
5728 case 2:
5729 scsp.slot[i].einc = &scsp.slot[i].eincs;
5730 break;
5731 case 3:
5732 scsp.slot[i].einc = &scsp.slot[i].eincr;
5733 break;
5734 default:
5735 scsp.slot[i].einc = NULL;
5736 break;
5737 }
5738
5739 //einca,eincd,eincs,eincr
5740
5741 yread (&check, (void *)&scsp.slot[i].ecmp, 4, 1, fp);
5742 yread (&check, (void *)&scsp.slot[i].ecurp, 4, 1, fp);
5743 #ifdef IMPROVED_SAVESTATES
5744 yread(&check, (void *)&scsp.slot[i].env, sizeof(s32), 1, fp);
5745 #endif
5746 yread (&check, (void *)&nextphase, 1, 1, fp);
5747 switch (nextphase)
5748 {
5749 case 0:
5750 scsp.slot[i].enxt = scsp_env_null_next;
5751 break;
5752 case 1:
5753 scsp.slot[i].enxt = scsp_release_next;
5754 break;
5755 case 2:
5756 scsp.slot[i].enxt = scsp_sustain_next;
5757 break;
5758 case 3:
5759 scsp.slot[i].enxt = scsp_decay_next;
5760 break;
5761 case 4:
5762 scsp.slot[i].enxt = scsp_attack_next;
5763 break;
5764 default: break;
5765 }
5766
5767 yread (&check, (void *)&scsp.slot[i].lfocnt, 4, 1, fp);
5768 yread (&check, (void *)&scsp.slot[i].lfoinc, 4, 1, fp);
5769
5770 #ifdef IMPROVED_SAVESTATES
5771 yread(&check, (void *)&scsp.slot[i].sa, sizeof(u32), 1, fp);
5772 yread(&check, (void *)&scsp.slot[i].lsa, sizeof(u32), 1, fp);
5773 yread(&check, (void *)&scsp.slot[i].lea, sizeof(u32), 1, fp);
5774
5775 yread(&check, (void *)&scsp.slot[i].tl, sizeof(s32), 1, fp);
5776 yread(&check, (void *)&scsp.slot[i].sl, sizeof(s32), 1, fp);
5777
5778 yread(&check, (void *)&scsp.slot[i].ar, sizeof(s32), 1, fp);
5779 yread(&check, (void *)&scsp.slot[i].dr, sizeof(s32), 1, fp);
5780 yread(&check, (void *)&scsp.slot[i].sr, sizeof(s32), 1, fp);
5781 yread(&check, (void *)&scsp.slot[i].rr, sizeof(s32), 1, fp);
5782
5783 //arp
5784 //drp
5785 //srp
5786 //rrp
5787
5788 yread(&check, (void *)&scsp.slot[i].krs, sizeof(u32), 1, fp);
5789
5790 //lfofmw
5791 //lfoemw
5792
5793 yread(&check, (void *)&scsp.slot[i].lfofms, sizeof(u8), 1, fp);
5794 yread(&check, (void *)&scsp.slot[i].lfoems, sizeof(u8), 1, fp);
5795 yread(&check, (void *)&scsp.slot[i].fsft, sizeof(u8), 1, fp);
5796
5797 yread(&check, (void *)&scsp.slot[i].mdl, sizeof(u8), 1, fp);
5798 yread(&check, (void *)&scsp.slot[i].mdx, sizeof(u8), 1, fp);
5799 yread(&check, (void *)&scsp.slot[i].mdy, sizeof(u8), 1, fp);
5800
5801 yread(&check, (void *)&scsp.slot[i].imxl, sizeof(u8), 1, fp);
5802 yread(&check, (void *)&scsp.slot[i].disll, sizeof(u8), 1, fp);
5803 yread(&check, (void *)&scsp.slot[i].dislr, sizeof(u8), 1, fp);
5804 yread(&check, (void *)&scsp.slot[i].efsll, sizeof(u8), 1, fp);
5805 yread(&check, (void *)&scsp.slot[i].efslr, sizeof(u8), 1, fp);
5806
5807 yread(&check, (void *)&scsp.slot[i].eghold, sizeof(u8), 1, fp);
5808 yread(&check, (void *)&scsp.slot[i].lslnk, sizeof(u8), 1, fp);
5809 #endif
5810
5811 // depends on pcm8b, sa, lea being loaded first
5812 // Rebuild the buf8/buf16 variables
5813 if (scsp.slot[i].pcm8b)
5814 {
5815 scsp.slot[i].buf8 = (s8*)&(scsp.scsp_ram[scsp.slot[i].sa]);
5816 if ((scsp.slot[i].sa + (scsp.slot[i].lea >> SCSP_FREQ_LB)) >
5817 SCSP_RAM_MASK)
5818 scsp.slot[i].lea = (SCSP_RAM_MASK - scsp.slot[i].sa) <<
5819 SCSP_FREQ_LB;
5820 }
5821 else
5822 {
5823 scsp.slot[i].buf16 = (s16*)&(scsp.scsp_ram[scsp.slot[i].sa & ~1]);
5824 if ((scsp.slot[i].sa + (scsp.slot[i].lea >> (SCSP_FREQ_LB - 1))) >
5825 SCSP_RAM_MASK)
5826 scsp.slot[i].lea = (SCSP_RAM_MASK - scsp.slot[i].sa) <<
5827 (SCSP_FREQ_LB - 1);
5828 }
5829 }
5830
5831 // Read main internal variables
5832 yread (&check, (void *)&scsp.mem4b, 4, 1, fp);
5833 yread (&check, (void *)&scsp.mvol, 4, 1, fp);
5834
5835 yread (&check, (void *)&scsp.rbl, 4, 1, fp);
5836 yread (&check, (void *)&scsp.rbp, 4, 1, fp);
5837
5838 yread (&check, (void *)&scsp.mslc, 4, 1, fp);
5839
5840 yread (&check, (void *)&scsp.dmea, 4, 1, fp);
5841 yread (&check, (void *)&scsp.drga, 4, 1, fp);
5842 yread (&check, (void *)&scsp.dmfl, 4, 1, fp);
5843 yread (&check, (void *)&scsp.dmlen, 4, 1, fp);
5844
5845 yread (&check, (void *)scsp.midinbuf, 1, 4, fp);
5846 yread (&check, (void *)scsp.midoutbuf, 1, 4, fp);
5847 yread (&check, (void *)&scsp.midincnt, 1, 1, fp);
5848 yread (&check, (void *)&scsp.midoutcnt, 1, 1, fp);
5849 yread (&check, (void *)&scsp.midflag, 1, 1, fp);
5850
5851 yread (&check, (void *)&scsp.timacnt, 4, 1, fp);
5852 yread (&check, (void *)&scsp.timasd, 4, 1, fp);
5853 yread (&check, (void *)&scsp.timbcnt, 4, 1, fp);
5854 yread (&check, (void *)&scsp.timbsd, 4, 1, fp);
5855 yread (&check, (void *)&scsp.timccnt, 4, 1, fp);
5856 yread (&check, (void *)&scsp.timcsd, 4, 1, fp);
5857
5858 yread (&check, (void *)&scsp.scieb, 4, 1, fp);
5859 yread (&check, (void *)&scsp.scipd, 4, 1, fp);
5860 yread (&check, (void *)&scsp.scilv0, 4, 1, fp);
5861 yread (&check, (void *)&scsp.scilv1, 4, 1, fp);
5862 yread (&check, (void *)&scsp.scilv2, 4, 1, fp);
5863 yread (&check, (void *)&scsp.mcieb, 4, 1, fp);
5864 yread (&check, (void *)&scsp.mcipd, 4, 1, fp);
5865
5866 yread (&check, (void *)scsp.stack, 4, 32 * 2, fp);
5867 }
5868
5869 return size;
5870 }
5871
5872 //////////////////////////////////////////////////////////////////////////////
5873
5874 static char *
AddSoundLFO(char * outstring,const char * string,u16 level,u16 waveform)5875 AddSoundLFO (char *outstring, const char *string, u16 level, u16 waveform)
5876 {
5877 if (level > 0)
5878 {
5879 switch (waveform)
5880 {
5881 case 0:
5882 AddString(outstring, "%s Sawtooth\r\n", string);
5883 break;
5884 case 1:
5885 AddString(outstring, "%s Square\r\n", string);
5886 break;
5887 case 2:
5888 AddString(outstring, "%s Triangle\r\n", string);
5889 break;
5890 case 3:
5891 AddString(outstring, "%s Noise\r\n", string);
5892 break;
5893 }
5894 }
5895
5896 return outstring;
5897 }
5898
5899 //////////////////////////////////////////////////////////////////////////////
5900
5901 static char *
AddSoundPan(char * outstring,u16 pan)5902 AddSoundPan (char *outstring, u16 pan)
5903 {
5904 if (pan == 0x0F)
5905 {
5906 AddString(outstring, "Left = -MAX dB, Right = -0 dB\r\n");
5907 }
5908 else if (pan == 0x1F)
5909 {
5910 AddString(outstring, "Left = -0 dB, Right = -MAX dB\r\n");
5911 }
5912 else
5913 {
5914 AddString(outstring, "Left = -%d dB, Right = -%d dB\r\n", (pan & 0xF) * 3, (pan >> 4) * 3);
5915 }
5916
5917 return outstring;
5918 }
5919
5920 //////////////////////////////////////////////////////////////////////////////
5921
5922 static char *
AddSoundLevel(char * outstring,u16 level)5923 AddSoundLevel (char *outstring, u16 level)
5924 {
5925 if (level == 0)
5926 {
5927 AddString(outstring, "-MAX dB\r\n");
5928 }
5929 else
5930 {
5931 AddString(outstring, "-%d dB\r\n", (7-level) * 6);
5932 }
5933
5934 return outstring;
5935 }
5936
5937 //////////////////////////////////////////////////////////////////////////////
5938
5939 void
ScspSlotDebugStats(u8 slotnum,char * outstring)5940 ScspSlotDebugStats (u8 slotnum, char *outstring)
5941 {
5942 u32 slotoffset = slotnum * 0x20;
5943
5944 AddString (outstring, "Sound Source = ");
5945 switch (scsp.slot[slotnum].ssctl)
5946 {
5947 case 0:
5948 AddString (outstring, "External DRAM data\r\n");
5949 break;
5950 case 1:
5951 AddString (outstring, "Internal(Noise)\r\n");
5952 break;
5953 case 2:
5954 AddString (outstring, "Internal(0's)\r\n");
5955 break;
5956 default:
5957 AddString (outstring, "Invalid setting\r\n");
5958 break;
5959 }
5960
5961 AddString (outstring, "Source bit = ");
5962 switch(scsp.slot[slotnum].sbctl)
5963 {
5964 case 0:
5965 AddString (outstring, "No bit reversal\r\n");
5966 break;
5967 case 1:
5968 AddString (outstring, "Reverse other bits\r\n");
5969 break;
5970 case 2:
5971 AddString (outstring, "Reverse sign bit\r\n");
5972 break;
5973 case 3:
5974 AddString (outstring, "Reverse sign and other bits\r\n");
5975 break;
5976 }
5977
5978 // Loop Control
5979 AddString (outstring, "Loop Mode = ");
5980 switch (scsp.slot[slotnum].lpctl)
5981 {
5982 case 0:
5983 AddString (outstring, "Off\r\n");
5984 break;
5985 case 1:
5986 AddString (outstring, "Normal\r\n");
5987 break;
5988 case 2:
5989 AddString (outstring, "Reverse\r\n");
5990 break;
5991 case 3:
5992 AddString (outstring, "Alternating\r\n");
5993 break;
5994 }
5995
5996 // PCM8B
5997 // NOTE: Need curly braces here, as AddString is a macro.
5998 if (scsp.slot[slotnum].pcm8b)
5999 {
6000 AddString (outstring, "8-bit samples\r\n");
6001 }
6002 else
6003 {
6004 AddString (outstring, "16-bit samples\r\n");
6005 }
6006
6007 AddString (outstring, "Start Address = %05lX\r\n", (unsigned long)scsp.slot[slotnum].sa);
6008 AddString (outstring, "Loop Start Address = %04lX\r\n", (unsigned long)scsp.slot[slotnum].lsa >> SCSP_FREQ_LB);
6009 AddString (outstring, "Loop End Address = %04lX\r\n", (unsigned long)scsp.slot[slotnum].lea >> SCSP_FREQ_LB);
6010 AddString (outstring, "Decay 1 Rate = %ld\r\n", (unsigned long)scsp.slot[slotnum].dr);
6011 AddString (outstring, "Decay 2 Rate = %ld\r\n", (unsigned long)scsp.slot[slotnum].sr);
6012 if (scsp.slot[slotnum].eghold)
6013 AddString (outstring, "EG Hold Enabled\r\n");
6014 AddString (outstring, "Attack Rate = %ld\r\n", (unsigned long)scsp.slot[slotnum].ar);
6015
6016 if (scsp.slot[slotnum].lslnk)
6017 AddString (outstring, "Loop Start Link Enabled\r\n");
6018
6019 if (scsp.slot[slotnum].krs != 0)
6020 AddString (outstring, "Key rate scaling = %ld\r\n", (unsigned long)scsp.slot[slotnum].krs);
6021
6022 AddString (outstring, "Decay Level = %d\r\n", (scsp_r_w(slotoffset + 0xA) >> 5) & 0x1F);
6023 AddString (outstring, "Release Rate = %ld\r\n", (unsigned long)scsp.slot[slotnum].rr);
6024
6025 if (scsp.slot[slotnum].swe)
6026 AddString (outstring, "Stack Write Inhibited\r\n");
6027
6028 if (scsp.slot[slotnum].sdir)
6029 AddString (outstring, "Sound Direct Enabled\r\n");
6030
6031 AddString (outstring, "Total Level = %ld\r\n", (unsigned long)scsp.slot[slotnum].tl);
6032
6033 AddString (outstring, "Modulation Level = %d\r\n", scsp.slot[slotnum].mdl);
6034 AddString (outstring, "Modulation Input X = %d\r\n", scsp.slot[slotnum].mdx);
6035 AddString (outstring, "Modulation Input Y = %d\r\n", scsp.slot[slotnum].mdy);
6036
6037 AddString (outstring, "Octave = %d\r\n", (scsp_r_w(slotoffset + 0x10) >> 11) & 0xF);
6038 AddString (outstring, "Frequency Number Switch = %d\r\n", scsp_r_w(slotoffset + 0x10) & 0x3FF);
6039
6040 AddString (outstring, "LFO Reset = %s\r\n", ((scsp_r_w(slotoffset + 0x12) >> 15) & 0x1) ? "TRUE" : "FALSE");
6041 AddString (outstring, "LFO Frequency = %d\r\n", (scsp_r_w(slotoffset + 0x12) >> 10) & 0x1F);
6042 outstring = AddSoundLFO (outstring, "LFO Frequency modulation waveform = ",
6043 (scsp_r_w(slotoffset + 0x12) >> 5) & 0x7,
6044 (scsp_r_w(slotoffset + 0x12) >> 8) & 0x3);
6045 AddString (outstring, "LFO Frequency modulation level = %d\r\n", (scsp_r_w(slotoffset + 0x12) >> 5) & 0x7);
6046 outstring = AddSoundLFO (outstring, "LFO Amplitude modulation waveform = ",
6047 scsp_r_w(slotoffset + 0x12) & 0x7,
6048 (scsp_r_w(slotoffset + 0x12) >> 3) & 0x3);
6049 AddString (outstring, "LFO Amplitude modulation level = %d\r\n", scsp_r_w(slotoffset + 0x12) & 0x7);
6050
6051 AddString (outstring, "Input mix level = ");
6052 outstring = AddSoundLevel (outstring, scsp_r_w(slotoffset + 0x14) & 0x7);
6053 AddString (outstring, "Input Select = %d\r\n", (scsp_r_w(slotoffset + 0x14) >> 3) & 0x1F);
6054
6055 AddString (outstring, "Direct data send level = ");
6056 outstring = AddSoundLevel (outstring, (scsp_r_w(slotoffset + 0x16) >> 13) & 0x7);
6057 AddString (outstring, "Direct data panpot = ");
6058 outstring = AddSoundPan (outstring, (scsp_r_w(slotoffset + 0x16) >> 8) & 0x1F);
6059
6060 AddString (outstring, "Effect data send level = ");
6061 outstring = AddSoundLevel (outstring, (scsp_r_w(slotoffset + 0x16) >> 5) & 0x7);
6062 AddString (outstring, "Effect data panpot = ");
6063 outstring = AddSoundPan (outstring, scsp_r_w(slotoffset + 0x16) & 0x1F);
6064 }
6065
6066 //////////////////////////////////////////////////////////////////////////////
6067
6068 void
ScspCommonControlRegisterDebugStats(char * outstring)6069 ScspCommonControlRegisterDebugStats (char *outstring)
6070 {
6071 AddString (outstring, "Memory: %s\r\n", scsp.mem4b ? "4 Mbit" : "2 Mbit");
6072 AddString (outstring, "Master volume: %ld\r\n", (unsigned long)scsp.mvol);
6073 AddString (outstring, "Ring buffer length: %ld\r\n", (unsigned long)scsp.rbl);
6074 AddString (outstring, "Ring buffer address: %08lX\r\n", (unsigned long)scsp.rbp);
6075 AddString (outstring, "\r\n");
6076
6077 AddString (outstring, "Slot Status Registers\r\n");
6078 AddString (outstring, "-----------------\r\n");
6079 AddString (outstring, "Monitor slot: %ld\r\n", (unsigned long)scsp.mslc);
6080 AddString (outstring, "Call address: %ld\r\n", (unsigned long)scsp.ca);
6081 AddString (outstring, "\r\n");
6082
6083 AddString (outstring, "DMA Registers\r\n");
6084 AddString (outstring, "-----------------\r\n");
6085 AddString (outstring, "DMA memory address start: %08lX\r\n", (unsigned long)scsp.dmea);
6086 AddString (outstring, "DMA register address start: %08lX\r\n", (unsigned long)scsp.drga);
6087 AddString (outstring, "DMA Flags: %lX\r\n", (unsigned long)scsp.dmlen);
6088 AddString (outstring, "\r\n");
6089
6090 AddString (outstring, "Timer Registers\r\n");
6091 AddString (outstring, "-----------------\r\n");
6092 AddString (outstring, "Timer A counter: %02lX\r\n", (unsigned long)scsp.timacnt >> 8);
6093 AddString (outstring, "Timer A increment: Every %d sample(s)\r\n", (int)pow(2, (double)scsp.timasd));
6094 AddString (outstring, "Timer B counter: %02lX\r\n", (unsigned long)scsp.timbcnt >> 8);
6095 AddString (outstring, "Timer B increment: Every %d sample(s)\r\n", (int)pow(2, (double)scsp.timbsd));
6096 AddString (outstring, "Timer C counter: %02lX\r\n", (unsigned long)scsp.timccnt >> 8);
6097 AddString (outstring, "Timer C increment: Every %d sample(s)\r\n", (int)pow(2, (double)scsp.timcsd));
6098 AddString (outstring, "\r\n");
6099
6100 AddString (outstring, "Interrupt Registers\r\n");
6101 AddString (outstring, "-----------------\r\n");
6102 AddString (outstring, "Sound cpu interrupt pending: %04lX\r\n", (unsigned long)scsp.scipd);
6103 AddString (outstring, "Sound cpu interrupt enable: %04lX\r\n", (unsigned long)scsp.scieb);
6104 AddString (outstring, "Sound cpu interrupt level 0: %04lX\r\n", (unsigned long)scsp.scilv0);
6105 AddString (outstring, "Sound cpu interrupt level 1: %04lX\r\n", (unsigned long)scsp.scilv1);
6106 AddString (outstring, "Sound cpu interrupt level 2: %04lX\r\n", (unsigned long)scsp.scilv2);
6107 AddString (outstring, "Main cpu interrupt pending: %04lX\r\n", (unsigned long)scsp.mcipd);
6108 AddString (outstring, "Main cpu interrupt enable: %04lX\r\n", (unsigned long)scsp.mcieb);
6109 AddString (outstring, "\r\n");
6110 }
6111
6112 //////////////////////////////////////////////////////////////////////////////
6113
6114 int
ScspSlotDebugSaveRegisters(u8 slotnum,const char * filename)6115 ScspSlotDebugSaveRegisters (u8 slotnum, const char *filename)
6116 {
6117 FILE *fp;
6118 int i;
6119 IOCheck_struct check = { 0, 0 };
6120
6121 if ((fp = fopen (filename, "wb")) == NULL)
6122 return -1;
6123
6124 for (i = (slotnum * 0x20); i < ((slotnum+1) * 0x20); i += 2)
6125 {
6126 #ifdef WORDS_BIGENDIAN
6127 ywrite (&check, (void *)&scsp_isr[i ^ 2], 1, 2, fp);
6128 #else
6129 ywrite (&check, (void *)&scsp_isr[(i + 1) ^ 2], 1, 1, fp);
6130 ywrite (&check, (void *)&scsp_isr[i ^ 2], 1, 1, fp);
6131 #endif
6132 }
6133
6134 fclose (fp);
6135 return 0;
6136 }
6137
6138 //////////////////////////////////////////////////////////////////////////////
6139
6140 static slot_t debugslot;
6141
6142 u32
ScspSlotDebugAudio(u32 * workbuf,s16 * buf,u32 len)6143 ScspSlotDebugAudio (u32 *workbuf, s16 *buf, u32 len)
6144 {
6145 u32 *bufL, *bufR;
6146
6147 bufL = workbuf;
6148 bufR = workbuf+len;
6149 scsp_bufL = (s32 *)bufL;
6150 scsp_bufR = (s32 *)bufR;
6151
6152 if (debugslot.ecnt >= SCSP_ENV_DE)
6153 {
6154 // envelope null...
6155 memset (buf, 0, sizeof(s16) * 2 * len);
6156 return 0;
6157 }
6158
6159 if (debugslot.ssctl)
6160 {
6161 memset (buf, 0, sizeof(s16) * 2 * len);
6162 return 0; // not yet supported!
6163 }
6164
6165 scsp_buf_len = len;
6166 scsp_buf_pos = 0;
6167
6168 // take effect sound volume if no direct sound volume...
6169 if ((debugslot.disll == 31) && (debugslot.dislr == 31))
6170 {
6171 debugslot.disll = debugslot.efsll;
6172 debugslot.dislr = debugslot.efslr;
6173 }
6174
6175 memset (bufL, 0, sizeof(u32) * len);
6176 memset (bufR, 0, sizeof(u32) * len);
6177 scsp_slot_update_p[(debugslot.lfofms == 31)?0:1]
6178 [(debugslot.lfoems == 31)?0:1]
6179 [(debugslot.pcm8b == 0)?1:0]
6180 [(debugslot.disll == 31)?0:1]
6181 [(debugslot.dislr == 31)?0:1](&debugslot);
6182 ScspConvert32uto16s ((s32 *)bufL, (s32 *)bufR, (s16 *)buf, len);
6183
6184 return len;
6185 }
6186
6187 //////////////////////////////////////////////////////////////////////////////
6188
6189 typedef struct
6190 {
6191 char id[4];
6192 u32 size;
6193 } chunk_struct;
6194
6195 typedef struct
6196 {
6197 chunk_struct riff;
6198 char rifftype[4];
6199 } waveheader_struct;
6200
6201 typedef struct
6202 {
6203 chunk_struct chunk;
6204 u16 compress;
6205 u16 numchan;
6206 u32 rate;
6207 u32 bytespersec;
6208 u16 blockalign;
6209 u16 bitspersample;
6210 } fmt_struct;
6211
6212 //////////////////////////////////////////////////////////////////////////////
6213
6214 void
ScspSlotResetDebug(u8 slotnum)6215 ScspSlotResetDebug(u8 slotnum)
6216 {
6217 memcpy (&debugslot, &scsp.slot[slotnum], sizeof(slot_t));
6218
6219 // Clear out the phase counter, etc.
6220 debugslot.fcnt = 0;
6221 debugslot.ecnt = SCSP_ENV_AS;
6222 debugslot.einc = &debugslot.einca;
6223 debugslot.ecmp = SCSP_ENV_AE;
6224 debugslot.ecurp = SCSP_ENV_ATTACK;
6225 debugslot.enxt = scsp_attack_next;
6226 }
6227
6228 //////////////////////////////////////////////////////////////////////////////
6229
6230 int
ScspSlotDebugAudioSaveWav(u8 slotnum,const char * filename)6231 ScspSlotDebugAudioSaveWav (u8 slotnum, const char *filename)
6232 {
6233 u32 workbuf[512*2*2];
6234 s16 buf[512*2];
6235 FILE *fp;
6236 u32 counter = 0;
6237 waveheader_struct waveheader;
6238 fmt_struct fmt;
6239 chunk_struct data;
6240 long length;
6241 IOCheck_struct check = { 0, 0 };
6242
6243 if (scsp.slot[slotnum].lea == 0)
6244 return 0;
6245
6246 if ((fp = fopen (filename, "wb")) == NULL)
6247 return -1;
6248
6249 // Do wave header
6250 memcpy (waveheader.riff.id, "RIFF", 4);
6251 waveheader.riff.size = 0; // we'll fix this after the file is closed
6252 memcpy (waveheader.rifftype, "WAVE", 4);
6253 ywrite (&check, (void *)&waveheader, 1, sizeof(waveheader_struct), fp);
6254
6255 // fmt chunk
6256 memcpy (fmt.chunk.id, "fmt ", 4);
6257 fmt.chunk.size = 16; // we'll fix this at the end
6258 fmt.compress = 1; // PCM
6259 fmt.numchan = 2; // Stereo
6260 fmt.rate = 44100;
6261 fmt.bitspersample = 16;
6262 fmt.blockalign = fmt.bitspersample / 8 * fmt.numchan;
6263 fmt.bytespersec = fmt.rate * fmt.blockalign;
6264 ywrite (&check, (void *)&fmt, 1, sizeof(fmt_struct), fp);
6265
6266 // data chunk
6267 memcpy (data.id, "data", 4);
6268 data.size = 0; // we'll fix this at the end
6269 ywrite (&check, (void *)&data, 1, sizeof(chunk_struct), fp);
6270
6271 ScspSlotResetDebug(slotnum);
6272
6273 // Mix the audio, and then write it to the file
6274 for (;;)
6275 {
6276 if (ScspSlotDebugAudio (workbuf, buf, 512) == 0)
6277 break;
6278
6279 counter += 512;
6280 ywrite (&check, (void *)buf, 2, 512 * 2, fp);
6281 if (debugslot.lpctl != 0 && counter >= (44100 * 2 * 5))
6282 break;
6283 }
6284
6285 length = ftell (fp);
6286
6287 // Let's fix the riff chunk size and the data chunk size
6288 fseek (fp, sizeof(waveheader_struct)-0x8, SEEK_SET);
6289 length -= 0x4;
6290 ywrite (&check, (void *)&length, 1, 4, fp);
6291
6292 fseek (fp, sizeof(waveheader_struct) + sizeof(fmt_struct) + 0x4, SEEK_SET);
6293 length -= sizeof(waveheader_struct) + sizeof(fmt_struct);
6294 ywrite (&check, (void *)&length, 1, 4, fp);
6295 fclose (fp);
6296
6297 return 0;
6298 }
6299
6300 //////////////////////////////////////////////////////////////////////////////
6301