1 /*******************************************************************************
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
5 Jerremy Koot (jkoot@snes9x.com)
7 (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
9 (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net),
10 funkyass (funkyass@spam.shaw.ca),
11 Joel Yliluoma (http://iki.fi/bisqwit/)
12 Kris Bleakley (codeviolation@hotmail.com),
14 Nach (n-a-c-h@users.sourceforge.net),
15 Peter Bortas (peter@bortas.org) and
16 zones (kasumitokoduck@yahoo.com)
18 C4 x86 assembler and some C emulation code
19 (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com),
20 _Demo_ (_demo_@zsnes.com), and Nach
23 (c) Copyright 2003 Brad Jorsch
26 (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
27 John Weidman, neviksti (neviksti@hotmail.com),
28 Kris Bleakley, Andreas Naive
31 (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
32 Lord Nightmare (lord_nightmare@users.sourceforge.net
35 (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
37 Ported from x86 assembler to C by sanmaiwashi
39 SPC7110 and RTC C++ emulator code
40 (c) Copyright 2002 Matthew Kendora with research by
41 zsKnight, John Weidman, and Dark Force
44 (c) Copyright 2003 Brad Jorsch with research by
45 Andreas Naive and John Weidman
48 (c) Copyright 2001 John Weidman
50 ST010 C++ emulator code
51 (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
53 Super FX x86 assembler emulator code
54 (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
56 Super FX C emulator code
57 (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
60 SH assembler code partly based on x86 assembler code
61 (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
64 Specific ports contains the works of other authors. See headers in
67 Snes9x homepage: http://www.snes9x.com
69 Permission to use, copy, modify and distribute Snes9x in both binary and
70 source form, for non-commercial purposes, is hereby granted without fee,
71 providing that this license information and copyright notice appear with
72 all copies and any derived work.
74 This software is provided 'as-is', without any express or implied
75 warranty. In no event shall the authors be held liable for any damages
76 arising from the use of this software.
78 Snes9x is freeware for PERSONAL USE only. Commercial users should
79 seek permission of the copyright holders first. Commercial use includes
80 charging money for Snes9x or software derived from Snes9x.
82 The copyright holders request that bug fixes and improvements to the code
83 should be forwarded to them so everyone can benefit from the modifications
86 Super NES and Super Nintendo Entertainment System are trademarks of
87 Nintendo Co., Limited and its subsidiary companies.
88 *******************************************************************************/
95 #pragma GCC visibility push(internal)
98 //#include "dsp3emu.cpp"
99 #pragma GCC visibility pop
101 void (*SetDSP)(uint8, uint16)=&DSP1SetByte;
102 uint8 (*GetDSP)(uint16)=&DSP1GetByte;
106 static bool8 init = FALSE;
119 DSP1.waiting4command = TRUE;
124 DSP1.first_parameter = TRUE;
127 uint8 S9xGetDSP (uint16 address)
132 if (Settings.TraceDSP)
134 sprintf (String, "DSP read: 0x%04X", address);
135 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
139 t=(*GetDSP)(address);
140 //DSP1GetByte(address);
144 void S9xSetDSP (uint8 byte, uint16 address)
147 missing.unknowndsp_write = address;
148 if (Settings.TraceDSP)
150 sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte);
151 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
154 (*SetDSP)(byte, address);
155 //DSP1SetByte(byte, address);
158 void DSP1SetByte(uint8 byte, uint16 address)
160 if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 )
162 // if ((address & 1) == 0)
164 if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0)
170 else if (DSP1.waiting4command)
174 DSP1.waiting4command = FALSE;
175 DSP1.first_parameter = TRUE;
176 // printf("Op%02X\n",byte);
177 // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a
180 case 0x00: DSP1.in_count = 2; break;
182 case 0x10: DSP1.in_count = 2; break;
183 case 0x20: DSP1.in_count = 2; break;
185 case 0x04: DSP1.in_count = 2; break;
186 case 0x08: DSP1.in_count = 3; break;
187 case 0x18: DSP1.in_count = 4; break;
188 case 0x28: DSP1.in_count = 3; break;
189 case 0x38: DSP1.in_count = 4; break;
191 case 0x0c: DSP1.in_count = 3; break;
193 case 0x1c: DSP1.in_count = 6; break;
197 case 0x02: DSP1.in_count = 7; break;
198 case 0x0a: DSP1.in_count = 1; break;
203 DSP1.in_count = 1; break;
207 case 0x06: DSP1.in_count = 3; break;
211 case 0x0e: DSP1.in_count = 2; break;
215 case 0x01: DSP1.in_count = 4; break;
217 case 0x11: DSP1.in_count = 4; break;
219 case 0x21: DSP1.in_count = 4; break;
223 case 0x0d: DSP1.in_count = 3; break;
225 case 0x1d: DSP1.in_count = 3; break;
227 case 0x2d: DSP1.in_count = 3; break;
229 case 0x03: DSP1.in_count = 3; break;
230 case 0x13: DSP1.in_count = 3; break;
231 case 0x23: DSP1.in_count = 3; break;
233 case 0x0b: DSP1.in_count = 3; break;
234 case 0x1b: DSP1.in_count = 3; break;
235 case 0x2b: DSP1.in_count = 3; break;
237 case 0x14: DSP1.in_count = 6; break;
239 case 0x0f: DSP1.in_count = 1; break;
241 case 0x2F: DSP1.in_count=1; break;
246 case 0x1f: DSP1.in_count = 1; break;
247 // case 0x80: DSP1.in_count = 2; break;
249 //printf("Op%02X\n",byte);
252 DSP1.waiting4command = TRUE;
253 DSP1.first_parameter = TRUE;
260 DSP1.parameters [DSP1.in_index] = byte;
261 DSP1.first_parameter = FALSE;
265 if (DSP1.waiting4command ||
266 (DSP1.first_parameter && byte == 0x80))
268 DSP1.waiting4command = TRUE;
269 DSP1.first_parameter = FALSE;
271 else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0)))
274 // else if (DSP1.first_parameter)
281 //DSP1.parameters [DSP1.in_index] |= (byte << 8);
282 if (--DSP1.in_count == 0)
284 // Actually execute the command
285 DSP1.waiting4command = TRUE;
287 switch (DSP1.command)
292 case 0x00: // Multiple
293 Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
294 Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
299 DSP1.output [0] = Op00Result&0xFF;
300 DSP1.output [1] = (Op00Result>>8)&0xFF;
303 case 0x20: // Multiple
304 Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
305 Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
310 DSP1.output [0] = Op20Result&0xFF;
311 DSP1.output [1] = (Op20Result>>8)&0xFF;
315 case 0x10: // Inverse
316 Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
317 Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
322 DSP1.output [0] = (uint8) (((int16) Op10CoefficientR)&0xFF);
323 DSP1.output [1] = (uint8) ((((int16) Op10CoefficientR)>>8)&0xFF);
324 DSP1.output [2] = (uint8) (((int16) Op10ExponentR)&0xff);
325 DSP1.output [3] = (uint8) ((((int16) Op10ExponentR)>>8)&0xff);
329 case 0x04: // Sin and Cos of angle
330 Op04Angle = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
331 Op04Radius = (uint16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
336 DSP1.output [0] = (uint8) (Op04Sin&0xFF);
337 DSP1.output [1] = (uint8) ((Op04Sin>>8)&0xFF);
338 DSP1.output [2] = (uint8) (Op04Cos&0xFF);
339 DSP1.output [3] = (uint8) ((Op04Cos>>8)&0xFF);
343 Op08X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
344 Op08Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
345 Op08Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
350 DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF);
351 DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF);
352 DSP1.output [2] = (uint8) (((int16) Op08Lh)&0xFF);
353 DSP1.output [3] = (uint8) ((((int16) Op08Lh)>>8)&0xFF);
358 Op18X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
359 Op18Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
360 Op18Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
361 Op18R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
366 DSP1.output [0] = (uint8) (Op18D&0xFF);
367 DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF);
372 Op38X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
373 Op38Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
374 Op38Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
375 Op38R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
380 DSP1.output [0] = (uint8) (Op38D&0xFF);
381 DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF);
384 case 0x28: // Distance (vector length)
385 Op28X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
386 Op28Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
387 Op28Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
392 DSP1.output [0] = (uint8) (Op28R&0xFF);
393 DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF);
397 case 0x0c: // Rotate (2D rotate)
398 Op0CA = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
399 Op0CX1 = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
400 Op0CY1 = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
405 DSP1.output [0] = (uint8) (Op0CX2&0xFF);
406 DSP1.output [1] = (uint8) ((Op0CX2>>8)&0xFF);
407 DSP1.output [2] = (uint8) (Op0CY2&0xFF);
408 DSP1.output [3] = (uint8) ((Op0CY2>>8)&0xFF);
412 case 0x1c: // Polar (3D rotate)
413 Op1CZ = (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
414 //MK: reversed X and Y on neviksti and John's advice.
415 Op1CY = (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
416 Op1CX = (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
417 Op1CXBR = (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
418 Op1CYBR = (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
419 Op1CZBR = (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
424 DSP1.output [0] = (uint8) (Op1CXAR&0xFF);
425 DSP1.output [1] = (uint8) ((Op1CXAR>>8)&0xFF);
426 DSP1.output [2] = (uint8) (Op1CYAR&0xFF);
427 DSP1.output [3] = (uint8) ((Op1CYAR>>8)&0xFF);
428 DSP1.output [4] = (uint8) (Op1CZAR&0xFF);
429 DSP1.output [5] = (uint8) ((Op1CZAR>>8)&0xFF);
435 case 0x02: // Parameter (Projection)
436 Op02FX = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
437 Op02FY = (short)(DSP1.parameters [2]|(DSP1.parameters[3]<<8));
438 Op02FZ = (short)(DSP1.parameters [4]|(DSP1.parameters[5]<<8));
439 Op02LFE = (short)(DSP1.parameters [6]|(DSP1.parameters[7]<<8));
440 Op02LES = (short)(DSP1.parameters [8]|(DSP1.parameters[9]<<8));
441 Op02AAS = (unsigned short)(DSP1.parameters [10]|(DSP1.parameters[11]<<8));
442 Op02AZS = (unsigned short)(DSP1.parameters [12]|(DSP1.parameters[13]<<8));
447 DSP1.output [0] = (uint8) (Op02VOF&0xFF);
448 DSP1.output [1] = (uint8) ((Op02VOF>>8)&0xFF);
449 DSP1.output [2] = (uint8) (Op02VVA&0xFF);
450 DSP1.output [3] = (uint8) ((Op02VVA>>8)&0xFF);
451 DSP1.output [4] = (uint8) (Op02CX&0xFF);
452 DSP1.output [5] = (uint8) ((Op02CX>>8)&0xFF);
453 DSP1.output [6] = (uint8) (Op02CY&0xFF);
454 DSP1.output [7] = (uint8) ((Op02CY>>8)&0xFF);
457 case 0x3a: //1a Mirror
458 case 0x2a: //1a Mirror
459 case 0x1a: // Raster mode 7 matrix data
461 Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
466 DSP1.output [0] = (uint8) (Op0AA&0xFF);
467 DSP1.output [2] = (uint8) (Op0AB&0xFF);
468 DSP1.output [4] = (uint8) (Op0AC&0xFF);
469 DSP1.output [6] = (uint8) (Op0AD&0xFF);
470 DSP1.output [1] = (uint8) ((Op0AA>>8)&0xFF);
471 DSP1.output [3] = (uint8) ((Op0AB>>8)&0xFF);
472 DSP1.output [5] = (uint8) ((Op0AC>>8)&0xFF);
473 DSP1.output [7] = (uint8) ((Op0AD>>8)&0xFF);
480 case 0x06: // Project object
481 Op06X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
482 Op06Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
483 Op06Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
488 DSP1.output [0] = (uint8) (Op06H&0xff);
489 DSP1.output [1] = (uint8) ((Op06H>>8)&0xFF);
490 DSP1.output [2] = (uint8) (Op06V&0xFF);
491 DSP1.output [3] = (uint8) ((Op06V>>8)&0xFF);
492 DSP1.output [4] = (uint8) (Op06S&0xFF);
493 DSP1.output [5] = (uint8) ((Op06S>>8)&0xFF);
500 Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
501 Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
506 DSP1.output [0] = (uint8) (Op0EX&0xFF);
507 DSP1.output [1] = (uint8) ((Op0EX>>8)&0xFF);
508 DSP1.output [2] = (uint8) (Op0EY&0xFF);
509 DSP1.output [3] = (uint8) ((Op0EY>>8)&0xFF);
512 // Extra commands used by Pilot Wings
516 case 0x01: // Set attitude matrix A
517 Op01m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
518 Op01Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
519 Op01Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
520 Op01Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
526 case 0x11: // Set attitude matrix B
527 Op11m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
528 Op11Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
529 Op11Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
530 Op11Xr = (int16) (DSP1.parameters [7]|(DSP1.parameters[7]<<8));
536 case 0x21: // Set attitude matrix C
537 Op21m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
538 Op21Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
539 Op21Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
540 Op21Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
548 case 0x0d: // Objective matrix A
549 Op0DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
550 Op0DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
551 Op0DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
556 DSP1.output [0] = (uint8) (Op0DF&0xFF);
557 DSP1.output [1] = (uint8) ((Op0DF>>8)&0xFF);
558 DSP1.output [2] = (uint8) (Op0DL&0xFF);
559 DSP1.output [3] = (uint8) ((Op0DL>>8)&0xFF);
560 DSP1.output [4] = (uint8) (Op0DU&0xFF);
561 DSP1.output [5] = (uint8) ((Op0DU>>8)&0xFF);
565 case 0x1d: // Objective matrix B
566 Op1DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
567 Op1DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
568 Op1DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
573 DSP1.output [0] = (uint8) (Op1DF&0xFF);
574 DSP1.output [1] = (uint8) ((Op1DF>>8)&0xFF);
575 DSP1.output [2] = (uint8) (Op1DL&0xFF);
576 DSP1.output [3] = (uint8) ((Op1DL>>8)&0xFF);
577 DSP1.output [4] = (uint8) (Op1DU&0xFF);
578 DSP1.output [5] = (uint8) ((Op1DU>>8)&0xFF);
582 case 0x2d: // Objective matrix C
583 Op2DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
584 Op2DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
585 Op2DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
590 DSP1.output [0] = (uint8) (Op2DF&0xFF);
591 DSP1.output [1] = (uint8) ((Op2DF>>8)&0xFF);
592 DSP1.output [2] = (uint8) (Op2DL&0xFF);
593 DSP1.output [3] = (uint8) ((Op2DL>>8)&0xFF);
594 DSP1.output [4] = (uint8) (Op2DU&0xFF);
595 DSP1.output [5] = (uint8) ((Op2DU>>8)&0xFF);
599 case 0x03: // Subjective matrix A
600 Op03F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
601 Op03L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
602 Op03U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
607 DSP1.output [0] = (uint8) (Op03X&0xFF);
608 DSP1.output [1] = (uint8) ((Op03X>>8)&0xFF);
609 DSP1.output [2] = (uint8) (Op03Y&0xFF);
610 DSP1.output [3] = (uint8) ((Op03Y>>8)&0xFF);
611 DSP1.output [4] = (uint8) (Op03Z&0xFF);
612 DSP1.output [5] = (uint8) ((Op03Z>>8)&0xFF);
615 case 0x13: // Subjective matrix B
616 Op13F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
617 Op13L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
618 Op13U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
623 DSP1.output [0] = (uint8) (Op13X&0xFF);
624 DSP1.output [1] = (uint8) ((Op13X>>8)&0xFF);
625 DSP1.output [2] = (uint8) (Op13Y&0xFF);
626 DSP1.output [3] = (uint8) ((Op13Y>>8)&0xFF);
627 DSP1.output [4] = (uint8) (Op13Z&0xFF);
628 DSP1.output [5] = (uint8) ((Op13Z>>8)&0xFF);
631 case 0x23: // Subjective matrix C
632 Op23F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
633 Op23L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
634 Op23U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
639 DSP1.output [0] = (uint8) (Op23X&0xFF);
640 DSP1.output [1] = (uint8) ((Op23X>>8)&0xFF);
641 DSP1.output [2] = (uint8) (Op23Y&0xFF);
642 DSP1.output [3] = (uint8) ((Op23Y>>8)&0xFF);
643 DSP1.output [4] = (uint8) (Op23Z&0xFF);
644 DSP1.output [5] = (uint8) ((Op23Z>>8)&0xFF);
649 Op0BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
650 Op0BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
651 Op0BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
656 DSP1.output [0] = (uint8) (Op0BS&0xFF);
657 DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF);
661 Op1BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
662 Op1BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
663 Op1BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
668 DSP1.output [0] = (uint8) (Op1BS&0xFF);
669 DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF);
673 Op2BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
674 Op2BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
675 Op2BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
680 DSP1.output [0] = (uint8) (Op2BS&0xFF);
681 DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF);
686 Op14Zr = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
687 Op14Xr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
688 Op14Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
689 Op14U = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
690 Op14F = (int16) (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
691 Op14L = (int16) (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
696 DSP1.output [0] = (uint8) (Op14Zrr&0xFF);
697 DSP1.output [1] = (uint8) ((Op14Zrr>>8)&0xFF);
698 DSP1.output [2] = (uint8) (Op14Xrr&0xFF);
699 DSP1.output [3] = (uint8) ((Op14Xrr>>8)&0xFF);
700 DSP1.output [4] = (uint8) (Op14Yrr&0xFF);
701 DSP1.output [5] = (uint8) ((Op14Yrr>>8)&0xFF);
706 Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
711 DSP1.output [0] = (uint8)(Op2FSize&0xFF);
712 DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF);
718 Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
723 DSP1.output [0] = (uint8)(Op0FPass&0xFF);
724 DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF);
736 uint8 DSP1GetByte(uint16 address)
739 if ((address & 0xf000) == 0x6000 ||
740 // (address >= 0x8000 && address < 0xc000))
741 (address&0x7fff) < 0x4000)
745 //if ((address & 1) == 0)
746 t = (uint8) DSP1.output [DSP1.out_index];
749 // t = (uint8) (DSP1.output [DSP1.out_index] >> 8);
751 if (--DSP1.out_count == 0)
753 if (DSP1.command == 0x1a || DSP1.command == 0x0a)
758 DSP1.output [0] = (Op0AA&0xFF);
759 DSP1.output [1] = (Op0AA>>8)&0xFF;
760 DSP1.output [2] = (Op0AB&0xFF);
761 DSP1.output [3] = (Op0AB>>8)&0xFF;
762 DSP1.output [4] = (Op0AC&0xFF);
763 DSP1.output [5] = (Op0AC>>8)&0xFF;
764 DSP1.output [6] = (Op0AD&0xFF);
765 DSP1.output [7] = (Op0AD>>8)&0xFF;
767 if(DSP1.command==0x1f)
769 if((DSP1.out_index%2)!=0)
771 t=(uint8)DSP1ROM[DSP1.out_index>>1];
775 t=DSP1ROM[DSP1.out_index>>1]>>8;
779 DSP1.waiting4command = TRUE;
784 // Top Gear 3000 requires this value....
785 // if(4==Settings.DSPVersion)
787 //Ballz3d requires this one:
795 void DSP2SetByte(uint8 byte, uint16 address)
797 if ((address & 0xf000) == 0x6000 ||
798 (address >= 0x8000 && address < 0xc000))
800 if (DSP1.waiting4command)
804 DSP1.waiting4command = FALSE;
805 // DSP1.first_parameter = TRUE;
806 // printf("Op%02X\n",byte);
809 case 0x01:DSP1.in_count=32;break;
810 case 0x03:DSP1.in_count=1;break;
811 case 0x05:DSP1.in_count=1;break;
812 case 0x09:DSP1.in_count=4;break;
813 case 0x06:DSP1.in_count=1;break;
814 case 0x0D:DSP1.in_count=2;break;
816 printf("Op%02X\n",byte);
817 case 0x0f:DSP1.in_count=0;break;
822 DSP1.parameters [DSP1.in_index] = byte;
823 // DSP1.first_parameter = FALSE;
827 if (DSP1.in_count==DSP1.in_index)
829 //DSP1.parameters [DSP1.in_index] |= (byte << 8);
830 // Actually execute the command
831 DSP1.waiting4command = TRUE;
833 switch (DSP1.command)
838 DSP2Op0DHasLen=false;
839 DSP1.out_count=DSP2Op0DOutLen;
845 DSP2Op0DInLen=DSP1.parameters[0];
846 DSP2Op0DOutLen=DSP1.parameters[1];
848 DSP1.in_count=(DSP2Op0DInLen+1)>>1;
851 DSP1.waiting4command=false;
857 DSP2Op06HasLen=false;
858 DSP1.out_count=DSP2Op06Len;
864 DSP2Op06Len=DSP1.parameters[0];
866 DSP1.in_count=DSP2Op06Len;
869 DSP1.waiting4command=false;
877 // Multiply - don't yet know if this is signed or unsigned
878 DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1]<<8);
879 DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3]<<8);
881 #ifdef FAST_LSB_WORD_ACCESS
882 *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2;
885 temp=DSP2Op09Word1 * DSP2Op09Word2;
886 DSP1.output[0]=temp&0xFF;
887 DSP1.output[1]=(temp>>8)&0xFF;
888 DSP1.output[2]=(temp>>16)&0xFF;
889 DSP1.output[3]=(temp>>24)&0xFF;
895 DSP2Op05HasLen=false;
896 DSP1.out_count=DSP2Op05Len;
902 DSP2Op05Len=DSP1.parameters[0];
904 DSP1.in_count=2*DSP2Op05Len;
907 DSP1.waiting4command=false;
912 DSP2Op05Transparent= DSP1.parameters[0];
923 uint8 DSP2GetByte(uint16 address)
926 if ((address & 0xf000) == 0x6000 ||
927 (address >= 0x8000 && address < 0xc000))
931 t = (uint8) DSP1.output [DSP1.out_index];
933 if(DSP1.out_count==DSP1.out_index)
946 bool8 waiting4command;
953 uint8 parameters [512];
959 //#include "dsp4emu.cpp"
961 bool DSP4_init=FALSE;
963 void DSP4SetByte(uint8 byte, uint16 address)
968 DSP4.waiting4command=1;
972 if ((address & 0xf000) == 0x6000 ||
973 (address >= 0x8000 && address < 0xc000))
975 if(DSP4.out_index<DSP4.out_count)
981 if (DSP4.waiting4command)
983 if(DSP4.half_command)
985 DSP4.command |= (byte<<8);
987 DSP4.waiting4command = FALSE;
988 // DSP4.first_parameter = TRUE;
994 switch (DSP4.command)
996 case 0x0000:DSP4.in_count=4;break;
997 case 0x0001:DSP4.in_count=36;break;
998 case 0x0003:DSP4.in_count=0;break;
999 case 0x0005:DSP4.in_count=0;break;
1000 case 0x0006:DSP4.in_count=0;break;
1001 case 0x0007:DSP4.in_count=22;break;
1002 case 0x0008:DSP4.in_count=72;break;
1003 case 0x0009:DSP4.in_count=14;break;
1004 case 0x000A:DSP4.in_count=6;break;
1005 case 0x000B:DSP4.in_count=6;break;
1006 case 0x000D:DSP4.in_count=34;break;
1007 case 0x000E:DSP4.in_count=0;break;
1008 case 0x0011:DSP4.in_count=8;break;
1010 DSP4.waiting4command=TRUE;
1011 //printf("(line %d) Unknown Op%02X\n",line,DSP4.command);
1018 DSP4.half_command=1;
1023 DSP4.parameters [DSP4.in_index] = byte;
1024 // DSP4.first_parameter = FALSE;
1028 if (!DSP4.waiting4command && DSP4.in_count==DSP4.in_index)
1030 //DSP4.parameters [DSP4.in_index] |= (byte << 8);
1031 // Actually execute the command
1032 DSP4.waiting4command = TRUE;
1035 switch (DSP4.command)
1037 // 16-bit multiplication
1040 int16 multiplier, multiplicand;
1043 multiplier = DSP4_READ_WORD(0);
1044 multiplicand = DSP4_READ_WORD(2);
1046 DSP4_Multiply(multiplicand,multiplier,product);
1049 DSP4_WRITE_WORD(0,product);
1050 DSP4_WRITE_WORD(2,product>>16);
1054 // unknown: horizontal mapping command
1059 a = DSP4_READ_WORD(6);
1060 b = DSP4_READ_WORD(4);
1061 c = DSP4_READ_WORD(2);
1062 d = DSP4_READ_WORD(0);
1064 DSP4_UnknownOP11(a,b,c,d,m);
1067 DSP4_WRITE_WORD(0,m);
1072 case 0x0001: DSP4_Op01(); break;
1074 // track projection (pass 2)
1075 case 0x0007: DSP4_Op07(); break;
1077 // zone projections (fuel/repair/lap/teleport/...)
1078 case 0x0008: DSP4_Op08(); break;
1080 // sprite transformation
1081 case 0x0009: DSP4_Op09(); break;
1083 // fast track projection
1084 case 0x000D: DSP4_Op0D(); break;
1086 // single-player selection
1087 case 0x0003: DSP4_Op03(); break;
1094 for( int lcv=0; lcv<32; lcv++ )
1099 // multi-player selection
1100 case 0x000E: DSP4_Op0E(); break;
1107 DSP4.out_count = 32;
1108 for( int lcv=0; lcv<32; lcv++ )
1109 DSP4.output[lcv] = op06_OAM[lcv];
1116 int16 in1a = DSP4_READ_WORD(0);
1117 int16 in2a = DSP4_READ_WORD(2);
1118 int16 in3a = DSP4_READ_WORD(4);
1119 int16 out1a,out2a,out3a,out4a;
1121 // NOTE: Snes9x only!
1122 // For some odd reason, the input nybbles are reversed
1124 DSP4_Op0A(in2a,out1a,out2a,out3a,out4a);
1128 // Hack: Reverse the outputs for now to compensate
1129 // Otherwise the AI gets really flaky
1130 DSP4_WRITE_WORD(0,out2a);
1131 DSP4_WRITE_WORD(2,out1a);
1132 DSP4_WRITE_WORD(4,out4a);
1133 DSP4_WRITE_WORD(6,out3a);
1140 int16 sp_x = DSP4_READ_WORD(0);
1141 int16 sp_y = DSP4_READ_WORD(2);
1142 int16 oam = DSP4_READ_WORD(4);
1144 if ((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))
1146 short Row = (sp_y >> 3) & 0x1f;
1148 if (RowCount[Row] < MaxTilesPerRow)
1154 DSP4_WRITE_WORD(0,1);
1156 // pack OAM data: x,y,name,attr
1157 DSP4.output[2] = sp_x & 0xff;
1158 DSP4.output[3] = sp_y & 0xff;
1159 DSP4_WRITE_WORD(4,oam);
1161 // OAM: size,msb data
1174 uint8 DSP4GetByte(uint16 address)
1177 if ((address & 0xf000) == 0x6000 ||
1178 (address >= 0x8000 && address < 0xc000))
1182 t = (uint8) DSP4.output [DSP4.out_index];
1184 if(DSP4.out_count==DSP4.out_index)