From 1b08996e2b3b043bdd0b68868d7c6578b97cb484 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Mon, 12 Nov 2018 02:41:55 +0100 Subject: -dp8573.cpp: Added DP8573 Real-Time Clock emulation. [Ryan Holtz] -indigo.cpp: Hooked up new DP8573 implementation. [Ryan Holtz] --- scripts/src/machine.lua | 12 ++ scripts/target/mame/arcade.lua | 1 + scripts/target/mame/mess.lua | 1 + src/devices/machine/dp8573.cpp | 355 +++++++++++++++++++++++++++++++++++++++++ src/devices/machine/dp8573.h | 148 +++++++++++++++++ src/devices/machine/timehelp.h | 8 +- src/mame/drivers/indigo.cpp | 144 ++++------------- src/mame/mame.lst | 1 + 8 files changed, 552 insertions(+), 118 deletions(-) create mode 100644 src/devices/machine/dp8573.cpp create mode 100644 src/devices/machine/dp8573.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 836d3e2d5b9..9433450b1b9 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -3226,6 +3226,18 @@ if (MACHINES["DP83932C"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/dp8573.h,MACHINES["DP8573"] = true +--------------------------------------------------- + +if (MACHINES["DP8573"]~=null) then + files { + MAME_DIR .. "src/devices/machine/dp8573.cpp", + MAME_DIR .. "src/devices/machine/dp8573.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/pc_lpt.h,MACHINES["PC_LPT"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 1d873296b17..b021e1fa34b 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -424,6 +424,7 @@ MACHINES["CR589"] = true --MACHINES["CS8221"] = true MACHINES["CXD1095"] = true MACHINES["DP8390"] = true +--MACHINES["DP8573"] = true MACHINES["DS1204"] = true MACHINES["DS1205"] = true MACHINES["DS1302"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index e140389b39b..ca93926dffe 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -424,6 +424,7 @@ MACHINES["CS8221"] = true MACHINES["CXD1095"] = true MACHINES["DP8390"] = true MACHINES["DP83932C"] = true +MACHINES["DP8573"] = true --MACHINES["DS1204"] = true MACHINES["DS1302"] = true MACHINES["DS1315"] = true diff --git a/src/devices/machine/dp8573.cpp b/src/devices/machine/dp8573.cpp new file mode 100644 index 00000000000..0568d507471 --- /dev/null +++ b/src/devices/machine/dp8573.cpp @@ -0,0 +1,355 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*************************************************************************** + + DP8573 Real Time Clock (RTC) + +***************************************************************************/ + +#include "emu.h" +#include "machine/dp8573.h" +#include "machine/timehelp.h" + +#define LOG_GENERAL (1 << 0) +#define LOG_TICKS (1 << 1) +#define LOG_ALL (LOG_GENERAL | LOG_TICKS) + +#define VERBOSE (LOG_ALL) +#include "logmacro.h" + +// device type definition +DEFINE_DEVICE_TYPE(DP8573, dp8573_device, "dp8573", "DP8573 Real-Time Clock") + +dp8573_device::dp8573_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DP8573, tag, owner, clock) + , device_nvram_interface(mconfig, *this) + , m_irq(*this) + , m_pfail(*this) +{ +} + +void dp8573_device::device_start() +{ + save_item(NAME(m_ram)); + save_item(NAME(m_tscr)); + save_item(NAME(m_pfr)); + save_item(NAME(m_millis)); + + m_timer = timer_alloc(TIMER_ID); + m_timer->adjust(attotime::never); + + m_irq.resolve_safe(); + m_pfail.resolve_safe(); +} + +void dp8573_device::device_reset() +{ + memset(m_ram, 0, 32); + + m_tscr = 0; + m_pfr = 0; + m_millis = 0; + + system_time systime; + machine().base_datetime(systime); + + m_ram[REG_SECOND] = time_helper::make_bcd(systime.local_time.second); + m_ram[REG_MINUTE] = time_helper::make_bcd(systime.local_time.minute); + m_ram[REG_HOUR] = time_helper::make_bcd(systime.local_time.hour); + m_ram[REG_DAY] = time_helper::make_bcd(systime.local_time.mday); + m_ram[REG_MONTH] = time_helper::make_bcd(systime.local_time.month + 1); + m_ram[REG_YEAR] = time_helper::make_bcd(systime.local_time.year % 100); + m_ram[REG_DAYOFWEEK] = time_helper::make_bcd(systime.local_time.weekday + 1); + m_ram[REG_RTMR] = RTMR_CSS; + + m_timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1)); +} + +void dp8573_device::save_registers() +{ + m_ram[REG_SAVE_SECOND] = m_ram[REG_SECOND]; + m_ram[REG_SAVE_MINUTE] = m_ram[REG_MINUTE]; + m_ram[REG_SAVE_HOUR] = m_ram[REG_HOUR]; + m_ram[REG_SAVE_DAY] = m_ram[REG_DAY]; + m_ram[REG_SAVE_MONTH] = m_ram[REG_MONTH]; +} + +void dp8573_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if ((m_pfr & PFR_OSF) || !(m_ram[REG_RTMR] & RTMR_CSS)) + { + LOGMASKED(LOG_TICKS, "Tick suppressed due to OSF or !CSS\n"); + return; + } + + m_pfr ^= PFR_1MS; + + m_millis++; + bool carry = false; + bool tens_carry = false; + time_helper::inc_bcd(&m_millis, 0xff, 0x00, 0x09, &tens_carry); + if (tens_carry) + { + m_pfr ^= PFR_10MS; + carry = time_helper::inc_bcd(&m_ram[REG_HUNDREDTH], 0xff, 0x00, 0x99, &tens_carry); + if (tens_carry) + m_pfr ^= PFR_100MS; + } + if (carry) + { + m_pfr ^= PFR_1S; + carry = time_helper::inc_bcd(&m_ram[REG_SECOND], 0xff, 0x00, 0x59, &tens_carry); + if (tens_carry) + m_pfr ^= PFR_10S; + } + if (carry) + { + m_pfr ^= PFR_1MIN; + carry = time_helper::inc_bcd(&m_ram[REG_MINUTE], 0xff, 0x00, 0x59); + } + if (carry) + { + if (m_ram[REG_RTMR] & RTMR_12H) + { + carry = time_helper::inc_bcd(&m_ram[REG_HOUR], 0xff, 0x01, 0x12); + if (carry) + { + m_ram[REG_HOUR] ^= 0x20; + carry = !(m_ram[REG_HOUR] & 0x20); + } + } + else + { + carry = time_helper::inc_bcd(&m_ram[REG_HOUR], 0xff, 0x00, 0x23); + } + } + if (carry) + { + static const uint8_t daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; + + time_helper::inc_bcd(&m_ram[REG_DAYOFWEEK], 0xff, 0x01, 0x07); + + uint8_t month = time_helper::from_bcd(m_ram[REG_MONTH]); + + uint8_t maxdays; + if (month == 2 && (m_ram[REG_RTMR] & RTMR_LY) == 0) + { + maxdays = 0x29; + } + else if (month >= 1 && month <= 12) + { + maxdays = daysinmonth[month - 1]; + } + else + { + maxdays = 0x31; + } + + carry = time_helper::inc_bcd(&m_ram[REG_DAY], 0xff, 0x01, maxdays); + } + if (carry) + { + carry = time_helper::inc_bcd(&m_ram[REG_MONTH], 0xff, 0x01, 0x12); + } + if (carry) + { + carry = time_helper::inc_bcd(&m_ram[REG_YEAR], 0xff, 0x00, 0x99); + } + if (carry) + { + // Advance the leap-year counter + uint8_t leap = m_ram[REG_RTMR] & RTMR_LY; + leap = (leap + 1) & RTMR_LY; + m_ram[REG_RTMR] &= ~RTMR_LY; + m_ram[REG_RTMR] |= leap; + } + + // Check for Time Save mode + if (m_tscr & TSCR_TS) + { + save_registers(); + } + + // Check for periodic interrupts + const uint8_t icr0 = m_ram[REG_PFR_ICR0] & ~ICR0_RAM_MASK; + const uint8_t pfr = m_pfr & ~ICR0_RAM_MASK; + if (icr0 & pfr) + { + set_interrupt(MSR_PER); + } + + const uint8_t icr1 = m_ram[REG_TSCR_ICR1] & ICR1_COMPARE_MASK; + if (icr1) + { + if (m_ram[REG_SECOND] == m_ram[REG_COMP_SECOND] || + m_ram[REG_MINUTE] == m_ram[REG_COMP_MINUTE] || + m_ram[REG_HOUR] == m_ram[REG_COMP_HOUR] || + m_ram[REG_DAY] == m_ram[REG_COMP_DAY] || + m_ram[REG_MONTH] == m_ram[REG_COMP_MONTH] || + m_ram[REG_DAYOFWEEK] == m_ram[REG_COMP_DAYOFWEEK]) + { + set_interrupt(MSR_AL); + } + } +} + +void dp8573_device::set_interrupt(uint8_t mask) +{ + bool was_intr = m_ram[REG_MSR] & MSR_INT; + m_ram[REG_MSR] |= mask; + + if (m_ram[REG_MSR] & MSR_INT_MASK) + m_ram[REG_MSR] |= MSR_INT; + + if (!was_intr && (m_ram[REG_MSR] & MSR_INT)) + m_irq(1); +} + +void dp8573_device::clear_interrupt(uint8_t mask) +{ + bool was_intr = m_ram[REG_MSR] & MSR_INT; + m_ram[REG_MSR] &= ~mask; + + if (was_intr && !(m_ram[REG_MSR] & MSR_INT)) + m_irq(0); +} + +WRITE8_MEMBER(dp8573_device::write) +{ + LOGMASKED(LOG_GENERAL, "%s: DP8573 - Register Write: %02x = %02x\n", machine().describe_context(), offset, data); + + switch (offset) + { + case REG_MSR: // Main Status Register + m_ram[offset] &= ~MSR_RAM_MASK; + m_ram[offset] |= data & MSR_RAM_MASK; + if (data & MSR_CLEARABLE_MASK) + clear_interrupt(data & MSR_CLEARABLE_MASK); + break; + + case REG_RTMR: // Not Applicable / Real-Time Mode Register + if (m_ram[REG_MSR] & MSR_RS) + { + const uint8_t old = m_ram[offset]; + m_ram[offset] = data; + if ((old ^ data) & RTMR_12H) + { + uint8_t hour; + if (old & RTMR_12H) + hour = time_helper::from_bcd(m_ram[REG_HOUR] & 0x1f) + (BIT(m_ram[REG_HOUR], 5) ? 12 : 0); + else + hour = time_helper::from_bcd(m_ram[REG_HOUR]); + + if (data & RTMR_12H) + { + m_ram[REG_HOUR] = time_helper::make_bcd(hour % 12); + m_ram[REG_HOUR] |= (hour > 11) ? 0x20 : 0; + } + else + { + m_ram[REG_HOUR] = time_helper::make_bcd(hour); + } + } + } + break; + + case REG_OMR: // Not Applicable / Output Mode Register + if (m_ram[REG_MSR] & MSR_RS) + { + // Not yet implemented: Buffered Crystal Oscillator output on MFO pin + m_ram[offset] = data; + } + break; + + case REG_PFR_ICR0: // Periodic Flag Register / Interrupt Control Register 0 + if (m_ram[REG_MSR] & MSR_RS) + { + m_ram[offset] = data; + } + else + { + m_pfr &= ~PFR_TM; + m_pfr |= data & PFR_TM; + } + break; + + case REG_TSCR_ICR1: // Time Save Control Register / Interrupt Control Register 1 + if (m_ram[REG_MSR] & MSR_RS) + { + m_ram[offset] = data; + } + else + { + m_tscr = data & ~TSCR_NA; + if (data & TSCR_TS) + save_registers(); + } + break; + + case REG_RAM_D1D0: // RAM, D1/D0 bits only + m_ram[offset] = data & 3; + break; + + case REG_NA_0FH: + case REG_NA_10H: + case REG_NA_11H: + case REG_NA_12H: + break; + + default: + m_ram[offset] = data; + break; + } +} + +READ8_MEMBER(dp8573_device::read) +{ + uint8_t ret = m_ram[offset]; + + if (offset >= REG_RTMR && offset <= REG_TSCR_ICR1) + { + if (m_ram[REG_MSR] & MSR_RS) + { + } + else + { + switch (offset) + { + case REG_RTMR: + case REG_OMR: + ret = 0; + break; + case REG_PFR_ICR0: + ret = m_pfr; + m_pfr &= ~PFR_READ_CLEAR_MASK; + break; + case REG_TSCR_ICR1: + ret = m_tscr; + break; + default: + break; + } + } + } + + LOGMASKED(LOG_GENERAL, "%s: DP8573 - Register Read: %02x = %02x\n", machine().describe_context(), offset, ret); + return ret; +} + +void dp8573_device::nvram_default() +{ + memset(m_ram, 0, 32); + + m_pfr = 0; + m_ram[REG_RTMR] = RTMR_CSS; +} + +void dp8573_device::nvram_read(emu_file &file) +{ + file.read(m_ram, 32); +} + +void dp8573_device::nvram_write(emu_file &file) +{ + file.write(m_ram, 32); +} diff --git a/src/devices/machine/dp8573.h b/src/devices/machine/dp8573.h new file mode 100644 index 00000000000..cc4a7a32479 --- /dev/null +++ b/src/devices/machine/dp8573.h @@ -0,0 +1,148 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*************************************************************************** + + DP8573 Real Time Clock (RTC) + +***************************************************************************/ + +#ifndef DEVICES_MACHINE_DP8573_H +#define DEVICES_MACHINE_DP8573_H + +#pragma once + +class dp8573_device : public device_t, public device_nvram_interface +{ +public: + dp8573_device(const machine_config &mconfig, const char *tag, device_t *owner) + : dp8573_device(mconfig, tag, owner, 32768) + { + } + + dp8573_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE8_MEMBER(write); + DECLARE_READ8_MEMBER(read); + + auto irq() { return m_irq.bind(); } + auto power_fail() { return m_pfail.bind(); } + +protected: + // device-level overrides + 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; + + // device_nvram_interface overrides + virtual void nvram_default() override; + virtual void nvram_read(emu_file &file) override; + virtual void nvram_write(emu_file &file) override; + + void save_registers(); + void set_interrupt(uint8_t mask); + void clear_interrupt(uint8_t mask); + + static const device_timer_id TIMER_ID = 0; + + enum + { + REG_MSR = 0x00, // Main Status Register + REG_RTMR = 0x01, // Not Applicable / Real-Time Mode Register + REG_OMR = 0x02, // Not Applicable / Output Mode Register + REG_PFR_ICR0 = 0x03, // Periodic Flag Register / Interrupt Control Register 0 + REG_TSCR_ICR1 = 0x04, // Time Save Control Register / Interrupt Control Register 1 + REG_HUNDREDTH = 0x05, // Hundredths and Teneths of a Second (0-99) + REG_SECOND = 0x06, // Seconds (0-59) + REG_MINUTE = 0x07, // Minutes (0-59) + REG_HOUR = 0x08, // Hours (1-12, 0-23) + REG_DAY = 0x09, // Day of Month (1-28/29/30/31) + REG_MONTH = 0x0a, // Month (1-12) + REG_YEAR = 0x0b, // Year (0-99) + // 0x0c - RAM + REG_RAM_D1D0 = 0x0d, // RAM, D1/D0 bits only + REG_DAYOFWEEK = 0x0e, // Day of Week (1-7) + REG_NA_0FH = 0x0f, + REG_NA_10H = 0x10, + REG_NA_11H = 0x11, + REG_NA_12H = 0x12, + REG_COMP_SECOND = 0x13, // Seconds Compare RAM (0-59) + REG_COMP_MINUTE = 0x14, // Minutes Compare RAM (0-59) + REG_COMP_HOUR = 0x15, // Hours Compare RAM (1-12, 0-23) + REG_COMP_DAY = 0x16, // Day of Month Compare RAM (1-28/29/30/31) + REG_COMP_MONTH = 0x17, // Month Compare RAM (1-12) + REG_COMP_DAYOFWEEK = 0x18, // Day of Week Compare RAM (1-7) + REG_SAVE_SECOND = 0x19, // Seconds Time Save RAM + REG_SAVE_MINUTE = 0x1a, // Minutes Time Save RAM + REG_SAVE_HOUR = 0x1b, // Hours Time Save RAM + REG_SAVE_DAY = 0x1c, // Day of Month Time Save RAM + REG_SAVE_MONTH = 0x1d, // Month Time Save RAM + // 0x1e - RAM + REG_TEST = 0x1f, // RAM / Test Mode Register + + MSR_INT = 0x01, // Interrupt Status + MSR_PF = 0x02, // Power Fail Interrupt + MSR_PER = 0x04, // Period Interrupt + MSR_AL = 0x08, // Alarm Interrupt + MSR_RS = 0x40, // Register Select Bit + MSR_RAM_MASK = 0xf0, + MSR_INT_MASK = 0x0e, + MSR_CLEARABLE_MASK = 0x0c, + + PFR_1MIN = 0x01, // Minutes flag + PFR_10S = 0x02, // 10-second flag + PFR_1S = 0x04, // Seconds flag + PFR_100MS = 0x08, // 100-millisecond flag + PFR_10MS = 0x10, // 10-millisecond flag + PFR_1MS = 0x20, // Millisecond flag + PFR_OSF = 0x40, // Oscillator Failed / Single Supply Bit + PFR_TM = 0x80, // Test Mode Enable + PFR_READ_CLEAR_MASK = 0x3f, + + TSCR_RAM_MASK = 0x3f, + TSCR_NA = 0x40, // N/A + TSCR_TS = 0x80, // Time Save Enable + + RTMR_LY0 = 0x01, // Leap Year LSB + RTMR_LY1 = 0x02, // Leap Year MSB + RTMR_LY = 0x03, + RTMR_12H = 0x04, // 12/!24 hour mode + RTMR_CSS = 0x08, // Clock Start/!Stop + RTMR_IPF = 0x10, // Interrupt PF Operation + RTMR_RAM_MASK = 0xe0, + + OMR_RAM_MASK = 0x7f, + OMR_MO = 0x80, // MFO Pin as Oscillator + + ICR0_MN = 0x01, // Minutes enable + ICR0_TS = 0x02, // 10-second enable + ICR0_S = 0x04, // Seconds enable + ICR0_HM = 0x08, // 100 millisecond enable + ICR0_TM = 0x10, // 10 millisecond enable + ICR0_1M = 0x20, // Milliseconds enable + ICR0_RAM_MASK = 0xc0, + + ICR1_SC = 0x01, // Second compare enable + ICR1_MN = 0x02, // Minute compare enable + ICR1_HR = 0x04, // Hour compare enable + ICR1_DOM = 0x08, // Day of month compare enable + ICR1_MO = 0x10, // Month compare enable + ICR1_DOW = 0x20, // Day of week compare enable + ICR1_ALE = 0x40, // Alarm interrupt enable + ICR1_PFE = 0x80, // Power fail interrupt enable + ICR1_COMPARE_MASK = 0x3f + }; + + uint8_t m_ram[32]; + uint8_t m_tscr; + uint8_t m_pfr; + uint8_t m_millis; + + emu_timer *m_timer; + + devcb_write_line m_irq; + devcb_write_line m_pfail; +}; + +DECLARE_DEVICE_TYPE(DP8573, dp8573_device) + +#endif // DEVICES_MACHINE_DP8573_H diff --git a/src/devices/machine/timehelp.h b/src/devices/machine/timehelp.h index 62626b3e25b..9e1e5efeefc 100644 --- a/src/devices/machine/timehelp.h +++ b/src/devices/machine/timehelp.h @@ -26,13 +26,15 @@ public: return (((data >> 4) & 15) * 10) + (data & 15); } - static int inc_bcd(uint8_t *data, int mask, int min, int max) + static int inc_bcd(uint8_t *data, int mask, int min, int max, bool *tens_carry = nullptr) { int bcd = (*data + 1) & mask; int carry = 0; if ((bcd & 0x0f) > 9) { + if (tens_carry) + *tens_carry = true; bcd &= 0xf0; bcd += 0x10; if (bcd > max) @@ -41,6 +43,10 @@ public: carry = 1; } } + else if (tens_carry) + { + *tens_carry = false; + } *data = (*data & ~mask) | (bcd & mask); return carry; diff --git a/src/mame/drivers/indigo.cpp b/src/mame/drivers/indigo.cpp index 8ab7de2aa0f..01f480e5e81 100644 --- a/src/mame/drivers/indigo.cpp +++ b/src/mame/drivers/indigo.cpp @@ -21,8 +21,10 @@ #include "bus/scsi/scsi.h" #include "bus/scsi/scsicd.h" #include "bus/scsi/scsihd.h" +//#include "cpu/dsp56k/dsp56k.h" #include "cpu/mips/mips1.h" #include "cpu/mips/mips3.h" +#include "machine/dp8573.h" #include "machine/eepromser.h" #include "machine/pit8253.h" #include "machine/sgi.h" @@ -34,14 +36,13 @@ #define LOG_UNKNOWN (1 << 0) #define LOG_INT (1 << 1) #define LOG_HPC (1 << 2) -#define LOG_RTC (1 << 3) #define LOG_EEPROM (1 << 4) #define LOG_DMA (1 << 5) #define LOG_SCSI (1 << 6) #define LOG_SCSI_DMA (1 << 7) #define LOG_DUART (1 << 8) #define LOG_PIT (1 << 9) -#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_HPC | LOG_RTC | LOG_EEPROM | LOG_DMA | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT) +#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_HPC | LOG_EEPROM | LOG_DMA | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT) #define VERBOSE (0) #include "logmacro.h" @@ -56,6 +57,7 @@ public: , m_scc(*this, "scc%u", 0U) , m_eeprom(*this, "eeprom") , m_pit(*this, "pit") + , m_rtc(*this, "rtc") { } @@ -64,14 +66,13 @@ public: protected: virtual void machine_start() override; virtual void machine_reset() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - - static const device_timer_id TIMER_RTC = 0; DECLARE_READ32_MEMBER(hpc_r); DECLARE_WRITE32_MEMBER(hpc_w); DECLARE_READ32_MEMBER(int_r); DECLARE_WRITE32_MEMBER(int_w); + DECLARE_READ32_MEMBER(dspram_r); + DECLARE_WRITE32_MEMBER(dspram_w); DECLARE_WRITE_LINE_MEMBER(scsi_irq); void set_timer_int_clear(uint32_t data); @@ -142,37 +143,18 @@ protected: HPC_DMACTRL_ENABLE = 0x80 }; - enum - { - RTC_DAYOFWEEK = 0x0e, - RTC_YEAR = 0x0b, - RTC_MONTH = 0x0a, - RTC_DAY = 0x09, - RTC_HOUR = 0x08, - RTC_MINUTE = 0x07, - RTC_SECOND = 0x06, - RTC_HUNDREDTH = 0x05 - }; - - struct rtc_t - { - uint8_t m_ram[32]; - }; - required_device m_maincpu; required_device m_wd33c93; required_device_array m_scc; required_device m_eeprom; required_device m_pit; + required_device m_rtc; + + std::unique_ptr m_dsp_ram; hpc_t m_hpc; - rtc_t m_rtc; uint8_t m_duart_int_status; - emu_timer *m_rtc_timer; - - void indigo_timer_rtc(); - static char const *const RS232A_TAG; static char const *const RS232B_TAG; @@ -222,8 +204,7 @@ protected: void indigo_state::machine_start() { - m_rtc_timer = timer_alloc(TIMER_RTC); - m_rtc_timer->adjust(attotime::never); + m_dsp_ram = std::make_unique(0x8000); save_item(NAME(m_hpc.m_misc_status)); save_item(NAME(m_hpc.m_parbuf_ptr)); @@ -243,29 +224,24 @@ void indigo_state::machine_start() save_item(NAME(m_hpc.m_scsi0_dma_to_mem)); save_item(NAME(m_hpc.m_scsi0_dma_active)); - save_item(NAME(m_rtc.m_ram)); - save_item(NAME(m_duart_int_status)); + + save_pointer(NAME(m_dsp_ram), 0x8000); } void indigo_state::machine_reset() { memset(&m_hpc, 0, sizeof(hpc_t)); + memset(&m_dsp_ram[0], 0, sizeof(uint32_t) * 0x8000); m_duart_int_status = 0; - - // update RTC every 1/100th of a second - m_rtc_timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10)); } READ32_MEMBER(indigo_state::hpc_r) { if (offset >= 0x0e00/4 && offset <= 0x0e7c/4) - { - uint8_t ret = m_rtc.m_ram[offset - 0xe00/4]; - LOGMASKED(LOG_RTC, "%s: RTC RAM[0x%02x] Read: %02x\n", machine().describe_context(), offset - 0xe00/4, ret); - return ret; - } + return m_rtc->read(space, offset - 0xe00/4); + switch (offset) { case 0x005c/4: @@ -421,27 +397,7 @@ WRITE32_MEMBER(indigo_state::hpc_w) { if (offset >= 0x0e00/4 && offset <= 0x0e7c/4) { - LOGMASKED(LOG_RTC, "%s: RTC RAM[%02x] Write: %02x\n", machine().describe_context(), offset - 0xe00/4, (uint8_t)data); - m_rtc.m_ram[offset - 0xe00/4] = (uint8_t)data; - - switch (offset - 0xe00/4) - { - case 0: - break; - case 4: - if (!BIT(m_rtc.m_ram[0x00], 7)) - { - if (BIT(data, 7)) - { - m_rtc.m_ram[0x19] = m_rtc.m_ram[RTC_SECOND]; - m_rtc.m_ram[0x1a] = m_rtc.m_ram[RTC_MINUTE]; - m_rtc.m_ram[0x1b] = m_rtc.m_ram[RTC_HOUR]; - m_rtc.m_ram[0x1c] = m_rtc.m_ram[RTC_DAY]; - m_rtc.m_ram[0x1d] = m_rtc.m_ram[RTC_MONTH]; - } - } - break; - } + m_rtc->write(space, offset - 0xe00/4, (uint8_t)data); return; } @@ -709,18 +665,6 @@ WRITE_LINE_MEMBER(indigo_state::scsi_irq) } } -void indigo_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_RTC: - indigo_timer_rtc(); - break; - default: - assert_always(false, "Unknown id in indigo_state::device_timer"); - } -} - void indigo_state::set_timer_int_clear(uint32_t data) { if (BIT(data, 0)) @@ -818,53 +762,16 @@ WRITE32_MEMBER(indigo_state::int_w) LOGMASKED(LOG_INT, "%s: INT Write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fbd9000 + offset*4, data, mem_mask); } -void indigo_state::indigo_timer_rtc() +READ32_MEMBER(indigo_state::dspram_r) { - m_rtc.m_ram[RTC_HUNDREDTH]++; - - if ((m_rtc.m_ram[RTC_HUNDREDTH] & 0x0f) == 0x0a) - { - m_rtc.m_ram[RTC_HUNDREDTH] -= 0x0a; - m_rtc.m_ram[RTC_HUNDREDTH] += 0x10; - if ((m_rtc.m_ram[RTC_HUNDREDTH] & 0xa0) == 0xa0) - { - m_rtc.m_ram[RTC_HUNDREDTH] = 0; - m_rtc.m_ram[RTC_SECOND]++; + LOGMASKED(LOG_INT, "%s: DSP RAM Read: %08x & %08x\n", machine().describe_context(), 0x1fbe0000 + offset*4, mem_mask); + return m_dsp_ram[offset]; +} - if ((m_rtc.m_ram[RTC_SECOND] & 0x0f) == 0x0a) - { - m_rtc.m_ram[RTC_SECOND] -= 0x0a; - m_rtc.m_ram[RTC_SECOND] += 0x10; - if (m_rtc.m_ram[RTC_SECOND] == 0x60) - { - m_rtc.m_ram[RTC_SECOND] = 0; - m_rtc.m_ram[RTC_MINUTE]++; - - if ((m_rtc.m_ram[RTC_MINUTE] & 0x0f) == 0x0a) - { - m_rtc.m_ram[RTC_MINUTE] -= 0x0a; - m_rtc.m_ram[RTC_MINUTE] += 0x10; - if (m_rtc.m_ram[RTC_MINUTE] == 0x60) - { - m_rtc.m_ram[RTC_MINUTE] = 0; - m_rtc.m_ram[RTC_HOUR]++; - - if ((m_rtc.m_ram[RTC_HOUR] & 0x0f) == 0x0a) - { - m_rtc.m_ram[RTC_HOUR] -= 0x0a; - m_rtc.m_ram[RTC_HOUR] += 0x10; - if (m_rtc.m_ram[RTC_HOUR] == 0x24) - { - m_rtc.m_ram[RTC_HOUR] = 0; - m_rtc.m_ram[RTC_DAY]++; - } - } - } - } - } - } - } - } +WRITE32_MEMBER(indigo_state::dspram_w) +{ + LOGMASKED(LOG_INT, "%s: DSP RAM Write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fbe0000 + offset*4, data, mem_mask); + COMBINE_DATA(&m_dsp_ram[offset]); } void indigo_state::indigo_map(address_map &map) @@ -878,6 +785,7 @@ void indigo_state::indigo_map(address_map &map) map(0x18000000, 0x187fffff).ram().share("share7"); map(0x1fb80000, 0x1fb8ffff).rw(FUNC(indigo_state::hpc_r), FUNC(indigo_state::hpc_w)); map(0x1fbd9000, 0x1fbd903f).rw(FUNC(indigo_state::int_r), FUNC(indigo_state::int_w)); + map(0x1fbe0000, 0x1fbe7fff).rw(FUNC(indigo_state::dspram_r), FUNC(indigo_state::dspram_w)); } void indigo3k_state::mem_map(address_map &map) @@ -941,6 +849,8 @@ void indigo_state::indigo_base(machine_config &config) scsi.set_slot_device(2, "cdrom", SCSICD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4)); scsi.slot(2).set_option_machine_config("cdrom", cdrom_config); + DP8573(config, m_rtc); + WD33C93(config, m_wd33c93); m_wd33c93->set_scsi_port("scsi"); m_wd33c93->irq_cb().set(FUNC(indigo_state::scsi_irq)); diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ebd35493503..26556a23e43 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -21180,6 +21180,7 @@ gldarrow // (c) 1984 Meyco Games @source:mfabfz.cpp mfabfz // +mfabfz64k // mfabfz85 // @source:mgames.cpp -- cgit v1.2.3