st2204: Emulate prescaler and Timer 0 (nw)

gameking.cpp: Start faking LCD frame interrupt to allow gamekin3 to enter its own native games
This commit is contained in:
AJR 2019-11-07 16:53:09 -05:00
parent 7203696d53
commit dc620097c5
2 changed files with 71 additions and 0 deletions

View File

@ -49,6 +49,9 @@ st2xxx_device::st2xxx_device(const machine_config &mconfig, device_type type, co
, m_btsr(0)
, m_bt_mask(0)
, m_bt_ireq(0)
, m_pres_base(0)
, m_pres_started(attotime::zero)
, m_prs(0)
, m_sys(0)
, m_misc(0)
, m_ireq(0)
@ -149,6 +152,9 @@ void st2xxx_device::save_common_registers()
save_item(NAME(m_bten));
save_item(NAME(m_btsr));
}
save_item(NAME(m_pres_base));
save_item(NAME(m_pres_started));
save_item(NAME(m_prs));
save_item(NAME(m_sys));
if (st2xxx_misc_mask() != 0)
save_item(NAME(m_misc));
@ -197,6 +203,9 @@ void st2xxx_device::device_reset()
bten_w(0);
m_btsr = 0;
// reset prescaler
prs_w(0x80);
// reset miscellaneous registers
m_sys = 0;
m_misc = st2xxx_wdten_on_reset() ? 0x0c : 0;
@ -374,6 +383,56 @@ void st2xxx_device::btclr_all_w(u8 data)
m_btsr = 0;
}
u32 st2xxx_device::tclk_pres_div(u8 mode) const
{
assert(mode < 8);
if (mode == 0)
return 0x10000;
else if (mode < 4)
return 0x20000 >> (mode * 2);
else if (mode == 4)
return 0x100;
else
return 0x8000 >> (mode * 2);
}
u8 st2xxx_device::prs_r()
{
return (m_pres_base + ((m_prs & 0x60) == 0x40 ? attotime_to_cycles(machine().time() - m_pres_started) : 0)) & 0xff;
}
void st2xxx_device::prs_w(u8 data)
{
data &= st2xxx_prs_mask();
// Bit 7 produces prescaler reset pulse
if (BIT(data, 7))
{
st2xxx_tclk_stop();
m_pres_base = 0;
if ((m_prs & 0x60) == 0x40)
{
m_pres_started = machine().time();
st2xxx_tclk_start();
}
data &= 0x7f;
}
// Bit 6 enables prescaler; bit 5 selects clock source
if ((data & 0x60) == 0x40 && (m_prs & 0x60) != 0x40)
{
m_pres_started = machine().time();
st2xxx_tclk_start();
}
else if ((data & 0x60) == 0x40 && (m_prs & 0x60) != 0x40)
{
st2xxx_tclk_stop();
m_pres_base += attotime_to_cycles(machine().time() - m_pres_started);
}
m_prs = data;
}
u8 st2xxx_device::sys_r()
{
return m_sys | 0x01;

View File

@ -35,6 +35,7 @@ public:
ST_PSGC,
ST_BTEN,
ST_BTSR,
ST_PRS,
ST_SYS,
ST_IRR,
ST_PRR,
@ -83,6 +84,9 @@ protected:
virtual u16 st2xxx_ireq_mask() const = 0;
virtual const char *st2xxx_irq_name(int i) const = 0;
virtual unsigned st2xxx_bt_divider(int n) const = 0;
virtual u8 st2xxx_prs_mask() const = 0;
virtual void st2xxx_tclk_start() { }
virtual void st2xxx_tclk_stop() { }
virtual u8 st2xxx_sys_mask() const = 0;
virtual u8 st2xxx_misc_mask() const = 0;
virtual bool st2xxx_wdten_on_reset() const { return false; }
@ -163,6 +167,10 @@ protected:
void btclr_w(u8 data);
void btclr_all_w(u8 data);
u32 tclk_pres_div(u8 mode) const;
u8 prs_r();
void prs_w(u8 data);
u8 ireql_r();
void ireql_w(u8 data);
u8 ireqh_r();
@ -218,6 +226,10 @@ protected:
u8 m_bt_mask;
u16 m_bt_ireq;
u16 m_pres_base;
attotime m_pres_started;
u8 m_prs;
u8 m_sys;
u8 m_misc;