1 /***********************************************************************************
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3
4 (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
5 Jerremy Koot (jkoot@snes9x.com)
6
7 (c) Copyright 2002 - 2004 Matthew Kendora
8
9 (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
10
11 (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
12
13 (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
14
15 (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
16 Kris Bleakley (codeviolation@hotmail.com)
17
18 (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
19 Nach (n-a-c-h@users.sourceforge.net),
20 zones (kasumitokoduck@yahoo.com)
21
22 (c) Copyright 2006 - 2007 nitsuja
23
24 (c) Copyright 2009 - 2010 BearOso,
25 OV2
26
27
28 BS-X C emulator code
29 (c) Copyright 2005 - 2006 Dreamer Nom,
30 zones
31
32 C4 x86 assembler and some C emulation code
33 (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
34 Nach,
35 zsKnight (zsknight@zsnes.com)
36
37 C4 C++ code
38 (c) Copyright 2003 - 2006 Brad Jorsch,
39 Nach
40
41 DSP-1 emulator code
42 (c) Copyright 1998 - 2006 _Demo_,
43 Andreas Naive (andreasnaive@gmail.com),
44 Gary Henderson,
45 Ivar (ivar@snes9x.com),
46 John Weidman,
47 Kris Bleakley,
48 Matthew Kendora,
49 Nach,
50 neviksti (neviksti@hotmail.com)
51
52 DSP-2 emulator code
53 (c) Copyright 2003 John Weidman,
54 Kris Bleakley,
55 Lord Nightmare (lord_nightmare@users.sourceforge.net),
56 Matthew Kendora,
57 neviksti
58
59 DSP-3 emulator code
60 (c) Copyright 2003 - 2006 John Weidman,
61 Kris Bleakley,
62 Lancer,
63 z80 gaiden
64
65 DSP-4 emulator code
66 (c) Copyright 2004 - 2006 Dreamer Nom,
67 John Weidman,
68 Kris Bleakley,
69 Nach,
70 z80 gaiden
71
72 OBC1 emulator code
73 (c) Copyright 2001 - 2004 zsKnight,
74 pagefault (pagefault@zsnes.com),
75 Kris Bleakley
76 Ported from x86 assembler to C by sanmaiwashi
77
78 SPC7110 and RTC C++ emulator code used in 1.39-1.51
79 (c) Copyright 2002 Matthew Kendora with research by
80 zsKnight,
81 John Weidman,
82 Dark Force
83
84 SPC7110 and RTC C++ emulator code used in 1.52+
85 (c) Copyright 2009 byuu,
86 neviksti
87
88 S-DD1 C emulator code
89 (c) Copyright 2003 Brad Jorsch with research by
90 Andreas Naive,
91 John Weidman
92
93 S-RTC C emulator code
94 (c) Copyright 2001 - 2006 byuu,
95 John Weidman
96
97 ST010 C++ emulator code
98 (c) Copyright 2003 Feather,
99 John Weidman,
100 Kris Bleakley,
101 Matthew Kendora
102
103 Super FX x86 assembler emulator code
104 (c) Copyright 1998 - 2003 _Demo_,
105 pagefault,
106 zsKnight
107
108 Super FX C emulator code
109 (c) Copyright 1997 - 1999 Ivar,
110 Gary Henderson,
111 John Weidman
112
113 Sound emulator code used in 1.5-1.51
114 (c) Copyright 1998 - 2003 Brad Martin
115 (c) Copyright 1998 - 2006 Charles Bilyue'
116
117 Sound emulator code used in 1.52+
118 (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
119
120 SH assembler code partly based on x86 assembler code
121 (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
122
123 2xSaI filter
124 (c) Copyright 1999 - 2001 Derek Liauw Kie Fa
125
126 HQ2x, HQ3x, HQ4x filters
127 (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
128
129 NTSC filter
130 (c) Copyright 2006 - 2007 Shay Green
131
132 GTK+ GUI code
133 (c) Copyright 2004 - 2010 BearOso
134
135 Win32 GUI code
136 (c) Copyright 2003 - 2006 blip,
137 funkyass,
138 Matthew Kendora,
139 Nach,
140 nitsuja
141 (c) Copyright 2009 - 2010 OV2
142
143 Mac OS GUI code
144 (c) Copyright 1998 - 2001 John Stiles
145 (c) Copyright 2001 - 2010 zones
146
147 (c) Copyright 2010 - 2016 Daniel De Matteis. (UNDER NO CIRCUMSTANCE
148 WILL COMMERCIAL RIGHTS EVER BE APPROPRIATED TO ANY PARTY)
149
150 (c) Copyright 2020 Mahyar Koshkouei
151
152
153 Specific ports contains the works of other authors. See headers in
154 individual files.
155
156
157 Snes9x homepage: http://www.snes9x.com/
158
159 Permission to use, copy, modify and/or distribute Snes9x in both binary
160 and source form, for non-commercial purposes, is hereby granted without
161 fee, providing that this license information and copyright notice appear
162 with all copies and any derived work.
163
164 This software is provided 'as-is', without any express or implied
165 warranty. In no event shall the authors be held liable for any damages
166 arising from the use of this software or it's derivatives.
167
168 Snes9x is freeware for PERSONAL USE only. Commercial users should
169 seek permission of the copyright holders first. Commercial use includes,
170 but is not limited to, charging money for Snes9x or software derived from
171 Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
172 using Snes9x as a promotion for your commercial product.
173
174 The copyright holders request that bug fixes and improvements to the code
175 should be forwarded to them so everyone can benefit from the modifications
176 in future versions.
177
178 Super NES and Super Nintendo Entertainment System are trademarks of
179 Nintendo Co., Limited and its subsidiary companies.
180 ***********************************************************************************/
181 #include <stdio.h>
182 #include <math.h>
183 #include <string.h>
184 #include <stddef.h>
185 #include <stdlib.h>
186 #include <limits.h>
187
188 #include <retro_inline.h>
189
190 #include "blargg_endian.h"
191 #include "apu.h"
192
193 #include "snes9x.h"
194 #include "snapshot.h"
195 #include "display.h"
196
197 /* The Wii version sometimes has issues with memcpy fnt when optimized,
198 so we remove optimzations from save/load state fnts using this macro */
199 #ifdef GEKKO
200 #define NO_OPTIMIZE __attribute__((optimize("O0")))
201 #else
202 #define NO_OPTIMIZE
203 #endif
204
205 /***********************************************************************************
206 SPC DSP
207 ***********************************************************************************/
208
209 static dsp_state_t dsp_m;
210
211 /* Copyright (C) 2007 Shay Green. This module is free software; you
212 can redistribute it and/or modify it under the terms of the GNU Lesser
213 General Public License as published by the Free Software Foundation; either
214 version 2.1 of the License, or (at your option) any later version. This
215 module is distributed in the hope that it will be useful, but WITHOUT ANY
216 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
217 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
218 details. You should have received a copy of the GNU Lesser General Public
219 License along with this module; if not, write to the Free Software Foundation,
220 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
221
222 #if INT_MAX < 0x7FFFFFFF
223 #error "Requires that int type have at least 32 bits"
224 #endif
225
226 /* if ( io < -32768 ) io = -32768; */
227 /* if ( io > 32767 ) io = 32767; */
228 #define CLAMP16( io ) if ( (int16_t) io != io ) io = ((io >> 31) ^ 0x7FFF)
229
230 /* Access global DSP register */
231 #define REG(n) dsp_m.regs [R_##n]
232
233 /* Access voice DSP register */
234 #define VREG(r,n) r [V_##n]
235
236 #define WRITE_SAMPLES( l, r, out ) \
237 {\
238 out [0] = l;\
239 out [1] = r;\
240 out += 2;\
241 if ( out >= dsp_m.out_end )\
242 {\
243 out = dsp_m.extra;\
244 dsp_m.out_end = &dsp_m.extra [EXTRA_SIZE];\
245 }\
246 }\
247
248
249 /* Volume registers and efb are signed! Easy to forget int8_t cast. */
250 /* Prefixes are to avoid accidental use of locals with same names. */
251
252 /* Gaussian interpolation */
253
254 static short gauss [512] =
255 {
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
258 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5,
259 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
260 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17,
261 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27,
262 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40,
263 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
264 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77,
265 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102,
266 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132,
267 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168,
268 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210,
269 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257,
270 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311,
271 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370,
272 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434,
273 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504,
274 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577,
275 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654,
276 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732,
277 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811,
278 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889,
279 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965,
280 969, 974, 978, 983, 988, 992, 997,1001,1005,1010,1014,1019,1023,1027,1032,1036,
281 1040,1045,1049,1053,1057,1061,1066,1070,1074,1078,1082,1086,1090,1094,1098,1102,
282 1106,1109,1113,1117,1121,1125,1128,1132,1136,1139,1143,1146,1150,1153,1157,1160,
283 1164,1167,1170,1174,1177,1180,1183,1186,1190,1193,1196,1199,1202,1205,1207,1210,
284 1213,1216,1219,1221,1224,1227,1229,1232,1234,1237,1239,1241,1244,1246,1248,1251,
285 1253,1255,1257,1259,1261,1263,1265,1267,1269,1270,1272,1274,1275,1277,1279,1280,
286 1282,1283,1284,1286,1287,1288,1290,1291,1292,1293,1294,1295,1296,1297,1297,1298,
287 1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305,
288 };
289
290 /* Gaussian interpolation */
291
dsp_interpolate(dsp_voice_t * v)292 static INLINE int dsp_interpolate( dsp_voice_t *v )
293 {
294 /* Make pointers into gaussian based on fractional position between samples */
295 int offset = v->interp_pos >> 4 & 0xFF;
296 short *fwd = (short*)(gauss + 255 - offset);
297 short *rev = (short*)(gauss + offset); /* mirror left half of gaussian */
298
299 int *in = (int*)&v->buf[(v->interp_pos >> 12) + v->buf_pos];
300 int out = (fwd [ 0] * in [0]) >> 11;
301 out += (fwd [256] * in [1]) >> 11;
302 out += (rev [256] * in [2]) >> 11;
303 out = (int16_t) out;
304 out += (rev [ 0] * in [3]) >> 11;
305
306 CLAMP16( out );
307 out &= ~1;
308 return out;
309 }
310
311 /* Counters */
312
313 /* Number of samples per counter event.
314 * All rates are evently divisible by counter range
315 * (0x7800, 30720, or 2048 * 5 * 3).
316 *
317 * Note that counter_rates[0] is a special case,
318 * which never triggers. */
319 #define COUNTER_RANGE 30720
320
321 static unsigned const counter_rates [32] =
322 {
323 COUNTER_RANGE + 1, 2048, 1536,
324 1280, 1024, 768,
325 640, 512, 384,
326 320, 256, 192,
327 160, 128, 96,
328 80, 64, 48,
329 40, 32, 24,
330 20, 16, 12,
331 10, 8, 6,
332 5, 4, 3,
333 2,
334 1
335 };
336
337 /* Counter offset from zero.
338 *
339 * Counters do not appear to be aligned at zero
340 * for all rates.
341 */
342
343 static unsigned const counter_offsets [32] =
344 {
345 1, 0, 1040,
346 536, 0, 1040,
347 536, 0, 1040,
348 536, 0, 1040,
349 536, 0, 1040,
350 536, 0, 1040,
351 536, 0, 1040,
352 536, 0, 1040,
353 536, 0, 1040,
354 536, 0, 1040,
355 0,
356 0
357 };
358
359 #define READ_COUNTER(rate) (((unsigned) dsp_m.counter + counter_offsets [rate]) % counter_rates [rate])
360
361 /* Envelope */
362
dsp_run_envelope(dsp_voice_t * v)363 static INLINE void dsp_run_envelope( dsp_voice_t* v )
364 {
365 int env, rate, env_data;
366
367 env = v->env;
368 env_data = v->regs[V_ADSR1];
369
370 if ( dsp_m.t_adsr0 & 0x80 ) /* 99% ADSR */
371 {
372 if ( v->env_mode >= ENV_DECAY ) /* 99% */
373 {
374 env--;
375 env -= env >> 8;
376 rate = env_data & 0x1F;
377 if ( v->env_mode == ENV_DECAY ) /* 1% */
378 rate = (dsp_m.t_adsr0 >> 3 & 0x0E) + 0x10;
379 }
380 else /* ENV_ATTACK */
381 {
382 rate = (dsp_m.t_adsr0 & 0x0F) * 2 + 1;
383 env += rate < 31 ? 0x20 : 0x400;
384 }
385 }
386 else /* GAIN */
387 {
388 int mode;
389 env_data = v->regs[V_GAIN];
390 mode = env_data >> 5;
391 if ( mode < 4 ) /* direct */
392 {
393 env = env_data * 0x10;
394 rate = 31;
395 }
396 else
397 {
398 rate = env_data & 0x1F;
399 if ( mode == 4 ) /* 4: linear decrease */
400 {
401 env -= 0x20;
402 }
403 else if ( mode < 6 ) /* 5: exponential decrease */
404 {
405 env--;
406 env -= env >> 8;
407 }
408 else /* 6,7: linear increase */
409 {
410 env += 0x20;
411 if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 )
412 env += 0x8 - 0x20; /* 7: two-slope linear increase */
413 }
414 }
415 }
416
417 /* Sustain level */
418 if ( (env >> 8) == (env_data >> 5) && v->env_mode == ENV_DECAY )
419 v->env_mode = ENV_SUSTAIN;
420
421 v->hidden_env = env;
422
423 /* unsigned cast because linear decrease going negative also triggers this */
424 if ( (unsigned) env > 0x7FF )
425 {
426 env = (env < 0 ? 0 : 0x7FF);
427 if ( v->env_mode == ENV_ATTACK )
428 v->env_mode = ENV_DECAY;
429 }
430
431 if (!READ_COUNTER( rate ))
432 v->env = env; /* nothing else is controlled by the counter */
433 }
434
435 /* BRR Decoding */
436
dsp_decode_brr(dsp_voice_t * v)437 static INLINE void dsp_decode_brr( dsp_voice_t* v )
438 {
439 int *end;
440
441 /* Arrange the four input nybbles in 0xABCD order for easy decoding */
442 int nybbles = dsp_m.t_brr_byte * 0x100 + dsp_m.ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF];
443
444 int header = dsp_m.t_brr_header;
445 int filter = header & 0x0C;
446 int shift = header >> 4; /* Shift sample based on header */
447
448 /* Write to next four samples in circular buffer */
449 int *pos = (int*)&v->buf [v->buf_pos];
450
451 if ( (v->buf_pos += 4) >= BRR_BUF_SIZE )
452 v->buf_pos = 0;
453
454 /* Decode four samples */
455 for ( end = pos + 4; pos < end; pos++)
456 {
457 int s = (int16_t) nybbles >> 12; /* Extract nybble and sign-extend */
458 int p1 = pos [BRR_BUF_SIZE - 1];
459 int p2 = pos [BRR_BUF_SIZE - 2] >> 1;
460
461 s = (s << shift) >> 1;
462 if (shift >= 0xD) /* handle invalid range */
463 s = (s >> 25) << 11; /* same as: s = (s < 0 ? -0x800 : 0) */
464
465 if (filter)
466 {
467 /* Apply IIR filter (8 is the most commonly used) */
468
469 if ( filter >= 8 )
470 {
471 s += p1;
472 s -= p2;
473 if ( filter == 8 ) /* s += p1 * 0.953125 - p2 * 0.46875 */
474 {
475 s += p2 >> 4;
476 s += (p1 * -3) >> 6;
477 }
478 else /* s += p1 * 0.8984375 - p2 * 0.40625 */
479 {
480 s += (p1 * -13) >> 7;
481 s += (p2 * 3) >> 4;
482 }
483 }
484 else /* s += p1 * 0.46875 */
485 {
486 s += p1 >> 1;
487 s += (-p1) >> 5;
488 }
489 }
490
491 /* Adjust and write sample */
492 CLAMP16( s );
493 s = (int16_t) (s * 2);
494 pos [BRR_BUF_SIZE] = pos [0] = s; /* second copy simplifies wrap-around */
495
496 nybbles <<= 4;
497 }
498 }
499
500 /* Misc */
501
502 /* voice 0 doesn't support PMON */
503
504 #define MISC_27() dsp_m.t_pmon = dsp_m.regs[R_PMON] & 0xFE;
505
506 #define MISC_28() \
507 dsp_m.t_non = dsp_m.regs[R_NON]; \
508 dsp_m.t_eon = dsp_m.regs[R_EON]; \
509 dsp_m.t_dir = dsp_m.regs[R_DIR];
510
511 #define MISC_29() \
512 if ( (dsp_m.every_other_sample ^= 1) != 0 ) \
513 dsp_m.new_kon &= ~dsp_m.kon; /* clears KON 63 clocks after it was last read */
514
dsp_misc_30(void)515 static INLINE void dsp_misc_30 (void)
516 {
517 if ( dsp_m.every_other_sample )
518 {
519 dsp_m.kon = dsp_m.new_kon;
520 dsp_m.t_koff = dsp_m.regs[R_KOFF];
521 }
522
523 if ( --dsp_m.counter < 0 )
524 dsp_m.counter = COUNTER_RANGE - 1;
525
526 /* Noise */
527 if ( !READ_COUNTER( dsp_m.regs[R_FLG] & 0x1F ) )
528 {
529 int feedback = (dsp_m.noise << 13) ^ (dsp_m.noise << 14);
530 dsp_m.noise = (feedback & 0x4000) ^ (dsp_m.noise >> 1);
531 }
532 }
533
534 /* Voices */
535
536 #define dsp_voice_V1(v) \
537 dsp_m.t_dir_addr = (dsp_m.t_dir * 0x100 + dsp_m.t_srcn * 4) & 0xffff; \
538 dsp_m.t_srcn = v->regs[V_SRCN]
539
540 #define dsp_voice_V2(v) \
541 { \
542 uint8_t *entry = (uint8_t*)&dsp_m.ram [dsp_m.t_dir_addr]; \
543 if ( !v->kon_delay ) \
544 entry += 2; \
545 dsp_m.t_brr_next_addr = GET_LE16(entry); \
546 dsp_m.t_adsr0 = v->regs [V_ADSR0]; \
547 dsp_m.t_pitch = v->regs [V_PITCHL]; \
548 }
549
550 #define dsp_voice_V3a(v) (dsp_m.t_pitch += (v->regs [V_PITCHH] & 0x3F) << 8)
551
552 #define dsp_voice_V3b(v) \
553 dsp_m.t_brr_byte = dsp_m.ram [(v->brr_addr + v->brr_offset) & 0xffff]; \
554 dsp_m.t_brr_header = dsp_m.ram [v->brr_addr]
555
dsp_voice_V3c(dsp_voice_t * v)556 static void dsp_voice_V3c( dsp_voice_t* v )
557 {
558 int output;
559
560 /* Pitch modulation using previous voice's output */
561 if ( dsp_m.t_pmon & v->vbit )
562 dsp_m.t_pitch += ((dsp_m.t_output >> 5) * dsp_m.t_pitch) >> 10;
563
564 if ( v->kon_delay )
565 {
566 /* Get ready to start BRR decoding on next sample */
567 if ( v->kon_delay == 5 )
568 {
569 v->brr_addr = dsp_m.t_brr_next_addr;
570 v->brr_offset = 1;
571 v->buf_pos = 0;
572 dsp_m.t_brr_header = 0; /* header is ignored on this sample */
573 }
574
575 /* Envelope is never run during KON */
576 v->env = 0;
577 v->hidden_env = 0;
578
579 /* Disable BRR decoding until last three samples */
580 v->interp_pos = 0;
581 if ( --v->kon_delay & 3 )
582 v->interp_pos = 0x4000;
583
584 /* Pitch is never added during KON */
585 dsp_m.t_pitch = 0;
586 }
587
588 output = dsp_interpolate( v );
589
590 /* Noise */
591 if ( dsp_m.t_non & v->vbit )
592 output = (int16_t) (dsp_m.noise * 2);
593
594 /* Apply envelope */
595 dsp_m.t_output = (output * v->env) >> 11 & ~1;
596 v->t_envx_out = (uint8_t) (v->env >> 4);
597
598 /* Immediate silence due to end of sample or soft reset */
599 if ( dsp_m.regs[R_FLG] & 0x80 || (dsp_m.t_brr_header & 3) == 1 )
600 {
601 v->env_mode = ENV_RELEASE;
602 v->env = 0;
603 }
604
605 if ( dsp_m.every_other_sample )
606 {
607 /* KOFF */
608 if ( dsp_m.t_koff & v->vbit )
609 v->env_mode = ENV_RELEASE;
610
611 /* KON */
612 if ( dsp_m.kon & v->vbit )
613 {
614 v->kon_delay = 5;
615 v->env_mode = ENV_ATTACK;
616 }
617 }
618
619 /* Run envelope for next sample */
620 if ( !v->kon_delay )
621 {
622 int env = v->env;
623 if ( v->env_mode == ENV_RELEASE ) /* 60% */
624 {
625 if ( (env -= 0x8) < 0 )
626 env = 0;
627 v->env = env;
628 }
629 else
630 {
631 dsp_run_envelope( v );
632 }
633 }
634 }
635
dsp_voice_output(dsp_voice_t const * v,int ch)636 static INLINE void dsp_voice_output( dsp_voice_t const* v, int ch )
637 {
638 /* Apply left/right volume */
639 int amp = (dsp_m.t_output * (int8_t) VREG(v->regs,VOLL + ch)) >> 7;
640
641 /* Add to output total */
642 dsp_m.t_main_out [ch] += amp;
643 CLAMP16( dsp_m.t_main_out [ch] );
644
645 /* Optionally add to echo total */
646 if ( dsp_m.t_eon & v->vbit )
647 {
648 dsp_m.t_echo_out [ch] += amp;
649 CLAMP16( dsp_m.t_echo_out [ch] );
650 }
651 }
652
dsp_voice_V4(dsp_voice_t * v)653 static INLINE void dsp_voice_V4( dsp_voice_t* v )
654 {
655 /* Decode BRR */
656 dsp_m.t_looped = 0;
657 if ( v->interp_pos >= 0x4000 )
658 {
659 dsp_decode_brr( v );
660
661 if ( (v->brr_offset += 2) >= BRR_BLOCK_SIZE )
662 {
663 /* Start decoding next BRR block */
664 v->brr_addr = (v->brr_addr + BRR_BLOCK_SIZE) & 0xFFFF;
665 if ( dsp_m.t_brr_header & 1 )
666 {
667 v->brr_addr = dsp_m.t_brr_next_addr;
668 dsp_m.t_looped = v->vbit;
669 }
670 v->brr_offset = 1;
671 }
672 }
673
674 /* Apply pitch */
675 v->interp_pos = (v->interp_pos & 0x3FFF) + dsp_m.t_pitch;
676
677 /* Keep from getting too far ahead (when using pitch modulation) */
678 if ( v->interp_pos > 0x7FFF )
679 v->interp_pos = 0x7FFF;
680
681 /* Output left */
682 dsp_voice_output( v, 0 );
683 }
684
685 #define dsp_voice_V5(v) \
686 { \
687 int endx_buf; \
688 /* Output right */ \
689 dsp_voice_output( v, 1 ); \
690 /* ENDX, OUTX, and ENVX won't update if you wrote to them 1-2 clocks earlier */ \
691 endx_buf = dsp_m.regs[R_ENDX] | dsp_m.t_looped; \
692 /* Clear bit in ENDX if KON just began */ \
693 if ( v->kon_delay == 5 ) \
694 endx_buf &= ~v->vbit; \
695 dsp_m.endx_buf = (uint8_t) endx_buf; \
696 }
697
698 #define dsp_voice_V6(v) (dsp_m.outx_buf = (uint8_t) (dsp_m.t_output >> 8))
699
700 #define dsp_voice_V7(v) \
701 dsp_m.regs[R_ENDX] = dsp_m.endx_buf; \
702 dsp_m.envx_buf = v->t_envx_out
703
704 #define dsp_voice_V8(v) v->regs [V_OUTX] = dsp_m.outx_buf
705
706 #define dsp_voice_V9(v) v->regs [V_ENVX] = dsp_m.envx_buf
707
708 /* Echo */
709
710 /* Current echo buffer pointer for left/right channel */
711 #define ECHO_PTR( ch ) (&dsp_m.ram [dsp_m.t_echo_ptr + ch * 2])
712
713 /* Calculate FIR point for left/right channel */
714 #define CALC_FIR( i, ch ) ((dsp_m.echo_hist_pos[i + 1][ch] * (int8_t) REG(FIR + i * 0x10)) >> 6)
715
716 #define ECHO_READ(ch) \
717 { \
718 uint8_t *ptr = &dsp_m.ram [dsp_m.t_echo_ptr + ch * 2]; \
719 if ( dsp_m.t_echo_ptr >= 0xffc0 && dsp_m.rom_enabled ) \
720 ptr = (uint8_t*)&dsp_m.hi_ram [dsp_m.t_echo_ptr + ch * 2 - 0xffc0]; \
721 /* second copy simplifies wrap-around handling */ \
722 dsp_m.echo_hist_pos[0][ch] = dsp_m.echo_hist_pos[8][ch] = (GET_LE16SA(ptr)) >> 1; \
723 }
724
dsp_echo_22(void)725 static INLINE void dsp_echo_22 (void)
726 {
727 if ( ++dsp_m.echo_hist_pos >= &dsp_m.echo_hist [ECHO_HIST_SIZE] )
728 dsp_m.echo_hist_pos = dsp_m.echo_hist;
729
730 dsp_m.t_echo_ptr = (dsp_m.t_esa * 0x100 + dsp_m.echo_offset) & 0xFFFF;
731
732 ECHO_READ(0);
733
734 dsp_m.t_echo_in [0] = (int)((((dsp_m.echo_hist_pos [0 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 0 * 0x10]) >> 6));
735 dsp_m.t_echo_in [1] = (int)((((dsp_m.echo_hist_pos [0 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 0 * 0x10]) >> 6));
736 }
737
738 #define dsp_echo_23() \
739 dsp_m.t_echo_in [0] += (int)((((dsp_m.echo_hist_pos [1 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 1 * 0x10]) >> 6) + (((dsp_m.echo_hist_pos [2 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 2 * 0x10]) >> 6)); \
740 dsp_m.t_echo_in [1] += (int)((((dsp_m.echo_hist_pos [1 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 1 * 0x10]) >> 6) + (((dsp_m.echo_hist_pos [2 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 2 * 0x10]) >> 6)); \
741 ECHO_READ(1)
742
743 #define dsp_echo_24() \
744 dsp_m.t_echo_in [0] += (int)(((((dsp_m.echo_hist_pos [3 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 3 * 0x10]) >> 6) + (((dsp_m.echo_hist_pos [4 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 4 * 0x10]) >> 6) + (((dsp_m.echo_hist_pos [5 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 5 * 0x10]) >> 6))); \
745 dsp_m.t_echo_in [1] += (int)(((((dsp_m.echo_hist_pos [3 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 3 * 0x10]) >> 6) + (((dsp_m.echo_hist_pos [4 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 4 * 0x10]) >> 6) + (((dsp_m.echo_hist_pos [5 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 5 * 0x10]) >> 6)))
746
dsp_echo_25(void)747 static INLINE void dsp_echo_25 (void)
748 {
749 int l = (int16_t)(dsp_m.t_echo_in [0] + (((dsp_m.echo_hist_pos [6 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 6 * 0x10]) >> 6));
750 int r = (int16_t)(dsp_m.t_echo_in [1] + (((dsp_m.echo_hist_pos [6 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 6 * 0x10]) >> 6));
751
752 l += (int16_t) (((dsp_m.echo_hist_pos [7 + 1]) [0] * (int8_t) dsp_m.regs [R_FIR + 7 * 0x10]) >> 6);
753 r += (int16_t) (((dsp_m.echo_hist_pos [7 + 1]) [1] * (int8_t) dsp_m.regs [R_FIR + 7 * 0x10]) >> 6);
754
755 CLAMP16(l);
756 CLAMP16(r);
757
758 dsp_m.t_echo_in [0] = l & ~1;
759 dsp_m.t_echo_in [1] = r & ~1;
760 }
761
762 #define ECHO_OUTPUT(var, ch) \
763 { \
764 var = (int16_t) ((dsp_m.t_main_out [ch] * (int8_t) REG(MVOLL + ch * 0x10)) >> 7) + (int16_t) ((dsp_m.t_echo_in [ch] * (int8_t) REG(EVOLL + ch * 0x10)) >> 7); \
765 CLAMP16( var ); \
766 }
767
dsp_echo_26(void)768 static INLINE void dsp_echo_26 (void)
769 {
770 int l, r;
771
772 ECHO_OUTPUT(dsp_m.t_main_out[0], 0 );
773
774 l = dsp_m.t_echo_out [0] + (int16_t) ((dsp_m.t_echo_in [0] * (int8_t) dsp_m.regs [R_EFB]) >> 7);
775 r = dsp_m.t_echo_out [1] + (int16_t) ((dsp_m.t_echo_in [1] * (int8_t) dsp_m.regs [R_EFB]) >> 7);
776
777 CLAMP16(l);
778 CLAMP16(r);
779
780 dsp_m.t_echo_out [0] = l & ~1;
781 dsp_m.t_echo_out [1] = r & ~1;
782 }
783
dsp_echo_27(void)784 static INLINE void dsp_echo_27 (void)
785 {
786 int r;
787 short *out;
788
789 int l = dsp_m.t_main_out [0];
790 ECHO_OUTPUT(r, 1);
791 dsp_m.t_main_out [0] = 0;
792 dsp_m.t_main_out [1] = 0;
793
794 if ( dsp_m.regs [R_FLG] & 0x40 )
795 {
796 l = 0;
797 r = 0;
798 }
799
800 out = dsp_m.out;
801 out [0] = l;
802 out [1] = r;
803 out += 2;
804 if ( out >= dsp_m.out_end )
805 {
806 out = dsp_m.extra;
807 dsp_m.out_end = &dsp_m.extra [EXTRA_SIZE];
808 }
809 dsp_m.out = out;
810 }
811
812 #define ECHO_28() dsp_m.t_echo_enabled = dsp_m.regs [R_FLG];
813
814 #define ECHO_WRITE(ch) \
815 if ( !(dsp_m.t_echo_enabled & 0x20) ) \
816 { \
817 SET_LE16A( ECHO_PTR( ch ), dsp_m.t_echo_out [ch] ); \
818 if ( dsp_m.t_echo_ptr >= 0xffc0 ) \
819 { \
820 SET_LE16A( &dsp_m.hi_ram [dsp_m.t_echo_ptr + ch * 2 - 0xffc0], dsp_m.t_echo_out [ch] ); \
821 if ( dsp_m.rom_enabled ) \
822 SET_LE16A( ECHO_PTR( ch ), GET_LE16A( &dsp_m.rom [dsp_m.t_echo_ptr + ch * 2 - 0xffc0] ) ); \
823 } \
824 } \
825 dsp_m.t_echo_out [ch] = 0;
826
dsp_echo_29(void)827 static INLINE void dsp_echo_29 (void)
828 {
829 dsp_m.t_esa = dsp_m.regs [R_ESA];
830
831 if ( !dsp_m.echo_offset )
832 dsp_m.echo_length = (dsp_m.regs [R_EDL] & 0x0F) * 0x800;
833
834 dsp_m.echo_offset += 4;
835 if ( dsp_m.echo_offset >= dsp_m.echo_length )
836 dsp_m.echo_offset = 0;
837
838
839 ECHO_WRITE(0);
840
841 dsp_m.t_echo_enabled = dsp_m.regs [R_FLG];
842 }
843
844 /* Timing */
845
846 /* Execute clock for a particular voice */
847
848 /* The most common sequence of clocks uses composite operations
849 for efficiency. For example, the following are equivalent to the
850 individual steps on the right:
851
852 V(V7_V4_V1,2) -> V(V7,2) V(V4,3) V(V1,5)
853 V(V8_V5_V2,2) -> V(V8,2) V(V5,3) V(V2,4)
854 V(V9_V6_V3,2) -> V(V9,2) V(V6,3) V(V3,4) */
855
856 /* Voice 0 1 2 3 4 5 6 7 */
857
858 /* Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks
859 a pair of samples is be generated. */
860
dsp_run(int clocks_remain)861 static void dsp_run( int clocks_remain )
862 {
863 dsp_voice_t *v0, *v1, *v2;
864 int phase;
865 if (Settings.HardDisableAudio)
866 return;
867 phase = dsp_m.phase;
868 dsp_m.phase = (phase + clocks_remain) & 31;
869
870 for (; clocks_remain > 0;)
871 {
872 switch ( phase )
873 {
874 #if 0
875 if ( 0 && !--clocks_remain )
876 break;
877 #endif
878 case 0:
879 v0 = (dsp_voice_t*)&dsp_m.voices[0];
880 v1 = (dsp_voice_t*)(v0 + 1);
881 dsp_voice_V5(v0);
882 dsp_voice_V2(v1);
883 if ( 1 && !--clocks_remain )
884 break;
885 case 1:
886 v0 = (dsp_voice_t*)&dsp_m.voices[0];
887 v1 = (dsp_voice_t*)(v0 + 1);
888 dsp_voice_V6(v0);
889 dsp_voice_V3a(v1);
890 dsp_voice_V3b(v1);
891 dsp_voice_V3c(v1);
892 if ( 2 && !--clocks_remain )
893 break;
894 case 2:
895 v0 = (dsp_voice_t*)&dsp_m.voices[0];
896 v1 = (dsp_voice_t*)(v0 + 1);
897 v2 = (dsp_voice_t*)(v0 + 3);
898 dsp_voice_V7(v0);
899 dsp_voice_V1(v2);
900 dsp_voice_V4(v1);
901 if ( 3 && !--clocks_remain )
902 break;
903 case 3:
904 v0 = (dsp_voice_t*)&dsp_m.voices[0];
905 v1 = (dsp_voice_t*)(v0 + 1);
906 v2 = (dsp_voice_t*)(v0 + 2);
907 dsp_voice_V8(v0);
908 dsp_voice_V5(v1);
909 dsp_voice_V2(v2);
910 if ( 4 && !--clocks_remain )
911 break;
912 case 4:
913 v0 = (dsp_voice_t*)&dsp_m.voices[0];
914 v1 = (dsp_voice_t*)(v0 + 1);
915 v2 = (dsp_voice_t*)(v0 + 2);
916 dsp_voice_V9(v0);
917 dsp_voice_V6(v1);
918 dsp_voice_V3a(v2);
919 dsp_voice_V3b(v2);
920 dsp_voice_V3c(v2);
921 if ( 5 && !--clocks_remain )
922 break;
923 case 5:
924 v0 = (dsp_voice_t*)&dsp_m.voices[1];
925 v1 = (dsp_voice_t*)(v0 + 1);
926 v2 = (dsp_voice_t*)(v0 + 3);
927 dsp_voice_V7(v0);
928 dsp_voice_V1(v2);
929 dsp_voice_V4(v1);
930 if ( 6 && !--clocks_remain )
931 break;
932 case 6:
933 v0 = (dsp_voice_t*)&dsp_m.voices[1];
934 v1 = (dsp_voice_t*)(v0 + 1);
935 v2 = (dsp_voice_t*)(v0 + 2);
936 dsp_voice_V8(v0);
937 dsp_voice_V5(v1);
938 dsp_voice_V2(v2);
939 if ( 7 && !--clocks_remain )
940 break;
941 case 7:
942 v0 = (dsp_voice_t*)&dsp_m.voices[1];
943 v1 = (dsp_voice_t*)(v0 + 1);
944 v2 = (dsp_voice_t*)(v0 + 2);
945 dsp_voice_V9(v0);
946 dsp_voice_V6(v1);
947 dsp_voice_V3a(v2);
948 dsp_voice_V3b(v2);
949 dsp_voice_V3c(v2);
950 if ( 8 && !--clocks_remain )
951 break;
952 case 8:
953 v0 = (dsp_voice_t*)&dsp_m.voices[2];
954 v1 = (dsp_voice_t*)(v0 + 1);
955 v2 = (dsp_voice_t*)(v0 + 3);
956 dsp_voice_V7(v0);
957 dsp_voice_V1(v2);
958 dsp_voice_V4(v1);
959 if ( 9 && !--clocks_remain )
960 break;
961 case 9:
962 v0 = (dsp_voice_t*)&dsp_m.voices[2];
963 v1 = (dsp_voice_t*)(v0 + 1);
964 v2 = (dsp_voice_t*)(v0 + 2);
965 dsp_voice_V8(v0);
966 dsp_voice_V5(v1);
967 dsp_voice_V2(v2);
968 if ( 10 && !--clocks_remain )
969 break;
970 case 10:
971 v0 = (dsp_voice_t*)&dsp_m.voices[2];
972 v1 = (dsp_voice_t*)(v0 + 1);
973 v2 = (dsp_voice_t*)(v0 + 2);
974 dsp_voice_V9(v0);
975 dsp_voice_V6(v1);
976 dsp_voice_V3a(v2);
977 dsp_voice_V3b(v2);
978 dsp_voice_V3c(v2);
979 if ( 11 && !--clocks_remain )
980 break;
981 case 11:
982 v0 = (dsp_voice_t*)&dsp_m.voices[3];
983 v1 = (dsp_voice_t*)(v0 + 1);
984 v2 = (dsp_voice_t*)(v0 + 3);
985 dsp_voice_V7(v0);
986 dsp_voice_V1(v2);
987 dsp_voice_V4(v1);
988 if ( 12 && !--clocks_remain )
989 break;
990 case 12:
991 v0 = (dsp_voice_t*)&dsp_m.voices[3];
992 v1 = (dsp_voice_t*)(v0 + 1);
993 v2 = (dsp_voice_t*)(v0 + 2);
994 dsp_voice_V8(v0);
995 dsp_voice_V5(v1);
996 dsp_voice_V2(v2);
997 if ( 13 && !--clocks_remain )
998 break;
999 case 13:
1000 v0 = (dsp_voice_t*)&dsp_m.voices[3];
1001 v1 = (dsp_voice_t*)(v0 + 1);
1002 v2 = (dsp_voice_t*)(v0 + 2);
1003 dsp_voice_V9(v0);
1004 dsp_voice_V6(v1);
1005 dsp_voice_V3a(v2);
1006 dsp_voice_V3b(v2);
1007 dsp_voice_V3c(v2);
1008 if ( 14 && !--clocks_remain )
1009 break;
1010 case 14:
1011 v0 = (dsp_voice_t*)&dsp_m.voices[4];
1012 v1 = (dsp_voice_t*)(v0 + 1);
1013 v2 = (dsp_voice_t*)(v0 + 3);
1014 dsp_voice_V7(v0);
1015 dsp_voice_V1(v2);
1016 dsp_voice_V4(v1);
1017 if ( 15 && !--clocks_remain )
1018 break;
1019 case 15:
1020 v0 = (dsp_voice_t*)&dsp_m.voices[4];
1021 v1 = (dsp_voice_t*)(v0 + 1);
1022 v2 = (dsp_voice_t*)(v0 + 2);
1023 dsp_voice_V8(v0);
1024 dsp_voice_V5(v1);
1025 dsp_voice_V2(v2);
1026 if ( 16 && !--clocks_remain )
1027 break;
1028 case 16:
1029 v0 = (dsp_voice_t*)&dsp_m.voices[4];
1030 v1 = (dsp_voice_t*)(v0 + 1);
1031 v2 = (dsp_voice_t*)(v0 + 2);
1032 dsp_voice_V9(v0);
1033 dsp_voice_V6(v1);
1034 dsp_voice_V3a(v2);
1035 dsp_voice_V3b(v2);
1036 dsp_voice_V3c(v2);
1037 if ( 17 && !--clocks_remain )
1038 break;
1039 case 17:
1040 v0 = (dsp_voice_t*)&dsp_m.voices[0];
1041 v1 = (dsp_voice_t*)(v0 + 5);
1042 v2 = (dsp_voice_t*)(v0 + 6);
1043 dsp_voice_V1(v0);
1044 dsp_voice_V7(v1);
1045 dsp_voice_V4(v2);
1046 if ( 18 && !--clocks_remain )
1047 break;
1048 case 18:
1049 v0 = (dsp_voice_t*)&dsp_m.voices[5];
1050 v1 = (dsp_voice_t*)(v0 + 1);
1051 v2 = (dsp_voice_t*)(v0 + 2);
1052 dsp_voice_V8(v0);
1053 dsp_voice_V5(v1);
1054 dsp_voice_V2(v2);
1055 if ( 19 && !--clocks_remain )
1056 break;
1057 case 19:
1058 v0 = (dsp_voice_t*)&dsp_m.voices[5];
1059 v1 = (dsp_voice_t*)(v0 + 1);
1060 v2 = (dsp_voice_t*)(v0 + 2);
1061 dsp_voice_V9(v0);
1062 dsp_voice_V6(v1);
1063 dsp_voice_V3a(v2);
1064 dsp_voice_V3b(v2);
1065 dsp_voice_V3c(v2);
1066 if ( 20 && !--clocks_remain )
1067 break;
1068 case 20:
1069 v0 = (dsp_voice_t*)&dsp_m.voices[1];
1070 v1 = (dsp_voice_t*)(v0 + 5);
1071 v2 = (dsp_voice_t*)(v0 + 6);
1072 dsp_voice_V1(v0);
1073 dsp_voice_V7(v1);
1074 dsp_voice_V4(v2);
1075 if ( 21 && !--clocks_remain )
1076 break;
1077 case 21:
1078 v2 = (dsp_voice_t*)&dsp_m.voices[0];
1079 v0 = (dsp_voice_t*)(v2 + 6);
1080 v1 = (dsp_voice_t*)(v2 + 7);
1081 dsp_voice_V8(v0);
1082 dsp_voice_V5(v1);
1083 dsp_voice_V2(v2);
1084 if ( 22 && !--clocks_remain )
1085 break;
1086 case 22:
1087 v0 = (dsp_voice_t*)&dsp_m.voices[0];
1088 v1 = (dsp_voice_t*)(v0 + 6);
1089 v2 = (dsp_voice_t*)(v0 + 7);
1090 dsp_voice_V3a(v0);
1091 dsp_voice_V9(v1);
1092 dsp_voice_V6(v2);
1093 dsp_echo_22();
1094 if ( 23 && !--clocks_remain )
1095 break;
1096 case 23:
1097 v0 = (dsp_voice_t*)&dsp_m.voices[7];
1098 dsp_voice_V7(v0);
1099 dsp_echo_23();
1100 if ( 24 && !--clocks_remain )
1101 break;
1102 case 24:
1103 v0 = (dsp_voice_t*)&dsp_m.voices[7];
1104 dsp_voice_V8(v0);
1105 dsp_echo_24();
1106 if ( 25 && !--clocks_remain )
1107 break;
1108 case 25:
1109 v0 = (dsp_voice_t*)&dsp_m.voices[0];
1110 v1 = (dsp_voice_t*)(v0 + 7);
1111 dsp_voice_V3b(v0);
1112 dsp_voice_V9(v1);
1113 dsp_echo_25();
1114 if ( 26 && !--clocks_remain )
1115 break;
1116 case 26:
1117 dsp_echo_26();
1118 if ( 27 && !--clocks_remain )
1119 break;
1120 case 27:
1121 MISC_27();
1122 dsp_echo_27();
1123 if ( 28 && !--clocks_remain )
1124 break;
1125 case 28:
1126 MISC_28();
1127 ECHO_28();
1128 if ( 29 && !--clocks_remain )
1129 break;
1130 case 29:
1131 MISC_29();
1132 dsp_echo_29();
1133 if ( 30 && !--clocks_remain )
1134 break;
1135 case 30:
1136 v0 = (dsp_voice_t*)&dsp_m.voices[0];
1137 dsp_misc_30();
1138 dsp_voice_V3c(v0);
1139 ECHO_WRITE(1);
1140 if ( 31 && !--clocks_remain )
1141 break;
1142 case 31:
1143 v0 = (dsp_voice_t*)&dsp_m.voices[0];
1144 v1 = (dsp_voice_t*)(v0 + 2);
1145 dsp_voice_V4(v0);
1146 dsp_voice_V1(v1);
1147
1148 --clocks_remain;
1149 }
1150 }
1151 }
1152
1153 /* Sets destination for output samples. If out is NULL or out_size is 0,
1154 doesn't generate any. */
1155
dsp_set_output(short * out,int size)1156 static void dsp_set_output( short * out, int size )
1157 {
1158 if ( !out )
1159 {
1160 out = dsp_m.extra;
1161 size = EXTRA_SIZE;
1162 }
1163 dsp_m.out_begin = out;
1164 dsp_m.out = out;
1165 dsp_m.out_end = out + size;
1166 }
1167
1168 /* Setup */
1169
dsp_soft_reset_common(void)1170 static void dsp_soft_reset_common (void)
1171 {
1172 dsp_m.noise = 0x4000;
1173 dsp_m.echo_hist_pos = dsp_m.echo_hist;
1174 dsp_m.every_other_sample = 1;
1175 dsp_m.echo_offset = 0;
1176 dsp_m.phase = 0;
1177
1178 dsp_m.counter = 0;
1179 }
1180
1181 /* Resets DSP to power-on state */
1182
dsp_reset(void)1183 static void dsp_reset (void)
1184 {
1185 int i;
1186
1187 uint8_t const initial_regs [REGISTER_COUNT] =
1188 {
1189 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80,
1190 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF,
1191 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A,
1192 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF,
1193 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67,
1194 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x00,0x4E,0x7B,0xFF,
1195 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F,
1196 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF
1197 };
1198
1199 /* Resets DSP and uses supplied values to initialize registers */
1200 memcpy(dsp_m.regs,initial_regs,REGISTER_COUNT);
1201
1202 /* Internal state */
1203 for ( i = VOICE_COUNT; --i >= 0; )
1204 {
1205 dsp_voice_t* v = &dsp_m.voices [i];
1206 v->brr_offset = 1;
1207 v->vbit = 1 << i;
1208 v->regs = &dsp_m.regs [i * 0x10];
1209 }
1210 dsp_m.new_kon = dsp_m.regs[R_KON];
1211 dsp_m.t_dir = dsp_m.regs[R_DIR];
1212 dsp_m.t_esa = dsp_m.regs[R_ESA];
1213
1214 dsp_soft_reset_common();
1215 }
1216
1217 /* Initializes DSP and has it use the 64K RAM provided */
1218
dsp_init(void * ram_64k)1219 static void dsp_init( void* ram_64k )
1220 {
1221 dsp_m.ram = (uint8_t*) ram_64k;
1222 dsp_set_output( 0, 0 );
1223 dsp_reset();
1224 }
1225
1226 /* Emulates pressing reset switch on SNES */
1227
dsp_soft_reset(void)1228 static void dsp_soft_reset (void)
1229 {
1230 dsp_m.regs[R_FLG] = 0xE0;
1231 dsp_soft_reset_common();
1232 }
1233
1234
1235 /* State save/load */
1236
1237 #if !SPC_NO_COPY_STATE_FUNCS
1238
spc_copier_copy(spc_state_copy_t * copier,void * state,size_t size)1239 static void spc_copier_copy(spc_state_copy_t * copier, void* state, size_t size )
1240 {
1241 copier->func(copier->buf, state, size );
1242 }
1243
spc_copier_copy_int(spc_state_copy_t * copier,int32_t state,int32_t size)1244 static int spc_copier_copy_int(spc_state_copy_t * copier, int32_t state, int32_t size )
1245 {
1246 uint8_t s [2];
1247 SET_LE16( s, state );
1248 copier->func(copier->buf, &s, size );
1249 return GET_LE16( s );
1250 }
1251
spc_copier_extra(spc_state_copy_t * copier)1252 static void spc_copier_extra(spc_state_copy_t * copier)
1253 {
1254 int32_t n = 0;
1255 n = (uint8_t) spc_copier_copy_int(copier, n, sizeof (uint8_t) );
1256
1257 if ( n > 0 )
1258 {
1259 int8_t temp [64];
1260 memset( temp, 0, sizeof(temp));
1261 do
1262 {
1263 int32_t size_n = sizeof(temp);
1264 if ( size_n > n )
1265 size_n = n;
1266 n -= size_n;
1267 copier->func(copier->buf, temp, size_n );
1268 }
1269 while ( n );
1270 }
1271 }
1272
1273 /* Saves/loads exact emulator state */
1274
dsp_copy_state(unsigned char ** io,dsp_copy_func_t copy)1275 static void NO_OPTIMIZE dsp_copy_state( unsigned char** io, dsp_copy_func_t copy )
1276 {
1277 int32_t i, j;
1278
1279 spc_state_copy_t copier;
1280 copier.func = copy;
1281 copier.buf = io;
1282
1283 /* DSP registers */
1284 spc_copier_copy(&copier, dsp_m.regs, REGISTER_COUNT );
1285
1286 /* Internal state */
1287
1288 /* Voices */
1289 for ( i = 0; i < VOICE_COUNT; i++ )
1290 {
1291 dsp_voice_t *v = (dsp_voice_t*)&dsp_m.voices [i];
1292
1293 /* BRR buffer */
1294 for ( j = 0; j < BRR_BUF_SIZE; j++ )
1295 {
1296 int s;
1297
1298 s = v->buf [j];
1299 SPC_COPY( int16_t, s );
1300 v->buf [j] = v->buf [j + BRR_BUF_SIZE] = s;
1301 }
1302
1303 SPC_COPY( uint16_t, v->interp_pos );
1304 SPC_COPY( uint16_t, v->brr_addr );
1305 SPC_COPY( uint16_t, v->env );
1306 SPC_COPY( int16_t, v->hidden_env );
1307 SPC_COPY( uint8_t, v->buf_pos );
1308 SPC_COPY( uint8_t, v->brr_offset );
1309 SPC_COPY( uint8_t, v->kon_delay );
1310 {
1311 int m;
1312
1313 m = v->env_mode;
1314 SPC_COPY( uint8_t, m );
1315 v->env_mode = m;
1316 }
1317 SPC_COPY( uint8_t, v->t_envx_out );
1318
1319 spc_copier_extra(&copier);
1320 }
1321
1322 /* Echo history */
1323 for ( i = 0; i < ECHO_HIST_SIZE; i++ )
1324 {
1325 int s, s2;
1326
1327 s = dsp_m.echo_hist_pos [i] [0];
1328 s2 = dsp_m.echo_hist_pos [i] [1];
1329
1330 SPC_COPY( int16_t, s );
1331 dsp_m.echo_hist [i] [0] = s; /* write back at offset 0 */
1332
1333 SPC_COPY( int16_t, s2 );
1334 dsp_m.echo_hist [i] [1] = s2; /* write back at offset 0 */
1335 }
1336 dsp_m.echo_hist_pos = dsp_m.echo_hist;
1337 memcpy( &dsp_m.echo_hist [ECHO_HIST_SIZE], dsp_m.echo_hist, ECHO_HIST_SIZE * sizeof dsp_m.echo_hist [0] );
1338
1339 /* Misc */
1340 SPC_COPY( uint8_t, dsp_m.every_other_sample );
1341 SPC_COPY( uint8_t, dsp_m.kon );
1342
1343 SPC_COPY( uint16_t, dsp_m.noise );
1344 SPC_COPY( uint16_t, dsp_m.counter );
1345 SPC_COPY( uint16_t, dsp_m.echo_offset );
1346 SPC_COPY( uint16_t, dsp_m.echo_length );
1347 SPC_COPY( uint8_t, dsp_m.phase );
1348
1349 SPC_COPY( uint8_t, dsp_m.new_kon );
1350 SPC_COPY( uint8_t, dsp_m.endx_buf );
1351 SPC_COPY( uint8_t, dsp_m.envx_buf );
1352 SPC_COPY( uint8_t, dsp_m.outx_buf );
1353
1354 SPC_COPY( uint8_t, dsp_m.t_pmon );
1355 SPC_COPY( uint8_t, dsp_m.t_non );
1356 SPC_COPY( uint8_t, dsp_m.t_eon );
1357 SPC_COPY( uint8_t, dsp_m.t_dir );
1358 SPC_COPY( uint8_t, dsp_m.t_koff );
1359
1360 SPC_COPY( uint16_t, dsp_m.t_brr_next_addr );
1361 SPC_COPY( uint8_t, dsp_m.t_adsr0 );
1362 SPC_COPY( uint8_t, dsp_m.t_brr_header );
1363 SPC_COPY( uint8_t, dsp_m.t_brr_byte );
1364 SPC_COPY( uint8_t, dsp_m.t_srcn );
1365 SPC_COPY( uint8_t, dsp_m.t_esa );
1366 SPC_COPY( uint8_t, dsp_m.t_echo_enabled );
1367
1368 SPC_COPY( int16_t, dsp_m.t_main_out [0] );
1369 SPC_COPY( int16_t, dsp_m.t_main_out [1] );
1370 SPC_COPY( int16_t, dsp_m.t_echo_out [0] );
1371 SPC_COPY( int16_t, dsp_m.t_echo_out [1] );
1372 SPC_COPY( int16_t, dsp_m.t_echo_in [0] );
1373 SPC_COPY( int16_t, dsp_m.t_echo_in [1] );
1374
1375 SPC_COPY( uint16_t, dsp_m.t_dir_addr );
1376 SPC_COPY( uint16_t, dsp_m.t_pitch );
1377 SPC_COPY( int16_t, dsp_m.t_output );
1378 SPC_COPY( uint16_t, dsp_m.t_echo_ptr );
1379 SPC_COPY( uint8_t, dsp_m.t_looped );
1380
1381 spc_copier_extra(&copier);
1382 }
1383 #endif
1384
1385 /* Core SPC emulation: CPU, timers, SMP registers, memory */
1386
1387 /* snes_spc 0.9.0. http://www.slack.net/~ant/ */
1388
1389 /***********************************************************************************
1390 SNES SPC
1391 ***********************************************************************************/
1392
1393 static spc_state_t m;
1394 static signed char reg_times [256];
1395 static bool8 allow_time_overflow;
1396
1397 /* Copyright (C) 2004-2007 Shay Green. This module is free software; you
1398 can redistribute it and/or modify it under the terms of the GNU Lesser
1399 General Public License as published by the Free Software Foundation; either
1400 version 2.1 of the License, or (at your option) any later version. This
1401 module is distributed in the hope that it will be useful, but WITHOUT ANY
1402 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1403 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
1404 details. You should have received a copy of the GNU Lesser General Public
1405 License along with this module; if not, write to the Free Software Foundation,
1406 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
1407
1408 /* (n ? n : 256) */
1409 #define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
1410
1411 /* Timers */
1412
1413 #define TIMER_DIV( t, n ) ((n) >> t->prescaler)
1414 #define TIMER_MUL( t, n ) ((n) << t->prescaler)
1415
spc_run_timer_(Timer * t,int time)1416 static Timer* spc_run_timer_( Timer* t, int time )
1417 {
1418 int remain, divider, over, n;
1419 int elapsed = TIMER_DIV( t, time - t->next_time ) + 1;
1420
1421 t->next_time += TIMER_MUL( t, elapsed );
1422
1423 if (!t->enabled )
1424 return t;
1425
1426 remain = IF_0_THEN_256( t->period - t->divider );
1427 divider = t->divider + elapsed;
1428 over = elapsed - remain;
1429
1430 if ( over >= 0 )
1431 {
1432 n = over / t->period;
1433 t->counter = (t->counter + 1 + n) & 0x0F;
1434 divider = over - n * t->period;
1435 }
1436
1437 t->divider = (uint8_t) divider;
1438
1439 return t;
1440 }
1441
1442 /* ROM */
1443
spc_enable_rom(int enable)1444 void spc_enable_rom( int enable )
1445 {
1446 if ( m.rom_enabled != enable )
1447 {
1448 m.rom_enabled = dsp_m.rom_enabled = enable;
1449 if ( enable )
1450 memcpy( m.hi_ram, &m.ram.ram[ROM_ADDR], sizeof m.hi_ram );
1451 memcpy( &m.ram.ram[ROM_ADDR], (enable ? m.rom : m.hi_ram), ROM_SIZE );
1452 /* TODO: ROM can still get overwritten when DSP writes to echo buffer */
1453 }
1454 }
1455
1456
1457 /* DSP */
1458
1459 #define MAX_REG_TIME 29
1460
1461 #define RUN_DSP( time, offset ) \
1462 int count = (time) - (offset) - m.dsp_time; \
1463 if ( count >= 0 ) \
1464 { \
1465 int clock_count; \
1466 clock_count = (count & ~(CLOCKS_PER_SAMPLE - 1)) + CLOCKS_PER_SAMPLE; \
1467 m.dsp_time += clock_count; \
1468 dsp_run( clock_count ); \
1469 }
1470
spc_dsp_write(const uint8_t data)1471 static INLINE void spc_dsp_write( const uint8_t data )
1472 {
1473 uint_fast8_t addr;
1474
1475 /* Writes DSP registers. */
1476 addr = m.smp_regs[0][R_DSPADDR];
1477 dsp_m.regs [addr] = data;
1478 switch ( addr & 0x0F )
1479 {
1480 case V_ENVX:
1481 dsp_m.envx_buf = data;
1482 break;
1483
1484 case V_OUTX:
1485 dsp_m.outx_buf = data;
1486 break;
1487 case 0x0C:
1488 if ( addr == R_KON )
1489 dsp_m.new_kon = data;
1490
1491 if ( addr == R_ENDX ) /* always cleared, regardless of data written */
1492 {
1493 dsp_m.endx_buf = 0;
1494 dsp_m.regs [R_ENDX] = 0;
1495 }
1496 break;
1497 }
1498 /* dprintf( "SPC wrote to DSP register > $7F\n" ); */
1499 }
1500
1501
1502 /* Memory access extras */
1503
1504 /* CPU write */
1505
1506 /* divided into multiple functions to keep rarely-used functionality separate
1507 so often-used functionality can be optimized better by compiler */
1508
1509 /* If write isn't preceded by read, data has this added to it
1510 int const no_read_before_write = 0x2000; */
1511
1512 #define NO_READ_BEFORE_WRITE 8192
1513 #define NO_READ_BEFORE_WRITE_DIVIDED_BY_TWO 4096
1514
spc_cpu_write_smp_reg_(unsigned data,int time,int addr)1515 static void spc_cpu_write_smp_reg_( unsigned data, int time, int addr )
1516 {
1517 switch ( addr )
1518 {
1519 case R_T0TARGET:
1520 case R_T1TARGET:
1521 case R_T2TARGET:
1522 {
1523 Timer *t = (Timer*)&m.timers [addr - R_T0TARGET];
1524 int period = IF_0_THEN_256( data );
1525
1526 if ( t->period != period )
1527 {
1528 if ( time >= t->next_time )
1529 t = spc_run_timer_( t, time );
1530 t->period = period;
1531 }
1532 break;
1533 }
1534 case R_T0OUT:
1535 case R_T1OUT:
1536 case R_T2OUT:
1537 /* dprintf( "SPC wrote to counter %d\n", (int) addr - R_T0OUT ); */
1538
1539 if ( data < NO_READ_BEFORE_WRITE_DIVIDED_BY_TWO)
1540 {
1541 if ( (time - 1) >= m.timers[addr - R_T0OUT].next_time )
1542 spc_run_timer_( &m.timers [addr - R_T0OUT], time - 1 )->counter = 0;
1543 else
1544 m.timers[addr - R_T0OUT].counter = 0;
1545 }
1546 break;
1547
1548 /* Registers that act like RAM */
1549 case 0x8:
1550 case 0x9:
1551 m.smp_regs[1][addr] = (uint8_t) data;
1552 break;
1553
1554 case R_TEST:
1555 #if 0
1556 if ( (uint8_t) data != 0x0A )
1557 dprintf( "SPC wrote to test register\n" );
1558 #endif
1559 break;
1560
1561 case R_CONTROL:
1562 {
1563 int i;
1564 /* port clears */
1565 if ( data & 0x10 )
1566 {
1567 m.smp_regs[1][R_CPUIO0] = 0;
1568 m.smp_regs[1][R_CPUIO1] = 0;
1569 }
1570 if ( data & 0x20 )
1571 {
1572 m.smp_regs[1][R_CPUIO2] = 0;
1573 m.smp_regs[1][R_CPUIO3] = 0;
1574 }
1575
1576 /* timers */
1577 {
1578 for ( i = 0; i < TIMER_COUNT; i++ )
1579 {
1580 Timer* t = (Timer*)&m.timers [i];
1581 int enabled = data >> i & 1;
1582 if ( t->enabled != enabled )
1583 {
1584 if ( time >= t->next_time )
1585 t = spc_run_timer_( t, time );
1586 t->enabled = enabled;
1587 if ( enabled )
1588 {
1589 t->divider = 0;
1590 t->counter = 0;
1591 }
1592 }
1593 }
1594 }
1595 spc_enable_rom( data & 0x80 );
1596 }
1597 break;
1598 }
1599 }
1600
spc_cpu_write(unsigned data,uint16_t addr,int32_t time)1601 static void spc_cpu_write( unsigned data, uint16_t addr, int32_t time )
1602 {
1603 int32_t reg;
1604 /* RAM */
1605 m.ram.ram[addr] = (uint8_t) data;
1606 reg = addr - 0xF0;
1607 if ( reg >= 0 ) /* 64% */
1608 {
1609 /* $F0-$FF */
1610 if ( reg < REG_COUNT ) /* 87% */
1611 {
1612 m.smp_regs[0][reg] = (uint8_t) data;
1613
1614 /* Registers other than $F2 and $F4-$F7
1615 if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
1616 TODO: this is a bit on the fragile side */
1617
1618 if ( ((~0x2F00 << 16) << reg) < 0 ) /* 36% */
1619 {
1620 if ( reg == R_DSPDATA ) /* 99% */
1621 {
1622 RUN_DSP(time, reg_times [m.smp_regs[0][R_DSPADDR]] );
1623 if (m.smp_regs[0][R_DSPADDR] <= 0x7F )
1624 spc_dsp_write( data );
1625 }
1626 else
1627 spc_cpu_write_smp_reg_( data, time, reg);
1628 }
1629 }
1630 /* High mem/address wrap-around */
1631 else
1632 {
1633 reg -= ROM_ADDR - 0xF0;
1634 if ( reg >= 0 ) /* 1% in IPL ROM area or address wrapped around */
1635 {
1636 m.hi_ram [reg] = (uint8_t) data;
1637 if ( m.rom_enabled )
1638 m.ram.ram[reg + ROM_ADDR] = m.rom [reg]; /* restore overwritten ROM */
1639 }
1640 }
1641 }
1642 }
1643
1644 /* CPU read */
1645
spc_cpu_read(uint16_t addr,int32_t time)1646 static int spc_cpu_read( uint16_t addr, int32_t time )
1647 {
1648 int32_t result = m.ram.ram[addr];
1649 int32_t reg = addr - 0xF0;
1650
1651 if ( reg >= 0 ) /* 40% */
1652 {
1653 reg -= 0x10;
1654 if ( (uint32_t) reg >= 0xFF00 ) /* 21% */
1655 {
1656 reg += 0x10 - R_T0OUT;
1657
1658 /* Timers */
1659 if ( (uint32_t) reg < TIMER_COUNT ) /* 90% */
1660 {
1661 Timer* t = &m.timers [reg];
1662 if ( time >= t->next_time )
1663 t = spc_run_timer_( t, time );
1664 result = t->counter;
1665 t->counter = 0;
1666 }
1667 /* Other registers */
1668 else /* 10% */
1669 {
1670 int32_t reg_tmp = reg + R_T0OUT;
1671 result = m.smp_regs[1][reg_tmp];
1672 reg_tmp -= R_DSPADDR;
1673 /* DSP addr and data */
1674 if ( (uint32_t) reg_tmp <= 1 ) /* 4% 0xF2 and 0xF3 */
1675 {
1676 result = m.smp_regs[0][R_DSPADDR];
1677 if ( (uint32_t) reg_tmp == 1 )
1678 {
1679 RUN_DSP( time, reg_times [m.smp_regs[0][R_DSPADDR] & 0x7F] );
1680
1681 result = dsp_m.regs[m.smp_regs[0][R_DSPADDR] & 0x7F]; /* 0xF3 */
1682 }
1683 }
1684 }
1685 }
1686 }
1687
1688 return result;
1689 }
1690
1691 /***********************************************************************************
1692 SPC CPU
1693 ***********************************************************************************/
1694
1695 /* Inclusion here allows static memory access functions and better optimization */
1696
1697 /* Timers are by far the most common thing read from dp */
1698
1699 #define CPU_READ_TIMER( time, offset, addr_, out ) \
1700 { \
1701 int adj_time = time + offset; \
1702 int dp_addr = addr_; \
1703 int ti = dp_addr - (R_T0OUT + 0xF0); \
1704 if ( (unsigned) ti < TIMER_COUNT ) \
1705 { \
1706 Timer* t = &m.timers [ti]; \
1707 if ( adj_time >= t->next_time ) \
1708 t = spc_run_timer_( t, adj_time ); \
1709 out = t->counter; \
1710 t->counter = 0; \
1711 } \
1712 else \
1713 { \
1714 int i, reg; \
1715 out = ram [dp_addr]; \
1716 i = dp_addr - 0xF0; \
1717 if ( (unsigned) i < 0x10 ) \
1718 { \
1719 reg = i; \
1720 out = m.smp_regs[1][reg]; \
1721 reg -= R_DSPADDR; \
1722 /* DSP addr and data */ \
1723 if ( (unsigned) reg <= 1 ) /* 4% 0xF2 and 0xF3 */ \
1724 { \
1725 out = m.smp_regs[0][R_DSPADDR]; \
1726 if ( (unsigned) reg == 1 ) \
1727 { \
1728 RUN_DSP( adj_time, reg_times [m.smp_regs[0][R_DSPADDR] & 0x7F] ); \
1729 out = dsp_m.regs[m.smp_regs[0][R_DSPADDR] & 0x7F ]; /* 0xF3 */ \
1730 } \
1731 } \
1732 } \
1733 } \
1734 }
1735
1736 #define READ_TIMER( time, addr, out ) CPU_READ_TIMER( rel_time, time, (addr), out )
1737 #define SPC_CPU_READ( time, addr ) spc_cpu_read((addr), rel_time + time )
1738 #define SPC_CPU_WRITE( time, addr, data ) spc_cpu_write((data), (addr), rel_time + time )
1739
1740 #define spc_CPU_mem_bit(pc, rel_time, result) \
1741 addr = GET_LE16( pc ); \
1742 t = spc_cpu_read((addr & 0x1FFF), (rel_time)) >> (addr >> 13); \
1743 result = ((t << 8) & 0x100)
1744
1745 #define DP_ADDR( addr ) (dp + (addr))
1746
1747 #define READ_DP_TIMER( time, addr, out ) CPU_READ_TIMER( rel_time, time, DP_ADDR( addr ), out )
1748 #define READ_DP( time, addr ) SPC_CPU_READ( time, DP_ADDR( addr ) )
1749 #define WRITE_DP( time, addr, data ) SPC_CPU_WRITE( time, DP_ADDR( addr ), data )
1750
1751 #define READ_PROG16( addr ) GET_LE16( ram + (addr) )
1752
1753 #define SET_PC( n ) (pc = ram + (n))
1754 #define GET_PC() (pc - ram)
1755 #define READ_PC( pc ) (*(pc))
1756
1757 #define SET_SP( v ) (sp = ram + 0x101 + (v))
1758 #define GET_SP() (sp - 0x101 - ram)
1759
1760 #define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
1761 #define PUSH( v ) (void) (*--sp = (uint8_t) (v))
1762 #define POP( out ) (void) ((out) = *sp++)
1763
1764 #define GET_PSW( out )\
1765 {\
1766 out = psw & ~(N80 | P20 | Z02 | C01);\
1767 out |= c >> 8 & C01;\
1768 out |= dp >> 3 & P20;\
1769 out |= ((nz >> 4) | nz) & N80;\
1770 if ( !(uint8_t) nz ) out |= Z02;\
1771 }
1772
1773 #define SET_PSW( in )\
1774 {\
1775 psw = in;\
1776 c = in << 8;\
1777 dp = in << 3 & 0x100;\
1778 nz = (in << 4 & 0x800) | (~in & Z02);\
1779 }
1780
spc_run_until_(int end_time)1781 static uint8_t* spc_run_until_( int end_time )
1782 {
1783 unsigned addr, t;
1784 unsigned tmp_spc_cpu_mem_bit;
1785 int dp, nz, c, psw, a, x, y;
1786 uint8_t *ram, *pc, *sp;
1787 int rel_time = m.spc_time - end_time;
1788 m.spc_time = end_time;
1789 m.dsp_time += rel_time;
1790 m.timers [0].next_time += rel_time;
1791 m.timers [1].next_time += rel_time;
1792 m.timers [2].next_time += rel_time;
1793 ram = m.ram.ram;
1794 a = m.cpu_regs.a;
1795 x = m.cpu_regs.x;
1796 y = m.cpu_regs.y;
1797
1798 SET_PC( m.cpu_regs.pc );
1799 SET_SP( m.cpu_regs.sp );
1800 SET_PSW( m.cpu_regs.psw );
1801
1802 goto loop;
1803
1804
1805 /* Main loop */
1806
1807 cbranch_taken_loop:
1808 pc += *(int8_t const*) pc;
1809 inc_pc_loop:
1810 pc++;
1811 loop:
1812 {
1813 unsigned data;
1814 unsigned opcode = *pc;
1815
1816 if (allow_time_overflow && rel_time >= 0 )
1817 goto stop;
1818 if ( (rel_time += m.cycle_table [opcode]) > 0 && !allow_time_overflow)
1819 goto out_of_time;
1820
1821 /* TODO: if PC is at end of memory, this will get wrong operand (very obscure) */
1822 data = *++pc;
1823 switch ( opcode )
1824 {
1825
1826 /* Common instructions */
1827
1828 #define BRANCH( cond )\
1829 {\
1830 pc++;\
1831 pc += (int8_t) data;\
1832 if ( cond )\
1833 goto loop;\
1834 pc -= (int8_t) data;\
1835 rel_time -= 2;\
1836 goto loop;\
1837 }
1838
1839 case 0xF0: /* BEQ */
1840 BRANCH( !(uint8_t) nz ) /* 89% taken */
1841
1842 case 0xD0: /* BNE */
1843 BRANCH( (uint8_t) nz )
1844
1845 case 0x3F:
1846 { /* CALL */
1847 int old_addr = GET_PC() + 2;
1848 SET_PC( GET_LE16( pc ) );
1849 PUSH16( old_addr );
1850 goto loop;
1851 }
1852 case 0x6F: /* RET */
1853 SET_PC( GET_LE16( sp ) );
1854 sp += 2;
1855 goto loop;
1856
1857 case 0xE4: /* MOV a,dp */
1858 ++pc;
1859 /* 80% from timer */
1860 READ_DP_TIMER( 0, data, a = nz );
1861 goto loop;
1862
1863 case 0xFA:{ /* MOV dp,dp */
1864 int temp;
1865 READ_DP_TIMER( -2, data, temp );
1866 data = temp + NO_READ_BEFORE_WRITE ;
1867 }
1868 /* fall through */
1869 case 0x8F:
1870 { /* MOV dp,#imm */
1871 int32_t i;
1872 int32_t temp = READ_PC( pc + 1 );
1873 pc += 2;
1874
1875 i = dp + temp;
1876 ram [i] = (uint8_t) data;
1877 i -= 0xF0;
1878 if ( (uint32_t) i < 0x10 ) /* 76% */
1879 {
1880 m.smp_regs[0][i] = (uint8_t) data;
1881
1882 /* Registers other than $F2 and $F4-$F7 */
1883 if ( ((~0x2F00 << 16) << i) < 0 ) /* 12% */
1884 {
1885 if ( i == R_DSPDATA ) /* 99% */
1886 {
1887 RUN_DSP(rel_time, reg_times [m.smp_regs[0][R_DSPADDR]] );
1888 if (m.smp_regs[0][R_DSPADDR] <= 0x7F )
1889 spc_dsp_write( data );
1890 }
1891 else
1892 spc_cpu_write_smp_reg_( data, rel_time, i);
1893 }
1894 }
1895 goto loop;
1896 }
1897
1898 case 0xC4: /* MOV dp,a */
1899 ++pc;
1900 {
1901 int i = dp + data;
1902 ram [i] = (uint8_t) a;
1903 i -= 0xF0;
1904 if ( (unsigned) i < 0x10 ) /* 39% */
1905 {
1906 unsigned sel = i - 2;
1907 m.smp_regs[0][i] = (uint8_t) a;
1908
1909 if ( sel == 1 ) /* 51% $F3 */
1910 {
1911 RUN_DSP(rel_time, reg_times [m.smp_regs[0][R_DSPADDR]] );
1912 if (m.smp_regs[0][R_DSPADDR] <= 0x7F )
1913 spc_dsp_write( a );
1914 }
1915 else if ( sel > 1 ) /* 1% not $F2 or $F3 */
1916 spc_cpu_write_smp_reg_( a, rel_time, i );
1917 }
1918 }
1919 goto loop;
1920
1921 #define CASE( n ) case n:
1922
1923 /* Define common address modes based on opcode for immediate mode. Execution
1924 ends with data set to the address of the operand. */
1925 #define ADDR_MODES_( op )\
1926 CASE( op - 0x02 ) /* (X) */\
1927 data = x + dp;\
1928 pc--;\
1929 goto end_##op;\
1930 CASE( op + 0x0F ) /* (dp)+Y */\
1931 data = READ_PROG16( data + dp ) + y;\
1932 goto end_##op;\
1933 CASE( op - 0x01 ) /* (dp+X) */\
1934 data = READ_PROG16( ((uint8_t) (data + x)) + dp );\
1935 goto end_##op;\
1936 CASE( op + 0x0E ) /* abs+Y */\
1937 data += y;\
1938 goto abs_##op;\
1939 CASE( op + 0x0D ) /* abs+X */\
1940 data += x;\
1941 CASE( op - 0x03 ) /* abs */\
1942 abs_##op:\
1943 data += 0x100 * READ_PC( ++pc );\
1944 goto end_##op;\
1945 CASE( op + 0x0C ) /* dp+X */\
1946 data = (uint8_t) (data + x);
1947
1948 #define ADDR_MODES_NO_DP( op )\
1949 ADDR_MODES_( op )\
1950 data += dp;\
1951 end_##op:
1952
1953 #define ADDR_MODES( op )\
1954 ADDR_MODES_( op )\
1955 CASE( op - 0x04 ) /* dp */\
1956 data += dp;\
1957 end_##op:
1958
1959 /* 1. 8-bit Data Transmission Commands. Group I */
1960
1961 ADDR_MODES_NO_DP( 0xE8 ) /* MOV A,addr */
1962 a = nz = SPC_CPU_READ( 0, data );
1963 goto inc_pc_loop;
1964
1965 case 0xBF:
1966 {
1967 /* MOV A,(X)+ */
1968 int temp = x + dp;
1969 x = (uint8_t) (x + 1);
1970 a = nz = SPC_CPU_READ( -1, temp );
1971 goto loop;
1972 }
1973
1974 case 0xE8: /* MOV A,imm */
1975 a = data;
1976 nz = data;
1977 goto inc_pc_loop;
1978
1979 case 0xF9: /* MOV X,dp+Y */
1980 data = (uint8_t) (data + y);
1981 case 0xF8: /* MOV X,dp */
1982 READ_DP_TIMER( 0, data, x = nz );
1983 goto inc_pc_loop;
1984
1985 case 0xE9: /* MOV X,abs */
1986 data = GET_LE16( pc );
1987 ++pc;
1988 data = SPC_CPU_READ( 0, data );
1989 case 0xCD: /* MOV X,imm */
1990 x = data;
1991 nz = data;
1992 goto inc_pc_loop;
1993
1994 case 0xFB: /* MOV Y,dp+X */
1995 data = (uint8_t) (data + x);
1996 case 0xEB: /* MOV Y,dp */
1997 /* 70% from timer */
1998 pc++;
1999 READ_DP_TIMER( 0, data, y = nz );
2000 goto loop;
2001
2002 case 0xEC:
2003 { /* MOV Y,abs */
2004 int temp = GET_LE16( pc );
2005 pc += 2;
2006 READ_TIMER( 0, temp, y = nz );
2007 /* y = nz = SPC_CPU_READ( 0, temp ); */
2008 goto loop;
2009 }
2010
2011 case 0x8D: /* MOV Y,imm */
2012 y = data;
2013 nz = data;
2014 goto inc_pc_loop;
2015
2016 /* 2. 8-BIT DATA TRANSMISSION COMMANDS, GROUP 2 */
2017
2018 ADDR_MODES_NO_DP( 0xC8 ) /* MOV addr,A */
2019 SPC_CPU_WRITE( 0, data, a );
2020 goto inc_pc_loop;
2021
2022 {
2023 int temp;
2024 case 0xCC: /* MOV abs,Y */
2025 temp = y;
2026 goto mov_abs_temp;
2027 case 0xC9: /* MOV abs,X */
2028 temp = x;
2029 mov_abs_temp:
2030 SPC_CPU_WRITE( 0, GET_LE16( pc ), temp );
2031 pc += 2;
2032 goto loop;
2033 }
2034
2035 case 0xD9: /* MOV dp+Y,X */
2036 data = (uint8_t) (data + y);
2037 case 0xD8: /* MOV dp,X */
2038 SPC_CPU_WRITE( 0, data + dp, x );
2039 goto inc_pc_loop;
2040
2041 case 0xDB: /* MOV dp+X,Y */
2042 data = (uint8_t) (data + x);
2043 case 0xCB: /* MOV dp,Y */
2044 SPC_CPU_WRITE( 0, data + dp, y );
2045 goto inc_pc_loop;
2046
2047 /* 3. 8-BIT DATA TRANSMISSION COMMANDS, GROUP 3. */
2048
2049 case 0x7D: /* MOV A,X */
2050 a = x;
2051 nz = x;
2052 goto loop;
2053
2054 case 0xDD: /* MOV A,Y */
2055 a = y;
2056 nz = y;
2057 goto loop;
2058
2059 case 0x5D: /* MOV X,A */
2060 x = a;
2061 nz = a;
2062 goto loop;
2063
2064 case 0xFD: /* MOV Y,A */
2065 y = a;
2066 nz = a;
2067 goto loop;
2068
2069 case 0x9D: /* MOV X,SP */
2070 x = nz = GET_SP();
2071 goto loop;
2072
2073 case 0xBD: /* MOV SP,X */
2074 SET_SP( x );
2075 goto loop;
2076
2077 /* case 0xC6: // MOV (X),A (handled by MOV addr,A in group 2) */
2078
2079 case 0xAF: /* MOV (X)+,A */
2080 WRITE_DP( 0, x, a + NO_READ_BEFORE_WRITE );
2081 x++;
2082 goto loop;
2083
2084 /* 5. 8-BIT LOGIC OPERATION COMMANDS */
2085
2086 #define LOGICAL_OP( op, func )\
2087 ADDR_MODES( op ) /* addr */\
2088 data = SPC_CPU_READ( 0, data );\
2089 case op: /* imm */\
2090 nz = a func##= data;\
2091 goto inc_pc_loop;\
2092 { unsigned addr;\
2093 case op + 0x11: /* X,Y */\
2094 data = READ_DP( -2, y );\
2095 addr = x + dp;\
2096 goto addr_##op;\
2097 case op + 0x01: /* dp,dp */\
2098 data = READ_DP( -3, data );\
2099 case op + 0x10:{/*dp,imm*/\
2100 uint8_t const* addr2 = pc + 1;\
2101 pc += 2;\
2102 addr = READ_PC( addr2 ) + dp;\
2103 }\
2104 addr_##op:\
2105 nz = data func SPC_CPU_READ( -1, addr );\
2106 SPC_CPU_WRITE( 0, addr, nz );\
2107 goto loop;\
2108 }
2109
2110 LOGICAL_OP( 0x28, & ); /* AND */
2111
2112 LOGICAL_OP( 0x08, | ); /* OR */
2113
2114 LOGICAL_OP( 0x48, ^ ); /* EOR */
2115
2116 /* 4. 8-BIT ARITHMETIC OPERATION COMMANDS */
2117
2118 ADDR_MODES( 0x68 ) /* CMP addr */
2119 data = SPC_CPU_READ( 0, data );
2120 case 0x68: /* CMP imm */
2121 nz = a - data;
2122 c = ~nz;
2123 nz &= 0xFF;
2124 goto inc_pc_loop;
2125
2126 case 0x79: /* CMP (X),(Y) */
2127 data = READ_DP( -2, y );
2128 nz = READ_DP( -1, x ) - data;
2129 c = ~nz;
2130 nz &= 0xFF;
2131 goto loop;
2132
2133 case 0x69: /* CMP dp,dp */
2134 data = READ_DP( -3, data );
2135 case 0x78: /* CMP dp,imm */
2136 nz = READ_DP( -1, READ_PC( ++pc ) ) - data;
2137 c = ~nz;
2138 nz &= 0xFF;
2139 goto inc_pc_loop;
2140
2141 case 0x3E: /* CMP X,dp */
2142 data += dp;
2143 goto cmp_x_addr;
2144 case 0x1E: /* CMP X,abs */
2145 data = GET_LE16( pc );
2146 pc++;
2147 cmp_x_addr:
2148 data = SPC_CPU_READ( 0, data );
2149 case 0xC8: /* CMP X,imm */
2150 nz = x - data;
2151 c = ~nz;
2152 nz &= 0xFF;
2153 goto inc_pc_loop;
2154
2155 case 0x7E: /* CMP Y,dp */
2156 data += dp;
2157 goto cmp_y_addr;
2158 case 0x5E: /* CMP Y,abs */
2159 data = GET_LE16( pc );
2160 pc++;
2161 cmp_y_addr:
2162 data = SPC_CPU_READ( 0, data );
2163 case 0xAD: /* CMP Y,imm */
2164 nz = y - data;
2165 c = ~nz;
2166 nz &= 0xFF;
2167 goto inc_pc_loop;
2168
2169 {
2170 int addr;
2171 case 0xB9: /* SBC (x),(y) */
2172 case 0x99: /* ADC (x),(y) */
2173 pc--; /* compensate for inc later */
2174 data = READ_DP( -2, y );
2175 addr = x + dp;
2176 goto adc_addr;
2177 case 0xA9: /* SBC dp,dp */
2178 case 0x89: /* ADC dp,dp */
2179 data = READ_DP( -3, data );
2180 case 0xB8: /* SBC dp,imm */
2181 case 0x98: /* ADC dp,imm */
2182 addr = READ_PC( ++pc ) + dp;
2183 adc_addr:
2184 nz = SPC_CPU_READ( -1, addr );
2185 goto adc_data;
2186
2187 /* catch ADC and SBC together, then decode later based on operand */
2188 #undef CASE
2189 #define CASE( n ) case n: case (n) + 0x20:
2190 ADDR_MODES( 0x88 ) /* ADC/SBC addr */
2191 data = SPC_CPU_READ( 0, data );
2192 case 0xA8: /* SBC imm */
2193 case 0x88: /* ADC imm */
2194 addr = -1; /* A */
2195 nz = a;
2196 adc_data: {
2197 int flags;
2198 if ( opcode >= 0xA0 ) /* SBC */
2199 data ^= 0xFF;
2200
2201 flags = data ^ nz;
2202 nz += data + (c >> 8 & 1);
2203 flags ^= nz;
2204
2205 psw = (psw & ~(V40 | H08)) |
2206 (flags >> 1 & H08) |
2207 ((flags + 0x80) >> 2 & V40);
2208 c = nz;
2209 if ( addr < 0 )
2210 {
2211 a = (uint8_t) nz;
2212 goto inc_pc_loop;
2213 }
2214 SPC_CPU_WRITE( 0, addr, /*(uint8_t)*/ nz );
2215 goto inc_pc_loop;
2216 }
2217
2218 }
2219
2220 /* 6. ADDITION & SUBTRACTION COMMANDS */
2221
2222 #define INC_DEC_REG( reg, op )\
2223 nz = reg op;\
2224 reg = (uint8_t) nz;\
2225 goto loop;
2226
2227 case 0xBC: INC_DEC_REG( a, + 1 ) /* INC A */
2228 case 0x3D: INC_DEC_REG( x, + 1 ) /* INC X */
2229 case 0xFC: INC_DEC_REG( y, + 1 ) /* INC Y */
2230
2231 case 0x9C: INC_DEC_REG( a, - 1 ) /* DEC A */
2232 case 0x1D: INC_DEC_REG( x, - 1 ) /* DEC X */
2233 case 0xDC: INC_DEC_REG( y, - 1 ) /* DEC Y */
2234
2235 case 0x9B: /* DEC dp+X */
2236 case 0xBB: /* INC dp+X */
2237 data = (uint8_t) (data + x);
2238 case 0x8B: /* DEC dp */
2239 case 0xAB: /* INC dp */
2240 data += dp;
2241 goto inc_abs;
2242 case 0x8C: /* DEC abs */
2243 case 0xAC: /* INC abs */
2244 data = GET_LE16( pc );
2245 pc++;
2246 inc_abs:
2247 nz = (opcode >> 4 & 2) - 1;
2248 nz += SPC_CPU_READ( -1, data );
2249 SPC_CPU_WRITE( 0, data, /*(uint8_t)*/ nz );
2250 goto inc_pc_loop;
2251
2252 /* 7. SHIFT, ROTATION COMMANDS */
2253
2254 case 0x5C: /* LSR A */
2255 c = 0;
2256 case 0x7C: /* ROR A */
2257 {
2258 nz = (c >> 1 & 0x80) | (a >> 1);
2259 c = a << 8;
2260 a = nz;
2261 goto loop;
2262 }
2263
2264 case 0x1C: /* ASL A */
2265 c = 0;
2266 case 0x3C:
2267 {/* ROL A */
2268 int temp = c >> 8 & 1;
2269 c = a << 1;
2270 nz = c | temp;
2271 a = (uint8_t) nz;
2272 goto loop;
2273 }
2274
2275 case 0x0B: /* ASL dp */
2276 c = 0;
2277 data += dp;
2278 goto rol_mem;
2279 case 0x1B: /* ASL dp+X */
2280 c = 0;
2281 case 0x3B: /* ROL dp+X */
2282 data = (uint8_t) (data + x);
2283 case 0x2B: /* ROL dp */
2284 data += dp;
2285 goto rol_mem;
2286 case 0x0C: /* ASL abs */
2287 c = 0;
2288 case 0x2C: /* ROL abs */
2289 data = GET_LE16( pc );
2290 pc++;
2291 rol_mem:
2292 nz = c >> 8 & 1;
2293 nz |= (c = SPC_CPU_READ( -1, data ) << 1);
2294 SPC_CPU_WRITE( 0, data, /*(uint8_t)*/ nz );
2295 goto inc_pc_loop;
2296
2297 case 0x4B: /* LSR dp */
2298 c = 0;
2299 data += dp;
2300 goto ror_mem;
2301 case 0x5B: /* LSR dp+X */
2302 c = 0;
2303 case 0x7B: /* ROR dp+X */
2304 data = (uint8_t) (data + x);
2305 case 0x6B: /* ROR dp */
2306 data += dp;
2307 goto ror_mem;
2308 case 0x4C: /* LSR abs */
2309 c = 0;
2310 case 0x6C: /* ROR abs */
2311 data = GET_LE16( pc );
2312 pc++;
2313 ror_mem: {
2314 int temp = SPC_CPU_READ( -1, data );
2315 nz = (c >> 1 & 0x80) | (temp >> 1);
2316 c = temp << 8;
2317 SPC_CPU_WRITE( 0, data, nz );
2318 goto inc_pc_loop;
2319 }
2320
2321 case 0x9F: /* XCN */
2322 nz = a = (a >> 4) | (uint8_t) (a << 4);
2323 goto loop;
2324
2325 /* 8. 16-BIT TRANSMISION COMMANDS */
2326
2327 case 0xBA: /* MOVW YA,dp */
2328 a = READ_DP( -2, data );
2329 nz = (a & 0x7F) | (a >> 1);
2330 y = READ_DP( 0, (uint8_t) (data + 1) );
2331 nz |= y;
2332 goto inc_pc_loop;
2333
2334 case 0xDA: /* MOVW dp,YA */
2335 WRITE_DP( -1, data, a );
2336 WRITE_DP( 0, (uint8_t) (data + 1), y + NO_READ_BEFORE_WRITE );
2337 goto inc_pc_loop;
2338
2339 /* 9. 16-BIT OPERATION COMMANDS */
2340
2341 case 0x3A: /* INCW dp */
2342 case 0x1A:{/* DECW dp */
2343 int temp;
2344 /* low byte */
2345 data += dp;
2346 temp = SPC_CPU_READ( -3, data );
2347 temp += (opcode >> 4 & 2) - 1; /* +1 for INCW, -1 for DECW */
2348 nz = ((temp >> 1) | temp) & 0x7F;
2349 SPC_CPU_WRITE( -2, data, /*(uint8_t)*/ temp );
2350
2351 /* high byte */
2352 data = (uint8_t) (data + 1) + dp;
2353 temp = (uint8_t) ((temp >> 8) + SPC_CPU_READ( -1, data ));
2354 nz |= temp;
2355 SPC_CPU_WRITE( 0, data, temp );
2356
2357 goto inc_pc_loop;
2358 }
2359
2360 case 0x7A: /* ADDW YA,dp */
2361 case 0x9A:
2362 {/* SUBW YA,dp */
2363 int result, flags;
2364 int lo = READ_DP( -2, data );
2365 int hi = READ_DP( 0, (uint8_t) (data + 1) );
2366
2367 if ( opcode == 0x9A ) /* SUBW */
2368 {
2369 lo = (lo ^ 0xFF) + 1;
2370 hi ^= 0xFF;
2371 }
2372
2373 lo += a;
2374 result = y + hi + (lo >> 8);
2375 flags = hi ^ y ^ result;
2376
2377 psw = (psw & ~(V40 | H08)) |
2378 (flags >> 1 & H08) |
2379 ((flags + 0x80) >> 2 & V40);
2380 c = result;
2381 a = (uint8_t) lo;
2382 result = (uint8_t) result;
2383 y = result;
2384 nz = (((lo >> 1) | lo) & 0x7F) | result;
2385
2386 goto inc_pc_loop;
2387 }
2388
2389 case 0x5A:
2390 { /* CMPW YA,dp */
2391 int temp;
2392 temp = a - READ_DP( -1, data );
2393 nz = ((temp >> 1) | temp) & 0x7F;
2394 temp = y + (temp >> 8);
2395 temp -= READ_DP( 0, (uint8_t) (data + 1) );
2396 nz |= temp;
2397 c = ~temp;
2398 nz &= 0xFF;
2399 goto inc_pc_loop;
2400 }
2401
2402 /* 10. MULTIPLICATION & DIVISON COMMANDS */
2403
2404 case 0xCF: { /* MUL YA */
2405 unsigned temp = y * a;
2406 a = (uint8_t) temp;
2407 nz = ((temp >> 1) | temp) & 0x7F;
2408 y = temp >> 8;
2409 nz |= y;
2410 goto loop;
2411 }
2412
2413 case 0x9E: /* DIV YA,X */
2414 {
2415 unsigned ya = y * 0x100 + a;
2416
2417 psw &= ~(H08 | V40);
2418
2419 if ( y >= x )
2420 psw |= V40;
2421
2422 if ( (y & 15) >= (x & 15) )
2423 psw |= H08;
2424
2425 if ( y < x * 2 )
2426 {
2427 a = ya / x;
2428 y = ya - a * x;
2429 }
2430 else
2431 {
2432 a = 255 - (ya - x * 0x200) / (256 - x);
2433 y = x + (ya - x * 0x200) % (256 - x);
2434 }
2435
2436 nz = (uint8_t) a;
2437 a = (uint8_t) a;
2438
2439 goto loop;
2440 }
2441
2442 /* 11. DECIMAL COMPENSATION COMMANDS */
2443
2444 case 0xDF: /* DAA */
2445 if ( a > 0x99 || c & 0x100 )
2446 {
2447 a += 0x60;
2448 c = 0x100;
2449 }
2450
2451 if ( (a & 0x0F) > 9 || psw & H08 )
2452 a += 0x06;
2453
2454 nz = a;
2455 a = (uint8_t) a;
2456 goto loop;
2457
2458 case 0xBE: /* DAS */
2459 if ( a > 0x99 || !(c & 0x100) )
2460 {
2461 a -= 0x60;
2462 c = 0;
2463 }
2464
2465 if ( (a & 0x0F) > 9 || !(psw & H08) )
2466 a -= 0x06;
2467
2468 nz = a;
2469 a = (uint8_t) a;
2470 goto loop;
2471
2472 /* 12. BRANCHING COMMANDS */
2473
2474 case 0x2F: /* BRA rel */
2475 pc += (int8_t) data;
2476 goto inc_pc_loop;
2477
2478 case 0x30: /* BMI */
2479 BRANCH( (nz & NZ_NEG_MASK) )
2480
2481 case 0x10: /* BPL */
2482 BRANCH( !(nz & NZ_NEG_MASK) )
2483
2484 case 0xB0: /* BCS */
2485 BRANCH( c & 0x100 )
2486
2487 case 0x90: /* BCC */
2488 BRANCH( !(c & 0x100) )
2489
2490 case 0x70: /* BVS */
2491 BRANCH( psw & V40 )
2492
2493 case 0x50: /* BVC */
2494 BRANCH( !(psw & V40) )
2495
2496 #define CBRANCH( cond )\
2497 {\
2498 pc++;\
2499 if ( cond )\
2500 goto cbranch_taken_loop;\
2501 rel_time -= 2;\
2502 goto inc_pc_loop;\
2503 }
2504
2505 case 0x03: /* BBS dp.bit,rel */
2506 case 0x23:
2507 case 0x43:
2508 case 0x63:
2509 case 0x83:
2510 case 0xA3:
2511 case 0xC3:
2512 case 0xE3:
2513 CBRANCH( READ_DP( -4, data ) >> (opcode >> 5) & 1 )
2514
2515 case 0x13: /* BBC dp.bit,rel */
2516 case 0x33:
2517 case 0x53:
2518 case 0x73:
2519 case 0x93:
2520 case 0xB3:
2521 case 0xD3:
2522 case 0xF3:
2523 CBRANCH( !(READ_DP( -4, data ) >> (opcode >> 5) & 1) )
2524
2525 case 0xDE: /* CBNE dp+X,rel */
2526 data = (uint8_t) (data + x);
2527 /* fall through */
2528 case 0x2E:{ /* CBNE dp,rel */
2529 int temp;
2530 /* 61% from timer */
2531 READ_DP_TIMER( -4, data, temp );
2532 CBRANCH( temp != a )
2533 }
2534
2535 case 0x6E: { /* DBNZ dp,rel */
2536 unsigned temp = READ_DP( -4, data ) - 1;
2537 WRITE_DP( -3, (uint8_t) data, /*(uint8_t)*/ temp + NO_READ_BEFORE_WRITE );
2538 CBRANCH( temp )
2539 }
2540
2541 case 0xFE: /* DBNZ Y,rel */
2542 y = (uint8_t) (y - 1);
2543 BRANCH( y )
2544
2545 case 0x1F: /* JMP [abs+X] */
2546 SET_PC( GET_LE16( pc ) + x );
2547 /* fall through */
2548 case 0x5F: /* JMP abs */
2549 SET_PC( GET_LE16( pc ) );
2550 goto loop;
2551
2552 /* 13. SUB-ROUTINE CALL RETURN COMMANDS */
2553
2554 case 0x0F:{/* BRK */
2555 int temp;
2556 int ret_addr = GET_PC();
2557 SET_PC( READ_PROG16( 0xFFDE ) ); /* vector address verified */
2558 PUSH16( ret_addr );
2559 GET_PSW( temp );
2560 psw = (psw | B10) & ~I04;
2561 PUSH( temp );
2562 goto loop;
2563 }
2564
2565 case 0x4F:{/* PCALL offset */
2566 int ret_addr = GET_PC() + 1;
2567 SET_PC( 0xFF00 | data );
2568 PUSH16( ret_addr );
2569 goto loop;
2570 }
2571
2572 case 0x01: /* TCALL n */
2573 case 0x11:
2574 case 0x21:
2575 case 0x31:
2576 case 0x41:
2577 case 0x51:
2578 case 0x61:
2579 case 0x71:
2580 case 0x81:
2581 case 0x91:
2582 case 0xA1:
2583 case 0xB1:
2584 case 0xC1:
2585 case 0xD1:
2586 case 0xE1:
2587 case 0xF1: {
2588 int ret_addr = GET_PC();
2589 SET_PC( READ_PROG16( 0xFFDE - (opcode >> 3) ) );
2590 PUSH16( ret_addr );
2591 goto loop;
2592 }
2593
2594 /* 14. STACK OPERATION COMMANDS */
2595
2596 {
2597 int temp;
2598 case 0x7F: /* RET1 */
2599 temp = *sp;
2600 SET_PC( GET_LE16( sp + 1 ) );
2601 sp += 3;
2602 goto set_psw;
2603 case 0x8E: /* POP PSW */
2604 POP( temp );
2605 set_psw:
2606 SET_PSW( temp );
2607 goto loop;
2608 }
2609
2610 case 0x0D: { /* PUSH PSW */
2611 int temp;
2612 GET_PSW( temp );
2613 PUSH( temp );
2614 goto loop;
2615 }
2616
2617 case 0x2D: /* PUSH A */
2618 PUSH( a );
2619 goto loop;
2620
2621 case 0x4D: /* PUSH X */
2622 PUSH( x );
2623 goto loop;
2624
2625 case 0x6D: /* PUSH Y */
2626 PUSH( y );
2627 goto loop;
2628
2629 case 0xAE: /* POP A */
2630 POP( a );
2631 goto loop;
2632
2633 case 0xCE: /* POP X */
2634 POP( x );
2635 goto loop;
2636
2637 case 0xEE: /* POP Y */
2638 POP( y );
2639 goto loop;
2640
2641 /* 15. BIT OPERATION COMMANDS */
2642
2643 case 0x02: /* SET1 */
2644 case 0x22:
2645 case 0x42:
2646 case 0x62:
2647 case 0x82:
2648 case 0xA2:
2649 case 0xC2:
2650 case 0xE2:
2651 case 0x12: /* CLR1 */
2652 case 0x32:
2653 case 0x52:
2654 case 0x72:
2655 case 0x92:
2656 case 0xB2:
2657 case 0xD2:
2658 case 0xF2:
2659 {
2660 int bit = 1 << (opcode >> 5);
2661 int mask = ~bit;
2662 if ( opcode & 0x10 )
2663 bit = 0;
2664 data += dp;
2665 SPC_CPU_WRITE( 0, data, (SPC_CPU_READ( -1, data ) & mask) | bit );
2666 goto inc_pc_loop;
2667 }
2668
2669 case 0x0E: /* TSET1 abs */
2670 case 0x4E: /* TCLR1 abs */
2671 data = GET_LE16( pc );
2672 pc += 2;
2673 {
2674 unsigned temp = SPC_CPU_READ( -2, data );
2675 nz = (uint8_t) (a - temp);
2676 temp &= ~a;
2677 if ( opcode == 0x0E )
2678 temp |= a;
2679 SPC_CPU_WRITE( 0, data, temp );
2680 }
2681 goto loop;
2682
2683 case 0x4A: /* AND1 C,mem.bit */
2684 spc_CPU_mem_bit(pc, rel_time, tmp_spc_cpu_mem_bit);
2685 c &= tmp_spc_cpu_mem_bit;
2686 pc += 2;
2687 goto loop;
2688
2689 case 0x6A: /* AND1 C,/mem.bit */
2690 spc_CPU_mem_bit(pc, rel_time, tmp_spc_cpu_mem_bit);
2691 c &= ~tmp_spc_cpu_mem_bit;
2692 pc += 2;
2693 goto loop;
2694
2695 case 0x0A: /* OR1 C,mem.bit */
2696 spc_CPU_mem_bit(pc, rel_time - 1, tmp_spc_cpu_mem_bit);
2697 c |= tmp_spc_cpu_mem_bit;
2698 pc += 2;
2699 goto loop;
2700
2701 case 0x2A: /* OR1 C,/mem.bit */
2702 spc_CPU_mem_bit(pc, rel_time - 1, tmp_spc_cpu_mem_bit);
2703 c |= ~tmp_spc_cpu_mem_bit;
2704 pc += 2;
2705 goto loop;
2706
2707 case 0x8A: /* EOR1 C,mem.bit */
2708 spc_CPU_mem_bit(pc, rel_time - 1, tmp_spc_cpu_mem_bit);
2709 c ^= tmp_spc_cpu_mem_bit;
2710 pc += 2;
2711 goto loop;
2712
2713 case 0xEA: /* NOT1 mem.bit */
2714 data = GET_LE16( pc );
2715 pc += 2;
2716 {
2717 unsigned temp = SPC_CPU_READ( -1, data & 0x1FFF );
2718 temp ^= 1 << (data >> 13);
2719 SPC_CPU_WRITE( 0, data & 0x1FFF, temp );
2720 }
2721 goto loop;
2722
2723 case 0xCA: /* MOV1 mem.bit,C */
2724 data = GET_LE16( pc );
2725 pc += 2;
2726 {
2727 unsigned temp, bit;
2728 temp = SPC_CPU_READ( -2, data & 0x1FFF );
2729 bit = data >> 13;
2730 temp = (temp & ~(1 << bit)) | ((c >> 8 & 1) << bit);
2731 SPC_CPU_WRITE( 0, data & 0x1FFF, temp + NO_READ_BEFORE_WRITE );
2732 }
2733 goto loop;
2734
2735 case 0xAA: /* MOV1 C,mem.bit */
2736 spc_CPU_mem_bit(pc, rel_time, tmp_spc_cpu_mem_bit);
2737 c = tmp_spc_cpu_mem_bit;
2738 pc += 2;
2739 goto loop;
2740
2741 /* 16. PROGRAM PSW FLAG OPERATION COMMANDS */
2742
2743 case 0x60: /* CLRC */
2744 c = 0;
2745 goto loop;
2746
2747 case 0x80: /* SETC */
2748 c = ~0;
2749 goto loop;
2750
2751 case 0xED: /* NOTC */
2752 c ^= 0x100;
2753 goto loop;
2754
2755 case 0xE0: /* CLRV */
2756 psw &= ~(V40 | H08);
2757 goto loop;
2758
2759 case 0x20: /* CLRP */
2760 dp = 0;
2761 goto loop;
2762
2763 case 0x40: /* SETP */
2764 dp = 0x100;
2765 goto loop;
2766
2767 case 0xA0: /* EI */
2768 psw |= I04;
2769 goto loop;
2770
2771 case 0xC0: /* DI */
2772 psw &= ~I04;
2773 goto loop;
2774
2775 /* 17. OTHER COMMANDS */
2776
2777 case 0x00: /* NOP */
2778 goto loop;
2779
2780 case 0xFF:
2781 { /* STOP */
2782 /* handle PC wrap-around */
2783 unsigned addr = GET_PC() - 1;
2784 if ( addr >= 0x10000 )
2785 {
2786 addr &= 0xFFFF;
2787 SET_PC( addr );
2788 /* dprintf( "SPC: PC wrapped around\n" ); */
2789 goto loop;
2790 }
2791 }
2792 /* fall through */
2793 case 0xEF: /* SLEEP */
2794 --pc;
2795 rel_time = 0;
2796 goto stop;
2797 } /* switch */
2798 }
2799 out_of_time:
2800 rel_time -= m.cycle_table [*pc]; /* undo partial execution of opcode */
2801 stop:
2802
2803 /* Uncache registers */
2804 #if 0
2805 if ( GET_PC() >= 0x10000 )
2806 dprintf( "SPC: PC wrapped around\n" );
2807 #endif
2808 m.cpu_regs.pc = (uint16_t) GET_PC();
2809 m.cpu_regs.sp = ( uint8_t) GET_SP();
2810 m.cpu_regs.a = ( uint8_t) a;
2811 m.cpu_regs.x = ( uint8_t) x;
2812 m.cpu_regs.y = ( uint8_t) y;
2813 {
2814 int temp;
2815 GET_PSW( temp );
2816 m.cpu_regs.psw = (uint8_t) temp;
2817 }
2818 m.spc_time += rel_time;
2819 m.dsp_time -= rel_time;
2820 m.timers [0].next_time -= rel_time;
2821 m.timers [1].next_time -= rel_time;
2822 m.timers [2].next_time -= rel_time;
2823 return &m.smp_regs[0][R_CPUIO0];
2824 }
2825
2826 /* Runs SPC to end_time and starts a new time frame at 0 */
2827
spc_end_frame(int end_time)2828 static void spc_end_frame( int end_time )
2829 {
2830 int i;
2831 /* Catch CPU up to as close to end as possible. If final instruction
2832 would exceed end, does NOT execute it and leaves m.spc_time < end. */
2833
2834 if ( end_time > m.spc_time )
2835 spc_run_until_( end_time );
2836
2837 m.spc_time -= end_time;
2838 m.extra_clocks += end_time;
2839
2840 /* Catch timers up to CPU */
2841 for ( i = 0; i < TIMER_COUNT; i++ )
2842 {
2843 if ( 0 >= m.timers[i].next_time )
2844 spc_run_timer_( &m.timers [i], 0 );
2845 }
2846
2847 /* Catch DSP up to CPU */
2848 if ( m.dsp_time < 0 )
2849 {
2850 RUN_DSP( 0, MAX_REG_TIME );
2851 }
2852
2853 /* Save any extra samples beyond what should be generated */
2854 if ( m.buf_begin )
2855 {
2856 short *main_end, *dsp_end, *out, *in;
2857 /* Get end pointers */
2858 main_end = m.buf_end; /* end of data written to buf */
2859 dsp_end = dsp_m.out; /* end of data written to dsp.extra() */
2860 if ( m.buf_begin <= dsp_end && dsp_end <= main_end )
2861 {
2862 main_end = dsp_end;
2863 dsp_end = dsp_m.extra; /* nothing in DSP's extra */
2864 }
2865
2866 /* Copy any extra samples at these ends into extra_buf */
2867 out = m.extra_buf;
2868 for ( in = m.buf_begin + SPC_SAMPLE_COUNT(); in < main_end; in++ )
2869 *out++ = *in;
2870 for ( in = dsp_m.extra; in < dsp_end ; in++ )
2871 *out++ = *in;
2872
2873 m.extra_pos = out;
2874 }
2875 }
2876
2877 /* Support SNES_MEMORY_APURAM */
2878
spc_apuram()2879 uint8_t * spc_apuram()
2880 {
2881 return m.ram.ram;
2882 }
2883
2884 /* Init */
2885
spc_reset_buffer(void)2886 static void spc_reset_buffer(void)
2887 {
2888 short *out;
2889 /* Start with half extra buffer of silence */
2890 out = m.extra_buf;
2891 while ( out < &m.extra_buf [EXTRA_SIZE_DIV_2] )
2892 *out++ = 0;
2893 m.extra_pos = out;
2894 m.buf_begin = 0;
2895 dsp_set_output( 0, 0 );
2896 }
2897
2898 /* Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc. */
2899
spc_set_tempo(int t)2900 static void spc_set_tempo( int t )
2901 {
2902 int timer2_shift, other_shift;
2903 m.tempo = t;
2904 timer2_shift = 4; /* 64 kHz */
2905 other_shift = 3; /* 8 kHz */
2906
2907 m.timers [2].prescaler = timer2_shift;
2908 m.timers [1].prescaler = timer2_shift + other_shift;
2909 m.timers [0].prescaler = timer2_shift + other_shift;
2910 }
2911
spc_reset_common(int timer_counter_init)2912 static void spc_reset_common( int timer_counter_init )
2913 {
2914 int i;
2915 for ( i = 0; i < TIMER_COUNT; i++ )
2916 m.smp_regs[1][R_T0OUT + i] = timer_counter_init;
2917
2918 /* Run IPL ROM */
2919 memset( &m.cpu_regs, 0, sizeof(m.cpu_regs));
2920 m.cpu_regs.pc = ROM_ADDR;
2921
2922 m.smp_regs[0][R_TEST ] = 0x0A;
2923 m.smp_regs[0][R_CONTROL] = 0xB0; /* ROM enabled, clear ports */
2924 for ( i = 0; i < PORT_COUNT; i++ )
2925 m.smp_regs[1][R_CPUIO0 + i] = 0;
2926
2927 /* reset time registers */
2928 m.spc_time = 0;
2929 m.dsp_time = 0;
2930 m.dsp_time = CLOCKS_PER_SAMPLE + 1;
2931
2932 for ( i = 0; i < TIMER_COUNT; i++ )
2933 {
2934 Timer* t = &m.timers [i];
2935 t->next_time = 1;
2936 t->divider = 0;
2937 }
2938
2939 /* Registers were just loaded. Applies these new values. */
2940 spc_enable_rom( m.smp_regs[0][R_CONTROL] & 0x80 );
2941
2942 /* Timer registers have been loaded. Applies these to the timers. Does not
2943 reset timer prescalers or dividers. */
2944 for ( i = 0; i < TIMER_COUNT; i++ )
2945 {
2946 Timer* t = &m.timers [i];
2947 t->period = IF_0_THEN_256( m.smp_regs[0][R_T0TARGET + i] );
2948 t->enabled = m.smp_regs[0][R_CONTROL] >> i & 1;
2949 t->counter = m.smp_regs[1][R_T0OUT + i] & 0x0F;
2950 }
2951
2952 spc_set_tempo( m.tempo );
2953
2954 m.extra_clocks = 0;
2955 spc_reset_buffer();
2956 }
2957
2958 /* Resets SPC to power-on state. This resets your output buffer, so you must
2959 call set_output() after this. */
2960
spc_reset(void)2961 static void spc_reset (void)
2962 {
2963 m.cpu_regs.pc = 0xFFC0;
2964 m.cpu_regs.a = 0x00;
2965 m.cpu_regs.x = 0x00;
2966 m.cpu_regs.y = 0x00;
2967 m.cpu_regs.psw = 0x02;
2968 m.cpu_regs.sp = 0xEF;
2969 memset( m.ram.ram, 0x00, 0x10000 );
2970
2971 /* RAM was just loaded from SPC, with $F0-$FF containing SMP registers
2972 and timer counts. Copies these to proper registers. */
2973 m.rom_enabled = dsp_m.rom_enabled = 0;
2974
2975 /* Loads registers from unified 16-byte format */
2976 memcpy( m.smp_regs[0], &m.ram.ram[0xF0], REG_COUNT );
2977 memcpy( m.smp_regs[1], m.smp_regs[0], REG_COUNT );
2978
2979 /* These always read back as 0 */
2980 m.smp_regs[1][R_TEST ] = 0;
2981 m.smp_regs[1][R_CONTROL ] = 0;
2982 m.smp_regs[1][R_T0TARGET] = 0;
2983 m.smp_regs[1][R_T1TARGET] = 0;
2984 m.smp_regs[1][R_T2TARGET] = 0;
2985
2986 /* Put STOP instruction around memory to catch PC underflow/overflow */
2987 memset( m.ram.padding1, CPU_PAD_FILL, sizeof m.ram.padding1 );
2988 memset( m.ram.padding2, CPU_PAD_FILL, sizeof m.ram.padding2 );
2989
2990 spc_reset_common( 0x0F );
2991 dsp_reset();
2992 }
2993
2994
2995 /* Emulates pressing reset switch on SNES. This resets your output buffer, so
2996 you must call set_output() after this. */
2997
spc_soft_reset(void)2998 static void spc_soft_reset (void)
2999 {
3000 spc_reset_common( 0 );
3001 dsp_soft_reset();
3002 }
3003
3004 #if !SPC_NO_COPY_STATE_FUNCS
spc_copy_state(unsigned char ** io,dsp_copy_func_t copy)3005 void NO_OPTIMIZE spc_copy_state( unsigned char** io, dsp_copy_func_t copy )
3006 {
3007 int i;
3008 spc_state_copy_t copier;
3009 copier.func = copy;
3010 copier.buf = io;
3011
3012 /* Make state data more readable by putting 64K RAM, 16 SMP registers,
3013 then DSP (with its 128 registers) first */
3014
3015 /* RAM */
3016 spc_enable_rom( 0 ); /* will get re-enabled if necessary in regs_loaded() below */
3017 spc_copier_copy(&copier, m.ram.ram, 0x10000 );
3018
3019 {
3020 /* SMP registers */
3021 uint8_t regs [REG_COUNT], regs_in [REG_COUNT];
3022
3023 memcpy( regs, m.smp_regs[0], REG_COUNT );
3024 memcpy( regs_in, m.smp_regs[1], REG_COUNT );
3025
3026 spc_copier_copy(&copier, regs, sizeof(regs));
3027 spc_copier_copy(&copier, regs_in, sizeof(regs_in));
3028
3029 memcpy( m.smp_regs[0], regs, REG_COUNT);
3030 memcpy( m.smp_regs[1], regs_in, REG_COUNT );
3031
3032 spc_enable_rom( m.smp_regs[0][R_CONTROL] & 0x80 );
3033 }
3034
3035 /* CPU registers */
3036 SPC_COPY( uint16_t, m.cpu_regs.pc );
3037 SPC_COPY( uint8_t, m.cpu_regs.a );
3038 SPC_COPY( uint8_t, m.cpu_regs.x );
3039 SPC_COPY( uint8_t, m.cpu_regs.y );
3040 SPC_COPY( uint8_t, m.cpu_regs.psw );
3041 SPC_COPY( uint8_t, m.cpu_regs.sp );
3042 spc_copier_extra(&copier);
3043
3044 SPC_COPY( int16_t, m.spc_time );
3045 SPC_COPY( int16_t, m.dsp_time );
3046
3047 /* DSP */
3048 dsp_copy_state( io, copy );
3049
3050 /* Timers */
3051 for ( i = 0; i < TIMER_COUNT; i++ )
3052 {
3053 Timer *t;
3054
3055 t = &m.timers [i];
3056 t->period = IF_0_THEN_256( m.smp_regs[0][R_T0TARGET + i] );
3057 t->enabled = m.smp_regs[0][R_CONTROL] >> i & 1;
3058 SPC_COPY( int16_t, t->next_time );
3059 SPC_COPY( uint8_t, t->divider );
3060 SPC_COPY( uint8_t, t->counter );
3061 spc_copier_extra(&copier);
3062 }
3063
3064 spc_set_tempo( m.tempo );
3065
3066 spc_copier_extra(&copier);
3067 }
3068 #endif
3069
3070
3071 /***********************************************************************************
3072 APU
3073 ***********************************************************************************/
3074
3075 #define APU_MINIMUM_SAMPLE_COUNT (512)
3076 #define APU_MINIMUM_BUFF_SIZE (APU_MINIMUM_SAMPLE_COUNT * 2 * 2)
3077 #define APU_MINIMUM_SAMPLE_BLOCK (128)
3078 #define APU_NUMERATOR_NTSC 15664
3079 #define APU_DENOMINATOR_NTSC 328125
3080 #define APU_NUMERATOR_PAL 34176
3081 #define APU_DENOMINATOR_PAL 709379
3082
3083 static apu_callback sa_callback = NULL;
3084
3085 static bool8 sound_in_sync = TRUE;
3086
3087 static int lag_master = 0;
3088 static int lag = 0;
3089
3090 static int16_t *landing_buffer = NULL;
3091 static size_t buffer_size = 0;
3092
3093 static bool8 resampler = FALSE;
3094
3095 static int32 reference_time;
3096 static uint32 spc_remainder;
3097
3098 static int timing_hack_denominator = TEMPO_UNIT;
3099 /* Set these to NTSC for now. Will change to PAL in S9xAPUTimingSetSpeedup
3100 if necessary on game load. */
3101 static uint32 ratio_numerator = APU_NUMERATOR_NTSC;
3102 static uint32 ratio_denominator = APU_DENOMINATOR_NTSC;
3103
3104 /***********************************************************************************
3105 RESAMPLER
3106 ************************************************************************************/
3107 static int rb_size;
3108 static int rb_buffer_size;
3109 static int rb_start;
3110 static unsigned char *rb_buffer;
3111 static uint32_t r_step;
3112 static uint32_t r_frac;
3113 static int r_left[4], r_right[4];
3114
3115 #define SPACE_EMPTY() (rb_buffer_size - rb_size)
3116 #define SPACE_FILLED() (rb_size)
3117 #define MAX_WRITE() (SPACE_EMPTY() >> 1)
3118
3119 #define RESAMPLER_MIN(a, b) ((a) < (b) ? (a) : (b))
3120 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
3121 #define SHORT_CLAMP(n) ((short) CLAMP((n), -32768, 32767))
3122
hermite(int32_t mu1,int32_t a,int32_t b,int32_t c,int32_t d)3123 static INLINE int32_t hermite (int32_t mu1, int32_t a, int32_t b, int32_t c, int32_t d)
3124 {
3125 int32_t mu2, mu3, m0, m1, a0, a1, a2, a3;
3126
3127 mu2 = ((mu1 * mu1) >> 15);
3128 mu3 = ((mu2 * mu1) >> 15);
3129
3130 m0 = (c - a) << 14;
3131 m1 = (d - b) << 14;
3132
3133 a0 = (((mu3 << 1) - (3 * mu2) + 32768) * b);
3134 a1 = ((mu3 - (mu2 << 1) + mu1) * m0) >> 15;
3135 a2 = ((mu3 - mu2) * m1) >> 15;
3136 a3 = ((3 * mu2 - (mu3 << 1)) * c);
3137
3138 return ((a0) + (a1) + (a2) + (a3)) >> 15;
3139 }
3140
resampler_clear(void)3141 static void resampler_clear(void)
3142 {
3143 rb_start = 0;
3144 rb_size = 0;
3145 memset (rb_buffer, 0, rb_buffer_size);
3146
3147 r_frac = 65536;
3148 r_left [0] = r_left [1] = r_left [2] = r_left [3] = 0;
3149 r_right[0] = r_right[1] = r_right[2] = r_right[3] = 0;
3150 }
3151
resampler_time_ratio(double ratio)3152 static void resampler_time_ratio(double ratio)
3153 {
3154 r_step = 65536 * ratio;
3155 resampler_clear();
3156 }
3157
resampler_read(short * data,int num_samples)3158 static void resampler_read(short *data, int num_samples)
3159 {
3160 int i_position, o_position, consumed;
3161 short *internal_buffer;
3162
3163 if (r_step == 65536)
3164 {
3165 //direct copy if we are not resampling
3166 int bytesUntilBufferEnd = rb_buffer_size - rb_start;
3167 while (num_samples > 0)
3168 {
3169 int bytesToConsume = num_samples * sizeof(short);
3170 if (bytesToConsume >= bytesUntilBufferEnd)
3171 bytesToConsume = bytesUntilBufferEnd;
3172 if (rb_start >= rb_buffer_size)
3173 rb_start = 0;
3174
3175 memcpy(data, &rb_buffer[rb_start], bytesToConsume);
3176 data += bytesToConsume / sizeof(short);
3177 rb_start += bytesToConsume;
3178 rb_size -= bytesToConsume;
3179 num_samples -= bytesToConsume / sizeof(short);
3180 if (rb_start >= rb_buffer_size)
3181 rb_start = 0;
3182 }
3183 return;
3184 }
3185
3186
3187 i_position = rb_start >> 1;
3188 internal_buffer = (short *)rb_buffer;
3189 o_position = 0;
3190 consumed = 0;
3191
3192 while (o_position < num_samples && consumed < rb_buffer_size)
3193 {
3194 int s_left = internal_buffer[i_position];
3195 int s_right = internal_buffer[i_position + 1];
3196 int max_samples = rb_buffer_size >> 1;
3197
3198 while (r_frac <= 65536 && o_position < num_samples)
3199 {
3200 int hermite_val = hermite(r_frac >> 1,
3201 r_left [0], r_left [1], r_left [2], r_left [3]);
3202 data[o_position] = SHORT_CLAMP (hermite_val);
3203 hermite_val = hermite(r_frac >> 1,
3204 r_right[0], r_right[1], r_right[2], r_right[3]);
3205 data[o_position + 1] = SHORT_CLAMP (hermite_val);
3206
3207 o_position += 2;
3208
3209 r_frac += r_step;
3210 }
3211
3212 if (r_frac > 65536)
3213 {
3214 r_left [0] = r_left [1];
3215 r_left [1] = r_left [2];
3216 r_left [2] = r_left [3];
3217 r_left [3] = s_left;
3218
3219 r_right[0] = r_right[1];
3220 r_right[1] = r_right[2];
3221 r_right[2] = r_right[3];
3222 r_right[3] = s_right;
3223
3224 r_frac -= 65536;
3225
3226 i_position += 2;
3227 if (i_position >= max_samples)
3228 i_position -= max_samples;
3229 consumed += 2;
3230 }
3231 }
3232
3233 rb_size -= consumed << 1;
3234 rb_start += consumed << 1;
3235 if (rb_start >= rb_buffer_size)
3236 rb_start -= rb_buffer_size;
3237 }
3238
resampler_new(void)3239 static uint_fast8_t resampler_new(void)
3240 {
3241 rb_buffer_size = buffer_size;
3242 rb_buffer = malloc(rb_buffer_size);
3243 if(rb_buffer == NULL)
3244 return 1;
3245
3246 resampler_clear();
3247 return 0;
3248 }
3249
resampler_push(short * src,int num_samples)3250 static INLINE bool8 resampler_push(short *src, int num_samples)
3251 {
3252 int bytes, end, first_write_size;
3253 unsigned char *src_ring;
3254
3255 bytes = num_samples << 1;
3256 if (MAX_WRITE() < num_samples || SPACE_EMPTY() < bytes)
3257 return FALSE;
3258
3259 /* Ring buffer push */
3260 src_ring = (unsigned char*)src;
3261 end = (rb_start + rb_size) % rb_buffer_size;
3262 first_write_size = RESAMPLER_MIN(bytes, rb_buffer_size - end);
3263
3264 memcpy (rb_buffer + end, src_ring, first_write_size);
3265
3266 if (bytes > first_write_size)
3267 memcpy (rb_buffer, src_ring + first_write_size, bytes - first_write_size);
3268
3269 rb_size += bytes;
3270
3271 return TRUE;
3272 }
3273
3274 /***********************************************************************************
3275 APU
3276 ***********************************************************************************/
3277
S9xMixSamples(short * buffer,unsigned sample_count)3278 bool8 S9xMixSamples (short *buffer, unsigned sample_count)
3279 {
3280 if (!Settings.Mute)
3281 {
3282 if (S9xGetSampleCount() >= (sample_count + lag))
3283 {
3284 resampler_read(buffer, sample_count);
3285 if (lag == lag_master)
3286 lag = 0;
3287 }
3288 else
3289 {
3290 memset(buffer, 0, sample_count << 1);
3291 if (lag == 0)
3292 lag = lag_master;
3293
3294 return (FALSE);
3295 }
3296 }
3297
3298 return (TRUE);
3299 }
3300
S9xGetSampleCount(void)3301 int S9xGetSampleCount (void)
3302 {
3303 if (r_step == 65536)
3304 {
3305 return rb_size / sizeof(short);
3306 }
3307 return (((((uint32_t)rb_size) << 14) - r_frac) / r_step * 2);
3308 }
3309
3310 /* Sets destination for output samples */
3311
spc_set_output(short * out,int size)3312 static void spc_set_output( short* out, int size )
3313 {
3314 short *out_end, *in;
3315
3316 out_end = out + size;
3317 m.buf_begin = out;
3318 m.buf_end = out_end;
3319
3320 /* Copy extra to output */
3321 in = m.extra_buf;
3322 while ( in < m.extra_pos && out < out_end )
3323 *out++ = *in++;
3324
3325 /* Handle output being full already */
3326 if ( out >= out_end )
3327 {
3328 /* Have DSP write to remaining extra space */
3329 out = dsp_m.extra;
3330 out_end = &dsp_m.extra[EXTRA_SIZE];
3331
3332 /* Copy any remaining extra samples as if DSP wrote them */
3333 while ( in < m.extra_pos )
3334 *out++ = *in++;
3335 }
3336
3337 dsp_set_output( out, out_end - out );
3338 }
3339
S9xFinalizeSamples(void)3340 void S9xFinalizeSamples (void)
3341 {
3342 if (!Settings.Mute)
3343 {
3344 bool8 ret = resampler_push(landing_buffer, SPC_SAMPLE_COUNT());
3345
3346 /* We weren't able to process the entire buffer. Potential overrun. */
3347 if (!ret)
3348 {
3349 sound_in_sync = FALSE;
3350 return;
3351 }
3352 }
3353
3354 sound_in_sync = TRUE;
3355
3356 m.extra_clocks &= CLOCKS_PER_SAMPLE - 1;
3357 spc_set_output(landing_buffer, buffer_size);
3358 }
3359
S9xClearSamples(void)3360 void S9xClearSamples (void)
3361 {
3362 resampler_clear();
3363 lag = lag_master;
3364 }
3365
S9xSetSamplesAvailableCallback(apu_callback callback)3366 void S9xSetSamplesAvailableCallback (apu_callback callback)
3367 {
3368 sa_callback = callback;
3369 }
3370
UpdatePlaybackRate(void)3371 static void UpdatePlaybackRate (void)
3372 {
3373 double time_ratio;
3374 if (Settings.SoundInputRate == 0)
3375 Settings.SoundInputRate = SNES_AUDIO_FREQ;
3376
3377 time_ratio = (double) Settings.SoundInputRate * TEMPO_UNIT / (Settings.SoundPlaybackRate * timing_hack_denominator);
3378 resampler_time_ratio(time_ratio);
3379 }
3380
S9xInitSound(size_t req_buff_size,int lag_ms)3381 bool8 S9xInitSound (size_t req_buff_size, int lag_ms)
3382 {
3383 /* buffer_size : size of buffer in bytes
3384 lag_ms : allowable time-lag given in millisecond */
3385 int lag_sample_count;
3386
3387 lag_sample_count = lag_ms * SNES_AUDIO_FREQ / 1000;
3388 lag_master = lag_sample_count;
3389 lag_master <<= 1;
3390 lag = lag_master;
3391
3392 if(req_buff_size < APU_MINIMUM_BUFF_SIZE)
3393 {
3394 S9xMessage(S9X_MSG_ERROR, S9X_CATEGORY_APU,
3395 "The requested buffer size was too small");
3396 goto err;
3397 }
3398
3399 buffer_size = req_buff_size;
3400
3401 if (landing_buffer)
3402 free(landing_buffer);
3403
3404 landing_buffer = (short*)malloc(req_buff_size);
3405 if (!landing_buffer)
3406 goto err;
3407
3408 /* The resampler and spc unit use samples (16-bit short) as
3409 arguments. */
3410 if (!resampler)
3411 {
3412 resampler_new();
3413 resampler = TRUE;
3414 }
3415
3416 m.extra_clocks &= CLOCKS_PER_SAMPLE - 1;
3417 spc_set_output(landing_buffer, buffer_size >> 1);
3418
3419 UpdatePlaybackRate();
3420
3421 return TRUE;
3422
3423 err:
3424 Settings.Mute = 1;
3425 S9xMessage(S9X_MSG_WARN, S9X_CATEGORY_APU,
3426 "Audio output is disabled due to an error");
3427 return FALSE;
3428 }
3429
S9xSetSoundMute(bool8 mute)3430 void S9xSetSoundMute(bool8 mute)
3431 {
3432 if(landing_buffer == NULL)
3433 return;
3434
3435 Settings.Mute = mute;
3436 }
3437
S9xInitAPU(void)3438 bool8 S9xInitAPU (void)
3439 {
3440 unsigned i;
3441
3442 uint8_t APUROM[64] =
3443 {
3444 0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0,
3445 0xFC, 0x8F, 0xAA, 0xF4, 0x8F, 0xBB, 0xF5, 0x78,
3446 0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4,
3447 0xD0, 0xFC, 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5,
3448 0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, 0xAB,
3449 0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA,
3450 0xF6, 0xDA, 0x00, 0xBA, 0xF4, 0xC4, 0xF4, 0xDD,
3451 0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF
3452 };
3453
3454 /* Must be called once before using */
3455 const uint8_t cycle_table [128] =
3456 { /* 01 23 45 67 89 AB CD EF */
3457 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x68, /* 0 */
3458 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x46, /* 1 */
3459 0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x74, /* 2 */
3460 0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x38, /* 3 */
3461 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x66, /* 4 */
3462 0x48,0x47,0x45,0x56,0x55,0x45,0x22,0x43, /* 5 */
3463 0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x75, /* 6 */
3464 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x36, /* 7 */
3465 0x28,0x47,0x34,0x36,0x26,0x54,0x52,0x45, /* 8 */
3466 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0xC5, /* 9 */
3467 0x38,0x47,0x34,0x36,0x26,0x44,0x52,0x44, /* A */
3468 0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x34, /* B */
3469 0x38,0x47,0x45,0x47,0x25,0x64,0x52,0x49, /* C */
3470 0x48,0x47,0x56,0x67,0x45,0x55,0x22,0x83, /* D */
3471 0x28,0x47,0x34,0x36,0x24,0x53,0x43,0x40, /* E */
3472 0x48,0x47,0x45,0x56,0x34,0x54,0x22,0x60, /* F */
3473 };
3474
3475 const int8_t reg_times_ [256] =
3476 {
3477 -1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22,
3478 2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23,
3479 5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23,
3480 8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24,
3481 11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24,
3482 14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24,
3483 17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25,
3484 20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25,
3485 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3486 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3487 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3488 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3489 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3490 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3491 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3492 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
3493 };
3494
3495 memset( &m, 0, sizeof m );
3496 dsp_init( m.ram.ram );
3497
3498 m.tempo = TEMPO_UNIT;
3499
3500 /* Most SPC music doesn't need ROM, and almost all the rest only
3501 rely on these two bytes */
3502
3503 m.rom [0x3E] = 0xFF;
3504 m.rom [0x3F] = 0xC0;
3505
3506
3507 /* unpack cycle table */
3508 for (i = 0; i < 128; i++ )
3509 {
3510 int n = cycle_table [i];
3511 m.cycle_table [i * 2 + 0] = n >> 4;
3512 m.cycle_table [i * 2 + 1] = n & 0x0F;
3513 }
3514
3515 allow_time_overflow = FALSE;
3516
3517 dsp_m.rom = m.rom;
3518 dsp_m.hi_ram = m.hi_ram;
3519
3520 memcpy( reg_times, reg_times_, sizeof(reg_times) );
3521
3522 spc_reset();
3523
3524
3525 memcpy( m.rom, APUROM, sizeof m.rom );
3526
3527 landing_buffer = NULL;
3528
3529 return TRUE;
3530 }
3531
S9xDeinitAPU(void)3532 void S9xDeinitAPU (void)
3533 {
3534 if (resampler)
3535 {
3536 free(rb_buffer);
3537 resampler = FALSE;
3538 }
3539
3540 if (landing_buffer)
3541 {
3542 free(landing_buffer);
3543 landing_buffer = NULL;
3544 }
3545 }
3546
3547 #define S9X_APU_GET_CLOCK(cpucycles) ((ratio_numerator * (cpucycles - reference_time) + spc_remainder) / ratio_denominator)
3548 #define S9X_APU_GET_CLOCK_REMAINDER(cpucycles) ((ratio_numerator * (cpucycles - reference_time) + spc_remainder) % ratio_denominator)
3549
3550 /* Emulated port read at specified time */
3551
S9xAPUReadPort(int port)3552 uint8 S9xAPUReadPort (int port) { return ((uint8) spc_run_until_(S9X_APU_GET_CLOCK(CPU.Cycles))[port]); }
3553
3554 /* Emulated port write at specified time */
3555
S9xAPUWritePort(int port,uint8 byte)3556 void S9xAPUWritePort (int port, uint8 byte)
3557 {
3558 spc_run_until_( S9X_APU_GET_CLOCK(CPU.Cycles) ) [0x10 + port] = byte;
3559 m.ram.ram [0xF4 + port] = byte;
3560 }
3561
S9xAPUSetReferenceTime(int32 cpucycles)3562 void S9xAPUSetReferenceTime (int32 cpucycles)
3563 {
3564 reference_time = cpucycles;
3565 }
3566
S9xAPUExecute(void)3567 void S9xAPUExecute (void)
3568 {
3569 /* Accumulate partial APU cycles */
3570 spc_end_frame(S9X_APU_GET_CLOCK(CPU.Cycles));
3571
3572 spc_remainder = S9X_APU_GET_CLOCK_REMAINDER(CPU.Cycles);
3573 reference_time = CPU.Cycles;
3574
3575 if (SPC_SAMPLE_COUNT() >= APU_MINIMUM_SAMPLE_BLOCK || !sound_in_sync)
3576 sa_callback();
3577 }
3578
S9xAPUTimingSetSpeedup(int ticks)3579 void S9xAPUTimingSetSpeedup (int ticks)
3580 {
3581 if (ticks != 0)
3582 {
3583 char buf[128];
3584 snprintf(buf, sizeof(buf),
3585 "Setting APU speedup hack to %d ticks", ticks);
3586 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_APU, buf);
3587 }
3588
3589 timing_hack_denominator = TEMPO_UNIT - ticks;
3590 spc_set_tempo(timing_hack_denominator);
3591
3592 ratio_numerator = Settings.PAL ? APU_NUMERATOR_PAL : APU_NUMERATOR_NTSC;
3593 ratio_denominator = Settings.PAL ? APU_DENOMINATOR_PAL : APU_DENOMINATOR_NTSC;
3594 ratio_denominator = ratio_denominator * timing_hack_denominator / TEMPO_UNIT;
3595
3596 UpdatePlaybackRate();
3597 }
3598
S9xAPUAllowTimeOverflow(bool8 allow)3599 void S9xAPUAllowTimeOverflow (bool8 allow)
3600 {
3601 allow_time_overflow = allow;
3602 }
3603
S9xResetAPU(void)3604 void S9xResetAPU (void)
3605 {
3606 reference_time = 0;
3607 spc_remainder = 0;
3608 spc_reset();
3609
3610 m.extra_clocks &= CLOCKS_PER_SAMPLE - 1;
3611
3612 spc_set_output(landing_buffer, buffer_size >> 1);
3613
3614 resampler_clear();
3615 }
3616
S9xSoftResetAPU(void)3617 void S9xSoftResetAPU (void)
3618 {
3619 reference_time = 0;
3620 spc_remainder = 0;
3621 spc_soft_reset();
3622
3623 m.extra_clocks &= CLOCKS_PER_SAMPLE - 1;
3624 spc_set_output(landing_buffer, buffer_size >> 1);
3625
3626 resampler_clear();
3627 }
3628
from_apu_to_state(uint8 ** buf,void * var,size_t size)3629 static void NO_OPTIMIZE from_apu_to_state (uint8 **buf, void *var, size_t size)
3630 {
3631 memcpy(*buf, var, size);
3632 *buf += size;
3633 }
3634
to_apu_from_state(uint8 ** buf,void * var,size_t size)3635 static void NO_OPTIMIZE to_apu_from_state (uint8 **buf, void *var, size_t size)
3636 {
3637 memcpy(var, *buf, size);
3638 *buf += size;
3639 }
3640
3641 // work around optimization bug in android GCC
3642 // similar to this: http://jeffq.com/blog/over-aggressive-gcc-optimization-can-cause-sigbus-crash-when-using-memcpy-with-the-android-ndk/
3643 #if defined(ANDROID) || defined(__QNX__)
S9xAPUSaveState(uint8 * block)3644 void __attribute__((optimize(0))) S9xAPUSaveState (uint8 *block)
3645 #else
3646 void S9xAPUSaveState (uint8 *block)
3647 #endif
3648 {
3649 uint8 *ptr = block;
3650
3651 spc_copy_state(&ptr, from_apu_to_state);
3652
3653 SET_LE32(ptr, reference_time);
3654 ptr += sizeof(int32);
3655 SET_LE32(ptr, spc_remainder);
3656 ptr += sizeof(int32);
3657
3658 //zero out the rest of the save state block
3659 memset(ptr, 0, SPC_SAVE_STATE_BLOCK_SIZE - (ptr - block));
3660 }
3661
3662 #if defined(ANDROID) || defined(__QNX__)
S9xAPULoadState(uint8 * block)3663 void __attribute__((optimize(0))) S9xAPULoadState (uint8 *block)
3664 #else
3665 void S9xAPULoadState (uint8 *block)
3666 #endif
3667 {
3668 uint8 *ptr = block;
3669
3670 S9xResetAPU();
3671
3672 spc_copy_state(&ptr, to_apu_from_state);
3673
3674 reference_time = GET_LE32(ptr);
3675 ptr += sizeof(int32);
3676 spc_remainder = GET_LE32(ptr);
3677 ptr += sizeof(int32);
3678 }
3679