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