dsp1.cpp
   1  #include <Arduino.h>
   2  
   3  /*****************************************************************************\
   4       Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
   5                  This file is licensed under the Snes9x License.
   6     For further information, consult the LICENSE file in the root directory.
   7  \*****************************************************************************/
   8  
   9  /*
  10  Copyright (C) 1997-2006 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
  11  
  12  http://www.zsnes.com
  13  http://sourceforge.net/projects/zsnes
  14  
  15  This program is free software; you can redistribute it and/or
  16  modify it under the terms of the GNU General Public License
  17  version 2 as published by the Free Software Foundation.
  18  
  19  This program is distributed in the hope that it will be useful,
  20  but WITHOUT ANY WARRANTY; without even the implied warranty of
  21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22  GNU General Public License for more details.
  23  
  24  You should have received a copy of the GNU General Public License
  25  along with this program; if not, write to the Free Software
  26  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27  */
  28  
  29  
  30  #include "snes9x.h"
  31  #include "memory.h"
  32  
  33  #ifdef DEBUGGER
  34  //#define DebugDSP1
  35  #endif
  36  
  37  #ifdef DebugDSP1
  38  #include <stdarg.h>
  39  static FILE	*LogFile = NULL;
  40  #endif
  41  
  42  
  43  PROGMEM static const uint16	DSP1ROM[1024] =
  44  {
  45  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  46  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  47  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  48  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  49  	 0x0000,  0x0000,  0x0001,  0x0002,  0x0004,  0x0008,  0x0010,  0x0020,
  50  	 0x0040,  0x0080,  0x0100,  0x0200,  0x0400,  0x0800,  0x1000,  0x2000,
  51  	 0x4000,  0x7fff,  0x4000,  0x2000,  0x1000,  0x0800,  0x0400,  0x0200,
  52  	 0x0100,  0x0080,  0x0040,  0x0020,  0x0001,  0x0008,  0x0004,  0x0002,
  53  	 0x0001,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  54  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  55  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  56  	 0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,  0x0000,
  57  	 0x0000,  0x0000,  0x8000,  0xffe5,  0x0100,  0x7fff,  0x7f02,  0x7e08,
  58  	 0x7d12,  0x7c1f,  0x7b30,  0x7a45,  0x795d,  0x7878,  0x7797,  0x76ba,
  59  	 0x75df,  0x7507,  0x7433,  0x7361,  0x7293,  0x71c7,  0x70fe,  0x7038,
  60  	 0x6f75,  0x6eb4,  0x6df6,  0x6d3a,  0x6c81,  0x6bca,  0x6b16,  0x6a64,
  61  	 0x69b4,  0x6907,  0x685b,  0x67b2,  0x670b,  0x6666,  0x65c4,  0x6523,
  62  	 0x6484,  0x63e7,  0x634c,  0x62b3,  0x621c,  0x6186,  0x60f2,  0x6060,
  63  	 0x5fd0,  0x5f41,  0x5eb5,  0x5e29,  0x5d9f,  0x5d17,  0x5c91,  0x5c0c,
  64  	 0x5b88,  0x5b06,  0x5a85,  0x5a06,  0x5988,  0x590b,  0x5890,  0x5816,
  65  	 0x579d,  0x5726,  0x56b0,  0x563b,  0x55c8,  0x5555,  0x54e4,  0x5474,
  66  	 0x5405,  0x5398,  0x532b,  0x52bf,  0x5255,  0x51ec,  0x5183,  0x511c,
  67  	 0x50b6,  0x5050,  0x4fec,  0x4f89,  0x4f26,  0x4ec5,  0x4e64,  0x4e05,
  68  	 0x4da6,  0x4d48,  0x4cec,  0x4c90,  0x4c34,  0x4bda,  0x4b81,  0x4b28,
  69  	 0x4ad0,  0x4a79,  0x4a23,  0x49cd,  0x4979,  0x4925,  0x48d1,  0x487f,
  70  	 0x482d,  0x47dc,  0x478c,  0x473c,  0x46ed,  0x469f,  0x4651,  0x4604,
  71  	 0x45b8,  0x456c,  0x4521,  0x44d7,  0x448d,  0x4444,  0x43fc,  0x43b4,
  72  	 0x436d,  0x4326,  0x42e0,  0x429a,  0x4255,  0x4211,  0x41cd,  0x4189,
  73  	 0x4146,  0x4104,  0x40c2,  0x4081,  0x4040,  0x3fff,  0x41f7,  0x43e1,
  74  	 0x45bd,  0x478d,  0x4951,  0x4b0b,  0x4cbb,  0x4e61,  0x4fff,  0x5194,
  75  	 0x5322,  0x54a9,  0x5628,  0x57a2,  0x5914,  0x5a81,  0x5be9,  0x5d4a,
  76  	 0x5ea7,  0x5fff,  0x6152,  0x62a0,  0x63ea,  0x6530,  0x6672,  0x67b0,
  77  	 0x68ea,  0x6a20,  0x6b53,  0x6c83,  0x6daf,  0x6ed9,  0x6fff,  0x7122,
  78  	 0x7242,  0x735f,  0x747a,  0x7592,  0x76a7,  0x77ba,  0x78cb,  0x79d9,
  79  	 0x7ae5,  0x7bee,  0x7cf5,  0x7dfa,  0x7efe,  0x7fff,  0x0000,  0x0324,
  80  	 0x0647,  0x096a,  0x0c8b,  0x0fab,  0x12c8,  0x15e2,  0x18f8,  0x1c0b,
  81  	 0x1f19,  0x2223,  0x2528,  0x2826,  0x2b1f,  0x2e11,  0x30fb,  0x33de,
  82  	 0x36ba,  0x398c,  0x3c56,  0x3f17,  0x41ce,  0x447a,  0x471c,  0x49b4,
  83  	 0x4c3f,  0x4ebf,  0x5133,  0x539b,  0x55f5,  0x5842,  0x5a82,  0x5cb4,
  84  	 0x5ed7,  0x60ec,  0x62f2,  0x64e8,  0x66cf,  0x68a6,  0x6a6d,  0x6c24,
  85  	 0x6dca,  0x6f5f,  0x70e2,  0x7255,  0x73b5,  0x7504,  0x7641,  0x776c,
  86  	 0x7884,  0x798a,  0x7a7d,  0x7b5d,  0x7c29,  0x7ce3,  0x7d8a,  0x7e1d,
  87  	 0x7e9d,  0x7f09,  0x7f62,  0x7fa7,  0x7fd8,  0x7ff6,  0x7fff,  0x7ff6,
  88  	 0x7fd8,  0x7fa7,  0x7f62,  0x7f09,  0x7e9d,  0x7e1d,  0x7d8a,  0x7ce3,
  89  	 0x7c29,  0x7b5d,  0x7a7d,  0x798a,  0x7884,  0x776c,  0x7641,  0x7504,
  90  	 0x73b5,  0x7255,  0x70e2,  0x6f5f,  0x6dca,  0x6c24,  0x6a6d,  0x68a6,
  91  	 0x66cf,  0x64e8,  0x62f2,  0x60ec,  0x5ed7,  0x5cb4,  0x5a82,  0x5842,
  92  	 0x55f5,  0x539b,  0x5133,  0x4ebf,  0x4c3f,  0x49b4,  0x471c,  0x447a,
  93  	 0x41ce,  0x3f17,  0x3c56,  0x398c,  0x36ba,  0x33de,  0x30fb,  0x2e11,
  94  	 0x2b1f,  0x2826,  0x2528,  0x2223,  0x1f19,  0x1c0b,  0x18f8,  0x15e2,
  95  	 0x12c8,  0x0fab,  0x0c8b,  0x096a,  0x0647,  0x0324,  0x7fff,  0x7ff6,
  96  	 0x7fd8,  0x7fa7,  0x7f62,  0x7f09,  0x7e9d,  0x7e1d,  0x7d8a,  0x7ce3,
  97  	 0x7c29,  0x7b5d,  0x7a7d,  0x798a,  0x7884,  0x776c,  0x7641,  0x7504,
  98  	 0x73b5,  0x7255,  0x70e2,  0x6f5f,  0x6dca,  0x6c24,  0x6a6d,  0x68a6,
  99  	 0x66cf,  0x64e8,  0x62f2,  0x60ec,  0x5ed7,  0x5cb4,  0x5a82,  0x5842,
 100  	 0x55f5,  0x539b,  0x5133,  0x4ebf,  0x4c3f,  0x49b4,  0x471c,  0x447a,
 101  	 0x41ce,  0x3f17,  0x3c56,  0x398c,  0x36ba,  0x33de,  0x30fb,  0x2e11,
 102  	 0x2b1f,  0x2826,  0x2528,  0x2223,  0x1f19,  0x1c0b,  0x18f8,  0x15e2,
 103  	 0x12c8,  0x0fab,  0x0c8b,  0x096a,  0x0647,  0x0324,  0x0000,  0xfcdc,
 104  	 0xf9b9,  0xf696,  0xf375,  0xf055,  0xed38,  0xea1e,  0xe708,  0xe3f5,
 105  	 0xe0e7,  0xdddd,  0xdad8,  0xd7da,  0xd4e1,  0xd1ef,  0xcf05,  0xcc22,
 106  	 0xc946,  0xc674,  0xc3aa,  0xc0e9,  0xbe32,  0xbb86,  0xb8e4,  0xb64c,
 107  	 0xb3c1,  0xb141,  0xaecd,  0xac65,  0xaa0b,  0xa7be,  0xa57e,  0xa34c,
 108  	 0xa129,  0x9f14,  0x9d0e,  0x9b18,  0x9931,  0x975a,  0x9593,  0x93dc,
 109  	 0x9236,  0x90a1,  0x8f1e,  0x8dab,  0x8c4b,  0x8afc,  0x89bf,  0x8894,
 110  	 0x877c,  0x8676,  0x8583,  0x84a3,  0x83d7,  0x831d,  0x8276,  0x81e3,
 111  	 0x8163,  0x80f7,  0x809e,  0x8059,  0x8028,  0x800a,  0x6488,  0x0080,
 112  	 0x03ff,  0x0116,  0x0002,  0x0080,  0x4000,  0x3fd7,  0x3faf,  0x3f86,
 113  	 0x3f5d,  0x3f34,  0x3f0c,  0x3ee3,  0x3eba,  0x3e91,  0x3e68,  0x3e40,
 114  	 0x3e17,  0x3dee,  0x3dc5,  0x3d9c,  0x3d74,  0x3d4b,  0x3d22,  0x3cf9,
 115  	 0x3cd0,  0x3ca7,  0x3c7f,  0x3c56,  0x3c2d,  0x3c04,  0x3bdb,  0x3bb2,
 116  	 0x3b89,  0x3b60,  0x3b37,  0x3b0e,  0x3ae5,  0x3abc,  0x3a93,  0x3a69,
 117  	 0x3a40,  0x3a17,  0x39ee,  0x39c5,  0x399c,  0x3972,  0x3949,  0x3920,
 118  	 0x38f6,  0x38cd,  0x38a4,  0x387a,  0x3851,  0x3827,  0x37fe,  0x37d4,
 119  	 0x37aa,  0x3781,  0x3757,  0x372d,  0x3704,  0x36da,  0x36b0,  0x3686,
 120  	 0x365c,  0x3632,  0x3609,  0x35df,  0x35b4,  0x358a,  0x3560,  0x3536,
 121  	 0x350c,  0x34e1,  0x34b7,  0x348d,  0x3462,  0x3438,  0x340d,  0x33e3,
 122  	 0x33b8,  0x338d,  0x3363,  0x3338,  0x330d,  0x32e2,  0x32b7,  0x328c,
 123  	 0x3261,  0x3236,  0x320b,  0x31df,  0x31b4,  0x3188,  0x315d,  0x3131,
 124  	 0x3106,  0x30da,  0x30ae,  0x3083,  0x3057,  0x302b,  0x2fff,  0x2fd2,
 125  	 0x2fa6,  0x2f7a,  0x2f4d,  0x2f21,  0x2ef4,  0x2ec8,  0x2e9b,  0x2e6e,
 126  	 0x2e41,  0x2e14,  0x2de7,  0x2dba,  0x2d8d,  0x2d60,  0x2d32,  0x2d05,
 127  	 0x2cd7,  0x2ca9,  0x2c7b,  0x2c4d,  0x2c1f,  0x2bf1,  0x2bc3,  0x2b94,
 128  	 0x2b66,  0x2b37,  0x2b09,  0x2ada,  0x2aab,  0x2a7c,  0x2a4c,  0x2a1d,
 129  	 0x29ed,  0x29be,  0x298e,  0x295e,  0x292e,  0x28fe,  0x28ce,  0x289d,
 130  	 0x286d,  0x283c,  0x280b,  0x27da,  0x27a9,  0x2777,  0x2746,  0x2714,
 131  	 0x26e2,  0x26b0,  0x267e,  0x264c,  0x2619,  0x25e7,  0x25b4,  0x2581,
 132  	 0x254d,  0x251a,  0x24e6,  0x24b2,  0x247e,  0x244a,  0x2415,  0x23e1,
 133  	 0x23ac,  0x2376,  0x2341,  0x230b,  0x22d6,  0x229f,  0x2269,  0x2232,
 134  	 0x21fc,  0x21c4,  0x218d,  0x2155,  0x211d,  0x20e5,  0x20ad,  0x2074,
 135  	 0x203b,  0x2001,  0x1fc7,  0x1f8d,  0x1f53,  0x1f18,  0x1edd,  0x1ea1,
 136  	 0x1e66,  0x1e29,  0x1ded,  0x1db0,  0x1d72,  0x1d35,  0x1cf6,  0x1cb8,
 137  	 0x1c79,  0x1c39,  0x1bf9,  0x1bb8,  0x1b77,  0x1b36,  0x1af4,  0x1ab1,
 138  	 0x1a6e,  0x1a2a,  0x19e6,  0x19a1,  0x195c,  0x1915,  0x18ce,  0x1887,
 139  	 0x183f,  0x17f5,  0x17ac,  0x1761,  0x1715,  0x16c9,  0x167c,  0x162e,
 140  	 0x15df,  0x158e,  0x153d,  0x14eb,  0x1497,  0x1442,  0x13ec,  0x1395,
 141  	 0x133c,  0x12e2,  0x1286,  0x1228,  0x11c9,  0x1167,  0x1104,  0x109e,
 142  	 0x1036,  0x0fcc,  0x0f5f,  0x0eef,  0x0e7b,  0x0e04,  0x0d89,  0x0d0a,
 143  	 0x0c86,  0x0bfd,  0x0b6d,  0x0ad6,  0x0a36,  0x098d,  0x08d7,  0x0811,
 144  	 0x0736,  0x063e,  0x0519,  0x039a,  0x0000,  0x7fff,  0x0100,  0x0080,
 145  	 0x021d,  0x00c8,  0x00ce,  0x0048,  0x0a26,  0x277a,  0x00ce,  0x6488,
 146  	 0x14ac,  0x0001,  0x00f9,  0x00fc,  0x00ff,  0x00fc,  0x00f9,  0xffff,
 147  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 148  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 149  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 150  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 151  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 152  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 153  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 154  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 155  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 156  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 157  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 158  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 159  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 160  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 161  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 162  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 163  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 164  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 165  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 166  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 167  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 168  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 169  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 170  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 171  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,
 172  	 0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff,  0xffff
 173  };
 174  
 175  PROGMEM static const int16	DSP1_MulTable[256] =
 176  {
 177  	 0x0000,  0x0003,  0x0006,  0x0009,  0x000c,  0x000f,  0x0012,  0x0015,
 178  	 0x0019,  0x001c,  0x001f,  0x0022,  0x0025,  0x0028,  0x002b,  0x002f,
 179  	 0x0032,  0x0035,  0x0038,  0x003b,  0x003e,  0x0041,  0x0045,  0x0048,
 180  	 0x004b,  0x004e,  0x0051,  0x0054,  0x0057,  0x005b,  0x005e,  0x0061,
 181  	 0x0064,  0x0067,  0x006a,  0x006d,  0x0071,  0x0074,  0x0077,  0x007a,
 182  	 0x007d,  0x0080,  0x0083,  0x0087,  0x008a,  0x008d,  0x0090,  0x0093,
 183  	 0x0096,  0x0099,  0x009d,  0x00a0,  0x00a3,  0x00a6,  0x00a9,  0x00ac,
 184  	 0x00af,  0x00b3,  0x00b6,  0x00b9,  0x00bc,  0x00bf,  0x00c2,  0x00c5,
 185  	 0x00c9,  0x00cc,  0x00cf,  0x00d2,  0x00d5,  0x00d8,  0x00db,  0x00df,
 186  	 0x00e2,  0x00e5,  0x00e8,  0x00eb,  0x00ee,  0x00f1,  0x00f5,  0x00f8,
 187  	 0x00fb,  0x00fe,  0x0101,  0x0104,  0x0107,  0x010b,  0x010e,  0x0111,
 188  	 0x0114,  0x0117,  0x011a,  0x011d,  0x0121,  0x0124,  0x0127,  0x012a,
 189  	 0x012d,  0x0130,  0x0133,  0x0137,  0x013a,  0x013d,  0x0140,  0x0143,
 190  	 0x0146,  0x0149,  0x014d,  0x0150,  0x0153,  0x0156,  0x0159,  0x015c,
 191  	 0x015f,  0x0163,  0x0166,  0x0169,  0x016c,  0x016f,  0x0172,  0x0175,
 192  	 0x0178,  0x017c,  0x017f,  0x0182,  0x0185,  0x0188,  0x018b,  0x018e,
 193  	 0x0192,  0x0195,  0x0198,  0x019b,  0x019e,  0x01a1,  0x01a4,  0x01a8,
 194  	 0x01ab,  0x01ae,  0x01b1,  0x01b4,  0x01b7,  0x01ba,  0x01be,  0x01c1,
 195  	 0x01c4,  0x01c7,  0x01ca,  0x01cd,  0x01d0,  0x01d4,  0x01d7,  0x01da,
 196  	 0x01dd,  0x01e0,  0x01e3,  0x01e6,  0x01ea,  0x01ed,  0x01f0,  0x01f3,
 197  	 0x01f6,  0x01f9,  0x01fc,  0x0200,  0x0203,  0x0206,  0x0209,  0x020c,
 198  	 0x020f,  0x0212,  0x0216,  0x0219,  0x021c,  0x021f,  0x0222,  0x0225,
 199  	 0x0228,  0x022c,  0x022f,  0x0232,  0x0235,  0x0238,  0x023b,  0x023e,
 200  	 0x0242,  0x0245,  0x0248,  0x024b,  0x024e,  0x0251,  0x0254,  0x0258,
 201  	 0x025b,  0x025e,  0x0261,  0x0264,  0x0267,  0x026a,  0x026e,  0x0271,
 202  	 0x0274,  0x0277,  0x027a,  0x027d,  0x0280,  0x0284,  0x0287,  0x028a,
 203  	 0x028d,  0x0290,  0x0293,  0x0296,  0x029a,  0x029d,  0x02a0,  0x02a3,
 204  	 0x02a6,  0x02a9,  0x02ac,  0x02b0,  0x02b3,  0x02b6,  0x02b9,  0x02bc,
 205  	 0x02bf,  0x02c2,  0x02c6,  0x02c9,  0x02cc,  0x02cf,  0x02d2,  0x02d5,
 206  	 0x02d8,  0x02db,  0x02df,  0x02e2,  0x02e5,  0x02e8,  0x02eb,  0x02ee,
 207  	 0x02f1,  0x02f5,  0x02f8,  0x02fb,  0x02fe,  0x0301,  0x0304,  0x0307,
 208  	 0x030b,  0x030e,  0x0311,  0x0314,  0x0317,  0x031a,  0x031d,  0x0321
 209  };
 210  
 211  PROGMEM static const int16	DSP1_SinTable[256] =
 212  {
 213  	 0x0000,  0x0324,  0x0647,  0x096a,  0x0c8b,  0x0fab,  0x12c8,  0x15e2,
 214  	 0x18f8,  0x1c0b,  0x1f19,  0x2223,  0x2528,  0x2826,  0x2b1f,  0x2e11,
 215  	 0x30fb,  0x33de,  0x36ba,  0x398c,  0x3c56,  0x3f17,  0x41ce,  0x447a,
 216  	 0x471c,  0x49b4,  0x4c3f,  0x4ebf,  0x5133,  0x539b,  0x55f5,  0x5842,
 217  	 0x5a82,  0x5cb4,  0x5ed7,  0x60ec,  0x62f2,  0x64e8,  0x66cf,  0x68a6,
 218  	 0x6a6d,  0x6c24,  0x6dca,  0x6f5f,  0x70e2,  0x7255,  0x73b5,  0x7504,
 219  	 0x7641,  0x776c,  0x7884,  0x798a,  0x7a7d,  0x7b5d,  0x7c29,  0x7ce3,
 220  	 0x7d8a,  0x7e1d,  0x7e9d,  0x7f09,  0x7f62,  0x7fa7,  0x7fd8,  0x7ff6,
 221  	 0x7fff,  0x7ff6,  0x7fd8,  0x7fa7,  0x7f62,  0x7f09,  0x7e9d,  0x7e1d,
 222  	 0x7d8a,  0x7ce3,  0x7c29,  0x7b5d,  0x7a7d,  0x798a,  0x7884,  0x776c,
 223  	 0x7641,  0x7504,  0x73b5,  0x7255,  0x70e2,  0x6f5f,  0x6dca,  0x6c24,
 224  	 0x6a6d,  0x68a6,  0x66cf,  0x64e8,  0x62f2,  0x60ec,  0x5ed7,  0x5cb4,
 225  	 0x5a82,  0x5842,  0x55f5,  0x539b,  0x5133,  0x4ebf,  0x4c3f,  0x49b4,
 226  	 0x471c,  0x447a,  0x41ce,  0x3f17,  0x3c56,  0x398c,  0x36ba,  0x33de,
 227  	 0x30fb,  0x2e11,  0x2b1f,  0x2826,  0x2528,  0x2223,  0x1f19,  0x1c0b,
 228  	 0x18f8,  0x15e2,  0x12c8,  0x0fab,  0x0c8b,  0x096a,  0x0647,  0x0324,
 229  	-0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2,
 230  	-0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
 231  	-0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a,
 232  	-0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
 233  	-0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6,
 234  	-0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504,
 235  	-0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3,
 236  	-0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6,
 237  	-0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d,
 238  	-0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c,
 239  	-0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24,
 240  	-0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4,
 241  	-0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4,
 242  	-0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de,
 243  	-0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b,
 244  	-0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324
 245  };
 246  
 247  
 248  #ifdef DebugDSP1
 249  
 250  static void Log_Message (const char *Message, ...)
 251  {
 252  	char	Msg[400];
 253  	va_list	ap;
 254  	size_t	ignore;
 255  
 256  	va_start(ap, Message);
 257  	vsprintf(Msg, Message, ap);
 258  	va_end(ap);
 259  
 260  	strcat(Msg, "\r\n\0");
 261  	ignore = fwrite(Msg, strlen(Msg), 1, LogFile);
 262  	fflush(LogFile);
 263  }
 264  
 265  static void Start_Log (void)
 266  {
 267  	LogFile = fopen("dsp1emu.log", "wb");
 268  }
 269  
 270  static void Stop_Log (void)
 271  {
 272  	if (LogFile)
 273  	{
 274  		fclose(LogFile);
 275  		LogFile = NULL;
 276  	}
 277  }
 278  
 279  #endif
 280  
 281  static void DSP1_Op00 (void)
 282  {
 283  	DSP1.Op00Result = DSP1.Op00Multiplicand * DSP1.Op00Multiplier >> 15;
 284  
 285  #ifdef DebugDSP1
 286  	Log_Message("OP00 MULT %d*%d/32768=%d", DSP1.Op00Multiplicand, DSP1.Op00Multiplier, DSP1.Op00Result);
 287  #endif
 288  }
 289  
 290  static void DSP1_Op20 (void)
 291  {
 292  	DSP1.Op20Result = DSP1.Op20Multiplicand * DSP1.Op20Multiplier >> 15;
 293  	DSP1.Op20Result++;
 294  
 295  #ifdef DebugDSP1
 296  	Log_Message("OP20 MULT %d*%d/32768=%d", DSP1.Op20Multiplicand, DSP1.Op20Multiplier, DSP1.Op20Result);
 297  #endif
 298  }
 299  
 300  static void DSP1_Inverse (int16 Coefficient, int16 Exponent, int16 *iCoefficient, int16 *iExponent)
 301  {
 302  	// Step One: Division by Zero
 303  	if (Coefficient == 0x0000)
 304  	{
 305  		*iCoefficient = 0x7fff;
 306  		*iExponent    = 0x002f;
 307  	}
 308  	else
 309  	{
 310  		int16	Sign = 1;
 311  
 312  		// Step Two: Remove Sign
 313  		if (Coefficient < 0)
 314  		{
 315  			if (Coefficient < -32767)
 316  				Coefficient = -32767;
 317  			Coefficient = -Coefficient;
 318  			Sign = -1;
 319  		}
 320  
 321  		// Step Three: Normalize
 322  		while (Coefficient < 0x4000)
 323  		{
 324  			Coefficient <<= 1;
 325  			Exponent--;
 326  		}
 327  
 328  		// Step Four: Special Case
 329  		if (Coefficient == 0x4000)
 330  		{
 331  			if (Sign == 1)
 332  				*iCoefficient =  0x7fff;
 333  			else
 334  			{
 335  				*iCoefficient = -0x4000;
 336  				Exponent--;
 337  			}
 338  		}
 339  		else
 340  		{
 341  			// Step Five: Initial Guess
 342  			int16	i = DSP1ROM[((Coefficient - 0x4000) >> 7) + 0x0065];
 343  
 344  			// Step Six: Iterate "estimated" Newton's Method
 345  			i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
 346  			i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
 347  
 348  			*iCoefficient = i * Sign;
 349  		}
 350  
 351  		*iExponent = 1 - Exponent;
 352  	}
 353  }
 354  
 355  static void DSP1_Op10 (void)
 356  {
 357  	DSP1_Inverse(DSP1.Op10Coefficient, DSP1.Op10Exponent, &DSP1.Op10CoefficientR, &DSP1.Op10ExponentR);
 358  
 359  #ifdef DebugDSP1
 360  	Log_Message("OP10 INV %d*2^%d = %d*2^%d", DSP1.Op10Coefficient, DSP1.Op10Exponent, DSP1.Op10CoefficientR, DSP1.Op10ExponentR);
 361  #endif
 362  }
 363  
 364  static int16 DSP1_Sin (int16 Angle)
 365  {
 366  	int32	S;
 367  
 368  	if (Angle < 0)
 369  	{
 370  		if (Angle == -32768)
 371  			return (0);
 372  
 373  		return (-DSP1_Sin(-Angle));
 374  	}
 375  
 376  	S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15);
 377  	if (S > 32767)
 378  		S = 32767;
 379  
 380  	return ((int16) S);
 381  }
 382  
 383  static int16 DSP1_Cos (int16 Angle)
 384  {
 385  	int32	S;
 386  
 387  	if (Angle < 0)
 388  	{
 389  		if (Angle == -32768)
 390  			return (-32768);
 391  
 392  		Angle = -Angle;
 393  	}
 394  
 395  	S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15);
 396  	if (S < -32768)
 397  		S = -32767;
 398  
 399  	return ((int16) S);
 400  }
 401  
 402  static void DSP1_Normalize (int16 m, int16 *Coefficient, int16 *Exponent)
 403  {
 404  	int16	i = 0x4000;
 405  	int16	e = 0;
 406  
 407  	if (m < 0)
 408  	{
 409  		while ((m & i) && i)
 410  		{
 411  			i >>= 1;
 412  			e++;
 413  		}
 414  	}
 415  	else
 416  	{
 417  		while (!(m & i) && i)
 418  		{
 419  			i >>= 1;
 420  			e++;
 421  		}
 422  	}
 423  
 424  	if (e > 0)
 425  		*Coefficient = m * DSP1ROM[0x21 + e] << 1;
 426  	else
 427  		*Coefficient = m;
 428  
 429  	*Exponent -= e;
 430  }
 431  
 432  static void DSP1_NormalizeDouble (int32 Product, int16 *Coefficient, int16 *Exponent)
 433  {
 434  	int16	n = Product & 0x7fff;
 435  	int16	m = Product >> 15;
 436  	int16	i = 0x4000;
 437  	int16	e = 0;
 438  
 439  	if (m < 0)
 440  	{
 441  		while ((m & i) && i)
 442  		{
 443  			i >>= 1;
 444  			e++;
 445  		}
 446  	}
 447  	else
 448  	{
 449  		while (!(m & i) && i)
 450  		{
 451  			i >>= 1;
 452  			e++;
 453  		}
 454  	}
 455  
 456  	if (e > 0)
 457  	{
 458  		*Coefficient = m * DSP1ROM[0x0021 + e] << 1;
 459  
 460  		if (e < 15)
 461  			*Coefficient += n * DSP1ROM[0x0040 - e] >> 15;
 462  		else
 463  		{
 464  			i = 0x4000;
 465  
 466  			if (m < 0)
 467  			{
 468  				while ((n & i) && i)
 469  				{
 470  					i >>= 1;
 471  					e++;
 472  				}
 473  			}
 474  			else
 475  			{
 476  				while (!(n & i) && i)
 477  				{
 478  					i >>= 1;
 479  					e++;
 480  				}
 481  			}
 482  
 483  			if (e > 15)
 484  				*Coefficient = n * DSP1ROM[0x0012 + e] << 1;
 485  			else
 486  				*Coefficient += n;
 487  		}
 488  	}
 489  	else
 490  		*Coefficient = m;
 491  
 492  	*Exponent = e;
 493  }
 494  
 495  static int16 DSP1_Truncate (int16 C, int16 E)
 496  {
 497  	if (E > 0)
 498  	{
 499  		if (C > 0)
 500  			return (32767);
 501  		else
 502  		if (C < 0)
 503  			return (-32767);
 504  	}
 505  	else
 506  	{
 507  		if (E < 0)
 508  			return (C * DSP1ROM[0x0031 + E] >> 15);
 509  	}
 510  
 511  	return (C);
 512  }
 513  
 514  static void DSP1_Op04 (void)
 515  {
 516  	DSP1.Op04Sin = DSP1_Sin(DSP1.Op04Angle) * DSP1.Op04Radius >> 15;
 517  	DSP1.Op04Cos = DSP1_Cos(DSP1.Op04Angle) * DSP1.Op04Radius >> 15;
 518  }
 519  
 520  static void DSP1_Op0C (void)
 521  {
 522  	DSP1.Op0CX2 = (DSP1.Op0CY1 * DSP1_Sin(DSP1.Op0CA) >> 15) + (DSP1.Op0CX1 * DSP1_Cos(DSP1.Op0CA) >> 15);
 523  	DSP1.Op0CY2 = (DSP1.Op0CY1 * DSP1_Cos(DSP1.Op0CA) >> 15) - (DSP1.Op0CX1 * DSP1_Sin(DSP1.Op0CA) >> 15);
 524  }
 525  
 526  static void DSP1_Parameter (int16 Fx, int16 Fy, int16 Fz, int16 Lfe, int16 Les, int16 Aas, int16 Azs, int16 *Vof, int16 *Vva, int16 *Cx, int16 *Cy)
 527  {
 528  	const int16	MaxAZS_Exp[16] =
 529  	{
 530  		0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca,
 531  		0x38ce,	0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4
 532  	};
 533  
 534  	int16	CSec, C, E, MaxAZS, Aux;
 535  	int16	LfeNx, LfeNy, LfeNz;
 536  	int16	LesNx, LesNy, LesNz;
 537  	int16	CentreZ;
 538  
 539  	// Copy Zenith angle for clipping
 540  	int16	AZS = Azs;
 541  
 542  	// Store Sine and Cosine of Azimuth and Zenith angle
 543  	DSP1.SinAas = DSP1_Sin(Aas);
 544  	DSP1.CosAas = DSP1_Cos(Aas);
 545  	DSP1.SinAzs = DSP1_Sin(Azs);
 546  	DSP1.CosAzs = DSP1_Cos(Azs);
 547  
 548  	DSP1.Nx = DSP1.SinAzs * -DSP1.SinAas >> 15;
 549  	DSP1.Ny = DSP1.SinAzs *  DSP1.CosAas >> 15;
 550  	DSP1.Nz = DSP1.CosAzs *  0x7fff >> 15;
 551  
 552  	LfeNx = Lfe * DSP1.Nx >> 15;
 553  	LfeNy = Lfe * DSP1.Ny >> 15;
 554  	LfeNz = Lfe * DSP1.Nz >> 15;
 555  
 556  	// Center of Projection
 557  	DSP1.CentreX = Fx + LfeNx;
 558  	DSP1.CentreY = Fy + LfeNy;
 559  	CentreZ = Fz + LfeNz;
 560  
 561  	LesNx = Les * DSP1.Nx >> 15;
 562  	LesNy = Les * DSP1.Ny >> 15;
 563  	LesNz = Les * DSP1.Nz >> 15;
 564  
 565  	DSP1.Gx = DSP1.CentreX - LesNx;
 566  	DSP1.Gy = DSP1.CentreY - LesNy;
 567  	DSP1.Gz = CentreZ - LesNz;
 568  
 569  	DSP1.E_Les = 0;
 570  	DSP1_Normalize(Les, &DSP1.C_Les, &DSP1.E_Les);
 571  	DSP1.G_Les = Les;
 572  
 573  	E = 0;
 574  	DSP1_Normalize(CentreZ, &C, &E);
 575  
 576  	DSP1.VPlane_C = C;
 577  	DSP1.VPlane_E = E;
 578  
 579  	// Determine clip boundary and clip Zenith angle if necessary
 580  	MaxAZS = MaxAZS_Exp[-E];
 581  
 582  	if (AZS < 0)
 583  	{
 584  		MaxAZS = -MaxAZS;
 585  		if (AZS < MaxAZS + 1)
 586  			AZS = MaxAZS + 1;
 587  	}
 588  	else
 589  	{
 590  		if (AZS > MaxAZS)
 591  			AZS = MaxAZS;
 592  	}
 593  
 594  	// Store Sine and Cosine of clipped Zenith angle
 595  	DSP1.SinAZS = DSP1_Sin(AZS);
 596  	DSP1.CosAZS = DSP1_Cos(AZS);
 597  
 598  	DSP1_Inverse(DSP1.CosAZS, 0, &DSP1.SecAZS_C1, &DSP1.SecAZS_E1);
 599  	DSP1_Normalize(C * DSP1.SecAZS_C1 >> 15, &C, &E);
 600  	E += DSP1.SecAZS_E1;
 601  
 602  	C = DSP1_Truncate(C, E) * DSP1.SinAZS >> 15;
 603  
 604  	DSP1.CentreX += C * DSP1.SinAas >> 15;
 605  	DSP1.CentreY -= C * DSP1.CosAas >> 15;
 606  
 607  	*Cx = DSP1.CentreX;
 608  	*Cy = DSP1.CentreY;
 609  
 610  	// Raster number of imaginary center and horizontal line
 611  	*Vof = 0;
 612  
 613  	if ((Azs != AZS) || (Azs == MaxAZS))
 614  	{
 615  		if (Azs == -32768)
 616  			Azs = -32767;
 617  
 618  		C = Azs - MaxAZS;
 619  		if (C >= 0)
 620  			C--;
 621  		Aux = ~(C << 2);
 622  
 623  		C = Aux * DSP1ROM[0x0328] >> 15;
 624  		C = (C * Aux >> 15) + DSP1ROM[0x0327];
 625  		*Vof -= (C * Aux >> 15) * Les >> 15;
 626  
 627  		C = Aux * Aux >> 15;
 628  		Aux = (C * DSP1ROM[0x0324] >> 15) + DSP1ROM[0x0325];
 629  		DSP1.CosAZS += (C * Aux >> 15) * DSP1.CosAZS >> 15;
 630  	}
 631  
 632  	DSP1.VOffset = Les * DSP1.CosAZS >> 15;
 633  
 634  	DSP1_Inverse(DSP1.SinAZS, 0, &CSec, &E);
 635  	DSP1_Normalize(DSP1.VOffset, &C, &E);
 636  	DSP1_Normalize(C * CSec >> 15, &C, &E);
 637  
 638  	if (C == -32768)
 639  	{
 640  		C >>= 1;
 641  		E++;
 642  	}
 643  
 644  	*Vva = DSP1_Truncate(-C, E);
 645  
 646  	// Store Secant of clipped Zenith angle
 647  	DSP1_Inverse(DSP1.CosAZS, 0, &DSP1.SecAZS_C2, &DSP1.SecAZS_E2);
 648  }
 649  
 650  static void DSP1_Raster (int16 Vs, int16 *An, int16 *Bn, int16 *Cn, int16 *Dn)
 651  {
 652  	int16	C, E, C1, E1;
 653  
 654  	DSP1_Inverse((Vs * DSP1.SinAzs >> 15) + DSP1.VOffset, 7, &C, &E);
 655  	E += DSP1.VPlane_E;
 656  
 657  	C1 = C * DSP1.VPlane_C >> 15;
 658  	E1 = E + DSP1.SecAZS_E2;
 659  
 660  	DSP1_Normalize(C1, &C, &E);
 661  
 662  	C = DSP1_Truncate(C, E);
 663  
 664  	*An = C *  DSP1.CosAas >> 15;
 665  	*Cn = C *  DSP1.SinAas >> 15;
 666  
 667  	DSP1_Normalize(C1 * DSP1.SecAZS_C2 >> 15, &C, &E1);
 668  
 669  	C = DSP1_Truncate(C, E1);
 670  
 671  	*Bn = C * -DSP1.SinAas >> 15;
 672  	*Dn = C *  DSP1.CosAas >> 15;
 673  }
 674  
 675  static void DSP1_Op02 (void)
 676  {
 677  	DSP1_Parameter(DSP1.Op02FX, DSP1.Op02FY, DSP1.Op02FZ, DSP1.Op02LFE, DSP1.Op02LES, DSP1.Op02AAS, DSP1.Op02AZS, &DSP1.Op02VOF, &DSP1.Op02VVA, &DSP1.Op02CX, &DSP1.Op02CY);
 678  }
 679  
 680  static void DSP1_Op0A (void)
 681  {
 682  	DSP1_Raster(DSP1.Op0AVS, &DSP1.Op0AA, &DSP1.Op0AB, &DSP1.Op0AC, &DSP1.Op0AD);
 683  	DSP1.Op0AVS++;
 684  }
 685  
 686  static int16 DSP1_ShiftR (int16 C, int16 E)
 687  {
 688  	return (C * DSP1ROM[0x0031 + E] >> 15);
 689  }
 690  
 691  static void DSP1_Project (int16 X, int16 Y, int16 Z, int16 *H, int16 *V, int16 *M)
 692  {
 693  	int32	aux, aux4;
 694  	int16	E, E2, E3, E4, E5, refE, E6, E7;
 695  	int16	C2, C4, C6, C8, C9, C10, C11, C12, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26;
 696  	int16	Px, Py, Pz;
 697  
 698  	E4 = E3 = E2 = E = E5 = 0;
 699  
 700  	DSP1_NormalizeDouble((int32) X - DSP1.Gx, &Px, &E4);
 701  	DSP1_NormalizeDouble((int32) Y - DSP1.Gy, &Py, &E );
 702  	DSP1_NormalizeDouble((int32) Z - DSP1.Gz, &Pz, &E3);
 703  	Px >>= 1; // to avoid overflows when calculating the scalar products
 704  	E4--;
 705  	Py >>= 1;
 706  	E--;
 707  	Pz >>= 1;
 708  	E3--;
 709  
 710  	refE = (E < E3) ? E : E3;
 711  	refE = (refE < E4) ? refE : E4;
 712  
 713  	Px = DSP1_ShiftR(Px, E4 - refE); // normalize them to the same exponent
 714  	Py = DSP1_ShiftR(Py, E  - refE);
 715  	Pz = DSP1_ShiftR(Pz, E3 - refE);
 716  
 717  	C11 = -(Px * DSP1.Nx >> 15);
 718  	C8  = -(Py * DSP1.Ny >> 15);
 719  	C9  = -(Pz * DSP1.Nz >> 15);
 720  	C12 = C11 + C8 + C9; // this cannot overflow!
 721  
 722  	aux4 = C12; // de-normalization with 32-bits arithmetic
 723  	refE = 16 - refE; // refE can be up to 3
 724  	if (refE >= 0)
 725  		aux4 <<=  (refE);
 726  	else
 727  		aux4 >>= -(refE);
 728  	if (aux4 == -1)
 729  		aux4 = 0; // why?
 730  	aux4 >>= 1;
 731  
 732  	aux = ((uint16) DSP1.G_Les) + aux4; // Les - the scalar product of P with the normal vector of the screen
 733  	DSP1_NormalizeDouble(aux, &C10, &E2);
 734  	E2 = 15 - E2;
 735  
 736  	DSP1_Inverse(C10, 0, &C4, &E4);
 737  	C2 = C4 * DSP1.C_Les >> 15; // scale factor
 738  
 739  	// H
 740  	E7 = 0;
 741  	C16 = Px * ( DSP1.CosAas *  0x7fff >> 15) >> 15;
 742  	C20 = Py * ( DSP1.SinAas *  0x7fff >> 15) >> 15;
 743  	C17 = C16 + C20; // scalar product of P with the normalized horizontal vector of the screen...
 744  
 745  	C18 = C17 * C2 >> 15; // ... multiplied by the scale factor
 746  	DSP1_Normalize(C18, &C19, &E7);
 747  	*H = DSP1_Truncate(C19, DSP1.E_Les - E2 + refE + E7);
 748  
 749  	// V
 750  	E6 = 0;
 751  	C21 = Px * ( DSP1.CosAzs * -DSP1.SinAas >> 15) >> 15;
 752  	C22 = Py * ( DSP1.CosAzs *  DSP1.CosAas >> 15) >> 15;
 753  	C23 = Pz * (-DSP1.SinAzs *  0x7fff >> 15) >> 15;
 754  	C24 = C21 + C22 + C23; // scalar product of P with the normalized vertical vector of the screen...
 755  
 756  	C26 = C24 * C2 >> 15; // ... multiplied by the scale factor
 757  	DSP1_Normalize(C26, &C25, &E6);
 758  	*V = DSP1_Truncate(C25, DSP1.E_Les - E2 + refE + E6);
 759  
 760  	// M
 761  	DSP1_Normalize(C2, &C6, &E4);
 762  	*M = DSP1_Truncate(C6, E4 + DSP1.E_Les - E2 - 7); // M is the scale factor divided by 2^7
 763  }
 764  
 765  static void DSP1_Op06 (void)
 766  {
 767  	DSP1_Project(DSP1.Op06X, DSP1.Op06Y, DSP1.Op06Z, &DSP1.Op06H, &DSP1.Op06V, &DSP1.Op06M);
 768  }
 769  
 770  static void DSP1_Op01 (void)
 771  {
 772  	int16	SinAz = DSP1_Sin(DSP1.Op01Zr);
 773  	int16	CosAz = DSP1_Cos(DSP1.Op01Zr);
 774  	int16	SinAy = DSP1_Sin(DSP1.Op01Yr);
 775  	int16	CosAy = DSP1_Cos(DSP1.Op01Yr);
 776  	int16	SinAx = DSP1_Sin(DSP1.Op01Xr);
 777  	int16	CosAx = DSP1_Cos(DSP1.Op01Xr);
 778  
 779  	DSP1.Op01m >>= 1;
 780  
 781  	DSP1.matrixA[0][0] =   (DSP1.Op01m * CosAz >> 15) * CosAy >> 15;
 782  	DSP1.matrixA[0][1] = -((DSP1.Op01m * SinAz >> 15) * CosAy >> 15);
 783  	DSP1.matrixA[0][2] =    DSP1.Op01m * SinAy >> 15;
 784  
 785  	DSP1.matrixA[1][0] =  ((DSP1.Op01m * SinAz >> 15) * CosAx >> 15) + (((DSP1.Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
 786  	DSP1.matrixA[1][1] =  ((DSP1.Op01m * CosAz >> 15) * CosAx >> 15) - (((DSP1.Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
 787  	DSP1.matrixA[1][2] = -((DSP1.Op01m * SinAx >> 15) * CosAy >> 15);
 788  
 789  	DSP1.matrixA[2][0] =  ((DSP1.Op01m * SinAz >> 15) * SinAx >> 15) - (((DSP1.Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
 790  	DSP1.matrixA[2][1] =  ((DSP1.Op01m * CosAz >> 15) * SinAx >> 15) + (((DSP1.Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
 791  	DSP1.matrixA[2][2] =   (DSP1.Op01m * CosAx >> 15) * CosAy >> 15;
 792  }
 793  
 794  static void DSP1_Op11 (void)
 795  {
 796  	int16	SinAz = DSP1_Sin(DSP1.Op11Zr);
 797  	int16	CosAz = DSP1_Cos(DSP1.Op11Zr);
 798  	int16	SinAy = DSP1_Sin(DSP1.Op11Yr);
 799  	int16	CosAy = DSP1_Cos(DSP1.Op11Yr);
 800  	int16	SinAx = DSP1_Sin(DSP1.Op11Xr);
 801  	int16	CosAx = DSP1_Cos(DSP1.Op11Xr);
 802  
 803  	DSP1.Op11m >>= 1;
 804  
 805  	DSP1.matrixB[0][0] =   (DSP1.Op11m * CosAz >> 15) * CosAy >> 15;
 806  	DSP1.matrixB[0][1] = -((DSP1.Op11m * SinAz >> 15) * CosAy >> 15);
 807  	DSP1.matrixB[0][2] =    DSP1.Op11m * SinAy >> 15;
 808  
 809  	DSP1.matrixB[1][0] =  ((DSP1.Op11m * SinAz >> 15) * CosAx >> 15) + (((DSP1.Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
 810  	DSP1.matrixB[1][1] =  ((DSP1.Op11m * CosAz >> 15) * CosAx >> 15) - (((DSP1.Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
 811  	DSP1.matrixB[1][2] = -((DSP1.Op11m * SinAx >> 15) * CosAy >> 15);
 812  
 813  	DSP1.matrixB[2][0] =  ((DSP1.Op11m * SinAz >> 15) * SinAx >> 15) - (((DSP1.Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
 814  	DSP1.matrixB[2][1] =  ((DSP1.Op11m * CosAz >> 15) * SinAx >> 15) + (((DSP1.Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
 815  	DSP1.matrixB[2][2] =   (DSP1.Op11m * CosAx >> 15) * CosAy >> 15;
 816  }
 817  
 818  static void DSP1_Op21 (void)
 819  {
 820  	int16	SinAz = DSP1_Sin(DSP1.Op21Zr);
 821  	int16	CosAz = DSP1_Cos(DSP1.Op21Zr);
 822  	int16	SinAy = DSP1_Sin(DSP1.Op21Yr);
 823  	int16	CosAy = DSP1_Cos(DSP1.Op21Yr);
 824  	int16	SinAx = DSP1_Sin(DSP1.Op21Xr);
 825  	int16	CosAx = DSP1_Cos(DSP1.Op21Xr);
 826  
 827  	DSP1.Op21m >>= 1;
 828  
 829  	DSP1.matrixC[0][0] =   (DSP1.Op21m * CosAz >> 15) * CosAy >> 15;
 830  	DSP1.matrixC[0][1] = -((DSP1.Op21m * SinAz >> 15) * CosAy >> 15);
 831  	DSP1.matrixC[0][2] =    DSP1.Op21m * SinAy >> 15;
 832  
 833  	DSP1.matrixC[1][0] =  ((DSP1.Op21m * SinAz >> 15) * CosAx >> 15) + (((DSP1.Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
 834  	DSP1.matrixC[1][1] =  ((DSP1.Op21m * CosAz >> 15) * CosAx >> 15) - (((DSP1.Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
 835  	DSP1.matrixC[1][2] = -((DSP1.Op21m * SinAx >> 15) * CosAy >> 15);
 836  
 837  	DSP1.matrixC[2][0] =  ((DSP1.Op21m * SinAz >> 15) * SinAx >> 15) - (((DSP1.Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
 838  	DSP1.matrixC[2][1] =  ((DSP1.Op21m * CosAz >> 15) * SinAx >> 15) + (((DSP1.Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
 839  	DSP1.matrixC[2][2] =   (DSP1.Op21m * CosAx >> 15) * CosAy >> 15;
 840  }
 841  
 842  static void DSP1_Op0D (void)
 843  {
 844  	DSP1.Op0DF = (DSP1.Op0DX * DSP1.matrixA[0][0] >> 15) + (DSP1.Op0DY * DSP1.matrixA[0][1] >> 15) + (DSP1.Op0DZ * DSP1.matrixA[0][2] >> 15);
 845  	DSP1.Op0DL = (DSP1.Op0DX * DSP1.matrixA[1][0] >> 15) + (DSP1.Op0DY * DSP1.matrixA[1][1] >> 15) + (DSP1.Op0DZ * DSP1.matrixA[1][2] >> 15);
 846  	DSP1.Op0DU = (DSP1.Op0DX * DSP1.matrixA[2][0] >> 15) + (DSP1.Op0DY * DSP1.matrixA[2][1] >> 15) + (DSP1.Op0DZ * DSP1.matrixA[2][2] >> 15);
 847  
 848  #ifdef DebugDSP1
 849  	Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d", DSP1.Op0DX, DSP1.Op0DY, DSP1.Op0DZ, DSP1.Op0DF, DSP1.Op0DL, DSP1.Op0DU);
 850  #endif
 851  }
 852  
 853  static void DSP1_Op1D (void)
 854  {
 855  	DSP1.Op1DF = (DSP1.Op1DX * DSP1.matrixB[0][0] >> 15) + (DSP1.Op1DY * DSP1.matrixB[0][1] >> 15) + (DSP1.Op1DZ * DSP1.matrixB[0][2] >> 15);
 856  	DSP1.Op1DL = (DSP1.Op1DX * DSP1.matrixB[1][0] >> 15) + (DSP1.Op1DY * DSP1.matrixB[1][1] >> 15) + (DSP1.Op1DZ * DSP1.matrixB[1][2] >> 15);
 857  	DSP1.Op1DU = (DSP1.Op1DX * DSP1.matrixB[2][0] >> 15) + (DSP1.Op1DY * DSP1.matrixB[2][1] >> 15) + (DSP1.Op1DZ * DSP1.matrixB[2][2] >> 15);
 858  
 859  #ifdef DebugDSP1
 860  	Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d", DSP1.Op1DX, DSP1.Op1DY, DSP1.Op1DZ, DSP1.Op1DF, DSP1.Op1DL, DSP1.Op1DU);
 861  #endif
 862  }
 863  
 864  static void DSP1_Op2D (void)
 865  {
 866  	DSP1.Op2DF = (DSP1.Op2DX * DSP1.matrixC[0][0] >> 15) + (DSP1.Op2DY * DSP1.matrixC[0][1] >> 15) + (DSP1.Op2DZ * DSP1.matrixC[0][2] >> 15);
 867  	DSP1.Op2DL = (DSP1.Op2DX * DSP1.matrixC[1][0] >> 15) + (DSP1.Op2DY * DSP1.matrixC[1][1] >> 15) + (DSP1.Op2DZ * DSP1.matrixC[1][2] >> 15);
 868  	DSP1.Op2DU = (DSP1.Op2DX * DSP1.matrixC[2][0] >> 15) + (DSP1.Op2DY * DSP1.matrixC[2][1] >> 15) + (DSP1.Op2DZ * DSP1.matrixC[2][2] >> 15);
 869  
 870  #ifdef DebugDSP1
 871  	Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d", DSP1.Op2DX, DSP1.Op2DY, DSP1.Op2DZ, DSP1.Op2DF, DSP1.Op2DL, DSP1.Op2DU);
 872  #endif
 873  }
 874  
 875  static void DSP1_Op03 (void)
 876  {
 877  	DSP1.Op03X = (DSP1.Op03F * DSP1.matrixA[0][0] >> 15) + (DSP1.Op03L * DSP1.matrixA[1][0] >> 15) + (DSP1.Op03U * DSP1.matrixA[2][0] >> 15);
 878  	DSP1.Op03Y = (DSP1.Op03F * DSP1.matrixA[0][1] >> 15) + (DSP1.Op03L * DSP1.matrixA[1][1] >> 15) + (DSP1.Op03U * DSP1.matrixA[2][1] >> 15);
 879  	DSP1.Op03Z = (DSP1.Op03F * DSP1.matrixA[0][2] >> 15) + (DSP1.Op03L * DSP1.matrixA[1][2] >> 15) + (DSP1.Op03U * DSP1.matrixA[2][2] >> 15);
 880  
 881  #ifdef DebugDSP1
 882  	Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d", DSP1.Op03F, DSP1.Op03L, DSP1.Op03U, DSP1.Op03X, DSP1.Op03Y, DSP1.Op03Z);
 883  #endif
 884  }
 885  
 886  static void DSP1_Op13 (void)
 887  {
 888  	DSP1.Op13X = (DSP1.Op13F * DSP1.matrixB[0][0] >> 15) + (DSP1.Op13L * DSP1.matrixB[1][0] >> 15) + (DSP1.Op13U * DSP1.matrixB[2][0] >> 15);
 889  	DSP1.Op13Y = (DSP1.Op13F * DSP1.matrixB[0][1] >> 15) + (DSP1.Op13L * DSP1.matrixB[1][1] >> 15) + (DSP1.Op13U * DSP1.matrixB[2][1] >> 15);
 890  	DSP1.Op13Z = (DSP1.Op13F * DSP1.matrixB[0][2] >> 15) + (DSP1.Op13L * DSP1.matrixB[1][2] >> 15) + (DSP1.Op13U * DSP1.matrixB[2][2] >> 15);
 891  
 892  #ifdef DebugDSP1
 893  	Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d", DSP1.Op13F, DSP1.Op13L, DSP1.Op13U, DSP1.Op13X, DSP1.Op13Y, DSP1.Op13Z);
 894  #endif
 895  }
 896  
 897  static void DSP1_Op23 (void)
 898  {
 899  	DSP1.Op23X = (DSP1.Op23F * DSP1.matrixC[0][0] >> 15) + (DSP1.Op23L * DSP1.matrixC[1][0] >> 15) + (DSP1.Op23U * DSP1.matrixC[2][0] >> 15);
 900  	DSP1.Op23Y = (DSP1.Op23F * DSP1.matrixC[0][1] >> 15) + (DSP1.Op23L * DSP1.matrixC[1][1] >> 15) + (DSP1.Op23U * DSP1.matrixC[2][1] >> 15);
 901  	DSP1.Op23Z = (DSP1.Op23F * DSP1.matrixC[0][2] >> 15) + (DSP1.Op23L * DSP1.matrixC[1][2] >> 15) + (DSP1.Op23U * DSP1.matrixC[2][2] >> 15);
 902  
 903  #ifdef DebugDSP1
 904  	Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d", DSP1.Op23F, DSP1.Op23L, DSP1.Op23U, DSP1.Op23X, DSP1.Op23Y, DSP1.Op23Z);
 905  #endif
 906  }
 907  
 908  static void DSP1_Op14 (void)
 909  {
 910  	int16	CSec, ESec, CTan, CSin, C, E;
 911  
 912  	DSP1_Inverse(DSP1_Cos(DSP1.Op14Xr), 0, &CSec, &ESec);
 913  
 914  	// Rotation Around Z
 915  	DSP1_NormalizeDouble(DSP1.Op14U * DSP1_Cos(DSP1.Op14Yr) - DSP1.Op14F * DSP1_Sin(DSP1.Op14Yr), &C, &E);
 916  
 917  	E = ESec - E;
 918  
 919  	DSP1_Normalize(C * CSec >> 15, &C, &E);
 920  
 921  	DSP1.Op14Zrr = DSP1.Op14Zr + DSP1_Truncate(C, E);
 922  
 923  	// Rotation Around X
 924  	DSP1.Op14Xrr = DSP1.Op14Xr + (DSP1.Op14U * DSP1_Sin(DSP1.Op14Yr) >> 15) + (DSP1.Op14F * DSP1_Cos(DSP1.Op14Yr) >> 15);
 925  
 926  	// Rotation Around Y
 927  	DSP1_NormalizeDouble(DSP1.Op14U * DSP1_Cos(DSP1.Op14Yr) + DSP1.Op14F * DSP1_Sin(DSP1.Op14Yr), &C, &E);
 928  
 929  	E = ESec - E;
 930  
 931  	DSP1_Normalize(DSP1_Sin(DSP1.Op14Xr), &CSin, &E);
 932  
 933  	CTan = CSec * CSin >> 15;
 934  
 935  	DSP1_Normalize(-(C * CTan >> 15), &C, &E);
 936  
 937  	DSP1.Op14Yrr = DSP1.Op14Yr + DSP1_Truncate(C, E) + DSP1.Op14L;
 938  }
 939  
 940  static void DSP1_Target (int16 H, int16 V, int16 *X, int16 *Y)
 941  {
 942  	int16	C, E, C1, E1;
 943  
 944  	DSP1_Inverse((V * DSP1.SinAzs >> 15) + DSP1.VOffset, 8, &C, &E);
 945  	E += DSP1.VPlane_E;
 946  
 947  	C1 = C * DSP1.VPlane_C >> 15;
 948  	E1 = E + DSP1.SecAZS_E1;
 949  
 950  	H <<= 8;
 951  
 952  	DSP1_Normalize(C1, &C, &E);
 953  
 954  	C = DSP1_Truncate(C, E) * H >> 15;
 955  
 956  	*X = DSP1.CentreX + (C * DSP1.CosAas >> 15);
 957  	*Y = DSP1.CentreY - (C * DSP1.SinAas >> 15);
 958  
 959  	V <<= 8;
 960  
 961  	DSP1_Normalize(C1 * DSP1.SecAZS_C1 >> 15, &C, &E1);
 962  
 963  	C = DSP1_Truncate(C, E1) * V >> 15;
 964  
 965  	*X += C * -DSP1.SinAas >> 15;
 966  	*Y += C *  DSP1.CosAas >> 15;
 967  }
 968  
 969  static void DSP1_Op0E (void)
 970  {
 971  	DSP1_Target(DSP1.Op0EH, DSP1.Op0EV, &DSP1.Op0EX, &DSP1.Op0EY);
 972  }
 973  
 974  static void DSP1_Op0B (void)
 975  {
 976  	DSP1.Op0BS = (DSP1.Op0BX * DSP1.matrixA[0][0] + DSP1.Op0BY * DSP1.matrixA[0][1] + DSP1.Op0BZ * DSP1.matrixA[0][2]) >> 15;
 977  
 978  #ifdef DebugDSP1
 979  	Log_Message("OP0B");
 980  #endif
 981  }
 982  
 983  static void DSP1_Op1B (void)
 984  {
 985  	DSP1.Op1BS = (DSP1.Op1BX * DSP1.matrixB[0][0] + DSP1.Op1BY * DSP1.matrixB[0][1] + DSP1.Op1BZ * DSP1.matrixB[0][2]) >> 15;
 986  
 987  #ifdef DebugDSP1
 988  	Log_Message("OP1B X: %d Y: %d Z: %d S: %d", DSP1.Op1BX, DSP1.Op1BY, DSP1.Op1BZ, DSP1.Op1BS);
 989  	Log_Message("     MX: %d MY: %d MZ: %d Scale: %d", (int16) (DSP1.matrixB[0][0] * 100), (int16) (DSP1.matrixB[0][1] * 100), (int16) (DSP1.matrixB[0][2] * 100), (int16) (DSP1.Op1BS * 100));
 990  #endif
 991  }
 992  
 993  static void DSP1_Op2B (void)
 994  {
 995  	DSP1.Op2BS = (DSP1.Op2BX * DSP1.matrixC[0][0] + DSP1.Op2BY * DSP1.matrixC[0][1] + DSP1.Op2BZ * DSP1.matrixC[0][2]) >> 15;
 996  
 997  #ifdef DebugDSP1
 998  	Log_Message("OP2B");
 999  #endif
1000  }
1001  
1002  static void DSP1_Op08 (void)
1003  {
1004  	int32	op08Size = (DSP1.Op08X * DSP1.Op08X + DSP1.Op08Y * DSP1.Op08Y + DSP1.Op08Z * DSP1.Op08Z) << 1;
1005  	DSP1.Op08Ll =  op08Size        & 0xffff;
1006  	DSP1.Op08Lh = (op08Size >> 16) & 0xffff;
1007  
1008  #ifdef DebugDSP1
1009  	Log_Message("OP08 %d,%d,%d", DSP1.Op08X, DSP1.Op08Y, DSP1.Op08Z);
1010  	Log_Message("OP08 ((OP08X^2)+(OP08Y^2)+(OP08Z^2))=%x", op08Size);
1011  #endif
1012  }
1013  
1014  static void DSP1_Op18 (void)
1015  {
1016  	DSP1.Op18D = (DSP1.Op18X * DSP1.Op18X + DSP1.Op18Y * DSP1.Op18Y + DSP1.Op18Z * DSP1.Op18Z - DSP1.Op18R * DSP1.Op18R) >> 15;
1017  
1018  #ifdef DebugDSP1
1019  	Log_Message("OP18 X: %d Y: %d Z: %d R: %D DIFF %d", DSP1.Op18X, DSP1.Op18Y, DSP1.Op38Z, DSP1.Op18D);
1020  #endif
1021  }
1022  
1023  static void DSP1_Op38 (void)
1024  {
1025  	DSP1.Op38D = (DSP1.Op38X * DSP1.Op38X + DSP1.Op38Y * DSP1.Op38Y + DSP1.Op38Z * DSP1.Op38Z - DSP1.Op38R * DSP1.Op38R) >> 15;
1026  	DSP1.Op38D++;
1027  
1028  #ifdef DebugDSP1
1029  	Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d", DSP1.Op38X, DSP1.Op38Y, DSP1.Op38Z, DSP1.Op38D);
1030  #endif
1031  }
1032  
1033  static void DSP1_Op28 (void)
1034  {
1035  	int32	Radius = DSP1.Op28X * DSP1.Op28X + DSP1.Op28Y * DSP1.Op28Y + DSP1.Op28Z * DSP1.Op28Z;
1036  
1037  	if (Radius == 0)
1038  		DSP1.Op28R = 0;
1039  	else
1040  	{
1041  		int16	C, E, Pos, Node1, Node2;
1042  
1043  		DSP1_NormalizeDouble(Radius, &C, &E);
1044  		if (E & 1)
1045  			C = C * 0x4000 >> 15;
1046  
1047  		Pos = C * 0x0040 >> 15;
1048  
1049  		Node1 = DSP1ROM[0x00d5 + Pos];
1050  		Node2 = DSP1ROM[0x00d6 + Pos];
1051  
1052  		DSP1.Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1;
1053  		DSP1.Op28R >>= (E >> 1);
1054  	}
1055  
1056  #ifdef DebugDSP1
1057  	Log_Message("OP28 X:%d Y:%d Z:%d", DSP1.Op28X, DSP1.Op28Y, DSP1.Op28Z);
1058  	Log_Message("OP28 Vector Length %d", DSP1.Op28R);
1059  #endif
1060  }
1061  
1062  static void DSP1_Op1C (void)
1063  {
1064  	// Rotate Around Op1CZ1
1065  	DSP1.Op1CX1 = (DSP1.Op1CYBR * DSP1_Sin(DSP1.Op1CZ) >> 15) + (DSP1.Op1CXBR * DSP1_Cos(DSP1.Op1CZ) >> 15);
1066  	DSP1.Op1CY1 = (DSP1.Op1CYBR * DSP1_Cos(DSP1.Op1CZ) >> 15) - (DSP1.Op1CXBR * DSP1_Sin(DSP1.Op1CZ) >> 15);
1067  	DSP1.Op1CXBR = DSP1.Op1CX1;
1068  	DSP1.Op1CYBR = DSP1.Op1CY1;
1069  
1070  	// Rotate Around Op1CY1
1071  	DSP1.Op1CZ1 = (DSP1.Op1CXBR * DSP1_Sin(DSP1.Op1CY) >> 15) + (DSP1.Op1CZBR * DSP1_Cos(DSP1.Op1CY) >> 15);
1072  	DSP1.Op1CX1 = (DSP1.Op1CXBR * DSP1_Cos(DSP1.Op1CY) >> 15) - (DSP1.Op1CZBR * DSP1_Sin(DSP1.Op1CY) >> 15);
1073  	DSP1.Op1CXAR = DSP1.Op1CX1;
1074  	DSP1.Op1CZBR = DSP1.Op1CZ1;
1075  
1076  	// Rotate Around Op1CX1
1077  	DSP1.Op1CY1 = (DSP1.Op1CZBR * DSP1_Sin(DSP1.Op1CX) >> 15) + (DSP1.Op1CYBR * DSP1_Cos(DSP1.Op1CX) >> 15);
1078  	DSP1.Op1CZ1 = (DSP1.Op1CZBR * DSP1_Cos(DSP1.Op1CX) >> 15) - (DSP1.Op1CYBR * DSP1_Sin(DSP1.Op1CX) >> 15);
1079  	DSP1.Op1CYAR = DSP1.Op1CY1;
1080  	DSP1.Op1CZAR = DSP1.Op1CZ1;
1081  
1082  #ifdef DebugDSP1
1083  	Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ", DSP1.Op1CXAR, DSP1.Op1CYAR, DSP1.Op1CZAR);
1084  #endif
1085  }
1086  
1087  static void DSP1_Op0F (void)
1088  {
1089  	DSP1.Op0FPass = 0x0000;
1090  
1091  #ifdef DebugDSP1
1092  	Log_Message("OP0F RAM Test Pass:%d", DSP1.Op0FPass);
1093  #endif
1094  }
1095  
1096  static void DSP1_Op2F (void)
1097  {
1098  	DSP1.Op2FSize = 0x100;
1099  }
1100  
1101  void DSP1SetByte (uint8 byte, uint16 address)
1102  {
1103  	if (address < DSP0.boundary)
1104  	{
1105  		if ((DSP1.command == 0x0A || DSP1.command == 0x1A) && DSP1.out_count != 0)
1106  		{
1107  			DSP1.out_count--;
1108  			DSP1.out_index++;
1109  			return;
1110  		}
1111  		else
1112  		if (DSP1.waiting4command)
1113  		{
1114  			DSP1.command         = byte;
1115  			DSP1.in_index        = 0;
1116  			DSP1.waiting4command = FALSE;
1117  			DSP1.first_parameter = TRUE;
1118  			#ifdef DEBUGGER
1119  				//printf("OP%02X\n",byte);
1120  			#endif
1121  
1122  			switch (byte)
1123  			{
1124  				case 0x00: DSP1.in_count = 2; break;
1125  				case 0x30:
1126  				case 0x10: DSP1.in_count = 2; break;
1127  				case 0x20: DSP1.in_count = 2; break;
1128  				case 0x24:
1129  				case 0x04: DSP1.in_count = 2; break;
1130  				case 0x08: DSP1.in_count = 3; break;
1131  				case 0x18: DSP1.in_count = 4; break;
1132  				case 0x28: DSP1.in_count = 3; break;
1133  				case 0x38: DSP1.in_count = 4; break;
1134  				case 0x2c:
1135  				case 0x0c: DSP1.in_count = 3; break;
1136  				case 0x3c:
1137  				case 0x1c: DSP1.in_count = 6; break;
1138  				case 0x32:
1139  				case 0x22:
1140  				case 0x12:
1141  				case 0x02: DSP1.in_count = 7; break;
1142  				case 0x0a: DSP1.in_count = 1; break;
1143  				case 0x3a:
1144  				case 0x2a:
1145  				case 0x1a:
1146  					DSP1.command = 0x1a;
1147  					DSP1.in_count = 1;
1148  					break;
1149  				case 0x16:
1150  				case 0x26:
1151  				case 0x36:
1152  				case 0x06: DSP1.in_count = 3; break;
1153  				case 0x1e:
1154  				case 0x2e:
1155  				case 0x3e:
1156  				case 0x0e: DSP1.in_count = 2; break;
1157  				case 0x05:
1158  				case 0x35:
1159  				case 0x31:
1160  				case 0x01: DSP1.in_count = 4; break;
1161  				case 0x15:
1162  				case 0x11: DSP1.in_count = 4; break;
1163  				case 0x25:
1164  				case 0x21: DSP1.in_count = 4; break;
1165  				case 0x09:
1166  				case 0x39:
1167  				case 0x3d:
1168  				case 0x0d: DSP1.in_count = 3; break;
1169  				case 0x19:
1170  				case 0x1d: DSP1.in_count = 3; break;
1171  				case 0x29:
1172  				case 0x2d: DSP1.in_count = 3; break;
1173  				case 0x33:
1174  				case 0x03: DSP1.in_count = 3; break;
1175  				case 0x13: DSP1.in_count = 3; break;
1176  				case 0x23: DSP1.in_count = 3; break;
1177  				case 0x3b:
1178  				case 0x0b: DSP1.in_count = 3; break;
1179  				case 0x1b: DSP1.in_count = 3; break;
1180  				case 0x2b: DSP1.in_count = 3; break;
1181  				case 0x34:
1182  				case 0x14: DSP1.in_count = 6; break;
1183  				case 0x07:
1184  				case 0x0f: DSP1.in_count = 1; break;
1185  				case 0x27:
1186  				case 0x2F: DSP1.in_count = 1; break;
1187  				case 0x17:
1188  				case 0x37:
1189  				case 0x3F:
1190  					DSP1.command = 0x1f; // Fall through
1191  				case 0x1f: DSP1.in_count = 1; break;
1192  				default:
1193  				#ifdef DEBUGGER
1194  					//printf("OP%02X\n", byte);
1195  				#endif
1196  				case 0x80:
1197  					DSP1.in_count        = 0;
1198  					DSP1.waiting4command = TRUE;
1199  					DSP1.first_parameter = TRUE;
1200  					break;
1201  			}
1202  
1203  			DSP1.in_count <<= 1;
1204  		}
1205  		else
1206  		{
1207  			DSP1.parameters[DSP1.in_index] = byte;
1208  			DSP1.first_parameter = FALSE;
1209  			DSP1.in_index++;
1210  		}
1211  
1212  		if (DSP1.waiting4command || (DSP1.first_parameter && byte == 0x80))
1213  		{
1214  			DSP1.waiting4command = TRUE;
1215  			DSP1.first_parameter = FALSE;
1216  		}
1217  		else
1218  		if (DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count == 0 && DSP1.in_index == 0)))
1219  			;
1220  		else
1221  		{
1222  			if (DSP1.in_count)
1223  			{
1224  				if (--DSP1.in_count == 0)
1225  				{
1226  					// Actually execute the command
1227  					DSP1.waiting4command = TRUE;
1228  					DSP1.out_index       = 0;
1229  
1230  					switch (DSP1.command)
1231  					{
1232  						case 0x1f:
1233  							DSP1.out_count = 2048;
1234  							break;
1235  
1236  						case 0x00: // Multiple
1237  							DSP1.Op00Multiplicand = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1238  							DSP1.Op00Multiplier   = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1239  
1240  							DSP1_Op00();
1241  
1242  							DSP1.out_count = 2;
1243  							DSP1.output[0] =  DSP1.Op00Result       & 0xFF;
1244  							DSP1.output[1] = (DSP1.Op00Result >> 8) & 0xFF;
1245  							break;
1246  
1247  						case 0x20: // Multiple
1248  							DSP1.Op20Multiplicand = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1249  							DSP1.Op20Multiplier   = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1250  
1251  							DSP1_Op20();
1252  
1253  							DSP1.out_count = 2;
1254  							DSP1.output[0] =  DSP1.Op20Result       & 0xFF;
1255  							DSP1.output[1] = (DSP1.Op20Result >> 8) & 0xFF;
1256  							break;
1257  
1258  						case 0x30:
1259  						case 0x10: // Inverse
1260  							DSP1.Op10Coefficient = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1261  							DSP1.Op10Exponent    = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1262  
1263  							DSP1_Op10();
1264  
1265  							DSP1.out_count = 4;
1266  							DSP1.output[0] = (uint8) ( ((int16) DSP1.Op10CoefficientR)       & 0xFF);
1267  							DSP1.output[1] = (uint8) ((((int16) DSP1.Op10CoefficientR) >> 8) & 0xFF);
1268  							DSP1.output[2] = (uint8) ( ((int16) DSP1.Op10ExponentR   )       & 0xFF);
1269  							DSP1.output[3] = (uint8) ((((int16) DSP1.Op10ExponentR   ) >> 8) & 0xFF);
1270  							break;
1271  
1272  						case 0x24:
1273  						case 0x04: // Sin and Cos of angle
1274  							DSP1.Op04Angle  = (int16)  (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1275  							DSP1.Op04Radius = (uint16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1276  
1277  							DSP1_Op04();
1278  
1279  							DSP1.out_count = 4;
1280  							DSP1.output[0] = (uint8)  (DSP1.Op04Sin       & 0xFF);
1281  							DSP1.output[1] = (uint8) ((DSP1.Op04Sin >> 8) & 0xFF);
1282  							DSP1.output[2] = (uint8)  (DSP1.Op04Cos       & 0xFF);
1283  							DSP1.output[3] = (uint8) ((DSP1.Op04Cos >> 8) & 0xFF);
1284  							break;
1285  
1286  						case 0x08: // Radius
1287  							DSP1.Op08X = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1288  							DSP1.Op08Y = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1289  							DSP1.Op08Z = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1290  
1291  							DSP1_Op08();
1292  
1293  							DSP1.out_count = 4;
1294  							DSP1.output[0] = (uint8) ( ((int16) DSP1.Op08Ll)       & 0xFF);
1295  							DSP1.output[1] = (uint8) ((((int16) DSP1.Op08Ll) >> 8) & 0xFF);
1296  							DSP1.output[2] = (uint8) ( ((int16) DSP1.Op08Lh)       & 0xFF);
1297  							DSP1.output[3] = (uint8) ((((int16) DSP1.Op08Lh) >> 8) & 0xFF);
1298  							break;
1299  
1300  						case 0x18: // Range
1301  
1302  							DSP1.Op18X = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1303  							DSP1.Op18Y = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1304  							DSP1.Op18Z = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1305  							DSP1.Op18R = (int16) (DSP1.parameters[6] | (DSP1.parameters[7] << 8));
1306  
1307  							DSP1_Op18();
1308  
1309  							DSP1.out_count = 2;
1310  							DSP1.output[0] = (uint8)  (DSP1.Op18D       & 0xFF);
1311  							DSP1.output[1] = (uint8) ((DSP1.Op18D >> 8) & 0xFF);
1312  							break;
1313  
1314  						case 0x38: // Range
1315  
1316  							DSP1.Op38X = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1317  							DSP1.Op38Y = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1318  							DSP1.Op38Z = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1319  							DSP1.Op38R = (int16) (DSP1.parameters[6] | (DSP1.parameters[7] << 8));
1320  
1321  							DSP1_Op38();
1322  
1323  							DSP1.out_count = 2;
1324  							DSP1.output[0] = (uint8)  (DSP1.Op38D       & 0xFF);
1325  							DSP1.output[1] = (uint8) ((DSP1.Op38D >> 8) & 0xFF);
1326  							break;
1327  
1328  						case 0x28: // Distance (vector length)
1329  							DSP1.Op28X = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1330  							DSP1.Op28Y = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1331  							DSP1.Op28Z = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1332  
1333  							DSP1_Op28();
1334  
1335  							DSP1.out_count = 2;
1336  							DSP1.output[0] = (uint8)  (DSP1.Op28R       & 0xFF);
1337  							DSP1.output[1] = (uint8) ((DSP1.Op28R >> 8) & 0xFF);
1338  							break;
1339  
1340  						case 0x2c:
1341  						case 0x0c: // Rotate (2D rotate)
1342  							DSP1.Op0CA  = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1343  							DSP1.Op0CX1 = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1344  							DSP1.Op0CY1 = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1345  
1346  							DSP1_Op0C();
1347  
1348  							DSP1.out_count = 4;
1349  							DSP1.output[0] = (uint8)  (DSP1.Op0CX2       & 0xFF);
1350  							DSP1.output[1] = (uint8) ((DSP1.Op0CX2 >> 8) & 0xFF);
1351  							DSP1.output[2] = (uint8)  (DSP1.Op0CY2       & 0xFF);
1352  							DSP1.output[3] = (uint8) ((DSP1.Op0CY2 >> 8) & 0xFF);
1353  							break;
1354  
1355  						case 0x3c:
1356  						case 0x1c: // Polar (3D rotate)
1357  							DSP1.Op1CZ   = (DSP1.parameters[ 0] | (DSP1.parameters[ 1] << 8));
1358  							//MK: reversed X and Y on neviksti and John's advice.
1359  							DSP1.Op1CY   = (DSP1.parameters[ 2] | (DSP1.parameters[ 3] << 8));
1360  							DSP1.Op1CX   = (DSP1.parameters[ 4] | (DSP1.parameters[ 5] << 8));
1361  							DSP1.Op1CXBR = (DSP1.parameters[ 6] | (DSP1.parameters[ 7] << 8));
1362  							DSP1.Op1CYBR = (DSP1.parameters[ 8] | (DSP1.parameters[ 9] << 8));
1363  							DSP1.Op1CZBR = (DSP1.parameters[10] | (DSP1.parameters[11] << 8));
1364  
1365  							DSP1_Op1C();
1366  
1367  							DSP1.out_count = 6;
1368  							DSP1.output[0] = (uint8)  (DSP1.Op1CXAR       & 0xFF);
1369  							DSP1.output[1] = (uint8) ((DSP1.Op1CXAR >> 8) & 0xFF);
1370  							DSP1.output[2] = (uint8)  (DSP1.Op1CYAR       & 0xFF);
1371  							DSP1.output[3] = (uint8) ((DSP1.Op1CYAR >> 8) & 0xFF);
1372  							DSP1.output[4] = (uint8)  (DSP1.Op1CZAR       & 0xFF);
1373  							DSP1.output[5] = (uint8) ((DSP1.Op1CZAR >> 8) & 0xFF);
1374  							break;
1375  
1376  						case 0x32:
1377  						case 0x22:
1378  						case 0x12:
1379  						case 0x02: // Parameter (Projection)
1380  							DSP1.Op02FX  = (int16)  (DSP1.parameters[ 0] | (DSP1.parameters[ 1] << 8));
1381  							DSP1.Op02FY  = (int16)  (DSP1.parameters[ 2] | (DSP1.parameters[ 3] << 8));
1382  							DSP1.Op02FZ  = (int16)  (DSP1.parameters[ 4] | (DSP1.parameters[ 5] << 8));
1383  							DSP1.Op02LFE = (int16)  (DSP1.parameters[ 6] | (DSP1.parameters[ 7] << 8));
1384  							DSP1.Op02LES = (int16)  (DSP1.parameters[ 8] | (DSP1.parameters[ 9] << 8));
1385  							DSP1.Op02AAS = (uint16) (DSP1.parameters[10] | (DSP1.parameters[11] << 8));
1386  							DSP1.Op02AZS = (uint16) (DSP1.parameters[12] | (DSP1.parameters[13] << 8));
1387  
1388  							DSP1_Op02();
1389  
1390  							DSP1.out_count = 8;
1391  							DSP1.output[0] = (uint8)  (DSP1.Op02VOF       & 0xFF);
1392  							DSP1.output[1] = (uint8) ((DSP1.Op02VOF >> 8) & 0xFF);
1393  							DSP1.output[2] = (uint8)  (DSP1.Op02VVA       & 0xFF);
1394  							DSP1.output[3] = (uint8) ((DSP1.Op02VVA >> 8) & 0xFF);
1395  							DSP1.output[4] = (uint8)  (DSP1.Op02CX        & 0xFF);
1396  							DSP1.output[5] = (uint8) ((DSP1.Op02CX  >> 8) & 0xFF);
1397  							DSP1.output[6] = (uint8)  (DSP1.Op02CY        & 0xFF);
1398  							DSP1.output[7] = (uint8) ((DSP1.Op02CY  >> 8) & 0xFF);
1399  							break;
1400  
1401  						case 0x3a:
1402  						case 0x2a:
1403  						case 0x1a: // Raster mode 7 matrix data
1404  						case 0x0a:
1405  							DSP1.Op0AVS = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1406  
1407  							DSP1_Op0A();
1408  
1409  							DSP1.out_count = 8;
1410  							DSP1.output[0] = (uint8)  (DSP1.Op0AA       & 0xFF);
1411  							DSP1.output[1] = (uint8) ((DSP1.Op0AA >> 8) & 0xFF);
1412  							DSP1.output[2] = (uint8)  (DSP1.Op0AB       & 0xFF);
1413  							DSP1.output[3] = (uint8) ((DSP1.Op0AB >> 8) & 0xFF);
1414  							DSP1.output[4] = (uint8)  (DSP1.Op0AC       & 0xFF);
1415  							DSP1.output[5] = (uint8) ((DSP1.Op0AC >> 8) & 0xFF);
1416  							DSP1.output[6] = (uint8)  (DSP1.Op0AD       & 0xFF);
1417  							DSP1.output[7] = (uint8) ((DSP1.Op0AD >> 8) & 0xFF);
1418  							DSP1.in_index  = 0;
1419  							break;
1420  
1421  						case 0x16:
1422  						case 0x26:
1423  						case 0x36:
1424  						case 0x06: // Project object
1425  							DSP1.Op06X = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1426  							DSP1.Op06Y = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1427  							DSP1.Op06Z = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1428  
1429  							DSP1_Op06();
1430  
1431  							DSP1.out_count = 6;
1432  							DSP1.output[0] = (uint8)  (DSP1.Op06H       & 0xFF);
1433  							DSP1.output[1] = (uint8) ((DSP1.Op06H >> 8) & 0xFF);
1434  							DSP1.output[2] = (uint8)  (DSP1.Op06V       & 0xFF);
1435  							DSP1.output[3] = (uint8) ((DSP1.Op06V >> 8) & 0xFF);
1436  							DSP1.output[4] = (uint8)  (DSP1.Op06M       & 0xFF);
1437  							DSP1.output[5] = (uint8) ((DSP1.Op06M >> 8) & 0xFF);
1438  							break;
1439  
1440  						case 0x1e:
1441  						case 0x2e:
1442  						case 0x3e:
1443  						case 0x0e: // Target
1444  							DSP1.Op0EH = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1445  							DSP1.Op0EV = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1446  
1447  							DSP1_Op0E();
1448  
1449  							DSP1.out_count = 4;
1450  							DSP1.output[0] = (uint8)  (DSP1.Op0EX       & 0xFF);
1451  							DSP1.output[1] = (uint8) ((DSP1.Op0EX >> 8) & 0xFF);
1452  							DSP1.output[2] = (uint8)  (DSP1.Op0EY       & 0xFF);
1453  							DSP1.output[3] = (uint8) ((DSP1.Op0EY >> 8) & 0xFF);
1454  							break;
1455  
1456  							// Extra commands used by Pilot Wings
1457  						case 0x05:
1458  						case 0x35:
1459  						case 0x31:
1460  						case 0x01: // Set attitude matrix A
1461  							DSP1.Op01m  = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1462  							DSP1.Op01Zr = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1463  							DSP1.Op01Yr = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1464  							DSP1.Op01Xr = (int16) (DSP1.parameters[6] | (DSP1.parameters[7] << 8));
1465  
1466  							DSP1_Op01();
1467  							break;
1468  
1469  						case 0x15:
1470  						case 0x11: // Set attitude matrix B
1471  							DSP1.Op11m  = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1472  							DSP1.Op11Zr = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1473  							DSP1.Op11Yr = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1474  							DSP1.Op11Xr = (int16) (DSP1.parameters[7] | (DSP1.parameters[7] << 8));
1475  
1476  							DSP1_Op11();
1477  							break;
1478  
1479  						case 0x25:
1480  						case 0x21: // Set attitude matrix C
1481  							DSP1.Op21m  = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1482  							DSP1.Op21Zr = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1483  							DSP1.Op21Yr = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1484  							DSP1.Op21Xr = (int16) (DSP1.parameters[6] | (DSP1.parameters[7] << 8));
1485  
1486  							DSP1_Op21();
1487  							break;
1488  
1489  						case 0x09:
1490  						case 0x39:
1491  						case 0x3d:
1492  						case 0x0d: // Objective matrix A
1493  							DSP1.Op0DX = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1494  							DSP1.Op0DY = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1495  							DSP1.Op0DZ = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1496  
1497  							DSP1_Op0D();
1498  
1499  							DSP1.out_count = 6;
1500  							DSP1.output [0] = (uint8)  (DSP1.Op0DF       & 0xFF);
1501  							DSP1.output [1] = (uint8) ((DSP1.Op0DF >> 8) & 0xFF);
1502  							DSP1.output [2] = (uint8)  (DSP1.Op0DL       & 0xFF);
1503  							DSP1.output [3] = (uint8) ((DSP1.Op0DL >> 8) & 0xFF);
1504  							DSP1.output [4] = (uint8)  (DSP1.Op0DU       & 0xFF);
1505  							DSP1.output [5] = (uint8) ((DSP1.Op0DU >> 8) & 0xFF);
1506  							break;
1507  
1508  						case 0x19:
1509  						case 0x1d: // Objective matrix B
1510  							DSP1.Op1DX = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1511  							DSP1.Op1DY = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1512  							DSP1.Op1DZ = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1513  
1514  							DSP1_Op1D();
1515  
1516  							DSP1.out_count = 6;
1517  							DSP1.output[0] = (uint8)  (DSP1.Op1DF       & 0xFF);
1518  							DSP1.output[1] = (uint8) ((DSP1.Op1DF >> 8) & 0xFF);
1519  							DSP1.output[2] = (uint8)  (DSP1.Op1DL       & 0xFF);
1520  							DSP1.output[3] = (uint8) ((DSP1.Op1DL >> 8) & 0xFF);
1521  							DSP1.output[4] = (uint8)  (DSP1.Op1DU       & 0xFF);
1522  							DSP1.output[5] = (uint8) ((DSP1.Op1DU >> 8) & 0xFF);
1523  							break;
1524  
1525  						case 0x29:
1526  						case 0x2d: // Objective matrix C
1527  							DSP1.Op2DX = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1528  							DSP1.Op2DY = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1529  							DSP1.Op2DZ = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1530  
1531  							DSP1_Op2D();
1532  
1533  							DSP1.out_count = 6;
1534  							DSP1.output[0] = (uint8)  (DSP1.Op2DF       & 0xFF);
1535  							DSP1.output[1] = (uint8) ((DSP1.Op2DF >> 8) & 0xFF);
1536  							DSP1.output[2] = (uint8)  (DSP1.Op2DL       & 0xFF);
1537  							DSP1.output[3] = (uint8) ((DSP1.Op2DL >> 8) & 0xFF);
1538  							DSP1.output[4] = (uint8)  (DSP1.Op2DU       & 0xFF);
1539  							DSP1.output[5] = (uint8) ((DSP1.Op2DU >> 8) & 0xFF);
1540  							break;
1541  
1542  						case 0x33:
1543  						case 0x03: // Subjective matrix A
1544  							DSP1.Op03F = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1545  							DSP1.Op03L = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1546  							DSP1.Op03U = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1547  
1548  							DSP1_Op03();
1549  
1550  							DSP1.out_count = 6;
1551  							DSP1.output[0] = (uint8)  (DSP1.Op03X       & 0xFF);
1552  							DSP1.output[1] = (uint8) ((DSP1.Op03X >> 8) & 0xFF);
1553  							DSP1.output[2] = (uint8)  (DSP1.Op03Y       & 0xFF);
1554  							DSP1.output[3] = (uint8) ((DSP1.Op03Y >> 8) & 0xFF);
1555  							DSP1.output[4] = (uint8)  (DSP1.Op03Z       & 0xFF);
1556  							DSP1.output[5] = (uint8) ((DSP1.Op03Z >> 8) & 0xFF);
1557  							break;
1558  
1559  						case 0x13: // Subjective matrix B
1560  							DSP1.Op13F = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1561  							DSP1.Op13L = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1562  							DSP1.Op13U = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1563  
1564  							DSP1_Op13();
1565  
1566  							DSP1.out_count = 6;
1567  							DSP1.output[0] = (uint8)  (DSP1.Op13X       & 0xFF);
1568  							DSP1.output[1] = (uint8) ((DSP1.Op13X >> 8) & 0xFF);
1569  							DSP1.output[2] = (uint8)  (DSP1.Op13Y       & 0xFF);
1570  							DSP1.output[3] = (uint8) ((DSP1.Op13Y >> 8) & 0xFF);
1571  							DSP1.output[4] = (uint8)  (DSP1.Op13Z       & 0xFF);
1572  							DSP1.output[5] = (uint8) ((DSP1.Op13Z >> 8) & 0xFF);
1573  							break;
1574  
1575  						case 0x23: // Subjective matrix C
1576  							DSP1.Op23F = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1577  							DSP1.Op23L = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1578  							DSP1.Op23U = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1579  
1580  							DSP1_Op23();
1581  
1582  							DSP1.out_count = 6;
1583  							DSP1.output[0] = (uint8)  (DSP1.Op23X       & 0xFF);
1584  							DSP1.output[1] = (uint8) ((DSP1.Op23X >> 8) & 0xFF);
1585  							DSP1.output[2] = (uint8)  (DSP1.Op23Y       & 0xFF);
1586  							DSP1.output[3] = (uint8) ((DSP1.Op23Y >> 8) & 0xFF);
1587  							DSP1.output[4] = (uint8)  (DSP1.Op23Z       & 0xFF);
1588  							DSP1.output[5] = (uint8) ((DSP1.Op23Z >> 8) & 0xFF);
1589  							break;
1590  
1591  						case 0x3b:
1592  						case 0x0b:
1593  							DSP1.Op0BX = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1594  							DSP1.Op0BY = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1595  							DSP1.Op0BZ = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1596  
1597  							DSP1_Op0B();
1598  
1599  							DSP1.out_count = 2;
1600  							DSP1.output[0] = (uint8)  (DSP1.Op0BS       & 0xFF);
1601  							DSP1.output[1] = (uint8) ((DSP1.Op0BS >> 8) & 0xFF);
1602  							break;
1603  
1604  						case 0x1b:
1605  							DSP1.Op1BX = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1606  							DSP1.Op1BY = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1607  							DSP1.Op1BZ = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1608  
1609  							DSP1_Op1B();
1610  
1611  							DSP1.out_count = 2;
1612  							DSP1.output[0] = (uint8)  (DSP1.Op1BS       & 0xFF);
1613  							DSP1.output[1] = (uint8) ((DSP1.Op1BS >> 8) & 0xFF);
1614  							break;
1615  
1616  						case 0x2b:
1617  							DSP1.Op2BX = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1618  							DSP1.Op2BY = (int16) (DSP1.parameters[2] | (DSP1.parameters[3] << 8));
1619  							DSP1.Op2BZ = (int16) (DSP1.parameters[4] | (DSP1.parameters[5] << 8));
1620  
1621  							DSP1_Op2B();
1622  
1623  							DSP1.out_count = 2;
1624  							DSP1.output[0] = (uint8)  (DSP1.Op2BS       & 0xFF);
1625  							DSP1.output[1] = (uint8) ((DSP1.Op2BS >> 8) & 0xFF);
1626  							break;
1627  
1628  						case 0x34:
1629  						case 0x14:
1630  							DSP1.Op14Zr = (int16) (DSP1.parameters[ 0] | (DSP1.parameters[ 1] << 8));
1631  							DSP1.Op14Xr = (int16) (DSP1.parameters[ 2] | (DSP1.parameters[ 3] << 8));
1632  							DSP1.Op14Yr = (int16) (DSP1.parameters[ 4] | (DSP1.parameters[ 5] << 8));
1633  							DSP1.Op14U  = (int16) (DSP1.parameters[ 6] | (DSP1.parameters[ 7] << 8));
1634  							DSP1.Op14F  = (int16) (DSP1.parameters[ 8] | (DSP1.parameters[ 9] << 8));
1635  							DSP1.Op14L  = (int16) (DSP1.parameters[10] | (DSP1.parameters[11] << 8));
1636  
1637  							DSP1_Op14();
1638  
1639  							DSP1.out_count = 6;
1640  							DSP1.output[0] = (uint8)  (DSP1.Op14Zrr       & 0xFF);
1641  							DSP1.output[1] = (uint8) ((DSP1.Op14Zrr >> 8) & 0xFF);
1642  							DSP1.output[2] = (uint8)  (DSP1.Op14Xrr       & 0xFF);
1643  							DSP1.output[3] = (uint8) ((DSP1.Op14Xrr >> 8) & 0xFF);
1644  							DSP1.output[4] = (uint8)  (DSP1.Op14Yrr       & 0xFF);
1645  							DSP1.output[5] = (uint8) ((DSP1.Op14Yrr >> 8) & 0xFF);
1646  							break;
1647  
1648  						case 0x27:
1649  						case 0x2F:
1650  							DSP1.Op2FUnknown = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1651  
1652  							DSP1_Op2F();
1653  
1654  							DSP1.out_count = 2;
1655  							DSP1.output[0] = (uint8)  (DSP1.Op2FSize       & 0xFF);
1656  							DSP1.output[1] = (uint8) ((DSP1.Op2FSize >> 8) & 0xFF);
1657  							break;
1658  
1659  
1660  						case 0x07:
1661  						case 0x0F:
1662  							DSP1.Op0FRamsize = (int16) (DSP1.parameters[0] | (DSP1.parameters[1] << 8));
1663  
1664  							DSP1_Op0F();
1665  
1666  							DSP1.out_count = 2;
1667  							DSP1.output[0] = (uint8)  (DSP1.Op0FPass       & 0xFF);
1668  							DSP1.output[1] = (uint8) ((DSP1.Op0FPass >> 8) & 0xFF);
1669  							break;
1670  
1671  						default:
1672  							break;
1673  					}
1674  				}
1675  			}
1676  		}
1677  	}
1678  }
1679  
1680  uint8 DSP1GetByte (uint16 address)
1681  {
1682  	uint8	t;
1683  
1684  	if (address < DSP0.boundary)
1685  	{
1686  		if (DSP1.out_count)
1687  		{
1688  			t = (uint8) DSP1.output[DSP1.out_index];
1689  
1690  			DSP1.out_index++;
1691  
1692  			if (--DSP1.out_count == 0)
1693  			{
1694  				if (DSP1.command == 0x1a || DSP1.command == 0x0a)
1695  				{
1696  					DSP1_Op0A();
1697  					DSP1.out_count = 8;
1698  					DSP1.out_index = 0;
1699  					DSP1.output[0] =  DSP1.Op0AA       & 0xFF;
1700  					DSP1.output[1] = (DSP1.Op0AA >> 8) & 0xFF;
1701  					DSP1.output[2] =  DSP1.Op0AB       & 0xFF;
1702  					DSP1.output[3] = (DSP1.Op0AB >> 8) & 0xFF;
1703  					DSP1.output[4] =  DSP1.Op0AC       & 0xFF;
1704  					DSP1.output[5] = (DSP1.Op0AC >> 8) & 0xFF;
1705  					DSP1.output[6] =  DSP1.Op0AD       & 0xFF;
1706  					DSP1.output[7] = (DSP1.Op0AD >> 8) & 0xFF;
1707  				}
1708  
1709  				if (DSP1.command == 0x1f)
1710  				{
1711  					if ((DSP1.out_index % 2) != 0)
1712  						t = (uint8) DSP1ROM[DSP1.out_index >> 1];
1713  					else
1714  						t = DSP1ROM[DSP1.out_index >> 1] >> 8;
1715  				}
1716  			}
1717  
1718  			DSP1.waiting4command = TRUE;
1719  		}
1720  		else
1721  			t = 0x80;
1722  	}
1723  	else
1724  		t = 0x80;
1725  
1726  	return (t);
1727  }