#pragma once #ifndef __ISA_SOUND_BLASTER_H__ #define __ISA_SOUND_BLASTER_H__ #include "emu.h" #include "machine/isa.h" #include "sound/dac.h" #include "machine/pc_joy.h" #include "machine/serial.h" #include "machine/midiinport.h" #include "machine/midioutport.h" #define SIXTEENBIT 0x01 #define STEREO 0x02 #define SIGNED 0x04 #define ADPCM2 0x08 #define ADPCM3 0x10 #define ADPCM4 0x20 #define IRQ_DMA8 0x01 #define IRQ_DMA16 0x02 #define IRQ_MPU 0x04 #define IRQ_ALL 0xff //************************************************************************** // TYPE DEFINITIONS //************************************************************************** struct sb8_dsp_state { UINT8 reset_latch; UINT8 rbuf_status; UINT8 wbuf_status; UINT8 fifo[16],fifo_ptr; UINT8 fifo_r[52],fifo_r_ptr; UINT16 version; UINT8 test_reg; UINT8 speaker_on; bool dma_no_irq; UINT32 prot_count; INT32 prot_value; UINT32 frequency; UINT32 adc_freq; UINT32 dma_length, dma_transferred; UINT32 adc_length, adc_transferred; UINT8 dma_autoinit; UINT8 data[128], d_wptr, d_rptr; bool dma_timer_started; bool dma_throttled; UINT8 flags; UINT8 irq_active; bool adpcm_new_ref; UINT8 adpcm_ref; UINT8 adpcm_step; UINT8 adpcm_count; }; struct sb8_mixer { UINT8 status; UINT8 main_vol; UINT8 dac_vol; UINT8 fm_vol; UINT8 mic_vol; UINT8 in_filter; UINT8 stereo_sel; UINT8 cd_vol; UINT8 line_vol; }; struct sb16_mixer { UINT8 data; UINT8 status; UINT8 main_vol[2]; UINT8 dac_vol[2]; UINT8 fm_vol[2]; UINT8 cd_vol[2]; UINT8 line_vol[2]; UINT8 mic_vol; UINT8 pc_speaker_vol; UINT8 output_ctl; UINT8 input_ctl[2]; UINT8 input_gain[2]; UINT8 output_gain[2]; UINT8 agc; UINT8 treble[2]; UINT8 bass[2]; }; // ======================> sb_device (parent) class sb_device : public device_t, public device_serial_interface { public: // construction/destruction sb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, const char *name, const char *shortname, const char *source); required_device m_dacl; required_device m_dacr; required_device m_joy; required_device m_mdout; void process_fifo(UINT8 cmd); void queue(UINT8 data); void queue_r(UINT8 data); UINT8 dequeue_r(); DECLARE_READ8_MEMBER(dsp_reset_r); DECLARE_WRITE8_MEMBER(dsp_reset_w); DECLARE_READ8_MEMBER(dsp_data_r); DECLARE_WRITE8_MEMBER(dsp_data_w); DECLARE_READ8_MEMBER(dsp_rbuf_status_r); DECLARE_READ8_MEMBER(dsp_wbuf_status_r); DECLARE_WRITE8_MEMBER(dsp_rbuf_status_w); DECLARE_WRITE8_MEMBER(dsp_cmd_w); DECLARE_WRITE_LINE_MEMBER( midi_rx_w ) { device_serial_interface::rx_w((UINT8)state); } protected: // device-level overrides virtual void device_reset(); UINT8 dack_r(int line); void dack_w(int line, UINT8 data); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); virtual void drq16_w(int state) { } virtual void drq_w(int state) { } virtual void irq_w(int state, int source) { } virtual void mixer_reset() {} void adpcm_decode(UINT8 sample, int size); // serial overrides virtual void rcv_complete(); // Rx completed receiving byte virtual void tra_complete(); // Tx completed sending byte virtual void tra_callback(); // Tx send bit void input_callback(UINT8 state) {} static const int MIDI_RING_SIZE = 2048; struct sb8_dsp_state m_dsp; UINT8 m_dack_out; void xmit_char(UINT8 data); bool m_onebyte_midi, m_uart_midi, m_uart_irq, m_mpu_midi; int m_rx_waiting, m_tx_waiting; UINT8 m_recvring[MIDI_RING_SIZE]; UINT8 m_xmitring[MIDI_RING_SIZE]; int m_xmit_read, m_xmit_write; int m_recv_read, m_recv_write; bool m_tx_busy; emu_timer *m_timer; }; class sb8_device : public sb_device, public device_isa8_card_interface { public: // construction/destruction sb8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, const char *name, const char *shortname, const char *source); protected: virtual void device_start(); virtual void drq_w(int state) { m_isa->drq1_w(state); } virtual void irq_w(int state, int source) { m_isa->irq5_w(state); } virtual UINT8 dack_r(int line) { return sb_device::dack_r(line); } virtual void dack_w(int line, UINT8 data) { sb_device::dack_w(line, data); } }; class isa8_sblaster1_0_device : public sb8_device { public: // construction/destruction isa8_sblaster1_0_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // optional information overrides virtual machine_config_constructor device_mconfig_additions() const; protected: // device-level overrides virtual void device_start(); private: // internal state }; class isa8_sblaster1_5_device : public sb8_device { public: // construction/destruction isa8_sblaster1_5_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // optional information overrides virtual machine_config_constructor device_mconfig_additions() const; protected: // device-level overrides virtual void device_start(); private: // internal state }; class sb16_device : public sb_device, public device_isa16_card_interface { public: // construction/destruction sb16_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, const char *name, const char *shortname, const char *source); DECLARE_READ8_MEMBER(mpu401_r); DECLARE_WRITE8_MEMBER(mpu401_w); DECLARE_READ8_MEMBER(mixer_r); DECLARE_WRITE8_MEMBER(mixer_w); protected: virtual void device_start(); virtual UINT16 dack16_r(int line); virtual UINT8 dack_r(int line) { return sb_device::dack_r(line); } virtual void dack_w(int line, UINT8 data) { sb_device::dack_w(line, data); } virtual void dack16_w(int line, UINT16 data); virtual void drq16_w(int state) { m_isa->drq5_w(state); } virtual void drq_w(int state) { m_isa->drq1_w(state); } virtual void irq_w(int state, int source) { (state?m_dsp.irq_active|=source:m_dsp.irq_active&=~source); m_isa->irq5_w(m_dsp.irq_active); } virtual void mixer_reset(); void mixer_set(); virtual void rcv_complete(); // Rx completed receiving byte private: struct sb16_mixer m_mixer; }; class isa16_sblaster16_device : public sb16_device { public: // construction/destruction isa16_sblaster16_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // optional information overrides virtual machine_config_constructor device_mconfig_additions() const; protected: // device-level overrides virtual void device_start(); private: // internal state }; // device type definition extern const device_type ISA8_SOUND_BLASTER_1_0; extern const device_type ISA8_SOUND_BLASTER_1_5; extern const device_type ISA16_SOUND_BLASTER_16; #endif /* __ISA_SOUND_BLASTER_H__ */