Celebrate marriage between stv.c and saturn.c, nw

This commit is contained in:
Angelo Salese 2011-04-24 23:35:30 +00:00
parent 78c28738ff
commit ae71618fd5
4 changed files with 776 additions and 7 deletions

2
.gitattributes vendored
View File

@ -2366,6 +2366,7 @@ src/mame/drivers/s9.c svneol=native#text/plain
src/mame/drivers/safarir.c svneol=native#text/plain
src/mame/drivers/sandscrp.c svneol=native#text/plain
src/mame/drivers/sangho.c svneol=native#text/plain
src/mame/drivers/saturn.c svneol=native#text/plain
src/mame/drivers/sauro.c svneol=native#text/plain
src/mame/drivers/savquest.c svneol=native#text/plain
src/mame/drivers/sbasketb.c svneol=native#text/plain
@ -2489,7 +2490,6 @@ src/mame/drivers/stepstag.c svneol=native#text/plain
src/mame/drivers/stfight.c svneol=native#text/plain
src/mame/drivers/stlforce.c svneol=native#text/plain
src/mame/drivers/strnskil.c svneol=native#text/plain
src/mame/drivers/stv.c svneol=native#text/plain
src/mame/drivers/stvinit.c svneol=native#text/plain
src/mame/drivers/sub.c svneol=native#text/plain
src/mame/drivers/subs.c svneol=native#text/plain

View File

