diff options
-rw-r--r-- | libretro.c | 16 | ||||
-rw-r--r-- | source/c4.c | 211 | ||||
-rw-r--r-- | source/c4.h | 6 | ||||
-rw-r--r-- | source/c4emu.c | 369 | ||||
-rw-r--r-- | source/dsp1.c | 4 | ||||
-rw-r--r-- | source/dsp1emu.c | 453 | ||||
-rw-r--r-- | source/globals.c | 61 | ||||
-rw-r--r-- | source/port.h | 33 | ||||
-rw-r--r-- | source/seta010.c | 84 |
9 files changed, 605 insertions, 632 deletions
@@ -43,8 +43,8 @@ char slash = '\\'; char slash = '/'; #endif -static float samples_per_frame = 0.0; -static float samplerate = (((SNES_CLOCK_SPEED * 6) / (32 * ONE_APU_CYCLE))); +static int32_t samples_per_frame = 0; +static int32_t samplerate = (((SNES_CLOCK_SPEED * 6) / (32 * ONE_APU_CYCLE))); #ifdef PERF_TEST #define RETRO_PERFORMANCE_INIT(name) \ @@ -400,7 +400,7 @@ static void check_variables(void) #define FRAMESKIP #endif -static float samples_to_play = 0.0; +static int32_t samples_to_play = 0; void retro_run(void) { bool updated = false; @@ -427,13 +427,13 @@ void retro_run(void) if (samples_to_play > 512) { - S9xMixSamples(audio_buf, ((int32_t)samples_to_play) * 2); - audio_batch_cb(audio_buf, (int32_t)samples_to_play); - samples_to_play -= (int32_t)samples_to_play; + S9xMixSamples(audio_buf, samples_to_play * 2); + audio_batch_cb(audio_buf, samples_to_play); + samples_to_play = 0; } #endif -#ifdef NO_VIDEO_OUTPUT +#ifdef NO_VIDEO_OUTPUT return; #endif @@ -767,7 +767,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char* code) Cheat.c[index].saved = false; // it'll be saved next time cheats run anyways - Settings.ApplyCheats=true; + Settings.ApplyCheats = true; S9xApplyCheats(); #endif } diff --git a/source/c4.c b/source/c4.c index 65d4c01..9519cc3 100644 --- a/source/c4.c +++ b/source/c4.c @@ -3,7 +3,7 @@ #include <math.h> #include <stdlib.h> #include "c4.h" -#include "memmap.h" +#include "port.h" int16_t C4WFXVal; int16_t C4WFYVal; @@ -13,70 +13,174 @@ int16_t C4WFY2Val; int16_t C4WFDist; int16_t C4WFScale; -static double tanval; -static double c4x, c4y, c4z; -static double c4x2, c4y2, c4z2; +int32_t tanval; +static int32_t c4x, c4y, c4z; +static int32_t c4x2, c4y2, c4z2; + +const int16_t C4MulTable[256] = +{ + 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, + 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f, + 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048, + 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061, + 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a, + 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, + 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac, + 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5, + 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df, + 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8, + 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111, + 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a, + 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143, + 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c, + 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175, + 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e, + 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8, + 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1, + 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da, + 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3, + 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c, + 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, + 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e, + 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258, + 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271, + 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a, + 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3, + 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc, + 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5, + 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee, + 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307, + 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321 +}; + +int16_t C4_Sin(int16_t Angle) +{ + if (Angle < 0) + { + if (Angle == -32768) + return 0; + return -C4_Sin(-Angle); + } + int16_t AngleS7 = Angle >> 7; + int32_t S = C4SinTable[AngleS7] + (C4MulTable[Angle & 0xff] * C4SinTable[0x80 + AngleS7] >> 15); + if (S > 32767) + S = 32767; + return (int16_t) S; +} + +int16_t C4_Cos(int16_t Angle) +{ + if (Angle < 0) + { + if (Angle == -32768) + return -32768; + Angle = -Angle; + } + int16_t AngleS7 = Angle >> 7; + int32_t S = C4SinTable[0x80 + AngleS7] - (C4MulTable[Angle & 0xff] * C4SinTable[AngleS7] >> 15); + if (S < -32768) + S = -32767; + return (int16_t) S; +} + +const int16_t atantbl[256] = { + 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, + 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 16, 17, 18, 18, 19, 20, + 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 29, + 30, 31, 31, 32, 33, 33, 34, 34, 35, 36, 36, 37, 37, 38, 39, 39, + 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 46, 46, 47, 47, 48, 49, + 49, 50, 50, 51, 51, 52, 53, 53, 54, 54, 55, 55, 56, 57, 57, 58, + 58, 59, 59, 60, 60, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, + 67, 67, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, + 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, + 83, 84, 84, 85, 85, 86, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, + 91, 91, 92, 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 96, 97, 97, + 98, 98, 99, 99, 99, 100, 100, 101, 101, 101, 102, 102, 103, 103, 104, 104, + 104, 105, 105, 106, 106, 106, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, + 111, 111, 111, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, + 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, + 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127 +}; + +int16_t _atan2(int16_t x, int16_t y) +{ + if (x == 0) + return 0; + + int32_t x1 = ABS(x), y1 = ABS(y); + int32_t absAtan; + + if (x1 > y1) + absAtan = atantbl[(unsigned char)((y1 << 8) / x1)]; + else + absAtan = atantbl[(unsigned char)((x1 << 8) / y1)]; + + if ((x >= 0) ^ (y >= 0)) + return -absAtan; + + return absAtan; +} void C4TransfWireFrame() { - c4x = (double) C4WFXVal; - c4y = (double) C4WFYVal; - c4z = (double) C4WFZVal - 0x95; + c4x = C4WFXVal; + c4y = C4WFYVal; + c4z = C4WFZVal - 0x95; // Rotate X - tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; - c4y2 = c4y * cos(tanval) - c4z * sin(tanval); - c4z2 = c4y * sin(tanval) + c4z * cos(tanval); + tanval = -C4WFX2Val << 9; + c4y2 = (c4y * C4_Cos(tanval) - c4z * C4_Sin(tanval)) >> 15; + c4z2 = (c4y * C4_Sin(tanval) + c4z * C4_Cos(tanval)) >> 15; // Rotate Y - tanval = -(double)C4WFY2Val * 3.14159265 * 2 / 128; - c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval); - c4z = c4x * - sin(tanval) + c4z2 * cos(tanval); + tanval = -C4WFY2Val << 9; + c4x2 = (c4x * C4_Cos(tanval) + c4z2 * C4_Sin(tanval)) >> 15; + c4z = (c4x * -C4_Sin(tanval) + c4z2 * C4_Cos(tanval)) >> 15; // Rotate Z - tanval = -(double) C4WFDist * 3.14159265 * 2 / 128; - c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval); - c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval); + tanval = -C4WFDist << 9; + c4x = (c4x2 * C4_Cos(tanval) - c4y2 * C4_Sin(tanval)) >> 15; + c4y = (c4x2 * C4_Sin(tanval) + c4y2 * C4_Cos(tanval)) >> 15; // Scale - C4WFXVal = (int16_t)(c4x * (double)C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); - C4WFYVal = (int16_t)(c4y * (double)C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); + C4WFXVal = (int16_t)(((int32_t)c4x * C4WFScale * 0x95) / (0x90 * (c4z + 0x95))); + C4WFYVal = (int16_t)(((int32_t)c4y * C4WFScale * 0x95) / (0x90 * (c4z + 0x95))); } void C4TransfWireFrame2() { - c4x = (double)C4WFXVal; - c4y = (double)C4WFYVal; - c4z = (double)C4WFZVal; + c4x = C4WFXVal; + c4y = C4WFYVal; + c4z = C4WFZVal; // Rotate X - tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; - c4y2 = c4y * cos(tanval) - c4z * sin(tanval); - c4z2 = c4y * sin(tanval) + c4z * cos(tanval); + tanval = -C4WFX2Val << 9; + c4y2 = (c4y * C4_Cos(tanval) - c4z * C4_Sin(tanval)) >> 15; + c4z2 = (c4y * C4_Sin(tanval) + c4z * C4_Cos(tanval)) >> 15; // Rotate Y - tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128; - c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval); - c4z = c4x * -sin(tanval) + c4z2 * cos(tanval); + tanval = -C4WFY2Val << 9; + c4x2 = (c4x * C4_Cos(tanval) + c4z2 * C4_Sin(tanval)) >> 15; + c4z = (c4x * -C4_Sin(tanval) + c4z2 * C4_Cos(tanval)) >> 15; // Rotate Z - tanval = -(double)C4WFDist * 3.14159265 * 2 / 128; - c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval); - c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval); + tanval = -C4WFDist << 9; + c4x = (c4x2 * C4_Cos(tanval) - c4y2 * C4_Sin(tanval)) >> 15; + c4y = (c4x2 * C4_Sin(tanval) + c4y2 * C4_Cos(tanval)) >> 15; // Scale - C4WFXVal = (int16_t)(c4x * (double)C4WFScale / 0x100); - C4WFYVal = (int16_t)(c4y * (double)C4WFScale / 0x100); + C4WFXVal = (int16_t)(((int32_t)c4x * C4WFScale) / 0x100); + C4WFYVal = (int16_t)(((int32_t)c4y * C4WFScale) / 0x100); } void C4CalcWireFrame() { C4WFXVal = C4WFX2Val - C4WFXVal; C4WFYVal = C4WFY2Val - C4WFYVal; - if (abs(C4WFXVal) > abs(C4WFYVal)) + if (ABS(C4WFXVal) > ABS(C4WFYVal)) { - C4WFDist = abs(C4WFXVal) + 1; - C4WFYVal = (int16_t)(256 * (double) C4WFYVal / abs(C4WFXVal)); + C4WFDist = ABS(C4WFXVal) + 1; + C4WFYVal = (int16_t)(((int32_t)C4WFYVal << 8) / ABS(C4WFXVal)); if (C4WFXVal < 0) C4WFXVal = -256; else @@ -86,8 +190,8 @@ void C4CalcWireFrame() { if (C4WFYVal != 0) { - C4WFDist = abs(C4WFYVal) + 1; - C4WFXVal = (int16_t)(256 * (double)C4WFXVal / abs(C4WFYVal)); + C4WFDist = ABS(C4WFYVal) + 1; + C4WFXVal = (int16_t)(((int32_t)C4WFXVal << 8) / ABS(C4WFYVal)); if (C4WFYVal < 0) C4WFYVal = -256; else @@ -103,36 +207,3 @@ int16_t C41FYVal; int16_t C41FAngleRes; int16_t C41FDist; int16_t C41FDistVal; - -void C4Op1F() -{ - if (C41FXVal == 0) - { - if (C41FYVal > 0) - C41FAngleRes = 0x80; - else - C41FAngleRes = 0x180; - } - else - { - tanval = (double) C41FYVal / C41FXVal; - C41FAngleRes = (int16_t)(atan(tanval) / (3.141592675 * 2) * 512); - if (C41FXVal < 0) - C41FAngleRes += 0x100; - C41FAngleRes &= 0x1FF; - } -} - -void C4Op15() -{ - tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); - C41FDist = (int16_t) tanval; -} - -void C4Op0D() -{ - tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); - tanval = C41FDistVal / tanval; - C41FYVal = (int16_t)(C41FYVal * tanval * 0.99); - C41FXVal = (int16_t)(C41FXVal * tanval * 0.98); -} diff --git a/source/c4.h b/source/c4.h index 590ead0..7ab3964 100644 --- a/source/c4.h +++ b/source/c4.h @@ -23,9 +23,9 @@ extern int16_t C41FAngleRes; extern int16_t C41FDist; extern int16_t C41FDistVal; -void C4Op1F(); -void C4Op15(); -void C4Op0D(); +extern int32_t tanval; + +int16_t _atan2(int16_t x, int16_t y); extern int16_t C4CosTable[]; extern int16_t C4SinTable[]; diff --git a/source/c4emu.c b/source/c4emu.c index a6baecf..0cfb3aa 100644 --- a/source/c4emu.c +++ b/source/c4emu.c @@ -12,11 +12,13 @@ void S9xInitC4() { - memset(Memory.C4RAM, 0, 0x2000); + Memory.C4RAM = &Memory.FillRAM [0x6000]; } uint8_t S9xGetC4(uint16_t Address) { + if (Address == 0x7f5e) + return 0; return (Memory.C4RAM [Address - 0x6000]); } @@ -37,15 +39,12 @@ static uint8_t C4TestPattern [12 * 4] = }; -static void C4ConvOAM(void) +static void C4ConvOAM() { uint8_t* i; uint8_t* OAMptr = Memory.C4RAM + (Memory.C4RAM[0x626] << 2); for (i = Memory.C4RAM + 0x1fd; i > OAMptr; i -= 4) - { - // Clear OAM-to-be - *i = 0xe0; - } + *i = 0xe0; // Clear OAM-to-be uint16_t globalX, globalY; uint8_t* OAMptr2; @@ -67,7 +66,8 @@ static void C4ConvOAM(void) uint8_t* srcptr = Memory.C4RAM + 0x220; for (i = Memory.C4RAM[0x0620]; i > 0 && SprCount > 0; i--, srcptr += 16) { - if ((srcptr[4] & 0x30) != prio) continue; + if ((srcptr[4] & 0x30) != prio) + continue; SprX = READ_WORD(srcptr) - globalX; SprY = READ_WORD(srcptr + 2) - globalY; SprName = srcptr[5]; @@ -97,12 +97,15 @@ static void C4ConvOAM(void) OAMptr[2] = SprName + sprptr[3]; OAMptr[3] = SprAttr ^ (sprptr[0] & 0xc0); // XXX: Carry from SprName addition? *OAMptr2 &= ~(3 << offset); - if (X & 0x100) *OAMptr2 |= 1 << offset; - if (sprptr[0] & 0x20) *OAMptr2 |= 2 << offset; + if (X & 0x100) + *OAMptr2 |= 1 << offset; + if (sprptr[0] & 0x20) + *OAMptr2 |= 2 << offset; OAMptr += 4; SprCount--; offset = (offset + 2) & 6; - if (offset == 0) OAMptr2++; + if (offset == 0) + OAMptr2++; } } } @@ -114,17 +117,19 @@ static void C4ConvOAM(void) OAMptr[2] = SprName; OAMptr[3] = SprAttr; *OAMptr2 &= ~(3 << offset); - if (SprX & 0x100) *OAMptr2 |= 3 << offset; - else *OAMptr2 |= 2 << offset; + if (SprX & 0x100) + *OAMptr2 |= 3 << offset; + else + *OAMptr2 |= 2 << offset; OAMptr += 4; SprCount--; offset = (offset + 2) & 6; - if (offset == 0) OAMptr2++; + if (offset == 0) + OAMptr2++; } } } } - // XXX: Copy to OAM? I doubt it. } static void C4DoScaleRotate(int32_t row_padding) @@ -133,9 +138,11 @@ static void C4DoScaleRotate(int32_t row_padding) // Calculate matrix int32_t XScale = READ_WORD(Memory.C4RAM + 0x1f8f); - if (XScale & 0x8000) XScale = 0x7fff; + if (XScale & 0x8000) + XScale = 0x7fff; int32_t YScale = READ_WORD(Memory.C4RAM + 0x1f92); - if (YScale & 0x8000) YScale = 0x7fff; + if (YScale & 0x8000) + YScale = 0x7fff; if (READ_WORD(Memory.C4RAM + 0x1f80) == 0) { @@ -173,14 +180,10 @@ static void C4DoScaleRotate(int32_t row_padding) } else { - A = (int16_t)SAR16(C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * XScale, - 15); - B = (int16_t)(-SAR16(C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * - YScale, 15)); - C = (int16_t)SAR16(C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * XScale, - 15); - D = (int16_t)SAR16(C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * YScale, - 15); + A = (int16_t) SAR16(C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * XScale, 15); + B = (int16_t)(-SAR16(C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * YScale, 15)); + C = (int16_t) SAR16(C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * XScale, 15); + D = (int16_t) SAR16(C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * YScale, 15); } // Calculate Pixel Resolution @@ -218,14 +221,19 @@ static void C4DoScaleRotate(int32_t row_padding) { uint32_t addr = (Y >> 12) * w + (X >> 12); byte = Memory.C4RAM[0x600 + (addr >> 1)]; - if (addr & 1) byte >>= 4; + if (addr & 1) + byte >>= 4; } // De-bitplanify - if (byte & 1) Memory.C4RAM[outidx] |= bit; - if (byte & 2) Memory.C4RAM[outidx + 1] |= bit; - if (byte & 4) Memory.C4RAM[outidx + 16] |= bit; - if (byte & 8) Memory.C4RAM[outidx + 17] |= bit; + if (byte & 1) + Memory.C4RAM[outidx] |= bit; + if (byte & 2) + Memory.C4RAM[outidx + 1] |= bit; + if (byte & 4) + Memory.C4RAM[outidx + 16] |= bit; + if (byte & 8) + Memory.C4RAM[outidx + 17] |= bit; bit >>= 1; if (bit == 0) @@ -247,8 +255,7 @@ static void C4DoScaleRotate(int32_t row_padding) } } -static void C4DrawLine(int32_t X1, int32_t Y1, int16_t Z1, - int32_t X2, int32_t Y2, int16_t Z2, uint8_t Color) +static void C4DrawLine(int32_t X1, int32_t Y1, int16_t Z1, int32_t X2, int32_t Y2, int16_t Z2, uint8_t Color) { // Transform coordinates C4WFXVal = (int16_t)X1; @@ -270,8 +277,8 @@ static void C4DrawLine(int32_t X1, int32_t Y1, int16_t Z1, Y2 = (C4WFYVal + 48) << 8; // get line info - C4WFXVal = (int16_t)(X1 >> 8); - C4WFYVal = (int16_t)(Y1 >> 8); + C4WFXVal = (int16_t)(X1 >> 8); + C4WFYVal = (int16_t)(Y1 >> 8); C4WFX2Val = (int16_t)(X2 >> 8); C4WFY2Val = (int16_t)(Y2 >> 8); C4CalcWireFrame(); @@ -285,20 +292,21 @@ static void C4DrawLine(int32_t X1, int32_t Y1, int16_t Z1, //.loop if (X1 > 0xff && Y1 > 0xff && X1 < 0x6000 && Y1 < 0x6000) { - uint16_t addr = (((Y1 >> 8) >> 3) << 8) - (((Y1 >> 8) >> 3) << 6) + ((( - X1 >> 8) >> 3) << 4) + ((Y1 >> 8) & 7) * 2; + uint16_t addr = (((Y1 >> 8) >> 3) << 8) - (((Y1 >> 8) >> 3) << 6) + (((X1 >> 8) >> 3) << 4) + ((Y1 >> 8) & 7) * 2; uint8_t bit = 0x80 >> ((X1 >> 8) & 7); Memory.C4RAM[addr + 0x300] &= ~bit; Memory.C4RAM[addr + 0x301] &= ~bit; - if (Color & 1) Memory.C4RAM[addr + 0x300] |= bit; - if (Color & 2) Memory.C4RAM[addr + 0x301] |= bit; + if (Color & 1) + Memory.C4RAM[addr + 0x300] |= bit; + if (Color & 2) + Memory.C4RAM[addr + 0x301] |= bit; } X1 += X2; Y1 += Y2; } } -static void C4DrawWireFrame(void) +static void C4DrawWireFrame() { uint8_t* line = S9xGetMemPointer(READ_3WORD(Memory.C4RAM + 0x1f80)); uint8_t* point1, *point2; @@ -312,15 +320,13 @@ static void C4DrawWireFrame(void) if (line[0] == 0xff && line[1] == 0xff) { uint8_t* tmp = line - 5; - while (line[2] == 0xff && line[3] == 0xff) tmp -= 5; - point1 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | - (tmp[2] << 8) | tmp[3]); + while (line[2] == 0xff && line[3] == 0xff) + tmp -= 5; + point1 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | (tmp[2] << 8) | tmp[3]); } else - point1 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | - (line[0] << 8) | line[1]); - point2 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | - (line[2] << 8) | line[3]); + point1 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | (line[0] << 8) | line[1]); + point2 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | (line[2] << 8) | line[3]); X1 = (point1[0] << 8) | point1[1]; Y1 = (point1[2] << 8) | point1[3]; @@ -333,7 +339,7 @@ static void C4DrawWireFrame(void) } } -static void C4TransformLines(void) +static void C4TransformLines() { C4WFX2Val = Memory.C4RAM[0x1f83]; C4WFY2Val = Memory.C4RAM[0x1f86]; @@ -366,19 +372,17 @@ static void C4TransformLines(void) ptr = Memory.C4RAM + 0xb02; uint8_t* ptr2 = Memory.C4RAM; + + for (i = READ_WORD(Memory.C4RAM + 0xb00); i > 0; i--, ptr += 2, ptr2 += 8) { - int32_t i; - for (i = READ_WORD(Memory.C4RAM + 0xb00); i > 0; i--, ptr += 2, ptr2 += 8) - { - C4WFXVal = READ_WORD(Memory.C4RAM + (ptr[0] << 4) + 1); - C4WFYVal = READ_WORD(Memory.C4RAM + (ptr[0] << 4) + 5); - C4WFX2Val = READ_WORD(Memory.C4RAM + (ptr[1] << 4) + 1); - C4WFY2Val = READ_WORD(Memory.C4RAM + (ptr[1] << 4) + 5); - C4CalcWireFrame(); - WRITE_WORD(ptr2 + 0x600, C4WFDist ? C4WFDist : 1); - WRITE_WORD(ptr2 + 0x602, C4WFXVal); - WRITE_WORD(ptr2 + 0x605, C4WFYVal); - } + C4WFXVal = READ_WORD(Memory.C4RAM + (ptr[0] << 4) + 1); + C4WFYVal = READ_WORD(Memory.C4RAM + (ptr[0] << 4) + 5); + C4WFX2Val = READ_WORD(Memory.C4RAM + (ptr[1] << 4) + 1); + C4WFY2Val = READ_WORD(Memory.C4RAM + (ptr[1] << 4) + 5); + C4CalcWireFrame(); + WRITE_WORD(ptr2 + 0x600, C4WFDist ? C4WFDist : 1); + WRITE_WORD(ptr2 + 0x602, C4WFXVal); + WRITE_WORD(ptr2 + 0x605, C4WFYVal); } } static void C4BitPlaneWave() @@ -479,12 +483,17 @@ static void C4SprDisintegrate() uint8_t pixel = (j & 1) ? (*src >> 4) : *src; int32_t idx = (y >> 11) * width * 4 + (x >> 11) * 32 + ((y >> 8) & 7) * 2; uint8_t mask = 0x80 >> ((x >> 8) & 7); - if (pixel & 1) Memory.C4RAM[idx] |= mask; - if (pixel & 2) Memory.C4RAM[idx + 1] |= mask; - if (pixel & 4) Memory.C4RAM[idx + 16] |= mask; - if (pixel & 8) Memory.C4RAM[idx + 17] |= mask; + if (pixel & 1) + Memory.C4RAM[idx] |= mask; + if (pixel & 2) + Memory.C4RAM[idx + 1] |= mask; + if (pixel & 4) + Memory.C4RAM[idx + 16] |= mask; + if (pixel & 8) + Memory.C4RAM[idx + 17] |= mask; } - if (j & 1) src++; + if (j & 1) + src++; } } } @@ -496,31 +505,24 @@ static void S9xC4ProcessSprites() case 0x00: // Build OAM C4ConvOAM(); break; - case 0x03: // Scale/Rotate C4DoScaleRotate(0); break; - case 0x05: // Transform Lines C4TransformLines(); break; - case 0x07: // Scale/Rotate C4DoScaleRotate(64); break; - case 0x08: // Draw wireframe C4DrawWireFrame(); break; - case 0x0b: // Disintegrate C4SprDisintegrate(); break; - case 0x0c: // Wave C4BitPlaneWave(); break; - default: break; } @@ -541,76 +543,75 @@ void S9xSetC4(uint8_t byte, uint16_t Address) case 0x00: // Sprite S9xC4ProcessSprites(); break; - case 0x01: // Draw wireframe memset(Memory.C4RAM + 0x300, 0, 16 * 12 * 3 * 4); C4DrawWireFrame(); break; - case 0x05: // Propulsion (?) { int32_t tmp = 0x10000; if (READ_WORD(Memory.C4RAM + 0x1f83)) - tmp = SAR32((tmp / READ_WORD(Memory.C4RAM + 0x1f83)) * READ_WORD( - Memory.C4RAM + 0x1f81), 8); + tmp = SAR32((tmp / READ_WORD(Memory.C4RAM + 0x1f83)) * READ_WORD(Memory.C4RAM + 0x1f81), 8); WRITE_WORD(Memory.C4RAM + 0x1f80, (uint16_t)tmp); + break; } - break; - case 0x0d: // Set vector length C41FXVal = READ_WORD(Memory.C4RAM + 0x1f80); C41FYVal = READ_WORD(Memory.C4RAM + 0x1f83); C41FDistVal = READ_WORD(Memory.C4RAM + 0x1f86); - C4Op0D(); + tanval = C41FDistVal / _isqrt((int32_t) C41FYVal * C41FYVal + (int32_t) C41FXVal * C41FXVal); + C41FYVal = (int16_t)(((int32_t)C41FYVal * tanval * 99) / 100); + C41FXVal = (int16_t)(((int32_t)C41FXVal * tanval * 98) / 100); WRITE_WORD(Memory.C4RAM + 0x1f89, C41FXVal); WRITE_WORD(Memory.C4RAM + 0x1f8c, C41FYVal); break; - case 0x10: // Polar to rectangluar { - int32_t tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * - C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 16); + int32_t tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 16); WRITE_3WORD(Memory.C4RAM + 0x1f86, tmp); - tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * C4SinTable[READ_WORD( - Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 16); + tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 16); WRITE_3WORD(Memory.C4RAM + 0x1f89, (tmp - SAR32(tmp, 6))); + break; } - break; - case 0x13: // Polar to rectangluar { - int32_t tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * - C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 8); + int32_t tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 8); WRITE_3WORD(Memory.C4RAM + 0x1f86, tmp); - tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * C4SinTable[READ_WORD( - Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 8); + tmp = SAR32((int32_t)READ_WORD(Memory.C4RAM + 0x1f83) * C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 8); WRITE_3WORD(Memory.C4RAM + 0x1f89, tmp); + break; } - break; - case 0x15: // Pythagorean C41FXVal = READ_WORD(Memory.C4RAM + 0x1f80); C41FYVal = READ_WORD(Memory.C4RAM + 0x1f83); - C41FDist = (int16_t)sqrt((double)C41FXVal * C41FXVal + (double)C41FYVal * - C41FYVal); + C41FDist = (int16_t)_isqrt((int32_t) C41FXVal * C41FXVal + (int32_t) C41FYVal * C41FYVal); WRITE_WORD(Memory.C4RAM + 0x1f80, C41FDist); break; - case 0x1f: // atan C41FXVal = READ_WORD(Memory.C4RAM + 0x1f80); C41FYVal = READ_WORD(Memory.C4RAM + 0x1f83); - C4Op1F(); + if (C41FXVal == 0) + { + if (C41FYVal > 0) + C41FAngleRes = 0x80; + else + C41FAngleRes = 0x180; + } + else + { + C41FAngleRes = (int16_t)(_atan2(C41FYVal, C41FXVal) / 2); + if (C41FXVal < 0) + C41FAngleRes += 0x100; + C41FAngleRes &= 0x1FF; + } WRITE_WORD(Memory.C4RAM + 0x1f86, C41FAngleRes); break; - case 0x22: // Trapezoid { int16_t angle1 = READ_WORD(Memory.C4RAM + 0x1f8c) & 0x1ff; int16_t angle2 = READ_WORD(Memory.C4RAM + 0x1f8f) & 0x1ff; - int32_t tan1 = (C4CosTable[angle1] != 0) ? ((((int32_t)C4SinTable[angle1]) << 16) / - C4CosTable[angle1]) : 0x80000000; - int32_t tan2 = (C4CosTable[angle2] != 0) ? ((((int32_t)C4SinTable[angle2]) << 16) / - C4CosTable[angle2]) : 0x80000000; + int32_t tan1 = (C4CosTable[angle1] != 0) ? ((((int32_t)C4SinTable[angle1]) << 16) / C4CosTable[angle1]) : 0x80000000; + int32_t tan2 = (C4CosTable[angle2] != 0) ? ((((int32_t)C4SinTable[angle2]) << 16) / C4CosTable[angle2]) : 0x80000000; int16_t y = READ_WORD(Memory.C4RAM + 0x1f83) - READ_WORD(Memory.C4RAM + 0x1f89); int16_t left, right; int32_t j; @@ -618,13 +619,8 @@ void S9xSetC4(uint8_t byte, uint16_t Address) { if (y >= 0) { - left = SAR32((int32_t)tan1 * y, 16) - - READ_WORD(Memory.C4RAM + 0x1f80) + - READ_WORD(Memory.C4RAM + 0x1f86); - right = SAR32((int32_t)tan2 * y, 16) - - READ_WORD(Memory.C4RAM + 0x1f80) + - READ_WORD(Memory.C4RAM + 0x1f86) + - READ_WORD(Memory.C4RAM + 0x1f93); + left = SAR32((int32_t)tan1 * y, 16) - READ_WORD(Memory.C4RAM + 0x1f80) + READ_WORD(Memory.C4RAM + 0x1f86); + right = SAR32((int32_t)tan2 * y, 16) - READ_WORD(Memory.C4RAM + 0x1f80) + READ_WORD(Memory.C4RAM + 0x1f86) + READ_WORD(Memory.C4RAM + 0x1f93); if (left < 0 && right < 0) { @@ -654,18 +650,16 @@ void S9xSetC4(uint8_t byte, uint16_t Address) Memory.C4RAM[j + 0x900] = (uint8_t)right; y++; } + break; } - break; - case 0x25: // Multiply { int32_t foo = READ_3WORD(Memory.C4RAM + 0x1f80); int32_t bar = READ_3WORD(Memory.C4RAM + 0x1f83); foo *= bar; WRITE_3WORD(Memory.C4RAM + 0x1f80, foo); + break; } - break; - case 0x2d: // Transform Coords C4WFXVal = READ_WORD(Memory.C4RAM + 0x1f81); C4WFYVal = READ_WORD(Memory.C4RAM + 0x1f84); @@ -678,88 +672,79 @@ void S9xSetC4(uint8_t byte, uint16_t Address) WRITE_WORD(Memory.C4RAM + 0x1f80, C4WFXVal); WRITE_WORD(Memory.C4RAM + 0x1f83, C4WFYVal); break; - case 0x40: // Sum { int32_t i; uint16_t sum = 0; for (i = 0; i < 0x800; sum += Memory.C4RAM[i++]); WRITE_WORD(Memory.C4RAM + 0x1f80, sum); + break; } - break; - case 0x54: // Square { int64_t a = SAR64((int64_t)READ_3WORD(Memory.C4RAM + 0x1f80) << 40, 40); a *= a; WRITE_3WORD(Memory.C4RAM + 0x1f83, a); WRITE_3WORD(Memory.C4RAM + 0x1f86, (a >> 24)); + break; } - break; - case 0x5c: // Immediate Reg for (i = 0; i < 12 * 4; i++) Memory.C4RAM [i] = C4TestPattern [i]; break; - case 0x89: // Immediate ROM Memory.C4RAM [0x1f80] = 0x36; Memory.C4RAM [0x1f81] = 0x43; Memory.C4RAM [0x1f82] = 0x05; break; - default: break; } } } else if (Address == 0x7f47) - { // memmove required: Can overlap arbitrarily [Neb] - memmove(Memory.C4RAM + (READ_WORD(Memory.C4RAM + 0x1f45) & 0x1fff), - S9xGetMemPointer(READ_3WORD(Memory.C4RAM + 0x1f40)), - READ_WORD(Memory.C4RAM + 0x1f43)); - } + memmove(Memory.C4RAM + (READ_WORD(Memory.C4RAM + 0x1f45) & 0x1fff), S9xGetMemPointer(READ_3WORD(Memory.C4RAM + 0x1f40)), READ_WORD(Memory.C4RAM + 0x1f43)); } int16_t C4SinTable[512] = { - 0, 402, 804, 1206, 1607, 2009, 2410, 2811, - 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, - 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, - 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, - 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, - 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, - 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, - 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, - 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, - 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, - 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, - 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, - 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, - 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, - 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, - 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, - 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, - 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, - 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, - 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, - 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, - 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, - 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, - 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, - 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, - 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, - 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, - 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, - 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, - 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, - 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, - 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, - 0, -402, -804, -1206, -1607, -2009, -2410, -2811, + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, + 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, + 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, + 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, + 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, + 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, + 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, + 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, + 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, + 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, + 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, + 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, + 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, + 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, + 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, + 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, + 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, + 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, + 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, + 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, + 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, + 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, + 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, + 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, + 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, + 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, + 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, + 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, + 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, + 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, + 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, + 0, -402, -804, -1206, -1607, -2009, -2410, -2811, -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, - -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, + -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, @@ -792,26 +777,26 @@ int16_t C4SinTable[512] = int16_t C4CosTable[512] = { - 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, - 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, - 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, - 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, - 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, - 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, - 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, - 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, - 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, - 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, - 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, - 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, - 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, - 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, - 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, - 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, - 0, -402, -804, -1206, -1607, -2009, -2410, -2811, + 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, + 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, + 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, + 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, + 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, + 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, + 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, + 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, + 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, + 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, + 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, + 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, + 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, + 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, + 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, + 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, + 0, -402, -804, -1206, -1607, -2009, -2410, -2811, -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, - -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, + -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, @@ -836,24 +821,24 @@ int16_t C4CosTable[512] = -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, - -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, + -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, - -3211, -2811, -2410, -2009, -1607, -1206, -804, -402, - 0, 402, 804, 1206, 1607, 2009, 2410, 2811, - 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, - 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, - 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, - 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, - 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, - 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, - 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, - 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, - 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, - 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, - 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, - 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, - 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, - 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, - 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765 + -3211, -2811, -2410, -2009, -1607, -1206, -804, -402, + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, + 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, + 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, + 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, + 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, + 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, + 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, + 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, + 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, + 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, + 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, + 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, + 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, + 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, + 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765 }; diff --git a/source/dsp1.c b/source/dsp1.c index 5d4d522..9e7f05b 100644 --- a/source/dsp1.c +++ b/source/dsp1.c @@ -356,8 +356,8 @@ void DSP1SetByte(uint8_t byte, uint16_t address) DSP1.output [1] = (uint8_t)((Op06H >> 8) & 0xFF); DSP1.output [2] = (uint8_t)(Op06V & 0xFF); DSP1.output [3] = (uint8_t)((Op06V >> 8) & 0xFF); - DSP1.output [4] = (uint8_t)(Op06S & 0xFF); - DSP1.output [5] = (uint8_t)((Op06S >> 8) & 0xFF); + DSP1.output [4] = (uint8_t)(Op06M & 0xFF); + DSP1.output [5] = (uint8_t)((Op06M >> 8) & 0xFF); break; case 0x1e: case 0x2e: diff --git a/source/dsp1emu.c b/source/dsp1emu.c index a2767b0..3e34795 100644 --- a/source/dsp1emu.c +++ b/source/dsp1emu.c @@ -6,9 +6,6 @@ #include <string.h> #include <stdlib.h> -#define __OPT__ -#define __OPT06__ - const uint16_t DSP1ROM[1024] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, @@ -142,46 +139,9 @@ const uint16_t DSP1ROM[1024] = }; /***************************************************************************\ -* Math tables * -\***************************************************************************/ - -#define INCR 2048 -#define Angle(x) (((x)/(65536/INCR)) & (INCR-1)) -#define Cos(x) ((double) CosTable2[x]) -#define Sin(x) ((double) SinTable2[x]) -#ifdef PI -#undef PI -#endif -#define PI 3.1415926535897932384626433832795 -double CosTable2[INCR]; -double SinTable2[INCR]; - - -double Atan(double x) -{ - if ((x >= 1) || (x <= 1)) - return (x / (1 + 0.28 * x * x)); - else - return (PI / 2 - Atan(1 / x)); -} - -/***************************************************************************\ * DSP1 code * \***************************************************************************/ -void InitDSP(void) -{ -#ifdef __OPT__ - uint32_t i; - for (i = 0; i < INCR; i++) - { - CosTable2[i] = (cos((double)(2 * PI * i / INCR))); - SinTable2[i] = (sin((double)(2 * PI * i / INCR))); - } -#endif -} - - int16_t Op00Multiplicand; int16_t Op00Multiplier; int16_t Op00Result; @@ -189,7 +149,6 @@ int16_t Op00Result; void DSPOp00() { Op00Result = Op00Multiplicand * Op00Multiplier >> 15; - } int16_t Op20Multiplicand; @@ -200,7 +159,6 @@ void DSPOp20() { Op20Result = Op20Multiplicand * Op20Multiplier >> 15; Op20Result++; - } int16_t Op10Coefficient; @@ -208,8 +166,7 @@ int16_t Op10Exponent; int16_t Op10CoefficientR; int16_t Op10ExponentR; -void DSP1_Inverse(int16_t Coefficient, int16_t Exponent, int16_t* iCoefficient, - int16_t* iExponent) +void DSP1_Inverse(int16_t Coefficient, int16_t Exponent, int16_t* iCoefficient, int16_t* iExponent) { // Step One: Division by Zero if (Coefficient == 0x0000) @@ -308,22 +265,22 @@ const int16_t DSP1_MulTable[256] = const int16_t DSP1_SinTable[256] = { - 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, - 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, - 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, - 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, - 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, - 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, - 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, + 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, + 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, + 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, + 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, + 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, + 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, + 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, + 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, + 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, + 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, + 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, + 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, + 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, + 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, + 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, + 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2, -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a, @@ -349,8 +306,7 @@ int16_t DSP1_Sin(int16_t Angle) if (Angle == -32768) return 0; return -DSP1_Sin(-Angle); } - int32_t S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * - DSP1_SinTable[0x40 + (Angle >> 8)] >> 15); + int32_t S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15); if (S > 32767) S = 32767; return (int16_t) S; } @@ -362,8 +318,7 @@ int16_t DSP1_Cos(int16_t Angle) if (Angle == -32768) return -32768; Angle = -Angle; } - int32_t S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * - DSP1_SinTable[Angle >> 8] >> 15); + int32_t S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15); if (S < -32768) S = -32767; return (int16_t) S; } @@ -502,50 +457,75 @@ int16_t SecAZS_E1; int16_t SecAZS_C2; int16_t SecAZS_E2; +int16_t Nx, Ny, Nz; +int16_t Gx, Gy, Gz; +int16_t C_Les, E_Les, G_Les; + const int16_t MaxAZS_Exp[16] = { 0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca, 0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4 }; -void DSP1_Parameter(int16_t Fx, int16_t Fy, int16_t Fz, int16_t Lfe, int16_t Les, - int16_t Aas, int16_t Azs, int16_t* Vof, int16_t* Vva, int16_t* Cx, int16_t* Cy) +void DSP1_Parameter(int16_t Fx, int16_t Fy, int16_t Fz, int16_t Lfe, int16_t Les, int16_t Aas, int16_t Azs, int16_t* Vof, int16_t* Vva, int16_t* Cx, int16_t* Cy) { - int16_t CSec, C, E; + int16_t CSec, C, E, MaxAZS, Aux; + int16_t LfeNx, LfeNy, LfeNz; + int16_t LesNx, LesNy, LesNz; + int16_t CentreZ; // Copy Zenith angle for clipping int16_t AZS = Azs; - // Store Sin and Cos of Azimuth and Zenith angles + // Store Sine and Cosine of Azimuth and Zenith angle SinAas = DSP1_Sin(Aas); CosAas = DSP1_Cos(Aas); SinAzs = DSP1_Sin(Azs); CosAzs = DSP1_Cos(Azs); + Nx = SinAzs * -SinAas >> 15; + Ny = SinAzs * CosAas >> 15; + Nz = CosAzs * 0x7fff >> 15; + + LfeNx = Lfe * Nx >> 15; + LfeNy = Lfe * Ny >> 15; + LfeNz = Lfe * Nz >> 15; + // Center of Projection - CentreX = Fx + (Lfe * (SinAzs * -SinAas >> 15) >> 15); - CentreY = Fy + (Lfe * (SinAzs * CosAas >> 15) >> 15); + CentreX = Fx + LfeNx; + CentreY = Fy + LfeNy; + CentreZ = Fz + LfeNz; + + LesNx = Les * Nx >> 15; + LesNy = Les * Ny >> 15; + LesNz = Les * Nz >> 15; + + Gx = CentreX - LesNx; + Gy = CentreY - LesNy; + Gz = CentreZ - LesNz; + + E_Les=0; + DSP1_Normalize(Les, &C_Les, &E_Les); + G_Les = Les; E = 0; - DSP1_Normalize(Fz + (Lfe * (CosAzs * 0x7fff >> 15) >> 15), &C, &E); + DSP1_Normalize(CentreZ, &C, &E); VPlane_C = C; VPlane_E = E; // Determine clip boundary and clip Zenith angle if necessary - int16_t MaxAZS = MaxAZS_Exp[-E]; + MaxAZS = MaxAZS_Exp[-E]; if (AZS < 0) { MaxAZS = -MaxAZS; if (AZS < MaxAZS + 1) AZS = MaxAZS + 1; } - else - { - if (AZS > MaxAZS) AZS = MaxAZS; - } + else if (AZS > MaxAZS) + AZS = MaxAZS; - // Store Sin and Cos of clipped Zenith angle + // Store Sine and Cosine of clipped Zenith angle SinAZS = DSP1_Sin(AZS); CosAZS = DSP1_Cos(AZS); @@ -570,7 +550,7 @@ void DSP1_Parameter(int16_t Fx, int16_t Fy, int16_t Fz, int16_t Lfe, int16_t Les C = Azs - MaxAZS; if (C >= 0) C--; - int16_t Aux = ~(C << 2); + Aux = ~(C << 2); C = Aux * DSP1ROM[0x0328] >> 15; C = (C * Aux >> 15) + DSP1ROM[0x0327]; @@ -595,7 +575,7 @@ void DSP1_Parameter(int16_t Fx, int16_t Fy, int16_t Fz, int16_t Lfe, int16_t Les *Vva = DSP1_Truncate(-C, E); - // Store Sec of clipped Zenith angle + // Store Secant of clipped Zenith angle DSP1_Inverse(CosAZS, 0, &SecAZS_C2, &SecAZS_E2); } @@ -638,8 +618,7 @@ int16_t Op02CY; void DSPOp02() { - DSP1_Parameter(Op02FX, Op02FY, Op02FZ, Op02LFE, Op02LES, Op02AAS, Op02AZS, - &Op02VOF, &Op02VVA, &Op02CX, &Op02CY); + DSP1_Parameter(Op02FX, Op02FY, Op02FZ, Op02LFE, Op02LES, Op02AAS, Op02AZS, &Op02VOF, &Op02VVA, &Op02CX, &Op02CY); } int16_t Op0AVS; @@ -654,115 +633,96 @@ void DSPOp0A() Op0AVS++; } +int16_t DSP1_ShiftR(int16_t C, int16_t E) +{ + return (C * DSP1ROM[0x0031 + E] >> 15); +} + +void DSP1_Project(int16_t X, int16_t Y, int16_t Z, int16_t *H, int16_t *V, int16_t *M) +{ + int32_t aux, aux4; + int16_t E, E2, E3, E4, E5, refE, E6, E7; + int16_t C2, C4, C6, C8, C9, C10, C11, C12, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26; + int16_t Px, Py, Pz; + + E4 = E3 = E2 = E = E5 = 0; + + DSP1_NormalizeDouble((int32_t) X - Gx, &Px, &E4); + DSP1_NormalizeDouble((int32_t) Y - Gy, &Py, &E); + DSP1_NormalizeDouble((int32_t) Z - Gz, &Pz, &E3); + Px>>=1; + E4--; // to avoid overflows when calculating the scalar products + Py>>=1; + E--; + Pz>>=1; + E3--; + + refE = MIN(E, E3); + refE = MIN(refE, E4); + + Px = DSP1_ShiftR(Px, E4 - refE); // normalize them to the same exponent + Py = DSP1_ShiftR(Py, E - refE); + Pz = DSP1_ShiftR(Pz, E3 - refE); + + C11 = -(Px * Nx >> 15); + C8 = -(Py * Ny >> 15); + C9 = -(Pz * Nz >> 15); + C12 = C11 + C8 + C9; // this cannot overflow! + + aux4 = C12; // de-normalization with 32-bit arithmetic + refE = 16 - refE; // refE can be up to 3 + if (refE >= 0) + aux4 <<= refE; + else + aux4 >>= -refE; + if (aux4 == -1) + aux4 = 0; // why? + aux4>>=1; + + aux = ((int16_t) G_Les) + aux4; // Les - the scalar product of P with the normal vector of the screen + DSP1_NormalizeDouble(aux, &C10, &E2); + E2 = 15 - E2; + + DSP1_Inverse(C10, 0, &C4, &E4); + C2 = C4 * C_Les >> 15; // scale factor + + // H + E7 = 0; + C16 = (Px * (CosAas * 0x7fff >> 15) >> 15); + C20 = (Py * (SinAas * 0x7fff >> 15) >> 15); + C17 = C16 + C20; // scalar product of P with the normalized horizontal vector of the screen... + + C18 = C17 * C2 >> 15; // ... multiplied by the scale factor + DSP1_Normalize(C18, &C19, &E7); + *H = DSP1_Truncate(C19, E_Les - E2 + refE + E7); + + // V + E6 = 0; + C21 = Px * (CosAzs * -SinAas >> 15) >> 15; + C22 = Py * (CosAzs * CosAas >> 15) >> 15; + C23 = Pz * (-SinAzs * 0x7fff >> 15) >> 15; + C24 = C21 + C22 + C23; // scalar product of P with the normalized vertical vector of the screen... + + C26 = C24 * C2 >> 15; // ... multiplied by the scale factor + DSP1_Normalize(C26, &C25, &E6); + *V = DSP1_Truncate(C25, E_Les - E2 + refE + E6); + + // M + DSP1_Normalize(C2, &C6, &E4); + *M = DSP1_Truncate(C6, E4 + E_Les - E2 - 7); // M is the scale factor divided by 2^7 +} + int16_t Op06X; int16_t Op06Y; int16_t Op06Z; int16_t Op06H; int16_t Op06V; -uint16_t Op06S; - -double ObjPX; -double ObjPY; -double ObjPZ; -double ObjPX1; -double ObjPY1; -double ObjPZ1; -double ObjPX2; -double ObjPY2; -double ObjPZ2; -double DivideOp06; -int32_t Temp; -int32_t tanval2; - -#ifdef __OPT06__ -void DSPOp06() -{ - ObjPX = Op06X - Op02FX; - ObjPY = Op06Y - Op02FY; - ObjPZ = Op06Z - Op02FZ; - - // rotate around Z - tanval2 = Angle(-Op02AAS + 32768); - ObjPX1 = (ObjPX * Cos(tanval2) + ObjPY * -Sin(tanval2)); - ObjPY1 = (ObjPX * Sin(tanval2) + ObjPY * Cos(tanval2)); - ObjPZ1 = ObjPZ; - - // rotate around X - tanval2 = Angle(-Op02AZS); - ObjPX2 = ObjPX1; - ObjPY2 = (ObjPY1 * Cos(tanval2) + ObjPZ1 * -Sin(tanval2)); - ObjPZ2 = (ObjPY1 * Sin(tanval2) + ObjPZ1 * Cos(tanval2)); - - ObjPZ2 = ObjPZ2 - Op02LFE; - - if (ObjPZ2 < 0) - { - double d; - Op06H = (int16_t)(-ObjPX2 * Op02LES / -(ObjPZ2)); - Op06V = (int16_t)(-ObjPY2 * Op02LES / -(ObjPZ2)); - d = (double)Op02LES; - d *= 256.0; - d /= (-ObjPZ2); - if (d > 65535.0) - d = 65535.0; - else if (d < 0.0) - d = 0.0; - Op06S = (uint16_t)d; - } - else - { - Op06H = 0; - Op06V = 14 * 16; - Op06S = 0xFFFF; - } - - -} -#else +int16_t Op06M; void DSPOp06() { - ObjPX = Op06X - Op02FX; - ObjPY = Op06Y - Op02FY; - ObjPZ = Op06Z - Op02FZ; - - // rotate around Z - tanval = (-Op02AAS + 32768) / 65536.0 * 6.2832; - ObjPX1 = (ObjPX * cos(tanval) + ObjPY * -sin(tanval)); - ObjPY1 = (ObjPX * sin(tanval) + ObjPY * cos(tanval)); - ObjPZ1 = ObjPZ; - - // rotate around X - tanval = (-Op02AZS) / 65536.0 * 6.2832; - ObjPX2 = ObjPX1; - ObjPY2 = (ObjPY1 * cos(tanval) + ObjPZ1 * -sin(tanval)); - ObjPZ2 = (ObjPY1 * sin(tanval) + ObjPZ1 * cos(tanval)); - - ObjPZ2 = ObjPZ2 - Op02LFE; - - if (ObjPZ2 < 0) - { - Op06H = (int16_t)(-ObjPX2 * Op02LES / -(ObjPZ2)); - Op06V = (int16_t)(-ObjPY2 * Op02LES / -(ObjPZ2)); - double d = (double)Op02LES; - d *= 256.0; - d /= (-ObjPZ2); - if (d > 65535.0) - d = 65535.0; - else if (d < 0.0) - d = 0.0; - Op06S = (uint16_t)d; - } - else - { - Op06H = 0; - Op06V = 14 * 16; - Op06S = 0xFFFF; - } - + DSP1_Project(Op06X, Op06Y, Op06Z, &Op06H, &Op06V, &Op06M); } -#endif - int16_t matrixC[3][3]; int16_t matrixB[3][3]; @@ -796,16 +756,12 @@ void DSPOp01() matrixA[0][1] = -((Op01m * SinAz >> 15) * CosAy >> 15); matrixA[0][2] = Op01m * SinAy >> 15; - matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + ((( - Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - ((( - Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + (((Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - (((Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); matrixA[1][2] = -((Op01m * SinAx >> 15) * CosAy >> 15); - matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - ((( - Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + ((( - Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - (((Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + (((Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); matrixA[2][2] = (Op01m * CosAx >> 15) * CosAy >> 15; } @@ -824,16 +780,12 @@ void DSPOp11() matrixB[0][1] = -((Op11m * SinAz >> 15) * CosAy >> 15); matrixB[0][2] = Op11m * SinAy >> 15; - matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + ((( - Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - ((( - Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + (((Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - (((Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); matrixB[1][2] = -((Op11m * SinAx >> 15) * CosAy >> 15); - matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - ((( - Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + ((( - Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - (((Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + (((Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); matrixB[2][2] = (Op11m * CosAx >> 15) * CosAy >> 15; } @@ -852,16 +804,12 @@ void DSPOp21() matrixC[0][1] = -((Op21m * SinAz >> 15) * CosAy >> 15); matrixC[0][2] = Op21m * SinAy >> 15; - matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + ((( - Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - ((( - Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + (((Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - (((Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); matrixC[1][2] = -((Op21m * SinAx >> 15) * CosAy >> 15); - matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - ((( - Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + ((( - Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - (((Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + (((Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); matrixC[2][2] = (Op21m * CosAx >> 15) * CosAy >> 15; } @@ -886,35 +834,23 @@ int16_t Op2DU; void DSPOp0D() { - Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + - (Op0DZ * matrixA[0][2] >> 15); - Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + - (Op0DZ * matrixA[1][2] >> 15); - Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + - (Op0DZ * matrixA[2][2] >> 15); - + Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + (Op0DZ * matrixA[0][2] >> 15); + Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + (Op0DZ * matrixA[1][2] >> 15); + Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + (Op0DZ * matrixA[2][2] >> 15); } void DSPOp1D() { - Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + - (Op1DZ * matrixB[0][2] >> 15); - Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + - (Op1DZ * matrixB[1][2] >> 15); - Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + - (Op1DZ * matrixB[2][2] >> 15); - + Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + (Op1DZ * matrixB[0][2] >> 15); + Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + (Op1DZ * matrixB[1][2] >> 15); + Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + (Op1DZ * matrixB[2][2] >> 15); } void DSPOp2D() { - Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + - (Op2DZ * matrixC[0][2] >> 15); - Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + - (Op2DZ * matrixC[1][2] >> 15); - Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + - (Op2DZ * matrixC[2][2] >> 15); - + Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + (Op2DZ * matrixC[0][2] >> 15); + Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + (Op2DZ * matrixC[1][2] >> 15); + Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + (Op2DZ * matrixC[2][2] >> 15); } int16_t Op03F; @@ -938,35 +874,23 @@ int16_t Op23Z; void DSPOp03() { - Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + - (Op03U * matrixA[2][0] >> 15); - Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + - (Op03U * matrixA[2][1] >> 15); - Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + - (Op03U * matrixA[2][2] >> 15); - + Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + (Op03U * matrixA[2][0] >> 15); + Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + (Op03U * matrixA[2][1] >> 15); + Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + (Op03U * matrixA[2][2] >> 15); } void DSPOp13() { - Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + - (Op13U * matrixB[2][0] >> 15); - Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + - (Op13U * matrixB[2][1] >> 15); - Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + - (Op13U * matrixB[2][2] >> 15); - + Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + (Op13U * matrixB[2][0] >> 15); + Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + (Op13U * matrixB[2][1] >> 15); + Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + (Op13U * matrixB[2][2] >> 15); } void DSPOp23() { - Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + - (Op23U * matrixC[2][0] >> 15); - Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + - (Op23U * matrixC[2][1] >> 15); - Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + - (Op23U * matrixC[2][2] >> 15); - + Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + (Op23U * matrixC[2][0] >> 15); + Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + (Op23U * matrixC[2][1] >> 15); + Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + (Op23U * matrixC[2][2] >> 15); } int16_t Op14Zr; @@ -986,8 +910,7 @@ void DSPOp14() DSP1_Inverse(DSP1_Cos(Op14Xr), 0, &CSec, &ESec); // Rotation Around Z - DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, - &E); + DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, &E); E = ESec - E; @@ -996,12 +919,10 @@ void DSPOp14() Op14Zrr = Op14Zr + DSP1_Truncate(C, E); // Rotation Around X - Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos( - Op14Yr) >> 15); + Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos(Op14Yr) >> 15); // Rotation Around Y - DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, - &E); + DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, &E); E = ESec - E; @@ -1068,23 +989,17 @@ int16_t Op2BS; void DSPOp0B() { - Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) - >> 15; - + Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) >> 15; } void DSPOp1B() { - Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) - >> 15; - + Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) >> 15; } void DSPOp2B() { - Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) - >> 15; - + Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) >> 15; } int16_t Op08X, Op08Y, Op08Z, Op08Ll, Op08Lh; @@ -1094,7 +1009,6 @@ void DSPOp08() int32_t Op08Size = (Op08X * Op08X + Op08Y * Op08Y + Op08Z * Op08Z) << 1; Op08Ll = Op08Size & 0xffff; Op08Lh = (Op08Size >> 16) & 0xffff; - } int16_t Op18X, Op18Y, Op18Z, Op18R, Op18D; @@ -1102,7 +1016,6 @@ int16_t Op18X, Op18Y, Op18Z, Op18R, Op18D; void DSPOp18() { Op18D = (Op18X * Op18X + Op18Y * Op18Y + Op18Z * Op18Z - Op18R * Op18R) >> 15; - } int16_t Op38X, Op38Y, Op38Z, Op38R, Op38D; @@ -1111,7 +1024,6 @@ void DSPOp38() { Op38D = (Op38X * Op38X + Op38Y * Op38Y + Op38Z * Op38Z - Op38R * Op38R) >> 15; Op38D++; - } int16_t Op28X; @@ -1126,19 +1038,18 @@ void DSPOp28() if (Radius == 0) Op28R = 0; else { - int16_t C, E; + int16_t C, E, Pos, Node1, Node2; DSP1_NormalizeDouble(Radius, &C, &E); if (E & 1) C = C * 0x4000 >> 15; - int16_t Pos = C * 0x0040 >> 15; + Pos = C * 0x0040 >> 15; - int16_t Node1 = DSP1ROM[0x00d5 + Pos]; - int16_t Node2 = DSP1ROM[0x00d6 + Pos]; + Node1 = DSP1ROM[0x00d5 + Pos]; + Node2 = DSP1ROM[0x00d6 + Pos]; Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1; Op28R >>= (E >> 1); } - } int16_t Op1CX, Op1CY, Op1CZ; @@ -1169,7 +1080,6 @@ void DSPOp1C() Op1CZ1 = (Op1CZBR * DSP1_Cos(Op1CX) >> 15) - (Op1CYBR * DSP1_Sin(Op1CX) >> 15); Op1CYAR = Op1CY1; Op1CZAR = Op1CZ1; - } uint16_t Op0FRamsize; @@ -1178,7 +1088,6 @@ uint16_t Op0FPass; void DSPOp0F() { Op0FPass = 0x0000; - } int16_t Op2FUnknown; diff --git a/source/globals.c b/source/globals.c index eecb297..b99e488 100644 --- a/source/globals.c +++ b/source/globals.c @@ -205,27 +205,26 @@ uint8_t APUROM [64] = 0xF4, 0xC4, 0xF4, 0xDD, 0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF }; - // Raw SPC700 instruction cycle lengths uint16_t S9xAPUCycleLengths [256] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ - /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, - /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, - /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, - /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, - /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, - /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, - /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, - /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, - /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 12, 5, - /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, - /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, - /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, - /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, - /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, - /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 }; // Actual data used by CPU emulation, will be scaled by APUReset routine @@ -233,20 +232,20 @@ uint16_t S9xAPUCycleLengths [256] = uint16_t S9xAPUCycles [256] = { /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ - /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, - /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, - /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, - /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, - /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, - /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, - /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, - /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, - /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 12, 5, - /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, - /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, - /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, - /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, - /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, - /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 }; diff --git a/source/port.h b/source/port.h index bbe28c3..622027f 100644 --- a/source/port.h +++ b/source/port.h @@ -30,10 +30,8 @@ #define _MAX_EXT PATH_MAX #define _MAX_PATH PATH_MAX -void _makepath(char* path, const char* drive, const char* dir, - const char* fname, const char* ext); -void _splitpath(const char* path, char* drive, char* dir, char* fname, - char* ext); +void _makepath(char* path, const char* drive, const char* dir, const char* fname, const char* ext); +void _splitpath(const char* path, char* drive, char* dir, char* fname, char* ext); #else /* __WIN32__ */ #define strcasecmp stricmp #define strncasecmp strnicmp @@ -57,4 +55,31 @@ void _splitpath(const char* path, char* drive, char* dir, char* fname, #define MIN(A,B) ((A) < (B) ? (A) : (B)) #define MAX(A,B) ((A) > (B) ? (A) : (B)) +/* Integer square root by Halleck's method, with Legalize's speedup */ +static inline int32_t _isqrt(int32_t val) +{ + int32_t squaredbit, remainder, root; + + if (val < 1) + return 0; + + squaredbit = 1 << 30; + remainder = val; + root = 0; + + while (squaredbit > 0) + { + if (remainder >= (squaredbit | root)) + { + remainder -= (squaredbit | root); + root >>= 1; + root |= squaredbit; + } else + root >>= 1; + squaredbit >>= 2; + } + + return root; +} + #endif diff --git a/source/seta010.c b/source/seta010.c index 0e64248..89ae4f8 100644 --- a/source/seta010.c +++ b/source/seta010.c @@ -30,12 +30,6 @@ const int16_t ST010_M7Scale[176] = 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b }; -// H-DMA hack -bool seta_hack; - -//temporary Op04 requirement -#include <math.h> - ST010_Regs ST010; uint8_t S9xGetST010(uint32_t Address) @@ -52,23 +46,23 @@ uint8_t S9xGetST010(uint32_t Address) const int16_t ST010_SinTable[256] = { - 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, - 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, - 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, - 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, - 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, - 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, - 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, - 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, + 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, + 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, + 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, + 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, + 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, + 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, + 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, + 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, + 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, + 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, + 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, + 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, + 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, + 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, + 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, + 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, + 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a, -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, @@ -228,8 +222,7 @@ int16_t ST010_Cos(int16_t Theta) return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff]; } -void ST010_OP01(int16_t x0, int16_t y0, int16_t* x1, int16_t* y1, int16_t* Quadrant, - int16_t* Theta) +void ST010_OP01(int16_t x0, int16_t y0, int16_t* x1, int16_t* y1, int16_t* Quadrant, int16_t* Theta) { if ((x0 < 0) && (y0 < 0)) { @@ -258,8 +251,10 @@ void ST010_OP01(int16_t x0, int16_t y0, int16_t* x1, int16_t* y1, int16_t* Quadr while ((*x1 > 0x1f) || (*y1 > 0x1f)) { - if (*x1 > 1) *x1 >>= 1; - if (*y1 > 1) *y1 >>= 1; + if (*x1 > 1) + *x1 >>= 1; + if (*y1 > 1) + *y1 >>= 1; } if (*y1 == 0) *Quadrant += 0x4000; @@ -346,8 +341,7 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) { #if defined(FAST_LSB_WORD_ACCESS) && !defined(ANDROID) /* TODO - FIXME */ - ST010_SortDrivers(*(int16_t*)&Memory.SRAM[0x0024], (uint16_t*)(Memory.SRAM + 0x0040), - (uint16_t*)(Memory.SRAM + 0x0080)); + ST010_SortDrivers(*(int16_t*)&Memory.SRAM[0x0024], (uint16_t*)(Memory.SRAM + 0x0040), (uint16_t*)(Memory.SRAM + 0x0080)); #else uint16_t Places[32]; uint16_t Positions = ST010_WORD(0x0024); @@ -391,13 +385,11 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) #if defined(FAST_LSB_WORD_ACCESS) && !defined(ANDROID) /* TODO - FIXME */ ST010_Scale(*(int16_t*)&Memory.SRAM[0x0004], *(int16_t*)&Memory.SRAM[0x0000], - *(int16_t*)&Memory.SRAM[0x0002], - (int32_t*)&Memory.SRAM[0x0010], (int32_t*)&Memory.SRAM[0x0014]); + *(int16_t*)&Memory.SRAM[0x0002], (int32_t*)&Memory.SRAM[0x0010], (int32_t*)&Memory.SRAM[0x0014]); #else int32_t x1, y1; - ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, - &y1); + ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, &y1); Memory.SRAM[0x0010] = (uint8_t)(x1); Memory.SRAM[0x0011] = (uint8_t)(x1 >> 8); @@ -423,8 +415,7 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) { #if defined(FAST_LSB_WORD_ACCESS) && !defined(ANDROID) /* TODO - FIXME */ - ST010_Multiply(*(int16_t*)&Memory.SRAM[0x0000], *(int16_t*)&Memory.SRAM[0x0002], - (int32_t*)&Memory.SRAM[0x0010]); + ST010_Multiply(*(int16_t*)&Memory.SRAM[0x0000], *(int16_t*)&Memory.SRAM[0x0002], (int32_t*)&Memory.SRAM[0x0010]); #else int32_t Product; @@ -501,13 +492,11 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) #if defined(FAST_LSB_WORD_ACCESS) && !defined(ANDROID) /* TODO - FIXME */ ST010_Rotate(*(int16_t*)&Memory.SRAM[0x0004], *(int16_t*)&Memory.SRAM[0x0000], - *(int16_t*)&Memory.SRAM[0x0002], - (int16_t*)&Memory.SRAM[0x0010], (int16_t*)&Memory.SRAM[0x0012]); + *(int16_t*)&Memory.SRAM[0x0002], (int16_t*)&Memory.SRAM[0x0010], (int16_t*)&Memory.SRAM[0x0012]); #else int16_t x1, y1; - ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, - &y1); + ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, &y1); Memory.SRAM[0x0010] = (uint8_t)(x1); Memory.SRAM[0x0011] = (uint8_t)(x1 >> 8); @@ -562,7 +551,7 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) x = Memory.SRAM[0] | (Memory.SRAM[1] << 8); y = Memory.SRAM[2] | (Memory.SRAM[3] << 8); #endif - square = (int16_t)sqrt((double)(y * y + x * x)); + square = (int16_t)_isqrt((int32_t) x * x + (int32_t) y * y); #if defined(FAST_LSB_WORD_ACCESS) && !defined(ANDROID) /* TODO - FIXME */ @@ -624,7 +613,7 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) ST010_OP01(dy, dx, &a1, &b1, &c1, (int16_t*)&o1); // check for wrapping - if (abs(o1 - rot) > 0x8000) + if (ABS(o1 - rot) > 0x8000) { o1 += 0x8000; rot += 0x8000; @@ -636,12 +625,12 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) old_speed = speed; // special case - if (abs(o1 - rot) == 0x8000) + if (ABS(o1 - rot) == 0x8000) speed = 0x100; // slow down for sharp curves - else if (abs(o1 - rot) >= 0x1000) + else if (ABS(o1 - rot) >= 0x1000) { - uint32_t slow = abs(o1 - rot); + uint32_t slow = ABS(o1 - rot); slow >>= 4; // scaling speed -= slow; } @@ -657,7 +646,7 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) } // prevent negative/positive overflow - if (abs(old_speed - speed) > 0x8000) + if (ABS(old_speed - speed) > 0x8000) { if (old_speed < speed) speed = 0; else speed = 0xff00; @@ -717,13 +706,8 @@ void S9xSetST010(uint32_t Address, uint8_t Byte) Memory.SRAM[0x00D5] = (uint8_t)(speed >> 8); Memory.SRAM[0x00DC] = (uint8_t)(flags); Memory.SRAM[0x00DD] = (uint8_t)(flags >> 8); - break; } - - default: - printf("Unknown Op\n"); - break; } // lower signal: op processed |