1 /***********************************************************************************
2   Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 
4   (c) Copyright 1996 - 2002  Gary Henderson (gary.henderson@ntlworld.com),
5                              Jerremy Koot (jkoot@snes9x.com)
6 
7   (c) Copyright 2002 - 2004  Matthew Kendora
8 
9   (c) Copyright 2002 - 2005  Peter Bortas (peter@bortas.org)
10 
11   (c) Copyright 2004 - 2005  Joel Yliluoma (http://iki.fi/bisqwit/)
12 
13   (c) Copyright 2001 - 2006  John Weidman (jweidman@slip.net)
14 
15   (c) Copyright 2002 - 2006  funkyass (funkyass@spam.shaw.ca),
16                              Kris Bleakley (codeviolation@hotmail.com)
17 
18   (c) Copyright 2002 - 2010  Brad Jorsch (anomie@users.sourceforge.net),
19                              Nach (n-a-c-h@users.sourceforge.net),
20 
21   (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
22 
23   (c) Copyright 2006 - 2007  nitsuja
24 
25   (c) Copyright 2009 - 2016  BearOso,
26                              OV2
27 
28 
29   BS-X C emulator code
30   (c) Copyright 2005 - 2006  Dreamer Nom,
31                              zones
32 
33   C4 x86 assembler and some C emulation code
34   (c) Copyright 2000 - 2003  _Demo_ (_demo_@zsnes.com),
35                              Nach,
36                              zsKnight (zsknight@zsnes.com)
37 
38   C4 C++ code
39   (c) Copyright 2003 - 2006  Brad Jorsch,
40                              Nach
41 
42   DSP-1 emulator code
43   (c) Copyright 1998 - 2006  _Demo_,
44                              Andreas Naive (andreasnaive@gmail.com),
45                              Gary Henderson,
46                              Ivar (ivar@snes9x.com),
47                              John Weidman,
48                              Kris Bleakley,
49                              Matthew Kendora,
50                              Nach,
51                              neviksti (neviksti@hotmail.com)
52 
53   DSP-2 emulator code
54   (c) Copyright 2003         John Weidman,
55                              Kris Bleakley,
56                              Lord Nightmare (lord_nightmare@users.sourceforge.net),
57                              Matthew Kendora,
58                              neviksti
59 
60   DSP-3 emulator code
61   (c) Copyright 2003 - 2006  John Weidman,
62                              Kris Bleakley,
63                              Lancer,
64                              z80 gaiden
65 
66   DSP-4 emulator code
67   (c) Copyright 2004 - 2006  Dreamer Nom,
68                              John Weidman,
69                              Kris Bleakley,
70                              Nach,
71                              z80 gaiden
72 
73   OBC1 emulator code
74   (c) Copyright 2001 - 2004  zsKnight,
75                              pagefault (pagefault@zsnes.com),
76                              Kris Bleakley
77                              Ported from x86 assembler to C by sanmaiwashi
78 
79   SPC7110 and RTC C++ emulator code used in 1.39-1.51
80   (c) Copyright 2002         Matthew Kendora with research by
81                              zsKnight,
82                              John Weidman,
83                              Dark Force
84 
85   SPC7110 and RTC C++ emulator code used in 1.52+
86   (c) Copyright 2009         byuu,
87                              neviksti
88 
89   S-DD1 C emulator code
90   (c) Copyright 2003         Brad Jorsch with research by
91                              Andreas Naive,
92                              John Weidman
93 
94   S-RTC C emulator code
95   (c) Copyright 2001 - 2006  byuu,
96                              John Weidman
97 
98   ST010 C++ emulator code
99   (c) Copyright 2003         Feather,
100                              John Weidman,
101                              Kris Bleakley,
102                              Matthew Kendora
103 
104   Super FX x86 assembler emulator code
105   (c) Copyright 1998 - 2003  _Demo_,
106                              pagefault,
107                              zsKnight
108 
109   Super FX C emulator code
110   (c) Copyright 1997 - 1999  Ivar,
111                              Gary Henderson,
112                              John Weidman
113 
114   Sound emulator code used in 1.5-1.51
115   (c) Copyright 1998 - 2003  Brad Martin
116   (c) Copyright 1998 - 2006  Charles Bilyue'
117 
118   Sound emulator code used in 1.52+
119   (c) Copyright 2004 - 2007  Shay Green (gblargg@gmail.com)
120 
121   S-SMP emulator code used in 1.54+
122   (c) Copyright 2016         byuu
123 
124   SH assembler code partly based on x86 assembler code
125   (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
126 
127   2xSaI filter
128   (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
129 
130   HQ2x, HQ3x, HQ4x filters
131   (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
132 
133   NTSC filter
134   (c) Copyright 2006 - 2007  Shay Green
135 
136   GTK+ GUI code
137   (c) Copyright 2004 - 2016  BearOso
138 
139   Win32 GUI code
140   (c) Copyright 2003 - 2006  blip,
141                              funkyass,
142                              Matthew Kendora,
143                              Nach,
144                              nitsuja
145   (c) Copyright 2009 - 2016  OV2
146 
147   Mac OS GUI code
148   (c) Copyright 1998 - 2001  John Stiles
149   (c) Copyright 2001 - 2011  zones
150 
151 
152   Specific ports contains the works of other authors. See headers in
153   individual files.
154 
155 
156   Snes9x homepage: http://www.snes9x.com/
157 
158   Permission to use, copy, modify and/or distribute Snes9x in both binary
159   and source form, for non-commercial purposes, is hereby granted without
160   fee, providing that this license information and copyright notice appear
161   with all copies and any derived work.
162 
163   This software is provided 'as-is', without any express or implied
164   warranty. In no event shall the authors be held liable for any damages
165   arising from the use of this software or it's derivatives.
166 
167   Snes9x is freeware for PERSONAL USE only. Commercial users should
168   seek permission of the copyright holders first. Commercial use includes,
169   but is not limited to, charging money for Snes9x or software derived from
170   Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
171   using Snes9x as a promotion for your commercial product.
172 
173   The copyright holders request that bug fixes and improvements to the code
174   should be forwarded to them so everyone can benefit from the modifications
175   in future versions.
176 
177   Super NES and Super Nintendo Entertainment System are trademarks of
178   Nintendo Co., Limited and its subsidiary companies.
179  ***********************************************************************************/
180 
181 
182 #include "snes9x.h"
183 #include "memmap.h"
184 
185 static void (*SetDSP3) (void);
186 
187 static const uint16	DSP3_DataROM[1024] =
188 {
189 	0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100,
190 	0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001,
191 	0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
192 	0x0000, 0x000f, 0x0400, 0x0200, 0x0140, 0x0400, 0x0200, 0x0040,
193 	0x007d, 0x007e, 0x007e, 0x007b, 0x007c, 0x007d, 0x007b, 0x007c,
194 	0x0002, 0x0020, 0x0030, 0x0000, 0x000d, 0x0019, 0x0026, 0x0032,
195 	0x003e, 0x004a, 0x0056, 0x0062, 0x006d, 0x0079, 0x0084, 0x008e,
196 	0x0098, 0x00a2, 0x00ac, 0x00b5, 0x00be, 0x00c6, 0x00ce, 0x00d5,
197 	0x00dc, 0x00e2, 0x00e7, 0x00ec, 0x00f1, 0x00f5, 0x00f8, 0x00fb,
198 	0x00fd, 0x00ff, 0x0100, 0x0100, 0x0100, 0x00ff, 0x00fd, 0x00fb,
199 	0x00f8, 0x00f5, 0x00f1, 0x00ed, 0x00e7, 0x00e2, 0x00dc, 0x00d5,
200 	0x00ce, 0x00c6, 0x00be, 0x00b5, 0x00ac, 0x00a2, 0x0099, 0x008e,
201 	0x0084, 0x0079, 0x006e, 0x0062, 0x0056, 0x004a, 0x003e, 0x0032,
202 	0x0026, 0x0019, 0x000d, 0x0000, 0xfff3, 0xffe7, 0xffdb, 0xffce,
203 	0xffc2, 0xffb6, 0xffaa, 0xff9e, 0xff93, 0xff87, 0xff7d, 0xff72,
204 	0xff68, 0xff5e, 0xff54, 0xff4b, 0xff42, 0xff3a, 0xff32, 0xff2b,
205 	0xff25, 0xff1e, 0xff19, 0xff14, 0xff0f, 0xff0b, 0xff08, 0xff05,
206 	0xff03, 0xff01, 0xff00, 0xff00, 0xff00, 0xff01, 0xff03, 0xff05,
207 	0xff08, 0xff0b, 0xff0f, 0xff13, 0xff18, 0xff1e, 0xff24, 0xff2b,
208 	0xff32, 0xff3a, 0xff42, 0xff4b, 0xff54, 0xff5d, 0xff67, 0xff72,
209 	0xff7c, 0xff87, 0xff92, 0xff9e, 0xffa9, 0xffb5, 0xffc2, 0xffce,
210 	0xffda, 0xffe7, 0xfff3, 0x002b, 0x007f, 0x0020, 0x00ff, 0xff00,
211 	0xffbe, 0x0000, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
212 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
213 	0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0x0045,
214 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
215 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
216 	0xffc5, 0x0003, 0x0004, 0x0005, 0x0047, 0x0000, 0x0000, 0x0000,
217 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
218 	0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
219 	0x0009, 0x004a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
220 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
221 	0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x004e, 0x0000,
222 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
223 	0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
224 	0x0012, 0x0013, 0x0014, 0x0053, 0x0000, 0x0000, 0x0000, 0x0000,
225 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
226 	0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
227 	0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
228 	0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
229 	0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0060, 0x0000, 0x0000,
230 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
231 	0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
232 	0x002b, 0x002c, 0x0068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
233 	0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
234 	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0071,
235 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
236 	0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
237 	0x003e, 0x003f, 0x0040, 0x0041, 0x007b, 0x0000, 0x0000, 0x0000,
238 	0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
239 	0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
240 	0x000b, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
241 	0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
242 	0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0050, 0x0000,
243 	0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
244 	0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
245 	0x0024, 0x0025, 0x0026, 0x005d, 0x0000, 0x0000, 0x0000, 0x0000,
246 	0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
247 	0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
248 	0x006b, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
249 	0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
250 	0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0044, 0x0000, 0x0000,
251 	0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
252 	0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
253 	0x001f, 0x0020, 0x0054, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
254 	0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
255 	0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0065,
256 	0xffbe, 0x0000, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
257 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
258 	0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0xfead,
259 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
260 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
261 	0xffc5, 0x0003, 0x0004, 0x0005, 0xfeaf, 0x0000, 0x0000, 0x0000,
262 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
263 	0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
264 	0x0009, 0xfeb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
265 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
266 	0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0xfeb6, 0x0000,
267 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
268 	0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
269 	0x0012, 0x0013, 0x0014, 0xfebb, 0x0000, 0x0000, 0x0000, 0x0000,
270 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
271 	0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
272 	0xfec1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
273 	0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
274 	0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0xfec8, 0x0000, 0x0000,
275 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
276 	0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
277 	0x002b, 0x002c, 0xfed0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
278 	0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
279 	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0xfed9,
280 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
281 	0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
282 	0x003e, 0x003f, 0x0040, 0x0041, 0xfee3, 0x0000, 0x0000, 0x0000,
283 	0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
284 	0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
285 	0x000b, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
286 	0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
287 	0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0xfeb8, 0x0000,
288 	0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
289 	0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
290 	0x0024, 0x0025, 0x0026, 0xfec5, 0x0000, 0x0000, 0x0000, 0x0000,
291 	0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
292 	0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
293 	0xfed3, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
294 	0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
295 	0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xfeac, 0x0000, 0x0000,
296 	0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
297 	0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
298 	0x001f, 0x0020, 0xfebc, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
299 	0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
300 	0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0xfecd,
301 	0x0154, 0x0218, 0x0110, 0x00b0, 0x00cc, 0x00b0, 0x0088, 0x00b0,
302 	0x0044, 0x00b0, 0x0000, 0x00b0, 0x00fe, 0xff07, 0x0002, 0x00ff,
303 	0x00f8, 0x0007, 0x00fe, 0x00ee, 0x07ff, 0x0200, 0x00ef, 0xf800,
304 	0x0700, 0x00ee, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0001,
305 	0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
306 	0xffff, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000,
307 	0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0x0001, 0x0000, 0x0001,
308 	0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000,
309 	0xffff, 0x0001, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff,
310 	0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0044, 0x0088, 0x00cc,
311 	0x0110, 0x0154, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
312 	0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
313 	0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
314 	0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
315 	0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
316 	0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
317 };
318 
319 static bool8 DSP3_GetBits (uint8);
320 //static void DSP3_MemorySize (void);
321 static void DSP3_TestMemory (void);
322 static void DSP3_DumpDataROM (void);
323 static void DSP3_MemoryDump (void);
324 static void DSP3_Coordinate (void);
325 static void DSP3_Command (void);
326 static void DSP3_Decode_Data (void);
327 static void DSP3_Decode_Tree (void);
328 static void DSP3_Decode_Symbols (void);
329 static void DSP3_Decode (void);
330 static void DSP3_Decode_A (void);
331 static void DSP3_Convert (void);
332 static void DSP3_Convert_A (void);
333 static void DSP3_OP03 (void);
334 static void DSP3_OP06 (void);
335 static void DSP3_OP07 (void);
336 static void DSP3_OP07_A (void);
337 static void DSP3_OP07_B (void);
338 static void DSP3_OP0C (void);
339 //static void DSP3_OP0C_A (void);
340 static void DSP3_OP10 (void);
341 static void DSP3_OP1C (void);
342 static void DSP3_OP1C_A (void);
343 static void DSP3_OP1C_B (void);
344 static void DSP3_OP1C_C (void);
345 static void DSP3_OP1E (void);
346 static void DSP3_OP1E_A (void);
347 static void DSP3_OP1E_A1 (void);
348 static void DSP3_OP1E_A2 (void);
349 static void DSP3_OP1E_A3 (void);
350 static void DSP3_OP1E_B (void);
351 static void DSP3_OP1E_B1 (void);
352 static void DSP3_OP1E_B2 (void);
353 static void DSP3_OP1E_C (void);
354 static void DSP3_OP1E_C1 (void);
355 static void DSP3_OP1E_C2 (void);
356 static void DSP3_OP1E_D (int16, int16 *, int16 *);
357 static void DSP3_OP1E_D1 (int16, int16 *, int16 *);
358 static void DSP3_OP3E (void);
359 
360 
DSP3_Reset(void)361 void DSP3_Reset (void)
362 {
363 	DSP3.DR = 0x0080;
364 	DSP3.SR = 0x0084;
365 	SetDSP3 = &DSP3_Command;
366 }
367 
368 /*
369 static void DSP3_MemorySize (void)
370 {
371 	DSP3.DR = 0x0300;
372 	SetDSP3 = &DSP3_Reset;
373 }
374 */
375 
DSP3_TestMemory(void)376 static void DSP3_TestMemory (void)
377 {
378 	DSP3.DR = 0x0000;
379 	SetDSP3 = &DSP3_Reset;
380 }
381 
DSP3_DumpDataROM(void)382 static void DSP3_DumpDataROM (void)
383 {
384 	DSP3.DR = DSP3_DataROM[DSP3.MemoryIndex++];
385 	if (DSP3.MemoryIndex == 1024)
386 		SetDSP3 = &DSP3_Reset;
387 }
388 
DSP3_MemoryDump(void)389 static void DSP3_MemoryDump (void)
390 {
391 	DSP3.MemoryIndex = 0;
392 	SetDSP3 = &DSP3_DumpDataROM;
393 	DSP3_DumpDataROM();
394 }
395 
DSP3_OP06(void)396 static void DSP3_OP06 (void)
397 {
398 	DSP3.WinLo = (uint8) (DSP3.DR);
399 	DSP3.WinHi = (uint8) (DSP3.DR >> 8);
400 	DSP3_Reset();
401 }
402 
DSP3_OP03(void)403 static void DSP3_OP03 (void)
404 {
405 	int16	Lo  = (uint8) (DSP3.DR);
406 	int16	Hi  = (uint8) (DSP3.DR >> 8);
407 	int16	Ofs = (DSP3.WinLo * Hi << 1) + (Lo << 1);
408 
409 	DSP3.DR = Ofs >> 1;
410 	SetDSP3 = &DSP3_Reset;
411 }
412 
DSP3_OP07_B(void)413 static void DSP3_OP07_B (void)
414 {
415 	int16	Ofs = (DSP3.WinLo * DSP3.AddHi << 1) + (DSP3.AddLo << 1);
416 
417 	DSP3.DR = Ofs >> 1;
418 	SetDSP3 = &DSP3_Reset;
419 }
420 
DSP3_OP07_A(void)421 static void DSP3_OP07_A (void)
422 {
423 	int16	Lo = (uint8) (DSP3.DR);
424 	int16	Hi = (uint8) (DSP3.DR >> 8);
425 
426 	if (Lo & 1)
427 		Hi += (DSP3.AddLo & 1);
428 
429 	DSP3.AddLo += Lo;
430 	DSP3.AddHi += Hi;
431 
432 	if (DSP3.AddLo < 0)
433 		DSP3.AddLo += DSP3.WinLo;
434 	else
435 	if (DSP3.AddLo >= DSP3.WinLo)
436 		DSP3.AddLo -= DSP3.WinLo;
437 
438 	if (DSP3.AddHi < 0)
439 		DSP3.AddHi += DSP3.WinHi;
440 	else
441 	if (DSP3.AddHi >= DSP3.WinHi)
442 		DSP3.AddHi -= DSP3.WinHi;
443 
444 	DSP3.DR = DSP3.AddLo | (DSP3.AddHi << 8) | ((DSP3.AddHi >> 8) & 0xff);
445 	SetDSP3 = &DSP3_OP07_B;
446 }
447 
DSP3_OP07(void)448 static void DSP3_OP07 (void)
449 {
450 	uint32	dataOfs = ((DSP3.DR << 1) + 0x03b2) & 0x03ff;
451 
452 	DSP3.AddHi = DSP3_DataROM[dataOfs];
453 	DSP3.AddLo = DSP3_DataROM[dataOfs + 1];
454 
455 	SetDSP3 = &DSP3_OP07_A;
456 	DSP3.SR = 0x0080;
457 }
458 
DSP3_Coordinate(void)459 static void DSP3_Coordinate (void)
460 {
461 	DSP3.Index++;
462 
463 	switch (DSP3.Index)
464 	{
465 		case 3:
466 			if (DSP3.DR == 0xffff)
467 				DSP3_Reset();
468 			break;
469 
470 		case 4:
471 			DSP3.X = DSP3.DR;
472 			break;
473 
474 		case 5:
475 			DSP3.Y = DSP3.DR;
476 			DSP3.DR = 1;
477 			break;
478 
479 		case 6:
480 			DSP3.DR = DSP3.X;
481 			break;
482 
483 		case 7:
484 			DSP3.DR = DSP3.Y;
485 			DSP3.Index = 0;
486 			break;
487 	}
488 }
489 
DSP3_Convert_A(void)490 static void DSP3_Convert_A (void)
491 {
492 	if (DSP3.BMIndex < 8)
493 	{
494 		DSP3.Bitmap[DSP3.BMIndex++] = (uint8) (DSP3.DR);
495 		DSP3.Bitmap[DSP3.BMIndex++] = (uint8) (DSP3.DR >> 8);
496 
497 		if (DSP3.BMIndex == 8)
498 		{
499 			for (int i = 0; i < 8; i++)
500 			{
501 				for (int j = 0; j < 8; j++)
502 				{
503 					DSP3.Bitplane[j] <<= 1;
504 					DSP3.Bitplane[j] |= (DSP3.Bitmap[i] >> j) & 1;
505 				}
506 			}
507 
508 			DSP3.BPIndex = 0;
509 			DSP3.Count--;
510 		}
511 	}
512 
513 	if (DSP3.BMIndex == 8)
514 	{
515 		if (DSP3.BPIndex == 8)
516 		{
517 			if (!DSP3.Count)
518 				DSP3_Reset();
519 
520 			DSP3.BMIndex = 0;
521 		}
522 		else
523 		{
524 			DSP3.DR  = DSP3.Bitplane[DSP3.BPIndex++];
525 			DSP3.DR |= DSP3.Bitplane[DSP3.BPIndex++] << 8;
526 		}
527 	}
528 }
529 
DSP3_Convert(void)530 static void DSP3_Convert (void)
531 {
532 	DSP3.Count = DSP3.DR;
533 	DSP3.BMIndex = 0;
534 	SetDSP3 = &DSP3_Convert_A;
535 }
536 
DSP3_GetBits(uint8 Count)537 static bool8 DSP3_GetBits (uint8 Count)
538 {
539 	if (!DSP3.BitsLeft)
540 	{
541 		DSP3.BitsLeft = Count;
542 		DSP3.ReqBits = 0;
543 	}
544 
545 	do
546 	{
547 		if (!DSP3.BitCount)
548 		{
549 			DSP3.SR = 0xC0;
550 			return (FALSE);
551 		}
552 
553 		DSP3.ReqBits <<= 1;
554 		if (DSP3.ReqData & 0x8000)
555 			DSP3.ReqBits++;
556 		DSP3.ReqData <<= 1;
557 
558 		DSP3.BitCount--;
559 		DSP3.BitsLeft--;
560 
561 	}
562 	while (DSP3.BitsLeft);
563 
564 	return (TRUE);
565 }
566 
DSP3_Decode_Data(void)567 static void DSP3_Decode_Data (void)
568 {
569 	if (!DSP3.BitCount)
570 	{
571 		if (DSP3.SR & 0x40)
572 		{
573 			DSP3.ReqData = DSP3.DR;
574 			DSP3.BitCount += 16;
575 		}
576 		else
577 		{
578 			DSP3.SR = 0xC0;
579 			return;
580 		}
581 	}
582 
583 	if (DSP3.LZCode == 1)
584 	{
585 		if (!DSP3_GetBits(1))
586 			return;
587 
588 		if (DSP3.ReqBits)
589 			DSP3.LZLength = 12;
590 		else
591 			DSP3.LZLength = 8;
592 
593 		DSP3.LZCode++;
594 	}
595 
596 	if (DSP3.LZCode == 2)
597 	{
598 		if (!DSP3_GetBits(DSP3.LZLength))
599 			return;
600 
601 		DSP3.LZCode = 0;
602 		DSP3.Outwords--;
603 		if (!DSP3.Outwords)
604 			SetDSP3 = &DSP3_Reset;
605 
606 		DSP3.SR = 0x80;
607 		DSP3.DR = DSP3.ReqBits;
608 		return;
609 	}
610 
611 	if (DSP3.BaseCode == 0xffff)
612 	{
613 		if (!DSP3_GetBits(DSP3.BaseLength))
614 			return;
615 
616 		DSP3.BaseCode = DSP3.ReqBits;
617 	}
618 
619 	if (!DSP3_GetBits(DSP3.CodeLengths[DSP3.BaseCode]))
620 		return;
621 
622 	DSP3.Symbol = DSP3.Codes[DSP3.CodeOffsets[DSP3.BaseCode] + DSP3.ReqBits];
623 	DSP3.BaseCode = 0xffff;
624 
625 	if (DSP3.Symbol & 0xff00)
626 	{
627 		DSP3.Symbol += 0x7f02;
628 		DSP3.LZCode++;
629 	}
630 	else
631 	{
632 		DSP3.Outwords--;
633 		if (!DSP3.Outwords)
634 			SetDSP3 = &DSP3_Reset;
635 	}
636 
637 	DSP3.SR = 0x80;
638 	DSP3.DR = DSP3.Symbol;
639 }
640 
DSP3_Decode_Tree(void)641 static void DSP3_Decode_Tree (void)
642 {
643 	if (!DSP3.BitCount)
644 	{
645 		DSP3.ReqData = DSP3.DR;
646 		DSP3.BitCount += 16;
647 	}
648 
649 	if (!DSP3.BaseCodes)
650 	{
651 		DSP3_GetBits(1);
652 
653 		if (DSP3.ReqBits)
654 		{
655 			DSP3.BaseLength = 3;
656 			DSP3.BaseCodes = 8;
657 		}
658 		else
659 		{
660 			DSP3.BaseLength = 2;
661 			DSP3.BaseCodes = 4;
662 		}
663 	}
664 
665 	while (DSP3.BaseCodes)
666 	{
667 		if (!DSP3_GetBits(3))
668 			return;
669 
670 		DSP3.ReqBits++;
671 
672 		DSP3.CodeLengths[DSP3.Index] = (uint8) DSP3.ReqBits;
673 		DSP3.CodeOffsets[DSP3.Index] = DSP3.Symbol;
674 		DSP3.Index++;
675 
676 		DSP3.Symbol += 1 << DSP3.ReqBits;
677 		DSP3.BaseCodes--;
678 	}
679 
680 	DSP3.BaseCode = 0xffff;
681 	DSP3.LZCode = 0;
682 
683 	SetDSP3 = &DSP3_Decode_Data;
684 	if (DSP3.BitCount)
685 		DSP3_Decode_Data();
686 }
687 
DSP3_Decode_Symbols(void)688 static void DSP3_Decode_Symbols (void)
689 {
690 	DSP3.ReqData = DSP3.DR;
691 	DSP3.BitCount += 16;
692 
693 	do
694 	{
695 		if (DSP3.BitCommand == 0xffff)
696 		{
697 			if (!DSP3_GetBits(2))
698 				return;
699 
700 			DSP3.BitCommand = DSP3.ReqBits;
701 		}
702 
703 		switch (DSP3.BitCommand)
704 		{
705 			case 0:
706 				if (!DSP3_GetBits(9))
707 					return;
708 				DSP3.Symbol = DSP3.ReqBits;
709 				break;
710 
711 			case 1:
712 				DSP3.Symbol++;
713 				break;
714 
715 			case 2:
716 				if (!DSP3_GetBits(1))
717 					return;
718 				DSP3.Symbol += 2 + DSP3.ReqBits;
719 				break;
720 
721 			case 3:
722 				if (!DSP3_GetBits(4))
723 					return;
724 				DSP3.Symbol += 4 + DSP3.ReqBits;
725 				break;
726 		}
727 
728 		DSP3.BitCommand = 0xffff;
729 
730 		DSP3.Codes[DSP3.Index++] = DSP3.Symbol;
731 		DSP3.Codewords--;
732 
733 	}
734 	while (DSP3.Codewords);
735 
736 	DSP3.Index = 0;
737 	DSP3.Symbol = 0;
738 	DSP3.BaseCodes = 0;
739 
740 	SetDSP3 = &DSP3_Decode_Tree;
741 	if (DSP3.BitCount)
742 		DSP3_Decode_Tree();
743 }
744 
DSP3_Decode_A(void)745 static void DSP3_Decode_A (void)
746 {
747 	DSP3.Outwords = DSP3.DR;
748 	SetDSP3 = &DSP3_Decode_Symbols;
749 	DSP3.BitCount = 0;
750 	DSP3.BitsLeft = 0;
751 	DSP3.Symbol = 0;
752 	DSP3.Index = 0;
753 	DSP3.BitCommand = 0xffff;
754 	DSP3.SR = 0xC0;
755 }
756 
DSP3_Decode(void)757 static void DSP3_Decode (void)
758 {
759 	DSP3.Codewords = DSP3.DR;
760 	SetDSP3 = &DSP3_Decode_A;
761 }
762 
763 // Opcodes 1E/3E bit-perfect to 'dsp3-intro' log
764 // src: adapted from SD Gundam X/G-Next
765 
DSP3_OP3E(void)766 static void DSP3_OP3E (void)
767 {
768 	DSP3. op3e_x = (uint8)  (DSP3.DR & 0x00ff);
769 	DSP3. op3e_y = (uint8) ((DSP3.DR & 0xff00) >> 8);
770 
771 	DSP3_OP03();
772 
773 	DSP3.op1e_terrain[DSP3.DR] = 0x00;
774 	DSP3.op1e_cost[DSP3.DR]    = 0xff;
775 	DSP3.op1e_weight[DSP3.DR]  = 0;
776 
777 	DSP3.op1e_max_search_radius = 0;
778 	DSP3.op1e_max_path_radius   = 0;
779 }
780 
DSP3_OP1E(void)781 static void DSP3_OP1E (void)
782 {
783 	DSP3.op1e_min_radius = (uint8)  (DSP3.DR & 0x00ff);
784 	DSP3.op1e_max_radius = (uint8) ((DSP3.DR & 0xff00) >> 8);
785 
786 	if (DSP3.op1e_min_radius == 0)
787 		DSP3.op1e_min_radius++;
788 
789 	if (DSP3.op1e_max_search_radius >= DSP3.op1e_min_radius)
790 		DSP3.op1e_min_radius = DSP3.op1e_max_search_radius + 1;
791 
792 	if (DSP3.op1e_max_radius > DSP3.op1e_max_search_radius)
793 		DSP3.op1e_max_search_radius = DSP3.op1e_max_radius;
794 
795 	DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
796 	DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
797 
798 	DSP3.op1e_lcv_turns = 6;
799 	DSP3.op1e_turn = 0;
800 
801 	DSP3.op1e_x = DSP3. op3e_x;
802 	DSP3.op1e_y = DSP3. op3e_y;
803 
804 	for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
805 		DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
806 
807 	DSP3_OP1E_A();
808 }
809 
DSP3_OP1E_A(void)810 static void DSP3_OP1E_A (void)
811 {
812 	if (DSP3.op1e_lcv_steps == 0)
813 	{
814 		DSP3.op1e_lcv_radius++;
815 
816 		DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
817 
818 		DSP3.op1e_x = DSP3. op3e_x;
819 		DSP3.op1e_y = DSP3. op3e_y;
820 
821 		for (int lcv = 0; lcv < DSP3.op1e_lcv_radius; lcv++)
822 			DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
823 	}
824 
825 	if (DSP3.op1e_lcv_radius > DSP3.op1e_max_radius)
826 	{
827 		DSP3.op1e_turn++;
828 		DSP3.op1e_lcv_turns--;
829 
830 		DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
831 		DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
832 
833 		DSP3.op1e_x = DSP3. op3e_x;
834 		DSP3.op1e_y = DSP3. op3e_y;
835 
836 		for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
837 			DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
838 	}
839 
840 	if (DSP3.op1e_lcv_turns == 0)
841 	{
842 		DSP3.DR = 0xffff;
843 		DSP3.SR = 0x0080;
844 		SetDSP3 = &DSP3_OP1E_B;
845 		return;
846 	}
847 
848 	DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
849 	DSP3_OP03();
850 
851 	DSP3.op1e_cell = DSP3.DR;
852 
853 	DSP3.SR = 0x0080;
854 	SetDSP3 = &DSP3_OP1E_A1;
855 }
856 
DSP3_OP1E_A1(void)857 static void DSP3_OP1E_A1 (void)
858 {
859 	DSP3.SR = 0x0084;
860 	SetDSP3 = &DSP3_OP1E_A2;
861 }
862 
DSP3_OP1E_A2(void)863 static void DSP3_OP1E_A2 (void)
864 {
865 	DSP3.op1e_terrain[DSP3.op1e_cell] = (uint8) (DSP3.DR & 0x00ff);
866 
867 	DSP3.SR = 0x0084;
868 	SetDSP3 = &DSP3_OP1E_A3;
869 }
870 
DSP3_OP1E_A3(void)871 static void DSP3_OP1E_A3 (void)
872 {
873 	DSP3.op1e_cost[DSP3.op1e_cell] = (uint8) (DSP3.DR & 0x00ff);
874 
875 	if (DSP3.op1e_lcv_radius == 1)
876 	{
877 		if (DSP3.op1e_terrain[DSP3.op1e_cell] & 1)
878 			DSP3.op1e_weight[DSP3.op1e_cell] = 0xff;
879 		else
880 			DSP3.op1e_weight[DSP3.op1e_cell] = DSP3.op1e_cost[DSP3.op1e_cell];
881 	}
882 	else
883 		DSP3.op1e_weight[DSP3.op1e_cell] = 0xff;
884 
885 	DSP3_OP1E_D((int16) (DSP3.op1e_turn + 2), &DSP3.op1e_x, &DSP3.op1e_y);
886 	DSP3.op1e_lcv_steps--;
887 
888 	DSP3.SR = 0x0080;
889 	DSP3_OP1E_A();
890 }
891 
DSP3_OP1E_B(void)892 static void DSP3_OP1E_B (void)
893 {
894 	DSP3.op1e_x = DSP3. op3e_x;
895 	DSP3.op1e_y = DSP3. op3e_y;
896 	DSP3.op1e_lcv_radius = 1;
897 
898 	DSP3.op1e_search = 0;
899 
900 	DSP3_OP1E_B1();
901 
902 	SetDSP3 = &DSP3_OP1E_C;
903 }
904 
DSP3_OP1E_B1(void)905 static void DSP3_OP1E_B1 (void)
906 {
907 	while (DSP3.op1e_lcv_radius < DSP3.op1e_max_radius)
908 	{
909 		DSP3.op1e_y--;
910 
911 		DSP3.op1e_lcv_turns = 6;
912 		DSP3.op1e_turn = 5;
913 
914 		while (DSP3.op1e_lcv_turns)
915 		{
916 			DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
917 
918 			while (DSP3.op1e_lcv_steps)
919 			{
920 				DSP3_OP1E_D1(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
921 
922 				if (0 <= DSP3.op1e_y && DSP3.op1e_y < DSP3.WinHi && 0 <= DSP3.op1e_x && DSP3.op1e_x < DSP3.WinLo)
923 				{
924 					DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
925 					DSP3_OP03();
926 
927 					DSP3.op1e_cell = DSP3.DR;
928 					if (DSP3.op1e_cost[DSP3.op1e_cell] < 0x80 && DSP3.op1e_terrain[DSP3.op1e_cell] < 0x40)
929 						DSP3_OP1E_B2(); // end cell perimeter
930 				}
931 
932 				DSP3.op1e_lcv_steps--;
933 			} // end search line
934 
935 			DSP3.op1e_turn--;
936 			if (DSP3.op1e_turn == 0)
937 				DSP3.op1e_turn = 6;
938 
939 			DSP3.op1e_lcv_turns--;
940 		} // end circle search
941 
942 		DSP3.op1e_lcv_radius++;
943 	} // end radius search
944 }
945 
DSP3_OP1E_B2(void)946 static void DSP3_OP1E_B2 (void)
947 {
948 	int16	cell;
949 	int16	path;
950 	int16	x, y;
951 	int16	lcv_turns;
952 
953 	path = 0xff;
954 	lcv_turns = 6;
955 
956 	while (lcv_turns)
957 	{
958 		x = DSP3.op1e_x;
959 		y = DSP3.op1e_y;
960 
961 		DSP3_OP1E_D1(lcv_turns, &x, &y);
962 
963 		DSP3.DR = (uint8) (x) | ((uint8) (y) << 8);
964 		DSP3_OP03();
965 
966 		cell = DSP3.DR;
967 
968 		if (0 <= y && y < DSP3.WinHi && 0 <= x && x < DSP3.WinLo)
969 		{
970 			if (DSP3.op1e_terrain[cell] < 0x80 || DSP3.op1e_weight[cell] == 0)
971 			{
972 				if (DSP3.op1e_weight[cell] < path)
973 					path = DSP3.op1e_weight[cell];
974 			}
975 		} // end step travel
976 
977 		lcv_turns--;
978 	} // end while turns
979 
980 	if (path != 0xff)
981 		DSP3.op1e_weight[DSP3.op1e_cell] = path + DSP3.op1e_cost[DSP3.op1e_cell];
982 }
983 
DSP3_OP1E_C(void)984 static void DSP3_OP1E_C (void)
985 {
986 	DSP3.op1e_min_radius = (uint8)  (DSP3.DR & 0x00ff);
987 	DSP3.op1e_max_radius = (uint8) ((DSP3.DR & 0xff00) >> 8);
988 
989 	if (DSP3.op1e_min_radius == 0)
990 		DSP3.op1e_min_radius++;
991 
992 	if (DSP3.op1e_max_path_radius >= DSP3.op1e_min_radius)
993 		DSP3.op1e_min_radius = DSP3.op1e_max_path_radius + 1;
994 
995 	if (DSP3.op1e_max_radius > DSP3.op1e_max_path_radius)
996 		DSP3.op1e_max_path_radius = DSP3.op1e_max_radius;
997 
998 	DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
999 	DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
1000 
1001 	DSP3.op1e_lcv_turns = 6;
1002 	DSP3.op1e_turn = 0;
1003 
1004 	DSP3.op1e_x = DSP3. op3e_x;
1005 	DSP3.op1e_y = DSP3. op3e_y;
1006 
1007 	for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
1008 		DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
1009 
1010 	DSP3_OP1E_C1();
1011 }
1012 
DSP3_OP1E_C1(void)1013 static void DSP3_OP1E_C1 (void)
1014 {
1015 	if (DSP3.op1e_lcv_steps == 0)
1016 	{
1017 		DSP3.op1e_lcv_radius++;
1018 
1019 		DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
1020 
1021 		DSP3.op1e_x = DSP3. op3e_x;
1022 		DSP3.op1e_y = DSP3. op3e_y;
1023 
1024 		for (int lcv = 0; lcv < DSP3.op1e_lcv_radius; lcv++)
1025 			DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
1026 	}
1027 
1028 	if (DSP3.op1e_lcv_radius > DSP3.op1e_max_radius)
1029 	{
1030 		DSP3.op1e_turn++;
1031 		DSP3.op1e_lcv_turns--;
1032 
1033 		DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
1034 		DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
1035 
1036 		DSP3.op1e_x = DSP3. op3e_x;
1037 		DSP3.op1e_y = DSP3. op3e_y;
1038 
1039 		for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
1040 			DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
1041 	}
1042 
1043 	if (DSP3.op1e_lcv_turns == 0)
1044 	{
1045 		DSP3.DR = 0xffff;
1046 		DSP3.SR = 0x0080;
1047 		SetDSP3 = &DSP3_Reset;
1048 		return;
1049 	}
1050 
1051 	DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
1052 	DSP3_OP03();
1053 
1054 	DSP3.op1e_cell = DSP3.DR;
1055 
1056 	DSP3.SR = 0x0080;
1057 	SetDSP3 = &DSP3_OP1E_C2;
1058 }
1059 
DSP3_OP1E_C2(void)1060 static void DSP3_OP1E_C2 (void)
1061 {
1062 	DSP3.DR = DSP3.op1e_weight[DSP3.op1e_cell];
1063 
1064 	DSP3_OP1E_D((int16) (DSP3.op1e_turn + 2), &DSP3.op1e_x, &DSP3.op1e_y);
1065 	DSP3.op1e_lcv_steps--;
1066 
1067 	DSP3.SR = 0x0084;
1068 	SetDSP3 = &DSP3_OP1E_C1;
1069 }
1070 
DSP3_OP1E_D(int16 move,int16 * lo,int16 * hi)1071 static void DSP3_OP1E_D (int16 move, int16 *lo, int16 *hi)
1072 {
1073 	uint32	dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
1074 	int16	Lo;
1075 	int16	Hi;
1076 
1077 	DSP3.AddHi = DSP3_DataROM[dataOfs];
1078 	DSP3.AddLo = DSP3_DataROM[dataOfs + 1];
1079 
1080 	Lo = (uint8) (*lo);
1081 	Hi = (uint8) (*hi);
1082 
1083 	if (Lo & 1)
1084 		Hi += (DSP3.AddLo & 1);
1085 
1086 	DSP3.AddLo += Lo;
1087 	DSP3.AddHi += Hi;
1088 
1089 	if (DSP3.AddLo < 0)
1090 		DSP3.AddLo += DSP3.WinLo;
1091 	else
1092 	if (DSP3.AddLo >= DSP3.WinLo)
1093 		DSP3.AddLo -= DSP3.WinLo;
1094 
1095 	if (DSP3.AddHi < 0)
1096 		DSP3.AddHi += DSP3.WinHi;
1097 	else
1098 	if (DSP3.AddHi >= DSP3.WinHi)
1099 		DSP3.AddHi -= DSP3.WinHi;
1100 
1101 	*lo = DSP3.AddLo;
1102 	*hi = DSP3.AddHi;
1103 }
1104 
DSP3_OP1E_D1(int16 move,int16 * lo,int16 * hi)1105 static void DSP3_OP1E_D1 (int16 move, int16 *lo, int16 *hi)
1106 {
1107 	const uint16	HiAdd[] =
1108 	{
1109 		0x00, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00
1110 	};
1111 
1112 	const uint16	LoAdd[] =
1113 	{
1114 		0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00
1115 	};
1116 
1117 	int16	Lo;
1118 	int16	Hi;
1119 
1120 	if ((*lo) & 1)
1121 		DSP3.AddHi = HiAdd[move + 8];
1122 	else
1123 		DSP3.AddHi = HiAdd[move + 0];
1124 
1125 	DSP3.AddLo = LoAdd[move];
1126 
1127 	Lo = (uint8) (*lo);
1128 	Hi = (uint8) (*hi);
1129 
1130 	if (Lo & 1)
1131 		Hi += (DSP3.AddLo & 1);
1132 
1133 	DSP3.AddLo += Lo;
1134 	DSP3.AddHi += Hi;
1135 
1136 	*lo = DSP3.AddLo;
1137 	*hi = DSP3.AddHi;
1138 }
1139 
DSP3_OP10(void)1140 static void DSP3_OP10 (void)
1141 {
1142 	if (DSP3.DR == 0xffff)
1143 		DSP3_Reset();
1144 	else
1145 		// absorb 2 bytes
1146 		DSP3.DR = DSP3.DR; // FIXME?
1147 }
1148 
1149 /*
1150 static void DSP3_OP0C_A (void)
1151 {
1152 	// absorb 2 bytes
1153 	DSP3.DR = 0;
1154 	SetDSP3 = &DSP3_Reset;
1155 }
1156 */
1157 
DSP3_OP0C(void)1158 static void DSP3_OP0C (void)
1159 {
1160 	// absorb 2 bytes
1161 	DSP3.DR = 0;
1162 	//SetDSP3 = &DSP3_OP0C_A;
1163 	SetDSP3 = &DSP3_Reset;
1164 }
1165 
DSP3_OP1C_C(void)1166 static void DSP3_OP1C_C (void)
1167 {
1168 	// return 2 bytes
1169 	DSP3.DR = 0;
1170 	SetDSP3 = &DSP3_Reset;
1171 }
1172 
DSP3_OP1C_B(void)1173 static void DSP3_OP1C_B (void)
1174 {
1175 	// return 2 bytes
1176 	DSP3.DR = 0;
1177 	SetDSP3 = &DSP3_OP1C_C;
1178 }
1179 
DSP3_OP1C_A(void)1180 static void DSP3_OP1C_A (void)
1181 {
1182 	// absorb 2 bytes
1183 	SetDSP3 = &DSP3_OP1C_B;
1184 }
1185 
DSP3_OP1C(void)1186 static void DSP3_OP1C (void)
1187 {
1188 	// absorb 2 bytes
1189 	SetDSP3 = &DSP3_OP1C_A;
1190 }
1191 
DSP3_Command(void)1192 static void DSP3_Command (void)
1193 {
1194 	if (DSP3.DR < 0x40)
1195 	{
1196 		switch (DSP3.DR)
1197 		{
1198 			case 0x02: SetDSP3 = &DSP3_Coordinate; break;
1199 			case 0x03: SetDSP3 = &DSP3_OP03;       break;
1200 			case 0x06: SetDSP3 = &DSP3_OP06;       break;
1201 			case 0x07: SetDSP3 = &DSP3_OP07;       return;
1202 			case 0x0c: SetDSP3 = &DSP3_OP0C;       break;
1203 			case 0x0f: SetDSP3 = &DSP3_TestMemory; break;
1204 			case 0x10: SetDSP3 = &DSP3_OP10;       break;
1205 			case 0x18: SetDSP3 = &DSP3_Convert;    break;
1206 			case 0x1c: SetDSP3 = &DSP3_OP1C;       break;
1207 			case 0x1e: SetDSP3 = &DSP3_OP1E;       break;
1208 			case 0x1f: SetDSP3 = &DSP3_MemoryDump; break;
1209 			case 0x38: SetDSP3 = &DSP3_Decode;     break;
1210 			case 0x3e: SetDSP3 = &DSP3_OP3E;       break;
1211 			default:
1212 				return;
1213 		}
1214 
1215 		DSP3.SR = 0x0080;
1216 		DSP3.Index = 0;
1217 	}
1218 }
1219 
DSP3SetByte(uint8 byte,uint16 address)1220 void DSP3SetByte (uint8 byte, uint16 address)
1221 {
1222 	if (address < DSP0.boundary)
1223 	{
1224 		if (DSP3.SR & 0x04)
1225 		{
1226 			DSP3.DR = (DSP3.DR & 0xff00) + byte;
1227 			(*SetDSP3)();
1228 		}
1229 		else
1230 		{
1231 			DSP3.SR ^= 0x10;
1232 
1233 			if (DSP3.SR & 0x10)
1234 				DSP3.DR = (DSP3.DR & 0xff00) + byte;
1235 			else
1236 			{
1237 				DSP3.DR = (DSP3.DR & 0x00ff) + (byte << 8);
1238 				(*SetDSP3)();
1239 			}
1240 		}
1241 	}
1242 }
1243 
DSP3GetByte(uint16 address)1244 uint8 DSP3GetByte (uint16 address)
1245 {
1246 	if (address < DSP0.boundary)
1247 	{
1248 		uint8	byte;
1249 
1250 		if (DSP3.SR & 0x04)
1251 		{
1252 			byte = (uint8) DSP3.DR;
1253 			(*SetDSP3)();
1254 		}
1255 		else
1256 		{
1257 			DSP3.SR ^= 0x10;
1258 
1259 			if (DSP3.SR & 0x10)
1260 				byte = (uint8) (DSP3.DR);
1261 			else
1262 			{
1263 				byte = (uint8) (DSP3.DR >> 8);
1264 				(*SetDSP3)();
1265 			}
1266 		}
1267 
1268 		return (byte);
1269 	}
1270 
1271 	return (uint8) DSP3.SR;
1272 }
1273