icm7170: basic time keeping [R. Belmont]

This commit is contained in:
arbee 2020-04-04 21:36:06 -04:00
parent da2c2135b7
commit 3b3ac7e0c8
3 changed files with 57 additions and 3 deletions

View File

@ -34,10 +34,31 @@ enum
REG_RAM_DAY,
REG_RAM_YEAR,
REG_RAM_DAY_OF_WEEK,
REG_INT_STATUS_MASK,
REG_INT_STATUS_AND_MASK,
REG_COMMAND
};
enum
{
CMD_REG_TEST_MODE = 0x20,
CMD_REG_IRQ_ENABLE = 0x10,
CMD_REG_RUN = 0x08,
CMD_REG_24_HOUR = 0x04,
CMD_REG_FREQ_MASK = 0x03
};
enum
{
IRQ_BIT_GLOBAL = 0x80,
IRQ_BIT_DAY = 0x40,
IRQ_BIT_HOUR = 0x20,
IRQ_BIT_MINUTE = 0x10,
IRQ_BIT_SECOND = 0x08,
IRQ_BIT_10TH_SECOND = 0x04,
IRQ_BIT_100TH_SECOND = 0x02,
IRQ_BIT_ALARM = 0x01
};
static constexpr int ICM7170_TIMER_ID = 0;
//**************************************************************************
@ -71,6 +92,16 @@ void icm7170_device::device_start()
save_item(NAME(m_regs));
}
//-------------------------------------------------
// device_reset - device-specific reset handling
//-------------------------------------------------
void icm7170_device::device_reset()
{
m_regs[REG_COMMAND] &= ~CMD_REG_RUN;
m_irq_status = 0;
recalc_irqs();
}
//-------------------------------------------------
// device_timer - handles timer events
@ -87,6 +118,16 @@ void icm7170_device::device_timer(emu_timer &timer, device_timer_id id, int para
void icm7170_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
{
if (m_regs[REG_COMMAND] & CMD_REG_RUN)
{
m_regs[REG_CNT_YEAR] = year % 99;
m_regs[REG_CNT_MONTH] = month;
m_regs[REG_CNT_DAY] = day;
m_regs[REG_CNT_DAY_OF_WEEK] = day_of_week;
m_regs[REG_CNT_HOURS] = hour;
m_regs[REG_CNT_MINUTES] = minute;
m_regs[REG_CNT_SECONDS] = second;
}
}
@ -127,6 +168,11 @@ uint8_t icm7170_device::read(offs_t offset)
{
uint8_t data = m_regs[offset & 0x1f];
if ((offset & 0x1f) == REG_INT_STATUS_AND_MASK)
{
data = m_irq_status;
}
LOG("ICM7170 Register %d Read %02x\n", offset, data);
return data;
@ -136,6 +182,12 @@ void icm7170_device::write(offs_t offset, uint8_t data)
{
switch (offset & 0x1f)
{
case REG_INT_STATUS_AND_MASK:
m_irq_mask = data;
LOG("ICM7170 IRQ Mask Write %02x\n", data);
recalc_irqs();
break;
default:
m_regs[offset & 0x1f] = data;
LOG("ICM7170 Register %d Write %02x\n", offset & 0x1f, data);

View File

@ -60,6 +60,7 @@ public:
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_rtc_interface overrides
@ -76,6 +77,7 @@ private:
devcb_write_line m_out_irq_cb;
uint8_t m_regs[0x20];
uint8_t m_irq_mask, m_irq_status;
emu_timer *m_timer;
};

View File

@ -77,7 +77,7 @@ public:
m_gfxsubcpu(*this, "gfxsubcpu"),
m_datacpu(*this, "datacpu"),
m_iocpu(*this, "iocpu"),
m_mainram(*this, "extram"),
m_mainram(*this, "mainram"),
m_extram(*this, "extram"),
m_vram(*this, "vram"),
m_rtc(*this, "rtc")
@ -141,7 +141,7 @@ void wxstar4k_state::cpubd_main(address_map &map)
// FDF000 - cause IRQ 6 on graphics card
// FDF004 - cause IRQ 6 on graphics card 2 (not used)
// FDF008 - reset watchdog
// FDFFC0-FDFFE2 - ICM7170 RTC, registers every 2 bytes
map(0xfdffc0, 0xfdffe3).rw(m_rtc, FUNC(icm7170_device::read), FUNC(icm7170_device::write)).umask16(0x00ff);
map(0xfe0000, 0xffffff).rom().region("maincpu", 0);
}