summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/smpc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/smpc.cpp')
-rw-r--r--src/devices/machine/smpc.cpp162
1 files changed, 97 insertions, 65 deletions
diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp
index 80e93f0f8c3..b4bc706dcff 100644
--- a/src/devices/machine/smpc.cpp
+++ b/src/devices/machine/smpc.cpp
@@ -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);
+ if(!m_NMI_reset)
+ {
+ m_smpc_hle->master_sh2_nmi(1);
+ m_smpc_hle->master_sh2_nmi(0);
+ }
- m_vdp2.dotsel = param ^ 1;
- stv_vdp2_dynamic_res_change();
+ m_smpc_hle->slave_sh2_reset(1);
- 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->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"*/