mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +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_PAD_CMD 0
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
/********************************************
|
||||
*
|
||||
* Bankswitch code for ST-V Multi Cart mode
|
||||
*
|
||||
*******************************************/
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device, "smpc_hle", "Sega Saturn SMPC HLE (HD404920FS)")
|
||||
|
||||
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
|
||||
@ -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]);
|
||||
m_smpc_hle->write(space,offset,data);
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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> ¶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_commands(int ref, const std::vector<std::string> ¶ms);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user