diff options
Diffstat (limited to 'src/devices/machine/smpc.cpp')
-rw-r--r-- | src/devices/machine/smpc.cpp | 285 |
1 files changed, 133 insertions, 152 deletions
diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp index 4f2e9ca8295..e70ab757dc7 100644 --- a/src/devices/machine/smpc.cpp +++ b/src/devices/machine/smpc.cpp @@ -160,14 +160,16 @@ SMPC NVRAM contents: */ #include "emu.h" -#include "machine/smpc.h" +#include "smpc.h" #include "screen.h" #include "coreutil.h" -#define LOG_SMPC 0 -#define LOG_PAD_CMD 0 +#define LOG_PAD_CMD (1U << 1) +#define VERBOSE (0) +#include "logmacro.h" + //************************************************************************** // GLOBAL VARIABLES @@ -205,6 +207,7 @@ void smpc_hle_device::smpc_regs(address_map &map) 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) + , device_rtc_interface(mconfig, *this) , m_space_config("regs", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(smpc_hle_device::smpc_regs), this)) , m_mini_nvram(*this, "smem") , m_mshres(*this) @@ -214,8 +217,8 @@ smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, , m_sysres(*this) , m_syshalt(*this) , m_dotsel(*this) - , m_pdr1_read(*this) - , m_pdr2_read(*this) + , m_pdr1_read(*this, 0xff) + , m_pdr2_read(*this, 0xff) , m_pdr1_write(*this) , m_pdr2_write(*this) , m_irq_line(*this) @@ -244,27 +247,10 @@ void smpc_hle_device::device_add_mconfig(machine_config &config) void smpc_hle_device::device_start() { - system_time systime; - machine().base_datetime(systime); - // check if SMEM has valid data via byte 4 in the array, if not then simulate a battery backup fail // (-> call the RTC / Language select menu for Saturn) m_mini_nvram->set_base(&m_smem, 5); - 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(); - m_pdr2_write.resolve_safe(); - save_item(NAME(m_sf)); save_item(NAME(m_sr)); save_item(NAME(m_ddr1)); @@ -285,18 +271,10 @@ void smpc_hle_device::device_start() save_item(NAME(m_rtc_data)); save_item(NAME(m_smem)); - m_cmd_timer = timer_alloc(COMMAND_ID); - m_rtc_timer = timer_alloc(RTC_ID); - m_intback_timer = timer_alloc(INTBACK_ID); - m_sndres_timer = timer_alloc(SNDRES_ID); - - 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); + m_cmd_timer = timer_alloc(FUNC(smpc_hle_device::handle_command), this); + m_rtc_timer = timer_alloc(FUNC(smpc_hle_device::handle_rtc_increment), this); + m_intback_timer = timer_alloc(FUNC(smpc_hle_device::intback_continue_request), this); + m_sndres_timer = timer_alloc(FUNC(smpc_hle_device::sound_reset), this); } @@ -328,6 +306,22 @@ void smpc_hle_device::device_reset() m_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); } + +//------------------------------------------------- +// rtc_clock_updated - update clock with real time +//------------------------------------------------- + +void smpc_hle_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) +{ + m_rtc_data[0] = DectoBCD(year / 100); + m_rtc_data[1] = DectoBCD(year % 100); + m_rtc_data[2] = ((day_of_week - 1) << 4) | month; + m_rtc_data[3] = DectoBCD(day); + m_rtc_data[4] = DectoBCD(hour); + m_rtc_data[5] = DectoBCD(minute); + m_rtc_data[6] = DectoBCD(second); +} + device_memory_interface::space_config_vector smpc_hle_device::memory_space_config() const { return space_config_vector { @@ -353,13 +347,13 @@ void smpc_hle_device::ireg_w(offs_t offset, uint8_t data) { if(data & 0x40) { - if(LOG_PAD_CMD) printf("SMPC: BREAK request\n"); + LOGMASKED(LOG_PAD_CMD, "SMPC: BREAK request\n"); sr_ack(); m_intback_stage = 0; } else if(data & 0x80) { - if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n"); + LOGMASKED(LOG_PAD_CMD, "SMPC: CONTINUE request\n"); m_intback_timer->adjust(attotime::from_usec(700)); // TODO: is timing correct? @@ -564,132 +558,119 @@ void smpc_hle_device::command_register_w(uint8_t data) } -void smpc_hle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(smpc_hle_device::handle_command) { - switch(id) + switch(m_comreg) { - 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 0x08: // CDON - case 0x09: // CDOFF - // ... - m_command_in_progress = false; - m_oreg[31] = m_comreg; - // TODO: diagnostic also wants this to have bit 3 high - sf_ack(true); //set hand-shake flag - return; - - case 0x0a: // NETLINKON - // TODO: understand where NetLink actually lies and implement delegation accordingly - // (is it really an SH1 device like suggested by the space access or it overlays on CS2 bus?) - popmessage("%s: NetLink enabled", this->tag()); - [[fallthrough]]; - case 0x0b: // NETLINKOFF - break; - - 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); - - // 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; - - // send a NMI to Master SH2 if enabled - // it is unconditionally requested: - // bigichig, capgen1, capgen4 and capgen5 triggers a SLEEP opcode from BIOS call and expects this to wake them up. - //if(m_NMI_reset == false) - master_sh2_nmi(); - 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 0x17: // SETSMEM - { - for(int i=0;i<4;i++) - m_smem[i] = m_ireg[i]; - - // clear the SETIME variable, simulate a cr2032 battery alive in the system - m_smem[4] = 0xff; - 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; - } + 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 0x08: // CDON + case 0x09: // CDOFF + // ... m_command_in_progress = false; m_oreg[31] = m_comreg; - sf_ack(false); + // TODO: diagnostic also wants this to have bit 3 high + sf_ack(true); //set hand-shake flag + return; + + case 0x0a: // NETLINKON + // TODO: understand where NetLink actually lies and implement delegation accordingly + // (is it really an SH1 device like suggested by the space access or it overlays on CS2 bus?) + popmessage("%s: NetLink enabled", this->tag()); + [[fallthrough]]; + case 0x0b: // NETLINKOFF + break; + + 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); + + // 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; + + // send a NMI to Master SH2 if enabled + // it is unconditionally requested: + // bigichig, capgen1, capgen4 and capgen5 triggers a SLEEP opcode from BIOS call and expects this to wake them up. + //if(m_NMI_reset == false) + master_sh2_nmi(); + 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 0x17: // SETSMEM + { + for(int i=0;i<4;i++) + m_smem[i] = m_ireg[i]; + + // clear the SETIME variable, simulate a cr2032 battery alive in the system + m_smem[4] = 0xff; break; } - case INTBACK_ID: intback_continue_request(); break; - case RTC_ID: handle_rtc_increment(); break; + case 0x18: // NMIREQ + // NMI is unconditionally requested + master_sh2_nmi(); + break; - // from m68k reset opcode trigger - case SNDRES_ID: - m_sndres(1); - m_sndres(0); + case 0x19: // RESENAB + case 0x1a: // RESDISA + m_NMI_reset = m_comreg & 1; break; default: - printf("%d\n",id); - break; + logerror("%s: unemulated %02x command\n",this->tag(),m_comreg); + return; } + + m_command_in_progress = false; + m_oreg[31] = m_comreg; + sf_ack(false); +} + +TIMER_CALLBACK_MEMBER(smpc_hle_device::sound_reset) +{ + // from m68k reset opcode trigger + m_sndres(1); + m_sndres(0); } void smpc_hle_device::resolve_intback() @@ -749,7 +730,7 @@ void smpc_hle_device::resolve_intback() m_intback_stage = (m_intback_buf[1] & 8) >> 3; // first peripheral sr_set(0x40); m_oreg[31] = 0x10; - intback_continue_request(); + intback_continue_request(0); } else { @@ -759,7 +740,7 @@ void smpc_hle_device::resolve_intback() } } -void smpc_hle_device::intback_continue_request() +TIMER_CALLBACK_MEMBER(smpc_hle_device::intback_continue_request) { if( m_has_ctrl_ports == true ) read_saturn_ports(); @@ -801,7 +782,7 @@ int smpc_hle_device::DectoBCD(int num) // RTC handling //************************************************************************** -void smpc_hle_device::handle_rtc_increment() +TIMER_CALLBACK_MEMBER(smpc_hle_device::handle_rtc_increment) { const uint8_t dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; int year_num, year_count; |