From d6dbbe54548aec59b8878b4709c52310ce0bc66a Mon Sep 17 00:00:00 2001 From: angelosa Date: Thu, 5 Oct 2017 01:51:12 +0200 Subject: smpc.cpp: execute commands internal to the device for ST-V (nw) --- src/devices/machine/smpc.cpp | 402 ++++++++++++++++++++++++++++++++++++++++++- src/devices/machine/smpc.h | 52 +++++- src/mame/drivers/saturn.cpp | 18 +- src/mame/drivers/stv.cpp | 16 +- src/mame/includes/saturn.h | 3 - src/mame/machine/saturn.cpp | 85 --------- 6 files changed, 443 insertions(+), 133 deletions(-) diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp index 30f6045e6ac..8e55d7a529c 100644 --- a/src/devices/machine/smpc.cpp +++ b/src/devices/machine/smpc.cpp @@ -14,6 +14,7 @@ TODO: - fix intback issue with inputs (according to the docs, it should fall in between VBLANK-IN and OUT, for obvious reasons); - clean-ups; +- RTC device (unknown type, handled here for convenience) Notes: SMPC NVRAM contents: @@ -181,6 +182,7 @@ DEFINE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device, "smpc_hle", "Sega Saturn SMPC HLE static ADDRESS_MAP_START( smpc_regs, 0, 8, smpc_hle_device ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00, 0x0d) AM_WRITE(ireg_w) + AM_RANGE(0x1f, 0x1f) AM_WRITE(command_register_w) AM_RANGE(0x20, 0x5f) AM_READ(oreg_r) AM_RANGE(0x61, 0x61) AM_READ(status_register_r) AM_RANGE(0x63, 0x63) AM_READWRITE(status_flag_r, status_flag_w) @@ -220,13 +222,15 @@ smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, } - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void smpc_hle_device::device_start() { + system_time systime; + machine().base_datetime(systime); + m_mshres.resolve_safe(); m_mshnmi.resolve_safe(); m_sshres.resolve_safe(); @@ -253,6 +257,28 @@ void smpc_hle_device::device_start() save_item(NAME(m_exle2)); save_item(NAME(m_ireg)); save_item(NAME(m_oreg)); + save_item(NAME(m_comreg)); + save_item(NAME(m_command_in_progress)); + save_item(NAME(m_intback_buf)); + save_item(NAME(m_intback_stage)); + save_item(NAME(m_pmode)); + save_item(NAME(m_rtc_data)); + + m_cmd_timer = timer_alloc(COMMAND_ID); + m_rtc_timer = timer_alloc(RTC_ID); + m_intback_timer = timer_alloc(INTBACK_ID); + +// TODO: tag-ify, needed when SCU will be a device + m_screen = machine().first_screen(); + + m_rtc_data[0] = DectoBCD(systime.local_time.year / 100); + m_rtc_data[1] = DectoBCD(systime.local_time.year % 100); + m_rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); + m_rtc_data[3] = DectoBCD(systime.local_time.mday); + m_rtc_data[4] = DectoBCD(systime.local_time.hour); + m_rtc_data[5] = DectoBCD(systime.local_time.minute); + m_rtc_data[6] = DectoBCD(systime.local_time.second); + } @@ -269,9 +295,18 @@ void smpc_hle_device::device_reset() m_ddr2 = 0; m_pdr1_readback = 0; m_pdr2_readback = 0; - + memset(m_ireg,0,7); memset(m_oreg,0,32); + + m_cmd_timer->reset(); + m_intback_timer->reset(); + m_comreg = 0xff; + m_command_in_progress = false; + m_NMI_reset = false; + m_cur_dotsel = false; + + m_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); } //------------------------------------------------- @@ -298,10 +333,33 @@ WRITE8_MEMBER( smpc_hle_device::ireg_w ) return; m_ireg[offset >> 1] = data; + + if(offset == 1) // check if we are under intback + { + if(m_intback_stage) + { + if(data & 0x40) + { + if(LOG_PAD_CMD) printf("SMPC: BREAK request\n"); + sr_ack(); + m_intback_stage = 0; + } + else if(data & 0x80) + { + if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n"); + + m_intback_timer->adjust(attotime::from_usec(700)); // TODO: is timing correct? + + // TODO: following looks wrong here + m_oreg[31] = 0x10; + sf_set(); + } + } + } } READ8_MEMBER( smpc_hle_device::oreg_r ) -{ +{ if (!(offset & 1)) // avoid reading to even bytes (TODO: is it 0s or 1s?) return 0x00; @@ -455,6 +513,11 @@ void smpc_hle_device::dot_select_request(bool state) m_dotsel(state); } +bool smpc_hle_device::get_nmi_status() +{ + return m_NMI_reset; +} + void smpc_hle_device::master_sh2_nmi() { m_mshnmi(1); @@ -477,8 +540,324 @@ WRITE8_MEMBER( smpc_hle_device::write ) this->space().write_byte(offset,data); } +//************************************************************************** +// Command simulation +//************************************************************************** +WRITE8_MEMBER( smpc_hle_device::command_register_w ) +{ +// don't send a command if previous one is still in progress +// ST-V tries to send a sysres command if OREG31 doesn't return the ack command + if(m_command_in_progress == true) + return; + + m_comreg = data & 0x1f; + + if(data & 0xe0) + logerror("%s COMREG = %02x!?\n",this->tag(),data); + + m_command_in_progress = true; + if(m_comreg == 0x0e || m_comreg == 0x0f) + { + /* on ST-V timing of this is pretty fussy, you get 2 credits at start-up otherwise + * 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_syshalt(1); + + m_cmd_timer->adjust(m_screen->time_until_pos(m_screen->visible_area().max_y,0)); + } + else if(m_comreg == 0x10) + { + // copy ireg to our intback buffer + for(int i=0;i<3;i++) + m_intback_buf[i] = m_ireg[i]; + + // calculate the timing for intback command + int timing; + + timing = 8; + if( m_ireg[0] != 0) // non-peripheral data + timing += 8; + + // TODO: At vblank-out actually ... + if( m_ireg[1] & 8) // peripheral data + timing += 700; + + // TODO: check against ireg2, must be 0xf0 + + m_cmd_timer->adjust(attotime::from_usec(timing)); + } + else + m_cmd_timer->adjust(attotime::from_usec(m_cmd_table_timing[m_comreg])); +} + + +void smpc_hle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch(id) + { + case COMMAND_ID: + { + switch(m_comreg) + { + case 0x00: // MSHON + // enable Master SH2 + m_mshres(m_comreg & 1); + break; + + case 0x02: // SSHON + case 0x03: // SSHOFF + // enable or disable Slave SH2 + m_sshres(m_comreg & 1); + break; + + case 0x06: // SNDON + case 0x07: // SNDOFF + // enable or disable 68k + m_sndres(m_comreg & 1); + break; + +// case 0x0a: // NETLINKON +// case 0x0b: // NETLINKOFF + + case 0x0d: // SYSRES + // send a 1 -> 0 to device reset lines + m_sysres(1); + m_sysres(0); + + // send a 1 -> 0 transition to reset line (was PULSE_LINE) + m_mshres(1); + m_mshres(0); + break; + + case 0x0e: // CKCHG352 + case 0x0f: // CKCHG320 + m_dotsel(m_comreg & 1); + + // send a NMI to Master SH2 if enabled + if(m_NMI_reset == false) + master_sh2_nmi(); + + // assert Slave SH2 line + m_sshres(1); + // clear PLL system halt + m_syshalt(0); + + // setup the new dot select + m_cur_dotsel = (m_comreg & 1) ^ 1; + break; + + case 0x10: // INTBACK + resolve_intback(); + return; + + case 0x16: // SETTIME + for(int i=0;i<7;i++) + m_rtc_data[i] = m_ireg[i]; + break; + + case 0x18: // NMIREQ + // NMI is unconditionally requested + master_sh2_nmi(); + break; + + case 0x19: // RESENAB + case 0x1a: // RESDISA + m_NMI_reset = m_comreg & 1; + break; + + default: + logerror("%s unemulated %02x command\n",this->tag(),m_comreg); + return; + } + + m_command_in_progress = false; + m_oreg[31] = m_comreg; + sf_ack(false); + break; + } + case INTBACK_ID: intback_continue_request(); break; + case RTC_ID: handle_rtc_increment(); break; + default: + printf("%d\n",id); + break; + } +} + +void smpc_hle_device::resolve_intback() +{ + int i; + + m_command_in_progress = false; + + if(m_intback_buf[0] != 0) + { + m_oreg[0] = ((0x80) | ((m_NMI_reset & 1) << 6)); + + for(i=0;i<7;i++) + m_oreg[1+i] = m_rtc_data[i]; + + m_oreg[8] = 0; // CTG0 / CTG1? + + m_oreg[9] = 0; // TODO: system region on Saturn + + /* + 0-11 -1-- unknown + -x-- ---- VDP2 dot select + ---- x--- MSHNMI + ---- --x- SYSRES + ---- ---x SOUNDRES + */ + m_oreg[10] = 0 << 7 | + m_cur_dotsel << 6 | + 1 << 5 | + 1 << 4 | + 0 << 3 | + 1 << 2 | + 0 << 1 | + 0 << 0; + + m_oreg[11] = 0 << 6; // CDRES + + for(i=0;i<4;i++) + m_oreg[12+i] = 0; //m_smpc.SMEM[i]); TODO + + for(i=0;i<15;i++) + m_oreg[16+i] = 0xff; // undefined + + m_intback_stage = (m_intback_buf[1] & 8) >> 3; // first peripheral + sr_set(0x40 | (m_intback_stage << 5)); + m_pmode = m_intback_buf[0]>>4; + + irq_request(); + + // put issued command in OREG31 + m_oreg[31] = 0x10; // TODO: doc says 0? + /* clear hand-shake flag */ + sf_ack(false); + } + else if(m_intback_buf[1] & 8) + { + m_intback_stage = (m_intback_buf[1] & 8) >> 3; // first peripheral + sr_set(0x40); + m_oreg[31] = 0x10; + intback_continue_request(); + } + else + { + /* Shienryu calls this, it would be plainly illegal on Saturn, I'll just return the command and clear the hs flag for now. */ + m_oreg[31] = 0x10; + sf_ack(false); + } +} + +void smpc_hle_device::intback_continue_request() +{ + if (m_intback_stage == 2) + { + sr_set(0x80 | m_pmode); // pad 2, no more data, echo back pad mode set by intback + m_intback_stage = 0; + } + else + { + sr_set(0xc0 | m_pmode); // pad 1, more data, echo back pad mode set by intback + m_intback_stage ++; + } + irq_request(); + + m_oreg[31] = 0x10; // callback for last command issued + sf_ack(false); + +} + +int smpc_hle_device::DectoBCD(int num) +{ + int i, cnt = 0, tmp, res = 0; + + while (num > 0) { + tmp = num; + while (tmp >= 10) tmp %= 10; + for (i=0; i 10*/ + if((m_rtc_data[6] & 0x0f) >= 0x0a) { m_rtc_data[6]+=0x10; m_rtc_data[6]&=0xf0; } + /* seconds from 59 -> 0 */ + if((m_rtc_data[6] & 0xf0) >= 0x60) { m_rtc_data[5]++; m_rtc_data[6] = 0; } + /* minutes from 9 -> 10 */ + if((m_rtc_data[5] & 0x0f) >= 0x0a) { m_rtc_data[5]+=0x10; m_rtc_data[5]&=0xf0; } + /* minutes from 59 -> 0 */ + if((m_rtc_data[5] & 0xf0) >= 0x60) { m_rtc_data[4]++; m_rtc_data[5] = 0; } + /* hours from 9 -> 10 */ + if((m_rtc_data[4] & 0x0f) >= 0x0a) { m_rtc_data[4]+=0x10; m_rtc_data[4]&=0xf0; } + /* hours from 23 -> 0 */ + if((m_rtc_data[4] & 0xff) >= 0x24) { m_rtc_data[3]++; m_rtc_data[2]+=0x10; m_rtc_data[4] = 0; } + /* week day name sunday -> monday */ + if((m_rtc_data[2] & 0xf0) >= 0x70) { m_rtc_data[2]&=0x0f; } + /* day number 9 -> 10 */ + if((m_rtc_data[3] & 0x0f) >= 0x0a) { m_rtc_data[3]+=0x10; m_rtc_data[3]&=0xf0; } + + // year BCD to dec conversion (for the leap year stuff) + { + year_num = (m_rtc_data[1] & 0xf); + + for(year_count = 0; year_count < (m_rtc_data[1] & 0xf0); year_count += 0x10) + year_num += 0xa; + + year_num += (m_rtc_data[0] & 0xf)*0x64; + + for(year_count = 0; year_count < (m_rtc_data[0] & 0xf0); year_count += 0x10) + year_num += 0x3e8; + } + + /* month +1 check */ + /* the RTC have a range of 1980 - 2100, so we don't actually need to support the leap year special conditions */ + if(((year_num % 4) == 0) && (m_rtc_data[2] & 0xf) == 2) + { + if((m_rtc_data[3] & 0xff) >= dpm[(m_rtc_data[2] & 0xf)-1]+1+1) + { m_rtc_data[2]++; m_rtc_data[3] = 0x01; } + } + else if((m_rtc_data[3] & 0xff) >= dpm[(m_rtc_data[2] & 0xf)-1]+1){ m_rtc_data[2]++; m_rtc_data[3] = 0x01; } + /* year +1 check */ + if((m_rtc_data[2] & 0x0f) > 12) { m_rtc_data[1]++; m_rtc_data[2] = (m_rtc_data[2] & 0xf0) | 0x01; } + /* year from 9 -> 10 */ + if((m_rtc_data[1] & 0x0f) >= 0x0a) { m_rtc_data[1]+=0x10; m_rtc_data[1]&=0xf0; } + /* year from 99 -> 100 */ + if((m_rtc_data[1] & 0xf0) >= 0xa0) { m_rtc_data[0]++; m_rtc_data[1] = 0; } + + // probably not SO precise, here just for reference ... + /* year from 999 -> 1000 */ + //if((m_rtc_data[0] & 0x0f) >= 0x0a) { m_rtc_data[0]+=0x10; m_rtc_data[0]&=0xf0; } + /* year from 9999 -> 0 */ + //if((m_rtc_data[0] & 0xf0) >= 0xa0) { m_rtc_data[0] = 0; } //roll over +} /******************************************** * @@ -529,7 +908,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock ) m_smpc_hle->dot_select_request(param); - if(!m_NMI_reset) + if(m_smpc_hle->get_nmi_status() == false) m_smpc_hle->master_sh2_nmi(); m_smpc_hle->slave_sh2_reset(1); @@ -546,7 +925,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock ) TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral ) { if (m_smpc.intback_stage == 2) - { + { 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; } @@ -570,7 +949,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback ) if(m_smpc.intback_buf[0] != 0) { - m_smpc_hle->set_oreg(0, (0x80) | ((m_NMI_reset & 1) << 6)); + m_smpc_hle->set_oreg(0, (0x80) | ((m_smpc_hle->get_nmi_status() & 1) << 6)); for(i=0;i<7;i++) m_smpc_hle->set_oreg(1+i, m_smpc.rtc_data[i]); @@ -730,7 +1109,7 @@ TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback ) { int i; - m_smpc_hle->set_oreg(0, (0x80) | ((m_NMI_reset & 1) << 6)); // bit 7: SETTIME (RTC isn't setted up properly) + m_smpc_hle->set_oreg(0, (0x80) | ((m_smpc_hle->get_nmi_status() & 1) << 6)); // bit 7: SETTIME (RTC isn't setted up properly) for(i=0;i<7;i++) m_smpc_hle->set_oreg(1+i, m_smpc.rtc_data[i]); @@ -979,7 +1358,7 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w ) if(offset >= 1 && offset <= 0xd) m_smpc_hle->write(space,offset,data); - + #if 0 if(offset == 1) //IREG0, check if a BREAK / CONTINUE request for INTBACK command { if(m_smpc.intback_stage) @@ -999,17 +1378,22 @@ WRITE8_MEMBER( saturn_state::stv_SMPC_w ) } } } + #endif if (offset == 0x1f) // COMREG { - smpc_comreg_exec(space,data,1); + m_smpc_hle->write(space,offset,data); + +// smpc_comreg_exec(space,data,1); // we've processed the command, clear status flag + #if 0 if(data != 0x10 && data != 0x02 && data != 0x03 && data != 0x08 && data != 0x09 && data != 0xe && data != 0xf && data != 0x19 && data != 0x1a) { m_smpc_hle->set_oreg(31,data); m_smpc_hle->sf_ack(false); } + #endif /*TODO:emulate the timing of each command...*/ } diff --git a/src/devices/machine/smpc.h b/src/devices/machine/smpc.h index 359194bfe6b..2c1ff6aa5c5 100644 --- a/src/devices/machine/smpc.h +++ b/src/devices/machine/smpc.h @@ -11,14 +11,15 @@ #pragma once +#include "screen.h" //************************************************************************** // INTERFACE CONFIGURATION MACROS //************************************************************************** -#define MCFG_SMPC_HLE_ADD(tag) \ - MCFG_DEVICE_ADD((tag), SMPC_HLE, (0)) +#define MCFG_SMPC_HLE_ADD(tag, clock) \ + MCFG_DEVICE_ADD((tag), SMPC_HLE, (clock)) #define MCFG_SMPC_HLE_PDR1_IN_CB(_devcb) \ devcb = &smpc_hle_device::set_pdr1_in_handler(*device, DEVCB_##_devcb); @@ -75,6 +76,7 @@ public: // I/O operations DECLARE_WRITE8_MEMBER( ireg_w ); + DECLARE_WRITE8_MEMBER( command_register_w ); DECLARE_READ8_MEMBER( oreg_r ); DECLARE_READ8_MEMBER( status_register_r ); DECLARE_WRITE8_MEMBER( status_flag_w ); @@ -104,6 +106,7 @@ public: void dot_select_request(bool state); void system_halt_request(bool state); void irq_request(); + bool get_nmi_status(); bool get_iosel(bool which); uint8_t get_ddr(bool which); @@ -129,6 +132,7 @@ public: // interrupt handler template static devcb_base &set_interrupt_handler(device_t &device, Object &&cb) { return downcast(device).m_irq_line.set_callback(std::forward(cb)); } + static void static_set_screentag(device_t &device, const char *tag); protected: // device-level overrides @@ -136,10 +140,20 @@ protected: // virtual void device_add_mconfig() override; virtual void device_start() override; virtual void device_reset() override; - + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + private: + enum { + COMMAND_ID = 1, + RTC_ID, + INTBACK_ID + }; + const address_space_config m_space_config; + emu_timer *m_cmd_timer; + emu_timer *m_rtc_timer; + emu_timer *m_intback_timer; bool m_sf; bool m_cd_sf; @@ -149,8 +163,36 @@ private: bool m_iosel1, m_iosel2; bool m_exle1, m_exle2; uint8_t m_ireg[7]; + uint8_t m_intback_buf[3]; uint8_t m_oreg[32]; - + uint8_t m_rtc_data[7]; + uint8_t m_comreg; + // in usec + // timing table, from manual in usec + const uint32_t m_cmd_table_timing[0x20] = + { + 30, 30, // MASTER ON / OFF + 30, 30, // SLAVE ON / OFF + 10, 10, // + 30, 30, // SOUND ON / OFF + 40, 40, // CD ON / OFF + 30, 30, 30, // NETLINK ON / OFF / + 100*1000, 100*1000, 100*1000, // SYSTEM RESET / ClocK CHaNGe 352 / 320 + 320*1000, // INTBACK + 30, 30, 30, 30, 30, // + 70, 40, 30, 30, 30, // SETTIME / SETSMEM / NMIREQ / RESENAB / RESDISA + 30, 30, 30, 30 // + }; + bool m_command_in_progress; + bool m_NMI_reset; + bool m_cur_dotsel; + void resolve_intback(); + void intback_continue_request(); + void handle_rtc_increment(); + int DectoBCD(int num); + int m_intback_stage; + int m_pmode; + devcb_write_line m_mshres; devcb_write_line m_mshnmi; devcb_write_line m_sshres; @@ -165,6 +207,8 @@ private: devcb_write8 m_pdr1_write; devcb_write8 m_pdr2_write; devcb_write_line m_irq_line; + + screen_device *m_screen; }; diff --git a/src/mame/drivers/saturn.cpp b/src/mame/drivers/saturn.cpp index 667854cd15c..183df5ca476 100644 --- a/src/mame/drivers/saturn.cpp +++ b/src/mame/drivers/saturn.cpp @@ -448,7 +448,6 @@ test1f diagnostic hacks: #include "softlist.h" #include "speaker.h" -#include "coreutil.h" class sat_console_state : public saturn_state @@ -649,9 +648,6 @@ void saturn_state::debug_commands(int ref, const std::vector ¶m MACHINE_START_MEMBER(sat_console_state, saturn) { - system_time systime; - machine().base_datetime(systime); - if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; @@ -735,16 +731,6 @@ MACHINE_START_MEMBER(sat_console_state, saturn) machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&sat_console_state::stvcd_exit, this)); - m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); - m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); - m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); - m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); - m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); - m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); - m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); - - m_stv_rtc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sat_console_state::stv_rtc_increment),this)); - m_audiocpu->set_reset_callback(write_line_delegate(FUNC(sat_console_state::m68k_reset_callback),this)); } @@ -785,8 +771,6 @@ MACHINE_RESET_MEMBER(sat_console_state,saturn) m_vdp2.old_crmd = -1; m_vdp2.old_tvmd = -1; - - m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); } READ8_MEMBER( saturn_state::saturn_pdr1_direct_r ) @@ -906,7 +890,7 @@ 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_ADD("smpc", XTAL_4MHz) 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)) diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp index 9b7b037fefa..e7d1dbd0fa1 100644 --- a/src/mame/drivers/stv.cpp +++ b/src/mame/drivers/stv.cpp @@ -1095,7 +1095,7 @@ 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_ADD("smpc", XTAL_4MHz) 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)) @@ -1245,7 +1245,6 @@ MACHINE_RESET_MEMBER(stv_state,stv) stvcd_reset(); - m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); m_prev_gamebank_select = 0xff; scu_reset(); @@ -1289,9 +1288,6 @@ image_init_result stv_state::load_cart(device_image_interface &image, generic_sl MACHINE_START_MEMBER(stv_state,stv) { - system_time systime; - machine().base_datetime(systime); - machine().device("scsp")->set_ram_base(m_sound_ram); // save states @@ -1315,16 +1311,6 @@ MACHINE_START_MEMBER(stv_state,stv) machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&stv_state::stvcd_exit, this)); - m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); - m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); - m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); - m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); - m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); - m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); - m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); - - m_stv_rtc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(stv_state::stv_rtc_increment),this)); - m_audiocpu->set_reset_callback(write_line_delegate(FUNC(stv_state::m68k_reset_callback),this)); } diff --git a/src/mame/includes/saturn.h b/src/mame/includes/saturn.h index 82e358b2a60..499e9eb34a4 100644 --- a/src/mame/includes/saturn.h +++ b/src/mame/includes/saturn.h @@ -155,7 +155,6 @@ public: uint32_t *m_cart_dram; /* ST-V specific */ - emu_timer *m_stv_rtc_timer; uint8_t m_port_sel,m_mux_data; uint8_t m_system_output; uint8_t m_ioga_mode; @@ -198,7 +197,6 @@ public: DECLARE_WRITE32_MEMBER(saturn_sinit_w); DECLARE_READ8_MEMBER(saturn_backupram_r); DECLARE_WRITE8_MEMBER(saturn_backupram_w); - TIMER_CALLBACK_MEMBER(stv_rtc_increment); DECLARE_WRITE_LINE_MEMBER(scsp_to_main_irq); DECLARE_WRITE8_MEMBER(scsp_irq); int m_scsp_last_line; @@ -657,7 +655,6 @@ public: int firstfile; // first non-directory file DECLARE_WRITE_LINE_MEMBER(m68k_reset_callback); - int DectoBCD(int num); DECLARE_WRITE_LINE_MEMBER(scudsp_end_w); DECLARE_READ16_MEMBER(scudsp_dma_r); diff --git a/src/mame/machine/saturn.cpp b/src/mame/machine/saturn.cpp index 83227ae7161..8a37c301ecd 100644 --- a/src/mame/machine/saturn.cpp +++ b/src/mame/machine/saturn.cpp @@ -54,23 +54,6 @@ #define LOG_IRQ 0 #define LOG_IOGA 0 -int saturn_state::DectoBCD(int num) -{ - int i, cnt = 0, tmp, res = 0; - - while (num > 0) { - tmp = num; - while (tmp >= 10) tmp %= 10; - for (i=0; i 10*/ - if((m_smpc.rtc_data[6] & 0x0f) >= 0x0a) { m_smpc.rtc_data[6]+=0x10; m_smpc.rtc_data[6]&=0xf0; } - /* seconds from 59 -> 0 */ - if((m_smpc.rtc_data[6] & 0xf0) >= 0x60) { m_smpc.rtc_data[5]++; m_smpc.rtc_data[6] = 0; } - /* minutes from 9 -> 10 */ - if((m_smpc.rtc_data[5] & 0x0f) >= 0x0a) { m_smpc.rtc_data[5]+=0x10; m_smpc.rtc_data[5]&=0xf0; } - /* minutes from 59 -> 0 */ - if((m_smpc.rtc_data[5] & 0xf0) >= 0x60) { m_smpc.rtc_data[4]++; m_smpc.rtc_data[5] = 0; } - /* hours from 9 -> 10 */ - if((m_smpc.rtc_data[4] & 0x0f) >= 0x0a) { m_smpc.rtc_data[4]+=0x10; m_smpc.rtc_data[4]&=0xf0; } - /* hours from 23 -> 0 */ - if((m_smpc.rtc_data[4] & 0xff) >= 0x24) { m_smpc.rtc_data[3]++; m_smpc.rtc_data[2]+=0x10; m_smpc.rtc_data[4] = 0; } - /* week day name sunday -> monday */ - if((m_smpc.rtc_data[2] & 0xf0) >= 0x70) { m_smpc.rtc_data[2]&=0x0f; } - /* day number 9 -> 10 */ - if((m_smpc.rtc_data[3] & 0x0f) >= 0x0a) { m_smpc.rtc_data[3]+=0x10; m_smpc.rtc_data[3]&=0xf0; } - - // year BCD to dec conversion (for the leap year stuff) - { - year_num = (m_smpc.rtc_data[1] & 0xf); - - for(year_count = 0; year_count < (m_smpc.rtc_data[1] & 0xf0); year_count += 0x10) - year_num += 0xa; - - year_num += (m_smpc.rtc_data[0] & 0xf)*0x64; - - for(year_count = 0; year_count < (m_smpc.rtc_data[0] & 0xf0); year_count += 0x10) - year_num += 0x3e8; - } - - /* month +1 check */ - /* the RTC have a range of 1980 - 2100, so we don't actually need to support the leap year special conditions */ - if(((year_num % 4) == 0) && (m_smpc.rtc_data[2] & 0xf) == 2) - { - if((m_smpc.rtc_data[3] & 0xff) >= dpm[(m_smpc.rtc_data[2] & 0xf)-1]+1+1) - { m_smpc.rtc_data[2]++; m_smpc.rtc_data[3] = 0x01; } - } - else if((m_smpc.rtc_data[3] & 0xff) >= dpm[(m_smpc.rtc_data[2] & 0xf)-1]+1){ m_smpc.rtc_data[2]++; m_smpc.rtc_data[3] = 0x01; } - /* year +1 check */ - if((m_smpc.rtc_data[2] & 0x0f) > 12) { m_smpc.rtc_data[1]++; m_smpc.rtc_data[2] = (m_smpc.rtc_data[2] & 0xf0) | 0x01; } - /* year from 9 -> 10 */ - if((m_smpc.rtc_data[1] & 0x0f) >= 0x0a) { m_smpc.rtc_data[1]+=0x10; m_smpc.rtc_data[1]&=0xf0; } - /* year from 99 -> 100 */ - if((m_smpc.rtc_data[1] & 0xf0) >= 0xa0) { m_smpc.rtc_data[0]++; m_smpc.rtc_data[1] = 0; } - - // probably not SO precise, here just for reference ... - /* year from 999 -> 1000 */ - //if((m_smpc.rtc_data[0] & 0x0f) >= 0x0a) { m_smpc.rtc_data[0]+=0x10; m_smpc.rtc_data[0]&=0xf0; } - /* year from 9999 -> 0 */ - //if((m_smpc.rtc_data[0] & 0xf0) >= 0xa0) { m_smpc.rtc_data[0] = 0; } //roll over -} /* Official documentation says that the "RESET/TAS opcodes aren't supported", but Out Run definitely contradicts with it. Since that m68k can't reset itself via the RESET opcode I suppose that the SMPC actually do it by reading an i/o -- cgit v1.2.3