~ubuntu-branches/ubuntu/lucid/sdlmame/lucid

« back to all changes in this revision

Viewing changes to src/mame/machine/snesdsp3.c

  • Committer: Bazaar Package Importer
  • Author(s): Cesare Falco
  • Date: 2009-11-03 17:10:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091103171015-6hop4ory5lxnumpn
Tags: 0.135-0ubuntu1
* New upstream release - Closes (LP: #403212)
* debian/watch: unstable releases are no longer detected
* mame.ini: added the cheat subdirectories to cheatpath so zipped
  cheatfiles will be searched too
* renamed crsshair subdirectory to crosshair to reflect upstream change
* mame.ini: renamed references to crosshair subdirectory (see above)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************
 
2
 
 
3
    DSP-3 emulator code
 
4
 
 
5
    Copyright (c) 2003-2009 John Weidman, Kris Bleakley, Lancer, Nach,
 
6
    z80 gaiden, and Jonas Quinn
 
7
 
 
8
    This code is released by ZSNES Team under GNU General Public License
 
9
    version 2 as published by the Free Software Foundation.
 
10
    The implementation below is released under the MAME license for use
 
11
    in MAME, MESS and derivatives by permission of the authors.
 
12
 
 
13
************************************************************************/
 
14
 
 
15
static UINT16 DSP3_DataROM[1024];
 
16
 
 
17
static void(*SetDSP3)(void);
 
18
static void DSP3_Command(void);
 
19
 
 
20
static UINT16 DSP3_DR;
 
21
static UINT16 DSP3_SR;
 
22
static UINT16 DSP3_MemoryIndex;
 
23
 
 
24
static void DSP3_Reset(void)
 
25
{
 
26
        DSP3_DR = 0x0080;
 
27
        DSP3_SR = 0x0084;
 
28
        SetDSP3 = &DSP3_Command;
 
29
}
 
30
 
 
31
#ifdef UNUSED_FUNCTION
 
32
void DSP3_MemorySize(void)
 
33
{
 
34
        DSP3_DR = 0x0300;
 
35
        SetDSP3 = &DSP3_Reset;
 
36
}
 
37
#endif
 
38
 
 
39
static void DSP3_TestMemory(void)
 
40
{
 
41
        DSP3_DR = 0x0000;
 
42
        SetDSP3 = &DSP3_Reset;
 
43
}
 
44
 
 
45
static void DSP3_DumpDataROM(void)
 
46
{
 
47
        DSP3_DR = DSP3_DataROM[DSP3_MemoryIndex++];
 
48
        if (DSP3_MemoryIndex == 1024)
 
49
                SetDSP3 = &DSP3_Reset;
 
50
}
 
51
 
 
52
static void DSP3_MemoryDump(void)
 
53
{
 
54
        DSP3_MemoryIndex = 0;
 
55
        SetDSP3 = &DSP3_DumpDataROM;
 
56
        DSP3_DumpDataROM();
 
57
}
 
58
 
 
59
static INT16 DSP3_WinLo;
 
60
static INT16 DSP3_WinHi;
 
61
 
 
62
static void DSP3_OP06(void)
 
63
{
 
64
        DSP3_WinLo = (UINT8)(DSP3_DR);
 
65
        DSP3_WinHi = (UINT8)(DSP3_DR >> 8);
 
66
        DSP3_Reset();
 
67
}
 
68
 
 
69
static void DSP3_OP03(void)
 
70
{
 
71
        INT16 Lo = (UINT8)(DSP3_DR);
 
72
        INT16 Hi = (UINT8)(DSP3_DR >> 8);
 
73
        INT16 Ofs = (DSP3_WinLo * Hi << 1) + (Lo << 1);
 
74
        DSP3_DR = Ofs >> 1;
 
75
        SetDSP3 = &DSP3_Reset;
 
76
}
 
77
 
 
78
static INT16 DSP3_AddLo;
 
79
static INT16 DSP3_AddHi;
 
80
 
 
81
static void DSP3_OP07_B(void)
 
82
{
 
83
        INT16 Ofs = (DSP3_WinLo * DSP3_AddHi << 1) + (DSP3_AddLo << 1);
 
84
        DSP3_DR = Ofs >> 1;
 
85
        SetDSP3 = &DSP3_Reset;
 
86
}
 
87
 
 
88
static void DSP3_OP07_A(void)
 
89
{
 
90
        INT16 Lo = (UINT8)(DSP3_DR);
 
91
        INT16 Hi = (UINT8)(DSP3_DR >> 8);
 
92
 
 
93
        if (Lo & 1)     Hi += (DSP3_AddLo & 1);
 
94
 
 
95
        DSP3_AddLo += Lo;
 
96
        DSP3_AddHi += Hi;
 
97
 
 
98
        if (DSP3_AddLo < 0)
 
99
                DSP3_AddLo += DSP3_WinLo;
 
100
        else
 
101
                if (DSP3_AddLo >= DSP3_WinLo)
 
102
                        DSP3_AddLo -= DSP3_WinLo;
 
103
 
 
104
        if (DSP3_AddHi < 0)
 
105
                DSP3_AddHi += DSP3_WinHi;
 
106
        else
 
107
                if (DSP3_AddHi >= DSP3_WinHi)
 
108
                        DSP3_AddHi -= DSP3_WinHi;
 
109
 
 
110
        DSP3_DR = DSP3_AddLo | (DSP3_AddHi << 8) | ((DSP3_AddHi >> 8) & 0xff);
 
111
        SetDSP3 = &DSP3_OP07_B;
 
112
}
 
113
 
 
114
static void DSP3_OP07(void)
 
115
{
 
116
        UINT32 dataOfs = ((DSP3_DR << 1) + 0x03b2) & 0x03ff;
 
117
 
 
118
        DSP3_AddHi = DSP3_DataROM[dataOfs];
 
119
        DSP3_AddLo = DSP3_DataROM[dataOfs + 1];
 
120
 
 
121
        SetDSP3 = &DSP3_OP07_A;
 
122
        DSP3_SR = 0x0080;
 
123
}
 
124
 
 
125
static UINT16 DSP3_Codewords;
 
126
static UINT16 DSP3_Outwords;
 
127
static UINT16 DSP3_Symbol;
 
128
static UINT16 DSP3_BitCount;
 
129
static UINT16 DSP3_Index;
 
130
static UINT16 DSP3_Codes[512];
 
131
static UINT16 DSP3_BitsLeft;
 
132
static UINT16 DSP3_ReqBits;
 
133
static UINT16 DSP3_ReqData;
 
134
static UINT16 DSP3_BitCommand;
 
135
static UINT8  DSP3_BaseLength;
 
136
static UINT16 DSP3_BaseCodes;
 
137
static UINT16 DSP3_BaseCode;
 
138
static UINT8  DSP3_CodeLengths[8];
 
139
static UINT16 DSP3_CodeOffsets[8];
 
140
static UINT16 DSP3_LZCode;
 
141
static UINT8  DSP3_LZLength;
 
142
 
 
143
static UINT16 DSP3_X;
 
144
static UINT16 DSP3_Y;
 
145
 
 
146
static void DSP3_Coordinate(void)
 
147
{
 
148
        DSP3_Index++;
 
149
 
 
150
        switch (DSP3_Index)
 
151
        {
 
152
        case 3:
 
153
                {
 
154
                        if (DSP3_DR == 0xffff)
 
155
                                DSP3_Reset();
 
156
                        break;
 
157
                }
 
158
        case 4:
 
159
                {
 
160
                        DSP3_X = DSP3_DR;
 
161
                        break;
 
162
                }
 
163
        case 5:
 
164
                {
 
165
                        DSP3_Y = DSP3_DR;
 
166
                        DSP3_DR = 1;
 
167
                        break;
 
168
                }
 
169
        case 6:
 
170
                {
 
171
                        DSP3_DR = DSP3_X;
 
172
                        break;
 
173
                }
 
174
        case 7:
 
175
                {
 
176
                        DSP3_DR = DSP3_Y;
 
177
                        DSP3_Index = 0;
 
178
                        break;
 
179
                }
 
180
        }
 
181
}
 
182
 
 
183
static UINT8  DSP3_Bitmap[8];
 
184
static UINT8  DSP3_Bitplane[8];
 
185
static UINT16 DSP3_BMIndex;
 
186
static UINT16 DSP3_BPIndex;
 
187
static UINT16 DSP3_Count;
 
188
 
 
189
static void DSP3_Convert_A(void)
 
190
{
 
191
        if (DSP3_BMIndex < 8)
 
192
        {
 
193
                DSP3_Bitmap[DSP3_BMIndex++] = (UINT8) (DSP3_DR);
 
194
                DSP3_Bitmap[DSP3_BMIndex++] = (UINT8) (DSP3_DR >> 8);
 
195
 
 
196
                if (DSP3_BMIndex == 8)
 
197
                {
 
198
      short i, j;
 
199
                        for (i=0; i < 8; i++)
 
200
                                for (j=0; j < 8; j++)
 
201
                                {
 
202
                                        DSP3_Bitplane[j] <<= 1;
 
203
                                        DSP3_Bitplane[j] |= (DSP3_Bitmap[i] >> j) & 1;
 
204
                                }
 
205
 
 
206
                        DSP3_BPIndex = 0;
 
207
                        DSP3_Count--;
 
208
                }
 
209
        }
 
210
 
 
211
        if (DSP3_BMIndex == 8)
 
212
        {
 
213
                if (DSP3_BPIndex == 8)
 
214
                {
 
215
                        if (!DSP3_Count) DSP3_Reset();
 
216
                        DSP3_BMIndex = 0;
 
217
                }
 
218
                else
 
219
                {
 
220
                        DSP3_DR = DSP3_Bitplane[DSP3_BPIndex++];
 
221
                        DSP3_DR |= DSP3_Bitplane[DSP3_BPIndex++] << 8;
 
222
                }
 
223
        }
 
224
}
 
225
 
 
226
static void DSP3_Convert(void)
 
227
{
 
228
        DSP3_Count = DSP3_DR;
 
229
        DSP3_BMIndex = 0;
 
230
        SetDSP3 = &DSP3_Convert_A;
 
231
}
 
232
 
 
233
static UINT8 DSP3_GetBits(UINT8 Count)
 
234
{
 
235
        if (!DSP3_BitsLeft)
 
236
        {
 
237
                DSP3_BitsLeft = Count;
 
238
                DSP3_ReqBits = 0;
 
239
        }
 
240
 
 
241
        do {
 
242
                if (!DSP3_BitCount)
 
243
                {
 
244
                        DSP3_SR = 0xC0;
 
245
                        return 0;
 
246
                }
 
247
 
 
248
                DSP3_ReqBits <<= 1;
 
249
                if (DSP3_ReqData & 0x8000) DSP3_ReqBits++;
 
250
                DSP3_ReqData <<= 1;
 
251
 
 
252
                DSP3_BitCount--;
 
253
                DSP3_BitsLeft--;
 
254
 
 
255
        } while (DSP3_BitsLeft);
 
256
 
 
257
        return 1;
 
258
}
 
259
 
 
260
static void DSP3_Decode_Data(void)
 
261
{
 
262
        if (!DSP3_BitCount)
 
263
        {
 
264
                if (DSP3_SR & 0x40)
 
265
                {
 
266
                        DSP3_ReqData = DSP3_DR;
 
267
                        DSP3_BitCount += 16;
 
268
                }
 
269
                else
 
270
                {
 
271
                        DSP3_SR = 0xC0;
 
272
                        return;
 
273
                }
 
274
        }
 
275
 
 
276
        if (DSP3_LZCode == 1)
 
277
        {
 
278
                if (!DSP3_GetBits(1))
 
279
                        return;
 
280
 
 
281
                if (DSP3_ReqBits)
 
282
                        DSP3_LZLength = 12;
 
283
                else
 
284
                        DSP3_LZLength = 8;
 
285
 
 
286
                DSP3_LZCode++;
 
287
        }
 
288
 
 
289
        if (DSP3_LZCode == 2)
 
290
        {
 
291
                if (!DSP3_GetBits(DSP3_LZLength))
 
292
                        return;
 
293
 
 
294
                DSP3_LZCode = 0;
 
295
                DSP3_Outwords--;
 
296
                if (!DSP3_Outwords) SetDSP3 = &DSP3_Reset;
 
297
 
 
298
                DSP3_SR = 0x80;
 
299
                DSP3_DR = DSP3_ReqBits;
 
300
                return;
 
301
        }
 
302
 
 
303
        if (DSP3_BaseCode == 0xffff)
 
304
        {
 
305
                if (!DSP3_GetBits(DSP3_BaseLength))
 
306
                        return;
 
307
 
 
308
                DSP3_BaseCode = DSP3_ReqBits;
 
309
        }
 
310
 
 
311
        if (!DSP3_GetBits(DSP3_CodeLengths[DSP3_BaseCode]))
 
312
                return;
 
313
 
 
314
        DSP3_Symbol = DSP3_Codes[DSP3_CodeOffsets[DSP3_BaseCode] + DSP3_ReqBits];
 
315
        DSP3_BaseCode = 0xffff;
 
316
 
 
317
        if (DSP3_Symbol & 0xff00)
 
318
        {
 
319
                DSP3_Symbol += 0x7f02;
 
320
                DSP3_LZCode++;
 
321
        }
 
322
        else
 
323
        {
 
324
                DSP3_Outwords--;
 
325
                if (!DSP3_Outwords)
 
326
                        SetDSP3 = &DSP3_Reset;
 
327
        }
 
328
 
 
329
        DSP3_SR = 0x80;
 
330
        DSP3_DR = DSP3_Symbol;
 
331
}
 
332
 
 
333
static void DSP3_Decode_Tree(void)
 
334
{
 
335
        if (!DSP3_BitCount)
 
336
        {
 
337
                DSP3_ReqData = DSP3_DR;
 
338
                DSP3_BitCount += 16;
 
339
        }
 
340
 
 
341
        if (!DSP3_BaseCodes)
 
342
        {
 
343
                DSP3_GetBits(1);
 
344
                if (DSP3_ReqBits)
 
345
                {
 
346
                        DSP3_BaseLength = 3;
 
347
                        DSP3_BaseCodes = 8;
 
348
                }
 
349
                else
 
350
                {
 
351
                        DSP3_BaseLength = 2;
 
352
                        DSP3_BaseCodes = 4;
 
353
                }
 
354
        }
 
355
 
 
356
        while (DSP3_BaseCodes)
 
357
        {
 
358
                if (!DSP3_GetBits(3))
 
359
                        return;
 
360
 
 
361
                DSP3_ReqBits++;
 
362
 
 
363
                DSP3_CodeLengths[DSP3_Index] = (UINT8) DSP3_ReqBits;
 
364
                DSP3_CodeOffsets[DSP3_Index] = DSP3_Symbol;
 
365
                DSP3_Index++;
 
366
 
 
367
                DSP3_Symbol += 1 << DSP3_ReqBits;
 
368
                DSP3_BaseCodes--;
 
369
        }
 
370
 
 
371
        DSP3_BaseCode = 0xffff;
 
372
        DSP3_LZCode = 0;
 
373
 
 
374
        SetDSP3 = &DSP3_Decode_Data;
 
375
        if (DSP3_BitCount) DSP3_Decode_Data();
 
376
}
 
377
 
 
378
static void DSP3_Decode_Symbols(void)
 
379
{
 
380
        DSP3_ReqData = DSP3_DR;
 
381
        DSP3_BitCount += 16;
 
382
 
 
383
        do {
 
384
 
 
385
                if (DSP3_BitCommand == 0xffff)
 
386
                {
 
387
                        if (!DSP3_GetBits(2)) return;
 
388
                        DSP3_BitCommand = DSP3_ReqBits;
 
389
                }
 
390
 
 
391
                switch (DSP3_BitCommand)
 
392
                {
 
393
                case 0:
 
394
                        {
 
395
                                if (!DSP3_GetBits(9)) return;
 
396
                                DSP3_Symbol = DSP3_ReqBits;
 
397
                                break;
 
398
                        }
 
399
                case 1:
 
400
                        {
 
401
                                DSP3_Symbol++;
 
402
                                break;
 
403
                        }
 
404
                case 2:
 
405
                        {
 
406
                                if (!DSP3_GetBits(1)) return;
 
407
                                DSP3_Symbol += 2 + DSP3_ReqBits;
 
408
                                break;
 
409
                        }
 
410
                case 3:
 
411
                        {
 
412
                                if (!DSP3_GetBits(4)) return;
 
413
                                DSP3_Symbol += 4 + DSP3_ReqBits;
 
414
                                break;
 
415
                        }
 
416
                }
 
417
 
 
418
                DSP3_BitCommand = 0xffff;
 
419
 
 
420
                DSP3_Codes[DSP3_Index++] = DSP3_Symbol;
 
421
                DSP3_Codewords--;
 
422
 
 
423
        } while (DSP3_Codewords);
 
424
 
 
425
        DSP3_Index = 0;
 
426
        DSP3_Symbol = 0;
 
427
        DSP3_BaseCodes = 0;
 
428
 
 
429
        SetDSP3 = &DSP3_Decode_Tree;
 
430
        if (DSP3_BitCount) DSP3_Decode_Tree();
 
431
}
 
432
 
 
433
static void DSP3_Decode_A(void)
 
434
{
 
435
        DSP3_Outwords = DSP3_DR;
 
436
        SetDSP3 = &DSP3_Decode_Symbols;
 
437
        DSP3_BitCount = 0;
 
438
        DSP3_BitsLeft = 0;
 
439
        DSP3_Symbol = 0;
 
440
        DSP3_Index = 0;
 
441
        DSP3_BitCommand = 0xffff;
 
442
        DSP3_SR = 0xC0;
 
443
}
 
444
 
 
445
static void DSP3_Decode(void)
 
446
{
 
447
        DSP3_Codewords = DSP3_DR;
 
448
        SetDSP3 = &DSP3_Decode_A;
 
449
}
 
450
 
 
451
 
 
452
// Opcodes 1E/3E bit-perfect to 'dsp3-intro' log
 
453
// src: adapted from SD Gundam X/G-Next
 
454
 
 
455
static INT16 op3e_x;
 
456
static INT16 op3e_y;
 
457
 
 
458
static INT16 op1e_terrain[0x2000];
 
459
static INT16 op1e_cost[0x2000];
 
460
static INT16 op1e_weight[0x2000];
 
461
 
 
462
static INT16 op1e_cell;
 
463
static INT16 op1e_turn;
 
464
static INT16 op1e_search;
 
465
 
 
466
static INT16 op1e_x;
 
467
static INT16 op1e_y;
 
468
 
 
469
static INT16 op1e_min_radius;
 
470
static INT16 op1e_max_radius;
 
471
 
 
472
static INT16 op1e_max_search_radius;
 
473
static INT16 op1e_max_path_radius;
 
474
 
 
475
static INT16 op1e_lcv_radius;
 
476
static INT16 op1e_lcv_steps;
 
477
static INT16 op1e_lcv_turns;
 
478
 
 
479
static void DSP3_OP3E(void)
 
480
{
 
481
        op3e_x = (UINT8)(DSP3_DR & 0x00ff);
 
482
        op3e_y = (UINT8)((DSP3_DR & 0xff00)>>8);
 
483
 
 
484
        DSP3_OP03();
 
485
 
 
486
        op1e_terrain[ DSP3_DR ] = 0x00;
 
487
        op1e_cost[ DSP3_DR ] = 0xff;
 
488
        op1e_weight[ DSP3_DR ] = 0;
 
489
 
 
490
        op1e_max_search_radius = 0;
 
491
        op1e_max_path_radius = 0;
 
492
}
 
493
 
 
494
static void DSP3_OP1E_A(void);
 
495
static void DSP3_OP1E_A1(void);
 
496
static void DSP3_OP1E_A2(void);
 
497
static void DSP3_OP1E_A3(void);
 
498
 
 
499
static void DSP3_OP1E_B(void);
 
500
static void DSP3_OP1E_B1(void);
 
501
static void DSP3_OP1E_B2(void);
 
502
 
 
503
static void DSP3_OP1E_C(void);
 
504
static void DSP3_OP1E_C1(void);
 
505
static void DSP3_OP1E_C2(void);
 
506
 
 
507
static void DSP3_OP1E_D( INT16, INT16 *, INT16 * );
 
508
static void DSP3_OP1E_D1( INT16 move, INT16 *lo, INT16 *hi );
 
509
 
 
510
static void DSP3_OP1E(void)
 
511
{
 
512
        int lcv;
 
513
 
 
514
        op1e_min_radius = (UINT8)(DSP3_DR & 0x00ff);
 
515
        op1e_max_radius = (UINT8)((DSP3_DR & 0xff00)>>8);
 
516
 
 
517
        if( op1e_min_radius == 0 )
 
518
                op1e_min_radius++;
 
519
 
 
520
        if( op1e_max_search_radius >= op1e_min_radius )
 
521
                op1e_min_radius = op1e_max_search_radius+1;
 
522
 
 
523
        if( op1e_max_radius > op1e_max_search_radius )
 
524
                op1e_max_search_radius = op1e_max_radius;
 
525
 
 
526
        op1e_lcv_radius = op1e_min_radius;
 
527
        op1e_lcv_steps = op1e_min_radius;
 
528
 
 
529
        op1e_lcv_turns = 6;
 
530
        op1e_turn = 0;
 
531
 
 
532
        op1e_x = op3e_x;
 
533
        op1e_y = op3e_y;
 
534
 
 
535
        for( lcv = 0; lcv < op1e_min_radius; lcv++ )
 
536
                DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
 
537
 
 
538
        DSP3_OP1E_A();
 
539
}
 
540
 
 
541
static void DSP3_OP1E_A(void)
 
542
{
 
543
        int lcv;
 
544
 
 
545
        if( op1e_lcv_steps == 0 ) {
 
546
                op1e_lcv_radius++;
 
547
 
 
548
                op1e_lcv_steps = op1e_lcv_radius;
 
549
 
 
550
                op1e_x = op3e_x;
 
551
                op1e_y = op3e_y;
 
552
 
 
553
                for( lcv = 0; lcv < op1e_lcv_radius; lcv++ )
 
554
                        DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
 
555
        }
 
556
 
 
557
        if( op1e_lcv_radius > op1e_max_radius ) {
 
558
                op1e_turn++;
 
559
                op1e_lcv_turns--;
 
560
 
 
561
                op1e_lcv_radius = op1e_min_radius;
 
562
                op1e_lcv_steps = op1e_min_radius;
 
563
 
 
564
                op1e_x = op3e_x;
 
565
                op1e_y = op3e_y;
 
566
 
 
567
                for( lcv = 0; lcv < op1e_min_radius; lcv++ )
 
568
                        DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
 
569
        }
 
570
 
 
571
        if( op1e_lcv_turns == 0 ) {
 
572
                DSP3_DR = 0xffff;
 
573
                DSP3_SR = 0x0080;
 
574
                SetDSP3 = &DSP3_OP1E_B;
 
575
                return;
 
576
        }
 
577
 
 
578
        DSP3_DR = (UINT8)(op1e_x) | ((UINT8)(op1e_y)<<8);
 
579
        DSP3_OP03();
 
580
 
 
581
        op1e_cell = DSP3_DR;
 
582
 
 
583
        DSP3_SR = 0x0080;
 
584
        SetDSP3 = &DSP3_OP1E_A1;
 
585
}
 
586
 
 
587
static void DSP3_OP1E_A1(void)
 
588
{
 
589
        DSP3_SR = 0x0084;
 
590
        SetDSP3 = &DSP3_OP1E_A2;
 
591
}
 
592
 
 
593
static void DSP3_OP1E_A2(void)
 
594
{
 
595
        op1e_terrain[ op1e_cell ] = (UINT8)(DSP3_DR & 0x00ff);
 
596
 
 
597
        DSP3_SR = 0x0084;
 
598
        SetDSP3 = &DSP3_OP1E_A3;
 
599
}
 
600
 
 
601
static void DSP3_OP1E_A3(void)
 
602
{
 
603
        op1e_cost[ op1e_cell ] = (UINT8)(DSP3_DR & 0x00ff);
 
604
 
 
605
        if( op1e_lcv_radius == 1 ) {
 
606
                if( op1e_terrain[ op1e_cell ] & 1 ) {
 
607
                        op1e_weight[ op1e_cell ] = 0xff;
 
608
                } else {
 
609
                        op1e_weight[ op1e_cell ] = op1e_cost[ op1e_cell ];
 
610
                }
 
611
        }
 
612
        else {
 
613
                op1e_weight[ op1e_cell ] = 0xff;
 
614
        }
 
615
 
 
616
        DSP3_OP1E_D( (INT16)(op1e_turn+2), &op1e_x, &op1e_y );
 
617
        op1e_lcv_steps--;
 
618
 
 
619
        DSP3_SR = 0x0080;
 
620
        DSP3_OP1E_A();
 
621
}
 
622
 
 
623
 
 
624
static void DSP3_OP1E_B(void)
 
625
{
 
626
        op1e_x = op3e_x;
 
627
        op1e_y = op3e_y;
 
628
        op1e_lcv_radius = 1;
 
629
 
 
630
        op1e_search = 0;
 
631
 
 
632
        DSP3_OP1E_B1();
 
633
 
 
634
        SetDSP3 = &DSP3_OP1E_C;
 
635
}
 
636
 
 
637
 
 
638
static void DSP3_OP1E_B1(void)
 
639
{
 
640
        while( op1e_lcv_radius < op1e_max_radius ) {
 
641
                op1e_y--;
 
642
 
 
643
                op1e_lcv_turns = 6;
 
644
                op1e_turn = 5;
 
645
 
 
646
                while( op1e_lcv_turns ) {
 
647
                        op1e_lcv_steps = op1e_lcv_radius;
 
648
 
 
649
                        while( op1e_lcv_steps ) {
 
650
                                DSP3_OP1E_D1( op1e_turn, &op1e_x, &op1e_y );
 
651
 
 
652
                                if( 0 <= op1e_y && op1e_y < DSP3_WinHi &&
 
653
                                                0 <= op1e_x && op1e_x < DSP3_WinLo ) {
 
654
                                        DSP3_DR = (UINT8)(op1e_x) | ((UINT8)(op1e_y)<<8);
 
655
                                        DSP3_OP03();
 
656
 
 
657
                                        op1e_cell = DSP3_DR;
 
658
                                        if( op1e_cost[ op1e_cell ] < 0x80 &&
 
659
                                                        op1e_terrain[ op1e_cell ] < 0x40 ) {
 
660
                                                DSP3_OP1E_B2();
 
661
                                        } // end cell perimeter
 
662
                                }
 
663
 
 
664
                                op1e_lcv_steps--;
 
665
                        } // end search line
 
666
 
 
667
                        op1e_turn--;
 
668
                        if( op1e_turn == 0 ) op1e_turn = 6;
 
669
 
 
670
                        op1e_lcv_turns--;
 
671
                } // end circle search
 
672
 
 
673
                op1e_lcv_radius++;
 
674
        } // end radius search
 
675
}
 
676
 
 
677
 
 
678
static void DSP3_OP1E_B2(void)
 
679
{
 
680
        INT16 cell;
 
681
        INT16 path;
 
682
        INT16 x,y;
 
683
        INT16 lcv_turns;
 
684
 
 
685
        path = 0xff;
 
686
        lcv_turns = 6;
 
687
 
 
688
        while( lcv_turns ) {
 
689
                x = op1e_x;
 
690
                y = op1e_y;
 
691
 
 
692
                DSP3_OP1E_D1( lcv_turns, &x, &y );
 
693
 
 
694
                DSP3_DR = (UINT8)(x) | ((UINT8)(y)<<8);
 
695
                DSP3_OP03();
 
696
 
 
697
                cell = DSP3_DR;
 
698
 
 
699
                if( 0 <= y && y < DSP3_WinHi &&
 
700
                                0 <= x && x < DSP3_WinLo  ) {
 
701
 
 
702
                        if( op1e_terrain[ cell ] < 0x80 || op1e_weight[ cell ] == 0 ) {
 
703
                                if( op1e_weight[ cell ] < path ) {
 
704
                                        path = op1e_weight[ cell ];
 
705
                                }
 
706
                        }
 
707
                } // end step travel
 
708
 
 
709
                lcv_turns--;
 
710
        } // end while turns
 
711
 
 
712
        if( path != 0xff ) {
 
713
                op1e_weight[ op1e_cell ] = path + op1e_cost[ op1e_cell ];
 
714
        }
 
715
}
 
716
 
 
717
 
 
718
static void DSP3_OP1E_C(void)
 
719
{
 
720
        int lcv;
 
721
 
 
722
        op1e_min_radius = (UINT8)(DSP3_DR & 0x00ff);
 
723
        op1e_max_radius = (UINT8)((DSP3_DR & 0xff00)>>8);
 
724
 
 
725
        if( op1e_min_radius == 0 )
 
726
                op1e_min_radius++;
 
727
 
 
728
        if( op1e_max_path_radius >= op1e_min_radius )
 
729
                op1e_min_radius = op1e_max_path_radius+1;
 
730
 
 
731
        if( op1e_max_radius > op1e_max_path_radius )
 
732
                op1e_max_path_radius = op1e_max_radius;
 
733
 
 
734
        op1e_lcv_radius = op1e_min_radius;
 
735
        op1e_lcv_steps = op1e_min_radius;
 
736
 
 
737
        op1e_lcv_turns = 6;
 
738
        op1e_turn = 0;
 
739
 
 
740
        op1e_x = op3e_x;
 
741
        op1e_y = op3e_y;
 
742
 
 
743
        for( lcv = 0; lcv < op1e_min_radius; lcv++ )
 
744
                DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
 
745
 
 
746
        DSP3_OP1E_C1();
 
747
}
 
748
 
 
749
 
 
750
static void DSP3_OP1E_C1(void)
 
751
{
 
752
        int lcv;
 
753
 
 
754
        if( op1e_lcv_steps == 0 ) {
 
755
                op1e_lcv_radius++;
 
756
 
 
757
                op1e_lcv_steps = op1e_lcv_radius;
 
758
 
 
759
                op1e_x = op3e_x;
 
760
                op1e_y = op3e_y;
 
761
 
 
762
                for( lcv = 0; lcv < op1e_lcv_radius; lcv++ )
 
763
                        DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
 
764
        }
 
765
 
 
766
        if( op1e_lcv_radius > op1e_max_radius ) {
 
767
                op1e_turn++;
 
768
                op1e_lcv_turns--;
 
769
 
 
770
                op1e_lcv_radius = op1e_min_radius;
 
771
                op1e_lcv_steps = op1e_min_radius;
 
772
 
 
773
                op1e_x = op3e_x;
 
774
                op1e_y = op3e_y;
 
775
 
 
776
                for( lcv = 0; lcv < op1e_min_radius; lcv++ )
 
777
                        DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
 
778
        }
 
779
 
 
780
        if( op1e_lcv_turns == 0 ) {
 
781
                DSP3_DR = 0xffff;
 
782
                DSP3_SR = 0x0080;
 
783
                SetDSP3 = &DSP3_Reset;
 
784
                return;
 
785
        }
 
786
 
 
787
        DSP3_DR = (UINT8)(op1e_x) | ((UINT8)(op1e_y)<<8);
 
788
        DSP3_OP03();
 
789
 
 
790
        op1e_cell = DSP3_DR;
 
791
 
 
792
        DSP3_SR = 0x0080;
 
793
        SetDSP3 = &DSP3_OP1E_C2;
 
794
}
 
795
 
 
796
 
 
797
static void DSP3_OP1E_C2(void)
 
798
{
 
799
        DSP3_DR = op1e_weight[ op1e_cell ];
 
800
 
 
801
        DSP3_OP1E_D( (INT16)(op1e_turn+2), &op1e_x, &op1e_y );
 
802
        op1e_lcv_steps--;
 
803
 
 
804
        DSP3_SR = 0x0084;
 
805
        SetDSP3 = &DSP3_OP1E_C1;
 
806
}
 
807
 
 
808
 
 
809
static void DSP3_OP1E_D( INT16 move, INT16 *lo, INT16 *hi )
 
810
{
 
811
        UINT32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
 
812
        INT16 Lo;
 
813
        INT16 Hi;
 
814
 
 
815
        DSP3_AddHi = DSP3_DataROM[dataOfs];
 
816
        DSP3_AddLo = DSP3_DataROM[dataOfs + 1];
 
817
 
 
818
        Lo = (UINT8)(*lo);
 
819
        Hi = (UINT8)(*hi);
 
820
 
 
821
        if (Lo & 1)     Hi += (DSP3_AddLo & 1);
 
822
 
 
823
        DSP3_AddLo += Lo;
 
824
        DSP3_AddHi += Hi;
 
825
 
 
826
        if (DSP3_AddLo < 0)
 
827
                DSP3_AddLo += DSP3_WinLo;
 
828
        else
 
829
                if (DSP3_AddLo >= DSP3_WinLo)
 
830
                        DSP3_AddLo -= DSP3_WinLo;
 
831
 
 
832
        if (DSP3_AddHi < 0)
 
833
                DSP3_AddHi += DSP3_WinHi;
 
834
        else
 
835
                if (DSP3_AddHi >= DSP3_WinHi)
 
836
                        DSP3_AddHi -= DSP3_WinHi;
 
837
 
 
838
        *lo = DSP3_AddLo;
 
839
        *hi = DSP3_AddHi;
 
840
}
 
841
 
 
842
 
 
843
static void DSP3_OP1E_D1( INT16 move, INT16 *lo, INT16 *hi )
 
844
{
 
845
        //UINT32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
 
846
        INT16 Lo;
 
847
        INT16 Hi;
 
848
 
 
849
        const unsigned short HiAdd[] = {
 
850
                0x00, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00,
 
851
                0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00
 
852
        };
 
853
        const unsigned short LoAdd[] = {
 
854
                0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00
 
855
        };
 
856
 
 
857
        if( (*lo) & 1 )
 
858
                DSP3_AddHi = HiAdd[ move + 8 ];
 
859
        else
 
860
                DSP3_AddHi = HiAdd[ move + 0 ];
 
861
        DSP3_AddLo = LoAdd[ move ];
 
862
 
 
863
        Lo = (UINT8)(*lo);
 
864
        Hi = (UINT8)(*hi);
 
865
 
 
866
        if (Lo & 1)     Hi += (DSP3_AddLo & 1);
 
867
 
 
868
        DSP3_AddLo += Lo;
 
869
        DSP3_AddHi += Hi;
 
870
 
 
871
        *lo = DSP3_AddLo;
 
872
        *hi = DSP3_AddHi;
 
873
}
 
874
 
 
875
 
 
876
static void DSP3_OP10(void)
 
877
{
 
878
        if( DSP3_DR == 0xffff ) {
 
879
                DSP3_Reset();
 
880
        } else {
 
881
                // absorb 2 bytes
 
882
                DSP3_DR = DSP3_DR;
 
883
        }
 
884
}
 
885
 
 
886
#ifdef UNUSED_FUNCTION
 
887
static void DSP3_OP0C_A(void)
 
888
{
 
889
        // absorb 2 bytes
 
890
 
 
891
        DSP3_DR = 0;
 
892
        SetDSP3 = &DSP3_Reset;
 
893
}
 
894
#endif
 
895
 
 
896
static void DSP3_OP0C(void)
 
897
{
 
898
        // absorb 2 bytes
 
899
 
 
900
        DSP3_DR = 0;
 
901
        //SetDSP3 = &DSP3_OP0C_A;
 
902
        SetDSP3 = &DSP3_Reset;
 
903
}
 
904
 
 
905
 
 
906
static void DSP3_OP1C_C(void)
 
907
{
 
908
        // return 2 bytes
 
909
        DSP3_DR = 0;
 
910
        SetDSP3 = &DSP3_Reset;
 
911
}
 
912
 
 
913
 
 
914
static void DSP3_OP1C_B(void)
 
915
{
 
916
        // absorb 2 bytes
 
917
 
 
918
        // return 2 bytes
 
919
        DSP3_DR = 0;
 
920
        SetDSP3 = &DSP3_OP1C_C;
 
921
}
 
922
 
 
923
 
 
924
static void DSP3_OP1C_A(void)
 
925
{
 
926
        // absorb 2 bytes
 
927
 
 
928
        SetDSP3 = &DSP3_OP1C_B;
 
929
}
 
930
 
 
931
 
 
932
static void DSP3_OP1C(void)
 
933
{
 
934
        // absorb 2 bytes
 
935
 
 
936
        SetDSP3 = &DSP3_OP1C_A;
 
937
}
 
938
 
 
939
 
 
940
static void DSP3_Command(void)
 
941
{
 
942
        if (DSP3_DR < 0x40)
 
943
        {
 
944
                switch (DSP3_DR)
 
945
                {
 
946
    case 0x02: SetDSP3 = &DSP3_Coordinate; break;
 
947
    case 0x03: SetDSP3 = &DSP3_OP03; break;
 
948
    case 0x06: SetDSP3 = &DSP3_OP06; break;
 
949
    case 0x07: SetDSP3 = &DSP3_OP07; return;
 
950
    case 0x0c: SetDSP3 = &DSP3_OP0C; break;
 
951
    case 0x0f: SetDSP3 = &DSP3_TestMemory; break;
 
952
    case 0x10: SetDSP3 = &DSP3_OP10; break;
 
953
    case 0x18: SetDSP3 = &DSP3_Convert; break;
 
954
    case 0x1c: SetDSP3 = &DSP3_OP1C; break;
 
955
    case 0x1e: SetDSP3 = &DSP3_OP1E; break;
 
956
    case 0x1f: SetDSP3 = &DSP3_MemoryDump; break;
 
957
    case 0x38: SetDSP3 = &DSP3_Decode; break;
 
958
    case 0x3e: SetDSP3 = &DSP3_OP3E; break;
 
959
    default:
 
960
     return;
 
961
                }
 
962
                DSP3_SR = 0x0080;
 
963
                DSP3_Index = 0;
 
964
        }
 
965
}
 
966
 
 
967
 
 
968
static void DSP3_write( UINT16 dsp3_address, UINT8 dsp3_byte )
 
969
{
 
970
  if (dsp3_address < 0xC000)
 
971
  {
 
972
                if (DSP3_SR & 0x04)
 
973
                {
 
974
                        DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte;
 
975
                        (*SetDSP3)();
 
976
                }
 
977
                else
 
978
                {
 
979
                        DSP3_SR ^= 0x10;
 
980
 
 
981
                        if (DSP3_SR & 0x10)
 
982
                                DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte;
 
983
                        else
 
984
                        {
 
985
                                DSP3_DR = (DSP3_DR & 0x00ff) + (dsp3_byte << 8);
 
986
                                (*SetDSP3)();
 
987
                        }
 
988
                }
 
989
  }
 
990
}
 
991
 
 
992
static UINT8 DSP3_read( UINT16 dsp3_address )
 
993
{
 
994
  UINT8 value;
 
995
  if (dsp3_address < 0xC000)
 
996
  {
 
997
                if (DSP3_SR & 0x04)
 
998
                {
 
999
                        value = (UINT8) DSP3_DR;
 
1000
                        (*SetDSP3)();
 
1001
                }
 
1002
                else
 
1003
                {
 
1004
                        DSP3_SR ^= 0x10;
 
1005
 
 
1006
                        if (DSP3_SR & 0x10)
 
1007
                                value = (UINT8) (DSP3_DR);
 
1008
                        else
 
1009
                        {
 
1010
                                value = (UINT8) (DSP3_DR >> 8);
 
1011
                                (*SetDSP3)();
 
1012
                        }
 
1013
                }
 
1014
 
 
1015
  }
 
1016
  else
 
1017
  {
 
1018
    value = (UINT8) DSP3_SR;
 
1019
  }
 
1020
 
 
1021
  return value;
 
1022
}
 
1023
 
 
1024
static void InitDSP3( running_machine *machine )
 
1025
{
 
1026
        UINT32 i;
 
1027
        UINT8 *dspin = memory_region(machine, "addons");
 
1028
 
 
1029
        DSP3_Reset();
 
1030
 
 
1031
        // expand the DSP-3 data ROM
 
1032
        for (i = 0; i < 2048; i+=2)
 
1033
        {
 
1034
                DSP3_DataROM[i/2] = dspin[0x800 + i] << 8 | dspin[0x800 + i + 1];
 
1035
        }
 
1036
}