summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Fabio Priuli <etabeta78@users.noreply.github.com>2010-03-22 18:00:22 +0000
committer Fabio Priuli <etabeta78@users.noreply.github.com>2010-03-22 18:00:22 +0000
commit00cf9859782e74ceadd47f1b1cb41fa837a9d287 (patch)
tree15accdd43499a9911c0f62015d5ab58ac53ee5b5
parentef6e27822afc242027df6ea32db31ad7f4fe7aa6 (diff)
snes.c: updated DSP1, DSP2, DSP3, DSP4, OBC1, SRTC and ST010 addon chips to store their variables in struct and to save them [Fabio Priuli]
-rw-r--r--src/mame/machine/snes.c76
-rw-r--r--src/mame/machine/snesdsp1.c2128
-rw-r--r--src/mame/machine/snesdsp2.c368
-rw-r--r--src/mame/machine/snesdsp3.c1192
-rw-r--r--src/mame/machine/snesdsp4.c3843
-rw-r--r--src/mame/machine/snesdsp4.h172
-rw-r--r--src/mame/machine/snesobc1.c54
-rw-r--r--src/mame/machine/snesrtc.c135
-rw-r--r--src/mame/machine/snesst10.c591
9 files changed, 4463 insertions, 4096 deletions
diff --git a/src/mame/machine/snes.c b/src/mame/machine/snes.c
index 761b5419b2c..04b2d5d89b9 100644
--- a/src/mame/machine/snes.c
+++ b/src/mame/machine/snes.c
@@ -365,7 +365,7 @@ READ8_HANDLER( snes_r_io )
{
if (offset == 0x2800 || offset == 0x2801)
{
- return srtc_mmio_read(space->machine, offset);
+ return srtc_read(space->machine, offset);
}
}
else if (snes_has_addon_chip == HAS_SDD1)
@@ -731,7 +731,7 @@ WRITE8_HANDLER( snes_w_io )
{
if (offset == 0x2800 || offset == 0x2801)
{
- srtc_mmio_write(space->machine, offset, data);
+ srtc_write(space->machine, offset, data);
return;
}
}
@@ -1443,9 +1443,9 @@ READ8_HANDLER( snes_r_bank1 )
else if (snes_has_addon_chip == HAS_OBC1)
value = obc1_read(space, offset);
else if ((snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
- value = (address < 0x7000) ? DSP2_read() : 0x00;
+ value = (address < 0x7000) ? dsp2_read() : 0x00;
else if ((snes_cart.mode == SNES_MODE_21) && (snes_has_addon_chip == HAS_DSP1) && (offset < 0x100000))
- value = (address < 0x7000) ? DSP1_getDr() : DSP1_getSr();
+ value = (address < 0x7000) ? dsp1_get_dr() : dsp1_get_sr();
else if (snes_has_addon_chip == HAS_CX4)
value = CX4_read(address - 0x6000);
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
@@ -1459,11 +1459,11 @@ READ8_HANDLER( snes_r_bank1 )
}
}
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
- value = (address < 0xc000) ? DSP1_getDr() : DSP1_getSr();
+ value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
- value = (address < 0xc000) ? DSP2_read() : 0x00;
+ value = (address < 0xc000) ? dsp2_read() : 0x00;
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
- value = DSP3_read(address);
+ value = dsp3_read(address);
else
value = snes_ram[offset];
@@ -1485,7 +1485,7 @@ READ8_HANDLER( snes_r_bank2 )
if (snes_has_addon_chip == HAS_OBC1)
value = obc1_read (space, offset);
else if (snes_has_addon_chip == HAS_DSP2)
- value = (address < 0x7000) ? DSP2_read() : 0x00;
+ value = (address < 0x7000) ? dsp2_read() : 0x00;
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
{
value = snes_ram[0x306000 + (offset & 0x1fff)];
@@ -1504,13 +1504,13 @@ READ8_HANDLER( snes_r_bank2 )
}
/* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1))
- value = (address < 0xc000) ? DSP1_getDr() : DSP1_getSr();
+ value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2))
- value = (address < 0xc000) ? DSP2_read() : 0x00;
+ value = (address < 0xc000) ? dsp2_read() : 0x00;
else if (snes_has_addon_chip == HAS_DSP3)
- value = DSP3_read(address);
+ value = dsp3_read(address);
else if (snes_has_addon_chip == HAS_DSP4)
- value = (address < 0xc000) ? DSP4_read() : 0x80;
+ value = (address < 0xc000) ? dsp4_read() : 0x80;
else
value = snes_ram[0x300000 + offset];
@@ -1565,7 +1565,7 @@ READ8_HANDLER( snes_r_bank4 )
value = snes_ram[0x600000 + offset];
/* some other dsp1 games use these banks 0x60 to 0x6f at address 0x0000 */
else if (snes_has_addon_chip == HAS_DSP1)
- value = (address >= 0x4000) ? DSP1_getSr() : DSP1_getDr();
+ value = (address >= 0x4000) ? dsp1_get_sr() : dsp1_get_dr();
else
{
logerror( "snes_r_bank4: Unmapped external chip read: %04x\n", address );
@@ -1645,13 +1645,13 @@ READ8_HANDLER( snes_r_bank6 )
}
}
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
- value = (address < 0xc000) ? DSP1_getDr() : DSP1_getSr();
+ value = (address < 0xc000) ? dsp1_get_dr() : dsp1_get_sr();
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
- value = (address < 0xc000) ? DSP2_read() : 0x00;
+ value = (address < 0xc000) ? dsp2_read() : 0x00;
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
- value = DSP3_read(address);
+ value = dsp3_read(address);
else if ((snes_has_addon_chip == HAS_DSP4) && (offset >= 0x300000))
- value = (address < 0xc000) ? DSP4_read() : 0x80;
+ value = (address < 0xc000) ? dsp4_read() : 0x80;
else
value = snes_ram[0x800000 + offset];
@@ -1709,9 +1709,9 @@ WRITE8_HANDLER( snes_w_bank1 )
else if (snes_has_addon_chip == HAS_OBC1)
obc1_write(space, offset, data);
else if ((snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000))
- DSP2_write(data);
+ dsp2_write(data);
else if ((snes_cart.mode == SNES_MODE_21) && (snes_has_addon_chip == HAS_DSP1) && (offset < 0x100000))
- DSP1_setDr(data);
+ dsp1_set_dr(data);
else if (snes_has_addon_chip == HAS_CX4)
CX4_write(space->machine, address - 0x6000, data);
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
@@ -1722,11 +1722,11 @@ WRITE8_HANDLER( snes_w_bank1 )
logerror( "snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data );
}
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
- DSP1_setDr(data);
+ dsp1_set_dr(data);
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000) && (address < 0xc000))
- DSP2_write(data);
+ dsp2_write(data);
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
- DSP3_write(address, data);
+ dsp3_write(address, data);
else
logerror( "Attempt to write to ROM address: %X\n", offset );
}
@@ -1745,7 +1745,7 @@ WRITE8_HANDLER( snes_w_bank2 )
if (snes_has_addon_chip == HAS_OBC1)
obc1_write(space, offset, data);
else if (snes_has_addon_chip == HAS_DSP2)
- DSP2_write(data);
+ dsp2_write(data);
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
{
snes_ram[0x306000 + (offset & 0x1fff)] = data;
@@ -1762,13 +1762,13 @@ WRITE8_HANDLER( snes_w_bank2 )
}
/* some dsp1 games use these banks 0x30 to 0x3f at address 0x8000 */
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1))
- DSP1_setDr(data);
+ dsp1_set_dr(data);
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (address < 0xc000))
- DSP2_write(data);
+ dsp2_write(data);
else if (snes_has_addon_chip == HAS_DSP3)
- DSP3_write(address, data);
+ dsp3_write(address, data);
else if ((snes_has_addon_chip == HAS_DSP4) && (address < 0xc000))
- DSP4_write(data);
+ dsp4_write(data);
else
logerror("Attempt to write to ROM address: %X\n", offset + 0x300000);
}
@@ -1795,7 +1795,7 @@ WRITE8_HANDLER( snes_w_bank4 )
}
else if (snes_has_addon_chip == HAS_DSP1)
{
- DSP1_setDr(data);
+ dsp1_set_dr(data);
}
else
{
@@ -1880,13 +1880,13 @@ WRITE8_HANDLER( snes_w_bank6 )
}
}
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP1) && (offset >= 0x200000))
- DSP1_setDr(data);
+ dsp1_set_dr(data);
else if ((snes_cart.mode == SNES_MODE_20) && (snes_has_addon_chip == HAS_DSP2) && (offset >= 0x200000) && (address < 0xc000))
- DSP2_write(data);
+ dsp2_write(data);
else if ((snes_has_addon_chip == HAS_DSP3) && (offset >= 0x200000))
- DSP3_write(address, data);
+ dsp3_write(address, data);
else if ((snes_has_addon_chip == HAS_DSP4) && (offset >= 0x300000) && (address < 0xc000))
- DSP4_write(data);
+ dsp4_write(data);
else if (snes_has_addon_chip == HAS_SUPERFX && state->superfx != NULL)
logerror( "snes_w_bank6 hit (ROM) in Super FX mode, please fix me\n" );
else
@@ -2103,23 +2103,23 @@ static void snes_init_ram( running_machine *machine )
switch (snes_has_addon_chip)
{
case HAS_DSP1:
- DSP1_reset(machine);
+ dsp1_init(machine);
break;
case HAS_DSP2:
- DSP2_reset();
+ dsp2_init(machine);
break;
case HAS_DSP3:
- InitDSP3(machine);
+ dsp3_init(machine);
break;
case HAS_DSP4:
- InitDSP4();
+ dsp4_init(machine);
break;
case HAS_RTC:
- srtc_reset(machine);
+ srtc_init(machine);
break;
case HAS_SDD1:
@@ -2127,7 +2127,7 @@ static void snes_init_ram( running_machine *machine )
break;
case HAS_OBC1:
- obc1_init();
+ obc1_init(machine);
break;
case HAS_ST010:
diff --git a/src/mame/machine/snesdsp1.c b/src/mame/machine/snesdsp1.c
index 3680bf32bbc..31c89917827 100644
--- a/src/mame/machine/snesdsp1.c
+++ b/src/mame/machine/snesdsp1.c
@@ -12,34 +12,70 @@
***************************************************************************/
-#define DSP1_VERSION 0x0102
+#define dsp1_VERSION 0x0102
// The DSP-1 status register has 16 bits, but only
// the upper 8 bits can be accessed from an external device, so all these
// positions are referred to the upper byte (bits D8 to D15)
-enum SrFlags {DRC=0x04, DRS=0x10, RQM=0x80};
+enum SrFlags { DRC = 0x04, DRS = 0x10, RQM = 0x80 };
// According to Overload's docs, these are the meanings of the flags:
// DRC: The Data Register Control (DRC) bit specifies the data transfer length to and from the host CPU.
-// 0: Data transfer to and from the DSP-1 is 16 bits.
-// 1: Data transfer to and from the DSP-1 is 8 bits.
+// 0: Data transfer to and from the DSP-1 is 16 bits.
+// 1: Data transfer to and from the DSP-1 is 8 bits.
// DRS: The Data Register Status (DRS) bit indicates the data transfer status in the case of transfering 16-bit data.
-// 0: Data transfer has terminated.
-// 1: Data transfer in progress.
+// 0: Data transfer has terminated.
+// 1: Data transfer in progress.
// RQM: The Request for Master (RQM) indicates that the DSP1 is requesting host CPU for data read/write.
-// 0: Internal Data Register Transfer.
-// 1: External Data Register Transfer.
+// 0: Internal Data Register Transfer.
+// 1: External Data Register Transfer.
-enum FsmMajorState {WAIT_COMMAND, READ_DATA, WRITE_DATA};
-enum MaxDataAccesses {MAX_READS=7, MAX_WRITES=1024};
+enum Fsm_Major_State { WAIT_COMMAND, READ_DATA, WRITE_DATA };
+enum Max_Data_Accesses { MAX_READS = 7, MAX_WRITES = 1024 };
-struct DSP1_Command {
- void (*callback)(INT16 *, INT16 *);
- unsigned int reads;
- unsigned int writes;
+struct dsp1_Command
+{
+ void (*callback)(INT16 *, INT16 *);
+ unsigned int reads;
+ unsigned int writes;
};
+struct SharedData
+{
+ // some RAM variables shared between commands
+ INT16 MatrixA[3][3]; // attitude matrix A
+ INT16 MatrixB[3][3];
+ INT16 MatrixC[3][3];
+ INT16 CentreX, CentreY, CentreZ; // center of projection
+ INT16 CentreZ_C, CentreZ_E;
+ INT16 VOffset; // vertical offset of the screen with regard to the centre of projection
+ INT16 Les, C_Les, E_Les;
+ INT16 SinAas, CosAas;
+ INT16 SinAzs, CosAzs;
+ INT16 SinAZS, CosAZS;
+ INT16 SecAZS_C1, SecAZS_E1;
+ INT16 SecAZS_C2, SecAZS_E2;
+ INT16 Nx, Ny, Nz; // normal vector to the screen (norm 1, points toward the center of projection)
+ INT16 Gx, Gy, Gz; // center of the screen (global coordinates)
+ INT16 Hx, Hy; // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen)
+ INT16 Vx, Vy, Vz; // vertical vector of the screen (norm 1, points toward the top of the screen)
+};
+
+struct _snes_dsp1_state
+{
+ SharedData shared;
+ UINT8 Sr; // status register
+ int SrLowByteAccess;
+ UINT16 Dr; // "internal" representation of the data register
+ Fsm_Major_State FsmMajorState; // current major state of the FSM
+ UINT8 Command; // current command processed by the FSM
+ UINT8 DataCounter; // #UINT16 read/writes counter used by the FSM
+ INT16 ReadBuffer[MAX_READS];
+ INT16 WriteBuffer[MAX_WRITES];
+ UINT8 Freeze; // need explanation? ;)
+
+
//////////////////////////////////////////////////////////////////
@@ -54,166 +90,145 @@ struct DSP1_Command {
// 257-points arccos table that, apparently, have been not used anywhere
// (maybe for the MaxAZS_Exp table?).
-static UINT16 DSP1_DataRom[1024];
-
-static struct SharedData { // some RAM variables shared between commands
- INT16 MatrixA[3][3]; // attitude matrix A
- INT16 MatrixB[3][3];
- INT16 MatrixC[3][3];
- INT16 CentreX, CentreY, CentreZ; // center of projection
- INT16 CentreZ_C, CentreZ_E;
- INT16 VOffset; // vertical offset of the screen with regard to the centre of projection
- INT16 Les, C_Les, E_Les;
- INT16 SinAas, CosAas;
- INT16 SinAzs, CosAzs;
- INT16 SinAZS, CosAZS;
- INT16 SecAZS_C1, SecAZS_E1;
- INT16 SecAZS_C2, SecAZS_E2;
- INT16 Nx, Ny, Nz; // normal vector to the screen (norm 1, points toward the center of projection)
- INT16 Gx, Gy, Gz; // center of the screen (global coordinates)
- INT16 Hx, Hy; // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen)
- INT16 Vx, Vy, Vz; // vertical vector of the screen (norm 1, points toward the top of the screen)
-
-} shared;
-
-static UINT8 mSr; // status register
-static int mSrLowByteAccess;
-static UINT16 mDr; // "internal" representation of the data register
-static enum FsmMajorState mFsmMajorState; // current major state of the FSM
-static UINT8 mCommand; // current command processed by the FSM
-static UINT8 mDataCounter; // #UINT16 read/writes counter used by the FSM
-static INT16 mReadBuffer[MAX_READS];
-static INT16 mWriteBuffer[MAX_WRITES];
-static UINT8 mFreeze; // need explanation? ;)
-
-static void DSP1_fsmStep(UINT8 read, UINT8 *data); // FSM logic
+ UINT16 DataRom[1024];
+};
+
+static struct _snes_dsp1_state dsp1_state;
+
+
+/* Prototypes */
+
+static void dsp1_fsm_step(UINT8 read, UINT8 *data); // FSM logic
// commands
-static void DSP1_memoryTest(INT16 *input, INT16 *output);
-static void DSP1_memoryDump(INT16 *input, INT16 *output);
-static void DSP1_memorySize(INT16 *input, INT16 *output);
-static void DSP1_multiply(INT16* input, INT16* output);
-static void DSP1_multiply2(INT16* input, INT16* output);
-static void DSP1_inverse(INT16 *input, INT16 *output);
-static void DSP1_triangle(INT16 *input, INT16 *output);
-static void DSP1_radius(INT16 *input, INT16 *output);
-static void DSP1_range(INT16 *input, INT16 *output);
-static void DSP1_range2(INT16 *input, INT16 *output);
-static void DSP1_distance(INT16 *input, INT16 *output);
-static void DSP1_rotate(INT16 *input, INT16 *output);
-static void DSP1_polar(INT16 *input, INT16 *output);
-static void DSP1_attitudeA(INT16 *input, INT16 *output);
-static void DSP1_attitudeB(INT16 *input, INT16 *output);
-static void DSP1_attitudeC(INT16 *input, INT16 *output);
-static void DSP1_objectiveA(INT16 *input, INT16 *output);
-static void DSP1_objectiveB(INT16 *input, INT16 *output);
-static void DSP1_objectiveC(INT16 *input, INT16 *output);
-static void DSP1_subjectiveA(INT16 *input, INT16 *output);
-static void DSP1_subjectiveB(INT16 *input, INT16 *output);
-static void DSP1_subjectiveC(INT16 *input, INT16 *output);
-static void DSP1_scalarA(INT16 *input, INT16 *output);
-static void DSP1_scalarB(INT16 *input, INT16 *output);
-static void DSP1_scalarC(INT16 *input, INT16 *output);
-static void DSP1_gyrate(INT16 *input, INT16 *output);
-static void DSP1_parameter(INT16 *input, INT16 *output);
-static void DSP1_raster(INT16 *input, INT16 *output);
-static void DSP1_target(INT16 *input, INT16 *output);
-static void DSP1_project(INT16 *input, INT16 *output);
+static void dsp1_memory_test(INT16 *input, INT16 *output);
+static void dsp1_memory_dump(INT16 *input, INT16 *output);
+static void dsp1_memory_size(INT16 *input, INT16 *output);
+static void dsp1_multiply(INT16* input, INT16* output);
+static void dsp1_multiply2(INT16* input, INT16* output);
+static void dsp1_inverse(INT16 *input, INT16 *output);
+static void dsp1_triangle(INT16 *input, INT16 *output);
+static void dsp1_radius(INT16 *input, INT16 *output);
+static void dsp1_range(INT16 *input, INT16 *output);
+static void dsp1_range2(INT16 *input, INT16 *output);
+static void dsp1_distance(INT16 *input, INT16 *output);
+static void dsp1_rotate(INT16 *input, INT16 *output);
+static void dsp1_polar(INT16 *input, INT16 *output);
+static void dsp1_attitudeA(INT16 *input, INT16 *output);
+static void dsp1_attitudeB(INT16 *input, INT16 *output);
+static void dsp1_attitudeC(INT16 *input, INT16 *output);
+static void dsp1_objectiveA(INT16 *input, INT16 *output);
+static void dsp1_objectiveB(INT16 *input, INT16 *output);
+static void dsp1_objectiveC(INT16 *input, INT16 *output);
+static void dsp1_subjectiveA(INT16 *input, INT16 *output);
+static void dsp1_subjectiveB(INT16 *input, INT16 *output);
+static void dsp1_subjectiveC(INT16 *input, INT16 *output);
+static void dsp1_scalarA(INT16 *input, INT16 *output);
+static void dsp1_scalarB(INT16 *input, INT16 *output);
+static void dsp1_scalarC(INT16 *input, INT16 *output);
+static void dsp1_gyrate(INT16 *input, INT16 *output);
+static void dsp1_parameter(INT16 *input, INT16 *output);
+static void dsp1_raster(INT16 *input, INT16 *output);
+static void dsp1_target(INT16 *input, INT16 *output);
+static void dsp1_project(INT16 *input, INT16 *output);
// auxiliar functions
-static INT16 DSP1_sin(INT16 Angle);
-static INT16 DSP1_cos(INT16 Angle);
+static INT16 dsp1_sin(INT16 Angle);
+static INT16 dsp1_cos(INT16 Angle);
static void inverse(INT16 Coefficient, INT16 Exponent, INT16 *iCoefficient, INT16 *iExponent);
-static INT16 denormalizeAndClip(INT16 C, INT16 E);
+static INT16 denormalize_and_clip(INT16 C, INT16 E);
static void normalize(INT16 m, INT16 *Coefficient, INT16 *Exponent);
-static void normalizeDouble(INT32 Product, INT16 *Coefficient, INT16 *Exponent);
+static void normalize_double(INT32 Product, INT16 *Coefficient, INT16 *Exponent);
static INT16 shiftR(INT16 C, INT16 E);
+// register saves
+static void dsp1_register_save(running_machine *machine);
+
//////////////////////////////////////////////////////////////////
// The info on this table follows Overload's docs.
-static const struct DSP1_Command mCommandTable[0x40] =
+static const struct dsp1_Command mCommandTable[0x40] =
{
- {&DSP1_multiply, 2, 1}, //0x00
- {&DSP1_attitudeA, 4, 0}, //0x01
- {&DSP1_parameter, 7, 4}, //0x02
- {&DSP1_subjectiveA, 3, 3}, //0x03
- {&DSP1_triangle, 2, 2}, //0x04
- {&DSP1_attitudeA, 4, 0}, //0x01
- {&DSP1_project, 3, 3}, //0x06
- {&DSP1_memoryTest, 1, 1}, //0x0f
- {&DSP1_radius, 3, 2}, //0x08
- {&DSP1_objectiveA, 3, 3}, //0x0d
- {&DSP1_raster, 1, 4}, // 0x0a. This will normally work in continuous mode
- {&DSP1_scalarA, 3, 1}, //0x0b
- {&DSP1_rotate, 3, 2}, //0x0c
- {&DSP1_objectiveA, 3, 3}, //0x0d
- {&DSP1_target, 2, 2}, //0x0e
- {&DSP1_memoryTest, 1, 1}, //0x0f
-
- {&DSP1_inverse, 2, 2}, //0x10
- {&DSP1_attitudeB, 4, 0}, //0x11
- {&DSP1_parameter, 7, 4}, //0x02
- {&DSP1_subjectiveB, 3, 3}, //0x13
- {&DSP1_gyrate, 6, 3}, //0x14
- {&DSP1_attitudeB, 4, 0}, //0x11
- {&DSP1_project, 3, 3}, //0x06
- {&DSP1_memoryDump, 1, 1024}, //0x1f
- {&DSP1_range, 4, 1}, //0x18
- {&DSP1_objectiveB, 3, 3}, //0x1d
- {0, 0, 0}, // 0x1a; the chip freezes
- {&DSP1_scalarB, 3, 1}, //0x1b
- {&DSP1_polar, 6, 3}, //0x1c
- {&DSP1_objectiveB, 3, 3}, //0x1d
- {&DSP1_target, 2, 2}, //0x0e
- {&DSP1_memoryDump, 1, 1024}, //0x1f
-
- {&DSP1_multiply2, 2, 1}, //0x20
- {&DSP1_attitudeC, 4, 0}, //0x21
- {&DSP1_parameter, 7, 4}, //0x02
- {&DSP1_subjectiveC, 3, 3}, //0x23
- {&DSP1_triangle, 2, 2}, //0x04
- {&DSP1_attitudeC, 4, 0}, //0x21
- {&DSP1_project, 3, 3}, //0x06
- {&DSP1_memorySize, 1, 1}, //0x2f
- {&DSP1_distance, 3, 1}, //0x28
- {&DSP1_objectiveC, 3, 3}, //0x2d
- {0, 0, 0}, // 0x1a; the chip freezes
- {&DSP1_scalarC, 3, 1}, //0x2b
- {&DSP1_rotate, 3, 2}, //0x0c
- {&DSP1_objectiveC, 3, 3}, //0x2d
- {&DSP1_target, 2, 2}, //0x0e
- {&DSP1_memorySize, 1, 1}, //0x2f
-
- {&DSP1_inverse, 2, 2}, //0x10
- {&DSP1_attitudeA, 4, 0}, //0x01
- {&DSP1_parameter, 7, 4}, //0x02
- {&DSP1_subjectiveA, 3, 3}, //0x03
- {&DSP1_gyrate, 6, 3}, //0x14
- {&DSP1_attitudeA, 4, 0}, //0x01
- {&DSP1_project, 3, 3}, //0x06
- {&DSP1_memoryDump, 1, 1024}, //0x1f
- {&DSP1_range2, 4, 1}, //0x38
- {&DSP1_objectiveA, 3, 3}, //0x0d
- {0, 0, 0}, // 0x1a; the chip freezes
- {&DSP1_scalarA, 3, 1}, //0x0b
- {&DSP1_polar, 6, 3}, //0x1c
- {&DSP1_objectiveA, 3, 3}, //0x0d
- {&DSP1_target, 2, 2}, //0x0e
- {&DSP1_memoryDump, 1, 1024}, //0x1f
+ {&dsp1_multiply, 2, 1}, //0x00
+ {&dsp1_attitudeA, 4, 0}, //0x01
+ {&dsp1_parameter, 7, 4}, //0x02
+ {&dsp1_subjectiveA, 3, 3}, //0x03
+ {&dsp1_triangle, 2, 2}, //0x04
+ {&dsp1_attitudeA, 4, 0}, //0x01
+ {&dsp1_project, 3, 3}, //0x06
+ {&dsp1_memory_test, 1, 1}, //0x0f
+ {&dsp1_radius, 3, 2}, //0x08
+ {&dsp1_objectiveA, 3, 3}, //0x0d
+ {&dsp1_raster, 1, 4}, // 0x0a. This will normally work in continuous mode
+ {&dsp1_scalarA, 3, 1}, //0x0b
+ {&dsp1_rotate, 3, 2}, //0x0c
+ {&dsp1_objectiveA, 3, 3}, //0x0d
+ {&dsp1_target, 2, 2}, //0x0e
+ {&dsp1_memory_test, 1, 1}, //0x0f
+
+ {&dsp1_inverse, 2, 2}, //0x10
+ {&dsp1_attitudeB, 4, 0}, //0x11
+ {&dsp1_parameter, 7, 4}, //0x02
+ {&dsp1_subjectiveB, 3, 3}, //0x13
+ {&dsp1_gyrate, 6, 3}, //0x14
+ {&dsp1_attitudeB, 4, 0}, //0x11
+ {&dsp1_project, 3, 3}, //0x06
+ {&dsp1_memory_dump, 1, 1024}, //0x1f
+ {&dsp1_range, 4, 1}, //0x18
+ {&dsp1_objectiveB, 3, 3}, //0x1d
+ {0, 0, 0}, // 0x1a; the chip freezes
+ {&dsp1_scalarB, 3, 1}, //0x1b
+ {&dsp1_polar, 6, 3}, //0x1c
+ {&dsp1_objectiveB, 3, 3}, //0x1d
+ {&dsp1_target, 2, 2}, //0x0e
+ {&dsp1_memory_dump, 1, 1024}, //0x1f
+
+ {&dsp1_multiply2, 2, 1}, //0x20
+ {&dsp1_attitudeC, 4, 0}, //0x21
+ {&dsp1_parameter, 7, 4}, //0x02
+ {&dsp1_subjectiveC, 3, 3}, //0x23
+ {&dsp1_triangle, 2, 2}, //0x04
+ {&dsp1_attitudeC, 4, 0}, //0x21
+ {&dsp1_project, 3, 3}, //0x06
+ {&dsp1_memory_size, 1, 1}, //0x2f
+ {&dsp1_distance, 3, 1}, //0x28
+ {&dsp1_objectiveC, 3, 3}, //0x2d
+ {0, 0, 0}, // 0x1a; the chip freezes
+ {&dsp1_scalarC, 3, 1}, //0x2b
+ {&dsp1_rotate, 3, 2}, //0x0c
+ {&dsp1_objectiveC, 3, 3}, //0x2d
+ {&dsp1_target, 2, 2}, //0x0e
+ {&dsp1_memory_size, 1, 1}, //0x2f
+
+ {&dsp1_inverse, 2, 2}, //0x10
+ {&dsp1_attitudeA, 4, 0}, //0x01
+ {&dsp1_parameter, 7, 4}, //0x02
+ {&dsp1_subjectiveA, 3, 3}, //0x03
+ {&dsp1_gyrate, 6, 3}, //0x14
+ {&dsp1_attitudeA, 4, 0}, //0x01
+ {&dsp1_project, 3, 3}, //0x06
+ {&dsp1_memory_dump, 1, 1024}, //0x1f
+ {&dsp1_range2, 4, 1}, //0x38
+ {&dsp1_objectiveA, 3, 3}, //0x0d
+ {0, 0, 0}, // 0x1a; the chip freezes
+ {&dsp1_scalarA, 3, 1}, //0x0b
+ {&dsp1_polar, 6, 3}, //0x1c
+ {&dsp1_objectiveA, 3, 3}, //0x0d
+ {&dsp1_target, 2, 2}, //0x0e
+ {&dsp1_memory_dump, 1, 1024}, //0x1f
};
//////////////////////////////////////////////////////////////////
-static const INT16 DSP1_MaxAZS_Exp[16] = {
+static const INT16 dsp1_MaxAZS_Exp[16] = {
0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca,
0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4
};
//////////////////////////////////////////////////////////////////
-static const INT16 DSP1_SinTable[256] = {
+static const INT16 dsp1_sin_table[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,
@@ -250,7 +265,7 @@ static const INT16 DSP1_SinTable[256] = {
//////////////////////////////////////////////////////////////////
// Optimised for Performance
-static const INT16 DSP1_MulTable[256] = {
+static const INT16 dsp1_mul_table[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,
@@ -286,55 +301,54 @@ static const INT16 DSP1_MulTable[256] = {
//////////////////////////////////////////////////////////////////
-static UINT8 DSP1_getSr(void)
+static UINT8 dsp1_get_sr( void )
{
- mSrLowByteAccess = ~mSrLowByteAccess;
- if (mSrLowByteAccess)
- {
- return 0;
- }
- else
- {
- return mSr;
- }
+ dsp1_state.SrLowByteAccess = ~dsp1_state.SrLowByteAccess;
+
+ if (dsp1_state.SrLowByteAccess)
+ return 0;
+ else
+ return dsp1_state.Sr;
}
//////////////////////////////////////////////////////////////////
-static UINT8 DSP1_getDr(void)
+static UINT8 dsp1_get_dr( void )
{
- UINT8 oDr;
+ UINT8 oDr;
- DSP1_fsmStep(1, &oDr);
- return oDr;
+ dsp1_fsm_step(1, &oDr);
+ return oDr;
}
//////////////////////////////////////////////////////////////////
-static void DSP1_setDr(UINT8 iDr)
+static void dsp1_set_dr( UINT8 iDr )
{
- DSP1_fsmStep(0, &iDr);
+ dsp1_fsm_step(0, &iDr);
}
//////////////////////////////////////////////////////////////////
-static void DSP1_reset(running_machine *machine)
+static void dsp1_init( running_machine *machine )
{
UINT32 i;
UINT8 *dspin = memory_region(machine, "addons");
- mSr = DRC|RQM;
- mSrLowByteAccess = FALSE;
- mDr = 0x0080; // Only a supposition. Is this correct?
- mFreeze = FALSE;
- mFsmMajorState = WAIT_COMMAND;
- memset(&shared, 0, sizeof(struct SharedData)); // another supposition
+ dsp1_state.Sr = DRC|RQM;
+ dsp1_state.SrLowByteAccess = FALSE;
+ dsp1_state.Dr = 0x0080; // Only a supposition. Is this correct?
+ dsp1_state.Freeze = FALSE;
+ dsp1_state.FsmMajorState = WAIT_COMMAND;
+ memset(&dsp1_state.shared, 0, sizeof(struct SharedData)); // another supposition
// expand the DSP-1 data ROM
- for (i = 0; i < 2048; i+=2)
+ for (i = 0; i < 2048; i += 2)
{
- DSP1_DataRom[i/2] = dspin[i]<<8 | dspin[i+1];
+ dsp1_state.DataRom[i / 2] = (dspin[i] << 8) | dspin[i + 1];
}
+
+ dsp1_register_save(machine);
}
//////////////////////////////////////////////////////////////////
@@ -344,183 +358,188 @@ static void DSP1_reset(running_machine *machine)
// is responsible for maintaining the binding between the
// "external" and "internal" representations of the DR (data register).
-static void DSP1_fsmStep(UINT8 read, UINT8 *data)
+static void dsp1_fsm_step( UINT8 read, UINT8 *data )
{
- if (0 == (mSr&RQM)) return;
- // Now RQM would be cleared; however, as this code is not to be used in
- // a multithread environment, we will simply fake RQM operation.
- // (The only exception would be Op1A's freeze.)
-
- // binding
- if (read)
- {
- if (mSr&DRS)
- *data = (UINT8)(mDr>>8);
- else
- *data = (UINT8)(mDr);
- }
- else
- {
- if (mSr&DRS)
- {
- mDr &= 0x00ff;
- mDr |= *data<<8;
- }
- else
- {
- mDr &= 0xff00;
- mDr |= *data;
- }
- }
-
-
- switch (mFsmMajorState)
- {
- case WAIT_COMMAND:
- mCommand = (UINT8)(mDr);
- if (!(mCommand & 0xc0)) // valid command?
- {
- switch(mCommand)
- {
- // freeze cases
- case 0x1a:
- case 0x2a:
- case 0x3a:
- mFreeze = TRUE;
- break;
- // normal cases
- default:
- mDataCounter=0;
- mFsmMajorState = READ_DATA;
- mSr &= ~DRC;
- break;
- }
- }
- break;
- case READ_DATA:
- mSr ^= DRS;
- if (!(mSr&DRS))
- {
- mReadBuffer[mDataCounter++] = (INT16)(mDr);
- if (mDataCounter >= mCommandTable[mCommand].reads)
- {
- (*mCommandTable[mCommand].callback)(mReadBuffer, mWriteBuffer);
- if (0 != mCommandTable[mCommand].writes) // any output?
- {
- mDataCounter = 0;
- mDr = (UINT16)(mWriteBuffer[mDataCounter]);
- mFsmMajorState = WRITE_DATA;
- }
- else
- {
- mDr = 0x0080; // valid command completion
- mFsmMajorState = WAIT_COMMAND;
- mSr |= DRC;
- }
- }
- }
- break;
- case WRITE_DATA:
- mSr ^= DRS;
- if (!(mSr&DRS))
- {
- ++mDataCounter;
- if (mDataCounter >= mCommandTable[mCommand].writes)
- {
- if ((mCommand == 0x0a)&&(mDr != 0x8000))
- {
- // works in continuous mode
- mReadBuffer[0]++; // next raster line
- (*mCommandTable[mCommand].callback)(mReadBuffer, mWriteBuffer);
- mDataCounter = 0;
- mDr = (UINT16)(mWriteBuffer[mDataCounter]);
- }
- else
- {
- mDr = 0x0080; // valid command completion
- mFsmMajorState = WAIT_COMMAND;
- mSr |= DRC;
- }
- }
- else
- {
- mDr = (UINT16)(mWriteBuffer[mDataCounter]);
- }
- }
- break;
- }
-
-
-
- // Now RQM would be set (except when executing Op1A -command equals 0x1a, 0x2a or 0x3a-).
- if (mFreeze)
- mSr &= ~RQM;
+ if (0 == (dsp1_state.Sr & RQM))
+ return;
+
+ // Now RQM would be cleared; however, as this code is not to be used in
+ // a multithread environment, we will simply fake RQM operation.
+ // (The only exception would be Op1A's freeze.)
+
+ // binding
+ if (read)
+ {
+ if (dsp1_state.Sr & DRS)
+ *data = (UINT8)(dsp1_state.Dr >> 8);
+ else
+ *data = (UINT8)(dsp1_state.Dr);
+ }
+ else
+ {
+ if (dsp1_state.Sr & DRS)
+ {
+ dsp1_state.Dr &= 0x00ff;
+ dsp1_state.Dr |= *data << 8;
+ }
+ else
+ {
+ dsp1_state.Dr &= 0xff00;
+ dsp1_state.Dr |= *data;
+ }
+ }
+
+
+ switch (dsp1_state.FsmMajorState)
+ {
+ case WAIT_COMMAND:
+ dsp1_state.Command = (UINT8)(dsp1_state.Dr);
+ if (!(dsp1_state.Command & 0xc0)) // valid command?
+ {
+ switch(dsp1_state.Command)
+ {
+ // freeze cases
+ case 0x1a:
+ case 0x2a:
+ case 0x3a:
+ dsp1_state.Freeze = TRUE;
+ break;
+
+ // normal cases
+ default:
+ dsp1_state.DataCounter = 0;
+ dsp1_state.FsmMajorState = READ_DATA;
+ dsp1_state.Sr &= ~DRC;
+ break;
+ }
+ }
+ break;
+
+ case READ_DATA:
+ dsp1_state.Sr ^= DRS;
+ if (!(dsp1_state.Sr & DRS))
+ {
+ dsp1_state.ReadBuffer[dsp1_state.DataCounter++] = (INT16)(dsp1_state.Dr);
+ if (dsp1_state.DataCounter >= mCommandTable[dsp1_state.Command].reads)
+ {
+ (*mCommandTable[dsp1_state.Command].callback)(dsp1_state.ReadBuffer, dsp1_state.WriteBuffer);
+ if (0 != mCommandTable[dsp1_state.Command].writes) // any output?
+ {
+ dsp1_state.DataCounter = 0;
+ dsp1_state.Dr = (UINT16)(dsp1_state.WriteBuffer[dsp1_state.DataCounter]);
+ dsp1_state.FsmMajorState = WRITE_DATA;
+ }
+ else
+ {
+ dsp1_state.Dr = 0x0080; // valid command completion
+ dsp1_state.FsmMajorState = WAIT_COMMAND;
+ dsp1_state.Sr |= DRC;
+ }
+ }
+ }
+ break;
+
+ case WRITE_DATA:
+ dsp1_state.Sr ^= DRS;
+ if (!(dsp1_state.Sr & DRS))
+ {
+ ++dsp1_state.DataCounter;
+ if (dsp1_state.DataCounter >= mCommandTable[dsp1_state.Command].writes)
+ {
+ if ((dsp1_state.Command == 0x0a) && (dsp1_state.Dr != 0x8000))
+ {
+ // works in continuous mode
+ dsp1_state.ReadBuffer[0]++; // next raster line
+ (*mCommandTable[dsp1_state.Command].callback)(dsp1_state.ReadBuffer, dsp1_state.WriteBuffer);
+ dsp1_state.DataCounter = 0;
+ dsp1_state.Dr = (UINT16)(dsp1_state.WriteBuffer[dsp1_state.DataCounter]);
+ }
+ else
+ {
+ dsp1_state.Dr = 0x0080; // valid command completion
+ dsp1_state.FsmMajorState = WAIT_COMMAND;
+ dsp1_state.Sr |= DRC;
+ }
+ }
+ else
+ {
+ dsp1_state.Dr = (UINT16)(dsp1_state.WriteBuffer[dsp1_state.DataCounter]);
+ }
+ }
+ break;
+ }
+
+
+
+ // Now RQM would be set (except when executing Op1A -command equals 0x1a, 0x2a or 0x3a-).
+ if (dsp1_state.Freeze)
+ dsp1_state.Sr &= ~RQM;
}
//////////////////////////////////////////////////////////////////
-static void DSP1_memoryTest(INT16 *input, INT16 *output)
+static void dsp1_memory_test( INT16 *input, INT16 *output )
{
-// INT16 *Size = &input[0];
- INT16 *Result = &output[0];
+// INT16 *Size = &input[0];
+ INT16 *Result = &output[0];
- *Result = 0x0000;
+ *Result = 0x0000;
}
//////////////////////////////////////////////////////////////////
-static void DSP1_memoryDump(INT16 *input, INT16 *output)
+static void dsp1_memory_dump( INT16 *input, INT16 *output )
{
- memcpy(output, DSP1_DataRom, 1024);
+ memcpy(output, dsp1_state.DataRom, 1024);
}
//////////////////////////////////////////////////////////////////
-static void DSP1_memorySize(INT16 *input, INT16 *output)
+static void dsp1_memory_size( INT16 *input, INT16 *output )
{
- INT16* Size = &output[0];
+ INT16* Size = &output[0];
- *Size = 0x0100;
+ *Size = 0x0100;
}
//////////////////////////////////////////////////////////////////
// 16-bit multiplication
-static void DSP1_multiply(INT16 *input, INT16 *output)
+static void dsp1_multiply( INT16 *input, INT16 *output )
{
- INT16 Multiplicand = input[0];
- INT16 Multiplier = input[1];
- INT16* Product = &output[0];
+ INT16 Multiplicand = input[0];
+ INT16 Multiplier = input[1];
+ INT16* Product = &output[0];
- *Product = Multiplicand * Multiplier >> 15;
+ *Product = Multiplicand * Multiplier >> 15;
}
//////////////////////////////////////////////////////////////////
// 16-bit multiplication. 'Alternative' method. Can anyone check this carefully?
-static void DSP1_multiply2(INT16 *input, INT16 *output)
+static void dsp1_multiply2( INT16 *input, INT16 *output )
{
- INT16 Multiplicand = input[0];
- INT16 Multiplier = input[1];
- INT16* Product = &output[0];
+ INT16 Multiplicand = input[0];
+ INT16 Multiplier = input[1];
+ INT16* Product = &output[0];
- *Product = (Multiplicand * Multiplier >> 15)+1;
+ *Product = (Multiplicand * Multiplier >> 15) + 1;
}
//////////////////////////////////////////////////////////////////
// This command determines the inverse of a floating point decimal number.
-static void DSP1_inverse(INT16 *input, INT16 *output)
+static void dsp1_inverse( INT16 *input, INT16 *output )
{
- INT16 Coefficient = input[0];
- INT16 Exponent = input[1];
- INT16* iCoefficient = &output[0];
- INT16* iExponent = &output[1];
+ INT16 Coefficient = input[0];
+ INT16 Exponent = input[1];
+ INT16* iCoefficient = &output[0];
+ INT16* iExponent = &output[1];
- inverse(Coefficient, Exponent, iCoefficient, iExponent);
+ inverse(Coefficient, Exponent, iCoefficient, iExponent);
}
//////////////////////////////////////////////////////////////////
@@ -530,15 +549,15 @@ static void DSP1_inverse(INT16 *input, INT16 *output)
// Y = Radius * sin(Angle)
// X = Radius * cos(Angle)
-static void DSP1_triangle(INT16 *input, INT16 *output)
+static void dsp1_triangle( INT16 *input, INT16 *output )
{
- INT16 Angle = input[0];
- INT16 Radius = input[1];
- INT16* Y = &output[0];
- INT16* X = &output[1];
+ INT16 Angle = input[0];
+ INT16 Radius = input[1];
+ INT16* Y = &output[0];
+ INT16* X = &output[1];
- *Y = DSP1_sin(Angle) * Radius >> 15;
- *X = DSP1_cos(Angle) * Radius >> 15;
+ *Y = dsp1_sin(Angle) * Radius >> 15;
+ *X = dsp1_cos(Angle) * Radius >> 15;
}
//////////////////////////////////////////////////////////////////
@@ -546,19 +565,19 @@ static void DSP1_triangle(INT16 *input, INT16 *output)
// Determines the squared norm of a vector (X,Y,Z)
// The output is Radius = X^2+Y^2+Z^2 (double integer)
-static void DSP1_radius(INT16 *input, INT16 *output)
+static void dsp1_radius( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* RadiusLow = &output[0];
- INT16* RadiusHigh = &output[1];
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* RadiusLow = &output[0];
+ INT16* RadiusHigh = &output[1];
- INT32 Radius;
+ INT32 Radius;
- Radius = (X * X + Y * Y + Z * Z) << 1;
- *RadiusLow = (INT16)(Radius);
- *RadiusHigh = (INT16)(Radius>>16);
+ Radius = (X * X + Y * Y + Z * Z) << 1;
+ *RadiusLow = (INT16)(Radius);
+ *RadiusHigh = (INT16)(Radius >> 16);
}
//////////////////////////////////////////////////////////////////
@@ -567,30 +586,30 @@ static void DSP1_radius(INT16 *input, INT16 *output)
// from a particular point, and so may be used to determine if a point is within the sphere or radius R.
// The output is D = X^2+Y^2+Z^2-R^2
-static void DSP1_range(INT16 *input, INT16 *output)
+static void dsp1_range( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16 Radius = input[3];
- INT16* Range = &output[0];
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16 Radius = input[3];
+ INT16* Range = &output[0];
- *Range = (X * X + Y * Y + Z * Z - Radius * Radius) >> 15;
+ *Range = (X * X + Y * Y + Z * Z - Radius * Radius) >> 15;
}
//////////////////////////////////////////////////////////////////
// Vector size comparison. 'Alternative' method.
-static void DSP1_range2(INT16 *input, INT16 *output)
+static void dsp1_range2( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16 Radius = input[3];
- INT16* Range = &output[0];
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16 Radius = input[3];
+ INT16* Range = &output[0];
- *Range = ((X * X + Y * Y + Z * Z - Radius * Radius) >> 15) + 1;
+ *Range = ((X * X + Y * Y + Z * Z - Radius * Radius) >> 15) + 1;
}
//////////////////////////////////////////////////////////////////
@@ -603,36 +622,39 @@ static void DSP1_range2(INT16 *input, INT16 *output)
// c=sqrt(b) by using lineal interpolation between points of a
// look-up table and, finally, you output the result as c*2^n.
-static void DSP1_distance(INT16 *input, INT16 *output)
+static void dsp1_distance( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* Distance = &output[0];
- INT16 Pos, Node1, Node2;
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* Distance = &output[0];
+ INT16 Pos, Node1, Node2;
- INT32 Radius = X * X + Y * Y + Z * Z;
+ INT32 Radius = X * X + Y * Y + Z * Z;
- if (Radius == 0) Distance = 0;
- else
- {
- INT16 C, E;
- normalizeDouble(Radius, &C, &E);
- if (E & 1) C = C * 0x4000 >> 15;
+ if (Radius == 0)
+ Distance = 0;
+ else
+ {
+ INT16 C, E;
+ normalize_double(Radius, &C, &E);
+ if (E & 1)
+ C = C * 0x4000 >> 15;
- Pos = C * 0x0040 >> 15;
+ Pos = C * 0x0040 >> 15;
- Node1 = DSP1_DataRom[0x00d5 + Pos];
- Node2 = DSP1_DataRom[0x00d6 + Pos];
+ Node1 = dsp1_state.DataRom[0x00d5 + Pos];
+ Node2 = dsp1_state.DataRom[0x00d6 + Pos];
- *Distance = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1;
+ *Distance = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1;
-#if DSP1_VERSION < 0x0102
- if (Pos & 1) *Distance -= (Node2 - Node1);
+#if dsp1_VERSION < 0x0102
+ if (Pos & 1)
+ *Distance -= (Node2 - Node1);
#endif
*Distance >>= (E >> 1);
- }
+ }
}
//////////////////////////////////////////////////////////////////
@@ -642,20 +664,20 @@ static void DSP1_distance(INT16 *input, INT16 *output)
// 'counterclockwise', but it's obviously wrong (surprise! :P)
//
// In matrix notation:
-// |X2| |cos(Angle) sin(Angle)| |X1|
-// | | = | | | |
-// |Y2| |-sin(Angle cos(Angle)| |Y1|
+// |X2| |cos(Angle) sin(Angle)| |X1|
+// | | = | | | |
+// |Y2| |-sin(Angle cos(Angle)| |Y1|
-static void DSP1_rotate(INT16 *input, INT16 *output)
+static void dsp1_rotate( INT16 *input, INT16 *output )
{
- INT16 Angle = input[0];
- INT16 X1 = input[1];
- INT16 Y1 = input[2];
- INT16* X2 = &output[0];
- INT16* Y2 = &output[1];
-
- *X2 = (Y1 * DSP1_sin(Angle) >> 15) + (X1 * DSP1_cos(Angle) >> 15);
- *Y2 = (Y1 * DSP1_cos(Angle) >> 15) - (X1 * DSP1_sin(Angle) >> 15);
+ INT16 Angle = input[0];
+ INT16 X1 = input[1];
+ INT16 Y1 = input[2];
+ INT16* X2 = &output[0];
+ INT16* Y2 = &output[1];
+
+ *X2 = (Y1 * dsp1_sin(Angle) >> 15) + (X1 * dsp1_cos(Angle) >> 15);
+ *Y2 = (Y1 * dsp1_cos(Angle) >> 15) - (X1 * dsp1_sin(Angle) >> 15);
}
//////////////////////////////////////////////////////////////////
@@ -668,46 +690,46 @@ static void DSP1_rotate(INT16 *input, INT16 *output)
// command (but not with the "gyrate" command).
//
// In matrix notation:
-// |X2| |1 0 0 | |cosRy 0 -sinRy| | cosRz sinRz 0| |X1|
-// |Y2| = |0 cosRx sinRx| | 0 1 0 | |-sinRz cosRz 0| |Y1|
-// |Z2| |0 -sinRx cosRx| |sinRy 0 cosRy| | 0 0 1| |Z1|
+// |X2| |1 0 0 | |cosRy 0 -sinRy| | cosRz sinRz 0| |X1|
+// |Y2| = |0 cosRx sinRx| | 0 1 0 | |-sinRz cosRz 0| |Y1|
+// |Z2| |0 -sinRx cosRx| |sinRy 0 cosRy| | 0 0 1| |Z1|
-static void DSP1_polar(INT16 *input, INT16 *output)
+static void dsp1_polar( INT16 *input, INT16 *output )
{
- INT16 Az = input[0];
- INT16 Ay = input[1];
- INT16 Ax = input[2];
- INT16 X1 = input[3];
- INT16 Y1 = input[4];
- INT16 Z1 = input[5];
- INT16* X2 = &output[0];
- INT16* Y2 = &output[1];
- INT16* Z2 = &output[2];
-
- INT16 X, Y, Z;
-
- // Rotate Around Z
- X = (Y1 * DSP1_sin(Az) >> 15) + (X1 * DSP1_cos(Az) >> 15);
- Y = (Y1 * DSP1_cos(Az) >> 15) - (X1 * DSP1_sin(Az) >> 15);
- X1 = X; Y1 = Y;
-
- // Rotate Around Y
- Z = (X1 * DSP1_sin(Ay) >> 15) + (Z1 * DSP1_cos(Ay) >> 15);
- X = (X1 * DSP1_cos(Ay) >> 15) - (Z1 * DSP1_sin(Ay) >> 15);
- *X2 = X; Z1 = Z;
-
- // Rotate Around X
- Y = (Z1 * DSP1_sin(Ax) >> 15) + (Y1 * DSP1_cos(Ax) >> 15);
- Z = (Z1 * DSP1_cos(Ax) >> 15) - (Y1 * DSP1_sin(Ax) >> 15);
- *Y2 = Y; *Z2 = Z;
+ INT16 Az = input[0];
+ INT16 Ay = input[1];
+ INT16 Ax = input[2];
+ INT16 X1 = input[3];
+ INT16 Y1 = input[4];
+ INT16 Z1 = input[5];
+ INT16* X2 = &output[0];
+ INT16* Y2 = &output[1];
+ INT16* Z2 = &output[2];
+
+ INT16 X, Y, Z;
+
+ // Rotate Around Z
+ X = (Y1 * dsp1_sin(Az) >> 15) + (X1 * dsp1_cos(Az) >> 15);
+ Y = (Y1 * dsp1_cos(Az) >> 15) - (X1 * dsp1_sin(Az) >> 15);
+ X1 = X; Y1 = Y;
+
+ // Rotate Around Y
+ Z = (X1 * dsp1_sin(Ay) >> 15) + (Z1 * dsp1_cos(Ay) >> 15);
+ X = (X1 * dsp1_cos(Ay) >> 15) - (Z1 * dsp1_sin(Ay) >> 15);
+ *X2 = X; Z1 = Z;
+
+ // Rotate Around X
+ Y = (Z1 * dsp1_sin(Ax) >> 15) + (Y1 * dsp1_cos(Ax) >> 15);
+ Z = (Z1 * dsp1_cos(Ax) >> 15) - (Y1 * dsp1_sin(Ax) >> 15);
+ *Y2 = Y; *Z2 = Z;
}
//////////////////////////////////////////////////////////////////
// Set up the elements of an "attitude matrix" (there are other ones):
-// S | cosRz sinRz 0| |cosRy 0 -sinRy| |1 0 0 |
-// MatrixA = - |-sinRz cosRz 0| | 0 1 0 | |0 cosRx sinRx|
-// 2 | 0 0 1| |sinRy 0 cosRy| |0 -sinRx cosRx|
+// S | cosRz sinRz 0| |cosRy 0 -sinRy| |1 0 0 |
+// MatrixA = - |-sinRz cosRz 0| | 0 1 0 | |0 cosRx sinRx|
+// 2 | 0 0 1| |sinRy 0 cosRy| |0 -sinRx cosRx|
// This matrix is thought to be used within the following framework:
// let's suppose we define positive rotations around a system of orthogonal axes in this manner:
// a rotation of +90 degrees around axis3 converts axis2 into axis1
@@ -736,99 +758,99 @@ static void DSP1_polar(INT16 *input, INT16 *output)
// input[2]: Ry
// input[3]: Rx
-static void DSP1_attitudeA(INT16 *input, INT16 *output)
+static void dsp1_attitudeA( INT16 *input, INT16 *output )
{
- INT16 S = input[0];
- INT16 Rz = input[1];
- INT16 Ry = input[2];
- INT16 Rx = input[3];
-
- INT16 SinRz = DSP1_sin(Rz);
- INT16 CosRz = DSP1_cos(Rz);
- INT16 SinRy = DSP1_sin(Ry);
- INT16 CosRy = DSP1_cos(Ry);
- INT16 SinRx = DSP1_sin(Rx);
- INT16 CosRx = DSP1_cos(Rx);
-
- S >>= 1;
-
- shared.MatrixA[0][0] = (S * CosRz >> 15) * CosRy >> 15;
- shared.MatrixA[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15);
- shared.MatrixA[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15);
-
- shared.MatrixA[1][0] = -((S * SinRz >> 15) * CosRy >> 15);
- shared.MatrixA[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15);
- shared.MatrixA[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15);
-
- shared.MatrixA[2][0] = S * SinRy >> 15;
- shared.MatrixA[2][1] = -((S * SinRx >> 15) * CosRy >> 15);
- shared.MatrixA[2][2] = (S * CosRx >> 15) * CosRy >> 15;
+ INT16 S = input[0];
+ INT16 Rz = input[1];
+ INT16 Ry = input[2];
+ INT16 Rx = input[3];
+
+ INT16 SinRz = dsp1_sin(Rz);
+ INT16 CosRz = dsp1_cos(Rz);
+ INT16 SinRy = dsp1_sin(Ry);
+ INT16 CosRy = dsp1_cos(Ry);
+ INT16 SinRx = dsp1_sin(Rx);
+ INT16 CosRx = dsp1_cos(Rx);
+
+ S >>= 1;
+
+ dsp1_state.shared.MatrixA[0][0] = (S * CosRz >> 15) * CosRy >> 15;
+ dsp1_state.shared.MatrixA[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15);
+ dsp1_state.shared.MatrixA[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15);
+
+ dsp1_state.shared.MatrixA[1][0] = -((S * SinRz >> 15) * CosRy >> 15);
+ dsp1_state.shared.MatrixA[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15);
+ dsp1_state.shared.MatrixA[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15);
+
+ dsp1_state.shared.MatrixA[2][0] = S * SinRy >> 15;
+ dsp1_state.shared.MatrixA[2][1] = -((S * SinRx >> 15) * CosRy >> 15);
+ dsp1_state.shared.MatrixA[2][2] = (S * CosRx >> 15) * CosRy >> 15;
}
//////////////////////////////////////////////////////////////////
// Same than 'attitudeA', but with a difference attitude matrix (matrixB)
-static void DSP1_attitudeB(INT16 *input, INT16 *output)
+static void dsp1_attitudeB( INT16 *input, INT16 *output )
{
- INT16 S = input[0];
- INT16 Rz = input[1];
- INT16 Ry = input[2];
- INT16 Rx = input[3];
-
- INT16 SinRz = DSP1_sin(Rz);
- INT16 CosRz = DSP1_cos(Rz);
- INT16 SinRy = DSP1_sin(Ry);
- INT16 CosRy = DSP1_cos(Ry);
- INT16 SinRx = DSP1_sin(Rx);
- INT16 CosRx = DSP1_cos(Rx);
-
- S >>= 1;
-
- shared.MatrixB[0][0] = (S * CosRz >> 15) * CosRy >> 15;
- shared.MatrixB[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15);
- shared.MatrixB[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15);
-
- shared.MatrixB[1][0] = -((S * SinRz >> 15) * CosRy >> 15);
- shared.MatrixB[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15);
- shared.MatrixB[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15);
-
- shared.MatrixB[2][0] = S * SinRy >> 15;
- shared.MatrixB[2][1] = -((S * SinRx >> 15) * CosRy >> 15);
- shared.MatrixB[2][2] = (S * CosRx >> 15) * CosRy >> 15;
+ INT16 S = input[0];
+ INT16 Rz = input[1];
+ INT16 Ry = input[2];
+ INT16 Rx = input[3];
+
+ INT16 SinRz = dsp1_sin(Rz);
+ INT16 CosRz = dsp1_cos(Rz);
+ INT16 SinRy = dsp1_sin(Ry);
+ INT16 CosRy = dsp1_cos(Ry);
+ INT16 SinRx = dsp1_sin(Rx);
+ INT16 CosRx = dsp1_cos(Rx);
+
+ S >>= 1;
+
+ dsp1_state.shared.MatrixB[0][0] = (S * CosRz >> 15) * CosRy >> 15;
+ dsp1_state.shared.MatrixB[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15);
+ dsp1_state.shared.MatrixB[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15);
+
+ dsp1_state.shared.MatrixB[1][0] = -((S * SinRz >> 15) * CosRy >> 15);
+ dsp1_state.shared.MatrixB[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15);
+ dsp1_state.shared.MatrixB[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15);
+
+ dsp1_state.shared.MatrixB[2][0] = S * SinRy >> 15;
+ dsp1_state.shared.MatrixB[2][1] = -((S * SinRx >> 15) * CosRy >> 15);
+ dsp1_state.shared.MatrixB[2][2] = (S * CosRx >> 15) * CosRy >> 15;
}
//////////////////////////////////////////////////////////////////
// Same than 'attitudeA', but with a difference attitude matrix (matrixC)
-static void DSP1_attitudeC(INT16 *input, INT16 *output)
+static void dsp1_attitudeC( INT16 *input, INT16 *output )
{
- INT16 S = input[0];
- INT16 Rz = input[1];
- INT16 Ry = input[2];
- INT16 Rx = input[3];
-
- INT16 SinRz = DSP1_sin(Rz);
- INT16 CosRz = DSP1_cos(Rz);
- INT16 SinRy = DSP1_sin(Ry);
- INT16 CosRy = DSP1_cos(Ry);
- INT16 SinRx = DSP1_sin(Rx);
- INT16 CosRx = DSP1_cos(Rx);
-
- S >>= 1;
-
- shared.MatrixC[0][0] = (S * CosRz >> 15) * CosRy >> 15;
- shared.MatrixC[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15);
- shared.MatrixC[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15);
-
- shared.MatrixC[1][0] = -((S * SinRz >> 15) * CosRy >> 15);
- shared.MatrixC[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15);
- shared.MatrixC[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15);
-
- shared.MatrixC[2][0] = S * SinRy >> 15;
- shared.MatrixC[2][1] = -((S * SinRx >> 15) * CosRy >> 15);
- shared.MatrixC[2][2] = (S * CosRx >> 15) * CosRy >> 15;
+ INT16 S = input[0];
+ INT16 Rz = input[1];
+ INT16 Ry = input[2];
+ INT16 Rx = input[3];
+
+ INT16 SinRz = dsp1_sin(Rz);
+ INT16 CosRz = dsp1_cos(Rz);
+ INT16 SinRy = dsp1_sin(Ry);
+ INT16 CosRy = dsp1_cos(Ry);
+ INT16 SinRx = dsp1_sin(Rx);
+ INT16 CosRx = dsp1_cos(Rx);
+
+ S >>= 1;
+
+ dsp1_state.shared.MatrixC[0][0] = (S * CosRz >> 15) * CosRy >> 15;
+ dsp1_state.shared.MatrixC[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15);
+ dsp1_state.shared.MatrixC[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15);
+
+ dsp1_state.shared.MatrixC[1][0] = -((S * SinRz >> 15) * CosRy >> 15);
+ dsp1_state.shared.MatrixC[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15);
+ dsp1_state.shared.MatrixC[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15);
+
+ dsp1_state.shared.MatrixC[2][0] = S * SinRy >> 15;
+ dsp1_state.shared.MatrixC[2][1] = -((S * SinRx >> 15) * CosRy >> 15);
+ dsp1_state.shared.MatrixC[2][2] = (S * CosRx >> 15) * CosRy >> 15;
}
//////////////////////////////////////////////////////////////////
@@ -839,54 +861,54 @@ static void DSP1_attitudeC(INT16 *input, INT16 *output)
// input[0]: X ; input[1]: Y ; input[2]: Z
// &output[0]: F ; &output[1]: L ; &output[2]: U
-static void DSP1_objectiveA(INT16 *input, INT16 *output)
+static void dsp1_objectiveA( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* F = &output[0];
- INT16* L = &output[1];
- INT16* U = &output[2];
-
- *F = (shared.MatrixA[0][0] * X >> 15) + (shared.MatrixA[1][0] * Y >> 15) + (shared.MatrixA[2][0] * Z >> 15);
- *L = (shared.MatrixA[0][1] * X >> 15) + (shared.MatrixA[1][1] * Y >> 15) + (shared.MatrixA[2][1] * Z >> 15);
- *U = (shared.MatrixA[0][2] * X >> 15) + (shared.MatrixA[1][2] * Y >> 15) + (shared.MatrixA[2][2] * Z >> 15);
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* F = &output[0];
+ INT16* L = &output[1];
+ INT16* U = &output[2];
+
+ *F = (dsp1_state.shared.MatrixA[0][0] * X >> 15) + (dsp1_state.shared.MatrixA[1][0] * Y >> 15) + (dsp1_state.shared.MatrixA[2][0] * Z >> 15);
+ *L = (dsp1_state.shared.MatrixA[0][1] * X >> 15) + (dsp1_state.shared.MatrixA[1][1] * Y >> 15) + (dsp1_state.shared.MatrixA[2][1] * Z >> 15);
+ *U = (dsp1_state.shared.MatrixA[0][2] * X >> 15) + (dsp1_state.shared.MatrixA[1][2] * Y >> 15) + (dsp1_state.shared.MatrixA[2][2] * Z >> 15);
}
//////////////////////////////////////////////////////////////////
// Same than 'objectiveA', but for the 'B' attitude
-static void DSP1_objectiveB(INT16 *input, INT16 *output)
+static void dsp1_objectiveB( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* F = &output[0];
- INT16* L = &output[1];
- INT16* U = &output[2];
-
- *F = (shared.MatrixB[0][0] * X >> 15) + (shared.MatrixB[1][0] * Y >> 15) + (shared.MatrixB[2][0] * Z >> 15);
- *L = (shared.MatrixB[0][1] * X >> 15) + (shared.MatrixB[1][1] * Y >> 15) + (shared.MatrixB[2][1] * Z >> 15);
- *U = (shared.MatrixB[0][2] * X >> 15) + (shared.MatrixB[1][2] * Y >> 15) + (shared.MatrixB[2][2] * Z >> 15);
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* F = &output[0];
+ INT16* L = &output[1];
+ INT16* U = &output[2];
+
+ *F = (dsp1_state.shared.MatrixB[0][0] * X >> 15) + (dsp1_state.shared.MatrixB[1][0] * Y >> 15) + (dsp1_state.shared.MatrixB[2][0] * Z >> 15);
+ *L = (dsp1_state.shared.MatrixB[0][1] * X >> 15) + (dsp1_state.shared.MatrixB[1][1] * Y >> 15) + (dsp1_state.shared.MatrixB[2][1] * Z >> 15);
+ *U = (dsp1_state.shared.MatrixB[0][2] * X >> 15) + (dsp1_state.shared.MatrixB[1][2] * Y >> 15) + (dsp1_state.shared.MatrixB[2][2] * Z >> 15);
}
//////////////////////////////////////////////////////////////////
// Same than 'objectiveA', but for the 'C' attitude
-static void DSP1_objectiveC(INT16 *input, INT16 *output)
+static void dsp1_objectiveC( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* F = &output[0];
- INT16* L = &output[1];
- INT16* U = &output[2];
-
- *F = (shared.MatrixC[0][0] * X >> 15) + (shared.MatrixC[1][0] * Y >> 15) + (shared.MatrixC[2][0] * Z >> 15);
- *L = (shared.MatrixC[0][1] * X >> 15) + (shared.MatrixC[1][1] * Y >> 15) + (shared.MatrixC[2][1] * Z >> 15);
- *U = (shared.MatrixC[0][2] * X >> 15) + (shared.MatrixC[1][2] * Y >> 15) + (shared.MatrixC[2][2] * Z >> 15);
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* F = &output[0];
+ INT16* L = &output[1];
+ INT16* U = &output[2];
+
+ *F = (dsp1_state.shared.MatrixC[0][0] * X >> 15) + (dsp1_state.shared.MatrixC[1][0] * Y >> 15) + (dsp1_state.shared.MatrixC[2][0] * Z >> 15);
+ *L = (dsp1_state.shared.MatrixC[0][1] * X >> 15) + (dsp1_state.shared.MatrixC[1][1] * Y >> 15) + (dsp1_state.shared.MatrixC[2][1] * Z >> 15);
+ *U = (dsp1_state.shared.MatrixC[0][2] * X >> 15) + (dsp1_state.shared.MatrixC[1][2] * Y >> 15) + (dsp1_state.shared.MatrixC[2][2] * Z >> 15);
}
//////////////////////////////////////////////////////////////////
@@ -897,54 +919,54 @@ static void DSP1_objectiveC(INT16 *input, INT16 *output)
// input[0]: F ; input[1]: L ; input[2]: U
// &output[0]: X ; &output[1]: Y ; &output[2]: Z
-static void DSP1_subjectiveA(INT16 *input, INT16 *output)
+static void dsp1_subjectiveA( INT16 *input, INT16 *output )
{
- INT16 F = input[0];
- INT16 L = input[1];
- INT16 U = input[2];
- INT16* X = &output[0];
- INT16* Y = &output[1];
- INT16* Z = &output[2];
-
- *X = (shared.MatrixA[0][0] * F >> 15) + (shared.MatrixA[0][1] * L >> 15) + (shared.MatrixA[0][2] * U >> 15);
- *Y = (shared.MatrixA[1][0] * F >> 15) + (shared.MatrixA[1][1] * L >> 15) + (shared.MatrixA[1][2] * U >> 15);
- *Z = (shared.MatrixA[2][0] * F >> 15) + (shared.MatrixA[2][1] * L >> 15) + (shared.MatrixA[2][2] * U >> 15);
+ INT16 F = input[0];
+ INT16 L = input[1];
+ INT16 U = input[2];
+ INT16* X = &output[0];
+ INT16* Y = &output[1];
+ INT16* Z = &output[2];
+
+ *X = (dsp1_state.shared.MatrixA[0][0] * F >> 15) + (dsp1_state.shared.MatrixA[0][1] * L >> 15) + (dsp1_state.shared.MatrixA[0][2] * U >> 15);
+ *Y = (dsp1_state.shared.MatrixA[1][0] * F >> 15) + (dsp1_state.shared.MatrixA[1][1] * L >> 15) + (dsp1_state.shared.MatrixA[1][2] * U >> 15);
+ *Z = (dsp1_state.shared.MatrixA[2][0] * F >> 15) + (dsp1_state.shared.MatrixA[2][1] * L >> 15) + (dsp1_state.shared.MatrixA[2][2] * U >> 15);
}
//////////////////////////////////////////////////////////////////
// Same than 'subjectiveA', but for the 'B' attitude
-static void DSP1_subjectiveB(INT16 *input, INT16 *output)
+static void dsp1_subjectiveB( INT16 *input, INT16 *output )
{
- INT16 F = input[0];
- INT16 L = input[1];
- INT16 U = input[2];
- INT16* X = &output[0];
- INT16* Y = &output[1];
- INT16* Z = &output[2];
-
- *X = (shared.MatrixB[0][0] * F >> 15) + (shared.MatrixB[0][1] * L >> 15) + (shared.MatrixB[0][2] * U >> 15);
- *Y = (shared.MatrixB[1][0] * F >> 15) + (shared.MatrixB[1][1] * L >> 15) + (shared.MatrixB[1][2] * U >> 15);
- *Z = (shared.MatrixB[2][0] * F >> 15) + (shared.MatrixB[2][1] * L >> 15) + (shared.MatrixB[2][2] * U >> 15);
+ INT16 F = input[0];
+ INT16 L = input[1];
+ INT16 U = input[2];
+ INT16* X = &output[0];
+ INT16* Y = &output[1];
+ INT16* Z = &output[2];
+
+ *X = (dsp1_state.shared.MatrixB[0][0] * F >> 15) + (dsp1_state.shared.MatrixB[0][1] * L >> 15) + (dsp1_state.shared.MatrixB[0][2] * U >> 15);
+ *Y = (dsp1_state.shared.MatrixB[1][0] * F >> 15) + (dsp1_state.shared.MatrixB[1][1] * L >> 15) + (dsp1_state.shared.MatrixB[1][2] * U >> 15);
+ *Z = (dsp1_state.shared.MatrixB[2][0] * F >> 15) + (dsp1_state.shared.MatrixB[2][1] * L >> 15) + (dsp1_state.shared.MatrixB[2][2] * U >> 15);
}
//////////////////////////////////////////////////////////////////
// Same than 'subjectiveA', but for the 'C' attitude
-static void DSP1_subjectiveC(INT16 *input, INT16 *output)
+static void dsp1_subjectiveC(INT16 *input, INT16 *output)
{
- INT16 F = input[0];
- INT16 L = input[1];
- INT16 U = input[2];
- INT16* X = &output[0];
- INT16* Y = &output[1];
- INT16* Z = &output[2];
-
- *X = (shared.MatrixC[0][0] * F >> 15) + (shared.MatrixC[0][1] * L >> 15) + (shared.MatrixC[0][2] * U >> 15);
- *Y = (shared.MatrixC[1][0] * F >> 15) + (shared.MatrixC[1][1] * L >> 15) + (shared.MatrixC[1][2] * U >> 15);
- *Z = (shared.MatrixC[2][0] * F >> 15) + (shared.MatrixC[2][1] * L >> 15) + (shared.MatrixC[2][2] * U >> 15);
+ INT16 F = input[0];
+ INT16 L = input[1];
+ INT16 U = input[2];
+ INT16* X = &output[0];
+ INT16* Y = &output[1];
+ INT16* Z = &output[2];
+
+ *X = (dsp1_state.shared.MatrixC[0][0] * F >> 15) + (dsp1_state.shared.MatrixC[0][1] * L >> 15) + (dsp1_state.shared.MatrixC[0][2] * U >> 15);
+ *Y = (dsp1_state.shared.MatrixC[1][0] * F >> 15) + (dsp1_state.shared.MatrixC[1][1] * L >> 15) + (dsp1_state.shared.MatrixC[1][2] * U >> 15);
+ *Z = (dsp1_state.shared.MatrixC[2][0] * F >> 15) + (dsp1_state.shared.MatrixC[2][1] * L >> 15) + (dsp1_state.shared.MatrixC[2][2] * U >> 15);
}
//////////////////////////////////////////////////////////////////
@@ -958,42 +980,42 @@ static void DSP1_subjectiveC(INT16 *input, INT16 *output)
// input[0]: X ; input[1]: Y ; input[2]: Z
// &output[0]: S
-static void DSP1_scalarA(INT16 *input, INT16 *output)
+static void dsp1_scalarA( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* S = &output[0];
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* S = &output[0];
- *S = (X * shared.MatrixA[0][0] + Y * shared.MatrixA[1][0] + Z * shared.MatrixA[2][0]) >> 15;
+ *S = (X * dsp1_state.shared.MatrixA[0][0] + Y * dsp1_state.shared.MatrixA[1][0] + Z * dsp1_state.shared.MatrixA[2][0]) >> 15;
}
//////////////////////////////////////////////////////////////////
// Same than 'scalarA', but for the 'B' attitude
-static void DSP1_scalarB(INT16 *input, INT16 *output)
+static void dsp1_scalarB( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* S = &output[0];
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* S = &output[0];
- *S = (X * shared.MatrixB[0][0] + Y * shared.MatrixB[1][0] + Z * shared.MatrixB[2][0]) >> 15;
+ *S = (X * dsp1_state.shared.MatrixB[0][0] + Y * dsp1_state.shared.MatrixB[1][0] + Z * dsp1_state.shared.MatrixB[2][0]) >> 15;
}
//////////////////////////////////////////////////////////////////
// Same than 'scalarA', but for the 'C' attitude
-static void DSP1_scalarC(INT16 *input, INT16 *output)
+static void dsp1_scalarC( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* S = &output[0];
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* S = &output[0];
- *S = (X * shared.MatrixC[0][0] + Y * shared.MatrixC[1][0] + Z * shared.MatrixC[2][0]) >> 15;
+ *S = (X * dsp1_state.shared.MatrixC[0][0] + Y * dsp1_state.shared.MatrixC[1][0] + Z * dsp1_state.shared.MatrixC[2][0]) >> 15;
}
//////////////////////////////////////////////////////////////////
@@ -1016,46 +1038,46 @@ static void DSP1_scalarC(INT16 *input, INT16 *output)
// opinion, a pretty severe implementation error. However, if you only use small "minor displacements", the error term
// introduced by that incoherence should be almost negligible.
-static void DSP1_gyrate(INT16 *input, INT16 *output)
+static void dsp1_gyrate( INT16 *input, INT16 *output )
{
- INT16 Az = input[0];
- INT16 Ax = input[1];
- INT16 Ay = input[2];
- INT16 U = input[3];
- INT16 F = input[4];
- INT16 L = input[5];
- INT16* Rz = &output[0];
- INT16* Rx = &output[1];
- INT16* Ry = &output[2];
+ INT16 Az = input[0];
+ INT16 Ax = input[1];
+ INT16 Ay = input[2];
+ INT16 U = input[3];
+ INT16 F = input[4];
+ INT16 L = input[5];
+ INT16* Rz = &output[0];
+ INT16* Rx = &output[1];
+ INT16* Ry = &output[2];
- INT16 CSec, ESec, CSin, C, E;
- INT16 SinAy = DSP1_sin(Ay);
- INT16 CosAy = DSP1_cos(Ay);
+ INT16 CSec, ESec, CSin, C, E;
+ INT16 SinAy = dsp1_sin(Ay);
+ INT16 CosAy = dsp1_cos(Ay);
- inverse(DSP1_cos(Ax), 0, &CSec, &ESec);
+ inverse(dsp1_cos(Ax), 0, &CSec, &ESec);
- // Rotation Around Z
- normalizeDouble(U * CosAy - F * SinAy, &C, &E);
+ // Rotation Around Z
+ normalize_double(U * CosAy - F * SinAy, &C, &E);
- E = ESec - E;
+ E = ESec - E;
- normalize(C * CSec >> 15, &C, &E);
+ normalize(C * CSec >> 15, &C, &E);
- *Rz = Az + denormalizeAndClip(C, E);
+ *Rz = Az + denormalize_and_clip(C, E);
- // Rotation Around X
- *Rx = Ax + (U * SinAy >> 15) + (F * CosAy >> 15);
+ // Rotation Around X
+ *Rx = Ax + (U * SinAy >> 15) + (F * CosAy >> 15);
- // Rotation Around Y
- normalizeDouble(U * CosAy + F * SinAy, &C, &E);
+ // Rotation Around Y
+ normalize_double(U * CosAy + F * SinAy, &C, &E);
- E = ESec - E;
+ E = ESec - E;
- normalize(DSP1_sin(Ax), &CSin, &E);
+ normalize(dsp1_sin(Ax), &CSin, &E);
- normalize(-(C * (CSec * CSin >> 15) >> 15), &C, &E);
+ normalize(-(C * (CSec * CSin >> 15) >> 15), &C, &E);
- *Ry = Ay + denormalizeAndClip(C, E) + L;
+ *Ry = Ay + denormalize_and_clip(C, E) + L;
}
//////////////////////////////////////////////////////////////////
@@ -1074,155 +1096,165 @@ static void DSP1_gyrate(INT16 *input, INT16 *output)
// Vva-> raster line representing the horizon line
// (Cx, Cy)-> coordinates of the projection of the center of the screen over the ground (ground coordinates)
-static void DSP1_parameter(INT16 *input, INT16 *output)
+static void dsp1_parameter( INT16 *input, INT16 *output )
{
- INT16 Fx = input[0];
- INT16 Fy = input[1];
- INT16 Fz = input[2];
- INT16 Lfe = input[3];
- INT16 Les = input[4];
- INT16 Aas = input[5];
- INT16 Azs = input[6];
- INT16* Vof = &output[0];
- INT16* Vva = &output[1];
- INT16* Cx = &output[2];
- INT16* Cy = &output[3];
-
- INT16 CSec, C, E;
- INT16 LfeNx, LfeNy, LfeNz;
- INT16 LesNx, LesNy, LesNz;
- INT16 AZS, MaxAZS;
-
- // Copy Zenith angle for clipping
- AZS = Azs;
-
- // Store Les and his coefficient and exponent when normalized
- shared.Les = Les;
- shared.E_Les=0;
- normalize(Les, &shared.C_Les, &shared.E_Les);
-
- // Store Sine and Cosine of Azimuth and Zenith angle
- shared.SinAas = DSP1_sin(Aas);
- shared.CosAas = DSP1_cos(Aas);
- shared.SinAzs = DSP1_sin(Azs);
- shared.CosAzs = DSP1_cos(Azs);
-
- // normal vector to the screen (norm 1, points toward the center of projection)
- shared.Nx = shared.SinAzs * -shared.SinAas >> 15;
- shared.Ny = shared.SinAzs * shared.CosAas >> 15;
- shared.Nz = shared.CosAzs * 0x7fff >> 15;
-
- // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen)
- shared.Hx = shared.CosAas*0x7fff>>15;
- shared.Hy = shared.SinAas*0x7fff>>15;
-
- // vertical vector of the screen (norm 1, points toward the top of the screen)
- shared.Vx = shared.CosAzs*-shared.SinAas>>15;
- shared.Vy = shared.CosAzs*shared.CosAas>>15;
- shared.Vz = -shared.SinAzs*0x7fff>>15;
-
- LfeNx = Lfe*shared.Nx>>15;
- LfeNy = Lfe*shared.Ny>>15;
- LfeNz = Lfe*shared.Nz>>15;
-
- // Center of Projection
- shared.CentreX = Fx+LfeNx;
- shared.CentreY = Fy+LfeNy;
- shared.CentreZ = Fz+LfeNz;
-
- LesNx = Les*shared.Nx>>15;
- LesNy = Les*shared.Ny>>15;
- LesNz = Les*shared.Nz>>15;
-
- // center of the screen (global coordinates)
- shared.Gx=shared.CentreX-LesNx;
- shared.Gy=shared.CentreY-LesNy;
- shared.Gz=shared.CentreZ-LesNz;
-
-
- E = 0;
- normalize(shared.CentreZ, &C, &E);
-
- shared.CentreZ_C = C;
- shared.CentreZ_E = E;
-
- // Determine clip boundary and clip Zenith angle if necessary
- // (Why to clip? Maybe to avoid the screen can only show sky with no ground? Only a guess...)
- MaxAZS = DSP1_MaxAZS_Exp[-E];
-
- if (AZS < 0) {
- MaxAZS = -MaxAZS;
- if (AZS < MaxAZS + 1) AZS = MaxAZS + 1;
- } else {
- if (AZS > MaxAZS) AZS = MaxAZS;
- }
-
- // Store Sine and Cosine of clipped Zenith angle
- shared.SinAZS = DSP1_sin(AZS);
- shared.CosAZS = DSP1_cos(AZS);
-
- // calculate the separation of (cx, cy) from the projection of
- // the 'centre of projection' over the ground... (CentreZ*tg(AZS))
- inverse(shared.CosAZS, 0, &shared.SecAZS_C1, &shared.SecAZS_E1);
- normalize(C * shared.SecAZS_C1 >> 15, &C, &E);
- E += shared.SecAZS_E1;
- C = denormalizeAndClip(C, E) * shared.SinAZS >> 15;
-
- // ... and then take into account the position of the centre of
- // projection and the azimuth angle
- shared.CentreX += C * shared.SinAas >> 15;
- shared.CentreY -= C * shared.CosAas >> 15;
-
- *Cx = shared.CentreX;
- *Cy = shared.CentreY;
-
- // Raster number of imaginary center and horizontal line
- *Vof = 0;
-
- if ((Azs != AZS) || (Azs == MaxAZS))
- {
- INT16 Aux;
-
- // correct vof and vva when Azs is outside the 'non-clipping interval'
- // we have only some few Taylor coefficients, so we cannot guess which ones
- // are the approximated functions and, what is worse, we don't know why
- // the own clipping stuff (and, particularly, this correction) is done
- if (Azs == -32768) Azs = -32767;
-
- C = Azs - MaxAZS;
- if (C >= 0) C--;
- Aux = ~(C << 2);
-
- // Vof += x+(1/3)*x^3, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000
- C = Aux * DSP1_DataRom[0x0328] >> 15;
- C = (C * Aux >> 15) + DSP1_DataRom[0x0327];
- *Vof -= (C * Aux >> 15) * Les >> 15;
-
- // CosAZS *= 1+(1/2)*x^2+(5/24)*x^24, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000
- C = Aux * Aux >> 15;
- Aux = (C * DSP1_DataRom[0x0324] >> 15) + DSP1_DataRom[0x0325];
- shared.CosAZS += (C * Aux >> 15) * shared.CosAZS >> 15;
- }
-
- // vertical offset of the screen with regard to the horizontal plane
- // containing the centre of projection
- shared.VOffset = Les * shared.CosAZS >> 15;
-
- // The horizon line (the line in the screen that is crossed by the horizon plane
- // -the horizontal plane containing the 'centre of projection'-),
- // will be at distance Les*cotg(AZS) from the centre of the screen. This is difficult
- // to explain but easily seen in a graph. To better see it, consider it in this way:
- // Les*tg(AZS-90), draw some lines and apply basic trigonometry. ;)
- inverse(shared.SinAZS, 0, &CSec, &E);
- normalize(shared.VOffset, &C, &E);
- normalize(C * CSec >> 15, &C, &E);
-
- if (C == -32768) { C >>= 1; E++; }
-
- *Vva = denormalizeAndClip(-C, E);
-
- // Store Secant of clipped Zenith angle
- inverse(shared.CosAZS, 0, &shared.SecAZS_C2, &shared.SecAZS_E2);
+ INT16 Fx = input[0];
+ INT16 Fy = input[1];
+ INT16 Fz = input[2];
+ INT16 Lfe = input[3];
+ INT16 Les = input[4];
+ INT16 Aas = input[5];
+ INT16 Azs = input[6];
+ INT16* Vof = &output[0];
+ INT16* Vva = &output[1];
+ INT16* Cx = &output[2];
+ INT16* Cy = &output[3];
+
+ INT16 CSec, C, E;
+ INT16 LfeNx, LfeNy, LfeNz;
+ INT16 LesNx, LesNy, LesNz;
+ INT16 AZS, MaxAZS;
+
+ // Copy Zenith angle for clipping
+ AZS = Azs;
+
+ // Store Les and his coefficient and exponent when normalized
+ dsp1_state.shared.Les = Les;
+ dsp1_state.shared.E_Les = 0;
+ normalize(Les, &dsp1_state.shared.C_Les, &dsp1_state.shared.E_Les);
+
+ // Store Sine and Cosine of Azimuth and Zenith angle
+ dsp1_state.shared.SinAas = dsp1_sin(Aas);
+ dsp1_state.shared.CosAas = dsp1_cos(Aas);
+ dsp1_state.shared.SinAzs = dsp1_sin(Azs);
+ dsp1_state.shared.CosAzs = dsp1_cos(Azs);
+
+ // normal vector to the screen (norm 1, points toward the center of projection)
+ dsp1_state.shared.Nx = dsp1_state.shared.SinAzs * -dsp1_state.shared.SinAas >> 15;
+ dsp1_state.shared.Ny = dsp1_state.shared.SinAzs * dsp1_state.shared.CosAas >> 15;
+ dsp1_state.shared.Nz = dsp1_state.shared.CosAzs * 0x7fff >> 15;
+
+ // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen)
+ dsp1_state.shared.Hx = dsp1_state.shared.CosAas*0x7fff>>15;
+ dsp1_state.shared.Hy = dsp1_state.shared.SinAas*0x7fff>>15;
+
+ // vertical vector of the screen (norm 1, points toward the top of the screen)
+ dsp1_state.shared.Vx = dsp1_state.shared.CosAzs * -dsp1_state.shared.SinAas >> 15;
+ dsp1_state.shared.Vy = dsp1_state.shared.CosAzs * dsp1_state.shared.CosAas >> 15;
+ dsp1_state.shared.Vz = -dsp1_state.shared.SinAzs * 0x7fff>>15;
+
+ LfeNx = Lfe * dsp1_state.shared.Nx >> 15;
+ LfeNy = Lfe * dsp1_state.shared.Ny >> 15;
+ LfeNz = Lfe * dsp1_state.shared.Nz >> 15;
+
+ // Center of Projection
+ dsp1_state.shared.CentreX = Fx + LfeNx;
+ dsp1_state.shared.CentreY = Fy + LfeNy;
+ dsp1_state.shared.CentreZ = Fz + LfeNz;
+
+ LesNx = Les * dsp1_state.shared.Nx >> 15;
+ LesNy = Les * dsp1_state.shared.Ny >> 15;
+ LesNz = Les * dsp1_state.shared.Nz >> 15;
+
+ // center of the screen (global coordinates)
+ dsp1_state.shared.Gx = dsp1_state.shared.CentreX - LesNx;
+ dsp1_state.shared.Gy = dsp1_state.shared.CentreY - LesNy;
+ dsp1_state.shared.Gz = dsp1_state.shared.CentreZ - LesNz;
+
+ E = 0;
+ normalize(dsp1_state.shared.CentreZ, &C, &E);
+
+ dsp1_state.shared.CentreZ_C = C;
+ dsp1_state.shared.CentreZ_E = E;
+
+ // Determine clip boundary and clip Zenith angle if necessary
+ // (Why to clip? Maybe to avoid the screen can only show sky with no ground? Only a guess...)
+ MaxAZS = dsp1_MaxAZS_Exp[-E];
+
+ if (AZS < 0)
+ {
+ MaxAZS = -MaxAZS;
+ if (AZS < MaxAZS + 1)
+ AZS = MaxAZS + 1;
+ }
+ else
+ {
+ if (AZS > MaxAZS)
+ AZS = MaxAZS;
+ }
+
+ // Store Sine and Cosine of clipped Zenith angle
+ dsp1_state.shared.SinAZS = dsp1_sin(AZS);
+ dsp1_state.shared.CosAZS = dsp1_cos(AZS);
+
+ // calculate the separation of (cx, cy) from the projection of
+ // the 'centre of projection' over the ground... (CentreZ*tg(AZS))
+ inverse(dsp1_state.shared.CosAZS, 0, &dsp1_state.shared.SecAZS_C1, &dsp1_state.shared.SecAZS_E1);
+ normalize(C * dsp1_state.shared.SecAZS_C1 >> 15, &C, &E);
+ E += dsp1_state.shared.SecAZS_E1;
+ C = denormalize_and_clip(C, E) * dsp1_state.shared.SinAZS >> 15;
+
+ // ... and then take into account the position of the centre of
+ // projection and the azimuth angle
+ dsp1_state.shared.CentreX += C * dsp1_state.shared.SinAas >> 15;
+ dsp1_state.shared.CentreY -= C * dsp1_state.shared.CosAas >> 15;
+
+ *Cx = dsp1_state.shared.CentreX;
+ *Cy = dsp1_state.shared.CentreY;
+
+ // Raster number of imaginary center and horizontal line
+ *Vof = 0;
+
+ if ((Azs != AZS) || (Azs == MaxAZS))
+ {
+ INT16 Aux;
+
+ // correct vof and vva when Azs is outside the 'non-clipping interval'
+ // we have only some few Taylor coefficients, so we cannot guess which ones
+ // are the approximated functions and, what is worse, we don't know why
+ // the own clipping stuff (and, particularly, this correction) is done
+ if (Azs == -32768)
+ Azs = -32767;
+
+ C = Azs - MaxAZS;
+ if (C >= 0)
+ C--;
+ Aux = ~(C << 2);
+
+ // Vof += x+(1/3)*x^3, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000
+ C = Aux * dsp1_state.DataRom[0x0328] >> 15;
+ C = (C * Aux >> 15) + dsp1_state.DataRom[0x0327];
+ *Vof -= (C * Aux >> 15) * Les >> 15;
+
+ // CosAZS *= 1+(1/2)*x^2+(5/24)*x^24, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000
+ C = Aux * Aux >> 15;
+ Aux = (C * dsp1_state.DataRom[0x0324] >> 15) + dsp1_state.DataRom[0x0325];
+ dsp1_state.shared.CosAZS += (C * Aux >> 15) * dsp1_state.shared.CosAZS >> 15;
+ }
+
+ // vertical offset of the screen with regard to the horizontal plane
+ // containing the centre of projection
+ dsp1_state.shared.VOffset = Les * dsp1_state.shared.CosAZS >> 15;
+
+ // The horizon line (the line in the screen that is crossed by the horizon plane
+ // -the horizontal plane containing the 'centre of projection'-),
+ // will be at distance Les*cotg(AZS) from the centre of the screen. This is difficult
+ // to explain but easily seen in a graph. To better see it, consider it in this way:
+ // Les*tg(AZS-90), draw some lines and apply basic trigonometry. ;)
+ inverse(dsp1_state.shared.SinAZS, 0, &CSec, &E);
+ normalize(dsp1_state.shared.VOffset, &C, &E);
+ normalize(C * CSec >> 15, &C, &E);
+
+ if (C == -32768)
+ {
+ C >>= 1;
+ E++;
+ }
+
+ *Vva = denormalize_and_clip(-C, E);
+
+ // Store Secant of clipped Zenith angle
+ inverse(dsp1_state.shared.CosAZS, 0, &dsp1_state.shared.SecAZS_C2, &dsp1_state.shared.SecAZS_E2);
}
//////////////////////////////////////////////////////////////////
@@ -1242,9 +1274,9 @@ static void DSP1_parameter(INT16 *input, INT16 *output)
// SecAZS). By last, you have to consider the effect of the azimuth angle Aas, and you are done.
//
// Using matrix notation:
-// |A B| Centre_ZS | cos(Aas) -sin(Aas)| |1 0|
-// ProjectionMatrix = | | = ----------- * | | * | |
-// |C D| Vs*sin(Azs) |sin(Aas) cos(Aas)| |0 sec(Azs)|
+// |A B| Centre_ZS | cos(Aas) -sin(Aas)| | 1 0 |
+// ProjectionMatrix = | | = ----------- * | | * | |
+// |C D| Vs*sin(Azs) | sin(Aas) cos(Aas)| | 0 sec(Azs)|
//
// (**)
// If Les=1, the vertical offset between the center
@@ -1252,34 +1284,34 @@ static void DSP1_parameter(INT16 *input, INT16 *output)
// offset is 1, the ratio of the projection over the ground respect to the
// line on the screen is 1/cos(Azs).
-static void DSP1_raster(INT16 *input, INT16 *output)
+static void dsp1_raster( INT16 *input, INT16 *output )
{
- INT16 Vs = input[0];
- INT16* An = &output[0];
- INT16* Bn = &output[1];
- INT16* Cn = &output[2];
- INT16* Dn = &output[3];
+ INT16 Vs = input[0];
+ INT16* An = &output[0];
+ INT16* Bn = &output[1];
+ INT16* Cn = &output[2];
+ INT16* Dn = &output[3];
- INT16 C, E, C1, E1;
+ INT16 C, E, C1, E1;
- inverse((Vs * shared.SinAzs >> 15) + shared.VOffset, 7, &C, &E);
+ inverse((Vs * dsp1_state.shared.SinAzs >> 15) + dsp1_state.shared.VOffset, 7, &C, &E);
- E += shared.CentreZ_E;
- C1 = C * shared.CentreZ_C >> 15;
+ E += dsp1_state.shared.CentreZ_E;
+ C1 = C * dsp1_state.shared.CentreZ_C >> 15;
- E1 = E + shared.SecAZS_E2;
+ E1 = E + dsp1_state.shared.SecAZS_E2;
- normalize(C1, &C, &E);
- C = denormalizeAndClip(C, E);
+ normalize(C1, &C, &E);
+ C = denormalize_and_clip(C, E);
- *An = C * shared.CosAas >> 15;
- *Cn = C * shared.SinAas >> 15;
+ *An = C * dsp1_state.shared.CosAas >> 15;
+ *Cn = C * dsp1_state.shared.SinAas >> 15;
- normalize(C1 * shared.SecAZS_C2 >> 15, &C, &E1);
- C = denormalizeAndClip(C, E1);
+ normalize(C1 * dsp1_state.shared.SecAZS_C2 >> 15, &C, &E1);
+ C = denormalize_and_clip(C, E1);
- *Bn = C * -shared.SinAas >> 15;
- *Dn = C * shared.CosAas >> 15;
+ *Bn = C * -dsp1_state.shared.SinAas >> 15;
+ *Dn = C * dsp1_state.shared.CosAas >> 15;
}
//////////////////////////////////////////////////////////////////
@@ -1292,35 +1324,35 @@ static void DSP1_raster(INT16 *input, INT16 *output)
// H is positive rightward, but V is positive downward; this is why
// the signs take that configuration
-static void DSP1_target(INT16 *input, INT16 *output)
+static void dsp1_target( INT16 *input, INT16 *output )
{
- INT16 H = input[0];
- INT16 V = input[1];
- INT16* X = &output[0];
- INT16* Y = &output[1];
+ INT16 H = input[0];
+ INT16 V = input[1];
+ INT16* X = &output[0];
+ INT16* Y = &output[1];
- INT16 C, E, C1, E1;
+ INT16 C, E, C1, E1;
- inverse((V * shared.SinAzs >> 15) + shared.VOffset, 8, &C, &E);
+ inverse((V * dsp1_state.shared.SinAzs >> 15) + dsp1_state.shared.VOffset, 8, &C, &E);
- E += shared.CentreZ_E;
- C1 = C * shared.CentreZ_C >> 15;
+ E += dsp1_state.shared.CentreZ_E;
+ C1 = C * dsp1_state.shared.CentreZ_C >> 15;
- E1 = E + shared.SecAZS_E1;
+ E1 = E + dsp1_state.shared.SecAZS_E1;
- H <<= 8;
- normalize(C1, &C, &E);
- C = denormalizeAndClip(C, E) * H >> 15;
+ H <<= 8;
+ normalize(C1, &C, &E);
+ C = denormalize_and_clip(C, E) * H >> 15;
- *X = shared.CentreX + (C * shared.CosAas >> 15);
- *Y = shared.CentreY - (C * shared.SinAas >> 15);
+ *X = dsp1_state.shared.CentreX + (C * dsp1_state.shared.CosAas >> 15);
+ *Y = dsp1_state.shared.CentreY - (C * dsp1_state.shared.SinAas >> 15);
- V <<= 8;
- normalize(C1 * shared.SecAZS_C1 >> 15, &C, &E1);
- C = denormalizeAndClip(C, E1) * V >> 15;
+ V <<= 8;
+ normalize(C1 * dsp1_state.shared.SecAZS_C1 >> 15, &C, &E1);
+ C = denormalize_and_clip(C, E1) * V >> 15;
- *X += C * -shared.SinAas >> 15;
- *Y += C * shared.CosAas >> 15;
+ *X += C * -dsp1_state.shared.SinAas >> 15;
+ *Y += C * dsp1_state.shared.CosAas >> 15;
}
//////////////////////////////////////////////////////////////////
@@ -1329,82 +1361,83 @@ static void DSP1_target(INT16 *input, INT16 *output)
// 'enlargement ratio' (M). The positive directions on the screen are as described
// in the targe command. M is scaled down by 2^-7, that is, M==0x0100 means ratio 1:1
-static void DSP1_project(INT16 *input, INT16 *output)
+static void dsp1_project( INT16 *input, INT16 *output )
{
- INT16 X = input[0];
- INT16 Y = input[1];
- INT16 Z = input[2];
- INT16* H = &output[0];
- INT16* V = &output[1];
- INT16* M = &output[2];
-
- INT32 aux, aux4;
- INT16 E, E2, E3, E4, E5, refE, E6, E7;
- INT16 C2, C4, C6, C8, C9, C10, C11, C12, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26;
- INT16 Px, Py, Pz;
-
- E4=E3=E2=E=E5=0;
-
- normalizeDouble((INT32)(X)-shared.Gx, &Px, &E4);
- normalizeDouble((INT32)(Y)-shared.Gy, &Py, &E);
- normalizeDouble((INT32)(Z)-shared.Gz, &Pz, &E3);
- Px>>=1; E4--; // to avoid overflows when calculating the scalar products
- Py>>=1; E--;
- Pz>>=1; E3--;
-
- refE = (E<E3)?E:E3;
- refE = (refE<E4)?refE:E4;
-
- Px=shiftR(Px,E4-refE); // normalize them to the same exponent
- Py=shiftR(Py,E-refE);
- Pz=shiftR(Pz,E3-refE);
-
- C11= -(Px*shared.Nx>>15);
- C8= -(Py*shared.Ny>>15);
- C9= -(Pz*shared.Nz>>15);
- C12=C11+C8+C9; // this cannot overflow!
-
- aux4=C12; // de-normalization with 32-bits 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 = (UINT16)(shared.Les) + aux4; // Les - the scalar product of P with the normal vector of the screen
- normalizeDouble(aux, &C10, &E2);
- E2 = 15-E2;
-
- inverse(C10, 0, &C4, &E4);
- C2=C4*shared.C_Les>>15; // scale factor
-
-
- // H
- E7=0;
- C16= (Px*shared.Hx>>15);
- C20= (Py*shared.Hy>>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
- normalize(C18, &C19, &E7);
- *H=denormalizeAndClip(C19, shared.E_Les-E2+refE+E7);
-
- // V
- E6=0;
- C21 = Px*shared.Vx>>15;
- C22 = Py*shared.Vy>>15;
- C23 = Pz*shared.Vz>>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
- normalize(C26, &C25, &E6);
- *V=denormalizeAndClip(C25, shared.E_Les-E2+refE+E6);
-
- // M
- normalize(C2, &C6, &E4);
- *M=denormalizeAndClip(C6, E4+shared.E_Les-E2-7); // M is the scale factor divided by 2^7
+ INT16 X = input[0];
+ INT16 Y = input[1];
+ INT16 Z = input[2];
+ INT16* H = &output[0];
+ INT16* V = &output[1];
+ INT16* M = &output[2];
+
+ INT32 aux, aux4;
+ INT16 E, E2, E3, E4, E5, refE, E6, E7;
+ INT16 C2, C4, C6, C8, C9, C10, C11, C12, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26;
+ INT16 Px, Py, Pz;
+
+ E4 = E3 = E2 = E = E5 = 0;
+
+ normalize_double((INT32)(X) - dsp1_state.shared.Gx, &Px, &E4);
+ normalize_double((INT32)(Y) - dsp1_state.shared.Gy, &Py, &E);
+ normalize_double((INT32)(Z) - dsp1_state.shared.Gz, &Pz, &E3);
+ Px >>= 1; E4--; // to avoid overflows when calculating the scalar products
+ Py >>= 1; E--;
+ Pz >>= 1; E3--;
+
+ refE = (E < E3) ? E : E3;
+ refE = (refE < E4) ? refE : E4;
+
+ Px = shiftR(Px, E4 - refE); // normalize them to the same exponent
+ Py = shiftR(Py, E - refE);
+ Pz = shiftR(Pz, E3 - refE);
+
+ C11 = -(Px * dsp1_state.shared.Nx >> 15);
+ C8 = -(Py * dsp1_state.shared.Ny >> 15);
+ C9 = -(Pz * dsp1_state.shared.Nz >> 15);
+ C12 = C11 + C8 + C9; // this cannot overflow!
+
+ aux4 = C12; // de-normalization with 32-bits 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 = (UINT16)(dsp1_state.shared.Les) + aux4; // Les - the scalar product of P with the normal vector of the screen
+ normalize_double(aux, &C10, &E2);
+ E2 = 15 - E2;
+
+ inverse(C10, 0, &C4, &E4);
+ C2 = C4 * dsp1_state.shared.C_Les >> 15; // scale factor
+
+
+ // H
+ E7 = 0;
+ C16 = (Px * dsp1_state.shared.Hx >> 15);
+ C20 = (Py * dsp1_state.shared.Hy >> 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
+ normalize(C18, &C19, &E7);
+ *H = denormalize_and_clip(C19, dsp1_state.shared.E_Les - E2 + refE + E7);
+
+ // V
+ E6 = 0;
+ C21 = Px * dsp1_state.shared.Vx >> 15;
+ C22 = Py * dsp1_state.shared.Vy >> 15;
+ C23 = Pz * dsp1_state.shared.Vz >> 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
+ normalize(C26, &C25, &E6);
+ *V = denormalize_and_clip(C25, dsp1_state.shared.E_Les - E2 + refE + E6);
+
+ // M
+ normalize(C2, &C6, &E4);
+ *M = denormalize_and_clip(C6, E4 + dsp1_state.shared.E_Les - E2 - 7); // M is the scale factor divided by 2^7
}
//////////////////////////////////////////////////////////////////
@@ -1413,17 +1446,21 @@ static void DSP1_project(INT16 *input, INT16 *output)
// this is done by linear interpolation between
// the points of a look-up table
-static INT16 DSP1_sin(INT16 Angle)
+static INT16 dsp1_sin( INT16 Angle )
{
- INT32 S;
-
- if (Angle < 0) {
- if (Angle == -32768) return 0;
- return -DSP1_sin(-Angle);
- }
- S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15);
- if (S > 32767) S = 32767;
- return (INT16) S;
+ INT32 S;
+
+ if (Angle < 0)
+ {
+ if (Angle == -32768)
+ return 0;
+
+ return -dsp1_sin(-Angle);
+ }
+ S = dsp1_sin_table[Angle >> 8] + (dsp1_mul_table[Angle & 0xff] * dsp1_sin_table[0x40 + (Angle >> 8)] >> 15);
+ if (S > 32767)
+ S = 32767;
+ return (INT16) S;
}
//////////////////////////////////////////////////////////////////
@@ -1431,17 +1468,20 @@ static INT16 DSP1_sin(INT16 Angle)
// Calculate the cosine of the input parameter.
// It's used the same method than in sin(INT16)
-static INT16 DSP1_cos(INT16 Angle)
+static INT16 dsp1_cos( INT16 Angle )
{
- INT32 S;
-
- if (Angle < 0) {
- if (Angle == -32768) return -32768;
- Angle = -Angle;
- }
- S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15);
- if (S < -32768) S = -32767;
- return (INT16) S;
+ INT32 S;
+
+ if (Angle < 0)
+ {
+ if (Angle == -32768)
+ return -32768;
+ Angle = -Angle;
+ }
+ S = dsp1_sin_table[0x40 + (Angle >> 8)] - (dsp1_mul_table[Angle & 0xff] * dsp1_sin_table[Angle >> 8] >> 15);
+ if (S < -32768)
+ S = -32767;
+ return (INT16) S;
}
//////////////////////////////////////////////////////////////////
@@ -1455,65 +1495,73 @@ static INT16 DSP1_cos(INT16 Angle)
// that verify Coefficient*y=1/2. This is why you have to correct the exponent by one
// unit at the end.
-static void inverse(INT16 Coefficient, INT16 Exponent, INT16 *iCoefficient, INT16 *iExponent)
+static void inverse( INT16 Coefficient, INT16 Exponent, INT16 *iCoefficient, INT16 *iExponent )
{
- // Step One: Division by Zero
- if (Coefficient == 0x0000)
- {
- *iCoefficient = 0x7fff;
- *iExponent = 0x002f;
- }
- else
- {
- INT16 Sign = 1;
-
- // Step Two: Remove Sign
- if (Coefficient < 0)
- {
- if (Coefficient < -32767) Coefficient = -32767;
- Coefficient = -Coefficient;
- Sign = -1;
- }
-
- // Step Three: Normalize
- while (Coefficient < 0x4000)
- {
- Coefficient <<= 1;
- Exponent--;
- }
-
- // Step Four: Special Case
- if (Coefficient == 0x4000)
- if (Sign == 1) *iCoefficient = 0x7fff;
- else {
- *iCoefficient = -0x4000;
- Exponent--;
- }
- else {
- // Step Five: Initial Guess
- INT16 i = DSP1_DataRom[((Coefficient - 0x4000) >> 7) + 0x0065];
-
- // Step Six: Iterate Newton's Method
- i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
- i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
-
- *iCoefficient = i * Sign;
- }
-
- *iExponent = 1 - Exponent;
- }
+ // Step One: Division by Zero
+ if (Coefficient == 0x0000)
+ {
+ *iCoefficient = 0x7fff;
+ *iExponent = 0x002f;
+ }
+ else
+ {
+ INT16 Sign = 1;
+
+ // Step Two: Remove Sign
+ if (Coefficient < 0)
+ {
+ if (Coefficient < -32767)
+ Coefficient = -32767;
+ Coefficient = -Coefficient;
+ Sign = -1;
+ }
+
+ // Step Three: Normalize
+ while (Coefficient < 0x4000)
+ {
+ Coefficient <<= 1;
+ Exponent--;
+ }
+
+ // Step Four: Special Case
+ if (Coefficient == 0x4000)
+ if (Sign == 1) *iCoefficient = 0x7fff;
+ else {
+ *iCoefficient = -0x4000;
+ Exponent--;
+ }
+ else {
+ // Step Five: Initial Guess
+ INT16 i = dsp1_state.DataRom[((Coefficient - 0x4000) >> 7) + 0x0065];
+
+ // Step Six: Iterate Newton's Method
+ i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
+ i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
+
+ *iCoefficient = i * Sign;
+ }
+
+ *iExponent = 1 - Exponent;
+ }
}
//////////////////////////////////////////////////////////////////
-static INT16 denormalizeAndClip(INT16 C, INT16 E)
+static INT16 denormalize_and_clip( INT16 C, INT16 E )
{
- if (E > 0) {
- if (C > 0) return 32767; else if (C < 0) return -32767;
- } else {
- if (E < 0) return C * DSP1_DataRom[0x0031 + E] >> 15;
- }
- return C;
+ if (E > 0)
+ {
+ if (C > 0)
+ return 32767;
+ else if (C < 0)
+ return -32767;
+ }
+ else
+ {
+ if (E < 0)
+ return C * dsp1_state.DataRom[0x0031 + E] >> 15;
+ }
+ return C;
}
//////////////////////////////////////////////////////////////////
@@ -1523,96 +1571,152 @@ static INT16 denormalizeAndClip(INT16 C, INT16 E)
// where the absolute value of Coefficient is >= 1/2
// (Coefficient>=0x4000 or Coefficient <= (INT16)0xc001)
-static void normalize(INT16 m, INT16 *Coefficient, INT16 *Exponent)
+static void normalize( INT16 m, INT16 *Coefficient, INT16 *Exponent )
{
- INT16 i = 0x4000;
- INT16 e = 0;
-
- if (m < 0)
- while ((m & i) && i)
- {
- i >>= 1;
- e++;
- }
- else
- while (!(m & i) && i)
- {
- i >>= 1;
- e++;
- }
-
- if (e > 0)
- *Coefficient = m * DSP1_DataRom[0x21 + e] << 1;
- else
- *Coefficient = m;
-
- *Exponent -= e;
+ INT16 i = 0x4000;
+ INT16 e = 0;
+
+ if (m < 0)
+ while ((m & i) && i)
+ {
+ i >>= 1;
+ e++;
+ }
+ else
+ while (!(m & i) && i)
+ {
+ i >>= 1;
+ e++;
+ }
+
+ if (e > 0)
+ *Coefficient = m * dsp1_state.DataRom[0x21 + e] << 1;
+ else
+ *Coefficient = m;
+
+ *Exponent -= e;
}
//////////////////////////////////////////////////////////////////
// Same than 'normalize' but with an INT32 input
-static void normalizeDouble(INT32 Product, INT16 *Coefficient, INT16 *Exponent)
+static void normalize_double( INT32 Product, INT16 *Coefficient, INT16 *Exponent )
{
- INT16 n = Product & 0x7fff;
- INT16 m = Product >> 15;
- INT16 i = 0x4000;
- INT16 e = 0;
-
- if (m < 0)
- while ((m & i) && i)
- {
- i >>= 1;
- e++;
- }
- else
- while (!(m & i) && i)
- {
- i >>= 1;
- e++;
- }
-
- if (e > 0)
- {
- *Coefficient = m * DSP1_DataRom[0x0021 + e] << 1;
-
- if (e < 15)
- *Coefficient += n * DSP1_DataRom[0x0040 - e] >> 15;
- else
- {
- i = 0x4000;
-
- if (m < 0)
- while ((n & i) && i)
- {
- i >>= 1;
- e++;
- }
- else
- while (!(n & i) && i)
- {
- i >>= 1;
- e++;
- }
-
- if (e > 15)
- *Coefficient = n * DSP1_DataRom[0x0012 + e] << 1;
- else
- *Coefficient += n;
- }
- }
- else
- *Coefficient = m;
-
- *Exponent = e;
+ INT16 n = Product & 0x7fff;
+ INT16 m = Product >> 15;
+ INT16 i = 0x4000;
+ INT16 e = 0;
+
+ if (m < 0)
+ while ((m & i) && i)
+ {
+ i >>= 1;
+ e++;
+ }
+ else
+ while (!(m & i) && i)
+ {
+ i >>= 1;
+ e++;
+ }
+
+ if (e > 0)
+ {
+ *Coefficient = m * dsp1_state.DataRom[0x0021 + e] << 1;
+
+ if (e < 15)
+ *Coefficient += n * dsp1_state.DataRom[0x0040 - e] >> 15;
+ else
+ {
+ i = 0x4000;
+
+ if (m < 0)
+ while ((n & i) && i)
+ {
+ i >>= 1;
+ e++;
+ }
+ else
+ while (!(n & i) && i)
+ {
+ i >>= 1;
+ e++;
+ }
+
+ if (e > 15)
+ *Coefficient = n * dsp1_state.DataRom[0x0012 + e] << 1;
+ else
+ *Coefficient += n;
+ }
+ }
+ else
+ *Coefficient = m;
+
+ *Exponent = e;
}
//////////////////////////////////////////////////////////////////
// Shift to the right
-static INT16 shiftR(INT16 C, INT16 E)
+static INT16 shiftR( INT16 C, INT16 E )
+{
+ return (C * dsp1_state.DataRom[0x0031 + E] >> 15);
+}
+
+//////////////////////////////////////////////////////////////////
+
+// Save DSP1 variables
+
+static void dsp1_register_save( running_machine *machine )
{
- return (C * DSP1_DataRom[0x0031 + E] >> 15);
+ state_save_register_global(machine, dsp1_state.Sr);
+ state_save_register_global(machine, dsp1_state.Dr);
+ state_save_register_global(machine, dsp1_state.SrLowByteAccess);
+ state_save_register_global(machine, dsp1_state.FsmMajorState);
+ state_save_register_global(machine, dsp1_state.Command);
+ state_save_register_global(machine, dsp1_state.DataCounter);
+ state_save_register_global(machine, dsp1_state.Freeze);
+ state_save_register_global_array(machine, dsp1_state.ReadBuffer);
+ state_save_register_global_array(machine, dsp1_state.WriteBuffer);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixA[0]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixA[1]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixA[2]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixB[0]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixB[1]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixB[2]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixC[0]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixC[1]);
+ state_save_register_global_array(machine, dsp1_state.shared.MatrixC[2]);
+ state_save_register_global(machine, dsp1_state.shared.CentreX);
+ state_save_register_global(machine, dsp1_state.shared.CentreY);
+ state_save_register_global(machine, dsp1_state.shared.CentreZ);
+ state_save_register_global(machine, dsp1_state.shared.CentreZ_C);
+ state_save_register_global(machine, dsp1_state.shared.CentreZ_E);
+ state_save_register_global(machine, dsp1_state.shared.VOffset);
+ state_save_register_global(machine, dsp1_state.shared.Les);
+ state_save_register_global(machine, dsp1_state.shared.C_Les);
+ state_save_register_global(machine, dsp1_state.shared.E_Les);
+ state_save_register_global(machine, dsp1_state.shared.SinAas);
+ state_save_register_global(machine, dsp1_state.shared.CosAas);
+ state_save_register_global(machine, dsp1_state.shared.SinAzs);
+ state_save_register_global(machine, dsp1_state.shared.CosAzs);
+ state_save_register_global(machine, dsp1_state.shared.SinAZS);
+ state_save_register_global(machine, dsp1_state.shared.CosAZS);
+ state_save_register_global(machine, dsp1_state.shared.SecAZS_C1);
+ state_save_register_global(machine, dsp1_state.shared.SecAZS_E1);
+ state_save_register_global(machine, dsp1_state.shared.SecAZS_C2);
+ state_save_register_global(machine, dsp1_state.shared.SecAZS_E2);
+ state_save_register_global(machine, dsp1_state.shared.Nx);
+ state_save_register_global(machine, dsp1_state.shared.Ny);
+ state_save_register_global(machine, dsp1_state.shared.Nz);
+ state_save_register_global(machine, dsp1_state.shared.Gx);
+ state_save_register_global(machine, dsp1_state.shared.Gy);
+ state_save_register_global(machine, dsp1_state.shared.Gz);
+ state_save_register_global(machine, dsp1_state.shared.Hx);
+ state_save_register_global(machine, dsp1_state.shared.Hy);
+ state_save_register_global(machine, dsp1_state.shared.Vx);
+ state_save_register_global(machine, dsp1_state.shared.Vy);
+ state_save_register_global(machine, dsp1_state.shared.Vz);
}
diff --git a/src/mame/machine/snesdsp2.c b/src/mame/machine/snesdsp2.c
index de4f9557999..bbdce8179e3 100644
--- a/src/mame/machine/snesdsp2.c
+++ b/src/mame/machine/snesdsp2.c
@@ -13,36 +13,43 @@
***************************************************************************/
-static int DSP2_waiting_for_command = 0;
-static int DSP2_command = 0;
-static int DSP2_in_count = 0, DSP2_in_index = 0;
-static int DSP2_out_count = 0, DSP2_out_index = 0;
-
-static UINT8 DSP2_parameters[512] = {0};
-static UINT8 DSP2_output[512] = {0};
-
-static UINT8 DSP2_op05transparent = 0;
-static int DSP2_op05haslen = 0;
-static int DSP2_op05len = 0;
-static int DSP2_op06haslen = 0;
-static int DSP2_op06len = 0;
-static UINT16 DSP2_op09word1 = 0;
-static UINT16 DSP2_op09word2 = 0;
-static int DSP2_op0dhaslen = 0;
-static int DSP2_op0doutlen = 0;
-static int DSP2_op0dinlen = 0;
+struct _snes_dsp2_state
+{
+ int waiting_for_command;
+ int command;
+ int in_count, in_index;
+ int out_count, out_index;
+
+ UINT8 parameters[512];
+ UINT8 output[512];
+
+ UINT8 op05transparent;
+ int op05haslen;
+ int op05len;
+ int op06haslen;
+ int op06len;
+ UINT16 op09word1;
+ UINT16 op09word2;
+ int op0dhaslen;
+ int op0doutlen;
+ int op0dinlen;
+};
+static struct _snes_dsp2_state dsp2_state;
+
+
+static void dsp2_register_save(running_machine *machine);
//convert bitmap to bitplane tile
-static void DSP2_op01( void )
+static void dsp2_op01( void )
{
//op01 size is always 32 bytes input and output
//the hardware does strange things if you vary the size
unsigned char c0, c1, c2, c3;
- unsigned char *p1 = DSP2_parameters;
- unsigned char *p2a = DSP2_output;
- unsigned char *p2b = DSP2_output + 16; //halfway
+ unsigned char *p1 = dsp2_state.parameters;
+ unsigned char *p2a = dsp2_state.output;
+ unsigned char *p2b = dsp2_state.output + 16; //halfway
int j;
//process 8 blocks of 4 bytes each
@@ -92,13 +99,13 @@ static void DSP2_op01( void )
}
//set transparent color
-static void DSP2_op03( void )
+static void dsp2_op03( void )
{
- DSP2_op05transparent = DSP2_parameters[0];
+ dsp2_state.op05transparent = dsp2_state.parameters[0];
}
//replace bitmap using transparent color
-static void DSP2_op05( void )
+static void dsp2_op05( void )
{
UINT8 color;
// Overlay bitmap with transparency.
@@ -127,53 +134,53 @@ static void DSP2_op05( void )
// proven necessary.
unsigned char c1, c2;
- unsigned char *p1 = DSP2_parameters;
- unsigned char *p2 = DSP2_parameters + DSP2_op05len;
- unsigned char *p3 = DSP2_output;
+ unsigned char *p1 = dsp2_state.parameters;
+ unsigned char *p2 = dsp2_state.parameters + dsp2_state.op05len;
+ unsigned char *p3 = dsp2_state.output;
int n;
- color = DSP2_op05transparent & 0x0f;
+ color = dsp2_state.op05transparent & 0x0f;
- for (n = 0; n < DSP2_op05len; n++)
+ for (n = 0; n < dsp2_state.op05len; n++)
{
c1 = *p1++;
c2 = *p2++;
- *p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0 : c2 & 0xf0 ) |
- ( ((c2 & 0x0f) == color ) ? c1 & 0x0f : c2 & 0x0f );
+ *p3++ = (((c2 >> 4) == color) ? c1 & 0xf0 : c2 & 0xf0) |
+ (((c2 & 0x0f) == color) ? c1 & 0x0f : c2 & 0x0f);
}
}
//reverse bitmap
-static void DSP2_op06( void )
+static void dsp2_op06( void )
{
// Input:
// size
// bitmap
int i, j;
- for (i = 0, j = DSP2_op06len - 1; i < DSP2_op06len; i++, j--)
+ for (i = 0, j = dsp2_state.op06len - 1; i < dsp2_state.op06len; i++, j--)
{
- DSP2_output[j] = (DSP2_parameters[i] << 4) | (DSP2_parameters[i] >> 4);
+ dsp2_state.output[j] = (dsp2_state.parameters[i] << 4) | (dsp2_state.parameters[i] >> 4);
}
}
//multiply
-static void DSP2_op09( void )
+static void dsp2_op09( void )
{
UINT32 r = 0;
- DSP2_out_count = 4;
+ dsp2_state.out_count = 4;
- DSP2_op09word1 = DSP2_parameters[0] | (DSP2_parameters[1] << 8);
- DSP2_op09word2 = DSP2_parameters[2] | (DSP2_parameters[3] << 8);
+ dsp2_state.op09word1 = dsp2_state.parameters[0] | (dsp2_state.parameters[1] << 8);
+ dsp2_state.op09word2 = dsp2_state.parameters[2] | (dsp2_state.parameters[3] << 8);
- r = DSP2_op09word1 * DSP2_op09word2;
- DSP2_output[0] = r;
- DSP2_output[1] = r >> 8;
- DSP2_output[2] = r >> 16;
- DSP2_output[3] = r >> 24;
+ r = dsp2_state.op09word1 * dsp2_state.op09word2;
+ dsp2_state.output[0] = r;
+ dsp2_state.output[1] = r >> 8;
+ dsp2_state.output[2] = r >> 16;
+ dsp2_state.output[3] = r >> 24;
}
//scale bitmap
-static void DSP2_op0d( void )
+static void dsp2_op0d( void )
{
// Bit accurate hardware algorithm - uses fixed point math
// This should match the DSP2 Op0D output exactly
@@ -193,174 +200,203 @@ static void DSP2_op0d( void )
UINT32 pixloc; // match size of multiplier
int i, j;
UINT8 pixelarray[512];
- if (DSP2_op0dinlen <= DSP2_op0doutlen)
+ if (dsp2_state.op0dinlen <= dsp2_state.op0doutlen)
{
multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
}
else
{
- multiplier = (DSP2_op0dinlen << 17) / ((DSP2_op0doutlen << 1) + 1);
+ multiplier = (dsp2_state.op0dinlen << 17) / ((dsp2_state.op0doutlen << 1) + 1);
}
pixloc = 0;
- for (i = 0; i < DSP2_op0doutlen * 2; i++)
+ for (i = 0; i < dsp2_state.op0doutlen * 2; i++)
{
j = pixloc >> 16;
if (j & 1)
- pixelarray[i] = (DSP2_parameters[j >> 1] & 0x0f);
+ pixelarray[i] = (dsp2_state.parameters[j >> 1] & 0x0f);
else
- pixelarray[i] = (DSP2_parameters[j >> 1] & 0xf0) >> 4;
+ pixelarray[i] = (dsp2_state.parameters[j >> 1] & 0xf0) >> 4;
pixloc += multiplier;
}
- for (i = 0; i < DSP2_op0doutlen; i++)
+ for (i = 0; i < dsp2_state.op0doutlen; i++)
{
- DSP2_output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
+ dsp2_state.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
}
}
-static void DSP2_reset( void )
+static void dsp2_init( running_machine *machine )
{
- DSP2_waiting_for_command = 1;
- DSP2_in_count = 0;
- DSP2_in_index = 0;
- DSP2_out_count = 0;
- DSP2_out_index = 0;
-
- DSP2_op05transparent = 0;
- DSP2_op05haslen = 0;
- DSP2_op05len = 0;
- DSP2_op06haslen = 0;
- DSP2_op06len = 0;
- DSP2_op09word1 = 0;
- DSP2_op09word2 = 0;
- DSP2_op0dhaslen = 0;
- DSP2_op0doutlen = 0;
- DSP2_op0dinlen = 0;
+ dsp2_state.waiting_for_command = 1;
+ dsp2_state.in_count = 0;
+ dsp2_state.in_index = 0;
+ dsp2_state.out_count = 0;
+ dsp2_state.out_index = 0;
+
+ memset(dsp2_state.parameters, 0 , ARRAY_LENGTH(dsp2_state.parameters));
+ memset(dsp2_state.output, 0 , ARRAY_LENGTH(dsp2_state.output));
+
+ dsp2_state.op05transparent = 0;
+ dsp2_state.op05haslen = 0;
+ dsp2_state.op05len = 0;
+ dsp2_state.op06haslen = 0;
+ dsp2_state.op06len = 0;
+ dsp2_state.op09word1 = 0;
+ dsp2_state.op09word2 = 0;
+ dsp2_state.op0dhaslen = 0;
+ dsp2_state.op0doutlen = 0;
+ dsp2_state.op0dinlen = 0;
+
+ dsp2_register_save(machine);
}
-static UINT8 DSP2_read( void )
+static UINT8 dsp2_read( void )
{
UINT8 r = 0xff;
- if (DSP2_out_count)
+ if (dsp2_state.out_count)
{
- r = DSP2_output[DSP2_out_index++];
- DSP2_out_index &= 511;
- if (DSP2_out_count == DSP2_out_index)
- DSP2_out_count = 0;
+ r = dsp2_state.output[dsp2_state.out_index++];
+ dsp2_state.out_index &= 511;
+ if (dsp2_state.out_count == dsp2_state.out_index)
+ dsp2_state.out_count = 0;
}
return r;
}
-static void DSP2_write(UINT8 data)
+static void dsp2_write(UINT8 data)
{
- if(DSP2_waiting_for_command)
+ if (dsp2_state.waiting_for_command)
{
- DSP2_command = data;
- DSP2_in_index = 0;
- DSP2_waiting_for_command = 0;
+ dsp2_state.command = data;
+ dsp2_state.in_index = 0;
+ dsp2_state.waiting_for_command = 0;
switch (data)
{
- case 0x01: DSP2_in_count = 32; break;
- case 0x03: DSP2_in_count = 1; break;
- case 0x05: DSP2_in_count = 1; break;
- case 0x06: DSP2_in_count = 1; break;
+ case 0x01: dsp2_state.in_count = 32; break;
+ case 0x03: dsp2_state.in_count = 1; break;
+ case 0x05: dsp2_state.in_count = 1; break;
+ case 0x06: dsp2_state.in_count = 1; break;
case 0x07: break;
case 0x08: break;
- case 0x09: DSP2_in_count = 4; break;
- case 0x0d: DSP2_in_count = 2; break;
- case 0x0f: DSP2_in_count = 0; break;
+ case 0x09: dsp2_state.in_count = 4; break;
+ case 0x0d: dsp2_state.in_count = 2; break;
+ case 0x0f: dsp2_state.in_count = 0; break;
}
}
else
{
- DSP2_parameters[DSP2_in_index++] = data;
- DSP2_in_index &= 511;
+ dsp2_state.parameters[dsp2_state.in_index++] = data;
+ dsp2_state.in_index &= 511;
}
- if (DSP2_in_count == DSP2_in_index)
+ if (dsp2_state.in_count == dsp2_state.in_index)
{
- DSP2_waiting_for_command = 1;
- DSP2_out_index = 0;
- switch (DSP2_command)
+ dsp2_state.waiting_for_command = 1;
+ dsp2_state.out_index = 0;
+ switch (dsp2_state.command)
{
- case 0x01:
- DSP2_out_count = 32;
- DSP2_op01();
- break;
-
- case 0x03:
- DSP2_op03();
- break;
-
- case 0x05:
- if (DSP2_op05haslen)
- {
- DSP2_op05haslen = 0;
- DSP2_out_count = DSP2_op05len;
- DSP2_op05();
- }
- else
- {
- DSP2_op05len = DSP2_parameters[0];
- DSP2_in_index = 0;
- DSP2_in_count = DSP2_op05len * 2;
- DSP2_op05haslen = 1;
- if (data)
- DSP2_waiting_for_command = 0;
- }
- break;
-
- case 0x06:
- if (DSP2_op06haslen)
- {
- DSP2_op06haslen = 0;
- DSP2_out_count = DSP2_op06len;
- DSP2_op06();
- }
- else
- {
- DSP2_op06len = DSP2_parameters[0];
- DSP2_in_index = 0;
- DSP2_in_count = DSP2_op06len;
- DSP2_op06haslen = 1;
- if (data)
- DSP2_waiting_for_command = 0;
- }
- break;
-
- case 0x07: break;
- case 0x08: break;
-
- case 0x09:
- DSP2_op09();
- break;
-
- case 0x0d:
- if (DSP2_op0dhaslen)
- {
- DSP2_op0dhaslen = 0;
- DSP2_out_count = DSP2_op0doutlen;
- DSP2_op0d();
- }
- else
- {
- DSP2_op0dinlen = DSP2_parameters[0];
- DSP2_op0doutlen = DSP2_parameters[1];
- DSP2_in_index = 0;
- DSP2_in_count = (DSP2_op0dinlen + 1) >> 1;
- DSP2_op0dhaslen = 1;
- if(data)
- DSP2_waiting_for_command = 0;
- }
- break;
-
- case 0x0f:
- break;
+ case 0x01:
+ dsp2_state.out_count = 32;
+ dsp2_op01();
+ break;
+
+ case 0x03:
+ dsp2_op03();
+ break;
+
+ case 0x05:
+ if (dsp2_state.op05haslen)
+ {
+ dsp2_state.op05haslen = 0;
+ dsp2_state.out_count = dsp2_state.op05len;
+ dsp2_op05();
+ }
+ else
+ {
+ dsp2_state.op05len = dsp2_state.parameters[0];
+ dsp2_state.in_index = 0;
+ dsp2_state.in_count = dsp2_state.op05len * 2;
+ dsp2_state.op05haslen = 1;
+ if (data)
+ dsp2_state.waiting_for_command = 0;
+ }
+ break;
+
+ case 0x06:
+ if (dsp2_state.op06haslen)
+ {
+ dsp2_state.op06haslen = 0;
+ dsp2_state.out_count = dsp2_state.op06len;
+ dsp2_op06();
+ }
+ else
+ {
+ dsp2_state.op06len = dsp2_state.parameters[0];
+ dsp2_state.in_index = 0;
+ dsp2_state.in_count = dsp2_state.op06len;
+ dsp2_state.op06haslen = 1;
+ if (data)
+ dsp2_state.waiting_for_command = 0;
+ }
+ break;
+
+ case 0x07: break;
+ case 0x08: break;
+
+ case 0x09:
+ dsp2_op09();
+ break;
+
+ case 0x0d:
+ if (dsp2_state.op0dhaslen)
+ {
+ dsp2_state.op0dhaslen = 0;
+ dsp2_state.out_count = dsp2_state.op0doutlen;
+ dsp2_op0d();
+ }
+ else
+ {
+ dsp2_state.op0dinlen = dsp2_state.parameters[0];
+ dsp2_state.op0doutlen = dsp2_state.parameters[1];
+ dsp2_state.in_index = 0;
+ dsp2_state.in_count = (dsp2_state.op0dinlen + 1) >> 1;
+ dsp2_state.op0dhaslen = 1;
+ if (data)
+ dsp2_state.waiting_for_command = 0;
+ }
+ break;
+
+ case 0x0f:
+ break;
}
}
}
+
+static void dsp2_register_save( running_machine *machine )
+{
+ state_save_register_global(machine, dsp2_state.waiting_for_command);
+ state_save_register_global(machine, dsp2_state.command);
+ state_save_register_global(machine, dsp2_state.in_count);
+ state_save_register_global(machine, dsp2_state.in_index);
+ state_save_register_global(machine, dsp2_state.out_count);
+ state_save_register_global(machine, dsp2_state.out_index);
+
+ state_save_register_global_array(machine, dsp2_state.parameters);
+ state_save_register_global_array(machine, dsp2_state.output);
+
+ state_save_register_global(machine, dsp2_state.op05transparent);
+ state_save_register_global(machine, dsp2_state.op05haslen);
+ state_save_register_global(machine, dsp2_state.op05len);
+ state_save_register_global(machine, dsp2_state.op06haslen);
+ state_save_register_global(machine, dsp2_state.op06len);
+ state_save_register_global(machine, dsp2_state.op09word1);
+ state_save_register_global(machine, dsp2_state.op09word2);
+ state_save_register_global(machine, dsp2_state.op0dhaslen);
+ state_save_register_global(machine, dsp2_state.op0doutlen);
+ state_save_register_global(machine, dsp2_state.op0dinlen);
+}
diff --git a/src/mame/machine/snesdsp3.c b/src/mame/machine/snesdsp3.c
index 3fb621f1f19..8a3d086832d 100644
--- a/src/mame/machine/snesdsp3.c
+++ b/src/mame/machine/snesdsp3.c
@@ -12,670 +12,680 @@
************************************************************************/
-static UINT16 DSP3_DataROM[1024];
+static void dsp3_Command(void);
-static void(*SetDSP3)(void);
-static void DSP3_Command(void);
-
-static UINT16 DSP3_DR;
-static UINT16 DSP3_SR;
-static UINT16 DSP3_MemoryIndex;
-
-static void DSP3_Reset(void)
+struct _snes_dsp3_state
+{
+ UINT16 DR;
+ UINT16 SR;
+ UINT16 MemoryIndex;
+
+ INT16 AddLo;
+ INT16 AddHi;
+ INT16 WinLo;
+ INT16 WinHi;
+ UINT16 Codewords;
+ UINT16 Outwords;
+ UINT16 Symbol;
+ UINT16 BitCount;
+ UINT16 Index;
+ UINT16 Codes[512];
+ UINT16 BitsLeft;
+ UINT16 ReqBits;
+ UINT16 ReqData;
+ UINT16 BitCommand;
+ UINT8 BaseLength;
+ UINT16 BaseCodes;
+ UINT16 BaseCode;
+ UINT8 CodeLengths[8];
+ UINT16 CodeOffsets[8];
+ UINT16 LZCode;
+ UINT8 LZLength;
+
+ UINT16 X;
+ UINT16 Y;
+
+ UINT8 Bitmap[8];
+ UINT8 Bitplane[8];
+ UINT16 BMIndex;
+ UINT16 BPIndex;
+ UINT16 Count;
+
+ INT16 op3e_x;
+ INT16 op3e_y;
+
+ INT16 op1e_terrain[0x2000];
+ INT16 op1e_cost[0x2000];
+ INT16 op1e_weight[0x2000];
+
+ INT16 op1e_cell;
+ INT16 op1e_turn;
+ INT16 op1e_search;
+
+ INT16 op1e_x;
+ INT16 op1e_y;
+
+ INT16 op1e_min_radius;
+ INT16 op1e_max_radius;
+
+ INT16 op1e_max_search_radius;
+ INT16 op1e_max_path_radius;
+
+ INT16 op1e_lcv_radius;
+ INT16 op1e_lcv_steps;
+ INT16 op1e_lcv_turns;
+
+ void(*SetDSP3)(void);
+
+ UINT16 DataROM[1024];
+};
+
+static struct _snes_dsp3_state dsp3_state;
+
+
+static void dsp3_Reset(void)
{
- DSP3_DR = 0x0080;
- DSP3_SR = 0x0084;
- SetDSP3 = &DSP3_Command;
+ dsp3_state.DR = 0x0080;
+ dsp3_state.SR = 0x0084;
+ dsp3_state.SetDSP3 = &dsp3_Command;
}
#ifdef UNUSED_FUNCTION
-void DSP3_MemorySize(void)
+void dsp3_MemorySize(void)
{
- DSP3_DR = 0x0300;
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.DR = 0x0300;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
#endif
-static void DSP3_TestMemory(void)
+static void dsp3_TestMemory(void)
{
- DSP3_DR = 0x0000;
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.DR = 0x0000;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
-static void DSP3_DumpDataROM(void)
+static void dsp3_DumpDataROM(void)
{
- DSP3_DR = DSP3_DataROM[DSP3_MemoryIndex++];
- if (DSP3_MemoryIndex == 1024)
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.DR = dsp3_state.DataROM[dsp3_state.MemoryIndex++];
+ if (dsp3_state.MemoryIndex == 1024)
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
-static void DSP3_MemoryDump(void)
+static void dsp3_MemoryDump(void)
{
- DSP3_MemoryIndex = 0;
- SetDSP3 = &DSP3_DumpDataROM;
- DSP3_DumpDataROM();
+ dsp3_state.MemoryIndex = 0;
+ dsp3_state.SetDSP3 = &dsp3_DumpDataROM;
+ dsp3_DumpDataROM();
}
-static INT16 DSP3_WinLo;
-static INT16 DSP3_WinHi;
-
-static void DSP3_OP06(void)
+static void dsp3_OP06(void)
{
- DSP3_WinLo = (UINT8)(DSP3_DR);
- DSP3_WinHi = (UINT8)(DSP3_DR >> 8);
- DSP3_Reset();
+ dsp3_state.WinLo = (UINT8)(dsp3_state.DR);
+ dsp3_state.WinHi = (UINT8)(dsp3_state.DR >> 8);
+ dsp3_Reset();
}
-static void DSP3_OP03(void)
+static void dsp3_OP03(void)
{
- INT16 Lo = (UINT8)(DSP3_DR);
- INT16 Hi = (UINT8)(DSP3_DR >> 8);
- INT16 Ofs = (DSP3_WinLo * Hi << 1) + (Lo << 1);
- DSP3_DR = Ofs >> 1;
- SetDSP3 = &DSP3_Reset;
+ INT16 Lo = (UINT8)(dsp3_state.DR);
+ INT16 Hi = (UINT8)(dsp3_state.DR >> 8);
+ INT16 Ofs = (dsp3_state.WinLo * Hi << 1) + (Lo << 1);
+ dsp3_state.DR = Ofs >> 1;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
-static INT16 DSP3_AddLo;
-static INT16 DSP3_AddHi;
-
-static void DSP3_OP07_B(void)
+static void dsp3_OP07_B(void)
{
- INT16 Ofs = (DSP3_WinLo * DSP3_AddHi << 1) + (DSP3_AddLo << 1);
- DSP3_DR = Ofs >> 1;
- SetDSP3 = &DSP3_Reset;
+ INT16 Ofs = (dsp3_state.WinLo * dsp3_state.AddHi << 1) + (dsp3_state.AddLo << 1);
+ dsp3_state.DR = Ofs >> 1;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
-static void DSP3_OP07_A(void)
+static void dsp3_OP07_A(void)
{
- INT16 Lo = (UINT8)(DSP3_DR);
- INT16 Hi = (UINT8)(DSP3_DR >> 8);
+ INT16 Lo = (UINT8)(dsp3_state.DR);
+ INT16 Hi = (UINT8)(dsp3_state.DR >> 8);
- if (Lo & 1) Hi += (DSP3_AddLo & 1);
+ if (Lo & 1)
+ Hi += (dsp3_state.AddLo & 1);
- DSP3_AddLo += Lo;
- DSP3_AddHi += Hi;
+ dsp3_state.AddLo += Lo;
+ dsp3_state.AddHi += Hi;
- if (DSP3_AddLo < 0)
- DSP3_AddLo += DSP3_WinLo;
- else
- if (DSP3_AddLo >= DSP3_WinLo)
- DSP3_AddLo -= DSP3_WinLo;
+ if (dsp3_state.AddLo < 0)
+ dsp3_state.AddLo += dsp3_state.WinLo;
+ else if (dsp3_state.AddLo >= dsp3_state.WinLo)
+ dsp3_state.AddLo -= dsp3_state.WinLo;
- if (DSP3_AddHi < 0)
- DSP3_AddHi += DSP3_WinHi;
- else
- if (DSP3_AddHi >= DSP3_WinHi)
- DSP3_AddHi -= DSP3_WinHi;
+ if (dsp3_state.AddHi < 0)
+ dsp3_state.AddHi += dsp3_state.WinHi;
+ else if (dsp3_state.AddHi >= dsp3_state.WinHi)
+ dsp3_state.AddHi -= dsp3_state.WinHi;
- DSP3_DR = DSP3_AddLo | (DSP3_AddHi << 8) | ((DSP3_AddHi >> 8) & 0xff);
- SetDSP3 = &DSP3_OP07_B;
+ dsp3_state.DR = dsp3_state.AddLo | (dsp3_state.AddHi << 8) | ((dsp3_state.AddHi >> 8) & 0xff);
+ dsp3_state.SetDSP3 = &dsp3_OP07_B;
}
-static void DSP3_OP07(void)
+static void dsp3_OP07(void)
{
- UINT32 dataOfs = ((DSP3_DR << 1) + 0x03b2) & 0x03ff;
+ UINT32 dataOfs = ((dsp3_state.DR << 1) + 0x03b2) & 0x03ff;
- DSP3_AddHi = DSP3_DataROM[dataOfs];
- DSP3_AddLo = DSP3_DataROM[dataOfs + 1];
+ dsp3_state.AddHi = dsp3_state.DataROM[dataOfs];
+ dsp3_state.AddLo = dsp3_state.DataROM[dataOfs + 1];
- SetDSP3 = &DSP3_OP07_A;
- DSP3_SR = 0x0080;
+ dsp3_state.SetDSP3 = &dsp3_OP07_A;
+ dsp3_state.SR = 0x0080;
}
-static UINT16 DSP3_Codewords;
-static UINT16 DSP3_Outwords;
-static UINT16 DSP3_Symbol;
-static UINT16 DSP3_BitCount;
-static UINT16 DSP3_Index;
-static UINT16 DSP3_Codes[512];
-static UINT16 DSP3_BitsLeft;
-static UINT16 DSP3_ReqBits;
-static UINT16 DSP3_ReqData;
-static UINT16 DSP3_BitCommand;
-static UINT8 DSP3_BaseLength;
-static UINT16 DSP3_BaseCodes;
-static UINT16 DSP3_BaseCode;
-static UINT8 DSP3_CodeLengths[8];
-static UINT16 DSP3_CodeOffsets[8];
-static UINT16 DSP3_LZCode;
-static UINT8 DSP3_LZLength;
-
-static UINT16 DSP3_X;
-static UINT16 DSP3_Y;
-
-static void DSP3_Coordinate(void)
+static void dsp3_Coordinate(void)
{
- DSP3_Index++;
+ dsp3_state.Index++;
- switch (DSP3_Index)
+ switch (dsp3_state.Index)
{
case 3:
- {
- if (DSP3_DR == 0xffff)
- DSP3_Reset();
- break;
- }
+ if (dsp3_state.DR == 0xffff)
+ dsp3_Reset();
+ break;
case 4:
- {
- DSP3_X = DSP3_DR;
- break;
- }
+ dsp3_state.X = dsp3_state.DR;
+ break;
case 5:
- {
- DSP3_Y = DSP3_DR;
- DSP3_DR = 1;
- break;
- }
+ dsp3_state.Y = dsp3_state.DR;
+ dsp3_state.DR = 1;
+ break;
case 6:
- {
- DSP3_DR = DSP3_X;
- break;
- }
+ dsp3_state.DR = dsp3_state.X;
+ break;
case 7:
- {
- DSP3_DR = DSP3_Y;
- DSP3_Index = 0;
- break;
- }
+ dsp3_state.DR = dsp3_state.Y;
+ dsp3_state.Index = 0;
+ break;
}
}
-static UINT8 DSP3_Bitmap[8];
-static UINT8 DSP3_Bitplane[8];
-static UINT16 DSP3_BMIndex;
-static UINT16 DSP3_BPIndex;
-static UINT16 DSP3_Count;
-
-static void DSP3_Convert_A(void)
+static void dsp3_Convert_A(void)
{
- if (DSP3_BMIndex < 8)
+ if (dsp3_state.BMIndex < 8)
{
- DSP3_Bitmap[DSP3_BMIndex++] = (UINT8) (DSP3_DR);
- DSP3_Bitmap[DSP3_BMIndex++] = (UINT8) (DSP3_DR >> 8);
+ dsp3_state.Bitmap[dsp3_state.BMIndex++] = (UINT8) (dsp3_state.DR);
+ dsp3_state.Bitmap[dsp3_state.BMIndex++] = (UINT8) (dsp3_state.DR >> 8);
- if (DSP3_BMIndex == 8)
+ if (dsp3_state.BMIndex == 8)
{
- short i, j;
- for (i=0; i < 8; i++)
- for (j=0; j < 8; j++)
+ short i, j;
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
{
- DSP3_Bitplane[j] <<= 1;
- DSP3_Bitplane[j] |= (DSP3_Bitmap[i] >> j) & 1;
+ dsp3_state.Bitplane[j] <<= 1;
+ dsp3_state.Bitplane[j] |= (dsp3_state.Bitmap[i] >> j) & 1;
}
- DSP3_BPIndex = 0;
- DSP3_Count--;
+ dsp3_state.BPIndex = 0;
+ dsp3_state.Count--;
}
}
- if (DSP3_BMIndex == 8)
+ if (dsp3_state.BMIndex == 8)
{
- if (DSP3_BPIndex == 8)
+ if (dsp3_state.BPIndex == 8)
{
- if (!DSP3_Count) DSP3_Reset();
- DSP3_BMIndex = 0;
+ if (!dsp3_state.Count)
+ dsp3_Reset();
+ dsp3_state.BMIndex = 0;
}
else
{
- DSP3_DR = DSP3_Bitplane[DSP3_BPIndex++];
- DSP3_DR |= DSP3_Bitplane[DSP3_BPIndex++] << 8;
+ dsp3_state.DR = dsp3_state.Bitplane[dsp3_state.BPIndex++];
+ dsp3_state.DR |= dsp3_state.Bitplane[dsp3_state.BPIndex++] << 8;
}
}
}
-static void DSP3_Convert(void)
+static void dsp3_Convert(void)
{
- DSP3_Count = DSP3_DR;
- DSP3_BMIndex = 0;
- SetDSP3 = &DSP3_Convert_A;
+ dsp3_state.Count = dsp3_state.DR;
+ dsp3_state.BMIndex = 0;
+ dsp3_state.SetDSP3 = &dsp3_Convert_A;
}
-static UINT8 DSP3_GetBits(UINT8 Count)
+static UINT8 dsp3_GetBits(UINT8 Count)
{
- if (!DSP3_BitsLeft)
+ if (!dsp3_state.BitsLeft)
{
- DSP3_BitsLeft = Count;
- DSP3_ReqBits = 0;
+ dsp3_state.BitsLeft = Count;
+ dsp3_state.ReqBits = 0;
}
do {
- if (!DSP3_BitCount)
+ if (!dsp3_state.BitCount)
{
- DSP3_SR = 0xC0;
+ dsp3_state.SR = 0xC0;
return 0;
}
- DSP3_ReqBits <<= 1;
- if (DSP3_ReqData & 0x8000) DSP3_ReqBits++;
- DSP3_ReqData <<= 1;
+ dsp3_state.ReqBits <<= 1;
+ if (dsp3_state.ReqData & 0x8000)
+ dsp3_state.ReqBits++;
+ dsp3_state.ReqData <<= 1;
- DSP3_BitCount--;
- DSP3_BitsLeft--;
+ dsp3_state.BitCount--;
+ dsp3_state.BitsLeft--;
- } while (DSP3_BitsLeft);
+ } while (dsp3_state.BitsLeft);
return 1;
}
-static void DSP3_Decode_Data(void)
+static void dsp3_Decode_Data(void)
{
- if (!DSP3_BitCount)
+ if (!dsp3_state.BitCount)
{
- if (DSP3_SR & 0x40)
+ if (dsp3_state.SR & 0x40)
{
- DSP3_ReqData = DSP3_DR;
- DSP3_BitCount += 16;
+ dsp3_state.ReqData = dsp3_state.DR;
+ dsp3_state.BitCount += 16;
}
else
{
- DSP3_SR = 0xC0;
+ dsp3_state.SR = 0xC0;
return;
}
}
- if (DSP3_LZCode == 1)
+ if (dsp3_state.LZCode == 1)
{
- if (!DSP3_GetBits(1))
+ if (!dsp3_GetBits(1))
return;
- if (DSP3_ReqBits)
- DSP3_LZLength = 12;
+ if (dsp3_state.ReqBits)
+ dsp3_state.LZLength = 12;
else
- DSP3_LZLength = 8;
+ dsp3_state.LZLength = 8;
- DSP3_LZCode++;
+ dsp3_state.LZCode++;
}
- if (DSP3_LZCode == 2)
+ if (dsp3_state.LZCode == 2)
{
- if (!DSP3_GetBits(DSP3_LZLength))
+ if (!dsp3_GetBits(dsp3_state.LZLength))
return;
- DSP3_LZCode = 0;
- DSP3_Outwords--;
- if (!DSP3_Outwords) SetDSP3 = &DSP3_Reset;
+ dsp3_state.LZCode = 0;
+ dsp3_state.Outwords--;
+ if (!dsp3_state.Outwords) dsp3_state.SetDSP3 = &dsp3_Reset;
- DSP3_SR = 0x80;
- DSP3_DR = DSP3_ReqBits;
+ dsp3_state.SR = 0x80;
+ dsp3_state.DR = dsp3_state.ReqBits;
return;
}
- if (DSP3_BaseCode == 0xffff)
+ if (dsp3_state.BaseCode == 0xffff)
{
- if (!DSP3_GetBits(DSP3_BaseLength))
+ if (!dsp3_GetBits(dsp3_state.BaseLength))
return;
- DSP3_BaseCode = DSP3_ReqBits;
+ dsp3_state.BaseCode = dsp3_state.ReqBits;
}
- if (!DSP3_GetBits(DSP3_CodeLengths[DSP3_BaseCode]))
+ if (!dsp3_GetBits(dsp3_state.CodeLengths[dsp3_state.BaseCode]))
return;
- DSP3_Symbol = DSP3_Codes[DSP3_CodeOffsets[DSP3_BaseCode] + DSP3_ReqBits];
- DSP3_BaseCode = 0xffff;
+ dsp3_state.Symbol = dsp3_state.Codes[dsp3_state.CodeOffsets[dsp3_state.BaseCode] + dsp3_state.ReqBits];
+ dsp3_state.BaseCode = 0xffff;
- if (DSP3_Symbol & 0xff00)
+ if (dsp3_state.Symbol & 0xff00)
{
- DSP3_Symbol += 0x7f02;
- DSP3_LZCode++;
+ dsp3_state.Symbol += 0x7f02;
+ dsp3_state.LZCode++;
}
else
{
- DSP3_Outwords--;
- if (!DSP3_Outwords)
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.Outwords--;
+ if (!dsp3_state.Outwords)
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
- DSP3_SR = 0x80;
- DSP3_DR = DSP3_Symbol;
+ dsp3_state.SR = 0x80;
+ dsp3_state.DR = dsp3_state.Symbol;
}
-static void DSP3_Decode_Tree(void)
+static void dsp3_Decode_Tree(void)
{
- if (!DSP3_BitCount)
+ if (!dsp3_state.BitCount)
{
- DSP3_ReqData = DSP3_DR;
- DSP3_BitCount += 16;
+ dsp3_state.ReqData = dsp3_state.DR;
+ dsp3_state.BitCount += 16;
}
- if (!DSP3_BaseCodes)
+ if (!dsp3_state.BaseCodes)
{
- DSP3_GetBits(1);
- if (DSP3_ReqBits)
+ dsp3_GetBits(1);
+ if (dsp3_state.ReqBits)
{
- DSP3_BaseLength = 3;
- DSP3_BaseCodes = 8;
+ dsp3_state.BaseLength = 3;
+ dsp3_state.BaseCodes = 8;
}
else
{
- DSP3_BaseLength = 2;
- DSP3_BaseCodes = 4;
+ dsp3_state.BaseLength = 2;
+ dsp3_state.BaseCodes = 4;
}
}
- while (DSP3_BaseCodes)
+ while (dsp3_state.BaseCodes)
{
- if (!DSP3_GetBits(3))
+ if (!dsp3_GetBits(3))
return;
- DSP3_ReqBits++;
+ dsp3_state.ReqBits++;
- DSP3_CodeLengths[DSP3_Index] = (UINT8) DSP3_ReqBits;
- DSP3_CodeOffsets[DSP3_Index] = DSP3_Symbol;
- DSP3_Index++;
+ dsp3_state.CodeLengths[dsp3_state.Index] = (UINT8) dsp3_state.ReqBits;
+ dsp3_state.CodeOffsets[dsp3_state.Index] = dsp3_state.Symbol;
+ dsp3_state.Index++;
- DSP3_Symbol += 1 << DSP3_ReqBits;
- DSP3_BaseCodes--;
+ dsp3_state.Symbol += 1 << dsp3_state.ReqBits;
+ dsp3_state.BaseCodes--;
}
- DSP3_BaseCode = 0xffff;
- DSP3_LZCode = 0;
+ dsp3_state.BaseCode = 0xffff;
+ dsp3_state.LZCode = 0;
- SetDSP3 = &DSP3_Decode_Data;
- if (DSP3_BitCount) DSP3_Decode_Data();
+ dsp3_state.SetDSP3 = &dsp3_Decode_Data;
+ if (dsp3_state.BitCount)
+ dsp3_Decode_Data();
}
-static void DSP3_Decode_Symbols(void)
+static void dsp3_Decode_Symbols(void)
{
- DSP3_ReqData = DSP3_DR;
- DSP3_BitCount += 16;
+ dsp3_state.ReqData = dsp3_state.DR;
+ dsp3_state.BitCount += 16;
do {
- if (DSP3_BitCommand == 0xffff)
+ if (dsp3_state.BitCommand == 0xffff)
{
- if (!DSP3_GetBits(2)) return;
- DSP3_BitCommand = DSP3_ReqBits;
+ if (!dsp3_GetBits(2)) return;
+ dsp3_state.BitCommand = dsp3_state.ReqBits;
}
- switch (DSP3_BitCommand)
+ switch (dsp3_state.BitCommand)
{
case 0:
{
- if (!DSP3_GetBits(9)) return;
- DSP3_Symbol = DSP3_ReqBits;
+ if (!dsp3_GetBits(9)) return;
+ dsp3_state.Symbol = dsp3_state.ReqBits;
break;
}
case 1:
{
- DSP3_Symbol++;
+ dsp3_state.Symbol++;
break;
}
case 2:
{
- if (!DSP3_GetBits(1)) return;
- DSP3_Symbol += 2 + DSP3_ReqBits;
+ if (!dsp3_GetBits(1)) return;
+ dsp3_state.Symbol += 2 + dsp3_state.ReqBits;
break;
}
case 3:
{
- if (!DSP3_GetBits(4)) return;
- DSP3_Symbol += 4 + DSP3_ReqBits;
+ if (!dsp3_GetBits(4)) return;
+ dsp3_state.Symbol += 4 + dsp3_state.ReqBits;
break;
}
}
- DSP3_BitCommand = 0xffff;
+ dsp3_state.BitCommand = 0xffff;
- DSP3_Codes[DSP3_Index++] = DSP3_Symbol;
- DSP3_Codewords--;
+ dsp3_state.Codes[dsp3_state.Index++] = dsp3_state.Symbol;
+ dsp3_state.Codewords--;
- } while (DSP3_Codewords);
+ } while (dsp3_state.Codewords);
- DSP3_Index = 0;
- DSP3_Symbol = 0;
- DSP3_BaseCodes = 0;
+ dsp3_state.Index = 0;
+ dsp3_state.Symbol = 0;
+ dsp3_state.BaseCodes = 0;
- SetDSP3 = &DSP3_Decode_Tree;
- if (DSP3_BitCount) DSP3_Decode_Tree();
+ dsp3_state.SetDSP3 = &dsp3_Decode_Tree;
+ if (dsp3_state.BitCount) dsp3_Decode_Tree();
}
-static void DSP3_Decode_A(void)
+static void dsp3_Decode_A(void)
{
- DSP3_Outwords = DSP3_DR;
- SetDSP3 = &DSP3_Decode_Symbols;
- DSP3_BitCount = 0;
- DSP3_BitsLeft = 0;
- DSP3_Symbol = 0;
- DSP3_Index = 0;
- DSP3_BitCommand = 0xffff;
- DSP3_SR = 0xC0;
+ dsp3_state.Outwords = dsp3_state.DR;
+ dsp3_state.SetDSP3 = &dsp3_Decode_Symbols;
+ dsp3_state.BitCount = 0;
+ dsp3_state.BitsLeft = 0;
+ dsp3_state.Symbol = 0;
+ dsp3_state.Index = 0;
+ dsp3_state.BitCommand = 0xffff;
+ dsp3_state.SR = 0xC0;
}
-static void DSP3_Decode(void)
+static void dsp3_Decode(void)
{
- DSP3_Codewords = DSP3_DR;
- SetDSP3 = &DSP3_Decode_A;
+ dsp3_state.Codewords = dsp3_state.DR;
+ dsp3_state.SetDSP3 = &dsp3_Decode_A;
}
// Opcodes 1E/3E bit-perfect to 'dsp3-intro' log
// src: adapted from SD Gundam X/G-Next
-static INT16 op3e_x;
-static INT16 op3e_y;
-
-static INT16 op1e_terrain[0x2000];
-static INT16 op1e_cost[0x2000];
-static INT16 op1e_weight[0x2000];
-
-static INT16 op1e_cell;
-static INT16 op1e_turn;
-static INT16 op1e_search;
-
-static INT16 op1e_x;
-static INT16 op1e_y;
-
-static INT16 op1e_min_radius;
-static INT16 op1e_max_radius;
-
-static INT16 op1e_max_search_radius;
-static INT16 op1e_max_path_radius;
-
-static INT16 op1e_lcv_radius;
-static INT16 op1e_lcv_steps;
-static INT16 op1e_lcv_turns;
-
-static void DSP3_OP3E(void)
+static void dsp3_OP3E(void)
{
- op3e_x = (UINT8)(DSP3_DR & 0x00ff);
- op3e_y = (UINT8)((DSP3_DR & 0xff00)>>8);
+ dsp3_state.op3e_x = (UINT8)(dsp3_state.DR & 0x00ff);
+ dsp3_state.op3e_y = (UINT8)((dsp3_state.DR & 0xff00) >> 8);
- DSP3_OP03();
+ dsp3_OP03();
- op1e_terrain[ DSP3_DR ] = 0x00;
- op1e_cost[ DSP3_DR ] = 0xff;
- op1e_weight[ DSP3_DR ] = 0;
+ dsp3_state.op1e_terrain[dsp3_state.DR] = 0x00;
+ dsp3_state.op1e_cost[dsp3_state.DR] = 0xff;
+ dsp3_state.op1e_weight[dsp3_state.DR] = 0;
- op1e_max_search_radius = 0;
- op1e_max_path_radius = 0;
+ dsp3_state.op1e_max_search_radius = 0;
+ dsp3_state.op1e_max_path_radius = 0;
}
-static void DSP3_OP1E_A(void);
-static void DSP3_OP1E_A1(void);
-static void DSP3_OP1E_A2(void);
-static void DSP3_OP1E_A3(void);
+static void dsp3_OP1E_A(void);
+static void dsp3_OP1E_A1(void);
+static void dsp3_OP1E_A2(void);
+static void dsp3_OP1E_A3(void);
-static void DSP3_OP1E_B(void);
-static void DSP3_OP1E_B1(void);
-static void DSP3_OP1E_B2(void);
+static void dsp3_OP1E_B(void);
+static void dsp3_OP1E_B1(void);
+static void dsp3_OP1E_B2(void);
-static void DSP3_OP1E_C(void);
-static void DSP3_OP1E_C1(void);
-static void DSP3_OP1E_C2(void);
+static void dsp3_OP1E_C(void);
+static void dsp3_OP1E_C1(void);
+static void dsp3_OP1E_C2(void);
-static void DSP3_OP1E_D( INT16, INT16 *, INT16 * );
-static void DSP3_OP1E_D1( INT16 move, INT16 *lo, INT16 *hi );
+static void dsp3_OP1E_D(INT16, INT16 *, INT16 *);
+static void dsp3_OP1E_D1(INT16 move, INT16 *lo, INT16 *hi);
-static void DSP3_OP1E(void)
+static void dsp3_OP1E(void)
{
int lcv;
- op1e_min_radius = (UINT8)(DSP3_DR & 0x00ff);
- op1e_max_radius = (UINT8)((DSP3_DR & 0xff00)>>8);
+ dsp3_state.op1e_min_radius = (UINT8)(dsp3_state.DR & 0x00ff);
+ dsp3_state.op1e_max_radius = (UINT8)((dsp3_state.DR & 0xff00)>>8);
- if( op1e_min_radius == 0 )
- op1e_min_radius++;
+ if (dsp3_state.op1e_min_radius == 0)
+ dsp3_state.op1e_min_radius++;
- if( op1e_max_search_radius >= op1e_min_radius )
- op1e_min_radius = op1e_max_search_radius+1;
+ if (dsp3_state.op1e_max_search_radius >= dsp3_state.op1e_min_radius)
+ dsp3_state.op1e_min_radius = dsp3_state.op1e_max_search_radius + 1;
- if( op1e_max_radius > op1e_max_search_radius )
- op1e_max_search_radius = op1e_max_radius;
+ if (dsp3_state.op1e_max_radius > dsp3_state.op1e_max_search_radius)
+ dsp3_state.op1e_max_search_radius = dsp3_state.op1e_max_radius;
- op1e_lcv_radius = op1e_min_radius;
- op1e_lcv_steps = op1e_min_radius;
+ dsp3_state.op1e_lcv_radius = dsp3_state.op1e_min_radius;
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_min_radius;
- op1e_lcv_turns = 6;
- op1e_turn = 0;
+ dsp3_state.op1e_lcv_turns = 6;
+ dsp3_state.op1e_turn = 0;
- op1e_x = op3e_x;
- op1e_y = op3e_y;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
- for( lcv = 0; lcv < op1e_min_radius; lcv++ )
- DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
+ for (lcv = 0; lcv < dsp3_state.op1e_min_radius; lcv++)
+ dsp3_OP1E_D(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
- DSP3_OP1E_A();
+ dsp3_OP1E_A();
}
-static void DSP3_OP1E_A(void)
+static void dsp3_OP1E_A(void)
{
int lcv;
- if( op1e_lcv_steps == 0 ) {
- op1e_lcv_radius++;
+ if (dsp3_state.op1e_lcv_steps == 0)
+ {
+ dsp3_state.op1e_lcv_radius++;
- op1e_lcv_steps = op1e_lcv_radius;
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_lcv_radius;
- op1e_x = op3e_x;
- op1e_y = op3e_y;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
- for( lcv = 0; lcv < op1e_lcv_radius; lcv++ )
- DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
+ for (lcv = 0; lcv < dsp3_state.op1e_lcv_radius; lcv++)
+ dsp3_OP1E_D(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
}
- if( op1e_lcv_radius > op1e_max_radius ) {
- op1e_turn++;
- op1e_lcv_turns--;
+ if (dsp3_state.op1e_lcv_radius > dsp3_state.op1e_max_radius)
+ {
+ dsp3_state.op1e_turn++;
+ dsp3_state.op1e_lcv_turns--;
- op1e_lcv_radius = op1e_min_radius;
- op1e_lcv_steps = op1e_min_radius;
+ dsp3_state.op1e_lcv_radius = dsp3_state.op1e_min_radius;
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_min_radius;
- op1e_x = op3e_x;
- op1e_y = op3e_y;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
- for( lcv = 0; lcv < op1e_min_radius; lcv++ )
- DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
+ for (lcv = 0; lcv < dsp3_state.op1e_min_radius; lcv++)
+ dsp3_OP1E_D(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
}
- if( op1e_lcv_turns == 0 ) {
- DSP3_DR = 0xffff;
- DSP3_SR = 0x0080;
- SetDSP3 = &DSP3_OP1E_B;
+ if (dsp3_state.op1e_lcv_turns == 0)
+ {
+ dsp3_state.DR = 0xffff;
+ dsp3_state.SR = 0x0080;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_B;
return;
}
- DSP3_DR = (UINT8)(op1e_x) | ((UINT8)(op1e_y)<<8);
- DSP3_OP03();
+ dsp3_state.DR = (UINT8)(dsp3_state.op1e_x) | ((UINT8)(dsp3_state.op1e_y) << 8);
+ dsp3_OP03();
- op1e_cell = DSP3_DR;
+ dsp3_state.op1e_cell = dsp3_state.DR;
- DSP3_SR = 0x0080;
- SetDSP3 = &DSP3_OP1E_A1;
+ dsp3_state.SR = 0x0080;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_A1;
}
-static void DSP3_OP1E_A1(void)
+static void dsp3_OP1E_A1(void)
{
- DSP3_SR = 0x0084;
- SetDSP3 = &DSP3_OP1E_A2;
+ dsp3_state.SR = 0x0084;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_A2;
}
-static void DSP3_OP1E_A2(void)
+static void dsp3_OP1E_A2(void)
{
- op1e_terrain[ op1e_cell ] = (UINT8)(DSP3_DR & 0x00ff);
+ dsp3_state.op1e_terrain[dsp3_state.op1e_cell] = (UINT8)(dsp3_state.DR & 0x00ff);
- DSP3_SR = 0x0084;
- SetDSP3 = &DSP3_OP1E_A3;
+ dsp3_state.SR = 0x0084;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_A3;
}
-static void DSP3_OP1E_A3(void)
+static void dsp3_OP1E_A3(void)
{
- op1e_cost[ op1e_cell ] = (UINT8)(DSP3_DR & 0x00ff);
+ dsp3_state.op1e_cost[dsp3_state.op1e_cell] = (UINT8)(dsp3_state.DR & 0x00ff);
- if( op1e_lcv_radius == 1 ) {
- if( op1e_terrain[ op1e_cell ] & 1 ) {
- op1e_weight[ op1e_cell ] = 0xff;
- } else {
- op1e_weight[ op1e_cell ] = op1e_cost[ op1e_cell ];
+ if (dsp3_state.op1e_lcv_radius == 1)
+ {
+ if (dsp3_state.op1e_terrain[dsp3_state.op1e_cell] & 1)
+ {
+ dsp3_state.op1e_weight[dsp3_state.op1e_cell] = 0xff;
+ }
+ else
+ {
+ dsp3_state.op1e_weight[dsp3_state.op1e_cell] = dsp3_state.op1e_cost[dsp3_state.op1e_cell];
}
}
- else {
- op1e_weight[ op1e_cell ] = 0xff;
+ else
+ {
+ dsp3_state.op1e_weight[dsp3_state.op1e_cell] = 0xff;
}
- DSP3_OP1E_D( (INT16)(op1e_turn+2), &op1e_x, &op1e_y );
- op1e_lcv_steps--;
+ dsp3_OP1E_D((INT16)(dsp3_state.op1e_turn + 2), &dsp3_state.op1e_x, &dsp3_state.op1e_y);
+ dsp3_state.op1e_lcv_steps--;
- DSP3_SR = 0x0080;
- DSP3_OP1E_A();
+ dsp3_state.SR = 0x0080;
+ dsp3_OP1E_A();
}
-static void DSP3_OP1E_B(void)
+static void dsp3_OP1E_B(void)
{
- op1e_x = op3e_x;
- op1e_y = op3e_y;
- op1e_lcv_radius = 1;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
+ dsp3_state.op1e_lcv_radius = 1;
- op1e_search = 0;
+ dsp3_state.op1e_search = 0;
- DSP3_OP1E_B1();
+ dsp3_OP1E_B1();
- SetDSP3 = &DSP3_OP1E_C;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_C;
}
-static void DSP3_OP1E_B1(void)
+static void dsp3_OP1E_B1(void)
{
- while( op1e_lcv_radius < op1e_max_radius ) {
- op1e_y--;
+ while (dsp3_state.op1e_lcv_radius < dsp3_state.op1e_max_radius)
+ {
+ dsp3_state.op1e_y--;
- op1e_lcv_turns = 6;
- op1e_turn = 5;
+ dsp3_state.op1e_lcv_turns = 6;
+ dsp3_state.op1e_turn = 5;
- while( op1e_lcv_turns ) {
- op1e_lcv_steps = op1e_lcv_radius;
+ while (dsp3_state.op1e_lcv_turns)
+ {
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_lcv_radius;
- while( op1e_lcv_steps ) {
- DSP3_OP1E_D1( op1e_turn, &op1e_x, &op1e_y );
+ while (dsp3_state.op1e_lcv_steps)
+ {
+ dsp3_OP1E_D1(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
- if( 0 <= op1e_y && op1e_y < DSP3_WinHi &&
- 0 <= op1e_x && op1e_x < DSP3_WinLo ) {
- DSP3_DR = (UINT8)(op1e_x) | ((UINT8)(op1e_y)<<8);
- DSP3_OP03();
+ if (0 <= dsp3_state.op1e_y && dsp3_state.op1e_y < dsp3_state.WinHi &&
+ 0 <= dsp3_state.op1e_x && dsp3_state.op1e_x < dsp3_state.WinLo )
+ {
+ dsp3_state.DR = (UINT8)(dsp3_state.op1e_x) | ((UINT8)(dsp3_state.op1e_y) << 8);
+ dsp3_OP03();
- op1e_cell = DSP3_DR;
- if( op1e_cost[ op1e_cell ] < 0x80 &&
- op1e_terrain[ op1e_cell ] < 0x40 ) {
- DSP3_OP1E_B2();
+ dsp3_state.op1e_cell = dsp3_state.DR;
+ if (dsp3_state.op1e_cost[dsp3_state.op1e_cell ] < 0x80 && dsp3_state.op1e_terrain[dsp3_state.op1e_cell] < 0x40)
+ {
+ dsp3_OP1E_B2();
} // end cell perimeter
}
- op1e_lcv_steps--;
+ dsp3_state.op1e_lcv_steps--;
} // end search line
- op1e_turn--;
- if( op1e_turn == 0 ) op1e_turn = 6;
+ dsp3_state.op1e_turn--;
+ if (dsp3_state.op1e_turn == 0)
+ dsp3_state.op1e_turn = 6;
- op1e_lcv_turns--;
+ dsp3_state.op1e_lcv_turns--;
} // end circle search
- op1e_lcv_radius++;
+ dsp3_state.op1e_lcv_radius++;
} // end radius search
}
-static void DSP3_OP1E_B2(void)
+static void dsp3_OP1E_B2(void)
{
INT16 cell;
INT16 path;
@@ -685,162 +695,162 @@ static void DSP3_OP1E_B2(void)
path = 0xff;
lcv_turns = 6;
- while( lcv_turns ) {
- x = op1e_x;
- y = op1e_y;
-
- DSP3_OP1E_D1( lcv_turns, &x, &y );
+ while (lcv_turns)
+ {
+ x = dsp3_state.op1e_x;
+ y = dsp3_state.op1e_y;
- DSP3_DR = (UINT8)(x) | ((UINT8)(y)<<8);
- DSP3_OP03();
+ dsp3_OP1E_D1(lcv_turns, &x, &y);
- cell = DSP3_DR;
+ dsp3_state.DR = (UINT8)(x) | ((UINT8)(y)<<8);
+ dsp3_OP03();
- if( 0 <= y && y < DSP3_WinHi &&
- 0 <= x && x < DSP3_WinLo ) {
+ cell = dsp3_state.DR;
- if( op1e_terrain[ cell ] < 0x80 || op1e_weight[ cell ] == 0 ) {
- if( op1e_weight[ cell ] < path ) {
- path = op1e_weight[ cell ];
- }
+ if (0 <= y && y < dsp3_state.WinHi && 0 <= x && x < dsp3_state.WinLo)
+ {
+ if (dsp3_state.op1e_terrain[cell] < 0x80 || dsp3_state.op1e_weight[cell] == 0)
+ {
+ if (dsp3_state.op1e_weight[cell] < path)
+ path = dsp3_state.op1e_weight[cell];
}
} // end step travel
lcv_turns--;
} // end while turns
- if( path != 0xff ) {
- op1e_weight[ op1e_cell ] = path + op1e_cost[ op1e_cell ];
- }
+ if (path != 0xff)
+ dsp3_state.op1e_weight[dsp3_state.op1e_cell] = path + dsp3_state.op1e_cost[dsp3_state.op1e_cell];
}
-static void DSP3_OP1E_C(void)
+static void dsp3_OP1E_C(void)
{
int lcv;
- op1e_min_radius = (UINT8)(DSP3_DR & 0x00ff);
- op1e_max_radius = (UINT8)((DSP3_DR & 0xff00)>>8);
+ dsp3_state.op1e_min_radius = (UINT8)(dsp3_state.DR & 0x00ff);
+ dsp3_state.op1e_max_radius = (UINT8)((dsp3_state.DR & 0xff00) >> 8);
- if( op1e_min_radius == 0 )
- op1e_min_radius++;
+ if (dsp3_state.op1e_min_radius == 0)
+ dsp3_state.op1e_min_radius++;
- if( op1e_max_path_radius >= op1e_min_radius )
- op1e_min_radius = op1e_max_path_radius+1;
+ if (dsp3_state.op1e_max_path_radius >= dsp3_state.op1e_min_radius)
+ dsp3_state.op1e_min_radius = dsp3_state.op1e_max_path_radius + 1;
- if( op1e_max_radius > op1e_max_path_radius )
- op1e_max_path_radius = op1e_max_radius;
+ if (dsp3_state.op1e_max_radius > dsp3_state.op1e_max_path_radius)
+ dsp3_state.op1e_max_path_radius = dsp3_state.op1e_max_radius;
- op1e_lcv_radius = op1e_min_radius;
- op1e_lcv_steps = op1e_min_radius;
+ dsp3_state.op1e_lcv_radius = dsp3_state.op1e_min_radius;
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_min_radius;
- op1e_lcv_turns = 6;
- op1e_turn = 0;
+ dsp3_state.op1e_lcv_turns = 6;
+ dsp3_state.op1e_turn = 0;
- op1e_x = op3e_x;
- op1e_y = op3e_y;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
- for( lcv = 0; lcv < op1e_min_radius; lcv++ )
- DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
+ for (lcv = 0; lcv < dsp3_state.op1e_min_radius; lcv++)
+ dsp3_OP1E_D(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
- DSP3_OP1E_C1();
+ dsp3_OP1E_C1();
}
-static void DSP3_OP1E_C1(void)
+static void dsp3_OP1E_C1(void)
{
int lcv;
- if( op1e_lcv_steps == 0 ) {
- op1e_lcv_radius++;
+ if (dsp3_state.op1e_lcv_steps == 0)
+ {
+ dsp3_state.op1e_lcv_radius++;
- op1e_lcv_steps = op1e_lcv_radius;
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_lcv_radius;
- op1e_x = op3e_x;
- op1e_y = op3e_y;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
- for( lcv = 0; lcv < op1e_lcv_radius; lcv++ )
- DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
+ for (lcv = 0; lcv < dsp3_state.op1e_lcv_radius; lcv++)
+ dsp3_OP1E_D(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
}
- if( op1e_lcv_radius > op1e_max_radius ) {
- op1e_turn++;
- op1e_lcv_turns--;
+ if (dsp3_state.op1e_lcv_radius > dsp3_state.op1e_max_radius)
+ {
+ dsp3_state.op1e_turn++;
+ dsp3_state.op1e_lcv_turns--;
- op1e_lcv_radius = op1e_min_radius;
- op1e_lcv_steps = op1e_min_radius;
+ dsp3_state.op1e_lcv_radius = dsp3_state.op1e_min_radius;
+ dsp3_state.op1e_lcv_steps = dsp3_state.op1e_min_radius;
- op1e_x = op3e_x;
- op1e_y = op3e_y;
+ dsp3_state.op1e_x = dsp3_state.op3e_x;
+ dsp3_state.op1e_y = dsp3_state.op3e_y;
- for( lcv = 0; lcv < op1e_min_radius; lcv++ )
- DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y );
+ for (lcv = 0; lcv < dsp3_state.op1e_min_radius; lcv++)
+ dsp3_OP1E_D(dsp3_state.op1e_turn, &dsp3_state.op1e_x, &dsp3_state.op1e_y);
}
- if( op1e_lcv_turns == 0 ) {
- DSP3_DR = 0xffff;
- DSP3_SR = 0x0080;
- SetDSP3 = &DSP3_Reset;
+ if (dsp3_state.op1e_lcv_turns == 0)
+ {
+ dsp3_state.DR = 0xffff;
+ dsp3_state.SR = 0x0080;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
return;
}
- DSP3_DR = (UINT8)(op1e_x) | ((UINT8)(op1e_y)<<8);
- DSP3_OP03();
+ dsp3_state.DR = (UINT8)(dsp3_state.op1e_x) | ((UINT8)(dsp3_state.op1e_y) << 8);
+ dsp3_OP03();
- op1e_cell = DSP3_DR;
+ dsp3_state.op1e_cell = dsp3_state.DR;
- DSP3_SR = 0x0080;
- SetDSP3 = &DSP3_OP1E_C2;
+ dsp3_state.SR = 0x0080;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_C2;
}
-static void DSP3_OP1E_C2(void)
+static void dsp3_OP1E_C2(void)
{
- DSP3_DR = op1e_weight[ op1e_cell ];
+ dsp3_state.DR = dsp3_state.op1e_weight[dsp3_state.op1e_cell];
- DSP3_OP1E_D( (INT16)(op1e_turn+2), &op1e_x, &op1e_y );
- op1e_lcv_steps--;
+ dsp3_OP1E_D((INT16)(dsp3_state.op1e_turn + 2), &dsp3_state.op1e_x, &dsp3_state.op1e_y);
+ dsp3_state.op1e_lcv_steps--;
- DSP3_SR = 0x0084;
- SetDSP3 = &DSP3_OP1E_C1;
+ dsp3_state.SR = 0x0084;
+ dsp3_state.SetDSP3 = &dsp3_OP1E_C1;
}
-static void DSP3_OP1E_D( INT16 move, INT16 *lo, INT16 *hi )
+static void dsp3_OP1E_D( INT16 move, INT16 *lo, INT16 *hi )
{
UINT32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
INT16 Lo;
INT16 Hi;
- DSP3_AddHi = DSP3_DataROM[dataOfs];
- DSP3_AddLo = DSP3_DataROM[dataOfs + 1];
+ dsp3_state.AddHi = dsp3_state.DataROM[dataOfs];
+ dsp3_state.AddLo = dsp3_state.DataROM[dataOfs + 1];
Lo = (UINT8)(*lo);
Hi = (UINT8)(*hi);
- if (Lo & 1) Hi += (DSP3_AddLo & 1);
+ if (Lo & 1) Hi += (dsp3_state.AddLo & 1);
- DSP3_AddLo += Lo;
- DSP3_AddHi += Hi;
+ dsp3_state.AddLo += Lo;
+ dsp3_state.AddHi += Hi;
- if (DSP3_AddLo < 0)
- DSP3_AddLo += DSP3_WinLo;
- else
- if (DSP3_AddLo >= DSP3_WinLo)
- DSP3_AddLo -= DSP3_WinLo;
+ if (dsp3_state.AddLo < 0)
+ dsp3_state.AddLo += dsp3_state.WinLo;
+ else if (dsp3_state.AddLo >= dsp3_state.WinLo)
+ dsp3_state.AddLo -= dsp3_state.WinLo;
- if (DSP3_AddHi < 0)
- DSP3_AddHi += DSP3_WinHi;
- else
- if (DSP3_AddHi >= DSP3_WinHi)
- DSP3_AddHi -= DSP3_WinHi;
+ if (dsp3_state.AddHi < 0)
+ dsp3_state.AddHi += dsp3_state.WinHi;
+ else if (dsp3_state.AddHi >= dsp3_state.WinHi)
+ dsp3_state.AddHi -= dsp3_state.WinHi;
- *lo = DSP3_AddLo;
- *hi = DSP3_AddHi;
+ *lo = dsp3_state.AddLo;
+ *hi = dsp3_state.AddHi;
}
-static void DSP3_OP1E_D1( INT16 move, INT16 *lo, INT16 *hi )
+static void dsp3_OP1E_D1( INT16 move, INT16 *lo, INT16 *hi )
{
//UINT32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff;
INT16 Lo;
@@ -854,183 +864,249 @@ static void DSP3_OP1E_D1( INT16 move, INT16 *lo, INT16 *hi )
0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00
};
- if( (*lo) & 1 )
- DSP3_AddHi = HiAdd[ move + 8 ];
+ if ((*lo) & 1)
+ dsp3_state.AddHi = HiAdd[move + 8];
else
- DSP3_AddHi = HiAdd[ move + 0 ];
- DSP3_AddLo = LoAdd[ move ];
+ dsp3_state.AddHi = HiAdd[move + 0];
+ dsp3_state.AddLo = LoAdd[move];
Lo = (UINT8)(*lo);
Hi = (UINT8)(*hi);
- if (Lo & 1) Hi += (DSP3_AddLo & 1);
+ if (Lo & 1)
+ Hi += (dsp3_state.AddLo & 1);
- DSP3_AddLo += Lo;
- DSP3_AddHi += Hi;
+ dsp3_state.AddLo += Lo;
+ dsp3_state.AddHi += Hi;
- *lo = DSP3_AddLo;
- *hi = DSP3_AddHi;
+ *lo = dsp3_state.AddLo;
+ *hi = dsp3_state.AddHi;
}
-static void DSP3_OP10(void)
+static void dsp3_OP10(void)
{
- if( DSP3_DR == 0xffff ) {
- DSP3_Reset();
- } else {
+ if (dsp3_state.DR == 0xffff )
+ dsp3_Reset();
+ else
+ {
// absorb 2 bytes
- DSP3_DR = DSP3_DR;
+ dsp3_state.DR = dsp3_state.DR;
}
}
#ifdef UNUSED_FUNCTION
-static void DSP3_OP0C_A(void)
+static void dsp3_OP0C_A(void)
{
// absorb 2 bytes
- DSP3_DR = 0;
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.DR = 0;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
#endif
-static void DSP3_OP0C(void)
+static void dsp3_OP0C(void)
{
// absorb 2 bytes
- DSP3_DR = 0;
- //SetDSP3 = &DSP3_OP0C_A;
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.DR = 0;
+ //dsp3_state.SetDSP3 = &dsp3_OP0C_A;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
-static void DSP3_OP1C_C(void)
+static void dsp3_OP1C_C(void)
{
// return 2 bytes
- DSP3_DR = 0;
- SetDSP3 = &DSP3_Reset;
+ dsp3_state.DR = 0;
+ dsp3_state.SetDSP3 = &dsp3_Reset;
}
-static void DSP3_OP1C_B(void)
+static void dsp3_OP1C_B(void)
{
// absorb 2 bytes
// return 2 bytes
- DSP3_DR = 0;
- SetDSP3 = &DSP3_OP1C_C;
+ dsp3_state.DR = 0;
+ dsp3_state.SetDSP3 = &dsp3_OP1C_C;
}
-static void DSP3_OP1C_A(void)
+static void dsp3_OP1C_A(void)
{
// absorb 2 bytes
- SetDSP3 = &DSP3_OP1C_B;
+ dsp3_state.SetDSP3 = &dsp3_OP1C_B;
}
-static void DSP3_OP1C(void)
+static void dsp3_OP1C(void)
{
// absorb 2 bytes
- SetDSP3 = &DSP3_OP1C_A;
+ dsp3_state.SetDSP3 = &dsp3_OP1C_A;
}
-static void DSP3_Command(void)
+static void dsp3_Command(void)
{
- if (DSP3_DR < 0x40)
+ if (dsp3_state.DR < 0x40)
{
- switch (DSP3_DR)
+ switch (dsp3_state.DR)
{
- case 0x02: SetDSP3 = &DSP3_Coordinate; break;
- case 0x03: SetDSP3 = &DSP3_OP03; break;
- case 0x06: SetDSP3 = &DSP3_OP06; break;
- case 0x07: SetDSP3 = &DSP3_OP07; return;
- case 0x0c: SetDSP3 = &DSP3_OP0C; break;
- case 0x0f: SetDSP3 = &DSP3_TestMemory; break;
- case 0x10: SetDSP3 = &DSP3_OP10; break;
- case 0x18: SetDSP3 = &DSP3_Convert; break;
- case 0x1c: SetDSP3 = &DSP3_OP1C; break;
- case 0x1e: SetDSP3 = &DSP3_OP1E; break;
- case 0x1f: SetDSP3 = &DSP3_MemoryDump; break;
- case 0x38: SetDSP3 = &DSP3_Decode; break;
- case 0x3e: SetDSP3 = &DSP3_OP3E; break;
- default:
- return;
+ case 0x02: dsp3_state.SetDSP3 = &dsp3_Coordinate; break;
+ case 0x03: dsp3_state.SetDSP3 = &dsp3_OP03; break;
+ case 0x06: dsp3_state.SetDSP3 = &dsp3_OP06; break;
+ case 0x07: dsp3_state.SetDSP3 = &dsp3_OP07; return;
+ case 0x0c: dsp3_state.SetDSP3 = &dsp3_OP0C; break;
+ case 0x0f: dsp3_state.SetDSP3 = &dsp3_TestMemory; break;
+ case 0x10: dsp3_state.SetDSP3 = &dsp3_OP10; break;
+ case 0x18: dsp3_state.SetDSP3 = &dsp3_Convert; break;
+ case 0x1c: dsp3_state.SetDSP3 = &dsp3_OP1C; break;
+ case 0x1e: dsp3_state.SetDSP3 = &dsp3_OP1E; break;
+ case 0x1f: dsp3_state.SetDSP3 = &dsp3_MemoryDump; break;
+ case 0x38: dsp3_state.SetDSP3 = &dsp3_Decode; break;
+ case 0x3e: dsp3_state.SetDSP3 = &dsp3_OP3E; break;
+ default: return;
}
- DSP3_SR = 0x0080;
- DSP3_Index = 0;
+
+ dsp3_state.SR = 0x0080;
+ dsp3_state.Index = 0;
}
}
-static void DSP3_write( UINT16 dsp3_address, UINT8 dsp3_byte )
+static void dsp3_write( UINT16 dsp3_address, UINT8 dsp3_byte )
{
- if (dsp3_address < 0xC000)
- {
- if (DSP3_SR & 0x04)
+ if (dsp3_address < 0xC000)
+ {
+ if (dsp3_state.SR & 0x04)
{
- DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte;
- (*SetDSP3)();
+ dsp3_state.DR = (dsp3_state.DR & 0xff00) + dsp3_byte;
+ (*dsp3_state.SetDSP3)();
}
else
{
- DSP3_SR ^= 0x10;
+ dsp3_state.SR ^= 0x10;
- if (DSP3_SR & 0x10)
- DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte;
+ if (dsp3_state.SR & 0x10)
+ dsp3_state.DR = (dsp3_state.DR & 0xff00) + dsp3_byte;
else
{
- DSP3_DR = (DSP3_DR & 0x00ff) + (dsp3_byte << 8);
- (*SetDSP3)();
+ dsp3_state.DR = (dsp3_state.DR & 0x00ff) + (dsp3_byte << 8);
+ (*dsp3_state.SetDSP3)();
}
}
- }
+ }
}
-static UINT8 DSP3_read( UINT16 dsp3_address )
+static UINT8 dsp3_read( UINT16 dsp3_address )
{
- UINT8 value;
- if (dsp3_address < 0xC000)
- {
- if (DSP3_SR & 0x04)
+ UINT8 value;
+ if (dsp3_address < 0xC000)
+ {
+ if (dsp3_state.SR & 0x04)
{
- value = (UINT8) DSP3_DR;
- (*SetDSP3)();
+ value = (UINT8) dsp3_state.DR;
+ (*dsp3_state.SetDSP3)();
}
else
{
- DSP3_SR ^= 0x10;
+ dsp3_state.SR ^= 0x10;
- if (DSP3_SR & 0x10)
- value = (UINT8) (DSP3_DR);
+ if (dsp3_state.SR & 0x10)
+ value = (UINT8) (dsp3_state.DR);
else
{
- value = (UINT8) (DSP3_DR >> 8);
- (*SetDSP3)();
+ value = (UINT8) (dsp3_state.DR >> 8);
+ (*dsp3_state.SetDSP3)();
}
}
- }
- else
- {
- value = (UINT8) DSP3_SR;
- }
+ }
+ else
+ {
+ value = (UINT8) dsp3_state.SR;
+ }
+
+ return value;
+}
+
+static void dsp3_register_save( running_machine *machine )
+{
+ state_save_register_global(machine, dsp3_state.DR);
+ state_save_register_global(machine, dsp3_state.SR);
+ state_save_register_global(machine, dsp3_state.MemoryIndex);
+
+ state_save_register_global(machine, dsp3_state.AddLo);
+ state_save_register_global(machine, dsp3_state.AddHi);
+ state_save_register_global(machine, dsp3_state.WinLo);
+ state_save_register_global(machine, dsp3_state.WinHi);
+ state_save_register_global(machine, dsp3_state.Codewords);
+ state_save_register_global(machine, dsp3_state.Outwords);
+ state_save_register_global(machine, dsp3_state.Symbol);
+ state_save_register_global(machine, dsp3_state.BitCount);
+ state_save_register_global(machine, dsp3_state.Index);
+ state_save_register_global_array(machine, dsp3_state.Codes);
+ state_save_register_global(machine, dsp3_state.BitsLeft);
+ state_save_register_global(machine, dsp3_state.ReqBits);
+ state_save_register_global(machine, dsp3_state.ReqData);
+ state_save_register_global(machine, dsp3_state.BitCommand);
+ state_save_register_global(machine, dsp3_state.BaseLength);
+ state_save_register_global(machine, dsp3_state.BaseCodes);
+ state_save_register_global(machine, dsp3_state.BaseCode);
+ state_save_register_global_array(machine, dsp3_state.CodeLengths);
+ state_save_register_global_array(machine, dsp3_state.CodeOffsets);
+ state_save_register_global(machine, dsp3_state.LZCode);
+ state_save_register_global(machine, dsp3_state.LZLength);
+
+ state_save_register_global(machine, dsp3_state.X);
+ state_save_register_global(machine, dsp3_state.Y);
+
+ state_save_register_global_array(machine, dsp3_state.Bitmap);
+ state_save_register_global_array(machine, dsp3_state.Bitplane);
+ state_save_register_global(machine, dsp3_state.BMIndex);
+ state_save_register_global(machine, dsp3_state.BPIndex);
+ state_save_register_global(machine, dsp3_state.Count);
+
+ state_save_register_global(machine, dsp3_state.op3e_x);
+ state_save_register_global(machine, dsp3_state.op3e_y);
+
+ state_save_register_global_array(machine, dsp3_state.op1e_terrain);
+ state_save_register_global_array(machine, dsp3_state.op1e_cost);
+ state_save_register_global_array(machine, dsp3_state.op1e_weight);
+
+ state_save_register_global(machine, dsp3_state.op1e_cell);
+ state_save_register_global(machine, dsp3_state.op1e_turn);
+ state_save_register_global(machine, dsp3_state.op1e_search);
+
+ state_save_register_global(machine, dsp3_state.op1e_x);
+ state_save_register_global(machine, dsp3_state.op1e_y);
+
+ state_save_register_global(machine, dsp3_state.op1e_min_radius);
+ state_save_register_global(machine, dsp3_state.op1e_max_radius);
+
+ state_save_register_global(machine, dsp3_state.op1e_max_search_radius);
+ state_save_register_global(machine, dsp3_state.op1e_max_path_radius);
+
+ state_save_register_global(machine, dsp3_state.op1e_lcv_radius);
+ state_save_register_global(machine, dsp3_state.op1e_lcv_steps);
+ state_save_register_global(machine, dsp3_state.op1e_lcv_turns);
- return value;
}
-static void InitDSP3( running_machine *machine )
+static void dsp3_init( running_machine *machine )
{
UINT32 i;
UINT8 *dspin = memory_region(machine, "addons");
- DSP3_Reset();
// expand the DSP-3 data ROM
- for (i = 0; i < 2048; i+=2)
+ for (i = 0; i < 2048; i += 2)
{
- DSP3_DataROM[i/2] = dspin[0x800 + i] << 8 | dspin[0x800 + i + 1];
+ dsp3_state.DataROM[i / 2] = dspin[0x800 + i] << 8 | dspin[0x800 + i + 1];
}
+
+ dsp3_register_save(machine);
}
diff --git a/src/mame/machine/snesdsp4.c b/src/mame/machine/snesdsp4.c
index f62073b4158..064cc0ffc30 100644
--- a/src/mame/machine/snesdsp4.c
+++ b/src/mame/machine/snesdsp4.c
@@ -27,8 +27,8 @@ Fixed-point math reminder:
#include "snesdsp4.h"
-static struct DSP4_t DSP4;
-static struct DSP4_vars_t DSP4_vars;
+static struct dsp4_t dsp4;
+static struct dsp4_vars_t dsp4_vars;
INLINE UINT16 READ_WORD(UINT8 *addr)
{
@@ -53,22 +53,22 @@ INLINE void WRITE_WORD(UINT8 *addr, UINT16 data)
static INT16 DSP4_READ_WORD( void )
{
- INT16 out;
+ INT16 out;
- out = READ_WORD(DSP4.parameters + DSP4.in_index);
- DSP4.in_index += 2;
+ out = READ_WORD(dsp4.parameters + dsp4.in_index);
+ dsp4.in_index += 2;
- return out;
+ return out;
}
static INT32 DSP4_READ_DWORD( void )
{
- INT32 out;
+ INT32 out;
- out = READ_DWORD(DSP4.parameters + DSP4.in_index);
- DSP4.in_index += 4;
+ out = READ_DWORD(dsp4.parameters + dsp4.in_index);
+ dsp4.in_index += 4;
- return out;
+ return out;
}
@@ -77,36 +77,37 @@ static INT32 DSP4_READ_DWORD( void )
// output protocol
#define DSP4_CLEAR_OUT() \
-{ DSP4.out_count = 0; DSP4.out_index = 0; }
+{ dsp4.out_count = 0; dsp4.out_index = 0; }
#define DSP4_WRITE_BYTE( d ) \
-{ WRITE_WORD( DSP4.output + DSP4.out_count, ( d ) ); DSP4.out_count++; }
+{ WRITE_WORD( dsp4.output + dsp4.out_count, ( d ) ); dsp4.out_count++; }
#define DSP4_WRITE_WORD( d ) \
-{ WRITE_WORD( DSP4.output + DSP4.out_count, ( d ) ); DSP4.out_count += 2; }
+{ WRITE_WORD( dsp4.output + dsp4.out_count, ( d ) ); dsp4.out_count += 2; }
#ifndef MSB_FIRST
#define DSP4_WRITE_16_WORD( d ) \
-{ memcpy(DSP4.output + DSP4.out_count, ( d ), 32); DSP4.out_count += 32; }
+{ memcpy(dsp4.output + dsp4.out_count, ( d ), 32); dsp4.out_count += 32; }
#else
-#define DSP4_WRITE_16_WORD( d ) \
-{ INT16 *p = ( d ), *end = ( d )+16; \
- for (; p != end; p++) \
- { \
- WRITE_WORD( DSP4.output + DSP4.out_count, *p ); \
- } \
- DSP4.out_count += 32; \
+#define DSP4_WRITE_16_WORD( d ) \
+{ \
+ INT16 *p = ( d ), *end = ( d )+16; \
+ for (; p != end; p++) \
+ { \
+ WRITE_WORD( dsp4.output + dsp4.out_count, *p ); \
+ } \
+ dsp4.out_count += 32; \
}
#endif
#ifdef PRINT_OP
#define DSP4_WRITE_DEBUG( x, d ) \
- WRITE_WORD( nop + x, d );
+ WRITE_WORD( nop + x, d );
#endif
#ifdef DEBUG_DSP
#define DSP4_WRITE_DEBUG( x, d ) \
- WRITE_WORD( nop + x, d );
+ WRITE_WORD( nop + x, d );
#endif
//////////////////////////////////////////////////////////////
@@ -114,7 +115,7 @@ static INT32 DSP4_READ_DWORD( void )
// used to wait for dsp i/o
#define DSP4_WAIT( x ) \
- DSP4.in_index = 0; DSP4_vars.DSP4_Logic = x; return;
+ dsp4.in_index = 0; dsp4_vars.Logic = x; return;
//////////////////////////////////////////////////////////////
@@ -142,1041 +143,1041 @@ static const UINT16 div_lut[64] = { 0x0000, 0x8000, 0x4000, 0x2aaa, 0x2000, 0x19
0x0333, 0x031f, 0x030c, 0x02fa, 0x02e8, 0x02d8, 0x02c8, 0x02b9, 0x02aa, 0x029c,
0x028f, 0x0282, 0x0276, 0x026a, 0x025e, 0x0253, 0x0249, 0x023e, 0x0234, 0x022b,
0x0222, 0x0219, 0x0210, 0x0208, };
-static INT16 DSP4_Inverse(INT16 value)
+static INT16 dsp4_Inverse(INT16 value)
{
- // saturate bounds
- if (value < 0)
- {
- value = 0;
- }
- if (value > 63)
- {
- value = 63;
- }
-
- return div_lut[value];
+ // saturate bounds
+ if (value < 0)
+ {
+ value = 0;
+ }
+ if (value > 63)
+ {
+ value = 63;
+ }
+
+ return div_lut[value];
}
//////////////////////////////////////////////////////////////
// Prototype
-static void DSP4_OP0B(UINT8 *draw, INT16 sp_x, INT16 sp_y, INT16 sp_attr, UINT8 size, UINT8 stop);
+static void dsp4_OP0B(UINT8 *draw, INT16 sp_x, INT16 sp_y, INT16 sp_attr, UINT8 size, UINT8 stop);
//////////////////////////////////////////////////////////////
// OP00
-static void DSP4_Multiply(INT16 Multiplicand, INT16 Multiplier, INT32 *Product)
+static void dsp4_Multiply(INT16 Multiplicand, INT16 Multiplier, INT32 *Product)
{
- *Product = (Multiplicand * Multiplier << 1) >> 1;
+ *Product = (Multiplicand * Multiplier << 1) >> 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP01( void )
+static void dsp4_OP01( void )
{
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- case 3:
- goto resume3; break;
- }
-
- ////////////////////////////////////////////////////
- // process initial inputs
-
- // sort inputs
- DSP4_vars.world_y = DSP4_READ_DWORD();
- DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();
- DSP4_vars.viewport_bottom = DSP4_READ_WORD();
- DSP4_vars.world_x = DSP4_READ_DWORD();
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
- DSP4_vars.world_yofs = DSP4_READ_WORD();
- DSP4_vars.world_dy = DSP4_READ_DWORD();
- DSP4_vars.world_dx = DSP4_READ_DWORD();
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_READ_WORD(); // 0x0000
- DSP4_vars.world_xenv = DSP4_READ_DWORD();
- DSP4_vars.world_ddy = DSP4_READ_WORD();
- DSP4_vars.world_ddx = DSP4_READ_WORD();
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
-
- // initial (x,y,offset) at starting DSP4_vars.raster line
- DSP4_vars.view_x1 = (INT16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16);
- DSP4_vars.view_y1 = (INT16)(DSP4_vars.world_y >> 16);
- DSP4_vars.view_xofs1 = (INT16)(DSP4_vars.world_x >> 16);
- DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;
- DSP4_vars.view_turnoff_x = 0;
- DSP4_vars.view_turnoff_dx = 0;
-
- // first DSP4_vars.raster line
- DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];
-
- do
- {
- ////////////////////////////////////////////////////
- // process one iteration of projection
-
- // perspective projection of world (x,y,scroll) points
- // based on the current projection lines
- DSP4_vars.view_x2 = (INT16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ));
- DSP4_vars.view_y2 = (INT16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15);
- DSP4_vars.view_xofs2 = DSP4_vars.view_x2;
- DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;
-
-
- // 1. World x-location before transformation
- // 2. Viewer x-position at the next
- // 3. World y-location before perspective projection
- // 4. Viewer y-position below the horizon
- // 5. Number of DSP4_vars.raster lines drawn in this iteration
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD((UINT16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16));
- DSP4_WRITE_WORD(DSP4_vars.view_x2);
- DSP4_WRITE_WORD((UINT16)(DSP4_vars.world_y >> 16));
- DSP4_WRITE_WORD(DSP4_vars.view_y2);
-
- //////////////////////////////////////////////////////
-
- // SR = 0x00
-
- // determine # of DSP4_vars.raster lines used
- DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2;
-
- // prevent overdraw
- if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])
- DSP4_vars.segments = 0;
- else
- DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;
-
- // don't draw outside the window
- if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])
- {
- DSP4_vars.segments = 0;
-
- // flush remaining DSP4_vars.raster lines
- if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];
- }
-
- // SR = 0x80
-
- DSP4_WRITE_WORD(DSP4_vars.segments);
-
- //////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- INT32 px_dx, py_dy;
- INT32 x_scroll, y_scroll;
-
- // SR = 0x00
-
- // linear interpolation (lerp) between projected points
- px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
- py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
-
- // starting step values
- x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);
- y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);
-
- // SR = 0x80
-
- // rasterize line
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)
- {
- // 1. HDMA memory pointer (bg1)
- // 2. vertical scroll offset ($210E)
- // 3. horizontal scroll offset ($210D)
-
- DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);
- DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
- DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
-
-
- // update memory address
- DSP4_vars.poly_ptr[0][0] -= 4;
-
- // update screen values
- x_scroll += px_dx;
- y_scroll += py_dy;
- }
- }
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ case 3:
+ goto resume3; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // sort inputs
+ dsp4_vars.world_y = DSP4_READ_DWORD();
+ dsp4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][0] = DSP4_READ_WORD();
+ dsp4_vars.viewport_bottom = DSP4_READ_WORD();
+ dsp4_vars.world_x = DSP4_READ_DWORD();
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
+ dsp4_vars.world_yofs = DSP4_READ_WORD();
+ dsp4_vars.world_dy = DSP4_READ_DWORD();
+ dsp4_vars.world_dx = DSP4_READ_DWORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ DSP4_READ_WORD(); // 0x0000
+ dsp4_vars.world_xenv = DSP4_READ_DWORD();
+ dsp4_vars.world_ddy = DSP4_READ_WORD();
+ dsp4_vars.world_ddx = DSP4_READ_WORD();
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+
+ // initial (x,y,offset) at starting dsp4_vars.raster line
+ dsp4_vars.view_x1 = (INT16)((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16);
+ dsp4_vars.view_y1 = (INT16)(dsp4_vars.world_y >> 16);
+ dsp4_vars.view_xofs1 = (INT16)(dsp4_vars.world_x >> 16);
+ dsp4_vars.view_yofs1 = dsp4_vars.world_yofs;
+ dsp4_vars.view_turnoff_x = 0;
+ dsp4_vars.view_turnoff_dx = 0;
+
+ // first dsp4_vars.raster line
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.poly_bottom[0][0];
+
+ do
+ {
+ ////////////////////////////////////////////////////
+ // process one iteration of projection
+
+ // perspective projection of world (x,y,scroll) points
+ // based on the current projection lines
+ dsp4_vars.view_x2 = (INT16)(( ( ( dsp4_vars.world_x + dsp4_vars.world_xenv ) >> 16 ) * dsp4_vars.distance >> 15 ) + ( dsp4_vars.view_turnoff_x * dsp4_vars.distance >> 15 ));
+ dsp4_vars.view_y2 = (INT16)((dsp4_vars.world_y >> 16) * dsp4_vars.distance >> 15);
+ dsp4_vars.view_xofs2 = dsp4_vars.view_x2;
+ dsp4_vars.view_yofs2 = (dsp4_vars.world_yofs * dsp4_vars.distance >> 15) + dsp4_vars.poly_bottom[0][0] - dsp4_vars.view_y2;
+
+
+ // 1. World x-location before transformation
+ // 2. Viewer x-position at the next
+ // 3. World y-location before perspective projection
+ // 4. Viewer y-position below the horizon
+ // 5. Number of dsp4_vars.raster lines drawn in this iteration
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD((UINT16)((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16));
+ DSP4_WRITE_WORD(dsp4_vars.view_x2);
+ DSP4_WRITE_WORD((UINT16)(dsp4_vars.world_y >> 16));
+ DSP4_WRITE_WORD(dsp4_vars.view_y2);
+
+ //////////////////////////////////////////////////////
+
+ // SR = 0x00
+
+ // determine # of dsp4_vars.raster lines used
+ dsp4_vars.segments = dsp4_vars.poly_raster[0][0] - dsp4_vars.view_y2;
+
+ // prevent overdraw
+ if (dsp4_vars.view_y2 >= dsp4_vars.poly_raster[0][0])
+ dsp4_vars.segments = 0;
+ else
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.view_y2;
+
+ // don't draw outside the window
+ if (dsp4_vars.view_y2 < dsp4_vars.poly_top[0][0])
+ {
+ dsp4_vars.segments = 0;
+
+ // flush remaining dsp4_vars.raster lines
+ if (dsp4_vars.view_y1 >= dsp4_vars.poly_top[0][0])
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.poly_top[0][0];
+ }
+
+ // SR = 0x80
+
+ DSP4_WRITE_WORD(dsp4_vars.segments);
+
+ //////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ INT32 px_dx, py_dy;
+ INT32 x_scroll, y_scroll;
+
+ // SR = 0x00
+
+ // linear interpolation (lerp) between projected points
+ px_dx = (dsp4_vars.view_xofs2 - dsp4_vars.view_xofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ py_dy = (dsp4_vars.view_yofs2 - dsp4_vars.view_yofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+
+ // starting step values
+ x_scroll = SEX16(dsp4_vars.poly_cx[0][0] + dsp4_vars.view_xofs1);
+ y_scroll = SEX16(-dsp4_vars.viewport_bottom + dsp4_vars.view_yofs1 + dsp4_vars.view_yofsenv + dsp4_vars.poly_cx[1][0] - dsp4_vars.world_yofs);
+
+ // SR = 0x80
+
+ // rasterize line
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < dsp4_vars.segments; dsp4_vars.lcv++)
+ {
+ // 1. HDMA memory pointer (bg1)
+ // 2. vertical scroll offset ($210E)
+ // 3. horizontal scroll offset ($210D)
+
+ DSP4_WRITE_WORD(dsp4_vars.poly_ptr[0][0]);
+ DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
+ DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
+
+
+ // update memory address
+ dsp4_vars.poly_ptr[0][0] -= 4;
+
+ // update screen values
+ x_scroll += px_dx;
+ y_scroll += py_dy;
+ }
+ }
- ////////////////////////////////////////////////////
- // Post-update
+ ////////////////////////////////////////////////////
+ // Post-update
- // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn
- DSP4_vars.view_x1 = DSP4_vars.view_x2;
- DSP4_vars.view_y1 = DSP4_vars.view_y2;
- DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;
- DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;
+ // update new viewer (x,y,scroll) to last dsp4_vars.raster line drawn
+ dsp4_vars.view_x1 = dsp4_vars.view_x2;
+ dsp4_vars.view_y1 = dsp4_vars.view_y2;
+ dsp4_vars.view_xofs1 = dsp4_vars.view_xofs2;
+ dsp4_vars.view_yofs1 = dsp4_vars.view_yofs2;
- // add deltas for projection lines
- DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx);
- DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy);
+ // add deltas for projection lines
+ dsp4_vars.world_dx += SEX78(dsp4_vars.world_ddx);
+ dsp4_vars.world_dy += SEX78(dsp4_vars.world_ddy);
- // update projection lines
- DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv);
- DSP4_vars.world_y += DSP4_vars.world_dy;
+ // update projection lines
+ dsp4_vars.world_x += (dsp4_vars.world_dx + dsp4_vars.world_xenv);
+ dsp4_vars.world_y += dsp4_vars.world_dy;
- // update road turnoff position
- DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx;
+ // update road turnoff position
+ dsp4_vars.view_turnoff_x += dsp4_vars.view_turnoff_dx;
- ////////////////////////////////////////////////////
- // command check
+ ////////////////////////////////////////////////////
+ // command check
- // scan next command
- DSP4.in_count = 2;
- DSP4_WAIT(1) resume1 :
+ // scan next command
+ dsp4.in_count = 2;
+ DSP4_WAIT(1) resume1 :
- // check for termination
- DSP4_vars.distance = DSP4_READ_WORD();
- if (DSP4_vars.distance == -0x8000)
- break;
+ // check for termination
+ dsp4_vars.distance = DSP4_READ_WORD();
+ if (dsp4_vars.distance == -0x8000)
+ break;
- // road turnoff
- if( (UINT16) DSP4_vars.distance == 0x8001 )
- {
- DSP4.in_count = 6;
- DSP4_WAIT(2) resume2:
+ // road turnoff
+ if( (UINT16) dsp4_vars.distance == 0x8001 )
+ {
+ dsp4.in_count = 6;
+ DSP4_WAIT(2) resume2:
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_vars.view_turnoff_x = DSP4_READ_WORD();
- DSP4_vars.view_turnoff_dx = DSP4_READ_WORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ dsp4_vars.view_turnoff_x = DSP4_READ_WORD();
+ dsp4_vars.view_turnoff_dx = DSP4_READ_WORD();
- // factor in new changes
- DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 );
- DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 );
+ // factor in new changes
+ dsp4_vars.view_x1 += ( dsp4_vars.view_turnoff_x * dsp4_vars.distance >> 15 );
+ dsp4_vars.view_xofs1 += ( dsp4_vars.view_turnoff_x * dsp4_vars.distance >> 15 );
- // update stepping values
- DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx;
+ // update stepping values
+ dsp4_vars.view_turnoff_x += dsp4_vars.view_turnoff_dx;
- DSP4.in_count = 2;
- DSP4_WAIT(1)
- }
+ dsp4.in_count = 2;
+ DSP4_WAIT(1)
+ }
- // already have 2 bytes read
- DSP4.in_count = 6;
- DSP4_WAIT(3) resume3 :
+ // already have 2 bytes read
+ dsp4.in_count = 6;
+ DSP4_WAIT(3) resume3 :
- // inspect inputs
- DSP4_vars.world_ddy = DSP4_READ_WORD();
- DSP4_vars.world_ddx = DSP4_READ_WORD();
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
-
- // no envelope here
- DSP4_vars.world_xenv = 0;
- }
- while (1);
+ // inspect inputs
+ dsp4_vars.world_ddy = DSP4_READ_WORD();
+ dsp4_vars.world_ddx = DSP4_READ_WORD();
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+
+ // no envelope here
+ dsp4_vars.world_xenv = 0;
+ }
+ while (1);
- // terminate op
- DSP4.waiting4command = 1;
+ // terminate op
+ dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP03( void )
+static void dsp4_OP03( void )
{
- DSP4_vars.OAM_RowMax = 33;
- memset(DSP4_vars.OAM_Row, 0, 64);
+ dsp4_vars.OAM_RowMax = 33;
+ memset(dsp4_vars.OAM_Row, 0, 64);
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP05( void )
+static void dsp4_OP05( void )
{
- DSP4_vars.OAM_index = 0;
- DSP4_vars.OAM_bits = 0;
- memset(DSP4_vars.OAM_attr, 0, 32);
- DSP4_vars.sprite_count = 0;
+ dsp4_vars.OAM_index = 0;
+ dsp4_vars.OAM_bits = 0;
+ memset(dsp4_vars.OAM_attr, 0, 32);
+ dsp4_vars.sprite_count = 0;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP06( void )
+static void dsp4_OP06( void )
{
- DSP4_CLEAR_OUT();
- DSP4_WRITE_16_WORD(DSP4_vars.OAM_attr);
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_16_WORD(dsp4_vars.OAM_attr);
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP07( void )
+static void dsp4_OP07( void )
{
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- }
-
- ////////////////////////////////////////////////////
- // sort inputs
-
- DSP4_vars.world_y = DSP4_READ_DWORD();
- DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();
- DSP4_vars.viewport_bottom = DSP4_READ_WORD();
- DSP4_vars.world_x = DSP4_READ_DWORD();
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
- DSP4_vars.world_yofs = DSP4_READ_WORD();
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_vars.view_y2 = DSP4_READ_WORD();
- DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_x2 = DSP4_READ_WORD();
- DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
-
- // initial (x,y,offset) at starting DSP4_vars.raster line
- DSP4_vars.view_x1 = (INT16)(DSP4_vars.world_x >> 16);
- DSP4_vars.view_y1 = (INT16)(DSP4_vars.world_y >> 16);
- DSP4_vars.view_xofs1 = DSP4_vars.view_x1;
- DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;
-
- // first DSP4_vars.raster line
- DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];
-
-
- do
- {
- ////////////////////////////////////////////////////
- // process one iteration of projection
-
- // add shaping
- DSP4_vars.view_x2 += DSP4_vars.view_dx;
- DSP4_vars.view_y2 += DSP4_vars.view_dy;
-
- // vertical scroll calculation
- DSP4_vars.view_xofs2 = DSP4_vars.view_x2;
- DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;
-
- // 1. Viewer x-position at the next
- // 2. Viewer y-position below the horizon
- // 3. Number of DSP4_vars.raster lines drawn in this iteration
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(DSP4_vars.view_x2);
- DSP4_WRITE_WORD(DSP4_vars.view_y2);
-
- //////////////////////////////////////////////////////
-
- // SR = 0x00
-
- // determine # of DSP4_vars.raster lines used
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2;
-
- // prevent overdraw
- if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])
- DSP4_vars.segments = 0;
- else
- DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;
-
- // don't draw outside the window
- if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])
- {
- DSP4_vars.segments = 0;
-
- // flush remaining DSP4_vars.raster lines
- if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];
- }
-
- // SR = 0x80
-
- DSP4_WRITE_WORD(DSP4_vars.segments);
-
- //////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- INT32 px_dx, py_dy;
- INT32 x_scroll, y_scroll;
-
- // SR = 0x00
-
- // linear interpolation (lerp) between projected points
- px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
- py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
-
- // starting step values
- x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);
- y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);
-
- // SR = 0x80
-
- // rasterize line
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)
- {
- // 1. HDMA memory pointer (bg2)
- // 2. vertical scroll offset ($2110)
- // 3. horizontal scroll offset ($210F)
-
- DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);
- DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
- DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
-
- // update memory address
- DSP4_vars.poly_ptr[0][0] -= 4;
-
- // update screen values
- x_scroll += px_dx;
- y_scroll += py_dy;
- }
- }
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // sort inputs
+
+ dsp4_vars.world_y = DSP4_READ_DWORD();
+ dsp4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][0] = DSP4_READ_WORD();
+ dsp4_vars.viewport_bottom = DSP4_READ_WORD();
+ dsp4_vars.world_x = DSP4_READ_DWORD();
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
+ dsp4_vars.world_yofs = DSP4_READ_WORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ dsp4_vars.view_y2 = DSP4_READ_WORD();
+ dsp4_vars.view_dy = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_x2 = DSP4_READ_WORD();
+ dsp4_vars.view_dx = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+
+ // initial (x,y,offset) at starting dsp4_vars.raster line
+ dsp4_vars.view_x1 = (INT16)(dsp4_vars.world_x >> 16);
+ dsp4_vars.view_y1 = (INT16)(dsp4_vars.world_y >> 16);
+ dsp4_vars.view_xofs1 = dsp4_vars.view_x1;
+ dsp4_vars.view_yofs1 = dsp4_vars.world_yofs;
+
+ // first dsp4_vars.raster line
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.poly_bottom[0][0];
+
+
+ do
+ {
+ ////////////////////////////////////////////////////
+ // process one iteration of projection
+
+ // add shaping
+ dsp4_vars.view_x2 += dsp4_vars.view_dx;
+ dsp4_vars.view_y2 += dsp4_vars.view_dy;
+
+ // vertical scroll calculation
+ dsp4_vars.view_xofs2 = dsp4_vars.view_x2;
+ dsp4_vars.view_yofs2 = (dsp4_vars.world_yofs * dsp4_vars.distance >> 15) + dsp4_vars.poly_bottom[0][0] - dsp4_vars.view_y2;
+
+ // 1. Viewer x-position at the next
+ // 2. Viewer y-position below the horizon
+ // 3. Number of dsp4_vars.raster lines drawn in this iteration
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(dsp4_vars.view_x2);
+ DSP4_WRITE_WORD(dsp4_vars.view_y2);
+
+ //////////////////////////////////////////////////////
+
+ // SR = 0x00
+
+ // determine # of dsp4_vars.raster lines used
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.view_y2;
+
+ // prevent overdraw
+ if (dsp4_vars.view_y2 >= dsp4_vars.poly_raster[0][0])
+ dsp4_vars.segments = 0;
+ else
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.view_y2;
+
+ // don't draw outside the window
+ if (dsp4_vars.view_y2 < dsp4_vars.poly_top[0][0])
+ {
+ dsp4_vars.segments = 0;
+
+ // flush remaining dsp4_vars.raster lines
+ if (dsp4_vars.view_y1 >= dsp4_vars.poly_top[0][0])
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.poly_top[0][0];
+ }
+
+ // SR = 0x80
+
+ DSP4_WRITE_WORD(dsp4_vars.segments);
+
+ //////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ INT32 px_dx, py_dy;
+ INT32 x_scroll, y_scroll;
+
+ // SR = 0x00
+
+ // linear interpolation (lerp) between projected points
+ px_dx = (dsp4_vars.view_xofs2 - dsp4_vars.view_xofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ py_dy = (dsp4_vars.view_yofs2 - dsp4_vars.view_yofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+
+ // starting step values
+ x_scroll = SEX16(dsp4_vars.poly_cx[0][0] + dsp4_vars.view_xofs1);
+ y_scroll = SEX16(-dsp4_vars.viewport_bottom + dsp4_vars.view_yofs1 + dsp4_vars.view_yofsenv + dsp4_vars.poly_cx[1][0] - dsp4_vars.world_yofs);
+
+ // SR = 0x80
+
+ // rasterize line
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < dsp4_vars.segments; dsp4_vars.lcv++)
+ {
+ // 1. HDMA memory pointer (bg2)
+ // 2. vertical scroll offset ($2110)
+ // 3. horizontal scroll offset ($210F)
+
+ DSP4_WRITE_WORD(dsp4_vars.poly_ptr[0][0]);
+ DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
+ DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
+
+ // update memory address
+ dsp4_vars.poly_ptr[0][0] -= 4;
+
+ // update screen values
+ x_scroll += px_dx;
+ y_scroll += py_dy;
+ }
+ }
- /////////////////////////////////////////////////////
- // Post-update
+ /////////////////////////////////////////////////////
+ // Post-update
- // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn
- DSP4_vars.view_x1 = DSP4_vars.view_x2;
- DSP4_vars.view_y1 = DSP4_vars.view_y2;
- DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;
- DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;
+ // update new viewer (x,y,scroll) to last dsp4_vars.raster line drawn
+ dsp4_vars.view_x1 = dsp4_vars.view_x2;
+ dsp4_vars.view_y1 = dsp4_vars.view_y2;
+ dsp4_vars.view_xofs1 = dsp4_vars.view_xofs2;
+ dsp4_vars.view_yofs1 = dsp4_vars.view_yofs2;
- ////////////////////////////////////////////////////
- // command check
+ ////////////////////////////////////////////////////
+ // command check
- // scan next command
- DSP4.in_count = 2;
- DSP4_WAIT(1) resume1 :
+ // scan next command
+ dsp4.in_count = 2;
+ DSP4_WAIT(1) resume1 :
- // check for opcode termination
- DSP4_vars.distance = DSP4_READ_WORD();
- if (DSP4_vars.distance == -0x8000)
- break;
+ // check for opcode termination
+ dsp4_vars.distance = DSP4_READ_WORD();
+ if (dsp4_vars.distance == -0x8000)
+ break;
- // already have 2 bytes in queue
- DSP4.in_count = 10;
- DSP4_WAIT(2) resume2 :
+ // already have 2 bytes in queue
+ dsp4.in_count = 10;
+ DSP4_WAIT(2) resume2 :
- // inspect inputs
- DSP4_vars.view_y2 = DSP4_READ_WORD();
- DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_x2 = DSP4_READ_WORD();
- DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
- }
- while (1);
+ // inspect inputs
+ dsp4_vars.view_y2 = DSP4_READ_WORD();
+ dsp4_vars.view_dy = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_x2 = DSP4_READ_WORD();
+ dsp4_vars.view_dx = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+ }
+ while (1);
- DSP4.waiting4command = 1;
+ dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP08( void )
+static void dsp4_OP08( void )
{
- INT16 wleft, wright;
- INT16 view_x[2], view_y[2];
- INT16 envelope[2][2];
-
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- }
-
- ////////////////////////////////////////////////////
- // process initial inputs for two polygons
-
- // clip values
- DSP4_vars.poly_clipRt[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_clipRt[0][1] = DSP4_READ_WORD();
- DSP4_vars.poly_clipRt[1][0] = DSP4_READ_WORD();
- DSP4_vars.poly_clipRt[1][1] = DSP4_READ_WORD();
-
- DSP4_vars.poly_clipLf[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_clipLf[0][1] = DSP4_READ_WORD();
- DSP4_vars.poly_clipLf[1][0] = DSP4_READ_WORD();
- DSP4_vars.poly_clipLf[1][1] = DSP4_READ_WORD();
-
- // unknown (constant) (ex. 1P/2P = $00A6, $00A6, $00A6, $00A6)
- DSP4_READ_WORD();
- DSP4_READ_WORD();
- DSP4_READ_WORD();
- DSP4_READ_WORD();
-
- // unknown (constant) (ex. 1P/2P = $00A5, $00A5, $00A7, $00A7)
- DSP4_READ_WORD();
- DSP4_READ_WORD();
- DSP4_READ_WORD();
- DSP4_READ_WORD();
-
- // polygon centering (left,right)
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[0][1] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][1] = DSP4_READ_WORD();
-
- // HDMA pointer locations
- DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[0][1] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[1][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[1][1] = DSP4_READ_WORD();
-
- // starting DSP4_vars.raster line below the horizon
- DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_bottom[0][1] = DSP4_READ_WORD();
- DSP4_vars.poly_bottom[1][0] = DSP4_READ_WORD();
- DSP4_vars.poly_bottom[1][1] = DSP4_READ_WORD();
-
- // top boundary line to clip
- DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[0][1] = DSP4_READ_WORD();
- DSP4_vars.poly_top[1][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[1][1] = DSP4_READ_WORD();
-
- // unknown
- // (ex. 1P = $2FC8, $0034, $FF5C, $0035)
- //
- // (ex. 2P = $3178, $0034, $FFCC, $0035)
- // (ex. 2P = $2FC8, $0034, $FFCC, $0035)
-
- DSP4_READ_WORD();
- DSP4_READ_WORD();
- DSP4_READ_WORD();
- DSP4_READ_WORD();
-
- // look at guidelines for both polygon shapes
- DSP4_vars.distance = DSP4_READ_WORD();
- view_x[0] = DSP4_READ_WORD();
- view_y[0] = DSP4_READ_WORD();
- view_x[1] = DSP4_READ_WORD();
- view_y[1] = DSP4_READ_WORD();
-
- // envelope shaping guidelines (one frame only)
- envelope[0][0] = DSP4_READ_WORD();
- envelope[0][1] = DSP4_READ_WORD();
- envelope[1][0] = DSP4_READ_WORD();
- envelope[1][1] = DSP4_READ_WORD();
-
- // starting base values to project from
- DSP4_vars.poly_start[0] = view_x[0];
- DSP4_vars.poly_start[1] = view_x[1];
-
- // starting DSP4_vars.raster lines to begin drawing
- DSP4_vars.poly_raster[0][0] = view_y[0];
- DSP4_vars.poly_raster[0][1] = view_y[0];
- DSP4_vars.poly_raster[1][0] = view_y[1];
- DSP4_vars.poly_raster[1][1] = view_y[1];
-
- // starting distances
- DSP4_vars.poly_plane[0] = DSP4_vars.distance;
- DSP4_vars.poly_plane[1] = DSP4_vars.distance;
-
- // SR = 0x00
-
- // re-center coordinates
- wleft = DSP4_vars.poly_cx[0][0] - view_x[0] + envelope[0][0];
- wright = DSP4_vars.poly_cx[0][1] - view_x[0] + envelope[0][1];
-
- // saturate offscreen data for polygon #1
- if (wleft < DSP4_vars.poly_clipLf[0][0])
- {
- wleft = DSP4_vars.poly_clipLf[0][0];
- }
- if (wleft > DSP4_vars.poly_clipRt[0][0])
- {
- wleft = DSP4_vars.poly_clipRt[0][0];
- }
- if (wright < DSP4_vars.poly_clipLf[0][1])
- {
- wright = DSP4_vars.poly_clipLf[0][1];
- }
- if (wright > DSP4_vars.poly_clipRt[0][1])
- {
- wright = DSP4_vars.poly_clipRt[0][1];
- }
-
- // SR = 0x80
-
- // initial output for polygon #1
- DSP4_CLEAR_OUT();
- DSP4_WRITE_BYTE(wleft & 0xff);
- DSP4_WRITE_BYTE(wright & 0xff);
-
-
- do
- {
- INT16 polygon;
- ////////////////////////////////////////////////////
- // command check
-
- // scan next command
- DSP4.in_count = 2;
- DSP4_WAIT(1) resume1 :
-
- // terminate op
- DSP4_vars.distance = DSP4_READ_WORD();
- if (DSP4_vars.distance == -0x8000)
- break;
-
- // already have 2 bytes in queue
- DSP4.in_count = 16;
-
- DSP4_WAIT(2) resume2 :
-
- // look at guidelines for both polygon shapes
- view_x[0] = DSP4_READ_WORD();
- view_y[0] = DSP4_READ_WORD();
- view_x[1] = DSP4_READ_WORD();
- view_y[1] = DSP4_READ_WORD();
-
- // envelope shaping guidelines (one frame only)
- envelope[0][0] = DSP4_READ_WORD();
- envelope[0][1] = DSP4_READ_WORD();
- envelope[1][0] = DSP4_READ_WORD();
- envelope[1][1] = DSP4_READ_WORD();
-
- ////////////////////////////////////////////////////
- // projection begins
-
- // init
- DSP4_CLEAR_OUT();
-
-
- //////////////////////////////////////////////
- // solid polygon renderer - 2 shapes
-
- for (polygon = 0; polygon < 2; polygon++)
- {
- INT32 left_inc, right_inc;
- INT16 x1_final, x2_final;
- INT16 env[2][2];
- INT16 poly;
-
- // SR = 0x00
-
- // # DSP4_vars.raster lines to draw
- DSP4_vars.segments = DSP4_vars.poly_raster[polygon][0] - view_y[polygon];
-
- // prevent overdraw
- if (DSP4_vars.segments > 0)
- {
- // bump drawing cursor
- DSP4_vars.poly_raster[polygon][0] = view_y[polygon];
- DSP4_vars.poly_raster[polygon][1] = view_y[polygon];
- }
- else
- DSP4_vars.segments = 0;
-
- // don't draw outside the window
- if (view_y[polygon] < DSP4_vars.poly_top[polygon][0])
- {
- DSP4_vars.segments = 0;
-
- // flush remaining DSP4_vars.raster lines
- if (view_y[polygon] >= DSP4_vars.poly_top[polygon][0])
- DSP4_vars.segments = view_y[polygon] - DSP4_vars.poly_top[polygon][0];
- }
-
- // SR = 0x80
-
- // tell user how many DSP4_vars.raster structures to read in
- DSP4_WRITE_WORD(DSP4_vars.segments);
-
- // normal parameters
- poly = polygon;
-
- /////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- INT32 win_left, win_right;
+ INT16 wleft, wright;
+ INT16 view_x[2], view_y[2];
+ INT16 envelope[2][2];
+
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs for two polygons
+
+ // clip values
+ dsp4_vars.poly_clipRt[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_clipRt[0][1] = DSP4_READ_WORD();
+ dsp4_vars.poly_clipRt[1][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_clipRt[1][1] = DSP4_READ_WORD();
+
+ dsp4_vars.poly_clipLf[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_clipLf[0][1] = DSP4_READ_WORD();
+ dsp4_vars.poly_clipLf[1][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_clipLf[1][1] = DSP4_READ_WORD();
+
+ // unknown (constant) (ex. 1P/2P = $00A6, $00A6, $00A6, $00A6)
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+
+ // unknown (constant) (ex. 1P/2P = $00A5, $00A5, $00A7, $00A7)
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+
+ // polygon centering (left,right)
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[0][1] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][1] = DSP4_READ_WORD();
+
+ // HDMA pointer locations
+ dsp4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[0][1] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[1][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[1][1] = DSP4_READ_WORD();
+
+ // starting dsp4_vars.raster line below the horizon
+ dsp4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_bottom[0][1] = DSP4_READ_WORD();
+ dsp4_vars.poly_bottom[1][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_bottom[1][1] = DSP4_READ_WORD();
+
+ // top boundary line to clip
+ dsp4_vars.poly_top[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[0][1] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[1][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[1][1] = DSP4_READ_WORD();
+
+ // unknown
+ // (ex. 1P = $2FC8, $0034, $FF5C, $0035)
+ //
+ // (ex. 2P = $3178, $0034, $FFCC, $0035)
+ // (ex. 2P = $2FC8, $0034, $FFCC, $0035)
+
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+ DSP4_READ_WORD();
+
+ // look at guidelines for both polygon shapes
+ dsp4_vars.distance = DSP4_READ_WORD();
+ view_x[0] = DSP4_READ_WORD();
+ view_y[0] = DSP4_READ_WORD();
+ view_x[1] = DSP4_READ_WORD();
+ view_y[1] = DSP4_READ_WORD();
+
+ // envelope shaping guidelines (one frame only)
+ envelope[0][0] = DSP4_READ_WORD();
+ envelope[0][1] = DSP4_READ_WORD();
+ envelope[1][0] = DSP4_READ_WORD();
+ envelope[1][1] = DSP4_READ_WORD();
+
+ // starting base values to project from
+ dsp4_vars.poly_start[0] = view_x[0];
+ dsp4_vars.poly_start[1] = view_x[1];
+
+ // starting dsp4_vars.raster lines to begin drawing
+ dsp4_vars.poly_raster[0][0] = view_y[0];
+ dsp4_vars.poly_raster[0][1] = view_y[0];
+ dsp4_vars.poly_raster[1][0] = view_y[1];
+ dsp4_vars.poly_raster[1][1] = view_y[1];
+
+ // starting distances
+ dsp4_vars.poly_plane[0] = dsp4_vars.distance;
+ dsp4_vars.poly_plane[1] = dsp4_vars.distance;
+
+ // SR = 0x00
+
+ // re-center coordinates
+ wleft = dsp4_vars.poly_cx[0][0] - view_x[0] + envelope[0][0];
+ wright = dsp4_vars.poly_cx[0][1] - view_x[0] + envelope[0][1];
+
+ // saturate offscreen data for polygon #1
+ if (wleft < dsp4_vars.poly_clipLf[0][0])
+ {
+ wleft = dsp4_vars.poly_clipLf[0][0];
+ }
+ if (wleft > dsp4_vars.poly_clipRt[0][0])
+ {
+ wleft = dsp4_vars.poly_clipRt[0][0];
+ }
+ if (wright < dsp4_vars.poly_clipLf[0][1])
+ {
+ wright = dsp4_vars.poly_clipLf[0][1];
+ }
+ if (wright > dsp4_vars.poly_clipRt[0][1])
+ {
+ wright = dsp4_vars.poly_clipRt[0][1];
+ }
+
+ // SR = 0x80
+
+ // initial output for polygon #1
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_BYTE(wleft & 0xff);
+ DSP4_WRITE_BYTE(wright & 0xff);
+
+
+ do
+ {
+ INT16 polygon;
+ ////////////////////////////////////////////////////
+ // command check
+
+ // scan next command
+ dsp4.in_count = 2;
+ DSP4_WAIT(1) resume1 :
+
+ // terminate op
+ dsp4_vars.distance = DSP4_READ_WORD();
+ if (dsp4_vars.distance == -0x8000)
+ break;
+
+ // already have 2 bytes in queue
+ dsp4.in_count = 16;
+
+ DSP4_WAIT(2) resume2 :
+
+ // look at guidelines for both polygon shapes
+ view_x[0] = DSP4_READ_WORD();
+ view_y[0] = DSP4_READ_WORD();
+ view_x[1] = DSP4_READ_WORD();
+ view_y[1] = DSP4_READ_WORD();
+
+ // envelope shaping guidelines (one frame only)
+ envelope[0][0] = DSP4_READ_WORD();
+ envelope[0][1] = DSP4_READ_WORD();
+ envelope[1][0] = DSP4_READ_WORD();
+ envelope[1][1] = DSP4_READ_WORD();
+
+ ////////////////////////////////////////////////////
+ // projection begins
+
+ // init
+ DSP4_CLEAR_OUT();
+
+
+ //////////////////////////////////////////////
+ // solid polygon renderer - 2 shapes
+
+ for (polygon = 0; polygon < 2; polygon++)
+ {
+ INT32 left_inc, right_inc;
+ INT16 x1_final, x2_final;
+ INT16 env[2][2];
+ INT16 poly;
+
+ // SR = 0x00
+
+ // # dsp4_vars.raster lines to draw
+ dsp4_vars.segments = dsp4_vars.poly_raster[polygon][0] - view_y[polygon];
+
+ // prevent overdraw
+ if (dsp4_vars.segments > 0)
+ {
+ // bump drawing cursor
+ dsp4_vars.poly_raster[polygon][0] = view_y[polygon];
+ dsp4_vars.poly_raster[polygon][1] = view_y[polygon];
+ }
+ else
+ dsp4_vars.segments = 0;
+
+ // don't draw outside the window
+ if (view_y[polygon] < dsp4_vars.poly_top[polygon][0])
+ {
+ dsp4_vars.segments = 0;
+
+ // flush remaining dsp4_vars.raster lines
+ if (view_y[polygon] >= dsp4_vars.poly_top[polygon][0])
+ dsp4_vars.segments = view_y[polygon] - dsp4_vars.poly_top[polygon][0];
+ }
+
+ // SR = 0x80
+
+ // tell user how many dsp4_vars.raster structures to read in
+ DSP4_WRITE_WORD(dsp4_vars.segments);
+
+ // normal parameters
+ poly = polygon;
+
+ /////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ INT32 win_left, win_right;
- // road turnoff selection
- if( (UINT16) envelope[ polygon ][ 0 ] == (UINT16) 0xc001 )
- poly = 1;
- else if( envelope[ polygon ][ 1 ] == 0x3fff )
- poly = 1;
+ // road turnoff selection
+ if( (UINT16) envelope[ polygon ][ 0 ] == (UINT16) 0xc001 )
+ poly = 1;
+ else if( envelope[ polygon ][ 1 ] == 0x3fff )
+ poly = 1;
- ///////////////////////////////////////////////
- // left side of polygon
+ ///////////////////////////////////////////////
+ // left side of polygon
- // perspective correction on additional shaping parameters
- env[0][0] = envelope[polygon][0] * DSP4_vars.poly_plane[poly] >> 15;
- env[0][1] = envelope[polygon][0] * DSP4_vars.distance >> 15;
+ // perspective correction on additional shaping parameters
+ env[0][0] = envelope[polygon][0] * dsp4_vars.poly_plane[poly] >> 15;
+ env[0][1] = envelope[polygon][0] * dsp4_vars.distance >> 15;
- // project new shapes (left side)
- x1_final = view_x[poly] + env[0][0];
- x2_final = DSP4_vars.poly_start[poly] + env[0][1];
+ // project new shapes (left side)
+ x1_final = view_x[poly] + env[0][0];
+ x2_final = dsp4_vars.poly_start[poly] + env[0][1];
- // interpolate between projected points with shaping
- left_inc = (x2_final - x1_final) * DSP4_Inverse(DSP4_vars.segments) << 1;
- if (DSP4_vars.segments == 1)
- left_inc = -left_inc;
+ // interpolate between projected points with shaping
+ left_inc = (x2_final - x1_final) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ if (dsp4_vars.segments == 1)
+ left_inc = -left_inc;
- ///////////////////////////////////////////////
- // right side of polygon
+ ///////////////////////////////////////////////
+ // right side of polygon
- // perspective correction on additional shaping parameters
- env[1][0] = envelope[polygon][1] * DSP4_vars.poly_plane[poly] >> 15;;
- env[1][1] = envelope[polygon][1] * DSP4_vars.distance >> 15;
+ // perspective correction on additional shaping parameters
+ env[1][0] = envelope[polygon][1] * dsp4_vars.poly_plane[poly] >> 15;;
+ env[1][1] = envelope[polygon][1] * dsp4_vars.distance >> 15;
- // project new shapes (right side)
- x1_final = view_x[poly] + env[1][0];
- x2_final = DSP4_vars.poly_start[poly] + env[1][1];
+ // project new shapes (right side)
+ x1_final = view_x[poly] + env[1][0];
+ x2_final = dsp4_vars.poly_start[poly] + env[1][1];
- // interpolate between projected points with shaping
- right_inc = (x2_final - x1_final) * DSP4_Inverse(DSP4_vars.segments) << 1;
- if (DSP4_vars.segments == 1)
- right_inc = -right_inc;
+ // interpolate between projected points with shaping
+ right_inc = (x2_final - x1_final) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ if (dsp4_vars.segments == 1)
+ right_inc = -right_inc;
- ///////////////////////////////////////////////
- // update each point on the line
+ ///////////////////////////////////////////////
+ // update each point on the line
- win_left = SEX16(DSP4_vars.poly_cx[polygon][0] - DSP4_vars.poly_start[poly] + env[0][0]);
- win_right = SEX16(DSP4_vars.poly_cx[polygon][1] - DSP4_vars.poly_start[poly] + env[1][0]);
+ win_left = SEX16(dsp4_vars.poly_cx[polygon][0] - dsp4_vars.poly_start[poly] + env[0][0]);
+ win_right = SEX16(dsp4_vars.poly_cx[polygon][1] - dsp4_vars.poly_start[poly] + env[1][0]);
- // update DSP4_vars.distance drawn into world
- DSP4_vars.poly_plane[polygon] = DSP4_vars.distance;
+ // update dsp4_vars.distance drawn into world
+ dsp4_vars.poly_plane[polygon] = dsp4_vars.distance;
- // rasterize line
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)
- {
- INT16 x_left, x_right;
+ // rasterize line
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < dsp4_vars.segments; dsp4_vars.lcv++)
+ {
+ INT16 x_left, x_right;
- // project new coordinates
- win_left += left_inc;
- win_right += right_inc;
+ // project new coordinates
+ win_left += left_inc;
+ win_right += right_inc;
- // grab integer portion, drop fraction (no rounding)
- x_left = (INT16)(win_left >> 16);
- x_right = (INT16)(win_right >> 16);
+ // grab integer portion, drop fraction (no rounding)
+ x_left = (INT16)(win_left >> 16);
+ x_right = (INT16)(win_right >> 16);
- // saturate offscreen data
- if (x_left < DSP4_vars.poly_clipLf[polygon][0])
- x_left = DSP4_vars.poly_clipLf[polygon][0];
- if (x_left > DSP4_vars.poly_clipRt[polygon][0])
- x_left = DSP4_vars.poly_clipRt[polygon][0];
- if (x_right < DSP4_vars.poly_clipLf[polygon][1])
- x_right = DSP4_vars.poly_clipLf[polygon][1];
- if (x_right > DSP4_vars.poly_clipRt[polygon][1])
- x_right = DSP4_vars.poly_clipRt[polygon][1];
+ // saturate offscreen data
+ if (x_left < dsp4_vars.poly_clipLf[polygon][0])
+ x_left = dsp4_vars.poly_clipLf[polygon][0];
+ if (x_left > dsp4_vars.poly_clipRt[polygon][0])
+ x_left = dsp4_vars.poly_clipRt[polygon][0];
+ if (x_right < dsp4_vars.poly_clipLf[polygon][1])
+ x_right = dsp4_vars.poly_clipLf[polygon][1];
+ if (x_right > dsp4_vars.poly_clipRt[polygon][1])
+ x_right = dsp4_vars.poly_clipRt[polygon][1];
- // 1. HDMA memory pointer
- // 2. Left window position ($2126/$2128)
- // 3. Right window position ($2127/$2129)
+ // 1. HDMA memory pointer
+ // 2. Left window position ($2126/$2128)
+ // 3. Right window position ($2127/$2129)
- DSP4_WRITE_WORD(DSP4_vars.poly_ptr[polygon][0]);
- DSP4_WRITE_BYTE(x_left & 0xff);
- DSP4_WRITE_BYTE(x_right & 0xff);
+ DSP4_WRITE_WORD(dsp4_vars.poly_ptr[polygon][0]);
+ DSP4_WRITE_BYTE(x_left & 0xff);
+ DSP4_WRITE_BYTE(x_right & 0xff);
- // update memory pointers
- DSP4_vars.poly_ptr[polygon][0] -= 4;
- DSP4_vars.poly_ptr[polygon][1] -= 4;
- } // end rasterize line
- }
+ // update memory pointers
+ dsp4_vars.poly_ptr[polygon][0] -= 4;
+ dsp4_vars.poly_ptr[polygon][1] -= 4;
+ } // end rasterize line
+ }
- ////////////////////////////////////////////////
- // Post-update
+ ////////////////////////////////////////////////
+ // Post-update
- // new projection spot to continue rasterizing from
- DSP4_vars.poly_start[polygon] = view_x[poly];
- } // end polygon rasterizer
- }
- while (1);
+ // new projection spot to continue rasterizing from
+ dsp4_vars.poly_start[polygon] = view_x[poly];
+ } // end polygon rasterizer
+ }
+ while (1);
- // unknown output
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(0);
+ // unknown output
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(0);
- DSP4.waiting4command = 1;
+ dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP09( void )
+static void dsp4_OP09( void )
{
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- case 3:
- goto resume3; break;
- case 4:
- goto resume4; break;
- case 5:
- goto resume5; break;
- case 6:
- goto resume6; break;
- }
-
- ////////////////////////////////////////////////////
- // process initial inputs
-
- // grab screen information
- DSP4_vars.viewport_cx = DSP4_READ_WORD();
- DSP4_vars.viewport_cy = DSP4_READ_WORD();
- DSP4_READ_WORD(); // 0x0000
- DSP4_vars.viewport_left = DSP4_READ_WORD();
- DSP4_vars.viewport_right = DSP4_READ_WORD();
- DSP4_vars.viewport_top = DSP4_READ_WORD();
- DSP4_vars.viewport_bottom = DSP4_READ_WORD();
-
- // starting DSP4_vars.raster line below the horizon
- DSP4_vars.poly_bottom[0][0] = DSP4_vars.viewport_bottom - DSP4_vars.viewport_cy;
- DSP4_vars.poly_raster[0][0] = 0x100;
-
- do
- {
- ////////////////////////////////////////////////////
- // check for new sprites
-
- DSP4.in_count = 4;
- DSP4_WAIT(1) resume1 :
-
- ////////////////////////////////////////////////
- // DSP4_vars.raster overdraw check
-
- DSP4_vars.raster = DSP4_READ_WORD();
-
- // continue updating the DSP4_vars.raster line where overdraw begins
- if (DSP4_vars.raster < DSP4_vars.poly_raster[0][0])
- {
- DSP4_vars.sprite_clipy = DSP4_vars.viewport_bottom - (DSP4_vars.poly_bottom[0][0] - DSP4_vars.raster);
- DSP4_vars.poly_raster[0][0] = DSP4_vars.raster;
- }
-
- /////////////////////////////////////////////////
- // identify sprite
-
- // op termination
- DSP4_vars.distance = DSP4_READ_WORD();
- if (DSP4_vars.distance == -0x8000)
- goto terminate;
-
-
- // no sprite
- if (DSP4_vars.distance == 0x0000)
- {
- continue;
- }
-
- ////////////////////////////////////////////////////
- // process projection information
-
- // vehicle sprite
- if ((UINT16) DSP4_vars.distance == 0x9000)
- {
- INT16 car_left, car_right, car_back;
- INT16 impact_left, impact_back;
- INT16 world_spx, world_spy;
- INT16 view_spx, view_spy;
- UINT16 energy;
-
- // we already have 4 bytes we want
- DSP4.in_count = 14;
- DSP4_WAIT(2) resume2 :
-
- // filter inputs
- energy = DSP4_READ_WORD();
- impact_back = DSP4_READ_WORD();
- car_back = DSP4_READ_WORD();
- impact_left = DSP4_READ_WORD();
- car_left = DSP4_READ_WORD();
- DSP4_vars.distance = DSP4_READ_WORD();
- car_right = DSP4_READ_WORD();
-
- // calculate car's world (x,y) values
- world_spx = car_right - car_left;
- world_spy = car_back;
-
- // add in collision vector [needs bit-twiddling]
- world_spx -= energy * (impact_left - car_left) >> 16;
- world_spy -= energy * (car_back - impact_back) >> 16;
-
- // perspective correction for world (x,y)
- view_spx = world_spx * DSP4_vars.distance >> 15;
- view_spy = world_spy * DSP4_vars.distance >> 15;
-
- // convert to screen values
- DSP4_vars.sprite_x = DSP4_vars.viewport_cx + view_spx;
- DSP4_vars.sprite_y = DSP4_vars.viewport_bottom - (DSP4_vars.poly_bottom[0][0] - view_spy);
-
- // make the car's (x)-coordinate available
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(world_spx);
-
- // grab a few remaining vehicle values
- DSP4.in_count = 4;
- DSP4_WAIT(3) resume3 :
-
- // add vertical lift factor
- DSP4_vars.sprite_y += DSP4_READ_WORD();
- }
- // terrain sprite
- else
- {
- INT16 world_spx, world_spy;
- INT16 view_spx, view_spy;
-
- // we already have 4 bytes we want
- DSP4.in_count = 10;
- DSP4_WAIT(4) resume4 :
-
- // sort loop inputs
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_raster[0][1] = DSP4_READ_WORD();
- world_spx = DSP4_READ_WORD();
- world_spy = DSP4_READ_WORD();
-
- // compute base DSP4_vars.raster line from the bottom
- DSP4_vars.segments = DSP4_vars.poly_bottom[0][0] - DSP4_vars.raster;
-
- // perspective correction for world (x,y)
- view_spx = world_spx * DSP4_vars.distance >> 15;
- view_spy = world_spy * DSP4_vars.distance >> 15;
-
- // convert to screen values
- DSP4_vars.sprite_x = DSP4_vars.viewport_cx + view_spx - DSP4_vars.poly_cx[0][0];
- DSP4_vars.sprite_y = DSP4_vars.viewport_bottom - DSP4_vars.segments + view_spy;
- }
-
- // default sprite size: 16x16
- DSP4_vars.sprite_size = 1;
- DSP4_vars.sprite_attr = DSP4_READ_WORD();
-
- ////////////////////////////////////////////////////
- // convert tile data to SNES OAM format
-
- do
- {
- UINT16 header;
-
- INT16 sp_x, sp_y, sp_attr, sp_dattr;
- INT16 sp_dx, sp_dy;
- INT16 pixels;
-
- UINT8 draw;
-
- DSP4.in_count = 2;
- DSP4_WAIT(5) resume5 :
-
- draw = 1;
-
- // opcode termination
- DSP4_vars.raster = DSP4_READ_WORD();
- if (DSP4_vars.raster == -0x8000)
- goto terminate;
-
- // stop code
- if (DSP4_vars.raster == 0x0000 && !DSP4_vars.sprite_size)
- break;
-
- // toggle sprite size
- if (DSP4_vars.raster == 0x0000)
- {
- DSP4_vars.sprite_size = !DSP4_vars.sprite_size;
- continue;
- }
-
- // check for valid sprite header
- header = DSP4_vars.raster;
- header >>= 8;
- if (header != 0x20 &&
- header != 0x2e && //This is for attractor sprite
- header != 0x40 &&
- header != 0x60 &&
- header != 0xa0 &&
- header != 0xc0 &&
- header != 0xe0)
- break;
-
- // read in rest of sprite data
- DSP4.in_count = 4;
- DSP4_WAIT(6) resume6 :
-
- draw = 1;
-
- /////////////////////////////////////
- // process tile data
-
- // sprite deltas
- sp_dattr = DSP4_vars.raster;
- sp_dy = DSP4_READ_WORD();
- sp_dx = DSP4_READ_WORD();
-
- // update coordinates to screen space
- sp_x = DSP4_vars.sprite_x + sp_dx;
- sp_y = DSP4_vars.sprite_y + sp_dy;
-
- // update sprite nametable/attribute information
- sp_attr = DSP4_vars.sprite_attr + sp_dattr;
-
- // allow partially visibile tiles
- pixels = DSP4_vars.sprite_size ? 15 : 7;
-
- DSP4_CLEAR_OUT();
-
- // transparent tile to clip off parts of a sprite (overdraw)
- if (DSP4_vars.sprite_clipy - pixels <= sp_y &&
- sp_y <= DSP4_vars.sprite_clipy &&
- sp_x >= DSP4_vars.viewport_left - pixels &&
- sp_x <= DSP4_vars.viewport_right &&
- DSP4_vars.sprite_clipy >= DSP4_vars.viewport_top - pixels &&
- DSP4_vars.sprite_clipy <= DSP4_vars.viewport_bottom)
- {
- DSP4_OP0B(&draw, sp_x, DSP4_vars.sprite_clipy, 0x00EE, DSP4_vars.sprite_size, 0);
- }
-
-
- // normal sprite tile
- if (sp_x >= DSP4_vars.viewport_left - pixels &&
- sp_x <= DSP4_vars.viewport_right &&
- sp_y >= DSP4_vars.viewport_top - pixels &&
- sp_y <= DSP4_vars.viewport_bottom &&
- sp_y <= DSP4_vars.sprite_clipy)
- {
- DSP4_OP0B(&draw, sp_x, sp_y, sp_attr, DSP4_vars.sprite_size, 0);
- }
-
-
- // no following OAM data
- DSP4_OP0B(&draw, 0, 0x0100, 0, 0, 1);
- }
- while (1);
- }
- while (1);
-
- terminate : DSP4.waiting4command = 1;
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ case 3:
+ goto resume3; break;
+ case 4:
+ goto resume4; break;
+ case 5:
+ goto resume5; break;
+ case 6:
+ goto resume6; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // grab screen information
+ dsp4_vars.viewport_cx = DSP4_READ_WORD();
+ dsp4_vars.viewport_cy = DSP4_READ_WORD();
+ DSP4_READ_WORD(); // 0x0000
+ dsp4_vars.viewport_left = DSP4_READ_WORD();
+ dsp4_vars.viewport_right = DSP4_READ_WORD();
+ dsp4_vars.viewport_top = DSP4_READ_WORD();
+ dsp4_vars.viewport_bottom = DSP4_READ_WORD();
+
+ // starting dsp4_vars.raster line below the horizon
+ dsp4_vars.poly_bottom[0][0] = dsp4_vars.viewport_bottom - dsp4_vars.viewport_cy;
+ dsp4_vars.poly_raster[0][0] = 0x100;
+
+ do
+ {
+ ////////////////////////////////////////////////////
+ // check for new sprites
+
+ dsp4.in_count = 4;
+ DSP4_WAIT(1) resume1 :
+
+ ////////////////////////////////////////////////
+ // dsp4_vars.raster overdraw check
+
+ dsp4_vars.raster = DSP4_READ_WORD();
+
+ // continue updating the dsp4_vars.raster line where overdraw begins
+ if (dsp4_vars.raster < dsp4_vars.poly_raster[0][0])
+ {
+ dsp4_vars.sprite_clipy = dsp4_vars.viewport_bottom - (dsp4_vars.poly_bottom[0][0] - dsp4_vars.raster);
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.raster;
+ }
+
+ /////////////////////////////////////////////////
+ // identify sprite
+
+ // op termination
+ dsp4_vars.distance = DSP4_READ_WORD();
+ if (dsp4_vars.distance == -0x8000)
+ goto terminate;
+
+
+ // no sprite
+ if (dsp4_vars.distance == 0x0000)
+ {
+ continue;
+ }
+
+ ////////////////////////////////////////////////////
+ // process projection information
+
+ // vehicle sprite
+ if ((UINT16) dsp4_vars.distance == 0x9000)
+ {
+ INT16 car_left, car_right, car_back;
+ INT16 impact_left, impact_back;
+ INT16 world_spx, world_spy;
+ INT16 view_spx, view_spy;
+ UINT16 energy;
+
+ // we already have 4 bytes we want
+ dsp4.in_count = 14;
+ DSP4_WAIT(2) resume2 :
+
+ // filter inputs
+ energy = DSP4_READ_WORD();
+ impact_back = DSP4_READ_WORD();
+ car_back = DSP4_READ_WORD();
+ impact_left = DSP4_READ_WORD();
+ car_left = DSP4_READ_WORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ car_right = DSP4_READ_WORD();
+
+ // calculate car's world (x,y) values
+ world_spx = car_right - car_left;
+ world_spy = car_back;
+
+ // add in collision vector [needs bit-twiddling]
+ world_spx -= energy * (impact_left - car_left) >> 16;
+ world_spy -= energy * (car_back - impact_back) >> 16;
+
+ // perspective correction for world (x,y)
+ view_spx = world_spx * dsp4_vars.distance >> 15;
+ view_spy = world_spy * dsp4_vars.distance >> 15;
+
+ // convert to screen values
+ dsp4_vars.sprite_x = dsp4_vars.viewport_cx + view_spx;
+ dsp4_vars.sprite_y = dsp4_vars.viewport_bottom - (dsp4_vars.poly_bottom[0][0] - view_spy);
+
+ // make the car's (x)-coordinate available
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(world_spx);
+
+ // grab a few remaining vehicle values
+ dsp4.in_count = 4;
+ DSP4_WAIT(3) resume3 :
+
+ // add vertical lift factor
+ dsp4_vars.sprite_y += DSP4_READ_WORD();
+ }
+ // terrain sprite
+ else
+ {
+ INT16 world_spx, world_spy;
+ INT16 view_spx, view_spy;
+
+ // we already have 4 bytes we want
+ dsp4.in_count = 10;
+ DSP4_WAIT(4) resume4 :
+
+ // sort loop inputs
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_raster[0][1] = DSP4_READ_WORD();
+ world_spx = DSP4_READ_WORD();
+ world_spy = DSP4_READ_WORD();
+
+ // compute base dsp4_vars.raster line from the bottom
+ dsp4_vars.segments = dsp4_vars.poly_bottom[0][0] - dsp4_vars.raster;
+
+ // perspective correction for world (x,y)
+ view_spx = world_spx * dsp4_vars.distance >> 15;
+ view_spy = world_spy * dsp4_vars.distance >> 15;
+
+ // convert to screen values
+ dsp4_vars.sprite_x = dsp4_vars.viewport_cx + view_spx - dsp4_vars.poly_cx[0][0];
+ dsp4_vars.sprite_y = dsp4_vars.viewport_bottom - dsp4_vars.segments + view_spy;
+ }
+
+ // default sprite size: 16x16
+ dsp4_vars.sprite_size = 1;
+ dsp4_vars.sprite_attr = DSP4_READ_WORD();
+
+ ////////////////////////////////////////////////////
+ // convert tile data to SNES OAM format
+
+ do
+ {
+ UINT16 header;
+
+ INT16 sp_x, sp_y, sp_attr, sp_dattr;
+ INT16 sp_dx, sp_dy;
+ INT16 pixels;
+
+ UINT8 draw;
+
+ dsp4.in_count = 2;
+ DSP4_WAIT(5) resume5 :
+
+ draw = 1;
+
+ // opcode termination
+ dsp4_vars.raster = DSP4_READ_WORD();
+ if (dsp4_vars.raster == -0x8000)
+ goto terminate;
+
+ // stop code
+ if (dsp4_vars.raster == 0x0000 && !dsp4_vars.sprite_size)
+ break;
+
+ // toggle sprite size
+ if (dsp4_vars.raster == 0x0000)
+ {
+ dsp4_vars.sprite_size = !dsp4_vars.sprite_size;
+ continue;
+ }
+
+ // check for valid sprite header
+ header = dsp4_vars.raster;
+ header >>= 8;
+ if (header != 0x20 &&
+ header != 0x2e && //This is for attractor sprite
+ header != 0x40 &&
+ header != 0x60 &&
+ header != 0xa0 &&
+ header != 0xc0 &&
+ header != 0xe0)
+ break;
+
+ // read in rest of sprite data
+ dsp4.in_count = 4;
+ DSP4_WAIT(6) resume6 :
+
+ draw = 1;
+
+ /////////////////////////////////////
+ // process tile data
+
+ // sprite deltas
+ sp_dattr = dsp4_vars.raster;
+ sp_dy = DSP4_READ_WORD();
+ sp_dx = DSP4_READ_WORD();
+
+ // update coordinates to screen space
+ sp_x = dsp4_vars.sprite_x + sp_dx;
+ sp_y = dsp4_vars.sprite_y + sp_dy;
+
+ // update sprite nametable/attribute information
+ sp_attr = dsp4_vars.sprite_attr + sp_dattr;
+
+ // allow partially visibile tiles
+ pixels = dsp4_vars.sprite_size ? 15 : 7;
+
+ DSP4_CLEAR_OUT();
+
+ // transparent tile to clip off parts of a sprite (overdraw)
+ if (dsp4_vars.sprite_clipy - pixels <= sp_y &&
+ sp_y <= dsp4_vars.sprite_clipy &&
+ sp_x >= dsp4_vars.viewport_left - pixels &&
+ sp_x <= dsp4_vars.viewport_right &&
+ dsp4_vars.sprite_clipy >= dsp4_vars.viewport_top - pixels &&
+ dsp4_vars.sprite_clipy <= dsp4_vars.viewport_bottom)
+ {
+ dsp4_OP0B(&draw, sp_x, dsp4_vars.sprite_clipy, 0x00EE, dsp4_vars.sprite_size, 0);
+ }
+
+
+ // normal sprite tile
+ if (sp_x >= dsp4_vars.viewport_left - pixels &&
+ sp_x <= dsp4_vars.viewport_right &&
+ sp_y >= dsp4_vars.viewport_top - pixels &&
+ sp_y <= dsp4_vars.viewport_bottom &&
+ sp_y <= dsp4_vars.sprite_clipy)
+ {
+ dsp4_OP0B(&draw, sp_x, sp_y, sp_attr, dsp4_vars.sprite_size, 0);
+ }
+
+
+ // no following OAM data
+ dsp4_OP0B(&draw, 0, 0x0100, 0, 0, 1);
+ }
+ while (1);
+ }
+ while (1);
+
+ terminate : dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
@@ -1184,764 +1185,764 @@ static void DSP4_OP09( void )
static const UINT16 OP0A_Values[16] = { 0x0000, 0x0030, 0x0060, 0x0090, 0x00c0, 0x00f0, 0x0120, 0x0150, 0xfe80,
0xfeb0, 0xfee0, 0xff10, 0xff40, 0xff70, 0xffa0, 0xffd0 };
-static void DSP4_OP0A(INT16 n2, INT16 *o1, INT16 *o2, INT16 *o3, INT16 *o4)
+static void dsp4_OP0A(INT16 n2, INT16 *o1, INT16 *o2, INT16 *o3, INT16 *o4)
{
- *o4 = OP0A_Values[(n2 & 0x000f)];
- *o3 = OP0A_Values[(n2 & 0x00f0) >> 4];
- *o2 = OP0A_Values[(n2 & 0x0f00) >> 8];
- *o1 = OP0A_Values[(n2 & 0xf000) >> 12];
+ *o4 = OP0A_Values[(n2 & 0x000f)];
+ *o3 = OP0A_Values[(n2 & 0x00f0) >> 4];
+ *o2 = OP0A_Values[(n2 & 0x0f00) >> 8];
+ *o1 = OP0A_Values[(n2 & 0xf000) >> 12];
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP0B(UINT8 *draw, INT16 sp_x, INT16 sp_y, INT16 sp_attr, UINT8 size, UINT8 stop)
+static void dsp4_OP0B(UINT8 *draw, INT16 sp_x, INT16 sp_y, INT16 sp_attr, UINT8 size, UINT8 stop)
{
- INT16 Row1, Row2;
-
- // SR = 0x00
-
- // align to nearest 8-pixel row
- Row1 = (sp_y >> 3) & 0x1f;
- Row2 = (Row1 + 1) & 0x1f;
-
- // check boundaries
- if (!((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb)))
- {
- *draw = 0;
- }
- if (size)
- {
- if (DSP4_vars.OAM_Row[Row1] + 1 >= DSP4_vars.OAM_RowMax)
- *draw = 0;
- if (DSP4_vars.OAM_Row[Row2] + 1 >= DSP4_vars.OAM_RowMax)
- *draw = 0;
- }
- else
- {
- if (DSP4_vars.OAM_Row[Row1] >= DSP4_vars.OAM_RowMax)
- {
- *draw = 0;
- }
- }
-
- // emulator fail-safe (unknown if this really exists)
- if (DSP4_vars.sprite_count >= 128)
- {
- *draw = 0;
- }
-
- // SR = 0x80
-
- if (*draw)
- {
- // Row tiles
- if (size)
- {
- DSP4_vars.OAM_Row[Row1] += 2;
- DSP4_vars.OAM_Row[Row2] += 2;
- }
- else
- {
- DSP4_vars.OAM_Row[Row1]++;
- }
-
- // yield OAM output
- DSP4_WRITE_WORD(1);
-
- // pack OAM data: x,y,name,attr
- DSP4_WRITE_BYTE(sp_x & 0xff);
- DSP4_WRITE_BYTE(sp_y & 0xff);
- DSP4_WRITE_WORD(sp_attr);
-
- DSP4_vars.sprite_count++;
-
- // OAM: size,msb data
- // save post-oam table data for future retrieval
- DSP4_vars.OAM_attr[DSP4_vars.OAM_index] |= ((sp_x <0 || sp_x> 255) << DSP4_vars.OAM_bits);
- DSP4_vars.OAM_bits++;
-
- DSP4_vars.OAM_attr[DSP4_vars.OAM_index] |= (size << DSP4_vars.OAM_bits);
- DSP4_vars.OAM_bits++;
-
- // move to next byte in buffer
- if (DSP4_vars.OAM_bits == 16)
- {
- DSP4_vars.OAM_bits = 0;
- DSP4_vars.OAM_index++;
- }
- }
- else if (stop)
- {
- // yield no OAM output
- DSP4_WRITE_WORD(0);
- }
+ INT16 Row1, Row2;
+
+ // SR = 0x00
+
+ // align to nearest 8-pixel row
+ Row1 = (sp_y >> 3) & 0x1f;
+ Row2 = (Row1 + 1) & 0x1f;
+
+ // check boundaries
+ if (!((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb)))
+ {
+ *draw = 0;
+ }
+ if (size)
+ {
+ if (dsp4_vars.OAM_Row[Row1] + 1 >= dsp4_vars.OAM_RowMax)
+ *draw = 0;
+ if (dsp4_vars.OAM_Row[Row2] + 1 >= dsp4_vars.OAM_RowMax)
+ *draw = 0;
+ }
+ else
+ {
+ if (dsp4_vars.OAM_Row[Row1] >= dsp4_vars.OAM_RowMax)
+ {
+ *draw = 0;
+ }
+ }
+
+ // emulator fail-safe (unknown if this really exists)
+ if (dsp4_vars.sprite_count >= 128)
+ {
+ *draw = 0;
+ }
+
+ // SR = 0x80
+
+ if (*draw)
+ {
+ // Row tiles
+ if (size)
+ {
+ dsp4_vars.OAM_Row[Row1] += 2;
+ dsp4_vars.OAM_Row[Row2] += 2;
+ }
+ else
+ {
+ dsp4_vars.OAM_Row[Row1]++;
+ }
+
+ // yield OAM output
+ DSP4_WRITE_WORD(1);
+
+ // pack OAM data: x,y,name,attr
+ DSP4_WRITE_BYTE(sp_x & 0xff);
+ DSP4_WRITE_BYTE(sp_y & 0xff);
+ DSP4_WRITE_WORD(sp_attr);
+
+ dsp4_vars.sprite_count++;
+
+ // OAM: size,msb data
+ // save post-oam table data for future retrieval
+ dsp4_vars.OAM_attr[dsp4_vars.OAM_index] |= ((sp_x <0 || sp_x> 255) << dsp4_vars.OAM_bits);
+ dsp4_vars.OAM_bits++;
+
+ dsp4_vars.OAM_attr[dsp4_vars.OAM_index] |= (size << dsp4_vars.OAM_bits);
+ dsp4_vars.OAM_bits++;
+
+ // move to next byte in buffer
+ if (dsp4_vars.OAM_bits == 16)
+ {
+ dsp4_vars.OAM_bits = 0;
+ dsp4_vars.OAM_index++;
+ }
+ }
+ else if (stop)
+ {
+ // yield no OAM output
+ DSP4_WRITE_WORD(0);
+ }
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP0D( void )
+static void dsp4_OP0D( void )
{
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- }
-
- ////////////////////////////////////////////////////
- // process initial inputs
-
- // sort inputs
- DSP4_vars.world_y = DSP4_READ_DWORD();
- DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();
- DSP4_vars.viewport_bottom = DSP4_READ_WORD();
- DSP4_vars.world_x = DSP4_READ_DWORD();
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
- DSP4_vars.world_yofs = DSP4_READ_WORD();
- DSP4_vars.world_dy = DSP4_READ_DWORD();
- DSP4_vars.world_dx = DSP4_READ_DWORD();
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_READ_WORD(); // 0x0000
- DSP4_vars.world_xenv = SEX78(DSP4_READ_WORD());
- DSP4_vars.world_ddy = DSP4_READ_WORD();
- DSP4_vars.world_ddx = DSP4_READ_WORD();
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
-
- // initial (x,y,offset) at starting DSP4_vars.raster line
- DSP4_vars.view_x1 = (INT16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16);
- DSP4_vars.view_y1 = (INT16)(DSP4_vars.world_y >> 16);
- DSP4_vars.view_xofs1 = (INT16)(DSP4_vars.world_x >> 16);
- DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;
-
- // first DSP4_vars.raster line
- DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];
-
-
- do
- {
- ////////////////////////////////////////////////////
- // process one iteration of projection
-
- // perspective projection of world (x,y,scroll) points
- // based on the current projection lines
- DSP4_vars.view_x2 = (INT16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ));
- DSP4_vars.view_y2 = (INT16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15);
- DSP4_vars.view_xofs2 = DSP4_vars.view_x2;
- DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;
-
- // 1. World x-location before transformation
- // 2. Viewer x-position at the current
- // 3. World y-location before perspective projection
- // 4. Viewer y-position below the horizon
- // 5. Number of DSP4_vars.raster lines drawn in this iteration
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD((UINT16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16));
- DSP4_WRITE_WORD(DSP4_vars.view_x2);
- DSP4_WRITE_WORD((UINT16)(DSP4_vars.world_y >> 16));
- DSP4_WRITE_WORD(DSP4_vars.view_y2);
-
- //////////////////////////////////////////////////////////
-
- // SR = 0x00
-
- // determine # of DSP4_vars.raster lines used
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2;
-
- // prevent overdraw
- if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])
- DSP4_vars.segments = 0;
- else
- DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;
-
- // don't draw outside the window
- if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])
- {
- DSP4_vars.segments = 0;
-
- // flush remaining DSP4_vars.raster lines
- if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];
- }
-
- // SR = 0x80
-
- DSP4_WRITE_WORD(DSP4_vars.segments);
-
- //////////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- INT32 px_dx, py_dy;
- INT32 x_scroll, y_scroll;
-
- // SR = 0x00
-
- // linear interpolation (lerp) between projected points
- px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
- py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
-
- // starting step values
- x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);
- y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);
-
- // SR = 0x80
-
- // rasterize line
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)
- {
- // 1. HDMA memory pointer (bg1)
- // 2. vertical scroll offset ($210E)
- // 3. horizontal scroll offset ($210D)
-
- DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);
- DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
- DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
-
-
- // update memory address
- DSP4_vars.poly_ptr[0][0] -= 4;
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // sort inputs
+ dsp4_vars.world_y = DSP4_READ_DWORD();
+ dsp4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][0] = DSP4_READ_WORD();
+ dsp4_vars.viewport_bottom = DSP4_READ_WORD();
+ dsp4_vars.world_x = DSP4_READ_DWORD();
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
+ dsp4_vars.world_yofs = DSP4_READ_WORD();
+ dsp4_vars.world_dy = DSP4_READ_DWORD();
+ dsp4_vars.world_dx = DSP4_READ_DWORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ DSP4_READ_WORD(); // 0x0000
+ dsp4_vars.world_xenv = SEX78(DSP4_READ_WORD());
+ dsp4_vars.world_ddy = DSP4_READ_WORD();
+ dsp4_vars.world_ddx = DSP4_READ_WORD();
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+
+ // initial (x,y,offset) at starting dsp4_vars.raster line
+ dsp4_vars.view_x1 = (INT16)((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16);
+ dsp4_vars.view_y1 = (INT16)(dsp4_vars.world_y >> 16);
+ dsp4_vars.view_xofs1 = (INT16)(dsp4_vars.world_x >> 16);
+ dsp4_vars.view_yofs1 = dsp4_vars.world_yofs;
+
+ // first dsp4_vars.raster line
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.poly_bottom[0][0];
+
+
+ do
+ {
+ ////////////////////////////////////////////////////
+ // process one iteration of projection
+
+ // perspective projection of world (x,y,scroll) points
+ // based on the current projection lines
+ dsp4_vars.view_x2 = (INT16)(( ( ( dsp4_vars.world_x + dsp4_vars.world_xenv ) >> 16 ) * dsp4_vars.distance >> 15 ) + ( dsp4_vars.view_turnoff_x * dsp4_vars.distance >> 15 ));
+ dsp4_vars.view_y2 = (INT16)((dsp4_vars.world_y >> 16) * dsp4_vars.distance >> 15);
+ dsp4_vars.view_xofs2 = dsp4_vars.view_x2;
+ dsp4_vars.view_yofs2 = (dsp4_vars.world_yofs * dsp4_vars.distance >> 15) + dsp4_vars.poly_bottom[0][0] - dsp4_vars.view_y2;
+
+ // 1. World x-location before transformation
+ // 2. Viewer x-position at the current
+ // 3. World y-location before perspective projection
+ // 4. Viewer y-position below the horizon
+ // 5. Number of dsp4_vars.raster lines drawn in this iteration
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD((UINT16)((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16));
+ DSP4_WRITE_WORD(dsp4_vars.view_x2);
+ DSP4_WRITE_WORD((UINT16)(dsp4_vars.world_y >> 16));
+ DSP4_WRITE_WORD(dsp4_vars.view_y2);
+
+ //////////////////////////////////////////////////////////
+
+ // SR = 0x00
+
+ // determine # of dsp4_vars.raster lines used
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.view_y2;
+
+ // prevent overdraw
+ if (dsp4_vars.view_y2 >= dsp4_vars.poly_raster[0][0])
+ dsp4_vars.segments = 0;
+ else
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.view_y2;
+
+ // don't draw outside the window
+ if (dsp4_vars.view_y2 < dsp4_vars.poly_top[0][0])
+ {
+ dsp4_vars.segments = 0;
+
+ // flush remaining dsp4_vars.raster lines
+ if (dsp4_vars.view_y1 >= dsp4_vars.poly_top[0][0])
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.poly_top[0][0];
+ }
+
+ // SR = 0x80
+
+ DSP4_WRITE_WORD(dsp4_vars.segments);
+
+ //////////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ INT32 px_dx, py_dy;
+ INT32 x_scroll, y_scroll;
+
+ // SR = 0x00
+
+ // linear interpolation (lerp) between projected points
+ px_dx = (dsp4_vars.view_xofs2 - dsp4_vars.view_xofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ py_dy = (dsp4_vars.view_yofs2 - dsp4_vars.view_yofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+
+ // starting step values
+ x_scroll = SEX16(dsp4_vars.poly_cx[0][0] + dsp4_vars.view_xofs1);
+ y_scroll = SEX16(-dsp4_vars.viewport_bottom + dsp4_vars.view_yofs1 + dsp4_vars.view_yofsenv + dsp4_vars.poly_cx[1][0] - dsp4_vars.world_yofs);
+
+ // SR = 0x80
+
+ // rasterize line
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < dsp4_vars.segments; dsp4_vars.lcv++)
+ {
+ // 1. HDMA memory pointer (bg1)
+ // 2. vertical scroll offset ($210E)
+ // 3. horizontal scroll offset ($210D)
+
+ DSP4_WRITE_WORD(dsp4_vars.poly_ptr[0][0]);
+ DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
+ DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
+
+
+ // update memory address
+ dsp4_vars.poly_ptr[0][0] -= 4;
- // update screen values
- x_scroll += px_dx;
- y_scroll += py_dy;
- }
- }
+ // update screen values
+ x_scroll += px_dx;
+ y_scroll += py_dy;
+ }
+ }
- /////////////////////////////////////////////////////
- // Post-update
+ /////////////////////////////////////////////////////
+ // Post-update
- // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn
- DSP4_vars.view_x1 = DSP4_vars.view_x2;
- DSP4_vars.view_y1 = DSP4_vars.view_y2;
- DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;
- DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;
+ // update new viewer (x,y,scroll) to last dsp4_vars.raster line drawn
+ dsp4_vars.view_x1 = dsp4_vars.view_x2;
+ dsp4_vars.view_y1 = dsp4_vars.view_y2;
+ dsp4_vars.view_xofs1 = dsp4_vars.view_xofs2;
+ dsp4_vars.view_yofs1 = dsp4_vars.view_yofs2;
- // add deltas for projection lines
- DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx);
- DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy);
+ // add deltas for projection lines
+ dsp4_vars.world_dx += SEX78(dsp4_vars.world_ddx);
+ dsp4_vars.world_dy += SEX78(dsp4_vars.world_ddy);
- // update projection lines
- DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv);
- DSP4_vars.world_y += DSP4_vars.world_dy;
+ // update projection lines
+ dsp4_vars.world_x += (dsp4_vars.world_dx + dsp4_vars.world_xenv);
+ dsp4_vars.world_y += dsp4_vars.world_dy;
- ////////////////////////////////////////////////////
- // command check
+ ////////////////////////////////////////////////////
+ // command check
- // scan next command
- DSP4.in_count = 2;
- DSP4_WAIT(1) resume1 :
+ // scan next command
+ dsp4.in_count = 2;
+ DSP4_WAIT(1) resume1 :
- // inspect input
- DSP4_vars.distance = DSP4_READ_WORD();
+ // inspect input
+ dsp4_vars.distance = DSP4_READ_WORD();
- // terminate op
- if (DSP4_vars.distance == -0x8000)
- break;
+ // terminate op
+ if (dsp4_vars.distance == -0x8000)
+ break;
- // already have 2 bytes in queue
- DSP4.in_count = 6;
- DSP4_WAIT(2) resume2:
+ // already have 2 bytes in queue
+ dsp4.in_count = 6;
+ DSP4_WAIT(2) resume2:
- // inspect inputs
- DSP4_vars.world_ddy = DSP4_READ_WORD();
- DSP4_vars.world_ddx = DSP4_READ_WORD();
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
+ // inspect inputs
+ dsp4_vars.world_ddy = DSP4_READ_WORD();
+ dsp4_vars.world_ddx = DSP4_READ_WORD();
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
- // no envelope here
- DSP4_vars.world_xenv = 0;
- }
- while (1);
+ // no envelope here
+ dsp4_vars.world_xenv = 0;
+ }
+ while (1);
- DSP4.waiting4command = 1;
+ dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP0E( void )
+static void dsp4_OP0E( void )
{
- DSP4_vars.OAM_RowMax = 16;
- memset(DSP4_vars.OAM_Row, 0, 64);
+ dsp4_vars.OAM_RowMax = 16;
+ memset(dsp4_vars.OAM_Row, 0, 64);
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP0F( void )
+static void dsp4_OP0F( void )
{
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- case 3:
- goto resume3; break;
- case 4:
- goto resume4; break;
- }
-
- ////////////////////////////////////////////////////
- // process initial inputs
-
- // sort inputs
- DSP4_READ_WORD(); // 0x0000
- DSP4_vars.world_y = DSP4_READ_DWORD();
- DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();
- DSP4_vars.viewport_bottom = DSP4_READ_WORD();
- DSP4_vars.world_x = DSP4_READ_DWORD();
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
- DSP4_vars.world_yofs = DSP4_READ_WORD();
- DSP4_vars.world_dy = DSP4_READ_DWORD();
- DSP4_vars.world_dx = DSP4_READ_DWORD();
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_READ_WORD(); // 0x0000
- DSP4_vars.world_xenv = DSP4_READ_DWORD();
- DSP4_vars.world_ddy = DSP4_READ_WORD();
- DSP4_vars.world_ddx = DSP4_READ_WORD();
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
-
- // initial (x,y,offset) at starting DSP4_vars.raster line
- DSP4_vars.view_x1 = (INT16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16);
- DSP4_vars.view_y1 = (INT16)(DSP4_vars.world_y >> 16);
- DSP4_vars.view_xofs1 = (INT16)(DSP4_vars.world_x >> 16);
- DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;
- DSP4_vars.view_turnoff_x = 0;
- DSP4_vars.view_turnoff_dx = 0;
-
- // first DSP4_vars.raster line
- DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];
-
-
- do
- {
- ////////////////////////////////////////////////////
- // process one iteration of projection
-
- // perspective projection of world (x,y,scroll) points
- // based on the current projection lines
- DSP4_vars.view_x2 = (INT16)(((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16) * DSP4_vars.distance >> 15);
- DSP4_vars.view_y2 = (INT16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15);
- DSP4_vars.view_xofs2 = DSP4_vars.view_x2;
- DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;
-
- // 1. World x-location before transformation
- // 2. Viewer x-position at the next
- // 3. World y-location before perspective projection
- // 4. Viewer y-position below the horizon
- // 5. Number of DSP4_vars.raster lines drawn in this iteration
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD((UINT16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16));
- DSP4_WRITE_WORD(DSP4_vars.view_x2);
- DSP4_WRITE_WORD((UINT16)(DSP4_vars.world_y >> 16));
- DSP4_WRITE_WORD(DSP4_vars.view_y2);
-
- //////////////////////////////////////////////////////
-
- // SR = 0x00
-
- // determine # of DSP4_vars.raster lines used
- DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2;
-
- // prevent overdraw
- if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])
- DSP4_vars.segments = 0;
- else
- DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;
-
- // don't draw outside the window
- if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])
- {
- DSP4_vars.segments = 0;
-
- // flush remaining DSP4_vars.raster lines
- if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];
- }
-
- // SR = 0x80
-
- DSP4_WRITE_WORD(DSP4_vars.segments);
-
- //////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- INT32 px_dx, py_dy;
- INT32 x_scroll, y_scroll;
-
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++)
- {
- // grab inputs
- DSP4.in_count = 4;
- DSP4_WAIT(1);
- resume1 :
- for (;;)
- {
- INT16 distance;
- INT16 color, red, green, blue;
-
- distance = DSP4_READ_WORD();
- color = DSP4_READ_WORD();
-
- // U1+B5+G5+R5
- red = color & 0x1f;
- green = (color >> 5) & 0x1f;
- blue = (color >> 10) & 0x1f;
-
- // dynamic lighting
- red = (red * distance >> 15) & 0x1f;
- green = (green * distance >> 15) & 0x1f;
- blue = (blue * distance >> 15) & 0x1f;
- color = red | (green << 5) | (blue << 10);
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(color);
- break;
- }
- }
-
- //////////////////////////////////////////////////////
-
- // SR = 0x00
-
- // linear interpolation (lerp) between projected points
- px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
- py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
-
-
- // starting step values
- x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);
- y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);
-
- // SR = 0x80
-
- // rasterize line
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)
- {
- // 1. HDMA memory pointer
- // 2. vertical scroll offset ($210E)
- // 3. horizontal scroll offset ($210D)
-
- DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);
- DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
- DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
-
- // update memory address
- DSP4_vars.poly_ptr[0][0] -= 4;
-
- // update screen values
- x_scroll += px_dx;
- y_scroll += py_dy;
- }
- }
-
- ////////////////////////////////////////////////////
- // Post-update
-
- // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn
- DSP4_vars.view_x1 = DSP4_vars.view_x2;
- DSP4_vars.view_y1 = DSP4_vars.view_y2;
- DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;
- DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;
-
- // add deltas for projection lines
- DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx);
- DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy);
-
- // update projection lines
- DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv);
- DSP4_vars.world_y += DSP4_vars.world_dy;
-
- // update road turnoff position
- DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx;
-
- ////////////////////////////////////////////////////
- // command check
-
- // scan next command
- DSP4.in_count = 2;
- DSP4_WAIT(2) resume2:
-
- // check for termination
- DSP4_vars.distance = DSP4_READ_WORD();
- if (DSP4_vars.distance == -0x8000)
- break;
-
- // road splice
- if( (UINT16) DSP4_vars.distance == 0x8001 )
- {
- DSP4.in_count = 6;
- DSP4_WAIT(3) resume3:
-
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_vars.view_turnoff_x = DSP4_READ_WORD();
- DSP4_vars.view_turnoff_dx = DSP4_READ_WORD();
-
- // factor in new changes
- DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 );
- DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 );
-
- // update stepping values
- DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx;
-
- DSP4.in_count = 2;
- DSP4_WAIT(2)
- }
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ case 3:
+ goto resume3; break;
+ case 4:
+ goto resume4; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // process initial inputs
+
+ // sort inputs
+ DSP4_READ_WORD(); // 0x0000
+ dsp4_vars.world_y = DSP4_READ_DWORD();
+ dsp4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][0] = DSP4_READ_WORD();
+ dsp4_vars.viewport_bottom = DSP4_READ_WORD();
+ dsp4_vars.world_x = DSP4_READ_DWORD();
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
+ dsp4_vars.world_yofs = DSP4_READ_WORD();
+ dsp4_vars.world_dy = DSP4_READ_DWORD();
+ dsp4_vars.world_dx = DSP4_READ_DWORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ DSP4_READ_WORD(); // 0x0000
+ dsp4_vars.world_xenv = DSP4_READ_DWORD();
+ dsp4_vars.world_ddy = DSP4_READ_WORD();
+ dsp4_vars.world_ddx = DSP4_READ_WORD();
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+
+ // initial (x,y,offset) at starting dsp4_vars.raster line
+ dsp4_vars.view_x1 = (INT16)((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16);
+ dsp4_vars.view_y1 = (INT16)(dsp4_vars.world_y >> 16);
+ dsp4_vars.view_xofs1 = (INT16)(dsp4_vars.world_x >> 16);
+ dsp4_vars.view_yofs1 = dsp4_vars.world_yofs;
+ dsp4_vars.view_turnoff_x = 0;
+ dsp4_vars.view_turnoff_dx = 0;
+
+ // first dsp4_vars.raster line
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.poly_bottom[0][0];
+
+
+ do
+ {
+ ////////////////////////////////////////////////////
+ // process one iteration of projection
+
+ // perspective projection of world (x,y,scroll) points
+ // based on the current projection lines
+ dsp4_vars.view_x2 = (INT16)(((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16) * dsp4_vars.distance >> 15);
+ dsp4_vars.view_y2 = (INT16)((dsp4_vars.world_y >> 16) * dsp4_vars.distance >> 15);
+ dsp4_vars.view_xofs2 = dsp4_vars.view_x2;
+ dsp4_vars.view_yofs2 = (dsp4_vars.world_yofs * dsp4_vars.distance >> 15) + dsp4_vars.poly_bottom[0][0] - dsp4_vars.view_y2;
+
+ // 1. World x-location before transformation
+ // 2. Viewer x-position at the next
+ // 3. World y-location before perspective projection
+ // 4. Viewer y-position below the horizon
+ // 5. Number of dsp4_vars.raster lines drawn in this iteration
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD((UINT16)((dsp4_vars.world_x + dsp4_vars.world_xenv) >> 16));
+ DSP4_WRITE_WORD(dsp4_vars.view_x2);
+ DSP4_WRITE_WORD((UINT16)(dsp4_vars.world_y >> 16));
+ DSP4_WRITE_WORD(dsp4_vars.view_y2);
+
+ //////////////////////////////////////////////////////
+
+ // SR = 0x00
+
+ // determine # of dsp4_vars.raster lines used
+ dsp4_vars.segments = dsp4_vars.poly_raster[0][0] - dsp4_vars.view_y2;
+
+ // prevent overdraw
+ if (dsp4_vars.view_y2 >= dsp4_vars.poly_raster[0][0])
+ dsp4_vars.segments = 0;
+ else
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.view_y2;
+
+ // don't draw outside the window
+ if (dsp4_vars.view_y2 < dsp4_vars.poly_top[0][0])
+ {
+ dsp4_vars.segments = 0;
+
+ // flush remaining dsp4_vars.raster lines
+ if (dsp4_vars.view_y1 >= dsp4_vars.poly_top[0][0])
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.poly_top[0][0];
+ }
+
+ // SR = 0x80
+
+ DSP4_WRITE_WORD(dsp4_vars.segments);
+
+ //////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ INT32 px_dx, py_dy;
+ INT32 x_scroll, y_scroll;
+
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < 4; dsp4_vars.lcv++)
+ {
+ // grab inputs
+ dsp4.in_count = 4;
+ DSP4_WAIT(1);
+ resume1 :
+ for (;;)
+ {
+ INT16 distance;
+ INT16 color, red, green, blue;
+
+ distance = DSP4_READ_WORD();
+ color = DSP4_READ_WORD();
+
+ // U1+B5+G5+R5
+ red = color & 0x1f;
+ green = (color >> 5) & 0x1f;
+ blue = (color >> 10) & 0x1f;
+
+ // dynamic lighting
+ red = (red * distance >> 15) & 0x1f;
+ green = (green * distance >> 15) & 0x1f;
+ blue = (blue * distance >> 15) & 0x1f;
+ color = red | (green << 5) | (blue << 10);
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(color);
+ break;
+ }
+ }
+
+ //////////////////////////////////////////////////////
+
+ // SR = 0x00
+
+ // linear interpolation (lerp) between projected points
+ px_dx = (dsp4_vars.view_xofs2 - dsp4_vars.view_xofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ py_dy = (dsp4_vars.view_yofs2 - dsp4_vars.view_yofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+
+
+ // starting step values
+ x_scroll = SEX16(dsp4_vars.poly_cx[0][0] + dsp4_vars.view_xofs1);
+ y_scroll = SEX16(-dsp4_vars.viewport_bottom + dsp4_vars.view_yofs1 + dsp4_vars.view_yofsenv + dsp4_vars.poly_cx[1][0] - dsp4_vars.world_yofs);
+
+ // SR = 0x80
+
+ // rasterize line
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < dsp4_vars.segments; dsp4_vars.lcv++)
+ {
+ // 1. HDMA memory pointer
+ // 2. vertical scroll offset ($210E)
+ // 3. horizontal scroll offset ($210D)
+
+ DSP4_WRITE_WORD(dsp4_vars.poly_ptr[0][0]);
+ DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
+ DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
+
+ // update memory address
+ dsp4_vars.poly_ptr[0][0] -= 4;
+
+ // update screen values
+ x_scroll += px_dx;
+ y_scroll += py_dy;
+ }
+ }
+
+ ////////////////////////////////////////////////////
+ // Post-update
+
+ // update new viewer (x,y,scroll) to last dsp4_vars.raster line drawn
+ dsp4_vars.view_x1 = dsp4_vars.view_x2;
+ dsp4_vars.view_y1 = dsp4_vars.view_y2;
+ dsp4_vars.view_xofs1 = dsp4_vars.view_xofs2;
+ dsp4_vars.view_yofs1 = dsp4_vars.view_yofs2;
+
+ // add deltas for projection lines
+ dsp4_vars.world_dx += SEX78(dsp4_vars.world_ddx);
+ dsp4_vars.world_dy += SEX78(dsp4_vars.world_ddy);
+
+ // update projection lines
+ dsp4_vars.world_x += (dsp4_vars.world_dx + dsp4_vars.world_xenv);
+ dsp4_vars.world_y += dsp4_vars.world_dy;
+
+ // update road turnoff position
+ dsp4_vars.view_turnoff_x += dsp4_vars.view_turnoff_dx;
+
+ ////////////////////////////////////////////////////
+ // command check
+
+ // scan next command
+ dsp4.in_count = 2;
+ DSP4_WAIT(2) resume2:
+
+ // check for termination
+ dsp4_vars.distance = DSP4_READ_WORD();
+ if (dsp4_vars.distance == -0x8000)
+ break;
+
+ // road splice
+ if( (UINT16) dsp4_vars.distance == 0x8001 )
+ {
+ dsp4.in_count = 6;
+ DSP4_WAIT(3) resume3:
+
+ dsp4_vars.distance = DSP4_READ_WORD();
+ dsp4_vars.view_turnoff_x = DSP4_READ_WORD();
+ dsp4_vars.view_turnoff_dx = DSP4_READ_WORD();
+
+ // factor in new changes
+ dsp4_vars.view_x1 += ( dsp4_vars.view_turnoff_x * dsp4_vars.distance >> 15 );
+ dsp4_vars.view_xofs1 += ( dsp4_vars.view_turnoff_x * dsp4_vars.distance >> 15 );
+
+ // update stepping values
+ dsp4_vars.view_turnoff_x += dsp4_vars.view_turnoff_dx;
+
+ dsp4.in_count = 2;
+ DSP4_WAIT(2)
+ }
- // already have 2 bytes in queue
- DSP4.in_count = 6;
- DSP4_WAIT(4) resume4 :
+ // already have 2 bytes in queue
+ dsp4.in_count = 6;
+ DSP4_WAIT(4) resume4 :
- // inspect inputs
- DSP4_vars.world_ddy = DSP4_READ_WORD();
- DSP4_vars.world_ddx = DSP4_READ_WORD();
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
+ // inspect inputs
+ dsp4_vars.world_ddy = DSP4_READ_WORD();
+ dsp4_vars.world_ddx = DSP4_READ_WORD();
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
- // no envelope here
- DSP4_vars.world_xenv = 0;
- }
- while (1);
+ // no envelope here
+ dsp4_vars.world_xenv = 0;
+ }
+ while (1);
- // terminate op
- DSP4.waiting4command = 1;
+ // terminate op
+ dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP10( void )
+static void dsp4_OP10( void )
{
- DSP4.waiting4command = 0;
-
- // op flow control
- switch (DSP4_vars.DSP4_Logic)
- {
- case 1:
- goto resume1; break;
- case 2:
- goto resume2; break;
- case 3:
- goto resume3; break;
- }
-
- ////////////////////////////////////////////////////
- // sort inputs
-
- DSP4_READ_WORD(); // 0x0000
- DSP4_vars.world_y = DSP4_READ_DWORD();
- DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_top[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD();
- DSP4_vars.viewport_bottom = DSP4_READ_WORD();
- DSP4_vars.world_x = DSP4_READ_DWORD();
- DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD();
- DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
- DSP4_vars.world_yofs = DSP4_READ_WORD();
- DSP4_vars.distance = DSP4_READ_WORD();
- DSP4_vars.view_y2 = DSP4_READ_WORD();
- DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_x2 = DSP4_READ_WORD();
- DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_yofsenv = DSP4_READ_WORD();
-
- // initial (x,y,offset) at starting DSP4_vars.raster line
- DSP4_vars.view_x1 = (INT16)(DSP4_vars.world_x >> 16);
- DSP4_vars.view_y1 = (INT16)(DSP4_vars.world_y >> 16);
- DSP4_vars.view_xofs1 = DSP4_vars.view_x1;
- DSP4_vars.view_yofs1 = DSP4_vars.world_yofs;
-
- // first DSP4_vars.raster line
- DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0];
-
- do
- {
- ////////////////////////////////////////////////////
- // process one iteration of projection
-
- // add shaping
- DSP4_vars.view_x2 += DSP4_vars.view_dx;
- DSP4_vars.view_y2 += DSP4_vars.view_dy;
-
- // vertical scroll calculation
- DSP4_vars.view_xofs2 = DSP4_vars.view_x2;
- DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2;
-
- // 1. Viewer x-position at the next
- // 2. Viewer y-position below the horizon
- // 3. Number of DSP4_vars.raster lines drawn in this iteration
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(DSP4_vars.view_x2);
- DSP4_WRITE_WORD(DSP4_vars.view_y2);
-
- //////////////////////////////////////////////////////
-
- // SR = 0x00
-
- // determine # of DSP4_vars.raster lines used
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2;
-
- // prevent overdraw
- if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0])
- DSP4_vars.segments = 0;
- else
- DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2;
-
- // don't draw outside the window
- if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0])
- {
- DSP4_vars.segments = 0;
-
- // flush remaining DSP4_vars.raster lines
- if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0])
- DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0];
- }
-
- // SR = 0x80
-
- DSP4_WRITE_WORD(DSP4_vars.segments);
-
- //////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++)
- {
- // grab inputs
- DSP4.in_count = 4;
- DSP4_WAIT(1);
- resume1 :
- for (;;)
- {
- INT16 distance;
- INT16 color, red, green, blue;
-
- distance = DSP4_READ_WORD();
- color = DSP4_READ_WORD();
-
- // U1+B5+G5+R5
- red = color & 0x1f;
- green = (color >> 5) & 0x1f;
- blue = (color >> 10) & 0x1f;
-
- // dynamic lighting
- red = (red * distance >> 15) & 0x1f;
- green = (green * distance >> 15) & 0x1f;
- blue = (blue * distance >> 15) & 0x1f;
- color = red | (green << 5) | (blue << 10);
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(color);
- break;
- }
- }
- }
-
- //////////////////////////////////////////////////////
-
- // scan next command if no SR check needed
- if (DSP4_vars.segments)
- {
- INT32 px_dx, py_dy;
- INT32 x_scroll, y_scroll;
-
- // SR = 0x00
-
- // linear interpolation (lerp) between projected points
- px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
- py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1;
-
- // starting step values
- x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1);
- y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs);
-
- // SR = 0x80
-
- // rasterize line
- for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++)
- {
- // 1. HDMA memory pointer (bg2)
- // 2. vertical scroll offset ($2110)
- // 3. horizontal scroll offset ($210F)
-
- DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]);
- DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
- DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
-
- // update memory address
- DSP4_vars.poly_ptr[0][0] -= 4;
-
- // update screen values
- x_scroll += px_dx;
- y_scroll += py_dy;
- }
- }
-
- /////////////////////////////////////////////////////
- // Post-update
-
- // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn
- DSP4_vars.view_x1 = DSP4_vars.view_x2;
- DSP4_vars.view_y1 = DSP4_vars.view_y2;
- DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2;
- DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2;
-
- ////////////////////////////////////////////////////
- // command check
-
- // scan next command
- DSP4.in_count = 2;
- DSP4_WAIT(2) resume2 :
-
- // check for opcode termination
- DSP4_vars.distance = DSP4_READ_WORD();
- if (DSP4_vars.distance == -0x8000)
- break;
-
- // already have 2 bytes in queue
- DSP4.in_count = 10;
- DSP4_WAIT(3) resume3 :
-
-
- // inspect inputs
- DSP4_vars.view_y2 = DSP4_READ_WORD();
- DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- DSP4_vars.view_x2 = DSP4_READ_WORD();
- DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15;
- }
- while (1);
-
- DSP4.waiting4command = 1;
+ dsp4.waiting4command = 0;
+
+ // op flow control
+ switch (dsp4_vars.Logic)
+ {
+ case 1:
+ goto resume1; break;
+ case 2:
+ goto resume2; break;
+ case 3:
+ goto resume3; break;
+ }
+
+ ////////////////////////////////////////////////////
+ // sort inputs
+
+ DSP4_READ_WORD(); // 0x0000
+ dsp4_vars.world_y = DSP4_READ_DWORD();
+ dsp4_vars.poly_bottom[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_top[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_cx[1][0] = DSP4_READ_WORD();
+ dsp4_vars.viewport_bottom = DSP4_READ_WORD();
+ dsp4_vars.world_x = DSP4_READ_DWORD();
+ dsp4_vars.poly_cx[0][0] = DSP4_READ_WORD();
+ dsp4_vars.poly_ptr[0][0] = DSP4_READ_WORD();
+ dsp4_vars.world_yofs = DSP4_READ_WORD();
+ dsp4_vars.distance = DSP4_READ_WORD();
+ dsp4_vars.view_y2 = DSP4_READ_WORD();
+ dsp4_vars.view_dy = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_x2 = DSP4_READ_WORD();
+ dsp4_vars.view_dx = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_yofsenv = DSP4_READ_WORD();
+
+ // initial (x,y,offset) at starting dsp4_vars.raster line
+ dsp4_vars.view_x1 = (INT16)(dsp4_vars.world_x >> 16);
+ dsp4_vars.view_y1 = (INT16)(dsp4_vars.world_y >> 16);
+ dsp4_vars.view_xofs1 = dsp4_vars.view_x1;
+ dsp4_vars.view_yofs1 = dsp4_vars.world_yofs;
+
+ // first dsp4_vars.raster line
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.poly_bottom[0][0];
+
+ do
+ {
+ ////////////////////////////////////////////////////
+ // process one iteration of projection
+
+ // add shaping
+ dsp4_vars.view_x2 += dsp4_vars.view_dx;
+ dsp4_vars.view_y2 += dsp4_vars.view_dy;
+
+ // vertical scroll calculation
+ dsp4_vars.view_xofs2 = dsp4_vars.view_x2;
+ dsp4_vars.view_yofs2 = (dsp4_vars.world_yofs * dsp4_vars.distance >> 15) + dsp4_vars.poly_bottom[0][0] - dsp4_vars.view_y2;
+
+ // 1. Viewer x-position at the next
+ // 2. Viewer y-position below the horizon
+ // 3. Number of dsp4_vars.raster lines drawn in this iteration
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(dsp4_vars.view_x2);
+ DSP4_WRITE_WORD(dsp4_vars.view_y2);
+
+ //////////////////////////////////////////////////////
+
+ // SR = 0x00
+
+ // determine # of dsp4_vars.raster lines used
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.view_y2;
+
+ // prevent overdraw
+ if (dsp4_vars.view_y2 >= dsp4_vars.poly_raster[0][0])
+ dsp4_vars.segments = 0;
+ else
+ dsp4_vars.poly_raster[0][0] = dsp4_vars.view_y2;
+
+ // don't draw outside the window
+ if (dsp4_vars.view_y2 < dsp4_vars.poly_top[0][0])
+ {
+ dsp4_vars.segments = 0;
+
+ // flush remaining dsp4_vars.raster lines
+ if (dsp4_vars.view_y1 >= dsp4_vars.poly_top[0][0])
+ dsp4_vars.segments = dsp4_vars.view_y1 - dsp4_vars.poly_top[0][0];
+ }
+
+ // SR = 0x80
+
+ DSP4_WRITE_WORD(dsp4_vars.segments);
+
+ //////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < 4; dsp4_vars.lcv++)
+ {
+ // grab inputs
+ dsp4.in_count = 4;
+ DSP4_WAIT(1);
+ resume1 :
+ for (;;)
+ {
+ INT16 distance;
+ INT16 color, red, green, blue;
+
+ distance = DSP4_READ_WORD();
+ color = DSP4_READ_WORD();
+
+ // U1+B5+G5+R5
+ red = color & 0x1f;
+ green = (color >> 5) & 0x1f;
+ blue = (color >> 10) & 0x1f;
+
+ // dynamic lighting
+ red = (red * distance >> 15) & 0x1f;
+ green = (green * distance >> 15) & 0x1f;
+ blue = (blue * distance >> 15) & 0x1f;
+ color = red | (green << 5) | (blue << 10);
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(color);
+ break;
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////////
+
+ // scan next command if no SR check needed
+ if (dsp4_vars.segments)
+ {
+ INT32 px_dx, py_dy;
+ INT32 x_scroll, y_scroll;
+
+ // SR = 0x00
+
+ // linear interpolation (lerp) between projected points
+ px_dx = (dsp4_vars.view_xofs2 - dsp4_vars.view_xofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+ py_dy = (dsp4_vars.view_yofs2 - dsp4_vars.view_yofs1) * dsp4_Inverse(dsp4_vars.segments) << 1;
+
+ // starting step values
+ x_scroll = SEX16(dsp4_vars.poly_cx[0][0] + dsp4_vars.view_xofs1);
+ y_scroll = SEX16(-dsp4_vars.viewport_bottom + dsp4_vars.view_yofs1 + dsp4_vars.view_yofsenv + dsp4_vars.poly_cx[1][0] - dsp4_vars.world_yofs);
+
+ // SR = 0x80
+
+ // rasterize line
+ for (dsp4_vars.lcv = 0; dsp4_vars.lcv < dsp4_vars.segments; dsp4_vars.lcv++)
+ {
+ // 1. HDMA memory pointer (bg2)
+ // 2. vertical scroll offset ($2110)
+ // 3. horizontal scroll offset ($210F)
+
+ DSP4_WRITE_WORD(dsp4_vars.poly_ptr[0][0]);
+ DSP4_WRITE_WORD((UINT16)((y_scroll + 0x8000) >> 16));
+ DSP4_WRITE_WORD((UINT16)((x_scroll + 0x8000) >> 16));
+
+ // update memory address
+ dsp4_vars.poly_ptr[0][0] -= 4;
+
+ // update screen values
+ x_scroll += px_dx;
+ y_scroll += py_dy;
+ }
+ }
+
+ /////////////////////////////////////////////////////
+ // Post-update
+
+ // update new viewer (x,y,scroll) to last dsp4_vars.raster line drawn
+ dsp4_vars.view_x1 = dsp4_vars.view_x2;
+ dsp4_vars.view_y1 = dsp4_vars.view_y2;
+ dsp4_vars.view_xofs1 = dsp4_vars.view_xofs2;
+ dsp4_vars.view_yofs1 = dsp4_vars.view_yofs2;
+
+ ////////////////////////////////////////////////////
+ // command check
+
+ // scan next command
+ dsp4.in_count = 2;
+ DSP4_WAIT(2) resume2 :
+
+ // check for opcode termination
+ dsp4_vars.distance = DSP4_READ_WORD();
+ if (dsp4_vars.distance == -0x8000)
+ break;
+
+ // already have 2 bytes in queue
+ dsp4.in_count = 10;
+ DSP4_WAIT(3) resume3 :
+
+
+ // inspect inputs
+ dsp4_vars.view_y2 = DSP4_READ_WORD();
+ dsp4_vars.view_dy = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ dsp4_vars.view_x2 = DSP4_READ_WORD();
+ dsp4_vars.view_dx = DSP4_READ_WORD() * dsp4_vars.distance >> 15;
+ }
+ while (1);
+
+ dsp4.waiting4command = 1;
}
//////////////////////////////////////////////////////////////
-static void DSP4_OP11(INT16 A, INT16 B, INT16 C, INT16 D, INT16 *M)
+static void dsp4_OP11(INT16 A, INT16 B, INT16 C, INT16 D, INT16 *M)
{
- // 0x155 = 341 = Horizontal Width of the Screen
- *M = ((A * 0x0155 >> 2) & 0xf000) |
- ((B * 0x0155 >> 6) & 0x0f00) |
- ((C * 0x0155 >> 10) & 0x00f0) |
- ((D * 0x0155 >> 14) & 0x000f);
+ // 0x155 = 341 = Horizontal Width of the Screen
+ *M = ((A * 0x0155 >> 2) & 0xf000) |
+ ((B * 0x0155 >> 6) & 0x0f00) |
+ ((C * 0x0155 >> 10) & 0x00f0) |
+ ((D * 0x0155 >> 14) & 0x000f);
}
@@ -1952,228 +1953,312 @@ static void DSP4_OP11(INT16 A, INT16 B, INT16 C, INT16 D, INT16 *M)
//Processing Code
/////////////////////////////////////////////////////////////
-static void InitDSP4( void )
+static void dsp4_register_save( running_machine *machine )
{
- memset(&DSP4, 0, sizeof(DSP4));
- DSP4.waiting4command = 1;
+ state_save_register_global(machine, dsp4.waiting4command);
+ state_save_register_global(machine, dsp4.half_command);
+ state_save_register_global(machine, dsp4.command);
+ state_save_register_global(machine, dsp4.in_count);
+ state_save_register_global(machine, dsp4.in_index);
+ state_save_register_global(machine, dsp4.out_count);
+ state_save_register_global(machine, dsp4.out_index);
+ state_save_register_global_array(machine, dsp4.parameters);
+ state_save_register_global_array(machine, dsp4.output);
+
+ state_save_register_global(machine, dsp4_vars.Logic);
+ state_save_register_global(machine, dsp4_vars.lcv);
+ state_save_register_global(machine, dsp4_vars.distance);
+ state_save_register_global(machine, dsp4_vars.raster);
+ state_save_register_global(machine, dsp4_vars.segments);
+
+ state_save_register_global(machine, dsp4_vars.world_x);
+ state_save_register_global(machine, dsp4_vars.world_y);
+ state_save_register_global(machine, dsp4_vars.world_dx);
+ state_save_register_global(machine, dsp4_vars.world_dy);
+ state_save_register_global(machine, dsp4_vars.world_ddx);
+ state_save_register_global(machine, dsp4_vars.world_ddy);
+ state_save_register_global(machine, dsp4_vars.world_xenv);
+ state_save_register_global(machine, dsp4_vars.world_yofs);
+
+ state_save_register_global(machine, dsp4_vars.view_x1);
+ state_save_register_global(machine, dsp4_vars.view_y1);
+ state_save_register_global(machine, dsp4_vars.view_x2);
+ state_save_register_global(machine, dsp4_vars.view_y2);
+ state_save_register_global(machine, dsp4_vars.view_dx);
+ state_save_register_global(machine, dsp4_vars.view_dy);
+ state_save_register_global(machine, dsp4_vars.view_xofs1);
+ state_save_register_global(machine, dsp4_vars.view_yofs1);
+ state_save_register_global(machine, dsp4_vars.view_xofs2);
+ state_save_register_global(machine, dsp4_vars.view_yofs2);
+ state_save_register_global(machine, dsp4_vars.view_yofsenv);
+ state_save_register_global(machine, dsp4_vars.view_turnoff_x);
+ state_save_register_global(machine, dsp4_vars.view_turnoff_dx);
+
+
+ state_save_register_global(machine, dsp4_vars.viewport_cx);
+ state_save_register_global(machine, dsp4_vars.viewport_cy);
+ state_save_register_global(machine, dsp4_vars.viewport_left);
+ state_save_register_global(machine, dsp4_vars.viewport_right);
+ state_save_register_global(machine, dsp4_vars.viewport_top);
+ state_save_register_global(machine, dsp4_vars.viewport_bottom);
+
+
+ state_save_register_global(machine, dsp4_vars.sprite_x);
+ state_save_register_global(machine, dsp4_vars.sprite_y);
+ state_save_register_global(machine, dsp4_vars.sprite_attr);
+ state_save_register_global(machine, dsp4_vars.sprite_size);
+ state_save_register_global(machine, dsp4_vars.sprite_clipy);
+ state_save_register_global(machine, dsp4_vars.sprite_count);
+
+ state_save_register_global_array(machine, dsp4_vars.poly_clipLf[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_clipLf[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_clipRt[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_clipRt[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_ptr[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_ptr[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_raster[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_raster[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_top[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_top[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_bottom[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_bottom[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_cx[0]);
+ state_save_register_global_array(machine, dsp4_vars.poly_cx[1]);
+ state_save_register_global_array(machine, dsp4_vars.poly_start);
+ state_save_register_global_array(machine, dsp4_vars.poly_plane);
+
+ state_save_register_global_array(machine, dsp4_vars.OAM_attr);
+ state_save_register_global(machine, dsp4_vars.OAM_index);
+ state_save_register_global(machine, dsp4_vars.OAM_bits);
+
+ state_save_register_global(machine, dsp4_vars.OAM_RowMax);
+ state_save_register_global_array(machine, dsp4_vars.OAM_Row);
}
-static void DSP4_write( UINT8 dsp4_byte )
+static void dsp4_init( running_machine *machine )
{
- // clear pending read
- if (DSP4.out_index < DSP4.out_count)
- {
- DSP4.out_index++;
- return;
- }
-
- if (DSP4.waiting4command)
- {
- if (DSP4.half_command)
- {
- DSP4.command |= (dsp4_byte << 8);
- DSP4.in_index = 0;
- DSP4.waiting4command = 0;
- DSP4.half_command = 0;
- DSP4.out_count = 0;
- DSP4.out_index = 0;
-
- DSP4_vars.DSP4_Logic = 0;
-
-
- switch (DSP4.command)
- {
- case 0x0000:
- DSP4.in_count = 4; break;
- case 0x0001:
- DSP4.in_count = 44; break;
- case 0x0003:
- DSP4.in_count = 0; break;
- case 0x0005:
- DSP4.in_count = 0; break;
- case 0x0006:
- DSP4.in_count = 0; break;
- case 0x0007:
- DSP4.in_count = 34; break;
- case 0x0008:
- DSP4.in_count = 90; break;
- case 0x0009:
- DSP4.in_count = 14; break;
- case 0x000a:
- DSP4.in_count = 6; break;
- case 0x000b:
- DSP4.in_count = 6; break;
- case 0x000d:
- DSP4.in_count = 42; break;
- case 0x000e:
- DSP4.in_count = 0; break;
- case 0x000f:
- DSP4.in_count = 46; break;
- case 0x0010:
- DSP4.in_count = 36; break;
- case 0x0011:
- DSP4.in_count = 8; break;
- default:
- DSP4.waiting4command = 1;
- break;
- }
- }
- else
- {
- DSP4.command = dsp4_byte;
- DSP4.half_command = 1;
- }
- }
- else
- {
- DSP4.parameters[DSP4.in_index] = dsp4_byte;
- DSP4.in_index++;
- }
-
- if (!DSP4.waiting4command && DSP4.in_count == DSP4.in_index)
- {
- // Actually execute the command
- DSP4.waiting4command = 1;
- DSP4.out_index = 0;
- DSP4.in_index = 0;
-
- switch (DSP4.command)
- {
- // 16-bit multiplication
- case 0x0000:
- {
- INT16 multiplier, multiplicand;
- INT32 product;
-
- multiplier = DSP4_READ_WORD();
- multiplicand = DSP4_READ_WORD();
-
- DSP4_Multiply(multiplicand, multiplier, &product);
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD((UINT16)(product));
- DSP4_WRITE_WORD((UINT16)(product >> 16));
- }
- break;
-
- // single-player track projection
- case 0x0001:
- DSP4_OP01(); break;
-
- // single-player selection
- case 0x0003:
- DSP4_OP03(); break;
-
- // clear OAM
- case 0x0005:
- DSP4_OP05(); break;
-
- // transfer OAM
- case 0x0006:
- DSP4_OP06(); break;
-
- // single-player track turnoff projection
- case 0x0007:
- DSP4_OP07(); break;
-
- // solid polygon projection
- case 0x0008:
- DSP4_OP08(); break;
-
- // sprite projection
- case 0x0009:
- DSP4_OP09(); break;
-
- // unknown
- case 0x000A:
- {
- INT16 in2a;
- INT16 out1a, out2a, out3a, out4a;
-
- /* in1a = */ DSP4_READ_WORD();
- in2a = DSP4_READ_WORD();
- /* in3a = */ DSP4_READ_WORD();
-
- DSP4_OP0A(in2a, &out2a, &out1a, &out4a, &out3a);
-
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(out1a);
- DSP4_WRITE_WORD(out2a);
- DSP4_WRITE_WORD(out3a);
- DSP4_WRITE_WORD(out4a);
- }
- break;
-
- // set OAM
- case 0x000B:
- {
- INT16 sp_x = DSP4_READ_WORD();
- INT16 sp_y = DSP4_READ_WORD();
- INT16 sp_attr = DSP4_READ_WORD();
- UINT8 draw = 1;
-
- DSP4_CLEAR_OUT();
-
- DSP4_OP0B(&draw, sp_x, sp_y, sp_attr, 0, 1);
- }
- break;
-
- // multi-player track projection
- case 0x000D:
- DSP4_OP0D(); break;
-
- // multi-player selection
- case 0x000E:
- DSP4_OP0E(); break;
-
- // single-player track projection with lighting
- case 0x000F:
- DSP4_OP0F(); break;
-
- // single-player track turnoff projection with lighting
- case 0x0010:
- DSP4_OP10(); break;
-
- // unknown: horizontal mapping command
- case 0x0011:
- {
- INT16 a, b, c, d, m;
-
-
- d = DSP4_READ_WORD();
- c = DSP4_READ_WORD();
- b = DSP4_READ_WORD();
- a = DSP4_READ_WORD();
+ memset(&dsp4, 0, sizeof(dsp4));
+ dsp4.waiting4command = 1;
- DSP4_OP11(a, b, c, d, &m);
+ dsp4_register_save(machine);
+}
+
+static void dsp4_write( UINT8 dsp4_byte )
+{
+ // clear pending read
+ if (dsp4.out_index < dsp4.out_count)
+ {
+ dsp4.out_index++;
+ return;
+ }
+
+ if (dsp4.waiting4command)
+ {
+ if (dsp4.half_command)
+ {
+ dsp4.command |= (dsp4_byte << 8);
+ dsp4.in_index = 0;
+ dsp4.waiting4command = 0;
+ dsp4.half_command = 0;
+ dsp4.out_count = 0;
+ dsp4.out_index = 0;
+
+ dsp4_vars.Logic = 0;
+
+
+ switch (dsp4.command)
+ {
+ case 0x0000:
+ dsp4.in_count = 4; break;
+ case 0x0001:
+ dsp4.in_count = 44; break;
+ case 0x0003:
+ dsp4.in_count = 0; break;
+ case 0x0005:
+ dsp4.in_count = 0; break;
+ case 0x0006:
+ dsp4.in_count = 0; break;
+ case 0x0007:
+ dsp4.in_count = 34; break;
+ case 0x0008:
+ dsp4.in_count = 90; break;
+ case 0x0009:
+ dsp4.in_count = 14; break;
+ case 0x000a:
+ dsp4.in_count = 6; break;
+ case 0x000b:
+ dsp4.in_count = 6; break;
+ case 0x000d:
+ dsp4.in_count = 42; break;
+ case 0x000e:
+ dsp4.in_count = 0; break;
+ case 0x000f:
+ dsp4.in_count = 46; break;
+ case 0x0010:
+ dsp4.in_count = 36; break;
+ case 0x0011:
+ dsp4.in_count = 8; break;
+ default:
+ dsp4.waiting4command = 1;
+ break;
+ }
+ }
+ else
+ {
+ dsp4.command = dsp4_byte;
+ dsp4.half_command = 1;
+ }
+ }
+ else
+ {
+ dsp4.parameters[dsp4.in_index] = dsp4_byte;
+ dsp4.in_index++;
+ }
+
+ if (!dsp4.waiting4command && dsp4.in_count == dsp4.in_index)
+ {
+ // Actually execute the command
+ dsp4.waiting4command = 1;
+ dsp4.out_index = 0;
+ dsp4.in_index = 0;
+
+ switch (dsp4.command)
+ {
+ // 16-bit multiplication
+ case 0x0000:
+ {
+ INT16 multiplier, multiplicand;
+ INT32 product;
+
+ multiplier = DSP4_READ_WORD();
+ multiplicand = DSP4_READ_WORD();
+
+ dsp4_Multiply(multiplicand, multiplier, &product);
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD((UINT16)(product));
+ DSP4_WRITE_WORD((UINT16)(product >> 16));
+ }
+ break;
+
+ // single-player track projection
+ case 0x0001:
+ dsp4_OP01(); break;
+
+ // single-player selection
+ case 0x0003:
+ dsp4_OP03(); break;
+
+ // clear OAM
+ case 0x0005:
+ dsp4_OP05(); break;
+
+ // transfer OAM
+ case 0x0006:
+ dsp4_OP06(); break;
+
+ // single-player track turnoff projection
+ case 0x0007:
+ dsp4_OP07(); break;
+
+ // solid polygon projection
+ case 0x0008:
+ dsp4_OP08(); break;
+
+ // sprite projection
+ case 0x0009:
+ dsp4_OP09(); break;
+
+ // unknown
+ case 0x000A:
+ {
+ INT16 in2a;
+ INT16 out1a, out2a, out3a, out4a;
+
+ /* in1a = */ DSP4_READ_WORD();
+ in2a = DSP4_READ_WORD();
+ /* in3a = */ DSP4_READ_WORD();
+
+ dsp4_OP0A(in2a, &out2a, &out1a, &out4a, &out3a);
+
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(out1a);
+ DSP4_WRITE_WORD(out2a);
+ DSP4_WRITE_WORD(out3a);
+ DSP4_WRITE_WORD(out4a);
+ }
+ break;
+
+ // set OAM
+ case 0x000B:
+ {
+ INT16 sp_x = DSP4_READ_WORD();
+ INT16 sp_y = DSP4_READ_WORD();
+ INT16 sp_attr = DSP4_READ_WORD();
+ UINT8 draw = 1;
+
+ DSP4_CLEAR_OUT();
+
+ dsp4_OP0B(&draw, sp_x, sp_y, sp_attr, 0, 1);
+ }
+ break;
+
+ // multi-player track projection
+ case 0x000D:
+ dsp4_OP0D(); break;
+
+ // multi-player selection
+ case 0x000E:
+ dsp4_OP0E(); break;
+
+ // single-player track projection with lighting
+ case 0x000F:
+ dsp4_OP0F(); break;
+
+ // single-player track turnoff projection with lighting
+ case 0x0010:
+ dsp4_OP10(); break;
+
+ // unknown: horizontal mapping command
+ case 0x0011:
+ {
+ INT16 a, b, c, d, m;
+
+
+ d = DSP4_READ_WORD();
+ c = DSP4_READ_WORD();
+ b = DSP4_READ_WORD();
+ a = DSP4_READ_WORD();
+
+ dsp4_OP11(a, b, c, d, &m);
- DSP4_CLEAR_OUT();
- DSP4_WRITE_WORD(m);
-
- break;
- }
-
- default:
- break;
- }
- }
+ DSP4_CLEAR_OUT();
+ DSP4_WRITE_WORD(m);
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
}
-static UINT8 DSP4_read( void )
+static UINT8 dsp4_read( void )
{
- UINT8 value;
-
- if (DSP4.out_count)
- {
- value = (UINT8) DSP4.output[DSP4.out_index&0x1FF];
- DSP4.out_index++;
- if (DSP4.out_count == DSP4.out_index)
- DSP4.out_count = 0;
- }
- else
- {
- value = 0xff;
- }
-
- return value;
+ UINT8 value;
+
+ if (dsp4.out_count)
+ {
+ value = (UINT8) dsp4.output[dsp4.out_index&0x1FF];
+ dsp4.out_index++;
+ if (dsp4.out_count == dsp4.out_index)
+ dsp4.out_count = 0;
+ }
+ else
+ {
+ value = 0xff;
+ }
+
+ return value;
}
diff --git a/src/mame/machine/snesdsp4.h b/src/mame/machine/snesdsp4.h
index c37d37a3a02..fd3fd0bceb7 100644
--- a/src/mame/machine/snesdsp4.h
+++ b/src/mame/machine/snesdsp4.h
@@ -5,96 +5,96 @@
#define TRUE 1
-struct DSP4_t
+struct dsp4_t
{
- UINT8 waiting4command;
- UINT8 half_command;
- UINT16 command;
- UINT32 in_count;
- UINT32 in_index;
- UINT32 out_count;
- UINT32 out_index;
- UINT8 parameters[512];
- UINT8 output[512];
+ UINT8 waiting4command;
+ UINT8 half_command;
+ UINT16 command;
+ UINT32 in_count;
+ UINT32 in_index;
+ UINT32 out_count;
+ UINT32 out_index;
+ UINT8 parameters[512];
+ UINT8 output[512];
};
-struct DSP4_vars_t
+struct dsp4_vars_t
{
- // op control
- INT8 DSP4_Logic; // controls op flow
-
-
- // projection format
- INT16 lcv; // loop-control variable
- INT16 distance; // z-position INTo virtual world
- INT16 raster; // current raster line
- INT16 segments; // number of raster lines drawn
-
- // 1.15.16 or 1.15.0 [sign, INTeger, fraction]
- INT32 world_x; // line of x-projection in world
- INT32 world_y; // line of y-projection in world
- INT32 world_dx; // projection line x-delta
- INT32 world_dy; // projection line y-delta
- INT16 world_ddx; // x-delta increment
- INT16 world_ddy; // y-delta increment
- INT32 world_xenv; // world x-shaping factor
- INT16 world_yofs; // world y-vertical scroll
-
- INT16 view_x1; // current viewer-x
- INT16 view_y1; // current viewer-y
- INT16 view_x2; // future viewer-x
- INT16 view_y2; // future viewer-y
- INT16 view_dx; // view x-delta factor
- INT16 view_dy; // view y-delta factor
- INT16 view_xofs1; // current viewer x-vertical scroll
- INT16 view_yofs1; // current viewer y-vertical scroll
- INT16 view_xofs2; // future viewer x-vertical scroll
- INT16 view_yofs2; // future viewer y-vertical scroll
- INT16 view_yofsenv; // y-scroll shaping factor
- INT16 view_turnoff_x; // road turnoff data
- INT16 view_turnoff_dx; // road turnoff delta factor
-
-
- // drawing area
-
- INT16 viewport_cx; // x-center of viewport window
- INT16 viewport_cy; // y-center of render window
- INT16 viewport_left; // x-left of viewport
- INT16 viewport_right; // x-right of viewport
- INT16 viewport_top; // y-top of viewport
- INT16 viewport_bottom; // y-bottom of viewport
-
-
- // sprite structure
-
- INT16 sprite_x; // projected x-pos of sprite
- INT16 sprite_y; // projected y-pos of sprite
- INT16 sprite_attr; // obj attributes
- UINT8 sprite_size; // sprite size: 8x8 or 16x16
- INT16 sprite_clipy; // visible line to clip pixels off
- INT16 sprite_count;
-
- // generic projection variables designed for
- // two solid polygons + two polygon sides
-
- INT16 poly_clipLf[2][2]; // left clip boundary
- INT16 poly_clipRt[2][2]; // right clip boundary
- INT16 poly_ptr[2][2]; // HDMA structure poINTers
- INT16 poly_raster[2][2]; // current raster line below horizon
- INT16 poly_top[2][2]; // top clip boundary
- INT16 poly_bottom[2][2]; // bottom clip boundary
- INT16 poly_cx[2][2]; // center for left/right poINTs
- INT16 poly_start[2]; // current projection poINTs
- INT16 poly_plane[2]; // previous z-plane distance
-
-
- // OAM
- INT16 OAM_attr[16]; // OAM (size,MSB) data
- INT16 OAM_index; // index INTo OAM table
- INT16 OAM_bits; // offset INTo OAM table
-
- INT16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row)
- INT16 OAM_Row[32]; // current number of tiles per row
+ // op control
+ INT8 Logic; // controls op flow
+
+
+ // projection format
+ INT16 lcv; // loop-control variable
+ INT16 distance; // z-position into virtual world
+ INT16 raster; // current raster line
+ INT16 segments; // number of raster lines drawn
+
+ // 1.15.16 or 1.15.0 [sign, INTeger, fraction]
+ INT32 world_x; // line of x-projection in world
+ INT32 world_y; // line of y-projection in world
+ INT32 world_dx; // projection line x-delta
+ INT32 world_dy; // projection line y-delta
+ INT16 world_ddx; // x-delta increment
+ INT16 world_ddy; // y-delta increment
+ INT32 world_xenv; // world x-shaping factor
+ INT16 world_yofs; // world y-vertical scroll
+
+ INT16 view_x1; // current viewer-x
+ INT16 view_y1; // current viewer-y
+ INT16 view_x2; // future viewer-x
+ INT16 view_y2; // future viewer-y
+ INT16 view_dx; // view x-delta factor
+ INT16 view_dy; // view y-delta factor
+ INT16 view_xofs1; // current viewer x-vertical scroll
+ INT16 view_yofs1; // current viewer y-vertical scroll
+ INT16 view_xofs2; // future viewer x-vertical scroll
+ INT16 view_yofs2; // future viewer y-vertical scroll
+ INT16 view_yofsenv; // y-scroll shaping factor
+ INT16 view_turnoff_x; // road turnoff data
+ INT16 view_turnoff_dx; // road turnoff delta factor
+
+
+ // drawing area
+
+ INT16 viewport_cx; // x-center of viewport window
+ INT16 viewport_cy; // y-center of render window
+ INT16 viewport_left; // x-left of viewport
+ INT16 viewport_right; // x-right of viewport
+ INT16 viewport_top; // y-top of viewport
+ INT16 viewport_bottom; // y-bottom of viewport
+
+
+ // sprite structure
+
+ INT16 sprite_x; // projected x-pos of sprite
+ INT16 sprite_y; // projected y-pos of sprite
+ INT16 sprite_attr; // obj attributes
+ UINT8 sprite_size; // sprite size: 8x8 or 16x16
+ INT16 sprite_clipy; // visible line to clip pixels off
+ INT16 sprite_count;
+
+ // generic projection variables designed for
+ // two solid polygons + two polygon sides
+
+ INT16 poly_clipLf[2][2]; // left clip boundary
+ INT16 poly_clipRt[2][2]; // right clip boundary
+ INT16 poly_ptr[2][2]; // HDMA structure pointers
+ INT16 poly_raster[2][2]; // current raster line below horizon
+ INT16 poly_top[2][2]; // top clip boundary
+ INT16 poly_bottom[2][2]; // bottom clip boundary
+ INT16 poly_cx[2][2]; // center for left/right points
+ INT16 poly_start[2]; // current projection points
+ INT16 poly_plane[2]; // previous z-plane distance
+
+
+ // OAM
+ INT16 OAM_attr[16]; // OAM (size,MSB) data
+ INT16 OAM_index; // index into OAM table
+ INT16 OAM_bits; // offset into OAM table
+
+ INT16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row)
+ INT16 OAM_Row[32]; // current number of tiles per row
};
#endif
diff --git a/src/mame/machine/snesobc1.c b/src/mame/machine/snesobc1.c
index c1901d46f65..4720effa0cb 100644
--- a/src/mame/machine/snesobc1.c
+++ b/src/mame/machine/snesobc1.c
@@ -12,11 +12,15 @@
***************************************************************************/
-#include "includes/snes.h"
+struct _snes_obc1_state
+{
+ int address;
+ int offset;
+ int shift;
+};
+
+static struct _snes_obc1_state obc1_state;
-static int obc1_address;
-static int obc1_offset;
-static int obc1_shift;
static READ8_HANDLER( obc1_read )
{
@@ -26,23 +30,23 @@ static READ8_HANDLER( obc1_read )
switch (address)
{
case 0x1ff0:
- value = snes_ram[obc1_offset + (obc1_address << 2) + 0];
+ value = snes_ram[obc1_state.offset + (obc1_state.address << 2) + 0];
break;
case 0x1ff1:
- value = snes_ram[obc1_offset + (obc1_address << 2) + 1];
+ value = snes_ram[obc1_state.offset + (obc1_state.address << 2) + 1];
break;
case 0x1ff2:
- value = snes_ram[obc1_offset + (obc1_address << 2) + 2];
+ value = snes_ram[obc1_state.offset + (obc1_state.address << 2) + 2];
break;
case 0x1ff3:
- value = snes_ram[obc1_offset + (obc1_address << 2) + 3];
+ value = snes_ram[obc1_state.offset + (obc1_state.address << 2) + 3];
break;
case 0x1ff4:
- value = snes_ram[obc1_offset + (obc1_address >> 2) + 0x200];
+ value = snes_ram[obc1_state.offset + (obc1_state.address >> 2) + 0x200];
break;
default:
@@ -62,35 +66,35 @@ static WRITE8_HANDLER( obc1_write )
switch(address)
{
case 0x1ff0:
- snes_ram[obc1_offset + (obc1_address << 2) + 0] = data;
+ snes_ram[obc1_state.offset + (obc1_state.address << 2) + 0] = data;
break;
case 0x1ff1:
- snes_ram[obc1_offset + (obc1_address << 2) + 1] = data;
+ snes_ram[obc1_state.offset + (obc1_state.address << 2) + 1] = data;
break;
case 0x1ff2:
- snes_ram[obc1_offset + (obc1_address << 2) + 2] = data;
+ snes_ram[obc1_state.offset + (obc1_state.address << 2) + 2] = data;
break;
case 0x1ff3:
- snes_ram[obc1_offset + (obc1_address << 2) + 3] = data;
+ snes_ram[obc1_state.offset + (obc1_state.address << 2) + 3] = data;
break;
case 0x1ff4:
- temp = snes_ram[obc1_offset + (obc1_address >> 2) + 0x200];
- temp = (temp & ~(3 << obc1_shift)) | ((data & 0x03) << obc1_shift);
- snes_ram[obc1_offset + (obc1_address >> 2) + 0x200] = temp;
+ temp = snes_ram[obc1_state.offset + (obc1_state.address >> 2) + 0x200];
+ temp = (temp & ~(3 << obc1_state.shift)) | ((data & 0x03) << obc1_state.shift);
+ snes_ram[obc1_state.offset + (obc1_state.address >> 2) + 0x200] = temp;
break;
case 0x1ff5:
- obc1_offset = (data & 0x01) ? 0x1800 : 0x1c00;
+ obc1_state.offset = (data & 0x01) ? 0x1800 : 0x1c00;
snes_ram[address & 0x1fff] = data;
break;
case 0x1ff6:
- obc1_address = data & 0x7f;
- obc1_shift = (data & 0x03) << 1;
+ obc1_state.address = data & 0x7f;
+ obc1_state.shift = (data & 0x03) << 1;
snes_ram[address & 0x1fff] = data;
break;
@@ -100,9 +104,13 @@ static WRITE8_HANDLER( obc1_write )
}
}
-static void obc1_init( void )
+static void obc1_init( running_machine *machine )
{
- obc1_offset = (snes_ram[0x1ff5] & 0x01) ? 0x1800 : 0x1c00;
- obc1_address = (snes_ram[0x1ff6] & 0x7f);
- obc1_shift = (snes_ram[0x1ff6] & 0x03) << 1;
+ obc1_state.offset = (snes_ram[0x1ff5] & 0x01) ? 0x1800 : 0x1c00;
+ obc1_state.address = (snes_ram[0x1ff6] & 0x7f);
+ obc1_state.shift = (snes_ram[0x1ff6] & 0x03) << 1;
+
+ state_save_register_global(machine, obc1_state.offset);
+ state_save_register_global(machine, obc1_state.address);
+ state_save_register_global(machine, obc1_state.shift);
}
diff --git a/src/mame/machine/snesrtc.c b/src/mame/machine/snesrtc.c
index 26a4b6ced93..c69d4d56fd6 100644
--- a/src/mame/machine/snesrtc.c
+++ b/src/mame/machine/snesrtc.c
@@ -1,6 +1,6 @@
/***************************************************************************
- snessdd1.c
+ snesrtc.c
File to handle emulation of the SNES "S-RTC" add-on chip.
@@ -22,14 +22,14 @@ enum
RTCM_Write
};
-typedef struct
+struct _snes_rtc_state
{
- UINT8 rtc_ram[13];
- INT32 rtc_mode;
- INT8 rtc_index;
-} _snes_rtc_t;
+ UINT8 ram[13];
+ INT32 mode;
+ INT8 index;
+};
-static _snes_rtc_t snes_rtc;
+static _snes_rtc_state rtc_state;
static const UINT8 srtc_months[12] =
{
@@ -39,29 +39,29 @@ static const UINT8 srtc_months[12] =
31, 30, 31
};
-static void srtc_update_time(running_machine *machine)
+static void srtc_update_time( running_machine *machine )
{
mame_system_time curtime, *systime = &curtime;
mame_get_current_datetime(machine, &curtime);
- snes_rtc.rtc_ram[0] = systime->local_time.second % 10;
- snes_rtc.rtc_ram[1] = systime->local_time.second / 10;
- snes_rtc.rtc_ram[2] = systime->local_time.minute % 10;
- snes_rtc.rtc_ram[3] = systime->local_time.minute / 10;
- snes_rtc.rtc_ram[4] = systime->local_time.hour % 10;
- snes_rtc.rtc_ram[5] = systime->local_time.hour / 10;
- snes_rtc.rtc_ram[6] = systime->local_time.mday % 10;
- snes_rtc.rtc_ram[7] = systime->local_time.mday / 10;
- snes_rtc.rtc_ram[8] = systime->local_time.month;
- snes_rtc.rtc_ram[9] = (systime->local_time.year - 1900) % 10;
- snes_rtc.rtc_ram[10] = ((systime->local_time.year - 1900) / 10) % 10;
- snes_rtc.rtc_ram[11] = (systime->local_time.year - 1900) / 100;
- snes_rtc.rtc_ram[12] = systime->local_time.weekday % 7;
+ rtc_state.ram[0] = systime->local_time.second % 10;
+ rtc_state.ram[1] = systime->local_time.second / 10;
+ rtc_state.ram[2] = systime->local_time.minute % 10;
+ rtc_state.ram[3] = systime->local_time.minute / 10;
+ rtc_state.ram[4] = systime->local_time.hour % 10;
+ rtc_state.ram[5] = systime->local_time.hour / 10;
+ rtc_state.ram[6] = systime->local_time.mday % 10;
+ rtc_state.ram[7] = systime->local_time.mday / 10;
+ rtc_state.ram[8] = systime->local_time.month;
+ rtc_state.ram[9] = (systime->local_time.year - 1900) % 10;
+ rtc_state.ram[10] = ((systime->local_time.year - 1900) / 10) % 10;
+ rtc_state.ram[11] = (systime->local_time.year - 1900) / 100;
+ rtc_state.ram[12] = systime->local_time.weekday % 7;
}
// Returns day-of-week for specified date
// e.g. 0 = Sunday, 1 = Monday, ... 6 = Saturday
// Usage: weekday(2008, 1, 1) returns the weekday of January 1st, 2008
-static UINT8 srtc_weekday(UINT32 year, UINT32 month, UINT32 day)
+static UINT8 srtc_weekday( UINT32 year, UINT32 month, UINT32 day )
{
UINT32 y = 1900, m = 1; // Epoch is 1900-01-01
UINT32 sum = 0; // Number of days passed since epoch
@@ -70,13 +70,13 @@ static UINT8 srtc_weekday(UINT32 year, UINT32 month, UINT32 day)
month = MAX(1, MIN(12, month));
day = MAX(1, MIN(31, day));
- while(y < year)
+ while (y < year)
{
UINT8 leapyear = 0;
- if((y % 4) == 0)
+ if ((y % 4) == 0)
{
leapyear = 1;
- if((y % 100) == 0 && (y % 400) != 0)
+ if ((y % 100) == 0 && (y % 400) != 0)
{
leapyear = 0;
}
@@ -85,16 +85,16 @@ static UINT8 srtc_weekday(UINT32 year, UINT32 month, UINT32 day)
y++;
}
- while(m < month)
+ while (m < month)
{
UINT32 days = srtc_months[m - 1];
- if(days == 28)
+ if (days == 28)
{
UINT8 leapyear = 0;
- if((y % 4) == 0)
+ if ((y % 4) == 0)
{
leapyear = 1;
- if((y % 100) == 0 && (y % 400) != 0)
+ if ((y % 100) == 0 && (y % 400) != 0)
{
leapyear = 0;
}
@@ -109,111 +109,114 @@ static UINT8 srtc_weekday(UINT32 year, UINT32 month, UINT32 day)
return (sum + 1) % 7; // 1900-01-01 was a Monday
}
-static UINT8 srtc_mmio_read(running_machine *machine, UINT16 addr)
+static UINT8 srtc_read( running_machine *machine, UINT16 addr )
{
addr &= 0xffff;
- if(addr == 0x2800)
+ if (addr == 0x2800)
{
- if(snes_rtc.rtc_mode != RTCM_Read)
+ if (rtc_state.mode != RTCM_Read)
{
return 0x00;
}
- if(snes_rtc.rtc_index < 0)
+ if (rtc_state.index < 0)
{
srtc_update_time(machine);
- snes_rtc.rtc_index++;
+ rtc_state.index++;
return 0x0f;
}
- else if(snes_rtc.rtc_index > 12)
+ else if (rtc_state.index > 12)
{
- snes_rtc.rtc_index = -1;
+ rtc_state.index = -1;
return 0x0f;
}
else
{
- return snes_rtc.rtc_ram[snes_rtc.rtc_index++];
+ return rtc_state.ram[rtc_state.index++];
}
}
return 0xff;
}
-static void srtc_mmio_write(running_machine *machine, UINT16 addr, UINT8 data)
+static void srtc_write( running_machine *machine, UINT16 addr, UINT8 data )
{
addr &= 0xffff;
- if(addr == 0x2801)
+ if (addr == 0x2801)
{
data &= 0x0f; // Only the low four bits are used
- if(data == 0x0d)
+ if (data == 0x0d)
{
- snes_rtc.rtc_mode = RTCM_Read;
- snes_rtc.rtc_index = -1;
+ rtc_state.mode = RTCM_Read;
+ rtc_state.index = -1;
return;
}
- if(data == 0x0e)
+ if (data == 0x0e)
{
- snes_rtc.rtc_mode = RTCM_Command;
+ rtc_state.mode = RTCM_Command;
return;
}
- if(data == 0x0f)
+ if (data == 0x0f)
{
return; // Unknown behaviour
}
- if(snes_rtc.rtc_mode == RTCM_Write)
+ if (rtc_state.mode == RTCM_Write)
{
- if(snes_rtc.rtc_index >= 0 && snes_rtc.rtc_index < 12)
+ if (rtc_state.index >= 0 && rtc_state.index < 12)
{
- snes_rtc.rtc_ram[snes_rtc.rtc_index++] = data;
+ rtc_state.ram[rtc_state.index++] = data;
- if(snes_rtc.rtc_index == 12)
+ if (rtc_state.index == 12)
{
// Day of week is automatically calculated and written
- UINT32 day = snes_rtc.rtc_ram[6] + snes_rtc.rtc_ram[7] * 10;
- UINT32 month = snes_rtc.rtc_ram[8];
- UINT32 year = snes_rtc.rtc_ram[9] + snes_rtc.rtc_ram[10] * 10 + snes_rtc.rtc_ram[11] * 100;
+ UINT32 day = rtc_state.ram[6] + rtc_state.ram[7] * 10;
+ UINT32 month = rtc_state.ram[8];
+ UINT32 year = rtc_state.ram[9] + rtc_state.ram[10] * 10 + rtc_state.ram[11] * 100;
year += 1000;
- snes_rtc.rtc_ram[snes_rtc.rtc_index++] = srtc_weekday(year, month, day);
+ rtc_state.ram[rtc_state.index++] = srtc_weekday(year, month, day);
}
}
}
- else if(snes_rtc.rtc_mode == RTCM_Command)
+ else if (rtc_state.mode == RTCM_Command)
{
- if(data == 0)
+ if (data == 0)
{
- snes_rtc.rtc_mode = RTCM_Write;
- snes_rtc.rtc_index = 0;
+ rtc_state.mode = RTCM_Write;
+ rtc_state.index = 0;
}
- else if(data == 4)
+ else if (data == 4)
{
UINT8 i;
- snes_rtc.rtc_mode = RTCM_Ready;
- snes_rtc.rtc_index = -1;
+ rtc_state.mode = RTCM_Ready;
+ rtc_state.index = -1;
for(i = 0; i < 13; i++)
{
- snes_rtc.rtc_ram[i] = 0;
+ rtc_state.ram[i] = 0;
}
}
else
{
// Unknown behaviour
- snes_rtc.rtc_mode = RTCM_Ready;
+ rtc_state.mode = RTCM_Ready;
}
}
}
}
-static void srtc_reset(running_machine *machine)
+static void srtc_init( running_machine *machine )
{
- snes_rtc.rtc_mode = RTCM_Read;
- snes_rtc.rtc_index = -1;
+ rtc_state.mode = RTCM_Read;
+ rtc_state.index = -1;
srtc_update_time(machine);
-}
+ state_save_register_global_array(machine, rtc_state.ram);
+ state_save_register_global(machine, rtc_state.mode);
+ state_save_register_global(machine, rtc_state.index);
+}
diff --git a/src/mame/machine/snesst10.c b/src/mame/machine/snesst10.c
index 4485f8d35db..17a54b9e297 100644
--- a/src/mame/machine/snesst10.c
+++ b/src/mame/machine/snesst10.c
@@ -15,13 +15,13 @@
***************************************************************************/
-typedef struct
+struct _snes_st010_state
{
INT16 x1, y1, quadrant, theta, o1;
UINT8 *ram;
-} _snes_st010_t;
+};
-static _snes_st010_t snes_st010;
+static _snes_st010_state st010_state;
static const INT16 st010_sin_table[256] = {
0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2,
@@ -163,13 +163,12 @@ static INT16 st010_cos( INT16 theta )
static UINT8 st010_readb( UINT16 address )
{
- return snes_st010.ram[address & 0xfff];
+ return st010_state.ram[address & 0xfff];
}
static UINT16 st010_readw( UINT16 address )
{
- return (st010_readb(address + 0) << 0) |
- (st010_readb(address + 1) << 8);
+ return (st010_readb(address + 0) << 0) | (st010_readb(address + 1) << 8);
}
static UINT32 st010_readd( UINT16 address )
@@ -182,7 +181,7 @@ static UINT32 st010_readd( UINT16 address )
static void st010_writeb( UINT16 address, UINT8 data )
{
- snes_st010.ram[address & 0xfff] = data;
+ st010_state.ram[address & 0xfff] = data;
}
static void st010_writew( UINT16 address, UINT16 data )
@@ -201,292 +200,341 @@ static void st010_writed( UINT16 address, UINT32 data )
//
-static void st010_op_01_do_work(INT16 x0, INT16 y0) {
- if((x0 < 0) && (y0 < 0)) {
- snes_st010.x1 = -x0;
- snes_st010.y1 = -y0;
- snes_st010.quadrant = -0x8000;
- } else if(x0 < 0) {
- snes_st010.x1 = y0;
- snes_st010.y1 = -x0;
- snes_st010.quadrant = -0x4000;
- } else if(y0 < 0) {
- snes_st010.x1 = -y0;
- snes_st010.y1 = x0;
- snes_st010.quadrant = 0x4000;
- } else {
- snes_st010.x1 = x0;
- snes_st010.y1 = y0;
- snes_st010.quadrant = 0x0000;
- }
-
- while((snes_st010.x1 > 0x1f) || (snes_st010.y1 > 0x1f)) {
- if(snes_st010.x1 > 1) { snes_st010.x1 >>= 1; }
- if(snes_st010.y1 > 1) { snes_st010.y1 >>= 1; }
- }
-
- if(snes_st010.y1 == 0) { snes_st010.quadrant += 0x4000; }
-
- snes_st010.theta = (st010_arctan[snes_st010.y1][snes_st010.x1] << 8) ^ snes_st010.quadrant;
+static void st010_op_01_do_work( INT16 x0, INT16 y0 )
+{
+ if ((x0 < 0) && (y0 < 0))
+ {
+ st010_state.x1 = -x0;
+ st010_state.y1 = -y0;
+ st010_state.quadrant = -0x8000;
+ }
+ else if (x0 < 0)
+ {
+ st010_state.x1 = y0;
+ st010_state.y1 = -x0;
+ st010_state.quadrant = -0x4000;
+ }
+ else if (y0 < 0)
+ {
+ st010_state.x1 = -y0;
+ st010_state.y1 = x0;
+ st010_state.quadrant = 0x4000;
+ }
+ else
+ {
+ st010_state.x1 = x0;
+ st010_state.y1 = y0;
+ st010_state.quadrant = 0x0000;
+ }
+
+ while((st010_state.x1 > 0x1f) || (st010_state.y1 > 0x1f))
+ {
+ if (st010_state.x1 > 1)
+ st010_state.x1 >>= 1;
+ if (st010_state.y1 > 1)
+ st010_state.y1 >>= 1;
+ }
+
+ if (st010_state.y1 == 0)
+ st010_state.quadrant += 0x4000;
+
+ st010_state.theta = (st010_arctan[st010_state.y1][st010_state.x1] << 8) ^ st010_state.quadrant;
}
//
-static void st010_op_01( void ) {
- INT16 x0 = st010_readw(0x0000);
- INT16 y0 = st010_readw(0x0002);
+static void st010_op_01( void )
+{
+ INT16 x0 = st010_readw(0x0000);
+ INT16 y0 = st010_readw(0x0002);
- st010_op_01_do_work(x0, y0);
+ st010_op_01_do_work(x0, y0);
- st010_writew(0x0000, snes_st010.x1);
- st010_writew(0x0002, snes_st010.y1);
- st010_writew(0x0004, snes_st010.quadrant);
-//st010_writew(0x0006, y0); //Overload's docs note this write occurs, SNES9x disagrees
- st010_writew(0x0010, snes_st010.theta);
+ st010_writew(0x0000, st010_state.x1);
+ st010_writew(0x0002, st010_state.y1);
+ st010_writew(0x0004, st010_state.quadrant);
+ //st010_writew(0x0006, y0); //Overload's docs note this write occurs, SNES9x disagrees
+ st010_writew(0x0010, st010_state.theta);
}
-static void st010_op_02( void ) {
- INT16 positions = st010_readw(0x0024);
- UINT16 *places = (UINT16*)(snes_st010.ram + 0x0040);
- UINT16 *drivers = (UINT16*)(snes_st010.ram + 0x0080);
-
- UINT8 sorted;
- UINT16 temp;
- int i;
- if(positions > 1) {
- do {
- sorted = 1;
- for(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 = 0;
- }
- }
- positions--;
- } while(!sorted);
- }
+static void st010_op_02( void )
+{
+ INT16 positions = st010_readw(0x0024);
+ UINT16 *places = (UINT16*)(st010_state.ram + 0x0040);
+ UINT16 *drivers = (UINT16*)(st010_state.ram + 0x0080);
+
+ UINT8 sorted;
+ UINT16 temp;
+ int i;
+
+ if (positions > 1)
+ {
+ do
+ {
+ sorted = 1;
+ for (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 = 0;
+ }
+ }
+ positions--;
+ } while(!sorted);
+ }
}
-static void st010_op_03( void ) {
- INT16 x0 = st010_readw(0x0000);
- INT16 y0 = st010_readw(0x0002);
- INT16 multiplier = st010_readw(0x0004);
- INT32 x1, y1;
+static void st010_op_03( void )
+{
+ INT16 x0 = st010_readw(0x0000);
+ INT16 y0 = st010_readw(0x0002);
+ INT16 multiplier = st010_readw(0x0004);
+ INT32 x1, y1;
- x1 = x0 * multiplier << 1;
- y1 = y0 * multiplier << 1;
+ x1 = x0 * multiplier << 1;
+ y1 = y0 * multiplier << 1;
- st010_writed(0x0010, x1);
- st010_writed(0x0014, y1);
+ st010_writed(0x0010, x1);
+ st010_writed(0x0014, y1);
}
-static void st010_op_04( void ) {
- INT16 x = st010_readw(0x0000);
- INT16 y = st010_readw(0x0002);
- INT16 square;
- //calculate the vector length of (x,y)
- square = sqrt((double)(y * y + x * x));
+static void st010_op_04( void )
+{
+ INT16 x = st010_readw(0x0000);
+ INT16 y = st010_readw(0x0002);
+ INT16 square;
+ //calculate the vector length of (x,y)
+ square = sqrt((double)(y * y + x * x));
- st010_writew(0x0010, square);
+ st010_writew(0x0010, square);
}
// same as op_01_do_work, but we are only interested in the angle!
-static void st010_op_05_do_work(INT16 x0, INT16 y0) {
- INT16 x1, y1, quadrant;
- 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; }
-
- snes_st010.o1 = (st010_arctan[y1][x1] << 8) ^ quadrant;
+static void st010_op_05_do_work( INT16 x0, INT16 y0 )
+{
+ INT16 x1, y1, quadrant;
+ 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;
+
+ st010_state.o1 = (st010_arctan[y1][x1] << 8) ^ quadrant;
}
-static void st010_op_05( void ) {
- INT32 dx, dy;
- UINT16 o1 = 0;
- UINT8 wrap = 0;
-
- //target (x,y) coordinates
- INT16 ypos_max = st010_readw(0x00c0);
- INT16 xpos_max = st010_readw(0x00c2);
-
- //current coordinates and direction
- INT32 ypos = st010_readd(0x00c4);
- INT32 xpos = st010_readd(0x00c8);
- UINT16 rot = st010_readw(0x00cc);
-
- //physics
- UINT16 speed = st010_readw(0x00d4);
- UINT16 accel = st010_readw(0x00d6);
- UINT16 speed_max = st010_readw(0x00d8);
- UINT16 old_speed;
-
- //special condition acknowledgement
- INT16 system = st010_readw(0x00da);
- INT16 flags = st010_readw(0x00dc);
-
- //new target coordinates
- INT16 ypos_new = st010_readw(0x00de);
- INT16 xpos_new = st010_readw(0x00e0);
-
- //mask upper bit
- xpos_new &= 0x7fff;
-
- //get the current distance
- dx = xpos_max - (xpos >> 16);
- dy = ypos_max - (ypos >> 16);
-
- //quirk: clear and move in9
- st010_writew(0x00d2, 0xffff);
- st010_writew(0x00da, 0x0000);
-
- //grab the target angle
- st010_op_05_do_work(dy, dx);
- o1 = (UINT16)snes_st010.o1;
-
- //check for wrapping
- if(abs(o1 - rot) > 0x8000) {
- o1 += 0x8000;
- rot += 0x8000;
- wrap = 1;
- }
-
- old_speed = speed;
-
- //special case
- if(abs(o1 - rot) == 0x8000) {
- speed = 0x100;
- }
-
- //slow down for sharp curves
- else if(abs(o1 - rot) >= 0x1000) {
- UINT32 slow = abs(o1 - rot);
- slow >>= 4; //scaling
- speed -= slow;
- }
-
- //otherwise accelerate
- else {
- speed += accel;
- if(speed > speed_max) {
- speed = speed_max; //clip speed
- }
- }
-
- //prevent negative/positive overflow
- if(abs(old_speed - speed) > 0x8000) {
- if(old_speed < speed) { speed = 0; }
- else speed = 0xff00;
- }
-
- //adjust direction by so many degrees
- //be careful of negative adjustments
- if((o1 > rot && (o1 - rot) > 0x80) || (o1 < rot && (rot - o1) >= 0x80)) {
- if(o1 < rot) { rot -= 0x280; }
- else if(o1 > rot) { rot += 0x280; }
- }
-
- //turn off wrapping
- if(wrap) { rot -= 0x8000; }
-
- //now check the distances (store for later)
- dx = (xpos_max << 16) - xpos;
- dy = (ypos_max << 16) - ypos;
- dx >>= 16;
- dy >>= 16;
-
- //if we're in so many units of the target, signal it
- if((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128))) {
- //announce our new destination and flag it
- xpos_max = xpos_new & 0x7fff;
- ypos_max = ypos_new;
- flags |= 0x08;
- }
-
- //update position
- xpos -= (st010_cos(rot) * 0x400 >> 15) * (speed >> 8) << 1;
- ypos -= (st010_sin(rot) * 0x400 >> 15) * (speed >> 8) << 1;
-
- //quirk: mask upper byte
- xpos &= 0x1fffffff;
- ypos &= 0x1fffffff;
-
- st010_writew(0x00c0, ypos_max);
- st010_writew(0x00c2, xpos_max);
- st010_writed(0x00c4, ypos);
- st010_writed(0x00c8, xpos);
- st010_writew(0x00cc, rot);
- st010_writew(0x00d4, speed);
- st010_writew(0x00dc, flags);
+static void st010_op_05( void )
+{
+ INT32 dx, dy;
+ UINT16 o1 = 0;
+ UINT8 wrap = 0;
+
+ //target (x,y) coordinates
+ INT16 ypos_max = st010_readw(0x00c0);
+ INT16 xpos_max = st010_readw(0x00c2);
+
+ //current coordinates and direction
+ INT32 ypos = st010_readd(0x00c4);
+ INT32 xpos = st010_readd(0x00c8);
+ UINT16 rot = st010_readw(0x00cc);
+
+ //physics
+ UINT16 speed = st010_readw(0x00d4);
+ UINT16 accel = st010_readw(0x00d6);
+ UINT16 speed_max = st010_readw(0x00d8);
+ UINT16 old_speed;
+
+ //special condition acknowledgement
+ INT16 system = st010_readw(0x00da);
+ INT16 flags = st010_readw(0x00dc);
+
+ //new target coordinates
+ INT16 ypos_new = st010_readw(0x00de);
+ INT16 xpos_new = st010_readw(0x00e0);
+
+ //mask upper bit
+ xpos_new &= 0x7fff;
+
+ //get the current distance
+ dx = xpos_max - (xpos >> 16);
+ dy = ypos_max - (ypos >> 16);
+
+ //quirk: clear and move in9
+ st010_writew(0x00d2, 0xffff);
+ st010_writew(0x00da, 0x0000);
+
+ //grab the target angle
+ st010_op_05_do_work(dy, dx);
+ o1 = (UINT16)st010_state.o1;
+
+ //check for wrapping
+ if (abs(o1 - rot) > 0x8000)
+ {
+ o1 += 0x8000;
+ rot += 0x8000;
+ wrap = 1;
+ }
+
+ old_speed = speed;
+
+ //special case
+ if (abs(o1 - rot) == 0x8000)
+ {
+ speed = 0x100;
+ }
+ //slow down for sharp curves
+ else if (abs(o1 - rot) >= 0x1000)
+ {
+ UINT32 slow = abs(o1 - rot);
+ slow >>= 4; //scaling
+ speed -= slow;
+ }
+ //otherwise accelerate
+ else
+ {
+ speed += accel;
+ if (speed > speed_max)
+ speed = speed_max; //clip speed
+ }
+
+ //prevent negative/positive overflow
+ if (abs(old_speed - speed) > 0x8000)
+ {
+ if (old_speed < speed)
+ speed = 0;
+ else
+ speed = 0xff00;
+ }
+
+ //adjust direction by so many degrees
+ //be careful of negative adjustments
+ if ((o1 > rot && (o1 - rot) > 0x80) || (o1 < rot && (rot - o1) >= 0x80))
+ {
+ if (o1 < rot)
+ rot -= 0x280;
+ else if (o1 > rot)
+ rot += 0x280;
+ }
+
+ //turn off wrapping
+ if (wrap)
+ rot -= 0x8000;
+
+ //now check the distances (store for later)
+ dx = (xpos_max << 16) - xpos;
+ dy = (ypos_max << 16) - ypos;
+ dx >>= 16;
+ dy >>= 16;
+
+ //if we're in so many units of the target, signal it
+ if ((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128)))
+ {
+ //announce our new destination and flag it
+ xpos_max = xpos_new & 0x7fff;
+ ypos_max = ypos_new;
+ flags |= 0x08;
+ }
+
+ //update position
+ xpos -= (st010_cos(rot) * 0x400 >> 15) * (speed >> 8) << 1;
+ ypos -= (st010_sin(rot) * 0x400 >> 15) * (speed >> 8) << 1;
+
+ //quirk: mask upper byte
+ xpos &= 0x1fffffff;
+ ypos &= 0x1fffffff;
+
+ st010_writew(0x00c0, ypos_max);
+ st010_writew(0x00c2, xpos_max);
+ st010_writed(0x00c4, ypos);
+ st010_writed(0x00c8, xpos);
+ st010_writew(0x00cc, rot);
+ st010_writew(0x00d4, speed);
+ st010_writew(0x00dc, flags);
}
-static void st010_op_06( void ) {
- INT16 multiplicand = st010_readw(0x0000);
- INT16 multiplier = st010_readw(0x0002);
- INT32 product;
+static void st010_op_06( void )
+{
+ INT16 multiplicand = st010_readw(0x0000);
+ INT16 multiplier = st010_readw(0x0002);
+ INT32 product;
- product = multiplicand * multiplier << 1;
+ product = multiplicand * multiplier << 1;
- st010_writed(0x0010, product);
+ st010_writed(0x0010, product);
}
-static void st010_op_07( void ) {
- INT16 theta = st010_readw(0x0000);
+static void st010_op_07( void )
+{
+ INT16 theta = st010_readw(0x0000);
+
+ INT16 data;
+ int i, offset;
+ for (i = 0, offset = 0; i < 176; i++)
+ {
+ data = st010_mode7_scale[i] * st010_cos(theta) >> 15;
+ st010_writew(0x00f0 + offset, data);
+ st010_writew(0x0510 + offset, data);
- INT16 data;
- int i, offset;
- for(i = 0, offset = 0; i < 176; i++) {
- data = st010_mode7_scale[i] * st010_cos(theta) >> 15;
- st010_writew(0x00f0 + offset, data);
- st010_writew(0x0510 + offset, data);
+ data = st010_mode7_scale[i] * st010_sin(theta) >> 15;
+ st010_writew(0x0250 + offset, data);
+ if (data)
+ data = ~data;
- data = st010_mode7_scale[i] * st010_sin(theta) >> 15;
- st010_writew(0x0250 + offset, data);
- if(data) { data = ~data; }
- st010_writew(0x03b0 + offset, data);
+ st010_writew(0x03b0 + offset, data);
- offset += 2;
- }
+ offset += 2;
+ }
}
-static void st010_op_08( void ) {
- INT16 x0 = st010_readw(0x0000);
- INT16 y0 = st010_readw(0x0002);
- INT16 theta = st010_readw(0x0004);
- INT16 x1, y1;
+static void st010_op_08( void )
+{
+ INT16 x0 = st010_readw(0x0000);
+ INT16 y0 = st010_readw(0x0002);
+ INT16 theta = st010_readw(0x0004);
+ INT16 x1, y1;
- x1 = (y0 * st010_sin(theta) >> 15) + (x0 * st010_cos(theta) >> 15);
- y1 = (y0 * st010_cos(theta) >> 15) - (x0 * st010_sin(theta) >> 15);
+ x1 = (y0 * st010_sin(theta) >> 15) + (x0 * st010_cos(theta) >> 15);
+ y1 = (y0 * st010_cos(theta) >> 15) - (x0 * st010_sin(theta) >> 15);
- st010_writew(0x0010, x1);
- st010_writew(0x0012, y1);
+ st010_writew(0x0010, x1);
+ st010_writew(0x0012, y1);
}
// init, reset & handlers
@@ -502,7 +550,7 @@ static void st010_write( UINT16 address, UINT8 data )
if ((address & 0xfff) == 0x0021 && (data & 0x80))
{
- switch (snes_st010.ram[0x0020])
+ switch (st010_state.ram[0x0020])
{
case 0x01: st010_op_01(); break;
case 0x02: st010_op_02(); break;
@@ -514,21 +562,28 @@ static void st010_write( UINT16 address, UINT8 data )
case 0x08: st010_op_08(); break;
}
- snes_st010.ram[0x0021] &= ~0x80;
+ st010_state.ram[0x0021] &= ~0x80;
}
}
static void st010_init( running_machine* machine )
{
- snes_st010.ram = (UINT8*)auto_alloc_array(machine, UINT8, 0x1000);
+ st010_state.ram = (UINT8*)auto_alloc_array_clear(machine, UINT8, 0x1000);
+
+ state_save_register_global(machine, st010_state.x1);
+ state_save_register_global(machine, st010_state.y1);
+ state_save_register_global(machine, st010_state.quadrant);
+ state_save_register_global(machine, st010_state.theta);
+ state_save_register_global(machine, st010_state.o1);
+
+ state_save_register_global_pointer(machine, st010_state.ram, 0x1000);
}
static void st010_reset( void )
{
- snes_st010.x1 = 0;
- snes_st010.y1 = 0;
- snes_st010.quadrant = 0;
- snes_st010.theta = 0;
- memset(snes_st010.ram, 0, 0x1000);
+ st010_state.x1 = 0;
+ st010_state.y1 = 0;
+ st010_state.quadrant = 0;
+ st010_state.theta = 0;
}