mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-26 19:21:50 +01:00
1098 lines
26 KiB
C++
1098 lines
26 KiB
C++
/*****************************************************************************\
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
This file is licensed under the Snes9x License.
|
|
For further information, consult the LICENSE file in the root directory.
|
|
\*****************************************************************************/
|
|
|
|
#include "snes9x.h"
|
|
#include "memmap.h"
|
|
|
|
static void (*SetDSP3) (void);
|
|
|
|
static const uint16 DSP3_DataROM[1024] =
|
|
{
|
|
0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100,
|
|
0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001,
|
|
0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
|
|
0x0000, 0x000f, 0x0400, 0x0200, 0x0140, 0x0400, 0x0200, 0x0040,
|
|
0x007d, 0x007e, 0x007e, 0x007b, 0x007c, 0x007d, 0x007b, 0x007c,
|
|
0x0002, 0x0020, 0x0030, 0x0000, 0x000d, 0x0019, 0x0026, 0x0032,
|
|
0x003e, 0x004a, 0x0056, 0x0062, 0x006d, 0x0079, 0x0084, 0x008e,
|
|
0x0098, 0x00a2, 0x00ac, 0x00b5, 0x00be, 0x00c6, 0x00ce, 0x00d5,
|
|
0x00dc, 0x00e2, 0x00e7, 0x00ec, 0x00f1, 0x00f5, 0x00f8, 0x00fb,
|
|
0x00fd, 0x00ff, 0x0100, 0x0100, 0x0100, 0x00ff, 0x00fd, 0x00fb,
|
|
0x00f8, 0x00f5, 0x00f1, 0x00ed, 0x00e7, 0x00e2, 0x00dc, 0x00d5,
|
|
0x00ce, 0x00c6, 0x00be, 0x00b5, 0x00ac, 0x00a2, 0x0099, 0x008e,
|
|
0x0084, 0x0079, 0x006e, 0x0062, 0x0056, 0x004a, 0x003e, 0x0032,
|
|
0x0026, 0x0019, 0x000d, 0x0000, 0xfff3, 0xffe7, 0xffdb, 0xffce,
|
|
0xffc2, 0xffb6, 0xffaa, 0xff9e, 0xff93, 0xff87, 0xff7d, 0xff72,
|
|
0xff68, 0xff5e, 0xff54, 0xff4b, 0xff42, 0xff3a, 0xff32, 0xff2b,
|
|
0xff25, 0xff1e, 0xff19, 0xff14, 0xff0f, 0xff0b, 0xff08, 0xff05,
|
|
0xff03, 0xff01, 0xff00, 0xff00, 0xff00, 0xff01, 0xff03, 0xff05,
|
|
0xff08, 0xff0b, 0xff0f, 0xff13, 0xff18, 0xff1e, 0xff24, 0xff2b,
|
|
0xff32, 0xff3a, 0xff42, 0xff4b, 0xff54, 0xff5d, 0xff67, 0xff72,
|
|
0xff7c, 0xff87, 0xff92, 0xff9e, 0xffa9, 0xffb5, 0xffc2, 0xffce,
|
|
0xffda, 0xffe7, 0xfff3, 0x002b, 0x007f, 0x0020, 0x00ff, 0xff00,
|
|
0xffbe, 0x0000, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0x0045,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffc5, 0x0003, 0x0004, 0x0005, 0x0047, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
|
|
0x0009, 0x004a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x004e, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
|
|
0x0012, 0x0013, 0x0014, 0x0053, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
|
|
0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
|
|
0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0060, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
|
|
0x002b, 0x002c, 0x0068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
|
|
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0071,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
|
|
0x003e, 0x003f, 0x0040, 0x0041, 0x007b, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
|
|
0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
|
|
0x000b, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
|
|
0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0050, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
|
|
0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
|
|
0x0024, 0x0025, 0x0026, 0x005d, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
|
|
0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
|
|
0x006b, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
|
|
0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
|
|
0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0044, 0x0000, 0x0000,
|
|
0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
|
|
0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
|
|
0x001f, 0x0020, 0x0054, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
|
|
0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
|
|
0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0065,
|
|
0xffbe, 0x0000, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0xfead,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffc5, 0x0003, 0x0004, 0x0005, 0xfeaf, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008,
|
|
0x0009, 0xfeb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0xfeb6, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011,
|
|
0x0012, 0x0013, 0x0014, 0xfebb, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b,
|
|
0xfec1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e,
|
|
0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0xfec8, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a,
|
|
0x002b, 0x002c, 0xfed0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f,
|
|
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0xfed9,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d,
|
|
0x003e, 0x003f, 0x0040, 0x0041, 0xfee3, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002,
|
|
0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
|
|
0x000b, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012,
|
|
0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0xfeb8, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b,
|
|
0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
|
|
0x0024, 0x0025, 0x0026, 0xfec5, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
|
|
0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
|
|
0xfed3, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002,
|
|
0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
|
|
0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xfeac, 0x0000, 0x0000,
|
|
0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016,
|
|
0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e,
|
|
0x001f, 0x0020, 0xfebc, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023,
|
|
0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
|
|
0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0xfecd,
|
|
0x0154, 0x0218, 0x0110, 0x00b0, 0x00cc, 0x00b0, 0x0088, 0x00b0,
|
|
0x0044, 0x00b0, 0x0000, 0x00b0, 0x00fe, 0xff07, 0x0002, 0x00ff,
|
|
0x00f8, 0x0007, 0x00fe, 0x00ee, 0x07ff, 0x0200, 0x00ef, 0xf800,
|
|
0x0700, 0x00ee, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0001,
|
|
0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
|
|
0xffff, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000,
|
|
0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0x0001, 0x0000, 0x0001,
|
|
0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000,
|
|
0xffff, 0x0001, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff,
|
|
0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0044, 0x0088, 0x00cc,
|
|
0x0110, 0x0154, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
|
|
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
|
|
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
|
|
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
|
|
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
|
|
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
|
|
};
|
|
|
|
static bool8 DSP3_GetBits (uint8);
|
|
//static void DSP3_MemorySize (void);
|
|
static void DSP3_TestMemory (void);
|
|
static void DSP3_DumpDataROM (void);
|
|
static void DSP3_MemoryDump (void);
|
|
static void DSP3_Coordinate (void);
|
|
static void DSP3_Command (void);
|
|
static void DSP3_Decode_Data (void);
|
|
static void DSP3_Decode_Tree (void);
|
|
static void DSP3_Decode_Symbols (void);
|
|
static void DSP3_Decode (void);
|
|
static void DSP3_Decode_A (void);
|
|
static void DSP3_Convert (void);
|
|
static void DSP3_Convert_A (void);
|
|
static void DSP3_OP03 (void);
|
|
static void DSP3_OP06 (void);
|
|
static void DSP3_OP07 (void);
|
|
static void DSP3_OP07_A (void);
|
|
static void DSP3_OP07_B (void);
|
|
static void DSP3_OP0C (void);
|
|
//static void DSP3_OP0C_A (void);
|
|
static void DSP3_OP10 (void);
|
|
static void DSP3_OP1C (void);
|
|
static void DSP3_OP1C_A (void);
|
|
static void DSP3_OP1C_B (void);
|
|
static void DSP3_OP1C_C (void);
|
|
static void DSP3_OP1E (void);
|
|
static void DSP3_OP1E_A (void);
|
|
static void DSP3_OP1E_A1 (void);
|
|
static void DSP3_OP1E_A2 (void);
|
|
static void DSP3_OP1E_A3 (void);
|
|
static void DSP3_OP1E_B (void);
|
|
static void DSP3_OP1E_B1 (void);
|
|
static void DSP3_OP1E_B2 (void);
|
|
static void DSP3_OP1E_C (void);
|
|
static void DSP3_OP1E_C1 (void);
|
|
static void DSP3_OP1E_C2 (void);
|
|
static void DSP3_OP1E_D (int16, int16 *, int16 *);
|
|
static void DSP3_OP1E_D1 (int16, int16 *, int16 *);
|
|
static void DSP3_OP3E (void);
|
|
|
|
|
|
void DSP3_Reset (void)
|
|
{
|
|
DSP3.DR = 0x0080;
|
|
DSP3.SR = 0x0084;
|
|
SetDSP3 = &DSP3_Command;
|
|
}
|
|
|
|
/*
|
|
static void DSP3_MemorySize (void)
|
|
{
|
|
DSP3.DR = 0x0300;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
*/
|
|
|
|
static void DSP3_TestMemory (void)
|
|
{
|
|
DSP3.DR = 0x0000;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
static void DSP3_DumpDataROM (void)
|
|
{
|
|
DSP3.DR = DSP3_DataROM[DSP3.MemoryIndex++];
|
|
if (DSP3.MemoryIndex == 1024)
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
static void DSP3_MemoryDump (void)
|
|
{
|
|
DSP3.MemoryIndex = 0;
|
|
SetDSP3 = &DSP3_DumpDataROM;
|
|
DSP3_DumpDataROM();
|
|
}
|
|
|
|
static void DSP3_OP06 (void)
|
|
{
|
|
DSP3.WinLo = (uint8) (DSP3.DR);
|
|
DSP3.WinHi = (uint8) (DSP3.DR >> 8);
|
|
DSP3_Reset();
|
|
}
|
|
|
|
static void DSP3_OP03 (void)
|
|
{
|
|
int16 Lo = (uint8) (DSP3.DR);
|
|
int16 Hi = (uint8) (DSP3.DR >> 8);
|
|
int16 Ofs = (DSP3.WinLo * Hi << 1) + (Lo << 1);
|
|
|
|
DSP3.DR = Ofs >> 1;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
static void DSP3_OP07_B (void)
|
|
{
|
|
int16 Ofs = (DSP3.WinLo * DSP3.AddHi << 1) + (DSP3.AddLo << 1);
|
|
|
|
DSP3.DR = Ofs >> 1;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
static void DSP3_OP07_A (void)
|
|
{
|
|
int16 Lo = (uint8) (DSP3.DR);
|
|
int16 Hi = (uint8) (DSP3.DR >> 8);
|
|
|
|
if (Lo & 1)
|
|
Hi += (DSP3.AddLo & 1);
|
|
|
|
DSP3.AddLo += Lo;
|
|
DSP3.AddHi += Hi;
|
|
|
|
if (DSP3.AddLo < 0)
|
|
DSP3.AddLo += DSP3.WinLo;
|
|
else
|
|
if (DSP3.AddLo >= DSP3.WinLo)
|
|
DSP3.AddLo -= DSP3.WinLo;
|
|
|
|
if (DSP3.AddHi < 0)
|
|
DSP3.AddHi += DSP3.WinHi;
|
|
else
|
|
if (DSP3.AddHi >= DSP3.WinHi)
|
|
DSP3.AddHi -= DSP3.WinHi;
|
|
|
|
DSP3.DR = DSP3.AddLo | (DSP3.AddHi << 8) | ((DSP3.AddHi >> 8) & 0xff);
|
|
SetDSP3 = &DSP3_OP07_B;
|
|
}
|
|
|
|
static void DSP3_OP07 (void)
|
|
{
|
|
uint32 dataOfs = ((DSP3.DR << 1) + 0x03b2) & 0x03ff;
|
|
|
|
DSP3.AddHi = DSP3_DataROM[dataOfs];
|
|
DSP3.AddLo = DSP3_DataROM[dataOfs + 1];
|
|
|
|
SetDSP3 = &DSP3_OP07_A;
|
|
DSP3.SR = 0x0080;
|
|
}
|
|
|
|
static void DSP3_Coordinate (void)
|
|
{
|
|
DSP3.Index++;
|
|
|
|
switch (DSP3.Index)
|
|
{
|
|
case 3:
|
|
if (DSP3.DR == 0xffff)
|
|
DSP3_Reset();
|
|
break;
|
|
|
|
case 4:
|
|
DSP3.X = DSP3.DR;
|
|
break;
|
|
|
|
case 5:
|
|
DSP3.Y = DSP3.DR;
|
|
DSP3.DR = 1;
|
|
break;
|
|
|
|
case 6:
|
|
DSP3.DR = DSP3.X;
|
|
break;
|
|
|
|
case 7:
|
|
DSP3.DR = DSP3.Y;
|
|
DSP3.Index = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void DSP3_Convert_A (void)
|
|
{
|
|
if (DSP3.BMIndex < 8)
|
|
{
|
|
DSP3.Bitmap[DSP3.BMIndex++] = (uint8) (DSP3.DR);
|
|
DSP3.Bitmap[DSP3.BMIndex++] = (uint8) (DSP3.DR >> 8);
|
|
|
|
if (DSP3.BMIndex == 8)
|
|
{
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
for (int j = 0; j < 8; j++)
|
|
{
|
|
DSP3.Bitplane[j] <<= 1;
|
|
DSP3.Bitplane[j] |= (DSP3.Bitmap[i] >> j) & 1;
|
|
}
|
|
}
|
|
|
|
DSP3.BPIndex = 0;
|
|
DSP3.Count--;
|
|
}
|
|
}
|
|
|
|
if (DSP3.BMIndex == 8)
|
|
{
|
|
if (DSP3.BPIndex == 8)
|
|
{
|
|
if (!DSP3.Count)
|
|
DSP3_Reset();
|
|
|
|
DSP3.BMIndex = 0;
|
|
}
|
|
else
|
|
{
|
|
DSP3.DR = DSP3.Bitplane[DSP3.BPIndex++];
|
|
DSP3.DR |= DSP3.Bitplane[DSP3.BPIndex++] << 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DSP3_Convert (void)
|
|
{
|
|
DSP3.Count = DSP3.DR;
|
|
DSP3.BMIndex = 0;
|
|
SetDSP3 = &DSP3_Convert_A;
|
|
}
|
|
|
|
static bool8 DSP3_GetBits (uint8 Count)
|
|
{
|
|
if (!DSP3.BitsLeft)
|
|
{
|
|
DSP3.BitsLeft = Count;
|
|
DSP3.ReqBits = 0;
|
|
}
|
|
|
|
do
|
|
{
|
|
if (!DSP3.BitCount)
|
|
{
|
|
DSP3.SR = 0xC0;
|
|
return (FALSE);
|
|
}
|
|
|
|
DSP3.ReqBits <<= 1;
|
|
if (DSP3.ReqData & 0x8000)
|
|
DSP3.ReqBits++;
|
|
DSP3.ReqData <<= 1;
|
|
|
|
DSP3.BitCount--;
|
|
DSP3.BitsLeft--;
|
|
|
|
}
|
|
while (DSP3.BitsLeft);
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
static void DSP3_Decode_Data (void)
|
|
{
|
|
if (!DSP3.BitCount)
|
|
{
|
|
if (DSP3.SR & 0x40)
|
|
{
|
|
DSP3.ReqData = DSP3.DR;
|
|
DSP3.BitCount += 16;
|
|
}
|
|
else
|
|
{
|
|
DSP3.SR = 0xC0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (DSP3.LZCode == 1)
|
|
{
|
|
if (!DSP3_GetBits(1))
|
|
return;
|
|
|
|
if (DSP3.ReqBits)
|
|
DSP3.LZLength = 12;
|
|
else
|
|
DSP3.LZLength = 8;
|
|
|
|
DSP3.LZCode++;
|
|
}
|
|
|
|
if (DSP3.LZCode == 2)
|
|
{
|
|
if (!DSP3_GetBits(DSP3.LZLength))
|
|
return;
|
|
|
|
DSP3.LZCode = 0;
|
|
DSP3.Outwords--;
|
|
if (!DSP3.Outwords)
|
|
SetDSP3 = &DSP3_Reset;
|
|
|
|
DSP3.SR = 0x80;
|
|
DSP3.DR = DSP3.ReqBits;
|
|
return;
|
|
}
|
|
|
|
if (DSP3.BaseCode == 0xffff)
|
|
{
|
|
if (!DSP3_GetBits(DSP3.BaseLength))
|
|
return;
|
|
|
|
DSP3.BaseCode = DSP3.ReqBits;
|
|
}
|
|
|
|
if (!DSP3_GetBits(DSP3.CodeLengths[DSP3.BaseCode]))
|
|
return;
|
|
|
|
DSP3.Symbol = DSP3.Codes[DSP3.CodeOffsets[DSP3.BaseCode] + DSP3.ReqBits];
|
|
DSP3.BaseCode = 0xffff;
|
|
|
|
if (DSP3.Symbol & 0xff00)
|
|
{
|
|
DSP3.Symbol += 0x7f02;
|
|
DSP3.LZCode++;
|
|
}
|
|
else
|
|
{
|
|
DSP3.Outwords--;
|
|
if (!DSP3.Outwords)
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
DSP3.SR = 0x80;
|
|
DSP3.DR = DSP3.Symbol;
|
|
}
|
|
|
|
static void DSP3_Decode_Tree (void)
|
|
{
|
|
if (!DSP3.BitCount)
|
|
{
|
|
DSP3.ReqData = DSP3.DR;
|
|
DSP3.BitCount += 16;
|
|
}
|
|
|
|
if (!DSP3.BaseCodes)
|
|
{
|
|
DSP3_GetBits(1);
|
|
|
|
if (DSP3.ReqBits)
|
|
{
|
|
DSP3.BaseLength = 3;
|
|
DSP3.BaseCodes = 8;
|
|
}
|
|
else
|
|
{
|
|
DSP3.BaseLength = 2;
|
|
DSP3.BaseCodes = 4;
|
|
}
|
|
}
|
|
|
|
while (DSP3.BaseCodes)
|
|
{
|
|
if (!DSP3_GetBits(3))
|
|
return;
|
|
|
|
DSP3.ReqBits++;
|
|
|
|
DSP3.CodeLengths[DSP3.Index] = (uint8) DSP3.ReqBits;
|
|
DSP3.CodeOffsets[DSP3.Index] = DSP3.Symbol;
|
|
DSP3.Index++;
|
|
|
|
DSP3.Symbol += 1 << DSP3.ReqBits;
|
|
DSP3.BaseCodes--;
|
|
}
|
|
|
|
DSP3.BaseCode = 0xffff;
|
|
DSP3.LZCode = 0;
|
|
|
|
SetDSP3 = &DSP3_Decode_Data;
|
|
if (DSP3.BitCount)
|
|
DSP3_Decode_Data();
|
|
}
|
|
|
|
static void DSP3_Decode_Symbols (void)
|
|
{
|
|
DSP3.ReqData = DSP3.DR;
|
|
DSP3.BitCount += 16;
|
|
|
|
do
|
|
{
|
|
if (DSP3.BitCommand == 0xffff)
|
|
{
|
|
if (!DSP3_GetBits(2))
|
|
return;
|
|
|
|
DSP3.BitCommand = DSP3.ReqBits;
|
|
}
|
|
|
|
switch (DSP3.BitCommand)
|
|
{
|
|
case 0:
|
|
if (!DSP3_GetBits(9))
|
|
return;
|
|
DSP3.Symbol = DSP3.ReqBits;
|
|
break;
|
|
|
|
case 1:
|
|
DSP3.Symbol++;
|
|
break;
|
|
|
|
case 2:
|
|
if (!DSP3_GetBits(1))
|
|
return;
|
|
DSP3.Symbol += 2 + DSP3.ReqBits;
|
|
break;
|
|
|
|
case 3:
|
|
if (!DSP3_GetBits(4))
|
|
return;
|
|
DSP3.Symbol += 4 + DSP3.ReqBits;
|
|
break;
|
|
}
|
|
|
|
DSP3.BitCommand = 0xffff;
|
|
|
|
DSP3.Codes[DSP3.Index++] = DSP3.Symbol;
|
|
DSP3.Codewords--;
|
|
|
|
}
|
|
while (DSP3.Codewords);
|
|
|
|
DSP3.Index = 0;
|
|
DSP3.Symbol = 0;
|
|
DSP3.BaseCodes = 0;
|
|
|
|
SetDSP3 = &DSP3_Decode_Tree;
|
|
if (DSP3.BitCount)
|
|
DSP3_Decode_Tree();
|
|
}
|
|
|
|
static void DSP3_Decode_A (void)
|
|
{
|
|
DSP3.Outwords = DSP3.DR;
|
|
SetDSP3 = &DSP3_Decode_Symbols;
|
|
DSP3.BitCount = 0;
|
|
DSP3.BitsLeft = 0;
|
|
DSP3.Symbol = 0;
|
|
DSP3.Index = 0;
|
|
DSP3.BitCommand = 0xffff;
|
|
DSP3.SR = 0xC0;
|
|
}
|
|
|
|
static void DSP3_Decode (void)
|
|
{
|
|
DSP3.Codewords = DSP3.DR;
|
|
SetDSP3 = &DSP3_Decode_A;
|
|
}
|
|
|
|
// Opcodes 1E/3E bit-perfect to 'dsp3-intro' log
|
|
// src: adapted from SD Gundam X/G-Next
|
|
|
|
static void DSP3_OP3E (void)
|
|
{
|
|
DSP3. op3e_x = (uint8) (DSP3.DR & 0x00ff);
|
|
DSP3. op3e_y = (uint8) ((DSP3.DR & 0xff00) >> 8);
|
|
|
|
DSP3_OP03();
|
|
|
|
DSP3.op1e_terrain[DSP3.DR] = 0x00;
|
|
DSP3.op1e_cost[DSP3.DR] = 0xff;
|
|
DSP3.op1e_weight[DSP3.DR] = 0;
|
|
|
|
DSP3.op1e_max_search_radius = 0;
|
|
DSP3.op1e_max_path_radius = 0;
|
|
}
|
|
|
|
static void DSP3_OP1E (void)
|
|
{
|
|
DSP3.op1e_min_radius = (uint8) (DSP3.DR & 0x00ff);
|
|
DSP3.op1e_max_radius = (uint8) ((DSP3.DR & 0xff00) >> 8);
|
|
|
|
if (DSP3.op1e_min_radius == 0)
|
|
DSP3.op1e_min_radius++;
|
|
|
|
if (DSP3.op1e_max_search_radius >= DSP3.op1e_min_radius)
|
|
DSP3.op1e_min_radius = DSP3.op1e_max_search_radius + 1;
|
|
|
|
if (DSP3.op1e_max_radius > DSP3.op1e_max_search_radius)
|
|
DSP3.op1e_max_search_radius = DSP3.op1e_max_radius;
|
|
|
|
DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
|
|
|
|
DSP3.op1e_lcv_turns = 6;
|
|
DSP3.op1e_turn = 0;
|
|
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
|
|
for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
|
|
DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
|
|
DSP3_OP1E_A();
|
|
}
|
|
|
|
static void DSP3_OP1E_A (void)
|
|
{
|
|
if (DSP3.op1e_lcv_steps == 0)
|
|
{
|
|
DSP3.op1e_lcv_radius++;
|
|
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
|
|
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
|
|
for (int lcv = 0; lcv < DSP3.op1e_lcv_radius; lcv++)
|
|
DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
}
|
|
|
|
if (DSP3.op1e_lcv_radius > DSP3.op1e_max_radius)
|
|
{
|
|
DSP3.op1e_turn++;
|
|
DSP3.op1e_lcv_turns--;
|
|
|
|
DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
|
|
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
|
|
for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
|
|
DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
}
|
|
|
|
if (DSP3.op1e_lcv_turns == 0)
|
|
{
|
|
DSP3.DR = 0xffff;
|
|
DSP3.SR = 0x0080;
|
|
SetDSP3 = &DSP3_OP1E_B;
|
|
return;
|
|
}
|
|
|
|
DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
|
|
DSP3_OP03();
|
|
|
|
DSP3.op1e_cell = DSP3.DR;
|
|
|
|
DSP3.SR = 0x0080;
|
|
SetDSP3 = &DSP3_OP1E_A1;
|
|
}
|
|
|
|
static void DSP3_OP1E_A1 (void)
|
|
{
|
|
DSP3.SR = 0x0084;
|
|
SetDSP3 = &DSP3_OP1E_A2;
|
|
}
|
|
|
|
static void DSP3_OP1E_A2 (void)
|
|
{
|
|
DSP3.op1e_terrain[DSP3.op1e_cell] = (uint8) (DSP3.DR & 0x00ff);
|
|
|
|
DSP3.SR = 0x0084;
|
|
SetDSP3 = &DSP3_OP1E_A3;
|
|
}
|
|
|
|
static void DSP3_OP1E_A3 (void)
|
|
{
|
|
DSP3.op1e_cost[DSP3.op1e_cell] = (uint8) (DSP3.DR & 0x00ff);
|
|
|
|
if (DSP3.op1e_lcv_radius == 1)
|
|
{
|
|
if (DSP3.op1e_terrain[DSP3.op1e_cell] & 1)
|
|
DSP3.op1e_weight[DSP3.op1e_cell] = 0xff;
|
|
else
|
|
DSP3.op1e_weight[DSP3.op1e_cell] = DSP3.op1e_cost[DSP3.op1e_cell];
|
|
}
|
|
else
|
|
DSP3.op1e_weight[DSP3.op1e_cell] = 0xff;
|
|
|
|
DSP3_OP1E_D((int16) (DSP3.op1e_turn + 2), &DSP3.op1e_x, &DSP3.op1e_y);
|
|
DSP3.op1e_lcv_steps--;
|
|
|
|
DSP3.SR = 0x0080;
|
|
DSP3_OP1E_A();
|
|
}
|
|
|
|
static void DSP3_OP1E_B (void)
|
|
{
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
DSP3.op1e_lcv_radius = 1;
|
|
|
|
DSP3.op1e_search = 0;
|
|
|
|
DSP3_OP1E_B1();
|
|
|
|
SetDSP3 = &DSP3_OP1E_C;
|
|
}
|
|
|
|
static void DSP3_OP1E_B1 (void)
|
|
{
|
|
while (DSP3.op1e_lcv_radius < DSP3.op1e_max_radius)
|
|
{
|
|
DSP3.op1e_y--;
|
|
|
|
DSP3.op1e_lcv_turns = 6;
|
|
DSP3.op1e_turn = 5;
|
|
|
|
while (DSP3.op1e_lcv_turns)
|
|
{
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
|
|
|
|
while (DSP3.op1e_lcv_steps)
|
|
{
|
|
DSP3_OP1E_D1(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
|
|
if (0 <= DSP3.op1e_y && DSP3.op1e_y < DSP3.WinHi && 0 <= DSP3.op1e_x && DSP3.op1e_x < DSP3.WinLo)
|
|
{
|
|
DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
|
|
DSP3_OP03();
|
|
|
|
DSP3.op1e_cell = DSP3.DR;
|
|
if (DSP3.op1e_cost[DSP3.op1e_cell] < 0x80 && DSP3.op1e_terrain[DSP3.op1e_cell] < 0x40)
|
|
DSP3_OP1E_B2(); // end cell perimeter
|
|
}
|
|
|
|
DSP3.op1e_lcv_steps--;
|
|
} // end search line
|
|
|
|
DSP3.op1e_turn--;
|
|
if (DSP3.op1e_turn == 0)
|
|
DSP3.op1e_turn = 6;
|
|
|
|
DSP3.op1e_lcv_turns--;
|
|
} // end circle search
|
|
|
|
DSP3.op1e_lcv_radius++;
|
|
} // end radius search
|
|
}
|
|
|
|
static void DSP3_OP1E_B2 (void)
|
|
{
|
|
int16 cell;
|
|
int16 path;
|
|
int16 x, y;
|
|
int16 lcv_turns;
|
|
|
|
path = 0xff;
|
|
lcv_turns = 6;
|
|
|
|
while (lcv_turns)
|
|
{
|
|
x = DSP3.op1e_x;
|
|
y = DSP3.op1e_y;
|
|
|
|
DSP3_OP1E_D1(lcv_turns, &x, &y);
|
|
|
|
DSP3.DR = (uint8) (x) | ((uint8) (y) << 8);
|
|
DSP3_OP03();
|
|
|
|
cell = DSP3.DR;
|
|
|
|
if (0 <= y && y < DSP3.WinHi && 0 <= x && x < DSP3.WinLo)
|
|
{
|
|
if (DSP3.op1e_terrain[cell] < 0x80 || DSP3.op1e_weight[cell] == 0)
|
|
{
|
|
if (DSP3.op1e_weight[cell] < path)
|
|
path = DSP3.op1e_weight[cell];
|
|
}
|
|
} // end step travel
|
|
|
|
lcv_turns--;
|
|
} // end while turns
|
|
|
|
if (path != 0xff)
|
|
DSP3.op1e_weight[DSP3.op1e_cell] = path + DSP3.op1e_cost[DSP3.op1e_cell];
|
|
}
|
|
|
|
static void DSP3_OP1E_C (void)
|
|
{
|
|
DSP3.op1e_min_radius = (uint8) (DSP3.DR & 0x00ff);
|
|
DSP3.op1e_max_radius = (uint8) ((DSP3.DR & 0xff00) >> 8);
|
|
|
|
if (DSP3.op1e_min_radius == 0)
|
|
DSP3.op1e_min_radius++;
|
|
|
|
if (DSP3.op1e_max_path_radius >= DSP3.op1e_min_radius)
|
|
DSP3.op1e_min_radius = DSP3.op1e_max_path_radius + 1;
|
|
|
|
if (DSP3.op1e_max_radius > DSP3.op1e_max_path_radius)
|
|
DSP3.op1e_max_path_radius = DSP3.op1e_max_radius;
|
|
|
|
DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
|
|
|
|
DSP3.op1e_lcv_turns = 6;
|
|
DSP3.op1e_turn = 0;
|
|
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
|
|
for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
|
|
DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
|
|
DSP3_OP1E_C1();
|
|
}
|
|
|
|
static void DSP3_OP1E_C1 (void)
|
|
{
|
|
if (DSP3.op1e_lcv_steps == 0)
|
|
{
|
|
DSP3.op1e_lcv_radius++;
|
|
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_lcv_radius;
|
|
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
|
|
for (int lcv = 0; lcv < DSP3.op1e_lcv_radius; lcv++)
|
|
DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
}
|
|
|
|
if (DSP3.op1e_lcv_radius > DSP3.op1e_max_radius)
|
|
{
|
|
DSP3.op1e_turn++;
|
|
DSP3.op1e_lcv_turns--;
|
|
|
|
DSP3.op1e_lcv_radius = DSP3.op1e_min_radius;
|
|
DSP3.op1e_lcv_steps = DSP3.op1e_min_radius;
|
|
|
|
DSP3.op1e_x = DSP3. op3e_x;
|
|
DSP3.op1e_y = DSP3. op3e_y;
|
|
|
|
for (int lcv = 0; lcv < DSP3.op1e_min_radius; lcv++)
|
|
DSP3_OP1E_D(DSP3.op1e_turn, &DSP3.op1e_x, &DSP3.op1e_y);
|
|
}
|
|
|
|
if (DSP3.op1e_lcv_turns == 0)
|
|
{
|
|
DSP3.DR = 0xffff;
|
|
DSP3.SR = 0x0080;
|
|
SetDSP3 = &DSP3_Reset;
|
|
return;
|
|
}
|
|
|
|
DSP3.DR = (uint8) (DSP3.op1e_x) | ((uint8) (DSP3.op1e_y) << 8);
|
|
DSP3_OP03();
|
|
|
|
DSP3.op1e_cell = DSP3.DR;
|
|
|
|
DSP3.SR = 0x0080;
|
|
SetDSP3 = &DSP3_OP1E_C2;
|
|
}
|
|
|
|
static void DSP3_OP1E_C2 (void)
|
|
{
|
|
DSP3.DR = DSP3.op1e_weight[DSP3.op1e_cell];
|
|
|
|
DSP3_OP1E_D((int16) (DSP3.op1e_turn + 2), &DSP3.op1e_x, &DSP3.op1e_y);
|
|
DSP3.op1e_lcv_steps--;
|
|
|
|
DSP3.SR = 0x0084;
|
|
SetDSP3 = &DSP3_OP1E_C1;
|
|
}
|
|
|
|
static void DSP3_OP1E_D (int16 move, int16 *lo, int16 *hi)
|
|
{
|
|
uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
|
|
int16 Lo;
|
|
int16 Hi;
|
|
|
|
DSP3.AddHi = DSP3_DataROM[dataOfs];
|
|
DSP3.AddLo = DSP3_DataROM[dataOfs + 1];
|
|
|
|
Lo = (uint8) (*lo);
|
|
Hi = (uint8) (*hi);
|
|
|
|
if (Lo & 1)
|
|
Hi += (DSP3.AddLo & 1);
|
|
|
|
DSP3.AddLo += Lo;
|
|
DSP3.AddHi += Hi;
|
|
|
|
if (DSP3.AddLo < 0)
|
|
DSP3.AddLo += DSP3.WinLo;
|
|
else
|
|
if (DSP3.AddLo >= DSP3.WinLo)
|
|
DSP3.AddLo -= DSP3.WinLo;
|
|
|
|
if (DSP3.AddHi < 0)
|
|
DSP3.AddHi += DSP3.WinHi;
|
|
else
|
|
if (DSP3.AddHi >= DSP3.WinHi)
|
|
DSP3.AddHi -= DSP3.WinHi;
|
|
|
|
*lo = DSP3.AddLo;
|
|
*hi = DSP3.AddHi;
|
|
}
|
|
|
|
static void DSP3_OP1E_D1 (int16 move, int16 *lo, int16 *hi)
|
|
{
|
|
static const uint16 HiAdd[] =
|
|
{
|
|
0x00, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00
|
|
};
|
|
|
|
static const uint16 LoAdd[] =
|
|
{
|
|
0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00
|
|
};
|
|
|
|
int16 Lo;
|
|
int16 Hi;
|
|
|
|
if ((*lo) & 1)
|
|
DSP3.AddHi = HiAdd[move + 8];
|
|
else
|
|
DSP3.AddHi = HiAdd[move + 0];
|
|
|
|
DSP3.AddLo = LoAdd[move];
|
|
|
|
Lo = (uint8) (*lo);
|
|
Hi = (uint8) (*hi);
|
|
|
|
if (Lo & 1)
|
|
Hi += (DSP3.AddLo & 1);
|
|
|
|
DSP3.AddLo += Lo;
|
|
DSP3.AddHi += Hi;
|
|
|
|
*lo = DSP3.AddLo;
|
|
*hi = DSP3.AddHi;
|
|
}
|
|
|
|
static void DSP3_OP10 (void)
|
|
{
|
|
if (DSP3.DR == 0xffff)
|
|
DSP3_Reset();
|
|
else
|
|
// absorb 2 bytes
|
|
DSP3.DR = DSP3.DR; // FIXME?
|
|
}
|
|
|
|
/*
|
|
static void DSP3_OP0C_A (void)
|
|
{
|
|
// absorb 2 bytes
|
|
DSP3.DR = 0;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
*/
|
|
|
|
static void DSP3_OP0C (void)
|
|
{
|
|
// absorb 2 bytes
|
|
DSP3.DR = 0;
|
|
//SetDSP3 = &DSP3_OP0C_A;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
static void DSP3_OP1C_C (void)
|
|
{
|
|
// return 2 bytes
|
|
DSP3.DR = 0;
|
|
SetDSP3 = &DSP3_Reset;
|
|
}
|
|
|
|
static void DSP3_OP1C_B (void)
|
|
{
|
|
// return 2 bytes
|
|
DSP3.DR = 0;
|
|
SetDSP3 = &DSP3_OP1C_C;
|
|
}
|
|
|
|
static void DSP3_OP1C_A (void)
|
|
{
|
|
// absorb 2 bytes
|
|
SetDSP3 = &DSP3_OP1C_B;
|
|
}
|
|
|
|
static void DSP3_OP1C (void)
|
|
{
|
|
// absorb 2 bytes
|
|
SetDSP3 = &DSP3_OP1C_A;
|
|
}
|
|
|
|
static void DSP3_Command (void)
|
|
{
|
|
if (DSP3.DR < 0x40)
|
|
{
|
|
switch (DSP3.DR)
|
|
{
|
|
case 0x02: SetDSP3 = &DSP3_Coordinate; break;
|
|
case 0x03: SetDSP3 = &DSP3_OP03; break;
|
|
case 0x06: SetDSP3 = &DSP3_OP06; break;
|
|
case 0x07: SetDSP3 = &DSP3_OP07; return;
|
|
case 0x0c: SetDSP3 = &DSP3_OP0C; break;
|
|
case 0x0f: SetDSP3 = &DSP3_TestMemory; break;
|
|
case 0x10: SetDSP3 = &DSP3_OP10; break;
|
|
case 0x18: SetDSP3 = &DSP3_Convert; break;
|
|
case 0x1c: SetDSP3 = &DSP3_OP1C; break;
|
|
case 0x1e: SetDSP3 = &DSP3_OP1E; break;
|
|
case 0x1f: SetDSP3 = &DSP3_MemoryDump; break;
|
|
case 0x38: SetDSP3 = &DSP3_Decode; break;
|
|
case 0x3e: SetDSP3 = &DSP3_OP3E; break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
DSP3.SR = 0x0080;
|
|
DSP3.Index = 0;
|
|
}
|
|
}
|
|
|
|
void DSP3SetByte (uint8 byte, uint16 address)
|
|
{
|
|
if (address < DSP0.boundary)
|
|
{
|
|
if (DSP3.SR & 0x04)
|
|
{
|
|
DSP3.DR = (DSP3.DR & 0xff00) + byte;
|
|
(*SetDSP3)();
|
|
}
|
|
else
|
|
{
|
|
DSP3.SR ^= 0x10;
|
|
|
|
if (DSP3.SR & 0x10)
|
|
DSP3.DR = (DSP3.DR & 0xff00) + byte;
|
|
else
|
|
{
|
|
DSP3.DR = (DSP3.DR & 0x00ff) + (byte << 8);
|
|
(*SetDSP3)();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8 DSP3GetByte (uint16 address)
|
|
{
|
|
if (address < DSP0.boundary)
|
|
{
|
|
uint8 byte;
|
|
|
|
if (DSP3.SR & 0x04)
|
|
{
|
|
byte = (uint8) DSP3.DR;
|
|
(*SetDSP3)();
|
|
}
|
|
else
|
|
{
|
|
DSP3.SR ^= 0x10;
|
|
|
|
if (DSP3.SR & 0x10)
|
|
byte = (uint8) (DSP3.DR);
|
|
else
|
|
{
|
|
byte = (uint8) (DSP3.DR >> 8);
|
|
(*SetDSP3)();
|
|
}
|
|
}
|
|
|
|
return (byte);
|
|
}
|
|
|
|
return (uint8) DSP3.SR;
|
|
}
|