summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2017-10-04 04:00:59 +0200
committer angelosa <salese_corp_ltd@email.it>2017-10-05 05:10:25 +0200
commite09bcca8ae23e13bb765b8d59b4c8c76a2f9240d (patch)
tree65c8c6ae4a5513587e897c858d43b68026a811d0
parenta5c860a5cf9e74380303c0ffd50f2a40b1a92998 (diff)
saturn.cpp: SMPC device-ification part 1 (nw)
-rw-r--r--src/devices/machine/smpc.cpp442
-rw-r--r--src/devices/machine/smpc.h109
-rw-r--r--src/mame/drivers/saturn.cpp112
-rw-r--r--src/mame/drivers/stv.cpp112
-rw-r--r--src/mame/includes/saturn.h46
-rw-r--r--src/mame/includes/stv.h15
6 files changed, 603 insertions, 233 deletions
diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp
index e0ca640ea0c..80e93f0f8c3 100644
--- a/src/devices/machine/smpc.cpp
+++ b/src/devices/machine/smpc.cpp
@@ -161,26 +161,224 @@ TODO:
#define LOG_SMPC 0
#define LOG_PAD_CMD 0
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+DEFINE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device, "smpc_hle", "Sega Saturn SMPC HLE (HD404920FS)")
+
+// TODO: this is actually a DEVICE_ADDRESS_MAP, fix once everything is merged
+static ADDRESS_MAP_START( smpc_regs, 0, 8, smpc_hle_device )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x61, 0x61) AM_READ(status_register_r)
+ AM_RANGE(0x63, 0x63) AM_READWRITE(status_flag_r, status_flag_w)
+ AM_RANGE(0x75, 0x75) AM_READWRITE(pdr1_r, pdr1_w)
+ AM_RANGE(0x77, 0x77) AM_READWRITE(pdr2_r, pdr2_w)
+ AM_RANGE(0x79, 0x79) AM_WRITE(ddr1_w)
+ AM_RANGE(0x7b, 0x7b) AM_WRITE(ddr2_w)
+ AM_RANGE(0x7d, 0x7d) AM_WRITE(iosel_w)
+ AM_RANGE(0x7f, 0x7f) AM_WRITE(exle_w)
+ADDRESS_MAP_END
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// smpc_hle_device - constructor
+//-------------------------------------------------
+
+smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SMPC_HLE, tag, owner, clock),
+ device_memory_interface(mconfig, *this),
+ m_space_config("regs", ENDIANNESS_LITTLE, 8, 7, 0, nullptr, *ADDRESS_MAP_NAME(smpc_regs)),
+ m_pdr1_read(*this),
+ m_pdr2_read(*this),
+ m_pdr1_write(*this),
+ m_pdr2_write(*this)
+{
+}
-/********************************************
- *
- * Bankswitch code for ST-V Multi Cart mode
- *
- *******************************************/
-void saturn_state::stv_select_game(int gameno)
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void smpc_hle_device::device_start()
{
- if (m_prev_bankswitch != gameno)
- {
- if (m_cart_reg[gameno] && m_cart_reg[gameno]->base())
- memcpy(memregion("abus")->base(), m_cart_reg[gameno]->base(), 0x3000000);
- else
- memset(memregion("abus")->base(), 0x00, 0x3000000); // TODO: 1-filled?
+ m_pdr1_read.resolve_safe(0xff);
+ m_pdr2_read.resolve_safe(0xff);
+ m_pdr1_write.resolve_safe();
+ m_pdr2_write.resolve_safe();
+
+ save_item(NAME(m_sf));
+ save_item(NAME(m_sr));
+ save_item(NAME(m_ddr1));
+ save_item(NAME(m_ddr2));
+ save_item(NAME(m_pdr1_readback));
+ save_item(NAME(m_pdr2_readback));
+ save_item(NAME(m_iosel1));
+ save_item(NAME(m_iosel2));
+ save_item(NAME(m_exle1));
+ save_item(NAME(m_exle2));
+}
- m_prev_bankswitch = gameno;
- }
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void smpc_hle_device::device_reset()
+{
+ m_sr = 0x40; // this bit is always on according to docs (?)
+ m_sf = false;
+ m_cd_sf = false;
+ m_ddr1 = 0;
+ m_ddr2 = 0;
+ m_pdr1_readback = 0;
+ m_pdr2_readback = 0;
+}
+
+//-------------------------------------------------
+// memory_space_config - return a description of
+// any address spaces owned by this device
+//-------------------------------------------------
+
+device_memory_interface::space_config_vector smpc_hle_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+READ8_MEMBER( smpc_hle_device::status_register_r )
+{
+ return m_sr;
+}
+
+READ8_MEMBER( smpc_hle_device::status_flag_r )
+{
+ // bit 3: CD enable related?
+ return (m_sf<<0) | (m_cd_sf<<3);
+}
+
+WRITE8_MEMBER( smpc_hle_device::status_flag_w )
+{
+ m_sf = BIT(data,0);
+ m_cd_sf = false;
+}
+
+READ8_MEMBER( smpc_hle_device::pdr1_r )
+{
+ uint8_t res = (m_pdr1_read() & ~m_ddr1) | m_pdr1_readback;
+
+ return res;
+}
+
+READ8_MEMBER( smpc_hle_device::pdr2_r )
+{
+ uint8_t res = (m_pdr2_read() & ~m_ddr2) | m_pdr2_readback;
+
+ return res;
+}
+
+WRITE8_MEMBER( smpc_hle_device::pdr1_w )
+{
+// pins defined as output returns in input
+ m_pdr1_readback = (data & m_ddr1);
+ m_pdr1_readback &= 0x7f;
+ m_pdr1_write(m_pdr1_readback);
+// bit 7 can be read back apparently
+ m_pdr1_readback |= data & 0x80;
+}
+
+WRITE8_MEMBER( smpc_hle_device::pdr2_w )
+{
+// pins defined as output returns in input
+ m_pdr2_readback = (data & m_ddr2);
+ m_pdr2_readback &= 0x7f;
+ m_pdr2_write(m_pdr2_readback);
+// bit 7 can be read back apparently
+ m_pdr2_readback |= data & 0x80;
+}
+
+WRITE8_MEMBER( smpc_hle_device::ddr1_w )
+{
+ m_ddr1 = data & 0x7f;
+}
+
+WRITE8_MEMBER( smpc_hle_device::ddr2_w )
+{
+ m_ddr2 = data & 0x7f;
+}
+
+WRITE8_MEMBER( smpc_hle_device::iosel_w )
+{
+ m_iosel1 = BIT(data,0);
+ m_iosel2 = BIT(data,1);
+}
+
+WRITE8_MEMBER( smpc_hle_device::exle_w )
+{
+ m_exle1 = BIT(data,0);
+ m_exle2 = BIT(data,1);
+}
+
+inline void smpc_hle_device::sr_ack()
+{
+ m_sr &= 0x0f;
}
+inline void smpc_hle_device::sr_set(uint8_t data)
+{
+ m_sr = data;
+}
+
+inline void smpc_hle_device::sf_ack(bool cd_enable)
+{
+ m_sf = false;
+ m_cd_sf = cd_enable;
+}
+
+inline void smpc_hle_device::sf_set()
+{
+ m_sf = true;
+}
+
+// Saturn Direct Mode polling check for delegate
+bool smpc_hle_device::get_iosel(bool which)
+{
+ return which == true ? m_iosel2 : m_iosel1;
+}
+
+uint8_t smpc_hle_device::get_ddr(bool which)
+{
+ return which == true ? m_ddr2 : m_ddr1;
+}
+
+
+// TODO: trampolines that needs to go away
+READ8_MEMBER( smpc_hle_device::read )
+{
+ return this->space().read_byte(offset);
+}
+
+WRITE8_MEMBER( smpc_hle_device::write )
+{
+ this->space().write_byte(offset,data);
+}
+
+
+
+
/********************************************
*
* Command functions
@@ -196,7 +394,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_slave_enable )
{
m_slave->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
m_smpc.OREG[31] = param + 0x02; //read-back for last command issued
- m_smpc.SF = 0x00; //clear hand-shake flag
+ m_smpc_hle->sf_ack(false);
m_smpc.slave_on = param;
// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
}
@@ -206,13 +404,13 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_sound_enable )
m_audiocpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
m_en_68k = param ^ 1;
m_smpc.OREG[31] = param + 0x06; //read-back for last command issued
- m_smpc.SF = 0x00; //clear hand-shake flag
+ m_smpc_hle->sf_ack(false);
}
TIMER_CALLBACK_MEMBER( saturn_state::smpc_cd_enable )
{
m_smpc.OREG[31] = param + 0x08; //read-back for last command issued
- m_smpc.SF = 0x08; //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high)
+ m_smpc_hle->sf_ack(true); //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high)
}
void saturn_state::smpc_system_reset()
@@ -256,21 +454,20 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock )
/* put issued command in OREG31 */
m_smpc.OREG[31] = 0x0e + param;
/* clear hand-shake flag */
- m_smpc.SF = 0x00;
-
+ m_smpc_hle->sf_ack(false);
/* TODO: VDP1 / VDP2 / SCU / SCSP default power ON values? */
}
TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
{
if (m_smpc.intback_stage == 2)
- {
- m_smpc.SR = (0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
+ {
+ m_smpc_hle->sr_set(0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
m_smpc.intback_stage = 0;
}
else
{
- m_smpc.SR = (0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
+ m_smpc_hle->sr_set(0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
m_smpc.intback_stage ++;
}
@@ -280,7 +477,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
m_scu.ist |= (IRQ_SMPC);
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
- m_smpc.SF = 0x00; /* clear hand-shake flag */
+ m_smpc_hle->sf_ack(false);
}
@@ -318,7 +515,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback )
m_smpc.OREG[16+i]=0xff; // undefined
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
- m_smpc.SR = 0x40 | m_smpc.intback_stage << 5;
+ m_smpc_hle->sr_set(0x40 | (m_smpc.intback_stage << 5));
m_smpc.pmode = m_smpc.intback_buf[0]>>4;
// /*This is for RTC,cartridge code and similar stuff...*/
@@ -331,12 +528,12 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback )
/* put issued command in OREG31 */
m_smpc.OREG[31] = 0x10; // TODO: doc says 0?
/* clear hand-shake flag */
- m_smpc.SF = 0x00;
+ m_smpc_hle->sf_ack(false);
}
else if(m_smpc.intback_buf[1] & 8)
{
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
- m_smpc.SR = 0x40;
+ m_smpc_hle->sr_set(0x40);
m_smpc.OREG[31] = 0x10;
machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0);
}
@@ -344,7 +541,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback )
{
/* Shienryu calls this, it would be plainly illegal on Saturn, I'll just return the command and clear the hs flag for now. */
m_smpc.OREG[31] = 0x10;
- m_smpc.SF = 0x00;
+ m_smpc_hle->sf_ack(false);
}
}
@@ -416,12 +613,12 @@ TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral )
if (m_smpc.intback_stage == 2)
{
- m_smpc.SR = (0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
+ m_smpc_hle->sr_set(0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback
m_smpc.intback_stage = 0;
}
else
{
- m_smpc.SR = (0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
+ m_smpc_hle->sr_set(0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
m_smpc.intback_stage ++;
}
@@ -431,7 +628,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral )
m_scu.ist |= (IRQ_SMPC);
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
- m_smpc.SF = 0x00; /* clear hand-shake flag */
+ m_smpc_hle->sf_ack(false);
}
TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback )
@@ -468,7 +665,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback )
}
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
- m_smpc.SR = 0x40 | m_smpc.intback_stage << 5;
+ m_smpc_hle->sr_set(0x40 | (m_smpc.intback_stage << 5));
m_smpc.pmode = m_smpc.intback_buf[0]>>4;
if(!(m_scu.ism & IRQ_SMPC))
@@ -479,12 +676,12 @@ TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback )
/* put issued command in OREG31 */
m_smpc.OREG[31] = 0x10;
/* clear hand-shake flag */
- m_smpc.SF = 0x00;
+ m_smpc_hle->sf_ack(false);
}
else if(m_smpc.intback_buf[1] & 8)
{
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
- m_smpc.SR = 0x40;
+ m_smpc_hle->sr_set(0x40);
m_smpc.OREG[31] = 0x10;
machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0);
}
@@ -525,7 +722,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_nmi_set )
/* put issued command in OREG31 */
m_smpc.OREG[31] = 0x19 + param;
/* clear hand-shake flag */
- m_smpc.SF = 0x00;
+ m_smpc_hle->sf_ack(false);
//m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6);
}
@@ -663,7 +860,7 @@ void saturn_state::smpc_comreg_exec(address_space &space, uint8_t data, uint8_t
READ8_MEMBER( saturn_state::stv_SMPC_r )
{
int return_data = 0;
-
+
if(!(offset & 1))
return 0;
@@ -671,22 +868,22 @@ READ8_MEMBER( saturn_state::stv_SMPC_r )
return_data = m_smpc.OREG[(offset-0x21) >> 1];
if (offset == 0x61) // TODO: SR
- return_data = m_smpc.SR;
+ return_data = m_smpc_hle->read(space,offset);
if (offset == 0x63)
- return_data = m_smpc.SF;
+ return_data = m_smpc_hle->read(space,offset);
if (offset == 0x75)//PDR1 read
- return_data = ioport("DSW1")->read();
+ return_data = m_smpc_hle->read(space,offset); //ioport("DSW1")->read();
if (offset == 0x77)//PDR2 read
- return_data = (0xfe | m_eeprom->do_read());
+ return_data = m_smpc_hle->read(space,offset); //(0xfe | m_eeprom->do_read());
return return_data;
}
WRITE8_MEMBER( saturn_state::stv_SMPC_w )
-{
+{
if (!(offset & 1)) // avoid writing to even bytes
return;
@@ -702,7 +899,7 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w )
if(data & 0x40)
{
if(LOG_PAD_CMD) printf("SMPC: BREAK request\n");
- m_smpc.SR &= 0x0f;
+ m_smpc_hle->sr_ack();
m_smpc.intback_stage = 0;
}
else if(data & 0x80)
@@ -710,7 +907,7 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w )
if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n");
machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0); /* TODO: is timing correct? */
m_smpc.OREG[31] = 0x10;
- m_smpc.SF = 0x01; //TODO: set hand-shake flag?
+ m_smpc_hle->sf_set();
}
}
}
@@ -723,65 +920,36 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w )
if(data != 0x10 && data != 0x02 && data != 0x03 && data != 0x08 && data != 0x09 && data != 0xe && data != 0xf && data != 0x19 && data != 0x1a)
{
m_smpc.OREG[31] = data; //read-back command
- m_smpc.SF = 0x00;
+ m_smpc_hle->sf_ack(false);
}
/*TODO:emulate the timing of each command...*/
}
if(offset == 0x63)
- m_smpc.SF = data & 1;
+ m_smpc_hle->write(space,offset,data);
+ // PDR1
if(offset == 0x75)
- {
- /*
- -xx- ---- PDR1
- ---x ---- EEPROM write bit
- ---- x--- EEPROM CLOCK line
- ---- -x-- EEPROM CS line
- ---- --xx A-Bus bank bits
- */
- m_eeprom->clk_write((data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
- m_eeprom->di_write((data >> 4) & 1);
- m_eeprom->cs_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE);
- m_stv_multi_bank = data & 3;
-
- stv_select_game(m_stv_multi_bank);
-
- m_smpc.PDR1 = (data & 0x60);
- }
+ m_smpc_hle->write(space,offset,data);
+ // PDR2
if(offset == 0x77)
- {
- /*
- -xx- ---- PDR2
- ---x ---- Enable Sound System (ACTIVE LOW)
- */
- //popmessage("PDR2 = %02x",m_smpc_ram[0x77]);
-
- if(LOG_SMPC) printf("SMPC: M68k %s\n",(data & 0x10) ? "off" : "on");
- //machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_sound_enable),this),(m_smpc_ram[0x77] & 0x10) >> 4);
- m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
- m_en_68k = ((data & 0x10) >> 4) ^ 1;
-
- //if(LOG_SMPC) printf("SMPC: ram [0x77] = %02x\n",data);
- m_smpc.PDR2 = (data & 0x60);
- }
+ m_smpc_hle->write(space,offset,data);
+
+ if(offset == 0x79)
+ m_smpc_hle->write(space,offset,data);
+ if(offset == 0x7b)
+ m_smpc_hle->write(space,offset,data);
+
if(offset == 0x7d)
{
- /*
- ---- --x- IOSEL2 direct (1) / control mode (0) port select
- ---- ---x IOSEL1 direct (1) / control mode (0) port select
- */
- m_smpc.IOSEL1 = (data & 1) >> 0;
- m_smpc.IOSEL2 = (data & 2) >> 1;
+ m_smpc_hle->write(space,offset,data);
}
if(offset == 0x7f)
{
- //enable PAD irq & VDP2 external latch for port 1/2
- m_smpc.EXLE1 = (data & 1) >> 0;
- m_smpc.EXLE2 = (data & 2) >> 1;
+ m_smpc_hle->write(space,offset,data);
}
}
@@ -791,67 +959,8 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w )
*
*******************************************/
-uint8_t saturn_state::smpc_th_control_mode(uint8_t pad_n)
-{
- uint8_t res = 0;
- int th = (pad_n == 0) ? ((m_smpc.PDR1 >> 5) & 3) : ((m_smpc.PDR2 >> 5) & 3);
- uint16_t ctrl_read = 0;
- if (m_ctrl1 && pad_n == 0)
- ctrl_read = m_ctrl1->read_direct();
- if (m_ctrl2 && pad_n == 1)
- ctrl_read = m_ctrl2->read_direct();
- if (LOG_SMPC) printf("SMPC: SH-2 TH control mode, returning pad data %d for phase %d\n", pad_n + 1, th);
-
- switch (th)
- {
- /* TODO: 3D Lemmings bogusly enables TH Control mode, wants this to return the ID, needs HW tests. */
- case 3:
- res = th << 6;
- res |= 0x14;
- res |= (ctrl_read & 8); // L
- break;
- case 2:
- res = th << 6;
- // 1 C B Right Left Down Up
- // WHP actually has a very specific code at 0x6015f30, doesn't like bits 0-1 active here ...
- res|= ((ctrl_read >> 4) & 0x30); // C & B
- res|= ((ctrl_read >> 12) & 0xc);
- break;
- case 1:
- res = th << 6;
- res |= 0x10;
- res |= ((ctrl_read >> 4) & 0xf); // R, X, Y, Z
- break;
- case 0:
- res = th << 6;
- // 0 Start A 0 0 Down Up
- res |= ((ctrl_read >> 6) & 0x30); // Start & A
- res |= ((ctrl_read >> 12) & 0x03);
- // ... and it actually wants bits 2 - 3 active here.
- res |= 0xc;
- break;
- }
-
- return res;
-}
-
-uint8_t saturn_state::smpc_direct_mode(uint8_t pad_n)
-{
- int hshake = (pad_n == 0) ? ((m_smpc.PDR1 >> 5) & 3) : ((m_smpc.PDR2 >> 5) & 3);
- const int shift_bit[4] = { 4, 12, 8, 0 };
-
- uint16_t ctrl_read = 0;
- if (m_ctrl1 && pad_n == 0)
- ctrl_read = m_ctrl1->read_direct();
- if (m_ctrl2 && pad_n == 1)
- ctrl_read = m_ctrl2->read_direct();
-
- if (LOG_SMPC) logerror("SMPC: SH-2 direct mode, returning data for phase %d\n", hshake);
-
- return 0x80 | 0x10 | ((ctrl_read >> shift_bit[hshake]) & 0xf);
-}
READ8_MEMBER( saturn_state::saturn_SMPC_r )
{
@@ -864,16 +973,18 @@ READ8_MEMBER( saturn_state::saturn_SMPC_r )
return_data = m_smpc.OREG[(offset-0x21) >> 1];
if (offset == 0x61)
- return_data = m_smpc.SR;
+ return_data = m_smpc_hle->read(space,offset);
if (offset == 0x63)
{
//printf("SF %d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
- return_data = m_smpc.SF;
+ return_data = m_smpc_hle->read(space,offset);
}
if (offset == 0x75 || offset == 0x77)//PDR1/2 read
{
+ return_data = m_smpc_hle->read(space,offset);
+ #if 0
if ((m_smpc.IOSEL1 && offset == 0x75) || (m_smpc.IOSEL2 && offset == 0x77))
{
uint8_t cur_ddr;
@@ -897,6 +1008,7 @@ READ8_MEMBER( saturn_state::saturn_SMPC_r )
break;
}
}
+ #endif
}
if (LOG_SMPC) logerror ("cpu %s (PC=%08X) SMPC: Read from Byte Offset %02x (%d) Returns %02x\n", space.device().tag(), space.device().safe_pc(), offset, offset>>1, return_data);
@@ -921,7 +1033,7 @@ WRITE8_MEMBER( saturn_state::saturn_SMPC_w )
if(data & 0x40)
{
if(LOG_PAD_CMD) printf("SMPC: BREAK request %02x\n",data);
- m_smpc.SR &= 0x0f;
+ m_smpc_hle->sr_ack();
m_smpc.intback_stage = 0;
}
else if(data & 0x80)
@@ -929,7 +1041,7 @@ WRITE8_MEMBER( saturn_state::saturn_SMPC_w )
if(LOG_PAD_CMD) printf("SMPC: CONTINUE request %02x\n",data);
machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0); /* TODO: is timing correct? */
m_smpc.OREG[31] = 0x10;
- m_smpc.SF = 0x01; //TODO: set hand-shake flag?
+ m_smpc_hle->sf_set(); //TODO: set hand-shake flag?
}
}
}
@@ -942,36 +1054,48 @@ WRITE8_MEMBER( saturn_state::saturn_SMPC_w )
if(data != 0x10 && data != 2 && data != 3 && data != 6 && data != 7 && data != 0x08 && data != 0x09 && data != 0x0e && data != 0x0f && data != 0x19 && data != 0x1a)
{
m_smpc.OREG[31] = data; //read-back for last command issued
- m_smpc.SF = 0x00; //clear hand-shake flag
+ m_smpc_hle->sf_ack(false); //clear hand-shake flag
}
- /*TODO:emulate the timing of each command...*/
+ // TODO: emulate the timing of each command...
}
if (offset == 0x63)
- m_smpc.SF = data & 1; // hand-shake flag
+ m_smpc_hle->write(space,offset,data);
if(offset == 0x75) // PDR1
- m_smpc.PDR1 = data & 0x7f;
+ m_smpc_hle->write(space,offset,data);
+
+ //m_smpc.PDR1 = data & 0x7f;
if(offset == 0x77) // PDR2
- m_smpc.PDR2 = data & 0x7f;
+ m_smpc_hle->write(space,offset,data);
+
+ //m_smpc.PDR2 = data & 0x7f;
if(offset == 0x79)
- m_smpc.DDR1 = data & 0x7f;
+ m_smpc_hle->write(space,offset,data);
+
+// m_smpc.DDR1 = data & 0x7f;
if(offset == 0x7b)
- m_smpc.DDR2 = data & 0x7f;
+ m_smpc_hle->write(space,offset,data);
+
+// m_smpc.DDR2 = data & 0x7f;
if(offset == 0x7d)
{
- m_smpc.IOSEL1 = data & 1;
- m_smpc.IOSEL2 = (data & 2) >> 1;
+ m_smpc_hle->write(space,offset,data);
+
+// m_smpc.IOSEL1 = data & 1;
+// m_smpc.IOSEL2 = (data & 2) >> 1;
}
if(offset == 0x7f)
{
+ m_smpc_hle->write(space,offset,data);
+
//enable PAD irq & VDP2 external latch for port 1/2
- m_smpc.EXLE1 = (data & 1) >> 0;
- m_smpc.EXLE2 = (data & 2) >> 1;
+// m_smpc.EXLE1 = (data & 1) >> 0;
+// m_smpc.EXLE2 = (data & 2) >> 1;
}
}
diff --git a/src/devices/machine/smpc.h b/src/devices/machine/smpc.h
index 7bb17fe337d..9c8a33e43dc 100644
--- a/src/devices/machine/smpc.h
+++ b/src/devices/machine/smpc.h
@@ -5,3 +5,112 @@
//DECLARE_READ8_MEMBER( stv_SMPC_r );
//DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
//DECLARE_READ8_MEMBER( saturn_SMPC_r );
+
+#ifndef MAME_MACHINE_SMPC_HLE_H
+#define MAME_MACHINE_SMPC_HLE_H
+
+#pragma once
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_SMPC_HLE_ADD(tag) \
+ MCFG_DEVICE_ADD((tag), SMPC_HLE, (0))
+
+#define MCFG_SMPC_HLE_PDR1_IN_CB(_devcb) \
+ devcb = &smpc_hle_device::set_pdr1_in_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SMPC_HLE_PDR2_IN_CB(_devcb) \
+ devcb = &smpc_hle_device::set_pdr2_in_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SMPC_HLE_PDR1_OUT_CB(_devcb) \
+ devcb = &smpc_hle_device::set_pdr1_out_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SMPC_HLE_PDR2_OUT_CB(_devcb) \
+ devcb = &smpc_hle_device::set_pdr2_out_handler(*device, DEVCB_##_devcb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> smpc_hle_device
+
+class smpc_hle_device : public device_t,
+ public device_memory_interface
+{
+public:
+ // construction/destruction
+ smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual space_config_vector memory_space_config() const override;
+
+ // I/O operations
+ DECLARE_WRITE8_MEMBER( write );
+ DECLARE_READ8_MEMBER( read );
+ // TODO: public stuff that should be internal to the device
+ void sr_set(uint8_t data);
+ void sr_ack();
+ void sf_ack(bool cd_enable);
+ void sf_set();
+ bool get_iosel(bool which);
+ uint8_t get_ddr(bool which);
+ DECLARE_READ8_MEMBER( status_register_r );
+ DECLARE_WRITE8_MEMBER( status_flag_w );
+ DECLARE_READ8_MEMBER( status_flag_r );
+ DECLARE_READ8_MEMBER( pdr1_r );
+ DECLARE_READ8_MEMBER( pdr2_r );
+ DECLARE_WRITE8_MEMBER( pdr1_w );
+ DECLARE_WRITE8_MEMBER( pdr2_w );
+ DECLARE_WRITE8_MEMBER( ddr1_w );
+ DECLARE_WRITE8_MEMBER( ddr2_w );
+ DECLARE_WRITE8_MEMBER( iosel_w );
+ DECLARE_WRITE8_MEMBER( exle_w );
+
+ template <class Object> static devcb_base &set_pdr1_in_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_pdr1_read.set_callback(std::forward<Object>(cb)); }
+ template <class Object> static devcb_base &set_pdr2_in_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_pdr2_read.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> static devcb_base &set_pdr1_out_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_pdr1_write.set_callback(std::forward<Object>(cb)); }
+ template <class Object> static devcb_base &set_pdr2_out_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_pdr2_write.set_callback(std::forward<Object>(cb)); }
+
+
+protected:
+ // device-level overrides
+// virtual void device_validity_check(validity_checker &valid) const override;
+// virtual void device_add_mconfig() override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+
+ const address_space_config m_space_config;
+
+ bool m_sf;
+ bool m_cd_sf;
+ uint8_t m_sr;
+ uint8_t m_ddr1, m_ddr2;
+ uint8_t m_pdr1_readback, m_pdr2_readback;
+ bool m_iosel1, m_iosel2;
+ bool m_exle1, m_exle2;
+ devcb_read8 m_pdr1_read;
+ devcb_read8 m_pdr2_read;
+ devcb_write8 m_pdr1_write;
+ devcb_write8 m_pdr2_write;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device)
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+
+#endif // MAME_MACHINE_SMPC_HLE_H
+
diff --git a/src/mame/drivers/saturn.cpp b/src/mame/drivers/saturn.cpp
index 73d1ff54fdb..a14c75284f7 100644
--- a/src/mame/drivers/saturn.cpp
+++ b/src/mame/drivers/saturn.cpp
@@ -719,18 +719,18 @@ MACHINE_START_MEMBER(sat_console_state, saturn)
save_pointer(NAME(m_scsp_regs.get()), 0x1000/2);
save_item(NAME(m_NMI_reset));
save_item(NAME(m_en_68k));
- save_item(NAME(m_smpc.IOSEL1));
- save_item(NAME(m_smpc.IOSEL2));
- save_item(NAME(m_smpc.EXLE1));
- save_item(NAME(m_smpc.EXLE2));
- save_item(NAME(m_smpc.PDR1));
- save_item(NAME(m_smpc.PDR2));
+// save_item(NAME(m_smpc.IOSEL1));
+// save_item(NAME(m_smpc.IOSEL2));
+// save_item(NAME(m_smpc.EXLE1));
+// save_item(NAME(m_smpc.EXLE2));
+// save_item(NAME(m_smpc.PDR1));
+// save_item(NAME(m_smpc.PDR2));
// save_item(NAME(m_port_sel));
// save_item(NAME(mux_data));
save_item(NAME(m_scsp_last_line));
save_item(NAME(m_smpc.intback_stage));
save_item(NAME(m_smpc.pmode));
- save_item(NAME(m_smpc.SR));
+// save_item(NAME(m_smpc.SR));
save_item(NAME(m_smpc.SMEM));
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&sat_console_state::stvcd_exit, this));
@@ -767,7 +767,7 @@ MACHINE_RESET_MEMBER(sat_console_state,saturn)
m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
m_scudsp->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- m_smpc.SR = 0x40; // this bit is always on according to docs
+// m_smpc.SR = 0x40; // this bit is always on according to docs
scu_reset();
@@ -789,6 +789,97 @@ MACHINE_RESET_MEMBER(sat_console_state,saturn)
m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1));
}
+READ8_MEMBER( saturn_state::saturn_pdr1_direct_r )
+{
+ return saturn_direct_port_read(false);
+}
+
+READ8_MEMBER( saturn_state::saturn_pdr2_direct_r )
+{
+ return saturn_direct_port_read(true);
+}
+
+WRITE8_MEMBER( saturn_state::saturn_pdr1_direct_w )
+{
+ m_direct_mux[0] = data;
+}
+
+WRITE8_MEMBER( saturn_state::saturn_pdr2_direct_w )
+{
+ m_direct_mux[1] = data;
+}
+
+inline uint8_t saturn_state::saturn_direct_port_read(bool which)
+{
+ // bail out if direct mode is disabled
+ if(m_smpc_hle->get_iosel(which) == false)
+ return 0xff;
+
+ saturn_control_port_device *port = which == true ? m_ctrl2 : m_ctrl1;
+ uint8_t cur_mode = m_smpc_hle->get_ddr(which);
+ uint8_t res = 0;
+ uint16_t ctrl_read = port->read_direct();
+
+// check for control method
+ switch(cur_mode & 0x60)
+ {
+ case 0: break;
+ case 0x40: res = smpc_th_control_mode(ctrl_read,which); break;
+ case 0x60: res = smpc_direct_mode(ctrl_read,which); break;
+ default:
+ popmessage("SMPC: unemulated control method %02x, contact MAMEdev",cur_mode & 0x60);
+ break;
+ }
+
+ return res;
+}
+
+uint8_t saturn_state::smpc_th_control_mode(uint16_t in_value, bool which)
+{
+ uint8_t res = 0;
+ uint8_t th = (m_direct_mux[which] >> 5) & 3;
+
+ switch (th)
+ {
+ /* TODO: 3D Lemmings bogusly enables TH Control mode, wants this to return the ID, needs HW tests. */
+ case 3:
+ res = th << 6;
+ res |= 0x14;
+ res |= (in_value & 8); // L
+ break;
+ case 2:
+ res = th << 6;
+ // 1 C B Right Left Down Up
+ // WHP actually has a very specific code at 0x6015f30, doesn't like bits 0-1 active here ...
+ res|= ((in_value >> 4) & 0x30); // C & B
+ res|= ((in_value >> 12) & 0xc);
+ break;
+ case 1:
+ res = th << 6;
+ res |= 0x10;
+ res |= ((in_value >> 4) & 0xf); // R, X, Y, Z
+ break;
+ case 0:
+ res = th << 6;
+ // 0 Start A 0 0 Down Up
+ res |= ((in_value >> 6) & 0x30); // Start & A
+ res |= ((in_value >> 12) & 0x03);
+ // ... and it actually wants bits 2 - 3 active here.
+ res |= 0xc;
+ break;
+ }
+
+ return res;
+}
+
+
+uint8_t saturn_state::smpc_direct_mode(uint16_t in_value,bool which)
+{
+ uint8_t hshake = (m_direct_mux[which] >> 5) & 3;
+ const int shift_bit[4] = { 4, 12, 8, 0 };
+
+ return 0x80 | 0x10 | ((in_value >> shift_bit[hshake]) & 0xf);
+}
static MACHINE_CONFIG_START( saturn )
@@ -815,6 +906,11 @@ static MACHINE_CONFIG_START( saturn )
// SH-1
+ MCFG_SMPC_HLE_ADD("smpc")
+ MCFG_SMPC_HLE_PDR1_IN_CB(READ8(saturn_state, saturn_pdr1_direct_r))
+ MCFG_SMPC_HLE_PDR2_IN_CB(READ8(saturn_state, saturn_pdr2_direct_r))
+ MCFG_SMPC_HLE_PDR1_OUT_CB(WRITE8(saturn_state, saturn_pdr1_direct_w))
+ MCFG_SMPC_HLE_PDR2_OUT_CB(WRITE8(saturn_state, saturn_pdr2_direct_w))
// SMPC MCU, running at 4 MHz (+ custom RTC device that runs at 32.768 KHz)
MCFG_MACHINE_START_OVERRIDE(sat_console_state,saturn)
diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp
index a27a6df6ab0..94be6b5e9a4 100644
--- a/src/mame/drivers/stv.cpp
+++ b/src/mame/drivers/stv.cpp
@@ -1021,6 +1021,57 @@ static ADDRESS_MAP_START( scudsp_data, AS_DATA, 32, stv_state )
ADDRESS_MAP_END
+
+/********************************************
+ *
+ * SMPC outputs
+ *
+ *******************************************/
+
+void stv_state::stv_select_game(int gameno)
+{
+ if (m_prev_gamebank_select != gameno)
+ {
+ if (m_cart_reg[gameno] && m_cart_reg[gameno]->base())
+ memcpy(memregion("abus")->base(), m_cart_reg[gameno]->base(), 0x3000000);
+ else
+ memset(memregion("abus")->base(), 0x00, 0x3000000); // TODO: 1-filled?
+
+ m_prev_gamebank_select = gameno;
+ }
+}
+
+READ8_MEMBER( stv_state::pdr1_input_r )
+{
+ return (ioport("PDR1")->read() & 0x40) | 0x3f;
+}
+
+
+READ8_MEMBER( stv_state::pdr2_input_r )
+{
+ return (ioport("PDR2")->read() & ~0x19) | 0x18 | (m_eeprom->do_read()<<0);
+}
+
+
+WRITE8_MEMBER( stv_state::pdr1_output_w )
+{
+ m_eeprom->clk_write((data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
+ m_eeprom->di_write((data >> 4) & 1);
+ m_eeprom->cs_write((data & 0x04) ? ASSERT_LINE : CLEAR_LINE);
+
+ stv_select_game(data & 3);
+}
+
+WRITE8_MEMBER( stv_state::pdr2_output_w )
+{
+ m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE);
+ m_en_68k = ((data & 0x10) >> 4) ^ 1;
+
+ if(data & 8)
+ logerror("PDR2: data 0x8 active!\n");
+}
+
+
static MACHINE_CONFIG_START( stv )
/* basic machine hardware */
@@ -1044,6 +1095,12 @@ static MACHINE_CONFIG_START( stv )
MCFG_SCUDSP_IN_DMA_CB(READ16(saturn_state, scudsp_dma_r))
MCFG_SCUDSP_OUT_DMA_CB(WRITE16(saturn_state, scudsp_dma_w))
+ MCFG_SMPC_HLE_ADD("smpc")
+ MCFG_SMPC_HLE_PDR1_IN_CB(READ8(stv_state, pdr1_input_r))
+ MCFG_SMPC_HLE_PDR2_IN_CB(READ8(stv_state, pdr2_input_r))
+ MCFG_SMPC_HLE_PDR1_OUT_CB(WRITE8(stv_state, pdr1_output_w))
+ MCFG_SMPC_HLE_PDR2_OUT_CB(WRITE8(stv_state, pdr2_output_w))
+
MCFG_MACHINE_START_OVERRIDE(stv_state,stv)
MCFG_MACHINE_RESET_OVERRIDE(stv_state,stv)
@@ -1181,7 +1238,7 @@ MACHINE_RESET_MEMBER(stv_state,stv)
stvcd_reset();
m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1));
- m_prev_bankswitch = 0xff;
+ m_prev_gamebank_select = 0xff;
scu_reset();
@@ -1234,13 +1291,14 @@ MACHINE_START_MEMBER(stv_state,stv)
save_pointer(NAME(m_scsp_regs.get()), 0x1000/2);
save_item(NAME(m_NMI_reset));
save_item(NAME(m_en_68k));
+ save_item(NAME(m_prev_gamebank_select));
// save_item(NAME(scanline));
- save_item(NAME(m_smpc.IOSEL1));
- save_item(NAME(m_smpc.IOSEL2));
- save_item(NAME(m_smpc.EXLE1));
- save_item(NAME(m_smpc.EXLE2));
- save_item(NAME(m_smpc.PDR1));
- save_item(NAME(m_smpc.PDR2));
+// save_item(NAME(m_smpc.IOSEL1));
+// save_item(NAME(m_smpc.IOSEL2));
+// save_item(NAME(m_smpc.EXLE1));
+// save_item(NAME(m_smpc.EXLE2));
+// save_item(NAME(m_smpc.PDR1));
+// save_item(NAME(m_smpc.PDR2));
save_item(NAME(m_port_sel));
save_item(NAME(m_mux_data));
save_item(NAME(m_scsp_last_line));
@@ -1274,57 +1332,27 @@ MACHINE_START_MEMBER(stv_state,stv)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(_n_)
static INPUT_PORTS_START( stv )
- PORT_START("DSW1")
- 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_START("PDR1")
+ PORT_DIPNAME( 0x40, 0x40, "PDR1" ) // P1 Gun Trigger
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("DSW2")
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_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) // test mode mirror
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) // service button mirror
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_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) // P2 Gun Trigger
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("PORTA")
STV_PLAYER_INPUTS(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4)
diff --git a/src/mame/includes/saturn.h b/src/mame/includes/saturn.h
index 86f5ce56109..d469cec2a08 100644
--- a/src/mame/includes/saturn.h
+++ b/src/mame/includes/saturn.h
@@ -7,6 +7,7 @@
#include "cpu/m68000/m68000.h"
#include "cpu/adsp2100/adsp2100.h"
#include "cpu/scudsp/scudsp.h"
+#include "machine/smpc.h"
#include "cpu/sh/sh2.h"
#include "bus/sat_ctrl/ctrl.h"
@@ -38,12 +39,9 @@ public:
m_maincpu(*this, "maincpu"),
m_slave(*this, "slave"),
m_audiocpu(*this, "audiocpu"),
+ m_smpc_hle(*this, "smpc"),
m_scudsp(*this, "scudsp"),
m_eeprom(*this, "eeprom"),
- m_cart1(*this, "stv_slot1"),
- m_cart2(*this, "stv_slot2"),
- m_cart3(*this, "stv_slot3"),
- m_cart4(*this, "stv_slot4"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_ctrl1(*this, "ctrl1"),
@@ -130,16 +128,16 @@ public:
}m_vdp2;
struct {
- uint8_t IOSEL1;
- uint8_t IOSEL2;
- uint8_t EXLE1;
- uint8_t EXLE2;
- uint8_t PDR1;
- uint8_t PDR2;
- uint8_t DDR1;
- uint8_t DDR2;
- uint8_t SF;
- uint8_t SR;
+// uint8_t IOSEL1;
+// uint8_t IOSEL2;
+// uint8_t EXLE1;
+// uint8_t EXLE2;
+// uint8_t PDR1;
+// uint8_t PDR2;
+// uint8_t DDR1;
+// uint8_t DDR2;
+// uint8_t SF;
+// uint8_t SR;
uint8_t IREG[7];
uint8_t intback_buf[7];
uint8_t OREG[32];
@@ -157,8 +155,6 @@ public:
uint32_t *m_cart_dram;
/* ST-V specific */
- uint8_t m_stv_multi_bank;
- uint8_t m_prev_bankswitch;
emu_timer *m_stv_rtc_timer;
uint8_t m_port_sel,m_mux_data;
uint8_t m_system_output;
@@ -169,12 +165,9 @@ public:
required_device<sh2_device> m_maincpu;
required_device<sh2_device> m_slave;
required_device<m68000_base_device> m_audiocpu;
+ required_device<smpc_hle_device> m_smpc_hle;
required_device<scudsp_cpu_device> m_scudsp;
optional_device<eeprom_serial_93cxx_device> m_eeprom;
- optional_device<generic_slot_device> m_cart1;
- optional_device<generic_slot_device> m_cart2;
- optional_device<generic_slot_device> m_cart3;
- optional_device<generic_slot_device> m_cart4;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_device<saturn_control_port_device> m_ctrl1;
@@ -210,8 +203,6 @@ public:
DECLARE_WRITE8_MEMBER(scsp_irq);
int m_scsp_last_line;
- uint8_t smpc_direct_mode(uint8_t pad_n);
- uint8_t smpc_th_control_mode(uint8_t pad_n);
TIMER_CALLBACK_MEMBER( smpc_audio_reset_line_pulse );
DECLARE_READ8_MEMBER( saturn_SMPC_r );
DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
@@ -673,7 +664,6 @@ public:
DECLARE_WRITE16_MEMBER(scudsp_dma_w);
// FROM smpc.c
- void stv_select_game(int gameno);
void smpc_master_on();
TIMER_CALLBACK_MEMBER( smpc_slave_enable );
TIMER_CALLBACK_MEMBER( smpc_sound_enable );
@@ -692,11 +682,19 @@ public:
DECLARE_READ8_MEMBER( stv_SMPC_r );
DECLARE_WRITE8_MEMBER( stv_SMPC_w );
+ DECLARE_READ8_MEMBER(saturn_pdr1_direct_r);
+ DECLARE_READ8_MEMBER(saturn_pdr2_direct_r);
+ DECLARE_WRITE8_MEMBER(saturn_pdr1_direct_w);
+ DECLARE_WRITE8_MEMBER(saturn_pdr2_direct_w);
+ uint8_t m_direct_mux[2];
+ uint8_t saturn_direct_port_read(bool which);
+ uint8_t smpc_direct_mode(uint16_t in_value, bool which);
+ uint8_t smpc_th_control_mode(uint16_t in_value, bool which);
+
void debug_scudma_command(int ref, const std::vector<std::string> &params);
void debug_scuirq_command(int ref, const std::vector<std::string> &params);
void debug_help_command(int ref, const std::vector<std::string> &params);
void debug_commands(int ref, const std::vector<std::string> &params);
-
};
diff --git a/src/mame/includes/stv.h b/src/mame/includes/stv.h
index 7a45f717aee..83747631329 100644
--- a/src/mame/includes/stv.h
+++ b/src/mame/includes/stv.h
@@ -10,6 +10,10 @@ class stv_state : public saturn_state
public:
stv_state(const machine_config &mconfig, device_type type, const char *tag)
: saturn_state(mconfig, type, tag),
+ m_cart1(*this, "stv_slot1"),
+ m_cart2(*this, "stv_slot2"),
+ m_cart3(*this, "stv_slot3"),
+ m_cart4(*this, "stv_slot4"),
m_rax(*this, "rax"),
m_cryptdevice(*this, "315_5881"),
m_5838crypt(*this, "315_5838"),
@@ -88,6 +92,10 @@ public:
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( stv_cart2 ) { return load_cart(image, m_cart2); }
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( stv_cart3 ) { return load_cart(image, m_cart3); }
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( stv_cart4 ) { return load_cart(image, m_cart4); }
+ optional_device<generic_slot_device> m_cart1;
+ optional_device<generic_slot_device> m_cart2;
+ optional_device<generic_slot_device> m_cart3;
+ optional_device<generic_slot_device> m_cart4;
void install_stvbios_speedups( void );
@@ -116,6 +124,13 @@ public:
uint16_t crypt_read_callback(uint32_t addr);
uint16_t crypt_read_callback_ch1(uint32_t addr);
uint16_t crypt_read_callback_ch2(uint32_t addr);
+
+ DECLARE_READ8_MEMBER(pdr1_input_r);
+ DECLARE_READ8_MEMBER(pdr2_input_r);
+ DECLARE_WRITE8_MEMBER(pdr1_output_w);
+ DECLARE_WRITE8_MEMBER(pdr2_output_w);
+ void stv_select_game(int gameno);
+ uint8_t m_prev_gamebank_select;
};