inline void am9517a_device::set_eop(int state) { if (m_eop != state) { m_out_eop_func(state); m_eop = state; } }
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; } }