mirror of
https://github.com/holub/mame
synced 2025-07-02 00:29:37 +03:00
saturn.cpp: SMPC device-ification part 1 (nw)
This commit is contained in:
parent
a5c860a5cf
commit
e09bcca8ae
@ -161,26 +161,224 @@ TODO:
|
|||||||
#define LOG_SMPC 0
|
#define LOG_SMPC 0
|
||||||
#define LOG_PAD_CMD 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)")
|
||||||
* Bankswitch code for ST-V Multi Cart mode
|
|
||||||
*
|
|
||||||
*******************************************/
|
|
||||||
|
|
||||||
void saturn_state::stv_select_game(int gameno)
|
// 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)
|
||||||
{
|
{
|
||||||
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_prev_bankswitch = gameno;
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void smpc_hle_device::device_start()
|
||||||
|
{
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// 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
|
* 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_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.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;
|
m_smpc.slave_on = param;
|
||||||
// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
// 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_audiocpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
|
||||||
m_en_68k = param ^ 1;
|
m_en_68k = param ^ 1;
|
||||||
m_smpc.OREG[31] = param + 0x06; //read-back for last command issued
|
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 )
|
TIMER_CALLBACK_MEMBER( saturn_state::smpc_cd_enable )
|
||||||
{
|
{
|
||||||
m_smpc.OREG[31] = param + 0x08; //read-back for last command issued
|
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()
|
void saturn_state::smpc_system_reset()
|
||||||
@ -256,8 +454,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock )
|
|||||||
/* put issued command in OREG31 */
|
/* put issued command in OREG31 */
|
||||||
m_smpc.OREG[31] = 0x0e + param;
|
m_smpc.OREG[31] = 0x0e + param;
|
||||||
/* clear hand-shake flag */
|
/* clear hand-shake flag */
|
||||||
m_smpc.SF = 0x00;
|
m_smpc_hle->sf_ack(false);
|
||||||
|
|
||||||
/* TODO: VDP1 / VDP2 / SCU / SCSP default power ON values? */
|
/* TODO: VDP1 / VDP2 / SCU / SCSP default power ON values? */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,12 +462,12 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
|
|||||||
{
|
{
|
||||||
if (m_smpc.intback_stage == 2)
|
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;
|
m_smpc.intback_stage = 0;
|
||||||
}
|
}
|
||||||
else
|
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 ++;
|
m_smpc.intback_stage ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +477,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
|
|||||||
m_scu.ist |= (IRQ_SMPC);
|
m_scu.ist |= (IRQ_SMPC);
|
||||||
|
|
||||||
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
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.OREG[16+i]=0xff; // undefined
|
||||||
|
|
||||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
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;
|
m_smpc.pmode = m_smpc.intback_buf[0]>>4;
|
||||||
|
|
||||||
// /*This is for RTC,cartridge code and similar stuff...*/
|
// /*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 */
|
/* put issued command in OREG31 */
|
||||||
m_smpc.OREG[31] = 0x10; // TODO: doc says 0?
|
m_smpc.OREG[31] = 0x10; // TODO: doc says 0?
|
||||||
/* clear hand-shake flag */
|
/* clear hand-shake flag */
|
||||||
m_smpc.SF = 0x00;
|
m_smpc_hle->sf_ack(false);
|
||||||
}
|
}
|
||||||
else if(m_smpc.intback_buf[1] & 8)
|
else if(m_smpc.intback_buf[1] & 8)
|
||||||
{
|
{
|
||||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
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;
|
m_smpc.OREG[31] = 0x10;
|
||||||
machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0);
|
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. */
|
/* 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.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)
|
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;
|
m_smpc.intback_stage = 0;
|
||||||
}
|
}
|
||||||
else
|
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 ++;
|
m_smpc.intback_stage ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,7 +628,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral )
|
|||||||
m_scu.ist |= (IRQ_SMPC);
|
m_scu.ist |= (IRQ_SMPC);
|
||||||
|
|
||||||
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
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 )
|
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.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;
|
m_smpc.pmode = m_smpc.intback_buf[0]>>4;
|
||||||
|
|
||||||
if(!(m_scu.ism & IRQ_SMPC))
|
if(!(m_scu.ism & IRQ_SMPC))
|
||||||
@ -479,12 +676,12 @@ TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback )
|
|||||||
/* put issued command in OREG31 */
|
/* put issued command in OREG31 */
|
||||||
m_smpc.OREG[31] = 0x10;
|
m_smpc.OREG[31] = 0x10;
|
||||||
/* clear hand-shake flag */
|
/* clear hand-shake flag */
|
||||||
m_smpc.SF = 0x00;
|
m_smpc_hle->sf_ack(false);
|
||||||
}
|
}
|
||||||
else if(m_smpc.intback_buf[1] & 8)
|
else if(m_smpc.intback_buf[1] & 8)
|
||||||
{
|
{
|
||||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
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;
|
m_smpc.OREG[31] = 0x10;
|
||||||
machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0);
|
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 */
|
/* put issued command in OREG31 */
|
||||||
m_smpc.OREG[31] = 0x19 + param;
|
m_smpc.OREG[31] = 0x19 + param;
|
||||||
/* clear hand-shake flag */
|
/* clear hand-shake flag */
|
||||||
m_smpc.SF = 0x00;
|
m_smpc_hle->sf_ack(false);
|
||||||
|
|
||||||
//m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6);
|
//m_smpc.OREG[0] = (0x80) | ((m_NMI_reset & 1) << 6);
|
||||||
}
|
}
|
||||||
@ -671,16 +868,16 @@ READ8_MEMBER( saturn_state::stv_SMPC_r )
|
|||||||
return_data = m_smpc.OREG[(offset-0x21) >> 1];
|
return_data = m_smpc.OREG[(offset-0x21) >> 1];
|
||||||
|
|
||||||
if (offset == 0x61) // TODO: SR
|
if (offset == 0x61) // TODO: SR
|
||||||
return_data = m_smpc.SR;
|
return_data = m_smpc_hle->read(space,offset);
|
||||||
|
|
||||||
if (offset == 0x63)
|
if (offset == 0x63)
|
||||||
return_data = m_smpc.SF;
|
return_data = m_smpc_hle->read(space,offset);
|
||||||
|
|
||||||
if (offset == 0x75)//PDR1 read
|
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
|
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;
|
return return_data;
|
||||||
}
|
}
|
||||||
@ -702,7 +899,7 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w )
|
|||||||
if(data & 0x40)
|
if(data & 0x40)
|
||||||
{
|
{
|
||||||
if(LOG_PAD_CMD) printf("SMPC: BREAK request\n");
|
if(LOG_PAD_CMD) printf("SMPC: BREAK request\n");
|
||||||
m_smpc.SR &= 0x0f;
|
m_smpc_hle->sr_ack();
|
||||||
m_smpc.intback_stage = 0;
|
m_smpc.intback_stage = 0;
|
||||||
}
|
}
|
||||||
else if(data & 0x80)
|
else if(data & 0x80)
|
||||||
@ -710,7 +907,7 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w )
|
|||||||
if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n");
|
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? */
|
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.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)
|
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.OREG[31] = data; //read-back command
|
||||||
m_smpc.SF = 0x00;
|
m_smpc_hle->sf_ack(false);
|
||||||
}
|
}
|
||||||
/*TODO:emulate the timing of each command...*/
|
/*TODO:emulate the timing of each command...*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset == 0x63)
|
if(offset == 0x63)
|
||||||
m_smpc.SF = data & 1;
|
m_smpc_hle->write(space,offset,data);
|
||||||
|
|
||||||
|
// PDR1
|
||||||
if(offset == 0x75)
|
if(offset == 0x75)
|
||||||
{
|
m_smpc_hle->write(space,offset,data);
|
||||||
/*
|
|
||||||
-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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// PDR2
|
||||||
if(offset == 0x77)
|
if(offset == 0x77)
|
||||||
{
|
m_smpc_hle->write(space,offset,data);
|
||||||
/*
|
|
||||||
-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");
|
if(offset == 0x79)
|
||||||
//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_smpc_hle->write(space,offset,data);
|
||||||
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);
|
if(offset == 0x7b)
|
||||||
m_smpc.PDR2 = (data & 0x60);
|
m_smpc_hle->write(space,offset,data);
|
||||||
}
|
|
||||||
|
|
||||||
if(offset == 0x7d)
|
if(offset == 0x7d)
|
||||||
{
|
{
|
||||||
/*
|
m_smpc_hle->write(space,offset,data);
|
||||||
---- --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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset == 0x7f)
|
if(offset == 0x7f)
|
||||||
{
|
{
|
||||||
//enable PAD irq & VDP2 external latch for port 1/2
|
m_smpc_hle->write(space,offset,data);
|
||||||
m_smpc.EXLE1 = (data & 1) >> 0;
|
|
||||||
m_smpc.EXLE2 = (data & 2) >> 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 )
|
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];
|
return_data = m_smpc.OREG[(offset-0x21) >> 1];
|
||||||
|
|
||||||
if (offset == 0x61)
|
if (offset == 0x61)
|
||||||
return_data = m_smpc.SR;
|
return_data = m_smpc_hle->read(space,offset);
|
||||||
|
|
||||||
if (offset == 0x63)
|
if (offset == 0x63)
|
||||||
{
|
{
|
||||||
//printf("SF %d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
//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
|
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))
|
if ((m_smpc.IOSEL1 && offset == 0x75) || (m_smpc.IOSEL2 && offset == 0x77))
|
||||||
{
|
{
|
||||||
uint8_t cur_ddr;
|
uint8_t cur_ddr;
|
||||||
@ -897,6 +1008,7 @@ READ8_MEMBER( saturn_state::saturn_SMPC_r )
|
|||||||
break;
|
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);
|
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(data & 0x40)
|
||||||
{
|
{
|
||||||
if(LOG_PAD_CMD) printf("SMPC: BREAK request %02x\n",data);
|
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;
|
m_smpc.intback_stage = 0;
|
||||||
}
|
}
|
||||||
else if(data & 0x80)
|
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);
|
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? */
|
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.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)
|
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.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)
|
if (offset == 0x63)
|
||||||
m_smpc.SF = data & 1; // hand-shake flag
|
m_smpc_hle->write(space,offset,data);
|
||||||
|
|
||||||
if(offset == 0x75) // PDR1
|
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
|
if(offset == 0x77) // PDR2
|
||||||
m_smpc.PDR2 = data & 0x7f;
|
m_smpc_hle->write(space,offset,data);
|
||||||
|
|
||||||
|
//m_smpc.PDR2 = data & 0x7f;
|
||||||
|
|
||||||
if(offset == 0x79)
|
if(offset == 0x79)
|
||||||
m_smpc.DDR1 = data & 0x7f;
|
m_smpc_hle->write(space,offset,data);
|
||||||
|
|
||||||
|
// m_smpc.DDR1 = data & 0x7f;
|
||||||
|
|
||||||
if(offset == 0x7b)
|
if(offset == 0x7b)
|
||||||
m_smpc.DDR2 = data & 0x7f;
|
m_smpc_hle->write(space,offset,data);
|
||||||
|
|
||||||
|
// m_smpc.DDR2 = data & 0x7f;
|
||||||
|
|
||||||
if(offset == 0x7d)
|
if(offset == 0x7d)
|
||||||
{
|
{
|
||||||
m_smpc.IOSEL1 = data & 1;
|
m_smpc_hle->write(space,offset,data);
|
||||||
m_smpc.IOSEL2 = (data & 2) >> 1;
|
|
||||||
|
// m_smpc.IOSEL1 = data & 1;
|
||||||
|
// m_smpc.IOSEL2 = (data & 2) >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(offset == 0x7f)
|
if(offset == 0x7f)
|
||||||
{
|
{
|
||||||
|
m_smpc_hle->write(space,offset,data);
|
||||||
|
|
||||||
//enable PAD irq & VDP2 external latch for port 1/2
|
//enable PAD irq & VDP2 external latch for port 1/2
|
||||||
m_smpc.EXLE1 = (data & 1) >> 0;
|
// m_smpc.EXLE1 = (data & 1) >> 0;
|
||||||
m_smpc.EXLE2 = (data & 2) >> 1;
|
// m_smpc.EXLE2 = (data & 2) >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,3 +5,112 @@
|
|||||||
//DECLARE_READ8_MEMBER( stv_SMPC_r );
|
//DECLARE_READ8_MEMBER( stv_SMPC_r );
|
||||||
//DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
|
//DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
|
||||||
//DECLARE_READ8_MEMBER( saturn_SMPC_r );
|
//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
|
||||||
|
|
||||||
|
@ -719,18 +719,18 @@ MACHINE_START_MEMBER(sat_console_state, saturn)
|
|||||||
save_pointer(NAME(m_scsp_regs.get()), 0x1000/2);
|
save_pointer(NAME(m_scsp_regs.get()), 0x1000/2);
|
||||||
save_item(NAME(m_NMI_reset));
|
save_item(NAME(m_NMI_reset));
|
||||||
save_item(NAME(m_en_68k));
|
save_item(NAME(m_en_68k));
|
||||||
save_item(NAME(m_smpc.IOSEL1));
|
// save_item(NAME(m_smpc.IOSEL1));
|
||||||
save_item(NAME(m_smpc.IOSEL2));
|
// save_item(NAME(m_smpc.IOSEL2));
|
||||||
save_item(NAME(m_smpc.EXLE1));
|
// save_item(NAME(m_smpc.EXLE1));
|
||||||
save_item(NAME(m_smpc.EXLE2));
|
// save_item(NAME(m_smpc.EXLE2));
|
||||||
save_item(NAME(m_smpc.PDR1));
|
// save_item(NAME(m_smpc.PDR1));
|
||||||
save_item(NAME(m_smpc.PDR2));
|
// save_item(NAME(m_smpc.PDR2));
|
||||||
// save_item(NAME(m_port_sel));
|
// save_item(NAME(m_port_sel));
|
||||||
// save_item(NAME(mux_data));
|
// save_item(NAME(mux_data));
|
||||||
save_item(NAME(m_scsp_last_line));
|
save_item(NAME(m_scsp_last_line));
|
||||||
save_item(NAME(m_smpc.intback_stage));
|
save_item(NAME(m_smpc.intback_stage));
|
||||||
save_item(NAME(m_smpc.pmode));
|
save_item(NAME(m_smpc.pmode));
|
||||||
save_item(NAME(m_smpc.SR));
|
// save_item(NAME(m_smpc.SR));
|
||||||
save_item(NAME(m_smpc.SMEM));
|
save_item(NAME(m_smpc.SMEM));
|
||||||
|
|
||||||
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&sat_console_state::stvcd_exit, this));
|
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_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||||
m_scudsp->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();
|
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));
|
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 )
|
static MACHINE_CONFIG_START( saturn )
|
||||||
|
|
||||||
@ -815,6 +906,11 @@ static MACHINE_CONFIG_START( saturn )
|
|||||||
|
|
||||||
// SH-1
|
// 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)
|
// SMPC MCU, running at 4 MHz (+ custom RTC device that runs at 32.768 KHz)
|
||||||
|
|
||||||
MCFG_MACHINE_START_OVERRIDE(sat_console_state,saturn)
|
MCFG_MACHINE_START_OVERRIDE(sat_console_state,saturn)
|
||||||
|
@ -1021,6 +1021,57 @@ static ADDRESS_MAP_START( scudsp_data, AS_DATA, 32, stv_state )
|
|||||||
ADDRESS_MAP_END
|
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 )
|
static MACHINE_CONFIG_START( stv )
|
||||||
|
|
||||||
/* basic machine hardware */
|
/* 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_IN_DMA_CB(READ16(saturn_state, scudsp_dma_r))
|
||||||
MCFG_SCUDSP_OUT_DMA_CB(WRITE16(saturn_state, scudsp_dma_w))
|
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_START_OVERRIDE(stv_state,stv)
|
||||||
MCFG_MACHINE_RESET_OVERRIDE(stv_state,stv)
|
MCFG_MACHINE_RESET_OVERRIDE(stv_state,stv)
|
||||||
|
|
||||||
@ -1181,7 +1238,7 @@ MACHINE_RESET_MEMBER(stv_state,stv)
|
|||||||
stvcd_reset();
|
stvcd_reset();
|
||||||
|
|
||||||
m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1));
|
m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1));
|
||||||
m_prev_bankswitch = 0xff;
|
m_prev_gamebank_select = 0xff;
|
||||||
|
|
||||||
scu_reset();
|
scu_reset();
|
||||||
|
|
||||||
@ -1234,13 +1291,14 @@ MACHINE_START_MEMBER(stv_state,stv)
|
|||||||
save_pointer(NAME(m_scsp_regs.get()), 0x1000/2);
|
save_pointer(NAME(m_scsp_regs.get()), 0x1000/2);
|
||||||
save_item(NAME(m_NMI_reset));
|
save_item(NAME(m_NMI_reset));
|
||||||
save_item(NAME(m_en_68k));
|
save_item(NAME(m_en_68k));
|
||||||
|
save_item(NAME(m_prev_gamebank_select));
|
||||||
// save_item(NAME(scanline));
|
// save_item(NAME(scanline));
|
||||||
save_item(NAME(m_smpc.IOSEL1));
|
// save_item(NAME(m_smpc.IOSEL1));
|
||||||
save_item(NAME(m_smpc.IOSEL2));
|
// save_item(NAME(m_smpc.IOSEL2));
|
||||||
save_item(NAME(m_smpc.EXLE1));
|
// save_item(NAME(m_smpc.EXLE1));
|
||||||
save_item(NAME(m_smpc.EXLE2));
|
// save_item(NAME(m_smpc.EXLE2));
|
||||||
save_item(NAME(m_smpc.PDR1));
|
// save_item(NAME(m_smpc.PDR1));
|
||||||
save_item(NAME(m_smpc.PDR2));
|
// save_item(NAME(m_smpc.PDR2));
|
||||||
save_item(NAME(m_port_sel));
|
save_item(NAME(m_port_sel));
|
||||||
save_item(NAME(m_mux_data));
|
save_item(NAME(m_mux_data));
|
||||||
save_item(NAME(m_scsp_last_line));
|
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_)
|
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(_n_)
|
||||||
|
|
||||||
static INPUT_PORTS_START( stv )
|
static INPUT_PORTS_START( stv )
|
||||||
PORT_START("DSW1")
|
PORT_START("PDR1")
|
||||||
PORT_DIPNAME( 0x01, 0x01, "PDR1" )
|
PORT_DIPNAME( 0x40, 0x40, "PDR1" ) // P1 Gun Trigger
|
||||||
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( 0x40, DEF_STR( Off ) )
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
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_START("DSW2")
|
||||||
PORT_DIPNAME( 0x01, 0x01, "PDR2" )
|
PORT_DIPNAME( 0x01, 0x01, "PDR2" )
|
||||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
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( 0x02, DEF_STR( Off ) )
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
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( 0x04, DEF_STR( Off ) )
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
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_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
|
||||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
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( 0x40, DEF_STR( Off ) )
|
||||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
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")
|
PORT_START("PORTA")
|
||||||
STV_PLAYER_INPUTS(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4)
|
STV_PLAYER_INPUTS(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "cpu/m68000/m68000.h"
|
#include "cpu/m68000/m68000.h"
|
||||||
#include "cpu/adsp2100/adsp2100.h"
|
#include "cpu/adsp2100/adsp2100.h"
|
||||||
#include "cpu/scudsp/scudsp.h"
|
#include "cpu/scudsp/scudsp.h"
|
||||||
|
#include "machine/smpc.h"
|
||||||
#include "cpu/sh/sh2.h"
|
#include "cpu/sh/sh2.h"
|
||||||
|
|
||||||
#include "bus/sat_ctrl/ctrl.h"
|
#include "bus/sat_ctrl/ctrl.h"
|
||||||
@ -38,12 +39,9 @@ public:
|
|||||||
m_maincpu(*this, "maincpu"),
|
m_maincpu(*this, "maincpu"),
|
||||||
m_slave(*this, "slave"),
|
m_slave(*this, "slave"),
|
||||||
m_audiocpu(*this, "audiocpu"),
|
m_audiocpu(*this, "audiocpu"),
|
||||||
|
m_smpc_hle(*this, "smpc"),
|
||||||
m_scudsp(*this, "scudsp"),
|
m_scudsp(*this, "scudsp"),
|
||||||
m_eeprom(*this, "eeprom"),
|
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_gfxdecode(*this, "gfxdecode"),
|
||||||
m_palette(*this, "palette"),
|
m_palette(*this, "palette"),
|
||||||
m_ctrl1(*this, "ctrl1"),
|
m_ctrl1(*this, "ctrl1"),
|
||||||
@ -130,16 +128,16 @@ public:
|
|||||||
}m_vdp2;
|
}m_vdp2;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t IOSEL1;
|
// uint8_t IOSEL1;
|
||||||
uint8_t IOSEL2;
|
// uint8_t IOSEL2;
|
||||||
uint8_t EXLE1;
|
// uint8_t EXLE1;
|
||||||
uint8_t EXLE2;
|
// uint8_t EXLE2;
|
||||||
uint8_t PDR1;
|
// uint8_t PDR1;
|
||||||
uint8_t PDR2;
|
// uint8_t PDR2;
|
||||||
uint8_t DDR1;
|
// uint8_t DDR1;
|
||||||
uint8_t DDR2;
|
// uint8_t DDR2;
|
||||||
uint8_t SF;
|
// uint8_t SF;
|
||||||
uint8_t SR;
|
// uint8_t SR;
|
||||||
uint8_t IREG[7];
|
uint8_t IREG[7];
|
||||||
uint8_t intback_buf[7];
|
uint8_t intback_buf[7];
|
||||||
uint8_t OREG[32];
|
uint8_t OREG[32];
|
||||||
@ -157,8 +155,6 @@ public:
|
|||||||
uint32_t *m_cart_dram;
|
uint32_t *m_cart_dram;
|
||||||
|
|
||||||
/* ST-V specific */
|
/* ST-V specific */
|
||||||
uint8_t m_stv_multi_bank;
|
|
||||||
uint8_t m_prev_bankswitch;
|
|
||||||
emu_timer *m_stv_rtc_timer;
|
emu_timer *m_stv_rtc_timer;
|
||||||
uint8_t m_port_sel,m_mux_data;
|
uint8_t m_port_sel,m_mux_data;
|
||||||
uint8_t m_system_output;
|
uint8_t m_system_output;
|
||||||
@ -169,12 +165,9 @@ public:
|
|||||||
required_device<sh2_device> m_maincpu;
|
required_device<sh2_device> m_maincpu;
|
||||||
required_device<sh2_device> m_slave;
|
required_device<sh2_device> m_slave;
|
||||||
required_device<m68000_base_device> m_audiocpu;
|
required_device<m68000_base_device> m_audiocpu;
|
||||||
|
required_device<smpc_hle_device> m_smpc_hle;
|
||||||
required_device<scudsp_cpu_device> m_scudsp;
|
required_device<scudsp_cpu_device> m_scudsp;
|
||||||
optional_device<eeprom_serial_93cxx_device> m_eeprom;
|
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<gfxdecode_device> m_gfxdecode;
|
||||||
required_device<palette_device> m_palette;
|
required_device<palette_device> m_palette;
|
||||||
optional_device<saturn_control_port_device> m_ctrl1;
|
optional_device<saturn_control_port_device> m_ctrl1;
|
||||||
@ -210,8 +203,6 @@ public:
|
|||||||
DECLARE_WRITE8_MEMBER(scsp_irq);
|
DECLARE_WRITE8_MEMBER(scsp_irq);
|
||||||
int m_scsp_last_line;
|
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 );
|
TIMER_CALLBACK_MEMBER( smpc_audio_reset_line_pulse );
|
||||||
DECLARE_READ8_MEMBER( saturn_SMPC_r );
|
DECLARE_READ8_MEMBER( saturn_SMPC_r );
|
||||||
DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
|
DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
|
||||||
@ -673,7 +664,6 @@ public:
|
|||||||
DECLARE_WRITE16_MEMBER(scudsp_dma_w);
|
DECLARE_WRITE16_MEMBER(scudsp_dma_w);
|
||||||
|
|
||||||
// FROM smpc.c
|
// FROM smpc.c
|
||||||
void stv_select_game(int gameno);
|
|
||||||
void smpc_master_on();
|
void smpc_master_on();
|
||||||
TIMER_CALLBACK_MEMBER( smpc_slave_enable );
|
TIMER_CALLBACK_MEMBER( smpc_slave_enable );
|
||||||
TIMER_CALLBACK_MEMBER( smpc_sound_enable );
|
TIMER_CALLBACK_MEMBER( smpc_sound_enable );
|
||||||
@ -692,11 +682,19 @@ public:
|
|||||||
DECLARE_READ8_MEMBER( stv_SMPC_r );
|
DECLARE_READ8_MEMBER( stv_SMPC_r );
|
||||||
DECLARE_WRITE8_MEMBER( stv_SMPC_w );
|
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> ¶ms);
|
void debug_scudma_command(int ref, const std::vector<std::string> ¶ms);
|
||||||
void debug_scuirq_command(int ref, const std::vector<std::string> ¶ms);
|
void debug_scuirq_command(int ref, const std::vector<std::string> ¶ms);
|
||||||
void debug_help_command(int ref, const std::vector<std::string> ¶ms);
|
void debug_help_command(int ref, const std::vector<std::string> ¶ms);
|
||||||
void debug_commands(int ref, const std::vector<std::string> ¶ms);
|
void debug_commands(int ref, const std::vector<std::string> ¶ms);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,10 @@ class stv_state : public saturn_state
|
|||||||
public:
|
public:
|
||||||
stv_state(const machine_config &mconfig, device_type type, const char *tag)
|
stv_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: saturn_state(mconfig, type, 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_rax(*this, "rax"),
|
||||||
m_cryptdevice(*this, "315_5881"),
|
m_cryptdevice(*this, "315_5881"),
|
||||||
m_5838crypt(*this, "315_5838"),
|
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_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_cart3 ) { return load_cart(image, m_cart3); }
|
||||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( stv_cart4 ) { return load_cart(image, m_cart4); }
|
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 );
|
void install_stvbios_speedups( void );
|
||||||
|
|
||||||
@ -116,6 +124,13 @@ public:
|
|||||||
uint16_t crypt_read_callback(uint32_t addr);
|
uint16_t crypt_read_callback(uint32_t addr);
|
||||||
uint16_t crypt_read_callback_ch1(uint32_t addr);
|
uint16_t crypt_read_callback_ch1(uint32_t addr);
|
||||||
uint16_t crypt_read_callback_ch2(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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user