@ -1,6 +1,5 @@
/* Sega ST-V (Sega Titan Video)
a.k.a. known as a Sega Saturn for the Arcades.
/*
Sega Saturn & Sega ST-V (Sega Titan Video)
Driver by David Haywood,Angelo Salese,Olivier Galibert & Mariusz Wojcieszek
SCSP driver provided by R.Belmont,based on ElSemi's SCSP sound chip emulator
@ -159,6 +158,9 @@ ToDo / Notes:
#include "sound/scsp.h"
#include "machine/stvprot.h"
#include "includes/stv.h"
#include "imagedev/chd_cd.h"
#include "imagedev/cartslot.h"
#include "coreutil.h"
#define USE_SLAVE 1
@ -195,6 +197,7 @@ static UINT32* stv_backupram;
static UINT32* ioga;
static UINT16* scsp_regs;
static UINT16* sound_ram;
static int saturn_region;
int stv_enable_slave_sh2;
/*VDP2 stuff*/
@ -441,12 +444,16 @@ static UINT8 EXLE1;
static UINT8 EXLE2;
static UINT8 PDR1;
static UINT8 PDR2;
static int intback_stage = 0, smpcSR, pmode;
static UINT8 SMEM[4];
#define SH2_DIRECT_MODE_PORT_1 IOSEL1 = 1
#define SH2_DIRECT_MODE_PORT_2 IOSEL2 = 1
#define SMPC_CONTROL_MODE_PORT_1 IOSEL1 = 0
#define SMPC_CONTROL_MODE_PORT_2 IOSEL2 = 0
static void system_reset()
{
/*Only backup ram and SMPC ram are retained after that this command is issued.*/
@ -718,6 +725,330 @@ static void stv_SMPC_w8 (address_space *space, int offset, UINT8 data)
}
static void smpc_intbackhelper(running_machine &machine)
{
int pad;
static const char *const padnames[] = { "JOY1", "JOY2" };
if (intback_stage == 1)
{
intback_stage++;
return;
}
pad = input_port_read(machine, padnames[intback_stage-2]);
// if (LOG_SMPC) logerror("SMPC: providing PAD data for intback, pad %d\n", intback_stage-2);
smpc_ram[33] = 0xf1; // no tap, direct connect
smpc_ram[35] = 0x02; // saturn pad
smpc_ram[37] = pad>>8;
smpc_ram[39] = pad & 0xff;
if (intback_stage == 3)
{
smpcSR = (0x80 | pmode); // pad 2, no more data, echo back pad mode set by intback
}
else
{
smpcSR = (0xe0 | pmode); // pad 1, more data, echo back pad mode set by intback
}
intback_stage++;
}
static UINT8 saturn_SMPC_r8(address_space *space, int offset)
{
int return_data;
return_data = smpc_ram[offset];
if ((offset == 0x61))
return_data = smpcSR;
if (offset == 0x75)//PDR1 read
{
if (IOSEL1)
{
int hshake;
hshake = (PDR1>>5) & 3;
if (LOG_SMPC) logerror("SMPC: SH-2 direct mode, returning data for phase %d\n", hshake);
return_data = 0x9f;
switch (hshake)
{
case 0:
return_data = 0x90;
// return_data = 0xf0 | ((input_port_read(space->machine(), "JOY1")>>4) & 0xf);
break;
case 1:
// return_data = 0xf0 | ((input_port_read(space->machine(), "JOY1")>>12) & 0xf);
break;
case 2:
// return_data = 0xf0 | ((input_port_read(space->machine(), "JOY1")>>8) & 0xf);
break;
case 3:
return_data = 0x94;
// return_data = 0xf0 | (input_port_read(space->machine(), "JOY1")&0x8) | 0x4;
break;
}
}
}
if (offset == 0x77)//PDR2 read
{
return_data = 0xff; // | EEPROM_read_bit());
}
if (offset == 0x33) return_data = saturn_region;
if (LOG_SMPC) logerror ("cpu %s (PC=%08X) SMPC: Read from Byte Offset %02x (%d) Returns %02x\n", space->device().tag(), cpu_get_pc(&space->device()), offset, offset>>1, return_data);
return return_data;
}
static void saturn_SMPC_w8(address_space *space, int offset, UINT8 data)
{
system_time systime;
UINT8 last;
running_machine &machine = space->machine();
/* get the current date/time from the core */
machine.current_datetime(systime);
if (LOG_SMPC) logerror ("8-bit SMPC Write to Offset %02x (reg %d) with Data %02x (prev %02x)\n", offset, offset>>1, data, smpc_ram[offset]);
// if (offset == 0x7d) printf("IOSEL2 %d IOSEL1 %d\n", (data>>1)&1, data&1);
last = smpc_ram[offset];
if ((intback_stage > 0) && (offset == 1) && (((data ^ 0x80)&0x80) == (last&0x80)))
{
if (LOG_SMPC) logerror("SMPC: CONTINUE request, stage %d\n", intback_stage);
if (intback_stage != 3)
{
intback_stage = 2;
}
smpc_intbackhelper(machine);
cputag_set_input_line_and_vector(machine, "maincpu", 8, HOLD_LINE , 0x47);
}
if ((offset == 1) && (data & 0x40))
{
if (LOG_SMPC) logerror("SMPC: BREAK request\n");
intback_stage = 0;
}
smpc_ram[offset] = data;
if (offset == 0x75) // PDR1
{
PDR1 = (data & smpc_ram[0x79]);
}
if (offset == 0x77) // PDR2
{
PDR2 = (data & smpc_ram[0x7b]);
}
if(offset == 0x7d)
{
if(smpc_ram[0x7d] & 1)
SH2_DIRECT_MODE_PORT_1;
else
SMPC_CONTROL_MODE_PORT_1;
if(smpc_ram[0x7d] & 2)
SH2_DIRECT_MODE_PORT_2;
else
SMPC_CONTROL_MODE_PORT_2;
}
if(offset == 0x7f)
{
//enable PAD irq & VDP2 external latch for port 1/2
EXLE1 = smpc_ram[0x7f] & 1 ? 1 : 0;
EXLE2 = smpc_ram[0x7f] & 2 ? 1 : 0;
if(EXLE1 || EXLE2)
if(!(stv_scu[40] & 0x0100)) /*Pad irq*/
{
if(LOG_SMPC) logerror ("Interrupt: PAD irq, Vector 0x48 Level 0x08\n");
cputag_set_input_line_and_vector(machine, "maincpu", 8, HOLD_LINE , 0x48);
}
}
if (offset == 0x1f)
{
switch (data)
{
case 0x00:
if(LOG_SMPC) logerror ("SMPC: Master ON\n");
smpc_ram[0x5f]=0x00;
break;
//in theory 0x01 is for Master OFF,but obviously is not used.
case 0x02:
if(LOG_SMPC) logerror ("SMPC: Slave ON\n");
smpc_ram[0x5f]=0x02;
stv_enable_slave_sh2 = 1;
cputag_set_input_line(machine, "slave", INPUT_LINE_RESET, CLEAR_LINE);
break;
case 0x03:
if(LOG_SMPC) logerror ("SMPC: Slave OFF\n");
smpc_ram[0x5f]=0x03;
stv_enable_slave_sh2 = 0;
machine.scheduler().trigger(1000);
cputag_set_input_line(machine, "slave", INPUT_LINE_RESET, ASSERT_LINE);
break;
case 0x06:
if(LOG_SMPC) logerror ("SMPC: Sound ON\n");
/* wrong? */
smpc_ram[0x5f]=0x06;
cputag_set_input_line(machine, "audiocpu", INPUT_LINE_RESET, CLEAR_LINE);
en_68k = 1;
break;
case 0x07:
if(LOG_SMPC) logerror ("SMPC: Sound OFF\n");
cputag_set_input_line(machine, "audiocpu", INPUT_LINE_RESET, ASSERT_LINE);
en_68k = 0;
smpc_ram[0x5f]=0x07;
break;
/*CD (SH-1) ON/OFF,guess that this is needed for Sports Fishing games...*/
//case 0x08:
//case 0x09:
case 0x0d:
if(LOG_SMPC) logerror ("SMPC: System Reset\n");
smpc_ram[0x5f]=0x0d;
cputag_set_input_line(machine, "maincpu", INPUT_LINE_RESET, PULSE_LINE);
system_reset();
break;
case 0x0e:
if(LOG_SMPC) logerror ("SMPC: Change Clock to 352\n");
smpc_ram[0x5f]=0x0e;
machine.device("maincpu")->set_unscaled_clock(MASTER_CLOCK_352/2);
machine.device("slave")->set_unscaled_clock(MASTER_CLOCK_352/2);
machine.device("audiocpu")->set_unscaled_clock(MASTER_CLOCK_352/5);
cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE); // ff said this causes nmi, should we set a timer then nmi?
break;
case 0x0f:
if(LOG_SMPC) logerror ("SMPC: Change Clock to 320\n");
smpc_ram[0x5f]=0x0f;
machine.device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2);
machine.device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2);
machine.device("audiocpu")->set_unscaled_clock(MASTER_CLOCK_320/5);
cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE); // ff said this causes nmi, should we set a timer then nmi?
break;
/*"Interrupt Back"*/
case 0x10:
if(LOG_SMPC) logerror ("SMPC: Status Acquire (IntBack)\n");
smpc_ram[0x5f]=0x10;
smpc_ram[0x21] = (0x80) | ((NMI_reset & 1) << 6);
smpc_ram[0x23] = dec_2_bcd(systime.local_time.year / 100);
smpc_ram[0x25] = dec_2_bcd(systime.local_time.year % 100);
smpc_ram[0x27] = (systime.local_time.weekday << 4) | (systime.local_time.month + 1);
smpc_ram[0x29] = dec_2_bcd(systime.local_time.mday);
smpc_ram[0x2b] = dec_2_bcd(systime.local_time.hour);
smpc_ram[0x2d] = dec_2_bcd(systime.local_time.minute);
smpc_ram[0x2f] = dec_2_bcd(systime.local_time.second);
smpc_ram[0x31]=0x00; //?
smpc_ram[0x35]=0x00;
smpc_ram[0x37]=0x00;
smpc_ram[0x39] = SMEM[0];
smpc_ram[0x3b] = SMEM[1];
smpc_ram[0x3d] = SMEM[2];
smpc_ram[0x3f] = SMEM[3];
smpc_ram[0x41]=0xff;
smpc_ram[0x43]=0xff;
smpc_ram[0x45]=0xff;
smpc_ram[0x47]=0xff;
smpc_ram[0x49]=0xff;
smpc_ram[0x4b]=0xff;
smpc_ram[0x4d]=0xff;
smpc_ram[0x4f]=0xff;
smpc_ram[0x51]=0xff;
smpc_ram[0x53]=0xff;
smpc_ram[0x55]=0xff;
smpc_ram[0x57]=0xff;
smpc_ram[0x59]=0xff;
smpc_ram[0x5b]=0xff;
smpc_ram[0x5d]=0xff;
smpcSR = 0x60; // peripheral data ready, no reset, etc.
pmode = smpc_ram[1]>>4;
intback_stage = 1;
// /*This is for RTC,cartridge code and similar stuff...*/
// if(!(stv_scu[40] & 0x0080)) /*System Manager(SMPC) irq*/ /* we can't check this .. breaks controls .. probably issues elsewhere? */
{
// if(LOG_SMPC) logerror ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline);
smpc_intbackhelper(machine);
cputag_set_input_line_and_vector(machine, "maincpu", 8, HOLD_LINE , 0x47);
}
break;
/* RTC write*/
case 0x16:
if(LOG_SMPC) logerror("SMPC: RTC write\n");
smpc_ram[0x2f] = smpc_ram[0x0d];
smpc_ram[0x2d] = smpc_ram[0x0b];
smpc_ram[0x2b] = smpc_ram[0x09];
smpc_ram[0x29] = smpc_ram[0x07];
smpc_ram[0x27] = smpc_ram[0x05];
smpc_ram[0x25] = smpc_ram[0x03];
smpc_ram[0x23] = smpc_ram[0x01];
smpc_ram[0x5f]=0x16;
break;
/* SMPC memory setting*/
case 0x17:
if(LOG_SMPC) logerror ("SMPC: memory setting\n");
SMEM[0] = smpc_ram[1];
SMEM[1] = smpc_ram[3];
SMEM[2] = smpc_ram[5];
SMEM[3] = smpc_ram[7];
smpc_ram[0x5f]=0x17;
break;
case 0x18:
if(LOG_SMPC) logerror ("SMPC: NMI request\n");
smpc_ram[0x5f]=0x18;
/*NMI is unconditionally requested?*/
cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE);
break;
case 0x19:
if(LOG_SMPC) logerror ("SMPC: NMI Enable\n");
smpc_ram[0x5f]=0x19;
NMI_reset = 0;
smpc_ram[0x21] = (0x80) | ((NMI_reset & 1) << 6);
break;
case 0x1a:
if(LOG_SMPC) logerror ("SMPC: NMI Disable\n");
smpc_ram[0x5f]=0x1a;
NMI_reset = 1;
smpc_ram[0x21] = (0x80) | ((NMI_reset & 1) << 6);
break;
default:
if(LOG_SMPC) logerror ("cpu %s (PC=%08X) SMPC: undocumented Command %02x\n", space->device().tag(), cpu_get_pc(&space->device()), data);
}
// we've processed the command, clear status flag
smpc_ram[0x63] = 0x00;
/*TODO:emulate the timing of each command...*/
}
}
static READ32_HANDLER ( stv_SMPC_r32 )
{
int byte = 0;
@ -753,6 +1084,42 @@ static WRITE32_HANDLER ( stv_SMPC_w32 )
stv_SMPC_w8(space, offset,writedata);
}
static READ32_HANDLER ( saturn_SMPC_r32 )
{
int byte = 0;
int readdata = 0;
/* registers are all byte accesses, convert here */
offset = offset << 2; // multiply offset by 4
if (ACCESSING_BITS_24_31) { byte = 0; readdata = saturn_SMPC_r8(space, offset+byte) << 24; }
if (ACCESSING_BITS_16_23) { byte = 1; readdata = saturn_SMPC_r8(space, offset+byte) << 16; }
if (ACCESSING_BITS_8_15) { byte = 2; readdata = saturn_SMPC_r8(space, offset+byte) << 8; }
if (ACCESSING_BITS_0_7) { byte = 3; readdata = saturn_SMPC_r8(space, offset+byte) << 0; }
return readdata;
}
static WRITE32_HANDLER ( saturn_SMPC_w32 )
{
int byte = 0;
int writedata = 0;
/* registers are all byte accesses, convert here so we can use the data more easily later */
offset = offset << 2; // multiply offset by 4
if (ACCESSING_BITS_24_31) { byte = 0; writedata = data >> 24; }
if (ACCESSING_BITS_16_23) { byte = 1; writedata = data >> 16; }
if (ACCESSING_BITS_8_15) { byte = 2; writedata = data >> 8; }
if (ACCESSING_BITS_0_7) { byte = 3; writedata = data >> 0; }
writedata &= 0xff;
offset += byte;
saturn_SMPC_w8(space, offset,writedata);
}
/*
I/O overview:
PORT-A 1st player inputs
@ -1989,6 +2356,80 @@ static READ32_HANDLER( stv_sh2_random_r )
}
#endif
static UINT32 backup[64*1024/4];
static READ32_HANDLER(satram_r)
{
return backup[offset] & 0x00ff00ff; // yes, it makes sure the "holes" are there.
}
static WRITE32_HANDLER(satram_w)
{
COMBINE_DATA(&backup[offset]);
}
static NVRAM_HANDLER(saturn)
{
static const UINT32 init[8] =
{
0x420061, 0x63006b, 0x550070, 0x520061, 0x6d0020, 0x46006f, 0x72006d, 0x610074,
};
int i;
if (read_or_write)
file->write(backup, 64*1024/4);
else
{
if (file)
{
file->read(backup, 64*1024/4);
}
else
{
memset(backup, 0, 64*1024/4);
for (i = 0; i < 8; i++)
{
backup[i] = init[i];
backup[i+8] = init[i];
backup[i+16] = init[i];
backup[i+24] = init[i];
}
}
}
}
static ADDRESS_MAP_START( saturn_mem, AS_PROGRAM, 32 )
AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios
AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE(saturn_SMPC_r32, saturn_SMPC_w32)
AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE(satram_r, satram_w)
AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x100000) AM_SHARE("share2") AM_BASE(&stv_workram_l)
AM_RANGE(0x01000000, 0x01000003) AM_WRITE(minit_w)
AM_RANGE(0x01406f40, 0x01406f43) AM_WRITE(minit_w) // prikura seems to write here ..
AM_RANGE(0x01800000, 0x01800003) AM_WRITE(sinit_w)
AM_RANGE(0x02000000, 0x023fffff) AM_ROM AM_SHARE("share7") AM_REGION("maincpu", 0x80000) // cartridge space
AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w)
/* Sound */
AM_RANGE(0x05a00000, 0x05a7ffff) AM_READWRITE(stv_sh2_soundram_r, stv_sh2_soundram_w)
AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16("scsp", scsp_r, scsp_w, 0xffffffff)
/* VDP1 */
/*0x05c00000-0x05c7ffff VRAM*/
/*0x05c80000-0x05c9ffff Frame Buffer 0*/
/*0x05ca0000-0x05cbffff Frame Buffer 1*/
/*0x05d00000-0x05d7ffff VDP1 Regs */
AM_RANGE(0x05c00000, 0x05c7ffff) AM_READWRITE(stv_vdp1_vram_r, stv_vdp1_vram_w)
AM_RANGE(0x05c80000, 0x05cbffff) AM_READWRITE(stv_vdp1_framebuffer0_r, stv_vdp1_framebuffer0_w)
AM_RANGE(0x05d00000, 0x05d0001f) AM_READWRITE(stv_vdp1_regs_r, stv_vdp1_regs_w)
AM_RANGE(0x05e00000, 0x05efffff) AM_READWRITE(stv_vdp2_vram_r, stv_vdp2_vram_w)
AM_RANGE(0x05f00000, 0x05f7ffff) AM_READWRITE(stv_vdp2_cram_r, stv_vdp2_cram_w)
AM_RANGE(0x05f80000, 0x05fbffff) AM_READWRITE(stv_vdp2_regs_r, stv_vdp2_regs_w)
AM_RANGE(0x05fe0000, 0x05fe00cf) AM_READWRITE(stv_scu_r32, stv_scu_w32)
AM_RANGE(0x06000000, 0x060fffff) AM_RAM AM_MIRROR(0x01f00000) AM_SHARE("share3") AM_BASE(&stv_workram_h)
AM_RANGE(0x20000000, 0x2007ffff) AM_ROM AM_SHARE("share6") // bios mirror
AM_RANGE(0x22000000, 0x24ffffff) AM_ROM AM_SHARE("share7") // cart mirror
ADDRESS_MAP_END
static ADDRESS_MAP_START( stv_mem, AS_PROGRAM, 32 )
AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios
AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE(stv_SMPC_r32, stv_SMPC_w32)
@ -2023,6 +2464,91 @@ static ADDRESS_MAP_START( sound_mem, AS_PROGRAM, 16 )
AM_RANGE(0x100000, 0x100fff) AM_DEVREADWRITE("scsp", scsp_r, scsp_w)
ADDRESS_MAP_END
static INPUT_PORTS_START( saturn )
PORT_START("PDR1")
PORT_DIPNAME( 0x01, 0x01, "PDR1" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("PDR2")
PORT_DIPNAME( 0x01, 0x01, "PDR2" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("JOY1")
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) // START
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) // A
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) // B
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) // C
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) // X
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) // Y
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) // Z
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P1 L") PORT_PLAYER(1) // L
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 R") PORT_PLAYER(1) // R
PORT_START("JOY2")
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) // START
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) // A
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) // B
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) // C
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) // X
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) // Y
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) // Z
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P2 L") PORT_PLAYER(2) // L
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 R") PORT_PLAYER(2) // R
INPUT_PORTS_END
#define STV_PLAYER_INPUTS(_n_, _b1_, _b2_, _b3_) \
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_##_b1_ ) PORT_PLAYER(_n_) \
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_##_b2_ ) PORT_PLAYER(_n_) \
@ -2636,6 +3162,40 @@ static MACHINE_START( stv )
stv_rtc_timer = machine.scheduler().timer_alloc(FUNC(stv_rtc_increment));
}
static MACHINE_START( saturn )
{
scsp_set_ram_base(machine.device("scsp"), sound_ram);
// save states
state_save_register_global_pointer(machine, smpc_ram, 0x80);
state_save_register_global_pointer(machine, stv_scu, 0x100/4);
state_save_register_global_pointer(machine, scsp_regs, 0x1000/2);
state_save_register_global(machine, stv_vblank);
state_save_register_global(machine, stv_hblank);
state_save_register_global(machine, stv_enable_slave_sh2);
state_save_register_global(machine, NMI_reset);
state_save_register_global(machine, en_68k);
state_save_register_global(machine, timer_0);
state_save_register_global(machine, timer_1);
state_save_register_global(machine, IOSEL1);
state_save_register_global(machine, IOSEL2);
state_save_register_global(machine, EXLE1);
state_save_register_global(machine, EXLE2);
state_save_register_global(machine, PDR1);
state_save_register_global(machine, PDR2);
// state_save_register_global(machine, port_sel);
// state_save_register_global(machine, mux_data);
state_save_register_global(machine, scsp_last_line);
state_save_register_global(machine, intback_stage);
state_save_register_global(machine, pmode);
state_save_register_global(machine, smpcSR);
state_save_register_global_array(machine, SMEM);
machine.add_notifier(MACHINE_NOTIFY_EXIT, stvcd_exit);
}
/*
(Preliminary) explaination about this:
VBLANK-OUT is used at the start of the vblank period.It also sets the timer zero
@ -2819,6 +3379,42 @@ static INTERRUPT_GEN( stv_interrupt )
device->machine().scheduler().timer_set(device->machine().primary_screen->time_until_pos(0), FUNC(vdp1_irq));
}
static MACHINE_RESET( saturn )
{
// don't let the slave cpu and the 68k go anywhere
cputag_set_input_line(machine, "slave", INPUT_LINE_RESET, ASSERT_LINE);
stv_enable_slave_sh2 = 0;
cputag_set_input_line(machine, "audiocpu", INPUT_LINE_RESET, ASSERT_LINE);
smpcSR = 0x40; // this bit is always on according to docs
timer_0 = 0;
timer_1 = 0;
en_68k = 0;
NMI_reset = 1;
smpc_ram[0x21] = (0x80) | ((NMI_reset & 1) << 6);
DMA_STATUS = 0;
memset(stv_workram_l, 0, 0x100000);
memset(stv_workram_h, 0, 0x100000);
machine.device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2);
machine.device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2);
machine.device("audiocpu")->set_unscaled_clock(MASTER_CLOCK_320/5);
stvcd_reset( machine );
/* set the first scanline 0 timer to go off */
scan_timer = machine.device<timer_device>("scan_timer");
t1_timer = machine.device<timer_device>("t1_timer");
vblank_out_timer = machine.device<timer_device>("vbout_timer");
vblank_out_timer->adjust(machine.primary_screen->time_until_pos(0));
scan_timer->adjust(machine.primary_screen->time_until_pos(224, 352));
}
static MACHINE_RESET( stv )
{
// don't let the slave cpu and the 68k go anywhere
@ -2852,6 +3448,58 @@ static MACHINE_RESET( stv )
}
static MACHINE_CONFIG_START( saturn, driver_device )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz
MCFG_CPU_PROGRAM_MAP(saturn_mem)
MCFG_CPU_VBLANK_INT("screen",stv_interrupt)
MCFG_CPU_CONFIG(sh2_conf_master)
MCFG_CPU_ADD("slave", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz
MCFG_CPU_PROGRAM_MAP(saturn_mem)
MCFG_CPU_CONFIG(sh2_conf_slave)
MCFG_CPU_ADD("audiocpu", M68000, MASTER_CLOCK_352/5) //11.46 MHz
MCFG_CPU_PROGRAM_MAP(sound_mem)
MCFG_MACHINE_START(saturn)
MCFG_MACHINE_RESET(saturn)
MCFG_NVRAM_HANDLER(saturn)
MCFG_TIMER_ADD("scan_timer", hblank_in_irq)
MCFG_TIMER_ADD("t1_timer", timer1_irq)
MCFG_TIMER_ADD("vbout_timer", vblank_out_irq)
MCFG_TIMER_ADD("sector_timer", stv_sector_cb)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(192)) // guess, needed to force video update after V-Blank OUT interrupt
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB15)
MCFG_SCREEN_SIZE(704*2, 512*2)
MCFG_SCREEN_VISIBLE_AREA(0*8, 703, 0*8, 511) // we need to use a resolution as high as the max size it can change to
MCFG_SCREEN_UPDATE(stv_vdp2)
MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness.
MCFG_GFXDECODE(stv)
MCFG_VIDEO_START(stv_vdp2)
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("scsp", SCSP, 0)
MCFG_SOUND_CONFIG(scsp_config)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
MCFG_CDROM_ADD( "cdrom" )
MCFG_CARTSLOT_ADD("cart")
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( stv, driver_device )
/* basic machine hardware */
@ -2898,6 +3546,112 @@ static MACHINE_CONFIG_START( stv, driver_device )
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
MACHINE_CONFIG_END
static void saturn_init_driver(running_machine &machine, int rgn)
{
system_time systime;
saturn_region = rgn;
// set compatible options
sh2drc_set_options(machine.device("maincpu"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL);
sh2drc_set_options(machine.device("slave"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL);
/* get the current date/time from the core */
machine.current_datetime(systime);
/* amount of time to boost interleave for on MINIT / SINIT, needed for communication to work */
minit_boost = 400;
sinit_boost = 400;
minit_boost_timeslice = attotime::zero;
sinit_boost_timeslice = attotime::zero;
smpc_ram = auto_alloc_array(machine, UINT8, 0x80);
stv_scu = auto_alloc_array(machine, UINT32, 0x100/4);
scsp_regs = auto_alloc_array(machine, UINT16, 0x1000/2);
smpc_ram[0x23] = dec_2_bcd(systime.local_time.year / 100);
smpc_ram[0x25] = dec_2_bcd(systime.local_time.year % 100);
smpc_ram[0x27] = (systime.local_time.weekday << 4) | (systime.local_time.month + 1);
smpc_ram[0x29] = dec_2_bcd(systime.local_time.mday);
smpc_ram[0x2b] = dec_2_bcd(systime.local_time.hour);
smpc_ram[0x2d] = dec_2_bcd(systime.local_time.minute);
smpc_ram[0x2f] = dec_2_bcd(systime.local_time.second);
smpc_ram[0x31] = 0x00; //CTG1=0 CTG0=0 (correct??)
// smpc_ram[0x33] = input_port_read(machine, "???");
smpc_ram[0x5f] = 0x10;
}
static DRIVER_INIT( saturnus )
{
saturn_init_driver(machine, 4);
}
static DRIVER_INIT( saturneu )
{
saturn_init_driver(machine, 12);
}
static DRIVER_INIT( saturnjp )
{
saturn_init_driver(machine, 1);
}
/* Japanese Saturn */
ROM_START(saturnjp)
ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */
ROM_SYSTEM_BIOS(0, "101", "Japan v1.01 (941228)")
ROMX_LOAD("sega_101.bin", 0x00000000, 0x00080000, CRC(224b752c) SHA1(df94c5b4d47eb3cc404d88b33a8fda237eaf4720), ROM_BIOS(1))
ROM_SYSTEM_BIOS(1, "1003", "Japan v1.003 (941012)")
ROMX_LOAD("sega1003.bin", 0x00000000, 0x00080000, CRC(b3c63c25) SHA1(7b23b53d62de0f29a23e423d0fe751dfb469c2fa), ROM_BIOS(2))
ROM_SYSTEM_BIOS(2, "100", "Japan v1.00 (940921)")
ROMX_LOAD("sega_100.bin", 0x00000000, 0x00080000, CRC(2aba43c2) SHA1(2b8cb4f87580683eb4d760e4ed210813d667f0a2), ROM_BIOS(3))
ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL)
ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */
ROM_COPY( "maincpu",0,0,0x080000)
ROM_END
/* Overseas Saturn */
ROM_START(saturn)
ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */
ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)")
ROMX_LOAD("sega_101a.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1))
ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)")
ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2))
ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL)
ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */
ROM_COPY( "maincpu",0,0,0x080000)
ROM_END
ROM_START(saturneu)
ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */
ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)")
ROMX_LOAD("sega_101a.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1))
ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)")
ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2))
ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL)
ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */
ROM_COPY( "maincpu",0,0,0x080000)
ROM_END
ROM_START(vsaturn)
ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */
ROM_LOAD("vsaturn.bin", 0x00000000, 0x00080000, CRC(e4d61811) SHA1(4154e11959f3d5639b11d7902b3a393a99fb5776))
ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL)
ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */
ROM_COPY( "maincpu",0,0,0x080000)
ROM_END
ROM_START(hisaturn)
ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */
ROM_LOAD("hisaturn.bin", 0x00000000, 0x00080000, CRC(721e1b60) SHA1(49d8493008fa715ca0c94d99817a5439d6f2c796))
ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL)
ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */
ROM_COPY( "maincpu",0,0,0x080000)
ROM_END
#define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \
ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(bios+1)) /* Note '+1' */
@ -4034,6 +4788,15 @@ static DRIVER_INIT( sanjeon )
DRIVER_INIT_CALL(sasissu);
}
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
CONS( 1994, saturn, 0, 0, saturn, saturn, saturnus, "Sega", "Saturn (USA)", GAME_NOT_WORKING )
CONS( 1994, saturnjp, saturn, 0, saturn, saturn, saturnjp, "Sega", "Saturn (Japan)", GAME_NOT_WORKING )
CONS( 1994, saturneu, saturn, 0, saturn, saturn, saturneu, "Sega", "Saturn (PAL)", GAME_NOT_WORKING )
CONS( 1995, vsaturn, saturn, 0, saturn, saturn, saturnjp, "JVC", "V-Saturn", GAME_NOT_WORKING )
CONS( 1995, hisaturn, saturn, 0, saturn, saturn, saturnjp, "Hitachi", "HiSaturn", GAME_NOT_WORKING )
GAME( 1996, stvbios, 0, stv, stv, stv, ROT0, "Sega", "ST-V Bios", GAME_IS_BIOS_ROOT )
//GAME YEAR, NAME, PARENT, MACH, INP, INIT, MONITOR

