1/*****************************************************************************\
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3 This file is licensed under the Snes9x License.
4 For further information, consult the LICENSE file in the root directory.
5\*****************************************************************************/
6
7#include "snes9x.h"
8#include "memmap.h"
9
10static void (*SetDSP3) (void);
11
12static const uint16 DSP3_DataROM[1024] =
13{
14 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100,
15 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001,
16 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
17 0x0000, 0x000f, 0x0400, 0x0200, 0x0140, 0x0400, 0x0200, 0x0040,
18 0x007d, 0x007e, 0x007e, 0x007b, 0x007c, 0x007d, 0x007b, 0x007c,
19 0x0002, 0x0020, 0x0030, 0x0000, 0x000d, 0x0019, 0x0026, 0x0032,
20 0x003e, 0x004a, 0x0056, 0x0062, 0x006d, 0x0079, 0x0084, 0x008e,
21 0x0098, 0x00a2, 0x00ac, 0x00b5, 0x00be, 0x00c6, 0x00ce, 0x00d5,
22 0x00dc, 0x00e2, 0x00e7, 0x00ec, 0x00f1, 0x00f5, 0x00f8, 0x00fb,
23 0x00fd, 0x00ff, 0x0100, 0x0100, 0x0100, 0x00ff, 0x00fd, 0x00fb,
24 0x00f8, 0x00f5, 0x00f1, 0x00ed, 0x00e7, 0x00e2, 0x00dc, 0x00d5,
25 0x00ce, 0x00c6, 0x00be, 0x00b5, 0x00ac, 0x00a2, 0x0099, 0x008e,
26 0x0084, 0x0079, 0x006e, 0x0062, 0x0056, 0x004a, 0x003e, 0x0032,
27 0x0026, 0x0019, 0x000d, 0x0000, 0xfff3, 0xffe7, 0xffdb, 0xffce,
28 0xffc2, 0xffb6, 0xffaa, 0xff9e, 0xff93, 0xff87, 0xff7d, 0xff72,
29 0xff68, 0xff5e, 0xff54, 0xff4b, 0xff42, 0xff3a, 0xff32, 0xff2b,
30 0xff25, 0xff1e, 0xff19, 0xff14, 0xff0f, 0xff0b, 0xff08, 0xff05,
31 0xff03, 0xff01, 0xff00, 0xff00, 0xff00, 0xff01, 0xff03, 0xff05,
32 0xff08, 0xff0b, 0xff0f, 0xff13, 0xff18, 0xff1e, 0xff24, 0xff2b,
33 0xff32, 0xff3a, 0xff42, 0xff4b, 0xff54, 0xff5d, 0xff67, 0xff72,
34 0xff7c, 0xff87, 0xff92, 0xff9e, 0xffa9, 0xffb5, 0xffc2, 0xffce,
35 0xffda, 0xffe7, 0xfff3, 0x002b, 0x007f, 0x0020, 0x00ff, 0xff00,
36 0xffbe, 0x0000, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
37 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
38 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0x0045,
39 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
40 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
41 0xffc5, 0x0003, 0x0004, 0x0005, 0x0047, 0x0000, 0x0000, 0x0000,
42 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
43 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
44 0x0009, 0x004a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
45 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
46 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x004e, 0x0000,
47 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
48 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
49 0x0012, 0x0013, 0x0014, 0x0053, 0x0000, 0x0000, 0x0000, 0x0000,
50 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
51 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
52 0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
53 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
54 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0060, 0x0000, 0x0000,
55 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
56 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
57 0x002b, 0x002c, 0x0068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
58 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
59 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0071,
60 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
61 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
62 0x003e, 0x003f, 0x0040, 0x0041, 0x007b, 0x0000, 0x0000, 0x0000,
63 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
64 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
65 0x000b, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
66 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
67 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0050, 0x0000,
68 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
69 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
70 0x0024, 0x0025, 0x0026, 0x005d, 0x0000, 0x0000, 0x0000, 0x0000,
71 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
72 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
73 0x006b, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
74 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
75 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0044, 0x0000, 0x0000,
76 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
77 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
78 0x001f, 0x0020, 0x0054, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
79 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
80 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0065,
81 0xffbe, 0x0000, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
82 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
83 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0xfead,
84 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
85 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
86 0xffc5, 0x0003, 0x0004, 0x0005, 0xfeaf, 0x0000, 0x0000, 0x0000,
87 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
89 0x0009, 0xfeb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
90 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
91 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0xfeb6, 0x0000,
92 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
93 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
94 0x0012, 0x0013, 0x0014, 0xfebb, 0x0000, 0x0000, 0x0000, 0x0000,
95 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
96 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
97 0xfec1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
98 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
99 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0xfec8, 0x0000, 0x0000,
100 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
101 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
102 0x002b, 0x002c, 0xfed0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
103 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
104 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0xfed9,
105 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
106 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
107 0x003e, 0x003f, 0x0040, 0x0041, 0xfee3, 0x0000, 0x0000, 0x0000,
108 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
109 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
110 0x000b, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
111 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
112 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0xfeb8, 0x0000,
113 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
114 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
115 0x0024, 0x0025, 0x0026, 0xfec5, 0x0000, 0x0000, 0x0000, 0x0000,
116 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
117 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
118 0xfed3, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
119 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
120 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xfeac, 0x0000, 0x0000,
121 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
122 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
123 0x001f, 0x0020, 0xfebc, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
124 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
125 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0xfecd,
126 0x0154, 0x0218, 0x0110, 0x00b0, 0x00cc, 0x00b0, 0x0088, 0x00b0,
127 0x0044, 0x00b0, 0x0000, 0x00b0, 0x00fe, 0xff07, 0x0002, 0x00ff,
128 0x00f8, 0x0007, 0x00fe, 0x00ee, 0x07ff, 0x0200, 0x00ef, 0xf800,
129 0x0700, 0x00ee, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0001,
130 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
131 0xffff, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000,
132 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0x0001, 0x0000, 0x0001,
133 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000,
134 0xffff, 0x0001, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff,
135 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0044, 0x0088, 0x00cc,
136 0x0110, 0x0154, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
137 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
138 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
139 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
140 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
141 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
142};
143
144static bool8 DSP3_GetBits (uint8);
145//static void DSP3_MemorySize (void);
146static void DSP3_TestMemory (void);
147static void DSP3_DumpDataROM (void);
148static void DSP3_MemoryDump (void);
149static void DSP3_Coordinate (void);
150static void DSP3_Command (void);
151static void DSP3_Decode_Data (void);
152static void DSP3_Decode_Tree (void);
153static void DSP3_Decode_Symbols (void);
154static void DSP3_Decode (void);
155static void DSP3_Decode_A (void);
156static void DSP3_Convert (void);
157static void DSP3_Convert_A (void);
158static void DSP3_OP03 (void);
159static void DSP3_OP06 (void);
160static void DSP3_OP07 (void);
161static void DSP3_OP07_A (void);
162static void DSP3_OP07_B (void);
163static void DSP3_OP0C (void);
164//static void DSP3_OP0C_A (void);
165static void DSP3_OP10 (void);
166static void DSP3_OP1C (void);
167static void DSP3_OP1C_A (void);
168static void DSP3_OP1C_B (void);
169static void DSP3_OP1C_C (void);
170static void DSP3_OP1E (void);
171static void DSP3_OP1E_A (void);
172static void DSP3_OP1E_A1 (void);
173static void DSP3_OP1E_A2 (void);
174static void DSP3_OP1E_A3 (void);
175static void DSP3_OP1E_B (void);
176static void DSP3_OP1E_B1 (void);
177static void DSP3_OP1E_B2 (void);
178static void DSP3_OP1E_C (void);
179static void DSP3_OP1E_C1 (void);
180static void DSP3_OP1E_C2 (void);
181static void DSP3_OP1E_D (int16, int16 *, int16 *);
182static void DSP3_OP1E_D1 (int16, int16 *, int16 *);
183static void DSP3_OP3E (void);
184
185
186void DSP3_Reset (void)
187{
188 DSP3.DR = 0x0080;
189 DSP3.SR = 0x0084;
190 SetDSP3 = &DSP3_Command;
191}
192
193/*
194static void DSP3_MemorySize (void)
195{
196 DSP3.DR = 0x0300;
197 SetDSP3 = &DSP3_Reset;
198}
199*/
200
201static void DSP3_TestMemory (void)
202{
203 DSP3.DR = 0x0000;
204 SetDSP3 = &DSP3_Reset;
205}
206
207static void DSP3_DumpDataROM (void)
208{
209 DSP3.DR = DSP3_DataROM[DSP3.MemoryIndex++];
210 if (DSP3.MemoryIndex == 1024)
211 SetDSP3 = &DSP3_Reset;
212}
213
214static void DSP3_MemoryDump (void)
215{
216 DSP3.MemoryIndex = 0;
217 SetDSP3 = &DSP3_DumpDataROM;
218 DSP3_DumpDataROM();
219}
220
221static void DSP3_OP06 (void)
222{
223 DSP3.WinLo = (uint8) (DSP3.DR);
224 DSP3.WinHi = (uint8) (DSP3.DR >> 8);
225 DSP3_Reset();
226}
227
228static void DSP3_OP03 (void)
229{
230 int16 Lo = (uint8) (DSP3.DR);
231 int16 Hi = (uint8) (DSP3.DR >> 8);
232 int16 Ofs = (DSP3.WinLo * Hi << 1) + (Lo << 1);
233
234 DSP3.DR = Ofs >> 1;
235 SetDSP3 = &DSP3_Reset;
236}
237
238static void DSP3_OP07_B (void)
239{
240 int16 Ofs = (DSP3.WinLo * DSP3.AddHi << 1) + (DSP3.AddLo << 1);
241
242 DSP3.DR = Ofs >> 1;
243 SetDSP3 = &DSP3_Reset;
244}
245
246static void DSP3_OP07_A (void)
247{
248 int16 Lo = (uint8) (DSP3.DR);
249 int16 Hi = (uint8) (DSP3.DR >> 8);
250
251 if (Lo & 1)
252 Hi += (DSP3.AddLo & 1);
253
254 DSP3.AddLo += Lo;
255 DSP3.AddHi += Hi;
256
257 if (DSP3.AddLo < 0)
258 DSP3.AddLo += DSP3.WinLo;
259 else
260 if (DSP3.AddLo >= DSP3.WinLo)
261 DSP3.AddLo -= DSP3.WinLo;
262
263 if (DSP3.AddHi < 0)
264 DSP3.AddHi += DSP3.WinHi;
265 else
266 if (DSP3.AddHi >= DSP3.WinHi)
267 DSP3.AddHi -= DSP3.WinHi;
268
269 DSP3.DR = DSP3.AddLo | (DSP3.AddHi << 8) | ((DSP3.AddHi >> 8) & 0xff);
270 SetDSP3 = &DSP3_OP07_B;
271}
272
273static void DSP3_OP07 (void)
274{
275 uint32 dataOfs = ((DSP3.DR << 1) + 0x03b2) & 0x03ff;
276
277 DSP3.AddHi = DSP3_DataROM[dataOfs];
278 DSP3.AddLo = DSP3_DataROM[dataOfs + 1];
279
280 SetDSP3 = &DSP3_OP07_A;
281 DSP3.SR = 0x0080;
282}
283
284static void DSP3_Coordinate (void)
285{
286 DSP3.Index++;
287
288 switch (DSP3.Index)
289 {
290 case 3:
291 if (DSP3.DR == 0xffff)
292 DSP3_Reset();
293 break;
294
295 case 4:
296 DSP3.X = DSP3.DR;
297 break;
298
299 case 5:
300 DSP3.Y = DSP3.DR;
301 DSP3.DR = 1;
302 break;
303
304 case 6:
305 DSP3.DR = DSP3.X;
306 break;
307
308 case 7:
309 DSP3.DR = DSP3.Y;
310 DSP3.Index = 0;
311 break;
312 }
313}
314
315static void DSP3_Convert_A (void)
316{
317 if (DSP3.BMIndex < 8)
318 {
319 DSP3.Bitmap[DSP3.BMIndex++] = (uint8) (DSP3.DR);
320 DSP3.Bitmap[DSP3.BMIndex++] = (uint8) (DSP3.DR >> 8);
321
322 if (DSP3.BMIndex == 8)
323 {
324 for (int i = 0; i < 8; i++)
325 {
326 for (int j = 0; j < 8; j++)
327 {
328 DSP3.Bitplane[j] <<= 1;
329 DSP3.Bitplane[j] |= (DSP3.Bitmap[i] >> j) & 1;
330 }
331 }
332
333 DSP3.BPIndex = 0;
334 DSP3.Count--;
335 }
336 }
337
338 if (DSP3.BMIndex == 8)
339 {
340 if (DSP3.BPIndex == 8)
341 {
342 if (!DSP3.Count)
343 DSP3_Reset();
344
345 DSP3.BMIndex = 0;
346 }
347 else
348 {
349 DSP3.DR = DSP3.Bitplane[DSP3.BPIndex++];
350 DSP3.DR |= DSP3.Bitplane[DSP3.BPIndex++] << 8;
351 }
352 }
353}
354
355static void DSP3_Convert (void)
356{
357 DSP3.Count = DSP3.DR;
358 DSP3.BMIndex = 0;
359 SetDSP3 = &DSP3_Convert_A;
360}
361
362static bool8 DSP3_GetBits (uint8 Count)
363{
364 if (!DSP3.BitsLeft)
365 {
366 DSP3.BitsLeft = Count;
367 DSP3.ReqBits = 0;
368 }
369
370 do
371 {
372 if (!DSP3.BitCount)
373 {
374 DSP3.SR = 0xC0;
375 return (FALSE);
376 }
377
378 DSP3.ReqBits <<= 1;
379 if (DSP3.ReqData & 0x8000)
380 DSP3.ReqBits++;
381 DSP3.ReqData <<= 1;
382
383 DSP3.BitCount--;
384 DSP3.BitsLeft--;
385
386 }
387 while (DSP3.BitsLeft);
388
389 return (TRUE);
390}
391
392static void DSP3_Decode_Data (void)
393{
394 if (!DSP3.BitCount)
395 {
396 if (DSP3.SR & 0x40)
397 {
398 DSP3.ReqData = DSP3.DR;
399 DSP3.BitCount += 16;
400 }
401 else
402 {
403 DSP3.SR = 0xC0;
404 return;
405 }
406 }
407
408 if (DSP3.LZCode == 1)
409 {
410 if (!DSP3_GetBits(1))
411 return;
412
413 if (DSP3.ReqBits)
414 DSP3.LZLength = 12;
415 else
416 DSP3.LZLength = 8;
417
418 DSP3.LZCode++;
419 }
420
421 if (DSP3.LZCode == 2)
422 {
423 if (!DSP3_GetBits(DSP3.LZLength))
424 return;
425
426 DSP3.LZCode = 0;
427 DSP3.Outwords--;
428 if (!DSP3.Outwords)
429 SetDSP3 = &DSP3_Reset;
430
431 DSP3.SR = 0x80;
432 DSP3.DR = DSP3.ReqBits;
433 return;
434 }
435
436 if (DSP3.BaseCode == 0xffff)
437 {
438 if (!DSP3_GetBits(DSP3.BaseLength))
439 return;
440
441 DSP3.BaseCode = DSP3.ReqBits;
442 }
443
444 if (!DSP3_GetBits(DSP3.CodeLengths[DSP3.BaseCode]))
445 return;
446
447 DSP3.Symbol = DSP3.Codes[DSP3.CodeOffsets[DSP3.BaseCode] + DSP3.ReqBits];
448 DSP3.BaseCode = 0xffff;
449
450 if (DSP3.Symbol & 0xff00)
451 {
452 DSP3.Symbol += 0x7f02;
453 DSP3.LZCode++;
454 }
455 else
456 {
457 DSP3.Outwords--;
458 if (!DSP3.Outwords)
459 SetDSP3 = &DSP3_Reset;
460 }
461
462 DSP3.SR = 0x80;
463 DSP3.DR = DSP3.Symbol;
464}
465
466static void DSP3_Decode_Tree (void)
467{
468 if (!DSP3.BitCount)
469 {
470 DSP3.ReqData = DSP3.DR;
471 DSP3.BitCount += 16;
472 }
473
474 if (!DSP3.BaseCodes)
475 {
476 DSP3_GetBits(1);
477
478 if (DSP3.ReqBits)
479 {
480 DSP3.BaseLength = 3;
481 DSP3.BaseCodes = 8;
482 }
483 else
484 {
485 DSP3.BaseLength = 2;
486 DSP3.BaseCodes = 4;
487 }
488 }
489
490 while (DSP3.BaseCodes)
491 {
492 if (!DSP3_GetBits(3))
493 return;
494
495 DSP3.ReqBits++;
496
497 DSP3.CodeLengths[DSP3.Index] = (uint8) DSP3.ReqBits;
498 DSP3.CodeOffsets[DSP3.Index] = DSP3.Symbol;
499 DSP3.Index++;
500
501 DSP3.Symbol += 1 << DSP3.ReqBits;
502 DSP3.BaseCodes--;
503 }
504
505 DSP3.BaseCode = 0xffff;
506 DSP3.LZCode = 0;
507
508 SetDSP3 = &DSP3_Decode_Data;
509 if (DSP3.BitCount)
510 DSP3_Decode_Data();
511}
512
513static void DSP3_Decode_Symbols (void)
514{
515 DSP3.ReqData = DSP3.DR;
516 DSP3.BitCount += 16;
517
518 do
519 {
520 if (DSP3.BitCommand == 0xffff)
521 {
522 if (!DSP3_GetBits(2))
523 return;
524
525 DSP3.BitCommand = DSP3.ReqBits;
526 }
527
528 switch (DSP3.BitCommand)
529 {
530 case 0:
531 if (!DSP3_GetBits(9))
532 return;
533 DSP3.Symbol = DSP3.ReqBits;
534 break;
535
536 case 1:
537 DSP3.Symbol++;
538 break;
539
540 case 2:
541 if (!DSP3_GetBits(1))
542 return;
543 DSP3.Symbol += 2 + DSP3.ReqBits;
544 break;
545
546 case 3:
547 if (!DSP3_GetBits(4))
548 return;
549 DSP3.Symbol += 4 + DSP3.ReqBits;
550 break;
551 }
552
553 DSP3.BitCommand = 0xffff;
554
555 DSP3.Codes[DSP3.Index++] = DSP3.Symbol;
556 DSP3.Codewords--;
557
558 }
559 while (DSP3.Codewords);
560
561 DSP3.Index = 0;
562 DSP3.Symbol = 0;
563 DSP3.BaseCodes = 0;
564
565 SetDSP3 = &DSP3_Decode_Tree;
566 if (DSP3.BitCount)
567 DSP3_Decode_Tree();
568}
569
570static void DSP3_Decode_A (void)
571{
572 DSP3.Outwords = DSP3.DR;
573 SetDSP3 = &DSP3_Decode_Symbols;
574 DSP3.BitCount = 0;
575 DSP3.BitsLeft = 0;
576 DSP3.Symbol = 0;
577 DSP3.Index = 0;
578 DSP3.BitCommand = 0xffff;
579 DSP3.SR = 0xC0;
580}
581
582static void DSP3_Decode (void)
583{
584 DSP3.Codewords = DSP3.DR;
585 SetDSP3 = &DSP3_Decode_A;
586}
587
588// Opcodes 1E/3E bit-perfect to 'dsp3-intro' log
589// src: adapted from SD Gundam X/G-Next
590
591static void DSP3_OP3E (void)
592{
593 DSP3. op3e_x = (uint8) (DSP3.DR & 0x00ff);
594 DSP3. op3e_y = (uint8) ((DSP3.DR & 0xff00) >> 8);
595
596 DSP3_OP03();
597
598 DSP3.op1e_terrain[DSP3.DR] = 0x00;
599 DSP3.op1e_cost[DSP3.DR] = 0xff;
600 DSP3.op1e_weight[DSP3.DR] = 0;
601
602 DSP3.op1e_max_search_radius = 0;
603 DSP3.op1e_max_path_radius = 0;
604}
605
606static void DSP3_OP1E (void)
607{
608 DSP3.op1e_min_radius = (uint8) (DSP3.DR & 0x00ff);
609 DSP3.op1e_max_radius = (uint8) ((DSP3.DR & 0xff00) >> 8);
610
611 if (DSP3.op1e_min_radius == 0)
612 DSP3.op1e_min_radius++;
613
614 if (DSP3.op1e_max_search_radius >= DSP3.op1e_min_radius)
615 DSP3.op1e_min_radius = DSP3.op1e_max_search_radius + 1;
616
617 if (DSP3.op1e_max_radius > DSP3.op1e_max_search_radius)
618 DSP3.op1e_max_search_radius = DSP3.op1e_max_radius;
619
620 DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
621 DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
622
623 DSP3.op1e_lcv_turns = 6;
624 DSP3.op1e_turn = 0;
625
626 DSP3.op1e_x = DSP3. op3e_x;
627 DSP3.op1e_y = DSP3. op3e_y;
628
629 for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
630 DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
631
632 DSP3_OP1E_A();
633}
634
635static void DSP3_OP1E_A (void)
636{
637 if (DSP3.op1e_lcv_steps == 0)
638 {
639 DSP3.op1e_lcv_radius++;
640
641 DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
642
643 DSP3.op1e_x = DSP3. op3e_x;
644 DSP3.op1e_y = DSP3. op3e_y;
645
646 for (int lcv = 0; lcv < DSP3.op1e_lcv_radius; lcv++)
647 DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
648 }
649
650 if (DSP3.op1e_lcv_radius > DSP3.op1e_max_radius)
651 {
652 DSP3.op1e_turn++;
653 DSP3.op1e_lcv_turns--;
654
655 DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
656 DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
657
658 DSP3.op1e_x = DSP3. op3e_x;
659 DSP3.op1e_y = DSP3. op3e_y;
660
661 for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
662 DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
663 }
664
665 if (DSP3.op1e_lcv_turns == 0)
666 {
667 DSP3.DR = 0xffff;
668 DSP3.SR = 0x0080;
669 SetDSP3 = &DSP3_OP1E_B;
670 return;
671 }
672
673 DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
674 DSP3_OP03();
675
676 DSP3.op1e_cell = DSP3.DR;
677
678 DSP3.SR = 0x0080;
679 SetDSP3 = &DSP3_OP1E_A1;
680}
681
682static void DSP3_OP1E_A1 (void)
683{
684 DSP3.SR = 0x0084;
685 SetDSP3 = &DSP3_OP1E_A2;
686}
687
688static void DSP3_OP1E_A2 (void)
689{
690 DSP3.op1e_terrain[DSP3.op1e_cell] = (uint8) (DSP3.DR & 0x00ff);
691
692 DSP3.SR = 0x0084;
693 SetDSP3 = &DSP3_OP1E_A3;
694}
695
696static void DSP3_OP1E_A3 (void)
697{
698 DSP3.op1e_cost[DSP3.op1e_cell] = (uint8) (DSP3.DR & 0x00ff);
699
700 if (DSP3.op1e_lcv_radius == 1)
701 {
702 if (DSP3.op1e_terrain[DSP3.op1e_cell] & 1)
703 DSP3.op1e_weight[DSP3.op1e_cell] = 0xff;
704 else
705 DSP3.op1e_weight[DSP3.op1e_cell] = DSP3.op1e_cost[DSP3.op1e_cell];
706 }
707 else
708 DSP3.op1e_weight[DSP3.op1e_cell] = 0xff;
709
710 DSP3_OP1E_D((int16) (DSP3.op1e_turn + 2), &DSP3.op1e_x, &DSP3.op1e_y);
711 DSP3.op1e_lcv_steps--;
712
713 DSP3.SR = 0x0080;
714 DSP3_OP1E_A();
715}
716
717static void DSP3_OP1E_B (void)
718{
719 DSP3.op1e_x = DSP3. op3e_x;
720 DSP3.op1e_y = DSP3. op3e_y;
721 DSP3.op1e_lcv_radius = 1;
722
723 DSP3.op1e_search = 0;
724
725 DSP3_OP1E_B1();
726
727 SetDSP3 = &DSP3_OP1E_C;
728}
729
730static void DSP3_OP1E_B1 (void)
731{
732 while (DSP3.op1e_lcv_radius < DSP3.op1e_max_radius)
733 {
734 DSP3.op1e_y--;
735
736 DSP3.op1e_lcv_turns = 6;
737 DSP3.op1e_turn = 5;
738
739 while (DSP3.op1e_lcv_turns)
740 {
741 DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
742
743 while (DSP3.op1e_lcv_steps)
744 {
745 DSP3_OP1E_D1(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
746
747 if (0 <= DSP3.op1e_y && DSP3.op1e_y < DSP3.WinHi && 0 <= DSP3.op1e_x && DSP3.op1e_x < DSP3.WinLo)
748 {
749 DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
750 DSP3_OP03();
751
752 DSP3.op1e_cell = DSP3.DR;
753 if (DSP3.op1e_cost[DSP3.op1e_cell] < 0x80 && DSP3.op1e_terrain[DSP3.op1e_cell] < 0x40)
754 DSP3_OP1E_B2(); // end cell perimeter
755 }
756
757 DSP3.op1e_lcv_steps--;
758 } // end search line
759
760 DSP3.op1e_turn--;
761 if (DSP3.op1e_turn == 0)
762 DSP3.op1e_turn = 6;
763
764 DSP3.op1e_lcv_turns--;
765 } // end circle search
766
767 DSP3.op1e_lcv_radius++;
768 } // end radius search
769}
770
771static void DSP3_OP1E_B2 (void)
772{
773 int16 cell;
774 int16 path;
775 int16 x, y;
776 int16 lcv_turns;
777
778 path = 0xff;
779 lcv_turns = 6;
780
781 while (lcv_turns)
782 {
783 x = DSP3.op1e_x;
784 y = DSP3.op1e_y;
785
786 DSP3_OP1E_D1(lcv_turns, &x, &y);
787
788 DSP3.DR = (uint8) (x) | ((uint8) (y) << 8);
789 DSP3_OP03();
790
791 cell = DSP3.DR;
792
793 if (0 <= y && y < DSP3.WinHi && 0 <= x && x < DSP3.WinLo)
794 {
795 if (DSP3.op1e_terrain[cell] < 0x80 || DSP3.op1e_weight[cell] == 0)
796 {
797 if (DSP3.op1e_weight[cell] < path)
798 path = DSP3.op1e_weight[cell];
799 }
800 } // end step travel
801
802 lcv_turns--;
803 } // end while turns
804
805 if (path != 0xff)
806 DSP3.op1e_weight[DSP3.op1e_cell] = path + DSP3.op1e_cost[DSP3.op1e_cell];
807}
808
809static void DSP3_OP1E_C (void)
810{
811 DSP3.op1e_min_radius = (uint8) (DSP3.DR & 0x00ff);
812 DSP3.op1e_max_radius = (uint8) ((DSP3.DR & 0xff00) >> 8);
813
814 if (DSP3.op1e_min_radius == 0)
815 DSP3.op1e_min_radius++;
816
817 if (DSP3.op1e_max_path_radius >= DSP3.op1e_min_radius)
818 DSP3.op1e_min_radius = DSP3.op1e_max_path_radius + 1;
819
820 if (DSP3.op1e_max_radius > DSP3.op1e_max_path_radius)
821 DSP3.op1e_max_path_radius = DSP3.op1e_max_radius;
822
823 DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
824 DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
825
826 DSP3.op1e_lcv_turns = 6;
827 DSP3.op1e_turn = 0;
828
829 DSP3.op1e_x = DSP3. op3e_x;
830 DSP3.op1e_y = DSP3. op3e_y;
831
832 for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
833 DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
834
835 DSP3_OP1E_C1();
836}
837
838static void DSP3_OP1E_C1 (void)
839{
840 if (DSP3.op1e_lcv_steps == 0)
841 {
842 DSP3.op1e_lcv_radius++;
843
844 DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
845
846 DSP3.op1e_x = DSP3. op3e_x;
847 DSP3.op1e_y = DSP3. op3e_y;
848
849 for (int lcv = 0; lcv < DSP3.op1e_lcv_radius; lcv++)
850 DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
851 }
852
853 if (DSP3.op1e_lcv_radius > DSP3.op1e_max_radius)
854 {
855 DSP3.op1e_turn++;
856 DSP3.op1e_lcv_turns--;
857
858 DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
859 DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
860
861 DSP3.op1e_x = DSP3. op3e_x;
862 DSP3.op1e_y = DSP3. op3e_y;
863
864 for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
865 DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
866 }
867
868 if (DSP3.op1e_lcv_turns == 0)
869 {
870 DSP3.DR = 0xffff;
871 DSP3.SR = 0x0080;
872 SetDSP3 = &DSP3_Reset;
873 return;
874 }
875
876 DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
877 DSP3_OP03();
878
879 DSP3.op1e_cell = DSP3.DR;
880
881 DSP3.SR = 0x0080;
882 SetDSP3 = &DSP3_OP1E_C2;
883}
884
885static void DSP3_OP1E_C2 (void)
886{
887 DSP3.DR = DSP3.op1e_weight[DSP3.op1e_cell];
888
889 DSP3_OP1E_D((int16) (DSP3.op1e_turn + 2), &DSP3.op1e_x, &DSP3.op1e_y);
890 DSP3.op1e_lcv_steps--;
891
892 DSP3.SR = 0x0084;
893 SetDSP3 = &DSP3_OP1E_C1;
894}
895
896static void DSP3_OP1E_D (int16 move, int16 *lo, int16 *hi)
897{
898 uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
899 int16 Lo;
900 int16 Hi;
901
902 DSP3.AddHi = DSP3_DataROM[dataOfs];
903 DSP3.AddLo = DSP3_DataROM[dataOfs + 1];
904
905 Lo = (uint8) (*lo);
906 Hi = (uint8) (*hi);
907
908 if (Lo & 1)
909 Hi += (DSP3.AddLo & 1);
910
911 DSP3.AddLo += Lo;
912 DSP3.AddHi += Hi;
913
914 if (DSP3.AddLo < 0)
915 DSP3.AddLo += DSP3.WinLo;
916 else
917 if (DSP3.AddLo >= DSP3.WinLo)
918 DSP3.AddLo -= DSP3.WinLo;
919
920 if (DSP3.AddHi < 0)
921 DSP3.AddHi += DSP3.WinHi;
922 else
923 if (DSP3.AddHi >= DSP3.WinHi)
924 DSP3.AddHi -= DSP3.WinHi;
925
926 *lo = DSP3.AddLo;
927 *hi = DSP3.AddHi;
928}
929
930static void DSP3_OP1E_D1 (int16 move, int16 *lo, int16 *hi)
931{
932 const uint16 HiAdd[] =
933 {
934 0x00, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00
935 };
936
937 const uint16 LoAdd[] =
938 {
939 0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00
940 };
941
942 int16 Lo;
943 int16 Hi;
944
945 if ((*lo) & 1)
946 DSP3.AddHi = HiAdd[move + 8];
947 else
948 DSP3.AddHi = HiAdd[move + 0];
949
950 DSP3.AddLo = LoAdd[move];
951
952 Lo = (uint8) (*lo);
953 Hi = (uint8) (*hi);
954
955 if (Lo & 1)
956 Hi += (DSP3.AddLo & 1);
957
958 DSP3.AddLo += Lo;
959 DSP3.AddHi += Hi;
960
961 *lo = DSP3.AddLo;
962 *hi = DSP3.AddHi;
963}
964
965static void DSP3_OP10 (void)
966{
967 if (DSP3.DR == 0xffff)
968 DSP3_Reset();
969 else
970 // absorb 2 bytes
971 DSP3.DR = DSP3.DR; // FIXME?
972}
973
974/*
975static void DSP3_OP0C_A (void)
976{
977 // absorb 2 bytes
978 DSP3.DR = 0;
979 SetDSP3 = &DSP3_Reset;
980}
981*/
982
983static void DSP3_OP0C (void)
984{
985 // absorb 2 bytes
986 DSP3.DR = 0;
987 //SetDSP3 = &DSP3_OP0C_A;
988 SetDSP3 = &DSP3_Reset;
989}
990
991static void DSP3_OP1C_C (void)
992{
993 // return 2 bytes
994 DSP3.DR = 0;
995 SetDSP3 = &DSP3_Reset;
996}
997
998static void DSP3_OP1C_B (void)
999{
1000 // return 2 bytes
1001 DSP3.DR = 0;
1002 SetDSP3 = &DSP3_OP1C_C;
1003}
1004
1005static void DSP3_OP1C_A (void)
1006{
1007 // absorb 2 bytes
1008 SetDSP3 = &DSP3_OP1C_B;
1009}
1010
1011static void DSP3_OP1C (void)
1012{
1013 // absorb 2 bytes
1014 SetDSP3 = &DSP3_OP1C_A;
1015}
1016
1017static void DSP3_Command (void)
1018{
1019 if (DSP3.DR < 0x40)
1020 {
1021 switch (DSP3.DR)
1022 {
1023 case 0x02: SetDSP3 = &DSP3_Coordinate; break;
1024 case 0x03: SetDSP3 = &DSP3_OP03; break;
1025 case 0x06: SetDSP3 = &DSP3_OP06; break;
1026 case 0x07: SetDSP3 = &DSP3_OP07; return;
1027 case 0x0c: SetDSP3 = &DSP3_OP0C; break;
1028 case 0x0f: SetDSP3 = &DSP3_TestMemory; break;
1029 case 0x10: SetDSP3 = &DSP3_OP10; break;
1030 case 0x18: SetDSP3 = &DSP3_Convert; break;
1031 case 0x1c: SetDSP3 = &DSP3_OP1C; break;
1032 case 0x1e: SetDSP3 = &DSP3_OP1E; break;
1033 case 0x1f: SetDSP3 = &DSP3_MemoryDump; break;
1034 case 0x38: SetDSP3 = &DSP3_Decode; break;
1035 case 0x3e: SetDSP3 = &DSP3_OP3E; break;
1036 default:
1037 return;
1038 }
1039
1040 DSP3.SR = 0x0080;
1041 DSP3.Index = 0;
1042 }
1043}
1044
1045void DSP3SetByte (uint8 byte, uint16 address)
1046{
1047 if (address < DSP0.boundary)
1048 {
1049 if (DSP3.SR & 0x04)
1050 {
1051 DSP3.DR = (DSP3.DR & 0xff00) + byte;
1052 (*SetDSP3)();
1053 }
1054 else
1055 {
1056 DSP3.SR ^= 0x10;
1057
1058 if (DSP3.SR & 0x10)
1059 DSP3.DR = (DSP3.DR & 0xff00) + byte;
1060 else
1061 {
1062 DSP3.DR = (DSP3.DR & 0x00ff) + (byte << 8);
1063 (*SetDSP3)();
1064 }
1065 }
1066 }
1067}
1068
1069uint8 DSP3GetByte (uint16 address)
1070{
1071 if (address < DSP0.boundary)
1072 {
1073 uint8 byte;
1074
1075 if (DSP3.SR & 0x04)
1076 {
1077 byte = (uint8) DSP3.DR;
1078 (*SetDSP3)();
1079 }
1080 else
1081 {
1082 DSP3.SR ^= 0x10;
1083
1084 if (DSP3.SR & 0x10)
1085 byte = (uint8) (DSP3.DR);
1086 else
1087 {
1088 byte = (uint8) (DSP3.DR >> 8);
1089 (*SetDSP3)();
1090 }
1091 }
1092
1093 return (byte);
1094 }
1095
1096 return (uint8) DSP3.SR;
1097}
1098