mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
dmac_0266: fixes and a hack
* changed handlers to reflect documented names * removed non-existant interrupt output * corrected number and width of map entries * added a hack to allow NEWS-OS to boot
This commit is contained in:
parent
fdac683d9a
commit
245c0b06b2
@ -12,9 +12,7 @@
|
||||
* - https://github.com/NetBSD/src/blob/trunk/sys/arch/news68k/dev/si.c
|
||||
*
|
||||
* TODO:
|
||||
* - tczero vs interrupt status
|
||||
* - verify if eop output exists
|
||||
* - verify map count/width
|
||||
* - find the real solution to the short transfer issue
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
@ -31,7 +29,6 @@ DEFINE_DEVICE_TYPE(DMAC_0266, dmac_0266_device, "dmac_0266", "Sony 0266 DMA Cont
|
||||
dmac_0266_device::dmac_0266_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, DMAC_0266, tag, owner, clock)
|
||||
, m_bus(*this, finder_base::DUMMY_TAG, -1, 32)
|
||||
, m_int(*this)
|
||||
, m_dma_r(*this)
|
||||
, m_dma_w(*this)
|
||||
{
|
||||
@ -49,8 +46,6 @@ void dmac_0266_device::map(address_map &map)
|
||||
|
||||
void dmac_0266_device::device_start()
|
||||
{
|
||||
m_int.resolve_safe();
|
||||
|
||||
m_dma_r.resolve_safe(0);
|
||||
m_dma_w.resolve_safe();
|
||||
|
||||
@ -61,13 +56,11 @@ void dmac_0266_device::device_start()
|
||||
save_item(NAME(m_offset));
|
||||
save_item(NAME(m_map));
|
||||
|
||||
save_item(NAME(m_int_state));
|
||||
save_item(NAME(m_drq_state));
|
||||
save_item(NAME(m_req_state));
|
||||
|
||||
m_dma_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dmac_0266_device::dma_check), this));
|
||||
|
||||
m_int_state = false;
|
||||
m_drq_state = false;
|
||||
m_req_state = false;
|
||||
}
|
||||
|
||||
void dmac_0266_device::device_reset()
|
||||
@ -90,33 +83,22 @@ void dmac_0266_device::soft_reset()
|
||||
m_dma_check->enable(false);
|
||||
}
|
||||
|
||||
void dmac_0266_device::irq_w(int state)
|
||||
void dmac_0266_device::eop_w(int state)
|
||||
{
|
||||
if (state)
|
||||
m_status |= INTERRUPT;
|
||||
else
|
||||
m_status &= ~INTERRUPT;
|
||||
|
||||
set_int(state);
|
||||
}
|
||||
|
||||
void dmac_0266_device::drq_w(int state)
|
||||
void dmac_0266_device::req_w(int state)
|
||||
{
|
||||
m_drq_state = bool(state);
|
||||
m_req_state = bool(state);
|
||||
|
||||
if (m_drq_state)
|
||||
if (m_req_state)
|
||||
m_dma_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
void dmac_0266_device::set_int(bool int_state)
|
||||
{
|
||||
if (int_state != m_int_state)
|
||||
{
|
||||
m_int_state = int_state;
|
||||
m_int(int_state);
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_0266_device::control_w(u32 data)
|
||||
{
|
||||
LOG("control_w 0x%08x (%s)\n", data, machine().describe_context());
|
||||
@ -144,8 +126,8 @@ void dmac_0266_device::control_w(u32 data)
|
||||
|
||||
void dmac_0266_device::dma_check(void *ptr, s32 param)
|
||||
{
|
||||
// check drq active
|
||||
if (!m_drq_state)
|
||||
// check req active
|
||||
if (!m_req_state)
|
||||
return;
|
||||
|
||||
// check enabled
|
||||
@ -154,7 +136,22 @@ void dmac_0266_device::dma_check(void *ptr, s32 param)
|
||||
|
||||
// check transfer count
|
||||
if (!m_tcount)
|
||||
{
|
||||
/*
|
||||
* HACK: NEWS-OS tries to write a block to disk but sets the transfer
|
||||
* count to less than the block length, causing a hang while the
|
||||
* adapter waits for more data that the DMAC is not ready to supply.
|
||||
* It's not clear how the real hardware works - for now this hack
|
||||
* continues to read and discard data from the device, or write
|
||||
* arbitrary zero bytes to it until it deasserts the request line.
|
||||
*/
|
||||
if (m_control & DIRECTION)
|
||||
m_dma_r();
|
||||
else
|
||||
m_dma_w(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
u32 const address = (m_map[m_tag & 0x7f] << 12) | (m_offset & 0xfff);
|
||||
|
||||
@ -195,7 +192,8 @@ void dmac_0266_device::dma_check(void *ptr, s32 param)
|
||||
if (!m_tcount)
|
||||
{
|
||||
LOG("transfer complete\n");
|
||||
m_control &= ~ENABLE;
|
||||
// HACK: per hack above, don't disable when reaching terminal count
|
||||
//m_control &= ~ENABLE;
|
||||
m_status |= TCZERO;
|
||||
}
|
||||
else
|
||||
|
@ -14,14 +14,13 @@ public:
|
||||
// configuration
|
||||
template <typename T> void set_bus(T &&tag, int spacenum) { m_bus.set_tag(std::forward<T>(tag), spacenum); }
|
||||
|
||||
auto out_int_cb() { return m_int.bind(); }
|
||||
auto dma_r_cb() { return m_dma_r.bind(); }
|
||||
auto dma_w_cb() { return m_dma_w.bind(); }
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
void irq_w(int state);
|
||||
void drq_w(int state);
|
||||
void eop_w(int state);
|
||||
void req_w(int state);
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
@ -34,20 +33,18 @@ protected:
|
||||
u32 tcount_r() { return m_tcount; }
|
||||
|
||||
void control_w(u32 data);
|
||||
void tcount_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tcount); }
|
||||
void tag_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_tag); }
|
||||
void offset_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_offset); }
|
||||
void entry_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_map[m_tag & 0x7f]); }
|
||||
void tcount_w(u32 data) { m_tcount = data; }
|
||||
void tag_w(u32 data) { m_tag = data; }
|
||||
void offset_w(u32 data) { m_offset = data; }
|
||||
void entry_w(u32 data) { m_map[m_tag & 0x7f] = data & 0x7fff; }
|
||||
|
||||
// dma logic
|
||||
void soft_reset();
|
||||
void set_int(bool int_state);
|
||||
void dma_check(void *ptr, s32 param);
|
||||
|
||||
private:
|
||||
required_address_space m_bus;
|
||||
|
||||
devcb_write_line m_int;
|
||||
devcb_read8 m_dma_r;
|
||||
devcb_write8 m_dma_w;
|
||||
|
||||
@ -72,11 +69,10 @@ private:
|
||||
u32 m_tcount;
|
||||
u32 m_tag;
|
||||
u32 m_offset;
|
||||
u32 m_map[128];
|
||||
u32 m_map[129];
|
||||
|
||||
// internal state
|
||||
bool m_int_state;
|
||||
bool m_drq_state;
|
||||
bool m_req_state;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(DMAC_0266, dmac_0266_device)
|
||||
|
Loading…
Reference in New Issue
Block a user