diff options
Diffstat (limited to 'src/emu/machine/i8257.c')
-rw-r--r-- | src/emu/machine/i8257.c | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/src/emu/machine/i8257.c b/src/emu/machine/i8257.c index a6a521de0c4..6de5771afbe 100644 --- a/src/emu/machine/i8257.c +++ b/src/emu/machine/i8257.c @@ -219,22 +219,35 @@ inline void i8257n_device::dma_write() // end_of_process - //------------------------------------------------- -inline void i8257n_device::end_of_process() +inline void i8257n_device::advance() { - m_status |= 1 << m_current_channel; - m_request &= ~(1 << m_current_channel); - set_tc(1); + bool tc = (m_channel[m_current_channel].m_count == 0); + bool al = (MODE_AUTOLOAD && (m_current_channel == 2)); - if (MODE_AUTOLOAD && (m_current_channel == 2)) + if(tc) { - // autoinitialize - m_channel[2].m_address = m_channel[3].m_address; - m_channel[2].m_count = m_channel[3].m_count; - m_channel[2].m_mode = m_channel[3].m_mode; + m_status |= 1 << m_current_channel; + m_request &= ~(1 << m_current_channel); // docs imply this isn't right but pc-8001 works better with it + set_tc(1); + + if(al) + { + // autoinitialize + m_channel[2].m_address = m_channel[3].m_address; + m_channel[2].m_count = m_channel[3].m_count; + m_channel[2].m_mode = m_channel[3].m_mode; + } + else if(MODE_TC_STOP) + // disable channel + m_transfer_mode &= ~(1 << m_current_channel); + } + + if(!(al && tc)) + { + m_channel[m_current_channel].m_count--; + m_channel[m_current_channel].m_count &= 0x3fff; + m_channel[m_current_channel].m_address++; } - else if(MODE_TC_STOP) - // disable channel - m_transfer_mode &= ~(1 << m_current_channel); } @@ -251,6 +264,7 @@ i8257n_device::i8257n_device(const machine_config &mconfig, const char *tag, dev : device_t(mconfig, I8257N, "I8257N", tag, owner, clock, "i8257n", __FILE__), device_execute_interface(mconfig, *this), m_icount(0), + m_reverse_rw(0), m_tc(false), m_msb(0), m_hreq(CLEAR_LINE), @@ -310,13 +324,6 @@ void i8257n_device::device_start() m_out_dack_2_cb.resolve_safe(); m_out_dack_3_cb.resolve_safe(); - for (int i = 0; i < 4; i++) - { - m_channel[i].m_address = 0; - m_channel[i].m_count = 0; - m_channel[i].m_mode = 0; - } - // state saving save_item(NAME(m_msb)); save_item(NAME(m_hreq)); @@ -328,6 +335,19 @@ void i8257n_device::device_start() save_item(NAME(m_transfer_mode)); save_item(NAME(m_status)); save_item(NAME(m_request)); + + save_item(NAME(m_channel[0].m_address)); + save_item(NAME(m_channel[0].m_count)); + save_item(NAME(m_channel[0].m_mode)); + save_item(NAME(m_channel[1].m_address)); + save_item(NAME(m_channel[1].m_count)); + save_item(NAME(m_channel[1].m_mode)); + save_item(NAME(m_channel[2].m_address)); + save_item(NAME(m_channel[2].m_count)); + save_item(NAME(m_channel[2].m_mode)); + save_item(NAME(m_channel[3].m_address)); + save_item(NAME(m_channel[3].m_count)); + save_item(NAME(m_channel[3].m_mode)); } @@ -347,6 +367,12 @@ void i8257n_device::device_reset() m_hreq = -1; m_tc = 0; + for (int i = 0; i < 4; i++) + { + m_channel[i].m_address = 0; + m_channel[i].m_count = 0; + m_channel[i].m_mode = 0; + } set_hreq(0); set_dack(); } @@ -444,12 +470,7 @@ void i8257n_device::execute_run() { dma_write(); } - m_channel[m_current_channel].m_count--; - m_channel[m_current_channel].m_count &= 0x3fff; - m_channel[m_current_channel].m_address++; - - if(!m_channel[m_current_channel].m_count) - end_of_process(); + advance(); if(next_channel()) m_state = STATE_S1; @@ -495,7 +516,11 @@ READ8_MEMBER( i8257n_device::read ) case REGISTER_WORD_COUNT: if (m_msb) { - data = (m_channel[channel].m_count >> 8) | (m_channel[channel].m_mode << 6); + data = (m_channel[channel].m_count >> 8); + if(m_reverse_rw && m_channel[channel].m_mode) + data |= (m_channel[channel].m_mode == 1) ? 0x2000 : 0x1000; + else + data |= (m_channel[channel].m_mode << 6); } else { @@ -550,10 +575,14 @@ WRITE8_MEMBER( i8257n_device::write ) { m_channel[channel].m_count = ((data & 0x3f) << 8) | (m_channel[channel].m_count & 0xff); m_channel[channel].m_mode = (data >> 6); + + if(m_reverse_rw && m_channel[channel].m_mode) + m_channel[channel].m_mode = (m_channel[channel].m_mode == 1) ? 2 : 1; + if(MODE_AUTOLOAD && (channel == 2)) { m_channel[3].m_count = ((data & 0x3f) << 8) | (m_channel[3].m_count & 0xff); - m_channel[3].m_mode = (data >> 6); + m_channel[3].m_mode = m_channel[2].m_mode; } } else |