summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <salese_corp_ltd@email.it>2017-10-05 01:51:12 +0200
committer angelosa <salese_corp_ltd@email.it>2017-10-05 05:10:31 +0200
commitd6dbbe54548aec59b8878b4709c52310ce0bc66a (patch)
treeacb256794a337e4432b1c606cbc8a32129420ded
parentb6f6b3bfd16f7172d2bc10c71cfe3ab1bc93cca0 (diff)
smpc.cpp: execute commands internal to the device for ST-V (nw)
-rw-r--r--src/devices/machine/smpc.cpp402
-rw-r--r--src/devices/machine/smpc.h52
-rw-r--r--src/mame/drivers/saturn.cpp18
-rw-r--r--src/mame/drivers/stv.cpp16
-rw-r--r--src/mame/includes/saturn.h3
-rw-r--r--src/mame/machine/saturn.cpp85
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<cnt; i++)
+ tmp *= 16;
+ res += tmp;
+ cnt++;
+ num /= 10;
+ }
+
+ return res;
+}
+
+void 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;
+
+ /*
+ 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_rtc_data[6]++;
+
+ /* seconds from 9 -> 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 <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)); }
+ 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, // <unknown>
+ 30, 30, // SOUND ON / OFF
+ 40, 40, // CD ON / OFF
+ 30, 30, 30, // NETLINK ON / OFF / <unknown>
+ 100*1000, 100*1000, 100*1000, // SYSTEM RESET / ClocK CHaNGe 352 / 320
+ 320*1000, // INTBACK
+ 30, 30, 30, 30, 30, // <unknown>
+ 70, 40, 30, 30, 30, // SETTIME / SETSMEM / NMIREQ / RESENAB / RESDISA
+ 30, 30, 30, 30 // <unknown>
+ };
+ 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<std::string> &param
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_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<cnt; i++)
- tmp *= 16;
- res += tmp;
- cnt++;
- num /= 10;
- }
-
- return res;
-}
-
/**************************************************************************************/
/*
@@ -676,74 +659,6 @@ void saturn_state::scu_reset(void)
m_scu.status = 0;
}
-TIMER_CALLBACK_MEMBER(saturn_state::stv_rtc_increment)
-{
- static const uint8_t dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 };
- static int year_num, year_count;
-
- /*
- 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_smpc.rtc_data[6]++;
-
- /* seconds from 9 -> 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