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 *******************************************************************************/
97 //#include "dsp3emu.cpp"
99 void (*SetDSP)(uint8, uint16)=&DSP1SetByte;
100 uint8 (*GetDSP)(uint16)=&DSP1GetByte;
104 static bool8 init = FALSE;
117 DSP1.waiting4command = TRUE;
122 DSP1.first_parameter = TRUE;
125 uint8 S9xGetDSP (uint16 address)
130 if (Settings.TraceDSP)
132 sprintf (String, "DSP read: 0x%04X", address);
133 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
137 t=(*GetDSP)(address);
138 //DSP1GetByte(address);
142 void S9xSetDSP (uint8 byte, uint16 address)
145 missing.unknowndsp_write = address;
146 if (Settings.TraceDSP)
148 sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte);
149 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
152 (*SetDSP)(byte, address);
153 //DSP1SetByte(byte, address);
156 void DSP1SetByte(uint8 byte, uint16 address)
158 if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 )
160 // if ((address & 1) == 0)
162 if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0)
168 else if (DSP1.waiting4command)
172 DSP1.waiting4command = FALSE;
173 DSP1.first_parameter = TRUE;
174 // printf("Op%02X\n",byte);
175 // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a
178 case 0x00: DSP1.in_count = 2; break;
180 case 0x10: DSP1.in_count = 2; break;
181 case 0x20: DSP1.in_count = 2; break;
183 case 0x04: DSP1.in_count = 2; break;
184 case 0x08: DSP1.in_count = 3; break;
185 case 0x18: DSP1.in_count = 4; break;
186 case 0x28: DSP1.in_count = 3; break;
187 case 0x38: DSP1.in_count = 4; break;
189 case 0x0c: DSP1.in_count = 3; break;
191 case 0x1c: DSP1.in_count = 6; break;
195 case 0x02: DSP1.in_count = 7; break;
196 case 0x0a: DSP1.in_count = 1; break;
201 DSP1.in_count = 1; break;
205 case 0x06: DSP1.in_count = 3; break;
209 case 0x0e: DSP1.in_count = 2; break;
213 case 0x01: DSP1.in_count = 4; break;
215 case 0x11: DSP1.in_count = 4; break;
217 case 0x21: DSP1.in_count = 4; break;
221 case 0x0d: DSP1.in_count = 3; break;
223 case 0x1d: DSP1.in_count = 3; break;
225 case 0x2d: DSP1.in_count = 3; break;
227 case 0x03: DSP1.in_count = 3; break;
228 case 0x13: DSP1.in_count = 3; break;
229 case 0x23: DSP1.in_count = 3; break;
231 case 0x0b: DSP1.in_count = 3; break;
232 case 0x1b: DSP1.in_count = 3; break;
233 case 0x2b: DSP1.in_count = 3; break;
235 case 0x14: DSP1.in_count = 6; break;
237 case 0x0f: DSP1.in_count = 1; break;
239 case 0x2F: DSP1.in_count=1; break;
244 case 0x1f: DSP1.in_count = 1; break;
245 // case 0x80: DSP1.in_count = 2; break;
247 //printf("Op%02X\n",byte);
250 DSP1.waiting4command = TRUE;
251 DSP1.first_parameter = TRUE;
258 DSP1.parameters [DSP1.in_index] = byte;
259 DSP1.first_parameter = FALSE;
263 if (DSP1.waiting4command ||
264 (DSP1.first_parameter && byte == 0x80))
266 DSP1.waiting4command = TRUE;
267 DSP1.first_parameter = FALSE;
269 else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0)))
272 // else if (DSP1.first_parameter)
279 //DSP1.parameters [DSP1.in_index] |= (byte << 8);
280 if (--DSP1.in_count == 0)
282 // Actually execute the command
283 DSP1.waiting4command = TRUE;
285 switch (DSP1.command)
290 case 0x00: // Multiple
291 Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
292 Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
297 DSP1.output [0] = Op00Result&0xFF;
298 DSP1.output [1] = (Op00Result>>8)&0xFF;
301 case 0x20: // Multiple
302 Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
303 Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
308 DSP1.output [0] = Op20Result&0xFF;
309 DSP1.output [1] = (Op20Result>>8)&0xFF;
313 case 0x10: // Inverse
314 Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
315 Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
320 DSP1.output [0] = (uint8) (((int16) Op10CoefficientR)&0xFF);
321 DSP1.output [1] = (uint8) ((((int16) Op10CoefficientR)>>8)&0xFF);
322 DSP1.output [2] = (uint8) (((int16) Op10ExponentR)&0xff);
323 DSP1.output [3] = (uint8) ((((int16) Op10ExponentR)>>8)&0xff);
327 case 0x04: // Sin and Cos of angle
328 Op04Angle = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
329 Op04Radius = (uint16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
334 DSP1.output [0] = (uint8) (Op04Sin&0xFF);
335 DSP1.output [1] = (uint8) ((Op04Sin>>8)&0xFF);
336 DSP1.output [2] = (uint8) (Op04Cos&0xFF);
337 DSP1.output [3] = (uint8) ((Op04Cos>>8)&0xFF);
341 Op08X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
342 Op08Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
343 Op08Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
348 DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF);
349 DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF);
350 DSP1.output [2] = (uint8) (((int16) Op08Lh)&0xFF);
351 DSP1.output [3] = (uint8) ((((int16) Op08Lh)>>8)&0xFF);
356 Op18X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
357 Op18Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
358 Op18Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
359 Op18R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
364 DSP1.output [0] = (uint8) (Op18D&0xFF);
365 DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF);
370 Op38X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
371 Op38Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
372 Op38Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
373 Op38R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
378 DSP1.output [0] = (uint8) (Op38D&0xFF);
379 DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF);
382 case 0x28: // Distance (vector length)
383 Op28X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
384 Op28Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
385 Op28Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
390 DSP1.output [0] = (uint8) (Op28R&0xFF);
391 DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF);
395 case 0x0c: // Rotate (2D rotate)
396 Op0CA = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
397 Op0CX1 = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
398 Op0CY1 = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
403 DSP1.output [0] = (uint8) (Op0CX2&0xFF);
404 DSP1.output [1] = (uint8) ((Op0CX2>>8)&0xFF);
405 DSP1.output [2] = (uint8) (Op0CY2&0xFF);
406 DSP1.output [3] = (uint8) ((Op0CY2>>8)&0xFF);
410 case 0x1c: // Polar (3D rotate)
411 Op1CZ = (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
412 //MK: reversed X and Y on neviksti and John's advice.
413 Op1CY = (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
414 Op1CX = (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
415 Op1CXBR = (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
416 Op1CYBR = (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
417 Op1CZBR = (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
422 DSP1.output [0] = (uint8) (Op1CXAR&0xFF);
423 DSP1.output [1] = (uint8) ((Op1CXAR>>8)&0xFF);
424 DSP1.output [2] = (uint8) (Op1CYAR&0xFF);
425 DSP1.output [3] = (uint8) ((Op1CYAR>>8)&0xFF);
426 DSP1.output [4] = (uint8) (Op1CZAR&0xFF);
427 DSP1.output [5] = (uint8) ((Op1CZAR>>8)&0xFF);
433 case 0x02: // Parameter (Projection)
434 Op02FX = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
435 Op02FY = (short)(DSP1.parameters [2]|(DSP1.parameters[3]<<8));
436 Op02FZ = (short)(DSP1.parameters [4]|(DSP1.parameters[5]<<8));
437 Op02LFE = (short)(DSP1.parameters [6]|(DSP1.parameters[7]<<8));
438 Op02LES = (short)(DSP1.parameters [8]|(DSP1.parameters[9]<<8));
439 Op02AAS = (unsigned short)(DSP1.parameters [10]|(DSP1.parameters[11]<<8));
440 Op02AZS = (unsigned short)(DSP1.parameters [12]|(DSP1.parameters[13]<<8));
445 DSP1.output [0] = (uint8) (Op02VOF&0xFF);
446 DSP1.output [1] = (uint8) ((Op02VOF>>8)&0xFF);
447 DSP1.output [2] = (uint8) (Op02VVA&0xFF);
448 DSP1.output [3] = (uint8) ((Op02VVA>>8)&0xFF);
449 DSP1.output [4] = (uint8) (Op02CX&0xFF);
450 DSP1.output [5] = (uint8) ((Op02CX>>8)&0xFF);
451 DSP1.output [6] = (uint8) (Op02CY&0xFF);
452 DSP1.output [7] = (uint8) ((Op02CY>>8)&0xFF);
455 case 0x3a: //1a Mirror
456 case 0x2a: //1a Mirror
457 case 0x1a: // Raster mode 7 matrix data
459 Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
464 DSP1.output [0] = (uint8) (Op0AA&0xFF);
465 DSP1.output [2] = (uint8) (Op0AB&0xFF);
466 DSP1.output [4] = (uint8) (Op0AC&0xFF);
467 DSP1.output [6] = (uint8) (Op0AD&0xFF);
468 DSP1.output [1] = (uint8) ((Op0AA>>8)&0xFF);
469 DSP1.output [3] = (uint8) ((Op0AB>>8)&0xFF);
470 DSP1.output [5] = (uint8) ((Op0AC>>8)&0xFF);
471 DSP1.output [7] = (uint8) ((Op0AD>>8)&0xFF);
478 case 0x06: // Project object
479 Op06X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
480 Op06Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
481 Op06Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
486 DSP1.output [0] = (uint8) (Op06H&0xff);
487 DSP1.output [1] = (uint8) ((Op06H>>8)&0xFF);
488 DSP1.output [2] = (uint8) (Op06V&0xFF);
489 DSP1.output [3] = (uint8) ((Op06V>>8)&0xFF);
490 DSP1.output [4] = (uint8) (Op06S&0xFF);
491 DSP1.output [5] = (uint8) ((Op06S>>8)&0xFF);
498 Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
499 Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
504 DSP1.output [0] = (uint8) (Op0EX&0xFF);
505 DSP1.output [1] = (uint8) ((Op0EX>>8)&0xFF);
506 DSP1.output [2] = (uint8) (Op0EY&0xFF);
507 DSP1.output [3] = (uint8) ((Op0EY>>8)&0xFF);
510 // Extra commands used by Pilot Wings
514 case 0x01: // Set attitude matrix A
515 Op01m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
516 Op01Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
517 Op01Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
518 Op01Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
524 case 0x11: // Set attitude matrix B
525 Op11m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
526 Op11Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
527 Op11Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
528 Op11Xr = (int16) (DSP1.parameters [7]|(DSP1.parameters[7]<<8));
534 case 0x21: // Set attitude matrix C
535 Op21m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
536 Op21Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
537 Op21Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
538 Op21Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
546 case 0x0d: // Objective matrix A
547 Op0DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
548 Op0DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
549 Op0DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
554 DSP1.output [0] = (uint8) (Op0DF&0xFF);
555 DSP1.output [1] = (uint8) ((Op0DF>>8)&0xFF);
556 DSP1.output [2] = (uint8) (Op0DL&0xFF);
557 DSP1.output [3] = (uint8) ((Op0DL>>8)&0xFF);
558 DSP1.output [4] = (uint8) (Op0DU&0xFF);
559 DSP1.output [5] = (uint8) ((Op0DU>>8)&0xFF);
563 case 0x1d: // Objective matrix B
564 Op1DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
565 Op1DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
566 Op1DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
571 DSP1.output [0] = (uint8) (Op1DF&0xFF);
572 DSP1.output [1] = (uint8) ((Op1DF>>8)&0xFF);
573 DSP1.output [2] = (uint8) (Op1DL&0xFF);
574 DSP1.output [3] = (uint8) ((Op1DL>>8)&0xFF);
575 DSP1.output [4] = (uint8) (Op1DU&0xFF);
576 DSP1.output [5] = (uint8) ((Op1DU>>8)&0xFF);
580 case 0x2d: // Objective matrix C
581 Op2DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
582 Op2DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
583 Op2DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
588 DSP1.output [0] = (uint8) (Op2DF&0xFF);
589 DSP1.output [1] = (uint8) ((Op2DF>>8)&0xFF);
590 DSP1.output [2] = (uint8) (Op2DL&0xFF);
591 DSP1.output [3] = (uint8) ((Op2DL>>8)&0xFF);
592 DSP1.output [4] = (uint8) (Op2DU&0xFF);
593 DSP1.output [5] = (uint8) ((Op2DU>>8)&0xFF);
597 case 0x03: // Subjective matrix A
598 Op03F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
599 Op03L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
600 Op03U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
605 DSP1.output [0] = (uint8) (Op03X&0xFF);
606 DSP1.output [1] = (uint8) ((Op03X>>8)&0xFF);
607 DSP1.output [2] = (uint8) (Op03Y&0xFF);
608 DSP1.output [3] = (uint8) ((Op03Y>>8)&0xFF);
609 DSP1.output [4] = (uint8) (Op03Z&0xFF);
610 DSP1.output [5] = (uint8) ((Op03Z>>8)&0xFF);
613 case 0x13: // Subjective matrix B
614 Op13F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
615 Op13L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
616 Op13U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
621 DSP1.output [0] = (uint8) (Op13X&0xFF);
622 DSP1.output [1] = (uint8) ((Op13X>>8)&0xFF);
623 DSP1.output [2] = (uint8) (Op13Y&0xFF);
624 DSP1.output [3] = (uint8) ((Op13Y>>8)&0xFF);
625 DSP1.output [4] = (uint8) (Op13Z&0xFF);
626 DSP1.output [5] = (uint8) ((Op13Z>>8)&0xFF);
629 case 0x23: // Subjective matrix C
630 Op23F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
631 Op23L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
632 Op23U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
637 DSP1.output [0] = (uint8) (Op23X&0xFF);
638 DSP1.output [1] = (uint8) ((Op23X>>8)&0xFF);
639 DSP1.output [2] = (uint8) (Op23Y&0xFF);
640 DSP1.output [3] = (uint8) ((Op23Y>>8)&0xFF);
641 DSP1.output [4] = (uint8) (Op23Z&0xFF);
642 DSP1.output [5] = (uint8) ((Op23Z>>8)&0xFF);
647 Op0BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
648 Op0BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
649 Op0BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
654 DSP1.output [0] = (uint8) (Op0BS&0xFF);
655 DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF);
659 Op1BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
660 Op1BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
661 Op1BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
666 DSP1.output [0] = (uint8) (Op1BS&0xFF);
667 DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF);
671 Op2BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
672 Op2BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
673 Op2BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
678 DSP1.output [0] = (uint8) (Op2BS&0xFF);
679 DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF);
684 Op14Zr = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
685 Op14Xr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
686 Op14Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8));
687 Op14U = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8));
688 Op14F = (int16) (DSP1.parameters [8]|(DSP1.parameters[9]<<8));
689 Op14L = (int16) (DSP1.parameters [10]|(DSP1.parameters[11]<<8));
694 DSP1.output [0] = (uint8) (Op14Zrr&0xFF);
695 DSP1.output [1] = (uint8) ((Op14Zrr>>8)&0xFF);
696 DSP1.output [2] = (uint8) (Op14Xrr&0xFF);
697 DSP1.output [3] = (uint8) ((Op14Xrr>>8)&0xFF);
698 DSP1.output [4] = (uint8) (Op14Yrr&0xFF);
699 DSP1.output [5] = (uint8) ((Op14Yrr>>8)&0xFF);
704 Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
709 DSP1.output [0] = (uint8)(Op2FSize&0xFF);
710 DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF);
716 Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
721 DSP1.output [0] = (uint8)(Op0FPass&0xFF);
722 DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF);
734 uint8 DSP1GetByte(uint16 address)
737 if ((address & 0xf000) == 0x6000 ||
738 // (address >= 0x8000 && address < 0xc000))
739 (address&0x7fff) < 0x4000)
743 //if ((address & 1) == 0)
744 t = (uint8) DSP1.output [DSP1.out_index];
747 // t = (uint8) (DSP1.output [DSP1.out_index] >> 8);
749 if (--DSP1.out_count == 0)
751 if (DSP1.command == 0x1a || DSP1.command == 0x0a)
756 DSP1.output [0] = (Op0AA&0xFF);
757 DSP1.output [1] = (Op0AA>>8)&0xFF;
758 DSP1.output [2] = (Op0AB&0xFF);
759 DSP1.output [3] = (Op0AB>>8)&0xFF;
760 DSP1.output [4] = (Op0AC&0xFF);
761 DSP1.output [5] = (Op0AC>>8)&0xFF;
762 DSP1.output [6] = (Op0AD&0xFF);
763 DSP1.output [7] = (Op0AD>>8)&0xFF;
765 if(DSP1.command==0x1f)
767 if((DSP1.out_index%2)!=0)
769 t=(uint8)DSP1ROM[DSP1.out_index>>1];
773 t=DSP1ROM[DSP1.out_index>>1]>>8;
777 DSP1.waiting4command = TRUE;
782 // Top Gear 3000 requires this value....
783 // if(4==Settings.DSPVersion)
785 //Ballz3d requires this one:
793 void DSP2SetByte(uint8 byte, uint16 address)
795 if ((address & 0xf000) == 0x6000 ||
796 (address >= 0x8000 && address < 0xc000))
798 if (DSP1.waiting4command)
802 DSP1.waiting4command = FALSE;
803 // DSP1.first_parameter = TRUE;
804 // printf("Op%02X\n",byte);
807 case 0x01:DSP1.in_count=32;break;
808 case 0x03:DSP1.in_count=1;break;
809 case 0x05:DSP1.in_count=1;break;
810 case 0x09:DSP1.in_count=4;break;
811 case 0x06:DSP1.in_count=1;break;
812 case 0x0D:DSP1.in_count=2;break;
814 printf("Op%02X\n",byte);
815 case 0x0f:DSP1.in_count=0;break;
820 DSP1.parameters [DSP1.in_index] = byte;
821 // DSP1.first_parameter = FALSE;
825 if (DSP1.in_count==DSP1.in_index)
827 //DSP1.parameters [DSP1.in_index] |= (byte << 8);
828 // Actually execute the command
829 DSP1.waiting4command = TRUE;
831 switch (DSP1.command)
836 DSP2Op0DHasLen=false;
837 DSP1.out_count=DSP2Op0DOutLen;
843 DSP2Op0DInLen=DSP1.parameters[0];
844 DSP2Op0DOutLen=DSP1.parameters[1];
846 DSP1.in_count=(DSP2Op0DInLen+1)>>1;
849 DSP1.waiting4command=false;
855 DSP2Op06HasLen=false;
856 DSP1.out_count=DSP2Op06Len;
862 DSP2Op06Len=DSP1.parameters[0];
864 DSP1.in_count=DSP2Op06Len;
867 DSP1.waiting4command=false;
875 // Multiply - don't yet know if this is signed or unsigned
876 DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1]<<8);
877 DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3]<<8);
879 #ifdef FAST_LSB_WORD_ACCESS
880 *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2;
883 temp=DSP2Op09Word1 * DSP2Op09Word2;
884 DSP1.output[0]=temp&0xFF;
885 DSP1.output[1]=(temp>>8)&0xFF;
886 DSP1.output[2]=(temp>>16)&0xFF;
887 DSP1.output[3]=(temp>>24)&0xFF;
893 DSP2Op05HasLen=false;
894 DSP1.out_count=DSP2Op05Len;
900 DSP2Op05Len=DSP1.parameters[0];
902 DSP1.in_count=2*DSP2Op05Len;
905 DSP1.waiting4command=false;
910 DSP2Op05Transparent= DSP1.parameters[0];
921 uint8 DSP2GetByte(uint16 address)
924 if ((address & 0xf000) == 0x6000 ||
925 (address >= 0x8000 && address < 0xc000))
929 t = (uint8) DSP1.output [DSP1.out_index];
931 if(DSP1.out_count==DSP1.out_index)
944 bool8 waiting4command;
951 uint8 parameters [512];
957 //#include "dsp4emu.cpp"
959 bool DSP4_init=FALSE;
961 void DSP4SetByte(uint8 byte, uint16 address)
966 DSP4.waiting4command=1;
970 if ((address & 0xf000) == 0x6000 ||
971 (address >= 0x8000 && address < 0xc000))
973 if(DSP4.out_index<DSP4.out_count)
979 if (DSP4.waiting4command)
981 if(DSP4.half_command)
983 DSP4.command |= (byte<<8);
985 DSP4.waiting4command = FALSE;
986 // DSP4.first_parameter = TRUE;
992 switch (DSP4.command)
994 case 0x0000:DSP4.in_count=4;break;
995 case 0x0001:DSP4.in_count=36;break;
996 case 0x0003:DSP4.in_count=0;break;
997 case 0x0005:DSP4.in_count=0;break;
998 case 0x0006:DSP4.in_count=0;break;
999 case 0x0007:DSP4.in_count=22;break;
1000 case 0x0008:DSP4.in_count=72;break;
1001 case 0x0009:DSP4.in_count=14;break;
1002 case 0x000A:DSP4.in_count=6;break;
1003 case 0x000B:DSP4.in_count=6;break;
1004 case 0x000D:DSP4.in_count=34;break;
1005 case 0x000E:DSP4.in_count=0;break;
1006 case 0x0011:DSP4.in_count=8;break;
1008 DSP4.waiting4command=TRUE;
1009 //printf("(line %d) Unknown Op%02X\n",line,DSP4.command);
1016 DSP4.half_command=1;
1021 DSP4.parameters [DSP4.in_index] = byte;
1022 // DSP4.first_parameter = FALSE;
1026 if (!DSP4.waiting4command && DSP4.in_count==DSP4.in_index)
1028 //DSP4.parameters [DSP4.in_index] |= (byte << 8);
1029 // Actually execute the command
1030 DSP4.waiting4command = TRUE;
1033 switch (DSP4.command)
1035 // 16-bit multiplication
1038 int16 multiplier, multiplicand;
1041 multiplier = DSP4_READ_WORD(0);
1042 multiplicand = DSP4_READ_WORD(2);
1044 DSP4_Multiply(multiplicand,multiplier,product);
1047 DSP4_WRITE_WORD(0,product);
1048 DSP4_WRITE_WORD(2,product>>16);
1052 // unknown: horizontal mapping command
1057 a = DSP4_READ_WORD(6);
1058 b = DSP4_READ_WORD(4);
1059 c = DSP4_READ_WORD(2);
1060 d = DSP4_READ_WORD(0);
1062 DSP4_UnknownOP11(a,b,c,d,m);
1065 DSP4_WRITE_WORD(0,m);
1070 case 0x0001: DSP4_Op01(); break;
1072 // track projection (pass 2)
1073 case 0x0007: DSP4_Op07(); break;
1075 // zone projections (fuel/repair/lap/teleport/...)
1076 case 0x0008: DSP4_Op08(); break;
1078 // sprite transformation
1079 case 0x0009: DSP4_Op09(); break;
1081 // fast track projection
1082 case 0x000D: DSP4_Op0D(); break;
1084 // single-player selection
1085 case 0x0003: DSP4_Op03(); break;
1092 for( int lcv=0; lcv<32; lcv++ )
1097 // multi-player selection
1098 case 0x000E: DSP4_Op0E(); break;
1105 DSP4.out_count = 32;
1106 for( int lcv=0; lcv<32; lcv++ )
1107 DSP4.output[lcv] = op06_OAM[lcv];
1114 int16 in1a = DSP4_READ_WORD(0);
1115 int16 in2a = DSP4_READ_WORD(2);
1116 int16 in3a = DSP4_READ_WORD(4);
1117 int16 out1a,out2a,out3a,out4a;
1119 // NOTE: Snes9x only!
1120 // For some odd reason, the input nybbles are reversed
1122 DSP4_Op0A(in2a,out1a,out2a,out3a,out4a);
1126 // Hack: Reverse the outputs for now to compensate
1127 // Otherwise the AI gets really flaky
1128 DSP4_WRITE_WORD(0,out2a);
1129 DSP4_WRITE_WORD(2,out1a);
1130 DSP4_WRITE_WORD(4,out4a);
1131 DSP4_WRITE_WORD(6,out3a);
1138 int16 sp_x = DSP4_READ_WORD(0);
1139 int16 sp_y = DSP4_READ_WORD(2);
1140 int16 oam = DSP4_READ_WORD(4);
1142 if ((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))
1144 short Row = (sp_y >> 3) & 0x1f;
1146 if (RowCount[Row] < MaxTilesPerRow)
1152 DSP4_WRITE_WORD(0,1);
1154 // pack OAM data: x,y,name,attr
1155 DSP4.output[2] = sp_x & 0xff;
1156 DSP4.output[3] = sp_y & 0xff;
1157 DSP4_WRITE_WORD(4,oam);
1159 // OAM: size,msb data
1172 uint8 DSP4GetByte(uint16 address)
1175 if ((address & 0xf000) == 0x6000 ||
1176 (address >= 0x8000 && address < 0xc000))
1180 t = (uint8) DSP4.output [DSP4.out_index];
1182 if(DSP4.out_count==DSP4.out_index)