The ST-0010 is a DSP chip from Seta; it is actually a NEC uPD96050, as confirmed by decapping. It's only used (and barely so) in one game:
The development PCB for this chip has the serial SETA ESP-0019C SHVC PCB
and the following chips:
DSP Crystal
=========== =========
ST010 DOL-70
D96050CW-012 22.000MHz
9243K2901 KDS-IL
ST-0010 Memory Mapping
Mode |
Size |
Bank |
Data Register |
Status Register |
0x20 |
8Mbit |
0x68 - 0x6F |
0x0000 - 0x0FFF |
0x0021 |
ST-0010 Command Summary
Commands are executed on the ST-0010 by writing the command to 0x0020
and setting bit 7 of 0x0021
. Bit 7 of 0x0021
will stay set until the command has completed, at which time output data will be available. See individual commands for input and output parameter addresses.
Command |
Function Name |
0x01 |
Unknown Command |
0x02 |
Sort Driver Placements |
0x03 |
2D Coordinate Scale |
0x04 |
Unknown Command |
0x05 |
Simulated Driver Coordinate Calculation |
0x06 |
Multiply |
0x07 |
Raster Data Calculation |
0x08 |
2D Coordinate Rotation |
ST-0010 Source Code Contributors
The Dumper, Matthew Kendora, Overload, Feather
const short 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,
-0x18F9, -0x1C0B, -0x1F1A, -0x2223, -0x2528, -0x2826, -0x2B1F, -0x2E11,
-0x30FB, -0x33DF, -0x36BA, -0x398D, -0x3C56, -0x3F17, -0x41CE, -0x447A,
-0x471C, -0x49B4, -0x4C3F, -0x4EBF, -0x5133, -0x539B, -0x55F5, -0x5842,
-0x5A82, -0x5CB3, -0x5ED7, -0x60EC, -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, -0x7883, -0x776B,
-0x7641, -0x7504, -0x73B5, -0x7254, -0x70E2, -0x6F5E, -0x6DC9, -0x6C23,
-0x6A6D, -0x68A6, -0x66CF, -0x64E8, -0x62F1, -0x60EB, -0x5ED7, -0x5CB3,
-0x5A82, -0x5842, -0x55F5, -0x539A, -0x5133, -0x4EBF, -0x4C3F, -0x49B3,
-0x471C, -0x447A, -0x41CD, -0x3F17, -0x3C56, -0x398C, -0x36B9, -0x33DE,
-0x30FB, -0x2E10, -0x2B1F, -0x2826, -0x2527, -0x2223, -0x1F19, -0x1C0B,
-0x18F8, -0x15E2, -0x12C8, -0x0FAB, -0x0C8B, -0x096A, -0x0647, -0x0324
};
const char ST010_ArcTan[32][32] = {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0xA0, 0xAD, 0xB3, 0xB6, 0xB8, 0xB9, 0xBA, 0xBB, 0xBB, 0xBC, 0xBC, 0xBD, 0xBD, 0xBD, 0xBD,
0xBD, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF,
0x80, 0x93, 0xA0, 0xA8, 0xAD, 0xB0, 0xB3, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBA, 0xBB,
0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD,
0x80, 0x8D, 0x98, 0xA0, 0xA6, 0xAA, 0xAD, 0xB0, 0xB1, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8,
0xB8, 0xB9, 0xB9, 0xBA, 0xBA, 0xBA, 0xBA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBC, 0xBC,
0x80, 0x8A, 0x93, 0x9A, 0xA0, 0xA5, 0xA8, 0xAB, 0xAD, 0xAF, 0xB0, 0xB2, 0xB3, 0xB4, 0xB5, 0xB5,
0xB6, 0xB7, 0xB7, 0xB8, 0xB8, 0xB8, 0xB9, 0xB9, 0xB9, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBB, 0xBB,
0x80, 0x88, 0x90, 0x96, 0x9B, 0xA0, 0xA4, 0xA7, 0xA9, 0xAB, 0xAD, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
0xB4, 0xB4, 0xB5, 0xB6, 0xB6, 0xB6, 0xB7, 0xB7, 0xB8, 0xB8, 0xB8, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
0x80, 0x87, 0x8D, 0x93, 0x98, 0x9C, 0xA0, 0xA3, 0xA6, 0xA8, 0xAA, 0xAC, 0xAD, 0xAE, 0xB0, 0xB0,
0xB1, 0xB2, 0xB3, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6, 0xB6, 0xB7, 0xB7, 0xB7, 0xB8, 0xB8, 0xB8,
0x80, 0x86, 0x8B, 0x90, 0x95, 0x99, 0x9D, 0xA0, 0xA3, 0xA5, 0xA7, 0xA9, 0xAA, 0xAC, 0xAD, 0xAE,
0xAF, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6, 0xB6, 0xB7, 0xB7,
0x80, 0x85, 0x8A, 0x8F, 0x93, 0x97, 0x9A, 0x9D, 0xA0, 0xA2, 0xA5, 0xA6, 0xA8, 0xAA, 0xAB, 0xAC,
0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB5, 0xB5, 0xB5, 0xB5,
0x80, 0x85, 0x89, 0x8D, 0x91, 0x95, 0x98, 0x9B, 0x9E, 0xA0, 0xA0, 0xA4, 0xA6, 0xA7, 0xA9, 0xAA,
0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4,
0x80, 0x84, 0x88, 0x8C, 0x90, 0x93, 0x96, 0x99, 0x9B, 0x9E, 0xA0, 0xA2, 0xA4, 0xA5, 0xA7, 0xA8,
0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB2, 0xB2, 0xB3, 0xB3,
0x80, 0x84, 0x87, 0x8B, 0x8E, 0x91, 0x94, 0x97, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA3, 0xA5, 0xA6,
0xA7, 0xA9, 0xAA, 0xAB, 0xAC, 0xAC, 0xAD, 0xAE, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1, 0xB2, 0xB2,
0x80, 0x83, 0x87, 0x8A, 0x8D, 0x90, 0x93, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA3, 0xA5,
0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAC, 0xAD, 0xAE, 0xAE, 0xAF, 0xB0, 0xB0, 0xB0, 0xB1,
0x80, 0x83, 0x86, 0x89, 0x8C, 0x8F, 0x92, 0x94, 0x96, 0x99, 0x9B, 0x9D, 0x9E, 0xA0, 0xA2, 0xA3,
0xA4, 0xA5, 0xA7, 0xA8, 0xA9, 0xA9, 0xAA, 0xAB, 0xAC, 0xAC, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0,
0x80, 0x83, 0x86, 0x89, 0x8B, 0x8E, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9B, 0x9D, 0x9E, 0xA0, 0xA1,
0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF,
0x80, 0x83, 0x85, 0x88, 0x8B, 0x8D, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9B, 0x9D, 0x9F, 0xA0,
0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE,
0x80, 0x83, 0x85, 0x88, 0x8A, 0x8C, 0x8F, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9A, 0x9C, 0x9D, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA5, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAB, 0xAC, 0xAD,
0x80, 0x82, 0x85, 0x87, 0x89, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9B, 0x9C, 0x9D,
0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAC,
0x80, 0x82, 0x85, 0x87, 0x89, 0x8B, 0x8D, 0x8F, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9B, 0x9C,
0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xA9, 0xAA, 0xAB,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9A, 0x9B,
0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA6, 0xA7, 0xA8, 0xA8, 0xA9, 0xAA,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9A,
0x9B, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8, 0xA9,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8B, 0x8D, 0x8F, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99,
0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA6, 0xA7, 0xA8,
0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8B, 0x8D, 0x8E, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98,
0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA3, 0xA4, 0xA5, 0xA6, 0xA6, 0xA7,
0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8A, 0x8C, 0x8E, 0x8F, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98,
0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA5, 0xA6,
0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8A, 0x8C, 0x8D, 0x8F, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97,
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA5,
0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8A, 0x8B, 0x8D, 0x8E, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA4,
0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8B, 0x8C, 0x8E, 0x8F, 0x90, 0x92, 0x93, 0x94, 0x95,
0x96, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4,
0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x90, 0x91, 0x92, 0x93, 0x95,
0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9E, 0x9F, 0xA0, 0xA1, 0xA1, 0xA2, 0xA3,
0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8A, 0x8B, 0x8D, 0x8E, 0x8F, 0x90, 0x92, 0x93, 0x94,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9E, 0x9F, 0xA0, 0xA1, 0xA1, 0xA2,
0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8A, 0x8B, 0x8C, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0x9F, 0xA0, 0xA1, 0xA1,
0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8B, 0x8C, 0x8D, 0x8E, 0x90, 0x91, 0x92, 0x93,
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0x9F, 0xA0, 0xA1,
0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9C, 0x9D, 0x9E, 0x9F, 0x9F, 0xA0};
short ST010_Sin(short Theta){
return ST010_SinTable[(Theta >> 8) & 0xFF];
}
short ST010_Cos(short Theta){
return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xFF];
}
0x01 - Unknown Command
I/O |
Address |
Name / Variable |
Input |
$0000 |
integer(X0) |
|
$0002 |
integer(Y0) |
Output |
$0000 |
integer(X1) |
|
$0002 |
integer(Y1) |
|
$0004 |
integer(Quadrant) |
|
$0006 |
integer(Y0) |
|
$0010 |
integer(Theta) |
void ST010_OP01(short X0, short Y0, short& X1, short& Y1, short& Quadrant, short& Theta){
if((X0 < 0) && (Y0 < 0)){
X1 = -X0;
Y1 = -Y0;
Quadrant = -0x8000;
}
else if(X0 < 0){
X1 = Y0;
Y1 = -X0;
Quadrant = -0x4000;
}
else if(Y0 < 0){
X1 = -Y0;
Y1 = X0;
Quadrant = 0x4000;
}
else{
X1 = X0;
Y1 = Y0;
Quadrant = 0x0000;
}
while((X1 > 0x1F) || (Y1 > 0x1F)){
if (X1 > 1) X1 >>= 1;
if (Y1 > 1) Y1 >>= 1;
}
if(Y1 == 0){ Quadrant += 0x4000; }
Theta = (ST010_ArcTan[Y1][X1] << 8) ^ Quadrant;
}
0x02 - Sort Driver Placements
I/O |
Address |
Name / Variable |
Input |
$0024 |
integer(Positions) |
|
$0040 |
integer[32] Places |
|
$0080 |
integer[32] Drivers |
Output |
$0040 |
integer[32] Places |
|
$0080 |
integer[32] Drivers |
void ST010_SortDrivers(short Positions, short Places[32], short Drivers[32]){
bool Sorted;
short Temp;
if(Positions > 1){
do{
Sorted = true;
for(int i = 0; i < Positions - 1; i++){
if(Places[i] < Places[i + 1]){
Temp = Places[i + 1];
Places[i + 1] = Places[i];
Places[i] = Temp;
Temp = Drivers[i + 1];
Drivers[i + 1] = Drivers[i];
Drivers[i] = Temp;
Sorted = false;
}
}
Positions--;
} while (!Sorted);
}
}
0x03 - 2D Coordinate Scale
This OP code has been tested and is thought to be bit perfect in its operation.
I/O |
Address |
Name / Variable |
Input |
$0000 |
integer(X0) |
|
$0002 |
integer(Y0) |
|
$0004 |
integer(Multiplier) |
Output |
$0010 |
double(X1) |
|
$0014 |
double(Y1) |
void ST010_Scale(short Multiplier, short X0, short Y0, int& X1, int& Y1){
X1 = X0 * Multiplier << 1;
Y1 = Y0 * Multiplier << 1;
}
0x04 - Unknown Command
I/O |
Address |
Name / Variable |
Input |
$0000 |
integer(X) |
|
$0002 |
integer(Y) |
Output |
$0010 |
integer(Distance) |
void ST010_Distance(short X0, short Y0, short& Distance){
if(X0 < 0){ X0 = -X0; }
Distance = ((X0 * 0x7AF0) + 0x4000) >> 15;
}
0x05 - Simulated Driver Coordinate Calculation
I/O |
Address |
Name / Variable |
Input |
$00C0 |
integer(MaxX) |
|
$00C2 |
integer(MaxY) |
|
$00C4 |
double(X0) |
|
$00C8 |
double(Y0) |
|
$00CC |
integer(Theta) |
|
$00D4 |
integer(Radius) |
|
$00D6 |
integer(Increment) |
|
$00D8 |
integer(Max Radius) |
|
$00DA |
integer(?) |
|
$00DC |
integer(Flags) |
|
$00DE |
integer(X1) |
|
$00E0 |
integer(Y1) |
0x06 - Multiply
This OP code has been tested and is thought to be bit perfect in its operation.
I/O |
Address |
Name / Variable |
Input |
$0000 |
integer(Multiplicand) |
|
$0002 |
integer(Multiplier) |
Output |
$0010 |
double(Product) |
void ST010_Multiply(short Multiplicand, short Multiplier, int &Product){
Product = Multiplicand * Multiplier << 1;
}
0x07 - Raster Data Calculation
This OP code has been tested and is thought to be bit perfect in its operation.
I/O |
Address |
Name / Variable |
Input |
$0000 |
integer(Theta) |
Output |
$00F0 |
integer[176] |
|
$0250 |
integer[176] |
|
$03B0 |
integer[176] |
|
$0510 |
integer[176] |
const short ST010_M7Scale[176] = {
0x0380, 0x0325, 0x02DA, 0x029C, 0x0268, 0x023B, 0x0215, 0x01F3,
0x01D5, 0x01BB, 0x01A3, 0x018E, 0x017B, 0x016A, 0x015A, 0x014B,
0x013E, 0x0132, 0x0126, 0x011C, 0x0112, 0x0109, 0x0100, 0x00F8,
0x00F0, 0x00E9, 0x00E3, 0x00DC, 0x00D6, 0x00D1, 0x00CB, 0x00C6,
0x00C1, 0x00BD, 0x00B8, 0x00B4, 0x00B0, 0x00AC, 0x00A8, 0x00A5,
0x00A2, 0x009E, 0x009B, 0x0098, 0x0095, 0x0093, 0x0090, 0x008D,
0x008B, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007E, 0x007C,
0x007A, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006F, 0x006E,
0x006C, 0x006B, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063,
0x0062, 0x0060, 0x005F, 0x005E, 0x005D, 0x005C, 0x005B, 0x005A,
0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052,
0x0051, 0x0051, 0x0050, 0x004F, 0x004E, 0x004D, 0x004D, 0x004C,
0x004B, 0x004B, 0x004A, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047,
0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042,
0x0041, 0x0041, 0x0040, 0x0040, 0x003F, 0x003F, 0x003E, 0x003E,
0x003D, 0x003D, 0x003C, 0x003C, 0x003B, 0x003B, 0x003A, 0x003A,
0x003A, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037,
0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034,
0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031,
0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002F, 0x002F,
0x002F, 0x002E, 0x002E, 0x002E, 0x002E, 0x002D, 0x002D, 0x002D,
0x002D, 0x002C, 0x002C, 0x002C, 0x002C, 0x002B, 0x002B, 0x002B};
void ST010_Raster(short Theta){
short data;
int offset = 0;
for(int i = 0; i < 176; i++){
data = ST010_M7Scale[i] * ST010_Cos(Theta) >> 15;
Memory.SRAM[0x00f0 + offset] = data;
Memory.SRAM[0x00f1 + offset] = data >> 8;
Memory.SRAM[0x0510 + offset] = data;
Memory.SRAM[0x0511 + offset] = data >> 8;
data = ST010_M7Scale[i] * ST010_Sin(Theta) >> 15;
Memory.SRAM[0x0250 + offset] = data;
Memory.SRAM[0x0251 + offset] = data >> 8;
if(data){ data = ~data; }
Memory.SRAM[0x03b0 + offset] = data;
Memory.SRAM[0x03b1 + offset] = data >> 8;
offset += 2;
}
}
0x08 - 2D Coordinate Rotation
This OP code has been tested and is thought to be bit perfect in its operation.
I/O |
Address |
Name / Variable |
Input |
$0000 |
integer(X0) |
|
$0002 |
integer(Y0) |
|
$0004 |
integer(Theta) |
Output |
$0010 |
integer(X1) |
|
$0012 |
integer(Y1) |
void ST010_Rotate(short Theta, short X0, short Y0, short& X1, short& Y1){
X1 = (Y0 * ST010_Sin(Theta) >> 15) + (X0 * ST010_Cos(Theta) >> 15);
Y1 = (Y0 * ST010_Cos(Theta) >> 15) - (X0 * ST010_Sin(Theta) >> 15);
}
Information provided by Overload (codeviolation@hotmail.com) / Dr. Decapitator / byuu.