static TIMER_CALLBACK( dma8257_timerproc ) { const device_config *device = (const device_config *)ptr; dma8257_t *dma8257 = get_safe_token(device); int i, channel = 0, rr; int done; rr = DMA_MODE_ROTPRIO(dma8257->mode) ? dma8257->rr : 0; for (i = 0; i < DMA8257_NUM_CHANNELS; i++) { channel = (i + rr) % DMA8257_NUM_CHANNELS; if ((dma8257->status & (1 << channel)) == 0) if (dma8257->mode & dma8257->drq & (1 << channel)) break; } done = dma8257_do_operation(device, channel); dma8257->rr = (channel + 1) & 0x03; if (done) { dma8257->drq &= ~(0x01 << channel); dma8257_update_status(device); if (!(DMA_MODE_AUTOLOAD(dma8257->mode) && channel==2)) { if (DMA_MODE_TCSTOP(dma8257->mode)) { dma8257->mode &= ~(0x01 << channel); } } } }
void i8257_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { case TIMER_OPERATION: { int i, channel = 0, rr; int done; rr = DMA_MODE_ROTPRIO(m_mode) ? m_rr : 0; for (i = 0; i < I8257_NUM_CHANNELS; i++) { channel = (i + rr) % I8257_NUM_CHANNELS; if ((m_status & (1 << channel)) == 0) { if (m_mode & m_drq & (1 << channel)) { break; } } } done = i8257_do_operation(channel); m_rr = (channel + 1) & 0x03; if (done) { m_drq &= ~(0x01 << channel); i8257_update_status(); if (!(DMA_MODE_AUTOLOAD(m_mode) && channel==2)) { if (DMA_MODE_TCSTOP(m_mode)) { m_mode &= ~(0x01 << channel); } } } break; } case TIMER_MSBFLIP: m_msb ^= 1; break; case TIMER_DRQ_SYNC: { int channel = param >> 1; int state = param & 0x01; /* normalize state */ if (state) { m_drq |= 0x01 << channel; m_address[channel] = m_registers[channel * 2]; m_count[channel] = m_registers[channel * 2 + 1] & 0x3FFF; m_rwmode[channel] = m_registers[channel * 2 + 1] >> 14; /* clear channel TC */ m_status &= ~(0x01 << channel); } else m_drq &= ~(0x01 << channel); i8257_update_status(); break; } }