1 /* src/scsp2.c: New, threadable SCSP implementation for Yabause
2 Copyright 2004 Stephane Dallongeville
3 Copyright 2004-2007 Theo Berkau
4 Copyright 2006 Guillaume Duhamel
5 Copyright 2010 Andrew Church
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 #include "core.h"
25 #include "debug.h"
26 #include "error.h"
27 #include "m68kcore.h"
28 #include "memory.h"
29 #include "scsp.h"
30 #include "threads.h"
31 #include "yabause.h"
32
33 #include <math.h>
34 #include <stdlib.h>
35
36 #undef round // In case math.h defines it
37 #define round(x) ((int) (floor((x) + 0.5)))
38
39 #undef ScspInit // Disable compatibility alias
40
41 extern SoundInterface_struct *SNDCoreList[]; // Defined by each port
42
43 ///////////////////////////////////////////////////////////////////////////
44
45 // This SCSP implementation is designed to be runnable as an independent
46 // thread, encompassing the SCSP emulation itself as well as the MC68EC000
47 // sound processor and the actual generation of PCM audio data.
48 //
49 // When running in multithreaded mode, the actual SCSP and M68K emulation
50 // is performed via ScspThread(). This function is started as a subthread
51 // (YAB_THREAD_SCSP), and loops over ScspDoExec() until scsp_thread_running
52 // goes to zero, which is used as a signal for the thread to stop.
53 // Synchronization is performed via the scsp_clock_target variable; the SCSP
54 // thread sleeps until clock_target != clock, then calls ScspDoExec() for
55 // (clock - clock_target) cycles. The main thread wakes up the subthread
56 // both when clock_target is updated and when register writes, discussed
57 // below, are submitted.
58 //
59 // Additionally, any register writes from outside the SCSP/M68K will be
60 // processed synchronously in multithreaded mode, by passing the write
61 // through a shared buffer (scsp_write_buffer_* variables). When the
62 // thread loop detects scsp_write_buffer_size nonzero, it processes the
63 // write before its next ScspDoExec() iteration and clears ..._size; the
64 // main thread then waits for ..._size to return to zero before returning
65 // from the write operation. (This will typically be no more expensive
66 // than a pair of context switches, and it seems that SCSP register writes
67 // from the SH-2 are uncommon.)
68 //
69 // The "PSP_*" macros scattered throughout the file are to support the
70 // execution of the SCSP thread on the Media Engine CPU (ME) in the PSP.
71 // The ME lacks cache coherence with the main CPU (SC), so special care
72 // needs to be taken to avoid bugs arising from inconsistent cache states;
73 // see the technical notes in README.PSP for details. These macros are all
74 // no-ops on other platforms.
75
76 //-------------------------------------------------------------------------
77 // PSP cache management macros
78
79 #ifdef PSP
80
81 # include "psp/common.h"
82 # include "psp/me.h"
83 # include "psp/me-utility.h"
84 # include "psp/misc.h" // psp_writeback_cache_for_scsp() declaration
85
86 // Data section management (to avoid cache line collisions between CPUs)
87 # define PSP_SECTION(name) \
88 __attribute__((section(".meshared.scsp." #name)))
89 # define PSP_SECTION_START(name) \
90 __attribute__((section(".meshared.scsp." #name), aligned(64))) \
91 extern volatile char __scsp_sectstart_##name[64];
92 # define PSP_SECTION_END(name) \
93 __attribute__((section(".meshared.scsp." #name))) \
94 extern volatile char __scsp_sectend_##name;
95
96 // Cache control
97 # define PSP_WRITEBACK_CACHE(ptr,len) \
98 sceKernelDcacheWritebackRange((ptr), (len))
99 # define PSP_WRITEBACK_ALL() \
100 sceKernelDcacheWritebackAll()
101 # define PSP_FLUSH_ALL() \
102 sceKernelDcacheWritebackInvalidateAll()
103
104 // Uncached pointer access
105 # define PSP_UCPTR(ptr) ((typeof(&*ptr))((uint32_t)(ptr) | 0x40000000))
106 // Uncached variable access (either read or write)
107 # define PSP_UC(var) (*((typeof(&var))((uint32_t)(&var) | 0x40000000)))
108
109 #else // !PSP
110
111 # define PSP_SECTION(name) /*nothing*/
112 # define PSP_SECTION_START(name) /*nothing*/
113 # define PSP_SECTION_END(name) /*nothing*/
114 # define PSP_WRITEBACK_CACHE(ptr,len) /*nothing*/
115 # define PSP_WRITEBACK_ALL() /*nothing*/
116 # define PSP_FLUSH_ALL() /*nothing*/
117 # define PSP_UCPTR(ptr) ptr
118 # define PSP_UC(var) var
119
120 #endif
121
122 //-------------------------------------------------------------------------
123 // SCSP constants
124
125 // SCSP hardware version (4 bits)
126 #define SCSP_VERSION 0
127
128 // SCSP clock frequency (11.2896 MHz, or exactly 44100*256)
129 #define SCSP_CLOCK_FREQ (44100 * 256)
130
131 // SCSP output frequency
132 #define SCSP_OUTPUT_FREQ (SCSP_CLOCK_FREQ / 256)
133
134 // SCSP clock increment per 1/10 scanline
135 #define SCSP_CLOCK_INC_NTSC (((u64)SCSP_CLOCK_FREQ<<20) * 1001 / 60000 / 263 / 10)
136 #define SCSP_CLOCK_INC_PAL (((u64)SCSP_CLOCK_FREQ<<20) / 50 / 313 / 10)
137
138 // Limit on execution time for a single thread loop (in SCSP clock cycles);
139 // if the thread's delay exceeds this value, we stop in the main loop to
140 // let the SCSP catch up
141 #define SCSP_CLOCK_MAX_EXEC (SCSP_CLOCK_FREQ / 1000)
142
143 // Sound RAM size
144 #define SCSP_RAM_SIZE 0x80000
145 #define SCSP_RAM_MASK (SCSP_RAM_SIZE - 1)
146
147 // Envelope phases
148 #define SCSP_ENV_RELEASE 0
149 #define SCSP_ENV_SUSTAIN 1
150 #define SCSP_ENV_DECAY 2
151 #define SCSP_ENV_ATTACK 3
152
153 // LFO waveform types (equal to ALFOWS/PLFOWS values)
154 #define SCSP_LFO_SAWTOOTH 0
155 #define SCSP_LFO_SQUARE 1
156 #define SCSP_LFO_TRIANGLE 2
157 #define SCSP_LFO_NOISE 3
158
159 // Bit sizes of fixed-point counters
160
161 // Fractional part of frequency counter (determines accuracy of audio
162 // playback frequency)
163 #define SCSP_FREQ_LOW_BITS 10
164 // Integer part of envelope counter (determines resolution of attack/decay
165 // envelope); also used to define envelope value range
166 #define SCSP_ENV_HIGH_BITS 10
167 // Fractional part of envelope counter (determines accuracy of envelope timing)
168 #define SCSP_ENV_LOW_BITS 10
169 // Integer part of LFO counter (determines resolution of LFO waveform);
170 // also used to define LFO value range
171 #define SCSP_LFO_HIGH_BITS 10
172 // Fractional part of LFO counter (determines accuracy of LFO frequency)
173 #define SCSP_LFO_LOW_BITS 10
174 // Fractional part of TL attenuation lookup table (determines resolution of
175 // per-voice volume control)
176 #define SCSP_TL_BITS 10
177
178 // Envelope/waveform table data sizes and corresponding masks
179 #define SCSP_ENV_LEN (1 << SCSP_ENV_HIGH_BITS)
180 #define SCSP_ENV_MASK (SCSP_ENV_LEN - 1)
181 #define SCSP_LFO_LEN (1 << SCSP_LFO_HIGH_BITS)
182 #define SCSP_LFO_MASK (SCSP_LFO_LEN - 1)
183
184 // Envelope attack/decay points (counter values)
185 #define SCSP_ENV_ATTACK_START 0
186 #define SCSP_ENV_DECAY_START (SCSP_ENV_LEN << SCSP_ENV_LOW_BITS)
187 #define SCSP_ENV_ATTACK_END (SCSP_ENV_DECAY_START - 1)
188 #define SCSP_ENV_DECAY_END (((2 * SCSP_ENV_LEN) << SCSP_ENV_LOW_BITS) - 1)
189
190 // Envelope attack/decay base times
191 #define SCSP_ATTACK_TIME ((u32) (8 * SCSP_OUTPUT_FREQ))
192 #define SCSP_DECAY_TIME ((u32) (12 * SCSP_ATTACK_TIME))
193
194 // Interrupt bit numbers
195 #define SCSP_INTERRUPT_MIDI_IN 3 // Data available in MIDI input buffer
196 #define SCSP_INTERRUPT_DMA 4 // DMA complete
197 #define SCSP_INTERRUPT_MANUAL 5 // 1 written to bit 5 of [MS]CIPD
198 #define SCSP_INTERRUPT_TIMER_A 6 // Timer A reached 0xFF
199 #define SCSP_INTERRUPT_TIMER_B 7 // Timer B reached 0xFF
200 #define SCSP_INTERRUPT_TIMER_C 8 // Timer C reached 0xFF
201 #define SCSP_INTERRUPT_MIDI_OUT 9 // MIDI output buffer became empty
202 #define SCSP_INTERRUPT_SAMPLE 10 // Raised once per output sample
203
204 // Interrupt target flags
205 #define SCSP_INTTARGET_MAIN (1 << 0) // Interrupt to main CPU (SCU)
206 #define SCSP_INTTARGET_SOUND (1 << 1) // Interrupt to sound CPU
207 #define SCSP_INTTARGET_BOTH (SCSP_INTTARGET_MAIN | SCSP_INTTARGET_SOUND)
208
209 // PCM output buffer size parameters
210 #define SCSP_SOUND_LEN_NTSC (SCSP_OUTPUT_FREQ / 60) // Samples per frame
211 #define SCSP_SOUND_LEN_PAL (SCSP_OUTPUT_FREQ / 50)
212 // Reserve 10x the maximum samples per frame
213 #define SCSP_SOUND_BUFSIZE (10 * SCSP_SOUND_LEN_PAL)
214
215 // CDDA data buffer size in sectors (must be at least 3)
216 #define CDDA_NUM_BUFFERS 3
217
218 // CDDA playback start delay in samples (see cdda_delay comments)
219 #define CDDA_DELAY_SAMPLES 100
220
221 //-------------------------------------------------------------------------
222 // Internal state data structures
223
224 // Per-slot data structure
225
226 typedef struct SlotState_struct
227 {
228 ////////////
229 // Register fields
230
231 // ISR $00
232 // [12] Write 1 to execute KEY state change
233 u8 key; // [11] KEY state (on/off)
234 u8 sbctl; // [10:9] Source bit control
235 u8 ssctl; // [8:7] Sound source control
236 u8 lpctl; // [6:5] Loop control
237 u8 pcm8b; // [4] PCM sound format
238 // [3:0] Start address (in bytes), high bits (19:16)
239
240 // ISR $02
241 u32 sa; // [15:0] Start address (in bytes), low bits (15:0)
242
243 // ISR $04
244 u16 lsa; // [15:0] Loop start address (in samples)
245
246 // ISR $06
247 u16 lea; // [15:0] Loop end address (in samples)
248
249 // ISR $08
250 u8 sr; // [15:11] Sustain rate
251 u8 dr; // [10:6] Decay rate
252 u8 eghold; // [5] Envelope hold (attack rate 0) flag
253 u8 ar; // [4:0] Attack rate
254
255 // ISR $0A
256 u8 lpslnk; // [14] Loop start link (start decay on reaching LSA)
257 u8 krs; // [13:10] Key rate scale
258 u8 sl; // [9:5] Sustain level
259 u8 rr; // [4:0] Release rate
260
261 // ISR $0C
262 u8 stwinh; // [9] Stack write inhibit flag
263 u8 sdir; // [8] Sound direct output flag
264 u8 tl; // [7:0] Total level
265
266 // ISR $0E
267 u8 mdl; // [15:12] Modulation level
268 u8 mdx; // [11:6] Modulation source X
269 u8 mdy; // [5:0] Modulation source Y
270
271 // ISR $10
272 u8 oct; // [14:11] Octave (treated as signed -8..7)
273 u16 fns; // [9:0] Frequency number switch
274
275 // ISR $12
276 u8 lfore; // [15] LFO reset flag (1 = reset, 0 = count)
277 u8 lfof; // [14:10] LFO frequency index
278 u8 plfows; // [9:8] Pitch LFO waveform select
279 u8 plfos; // [7:5] Pitch LFO sensitivity
280 u8 alfows; // [4:3] Amplitude LFO waveform select
281 u8 alfos; // [2:0] Amplitude LFO sensitivity
282
283 // ISR $14
284 u8 isel; // [6:3] Input selector
285 u8 imxl; // [2:0] Input mix level
286
287 // ISR $16
288 u8 disdl; // [15:13] Direct data send level
289 u8 dipan; // [12:8] Direct data pan position
290 u8 efsdl; // [7:5] Effect data send level
291 u8 efpan; // [2:0] Effect data pan position
292
293 ////////////
294 // Internal state
295
296 // Audio generation routine (selected based on slot parameters)
297 void (* FASTCALL audiogen)(struct SlotState_struct *slot, u32 len);
298
299 const void *buf; // Pointer to sample data in sound RAM
300
301 u32 addr_counter; // Address (playback) counter
302 u32 addr_step; // Address counter increment
303 u8 octave_shift; // Octave shift amount (0..15)
304 u32 lsa_shifted; // lsa << SCSP_FREQ_LOW_BITS (for addr_counter)
305 u32 lea_shifted; // lea << SCSP_FREQ_LOW_BITS (for addr_counter)
306 u32 looplen_shifted;// (lea - lsa + 1) << SCSP_FREQ_LOW_BITS
307
308 u32 env_phase; // Current envelope phase (attack/decay/...)
309 s32 env_counter; // Envelope counter
310 s32 env_step; // Envelope counter increment for current phase
311 s32 env_target; // Envelope target value for advancing to next phase
312 s32 env_step_a; // Envelope counter increment for attack phase
313 s32 env_step_d; // Envelope counter increment for decay phase
314 s32 env_step_s; // Envelope counter increment for sustain phase
315 s32 env_step_r; // Envelope counter increment for release phase
316 s32 last_env; // Last calculated envelope multiplier
317 u8 krs_shift; // Shift count corresponding to KRS
318 s32 sl_target; // Compare value corresponding to SL
319 s32 tl_mult; // Envelope volume multiplier corresponding to TL
320
321 u32 lfo_counter; // LFO counter (fixed point index into LFO waveforms)
322 s32 lfo_step; // LFO counter increment, or -1 if in reset mode
323 s32 *lfo_fm_wave; // LFO frequency modulation waveform pointer
324 s32 *lfo_am_wave; // LFO amplitude modulation waveform pointer
325 s8 lfo_fm_shift; // LFO frequency modulation strength, -1 if disabled
326 s8 lfo_am_shift; // LFO amplitude modulation strength, -1 if disabled
327
328 u8 outshift_l; // Output shift for left channel (down to 16 bits)
329 u8 outshift_r; // Output shift for right channel (down to 16 bits)
330
331 u8 imxl_shift; // Shift count for IMXL
332
333 } SlotState;
334
335 //------------------------------------
336
337 // Overall SCSP data structure
338
339 typedef struct ScspState_struct {
340
341 ////////////
342 // Register fields
343
344 // $400
345 u8 mem4mb; // [9] Sound RAM memory size flag (4Mbit vs. 2Mbit)
346 u8 dac18b; // [8] DAC 18-bit output flag (ignored)
347 u8 ver; // [7:4] Hardware version (fixed at 0)
348 u8 mvol; // [3:0] Master volume
349
350 // $402
351 u8 rbl; // [8:7] Ring buffer length (8192<<RBL words)
352 u32 rbp; // [6:0] Ring buffer pointer 19:13 (low bits are zero)
353
354 // $404
355 u8 mofull; // [12] MIDI output FIFO full flag
356 u8 moemp; // [11] MIDI output FIFO empty flag
357 u8 miovf; // [10] MIDI input FIFO overflow flag
358 u8 mifull; // [9] MIDI input FIFO full flag
359 u8 miemp; // [8] MIDI input FIFO empty flag
360 u8 mibuf; // [7:0] MIDI input data buffer
361
362 // $406
363 u8 mobuf; // [7:0] MIDI output data buffer
364
365 // $408
366 u8 mslc; // [15:11] Monitor slot
367 u8 ca; // [10:7] Call address
368 u8 sgc; // [6:5] Envelope phase
369 u8 eg; // [4:0] Envelope volume
370
371 // $40A..$410 unused (possibly used in the model 2 SCSP?)
372
373 // $412 // [15:1] DMA transfer start address 15:1
374 u32 dmea;
375
376 // $414
377 // [15:12] DMA transfer start address 19:16
378 u16 drga; // [11:1] DMA register address 11:1
379
380 // $416
381 u8 dgate; // [14] DMA gate (1 = zero-clear target)
382 u8 ddir; // [13] DMA direction (0 = from, 1 = to sound RAM)
383 u8 dexe; // [12] DMA execute (write 1 to start; returns to 0 when done)
384 u16 dtlg; // [11:1] DMA transfer length 11:1
385
386 // $418
387 u8 tactl; // [10:8] Timer A step divisor (step every 1<<tactl output samples)
388 u16 tima; // [7:0] Timer A counter (sends an IRQ at 0xFF), as 8.8 fixed point
389
390 // $41A
391 u8 tbctl; // [10:8] Timer B step divisor
392 u16 timb; // [7:0] Timer B counter, as 8.8 fixed point
393
394 // $41C
395 u8 tcctl; // [10:8] Timer C step divisor
396 u16 timc; // [7:0] Timer C counter, as 8.8 fixed point
397
398 // $41E
399 u16 scieb; // [10:0] Sound CPU interrupt enable
400
401 // $420
402 u16 scipd; // [10:0] Sound CPU interrupt pending
403
404 // $422
405 // scire; // [10:0] Sound CPU interrupt reset (not readable)
406
407 // $424
408 u8 scilv0; // [7:0] Sound CPU interrupt levels, bit 0
409
410 // $426
411 u8 scilv1; // [7:0] Sound CPU interrupt levels, bit 1
412
413 // $428
414 u8 scilv2; // [7:0] Sound CPU interrupt levels, bit 2
415
416 // $42A
417 u16 mcieb; // [10:0] Main CPU interrupt enable
418
419 // $42C
420 u16 mcipd; // [10:0] Main CPU interrupt pending
421
422 // $42E
423 // mcire; // [10:0] Main CPU interrupt reset (not readable)
424
425 ////////////
426 // Internal state
427
428 s32 stack[32*2]; // 2 generations of sound output data ($600..$67E)
429
430 SlotState slot[32]; // Data for each slot
431
432 u32 sample_timer; // Sample output timer (in SCSP clocks, 256 = 1 sample)
433
434 u32 sound_ram_mask; // Sound RAM address mask (tracks mem4mb)
435
436 u8 midi_in_buf[4]; // MIDI in buffer
437 u8 midi_out_buf[4];// MIDI out buffer
438 u8 midi_in_cnt; // MIDI in data count
439 u8 midi_out_cnt; // MIDI out data count
440
441 } ScspState;
442
443 //-------------------------------------------------------------------------
444 // Exported data
445
446 u8 *SoundRam;
447
448 //-------------------------------------------------------------------------
449 // Lookup tables
450
451 // Attack/decay envelope lookup table
452 static s32 scsp_env_table[SCSP_ENV_LEN*2];
453
454 // LFO waveforms for amplitude modulation
455 static s32 scsp_lfo_wave_amp[4][SCSP_LFO_LEN];
456 // LFO waveforms for frequency modulation
457 static s32 scsp_lfo_wave_freq[4][SCSP_LFO_LEN];
458 // LFO counter step values for each LFOF index
459 static s32 scsp_lfo_step[32];
460
461 // Envelope increments for each attack/decay rate (AR, DR, etc.)
462 static s32 scsp_attack_rate[62+16];
463 static s32 scsp_decay_rate[62+16];
464
465 // Table of volume multipliers for TL (total level) register
466 static s32 scsp_tl_table[256];
467
468 //-------------------------------------------------------------------------
469 // Other local data
470
471 //-------- Data written by main thread only --------//
472
473 // Cached fraction of a clock cycle (12.20 fixed point)
474 static u32 scsp_clock_frac;
475 // scsp_clock_frac increment per ScspExec(1) call
476 static u32 scsp_clock_inc;
477
478 // Selected sound output module
479 static SoundInterface_struct *SNDCore;
480
481 // Main CPU (SCU) interrupt function pointer
482 static void (*scsp_interrupt_handler)(void);
483
484 // Flag: Generate sound with frame-accurate timing?
485 static u8 scsp_frame_accurate;
486
487 //-------- Data used for inter-thread communication --------//
488
489 PSP_SECTION_START(sc_write)
490 PSP_SECTION_START(me_write)
491
492 // Core 11.2896MHz clock (continually counts up)
493 PSP_SECTION(me_write)
494 static volatile u32 scsp_clock;
495 // Target clock value for execution (execute until clock == clock_target)
496 PSP_SECTION(sc_write)
497 static volatile u32 scsp_clock_target;
498
499 // Flag: Is a subthread currently running? (Also used to signal the
500 // subthread to stop.)
501 PSP_SECTION(sc_write)
502 static volatile u8 scsp_thread_running;
503
504 // Flag: Has an interrupt request been generated for the main processor?
505 // (Set by the subthread, cleared by the main thread.)
506 PSP_SECTION(both_write)
507 static volatile u8 scsp_main_interrupt_pending;
508
509 // Buffer for external (SH-2) SCSP writes (only _size is written by both
510 // CPUs, but we keep all three in the same section for cache safety)
511 PSP_SECTION(both_write)
512 static volatile u8 scsp_write_buffer_size; // 0 = nothing buffered
513 PSP_SECTION(both_write)
514 static volatile u16 scsp_write_buffer_address;
515 PSP_SECTION(both_write)
516 static volatile u32 scsp_write_buffer_data;
517
518 // SCSP register value cache (caching handled separately)
519 #ifdef PSP
520 __attribute__((aligned(64)))
521 #endif
522 static u16 scsp_regcache[0x1000/2];
523
524 // CDDA input buffer and read/write pointers
525 PSP_SECTION(sc_write)
526 static union {
527 u8 sectors[CDDA_NUM_BUFFERS][2352];
528 u8 data[CDDA_NUM_BUFFERS*2352];
529 } cdda_buf;
530 PSP_SECTION(sc_write)
531 static volatile u32 cdda_next_in; // Offset of next _sector_ to store
532 PSP_SECTION(me_write)
533 static volatile u32 cdda_next_out; // Offset of next _byte_ to read out
534
535 PSP_SECTION_END(sc_write)
536 PSP_SECTION_END(me_write)
537
538 //--- Data written by SCSP thread only (except when thread is stopped) ---//
539
540 // Current SCSP state
541 static ScspState scsp;
542
543 // PCM output buffers and related data
544 static s32 scsp_buffer_L[SCSP_SOUND_BUFSIZE];
545 static s32 scsp_buffer_R[SCSP_SOUND_BUFSIZE];
546 static u32 scsp_sound_genpos; // Offset of next sample to generate
547 static u32 scsp_sound_left; // Samples not yet sent to host driver
548
549 // Parameters for audio data generation (these are file-scope to reduce
550 // parameter passing overhead)
551 static s32 *scsp_bufL; // Base pointer for left channel
552 static s32 *scsp_bufR; // Base pointer for right channel
553
554 // CDDA playback delay in samples (used to avoid audio popping when the
555 // SCSP emulation gets a few samples ahead of the CDDA input)
556 static u32 cdda_delay;
557
558 // M68K-related data
559 static u8 m68k_running; // Nonzero if M68K execution is enabled
560 static s32 FASTCALL (*m68k_execf)(s32 cycles); // M68K->Exec or M68KExecBP
561 static s32 m68k_saved_cycles; // Requested minus actual cycles executed
562 static M68KBreakpointInfo m68k_breakpoint[M68K_MAX_BREAKPOINTS];
563 static int m68k_num_breakpoints;
564 static void (*M68KBreakpointCallback)(u32);
565 static u8 m68k_in_breakpoint;
566
567 //-------------------------------------------------------------------------
568 // Local function declarations
569
570 static void ScspThread(void *arg);
571 static void ScspDoExec(u32 cycles);
572 static u32 ScspTimerCyclesLeft(u16 timer, u8 timer_scale);
573 static void ScspUpdateTimer(u32 samples, u16 *timer_ptr, u8 timer_scale,
574 int interrupt);
575 static void ScspGenerateAudio(s32 *bufL, s32 *bufR, u32 samples);
576 static void ScspGenerateAudioForSlot(SlotState *slot, u32 samples);
577 static void ScspGenerateAudioForCDDA(s32 *bufL, s32 *bufR, u32 samples);
578
579 static u8 FASTCALL ScspReadByteDirect(u32 address);
580 static u16 FASTCALL ScspReadWordDirect(u32 address);
581 static void FASTCALL ScspWriteByteDirect(u32 address, u8 data);
582 static void FASTCALL ScspWriteWordDirect(u32 address, u16 data);
583 static u16 ScspReadMonitor(void);
584 static void ScspDoKeyOnOff(void);
585 static void ScspKeyOn(SlotState *slot);
586 static void ScspKeyOff(SlotState *slot);
587 static void ScspUpdateSlotAddress(SlotState *slot);
588 static void ScspUpdateSlotEnv(SlotState *slot);
589 static void ScspUpdateSlotFunc(SlotState *slot);
590 static u16 ScspMidiIn(void);
591 static void ScspMidiOut(u8 data);
592 static void ScspDoDMA(void);
593
594 static void ScspSyncThread(void);
595 static void ScspRaiseInterrupt(int which, int target);
596 static void ScspCheckInterrupts(u16 mask, int target);
597 static void ScspClearInterrupts(u16 mask, int target);
598 static void ScspRunM68K(u32 cycles);
599 static s32 FASTCALL M68KExecBP(s32 cycles);
600
601 static int scsp_mute_flags = 0;
602 static int scsp_volume = 100;
603
604 ///////////////////////////////////////////////////////////////////////////
605 // Single-slot audio generation routines and corresponding table. The
606 // table is indexed by:
607 // scsp_audiogen_func_table[F][A][S][L][R]
608 // ^ ^ ^ ^ ^-- Right channel on/off (on = 1)
609 // | | | `-- Left channel on/off (on = 1)
610 // | | `-- Sample size 16/8 bit (16 bit = 1)
611 // | `-- Amplitude modulation on/off (on = 1)
612 // `-- Frequency modulation on/off (on = 1)
613 ///////////////////////////////////////////////////////////////////////////
614
615 // For convenience, we use a single, parameterized macro to define every
616 // function, with 0 or 1 in each of the F/A/S/L/R parameters; the compiler
617 // will optimize out the disabled branches.
618
619 // A couple of handy sub-macros:
620 #define ADDRESS (addr_counter >> SCSP_FREQ_LOW_BITS)
621 #ifdef WORDS_BIGENDIAN
622 #define ADDRESS_8BIT (ADDRESS)
623 #else
624 #define ADDRESS_8BIT (ADDRESS ^ 1)
625 #endif
626 #define ENV_POS (env_counter >> SCSP_ENV_LOW_BITS)
627 #define LFO_POS ((slot->lfo_counter >> SCSP_LFO_LOW_BITS) & SCSP_LFO_MASK)
628
629 #define DEFINE_AUDIOGEN(tag,F,A,S,L,R) \
630 static void FASTCALL audiogen_##tag(SlotState *slot, u32 len) \
631 { \
632 /* Load these first to avoid having to reload them every iteration */ \
633 u32 addr_counter = slot->addr_counter; \
634 const u32 addr_step = slot->addr_step; \
635 u32 env_counter = slot->env_counter; \
636 u32 env_step = slot->env_step; \
637 \
638 u32 pos; \
639 for (pos = 0; pos < len; pos++) \
640 { \
641 if (L || R) /* Don't bother with calculations if it's all silent */ \
642 { \
643 /* Compute envelope/TL multiplier for waveform data */ \
644 s32 env = scsp_env_table[ENV_POS] * slot->tl_mult >> SCSP_TL_BITS; \
645 if (A) \
646 env -= slot->lfo_am_wave[LFO_POS] >> slot->lfo_am_shift; \
647 slot->last_env = env; \
648 \
649 /* Apply envelope / channel volume to waveform data and output */ \
650 if (LIKELY(env > 0)) \
651 { \
652 s32 out; \
653 if (S) \
654 out = (s32) ((const s16 *)slot->buf)[ADDRESS]; \
655 else \
656 out = (s32) ((const s8 *)slot->buf)[ADDRESS_8BIT] << 8; \
657 out *= env; \
658 if (L) \
659 scsp_bufL[pos] += out >> slot->outshift_l; \
660 if (R) \
661 scsp_bufR[pos] += out >> slot->outshift_r; \
662 } \
663 } \
664 \
665 /* Update address counter, exiting if we reach the end of the data */ \
666 if (F) \
667 { \
668 /* FIXME: need to handle the case where LFO data range != 1<<FREQ_LOW_BITS */ \
669 addr_counter += slot->lfo_fm_wave[LFO_POS] \
670 << slot->lfo_fm_shift \
671 >> slot->octave_shift; \
672 } \
673 addr_counter += addr_step; \
674 if (UNLIKELY(addr_counter > slot->lea_shifted)) \
675 { \
676 /* FIXME: reverse/alternating loops not implemented */ \
677 if (slot->lpctl) \
678 { \
679 addr_counter = slot->lsa_shifted \
680 + ((addr_counter - slot->lsa_shifted) \
681 % slot->looplen_shifted); \
682 } \
683 else \
684 { \
685 env_counter = SCSP_ENV_DECAY_END; \
686 goto done; \
687 } \
688 } \
689 \
690 /* Update envelope counter, advancing the envelope phase as needed */ \
691 env_counter += env_step; \
692 if (UNLIKELY(env_counter >= slot->env_target)) \
693 { \
694 switch (slot->env_phase) \
695 { \
696 case SCSP_ENV_ATTACK: \
697 env_counter = SCSP_ENV_DECAY_START; \
698 env_step = slot->env_step = slot->env_step_d; \
699 slot->env_target = slot->sl_target; \
700 slot->env_phase = SCSP_ENV_DECAY; \
701 break; \
702 case SCSP_ENV_DECAY: \
703 env_counter = slot->sl_target; \
704 env_step = slot->env_step = slot->env_step_s; \
705 slot->env_target = SCSP_ENV_DECAY_END; \
706 slot->env_phase = SCSP_ENV_SUSTAIN; \
707 break; \
708 default: \
709 env_counter = SCSP_ENV_DECAY_END; \
710 env_step = slot->env_step = 0; \
711 slot->env_target = SCSP_ENV_DECAY_END + 1; \
712 goto done; \
713 } \
714 } \
715 \
716 /* Update the LFO counter if either LFO waveform is in use \
717 * (technically, we should update whenever slot->lfore == 0, but \
718 * we skip the update on non-modulated channels to save time) */ \
719 if (F || A) \
720 slot->lfo_counter += slot->lfo_step; \
721 } \
722 \
723 done: \
724 slot->addr_counter = addr_counter; \
725 slot->env_counter = env_counter; \
726 }
727
728 //-------------------------------------------------------------------------
729
730 // Define the actual audio generation functions. For simplicity, we name
731 // each function using the state of its parameter flags, with uppercase for
732 // an enabled flag and lowercase for a disabled flag. We also use the null
733 // output function for all cases where L and R are zero, to avoid
734 // unnecessary code bloat.
735
736 DEFINE_AUDIOGEN(null, 0,0,0,0,0)
737
738 DEFINE_AUDIOGEN(faslR, 0,0,0,0,1)
739 DEFINE_AUDIOGEN(fasLr, 0,0,0,1,0)
740 DEFINE_AUDIOGEN(fasLR, 0,0,0,1,1)
741 DEFINE_AUDIOGEN(faSlR, 0,0,1,0,1)
742 DEFINE_AUDIOGEN(faSLr, 0,0,1,1,0)
743 DEFINE_AUDIOGEN(faSLR, 0,0,1,1,1)
744
745 DEFINE_AUDIOGEN(fAslR, 0,1,0,0,1)
746 DEFINE_AUDIOGEN(fAsLr, 0,1,0,1,0)
747 DEFINE_AUDIOGEN(fAsLR, 0,1,0,1,1)
748 DEFINE_AUDIOGEN(fASlR, 0,1,1,0,1)
749 DEFINE_AUDIOGEN(fASLr, 0,1,1,1,0)
750 DEFINE_AUDIOGEN(fASLR, 0,1,1,1,1)
751
752 DEFINE_AUDIOGEN(FaslR, 1,0,0,0,1)
753 DEFINE_AUDIOGEN(FasLr, 1,0,0,1,0)
754 DEFINE_AUDIOGEN(FasLR, 1,0,0,1,1)
755 DEFINE_AUDIOGEN(FaSlR, 1,0,1,0,1)
756 DEFINE_AUDIOGEN(FaSLr, 1,0,1,1,0)
757 DEFINE_AUDIOGEN(FaSLR, 1,0,1,1,1)
758
759 DEFINE_AUDIOGEN(FAslR, 1,1,0,0,1)
760 DEFINE_AUDIOGEN(FAsLr, 1,1,0,1,0)
761 DEFINE_AUDIOGEN(FAsLR, 1,1,0,1,1)
762 DEFINE_AUDIOGEN(FASlR, 1,1,1,0,1)
763 DEFINE_AUDIOGEN(FASLr, 1,1,1,1,0)
764 DEFINE_AUDIOGEN(FASLR, 1,1,1,1,1)
765
766 // We don't need these anymore, so get rid of them
767 #undef ADDRESS
768 #undef ADDRESS_8BIT
769 #undef ENV_POS
770 #undef LFO_POS
771 #undef DEFINE_AUDIOGEN
772
773 //-------------------------------------------------------------------------
774
775 // Define the function lookup table.
776
777 static void (* FASTCALL scsp_audiogen_func_table[2][2][2][2][2])(SlotState *slot, u32 len) =
778 {
779 { // F==0
780 { // A==0
781 {{audiogen_null, audiogen_faslR}, {audiogen_fasLr, audiogen_fasLR}},
782 {{audiogen_null, audiogen_faSlR}, {audiogen_faSLr, audiogen_faSLR}}
783 },
784 { // A==1
785 {{audiogen_null, audiogen_fAslR}, {audiogen_fAsLr, audiogen_fAsLR}},
786 {{audiogen_null, audiogen_fASlR}, {audiogen_fASLr, audiogen_fASLR}}
787 }
788 },
789 { // F==1
790 { // A==0
791 {{audiogen_null, audiogen_FaslR}, {audiogen_FasLr, audiogen_FasLR}},
792 {{audiogen_null, audiogen_FaSlR}, {audiogen_FaSLr, audiogen_FaSLR}}
793 },
794 { // A==1
795 {{audiogen_null, audiogen_FAslR}, {audiogen_FAsLr, audiogen_FAsLR}},
796 {{audiogen_null, audiogen_FASlR}, {audiogen_FASLr, audiogen_FASLR}}
797 }
798 }
799 };
800
801 ///////////////////////////////////////////////////////////////////////////
802 // Initialization, configuration, and cleanup routines
803 ///////////////////////////////////////////////////////////////////////////
804
805 // ScspInit: Initialize the SCSP emulation. interrupt_handler should
806 // specify a function to handle interrupts delivered to the SCU.
807 // Must be called after M68KInit(); returns 0 on success, -1 on failure.
808
ScspInit(int coreid,void (* interrupt_handler)(void))809 int ScspInit(int coreid, void (*interrupt_handler)(void))
810 {
811 int i, j;
812 double x;
813
814 if ((SoundRam = T2MemoryInit(0x80000)) == NULL)
815 return -1;
816
817 // Fill in lookup tables
818
819 for (i = 0; i < SCSP_ENV_LEN; i++)
820 {
821 // Attack Curve (x^4 ?)
822 x = pow(((double) (SCSP_ENV_MASK - i) / SCSP_ENV_LEN), 4);
823 x *= (double) SCSP_ENV_LEN;
824 scsp_env_table[i] = SCSP_ENV_MASK - (s32) floor(x);
825
826 // Decay curve (x = linear)
827 scsp_env_table[i + SCSP_ENV_LEN] = SCSP_ENV_MASK - i;
828 }
829
830 for (i = 0, j = 0; i < 32; i++)
831 {
832 double lfo_frequency, lfo_step;
833 // Frequency divider follows the pattern 1,2,3,4, 6,8,10,12, 16,...
834 j += 1 << (i >> 2);
835 // Base LFO frequency is 44100/256 or ~172.3 Hz
836 lfo_frequency = (44100.0 / 256.0) / j;
837 // Calculate LFO address step per output sample; we use a literal
838 // 44100 above but OUTPUT_FREQ here in case anyone wants to try
839 // upsampling the audio output someday
840 lfo_step = (lfo_frequency / SCSP_OUTPUT_FREQ) * SCSP_LFO_LEN;
841 scsp_lfo_step[31 - i] = round(lfo_step * (1 << SCSP_LFO_LOW_BITS));
842 }
843
844 for (i = 0; i < SCSP_LFO_LEN; i++)
845 {
846 // Amplitude modulation uses unsigned values which are subtracted
847 // from the base envelope value
848 scsp_lfo_wave_amp[SCSP_LFO_SAWTOOTH][i] = i;
849 if (i < SCSP_LFO_LEN / 2)
850 scsp_lfo_wave_amp[SCSP_LFO_SQUARE][i] = 0;
851 else
852 scsp_lfo_wave_amp[SCSP_LFO_SQUARE][i] = SCSP_LFO_MASK;
853 if (i < SCSP_LFO_LEN / 2)
854 scsp_lfo_wave_amp[SCSP_LFO_TRIANGLE][i] = i*2;
855 else
856 scsp_lfo_wave_amp[SCSP_LFO_TRIANGLE][i] = SCSP_LFO_MASK - ((i - SCSP_LFO_LEN/2) * 2);
857 scsp_lfo_wave_amp[SCSP_LFO_NOISE][i] = rand() & SCSP_LFO_MASK;
858 // FIXME: note that the noise generator output should be independent
859 // of LFORE/LFOF
860
861 // Frequency modulation uses signed values which are added to the
862 // address counter
863 if (i < SCSP_LFO_LEN / 2)
864 scsp_lfo_wave_freq[SCSP_LFO_SAWTOOTH][i] = i;
865 else
866 scsp_lfo_wave_freq[SCSP_LFO_SAWTOOTH][i] = i - SCSP_LFO_LEN;
867 if (i < SCSP_LFO_LEN / 2)
868 scsp_lfo_wave_freq[SCSP_LFO_SQUARE][i] = SCSP_LFO_MASK - SCSP_LFO_LEN/2;
869 else
870 scsp_lfo_wave_freq[SCSP_LFO_SQUARE][i] = 0 - SCSP_LFO_LEN/2;
871 if (i < SCSP_LFO_LEN / 4)
872 scsp_lfo_wave_freq[SCSP_LFO_TRIANGLE][i] = i*2;
873 else if (i < SCSP_LFO_LEN * 3 / 4)
874 scsp_lfo_wave_freq[SCSP_LFO_TRIANGLE][i] = SCSP_LFO_MASK - i*2;
875 else
876 scsp_lfo_wave_freq[SCSP_LFO_TRIANGLE][i] = i*2 - SCSP_LFO_LEN*2;
877 scsp_lfo_wave_freq[SCSP_LFO_NOISE][i] = scsp_lfo_wave_amp[SCSP_LFO_NOISE][i] - SCSP_LFO_LEN/2;
878 }
879
880 for (i = 0; i < 4; i++)
881 {
882 scsp_attack_rate[i] = 0;
883 scsp_decay_rate[i] = 0;
884 }
885 for (i = 0; i < 60; i++)
886 {
887 x = 1.0 + ((i & 3) * 0.25); // Bits 0-1: x1.00, x1.25, x1.50, x1.75
888 x *= 1 << (i >> 2); // Bits 2-5: shift bits (x2^0 - x2^15)
889 x *= SCSP_ENV_LEN << SCSP_ENV_LOW_BITS; // Adjust for envelope table size
890
891 scsp_attack_rate[i + 4] = round(x / SCSP_ATTACK_TIME);
892 if (scsp_attack_rate[i + 4] == 0)
893 scsp_attack_rate[i + 4] = 1;
894 scsp_decay_rate[i + 4] = round(x / SCSP_DECAY_TIME);
895 if (scsp_decay_rate[i + 4] == 0)
896 scsp_decay_rate[i + 4] = 1;
897 }
898 scsp_attack_rate[63] = SCSP_ENV_ATTACK_END;
899 scsp_decay_rate[61] = scsp_decay_rate[60];
900 scsp_decay_rate[62] = scsp_decay_rate[60];
901 scsp_decay_rate[63] = scsp_decay_rate[60];
902 for (i = 64; i < 78; i++)
903 {
904 scsp_attack_rate[i] = scsp_attack_rate[63];
905 scsp_decay_rate[i] = scsp_decay_rate[63];
906 }
907
908 for (i = 0; i < 256; i++)
909 scsp_tl_table[i] = round(pow(2.0, -(i/16.0)) * (1 << SCSP_TL_BITS));
910
911 // Initialize the SCSP state
912
913 scsp_interrupt_handler = interrupt_handler;
914 scsp_clock_inc = yabsys.IsPal ? SCSP_CLOCK_INC_PAL : SCSP_CLOCK_INC_NTSC;
915
916 ScspReset();
917
918 // Note that we NEVER reset the clock counter after initialization,
919 // because in multithreaded mode, that would cause a race condition in
920 // which the SCSP thread runs between the two assignments and detects
921 // clock != clock_target, causing it to execute a huge number of cycles.
922 // (We do, however, reset the accumulated fraction of a cycle inside
923 // ScspReset().)
924 scsp_clock = 0;
925 scsp_clock_target = 0;
926
927 // Initialize the M68K state
928
929 if (M68K->Init() != 0)
930 return -1;
931
932 M68K->SetReadB(M68KReadByte);
933 M68K->SetReadW(M68KReadWord);
934 M68K->SetWriteB(M68KWriteByte);
935 M68K->SetWriteW(M68KWriteWord);
936
937 M68K->SetFetch(0x000000, 0x040000, (pointer)SoundRam);
938 M68K->SetFetch(0x040000, 0x080000, (pointer)SoundRam);
939 M68K->SetFetch(0x080000, 0x0C0000, (pointer)SoundRam);
940 M68K->SetFetch(0x0C0000, 0x100000, (pointer)SoundRam);
941
942 m68k_running = 0;
943 m68k_execf = M68K->Exec;
944 m68k_saved_cycles = 0;
945 for (i = 0; i < MAX_BREAKPOINTS; i++)
946 m68k_breakpoint[i].addr = 0xFFFFFFFF;
947 m68k_num_breakpoints = 0;
948 M68KBreakpointCallback = NULL;
949 m68k_in_breakpoint = 0;
950
951 // Set up sound output
952
953 scsp_sound_genpos = 0;
954 scsp_sound_left = 0;
955
956 if (ScspChangeSoundCore(coreid) < 0)
957 return -1;
958
959 // Start a subthread if requested
960
961 scsp_thread_running = 0;
962 if (yabsys.UseThreads)
963 {
964 scsp_thread_running = 1; // Set now so the thread doesn't quit instantly
965 PSP_FLUSH_ALL();
966 if (YabThreadStart(YAB_THREAD_SCSP, ScspThread, NULL) < 0)
967 {
968 SCSPLOG("Failed to start SCSP thread\n");
969 scsp_thread_running = 0;
970 }
971 }
972
973 // Successfully initialized!
974
975 return 0;
976 }
977
978 //-------------------------------------------------------------------------
979
980 // ScspReset: Reset the SCSP to its power-on state, also stopping the M68K
981 // processor.
982
ScspReset(void)983 void ScspReset(void)
984 {
985 int slotnum;
986
987 if (scsp_thread_running)
988 ScspSyncThread();
989
990 scsp.mem4mb = 0;
991 scsp.dac18b = 0;
992 scsp.ver = 0;
993 scsp.mvol = 0;
994
995 scsp.rbl = 0;
996 scsp.rbp = 0;
997
998 scsp.mofull = 0;
999 scsp.moemp = 1;
1000 scsp.miovf = 0;
1001 scsp.mifull = 0;
1002 scsp.miemp = 1;
1003 scsp.mibuf = 0;
1004 scsp.mobuf = 0;
1005
1006 scsp.mslc = 0;
1007 scsp.ca = 0;
1008
1009 scsp.dmea = 0;
1010 scsp.drga = 0;
1011 scsp.dgate = 0;
1012 scsp.ddir = 0;
1013 scsp.dexe = 0;
1014 scsp.dtlg = 0;
1015
1016 scsp.tactl = 0;
1017 scsp.tima = 0xFF00;
1018 scsp.tbctl = 0;
1019 scsp.timb = 0xFF00;
1020 scsp.tcctl = 0;
1021 scsp.timc = 0xFF00;
1022
1023 scsp.mcieb = 0;
1024 scsp.mcipd = 0;
1025 scsp.scilv0 = 0;
1026 scsp.scilv1 = 0;
1027 scsp.scilv2 = 0;
1028 scsp.scieb = 0;
1029 scsp.scipd = 0;
1030
1031 memset(scsp_regcache, 0, sizeof(scsp_regcache));
1032 scsp_regcache[0x400>>1] = SCSP_VERSION << 4;
1033
1034 memset(scsp.stack, 0, sizeof(scsp.stack));
1035
1036 for (slotnum = 0; slotnum < 32; slotnum++)
1037 {
1038 memset(&scsp.slot[slotnum], 0, sizeof(scsp.slot[slotnum]));
1039 scsp.slot[slotnum].env_counter = SCSP_ENV_DECAY_END; // Slot off
1040 scsp.slot[slotnum].outshift_l = 31; // Output off
1041 scsp.slot[slotnum].outshift_r = 31;
1042 scsp.slot[slotnum].audiogen = audiogen_null;
1043 }
1044
1045 scsp.sound_ram_mask = 0x3FFFF;
1046 scsp_clock_frac = 0;
1047 scsp.sample_timer = 0;
1048
1049 scsp_main_interrupt_pending = 0;
1050 scsp_write_buffer_size = 0;
1051
1052 cdda_next_in = 0;
1053 cdda_next_out = 0;
1054 cdda_delay = CDDA_DELAY_SAMPLES;
1055
1056 m68k_running = 0;
1057
1058 if (scsp_thread_running)
1059 PSP_FLUSH_ALL();
1060 }
1061
1062 //-------------------------------------------------------------------------
1063
1064 // ScspChangeSoundCore: Change the module used for sound output. Returns
1065 // 0 on success, -1 on error.
1066
ScspChangeSoundCore(int coreid)1067 int ScspChangeSoundCore(int coreid)
1068 {
1069 int i;
1070
1071 // Make sure the old core is freed
1072 if (SNDCore)
1073 SNDCore->DeInit();
1074
1075 // If the default was requested, use the first core in the list
1076 if (coreid == SNDCORE_DEFAULT)
1077 SNDCore = SNDCoreList[0];
1078 else
1079 {
1080 // Otherwise, go through core list and find the id
1081 for (i = 0; SNDCoreList[i] != NULL; i++)
1082 {
1083 if (SNDCoreList[i]->id == coreid)
1084 {
1085 // Set to current core
1086 SNDCore = SNDCoreList[i];
1087 break;
1088 }
1089 }
1090 }
1091
1092 if (SNDCore == NULL)
1093 {
1094 SNDCore = &SNDDummy;
1095 return -1;
1096 }
1097
1098 if (SNDCore->Init() == -1)
1099 {
1100 // Since it failed, instead of it being fatal, we'll just use the dummy
1101 // core instead
1102
1103 // This might be helpful though.
1104 YabSetError(YAB_ERR_CANNOTINIT, (void *)SNDCore->Name);
1105
1106 SNDCore = &SNDDummy;
1107 }
1108
1109 if (SNDCore)
1110 {
1111 if (scsp_mute_flags) SNDCore->MuteAudio();
1112 else SNDCore->UnMuteAudio();
1113 SNDCore->SetVolume(scsp_volume);
1114 }
1115
1116 return 0;
1117 }
1118
1119 //-------------------------------------------------------------------------
1120
1121 // ScspChangeVideoFormat: Update SCSP parameters for a change in video
1122 // format. type is nonzero for PAL (50Hz), zero for NTSC (59.94Hz) video.
1123 // Always returns 0 for success.
1124
ScspChangeVideoFormat(int type)1125 int ScspChangeVideoFormat(int type)
1126 {
1127 scsp_clock_inc = yabsys.IsPal ? SCSP_CLOCK_INC_PAL : SCSP_CLOCK_INC_NTSC;
1128
1129 SNDCore->ChangeVideoFormat(type ? 50 : 60);
1130
1131 return 0;
1132 }
1133
1134
1135 //-------------------------------------------------------------------------
1136
1137 // ScspSetFrameAccurate: Set whether sound should be generated with
1138 // frame-accurate timing.
1139
ScspSetFrameAccurate(int on)1140 void ScspSetFrameAccurate(int on)
1141 {
1142 scsp_frame_accurate = (on != 0);
1143 }
1144
1145 //-------------------------------------------------------------------------
1146
1147 // ScspMuteAudio, ScspUnMuteAudio: Mute or unmute the sound output. Does
1148 // not affect actual SCSP processing.
1149
ScspMuteAudio(int flags)1150 void ScspMuteAudio(int flags)
1151 {
1152 scsp_mute_flags |= flags;
1153 if (SNDCore && scsp_mute_flags)
1154 SNDCore->MuteAudio();
1155 }
1156
ScspUnMuteAudio(int flags)1157 void ScspUnMuteAudio(int flags)
1158 {
1159 scsp_mute_flags &= ~flags;
1160 if (SNDCore && (scsp_mute_flags == 0))
1161 SNDCore->UnMuteAudio();
1162 }
1163
1164 //-------------------------------------------------------------------------
1165
1166 // ScspSetVolume: Set the sound output volume. Does not affect actual
1167 // SCSP processing.
1168
ScspSetVolume(int volume)1169 void ScspSetVolume(int volume)
1170 {
1171 scsp_volume = volume;
1172 if (SNDCore)
1173 SNDCore->SetVolume(volume);
1174 }
1175
1176 //-------------------------------------------------------------------------
1177
1178 // ScspDeInit: Free all resources used by the SCSP emulation.
1179
ScspDeInit(void)1180 void ScspDeInit(void)
1181 {
1182 if (scsp_thread_running)
1183 {
1184 scsp_thread_running = 0; // Tell the subthread to stop
1185 YabThreadWake(YAB_THREAD_SCSP);
1186 YabThreadWait(YAB_THREAD_SCSP);
1187 }
1188
1189 if (SNDCore)
1190 SNDCore->DeInit();
1191 SNDCore = NULL;
1192
1193 if (SoundRam)
1194 T2MemoryDeInit(SoundRam);
1195 SoundRam = NULL;
1196 }
1197
1198 ///////////////////////////////////////////////////////////////////////////
1199 // Main SCSP processing routine and internal helpers
1200 ///////////////////////////////////////////////////////////////////////////
1201
1202 // ScspExec: Main SCSP processing routine. Executes (decilines/10.0)
1203 // scanlines worth of SCSP emulation; in multithreaded mode, bumps the
1204 // clock target by the same amount of time.
1205
ScspExec(int decilines)1206 void ScspExec(int decilines)
1207 {
1208 u32 new_target;
1209
1210 scsp_clock_frac += scsp_clock_inc * decilines;
1211 new_target = scsp_clock_target + (scsp_clock_frac >> 20);
1212 scsp_clock_target = new_target;
1213 scsp_clock_frac &= 0xFFFFF;
1214
1215 if (scsp_thread_running)
1216 {
1217 #ifdef PSP
1218 if (!psp_writeback_cache_for_scsp())
1219 PSP_UC(scsp_clock_target) = new_target; // Push just this one through
1220 #endif
1221 while (new_target - PSP_UC(scsp_clock) > SCSP_CLOCK_MAX_EXEC)
1222 {
1223 YabThreadWake(YAB_THREAD_SCSP);
1224 YabThreadYield();
1225 }
1226 if (PSP_UC(scsp_main_interrupt_pending))
1227 {
1228 (*scsp_interrupt_handler)();
1229 PSP_UC(scsp_main_interrupt_pending) = 0;
1230 }
1231 }
1232 else
1233 ScspDoExec(new_target - scsp_clock);
1234 }
1235
1236 ///////////////////////////////////////////////////////////////////////////
1237
1238 // ScspThread: Control routine for SCSP thread. Loops over ScspDoExec()
1239 // and SCSP write buffer processing until told to stop.
1240
ScspThread(void * arg)1241 static void ScspThread(void *arg)
1242 {
1243 while (PSP_UC(scsp_thread_running))
1244 {
1245 const u8 write_size = PSP_UC(scsp_write_buffer_size);
1246 u32 clock_cycles;
1247
1248 if (write_size != 0)
1249 {
1250 const u32 address = PSP_UC(scsp_write_buffer_address);
1251 const u32 data = PSP_UC(scsp_write_buffer_data);
1252 if (write_size == 1)
1253 ScspWriteByteDirect(address, data);
1254 else if (write_size == 2)
1255 ScspWriteWordDirect(address, data);
1256 else
1257 {
1258 ScspWriteWordDirect(address, data >> 16);
1259 ScspWriteWordDirect(address+2, data & 0xFFFF);
1260 }
1261 PSP_UC(scsp_write_buffer_size) = 0;
1262 }
1263
1264 clock_cycles = PSP_UC(scsp_clock_target) - scsp_clock;
1265 if (clock_cycles > SCSP_CLOCK_MAX_EXEC)
1266 clock_cycles = SCSP_CLOCK_MAX_EXEC;
1267 if (clock_cycles > 0)
1268 {
1269 ScspDoExec(clock_cycles);
1270 YabThreadYield();
1271 }
1272 else
1273 YabThreadSleep();
1274 }
1275 }
1276
1277 ///////////////////////////////////////////////////////////////////////////
1278
1279 // ScspDoExec: Main SCSP processing routine implementation. Runs M68K
1280 // code, updates timers, and generates samples for the given number of
1281 // SCSP clock cycles.
1282
ScspDoExec(u32 cycles)1283 static void ScspDoExec(u32 cycles)
1284 {
1285 #if 0
1286 s16 stereodata16[(44100 / 60) * 16]; //11760
1287 #endif
1288 u32 cycles_left;
1289 u32 sample_count;
1290 u32 audio_free;
1291
1292
1293 // If any of the timer interrupts are enabled, give the M68K a chance
1294 // to respond to them immediately, so that music doesn't slow down if
1295 // the SCSP thread gets behind and executes a lot of cycles at once.
1296 sample_count = 0;
1297 cycles_left = cycles;
1298 while (cycles_left > 0)
1299 {
1300 u32 this_samples = 0;
1301 u32 this_cycles = cycles_left;
1302 if (scsp.scieb & (1 << SCSP_INTERRUPT_TIMER_A))
1303 this_cycles = MIN(this_cycles, ScspTimerCyclesLeft(scsp.tima, scsp.tactl));
1304 if (scsp.scieb & (1 << SCSP_INTERRUPT_TIMER_B))
1305 this_cycles = MIN(this_cycles, ScspTimerCyclesLeft(scsp.timb, scsp.tbctl));
1306 if (scsp.scieb & (1 << SCSP_INTERRUPT_TIMER_C))
1307 this_cycles = MIN(this_cycles, ScspTimerCyclesLeft(scsp.timc, scsp.tcctl));
1308
1309 scsp.sample_timer += this_cycles;
1310 this_samples = scsp.sample_timer >> 8;
1311 scsp.sample_timer &= 0xFF;
1312 cycles_left -= this_cycles;
1313 sample_count += this_samples;
1314
1315 ScspRunM68K(this_cycles);
1316
1317 ScspUpdateTimer(this_samples, &scsp.tima, scsp.tactl,
1318 SCSP_INTERRUPT_TIMER_A);
1319 ScspUpdateTimer(this_samples, &scsp.timb, scsp.tbctl,
1320 SCSP_INTERRUPT_TIMER_B);
1321 ScspUpdateTimer(this_samples, &scsp.timc, scsp.tcctl,
1322 SCSP_INTERRUPT_TIMER_C);
1323 }
1324
1325 if (scsp_frame_accurate)
1326 {
1327 s32 *bufL, *bufR;
1328
1329 // Update sound buffers
1330 if (scsp_sound_left + sample_count > SCSP_SOUND_BUFSIZE)
1331 {
1332 u32 overrun = (scsp_sound_left + sample_count) - SCSP_SOUND_BUFSIZE;
1333 SCSPLOG("WARNING: Sound buffer overrun, %u samples\n", (int)overrun);
1334 scsp_sound_left -= overrun;
1335 }
1336 while (sample_count > 0)
1337 {
1338 u32 this_count = sample_count;
1339 if (scsp_sound_genpos >= SCSP_SOUND_BUFSIZE)
1340 scsp_sound_genpos = 0;
1341 if (this_count > SCSP_SOUND_BUFSIZE - scsp_sound_genpos)
1342 this_count = SCSP_SOUND_BUFSIZE - scsp_sound_genpos;
1343 bufL = &scsp_buffer_L[scsp_sound_genpos];
1344 bufR = &scsp_buffer_R[scsp_sound_genpos];
1345 ScspGenerateAudio(bufL, bufR, this_count);
1346 scsp_sound_genpos += this_count;
1347 scsp_sound_left += this_count;
1348 sample_count -= this_count;
1349 }
1350
1351 // Send audio to the output device if possible
1352 while (scsp_sound_left > 0 && (audio_free = SNDCore->GetAudioSpace()) > 0)
1353 {
1354 s32 out_start = (s32)scsp_sound_genpos - (s32)scsp_sound_left;
1355 if (out_start < 0)
1356 out_start += SCSP_SOUND_BUFSIZE;
1357 if (audio_free > scsp_sound_left)
1358 audio_free = scsp_sound_left;
1359 if (audio_free > SCSP_SOUND_BUFSIZE - out_start)
1360 audio_free = SCSP_SOUND_BUFSIZE - out_start;
1361 SNDCore->UpdateAudio((u32 *)&scsp_buffer_L[out_start],
1362 (u32 *)&scsp_buffer_R[out_start], audio_free);
1363 scsp_sound_left -= audio_free;
1364 #if 0
1365 ScspConvert32uto16s(&scsp_buffer_L[out_start], &scsp_buffer_R[out_start], (s16 *)stereodata16, audio_free);
1366 DRV_AviSoundUpdate(stereodata16, audio_free);
1367 #endif
1368 }
1369 }
1370 else // !scsp_frame_accurate
1371 {
1372 if ((audio_free = SNDCore->GetAudioSpace()))
1373 {
1374 if (audio_free > SCSP_SOUND_BUFSIZE)
1375 audio_free = SCSP_SOUND_BUFSIZE;
1376 ScspGenerateAudio(scsp_buffer_L, scsp_buffer_R, audio_free);
1377 SNDCore->UpdateAudio((u32 *)scsp_buffer_L,
1378 (u32 *)scsp_buffer_R, audio_free);
1379 #if 0
1380 ScspConvert32uto16s((s32 *)scsp_buffer_L, (s32 *)scsp_buffer_R, (s16 *)stereodata16, audio_free);
1381 DRV_AviSoundUpdate(stereodata16, audio_free);
1382 #endif
1383 }
1384 } // if (scsp_frame_accurate)
1385
1386 // Update scsp_clock last, so the main thread can use it as a signal
1387 // that we've finished processing to this point
1388 scsp_clock += cycles;
1389 }
1390
1391 //-------------------------------------------------------------------------
1392
1393 // ScspTimerCyclesLeft: Return the approximate number of SCSP clock cycles
1394 // before an SCSP timer (A, B, or C) triggers an interrupt.
1395
ScspTimerCyclesLeft(u16 timer,u8 timer_scale)1396 static u32 ScspTimerCyclesLeft(u16 timer, u8 timer_scale)
1397 {
1398 return (0xFF00 - timer) << timer_scale;
1399 }
1400
1401 //----------------------------------//
1402
1403 // ScspUpdateTimer: Update an SCSP timer (A, B, or C) by the given number
1404 // of output samples, and raise an interrupt if the timer reaches 0xFF.
1405
ScspUpdateTimer(u32 samples,u16 * timer_ptr,u8 timer_scale,int interrupt)1406 static void ScspUpdateTimer(u32 samples, u16 *timer_ptr, u8 timer_scale,
1407 int interrupt)
1408 {
1409 u32 timer_new = *timer_ptr + (samples << (8 - timer_scale));
1410 if (UNLIKELY(timer_new >= 0xFF00))
1411 {
1412 ScspRaiseInterrupt(interrupt, SCSP_INTTARGET_BOTH);
1413 timer_new -= 0xFF00; // We won't pass 0xFF00 multiple times at once
1414 }
1415 *timer_ptr = timer_new;
1416 }
1417
1418 //-------------------------------------------------------------------------
1419
1420 // ScspGenerateAudio: Generate the given number of audio samples based on
1421 // the current SCSP state, and update the sound slot counters.
1422
ScspGenerateAudio(s32 * bufL,s32 * bufR,u32 samples)1423 static void ScspGenerateAudio(s32 *bufL, s32 *bufR, u32 samples)
1424 {
1425 int slotnum;
1426
1427 u32 i;
1428 for (i = 0; i < samples; i++)
1429 bufL[i] = bufR[i] = 0;
1430
1431 scsp_bufL = bufL;
1432 scsp_bufR = bufR;
1433 for (slotnum = 0; slotnum < 32; slotnum++)
1434 ScspGenerateAudioForSlot(&scsp.slot[slotnum], samples);
1435
1436 if (cdda_next_out != PSP_UC(cdda_next_in) * 2352)
1437 {
1438 if (cdda_delay > 0)
1439 {
1440 if (samples > cdda_delay)
1441 {
1442 samples -= cdda_delay;
1443 cdda_delay = 0;
1444 }
1445 else
1446 {
1447 cdda_delay -= samples;
1448 samples = 0;
1449 }
1450 }
1451 if (cdda_delay == 0)
1452 ScspGenerateAudioForCDDA(bufL, bufR, samples);
1453 }
1454 if (cdda_next_out == PSP_UC(cdda_next_in) * 2352)
1455 cdda_delay = CDDA_DELAY_SAMPLES; // No data buffered, so reset delay
1456 }
1457
1458 //----------------------------------//
1459
1460 // ScspGenerateAudioForSlot: Generate audio samples and update counters for
1461 // a single slot. scsp_bufL and scsp_bufR are assumed to be set properly.
1462
ScspGenerateAudioForSlot(SlotState * slot,u32 samples)1463 static void ScspGenerateAudioForSlot(SlotState *slot, u32 samples)
1464 {
1465 if (slot->env_counter >= SCSP_ENV_DECAY_END)
1466 return; // No sound is currently playing
1467
1468 (*slot->audiogen)(slot, samples);
1469 }
1470
1471 //----------------------------------//
1472
1473 // ScspGenerateAudioForCDDA: Generate audio samples for buffered CDDA data.
1474
ScspGenerateAudioForCDDA(s32 * bufL,s32 * bufR,u32 samples)1475 static void ScspGenerateAudioForCDDA(s32 *bufL, s32 *bufR, u32 samples)
1476 {
1477 // May need to wrap around the buffer, so use nested loops
1478 while (samples > 0)
1479 {
1480 const u32 next_out = cdda_next_out; // Save volatile value locally
1481 const s32 temp = (PSP_UC(cdda_next_in) * 2352) - next_out;
1482 const u32 out_left = (temp < 0) ? sizeof(cdda_buf) - next_out : temp;
1483 const u32 this_len = (samples > out_left/4) ? out_left/4 : samples;
1484 const u8 *buf = &cdda_buf.data[next_out];
1485 const u8 *top = buf + this_len*4;
1486
1487 if (this_len == 0)
1488 break; // We ran out of buffered data
1489
1490 for (; buf < top; buf += 4, bufL++, bufR++)
1491 {
1492 *bufL += (s32)(s16)((buf[1] << 8) | buf[0]);
1493 *bufR += (s32)(s16)((buf[3] << 8) | buf[2]);
1494 }
1495
1496 if (next_out + this_len*4 >= sizeof(cdda_buf))
1497 cdda_next_out = 0;
1498 else
1499 cdda_next_out = next_out + this_len*4;
1500 samples -= this_len;
1501 }
1502 }
1503
1504 ///////////////////////////////////////////////////////////////////////////
1505 // SCSP register/memory access and I/O interface routines
1506 ///////////////////////////////////////////////////////////////////////////
1507
1508 // SoundRam{Read,Write}{Byte,Word,Long}: Read or write sound RAM.
1509 // Intended for calling from external sources.
1510
SoundRamReadByte(u32 address)1511 u8 FASTCALL SoundRamReadByte(u32 address)
1512 {
1513 address &= scsp.sound_ram_mask;
1514 return T2ReadByte(SoundRam, address);
1515 }
1516
SoundRamReadWord(u32 address)1517 u16 FASTCALL SoundRamReadWord(u32 address)
1518 {
1519 address &= scsp.sound_ram_mask;
1520 return T2ReadWord(SoundRam, address);
1521 }
1522
SoundRamReadLong(u32 address)1523 u32 FASTCALL SoundRamReadLong(u32 address)
1524 {
1525 address &= scsp.sound_ram_mask;
1526 return T2ReadLong(SoundRam, address);
1527 }
1528
1529 //----------------------------------//
1530
SoundRamWriteByte(u32 address,u8 data)1531 void FASTCALL SoundRamWriteByte(u32 address, u8 data)
1532 {
1533 address &= scsp.sound_ram_mask;
1534 T2WriteByte(SoundRam, address, data);
1535 M68K->WriteNotify(address, 1);
1536 }
1537
SoundRamWriteWord(u32 address,u16 data)1538 void FASTCALL SoundRamWriteWord(u32 address, u16 data)
1539 {
1540 address &= scsp.sound_ram_mask;
1541 T2WriteWord(SoundRam, address, data);
1542 M68K->WriteNotify(address, 2);
1543 }
1544
SoundRamWriteLong(u32 address,u32 data)1545 void FASTCALL SoundRamWriteLong(u32 address, u32 data)
1546 {
1547 address &= scsp.sound_ram_mask;
1548 T2WriteLong(SoundRam, address, data);
1549 M68K->WriteNotify(address, 4);
1550 }
1551
1552 //-------------------------------------------------------------------------
1553
1554 // Scsp{Read,Write}{Byte,Word,Long}: Read or write SCSP registers.
1555 // Intended for calling from external sources.
1556
ScspReadByte(u32 address)1557 u8 FASTCALL ScspReadByte(u32 address)
1558 {
1559 const u16 data = ScspReadWord(address & ~1);
1560 if (address & 1)
1561 return data & 0xFF;
1562 else
1563 return data >> 8;
1564 }
1565
ScspReadWord(u32 address)1566 u16 FASTCALL ScspReadWord(u32 address)
1567 {
1568 #ifdef PSP // Special handling for PSP cache management
1569 switch (address)
1570 {
1571 case 0x404: // MIDI in
1572 return 0xFF; // Not even supported, so don't bother trying
1573 case 0x408: // CA/SGC/EG
1574 return ScspReadMonitor();
1575 default:
1576 return PSP_UC(scsp_regcache[address >> 1]);
1577 }
1578 #else
1579 return ScspReadWordDirect(address & 0xFFF);
1580 #endif
1581 }
1582
ScspReadLong(u32 address)1583 u32 FASTCALL ScspReadLong(u32 address)
1584 {
1585 return (u32)ScspReadWord(address) << 16 | ScspReadWord(address+2);
1586 }
1587
1588 //----------------------------------//
1589
ScspWriteByte(u32 address,u8 data)1590 void FASTCALL ScspWriteByte(u32 address, u8 data)
1591 {
1592 if (scsp_thread_running)
1593 {
1594 PSP_UC(scsp_write_buffer_address) = address & 0xFFF;
1595 PSP_UC(scsp_write_buffer_data) = data;
1596 PSP_UC(scsp_write_buffer_size) = 1;
1597 while (PSP_UC(scsp_write_buffer_size) != 0)
1598 {
1599 YabThreadWake(YAB_THREAD_SCSP);
1600 YabThreadYield();
1601 }
1602 return;
1603 }
1604
1605 ScspWriteByteDirect(address & 0xFFF, data);
1606 }
1607
ScspWriteWord(u32 address,u16 data)1608 void FASTCALL ScspWriteWord(u32 address, u16 data)
1609 {
1610 if (scsp_thread_running)
1611 {
1612 PSP_UC(scsp_write_buffer_address) = address & 0xFFF;
1613 PSP_UC(scsp_write_buffer_data) = data;
1614 PSP_UC(scsp_write_buffer_size) = 2;
1615 while (PSP_UC(scsp_write_buffer_size) != 0)
1616 {
1617 YabThreadWake(YAB_THREAD_SCSP);
1618 YabThreadYield();
1619 }
1620 return;
1621 }
1622
1623 ScspWriteWordDirect(address & 0xFFF, data);
1624 }
1625
ScspWriteLong(u32 address,u32 data)1626 void FASTCALL ScspWriteLong(u32 address, u32 data)
1627 {
1628 if (scsp_thread_running)
1629 {
1630 PSP_UC(scsp_write_buffer_address) = address & 0xFFF;
1631 PSP_UC(scsp_write_buffer_data) = data;
1632 PSP_UC(scsp_write_buffer_size) = 4;
1633 while (PSP_UC(scsp_write_buffer_size) != 0)
1634 {
1635 YabThreadWake(YAB_THREAD_SCSP);
1636 YabThreadYield();
1637 }
1638 return;
1639 }
1640
1641 ScspWriteWordDirect(address & 0xFFF, data >> 16);
1642 ScspWriteWordDirect((address+2) & 0xFFF, data & 0xFFFF);
1643 }
1644
1645 //-------------------------------------------------------------------------
1646
1647 // ScspReceiveCDDA: Receive and buffer a sector (2352 bytes) of CDDA audio
1648 // data. Intended to be called by the CD driver when an audio sector has
1649 // been read in for playback.
1650
ScspReceiveCDDA(const u8 * sector)1651 void ScspReceiveCDDA(const u8 *sector)
1652 {
1653 const u32 next_in = cdda_next_in; // Save volatile value locally
1654 const u32 next_next_in =
1655 (next_in + 1) % (sizeof(cdda_buf.sectors) / sizeof(cdda_buf.sectors[0]));
1656
1657 // Make sure we have room for the new sector first
1658 const u32 next_out = PSP_UC(cdda_next_out);
1659 if (next_out > next_in * 2352 && next_out <= (next_in+1) * 2352)
1660 {
1661 SCSPLOG("WARNING: CDDA buffer overflow, discarding sector\n");
1662 return;
1663 }
1664
1665 memcpy(cdda_buf.sectors[next_in], sector, 2352);
1666 PSP_WRITEBACK_CACHE(cdda_buf.sectors[next_in], 2352);
1667 cdda_next_in = next_next_in;
1668 }
1669
1670 ///////////////////////////////////////////////////////////////////////////
1671 // Miscellaneous SCSP interface routines
1672 ///////////////////////////////////////////////////////////////////////////
1673
1674 // SoundSaveState: Save the current SCSP state to the given file.
1675
SoundSaveState(FILE * fp)1676 int SoundSaveState(FILE *fp)
1677 {
1678 int i;
1679 u32 temp;
1680 u8 temp8;
1681 int offset;
1682 IOCheck_struct check = { 0, 0 };
1683
1684 if (scsp_thread_running)
1685 ScspSyncThread();
1686
1687 offset = StateWriteHeader(fp, "SCSP", 2);
1688
1689 // Save 68k registers first
1690 ywrite(&check, (void *)&m68k_running, 1, 1, fp);
1691 for (i = 0; i < 8; i++)
1692 {
1693 temp = M68K->GetDReg(i);
1694 ywrite(&check, (void *)&temp, 4, 1, fp);
1695 }
1696 for (i = 0; i < 8; i++)
1697 {
1698 temp = M68K->GetAReg(i);
1699 ywrite(&check, (void *)&temp, 4, 1, fp);
1700 }
1701 temp = M68K->GetSR();
1702 ywrite(&check, (void *)&temp, 4, 1, fp);
1703 temp = M68K->GetPC();
1704 ywrite(&check, (void *)&temp, 4, 1, fp);
1705
1706 // Now for the SCSP registers
1707 ywrite(&check, (void *)scsp_regcache, 0x1000, 1, fp);
1708
1709 // Sound RAM is important
1710 ywrite(&check, (void *)SoundRam, 0x80000, 1, fp);
1711
1712 // Write slot internal variables
1713 for (i = 0; i < 32; i++)
1714 {
1715 ywrite(&check, (void *)&scsp.slot[i].key, 1, 1, fp);
1716 ywrite(&check, (void *)&scsp.slot[i].addr_counter, 4, 1, fp);
1717 ywrite(&check, (void *)&scsp.slot[i].env_counter, 4, 1, fp);
1718 ywrite(&check, (void *)&scsp.slot[i].env_step, 4, 1, fp);
1719 ywrite(&check, (void *)&scsp.slot[i].env_target, 4, 1, fp);
1720 ywrite(&check, (void *)&scsp.slot[i].env_phase, 4, 1, fp);
1721
1722 // Was enxt in scsp1; we don't use it, so just derive the proper
1723 // value from env_phase
1724 if (scsp.slot[i].env_phase == SCSP_ENV_RELEASE)
1725 temp8 = 1;
1726 else if (scsp.slot[i].env_phase == SCSP_ENV_SUSTAIN)
1727 temp8 = 2;
1728 else if (scsp.slot[i].env_phase == SCSP_ENV_DECAY)
1729 temp8 = 3;
1730 else if (scsp.slot[i].env_phase == SCSP_ENV_ATTACK)
1731 temp8 = 4;
1732 else // impossible, but avoid "undefined value" warnings
1733 temp8 = 0;
1734 ywrite(&check, (void *)&temp8, 1, 1, fp);
1735
1736 ywrite(&check, (void *)&scsp.slot[i].lfo_counter, 4, 1, fp);
1737 ywrite(&check, (void *)&scsp.slot[i].lfo_step, 4, 1, fp);
1738 }
1739
1740 // Write main internal variables
1741 // FIXME/SCSP1: need to write a lot of these from temporary variables
1742 // to maintain save state compatibility
1743 temp = scsp.mem4mb;
1744 ywrite(&check, (void *)&temp, 4, 1, fp);
1745 temp = scsp.mvol;
1746 ywrite(&check, (void *)&temp, 4, 1, fp);
1747
1748 temp = scsp.rbl;
1749 ywrite(&check, (void *)&temp, 4, 1, fp);
1750 ywrite(&check, (void *)&scsp.rbp, 4, 1, fp);
1751
1752 temp = scsp.mslc;
1753 ywrite(&check, (void *)&temp, 4, 1, fp);
1754
1755 ywrite(&check, (void *)&scsp.dmea, 4, 1, fp);
1756 temp = scsp.drga;
1757 ywrite(&check, (void *)&temp, 4, 1, fp);
1758 temp = scsp.dgate<<6 | scsp.ddir<<5 | scsp.dexe<<4;
1759 ywrite(&check, (void *)&temp, 4, 1, fp);
1760 temp = scsp.dtlg;
1761 ywrite(&check, (void *)&temp, 4, 1, fp);
1762
1763 ywrite(&check, (void *)scsp.midi_in_buf, 1, 4, fp);
1764 ywrite(&check, (void *)scsp.midi_out_buf, 1, 4, fp);
1765 ywrite(&check, (void *)&scsp.midi_in_cnt, 1, 1, fp);
1766 ywrite(&check, (void *)&scsp.midi_out_cnt, 1, 1, fp);
1767 temp8 = scsp.mofull<<4 | scsp.moemp<<3
1768 | scsp.miovf<<2 | scsp.mifull<<1 | scsp.miemp<<0;
1769 ywrite(&check, (void *)&temp8, 1, 1, fp);
1770
1771 temp = scsp.tima;
1772 ywrite(&check, (void *)&temp, 4, 1, fp);
1773 temp = scsp.tactl;
1774 ywrite(&check, (void *)&temp, 4, 1, fp);
1775 temp = scsp.timb;
1776 ywrite(&check, (void *)&temp, 4, 1, fp);
1777 temp = scsp.tbctl;
1778 ywrite(&check, (void *)&temp, 4, 1, fp);
1779 temp = scsp.timc;
1780 ywrite(&check, (void *)&temp, 4, 1, fp);
1781 temp = scsp.tcctl;
1782 ywrite(&check, (void *)&temp, 4, 1, fp);
1783
1784 temp = scsp.scieb;
1785 ywrite(&check, (void *)&temp, 4, 1, fp);
1786 temp = scsp.scipd;
1787 ywrite(&check, (void *)&temp, 4, 1, fp);
1788 temp = scsp.scilv0;
1789 ywrite(&check, (void *)&temp, 4, 1, fp);
1790 temp = scsp.scilv1;
1791 ywrite(&check, (void *)&temp, 4, 1, fp);
1792 temp = scsp.scilv2;
1793 ywrite(&check, (void *)&temp, 4, 1, fp);
1794 temp = scsp.mcieb;
1795 ywrite(&check, (void *)&temp, 4, 1, fp);
1796 temp = scsp.mcipd;
1797 ywrite(&check, (void *)&temp, 4, 1, fp);
1798
1799 ywrite(&check, (void *)scsp.stack, 4, 32 * 2, fp);
1800
1801 return StateFinishHeader(fp, offset);
1802 }
1803
1804 //-------------------------------------------------------------------------
1805
1806 // SoundLoadState: Load the current SCSP state from the given file.
1807
SoundLoadState(FILE * fp,int version,int size)1808 int SoundLoadState(FILE *fp, int version, int size)
1809 {
1810 int i, i2;
1811 u32 temp;
1812 u8 temp8;
1813 IOCheck_struct check = { 0, 0 };
1814
1815 if (scsp_thread_running)
1816 ScspSyncThread();
1817
1818 // Read 68k registers first
1819 yread(&check, (void *)&m68k_running, 1, 1, fp);
1820 for (i = 0; i < 8; i++)
1821 {
1822 yread(&check, (void *)&temp, 4, 1, fp);
1823 M68K->SetDReg(i, temp);
1824 }
1825 for (i = 0; i < 8; i++)
1826 {
1827 yread(&check, (void *)&temp, 4, 1, fp);
1828 M68K->SetAReg(i, temp);
1829 }
1830 yread(&check, (void *)&temp, 4, 1, fp);
1831 M68K->SetSR(temp);
1832 yread(&check, (void *)&temp, 4, 1, fp);
1833 M68K->SetPC(temp);
1834
1835 // Now for the SCSP registers
1836 yread(&check, (void *)scsp_regcache, 0x1000, 1, fp);
1837
1838 // And sound RAM
1839 yread(&check, (void *)SoundRam, 0x80000, 1, fp);
1840
1841 // Break out slot registers into their respective fields
1842 for (i = 0; i < 32; i++)
1843 {
1844 for (i2 = 0; i2 < 0x18; i2 += 2)
1845 ScspWriteWordDirect(i<<5 | i2, scsp_regcache[(i<<5 | i2) >> 1]);
1846 // These are also called during writes, so they're not technically
1847 // necessary, but call them again anyway just to ensure everything's
1848 // up to date
1849 ScspUpdateSlotAddress(&scsp.slot[i]);
1850 ScspUpdateSlotFunc(&scsp.slot[i]);
1851 }
1852
1853 if (version > 1)
1854 {
1855 // Read slot internal variables
1856 for (i = 0; i < 32; i++)
1857 {
1858 yread(&check, (void *)&scsp.slot[i].key, 1, 1, fp);
1859 yread(&check, (void *)&scsp.slot[i].addr_counter, 4, 1, fp);
1860 yread(&check, (void *)&scsp.slot[i].env_counter, 4, 1, fp);
1861 yread(&check, (void *)&scsp.slot[i].env_step, 4, 1, fp);
1862 yread(&check, (void *)&scsp.slot[i].env_target, 4, 1, fp);
1863 yread(&check, (void *)&scsp.slot[i].env_phase, 4, 1, fp);
1864
1865 // Was enxt in scsp1; we don't use it, so just read and ignore
1866 yread(&check, (void *)&temp8, 1, 1, fp);
1867
1868 yread(&check, (void *)&scsp.slot[i].lfo_counter, 4, 1, fp);
1869 yread(&check, (void *)&scsp.slot[i].lfo_step, 4, 1, fp);
1870 }
1871
1872 // Read main internal variables
1873 yread(&check, (void *)&temp, 4, 1, fp);
1874 scsp.mem4mb = temp;
1875 // This one isn't saved in the state file (though it's not used anyway)
1876 scsp.dac18b = (scsp_regcache[0x400>>1] >> 8) & 1;
1877 yread(&check, (void *)&temp, 4, 1, fp);
1878 scsp.mvol = temp;
1879
1880 yread(&check, (void *)&temp, 4, 1, fp);
1881 scsp.rbl = temp;
1882 yread(&check, (void *)&scsp.rbp, 4, 1, fp);
1883
1884 yread(&check, (void *)&temp, 4, 1, fp);
1885 scsp.mslc = temp;
1886
1887 yread(&check, (void *)&scsp.dmea, 4, 1, fp);
1888 yread(&check, (void *)&temp, 4, 1, fp);
1889 scsp.drga = temp;
1890 yread(&check, (void *)&temp, 4, 1, fp);
1891 scsp.dgate = temp>>6 & 1;
1892 scsp.ddir = temp>>5 & 1;
1893 scsp.dexe = temp>>4 & 1;
1894 yread(&check, (void *)&temp, 4, 1, fp);
1895 scsp.dtlg = temp;
1896
1897 yread(&check, (void *)scsp.midi_in_buf, 1, 4, fp);
1898 yread(&check, (void *)scsp.midi_out_buf, 1, 4, fp);
1899 yread(&check, (void *)&scsp.midi_in_cnt, 1, 1, fp);
1900 yread(&check, (void *)&scsp.midi_out_cnt, 1, 1, fp);
1901 yread(&check, (void *)&temp8, 1, 1, fp);
1902 scsp.mofull = temp8>>4 & 1;
1903 scsp.moemp = temp8>>3 & 1;
1904 scsp.miovf = temp8>>2 & 1;
1905 scsp.mifull = temp8>>1 & 1;
1906 scsp.miemp = temp8>>0 & 1;
1907
1908 yread(&check, (void *)&temp, 4, 1, fp);
1909 scsp.tima = temp;
1910 yread(&check, (void *)&temp, 4, 1, fp);
1911 scsp.tactl = temp;
1912 yread(&check, (void *)&temp, 4, 1, fp);
1913 scsp.timb = temp;
1914 yread(&check, (void *)&temp, 4, 1, fp);
1915 scsp.tbctl = temp;
1916 yread(&check, (void *)&temp, 4, 1, fp);
1917 scsp.timc = temp;
1918 yread(&check, (void *)&temp, 4, 1, fp);
1919 scsp.tcctl = temp;
1920
1921 yread(&check, (void *)&temp, 4, 1, fp);
1922 scsp.scieb = temp;
1923 yread(&check, (void *)&temp, 4, 1, fp);
1924 scsp.scipd = temp;
1925 yread(&check, (void *)&temp, 4, 1, fp);
1926 scsp.scilv0 = temp;
1927 yread(&check, (void *)&temp, 4, 1, fp);
1928 scsp.scilv1 = temp;
1929 yread(&check, (void *)&temp, 4, 1, fp);
1930 scsp.scilv2 = temp;
1931 yread(&check, (void *)&temp, 4, 1, fp);
1932 scsp.mcieb = temp;
1933 yread(&check, (void *)&temp, 4, 1, fp);
1934 scsp.mcipd = temp;
1935
1936 yread(&check, (void *)scsp.stack, 4, 32 * 2, fp);
1937 }
1938
1939 if (scsp_thread_running)
1940 PSP_FLUSH_ALL();
1941
1942 return size;
1943 }
1944
1945 //-------------------------------------------------------------------------
1946
1947 // ScspSlotDebugStats: Generate a string describing the given slot's state
1948 // and store it in the passed-in buffer (which is assumed to be large enough
1949 // to hold the result).
1950
1951 // Helper functions (defined below)
1952 static char *AddSoundLFO(char *outstring, const char *string, u16 level, u16 waveform);
1953 static char *AddSoundPan(char *outstring, u16 pan);
1954 static char *AddSoundLevel(char *outstring, u16 level);
1955
ScspSlotDebugStats(u8 slotnum,char * outstring)1956 void ScspSlotDebugStats(u8 slotnum, char *outstring)
1957 {
1958 AddString(outstring, "Sound Source = ");
1959 switch (scsp.slot[slotnum].ssctl)
1960 {
1961 case 0:
1962 {
1963 AddString(outstring, "External DRAM data\r\n");
1964 break;
1965 }
1966 case 1:
1967 {
1968 AddString(outstring, "Internal(Noise)\r\n");
1969 break;
1970 }
1971 case 2:
1972 {
1973 AddString(outstring, "Internal(0's)\r\n");
1974 break;
1975 }
1976 default:
1977 {
1978 AddString(outstring, "Invalid setting\r\n");
1979 break;
1980 }
1981 }
1982 AddString(outstring, "Source bit = ");
1983 switch (scsp.slot[slotnum].sbctl)
1984 {
1985 case 0:
1986 {
1987 AddString(outstring, "No bit reversal\r\n");
1988 break;
1989 }
1990 case 1:
1991 {
1992 AddString(outstring, "Reverse other bits\r\n");
1993 break;
1994 }
1995 case 2:
1996 {
1997 AddString(outstring, "Reverse sign bit\r\n");
1998 break;
1999 }
2000 case 3:
2001 {
2002 AddString(outstring, "Reverse sign and other bits\r\n");
2003 break;
2004 }
2005 }
2006
2007 // Loop Control
2008 AddString(outstring, "Loop Mode = ");
2009 switch (scsp.slot[slotnum].lpctl)
2010 {
2011 case 0:
2012 {
2013 AddString(outstring, "Off\r\n");
2014 break;
2015 }
2016 case 1:
2017 {
2018 AddString(outstring, "Normal\r\n");
2019 break;
2020 }
2021 case 2:
2022 {
2023 AddString(outstring, "Reverse\r\n");
2024 break;
2025 }
2026 case 3:
2027 {
2028 AddString(outstring, "Alternating\r\n");
2029 break;
2030 }
2031 }
2032 // PCM8B
2033 if (scsp.slot[slotnum].pcm8b)
2034 {
2035 AddString(outstring, "8-bit samples\r\n");
2036 }
2037 else
2038 {
2039 AddString(outstring, "16-bit samples\r\n");
2040 }
2041
2042 AddString(outstring, "Start Address = %05lX\r\n", (unsigned long)scsp.slot[slotnum].sa);
2043 AddString(outstring, "Loop Start Address = %04X\r\n", scsp.slot[slotnum].lsa);
2044 AddString(outstring, "Loop End Address = %04X\r\n", scsp.slot[slotnum].lea);
2045 AddString(outstring, "Decay 1 Rate = %d\r\n", scsp.slot[slotnum].dr);
2046 AddString(outstring, "Decay 2 Rate = %d\r\n", scsp.slot[slotnum].sr);
2047 if (scsp.slot[slotnum].eghold)
2048 {
2049 AddString(outstring, "EG Hold Enabled\r\n");
2050 }
2051 AddString(outstring, "Attack Rate = %d\r\n", scsp.slot[slotnum].ar);
2052
2053 if (scsp.slot[slotnum].lpslnk)
2054 {
2055 AddString(outstring, "Loop Start Link Enabled\r\n");
2056 }
2057
2058 if (scsp.slot[slotnum].krs != 0)
2059 {
2060 AddString(outstring, "Key rate scaling = %d\r\n", scsp.slot[slotnum].krs);
2061 }
2062
2063 AddString(outstring, "Decay Level = %d\r\n", scsp.slot[slotnum].sl);
2064 AddString(outstring, "Release Rate = %d\r\n", scsp.slot[slotnum].rr);
2065
2066 if (scsp.slot[slotnum].stwinh)
2067 {
2068 AddString(outstring, "Stack Write Inhibited\r\n");
2069 }
2070
2071 if (scsp.slot[slotnum].sdir)
2072 {
2073 AddString(outstring, "Sound Direct Enabled\r\n");
2074 }
2075
2076 AddString(outstring, "Total Level = %d\r\n", scsp.slot[slotnum].tl);
2077
2078 AddString(outstring, "Modulation Level = %d\r\n", scsp.slot[slotnum].mdl);
2079 AddString(outstring, "Modulation Input X = %d\r\n", scsp.slot[slotnum].mdx);
2080 AddString(outstring, "Modulation Input Y = %d\r\n", scsp.slot[slotnum].mdy);
2081
2082 AddString(outstring, "Octave = %d\r\n", scsp.slot[slotnum].oct);
2083 AddString(outstring, "Frequency Number Switch = %d\r\n", scsp.slot[slotnum].fns);
2084
2085 AddString(outstring, "LFO Reset = %s\r\n", scsp.slot[slotnum].lfore ? "TRUE" : "FALSE");
2086 AddString(outstring, "LFO Frequency = %d\r\n", scsp.slot[slotnum].lfof);
2087 outstring = AddSoundLFO(outstring, "LFO Frequency modulation waveform =",
2088 scsp.slot[slotnum].plfos, scsp.slot[slotnum].plfows);
2089 AddString(outstring, "LFO Frequency modulation level = %d\r\n", scsp.slot[slotnum].plfos);
2090 outstring = AddSoundLFO(outstring, "LFO Amplitude modulation waveform =",
2091 scsp.slot[slotnum].alfos, scsp.slot[slotnum].alfows);
2092 AddString(outstring, "LFO Amplitude modulation level = %d\r\n", scsp.slot[slotnum].alfos);
2093
2094 AddString(outstring, "Input mix level = ");
2095 outstring = AddSoundLevel(outstring, scsp.slot[slotnum].imxl);
2096 AddString(outstring, "Input Select = %d\r\n", scsp.slot[slotnum].isel);
2097
2098 AddString(outstring, "Direct data send level = ");
2099 outstring = AddSoundLevel(outstring, scsp.slot[slotnum].disdl);
2100 AddString(outstring, "Direct data panpot = ");
2101 outstring = AddSoundPan(outstring, scsp.slot[slotnum].dipan);
2102
2103 AddString(outstring, "Effect data send level = ");
2104 outstring = AddSoundLevel(outstring, scsp.slot[slotnum].efsdl);
2105 AddString(outstring, "Effect data panpot = ");
2106 outstring = AddSoundPan(outstring, scsp.slot[slotnum].efpan);
2107 }
2108
2109 //----------------------------------//
2110
AddSoundLFO(char * outstring,const char * string,u16 level,u16 waveform)2111 static char *AddSoundLFO(char *outstring, const char *string, u16 level, u16 waveform)
2112 {
2113 if (level > 0)
2114 {
2115 switch (waveform)
2116 {
2117 case 0:
2118 AddString(outstring, "%s Sawtooth\r\n", string);
2119 break;
2120 case 1:
2121 AddString(outstring, "%s Square\r\n", string);
2122 break;
2123 case 2:
2124 AddString(outstring, "%s Triangle\r\n", string);
2125 break;
2126 case 3:
2127 AddString(outstring, "%s Noise\r\n", string);
2128 break;
2129 }
2130 }
2131
2132 return outstring;
2133 }
2134
2135 //----------------------------------//
2136
AddSoundPan(char * outstring,u16 pan)2137 static char *AddSoundPan(char *outstring, u16 pan)
2138 {
2139 if (pan == 0x0F)
2140 {
2141 AddString(outstring, "Left = -MAX dB, Right = -0 dB\r\n");
2142 }
2143 else if (pan == 0x1F)
2144 {
2145 AddString(outstring, "Left = -0 dB, Right = -MAX dB\r\n");
2146 }
2147 else
2148 {
2149 AddString(outstring, "Left = -%d dB, Right = -%d dB\r\n", (pan & 0xF) * 3, (pan >> 4) * 3);
2150 }
2151
2152 return outstring;
2153 }
2154
2155 //----------------------------------//
2156
AddSoundLevel(char * outstring,u16 level)2157 static char *AddSoundLevel(char *outstring, u16 level)
2158 {
2159 if (level == 0)
2160 {
2161 AddString(outstring, "-MAX dB\r\n");
2162 }
2163 else
2164 {
2165 AddString(outstring, "-%d dB\r\n", (7-level) * 6);
2166 }
2167
2168 return outstring;
2169 }
2170
2171 //-------------------------------------------------------------------------
2172
2173 // ScspCommonControlRegisterDebugStats: Generate a string describing the
2174 // SCSP common state registers and store it in the passed-in buffer (which
2175 // is assumed to be large enough to hold the result).
2176
ScspCommonControlRegisterDebugStats(char * outstring)2177 void ScspCommonControlRegisterDebugStats(char *outstring)
2178 {
2179 AddString(outstring, "Memory: %s\r\n", scsp.mem4mb ? "4 Mbit" : "2 Mbit");
2180 AddString(outstring, "Master volume: %d\r\n", scsp.mvol);
2181 AddString(outstring, "Ring buffer length: %d\r\n", scsp.rbl);
2182 AddString(outstring, "Ring buffer address: %08lX\r\n", (unsigned long)scsp.rbp);
2183 AddString(outstring, "\r\n");
2184
2185 AddString(outstring, "Slot Status Registers\r\n");
2186 AddString(outstring, "-----------------\r\n");
2187 AddString(outstring, "Monitor slot: %d\r\n", scsp.mslc);
2188 AddString(outstring, "Call address: %d\r\n", (ScspReadWordDirect(0x408) >> 7) & 0xF);
2189 AddString(outstring, "\r\n");
2190
2191 AddString(outstring, "DMA Registers\r\n");
2192 AddString(outstring, "-----------------\r\n");
2193 AddString(outstring, "DMA memory address start: %08lX\r\n", (unsigned long)scsp.dmea);
2194 AddString(outstring, "DMA register address start: %03X\r\n", scsp.drga);
2195 AddString(outstring, "DMA Flags: %02X (%cDGATE %cDDIR %cDEXE)\r\n",
2196 scsp.dgate<<6 | scsp.ddir<<5 | scsp.dexe<<4,
2197 scsp.dgate ? '+' : '-', scsp.ddir ? '+' : '-',
2198 scsp.dexe ? '+' : '-');
2199 AddString(outstring, "\r\n");
2200
2201 AddString(outstring, "Timer Registers\r\n");
2202 AddString(outstring, "-----------------\r\n");
2203 AddString(outstring, "Timer A counter: %02X\r\n", scsp.tima >> 8);
2204 AddString(outstring, "Timer A increment: Every %d sample(s)\r\n", 1 << scsp.tactl);
2205 AddString(outstring, "Timer B counter: %02X\r\n", scsp.timb >> 8);
2206 AddString(outstring, "Timer B increment: Every %d sample(s)\r\n", 1 << scsp.tbctl);
2207 AddString(outstring, "Timer C counter: %02X\r\n", scsp.timc >> 8);
2208 AddString(outstring, "Timer C increment: Every %d sample(s)\r\n", 1 << scsp.tcctl);
2209 AddString(outstring, "\r\n");
2210
2211 AddString(outstring, "Interrupt Registers\r\n");
2212 AddString(outstring, "-----------------\r\n");
2213 AddString(outstring, "Sound cpu interrupt pending: %04X\r\n", scsp.scipd);
2214 AddString(outstring, "Sound cpu interrupt enable: %04X\r\n", scsp.scieb);
2215 AddString(outstring, "Sound cpu interrupt level 0: %04X\r\n", scsp.scilv0);
2216 AddString(outstring, "Sound cpu interrupt level 1: %04X\r\n", scsp.scilv1);
2217 AddString(outstring, "Sound cpu interrupt level 2: %04X\r\n", scsp.scilv2);
2218 AddString(outstring, "Main cpu interrupt pending: %04X\r\n", scsp.mcipd);
2219 AddString(outstring, "Main cpu interrupt enable: %04X\r\n", scsp.mcieb);
2220 AddString(outstring, "\r\n");
2221 }
2222
2223 //-------------------------------------------------------------------------
2224
2225 // ScspSlotDebugSaveRegisters: Write the values of a single slot's
2226 // registers to a file.
2227
ScspSlotDebugSaveRegisters(u8 slotnum,const char * filename)2228 int ScspSlotDebugSaveRegisters(u8 slotnum, const char *filename)
2229 {
2230 FILE *fp;
2231 int i;
2232 IOCheck_struct check = { 0, 0 };
2233
2234 if ((fp = fopen(filename, "wb")) == NULL)
2235 return -1;
2236
2237 for (i = (slotnum * 0x20); i < ((slotnum+1) * 0x20); i += 2)
2238 {
2239 #ifdef WORDS_BIGENDIAN
2240 ywrite(&check, (void *)&scsp_regcache[i], 1, 2, fp);
2241 #else
2242 ywrite(&check, (void *)&scsp_regcache[i+1], 1, 1, fp);
2243 ywrite(&check, (void *)&scsp_regcache[i], 1, 1, fp);
2244 #endif
2245 }
2246
2247 fclose(fp);
2248 return 0;
2249 }
2250
2251 //-------------------------------------------------------------------------
2252
2253 // ScspSlotDebugAudioSaveWav: Generate audio for a single slot and save it
2254 // to a WAV file.
2255
2256 // Helper function to generate audio (defined below)
2257 static u32 ScspSlotDebugAudio(SlotState *slot, s32 *workbuf, s16 *buf, u32 len);
2258
ScspSlotDebugAudioSaveWav(u8 slotnum,const char * filename)2259 int ScspSlotDebugAudioSaveWav(u8 slotnum, const char *filename)
2260 {
2261 typedef struct {
2262 char id[4];
2263 u32 size;
2264 } chunk_struct;
2265
2266 typedef struct {
2267 chunk_struct riff;
2268 char rifftype[4];
2269 } waveheader_struct;
2270
2271 typedef struct {
2272 chunk_struct chunk;
2273 u16 compress;
2274 u16 numchan;
2275 u32 rate;
2276 u32 bytespersec;
2277 u16 blockalign;
2278 u16 bitspersample;
2279 } fmt_struct;
2280
2281 s32 workbuf[512*2*2];
2282 s16 buf[512*2];
2283 SlotState slot;
2284 FILE *fp;
2285 u32 counter = 0;
2286 waveheader_struct waveheader;
2287 fmt_struct fmt;
2288 chunk_struct data;
2289 long length;
2290 IOCheck_struct check = { 0, 0 };
2291
2292 if (scsp.slot[slotnum].lea == 0)
2293 return 0;
2294
2295 if ((fp = fopen(filename, "wb")) == NULL)
2296 return -1;
2297
2298 // Do wave header
2299 memcpy(waveheader.riff.id, "RIFF", 4);
2300 waveheader.riff.size = 0; // we'll fix this after the file is closed
2301 memcpy(waveheader.rifftype, "WAVE", 4);
2302 ywrite(&check, (void *)&waveheader, 1, sizeof(waveheader_struct), fp);
2303
2304 // fmt chunk
2305 memcpy(fmt.chunk.id, "fmt ", 4);
2306 fmt.chunk.size = 16; // we'll fix this at the end
2307 fmt.compress = 1; // PCM
2308 fmt.numchan = 2; // Stereo
2309 fmt.rate = 44100;
2310 fmt.bitspersample = 16;
2311 fmt.blockalign = fmt.bitspersample / 8 * fmt.numchan;
2312 fmt.bytespersec = fmt.rate * fmt.blockalign;
2313 ywrite(&check, (void *)&fmt, 1, sizeof(fmt_struct), fp);
2314
2315 // data chunk
2316 memcpy(data.id, "data", 4);
2317 data.size = 0; // we'll fix this at the end
2318 ywrite(&check, (void *)&data, 1, sizeof(chunk_struct), fp);
2319
2320 memcpy(&slot, &scsp.slot[slotnum], sizeof(slot));
2321
2322 // Clear out the phase counter, etc.
2323 slot.addr_counter = 0;
2324 slot.env_counter = SCSP_ENV_ATTACK_START;
2325 slot.env_step = slot.env_step_a;
2326 slot.env_target = SCSP_ENV_ATTACK_END;
2327 slot.env_phase = SCSP_ENV_ATTACK;
2328
2329 // Mix the audio, and then write it to the file
2330 for(;;)
2331 {
2332 if (ScspSlotDebugAudio(&slot, workbuf, buf, 512) == 0)
2333 break;
2334
2335 counter += 512;
2336 ywrite(&check, (void *)buf, 2, 512 * 2, fp);
2337 if (slot.lpctl != 0 && counter >= (44100 * 2 * 5))
2338 break;
2339 }
2340
2341 length = ftell(fp);
2342
2343 // Let's fix the riff chunk size and the data chunk size
2344 fseek(fp, sizeof(waveheader_struct)-0x8, SEEK_SET);
2345 length -= 0x4;
2346 ywrite(&check, (void *)&length, 1, 4, fp);
2347
2348 fseek(fp, sizeof(waveheader_struct)+sizeof(fmt_struct)+0x4, SEEK_SET);
2349 length -= sizeof(waveheader_struct)+sizeof(fmt_struct);
2350 ywrite(&check, (void *)&length, 1, 4, fp);
2351 fclose(fp);
2352 return 0;
2353 }
2354
2355 //----------------------------------//
2356
ScspSlotDebugAudio(SlotState * slot,s32 * workbuf,s16 * buf,u32 len)2357 static u32 ScspSlotDebugAudio(SlotState *slot, s32 *workbuf, s16 *buf, u32 len)
2358 {
2359 s32 *bufL, *bufR;
2360
2361 bufL = workbuf;
2362 bufR = workbuf+len;
2363 scsp_bufL = bufL;
2364 scsp_bufR = bufR;
2365
2366 if (slot->env_counter >= SCSP_ENV_DECAY_END)
2367 return 0; // Not playing
2368
2369 if (slot->ssctl)
2370 return 0; // not yet supported!
2371
2372 memset(bufL, 0, sizeof(u32) * len);
2373 memset(bufR, 0, sizeof(u32) * len);
2374 ScspGenerateAudioForSlot(slot, len);
2375 ScspConvert32uto16s(bufL, bufR, buf, len);
2376 return len;
2377 }
2378
2379 //-------------------------------------------------------------------------
2380
2381 // ScspConvert32uto16s: Saturate two 32-bit input sample buffers to 16-bit
2382 // and interleave them into a single output buffer.
2383
ScspConvert32uto16s(s32 * srcL,s32 * srcR,s16 * dest,u32 len)2384 void ScspConvert32uto16s(s32 *srcL, s32 *srcR, s16 *dest, u32 len)
2385 {
2386 u32 i;
2387
2388 for (i = 0; i < len; i++, srcL++, srcR++, dest += 2)
2389 {
2390 // Left channel
2391 if (*srcL > 0x7FFF)
2392 dest[0] = 0x7FFF;
2393 else if (*srcL < -0x8000)
2394 dest[0] = -0x8000;
2395 else
2396 dest[0] = *srcL;
2397 // Right channel
2398 if (*srcR > 0x7FFF)
2399 dest[1] = 0x7FFF;
2400 else if (*srcR < -0x8000)
2401 dest[1] = -0x8000;
2402 else
2403 dest[1] = *srcR;
2404 }
2405 }
2406
2407 ///////////////////////////////////////////////////////////////////////////
2408 // SCSP register read/write routines and internal helpers
2409 ///////////////////////////////////////////////////////////////////////////
2410
2411 // Scsp{Read,Write}{Byte,Word}Direct: Perform an SCSP register read or
2412 // write. These are internal routines that implement the actual register
2413 // read/write logic. The address must be in the range [0,0xFFF].
2414
ScspReadByteDirect(u32 address)2415 static u8 FASTCALL ScspReadByteDirect(u32 address)
2416 {
2417 const u16 data = ScspReadWordDirect(address & ~1);
2418 if (address & 1)
2419 return data & 0xFF;
2420 else
2421 return data >> 8;
2422 }
2423
2424 //----------------------------------//
2425
ScspReadMonitor(void)2426 static u16 ScspReadMonitor(void)
2427 {
2428 u8 ca, sgc, eg;
2429
2430 ca = (scsp.slot[scsp.mslc].addr_counter >> (SCSP_FREQ_LOW_BITS + 12)) & 0xF;
2431
2432 switch (scsp.slot[scsp.mslc].env_phase) {
2433 case SCSP_ENV_ATTACK:
2434 sgc = 0;
2435 break;
2436 case SCSP_ENV_DECAY:
2437 sgc = 1;
2438 break;
2439 case SCSP_ENV_SUSTAIN:
2440 sgc = 2;
2441 break;
2442 case SCSP_ENV_RELEASE:
2443 sgc = 3;
2444 break;
2445 }
2446
2447 eg = 0x1f - (scsp.slot[scsp.mslc].last_env >> 27);
2448
2449 return (ca << 7) | (sgc << 5) | eg;
2450 }
2451
ScspReadWordDirect(u32 address)2452 static u16 FASTCALL ScspReadWordDirect(u32 address)
2453 {
2454 switch (address)
2455 {
2456 case 0x404: // MIDI in
2457 return ScspMidiIn();
2458 case 0x408: // CA/SGC/EG
2459 return ScspReadMonitor();
2460 default:
2461 return PSP_UC(scsp_regcache[address >> 1]);
2462 }
2463 }
2464
2465 //----------------------------------//
2466
ScspWriteByteDirect(u32 address,u8 data)2467 static void FASTCALL ScspWriteByteDirect(u32 address, u8 data)
2468 {
2469 switch (address >> 8)
2470 {
2471 case 0x0:
2472 case 0x1:
2473 case 0x2:
2474 case 0x3:
2475 write_as_word:
2476 {
2477 // These can be treated as word writes, borrowing the missing
2478 // 8 bits from the register cache
2479 u16 word_data;
2480 if (address & 1)
2481 word_data = (PSP_UC(scsp_regcache[address >> 1]) & 0xFF00) | data;
2482 else
2483 word_data = (PSP_UC(scsp_regcache[address >> 1]) & 0x00FF) | (data << 8);
2484 ScspWriteWordDirect(address & ~1, word_data);
2485 return;
2486 }
2487
2488 case 0x4:
2489 switch (address & 0xFF)
2490 {
2491 // FIXME: if interrupts are only triggered on 0->1 changes in
2492 // [SM]CIEB, we can skip 0x1E/0x1F/0x26/0x27 (see FIXME in
2493 // ScspWriteWordDirect())
2494
2495 case 0x1E:
2496 data &= 0x07;
2497 scsp.scieb = (data << 8) | (scsp.scieb & 0x00FF);
2498 ScspCheckInterrupts(0x700, SCSP_INTTARGET_SOUND);
2499 break;
2500
2501 case 0x1F:
2502 scsp.scieb = (scsp.scieb & 0xFF00) | data;
2503 ScspCheckInterrupts(0x700, SCSP_INTTARGET_SOUND);
2504 break;
2505
2506 case 0x20:
2507 return; // Not writable
2508
2509 case 0x21:
2510 if (data & (1<<5))
2511 ScspRaiseInterrupt(5, SCSP_INTTARGET_SOUND);
2512 return; // Not writable
2513
2514 case 0x2A:
2515 data &= 0x07;
2516 scsp.mcieb = (data << 8) | (scsp.mcieb & 0x00FF);
2517 ScspCheckInterrupts(0x700, SCSP_INTTARGET_MAIN);
2518 break;
2519
2520 case 0x2B:
2521 scsp.mcieb = (scsp.mcieb & 0xFF00) | data;
2522 ScspCheckInterrupts(0x700, SCSP_INTTARGET_MAIN);
2523 break;
2524
2525 case 0x2C:
2526 return; // Not writable
2527
2528 case 0x2D:
2529 if (data & (1<<5))
2530 ScspRaiseInterrupt(5, SCSP_INTTARGET_MAIN);
2531 return; // Not writable
2532
2533 case 0x00:
2534 case 0x01:
2535 case 0x02:
2536 case 0x03:
2537 case 0x04:
2538 case 0x05:
2539 case 0x06:
2540 case 0x07:
2541 case 0x08:
2542 case 0x09:
2543 case 0x12:
2544 case 0x13:
2545 case 0x14:
2546 case 0x15:
2547 case 0x16:
2548 case 0x17:
2549 case 0x18:
2550 case 0x19:
2551 case 0x1A:
2552 case 0x1B:
2553 case 0x1C:
2554 case 0x1D:
2555 case 0x22:
2556 case 0x23:
2557 case 0x24:
2558 case 0x25:
2559 case 0x26:
2560 case 0x27:
2561 case 0x28:
2562 case 0x29:
2563 case 0x2E:
2564 case 0x2F:
2565 goto write_as_word;
2566
2567 default:
2568 goto unhandled_write;
2569 }
2570 break;
2571
2572 default:
2573 unhandled_write:
2574 SCSPLOG("ScspWriteByteDirect(): unhandled write %02X to 0x%03X\n",
2575 data, address);
2576 break;
2577 }
2578
2579 if (address & 1)
2580 {
2581 PSP_UC(scsp_regcache[address >> 1]) &= 0xFF00;
2582 PSP_UC(scsp_regcache[address >> 1]) |= data;
2583 }
2584 else
2585 {
2586 PSP_UC(scsp_regcache[address >> 1]) &= 0x00FF;
2587 PSP_UC(scsp_regcache[address >> 1]) |= data << 8;
2588 }
2589 }
2590
2591 //----------------------------------//
2592
ScspWriteWordDirect(u32 address,u16 data)2593 static void FASTCALL ScspWriteWordDirect(u32 address, u16 data)
2594 {
2595 switch (address >> 8)
2596 {
2597 case 0x0:
2598 case 0x1:
2599 case 0x2:
2600 case 0x3:
2601 {
2602 const int slotnum = (address & 0x3E0) >> 5;
2603 SlotState *slot = &scsp.slot[slotnum];
2604 switch (address & 0x1F)
2605 {
2606 case 0x00:
2607 slot->key = (data >> 11) & 0x1;
2608 slot->sbctl = (data >> 9) & 0x3;
2609 slot->ssctl = (data >> 7) & 0x3;
2610 slot->lpctl = (data >> 5) & 0x3;
2611 slot->pcm8b = (data >> 4) & 0x1;
2612 slot->sa =((data >> 0) & 0xF) << 16 | (slot->sa & 0xFFFF);
2613
2614 ScspUpdateSlotFunc(slot);
2615 if (slot->env_counter < SCSP_ENV_DECAY_END)
2616 ScspUpdateSlotAddress(slot);
2617
2618 if (data & (1<<12))
2619 ScspDoKeyOnOff();
2620
2621 data &= 0x0FFF; // Don't save KYONEX
2622 break;
2623
2624 case 0x02:
2625 slot->sa = (slot->sa & 0xF0000) | data;
2626 if (slot->env_counter < SCSP_ENV_DECAY_END)
2627 ScspUpdateSlotAddress(slot);
2628 break;
2629
2630 case 0x04:
2631 slot->lsa = data;
2632 if (slot->env_counter < SCSP_ENV_DECAY_END)
2633 ScspUpdateSlotAddress(slot);
2634 break;
2635
2636 case 0x06:
2637 slot->lea = data;
2638 if (slot->env_counter < SCSP_ENV_DECAY_END)
2639 ScspUpdateSlotAddress(slot);
2640 break;
2641
2642 case 0x08:
2643 slot->sr = (data >> 11) & 0x1F;
2644 slot->dr = (data >> 6) & 0x1F;
2645 slot->eghold = (data >> 5) & 0x1;
2646 slot->ar = (data >> 0) & 0x1F;
2647 ScspUpdateSlotEnv(slot);
2648 break;
2649
2650 case 0x0A:
2651 data &= 0x7FFF;
2652 slot->lpslnk = (data >> 14) & 0x1;
2653 slot->krs = (data >> 10) & 0xF;
2654 slot->sl = (data >> 5) & 0x1F;
2655 slot->rr = (data >> 0) & 0x1F;
2656
2657 if (slot->krs == 0xF)
2658 slot->krs_shift = 4;
2659 else
2660 slot->krs_shift = slot->krs >> 2;
2661
2662 ScspUpdateSlotEnv(slot);
2663
2664 slot->sl_target = (slot->sl << (5 + SCSP_ENV_LOW_BITS))
2665 + SCSP_ENV_DECAY_START;
2666
2667 break;
2668
2669 case 0x0C:
2670 data &= 0x03FF;
2671 slot->stwinh = (data >> 9) & 0x1;
2672 slot->sdir = (data >> 8) & 0x1;
2673 slot->tl = (data >> 0) & 0xFF;
2674
2675 slot->tl_mult = scsp_tl_table[slot->tl];
2676
2677 break;
2678
2679 case 0x0E:
2680 slot->mdl = (data >> 12) & 0xF;
2681 slot->mdx = (data >> 6) & 0x3F;
2682 slot->mdy = (data >> 0) & 0x3F;
2683 break;
2684
2685 case 0x10:
2686 data &= 0x7BFF;
2687 slot->oct = (data >> 11) & 0xF;
2688 slot->fns = (data >> 0) & 0x3FF;
2689
2690 if (slot->oct & 8)
2691 slot->octave_shift = 23 - slot->oct;
2692 else
2693 slot->octave_shift = 7 - slot->oct;
2694 slot->addr_step = ((0x400 + slot->fns) << 7) >> slot->octave_shift;
2695
2696 ScspUpdateSlotEnv(slot);
2697
2698 break;
2699
2700 case 0x12:
2701 slot->lfore = (data >> 15) & 0x1;
2702 slot->lfof = (data >> 10) & 0x1F;
2703 slot->plfows = (data >> 8) & 0x3;
2704 slot->plfos = (data >> 5) & 0x7;
2705 slot->alfows = (data >> 3) & 0x3;
2706 slot->alfos = (data >> 0) & 0x7;
2707
2708 if (slot->lfore)
2709 {
2710 slot->lfo_step = -1;
2711 slot->lfo_counter = 0;
2712 slot->lfo_fm_shift = -1;
2713 slot->lfo_am_shift = -1;
2714 }
2715 else
2716 {
2717 slot->lfo_step = scsp_lfo_step[slot->lfof];
2718 if (slot->plfos)
2719 slot->lfo_fm_shift = slot->plfos - 1;
2720 else
2721 slot->lfo_fm_shift = -1;
2722 if (slot->alfos)
2723 slot->lfo_am_shift = 11 - slot->alfos;
2724 else
2725 slot->lfo_am_shift = -1;
2726 }
2727 slot->lfo_fm_wave = scsp_lfo_wave_freq[slot->plfows];
2728 slot->lfo_am_wave = scsp_lfo_wave_amp[slot->alfows];
2729
2730 ScspUpdateSlotFunc(slot);
2731
2732 break;
2733
2734 case 0x14:
2735 data &= 0x007F;
2736 slot->isel = (data >> 3) & 0xF;
2737 slot->imxl = (data >> 0) & 0x7;
2738
2739 if (slot->imxl)
2740 slot->imxl_shift = (7 - slot->imxl) + SCSP_ENV_HIGH_BITS;
2741 else
2742 slot->imxl_shift = 31;
2743
2744 break;
2745
2746 case 0x16:
2747 slot->disdl = (data >> 13) & 0x7;
2748 slot->dipan = (data >> 8) & 0x1F;
2749 slot->efsdl = (data >> 5) & 0x7;
2750 slot->efpan = (data >> 0) & 0x1F;
2751
2752 // Compute the output shift counts for the left and right
2753 // channels. If the direct sound output is muted, we assume
2754 // the data is being passed through the DSP (which we don't
2755 // currently implement) and take the effect output level
2756 // instead. Note that we lose 1 bit of resolution from the
2757 // panning parameter because we adjust the output level by
2758 // shifting (powers of two), while DIPAN/EFPAN have a
2759 // resolution of sqrt(2).
2760
2761 if (slot->disdl)
2762 {
2763 slot->outshift_l = slot->outshift_r = (7 - slot->disdl)
2764 + SCSP_ENV_HIGH_BITS;
2765 if (slot->dipan & 0x10) // Pan left
2766 {
2767 if (slot->dipan == 0x1F)
2768 slot->outshift_r = 31;
2769 else
2770 slot->outshift_r += (slot->dipan >> 1) & 7;
2771 }
2772 else // Pan right
2773 {
2774 if (slot->dipan == 0xF)
2775 slot->outshift_l = 31;
2776 else
2777 slot->outshift_l += (slot->dipan >> 1) & 7;
2778 }
2779 }
2780 else if (slot->efsdl)
2781 {
2782 slot->outshift_l = slot->outshift_r = (7 - slot->efsdl)
2783 + SCSP_ENV_HIGH_BITS;
2784 if (slot->efpan & 0x10) // Pan left
2785 {
2786 if (slot->efpan == 0x1F)
2787 slot->outshift_r = 31;
2788 else
2789 slot->outshift_r += (slot->efpan >> 1) & 7;
2790 }
2791 else // Pan right
2792 {
2793 if (slot->efpan == 0xF)
2794 slot->outshift_l = 31;
2795 else
2796 slot->outshift_l += (slot->efpan >> 1) & 7;
2797 }
2798 }
2799 else
2800 slot->outshift_l = slot->outshift_r = 31; // Muted
2801
2802 ScspUpdateSlotFunc(slot);
2803
2804 break;
2805
2806 default:
2807 goto unhandled_write;
2808 }
2809 break;
2810 }
2811
2812 case 0x4:
2813 switch (address & 0xFF)
2814 {
2815 case 0x00:
2816 data &= 0x030F; // VER is hardwired
2817 data |= SCSP_VERSION << 4;
2818 scsp.mem4mb = (data >> 9) & 0x1;
2819 scsp.dac18b = (data >> 8) & 0x1;
2820 scsp.mvol = (data >> 0) & 0xF;
2821
2822 if (scsp.mem4mb)
2823 M68K->SetFetch(0x000000, 0x080000, (pointer)SoundRam);
2824 else
2825 {
2826 M68K->SetFetch(0x000000, 0x040000, (pointer)SoundRam);
2827 M68K->SetFetch(0x040000, 0x080000, (pointer)SoundRam);
2828 M68K->SetFetch(0x080000, 0x0C0000, (pointer)SoundRam);
2829 M68K->SetFetch(0x0C0000, 0x100000, (pointer)SoundRam);
2830 }
2831 scsp.sound_ram_mask = scsp.mem4mb ? 0x7FFFF : 0x3FFFF;
2832
2833 break;
2834
2835 case 0x02:
2836 data &= 0x01FF;
2837 scsp.rbl = (data >> 7) & 0x3;
2838 scsp.rbp =((data >> 0) & 0x7F) << 13;
2839 break;
2840
2841 case 0x04:
2842 return; // Not writable
2843
2844 case 0x06:
2845 data &= 0x00FF;
2846 ScspMidiOut(data);
2847 break;
2848
2849 case 0x08:
2850 data &= 0x7800; // CA/SGC/EG are not writable
2851 scsp.mslc = (data >> 11) & 0x1F;
2852 break;
2853
2854 case 0x12:
2855 data &= 0xFFFE;
2856 scsp.dmea = (scsp.dmea & 0xF0000) | data;
2857 break;
2858
2859 case 0x14:
2860 data &= 0xFFFE;
2861 scsp.dmea =((data >> 12) & 0xF) << 16 | (scsp.dmea & 0xFFFF);
2862 scsp.drga = (data >> 0) & 0xFFF;
2863 break;
2864
2865 case 0x16:
2866 data &= 0x7FFE;
2867 scsp.dgate = (data >> 14) & 0x1;
2868 scsp.ddir = (data >> 13) & 0x1;
2869 scsp.dexe |= (data >> 12) & 0x1; // Writing 0 not allowed
2870 scsp.dtlg = (data >> 0) & 0xFFF;
2871 if (data & (1<<12))
2872 ScspDoDMA();
2873 break;
2874
2875 case 0x18:
2876 data &= 0x07FF;
2877 scsp.tactl = (data >> 8) & 0x7;
2878 scsp.tima =((data >> 0) & 0xFF) << 8;
2879 break;
2880
2881 case 0x1A:
2882 data &= 0x07FF;
2883 scsp.tbctl = (data >> 8) & 0x7;
2884 scsp.timb =((data >> 0) & 0xFF) << 8;
2885 break;
2886
2887 case 0x1C:
2888 data &= 0x07FF;
2889 scsp.tcctl = (data >> 8) & 0x7;
2890 scsp.timc =((data >> 0) & 0xFF) << 8;
2891 break;
2892
2893 case 0x1E:
2894 data &= 0x07FF;
2895 scsp.scieb = data;
2896 // FIXME: If a bit is already 1 in both SCIEB and SCIPD,
2897 // does writing another 1 here (no change) trigger another
2898 // interrupt or not?
2899 ScspCheckInterrupts(0x7FF, SCSP_INTTARGET_SOUND);
2900 break;
2901
2902 case 0x20:
2903 if (data & (1<<5))
2904 ScspRaiseInterrupt(5, SCSP_INTTARGET_SOUND);
2905 return; // Not writable
2906
2907 case 0x22:
2908 ScspClearInterrupts(data, SCSP_INTTARGET_SOUND);
2909 return; // Not writable
2910
2911 case 0x24:
2912 data &= 0x00FF;
2913 scsp.scilv0 = data;
2914 break;
2915
2916 case 0x26:
2917 data &= 0x00FF;
2918 scsp.scilv1 = data;
2919 break;
2920
2921 case 0x28:
2922 data &= 0x00FF;
2923 scsp.scilv2 = data;
2924 break;
2925
2926 case 0x2A:
2927 data &= 0x07FF;
2928 scsp.mcieb = data;
2929 // FIXME: as above (SCIEB)
2930 ScspCheckInterrupts(0x7FF, SCSP_INTTARGET_MAIN);
2931 break;
2932
2933 case 0x2C:
2934 if (data & (1<<5))
2935 ScspRaiseInterrupt(5, SCSP_INTTARGET_MAIN);
2936 return; // Not writable
2937
2938 case 0x2E:
2939 ScspClearInterrupts(data, SCSP_INTTARGET_MAIN);
2940 return; // Not writable
2941
2942 default:
2943 goto unhandled_write;
2944 }
2945 break;
2946
2947 default:
2948 unhandled_write:
2949 SCSPLOG("ScspWriteWordDirect(): unhandled write %04X to 0x%03X\n",
2950 data, address);
2951 break;
2952 }
2953
2954 PSP_UC(scsp_regcache[address >> 1]) = data;
2955 }
2956
2957 //-------------------------------------------------------------------------
2958
2959 // ScspDoKeyOnOff: Apply the key-on/key-off setting for all slots.
2960 // Implements the KYONEX trigger.
2961
ScspDoKeyOnOff(void)2962 static void ScspDoKeyOnOff(void)
2963 {
2964 int slotnum;
2965 for (slotnum = 0; slotnum < 32; slotnum++)
2966 {
2967 if (scsp.slot[slotnum].key)
2968 ScspKeyOn(&scsp.slot[slotnum]);
2969 else
2970 ScspKeyOff(&scsp.slot[slotnum]);
2971 }
2972 }
2973
2974 //----------------------------------//
2975
2976 // ScspKeyOn: Execute a key-on event for a single slot.
2977
ScspKeyOn(SlotState * slot)2978 static void ScspKeyOn(SlotState *slot)
2979 {
2980 if (slot->env_phase != SCSP_ENV_RELEASE)
2981 return; // Can't key a sound that's already playing
2982
2983 ScspUpdateSlotAddress(slot);
2984
2985 slot->addr_counter = 0;
2986 slot->env_phase = SCSP_ENV_ATTACK;
2987 slot->env_counter = SCSP_ENV_ATTACK_START; // FIXME: should this start at the current value if the old sound is still decaying?
2988 slot->env_step = slot->env_step_a;
2989 slot->env_target = SCSP_ENV_ATTACK_END;
2990 }
2991
2992 //----------------------------------//
2993
2994 // ScspKeyOff: Execute a key-off event for a single slot.
2995
ScspKeyOff(SlotState * slot)2996 static void ScspKeyOff(SlotState *slot)
2997 {
2998 if (slot->env_phase == SCSP_ENV_RELEASE)
2999 return; // Can't release a sound that's already released
3000
3001 // If we still are in attack phase at release time, convert attack to decay
3002 if (slot->env_phase == SCSP_ENV_ATTACK)
3003 slot->env_counter = SCSP_ENV_DECAY_END - slot->env_counter;
3004
3005 slot->env_phase = SCSP_ENV_RELEASE;
3006 slot->env_step = slot->env_step_r;
3007 slot->env_target = SCSP_ENV_DECAY_END;
3008 }
3009
3010 //-------------------------------------------------------------------------
3011
3012 // ScspUpdateSlotAddress: Update the sample data pointer for the given
3013 // slot, bound slot->lea to the end of sound RAM, and cache the shifted
3014 // values of slot->lsa and slot->lea in slot->{lea,lsa}_shifted.
3015
ScspUpdateSlotAddress(SlotState * slot)3016 static void ScspUpdateSlotAddress(SlotState *slot)
3017 {
3018 u32 max_samples;
3019
3020 if (slot->pcm8b)
3021 slot->sa &= ~1;
3022 slot->sa &= scsp.sound_ram_mask;
3023 slot->buf = &SoundRam[slot->sa];
3024 max_samples = scsp.sound_ram_mask - slot->sa;
3025 if (slot->pcm8b)
3026 max_samples >>= 1;
3027
3028 if (slot->lsa > max_samples)
3029 slot->lsa = max_samples;
3030 slot->lsa_shifted = slot->lsa << SCSP_FREQ_LOW_BITS;
3031
3032 if (slot->lea > max_samples)
3033 slot->lea = max_samples;
3034 slot->lea_shifted = ((slot->lea + 1) << SCSP_FREQ_LOW_BITS) - 1;
3035
3036 slot->looplen_shifted = slot->lea_shifted - slot->lsa_shifted + 1;
3037 }
3038
3039 //----------------------------------//
3040
3041 // ScspUpdateSlotEnv: Update the envelope step values from the SR/DR/AR/RR
3042 // slot registers. slot->krs_shift and slot->octave_shift are assumed to
3043 // be up to date with respect to the KRS and OCT registers.
3044
ScspUpdateSlotEnv(SlotState * slot)3045 static void ScspUpdateSlotEnv(SlotState *slot)
3046 {
3047 if (slot->sr)
3048 {
3049 const s32 *rate_table = &scsp_decay_rate[slot->sr << 1];
3050 slot->env_step_s = rate_table[(15 - slot->octave_shift)
3051 >> slot->krs_shift];
3052 }
3053 else
3054 slot->env_step_s = 0;
3055
3056 if (slot->dr)
3057 {
3058 const s32 *rate_table = &scsp_decay_rate[slot->dr << 1];
3059 slot->env_step_d = rate_table[(15 - slot->octave_shift)
3060 >> slot->krs_shift];
3061 }
3062 else
3063 slot->env_step_d = 0;
3064
3065 if (slot->ar)
3066 {
3067 const s32 *rate_table = &scsp_attack_rate[slot->ar << 1];
3068 slot->env_step_a = rate_table[(15 - slot->octave_shift)
3069 >> slot->krs_shift];
3070 }
3071 else
3072 slot->env_step_a = 0;
3073
3074 if (slot->rr)
3075 {
3076 const s32 *rate_table = &scsp_decay_rate[slot->rr << 1];
3077 slot->env_step_r = rate_table[(15 - slot->octave_shift)
3078 >> slot->krs_shift];
3079 }
3080 else
3081 slot->env_step_r = 0;
3082 }
3083
3084 //----------------------------------//
3085
3086 // ScspUpdateSlotFunc: Update the audio generation function for the given
3087 // slot based on the slot's parameters.
3088
ScspUpdateSlotFunc(SlotState * slot)3089 static void ScspUpdateSlotFunc(SlotState *slot)
3090 {
3091 if (slot->ssctl)
3092 // FIXME: noise (ssctl==1) not implemented
3093 slot->audiogen = scsp_audiogen_func_table[0][0][0][0][0];
3094 else
3095 slot->audiogen = scsp_audiogen_func_table[slot->lfo_fm_shift >= 0]
3096 [slot->lfo_am_shift >= 0]
3097 [slot->pcm8b == 0]
3098 [slot->outshift_l != 31]
3099 [slot->outshift_r != 31];
3100 }
3101
3102 //-------------------------------------------------------------------------
3103
3104 // ScspMidiIn: Handle a read from the MIDI input register ($404). Since
3105 // there is no facility for sending MIDI data (the Saturn does not have a
3106 // MIDI I/O port), most of this is essentially a giant no-op, but the logic
3107 // is included for reference.
3108
ScspMidiIn(void)3109 static u16 ScspMidiIn(void)
3110 {
3111 scsp.miovf = 0;
3112 scsp.mifull = 0;
3113 if (scsp.midi_in_cnt > 0)
3114 {
3115 scsp.mibuf = scsp.midi_in_buf[0];
3116 scsp.midi_in_buf[0] = scsp.midi_in_buf[1];
3117 scsp.midi_in_buf[1] = scsp.midi_in_buf[2];
3118 scsp.midi_in_buf[2] = scsp.midi_in_buf[3];
3119 scsp.midi_in_cnt--;
3120 scsp.miemp = (scsp.midi_in_cnt == 0);
3121 if (!scsp.miemp)
3122 ScspRaiseInterrupt(SCSP_INTERRUPT_MIDI_IN, SCSP_INTTARGET_BOTH);
3123 }
3124 else // scsp.midi_in_cnt == 0
3125 scsp.mibuf = 0xFF;
3126
3127 return scsp.mofull << 12
3128 | scsp.moemp << 11
3129 | scsp.miovf << 10
3130 | scsp.mifull << 9
3131 | scsp.miemp << 8
3132 | scsp.mibuf << 0;
3133 }
3134
3135 //----------------------------------//
3136
3137 // ScspMidiOut: Handle a write to the MIDI output register ($406).
3138
ScspMidiOut(u8 data)3139 static void ScspMidiOut(u8 data)
3140 {
3141 scsp.moemp = 0;
3142 if (scsp.midi_out_cnt < 4)
3143 scsp.midi_out_buf[scsp.midi_out_cnt++] = data;
3144 scsp.mofull = (scsp.midi_out_cnt >= 4);
3145 }
3146
3147 //-------------------------------------------------------------------------
3148
3149 // ScspDoDMA: Handle a DMA request (when 1 is written to DEXE). DMA is
3150 // processed instantaneously regardless of transfer size.
3151
ScspDoDMA(void)3152 static void ScspDoDMA(void)
3153 {
3154 const u32 dmea = scsp.dmea & scsp.sound_ram_mask;
3155
3156 if (scsp.ddir) // {RAM,zero} -> registers
3157 {
3158 SCSPLOG("DMA %s RAM[$%05X] -> registers[$%03X]\n",
3159 scsp.dgate ? "clear" : "copy", dmea, scsp.drga);
3160 if (scsp.dgate)
3161 {
3162 u32 i;
3163 for (i = 0; i < scsp.dtlg; i += 2)
3164 ScspWriteWordDirect(scsp.drga + i, 0);
3165 }
3166 else
3167 {
3168 u32 i;
3169 for (i = 0; i < scsp.dtlg; i += 2)
3170 ScspWriteWordDirect(scsp.drga + i, T2ReadWord(SoundRam, dmea + i));
3171 }
3172 }
3173 else // !scsp.ddir, i.e. registers -> RAM
3174 {
3175 SCSPLOG("DMA %s registers[$%03X] -> RAM[$%05X]\n",
3176 scsp.dgate ? "clear" : "copy", scsp.drga, dmea);
3177 if (scsp.dgate)
3178 memset(&SoundRam[dmea], 0, scsp.dtlg);
3179 else
3180 {
3181 u32 i;
3182 for (i = 0; i < scsp.dtlg; i += 2)
3183 T2WriteWord(SoundRam, dmea + i, ScspReadWordDirect(scsp.drga + i));
3184 }
3185 M68K->WriteNotify(dmea, scsp.dtlg);
3186 }
3187
3188 scsp.dexe = 0;
3189 PSP_UC(scsp_regcache[0x416>>1]) &= ~(1<<12);
3190 ScspRaiseInterrupt(SCSP_INTERRUPT_DMA, SCSP_INTTARGET_BOTH);
3191 }
3192
3193 ///////////////////////////////////////////////////////////////////////////
3194 // Other SCSP internal helper routines
3195 ///////////////////////////////////////////////////////////////////////////
3196
3197 // ScspSyncThread: Wait for the SCSP subthread to finish executing all
3198 // pending cycles. Do not call if the subthread is not running.
3199
ScspSyncThread(void)3200 static void ScspSyncThread(void)
3201 {
3202 PSP_FLUSH_ALL();
3203 while (PSP_UC(scsp_clock) != scsp_clock_target)
3204 {
3205 YabThreadWake(YAB_THREAD_SCSP);
3206 YabThreadYield();
3207 }
3208 }
3209
3210 //-------------------------------------------------------------------------
3211
3212 // ScspRaiseInterrupt: Raise an interrupt for the main and/or sound CPU.
3213
ScspRaiseInterrupt(int which,int target)3214 static void ScspRaiseInterrupt(int which, int target)
3215 {
3216 if (target & SCSP_INTTARGET_MAIN)
3217 {
3218 scsp.mcipd |= 1 << which;
3219 PSP_UC(scsp_regcache[0x42C >> 1]) = scsp.mcipd;
3220 if (scsp.mcieb & (1 << which))
3221 {
3222 if (scsp_thread_running)
3223 PSP_UC(scsp_main_interrupt_pending) = 1;
3224 else
3225 (*scsp_interrupt_handler)();
3226 }
3227 }
3228
3229 if (target & SCSP_INTTARGET_SOUND)
3230 {
3231 scsp.scipd |= 1 << which;
3232 PSP_UC(scsp_regcache[0x420 >> 1]) = scsp.scipd;
3233 if (scsp.scieb & (1 << which))
3234 {
3235 const int level_shift = (which > 7) ? 7 : which;
3236 const int level = ((scsp.scilv0 >> level_shift) & 1) << 0
3237 | ((scsp.scilv1 >> level_shift) & 1) << 1
3238 | ((scsp.scilv2 >> level_shift) & 1) << 2;
3239 M68K->SetIRQ(level);
3240 }
3241 }
3242 }
3243
3244 //----------------------------------//
3245
3246 // ScspCheckInterrupts: Check pending interrupts for the main or sound CPU
3247 // against the interrupt enable flags, and raise any interrupts which are
3248 // both enabled and pending. The mask parameter indicates which interrupts
3249 // should be checked. Implements writes to SCIEB and MCIEB.
3250
ScspCheckInterrupts(u16 mask,int target)3251 static void ScspCheckInterrupts(u16 mask, int target)
3252 {
3253 int i;
3254
3255 for (i = 0; i < 11; i++)
3256 {
3257 if ((1<<i) & mask & scsp.mcieb && scsp.mcipd)
3258 ScspRaiseInterrupt(i, SCSP_INTTARGET_MAIN & target);
3259 if ((1<<i) & mask & scsp.scieb && scsp.scipd)
3260 ScspRaiseInterrupt(i, SCSP_INTTARGET_SOUND & target);
3261 }
3262 }
3263
3264 //----------------------------------//
3265
3266 // ScspClearInterrupts: Clear all pending interrupts specified by the mask
3267 // parameter for the main or sound CPU. Implements writes to SCIRE and MCIRE.
3268
ScspClearInterrupts(u16 mask,int target)3269 static void ScspClearInterrupts(u16 mask, int target)
3270 {
3271 if (target & SCSP_INTTARGET_MAIN)
3272 {
3273 scsp.mcipd &= ~mask;
3274 PSP_UC(scsp_regcache[0x42C >> 1]) = scsp.mcipd;
3275 }
3276
3277 if (target & SCSP_INTTARGET_SOUND)
3278 {
3279 scsp.scipd &= ~mask;
3280 PSP_UC(scsp_regcache[0x420 >> 1]) = scsp.scipd;
3281 }
3282 }
3283
3284 //-------------------------------------------------------------------------
3285
3286 // ScspRunM68K: Run the M68K for the given number of cycles.
3287
ScspRunM68K(u32 cycles)3288 static void ScspRunM68K(u32 cycles)
3289 {
3290 if (LIKELY(m68k_running))
3291 {
3292 s32 new_cycles = m68k_saved_cycles + cycles;
3293 if (LIKELY(new_cycles > 0))
3294 new_cycles -= (*m68k_execf)(new_cycles);
3295 m68k_saved_cycles = new_cycles;
3296 }
3297 }
3298
3299 //----------------------------------//
3300
3301 // M68KExecBP: Wrapper for M68K->Exec() which checks for breakpoints and
3302 // calls the breakpoint callback when one is reached. This logic is
3303 // extracted from M68KExec() to avoid unnecessary register spillage on the
3304 // fast (no-breakpoint) path.
3305
M68KExecBP(s32 cycles)3306 static s32 FASTCALL M68KExecBP(s32 cycles)
3307 {
3308 s32 cycles_to_exec = cycles;
3309 s32 cycles_executed = 0;
3310 int i;
3311
3312 while (cycles_executed < cycles_to_exec)
3313 {
3314 // Make sure it isn't one of our breakpoints
3315 for (i = 0; i < m68k_num_breakpoints; i++)
3316 {
3317 if ((M68K->GetPC() == m68k_breakpoint[i].addr) && !m68k_in_breakpoint)
3318 {
3319 m68k_in_breakpoint = 1;
3320 if (M68KBreakpointCallback)
3321 M68KBreakpointCallback(m68k_breakpoint[i].addr);
3322 m68k_in_breakpoint = 0;
3323 }
3324 }
3325
3326 // Execute instructions individually
3327 cycles_executed += M68K->Exec(1);
3328 }
3329
3330 return cycles_executed;
3331 }
3332
3333 ///////////////////////////////////////////////////////////////////////////
3334 // M68K management routines
3335 ///////////////////////////////////////////////////////////////////////////
3336
3337 // M68KStart: Start the M68K processor running.
3338
M68KStart(void)3339 void M68KStart(void)
3340 {
3341 if (scsp_thread_running)
3342 ScspSyncThread();
3343
3344 M68K->Reset();
3345 m68k_saved_cycles = 0;
3346
3347 m68k_running = 1;
3348
3349 if (scsp_thread_running)
3350 PSP_FLUSH_ALL();
3351 }
3352
3353 //-------------------------------------------------------------------------
3354
3355 // M68KStop: Halt the M68K processor.
3356
M68KStop(void)3357 void M68KStop(void)
3358 {
3359 if (scsp_thread_running)
3360 ScspSyncThread();
3361
3362 m68k_running = 0;
3363
3364 if (scsp_thread_running)
3365 PSP_FLUSH_ALL();
3366 }
3367
3368 //-------------------------------------------------------------------------
3369
3370 // M68KStep: Execute a single M68K instruction.
3371
M68KStep(void)3372 void M68KStep(void)
3373 {
3374 M68K->Exec(1);
3375 }
3376
3377 //-------------------------------------------------------------------------
3378
3379 // M68KWriteNotify: Notify the M68K emulator that a region of sound RAM
3380 // has been written to by an external agent.
3381
M68KWriteNotify(u32 address,u32 size)3382 void M68KWriteNotify(u32 address, u32 size)
3383 {
3384 M68K->WriteNotify(address, size);
3385 }
3386
3387 //-------------------------------------------------------------------------
3388
3389 // M68KGetRegisters, M68KSetRegisters: Get or set the current values of
3390 // the M68K registers.
3391
M68KGetRegisters(M68KRegs * regs)3392 void M68KGetRegisters(M68KRegs *regs)
3393 {
3394 int i;
3395
3396 if (regs != NULL)
3397 {
3398 for (i = 0; i < 8; i++)
3399 {
3400 regs->D[i] = M68K->GetDReg(i);
3401 regs->A[i] = M68K->GetAReg(i);
3402 }
3403 regs->SR = M68K->GetSR();
3404 regs->PC = M68K->GetPC();
3405 }
3406 }
3407
M68KSetRegisters(const M68KRegs * regs)3408 void M68KSetRegisters(const M68KRegs *regs)
3409 {
3410 int i;
3411
3412 if (regs != NULL)
3413 {
3414 for (i = 0; i < 8; i++)
3415 {
3416 M68K->SetDReg(i, regs->D[i]);
3417 M68K->SetAReg(i, regs->A[i]);
3418 }
3419 M68K->SetSR(regs->SR);
3420 M68K->SetPC(regs->PC);
3421 }
3422 }
3423
3424 //-------------------------------------------------------------------------
3425
3426 // M68KSetBreakpointCallback: Set a function to be called whenever an M68K
3427 // breakpoint is reached.
3428
M68KSetBreakpointCallBack(void (* func)(u32 address))3429 void M68KSetBreakpointCallBack(void (*func)(u32 address))
3430 {
3431 M68KBreakpointCallback = func;
3432 }
3433
3434 //-------------------------------------------------------------------------
3435
3436 // M68KAddCodeBreakpoint: Add an M68K breakpoint on the given address.
3437 // Returns 0 on success, -1 if the breakpoint table is full or there is
3438 // already a breakpoint set on the address.
3439
M68KAddCodeBreakpoint(u32 address)3440 int M68KAddCodeBreakpoint(u32 address)
3441 {
3442 int i;
3443
3444 if (m68k_num_breakpoints >= MAX_BREAKPOINTS)
3445 return -1;
3446
3447 // Make sure it isn't already on the list
3448 for (i = 0; i < m68k_num_breakpoints; i++)
3449 {
3450 if (m68k_breakpoint[i].addr == address)
3451 return -1;
3452 }
3453
3454 m68k_breakpoint[m68k_num_breakpoints].addr = address;
3455 m68k_num_breakpoints++;
3456
3457 // Switch to the slow exec routine so we can catch the breakpoint
3458 m68k_execf = M68KExecBP;
3459
3460 return 0;
3461 }
3462
3463 //-------------------------------------------------------------------------
3464
3465 // M68KDelCodeBreakpoint: Delete an M68K breakpoint on the given address.
3466 // Returns 0 on success, -1 if there was no breakpoint set on the address.
3467
M68KDelCodeBreakpoint(u32 address)3468 int M68KDelCodeBreakpoint(u32 address)
3469 {
3470 int i;
3471
3472 if (m68k_num_breakpoints > 0)
3473 {
3474 for (i = 0; i < m68k_num_breakpoints; i++)
3475 {
3476 if (m68k_breakpoint[i].addr == address)
3477 {
3478 // Swap with the last breakpoint in the table, so there are
3479 // no holes in the breakpoint list
3480 m68k_breakpoint[i].addr = m68k_breakpoint[m68k_num_breakpoints-1].addr;
3481 m68k_breakpoint[m68k_num_breakpoints-1].addr = 0xFFFFFFFF;
3482 m68k_num_breakpoints--;
3483
3484 if (m68k_num_breakpoints == 0)
3485 {
3486 // Last breakpoint deleted, so go back to the fast exec routine
3487 m68k_execf = M68K->Exec;
3488 }
3489
3490 return 0;
3491 }
3492 }
3493 }
3494
3495 return -1;
3496 }
3497
3498 //-------------------------------------------------------------------------
3499
3500 // M68KGetBreakpointList: Return the array of breakpoints currently set.
3501 // The array is M68K_MAX_BREAKPOINTS elements long, and an address of
3502 // 0xFFFFFFFF indicates that no breakpoint is set in that slot.
3503
M68KGetBreakpointList(void)3504 const M68KBreakpointInfo *M68KGetBreakpointList(void)
3505 {
3506 return m68k_breakpoint;
3507 }
3508
3509 //-------------------------------------------------------------------------
3510
3511 // M68KClearCodeBreakpoints: Clear all M68K breakpoints.
3512
M68KClearCodeBreakpoints(void)3513 void M68KClearCodeBreakpoints(void)
3514 {
3515 int i;
3516 for (i = 0; i < MAX_BREAKPOINTS; i++)
3517 m68k_breakpoint[i].addr = 0xFFFFFFFF;
3518
3519 m68k_num_breakpoints = 0;
3520 m68k_execf = M68K->Exec;
3521 }
3522
3523 //-------------------------------------------------------------------------
3524
3525 // M68K{Read,Write}{Byte,Word}: Memory access routines for the M68K
3526 // emulation. Exported for use in debugging.
3527
M68KReadByte(u32 address)3528 u32 FASTCALL M68KReadByte(u32 address)
3529 {
3530 if (address < 0x100000)
3531 return T2ReadByte(SoundRam, address & scsp.sound_ram_mask);
3532 else
3533 return ScspReadByteDirect(address & 0xFFF);
3534 }
3535
M68KReadWord(u32 address)3536 u32 FASTCALL M68KReadWord(u32 address)
3537 {
3538 if (address < 0x100000)
3539 return T2ReadWord(SoundRam, address & scsp.sound_ram_mask);
3540 else
3541 return ScspReadWordDirect(address & 0xFFF);
3542 }
3543
M68KWriteByte(u32 address,u32 data)3544 void FASTCALL M68KWriteByte(u32 address, u32 data)
3545 {
3546 if (address < 0x100000)
3547 T2WriteByte(SoundRam, address & scsp.sound_ram_mask, data);
3548 else
3549 ScspWriteByteDirect(address & 0xFFF, data);
3550 }
3551
M68KWriteWord(u32 address,u32 data)3552 void FASTCALL M68KWriteWord(u32 address, u32 data)
3553 {
3554 if (address < 0x100000)
3555 T2WriteWord(SoundRam, address & scsp.sound_ram_mask, data);
3556 else
3557 ScspWriteWordDirect(address & 0xFFF, data);
3558 }
3559
3560 ///////////////////////////////////////////////////////////////////////////
3561