initial upstream import
[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 #include "dsp1emu.c"
96 #include "dsp2emu.c"
97 //#include "dsp3emu.cpp"
98
99 void (*SetDSP)(uint8, uint16)=&DSP1SetByte;
100 uint8 (*GetDSP)(uint16)=&DSP1GetByte;
101
102 void S9xInitDSP1 ()
103 {
104     static bool8 init = FALSE;
105     
106     if (!init)
107     {
108         InitDSP ();
109         init = TRUE;
110     }
111 }
112
113 void S9xResetDSP1 ()
114 {
115     S9xInitDSP1 ();
116     
117     DSP1.waiting4command = TRUE;
118     DSP1.in_count = 0;
119     DSP1.out_count = 0;
120     DSP1.in_index = 0;
121     DSP1.out_index = 0;
122     DSP1.first_parameter = TRUE;
123 }
124
125 uint8 S9xGetDSP (uint16 address)
126 {
127     uint8 t;
128         
129 #ifdef DEBUGGER
130     if (Settings.TraceDSP)
131     {
132                 sprintf (String, "DSP read: 0x%04X", address);
133                 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
134     }
135 #endif
136  
137         t=(*GetDSP)(address);
138                 //DSP1GetByte(address);
139     return (t);
140 }
141
142 void S9xSetDSP (uint8 byte, uint16 address)
143 {
144 #ifdef DEBUGGER
145     missing.unknowndsp_write = address;
146     if (Settings.TraceDSP)
147     {
148                 sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte);
149                 S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String);
150     }
151 #endif
152         (*SetDSP)(byte, address);
153         //DSP1SetByte(byte, address);
154 }
155
156 void DSP1SetByte(uint8 byte, uint16 address)
157 {
158     if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 )
159     {
160 //              if ((address & 1) == 0)
161 //              {
162                 if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0)
163                 {
164                         DSP1.out_count--;
165                         DSP1.out_index++;                       
166                         return;
167                 }
168                 else if (DSP1.waiting4command)
169                 {
170                         DSP1.command = byte;
171                         DSP1.in_index = 0;
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
176                         switch (byte)
177                         {
178                         case 0x00: DSP1.in_count = 2;   break;
179                         case 0x30:
180                         case 0x10: DSP1.in_count = 2;   break;
181                         case 0x20: DSP1.in_count = 2;   break;
182                         case 0x24:
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;
188                         case 0x2c:
189                         case 0x0c: DSP1.in_count = 3;   break;
190                         case 0x3c:
191                         case 0x1c: DSP1.in_count = 6;   break;
192                         case 0x32:
193                         case 0x22:
194                         case 0x12:
195                         case 0x02: DSP1.in_count = 7;   break;
196                         case 0x0a: DSP1.in_count = 1;   break;
197                         case 0x3a:
198                         case 0x2a:
199                         case 0x1a: 
200                                 DSP1. command =0x1a;
201                                 DSP1.in_count = 1;      break;
202                         case 0x16:
203                         case 0x26:
204                         case 0x36:
205                         case 0x06: DSP1.in_count = 3;   break;
206                         case 0x1e:
207                         case 0x2e:
208                         case 0x3e:
209                         case 0x0e: DSP1.in_count = 2;   break;
210                         case 0x05:
211                         case 0x35:
212                         case 0x31:
213                         case 0x01: DSP1.in_count = 4;   break;
214                         case 0x15:
215                         case 0x11: DSP1.in_count = 4;   break;
216                         case 0x25:
217                         case 0x21: DSP1.in_count = 4;   break;
218                         case 0x09:
219                         case 0x39:
220                         case 0x3d:
221                         case 0x0d: DSP1.in_count = 3;   break;
222                         case 0x19:
223                         case 0x1d: DSP1.in_count = 3;   break;
224                         case 0x29:
225                         case 0x2d: DSP1.in_count = 3;   break;
226                         case 0x33:
227                         case 0x03: DSP1.in_count = 3;   break;
228                         case 0x13: DSP1.in_count = 3;   break;
229                         case 0x23: DSP1.in_count = 3;   break;
230                         case 0x3b:
231                         case 0x0b: DSP1.in_count = 3;   break;
232                         case 0x1b: DSP1.in_count = 3;   break;
233                         case 0x2b: DSP1.in_count = 3;   break;
234                         case 0x34:
235                         case 0x14: DSP1.in_count = 6;   break;
236                         case 0x07:
237                         case 0x0f: DSP1.in_count = 1;   break;
238                         case 0x27:
239                         case 0x2F: DSP1.in_count=1; break;
240                         case 0x17:
241                         case 0x37:
242                         case 0x3F:
243                                 DSP1.command=0x1f;
244                         case 0x1f: DSP1.in_count = 1;   break;
245                                 //                  case 0x80: DSP1.in_count = 2;       break;
246                         default:
247                                 //printf("Op%02X\n",byte);
248                         case 0x80:
249                                 DSP1.in_count = 0;
250                                 DSP1.waiting4command = TRUE;
251                                 DSP1.first_parameter = TRUE;
252                                 break;
253                         }
254                         DSP1.in_count<<=1;
255                 }
256                 else
257                 {
258                         DSP1.parameters [DSP1.in_index] = byte;
259                         DSP1.first_parameter = FALSE;
260                         DSP1.in_index++;
261                 }
262                 
263                 if (DSP1.waiting4command ||
264                         (DSP1.first_parameter && byte == 0x80))
265                 {
266                         DSP1.waiting4command = TRUE;
267                         DSP1.first_parameter = FALSE;
268                 }
269                 else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0)))
270                 {
271                 }
272 //              else if (DSP1.first_parameter)
273 //              {
274 //              }
275                 else
276                 {
277                         if (DSP1.in_count)
278                         {
279                                 //DSP1.parameters [DSP1.in_index] |= (byte << 8);
280                                 if (--DSP1.in_count == 0)
281                                 {
282                                         // Actually execute the command
283                                         DSP1.waiting4command = TRUE;
284                                         DSP1.out_index = 0;
285                                         switch (DSP1.command)
286                                         {
287                                         case 0x1f:
288                                                 DSP1.out_count=2048;
289                                                 break;
290                                         case 0x00:      // Multiple
291                                                 Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
292                                                 Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
293                                                 
294                                                 DSPOp00 ();
295                                                 
296                                                 DSP1.out_count = 2;
297                                                 DSP1.output [0] = Op00Result&0xFF;
298                                                 DSP1.output [1] = (Op00Result>>8)&0xFF;
299                                                 break;
300
301                                         case 0x20:      // Multiple
302                                                 Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
303                                                 Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
304                                                 
305                                                 DSPOp20 ();
306                                                 
307                                                 DSP1.out_count = 2;
308                                                 DSP1.output [0] = Op20Result&0xFF;
309                                                 DSP1.output [1] = (Op20Result>>8)&0xFF;
310                                                 break;
311                                                 
312                                         case 0x30:
313                                         case 0x10:      // Inverse
314                                                 Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
315                                                 Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
316                                                 
317                                                 DSPOp10 ();
318                                                 
319                                                 DSP1.out_count = 4;
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);
324                                                 break;
325                                                 
326                                         case 0x24:
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));
330                                                 
331                                                 DSPOp04 ();
332                                                 
333                                                 DSP1.out_count = 4;
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);
338                                                 break;
339                                                 
340                                         case 0x08:      // Radius
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));
344                                                 
345                                                 DSPOp08 ();
346                                                 
347                                                 DSP1.out_count = 4;
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);
352                                                 break;
353                                                 
354                                         case 0x18:      // Range
355                                                 
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));
360                                                 
361                                                 DSPOp18 ();
362                                                 
363                                                 DSP1.out_count = 2;
364                                                 DSP1.output [0] = (uint8) (Op18D&0xFF);
365                                                 DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF);
366                                                 break;
367
368                                         case 0x38:      // Range
369                                                 
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));
374                                                 
375                                                 DSPOp38 ();
376                                                 
377                                                 DSP1.out_count = 2;
378                                                 DSP1.output [0] = (uint8) (Op38D&0xFF);
379                                                 DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF);
380                                                 break;
381                                                 
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));
386                                                 
387                                                 DSPOp28 ();
388                                                 
389                                                 DSP1.out_count = 2;
390                                                 DSP1.output [0] = (uint8) (Op28R&0xFF);
391                                                 DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF);
392                                                 break;
393                                                 
394                                         case 0x2c:
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));
399                                                 
400                                                 DSPOp0C ();
401                                                 
402                                                 DSP1.out_count = 4;
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);
407                                                 break;
408                                                 
409                                         case 0x3c:
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));
418                                                 
419                                                 DSPOp1C ();
420                                                 
421                                                 DSP1.out_count = 6;
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);
428                                                 break;
429                                                 
430                                         case 0x32:
431                                         case 0x22:
432                                         case 0x12:
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));
441                                                 
442                                                 DSPOp02 ();
443                                                 
444                                                 DSP1.out_count = 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);
453                                                 break;
454                                                 
455                                         case 0x3a:  //1a Mirror
456                                         case 0x2a:  //1a Mirror
457                                         case 0x1a:      // Raster mode 7 matrix data
458                                         case 0x0a:
459                                                 Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8));
460                                                 
461                                                 DSPOp0A ();
462                                                 
463                                                 DSP1.out_count = 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);
472                                                 DSP1.in_index=0;
473                                                 break;
474                                                 
475                                         case 0x16:
476                                         case 0x26:
477                                         case 0x36:
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));
482                                                 
483                                                 DSPOp06 ();
484                                                 
485                                                 DSP1.out_count = 6;
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);
492                                                 break;
493                                                 
494                                         case 0x1e:
495                                         case 0x2e:
496                                         case 0x3e:
497                                         case 0x0e:      // Target
498                                                 Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
499                                                 Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8));
500                                                 
501                                                 DSPOp0E ();
502                                                 
503                                                 DSP1.out_count = 4;
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);
508                                                 break;
509                                                 
510                                                 // Extra commands used by Pilot Wings
511                                         case 0x05:
512                                         case 0x35:
513                                         case 0x31:
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));
519                                                 
520                                                 DSPOp01 ();
521                                                 break;
522                                         
523                                         case 0x15:      
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));
529                                                 
530                                                 DSPOp11 ();
531                                                 break;
532                                                 
533                                         case 0x25:
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));
539                                                 
540                                                 DSPOp21 ();
541                                                 break;
542                                                 
543                                         case 0x09:
544                                         case 0x39:
545                                         case 0x3d:
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));
550                                                 
551                                                 DSPOp0D ();
552                                                 
553                                                 DSP1.out_count = 6;
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);
560                                                 break;
561                                                 
562                                         case 0x19:
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));
567                                                 
568                                                 DSPOp1D ();
569                                                 
570                                                 DSP1.out_count = 6;
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);
577                                                 break;
578                                                 
579                                         case 0x29:
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));
584                                                 
585                                                 DSPOp2D ();
586                                                 
587                                                 DSP1.out_count = 6;
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);
594                                                 break;
595                                                         
596                                         case 0x33:
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));
601                                                 
602                                                 DSPOp03 ();
603                                                 
604                                                 DSP1.out_count = 6;
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);
611                                                 break;
612                                                 
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));
617                                                 
618                                                 DSPOp13 ();
619                                                 
620                                                 DSP1.out_count = 6;
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);
627                                                 break;
628                                                 
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));
633                                                 
634                                                 DSPOp23 ();
635                                                 
636                                                 DSP1.out_count = 6;
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);
643                                                 break;
644                                                 
645                                         case 0x3b:
646                                         case 0x0b:
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));
650                                                 
651                                                 DSPOp0B ();
652                                                 
653                                                 DSP1.out_count = 2;
654                                                 DSP1.output [0] = (uint8) (Op0BS&0xFF);
655                                                 DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF);
656                                                 break;
657                                                 
658                                         case 0x1b:
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));
662                                                 
663                                                 DSPOp1B ();
664                                                 
665                                                 DSP1.out_count = 2;
666                                                 DSP1.output [0] = (uint8) (Op1BS&0xFF);
667                                                 DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF);
668                                                 break;
669                                                 
670                                         case 0x2b:
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));
674                                                 
675                                                 DSPOp2B ();
676                                                 
677                                                 DSP1.out_count = 2;
678                                                 DSP1.output [0] = (uint8) (Op2BS&0xFF);
679                                                 DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF);
680                                                 break;
681                                                 
682                                         case 0x34:
683                                         case 0x14:      
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));
690                                                 
691                                                 DSPOp14 ();
692                                                 
693                                                 DSP1.out_count = 6;
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);
700                                                 break;
701                                         
702                                         case 0x27:
703                                         case 0x2F:
704                                                 Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
705                                                 
706                                                 DSPOp2F ();
707                                                 
708                                                 DSP1.out_count = 2;
709                                                 DSP1.output [0] = (uint8)(Op2FSize&0xFF);
710                                                 DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF);
711                                                 break;
712                                                 
713         
714                                         case 0x07:
715                                         case 0x0F:
716                                                 Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8));
717                                                 
718                                                 DSPOp0F ();
719                                                 
720                                                 DSP1.out_count = 2;
721                                                 DSP1.output [0] = (uint8)(Op0FPass&0xFF);
722                                                 DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF);
723                                                 break;
724                                                 
725                                         default:
726                                                 break;
727                                         }
728                                 }
729                         }
730                 }
731     }
732 }
733
734 uint8 DSP1GetByte(uint16 address)
735 {
736         uint8 t;
737     if ((address & 0xf000) == 0x6000 ||
738 //              (address >= 0x8000 && address < 0xc000))
739                 (address&0x7fff) < 0x4000)
740     {
741                 if (DSP1.out_count)
742                 {
743                         //if ((address & 1) == 0)
744                                 t = (uint8) DSP1.output [DSP1.out_index];
745                         //else
746                         //{
747                         //      t = (uint8) (DSP1.output [DSP1.out_index] >> 8);
748                                 DSP1.out_index++;
749                                 if (--DSP1.out_count == 0)
750                                 {
751                                         if (DSP1.command == 0x1a || DSP1.command == 0x0a)
752                                         {
753                                                 DSPOp0A ();
754                                                 DSP1.out_count = 8;
755                                                 DSP1.out_index = 0;
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;
764                                         }
765                                         if(DSP1.command==0x1f)
766                                         {
767                                                 if((DSP1.out_index%2)!=0)
768                                                 {
769                                                         t=(uint8)DSP1ROM[DSP1.out_index>>1];
770                                                 }
771                                                 else
772                                                 {
773                                                         t=DSP1ROM[DSP1.out_index>>1]>>8;
774                                                 }
775                                         }
776                                 }
777                                 DSP1.waiting4command = TRUE;
778                         //}
779                 }
780                 else
781                 {
782                         // Top Gear 3000 requires this value....
783         //              if(4==Settings.DSPVersion)
784                                 t = 0xff;
785                         //Ballz3d requires this one:
786         //              else t = 0x00;
787                 }
788     }
789     else t = 0x80;
790         return t;
791 }
792
793 void DSP2SetByte(uint8 byte, uint16 address)
794 {
795         if ((address & 0xf000) == 0x6000 ||
796                 (address >= 0x8000 && address < 0xc000))
797     {
798                 if (DSP1.waiting4command)
799                 {
800                         DSP1.command = byte;
801                         DSP1.in_index = 0;
802                         DSP1.waiting4command = FALSE;
803 //                      DSP1.first_parameter = TRUE;
804 //                      printf("Op%02X\n",byte);
805                         switch (byte)
806                         {
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;
813                         default:
814                                 printf("Op%02X\n",byte);
815                         case 0x0f:DSP1.in_count=0;break;
816                         }
817                 }
818                 else
819                 {
820                         DSP1.parameters [DSP1.in_index] = byte;
821 //                      DSP1.first_parameter = FALSE;
822                         DSP1.in_index++;
823                 }
824                 
825                 if (DSP1.in_count==DSP1.in_index)
826                 {
827                         //DSP1.parameters [DSP1.in_index] |= (byte << 8);
828                         // Actually execute the command
829                         DSP1.waiting4command = TRUE;
830                         DSP1.out_index = 0;
831                         switch (DSP1.command)
832                         {
833                         case 0x0D:
834                                 if(DSP2Op0DHasLen)
835                                 {
836                                         DSP2Op0DHasLen=false;
837                                         DSP1.out_count=DSP2Op0DOutLen;
838                                         //execute Op5
839                                         DSP2_Op0D();
840                                 }
841                                 else
842                                 {
843                                         DSP2Op0DInLen=DSP1.parameters[0];
844                                         DSP2Op0DOutLen=DSP1.parameters[1];
845                                         DSP1.in_index=0;
846                                         DSP1.in_count=(DSP2Op0DInLen+1)>>1;
847                                         DSP2Op0DHasLen=true;
848                                         if(byte)
849                                                 DSP1.waiting4command=false;
850                                 }
851                                 break;
852                         case 0x06:
853                                 if(DSP2Op06HasLen)
854                                 {
855                                         DSP2Op06HasLen=false;
856                                         DSP1.out_count=DSP2Op06Len;
857                                         //execute Op5
858                                         DSP2_Op06();
859                                 }
860                                 else
861                                 {
862                                         DSP2Op06Len=DSP1.parameters[0];
863                                         DSP1.in_index=0;
864                                         DSP1.in_count=DSP2Op06Len;
865                                         DSP2Op06HasLen=true;
866                                         if(byte)
867                                                 DSP1.waiting4command=false;
868                                 }
869                                 break;
870                         case 0x01:
871                                 DSP1.out_count=32;
872                                 DSP2_Op01();
873                                 break;
874                         case 0x09:
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);
878                                 DSP1.out_count=4;
879 #ifdef FAST_LSB_WORD_ACCESS
880                 *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2;
881 #else
882                                 uint32 temp;
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;
888 #endif
889                                 break;
890                         case 0x05:
891                                 if(DSP2Op05HasLen)
892                                 {
893                                         DSP2Op05HasLen=false;
894                                         DSP1.out_count=DSP2Op05Len;
895                                         //execute Op5
896                                         DSP2_Op05();
897                                 }
898                                 else
899                                 {
900                                         DSP2Op05Len=DSP1.parameters[0];
901                                         DSP1.in_index=0;
902                                         DSP1.in_count=2*DSP2Op05Len;
903                                         DSP2Op05HasLen=true;
904                                         if(byte)
905                                                 DSP1.waiting4command=false;
906                                 }
907                                 break;
908
909                         case 0x03:
910                                 DSP2Op05Transparent= DSP1.parameters[0];
911                                 //DSP2Op03();
912                                 break;
913                         case 0x0f:
914                                 default:
915                                         break;
916                         }
917                 }
918         }
919 }
920
921 uint8 DSP2GetByte(uint16 address)
922 {
923         uint8 t;
924     if ((address & 0xf000) == 0x6000 ||
925                 (address >= 0x8000 && address < 0xc000))
926     {
927                 if (DSP1.out_count)
928                 {
929                         t = (uint8) DSP1.output [DSP1.out_index];
930                         DSP1.out_index++;
931                         if(DSP1.out_count==DSP1.out_index)
932                                 DSP1.out_count=0;
933                 }
934                 else
935                 {
936                         t = 0xff;
937                 }
938     }
939     else t = 0x80;
940         return t;
941 }
942
943 /*struct SDSP4 {
944     bool8 waiting4command;
945     bool8 half_command;
946     uint16 command;
947     uint32 in_count;
948     uint32 in_index;
949     uint32 out_count;
950     uint32 out_index;
951     uint8 parameters [512];
952     uint8 output [512];
953 };
954
955 SDSP4 DSP4;
956
957 //#include "dsp4emu.cpp"
958
959 bool DSP4_init=FALSE;
960
961 void DSP4SetByte(uint8 byte, uint16 address)
962 {
963         if(!DSP4_init)
964         {
965                 // bootup
966                 DSP4.waiting4command=1;
967                 DSP4_init=TRUE;
968         }
969
970         if ((address & 0xf000) == 0x6000 ||
971                         (address >= 0x8000 && address < 0xc000))
972         {
973                 if(DSP4.out_index<DSP4.out_count)
974                 {
975                         DSP4.out_index++;
976                         return;
977                 }
978
979                 if (DSP4.waiting4command)
980                 {
981                         if(DSP4.half_command)
982                         {
983                                 DSP4.command |= (byte<<8);
984                                 DSP4.in_index = 0;
985                                 DSP4.waiting4command = FALSE;
986         //                      DSP4.first_parameter = TRUE;
987                                 DSP4.half_command=0;
988                                 DSP4.out_count=0;
989                                 DSP4.out_index=0;
990                                 DSP4_Logic=0;
991
992                                 switch (DSP4.command)
993                                 {
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;
1007                                 default:
1008                                         DSP4.waiting4command=TRUE;
1009                                         //printf("(line %d) Unknown Op%02X\n",line,DSP4.command);
1010                                         break;
1011                                 }
1012                         }
1013                         else
1014                         {
1015                                 DSP4.command=byte;
1016                                 DSP4.half_command=1;
1017                         }
1018                 }
1019                 else
1020                 {
1021                         DSP4.parameters [DSP4.in_index] = byte;
1022 //                      DSP4.first_parameter = FALSE;
1023                         DSP4.in_index++;
1024                 }
1025                 
1026                 if (!DSP4.waiting4command && DSP4.in_count==DSP4.in_index)
1027                 {
1028                         //DSP4.parameters [DSP4.in_index] |= (byte << 8);
1029                         // Actually execute the command
1030                         DSP4.waiting4command = TRUE;
1031                         DSP4.out_index = 0;
1032                         DSP4.in_index=0;
1033                         switch (DSP4.command)
1034                         {
1035                         // 16-bit multiplication
1036                         case 0x0000:
1037                                 {
1038                                         int16 multiplier, multiplicand;
1039                                         int product;
1040                                         
1041                                         multiplier = DSP4_READ_WORD(0);
1042                                         multiplicand = DSP4_READ_WORD(2);
1043
1044                                         DSP4_Multiply(multiplicand,multiplier,product);
1045
1046                                         DSP4.out_count = 4;
1047                                         DSP4_WRITE_WORD(0,product);
1048                                         DSP4_WRITE_WORD(2,product>>16);
1049                                 }
1050                                 break;
1051
1052                         // unknown: horizontal mapping command
1053                         case 0x0011:
1054                                 {
1055                                         int16 a,b,c,d,m;
1056
1057                                         a = DSP4_READ_WORD(6);
1058                                         b = DSP4_READ_WORD(4);
1059                                         c = DSP4_READ_WORD(2);
1060                                         d = DSP4_READ_WORD(0);
1061
1062                                         DSP4_UnknownOP11(a,b,c,d,m);
1063
1064                                         DSP4.out_count = 2;
1065                                         DSP4_WRITE_WORD(0,m);
1066                                         break;
1067                                 }
1068
1069                         // track projection
1070                         case 0x0001: DSP4_Op01(); break;
1071
1072                         // track projection (pass 2)
1073                         case 0x0007: DSP4_Op07(); break;
1074
1075                         // zone projections (fuel/repair/lap/teleport/...)
1076                         case 0x0008: DSP4_Op08(); break;
1077
1078                         // sprite transformation
1079                         case 0x0009: DSP4_Op09(); break;
1080
1081                         // fast track projection
1082                         case 0x000D: DSP4_Op0D(); break;
1083
1084                         // single-player selection
1085                         case 0x0003: DSP4_Op03(); break;
1086
1087                         // clear OAM
1088                         case 0x0005:
1089                                 {
1090                                         op06_index = 0;
1091                                         op06_offset = 0;
1092                                         for( int lcv=0; lcv<32; lcv++ )
1093                                                 op06_OAM[lcv] = 0;
1094                                         break;
1095                                 }
1096
1097                         // multi-player selection
1098                         case 0x000E: DSP4_Op0E(); break;
1099
1100 #undef PRINT
1101
1102                         // transfer OAM
1103                         case 0x0006:
1104                                 {
1105                                         DSP4.out_count = 32;
1106                                         for( int lcv=0; lcv<32; lcv++ )
1107                                                 DSP4.output[lcv] = op06_OAM[lcv];
1108                                 }
1109                                 break;
1110
1111                         // unknown
1112                         case 0x000A:
1113                                 {
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;
1118
1119                                         // NOTE: Snes9x only!
1120                                         // For some odd reason, the input nybbles are reversed
1121
1122                                         DSP4_Op0A(in2a,out1a,out2a,out3a,out4a);
1123
1124                                         DSP4.out_count=8;
1125
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);
1132                                 }
1133                                 break;
1134
1135                         // set OAM
1136                         case 0x000B:
1137                                 {
1138                                         int16 sp_x = DSP4_READ_WORD(0);
1139                                         int16 sp_y = DSP4_READ_WORD(2);
1140                                         int16 oam = DSP4_READ_WORD(4);
1141
1142                                         if ((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))
1143                                         {
1144                                                 short Row = (sp_y >> 3) & 0x1f;
1145
1146                                                 if (RowCount[Row] < MaxTilesPerRow)
1147                                                 {
1148                                                         RowCount[Row]++;
1149
1150                                                         // yield OAM output
1151                                                         DSP4.out_count = 6;
1152                                                         DSP4_WRITE_WORD(0,1);
1153
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);
1158
1159                                                         // OAM: size,msb data
1160                                                         DSP4_Op06(0,0);
1161                                                 }
1162                                         }
1163                                 }
1164                                 break;
1165                         
1166                         default: break;
1167                         }
1168                 }
1169         }
1170 }
1171
1172 uint8 DSP4GetByte(uint16 address)
1173 {
1174         uint8 t;
1175         if ((address & 0xf000) == 0x6000 ||
1176                         (address >= 0x8000 && address < 0xc000))
1177         {
1178                 if (DSP4.out_count)
1179                 {
1180                         t = (uint8) DSP4.output [DSP4.out_index];
1181                         DSP4.out_index++;
1182                         if(DSP4.out_count==DSP4.out_index)
1183                                 DSP4.out_count=0;
1184                 }
1185                 else
1186                         t = 0xff;
1187         }
1188         else
1189         {
1190                 t = 0x80;
1191         }
1192
1193         return t;
1194 }
1195 */