news_68k: wip (nw)

SCSI irq is probably routed through dmac, which has no eop.
This commit is contained in:
Patrick Mackinlay 2020-05-08 16:08:21 +07:00
parent 773f5d155f
commit 79ee5614b9
3 changed files with 44 additions and 33 deletions

View File

@ -336,6 +336,7 @@ void news_68k_state::common(machine_config &config)
DMAC_0266(config, m_dma, 0); DMAC_0266(config, m_dma, 0);
m_dma->set_bus(m_cpu, 0); m_dma->set_bus(m_cpu, 0);
m_dma->out_int_cb().set(*this, FUNC(news_68k_state::irq_w<SCSI>));
INPUT_MERGER_ANY_HIGH(config, m_irq5); INPUT_MERGER_ANY_HIGH(config, m_irq5);
m_irq5->output_handler().set_inputline(m_cpu, INPUT_LINE_IRQ5); m_irq5->output_handler().set_inputline(m_cpu, INPUT_LINE_IRQ5);
@ -401,10 +402,9 @@ void news_68k_state::common(machine_config &config)
{ {
cxd1180_device &adapter = downcast<cxd1180_device &>(*device); cxd1180_device &adapter = downcast<cxd1180_device &>(*device);
adapter.irq_handler().set(*this, FUNC(news_68k_state::irq_w<SCSI>)); adapter.irq_handler().set(m_dma, FUNC(dmac_0266_device::irq_w));
adapter.drq_handler().set(m_dma, FUNC(dmac_0266_device::drq_w)); adapter.drq_handler().set(m_dma, FUNC(dmac_0266_device::drq_w));
//subdevice<dmac_0266_device>(":dma")->out_eop_cb().set(adapter, FUNC(cxd1180_device::eop_w));
subdevice<dmac_0266_device>(":dma")->dma_r_cb().set(adapter, FUNC(cxd1180_device::dma_r)); subdevice<dmac_0266_device>(":dma")->dma_r_cb().set(adapter, FUNC(cxd1180_device::dma_r));
subdevice<dmac_0266_device>(":dma")->dma_w_cb().set(adapter, FUNC(cxd1180_device::dma_w)); subdevice<dmac_0266_device>(":dma")->dma_w_cb().set(adapter, FUNC(cxd1180_device::dma_w));
}); });

View File

@ -20,7 +20,10 @@
#include "emu.h" #include "emu.h"
#include "dmac_0266.h" #include "dmac_0266.h"
#define VERBOSE 0 #define LOG_GENERAL (1U << 0)
#define LOG_DATA (1U << 1)
//#define VERBOSE (LOG_GENERAL)
#include "logmacro.h" #include "logmacro.h"
DEFINE_DEVICE_TYPE(DMAC_0266, dmac_0266_device, "dmac_0266", "Sony 0266 DMA Controller") DEFINE_DEVICE_TYPE(DMAC_0266, dmac_0266_device, "dmac_0266", "Sony 0266 DMA Controller")
@ -28,7 +31,7 @@ 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) 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) : device_t(mconfig, DMAC_0266, tag, owner, clock)
, m_bus(*this, finder_base::DUMMY_TAG, -1, 32) , m_bus(*this, finder_base::DUMMY_TAG, -1, 32)
, m_eop(*this) , m_int(*this)
, m_dma_r(*this) , m_dma_r(*this)
, m_dma_w(*this) , m_dma_w(*this)
{ {
@ -46,23 +49,24 @@ void dmac_0266_device::map(address_map &map)
void dmac_0266_device::device_start() void dmac_0266_device::device_start()
{ {
m_eop.resolve_safe(); m_int.resolve_safe();
m_dma_r.resolve_safe(0); m_dma_r.resolve_safe(0);
m_dma_w.resolve_safe(); m_dma_w.resolve_safe();
save_item(NAME(m_control));
save_item(NAME(m_status)); save_item(NAME(m_status));
save_item(NAME(m_tcount)); save_item(NAME(m_tcount));
save_item(NAME(m_tag)); save_item(NAME(m_tag));
save_item(NAME(m_offset)); save_item(NAME(m_offset));
save_item(NAME(m_map)); save_item(NAME(m_map));
save_item(NAME(m_eop_state)); save_item(NAME(m_int_state));
save_item(NAME(m_drq_state)); save_item(NAME(m_drq_state));
m_dma_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dmac_0266_device::dma_check), this)); m_dma_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dmac_0266_device::dma_check), this));
m_eop_state = false; m_int_state = false;
m_drq_state = false; m_drq_state = false;
} }
@ -78,15 +82,24 @@ void dmac_0266_device::soft_reset()
{ {
// soft reset does not clear map entries // soft reset does not clear map entries
m_control = 0; m_control = 0;
m_status = 0; m_status &= INTERRUPT;
m_tcount = 0; m_tcount = 0;
m_tag = 0; m_tag = 0;
m_offset = 0; m_offset = 0;
set_eop(false);
m_dma_check->enable(false); m_dma_check->enable(false);
} }
void dmac_0266_device::irq_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::drq_w(int state)
{ {
m_drq_state = bool(state); m_drq_state = bool(state);
@ -95,12 +108,12 @@ void dmac_0266_device::drq_w(int state)
m_dma_check->adjust(attotime::zero); m_dma_check->adjust(attotime::zero);
} }
void dmac_0266_device::set_eop(bool eop_state) void dmac_0266_device::set_int(bool int_state)
{ {
if (eop_state != m_eop_state) if (int_state != m_int_state)
{ {
m_eop_state = eop_state; m_int_state = int_state;
m_eop(eop_state); m_int(int_state);
} }
} }
@ -110,7 +123,7 @@ void dmac_0266_device::control_w(u32 data)
if (!(data & RESET)) if (!(data & RESET))
{ {
if ((data ^ m_status) & ENABLE) if ((data ^ m_control) & ENABLE)
{ {
if (data & ENABLE) if (data & ENABLE)
{ {
@ -124,7 +137,6 @@ void dmac_0266_device::control_w(u32 data)
} }
m_control = data; m_control = data;
m_status = data & (ENABLE | DIRECTION);
} }
else else
soft_reset(); soft_reset();
@ -137,7 +149,7 @@ void dmac_0266_device::dma_check(void *ptr, s32 param)
return; return;
// check enabled // check enabled
if (!(m_status & ENABLE)) if (!(m_control & ENABLE))
return; return;
// check transfer count // check transfer count
@ -146,17 +158,13 @@ void dmac_0266_device::dma_check(void *ptr, s32 param)
u32 const address = (m_map[m_tag & 0x7f] << 12) | (m_offset & 0xfff); u32 const address = (m_map[m_tag & 0x7f] << 12) | (m_offset & 0xfff);
// assert eop during last transfer
if (m_tcount == 1)
set_eop(true);
// perform dma transfer // perform dma transfer
if (m_status & DIRECTION) if (m_control & DIRECTION)
{ {
// device to memory // device to memory
u8 const data = m_dma_r(); u8 const data = m_dma_r();
LOG("dma_r data 0x%02x address 0x%08x\n", data, address); LOGMASKED(LOG_DATA, "dma_r data 0x%02x address 0x%08x\n", data, address);
m_bus->write_byte(address, data); m_bus->write_byte(address, data);
} }
@ -165,7 +173,7 @@ void dmac_0266_device::dma_check(void *ptr, s32 param)
// memory to device // memory to device
u8 const data = m_bus->read_byte(address); u8 const data = m_bus->read_byte(address);
LOG("dma_w data 0x%02x address 0x%08x\n", data, address); LOGMASKED(LOG_DATA, "dma_w data 0x%02x address 0x%08x\n", data, address);
m_dma_w(data); m_dma_w(data);
} }
@ -187,10 +195,8 @@ void dmac_0266_device::dma_check(void *ptr, s32 param)
if (!m_tcount) if (!m_tcount)
{ {
LOG("transfer complete\n"); LOG("transfer complete\n");
m_status &= ~ENABLE; m_control &= ~ENABLE;
m_status |= INTERRUPT | TCZERO; m_status |= TCZERO;
set_eop(false);
} }
else else
m_dma_check->adjust(attotime::zero); m_dma_check->adjust(attotime::zero);

