summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/am9517a.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/am9517a.cpp')
-rw-r--r--src/devices/machine/am9517a.cpp213
1 files changed, 108 insertions, 105 deletions
diff --git a/src/devices/machine/am9517a.cpp b/src/devices/machine/am9517a.cpp
index 5fda6ed486c..c9e8a7b2944 100644
--- a/src/devices/machine/am9517a.cpp
+++ b/src/devices/machine/am9517a.cpp
@@ -145,29 +145,53 @@ enum
// dma_request -
//-------------------------------------------------
-void am9517a_device::dma_request(int channel, int state)
+void am9517a_device::dma_request(int channel, bool state)
{
LOG("AM9517A Channel %u DMA Request: %u\n", channel, state);
- if (state ^ COMMAND_DREQ_ACTIVE_LOW)
- {
+ if (state)
m_status |= (1 << (channel + 4));
- }
else
- {
m_status &= ~(1 << (channel + 4));
- }
+
trigger(1);
}
//-------------------------------------------------
+// mask_channel -
+//-------------------------------------------------
+
+void am9517a_device::mask_channel(int channel, bool state)
+{
+ LOG("AM9517A Channel %u Mask: %u\n", channel, state);
+
+ if (state)
+ m_mask |= 1 << channel;
+ else
+ m_mask &= ~(1 << channel);
+}
+
+
+//-------------------------------------------------
+// set_mask_register -
+//-------------------------------------------------
+
+void am9517a_device::set_mask_register(uint8_t mask)
+{
+ LOG("AM9517A Mask Register: %01x\n", mask);
+
+ m_mask = mask;
+}
+
+
+//-------------------------------------------------
// is_request_active -
//-------------------------------------------------
inline bool am9517a_device::is_request_active(int channel)
{
- return (BIT(m_status, channel + 4) & ~BIT(m_mask, channel)) ? true : false;
+ return (BIT(COMMAND_DREQ_ACTIVE_LOW ? ~m_status : m_status, channel + 4) && !BIT(m_mask, channel)) ? true : false;
}
@@ -397,8 +421,7 @@ void am9517a_device::end_of_process()
m_mask |= 1 << m_current_channel;
}
- // signal end of process
- set_eop(ASSERT_LINE);
+ set_eop(CLEAR_LINE);
set_hreq(0);
m_current_channel = -1;
@@ -418,41 +441,41 @@ void am9517a_device::end_of_process()
//-------------------------------------------------
-am9517a_device::am9517a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, type, tag, owner, clock),
- device_execute_interface(mconfig, *this),
- m_icount(0),
- m_hack(0),
- m_ready(1),
- m_command(0),
- m_out_hreq_cb(*this),
- m_out_eop_cb(*this),
- m_in_memr_cb(*this),
- m_out_memw_cb(*this),
- m_in_ior_cb{ { *this }, { *this }, { *this }, { *this } },
- m_out_iow_cb{ { *this }, { *this }, { *this }, { *this } },
- m_out_dack_cb{ { *this }, { *this }, { *this }, { *this } }
+am9517a_device::am9517a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ device_execute_interface(mconfig, *this),
+ m_icount(0),
+ m_hack(0),
+ m_ready(1),
+ m_command(0),
+ m_status(0),
+ m_out_hreq_cb(*this),
+ m_out_eop_cb(*this),
+ m_in_memr_cb(*this, 0),
+ m_out_memw_cb(*this),
+ m_in_ior_cb(*this, 0),
+ m_out_iow_cb(*this),
+ m_out_dack_cb(*this)
{
}
-am9517a_device::am9517a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : am9517a_device(mconfig, AM9517A, tag, owner, clock)
+am9517a_device::am9517a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ am9517a_device(mconfig, AM9517A, tag, owner, clock)
{
}
-v5x_dmau_device::v5x_dmau_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : am9517a_device(mconfig, V5X_DMAU, tag, owner, clock)
- , m_in_mem16r_cb(*this)
- , m_out_mem16w_cb(*this)
- , m_in_io16r_cb{ { *this },{ *this },{ *this },{ *this } }
- , m_out_io16w_cb{ { *this },{ *this },{ *this },{ *this } }
-
+v5x_dmau_device::v5x_dmau_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ am9517a_device(mconfig, V5X_DMAU, tag, owner, clock),
+ m_in_mem16r_cb(*this, 0),
+ m_out_mem16w_cb(*this),
+ m_in_io16r_cb(*this, 0),
+ m_out_io16w_cb(*this)
{
}
-pcxport_dmac_device::pcxport_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : am9517a_device(mconfig, PCXPORT_DMAC, tag, owner, clock)
+pcxport_dmac_device::pcxport_dmac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ am9517a_device(mconfig, PCXPORT_DMAC, tag, owner, clock)
{
}
@@ -465,18 +488,6 @@ void am9517a_device::device_start()
// set our instruction counter
set_icountptr(m_icount);
- // resolve callbacks
- m_out_hreq_cb.resolve_safe();
- m_out_eop_cb.resolve_safe();
- m_in_memr_cb.resolve_safe(0);
- m_out_memw_cb.resolve_safe();
- for(auto &cb : m_in_ior_cb)
- cb.resolve_safe(0);
- for(auto &cb : m_out_iow_cb)
- cb.resolve_safe();
- for(auto &cb : m_out_dack_cb)
- cb.resolve_safe();
-
for(auto &elem : m_channel)
{
elem.m_address = 0;
@@ -501,17 +512,16 @@ void am9517a_device::device_start()
save_item(NAME(m_temp));
save_item(NAME(m_request));
- for (int i = 0; i < 4; i++)
- {
- save_item(NAME(m_channel[i].m_address), i);
- save_item(NAME(m_channel[i].m_count), i);
- save_item(NAME(m_channel[i].m_base_address), i);
- save_item(NAME(m_channel[i].m_base_count), i);
- save_item(NAME(m_channel[i].m_mode), i);
- }
+ save_item(STRUCT_MEMBER(m_channel, m_address));
+ save_item(STRUCT_MEMBER(m_channel, m_count));
+ save_item(STRUCT_MEMBER(m_channel, m_base_address));
+ save_item(STRUCT_MEMBER(m_channel, m_base_count));
+ save_item(STRUCT_MEMBER(m_channel, m_mode));
m_address_mask = 0xffff;
+ // force clear upon initial reset
+ m_eop = ASSERT_LINE;
}
@@ -523,7 +533,7 @@ void am9517a_device::device_reset()
{
m_state = STATE_SI;
m_command = 0;
- m_status = 0;
+ m_status &= 0xf0;
m_request = 0;
m_mask = 0x0f;
m_temp = 0;
@@ -531,10 +541,9 @@ void am9517a_device::device_reset()
m_current_channel = -1;
m_last_channel = 3;
m_hreq = -1;
- m_eop = 0;
set_hreq(0);
- set_eop(ASSERT_LINE);
+ set_eop(CLEAR_LINE);
set_dack();
}
@@ -551,8 +560,6 @@ void am9517a_device::execute_run()
switch (m_state)
{
case STATE_SI:
- set_eop(CLEAR_LINE);
-
if (!COMMAND_DISABLE)
{
int priority[] = { 0, 1, 2, 3 };
@@ -628,10 +635,23 @@ void am9517a_device::execute_run()
case STATE_S2:
set_dack();
- m_state = COMMAND_COMPRESSED_TIMING ? STATE_S4 : STATE_S3;
+ if (COMMAND_COMPRESSED_TIMING)
+ {
+ // signal end of process during last cycle
+ if (m_channel[m_current_channel].m_count == 0)
+ set_eop(ASSERT_LINE);
+
+ m_state = STATE_S4;
+ }
+ else
+ m_state = STATE_S3;
break;
case STATE_S3:
+ // signal end of process during last cycle
+ if (m_channel[m_current_channel].m_count == 0)
+ set_eop(ASSERT_LINE);
+
dma_read();
if (COMMAND_EXTENDED_WRITE)
@@ -691,6 +711,10 @@ void am9517a_device::execute_run()
break;
case STATE_S23:
+ // signal end of process during last cycle
+ if (m_channel[m_current_channel].m_count == 0)
+ set_eop(ASSERT_LINE);
+
m_state = STATE_S24;
break;
@@ -756,7 +780,8 @@ uint8_t am9517a_device::read(offs_t offset)
break;
}
- m_msb = !m_msb;
+ if (!machine().side_effects_disabled())
+ m_msb = !m_msb;
}
else
{
@@ -764,9 +789,12 @@ uint8_t am9517a_device::read(offs_t offset)
{
case REGISTER_STATUS:
data = m_status;
+ if (COMMAND_DREQ_ACTIVE_LOW)
+ data ^= 0xf0;
// clear TC bits
- m_status &= 0xf0;
+ if (!machine().side_effects_disabled())
+ m_status &= 0xf0;
break;
case REGISTER_TEMPORARY:
@@ -844,15 +872,11 @@ void am9517a_device::write(offs_t offset, uint8_t data)
if (BIT(data, 2))
{
- m_request |= (1 << (channel + 4));
- if (COMMAND_MEM_TO_MEM)
- {
- m_request |= (1 << channel);
- }
+ m_request |= (1 << channel);
}
else
{
- m_request &= ~(1 << (channel + 4));
+ m_request &= ~(1 << channel);
}
LOG("AM9517A Request Register: %01x\n", m_request);
@@ -862,17 +886,7 @@ void am9517a_device::write(offs_t offset, uint8_t data)
case REGISTER_SINGLE_MASK:
{
int channel = data & 0x03;
-
- if (BIT(data, 2))
- {
- m_mask |= (1 << channel);
- }
- else
- {
- m_mask &= ~(1 << channel);
- }
-
- LOG("AM9517A Mask Register: %01x\n", m_mask);
+ mask_channel(channel, BIT(data, 2));
}
break;
@@ -902,15 +916,11 @@ void am9517a_device::write(offs_t offset, uint8_t data)
break;
case REGISTER_CLEAR_MASK:
- LOG("AM9517A Clear Mask Register\n");
-
- m_mask = 0;
+ set_mask_register(0);
break;
case REGISTER_MASK:
- m_mask = data & 0x0f;
-
- LOG("AM9517A Mask Register: %01x\n", m_mask);
+ set_mask_register(data & 0x0f);
break;
}
}
@@ -922,7 +932,7 @@ void am9517a_device::write(offs_t offset, uint8_t data)
// hack_w - hold acknowledge
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::hack_w )
+void am9517a_device::hack_w(int state)
{
LOG("AM9517A Hold Acknowledge: %u\n", state);
@@ -935,7 +945,7 @@ WRITE_LINE_MEMBER( am9517a_device::hack_w )
// ready_w - ready
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::ready_w )
+void am9517a_device::ready_w(int state)
{
LOG("AM9517A Ready: %u\n", state);
@@ -947,7 +957,7 @@ WRITE_LINE_MEMBER( am9517a_device::ready_w )
// eop_w - end of process
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::eop_w )
+void am9517a_device::eop_w(int state)
{
LOG("AM9517A End of Process: %u\n", state);
}
@@ -957,7 +967,7 @@ WRITE_LINE_MEMBER( am9517a_device::eop_w )
// dreq0_w - DMA request for channel 0
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::dreq0_w )
+void am9517a_device::dreq0_w(int state)
{
dma_request(0, state);
}
@@ -967,7 +977,7 @@ WRITE_LINE_MEMBER( am9517a_device::dreq0_w )
// dreq0_w - DMA request for channel 1
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::dreq1_w )
+void am9517a_device::dreq1_w(int state)
{
dma_request(1, state);
}
@@ -977,7 +987,7 @@ WRITE_LINE_MEMBER( am9517a_device::dreq1_w )
// dreq1_w - DMA request for channel 2
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::dreq2_w )
+void am9517a_device::dreq2_w(int state)
{
dma_request(2, state);
}
@@ -987,7 +997,7 @@ WRITE_LINE_MEMBER( am9517a_device::dreq2_w )
// dreq3_w - DMA request for channel 3
//-------------------------------------------------
-WRITE_LINE_MEMBER( am9517a_device::dreq3_w )
+void am9517a_device::dreq3_w(int state)
{
dma_request(3, state);
}
@@ -1001,13 +1011,6 @@ void v5x_dmau_device::device_start()
am9517a_device::device_start();
m_address_mask = 0x00ffffff;
- m_in_mem16r_cb.resolve_safe(0);
- m_out_mem16w_cb.resolve_safe();
- for (auto &cb : m_in_io16r_cb)
- cb.resolve_safe(0);
- for (auto &cb : m_out_io16w_cb)
- cb.resolve_safe();
-
m_selected_channel = 0;
m_base = 0;
@@ -1087,7 +1090,8 @@ uint8_t v5x_dmau_device::read(offs_t offset)
case 0x0b: // Status
ret = m_status;
// clear TC bits
- m_status &= 0xf0;
+ if (!machine().side_effects_disabled())
+ m_status &= 0xf0;
break;
case 0x0c: // Temporary (low)
ret = m_temp & 0xff;
@@ -1260,7 +1264,7 @@ void pcxport_dmac_device::device_reset()
{
m_state = STATE_SI;
m_command = 0;
- m_status = 0;
+ m_status &= 0xf0;
m_request = 0;
m_mask = 0;
m_temp = 0;
@@ -1268,10 +1272,9 @@ void pcxport_dmac_device::device_reset()
m_current_channel = -1;
m_last_channel = 3;
m_hreq = -1;
- m_eop = 0;
set_hreq(0);
- set_eop(ASSERT_LINE);
+ set_eop(CLEAR_LINE);
set_dack();
}
@@ -1300,8 +1303,7 @@ void pcxport_dmac_device::end_of_process()
}
// don't mask out channel if not autoinitialize
- // signal end of process
- set_eop(ASSERT_LINE);
+ set_eop(CLEAR_LINE);
set_hreq(0);
m_current_channel = -1;
@@ -1322,4 +1324,5 @@ void eisa_dma_device::device_start()
m_address_mask = 0xffffffffU;
save_item(NAME(m_stop));
+ save_item(NAME(m_ext_mode));
}