View File

@ -12274,6 +12274,14 @@ strike
//multmega // (c)1994 Sega
//32x_scd // (c)1994 Sega
// Sega Saturn
// (hardware used by ST-V)
//saturn // (c)1994 Sega
//saturnjp // (c)1994 Sega
//saturneu // (c)1994 Sega
//vsaturn // (c)1995 Sega/JVC
//hisaturn // (c)1995 Sega/Hitachi
// Atari Jaguar
// (hardware used by CoJag)
//jaguar // (c)1993 Atari
@ -12293,4 +12301,3 @@ cdimono1 // (c)1991 Philips
// Commodore CD32
// (parent to Cubo32 sets)
cd32 // (c)1993 Commodore

View File

@ -1190,7 +1190,7 @@ $(MAMEOBJ)/sega.a: \
$(DRIVERS)/segaybd.o $(VIDEO)/segaybd.o \
$(DRIVERS)/sg1000a.o \
$(DRIVERS)/stactics.o $(VIDEO)/stactics.o \
$(DRIVERS)/stv.o $(DRIVERS)/stvinit.o $(MACHINE)/stvprot.o $(MACHINE)/stvcd.o \
$(DRIVERS)/saturn.o $(DRIVERS)/stvinit.o $(MACHINE)/stvprot.o $(MACHINE)/stvcd.o $(VIDEO)/stvvdp1.o $(VIDEO)/stvvdp2.o \
$(DRIVERS)/suprloco.o $(VIDEO)/suprloco.o \
$(DRIVERS)/system1.o $(VIDEO)/system1.o \
$(DRIVERS)/system16.o $(VIDEO)/system16.o \
@ -1214,7 +1214,6 @@ $(MAMEOBJ)/sega.a: \
$(VIDEO)/segaic16.o \
$(VIDEO)/sega16sp.o \
$(VIDEO)/segaic24.o \
$(VIDEO)/stvvdp1.o $(VIDEO)/stvvdp2.o \
$(MAMEOBJ)/seibu.a: \
$(DRIVERS)/bloodbro.o $(VIDEO)/bloodbro.o \