void i8237_device::i8237_do_write() { int channel = m_service_channel; switch( DMA_MODE_OPERATION( m_chan[ channel ].m_mode ) ) { case DMA8237_WRITE_TRANSFER: m_out_memw_func(m_chan[ channel ].m_address, m_temporary_data); break; case DMA8237_READ_TRANSFER: m_chan[channel].m_out_iow_func(0, m_temporary_data); break; case DMA8237_VERIFY_TRANSFER: case DMA8237_ILLEGAL_TRANSFER: break; } }
inline void am9517a_device::dma_write() { offs_t offset = m_channel[m_current_channel].m_address; switch (MODE_TRANSFER_MASK) { case MODE_TRANSFER_VERIFY: break; case MODE_TRANSFER_WRITE: m_out_memw_func(offset, m_temp); break; case MODE_TRANSFER_READ: m_channel[m_current_channel].m_out_iow_func(offset, m_temp); break; } }
inline void am9517a_device::dma_write() { offs_t offset = m_channel[m_current_channel].m_address; switch (MODE_TRANSFER_MASK) { case MODE_TRANSFER_VERIFY: { UINT8 v1 = m_in_memr_func(offset); if(0 && m_temp != v1) logerror("%s: verify error %02x vs. %02x\n", tag(), m_temp, v1); break; } case MODE_TRANSFER_WRITE: m_out_memw_func(offset, m_temp); break; case MODE_TRANSFER_READ: m_channel[m_current_channel].m_out_iow_func(offset, m_temp); break; } }
void i8237_device::i8237_timerproc() { /* Check if operation is disabled */ if ( m_command & 0x04 ) { return; } switch ( m_state ) { case DMA8237_SI: { /* Make sure EOP is high */ if ( !m_eop ) { m_eop = 1; m_out_eop_func(m_eop ? ASSERT_LINE : CLEAR_LINE); } /* Check if a new DMA request has been received. */ /* Bit 6 of the command register determines whether the DREQ signals are active high or active low. */ UINT16 pending_request = ( ( m_command & 0x40 ) ? ~m_drq : m_drq ) & ~m_mask; if ( pending_request & 0x0f ) { int prio_channel = 0; /* Determine the channel that should be serviced */ int channel = ( m_command & 0x10 ) ? m_last_service_channel : 3; for ( int i = 0; i < 4; i++ ) { if ( pending_request & ( 1 << channel ) ) { prio_channel = channel; } channel = ( channel - 1 ) & 0x03; } /* Store the channel we will be servicing and go to the next state */ m_service_channel = prio_channel; m_last_service_channel = prio_channel; m_hrq = 1; m_out_hrq_func(m_hrq); m_state = DMA8237_S0; m_timer->enable( true ); } else if (m_command == 3 && (m_drq & 1)) { /* Memory-to-memory transfers */ m_hlda = 1; m_state = DMA8237_S0; } else { m_timer->enable( false ); } break; } case DMA8237_S0: /* S0 is the first of the DMA service. We have requested a hold but are waiting for confirmation. */ if ( m_hlda ) { if ( DMA_MODE_TRANSFERMODE( m_chan[m_service_channel].m_mode ) == DMA8237_CASCADE_MODE ) { /* Cascade Mode, set DACK */ i8327_set_dack(m_service_channel); /* Wait until peripheral is done */ m_state = DMA8237_SC; } else { if ( m_command & 0x01 ) { /* Memory-to-memory transfers */ m_state = DMA8237_S11; } else { /* Regular transfers */ m_state = DMA8237_S1; } } } break; case DMA8237_SC: /* Cascade mode, waiting until peripheral is done */ if ( ! ( m_drq & ( 0x01 << m_service_channel ) ) ) { m_hrq = 0; m_hlda = 0; m_out_hrq_func(m_hrq); m_state = DMA8237_SI; /* Clear DACK */ i8327_set_dack(-1); } /* Not sure if this is correct, documentation is not clear */ /* Check if EOP output needs to be asserted */ if ( m_status & ( 0x01 << m_service_channel ) ) { m_eop = 0; m_out_eop_func(m_eop ? ASSERT_LINE : CLEAR_LINE); } break; case DMA8237_S1: /* Output A8-A15 */ m_state = DMA8237_S2; break; case DMA8237_S2: /* Output A7-A0 */ /* set DACK */ i8327_set_dack(m_service_channel); /* Check for compressed timing */ if ( m_command & 0x08 ) { m_state = DMA8237_S4; } else { m_state = DMA8237_S3; } break; case DMA8237_S3: /* Initiate read */ i8237_do_read(); m_state = DMA8237_S4; break; case DMA8237_S4: /* Perform read/write */ /* Perform read when in compressed timing mode */ if ( m_command & 0x08 ) { i8237_do_read(); } /* Perform write */ i8237_do_write(); /* Advance */ i8237_advance(); { int channel = m_service_channel; switch( DMA_MODE_TRANSFERMODE( m_chan[channel].m_mode ) ) { case DMA8237_DEMAND_MODE: /* Check for terminal count or EOP signal or DREQ begin de-asserted */ if ( ( m_status & ( 0x01 << channel ) ) || !m_eop || !( m_drq & ( 0x01 << channel ) ) ) { m_hrq = 0; m_hlda = 0; m_out_hrq_func(m_hrq); m_state = DMA8237_SI; } else { m_state = m_chan[channel].m_high_address_changed ? DMA8237_S1 : DMA8237_S2; } break; case DMA8237_SINGLE_MODE: m_hrq = 0; m_hlda = 0; m_out_hrq_func(m_hrq); m_state = DMA8237_SI; break; case DMA8237_BLOCK_MODE: /* Check for terminal count or EOP signal */ if ( ( m_status & ( 0x01 << channel ) ) || !m_eop ) { m_hrq = 0; m_hlda = 0; m_out_hrq_func(m_hrq); m_state = DMA8237_SI; } else { m_state = m_chan[channel].m_high_address_changed ? DMA8237_S1 : DMA8237_S2; } break; } /* Check if EOP output needs to be asserted */ if ( m_status & ( 0x01 << channel ) ) { m_eop = 0; m_out_eop_func(m_eop ? ASSERT_LINE : CLEAR_LINE); } } /* clear DACK */ if ( m_state == DMA8237_SI ) { i8327_set_dack(-1); } break; case DMA8237_S11: /* Output A8-A15 */ // logerror("###### dma8237_timerproc %s: from %04x count=%x to %04x count=%x\n", tag(), // m_chan[0].m_address, m_chan[0].m_count, // m_chan[1].m_address, m_chan[1].m_count); // FIXME: this will copy bytes correct, but not 16 bit words m_temporary_data = m_in_memr_func(m_chan[0].m_address); m_out_memw_func(m_chan[1].m_address, m_temporary_data); m_service_channel = 0; /* Advance */ i8237_advance(); // advance destination channel as well m_chan[1].m_count--; m_chan[1].m_address++; if (m_chan[0].m_count == 0xFFFF || m_chan[1].m_count == 0xFFFF) { m_hrq = 0; m_hlda = 0; m_out_hrq_func(m_hrq); m_state = DMA8237_SI; m_status |= 3; // set TC for channel 0 and 1 m_drq &= ~3; // clear drq for channel 0 and 1 // logerror("!!! dma8237_timerproc DMA8237_S11 %s: m_drq=%x m_command=%x\n", tag(), m_drq, m_command); } break; } }
int i8257_device::i8257_do_operation(int channel) { int done; UINT8 data; UINT8 mode = m_rwmode[channel]; if (m_count[channel] == 0x0000) { m_status |= (0x01 << channel); m_out_tc_func(ASSERT_LINE); } switch(mode) { case 1: if (!m_in_memr_func.isnull()) { data = m_in_memr_func(m_address[channel]); } else { data = 0; logerror("8257: No memory read function defined.\n"); } if (!m_out_iow_func[channel].isnull()) { m_out_iow_func[channel](m_address[channel], data); } else { logerror("8257: No channel write function for channel %d defined.\n",channel); } m_address[channel]++; m_count[channel]--; done = (m_count[channel] == 0xFFFF); break; case 2: if (!m_in_ior_func[channel].isnull()) { data = m_in_ior_func[channel](m_address[channel]); } else { data = 0; logerror("8257: No channel read function for channel %d defined.\n",channel); } if (!m_out_memw_func.isnull()) { m_out_memw_func(m_address[channel], data); } else { logerror("8257: No memory write function defined.\n"); } m_address[channel]++; m_count[channel]--; done = (m_count[channel] == 0xFFFF); break; case 0: /* verify */ m_address[channel]++; m_count[channel]--; done = (m_count[channel] == 0xFFFF); break; default: fatalerror("i8257_do_operation: invalid mode!\n"); break; } if (done) { if ((channel==2) && DMA_MODE_AUTOLOAD(m_mode)) { /* in case of autoload at the end channel 3 info is */ /* copied to channel 2 info */ m_registers[4] = m_registers[6]; m_registers[5] = m_registers[7]; } m_out_tc_func(CLEAR_LINE); } return done; }