void sb16_device::rcv_complete() // Rx completed receiving byte { receive_register_extract(); UINT8 data = get_received_char(); // for UART or MPU, add character to the receive queue if (m_uart_midi || m_mpu_midi) { m_recvring[m_recv_write++] = data; if (m_recv_write >= MIDI_RING_SIZE) { m_recv_write = 0; } if (m_recv_write != m_recv_read) { m_rx_waiting++; } if (m_uart_irq) { irq_w(1, IRQ_DMA8); } if (m_mpu_midi) { irq_w(1, IRQ_MPU); } } }
void hp98035_io_card::update_irq(void) { if (!m_inten) { m_irq = false; } irq_w(m_inten && m_irq); }
void hp98035_io_card_device::update_irq() { if (!m_inten) { m_irq = false; } irq_w(m_inten && m_irq); }
void microdisc_device::device_reset() { port_314 = 0x00; irq_w(false); remap(); fdc->set_floppy(floppies[0]); // The bootstrap checksums part of the high ram and if the sum is // 0 it goes wrong. ram[0xe000] = 0x42; }
UINT16 sb16_device::dack16_r(int line) { m_dsp.adc_transferred += 2; if (m_dsp.adc_transferred >= m_dsp.adc_length) { drq16_w(0); if (m_dsp.dma_autoinit) { m_dsp.adc_transferred = 0; drq16_w(1); } irq_w(1, IRQ_DMA16); } else drq16_w(1); return m_dack_out; }
/* TODO: this mustn't be instant! */ void sb_device::dack_w(int line, UINT8 data) { // printf("dack_w: line %x data %02x\n", line, data); // if(data != 0x80) // printf("%02x\n",data); // set the transfer timer on the 1st byte if (!m_dsp.dma_timer_started) { m_timer->adjust(attotime::from_hz((double)m_dsp.frequency), 0, attotime::from_hz((double)m_dsp.frequency)); m_dsp.d_rptr = m_dsp.d_wptr = 0; m_dsp.dma_timer_started = true; } m_dsp.data[m_dsp.d_wptr++] = data; m_dsp.d_wptr %= 128; if (m_dsp.d_wptr == m_dsp.d_rptr) { // printf("throttling DRQ\n"); drq_w(0); // drop DRQ here m_dsp.dma_throttled = true; } m_dsp.dma_transferred++; if (m_dsp.dma_transferred >= m_dsp.dma_length) { // printf("DMA fill completed (%d out of %d)\n", m_dsp.dma_transferred, m_dsp.dma_length); drq_w(0); // drop DRQ here if (m_dsp.dma_autoinit) { // printf("autoinit reset\n"); m_dsp.dma_transferred = 0; if (!m_dsp.dma_throttled) // if we're not throttled, re-raise DRQ right now { drq_w(1); // raise DRQ again (page 3-15 of the Creative manual indicates auto-init will keep going until you stop it) } } irq_w(1, IRQ_DMA8); // raise IRQ as per the Creative manual } }
UINT8 sb_device::dack_r(int line) { m_dsp.adc_transferred++; if(m_dsp.adc_transferred >= m_dsp.adc_length) { drq_w(0); if (m_dsp.dma_autoinit) { m_dsp.adc_transferred = 0; drq_w(1); } else m_dsp.wbuf_status = 0; if(!m_dsp.dma_no_irq) irq_w(1, IRQ_DMA8); else m_dsp.dma_no_irq = false; } else drq_w(1); return m_dack_out; }
void sb_device::rcv_complete() // Rx completed receiving byte { receive_register_extract(); UINT8 data = get_received_char(); // in UART MIDI mode, we set the DMA8 IRQ on receiving a character if (m_uart_midi) { m_recvring[m_recv_write++] = data; if (m_recv_write >= MIDI_RING_SIZE) { m_recv_write = 0; } if (m_recv_write != m_recv_read) { m_rx_waiting++; } if (m_uart_irq) { irq_w(1, IRQ_DMA8); } } }
void sb_device::process_fifo(UINT8 cmd) { if (m_cmd_fifo_length[cmd] == -1) { logerror("SB: unemulated or undefined fifo command %02x\n",cmd); m_dsp.fifo_ptr = 0; } else if(m_dsp.fifo_ptr == m_cmd_fifo_length[cmd]) { /* get FIFO params */ // printf("SB FIFO command: %02x\n", cmd); switch(cmd) { case 0x10: // Direct DAC break; case 0x14: // 8-bit DMA, no autoinit m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; // printf("Start DMA (not autoinit, size = %x)\n", m_dsp.dma_length); m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 0; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = 0; break; case 0x17: // 2-bit ADPCM w/new reference m_dsp.adpcm_new_ref = true; m_dsp.adpcm_step = 0; case 0x16: // 2-bit ADPCM m_dsp.adpcm_count = 0; m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 0; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = ADPCM2; break; case 0x1c: // 8-bit DMA with autoinit // printf("Start DMA (autoinit, size = %x)\n", m_dsp.dma_length); m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 1; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = 0; break; case 0x24: // 8-bit ADC DMA m_dsp.adc_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; // printf("Start DMA (not autoinit, size = %x)\n", m_dsp.adc_length); m_dsp.adc_transferred = 0; m_dsp.dma_autoinit = 0; drq_w(1); logerror("SB: ADC capture unimplemented\n"); break; case 0x34: m_uart_midi = true; m_uart_irq = false; break; case 0x35: m_uart_midi = true; m_uart_irq = true; break; case 0x36: case 0x37: // Enter UART mode printf("timestamp MIDI mode not supported, contact MESSDEV!\n"); break; case 0x38: // single-byte MIDI send m_onebyte_midi = true; break; case 0x40: // set time constant m_dsp.frequency = (1000000 / (256 - m_dsp.fifo[1])); //printf("Set time constant: %02x -> %d\n", m_dsp.fifo[1], m_dsp.frequency); break; case 0x48: // set DMA block size (for auto-init) m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; break; case 0x75: // 4-bit ADPCM w/new reference m_dsp.adpcm_new_ref = true; m_dsp.adpcm_step = 0; case 0x74: // 4-bit ADPCM m_dsp.adpcm_count = 0; m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 0; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = ADPCM4; break; case 0x77: // 2.6-bit ADPCM w/new reference m_dsp.adpcm_new_ref = true; m_dsp.adpcm_step = 0; case 0x76: // 2.6-bit ADPCM m_dsp.adpcm_count = 0; m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 0; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = ADPCM3; break; case 0xd0: // halt 8-bit DMA m_timer->adjust(attotime::never, 0); drq_w(0); // drop DRQ m_dsp.dma_throttled = false; m_dsp.dma_timer_started = false; break; case 0xd1: // speaker on // ... m_dsp.speaker_on = 1; break; case 0xd3: // speaker off // ... m_dsp.speaker_on = 0; break; case 0xd8: // speaker status queue_r(m_dsp.speaker_on ? 0xff : 0x00); break; case 0xe0: // get DSP identification queue_r(m_dsp.fifo[1] ^ 0xff); break; case 0xe1: // get DSP version queue_r(m_dsp.version >> 8); queue_r(m_dsp.version & 0xff); break; case 0xe2: // DSP protection m_dsp.prot_value += protection_magic[m_dsp.prot_count++] ^ m_dsp.fifo[1]; m_dsp.prot_count &= 3; m_dsp.adc_transferred = 0; m_dsp.adc_length = 1; m_dsp.wbuf_status = 0x80; m_dsp.dma_no_irq = true; m_dack_out = (UINT8)(m_dsp.prot_value & 0xff); drq_w(1); break; case 0xe4: // write test register m_dsp.test_reg = m_dsp.fifo[1]; break; case 0xe8: // read test register queue_r(m_dsp.test_reg); break; case 0xf2: // send PIC irq irq_w(1, IRQ_DMA8); break; case 0xf8: // ??? logerror("SB: Unknown command write 0xf8\n"); queue_r(0); break; default: if(m_dsp.version >= 0x0201) // SB 2.0 { switch(cmd) { case 0x1f: // 2-bit autoinit ADPCM w/new reference m_dsp.adpcm_new_ref = true; m_dsp.adpcm_step = 0; m_dsp.adpcm_count = 0; m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 1; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = ADPCM2; break; case 0x7d: // 4-bit autoinit ADPCM w/new reference m_dsp.adpcm_new_ref = true; m_dsp.adpcm_step = 0; m_dsp.adpcm_count = 0; m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 1; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = ADPCM4; break; case 0x7f: // 2.6-bit autoinit ADPCM w/new reference m_dsp.adpcm_new_ref = true; m_dsp.adpcm_step = 0; m_dsp.adpcm_count = 0; m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; m_dsp.dma_transferred = 0; m_dsp.dma_autoinit = 1; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; drq_w(1); m_dsp.flags = ADPCM3; break; case 0xda: // stop 8-bit autoinit m_dsp.dma_autoinit = 0; break; } } if(m_dsp.version >= 0x0301) // SB Pro 2 { switch(cmd) { case 0xe3: // copyright notice, check if in pro 2 const char* copyright = "NOT COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; int j = strlen(copyright); for(int k = 4; k <= j; k++) queue_r(copyright[k]); break; } } if(m_dsp.version >= 0x0400) // SB16 { int mode; switch(cmd) { case 0x0f: // read asp reg queue_r(0); case 0x0e: // write asp reg case 0x02: // get asp version case 0x04: // set asp mode register case 0x05: // set asp codec param logerror("SB16: unimplemented ASP command\n"); break; case 0x41: // set output sample rate m_dsp.frequency = m_dsp.fifo[2] + (m_dsp.fifo[1] << 8); break; case 0x42: // set input sample rate m_dsp.adc_freq = m_dsp.fifo[2] + (m_dsp.fifo[1] << 8); break; case 0xd5: // pause 16-bit dma m_timer->adjust(attotime::never, 0); drq16_w(0); // drop DRQ m_dsp.dma_throttled = false; m_dsp.dma_timer_started = false; break; case 0xd6: // resume 16-bit dma logerror("SB: 16-bit dma resume\n"); break; case 0xd9: // stop 16-bit autoinit m_dsp.dma_autoinit = 0; break; case 0xb0: case 0xb6: case 0xc0: case 0xc6: mode = m_dsp.fifo[1]; m_dsp.flags = 0; m_dsp.dma_length = (m_dsp.fifo[2] + (m_dsp.fifo[3]<<8)) + 1; if((cmd & 0xf0) == 0xb0) { m_dsp.flags |= SIXTEENBIT; m_dsp.dma_length <<= 1; drq16_w(1); } else drq_w(1); if(cmd & 0x04) m_dsp.dma_autoinit = 1; if(mode & 0x10) m_dsp.flags |= SIGNED; if(mode & 0x20) { m_dsp.flags |= STEREO; m_dsp.dma_length <<= 1; } m_dsp.dma_transferred = 0; m_dsp.dma_timer_started = false; m_dsp.dma_throttled = false; break; case 0xb8: case 0xbe: case 0xc8: case 0xce: mode = m_dsp.fifo[1]; m_dsp.adc_length = (m_dsp.fifo[2] + (m_dsp.fifo[3]<<8)) + 1; m_dsp.adc_transferred = 0; if(cmd & 0x04) m_dsp.dma_autoinit = 1; if(mode & 0x20) m_dsp.adc_length <<= 1; if((cmd & 0xf0) == 0xb0) { m_dsp.adc_length <<= 1; drq16_w(1); } else drq_w(1); logerror("SB: ADC capture unimplemented\n"); break; case 0xf3: // send PIC irq irq_w(1, IRQ_DMA16); break; case 0xfc: queue_r((((m_dsp.flags & SIXTEENBIT) && m_dsp.dma_autoinit) << 4) | ((!(m_dsp.flags & SIXTEENBIT) && m_dsp.dma_autoinit) << 2)); break; } } } m_dsp.fifo_ptr = 0; } }