Ported SPC7110 support from bsnes. [Harmony]

Ported ST010 support from bsnes. [Fabio Priuli]
This commit is contained in:
Ryan Holtz 2009-09-19 21:10:59 +00:00
parent f75ca12698
commit 0b68bd6ab9
5 changed files with 2006 additions and 9 deletions

2
.gitattributes vendored
View File

@ -2890,6 +2890,7 @@ src/mame/machine/slapfght.c svneol=native#text/plain
src/mame/machine/slapstic.c svneol=native#text/plain src/mame/machine/slapstic.c svneol=native#text/plain
src/mame/machine/slikshot.c svneol=native#text/plain src/mame/machine/slikshot.c svneol=native#text/plain
src/mame/machine/snes.c svneol=native#text/plain src/mame/machine/snes.c svneol=native#text/plain
src/mame/machine/snes7110.c svneol=native#text/plain
src/mame/machine/snescx4.c svneol=native#text/plain src/mame/machine/snescx4.c svneol=native#text/plain
src/mame/machine/snescx4.h svneol=native#text/plain src/mame/machine/snescx4.h svneol=native#text/plain
src/mame/machine/snesdsp1.c svneol=native#text/plain src/mame/machine/snesdsp1.c svneol=native#text/plain
@ -2900,6 +2901,7 @@ src/mame/machine/snesdsp4.h svneol=native#text/plain
src/mame/machine/snesobc1.c svneol=native#text/plain src/mame/machine/snesobc1.c svneol=native#text/plain
src/mame/machine/snesrtc.c svneol=native#text/plain src/mame/machine/snesrtc.c svneol=native#text/plain
src/mame/machine/snessdd1.c svneol=native#text/plain src/mame/machine/snessdd1.c svneol=native#text/plain
src/mame/machine/snesst10.c svneol=native#text/plain
src/mame/machine/spisprit.c svneol=native#text/plain src/mame/machine/spisprit.c svneol=native#text/plain
src/mame/machine/starwars.c svneol=native#text/plain src/mame/machine/starwars.c svneol=native#text/plain
src/mame/machine/steppers.c svneol=native#text/plain src/mame/machine/steppers.c svneol=native#text/plain

View File

