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.cpp285
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;