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