diff options
author | AJR <ajrhacker@users.noreply.github.com> | 2019-11-03 16:31:47 -0500 |
---|---|---|
committer | AJR <ajrhacker@users.noreply.github.com> | 2019-11-03 16:33:47 -0500 |
commit | ed087f295e4132c9686369a5b03fe3d5486d1b95 (patch) | |
tree | b640fff8f7e0f06cd7dfd1172de216d209110bff | |
parent | 2435f3cfed5317153cce3a94ccf7507ab2898bbe (diff) |
st2xxx: Add base timers and some of the LCD registers; fix IRR enable (nw)
-rw-r--r-- | src/devices/cpu/m6502/st2204.cpp | 75 | ||||
-rw-r--r-- | src/devices/cpu/m6502/st2204.h | 15 | ||||
-rw-r--r-- | src/devices/cpu/m6502/st2205u.cpp | 105 | ||||
-rw-r--r-- | src/devices/cpu/m6502/st2205u.h | 17 | ||||
-rw-r--r-- | src/devices/cpu/m6502/st2xxx.cpp | 41 | ||||
-rw-r--r-- | src/devices/cpu/m6502/st2xxx.h | 18 | ||||
-rw-r--r-- | src/mame/drivers/inteladv.cpp | 5 |
7 files changed, 271 insertions, 5 deletions
diff --git a/src/devices/cpu/m6502/st2204.cpp b/src/devices/cpu/m6502/st2204.cpp index 7f70fd70b89..cad69651872 100644 --- a/src/devices/cpu/m6502/st2204.cpp +++ b/src/devices/cpu/m6502/st2204.cpp @@ -35,9 +35,20 @@ st2204_device::st2204_device(const machine_config &mconfig, const char *tag, dev address_map_constructor(FUNC(st2204_device::int_map), this), 26, // logical; only 23 address lines are brought out 0x0f7f) + , m_bten(0) + , m_btsr(0) + , m_base_timer{0} { } +template<int N> +TIMER_CALLBACK_MEMBER(st2204_device::bt_interrupt) +{ + m_btsr |= 1 << N; + m_ireq |= 0x020; + update_irq_state(); +} + void st2204_device::device_start() { std::unique_ptr<mi_st2204> intf = std::make_unique<mi_st2204>(); @@ -49,14 +60,26 @@ void st2204_device::device_start() intf->drr = 0; intf->irq_service = false; + m_base_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2204_device::bt_interrupt<0>), this)); + m_base_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2204_device::bt_interrupt<1>), this)); + m_base_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2204_device::bt_interrupt<2>), this)); + m_base_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2204_device::bt_interrupt<3>), this)); + m_base_timer[4] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2204_device::bt_interrupt<4>), this)); + save_item(NAME(m_pdata)); save_item(NAME(m_pctrl)); save_item(NAME(m_psel)); save_item(NAME(m_pfun)); + save_item(NAME(m_bten)); + save_item(NAME(m_btsr)); save_item(NAME(m_sys)); save_item(NAME(m_pmcr)); save_item(NAME(m_ireq)); save_item(NAME(m_iena)); + save_item(NAME(m_lssa)); + save_item(NAME(m_lvpw)); + save_item(NAME(m_lxmax)); + save_item(NAME(m_lymax)); save_item(NAME(intf->irr_enable)); save_item(NAME(intf->irr)); save_item(NAME(intf->prr)); @@ -83,7 +106,13 @@ void st2204_device::device_start() state_add(ST_PDL, "PDL", m_pdata[6]); state_add(ST_PCL, "PCL", m_pctrl[6]); state_add(ST_PMCR, "PMCR", m_pmcr); + state_add<u8>(ST_BTEN, "BTEN", [this]() { return m_bten; }, [this](u8 data) { bten_w(data); }).mask(0x1f); + state_add(ST_BTSR, "BTSR", m_btsr).mask(0x1f); state_add<u8>(ST_SYS, "SYS", [this]() { return m_sys; }, [this](u8 data) { sys_w(data); }); + state_add(ST_LSSA, "LSSA", m_lssa); + state_add(ST_LVPW, "LVPW", m_lvpw); + state_add(ST_LXMAX, "LXMAX", m_lxmax); + state_add(ST_LYMAX, "LYMAX", m_lymax); } void st2204_device::device_reset() @@ -95,6 +124,9 @@ void st2204_device::device_reset() m.irr = 0; m.prr = 0; m.drr = 0; + + bten_w(0); + m_btsr = 0; } u8 st2204_device::mi_st2204::pread(u16 adr) @@ -165,6 +197,40 @@ void st2204_device::pmcr_w(u8 data) m_pmcr = data; } +u8 st2204_device::bten_r() +{ + return m_bten; +} + +void st2204_device::bten_w(u8 data) +{ + for (int n = 0; n < 5; n++) + { + if (BIT(data, n) && !BIT(m_bten, n)) + { + // 2 Hz, 8 Hz, 64 Hz, 256 Hz, 2048 Hz + attotime period = attotime::from_hz(2 << ((n & 1) * 2 + (n >> 1) * 5)); + m_base_timer[n]->adjust(period, 0, period); + } + else if (!BIT(data, n) && BIT(m_bten, n)) + m_base_timer[n]->adjust(attotime::never); + } + + m_bten = data & 0x1f; +} + +u8 st2204_device::btsr_r() +{ + return m_btsr; +} + +void st2204_device::btsr_w(u8 data) +{ + // Only bit 7 has any effect + if (BIT(data, 7)) + m_btsr = 0; +} + u8 st2204_device::sys_r() { return m_sys | 0x01; @@ -173,7 +239,7 @@ u8 st2204_device::sys_r() void st2204_device::sys_w(u8 data) { m_sys = data; - downcast<mi_st2204 &>(*mintf).irr_enable = BIT(data, 2); + downcast<mi_st2204 &>(*mintf).irr_enable = BIT(data, 1); } u8 st2204_device::irr_r() @@ -258,6 +324,8 @@ void st2204_device::int_map(address_map &map) map(0x000d, 0x000d).rw(FUNC(st2204_device::pfc_r), FUNC(st2204_device::pfc_w)); map(0x000e, 0x000e).rw(FUNC(st2204_device::pfd_r), FUNC(st2204_device::pfd_w)); map(0x000f, 0x000f).rw(FUNC(st2204_device::pmcr_r), FUNC(st2204_device::pmcr_w)); + map(0x0020, 0x0020).rw(FUNC(st2204_device::bten_r), FUNC(st2204_device::bten_w)); + map(0x0021, 0x0021).rw(FUNC(st2204_device::btsr_r), FUNC(st2204_device::btsr_w)); map(0x0030, 0x0030).rw(FUNC(st2204_device::sys_r), FUNC(st2204_device::sys_w)); map(0x0031, 0x0031).rw(FUNC(st2204_device::irr_r), FUNC(st2204_device::irr_w)); map(0x0032, 0x0032).rw(FUNC(st2204_device::prrl_r), FUNC(st2204_device::prrl_w)); @@ -268,6 +336,11 @@ void st2204_device::int_map(address_map &map) map(0x003d, 0x003d).rw(FUNC(st2204_device::ireqh_r), FUNC(st2204_device::ireqh_w)); map(0x003e, 0x003e).rw(FUNC(st2204_device::ienal_r), FUNC(st2204_device::ienal_w)); map(0x003f, 0x003f).rw(FUNC(st2204_device::ienah_r), FUNC(st2204_device::ienah_w)); + map(0x0040, 0x0040).w(FUNC(st2204_device::lssal_w)); + map(0x0041, 0x0041).w(FUNC(st2204_device::lssah_w)); + map(0x0042, 0x0042).w(FUNC(st2204_device::lvpw_w)); + map(0x0043, 0x0043).rw(FUNC(st2204_device::lxmax_r), FUNC(st2204_device::lxmax_w)); + map(0x0044, 0x0044).rw(FUNC(st2204_device::lymax_r), FUNC(st2204_device::lymax_w)); map(0x004c, 0x004c).rw(FUNC(st2204_device::pl_r), FUNC(st2204_device::pl_w)); map(0x004e, 0x004e).w(FUNC(st2204_device::pcl_w)); map(0x0080, 0x27ff).ram(); // 10K internal SRAM; extent of mapping guessed diff --git a/src/devices/cpu/m6502/st2204.h b/src/devices/cpu/m6502/st2204.h index 4ec61636d65..d88825a8b7f 100644 --- a/src/devices/cpu/m6502/st2204.h +++ b/src/devices/cpu/m6502/st2204.h @@ -16,6 +16,11 @@ class st2204_device : public st2xxx_device { public: + enum { + ST_BTEN = ST_LYMAX + 1, + ST_BTSR + }; + st2204_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: @@ -44,6 +49,8 @@ private: u16 drr; }; + template<int N> TIMER_CALLBACK_MEMBER(bt_interrupt); + u8 sys_r(); void sys_w(u8 data); u8 irr_r(); @@ -58,6 +65,10 @@ private: void drrh_w(u8 data); u8 pmcr_r(); void pmcr_w(u8 data); + u8 bten_r(); + void bten_w(u8 data); + u8 btsr_r(); + void btsr_w(u8 data); u8 pmem_r(offs_t offset); void pmem_w(offs_t offset, u8 data); @@ -65,6 +76,10 @@ private: void dmem_w(offs_t offset, u8 data); void int_map(address_map &map); + + u8 m_bten; + u8 m_btsr; + emu_timer *m_base_timer[5]; }; DECLARE_DEVICE_TYPE(ST2204, st2204_device) diff --git a/src/devices/cpu/m6502/st2205u.cpp b/src/devices/cpu/m6502/st2205u.cpp index 7084eb632c4..2dff95733f0 100644 --- a/src/devices/cpu/m6502/st2205u.cpp +++ b/src/devices/cpu/m6502/st2205u.cpp @@ -36,10 +36,22 @@ st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, d address_map_constructor(FUNC(st2205u_device::int_map), this), 26, // logical; only 23 address lines are brought out 0xdfff) + , m_bten(0) + , m_btreq(0) + , m_btc(0) + , m_base_timer{0} , m_lvctr(0) { } +template<int N> +TIMER_CALLBACK_MEMBER(st2205u_device::bt_interrupt) +{ + m_btreq |= 1 << N; + m_ireq |= 0x0020; + update_irq_state(); +} + void st2205u_device::device_start() { std::unique_ptr<mi_st2205u> intf = std::make_unique<mi_st2205u>(); @@ -52,16 +64,32 @@ void st2205u_device::device_start() intf->brr = 0; intf->irq_service = false; + m_base_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<0>), this)); + m_base_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<1>), this)); + m_base_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<2>), this)); + m_base_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<3>), this)); + m_base_timer[4] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<4>), this)); + m_base_timer[5] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<5>), this)); + m_base_timer[6] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<6>), this)); + m_base_timer[7] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2205u_device::bt_interrupt<7>), this)); + intf->ram = make_unique_clear<u8[]>(0x8000); save_item(NAME(m_pdata)); save_item(NAME(m_pctrl)); save_item(NAME(m_psel)); save_item(NAME(m_pfun)); + save_item(NAME(m_bten)); + save_item(NAME(m_btreq)); + save_item(NAME(m_btc)); save_item(NAME(m_sys)); save_item(NAME(m_pmcr)); save_item(NAME(m_ireq)); save_item(NAME(m_iena)); + save_item(NAME(m_lssa)); + save_item(NAME(m_lvpw)); + save_item(NAME(m_lxmax)); + save_item(NAME(m_lymax)); save_item(NAME(m_lvctr)); save_item(NAME(intf->irr_enable)); save_item(NAME(intf->irr)); @@ -93,6 +121,13 @@ void st2205u_device::device_start() state_add(ST_PCL, "PCL", m_pctrl[6]); state_add(ST_PMCR, "PMCR", m_pmcr); state_add<u8>(ST_SYS, "SYS", [this]() { return m_sys; }, [this](u8 data) { sys_w(data); }).mask(0xfe); + state_add<u8>(ST_BTEN, "BTEN", [this]() { return m_bten; }, [this](u8 data) { bten_w(data); }); + state_add(ST_BTREQ, "BTREQ", m_btreq); + state_add(ST_BTC, "BTC", m_btc); + state_add(ST_LSSA, "LSSA", m_lssa); + state_add(ST_LVPW, "LVPW", m_lvpw); + state_add(ST_LXMAX, "LXMAX", m_lxmax); + state_add(ST_LYMAX, "LYMAX", m_lymax); state_add(ST_LVCTR, "LVCTR", m_lvctr).mask(0x0f); } @@ -106,6 +141,10 @@ void st2205u_device::device_reset() m.prr = 0; m.drr = 0; + bten_w(0); + m_btreq = 0; + m_btc = 0; + m_lvctr = 0; } @@ -315,7 +354,63 @@ u8 st2205u_device::sys_r() void st2205u_device::sys_w(u8 data) { m_sys = data & 0xfe; - downcast<mi_st2205u &>(*mintf).irr_enable = BIT(data, 2); + downcast<mi_st2205u &>(*mintf).irr_enable = BIT(data, 1); +} + +u8 st2205u_device::bten_r() +{ + return m_bten; +} + +void st2205u_device::bten_w(u8 data) +{ + if (BIT(data, 0) && !BIT(m_bten, 0)) + m_base_timer[0]->adjust(attotime::from_hz(2), 0, attotime::from_hz(2)); + else if (!BIT(data, 0) && BIT(m_bten, 0)) + m_base_timer[0]->adjust(attotime::never); + + for (int n = 1; n <= 5; n++) + { + if (BIT(data, n) && !BIT(m_bten, n)) + m_base_timer[n]->adjust(attotime::from_hz(16 << n), 0, attotime::from_hz(16 << n)); + else if (!BIT(data, n) && BIT(m_bten, n)) + m_base_timer[n]->adjust(attotime::never); + } + + if (BIT(data, 6) && !BIT(m_bten, 6)) + m_base_timer[6]->adjust(attotime::from_hz(2048), 0, attotime::from_hz(2048)); + else if (!BIT(data, 6) && BIT(m_bten, 6)) + m_base_timer[6]->adjust(attotime::never); + + if (BIT(data, 7) && !BIT(m_bten, 7)) + { + attotime period = attotime::from_hz(8192) * (m_btc ? m_btc : 256); + m_base_timer[7]->adjust(period, 0, period); + } + else if (!BIT(data, 7) && BIT(m_bten, 7)) + m_base_timer[7]->adjust(attotime::never); + + m_bten = data; +} + +u8 st2205u_device::btreq_r() +{ + return m_btreq; +} + +void st2205u_device::btclr_w(u8 data) +{ + m_btreq &= ~data; +} + +u8 st2205u_device::btc_r() +{ + return m_btc; +} + +void st2205u_device::btc_w(u8 data) +{ + m_btc = data; } u8 st2205u_device::lvctr_r() @@ -376,6 +471,9 @@ void st2205u_device::int_map(address_map &map) map(0x0008, 0x000d).rw(FUNC(st2205u_device::pctrl_r), FUNC(st2205u_device::pctrl_w)); map(0x000e, 0x000e).rw(FUNC(st2205u_device::pfc_r), FUNC(st2205u_device::pfc_w)); map(0x000f, 0x000f).rw(FUNC(st2205u_device::pfd_r), FUNC(st2205u_device::pfd_w)); + map(0x002a, 0x002a).rw(FUNC(st2205u_device::bten_r), FUNC(st2205u_device::bten_w)); + map(0x002b, 0x002b).rw(FUNC(st2205u_device::btreq_r), FUNC(st2205u_device::btclr_w)); + map(0x002c, 0x002c).rw(FUNC(st2205u_device::btc_r), FUNC(st2205u_device::btc_w)); map(0x0030, 0x0030).rw(FUNC(st2205u_device::irrl_r), FUNC(st2205u_device::irrl_w)); map(0x0031, 0x0031).rw(FUNC(st2205u_device::irrh_r), FUNC(st2205u_device::irrh_w)); map(0x0032, 0x0032).rw(FUNC(st2205u_device::prrl_r), FUNC(st2205u_device::prrl_w)); @@ -390,6 +488,11 @@ void st2205u_device::int_map(address_map &map) map(0x003d, 0x003d).rw(FUNC(st2205u_device::ireqh_r), FUNC(st2205u_device::ireqh_w)); map(0x003e, 0x003e).rw(FUNC(st2205u_device::ienal_r), FUNC(st2205u_device::ienal_w)); map(0x003f, 0x003f).rw(FUNC(st2205u_device::ienah_r), FUNC(st2205u_device::ienah_w)); + map(0x0040, 0x0040).w(FUNC(st2205u_device::lssal_w)); + map(0x0041, 0x0041).w(FUNC(st2205u_device::lssah_w)); + map(0x0042, 0x0042).w(FUNC(st2205u_device::lvpw_w)); + map(0x0043, 0x0043).rw(FUNC(st2205u_device::lxmax_r), FUNC(st2205u_device::lxmax_w)); + map(0x0044, 0x0044).rw(FUNC(st2205u_device::lymax_r), FUNC(st2205u_device::lymax_w)); map(0x004e, 0x004e).rw(FUNC(st2205u_device::pl_r), FUNC(st2205u_device::pl_w)); map(0x004f, 0x004f).rw(FUNC(st2205u_device::pcl_r), FUNC(st2205u_device::pcl_w)); map(0x0057, 0x0057).rw(FUNC(st2205u_device::lvctr_r), FUNC(st2205u_device::lvctr_w)); diff --git a/src/devices/cpu/m6502/st2205u.h b/src/devices/cpu/m6502/st2205u.h index 15ab962b8f3..2a04bc67be7 100644 --- a/src/devices/cpu/m6502/st2205u.h +++ b/src/devices/cpu/m6502/st2205u.h @@ -17,7 +17,10 @@ class st2205u_device : public st2xxx_device { public: enum { - ST_BRR = ST_IENA + 1, + ST_BTEN = ST_LYMAX + 1, + ST_BTREQ, + ST_BTC, + ST_BRR, ST_LVCTR }; @@ -55,6 +58,8 @@ private: std::unique_ptr<u8[]> ram; }; + template<int N> TIMER_CALLBACK_MEMBER(bt_interrupt); + u8 irrl_r(); void irrl_w(u8 data); u8 irrh_r(); @@ -75,6 +80,12 @@ private: void sys_w(u8 data); u8 pmcr_r(); void pmcr_w(u8 data); + u8 bten_r(); + void bten_w(u8 data); + u8 btreq_r(); + void btclr_w(u8 data); + u8 btc_r(); + void btc_w(u8 data); u8 lvctr_r(); void lvctr_w(u8 data); @@ -89,6 +100,10 @@ private: void int_map(address_map &map); + u8 m_bten; + u8 m_btreq; + u8 m_btc; + emu_timer *m_base_timer[8]; u8 m_lvctr; }; diff --git a/src/devices/cpu/m6502/st2xxx.cpp b/src/devices/cpu/m6502/st2xxx.cpp index 711360b355f..8905e9942d4 100644 --- a/src/devices/cpu/m6502/st2xxx.cpp +++ b/src/devices/cpu/m6502/st2xxx.cpp @@ -76,6 +76,12 @@ void st2xxx_device::device_reset() // reset miscellaneous registers m_sys = 0; + + // reset LCDC registers + m_lssa = 0; + m_lvpw = 0; + m_lxmax = 0; + m_lymax = 0; } std::unique_ptr<util::disasm_interface> st2xxx_device::create_disassembler() @@ -249,4 +255,39 @@ void st2xxx_device::ienah_w(u8 data) update_irq_state(); } +void st2xxx_device::lssal_w(u8 data) +{ + m_lssa = (m_lssa & 0xff00) | data; +} + +void st2xxx_device::lssah_w(u8 data) +{ + m_lssa = (m_lssa & 0x00ff) | (u16(data) << 8); +} + +void st2xxx_device::lvpw_w(u8 data) +{ + m_lvpw = data; +} + +u8 st2xxx_device::lxmax_r() +{ + return m_lxmax; +} + +void st2xxx_device::lxmax_w(u8 data) +{ + m_lxmax = data; +} + +u8 st2xxx_device::lymax_r() +{ + return m_lymax; +} + +void st2xxx_device::lymax_w(u8 data) +{ + m_lymax = data; +} + #include "cpu/m6502/st2xxx.hxx" diff --git a/src/devices/cpu/m6502/st2xxx.h b/src/devices/cpu/m6502/st2xxx.h index 2d328be54f0..b39b63d5671 100644 --- a/src/devices/cpu/m6502/st2xxx.h +++ b/src/devices/cpu/m6502/st2xxx.h @@ -37,7 +37,11 @@ public: ST_PRR, ST_DRR, ST_IREQ, - ST_IENA + ST_IENA, + ST_LSSA, + ST_LVPW, + ST_LXMAX, + ST_LYMAX }; auto in_pa_callback() { return m_in_port_cb[0].bind(); } @@ -107,6 +111,14 @@ protected: u8 ienah_r(); void ienah_w(u8 data); + void lssal_w(u8 data); + void lssah_w(u8 data); + void lvpw_w(u8 data); + u8 lxmax_r(); + void lxmax_w(u8 data); + u8 lymax_r(); + void lymax_w(u8 data); + #define O(o) void o ## _full(); void o ## _partial() O(brk_st_imp); @@ -129,6 +141,10 @@ protected: u16 m_iena; const u16 m_ireq_mask; u8 m_sys; + u16 m_lssa; + u8 m_lvpw; + u8 m_lxmax; + u8 m_lymax; }; #endif // MAME_CPU_M6502_ST2XXX_H diff --git a/src/mame/drivers/inteladv.cpp b/src/mame/drivers/inteladv.cpp index a62436236fe..169f69eb304 100644 --- a/src/mame/drivers/inteladv.cpp +++ b/src/mame/drivers/inteladv.cpp @@ -4,6 +4,9 @@ VTech Intelligence Advance E/R Lerncomputer + TODO: dyndesk writes to low memory go to external RAM instead? It also + eventually runs off into nonexistent memory. + ***************************************************************************/ #include "emu.h" @@ -36,7 +39,7 @@ void inteladv_state::inteladv_map(address_map &map) void inteladv_state::dyndesk_map(address_map &map) { - map(0x000000, 0x1fffff).rom().region("maincpu", 0).nopw(); // writes to low memory go to external RAM instead? + map(0x000000, 0x1fffff).rom().region("maincpu", 0).nopw(); } static INPUT_PORTS_START( inteladv ) |