random bug fixes
[drnoksnes] / dsp1.cpp
1 /*******************************************************************************
2   Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  
4   (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
5                             Jerremy Koot (jkoot@snes9x.com)
6
7   (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net)
8
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),
13                             Matthew Kendora,
14                             Nach (n-a-c-h@users.sourceforge.net),
15                             Peter Bortas (peter@bortas.org) and
16                             zones (kasumitokoduck@yahoo.com)
17
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
21
22   C4 C++ code
23   (c) Copyright 2003 Brad Jorsch
24
25   DSP-1 emulator code
26   (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson,
27                             John Weidman, neviksti (neviksti@hotmail.com),
28                             Kris Bleakley, Andreas Naive
29
30   DSP-2 emulator code
31   (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and
32                      Lord Nightmare (lord_nightmare@users.sourceforge.net
33
34   OBC1 emulator code
35   (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and
36                             Kris Bleakley
37   Ported from x86 assembler to C by sanmaiwashi
38
39   SPC7110 and RTC C++ emulator code
40   (c) Copyright 2002 Matthew Kendora with research by
41                      zsKnight, John Weidman, and Dark Force
42
43   S-DD1 C emulator code
44   (c) Copyright 2003 Brad Jorsch with research by
45                      Andreas Naive and John Weidman
46  
47   S-RTC C emulator code
48   (c) Copyright 2001 John Weidman
49   
50   ST010 C++ emulator code
51   (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
52
53   Super FX x86 assembler emulator code 
54   (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault 
55
56   Super FX C emulator code 
57   (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
58
59
60   SH assembler code partly based on x86 assembler code
61   (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) 
62
63  
64   Specific ports contains the works of other authors. See headers in
65   individual files.
66  
67   Snes9x homepage: http://www.snes9x.com
68  
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.
73  
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.
77  
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.
81  
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
84   in future versions.
85  
86   Super NES and Super Nintendo Entertainment System are trademarks of
87   Nintendo Co., Limited and its subsidiary companies.
88 *******************************************************************************/
89 #include "snes9x.h"
90 #include "dsp1.h"
91 #include "missing.h"
92 #include "memmap.h"
93 #include <math.h>
94
95 #pragma GCC visibility push(internal)
96 #include "dsp1emu.c"
97 #include "dsp2emu.c"
98 //#include "dsp3emu.cpp"
99 #pragma GCC visibility pop
100
101 void (*SetDSP)(uint8, uint16)=&DSP1SetByte;
102 uint8 (*GetDSP)(uint16)=&DSP1GetByte;
103
104 void S9xInitDSP1 ()
105 {
106     static bool8 init = FALSE;
107     
108     if (!init)
109     {
110         InitDSP ();
111         init = TRUE;
112     }
113 }
114
115 void S9xResetDSP1 ()
116 {
117     S9xInitDSP1 ();
118     
119     DSP1.waiting4command = TRUE;
120     DSP1.in_count = 0;
121     DSP1.out_count = 0;
122     DSP1.in_index = 0;
123     DSP1.out_index = 0;
124     DSP1.first_parameter = TRUE;
125 }
126
127 uint8 S9xGetDSP (uint16 address)
128 {
129     uint8 t;
130         
131 #ifdef DEBUGGER
132     if (Settings.TraceDSP)
133     {
134                 sprintf (String, "DSP read: 0x%04X", address);
135                 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
136     }
137 #endif
138  
139         t=(*GetDSP)(address);
140                 //DSP1GetByte(address);
141     return (t);
142 }
143
144 void S9xSetDSP (uint8 byte, uint16 address)
145 {
146 #ifdef DEBUGGER
147     missing.unknowndsp_write = address;
148     if (Settings.TraceDSP)
149     {
150                 sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte);
151                 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
152     }
153 #endif
154         (*SetDSP)(byte, address);
155         //DSP1SetByte(byte, address);
156 }
157
158 void DSP1SetByte(uint8 byte, uint16 address)
159 {
160     if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 )
161     {
162 //              if ((address & 1) == 0)
163 //              {
164                 if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0)
165                 {
166                         DSP1.out_count--;
167                         DSP1.out_index++;                       
168                         return;
169                 }
170                 else if (DSP1.waiting4command)
171                 {
172                         DSP1.command = byte;
173                         DSP1.in_index = 0;
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
178                         switch (byte)
179                         {
180                         case 0x00: DSP1.in_count = 2;   break;
181                         case 0x30:
182                         case 0x10: DSP1.in_count = 2;   break;
183                         case 0x20: DSP1.in_count = 2;   break;
184                         case 0x24:
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;
190                         case 0x2c:
191                         case 0x0c: DSP1.in_count = 3;   break;
192                         case 0x3c:
193                         case 0x1c: DSP1.in_count = 6;   break;
194                         case 0x32:
195                         case 0x22:
196                         case 0x12:
197                         case 0x02: DSP1.in_count = 7;   break;
198                         case 0x0a: DSP1.in_count = 1;   break;
199                         case 0x3a:
200                         case 0x2a:
201                         case 0x1a: 
202                                 DSP1. command =0x1a;
203                                 DSP1.in_count = 1;      break;
204                         case 0x16:
205                         case 0x26:
206                         case 0x36:
207                         case 0x06: DSP1.in_count = 3;   break;
208                         case 0x1e:
209                         case 0x2e:
210                         case 0x3e:
211                         case 0x0e: DSP1.in_count = 2;   break;
212                         case 0x05:
213                         case 0x35:
214                         case 0x31:
215                         case 0x01: DSP1.in_count = 4;   break;
216                         case 0x15:
217                         case 0x11: DSP1.in_count = 4;   break;
218                         case 0x25:
219                         case 0x21: DSP1.in_count = 4;   break;
220                         case 0x09:
221                         case 0x39:
222                         case 0x3d:
223                         case 0x0d: DSP1.in_count = 3;   break;
224                         case 0x19:
225                         case 0x1d: DSP1.in_count = 3;   break;
226                         case 0x29:
227                         case 0x2d: DSP1.in_count = 3;   break;
228                         case 0x33:
229                         case 0x03: DSP1.in_count = 3;   break;
230                         case 0x13: DSP1.in_count = 3;   break;
231                         case 0x23: DSP1.in_count = 3;   break;
232                         case 0x3b:
233                         case 0x0b: DSP1.in_count = 3;   break;
234                         case 0x1b: DSP1.in_count = 3;   break;
235                         case 0x2b: DSP1.in_count = 3;   break;
236                         case 0x34:
237                         case 0x14: DSP1.in_count = 6;   break;
238                         case 0x07:
239                         case 0x0f: DSP1.in_count = 1;   break;
240                         case 0x27:
241                         case 0x2F: DSP1.in_count=1; break;
242                         case 0x17:
243                         case 0x37:
244                         case 0x3F:
245                                 DSP1.command=0x1f;
246                         case 0x1f: DSP1.in_count = 1;   break;
247                                 //                  case 0x80: DSP1.in_count = 2;       break;
248                         default:
249                                 //printf("Op%02X\n",byte);
250                         case 0x80:
251                                 DSP1.in_count = 0;
252                                 DSP1.waiting4command = TRUE;
253                                 DSP1.first_parameter = TRUE;
254                                 break;
255                         }
256                         DSP1.in_count<<=1;
257                 }
258                 else
259                 {
260                         DSP1.parameters [DSP1.in_index] = byte;
261                         DSP1.first_parameter = FALSE;
262                         DSP1.in_index++;
263                 }
264                 
265                 if (DSP1.waiting4command ||
266                         (DSP1.first_parameter && byte == 0x80))
267                 {
268                         DSP1.waiting4command = TRUE;
269                         DSP1.first_parameter = FALSE;
270                 }
271                 else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0)))
272                 {
273                 }
274 //              else if (DSP1.first_parameter)
275 //              {
276 //              }
277                 else
278                 {
279                         if (DSP1.in_count)
280                         {
281                                 //DSP1.parameters [DSP1.in_index] |= (byte << 8);
282                                 if (--DSP1.in_count == 0)
283                                 {
284                                         // Actually execute the command
285                                         DSP1.waiting4command = TRUE;
286                                         DSP1.out_index = 0;
287                                         switch (DSP1.command)
288                                         {
289                                         case 0x1f:
290                                                 DSP1.out_count=2048;
291                                                 break;
292                                         case 0x00:      // Multiple
293                                                 Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
294                                                 Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
295                                                 
296                                                 DSPOp00 ();
297                                                 
298                                                 DSP1.out_count = 2;
299                                                 DSP1.output [0] = Op00Result&0xFF;
300                                                 DSP1.output [1] = (Op00Result>>8)&0xFF;
301                                                 break;
302
303                                         case 0x20:      // Multiple
304                                                 Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
305                                                 Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
306                                                 
307                                                 DSPOp20 ();
308                                                 
309                                                 DSP1.out_count = 2;
310                                                 DSP1.output [0] = Op20Result&0xFF;
311                                                 DSP1.output [1] = (Op20Result>>8)&0xFF;
312                                                 break;
313                                                 
314                                         case 0x30:
315                                         case 0x10:      // Inverse
316                                                 Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
317                                                 Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
318                                                 
319                                                 DSPOp10 ();
320                                                 
321                                                 DSP1.out_count = 4;
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);
326                                                 break;
327                                                 
328                                         case 0x24:
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));
332                                                 
333                                                 DSPOp04 ();
334                                                 
335                                                 DSP1.out_count = 4;
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);
340                                                 break;
341                                                 
342                                         case 0x08:      // Radius
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));
346                                                 
347                                                 DSPOp08 ();
348                                                 
349                                                 DSP1.out_count = 4;
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);
354                                                 break;
355                                                 
356                                         case 0x18:      // Range
357                                                 
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));
362                                                 
363                                                 DSPOp18 ();
364                                                 
365                                                 DSP1.out_count = 2;
366                                                 DSP1.output [0] = (uint8) (Op18D&0xFF);
367                                                 DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF);
368                                                 break;
369
370                                         case 0x38:      // Range
371                                                 
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));
376                                                 
377                                                 DSPOp38 ();
378                                                 
379                                                 DSP1.out_count = 2;
380                                                 DSP1.output [0] = (uint8) (Op38D&0xFF);
381                                                 DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF);
382                                                 break;
383                                                 
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));
388                                                 
389                                                 DSPOp28 ();
390                                                 
391                                                 DSP1.out_count = 2;
392                                                 DSP1.output [0] = (uint8) (Op28R&0xFF);
393                                                 DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF);
394                                                 break;
395                                                 
396                                         case 0x2c:
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));
401                                                 
402                                                 DSPOp0C ();
403                                                 
404                                                 DSP1.out_count = 4;
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);
409                                                 break;
410                                                 
411                                         case 0x3c:
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));
420                                                 
421                                                 DSPOp1C ();
422                                                 
423                                                 DSP1.out_count = 6;
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);
430                                                 break;
431                                                 
432                                         case 0x32:
433                                         case 0x22:
434                                         case 0x12:
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));
443                                                 
444                                                 DSPOp02 ();
445                                                 
446                                                 DSP1.out_count = 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);
455                                                 break;
456                                                 
457                                         case 0x3a:  //1a Mirror
458                                         case 0x2a:  //1a Mirror
459                                         case 0x1a:      // Raster mode 7 matrix data
460                                         case 0x0a:
461                                                 Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
462                                                 
463                                                 DSPOp0A ();
464                                                 
465                                                 DSP1.out_count = 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);
474                                                 DSP1.in_index=0;
475                                                 break;
476                                                 
477                                         case 0x16:
478                                         case 0x26:
479                                         case 0x36:
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));
484                                                 
485                                                 DSPOp06 ();
486                                                 
487                                                 DSP1.out_count = 6;
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);
494                                                 break;
495                                                 
496                                         case 0x1e:
497                                         case 0x2e:
498                                         case 0x3e:
499                                         case 0x0e:      // Target
500                                                 Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
501                                                 Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
502                                                 
503                                                 DSPOp0E ();
504                                                 
505                                                 DSP1.out_count = 4;
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);
510                                                 break;
511                                                 
512                                                 // Extra commands used by Pilot Wings
513                                         case 0x05:
514                                         case 0x35:
515                                         case 0x31:
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));
521                                                 
522                                                 DSPOp01 ();
523                                                 break;
524                                         
525                                         case 0x15:      
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));
531                                                 
532                                                 DSPOp11 ();
533                                                 break;
534                                                 
535                                         case 0x25:
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));
541                                                 
542                                                 DSPOp21 ();
543                                                 break;
544                                                 
545                                         case 0x09:
546                                         case 0x39:
547                                         case 0x3d:
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));
552                                                 
553                                                 DSPOp0D ();
554                                                 
555                                                 DSP1.out_count = 6;
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);
562                                                 break;
563                                                 
564                                         case 0x19:
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));
569                                                 
570                                                 DSPOp1D ();
571                                                 
572                                                 DSP1.out_count = 6;
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);
579                                                 break;
580                                                 
581                                         case 0x29:
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));
586                                                 
587                                                 DSPOp2D ();
588                                                 
589                                                 DSP1.out_count = 6;
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);
596                                                 break;
597                                                         
598                                         case 0x33:
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));
603                                                 
604                                                 DSPOp03 ();
605                                                 
606                                                 DSP1.out_count = 6;
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);
613                                                 break;
614                                                 
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));
619                                                 
620                                                 DSPOp13 ();
621                                                 
622                                                 DSP1.out_count = 6;
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);
629                                                 break;
630                                                 
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));
635                                                 
636                                                 DSPOp23 ();
637                                                 
638                                                 DSP1.out_count = 6;
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);
645                                                 break;
646                                                 
647                                         case 0x3b:
648                                         case 0x0b:
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));
652                                                 
653                                                 DSPOp0B ();
654                                                 
655                                                 DSP1.out_count = 2;
656                                                 DSP1.output [0] = (uint8) (Op0BS&0xFF);
657                                                 DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF);
658                                                 break;
659                                                 
660                                         case 0x1b:
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));
664                                                 
665                                                 DSPOp1B ();
666                                                 
667                                                 DSP1.out_count = 2;
668                                                 DSP1.output [0] = (uint8) (Op1BS&0xFF);
669                                                 DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF);
670                                                 break;
671                                                 
672                                         case 0x2b:
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));
676                                                 
677                                                 DSPOp2B ();
678                                                 
679                                                 DSP1.out_count = 2;
680                                                 DSP1.output [0] = (uint8) (Op2BS&0xFF);
681                                                 DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF);
682                                                 break;
683                                                 
684                                         case 0x34:
685                                         case 0x14:      
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));
692                                                 
693                                                 DSPOp14 ();
694                                                 
695                                                 DSP1.out_count = 6;
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);
702                                                 break;
703                                         
704                                         case 0x27:
705                                         case 0x2F:
706                                                 Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
707                                                 
708                                                 DSPOp2F ();
709                                                 
710                                                 DSP1.out_count = 2;
711                                                 DSP1.output [0] = (uint8)(Op2FSize&0xFF);
712                                                 DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF);
713                                                 break;
714                                                 
715         
716                                         case 0x07:
717                                         case 0x0F:
718                                                 Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
719                                                 
720                                                 DSPOp0F ();
721                                                 
722                                                 DSP1.out_count = 2;
723                                                 DSP1.output [0] = (uint8)(Op0FPass&0xFF);
724                                                 DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF);
725                                                 break;
726                                                 
727                                         default:
728                                                 break;
729                                         }
730                                 }
731                         }
732                 }
733     }
734 }
735
736 uint8 DSP1GetByte(uint16 address)
737 {
738         uint8 t;
739     if ((address & 0xf000) == 0x6000 ||
740 //              (address >= 0x8000 && address < 0xc000))
741                 (address&0x7fff) < 0x4000)
742     {
743                 if (DSP1.out_count)
744                 {
745                         //if ((address & 1) == 0)
746                                 t = (uint8) DSP1.output [DSP1.out_index];
747                         //else
748                         //{
749                         //      t = (uint8) (DSP1.output [DSP1.out_index] >> 8);
750                                 DSP1.out_index++;
751                                 if (--DSP1.out_count == 0)
752                                 {
753                                         if (DSP1.command == 0x1a || DSP1.command == 0x0a)
754                                         {
755                                                 DSPOp0A ();
756                                                 DSP1.out_count = 8;
757                                                 DSP1.out_index = 0;
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;
766                                         }
767                                         if(DSP1.command==0x1f)
768                                         {
769                                                 if((DSP1.out_index%2)!=0)
770                                                 {
771                                                         t=(uint8)DSP1ROM[DSP1.out_index>>1];
772                                                 }
773                                                 else
774                                                 {
775                                                         t=DSP1ROM[DSP1.out_index>>1]>>8;
776                                                 }
777                                         }
778                                 }
779                                 DSP1.waiting4command = TRUE;
780                         //}
781                 }
782                 else
783                 {
784                         // Top Gear 3000 requires this value....
785         //              if(4==Settings.DSPVersion)
786                                 t = 0xff;
787                         //Ballz3d requires this one:
788         //              else t = 0x00;
789                 }
790     }
791     else t = 0x80;
792         return t;
793 }
794
795 void DSP2SetByte(uint8 byte, uint16 address)
796 {
797         if ((address & 0xf000) == 0x6000 ||
798                 (address >= 0x8000 && address < 0xc000))
799     {
800                 if (DSP1.waiting4command)
801                 {
802                         DSP1.command = byte;
803                         DSP1.in_index = 0;
804                         DSP1.waiting4command = FALSE;
805 //                      DSP1.first_parameter = TRUE;
806 //                      printf("Op%02X\n",byte);
807                         switch (byte)
808                         {
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;
815                         default:
816                                 printf("Op%02X\n",byte);
817                         case 0x0f:DSP1.in_count=0;break;
818                         }
819                 }
820                 else
821                 {
822                         DSP1.parameters [DSP1.in_index] = byte;
823 //                      DSP1.first_parameter = FALSE;
824                         DSP1.in_index++;
825                 }
826                 
827                 if (DSP1.in_count==DSP1.in_index)
828                 {
829                         //DSP1.parameters [DSP1.in_index] |= (byte << 8);
830                         // Actually execute the command
831                         DSP1.waiting4command = TRUE;
832                         DSP1.out_index = 0;
833                         switch (DSP1.command)
834                         {
835                         case 0x0D:
836                                 if(DSP2Op0DHasLen)
837                                 {
838                                         DSP2Op0DHasLen=false;
839                                         DSP1.out_count=DSP2Op0DOutLen;
840                                         //execute Op5
841                                         DSP2_Op0D();
842                                 }
843                                 else
844                                 {
845                                         DSP2Op0DInLen=DSP1.parameters[0];
846                                         DSP2Op0DOutLen=DSP1.parameters[1];
847                                         DSP1.in_index=0;
848                                         DSP1.in_count=(DSP2Op0DInLen+1)>>1;
849                                         DSP2Op0DHasLen=true;
850                                         if(byte)
851                                                 DSP1.waiting4command=false;
852                                 }
853                                 break;
854                         case 0x06:
855                                 if(DSP2Op06HasLen)
856                                 {
857                                         DSP2Op06HasLen=false;
858                                         DSP1.out_count=DSP2Op06Len;
859                                         //execute Op5
860                                         DSP2_Op06();
861                                 }
862                                 else
863                                 {
864                                         DSP2Op06Len=DSP1.parameters[0];
865                                         DSP1.in_index=0;
866                                         DSP1.in_count=DSP2Op06Len;
867                                         DSP2Op06HasLen=true;
868                                         if(byte)
869                                                 DSP1.waiting4command=false;
870                                 }
871                                 break;
872                         case 0x01:
873                                 DSP1.out_count=32;
874                                 DSP2_Op01();
875                                 break;
876                         case 0x09:
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);
880                                 DSP1.out_count=4;
881 #ifdef FAST_LSB_WORD_ACCESS
882                 *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2;
883 #else
884                                 uint32 temp;
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;
890 #endif
891                                 break;
892                         case 0x05:
893                                 if(DSP2Op05HasLen)
894                                 {
895                                         DSP2Op05HasLen=false;
896                                         DSP1.out_count=DSP2Op05Len;
897                                         //execute Op5
898                                         DSP2_Op05();
899                                 }
900                                 else
901                                 {
902                                         DSP2Op05Len=DSP1.parameters[0];
903                                         DSP1.in_index=0;
904                                         DSP1.in_count=2*DSP2Op05Len;
905                                         DSP2Op05HasLen=true;
906                                         if(byte)
907                                                 DSP1.waiting4command=false;
908                                 }
909                                 break;
910
911                         case 0x03:
912                                 DSP2Op05Transparent= DSP1.parameters[0];
913                                 //DSP2Op03();
914                                 break;
915                         case 0x0f:
916                                 default:
917                                         break;
918                         }
919                 }
920         }
921 }
922
923 uint8 DSP2GetByte(uint16 address)
924 {
925         uint8 t;
926     if ((address & 0xf000) == 0x6000 ||
927                 (address >= 0x8000 && address < 0xc000))
928     {
929                 if (DSP1.out_count)
930                 {
931                         t = (uint8) DSP1.output [DSP1.out_index];
932                         DSP1.out_index++;
933                         if(DSP1.out_count==DSP1.out_index)
934                                 DSP1.out_count=0;
935                 }
936                 else
937                 {
938                         t = 0xff;
939                 }
940     }
941     else t = 0x80;
942         return t;
943 }
944
945 /*struct SDSP4 {
946     bool8 waiting4command;
947     bool8 half_command;
948     uint16 command;
949     uint32 in_count;
950     uint32 in_index;
951     uint32 out_count;
952     uint32 out_index;
953     uint8 parameters [512];
954     uint8 output [512];
955 };
956
957 SDSP4 DSP4;
958
959 //#include "dsp4emu.cpp"
960
961 bool DSP4_init=FALSE;
962
963 void DSP4SetByte(uint8 byte, uint16 address)
964 {
965         if(!DSP4_init)
966         {
967                 // bootup
968                 DSP4.waiting4command=1;
969                 DSP4_init=TRUE;
970         }
971
972         if ((address & 0xf000) == 0x6000 ||
973                         (address >= 0x8000 && address < 0xc000))
974         {
975                 if(DSP4.out_index<DSP4.out_count)
976                 {
977                         DSP4.out_index++;
978                         return;
979                 }
980
981                 if (DSP4.waiting4command)
982                 {
983                         if(DSP4.half_command)
984                         {
985                                 DSP4.command |= (byte<<8);
986                                 DSP4.in_index = 0;
987                                 DSP4.waiting4command = FALSE;
988         //                      DSP4.first_parameter = TRUE;
989                                 DSP4.half_command=0;
990                                 DSP4.out_count=0;
991                                 DSP4.out_index=0;
992                                 DSP4_Logic=0;
993
994                                 switch (DSP4.command)
995                                 {
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;
1009                                 default:
1010                                         DSP4.waiting4command=TRUE;
1011                                         //printf("(line %d) Unknown Op%02X\n",line,DSP4.command);
1012                                         break;
1013                                 }
1014                         }
1015                         else
1016                         {
1017                                 DSP4.command=byte;
1018                                 DSP4.half_command=1;
1019                         }
1020                 }
1021                 else
1022                 {
1023                         DSP4.parameters [DSP4.in_index] = byte;
1024 //                      DSP4.first_parameter = FALSE;
1025                         DSP4.in_index++;
1026                 }
1027                 
1028                 if (!DSP4.waiting4command && DSP4.in_count==DSP4.in_index)
1029                 {
1030                         //DSP4.parameters [DSP4.in_index] |= (byte << 8);
1031                         // Actually execute the command
1032                         DSP4.waiting4command = TRUE;
1033                         DSP4.out_index = 0;
1034                         DSP4.in_index=0;
1035                         switch (DSP4.command)
1036                         {
1037                         // 16-bit multiplication
1038                         case 0x0000:
1039                                 {
1040                                         int16 multiplier, multiplicand;
1041                                         int product;
1042                                         
1043                                         multiplier = DSP4_READ_WORD(0);
1044                                         multiplicand = DSP4_READ_WORD(2);
1045
1046                                         DSP4_Multiply(multiplicand,multiplier,product);
1047
1048                                         DSP4.out_count = 4;
1049                                         DSP4_WRITE_WORD(0,product);
1050                                         DSP4_WRITE_WORD(2,product>>16);
1051                                 }
1052                                 break;
1053
1054                         // unknown: horizontal mapping command
1055                         case 0x0011:
1056                                 {
1057                                         int16 a,b,c,d,m;
1058
1059                                         a = DSP4_READ_WORD(6);
1060                                         b = DSP4_READ_WORD(4);
1061                                         c = DSP4_READ_WORD(2);
1062                                         d = DSP4_READ_WORD(0);
1063
1064                                         DSP4_UnknownOP11(a,b,c,d,m);
1065
1066                                         DSP4.out_count = 2;
1067                                         DSP4_WRITE_WORD(0,m);
1068                                         break;
1069                                 }
1070
1071                         // track projection
1072                         case 0x0001: DSP4_Op01(); break;
1073
1074                         // track projection (pass 2)
1075                         case 0x0007: DSP4_Op07(); break;
1076
1077                         // zone projections (fuel/repair/lap/teleport/...)
1078                         case 0x0008: DSP4_Op08(); break;
1079
1080                         // sprite transformation
1081                         case 0x0009: DSP4_Op09(); break;
1082
1083                         // fast track projection
1084                         case 0x000D: DSP4_Op0D(); break;
1085
1086                         // single-player selection
1087                         case 0x0003: DSP4_Op03(); break;
1088
1089                         // clear OAM
1090                         case 0x0005:
1091                                 {
1092                                         op06_index = 0;
1093                                         op06_offset = 0;
1094                                         for( int lcv=0; lcv<32; lcv++ )
1095                                                 op06_OAM[lcv] = 0;
1096                                         break;
1097                                 }
1098
1099                         // multi-player selection
1100                         case 0x000E: DSP4_Op0E(); break;
1101
1102 #undef PRINT
1103
1104                         // transfer OAM
1105                         case 0x0006:
1106                                 {
1107                                         DSP4.out_count = 32;
1108                                         for( int lcv=0; lcv<32; lcv++ )
1109                                                 DSP4.output[lcv] = op06_OAM[lcv];
1110                                 }
1111                                 break;
1112
1113                         // unknown
1114                         case 0x000A:
1115                                 {
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;
1120
1121                                         // NOTE: Snes9x only!
1122                                         // For some odd reason, the input nybbles are reversed
1123
1124                                         DSP4_Op0A(in2a,out1a,out2a,out3a,out4a);
1125
1126                                         DSP4.out_count=8;
1127
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);
1134                                 }
1135                                 break;
1136
1137                         // set OAM
1138                         case 0x000B:
1139                                 {
1140                                         int16 sp_x = DSP4_READ_WORD(0);
1141                                         int16 sp_y = DSP4_READ_WORD(2);
1142                                         int16 oam = DSP4_READ_WORD(4);
1143
1144                                         if ((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))
1145                                         {
1146                                                 short Row = (sp_y >> 3) & 0x1f;
1147
1148                                                 if (RowCount[Row] < MaxTilesPerRow)
1149                                                 {
1150                                                         RowCount[Row]++;
1151
1152                                                         // yield OAM output
1153                                                         DSP4.out_count = 6;
1154                                                         DSP4_WRITE_WORD(0,1);
1155
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);
1160
1161                                                         // OAM: size,msb data
1162                                                         DSP4_Op06(0,0);
1163                                                 }
1164                                         }
1165                                 }
1166                                 break;
1167                         
1168                         default: break;
1169                         }
1170                 }
1171         }
1172 }
1173
1174 uint8 DSP4GetByte(uint16 address)
1175 {
1176         uint8 t;
1177         if ((address & 0xf000) == 0x6000 ||
1178                         (address >= 0x8000 && address < 0xc000))
1179         {
1180                 if (DSP4.out_count)
1181                 {
1182                         t = (uint8) DSP4.output [DSP4.out_index];
1183                         DSP4.out_index++;
1184                         if(DSP4.out_count==DSP4.out_index)
1185                                 DSP4.out_count=0;
1186                 }
1187                 else
1188                         t = 0xff;
1189         }
1190         else
1191         {
1192                 t = 0x80;
1193         }
1194
1195         return t;
1196 }
1197 */
1198