summaryrefslogtreecommitdiffstats
path: root/src/devices/cpu/m6502/st2205u.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6502/st2205u.cpp')
-rw-r--r--src/devices/cpu/m6502/st2205u.cpp295
1 files changed, 127 insertions, 168 deletions
diff --git a/src/devices/cpu/m6502/st2205u.cpp b/src/devices/cpu/m6502/st2205u.cpp
index e43b79dc449..c6036fbe21d 100644
--- a/src/devices/cpu/m6502/st2205u.cpp
+++ b/src/devices/cpu/m6502/st2205u.cpp
@@ -39,23 +39,15 @@ st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, d
: st2xxx_device(mconfig, ST2205U, tag, owner, clock,
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)
+ true)
, m_btc(0)
- , m_base_timer{0}
+ , m_tc_12bit{0}
+ , m_t4c(0)
+ , m_tien(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>();
@@ -67,71 +59,64 @@ void st2205u_device::device_start()
intf->drr = 0;
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));
+ init_base_timer(0x0040);
+ init_lcd_timer(0x0080);
+
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_tc_12bit));
+ save_item(NAME(m_t4c));
+ save_item(NAME(m_tien));
save_item(NAME(m_lvctr));
- save_item(NAME(intf->irr_enable));
- save_item(NAME(intf->irr));
- save_item(NAME(intf->prr));
- save_item(NAME(intf->drr));
save_item(NAME(intf->brr));
- save_item(NAME(intf->irq_service));
save_pointer(NAME(intf->ram), 0x8000);
mintf = std::move(intf);
+ save_common_registers();
init();
state_add(ST_IRR, "IRR", downcast<mi_st2205u &>(*mintf).irr).mask(0x87ff);
state_add(ST_PRR, "PRR", downcast<mi_st2205u &>(*mintf).prr).mask(0x87ff);
state_add(ST_DRR, "DRR", downcast<mi_st2205u &>(*mintf).drr).mask(0x8fff);
state_add(ST_BRR, "BRR", downcast<mi_st2205u &>(*mintf).brr).mask(0x9fff);
- state_add<u8>(ST_IREQ, "IREQ", [this]() { return m_ireq; }, [this](u16 data) { m_ireq = data; update_irq_state(); }).mask(m_ireq_mask);
- state_add<u8>(ST_IENA, "IENA", [this]() { return m_iena; }, [this](u16 data) { m_iena = data; update_irq_state(); }).mask(m_ireq_mask);
+ state_add<u16>(ST_IREQ, "IREQ", [this]() { return m_ireq; }, [this](u16 data) { m_ireq = data; update_irq_state(); }).mask(st2xxx_ireq_mask());
+ state_add<u16>(ST_IENA, "IENA", [this]() { return m_iena; }, [this](u16 data) { m_iena = data; update_irq_state(); }).mask(st2xxx_ireq_mask());
for (int i = 0; i < 6; i++)
{
- state_add(ST_PDA + i, string_format("PD%c", 'A' + i).c_str(), m_pdata[i]);
+ state_add(ST_PAOUT + i, string_format("P%cOUT", 'A' + i).c_str(), m_pdata[i]);
state_add(ST_PCA + i, string_format("PC%c", 'A' + i).c_str(), m_pctrl[i]);
if (i == 2 || i == 4)
state_add(ST_PSA + i, string_format("PS%c", 'A' + i).c_str(), m_psel[i]);
if (i == 2 || i == 3)
state_add(ST_PFC + i - 2, string_format("PF%c", 'A' + i).c_str(), m_pfun[i - 2]).mask(i == 2 ? 0xfe : 0xff);
}
- state_add(ST_PDL, "PDL", m_pdata[6]);
+ state_add(ST_PLOUT, "PLOUT", m_pdata[6]);
state_add(ST_PCL, "PCL", m_pctrl[6]);
state_add(ST_PMCR, "PMCR", m_pmcr);
+ state_add(ST_MISC, "MISC", m_misc).mask(st2xxx_misc_mask());
state_add<u8>(ST_SYS, "SYS", [this]() { return m_sys; }, [this](u8 data) { sys_w(data); }).mask(0xfe);
+ state_add<u8>(ST_PRS, "PRS", [this]() { return m_prs; }, [this](u8 data) { prs_w(data); }).mask(0x40);
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_BTSR, "BTREQ", m_btsr);
state_add(ST_BTC, "BTC", m_btc);
+ for (int i = 0; i < 4; i++)
+ state_add(ST_T0C + i, string_format("T%dC", i).c_str(), m_tc_12bit[i]);
+ state_add(ST_T4C, "T4C", m_t4c);
+ state_add(ST_TIEN, "TIEN", m_tien);
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_LPAN, "LPAN", m_lpan).mask(st2xxx_lpan_mask());
+ state_add(ST_LCTR, "LCTR", m_lctr).mask(st2xxx_lctr_mask());
+ state_add(ST_LCKR, "LCKR", m_lckr).mask(st2xxx_lckr_mask());
+ state_add(ST_LFRA, "LFRA", m_lfra).mask(0x3f);
+ state_add(ST_LAC, "LAC", m_lac).mask(0x1f);
+ state_add(ST_LPWM, "LPWM", m_lpwm).mask(st2xxx_lpwm_mask());
+ state_add(ST_BCTR, "BCTR", m_bctr).mask(0xb7);
+ state_add(ST_BRS, "BRS", m_brs);
+ state_add(ST_BDIV, "BDIV", m_bdiv);
state_add(ST_LVCTR, "LVCTR", m_lvctr).mask(0x0f);
}
@@ -139,22 +124,43 @@ void st2205u_device::device_reset()
{
st2xxx_device::device_reset();
- mi_st2205u &m = downcast<mi_st2205u &>(*mintf);
- m.irr_enable = false;
- m.irr = 0;
- m.prr = 0;
- m.drr = 0;
+ downcast<mi_st2205u &>(*mintf).brr = 0;
- bten_w(0);
- m_btreq = 0;
m_btc = 0;
+ std::fill(std::begin(m_tc_12bit), std::end(m_tc_12bit), 0);
+ m_t4c = 0;
+ m_tien = 0;
+
m_lvctr = 0;
}
+const char *st2205u_device::st2xxx_irq_name(int i) const
+{
+ switch (i)
+ {
+ case 0: return "PE0/1/2 edge";
+ case 1: return "Timer 0";
+ case 2: return "Timer 1";
+ case 3: return "Timer 2";
+ case 4: return "Timer 3";
+ case 5: return "PA transition";
+ case 6: return "Base timer";
+ case 7: return "LCD buffer";
+ case 8: return "SPI TX empty";
+ case 9: return "SPI RX ready";
+ case 10: return "UART TX";
+ case 11: return "UART RX";
+ case 12: return "USB";
+ case 14: return "PCM";
+ case 15: return "RTC";
+ default: return "Reserved";
+ }
+}
+
u8 st2205u_device::mi_st2205u::pread(u16 adr)
{
- u16 bank = irq_service ? irr : prr;
+ u16 bank = irq_service && irr_enable ? irr : prr;
if (BIT(bank, 15))
return ram[0x4000 | (adr & 0x3fff)];
else
@@ -163,7 +169,7 @@ u8 st2205u_device::mi_st2205u::pread(u16 adr)
u8 st2205u_device::mi_st2205u::preadc(u16 adr)
{
- u16 bank = irq_service ? irr : prr;
+ u16 bank = irq_service && irr_enable ? irr : prr;
if (BIT(bank, 15))
return ram[0x4000 | (adr & 0x3fff)];
else
@@ -172,7 +178,7 @@ u8 st2205u_device::mi_st2205u::preadc(u16 adr)
void st2205u_device::mi_st2205u::pwrite(u16 adr, u8 val)
{
- u16 bank = irq_service ? irr : prr;
+ u16 bank = irq_service && irr_enable ? irr : prr;
if (BIT(bank, 15))
ram[0x4000 | (adr & 0x3fff)] = val;
else
@@ -252,72 +258,6 @@ void st2205u_device::mi_st2205u::write(u16 adr, u8 val)
program->write_byte(adr, val);
}
-u8 st2205u_device::irrl_r()
-{
- return downcast<mi_st2205u &>(*mintf).irr & 0xff;
-}
-
-void st2205u_device::irrl_w(u8 data)
-{
- u16 &irr = downcast<mi_st2205u &>(*mintf).irr;
- irr = data | (irr & 0x8f00);
-}
-
-u8 st2205u_device::irrh_r()
-{
- return downcast<mi_st2205u &>(*mintf).irr >> 8;
-}
-
-void st2205u_device::irrh_w(u8 data)
-{
- u16 &irr = downcast<mi_st2205u &>(*mintf).irr;
- irr = (data & 0x8f) << 8 | (irr & 0x00ff);
-}
-
-u8 st2205u_device::prrl_r()
-{
- return downcast<mi_st2205u &>(*mintf).prr & 0xff;
-}
-
-void st2205u_device::prrl_w(u8 data)
-{
- u16 &prr = downcast<mi_st2205u &>(*mintf).prr;
- prr = data | (prr & 0x8f00);
-}
-
-u8 st2205u_device::prrh_r()
-{
- return downcast<mi_st2205u &>(*mintf).prr >> 8;
-}
-
-void st2205u_device::prrh_w(u8 data)
-{
- u16 &prr = downcast<mi_st2205u &>(*mintf).prr;
- prr = (data & 0x8f) << 8 | (prr & 0x00ff);
-}
-
-u8 st2205u_device::drrl_r()
-{
- return downcast<mi_st2205u &>(*mintf).drr & 0xff;
-}
-
-void st2205u_device::drrl_w(u8 data)
-{
- u16 &drr = downcast<mi_st2205u &>(*mintf).drr;
- drr = data | (drr & 0x8700);
-}
-
-u8 st2205u_device::drrh_r()
-{
- return downcast<mi_st2205u &>(*mintf).drr >> 8;
-}
-
-void st2205u_device::drrh_w(u8 data)
-{
- u16 &drr = downcast<mi_st2205u &>(*mintf).drr;
- drr = (data & 0x87) << 8 | (drr & 0x00ff);
-}
-
u8 st2205u_device::brrl_r()
{
return downcast<mi_st2205u &>(*mintf).brr & 0xff;
@@ -340,81 +280,84 @@ void st2205u_device::brrh_w(u8 data)
brr = (data & 0x9f) << 8 | (brr & 0x00ff);
}
-u8 st2205u_device::pmcr_r()
+unsigned st2205u_device::st2xxx_bt_divider(int n) const
{
- return m_pmcr;
+ // 2 Hz
+ if (n == 0)
+ return 16384;
+
+ // 32 Hz, 64 Hz, 128 Hz, 256 Hz, 512 Hz
+ if (n <= 5)
+ return 2048 >> n;
+
+ // 2048 Hz
+ if (n == 6)
+ return 16;
+
+ // 8192 Hz / BTC
+ assert(n == 7);
+ return 4 * (m_btc != 0 ? m_btc : 256);
}
-void st2205u_device::pmcr_w(u8 data)
+u8 st2205u_device::btc_r()
{
- m_pmcr = data;
+ return m_btc;
}
-u8 st2205u_device::sys_r()
+void st2205u_device::btc_w(u8 data)
{
- return m_sys;
+ m_btc = data;
}
-void st2205u_device::sys_w(u8 data)
+u8 st2205u_device::tc_12bit_r(offs_t offset)
{
- m_sys = data & 0xfe;
- downcast<mi_st2205u &>(*mintf).irr_enable = BIT(data, 1);
+ return (m_tc_12bit[offset >> 1] >> (BIT(offset, 0) ? 8 : 0)) & 0x00ff;
}
-u8 st2205u_device::bten_r()
+void st2205u_device::tc_12bit_w(offs_t offset, u8 data)
{
- return m_bten;
+ if (BIT(offset, 0))
+ m_tc_12bit[offset >> 1] = (m_tc_12bit[offset >> 1] & 0x00ff) | u16(data) << 8;
+ else
+ m_tc_12bit[offset >> 1] = (m_tc_12bit[offset >> 1] & 0xff00) | data;
}
-void st2205u_device::bten_w(u8 data)
+u8 st2205u_device::t4c_r()
{
- 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);
+ return m_t4c;
+}
- 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);
+void st2205u_device::t4c_w(u8 data)
+{
+ m_t4c = data;
+}
- m_bten = data;
+u8 st2205u_device::tien_r()
+{
+ return m_tien;
}
-u8 st2205u_device::btreq_r()
+void st2205u_device::tien_w(u8 data)
{
- return m_btreq;
+ m_tien = data;
}
-void st2205u_device::btclr_w(u8 data)
+void st2205u_device::st2xxx_tclk_start()
{
- m_btreq &= ~data;
}
-u8 st2205u_device::btc_r()
+void st2205u_device::st2xxx_tclk_stop()
{
- return m_btc;
}
-void st2205u_device::btc_w(u8 data)
+unsigned st2205u_device::st2xxx_lfr_clocks() const
{
- m_btc = data;
+ unsigned lcdcks = ((m_lxmax * 2 + m_lfra * 4) + 5) * (m_lymax ? m_lymax : 256) * ((m_lctr & 0x03) == 0 ? 2 : 4);
+
+ if ((m_lckr & 0x30) == 0x00 || (m_lckr & 0x30) == 0x30)
+ return lcdcks * std::max(((m_lckr & 0x0c) >> 2) * 8, 4);
+ else
+ return lcdcks * std::max((m_lckr & 0x0f) * 2, 1);
}
u8 st2205u_device::lvctr_r()
@@ -475,9 +418,13 @@ 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(0x0020, 0x0027).rw(FUNC(st2205u_device::tc_12bit_r), FUNC(st2205u_device::tc_12bit_w));
+ map(0x0028, 0x0028).rw(FUNC(st2205u_device::tien_r), FUNC(st2205u_device::tien_w));
+ map(0x0029, 0x0029).rw(FUNC(st2205u_device::prs_r), FUNC(st2205u_device::prs_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(0x002b, 0x002b).rw(FUNC(st2205u_device::btsr_r), FUNC(st2205u_device::btclr_w));
map(0x002c, 0x002c).rw(FUNC(st2205u_device::btc_r), FUNC(st2205u_device::btc_w));
+ map(0x002d, 0x002d).rw(FUNC(st2205u_device::t4c_r), FUNC(st2205u_device::t4c_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));
@@ -486,6 +433,7 @@ void st2205u_device::int_map(address_map &map)
map(0x0035, 0x0035).rw(FUNC(st2205u_device::drrh_r), FUNC(st2205u_device::drrh_w));
map(0x0036, 0x0036).rw(FUNC(st2205u_device::brrl_r), FUNC(st2205u_device::brrl_w));
map(0x0037, 0x0037).rw(FUNC(st2205u_device::brrh_r), FUNC(st2205u_device::brrh_w));
+ map(0x0038, 0x0038).rw(FUNC(st2205u_device::misc_r), FUNC(st2205u_device::misc_w));
map(0x0039, 0x0039).rw(FUNC(st2205u_device::sys_r), FUNC(st2205u_device::sys_w));
map(0x003a, 0x003a).rw(FUNC(st2205u_device::pmcr_r), FUNC(st2205u_device::pmcr_w));
map(0x003c, 0x003c).rw(FUNC(st2205u_device::ireql_r), FUNC(st2205u_device::ireql_w));
@@ -497,9 +445,20 @@ void st2205u_device::int_map(address_map &map)
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(0x0045, 0x0045).rw(FUNC(st2205u_device::lpan_r), FUNC(st2205u_device::lpan_w));
+ map(0x0047, 0x0047).rw(FUNC(st2205u_device::lctr_r), FUNC(st2205u_device::lctr_w));
+ map(0x0048, 0x0048).w(FUNC(st2205u_device::lckr_w));
+ map(0x0049, 0x0049).w(FUNC(st2205u_device::lfra_w));
+ map(0x004a, 0x004a).rw(FUNC(st2205u_device::lac_r), FUNC(st2205u_device::lac_w));
+ map(0x004b, 0x004b).rw(FUNC(st2205u_device::lpwm_r), FUNC(st2205u_device::lpwm_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));
+ map(0x005a, 0x005a).rw(FUNC(st2205u_device::dmrl_r), FUNC(st2205u_device::dmrl_w));
+ map(0x005b, 0x005b).rw(FUNC(st2205u_device::dmrh_r), FUNC(st2205u_device::dmrh_w));
+ map(0x0063, 0x0063).rw(FUNC(st2205u_device::bctr_r), FUNC(st2205u_device::bctr_w));
+ map(0x0066, 0x0066).rw(FUNC(st2205u_device::brs_r), FUNC(st2205u_device::brs_w));
+ map(0x0067, 0x0067).rw(FUNC(st2205u_device::bdiv_r), FUNC(st2205u_device::bdiv_w));
map(0x0080, 0x1fff).rw(FUNC(st2205u_device::ram_r), FUNC(st2205u_device::ram_w)); // assumed to be shared with banked RAM
map(0x2000, 0x3fff).rw(FUNC(st2205u_device::bmem_r), FUNC(st2205u_device::bmem_w));
map(0x4000, 0x7fff).rw(FUNC(st2205u_device::pmem_r), FUNC(st2205u_device::pmem_w));