From 513495070bbb647159845d5e32aba5b429bdb1a2 Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 30 Aug 2023 19:02:35 -0400 Subject: epg3231: Add Timers 1 & 2 --- src/devices/cpu/rii/riscii.cpp | 106 ++++++++++++++++++++++++++++++++++------- src/devices/cpu/rii/riscii.h | 8 +++- 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/src/devices/cpu/rii/riscii.cpp b/src/devices/cpu/rii/riscii.cpp index a2364d99641..59e22c9f12d 100644 --- a/src/devices/cpu/rii/riscii.cpp +++ b/src/devices/cpu/rii/riscii.cpp @@ -200,7 +200,9 @@ void riscii_series_device::device_start() set_icountptr(m_icount); - m_timer0 = timer_alloc(FUNC(riscii_series_device::timer0), this); + m_timer[0] = timer_alloc(FUNC(riscii_series_device::timer0), this); + m_timer[1] = timer_alloc(FUNC(riscii_series_device::timer1), this); + m_timer[2] = timer_alloc(FUNC(riscii_series_device::timer2), this); m_speech_timer = timer_alloc(FUNC(riscii_series_device::speech_timer), this); state_add(RII_PC, "PC", [this]() { return m_pc; }, [this](u32 pc) { debug_set_pc(pc); }).mask(m_pcmask); @@ -346,7 +348,9 @@ void riscii_series_device::device_reset() m_tr01con = 0x00; m_tr2con = 0x00; m_sfcr = 0x00; - m_timer0->adjust(attotime::never); + m_timer[0]->adjust(attotime::never); + m_timer[1]->adjust(attotime::never); + m_timer[2]->adjust(attotime::never); // reset synthesizer std::fill_n(&m_env[0], 4, 0x00); @@ -821,11 +825,12 @@ void riscii_series_device::sprh_w(u8 data) void riscii_series_device::timer0_reload() { + // Prescaler values are 1:1, 1:4, 1:16, 1:64 const unsigned prescale = 1 << ((m_tr01con & 0x03) << 1); if (BIT(m_tr01con, 2)) - m_timer0->adjust(cycles_to_attotime((m_trl0 + 1) * prescale * 2)); + m_timer[0]->adjust(cycles_to_attotime((m_trl0 + 1) * prescale * 2)); else - m_timer0->adjust(attotime::from_ticks((m_trl0 + 1) * prescale, 32768)); + m_timer[0]->adjust(attotime::from_ticks((m_trl0 + 1) * prescale, 32768)); } TIMER_CALLBACK_MEMBER(riscii_series_device::timer0) @@ -836,12 +841,73 @@ TIMER_CALLBACK_MEMBER(riscii_series_device::timer0) u16 riscii_series_device::timer0_count() const { - if (!m_timer0->enabled()) + if (!m_timer[0]->enabled()) return 0; - else if (BIT(m_tr01con, 2)) - return m_trl0 - m_timer0->remaining().as_ticks(32768); else - return m_trl0 - attotime_to_cycles(m_timer0->remaining()) / 2; + { + // Timer 0 counts up + const unsigned prescale = 1 << ((m_tr01con & 0x03) << 1); + if (BIT(m_tr01con, 2)) + return m_trl0 - attotime_to_cycles(m_timer[0]->remaining()) / 2 / prescale; + else + return m_trl0 - m_timer[0]->remaining().as_ticks(32768) / prescale; + } +} + +void riscii_series_device::timer1_reload() +{ + // Prescaler values are 1:4, 1:16, 1:64, 1:256 + const unsigned prescale = 1 << (((m_tr01con & 0x30) >> 3) + 2); + m_timer[1]->adjust(attotime::from_ticks((m_trl1 + 1) * prescale, 32768)); +} + +TIMER_CALLBACK_MEMBER(riscii_series_device::timer1) +{ + m_intsta |= 0x02; + timer1_reload(); +} + +u8 riscii_series_device::timer1_count() const +{ + if (!m_timer[1]->enabled()) + return 0; + else + { + // Timer 1 counts down + const unsigned prescale = 1 << (((m_tr01con & 0x30) >> 3) + 2); + return m_timer[1]->remaining().as_ticks(32768) / prescale; + } +} + +void riscii_series_device::timer2_reload() +{ + // Prescaler values are 1:1, 1:2, 1:4, 1:8 + const unsigned prescale = 1 << (m_tr2con & 0x03); + if (BIT(m_tr2con, 2)) + m_timer[2]->adjust(cycles_to_attotime((m_trl2 + 1) * prescale * 2)); + else + m_timer[2]->adjust(attotime::from_ticks((m_trl2 + 1) * prescale, 32768)); +} + +TIMER_CALLBACK_MEMBER(riscii_series_device::timer2) +{ + m_intsta |= 0x04; + timer2_reload(); +} + +u8 riscii_series_device::timer2_count() const +{ + if (!m_timer[2]->enabled()) + return 0; + else + { + // Timer 2 counts down + const unsigned prescale = 1 << (m_tr2con & 0x03); + if (BIT(m_tr2con, 2)) + return attotime_to_cycles(m_timer[2]->remaining()) / 2 / prescale; + else + return m_timer[2]->remaining().as_ticks(32768) / prescale; + } } u8 riscii_series_device::trl0l_r() @@ -891,7 +957,11 @@ u8 riscii_series_device::tr01con_r() void riscii_series_device::tr01con_w(u8 data) { - m_tr01con = data; + u8 old_tr01con = std::exchange(m_tr01con, data); + if (BIT(data, 6) && !BIT(old_tr01con, 6)) + timer1_reload(); + else if (!BIT(data, 6) && BIT(old_tr01con, 6)) + m_timer[1]->adjust(attotime::never); } u8 riscii_series_device::tr2con_r() @@ -901,12 +971,16 @@ u8 riscii_series_device::tr2con_r() void riscii_series_device::tr2con_w(u8 data) { - // TODO: capture mode, event counter mode - if ((data & 0x30) == 0x10 && (m_tr2con & 0x30) == 0) + // TODO: Timer 0 capture mode, event counter mode + u8 old_tr2con = std::exchange(m_tr2con, data); + if ((data & 0x30) == 0x10 && (old_tr2con & 0x30) == 0) timer0_reload(); - else if ((data & 0x30) == 0x10 && (m_tr2con & 0x30) == 0) - m_timer0->adjust(attotime::never); - m_tr2con = data; + else if ((data & 0x30) == 0x10 && (old_tr2con & 0x30) == 0) + m_timer[0]->adjust(attotime::never); + if (BIT(data, 3) && !BIT(old_tr2con, 3)) + timer2_reload(); + else if (!BIT(data, 3) && BIT(old_tr2con, 3)) + m_timer[2]->adjust(attotime::never); } u8 riscii_series_device::trlir_r() @@ -931,12 +1005,12 @@ u8 riscii_series_device::t0ch_r() u8 riscii_series_device::tr1c_r() { - return 0xff; + return timer1_count(); } u8 riscii_series_device::tr2c_r() { - return 0xff; + return timer2_count(); } u8 riscii_series_device::sfcr_r() diff --git a/src/devices/cpu/rii/riscii.h b/src/devices/cpu/rii/riscii.h index 496281d260f..5dedcf53af5 100644 --- a/src/devices/cpu/rii/riscii.h +++ b/src/devices/cpu/rii/riscii.h @@ -187,6 +187,12 @@ protected: void timer0_reload(); TIMER_CALLBACK_MEMBER(timer0); u16 timer0_count() const; + void timer1_reload(); + TIMER_CALLBACK_MEMBER(timer1); + u8 timer1_count() const; + void timer2_reload(); + TIMER_CALLBACK_MEMBER(timer2); + u8 timer2_count() const; u8 trl0l_r(); void trl0l_w(u8 data); u8 trl0h_r(); @@ -361,7 +367,7 @@ private: u8 m_tr01con; u8 m_tr2con; u8 m_trlir; - emu_timer *m_timer0; + emu_timer *m_timer[3]; // synthesizer state u8 m_sfcr; -- cgit v1.2.3