mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
st2204: Add rudimentary DMA control (nw)
This commit is contained in:
parent
7ed066e2dd
commit
d9dcb8831b
@ -41,6 +41,9 @@ st2204_device::st2204_device(const machine_config &mconfig, const char *tag, dev
|
|||||||
, m_bten(0)
|
, m_bten(0)
|
||||||
, m_btsr(0)
|
, m_btsr(0)
|
||||||
, m_base_timer{0}
|
, m_base_timer{0}
|
||||||
|
, m_dms(0)
|
||||||
|
, m_dmd(0)
|
||||||
|
, m_dcnth(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +64,7 @@ void st2204_device::device_start()
|
|||||||
intf->irr = 0;
|
intf->irr = 0;
|
||||||
intf->prr = 0;
|
intf->prr = 0;
|
||||||
intf->drr = 0;
|
intf->drr = 0;
|
||||||
|
intf->dmr = 0;
|
||||||
intf->irq_service = false;
|
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[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(st2204_device::bt_interrupt<0>), this));
|
||||||
@ -75,6 +79,9 @@ void st2204_device::device_start()
|
|||||||
save_item(NAME(m_pfun));
|
save_item(NAME(m_pfun));
|
||||||
save_item(NAME(m_bten));
|
save_item(NAME(m_bten));
|
||||||
save_item(NAME(m_btsr));
|
save_item(NAME(m_btsr));
|
||||||
|
save_item(NAME(m_dms));
|
||||||
|
save_item(NAME(m_dmd));
|
||||||
|
save_item(NAME(m_dcnth));
|
||||||
save_item(NAME(m_sys));
|
save_item(NAME(m_sys));
|
||||||
save_item(NAME(m_pmcr));
|
save_item(NAME(m_pmcr));
|
||||||
save_item(NAME(m_ireq));
|
save_item(NAME(m_ireq));
|
||||||
@ -116,6 +123,9 @@ void st2204_device::device_start()
|
|||||||
state_add(ST_LVPW, "LVPW", m_lvpw);
|
state_add(ST_LVPW, "LVPW", m_lvpw);
|
||||||
state_add(ST_LXMAX, "LXMAX", m_lxmax);
|
state_add(ST_LXMAX, "LXMAX", m_lxmax);
|
||||||
state_add(ST_LYMAX, "LYMAX", m_lymax);
|
state_add(ST_LYMAX, "LYMAX", m_lymax);
|
||||||
|
state_add(ST_DMS, "DMS", m_dms);
|
||||||
|
state_add(ST_DMR, "DMR", downcast<mi_st2204 &>(*mintf).dmr).mask(0x7ff);
|
||||||
|
state_add(ST_DMD, "DMD", m_dmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void st2204_device::device_reset()
|
void st2204_device::device_reset()
|
||||||
@ -127,6 +137,7 @@ void st2204_device::device_reset()
|
|||||||
m.irr = 0;
|
m.irr = 0;
|
||||||
m.prr = 0;
|
m.prr = 0;
|
||||||
m.drr = 0;
|
m.drr = 0;
|
||||||
|
m.dmr = 0;
|
||||||
|
|
||||||
bten_w(0);
|
bten_w(0);
|
||||||
m_btsr = 0;
|
m_btsr = 0;
|
||||||
@ -180,6 +191,14 @@ u8 st2204_device::mi_st2204::read_arg(u16 adr)
|
|||||||
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : cache->read_byte(adr);
|
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : cache->read_byte(adr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::mi_st2204::read_dma(u16 adr)
|
||||||
|
{
|
||||||
|
if (BIT(adr, 15))
|
||||||
|
return dcache->read_byte(u32(dmr) << 15 | (adr & 0x7fff));
|
||||||
|
else
|
||||||
|
return read(adr);
|
||||||
|
}
|
||||||
|
|
||||||
u8 st2204_device::mi_st2204::read_vector(u16 adr)
|
u8 st2204_device::mi_st2204::read_vector(u16 adr)
|
||||||
{
|
{
|
||||||
return pread(adr);
|
return pread(adr);
|
||||||
@ -299,6 +318,98 @@ void st2204_device::drrh_w(u8 data)
|
|||||||
drr = (data & 0x07) << 16 | (drr & 0x00ff);
|
drr = (data & 0x07) << 16 | (drr & 0x00ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::dmsl_r()
|
||||||
|
{
|
||||||
|
return m_dms & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dmsl_w(u8 data)
|
||||||
|
{
|
||||||
|
m_dms = (m_dms & 0xff00) | data;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::dmsh_r()
|
||||||
|
{
|
||||||
|
return m_dms >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dmsh_w(u8 data)
|
||||||
|
{
|
||||||
|
m_dms = (m_dms & 0x00ff) | u16(data) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::dmdl_r()
|
||||||
|
{
|
||||||
|
return m_dmd & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dmdl_w(u8 data)
|
||||||
|
{
|
||||||
|
m_dmd = (m_dmd & 0xff00) | data;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::dmdh_r()
|
||||||
|
{
|
||||||
|
return m_dmd >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dmdh_w(u8 data)
|
||||||
|
{
|
||||||
|
m_dmd = (m_dmd & 0x00ff) | u16(data) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dcntl_w(u8 data)
|
||||||
|
{
|
||||||
|
u16 count = data | u16(m_dcnth & 0x0f) << 8;
|
||||||
|
|
||||||
|
// FIXME: not instantaneous (obviously), but takes 2 cycles per transfer while CPU is halted
|
||||||
|
mi_st2204 &intf = downcast<mi_st2204 &>(*mintf);
|
||||||
|
while (count != 0xffff)
|
||||||
|
{
|
||||||
|
intf.write(m_dmd, intf.read_dma(m_dms));
|
||||||
|
|
||||||
|
if (m_dms++ == 0xffff)
|
||||||
|
{
|
||||||
|
// DMR bank increments automatically when source is in data memory
|
||||||
|
m_dms = 0x8000;
|
||||||
|
intf.dmr = (intf.dmr + 1) & 0x7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DMAM inhibits destination increment
|
||||||
|
if (!BIT(m_dcnth, 4))
|
||||||
|
m_dmd++;
|
||||||
|
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dcnth_w(u8 data)
|
||||||
|
{
|
||||||
|
m_dcnth = data & 0x1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::dmrl_r()
|
||||||
|
{
|
||||||
|
return downcast<mi_st2204 &>(*mintf).dmr & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dmrl_w(u8 data)
|
||||||
|
{
|
||||||
|
u16 &dmr = downcast<mi_st2204 &>(*mintf).dmr;
|
||||||
|
dmr = data | (dmr & 0x0700);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 st2204_device::dmrh_r()
|
||||||
|
{
|
||||||
|
return downcast<mi_st2204 &>(*mintf).dmr >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void st2204_device::dmrh_w(u8 data)
|
||||||
|
{
|
||||||
|
u16 &dmr = downcast<mi_st2204 &>(*mintf).dmr;
|
||||||
|
dmr = (data & 0x07) << 16 | (dmr & 0x00ff);
|
||||||
|
}
|
||||||
|
|
||||||
u8 st2204_device::pmem_r(offs_t offset)
|
u8 st2204_device::pmem_r(offs_t offset)
|
||||||
{
|
{
|
||||||
return downcast<mi_st2204 &>(*mintf).pread(offset);
|
return downcast<mi_st2204 &>(*mintf).pread(offset);
|
||||||
@ -329,12 +440,21 @@ void st2204_device::int_map(address_map &map)
|
|||||||
map(0x000f, 0x000f).rw(FUNC(st2204_device::pmcr_r), FUNC(st2204_device::pmcr_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(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(0x0021, 0x0021).rw(FUNC(st2204_device::btsr_r), FUNC(st2204_device::btsr_w));
|
||||||
|
// Source/destination registers are not readable on ST2202, but may be readable here (count register isn't)
|
||||||
|
map(0x0028, 0x0028).rw(FUNC(st2204_device::dmsl_r), FUNC(st2204_device::dmsl_w));
|
||||||
|
map(0x0029, 0x0029).rw(FUNC(st2204_device::dmsh_r), FUNC(st2204_device::dmsh_w));
|
||||||
|
map(0x002a, 0x002a).rw(FUNC(st2204_device::dmdl_r), FUNC(st2204_device::dmdl_w));
|
||||||
|
map(0x002b, 0x002b).rw(FUNC(st2204_device::dmdh_r), FUNC(st2204_device::dmdh_w));
|
||||||
|
map(0x002c, 0x002c).w(FUNC(st2204_device::dcntl_w));
|
||||||
|
map(0x002d, 0x002d).w(FUNC(st2204_device::dcnth_w));
|
||||||
map(0x0030, 0x0030).rw(FUNC(st2204_device::sys_r), FUNC(st2204_device::sys_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(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));
|
map(0x0032, 0x0032).rw(FUNC(st2204_device::prrl_r), FUNC(st2204_device::prrl_w));
|
||||||
map(0x0033, 0x0033).rw(FUNC(st2204_device::prrh_r), FUNC(st2204_device::prrh_w));
|
map(0x0033, 0x0033).rw(FUNC(st2204_device::prrh_r), FUNC(st2204_device::prrh_w));
|
||||||
map(0x0034, 0x0034).rw(FUNC(st2204_device::drrl_r), FUNC(st2204_device::drrl_w));
|
map(0x0034, 0x0034).rw(FUNC(st2204_device::drrl_r), FUNC(st2204_device::drrl_w));
|
||||||
map(0x0035, 0x0035).rw(FUNC(st2204_device::drrh_r), FUNC(st2204_device::drrh_w));
|
map(0x0035, 0x0035).rw(FUNC(st2204_device::drrh_r), FUNC(st2204_device::drrh_w));
|
||||||
|
map(0x0036, 0x0036).rw(FUNC(st2204_device::dmrl_r), FUNC(st2204_device::dmrl_w));
|
||||||
|
map(0x0037, 0x0037).rw(FUNC(st2204_device::dmrh_r), FUNC(st2204_device::dmrh_w));
|
||||||
map(0x003c, 0x003c).rw(FUNC(st2204_device::ireql_r), FUNC(st2204_device::ireql_w));
|
map(0x003c, 0x003c).rw(FUNC(st2204_device::ireql_r), FUNC(st2204_device::ireql_w));
|
||||||
map(0x003d, 0x003d).rw(FUNC(st2204_device::ireqh_r), FUNC(st2204_device::ireqh_w));
|
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(0x003e, 0x003e).rw(FUNC(st2204_device::ienal_r), FUNC(st2204_device::ienal_w));
|
||||||
@ -346,7 +466,7 @@ void st2204_device::int_map(address_map &map)
|
|||||||
map(0x0044, 0x0044).rw(FUNC(st2204_device::lymax_r), FUNC(st2204_device::lymax_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(0x004c, 0x004c).rw(FUNC(st2204_device::pl_r), FUNC(st2204_device::pl_w));
|
||||||
map(0x004e, 0x004e).w(FUNC(st2204_device::pcl_w));
|
map(0x004e, 0x004e).w(FUNC(st2204_device::pcl_w));
|
||||||
map(0x0080, 0x287f).ram();
|
map(0x0080, 0x287f).ram(); // 2800-287F possibly not present in earlier versions
|
||||||
map(0x4000, 0x7fff).rw(FUNC(st2204_device::pmem_r), FUNC(st2204_device::pmem_w));
|
map(0x4000, 0x7fff).rw(FUNC(st2204_device::pmem_r), FUNC(st2204_device::pmem_w));
|
||||||
map(0x8000, 0xffff).rw(FUNC(st2204_device::dmem_r), FUNC(st2204_device::dmem_w));
|
map(0x8000, 0xffff).rw(FUNC(st2204_device::dmem_r), FUNC(st2204_device::dmem_w));
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,10 @@ class st2204_device : public st2xxx_device
|
|||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
ST_BTEN = ST_LYMAX + 1,
|
ST_BTEN = ST_LYMAX + 1,
|
||||||
ST_BTSR
|
ST_BTSR,
|
||||||
|
ST_DMS,
|
||||||
|
ST_DMD,
|
||||||
|
ST_DMR
|
||||||
};
|
};
|
||||||
|
|
||||||
st2204_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
st2204_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
@ -33,6 +36,7 @@ private:
|
|||||||
virtual u8 read(u16 adr) override;
|
virtual u8 read(u16 adr) override;
|
||||||
virtual u8 read_sync(u16 adr) override;
|
virtual u8 read_sync(u16 adr) override;
|
||||||
virtual u8 read_arg(u16 adr) override;
|
virtual u8 read_arg(u16 adr) override;
|
||||||
|
u8 read_dma(u16 adr);
|
||||||
virtual u8 read_vector(u16 adr) override;
|
virtual u8 read_vector(u16 adr) override;
|
||||||
virtual void write(u16 adr, u8 val) override;
|
virtual void write(u16 adr, u8 val) override;
|
||||||
|
|
||||||
@ -47,6 +51,7 @@ private:
|
|||||||
u8 irr;
|
u8 irr;
|
||||||
u16 prr;
|
u16 prr;
|
||||||
u16 drr;
|
u16 drr;
|
||||||
|
u16 dmr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N> TIMER_CALLBACK_MEMBER(bt_interrupt);
|
template<int N> TIMER_CALLBACK_MEMBER(bt_interrupt);
|
||||||
@ -69,6 +74,20 @@ private:
|
|||||||
void bten_w(u8 data);
|
void bten_w(u8 data);
|
||||||
u8 btsr_r();
|
u8 btsr_r();
|
||||||
void btsr_w(u8 data);
|
void btsr_w(u8 data);
|
||||||
|
u8 dmsl_r();
|
||||||
|
void dmsl_w(u8 data);
|
||||||
|
u8 dmsh_r();
|
||||||
|
void dmsh_w(u8 data);
|
||||||
|
u8 dmdl_r();
|
||||||
|
void dmdl_w(u8 data);
|
||||||
|
u8 dmdh_r();
|
||||||
|
void dmdh_w(u8 data);
|
||||||
|
void dcntl_w(u8 data);
|
||||||
|
void dcnth_w(u8 data);
|
||||||
|
u8 dmrl_r();
|
||||||
|
void dmrl_w(u8 data);
|
||||||
|
u8 dmrh_r();
|
||||||
|
void dmrh_w(u8 data);
|
||||||
|
|
||||||
u8 pmem_r(offs_t offset);
|
u8 pmem_r(offs_t offset);
|
||||||
void pmem_w(offs_t offset, u8 data);
|
void pmem_w(offs_t offset, u8 data);
|
||||||
@ -80,6 +99,10 @@ private:
|
|||||||
u8 m_bten;
|
u8 m_bten;
|
||||||
u8 m_btsr;
|
u8 m_btsr;
|
||||||
emu_timer *m_base_timer[5];
|
emu_timer *m_base_timer[5];
|
||||||
|
|
||||||
|
u16 m_dms;
|
||||||
|
u16 m_dmd;
|
||||||
|
u8 m_dcnth;
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_DEVICE_TYPE(ST2204, st2204_device)
|
DECLARE_DEVICE_TYPE(ST2204, st2204_device)
|
||||||
|
Loading…
Reference in New Issue
Block a user