View File

@ -14,12 +14,13 @@ public:
// configuration // configuration
template <typename T> void set_bus(T &&tag, int spacenum) { m_bus.set_tag(std::forward<T>(tag), spacenum); } template <typename T> void set_bus(T &&tag, int spacenum) { m_bus.set_tag(std::forward<T>(tag), spacenum); }
auto out_eop_cb() { return m_eop.bind(); } auto out_int_cb() { return m_int.bind(); }
auto dma_r_cb() { return m_dma_r.bind(); } auto dma_r_cb() { return m_dma_r.bind(); }
auto dma_w_cb() { return m_dma_w.bind(); } auto dma_w_cb() { return m_dma_w.bind(); }
void map(address_map &map); void map(address_map &map);
void irq_w(int state);
void drq_w(int state); void drq_w(int state);
protected: protected:
@ -29,7 +30,7 @@ protected:
// register handlers // register handlers
u32 control_r() { return m_control; } u32 control_r() { return m_control; }
u32 status_r() { return m_status; } u32 status_r() { return m_status | (m_control & (DIRECTION | ENABLE)); }
u32 tcount_r() { return m_tcount; } u32 tcount_r() { return m_tcount; }
void control_w(u32 data); void control_w(u32 data);
@ -40,23 +41,27 @@ protected:
// dma logic // dma logic
void soft_reset(); void soft_reset();
void set_eop(bool eop_state); void set_int(bool int_state);
void dma_check(void *ptr, s32 param); void dma_check(void *ptr, s32 param);
private: private:
required_address_space m_bus; required_address_space m_bus;
devcb_write_line m_eop; devcb_write_line m_int;
devcb_read8 m_dma_r; devcb_read8 m_dma_r;
devcb_write8 m_dma_w; devcb_write8 m_dma_w;
emu_timer *m_dma_check; emu_timer *m_dma_check;
enum status_mask : u32 enum control_mask : u32
{ {
ENABLE = 0x01, ENABLE = 0x01,
DIRECTION = 0x02, DIRECTION = 0x02,
RESET = 0x04, RESET = 0x04,
};
enum status_mask : u32
{
INTERRUPT = 0x08, INTERRUPT = 0x08,
TCZERO = 0x10, TCZERO = 0x10,
}; };
@ -70,7 +75,7 @@ private:
u32 m_map[128]; u32 m_map[128];
// internal state // internal state
bool m_eop_state; bool m_int_state;
bool m_drq_state; bool m_drq_state;
}; };