summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6502/st2xxx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6502/st2xxx.cpp')
-rw-r--r--src/devices/cpu/m6502/st2xxx.cpp44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/devices/cpu/m6502/st2xxx.cpp b/src/devices/cpu/m6502/st2xxx.cpp
index 62fd8871f85..47d6b6778b4 100644
--- a/src/devices/cpu/m6502/st2xxx.cpp
+++ b/src/devices/cpu/m6502/st2xxx.cpp
@@ -30,7 +30,8 @@
#define LOG_IRQ (1 << 1U)
#define LOG_BT (1 << 2U)
-//#define VERBOSE (LOG_IRQ | LOG_BT)
+#define LOG_LCDC (1 << 3U)
+//#define VERBOSE (LOG_IRQ | LOG_BT | LOG_LCDC)
#include "logmacro.h"
st2xxx_device::st2xxx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map, int data_bits, bool has_banked_ram)
@@ -66,6 +67,8 @@ st2xxx_device::st2xxx_device(const machine_config &mconfig, device_type type, co
, m_lfra(0)
, m_lac(0)
, m_lpwm(0)
+ , m_lcd_ireq(0)
+ , m_lcd_timer(nullptr)
, m_bctr(0)
{
program_config.m_internal_map = std::move(internal_map);
@@ -123,6 +126,20 @@ void st2xxx_device::init_base_timer(u16 ireq)
assert(m_bt_ireq != 0);
}
+TIMER_CALLBACK_MEMBER(st2xxx_device::lcd_interrupt)
+{
+ m_ireq |= m_lcd_ireq;
+ update_irq_state();
+}
+
+void st2xxx_device::init_lcd_timer(u16 ireq)
+{
+ m_lcd_ireq = ireq;
+ assert(m_lcd_ireq != 0);
+
+ m_lcd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2xxx_device::lcd_interrupt), this));
+}
+
void st2xxx_device::save_common_registers()
{
mi_st2xxx *intf = downcast<mi_st2xxx *>(mintf.get());
@@ -228,6 +245,7 @@ void st2xxx_device::device_reset()
m_lfra = 0;
m_lac = 0;
m_lpwm = 0;
+ m_lcd_timer->adjust(attotime::never);
// reset UART and BRG
m_bctr = 0;
@@ -676,6 +694,7 @@ u8 st2xxx_device::lxmax_r()
void st2xxx_device::lxmax_w(u8 data)
{
m_lxmax = data;
+ lfr_recalculate_period();
}
u8 st2xxx_device::lymax_r()
@@ -686,6 +705,7 @@ u8 st2xxx_device::lymax_r()
void st2xxx_device::lymax_w(u8 data)
{
m_lymax = data;
+ lfr_recalculate_period();
}
u8 st2xxx_device::lpan_r()
@@ -705,17 +725,37 @@ u8 st2xxx_device::lctr_r()
void st2xxx_device::lctr_w(u8 data)
{
- m_lctr = data & st2xxx_lctr_mask();
+ data &= st2xxx_lctr_mask();
+ u8 old_lctr = std::exchange(m_lctr, data);
+
+ if ((old_lctr & 0xbf) != (m_lctr & 0xbf))
+ lfr_recalculate_period();
}
void st2xxx_device::lckr_w(u8 data)
{
m_lckr = data & st2xxx_lckr_mask();
+ lfr_recalculate_period();
}
void st2xxx_device::lfra_w(u8 data)
{
m_lfra = data & 0x3f;
+ lfr_recalculate_period();
+}
+
+void st2xxx_device::lfr_recalculate_period()
+{
+ if (!BIT(m_lctr, 7))
+ {
+ unsigned clocks = st2xxx_lfr_clocks();
+ assert(clocks != 0);
+ attotime period = cycles_to_attotime(clocks);
+ LOGMASKED(LOG_LCDC, "LCD frame rate = %f Hz (PC = $%04X)\n", period.as_hz(), PPC);
+ m_lcd_timer->adjust(period, 0, period);
+ }
+ else
+ m_lcd_timer->adjust(attotime::never);
}
u8 st2xxx_device::lac_r()