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; } }
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; }
static int dma8257_do_operation(const device_config *device, int channel) { dma8257_t *dma8257 = get_safe_token(device); int done; UINT8 data; UINT8 mode; mode = dma8257->rwmode[channel]; if (dma8257->count[channel] == 0x0000) { dma8257->status |= (0x01 << channel); if (dma8257->intf->out_tc[channel]) dma8257->intf->out_tc[channel](device, 0, ASSERT_LINE); } switch(mode) { case 1: if (dma8257->intf->memory_read!=NULL) { data = dma8257->intf->memory_read(device, dma8257->address[channel]); } else { data = 0; logerror("8257: No memory read function defined.\n"); } if (dma8257->intf->channel_write[channel]!=NULL) { dma8257->intf->channel_write[channel](device, 0, data); } else { logerror("8257: No channel write function for channel %d defined.\n",channel); } dma8257->address[channel]++; dma8257->count[channel]--; done = (dma8257->count[channel] == 0xFFFF); break; case 2: if (dma8257->intf->channel_read[channel]!=NULL) { data = dma8257->intf->channel_read[channel](device, 0); } else { data = 0; logerror("8257: No channel read function for channel %d defined.\n",channel); } if (dma8257->intf->memory_write!=NULL) { dma8257->intf->memory_write(device, dma8257->address[channel], data); } else { logerror("8257: No memory write function defined.\n"); } dma8257->address[channel]++; dma8257->count[channel]--; done = (dma8257->count[channel] == 0xFFFF); break; case 0: /* verify */ dma8257->address[channel]++; dma8257->count[channel]--; done = (dma8257->count[channel] == 0xFFFF); break; default: fatalerror("dma8257_do_operation: invalid mode!\n"); break; } if (done) { if ((channel==2) && DMA_MODE_AUTOLOAD(dma8257->mode)) { /* in case of autoload at the end channel 3 info is */ /* copied to channel 2 info */ dma8257->registers[4] = dma8257->registers[6]; dma8257->registers[5] = dma8257->registers[7]; } if (dma8257->intf->out_tc[channel]) dma8257->intf->out_tc[channel](device, 0, CLEAR_LINE); } return done; }