@ -6,6 +6,7 @@
R. Belmont R. Belmont
Anthony Kruize Anthony Kruize
Harmony
Based on the original code by Lee Hammerton (aka Savoury Snax) Based on the original code by Lee Hammerton (aka Savoury Snax)
Thanks to Anomie for invaluable technical information. Thanks to Anomie for invaluable technical information.
Thanks to byuu for invaluable technical information. Thanks to byuu for invaluable technical information.
@ -38,6 +39,7 @@ static emu_timer *snes_hirq_timer;
static UINT16 hblank_offset; static UINT16 hblank_offset;
UINT16 snes_htmult; /* in 512 wide, we run HTOTAL double and halve it on latching */ UINT16 snes_htmult; /* in 512 wide, we run HTOTAL double and halve it on latching */
UINT8 snes_has_addon_chip; UINT8 snes_has_addon_chip;
UINT32 snes_rom_size;
// full graphic variables // full graphic variables
static UINT16 vram_fgr_high, vram_fgr_increment, vram_fgr_count, vram_fgr_mask, vram_fgr_shift, vram_read_buffer; static UINT16 vram_fgr_high, vram_fgr_increment, vram_fgr_count, vram_fgr_mask, vram_fgr_shift, vram_read_buffer;
@ -64,6 +66,8 @@ static struct
#include "machine/snescx4.c" #include "machine/snescx4.c"
#include "machine/snesrtc.c" #include "machine/snesrtc.c"
#include "machine/snessdd1.c" #include "machine/snessdd1.c"
#include "machine/snes7110.c"
#include "machine/snesst10.c"
/************************************* /*************************************
@ -379,6 +383,14 @@ READ8_HANDLER( snes_r_io )
offset += 0x4300; offset += 0x4300;
} }
} }
else if(snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
{
UINT16 limit = (snes_has_addon_chip == HAS_SPC7110_RTC) ? 0x4842 : 0x483f;
if(offset >= 0x4800 && offset < limit)
{
return spc7110_mmio_read(space->machine, offset);
}
}
/* offset is from 0x000000 */ /* offset is from 0x000000 */
switch( offset ) switch( offset )
@ -750,6 +762,15 @@ WRITE8_HANDLER( snes_w_io )
offset += 0x4300; offset += 0x4300;
} }
} }
else if(snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
{
UINT16 limit = (snes_has_addon_chip == HAS_SPC7110_RTC) ? 0x4842 : 0x483f;
if(offset >= 0x4800 && offset < limit)
{
spc7110_mmio_write(space->machine, (UINT32)offset, data);
return;
}
}
/* offset is from 0x000000 */ /* offset is from 0x000000 */
switch( offset ) switch( offset )
@ -1470,6 +1491,10 @@ READ8_HANDLER( snes_r_bank1 )
value = (address < 0x7000) ? DSP1_getDr() : DSP1_getSr(); value = (address < 0x7000) ? DSP1_getDr() : DSP1_getSr();
else if (snes_has_addon_chip == HAS_CX4) else if (snes_has_addon_chip == HAS_CX4)
value = CX4_read(address - 0x6000); value = CX4_read(address - 0x6000);
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
{
value = snes_ram[0x306000 + (offset & 0x1fff)];
}
else else
{ {
logerror( "snes_r_bank1: Unmapped external chip read: %04x\n", address ); logerror( "snes_r_bank1: Unmapped external chip read: %04x\n", address );
@ -1504,6 +1529,10 @@ READ8_HANDLER( snes_r_bank2 )
value = obc1_read (space, offset); value = obc1_read (space, offset);
else if (snes_has_addon_chip == HAS_DSP2) 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)];
}
else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0)) else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0))
{ {
int mask = ((snes_cart.sram * 1024) - 1); /* Limit SRAM size to what's actually present */ int mask = ((snes_cart.sram * 1024) - 1); /* Limit SRAM size to what's actually present */
@ -1565,6 +1594,10 @@ READ8_HANDLER( snes_r_bank4 )
{ {
value = snes_ram[0x600000 + offset]; value = snes_ram[0x600000 + offset];
} }
else if (snes_has_addon_chip == HAS_ST010 && offset >= 0x80000 && address < 0x1000)
{
value = st010_read(address);
}
else if (snes_cart.mode & 5) /* Mode 20 & 22 */ else if (snes_cart.mode & 5) /* Mode 20 & 22 */
{ {
if (address >= 0x8000) if (address >= 0x8000)
@ -1627,6 +1660,10 @@ READ8_HANDLER( snes_r_bank6 )
logerror( "snes_r_bank6 hit in Super FX mode, please fix me\n" ); logerror( "snes_r_bank6 hit in Super FX mode, please fix me\n" );
else if (snes_cart.mode != SNES_MODE_25) else if (snes_cart.mode != SNES_MODE_25)
value = memory_read_byte(space, offset); value = memory_read_byte(space, offset);
else if (snes_has_addon_chip == HAS_CX4)
{
//printf( "R: CX4 hit from 0x800000\n" );
}
else /* Mode 25 has SRAM not mirrored from lower banks */ else /* Mode 25 has SRAM not mirrored from lower banks */
{ {
if (address < 0x6000) if (address < 0x6000)
@ -1672,6 +1709,10 @@ READ8_HANDLER( snes_r_bank7 )
{ {
logerror( "snes_r_bank7 hit in Super FX mode, please fix me\n" ); logerror( "snes_r_bank7 hit in Super FX mode, please fix me\n" );
} }
else if (snes_has_addon_chip == HAS_ST010 && offset >= 0x280000 && offset < 0x300000 && address < 0x1000)
{
value = st010_read(address);
}
else if (snes_cart.mode & 5) /* Mode 20 & 22 */ else if (snes_cart.mode & 5) /* Mode 20 & 22 */
{ {
if (address < 0x8000) if (address < 0x8000)
@ -1709,6 +1750,10 @@ WRITE8_HANDLER( snes_w_bank1 )
DSP1_setDr(data); DSP1_setDr(data);
else if (snes_has_addon_chip == HAS_CX4) else if (snes_has_addon_chip == HAS_CX4)
CX4_write(space->machine, address - 0x6000, data); CX4_write(space->machine, address - 0x6000, data);
else if (snes_has_addon_chip == HAS_SPC7110 || snes_has_addon_chip == HAS_SPC7110_RTC)
{
snes_ram[0x306000 + (offset & 0x1fff)] = data;
}
else else
logerror( "snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data ); logerror( "snes_w_bank1: Attempt to write to reserved address: %x = %02x\n", offset, data );
} }
@ -1737,6 +1782,10 @@ WRITE8_HANDLER( snes_w_bank2 )
obc1_write(space, offset, data); obc1_write(space, offset, data);
else if (snes_has_addon_chip == HAS_DSP2) 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;
}
else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0)) else if ((snes_cart.mode == SNES_MODE_21) && (snes_cart.sram > 0))
{ {
int mask = ((snes_cart.sram * 1024) - 1); /* Limit SRAM size to what's actually present */ int mask = ((snes_cart.sram * 1024) - 1); /* Limit SRAM size to what's actually present */
@ -1767,9 +1816,12 @@ WRITE8_HANDLER( snes_w_bank4 )
if (snes_has_addon_chip == HAS_SUPERFX && cputag_get_cpu(space->machine, "superfx") != NULL) if (snes_has_addon_chip == HAS_SUPERFX && cputag_get_cpu(space->machine, "superfx") != NULL)
{ {
//printf( "Writing %02x to %08x\n", data, 0x600000 + offset );
snes_ram[0x600000 + offset] = data; snes_ram[0x600000 + offset] = data;
} }
else if (snes_has_addon_chip == HAS_ST010 && offset >= 0x80000 && address < 0x1000)
{
st010_write(address, data);
}
else if (snes_cart.mode & 5) /* Mode 20 & 22 */ else if (snes_cart.mode & 5) /* Mode 20 & 22 */
{ {
if (address >= 0x8000) if (address >= 0x8000)
@ -1830,6 +1882,10 @@ WRITE8_HANDLER( snes_w_bank6 )
{ {
logerror( "snes_w_bank6 hit (RAM) in Super FX mode, please fix me\n" ); logerror( "snes_w_bank6 hit (RAM) in Super FX mode, please fix me\n" );
} }
else if(snes_has_addon_chip == HAS_CX4)
{
//printf( "R: CX4 hit from 0x800000\n" );
}
if (snes_cart.mode != SNES_MODE_25) if (snes_cart.mode != SNES_MODE_25)
{ {
if (offset < 0x300000) if (offset < 0x300000)
@ -1887,6 +1943,10 @@ WRITE8_HANDLER( snes_w_bank7 )
logerror( "snes_w_bank7 hit (RAM) in Super FX mode, please fix me\n" ); logerror( "snes_w_bank7 hit (RAM) in Super FX mode, please fix me\n" );
} }
} }
else if (snes_has_addon_chip == HAS_ST010 && offset >= 0x280000 && offset < 0x300000 && address < 0x1000)
{
st010_write(address, data);
}
else if (snes_cart.mode & 5) /* Mode 20 & 22 */ else if (snes_cart.mode & 5) /* Mode 20 & 22 */
{ {
if (address < 0x8000) if (address < 0x8000)
@ -1993,10 +2053,22 @@ static void snes_init_ram(running_machine *machine)
InitDSP4(); InitDSP4();
break; break;
case HAS_RTC:
srtc_reset(machine);
break;
case HAS_SDD1:
sdd1_reset(machine);
break;
case HAS_OBC1: case HAS_OBC1:
obc1_init(); obc1_init();
break; break;
case HAS_ST010:
st010_reset();
break;
default: default:
break; break;
} }
@ -2059,6 +2131,8 @@ MACHINE_START( snes )
snes_ram[WRDIVH] = 0xff; snes_ram[WRDIVH] = 0xff;
sdd1_init(machine); sdd1_init(machine);
spc7110_init(machine);
st010_init(machine);
} }
MACHINE_RESET( snes ) MACHINE_RESET( snes )
@ -2081,9 +2155,6 @@ MACHINE_RESET( snes )
snes_htmult = 1; snes_htmult = 1;
snes_ppu.interlace = 1; snes_ppu.interlace = 1;
snes_ppu.obj_interlace = 1; snes_ppu.obj_interlace = 1;
srtc_reset(machine);
sdd1_reset(machine);
} }
@ -2095,8 +2166,8 @@ DRIVER_INIT( snes )
UINT8 *rom; UINT8 *rom;
rom = memory_region(machine, "user3"); rom = memory_region(machine, "user3");
snes_ram = auto_alloc_array(machine, UINT8, 0x1000000); snes_ram = auto_alloc_array(machine, UINT8, 0x1400000);
memset(snes_ram, 0, 0x1000000); memset(snes_ram, 0, 0x1400000);
/* all NSS games seem to use MODE 20 */ /* all NSS games seem to use MODE 20 */
snes_cart.mode = SNES_MODE_20; snes_cart.mode = SNES_MODE_20;
@ -2161,8 +2232,8 @@ DRIVER_INIT( snes_hirom )
UINT8 *rom; UINT8 *rom;
rom = memory_region(machine, "user3"); rom = memory_region(machine, "user3");
snes_ram = auto_alloc_array(machine, UINT8, 0x1000000); snes_ram = auto_alloc_array(machine, UINT8, 0x1400000);
memset(snes_ram, 0, 0x1000000); memset(snes_ram, 0, 0x1400000);
snes_cart.mode = SNES_MODE_21; snes_cart.mode = SNES_MODE_21;
snes_cart.sram_max = 0x40000; snes_cart.sram_max = 0x40000;

1393
src/mame/machine/snes7110.c Normal file

File diff suppressed because it is too large Load Diff

529
src/mame/machine/snesst10.c Normal file
View File

@ -0,0 +1,529 @@
/***************************************************************************
snesst10.c
File to handle emulation of the SNES "Seta ST-010" add-on chip.
Code based on original work by The Dumper, Matthew Kendora,
Overload and Feather.
This implementation is based on byuu's BSNES C++ version
***************************************************************************/
typedef struct
{
INT16 x1, y1, quadrant, theta, o1;
UINT8 *ram;
} _snes_st010_t;
static _snes_st010_t snes_st010;
static const INT16 st010_sin_table[256] = {
0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2,
0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a,
0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842,
0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6,
0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504,
0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3,
0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5,
0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d,
0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b,
0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23,
0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3,
0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4,
0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df,
0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b,
0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324,
0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2,
-0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
-0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a,
-0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
-0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6,
-0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504,
-0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3,
-0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5,
-0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d,
-0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b,
-0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23,
-0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3,
-0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3,
-0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de,
-0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b,
-0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324
};
static const INT16 st010_mode7_scale[176] = {
0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3,
0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b,
0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8,
0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6,
0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5,
0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d,
0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c,
0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e,
0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063,
0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a,
0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052,
0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c,
0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047,
0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042,
0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e,
0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a,
0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037,
0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034,
0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031,
0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f,
0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d,
0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b
};
static const UINT8 st010_arctan[32][32] = {
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
{ 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf },
{ 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb,
0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd },
{ 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8,
0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc },
{ 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5,
0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb },
{ 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9 },
{ 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0,
0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8 },
{ 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae,
0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7 },
{ 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac,
0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5 },
{ 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa,
0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4 },
{ 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8,
0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3 },
{ 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6,
0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2 },
{ 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1 },
{ 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3,
0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0 },
{ 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1,
0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf },
{ 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0,
0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae },
{ 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad },
{ 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d,
0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac },
{ 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c,
0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab },
{ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b,
0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa },
{ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a,
0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9 },
{ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99,
0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8 },
{ 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98,
0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7 },
{ 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98,
0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6 },
{ 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5 },
{ 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4 },
{ 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95,
0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4 },
{ 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95,
0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3 },
{ 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2 },
{ 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1 },
{ 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93,
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1 },
{ 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 }
};
static INT16 st010_sin( INT16 theta )
{
return st010_sin_table[(theta >> 8) & 0xff];
}
static INT16 st010_cos( INT16 theta )
{
return st010_sin_table[((theta + 0x4000) >> 8) & 0xff];
}
static UINT8 st010_readb( UINT16 address )
{
return snes_st010.ram[address & 0xfff];
}
static UINT16 st010_readw( UINT16 address )
{
return (st010_readb(address + 0) << 0) |
(st010_readb(address + 1) << 8);
}
static UINT32 st010_readd( UINT16 address )
{
return (st010_readb(address + 0) << 0) |
(st010_readb(address + 1) << 8) |
(st010_readb(address + 2) << 16) |
(st010_readb(address + 3) << 24);
}
static void st010_writeb( UINT16 address, UINT8 data )
{
snes_st010.ram[address & 0xfff] = data;
}
static void st010_writew( UINT16 address, UINT16 data )
{
st010_writeb(address + 0, data >> 0);
st010_writeb(address + 1, data >> 8);
}
static void st010_writed( UINT16 address, UINT32 data )
{
st010_writeb(address + 0, data >> 0);
st010_writeb(address + 1, data >> 8);
st010_writeb(address + 2, data >> 16);
st010_writeb(address + 3, data >> 24);
}
//
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( void ) {
INT16 x0 = st010_readw(0x0000);
INT16 y0 = st010_readw(0x0002);
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);
}
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_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;
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));
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( 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 = (UINT8)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_06( void ) {
INT16 multiplicand = st010_readw(0x0000);
INT16 multiplier = st010_readw(0x0002);
INT32 product;
product = multiplicand * multiplier << 1;
st010_writed(0x0010, product);
}
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);
data = st010_mode7_scale[i] * st010_sin(theta) >> 15;
st010_writew(0x0250 + offset, data);
if(data) { data = ~data; }
st010_writew(0x03b0 + offset, data);
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;
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);
}
// init, reset & handlers
UINT8 st010_read( UINT16 address )
{
return st010_readb(address);
}
void st010_write( UINT16 address, UINT8 data )
{
st010_writeb(address, data);
if ((address & 0xfff) == 0x0021 && (data & 0x80))
{
switch (snes_st010.ram[0x0020])
{
case 0x01: st010_op_01(); break;
case 0x02: st010_op_02(); break;
case 0x03: st010_op_03(); break;
case 0x04: st010_op_04(); break;
case 0x05: st010_op_05(); break;
case 0x06: st010_op_06(); break;
case 0x07: st010_op_07(); break;
case 0x08: st010_op_08(); break;
}
snes_st010.ram[0x0021] &= ~0x80;
}
}
void st010_init( running_machine* machine )
{
snes_st010.ram = (UINT8*)auto_alloc_array(machine, UINT8, 0x1000);
}
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);
}

View File

@ -1862,4 +1862,6 @@ $(MACHINE)/snes.o: $(MAMESRC)/machine/snesdsp1.c \
$(MAMESRC)/machine/cx4fn.c \ $(MAMESRC)/machine/cx4fn.c \
$(MAMESRC)/machine/cx4data.c \ $(MAMESRC)/machine/cx4data.c \
$(MAMESRC)/machine/snesrtc.c \ $(MAMESRC)/machine/snesrtc.c \
$(MAMESRC)/machine/snessdd1.c $(MAMESRC)/machine/snessdd1.c \
$(MAMESRC)/machine/snes7110.c \
$(MAMESRC)/machine/snesst10.c