mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
hd63450: add primitive /own and /dtack support
* also improve auto-request mode logic
This commit is contained in:
parent
3c729314b8
commit
ee6cb33f46
@ -18,6 +18,7 @@ hd63450_device::hd63450_device(const machine_config &mconfig, const char *tag, d
|
||||
: device_t(mconfig, HD63450, tag, owner, clock)
|
||||
, m_irq_callback(*this)
|
||||
, m_dma_end(*this)
|
||||
, m_own(*this)
|
||||
, m_dma_read(*this, 0)
|
||||
, m_dma_write(*this)
|
||||
, m_cpu(*this, finder_base::DUMMY_TAG)
|
||||
@ -360,6 +361,9 @@ void hd63450_device::single_transfer(int x)
|
||||
return;
|
||||
|
||||
m_bec = 0;
|
||||
m_dtack = true;
|
||||
|
||||
m_own(0);
|
||||
|
||||
if (m_reg[x].ocr & 0x80) // direction: 1 = device -> memory
|
||||
{
|
||||
@ -440,6 +444,11 @@ void hd63450_device::single_transfer(int x)
|
||||
// LOG("DMA#%i: byte transfer %08lx -> %08lx\n",x,m_reg[x].mar,m_reg[x].dar);
|
||||
}
|
||||
|
||||
m_own(1);
|
||||
|
||||
if (!m_dtack)
|
||||
return;
|
||||
|
||||
if (m_bec == ERR_BUS)
|
||||
{
|
||||
set_error(x, 9); //assume error in mar, TODO: other errors
|
||||
@ -525,14 +534,18 @@ void hd63450_device::drq_w(int channel, int state)
|
||||
bool ostate = m_drq_state[channel];
|
||||
m_drq_state[channel] = state;
|
||||
|
||||
if ((m_reg[channel].ocr & 2) && (state && !ostate))
|
||||
// check for external request modes
|
||||
if (m_reg[channel].ocr & 2)
|
||||
{
|
||||
// in cycle steal mode DRQ is supposed to be edge triggered
|
||||
single_transfer(channel);
|
||||
m_timer[channel]->adjust(m_our_clock[channel], channel, m_our_clock[channel]);
|
||||
if (state && !ostate)
|
||||
{
|
||||
// in cycle steal mode DRQ is supposed to be edge triggered
|
||||
single_transfer(channel);
|
||||
m_timer[channel]->adjust(m_our_clock[channel], channel, m_our_clock[channel]);
|
||||
}
|
||||
else if (!state)
|
||||
m_timer[channel]->adjust(attotime::never);
|
||||
}
|
||||
else if (!state)
|
||||
m_timer[channel]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
void hd63450_device::pcl_w(int channel, int state)
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
|
||||
auto irq_callback() { return m_irq_callback.bind(); }
|
||||
auto dma_end() { return m_dma_end.bind(); }
|
||||
auto own() { return m_own.bind(); }
|
||||
template <int Ch> auto dma_read() { return m_dma_read[Ch].bind(); }
|
||||
template <int Ch> auto dma_write() { return m_dma_write[Ch].bind(); }
|
||||
|
||||
@ -62,6 +63,7 @@ public:
|
||||
ERR_NONE= 7
|
||||
};
|
||||
void bec_w(offs_t offset, uint8_t data) { m_bec = data; }
|
||||
void dtack_w(int state) { m_dtack = !state; }
|
||||
|
||||
void single_transfer(int x);
|
||||
void set_timer(int channel, const attotime &tm);
|
||||
@ -96,6 +98,7 @@ private:
|
||||
|
||||
devcb_write_line m_irq_callback;
|
||||
devcb_write8 m_dma_end;
|
||||
devcb_write_line m_own;
|
||||
devcb_read8::array<4> m_dma_read;
|
||||
devcb_write8::array<4> m_dma_write;
|
||||
|
||||
@ -113,6 +116,8 @@ private:
|
||||
int8_t m_irq_channel;
|
||||
uint8_t m_bec;
|
||||
|
||||
bool m_dtack;
|
||||
|
||||
// tell if a channel is in use
|
||||
bool dma_in_progress(int channel) const { return (m_reg[channel].csr & 0x08) != 0; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user