mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
smpc.cpp: reset/halt/nmi lines delegation (nw)
This commit is contained in:
parent
e09bcca8ae
commit
27f564762a
@ -193,10 +193,18 @@ smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag,
|
||||
: 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_mshres(*this),
|
||||
m_mshnmi(*this),
|
||||
m_sshres(*this),
|
||||
m_sndres(*this),
|
||||
m_sysres(*this),
|
||||
m_syshalt(*this),
|
||||
m_dotsel(*this),
|
||||
m_pdr1_read(*this),
|
||||
m_pdr2_read(*this),
|
||||
m_pdr1_write(*this),
|
||||
m_pdr2_write(*this)
|
||||
m_pdr2_write(*this),
|
||||
m_irq_line(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -208,6 +216,15 @@ smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag,
|
||||
|
||||
void smpc_hle_device::device_start()
|
||||
{
|
||||
m_mshres.resolve_safe();
|
||||
m_mshnmi.resolve_safe();
|
||||
m_sshres.resolve_safe();
|
||||
m_sndres.resolve_safe();
|
||||
m_sysres.resolve_safe();
|
||||
m_syshalt.resolve_safe();
|
||||
m_dotsel.resolve_safe();
|
||||
m_irq_line.resolve_safe();
|
||||
|
||||
m_pdr1_read.resolve_safe(0xff);
|
||||
m_pdr2_read.resolve_safe(0xff);
|
||||
m_pdr1_write.resolve_safe();
|
||||
@ -364,8 +381,49 @@ uint8_t smpc_hle_device::get_ddr(bool which)
|
||||
return which == true ? m_ddr2 : m_ddr1;
|
||||
}
|
||||
|
||||
|
||||
// TODO: trampolines that needs to go away
|
||||
void smpc_hle_device::master_sh2_reset(bool state)
|
||||
{
|
||||
m_mshres(state);
|
||||
}
|
||||
|
||||
void smpc_hle_device::slave_sh2_reset(bool state)
|
||||
{
|
||||
m_sshres(state);
|
||||
}
|
||||
|
||||
void smpc_hle_device::sound_reset(bool state)
|
||||
{
|
||||
m_sndres(state);
|
||||
}
|
||||
|
||||
void smpc_hle_device::system_reset(bool state)
|
||||
{
|
||||
m_sysres(state);
|
||||
}
|
||||
|
||||
// actually a PLL connection, handled here for simplicity
|
||||
void smpc_hle_device::system_halt_request(bool state)
|
||||
{
|
||||
m_syshalt(state);
|
||||
}
|
||||
|
||||
void smpc_hle_device::dot_select_request(bool state)
|
||||
{
|
||||
m_dotsel(state);
|
||||
}
|
||||
|
||||
void smpc_hle_device::master_sh2_nmi(bool state)
|
||||
{
|
||||
m_mshnmi(state);
|
||||
}
|
||||
|
||||
void smpc_hle_device::irq_request()
|
||||
{
|
||||
m_irq_line(1);
|
||||
m_irq_line(0);
|
||||
}
|
||||
|
||||
READ8_MEMBER( smpc_hle_device::read )
|
||||
{
|
||||
return this->space().read_byte(offset);
|
||||
@ -387,75 +445,63 @@ WRITE8_MEMBER( smpc_hle_device::write )
|
||||
|
||||
void saturn_state::smpc_master_on()
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
|
||||
m_smpc_hle->master_sh2_reset(0);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_slave_enable )
|
||||
{
|
||||
m_slave->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_smpc_hle->slave_sh2_reset(param);
|
||||
m_smpc.OREG[31] = param + 0x02; //read-back for last command issued
|
||||
m_smpc_hle->sf_ack(false);
|
||||
m_smpc.slave_on = param;
|
||||
// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
}
|
||||
|
||||
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_hle->sound_reset(param);
|
||||
|
||||
m_smpc.OREG[31] = param + 0x06; //read-back for last command issued
|
||||
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_hle->sf_ack(true); //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high)
|
||||
}
|
||||
|
||||
void saturn_state::smpc_system_reset()
|
||||
{
|
||||
/*Only backup ram and SMPC ram are retained after that this command is issued.*/
|
||||
memset(m_scu_regs.get() ,0x00,0x000100);
|
||||
memset(m_scsp_regs.get(),0x00,0x001000);
|
||||
memset(m_sound_ram,0x00,0x080000);
|
||||
memset(m_workram_h,0x00,0x100000);
|
||||
memset(m_workram_l,0x00,0x100000);
|
||||
memset(m_vdp2_regs.get(),0x00,0x040000);
|
||||
memset(m_vdp2_vram.get(),0x00,0x100000);
|
||||
memset(m_vdp2_cram.get(),0x00,0x080000);
|
||||
memset(m_vdp1_vram.get(),0x00,0x100000);
|
||||
//A-Bus
|
||||
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
|
||||
m_smpc_hle->system_reset(1);
|
||||
m_smpc_hle->system_reset(0);
|
||||
|
||||
// send a 1 -> 0 transition to reset line (was PULSE_LINE)
|
||||
m_smpc_hle->master_sh2_reset(1);
|
||||
m_smpc_hle->master_sh2_reset(0);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock )
|
||||
{
|
||||
uint32_t xtal;
|
||||
|
||||
if(LOG_SMPC) printf ("Clock change execute at (%d %d)\n",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
|
||||
xtal = param ? MASTER_CLOCK_320 : MASTER_CLOCK_352;
|
||||
m_smpc_hle->dot_select_request(param);
|
||||
|
||||
machine().device("maincpu")->set_unscaled_clock(xtal/2);
|
||||
machine().device("slave")->set_unscaled_clock(xtal/2);
|
||||
|
||||
m_vdp2.dotsel = param ^ 1;
|
||||
stv_vdp2_dynamic_res_change();
|
||||
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
if(!m_NMI_reset)
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
|
||||
m_audiocpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
{
|
||||
m_smpc_hle->master_sh2_nmi(1);
|
||||
m_smpc_hle->master_sh2_nmi(0);
|
||||
}
|
||||
|
||||
m_smpc_hle->slave_sh2_reset(1);
|
||||
|
||||
m_smpc_hle->system_halt_request(0);
|
||||
|
||||
/* put issued command in OREG31 */
|
||||
m_smpc.OREG[31] = 0x0e + param;
|
||||
/* clear hand-shake flag */
|
||||
m_smpc_hle->sf_ack(false);
|
||||
/* TODO: VDP1 / VDP2 / SCU / SCSP default power ON values? */
|
||||
// TODO: VDP1 / VDP2 / SCU / SCSP default power ON values???
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
|
||||
@ -470,11 +516,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral )
|
||||
m_smpc_hle->sr_set(0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback
|
||||
m_smpc.intback_stage ++;
|
||||
}
|
||||
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
m_smpc_hle->irq_request();
|
||||
|
||||
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
||||
m_smpc_hle->sf_ack(false);
|
||||
@ -518,13 +560,10 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback )
|
||||
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...*/
|
||||
//if(LOG_SMPC) printf ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline);
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
|
||||
// send an interupt to the SCU
|
||||
m_smpc_hle->irq_request();
|
||||
|
||||
/* put issued command in OREG31 */
|
||||
m_smpc.OREG[31] = 0x10; // TODO: doc says 0?
|
||||
/* clear hand-shake flag */
|
||||
@ -622,10 +661,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral )
|
||||
m_smpc.intback_stage ++;
|
||||
}
|
||||
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
m_smpc_hle->irq_request();
|
||||
|
||||
m_smpc.OREG[31] = 0x10; /* callback for last command issued */
|
||||
m_smpc_hle->sf_ack(false);
|
||||
@ -667,11 +703,8 @@ TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback )
|
||||
m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral
|
||||
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))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
|
||||
m_smpc_hle->irq_request();
|
||||
|
||||
/* put issued command in OREG31 */
|
||||
m_smpc.OREG[31] = 0x10;
|
||||
@ -711,7 +744,8 @@ void saturn_state::smpc_memory_setting()
|
||||
void saturn_state::smpc_nmi_req()
|
||||
{
|
||||
/*NMI is unconditionally requested */
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
|
||||
m_smpc_hle->master_sh2_nmi(1);
|
||||
m_smpc_hle->master_sh2_nmi(0);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_nmi_set )
|
||||
@ -730,7 +764,8 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_nmi_set )
|
||||
|
||||
TIMER_CALLBACK_MEMBER( saturn_state::smpc_audio_reset_line_pulse )
|
||||
{
|
||||
m_audiocpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
|
||||
m_smpc_hle->sound_reset(1);
|
||||
m_smpc_hle->sound_reset(0);
|
||||
}
|
||||
|
||||
/********************************************
|
||||
@ -779,15 +814,12 @@ void saturn_state::smpc_comreg_exec(address_space &space, uint8_t data, uint8_t
|
||||
if(LOG_SMPC) printf ("SMPC: Change Clock to %s (%d %d)\n",data & 1 ? "320" : "352",machine().first_screen()->hpos(),machine().first_screen()->vpos());
|
||||
|
||||
/* on ST-V timing of this is pretty fussy, you get 2 credits at start-up otherwise
|
||||
My current theory is that SMPC first stops all CPUs until it executes the whole snippet for this,
|
||||
and restarts them when the screen is again ready for use. I really don't think that the system
|
||||
can do an usable mid-frame clock switching anyway.
|
||||
*/
|
||||
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
m_audiocpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
|
||||
* My current theory is that the PLL device can halt the whole system until the frequency change occurs.
|
||||
* (cfr. diagram on page 3 of SMPC manual)
|
||||
* I really don't think that the system can do an usable mid-frame clock switching anyway.
|
||||
*/
|
||||
m_smpc_hle->system_halt_request(1);
|
||||
|
||||
machine().scheduler().timer_set(machine().first_screen()->time_until_pos(get_vblank_start_position()*get_ystep_count(), 0), timer_expired_delegate(FUNC(saturn_state::smpc_change_clock),this),data & 1);
|
||||
break;
|
||||
/*"Interrupt Back"*/
|
||||
|
@ -32,6 +32,31 @@
|
||||
#define MCFG_SMPC_HLE_PDR2_OUT_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_pdr2_out_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_MASTER_RESET_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_master_reset_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_MASTER_NMI_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_master_nmi_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_SLAVE_RESET_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_slave_reset_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_SOUND_RESET_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_sound_reset_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_SYSTEM_RESET_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_system_reset_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_SYSTEM_HALT_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_system_halt_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_SMPC_HLE_DOT_SELECT_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_dot_select_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
// set_irq_handler doesn't work in Saturn driver???
|
||||
#define MCFG_SMPC_HLE_IRQ_HANDLER_CB(_devcb) \
|
||||
devcb = &smpc_hle_device::set_interrupt_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -49,15 +74,6 @@ public:
|
||||
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 );
|
||||
@ -69,13 +85,45 @@ public:
|
||||
DECLARE_WRITE8_MEMBER( ddr2_w );
|
||||
DECLARE_WRITE8_MEMBER( iosel_w );
|
||||
DECLARE_WRITE8_MEMBER( exle_w );
|
||||
|
||||
// TODO: public stuff & trampolines that should be internal to the device
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
void sr_set(uint8_t data);
|
||||
void sr_ack();
|
||||
void sf_ack(bool cd_enable);
|
||||
void sf_set();
|
||||
void master_sh2_reset(bool state);
|
||||
void master_sh2_nmi(bool state);
|
||||
void slave_sh2_reset(bool state);
|
||||
void sound_reset(bool state);
|
||||
void system_reset(bool state);
|
||||
void dot_select_request(bool state);
|
||||
void system_halt_request(bool state);
|
||||
void irq_request();
|
||||
|
||||
bool get_iosel(bool which);
|
||||
uint8_t get_ddr(bool which);
|
||||
|
||||
// system delegation
|
||||
template <class Object> static devcb_base &set_master_reset_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_mshres.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> static devcb_base &set_master_nmi_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_mshnmi.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> static devcb_base &set_slave_reset_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_sshres.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> static devcb_base &set_sound_reset_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_sndres.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> static devcb_base &set_system_reset_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_sysres.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> static devcb_base &set_system_halt_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_syshalt.set_callback(std::forward<Object>(cb)); }
|
||||
template <class Object> static devcb_base &set_dot_select_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_dotsel.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
|
||||
// PDR delegation
|
||||
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)); }
|
||||
|
||||
// interrupt handler
|
||||
template <class Object> static devcb_base &set_interrupt_handler(device_t &device, Object &&cb) { return downcast<smpc_hle_device &>(device).m_irq_line.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -95,10 +143,21 @@ private:
|
||||
uint8_t m_pdr1_readback, m_pdr2_readback;
|
||||
bool m_iosel1, m_iosel2;
|
||||
bool m_exle1, m_exle2;
|
||||
|
||||
devcb_write_line m_mshres;
|
||||
devcb_write_line m_mshnmi;
|
||||
devcb_write_line m_sshres;
|
||||
// devcb_write_line m_sshnmi;
|
||||
devcb_write_line m_sndres;
|
||||
devcb_write_line m_sysres;
|
||||
// devcb_write_line m_cdres;
|
||||
devcb_write_line m_syshalt;
|
||||
devcb_write_line m_dotsel;
|
||||
devcb_read8 m_pdr1_read;
|
||||
devcb_read8 m_pdr2_read;
|
||||
devcb_write8 m_pdr1_write;
|
||||
devcb_write8 m_pdr2_write;
|
||||
devcb_write_line m_irq_line;
|
||||
};
|
||||
|
||||
|
||||
|
@ -773,7 +773,7 @@ MACHINE_RESET_MEMBER(sat_console_state,saturn)
|
||||
|
||||
m_en_68k = 0;
|
||||
m_NMI_reset = 0;
|
||||
m_smpc.slave_on = 0;
|
||||
// m_smpc.slave_on = 0;
|
||||
|
||||
//memset(stv_m_workram_l, 0, 0x100000);
|
||||
//memset(stv_m_workram_h, 0, 0x100000);
|
||||
@ -872,7 +872,6 @@ uint8_t saturn_state::smpc_th_control_mode(uint16_t in_value, bool which)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
uint8_t saturn_state::smpc_direct_mode(uint16_t in_value,bool which)
|
||||
{
|
||||
uint8_t hshake = (m_direct_mux[which] >> 5) & 3;
|
||||
@ -906,12 +905,20 @@ static MACHINE_CONFIG_START( saturn )
|
||||
|
||||
// SH-1
|
||||
|
||||
// SMPC MCU, running at 4 MHz (+ custom RTC device that runs at 32.768 KHz)
|
||||
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_SMPC_HLE_MASTER_RESET_CB(WRITELINE(saturn_state, master_sh2_reset_w))
|
||||
MCFG_SMPC_HLE_MASTER_NMI_CB(WRITELINE(saturn_state, master_sh2_nmi_w))
|
||||
MCFG_SMPC_HLE_SLAVE_RESET_CB(WRITELINE(saturn_state, slave_sh2_reset_w))
|
||||
MCFG_SMPC_HLE_SOUND_RESET_CB(WRITELINE(saturn_state, sound_68k_reset_w))
|
||||
MCFG_SMPC_HLE_SYSTEM_RESET_CB(WRITELINE(saturn_state, system_reset_w))
|
||||
MCFG_SMPC_HLE_SYSTEM_HALT_CB(WRITELINE(saturn_state, system_halt_w))
|
||||
MCFG_SMPC_HLE_DOT_SELECT_CB(WRITELINE(saturn_state, dot_select_w))
|
||||
MCFG_SMPC_HLE_IRQ_HANDLER_CB(WRITELINE(saturn_state, smpc_irq_w))
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE(sat_console_state,saturn)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(sat_console_state,saturn)
|
||||
|
@ -1100,7 +1100,15 @@ static MACHINE_CONFIG_START( stv )
|
||||
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_SMPC_HLE_MASTER_RESET_CB(WRITELINE(saturn_state, master_sh2_reset_w))
|
||||
MCFG_SMPC_HLE_MASTER_NMI_CB(WRITELINE(saturn_state, master_sh2_nmi_w))
|
||||
MCFG_SMPC_HLE_SLAVE_RESET_CB(WRITELINE(saturn_state, slave_sh2_reset_w))
|
||||
// MCFG_SMPC_HLE_SOUND_RESET_CB(WRITELINE(saturn_state, sound_68k_reset_w)) // ST-V games controls reset line via PDR2
|
||||
MCFG_SMPC_HLE_SYSTEM_RESET_CB(WRITELINE(saturn_state, system_reset_w))
|
||||
MCFG_SMPC_HLE_SYSTEM_HALT_CB(WRITELINE(saturn_state, system_halt_w))
|
||||
MCFG_SMPC_HLE_DOT_SELECT_CB(WRITELINE(saturn_state, dot_select_w))
|
||||
MCFG_SMPC_HLE_IRQ_HANDLER_CB(WRITELINE(saturn_state, smpc_irq_w))
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE(stv_state,stv)
|
||||
MCFG_MACHINE_RESET_OVERRIDE(stv_state,stv)
|
||||
|
||||
@ -1337,7 +1345,7 @@ static INPUT_PORTS_START( stv )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START("DSW2")
|
||||
PORT_START("PDR2")
|
||||
PORT_DIPNAME( 0x01, 0x01, "PDR2" )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
uint8_t SMEM[4];
|
||||
uint8_t intback;
|
||||
uint8_t rtc_data[7];
|
||||
uint8_t slave_on;
|
||||
// uint8_t slave_on;
|
||||
}m_smpc;
|
||||
|
||||
/* Saturn specific*/
|
||||
@ -682,6 +682,15 @@ public:
|
||||
DECLARE_READ8_MEMBER( stv_SMPC_r );
|
||||
DECLARE_WRITE8_MEMBER( stv_SMPC_w );
|
||||
|
||||
// SMPC HLE delegates
|
||||
DECLARE_WRITE_LINE_MEMBER(master_sh2_reset_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(master_sh2_nmi_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(slave_sh2_reset_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(sound_68k_reset_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(system_reset_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(system_halt_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(dot_select_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(smpc_irq_w);
|
||||
DECLARE_READ8_MEMBER(saturn_pdr1_direct_r);
|
||||
DECLARE_READ8_MEMBER(saturn_pdr2_direct_r);
|
||||
DECLARE_WRITE8_MEMBER(saturn_pdr1_direct_w);
|
||||
|
@ -1016,3 +1016,77 @@ WRITE16_MEMBER(saturn_state::scudsp_dma_w)
|
||||
|
||||
program.write_word(addr, data,mem_mask);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( saturn_state::master_sh2_reset_w )
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(saturn_state::master_sh2_nmi_w)
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( saturn_state::slave_sh2_reset_w )
|
||||
{
|
||||
m_slave->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
// m_smpc.slave_on = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( saturn_state::sound_68k_reset_w )
|
||||
{
|
||||
m_audiocpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_en_68k = state ^ 1;
|
||||
}
|
||||
|
||||
// TODO: edge triggered?
|
||||
WRITE_LINE_MEMBER( saturn_state::system_reset_w )
|
||||
{
|
||||
if(!state)
|
||||
return;
|
||||
|
||||
/*Only backup ram and SMPC ram are retained after that this command is issued.*/
|
||||
memset(m_scu_regs.get() ,0x00,0x000100);
|
||||
memset(m_scsp_regs.get(),0x00,0x001000);
|
||||
memset(m_sound_ram,0x00,0x080000);
|
||||
memset(m_workram_h,0x00,0x100000);
|
||||
memset(m_workram_l,0x00,0x100000);
|
||||
memset(m_vdp2_regs.get(),0x00,0x040000);
|
||||
memset(m_vdp2_vram.get(),0x00,0x100000);
|
||||
memset(m_vdp2_cram.get(),0x00,0x080000);
|
||||
memset(m_vdp1_vram.get(),0x00,0x100000);
|
||||
//A-Bus
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(saturn_state::system_halt_w)
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_slave->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
m_audiocpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(saturn_state::dot_select_w)
|
||||
{
|
||||
uint32_t xtal;
|
||||
|
||||
xtal = state ? MASTER_CLOCK_320 : MASTER_CLOCK_352;
|
||||
|
||||
machine().device("maincpu")->set_unscaled_clock(xtal/2);
|
||||
machine().device("slave")->set_unscaled_clock(xtal/2);
|
||||
|
||||
m_vdp2.dotsel = state ^ 1;
|
||||
stv_vdp2_dynamic_res_change();
|
||||
}
|
||||
|
||||
// TODO: to move into SCU device
|
||||
WRITE_LINE_MEMBER(saturn_state::smpc_irq_w)
|
||||
{
|
||||
if(!state)
|
||||
return;
|
||||
|
||||
if(!(m_scu.ism & IRQ_SMPC))
|
||||
m_maincpu->set_input_line_and_vector(8, HOLD_LINE, 0x47);
|
||||
else
|
||||
m_scu.ist |= (IRQ_SMPC);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user