Integer-only C4 from snes9x2002. Integer-only, finalized DSP1 from snes9x 1.50. Integer-only libretro.c and seta010.c.

This commit is contained in:
João Silva 2017-02-12 02:40:43 +00:00
parent 3777d1fcf4
commit ae5fb3ae90
9 changed files with 605 additions and 632 deletions

View File

@ -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
}

View File

@ -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);
}

View File

@ -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[];

View File

@ -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
};

View File

@ -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:

View File

@ -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,
@ -141,47 +138,10 @@ const uint16_t DSP1ROM[1024] =
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};
/***************************************************************************\
* 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;

View File

@ -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
};

View File

@ -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

View File

@ -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