mirror of
https://github.com/holub/mame
synced 2025-07-04 09:28:51 +03:00
[mess] partially implement sb16 mixer
fixes Simcity 2000
This commit is contained in:
parent
91df0549a3
commit
732a6d11f5
@ -715,41 +715,242 @@ WRITE8_MEMBER( sb16_device::mpu401_w )
|
||||
|
||||
}
|
||||
|
||||
READ8_MEMBER( sb_device::mixer_r )
|
||||
void sb16_device::mixer_set()
|
||||
{
|
||||
if(offset == 0)
|
||||
return m_mixer_index;
|
||||
switch(m_mixer_index)
|
||||
{
|
||||
case 0: // reset
|
||||
return 0;
|
||||
default:
|
||||
if(m_dsp.version >= 0x0400)
|
||||
{
|
||||
switch(m_mixer_index)
|
||||
{
|
||||
case 0x82: // irqs
|
||||
return m_dsp.irq_active;
|
||||
}
|
||||
}
|
||||
}
|
||||
logerror("SB: Unimplemented read mixer command %02x\n", m_mixer_index);
|
||||
return 0;
|
||||
ymf262_device *ymf = subdevice<ymf262_device>("ymf262");
|
||||
float lmain = m_mixer.main_vol[0]/248.0;
|
||||
float rmain = m_mixer.main_vol[1]/248.0;
|
||||
m_dacl->set_output_gain(ALL_OUTPUTS, lmain*(m_mixer.dac_vol[0]/248.0));
|
||||
m_dacr->set_output_gain(ALL_OUTPUTS, rmain*(m_mixer.dac_vol[1]/248.0));
|
||||
ymf->set_output_gain(0, lmain*(m_mixer.fm_vol[0]/248.0));
|
||||
ymf->set_output_gain(1, rmain*(m_mixer.fm_vol[1]/248.0));
|
||||
ymf->set_output_gain(2, lmain*(m_mixer.fm_vol[0]/248.0));
|
||||
ymf->set_output_gain(3, rmain*(m_mixer.fm_vol[1]/248.0));
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sb_device::mixer_w )
|
||||
void sb16_device::mixer_reset()
|
||||
{
|
||||
m_mixer.status = 0x80;
|
||||
m_mixer.main_vol[0] = 0xc0;
|
||||
m_mixer.main_vol[1] = 0xc0;
|
||||
m_mixer.dac_vol[0] = 0xc0;
|
||||
m_mixer.dac_vol[1] = 0xc0;
|
||||
m_mixer.fm_vol[0] = 0xc0;
|
||||
m_mixer.fm_vol[1] = 0xc0;
|
||||
m_mixer.cd_vol[0] = 0x00;
|
||||
m_mixer.cd_vol[1] = 0x00;
|
||||
m_mixer.line_vol[0] = 0x00;
|
||||
m_mixer.line_vol[1] = 0x00;
|
||||
m_mixer.mic_vol = 0x00;
|
||||
m_mixer.pc_speaker_vol = 0x00;
|
||||
m_mixer.output_ctl = 0x1f;
|
||||
m_mixer.input_ctl[0] = 0x15;
|
||||
m_mixer.input_ctl[1] = 0x0b;
|
||||
m_mixer.input_gain[0] = 0x00;
|
||||
m_mixer.input_gain[1] = 0x00;
|
||||
m_mixer.output_gain[0] = 0x00;
|
||||
m_mixer.output_gain[1] = 0x00;
|
||||
m_mixer.agc = 0x00;
|
||||
m_mixer.treble[0] = 0x80;
|
||||
m_mixer.treble[1] = 0x80;
|
||||
m_mixer.bass[0] = 0x80;
|
||||
m_mixer.bass[1] = 0x80;
|
||||
mixer_set();
|
||||
}
|
||||
|
||||
READ8_MEMBER( sb16_device::mixer_r )
|
||||
{
|
||||
if(offset == 0)
|
||||
return m_mixer.status;
|
||||
return m_mixer.data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sb16_device::mixer_w )
|
||||
{
|
||||
if(offset == 0)
|
||||
{
|
||||
m_mixer_index = data;
|
||||
return;
|
||||
}
|
||||
switch(m_mixer_index)
|
||||
switch(data)
|
||||
{
|
||||
case 0: // reset
|
||||
case 0x00:
|
||||
mixer_reset();
|
||||
return;
|
||||
case 0x01:
|
||||
m_mixer.data = m_mixer.status;
|
||||
break;
|
||||
case 0x04:
|
||||
m_mixer.data = (m_mixer.dac_vol[0] & 0xf0) | (m_mixer.dac_vol[1] >> 4);
|
||||
break;
|
||||
case 0x0a:
|
||||
m_mixer.data = m_mixer.mic_vol >> 5;
|
||||
break;
|
||||
case 0x22:
|
||||
m_mixer.data = (m_mixer.main_vol[0] & 0xf0) | (m_mixer.main_vol[1] >> 4);
|
||||
break;
|
||||
case 0x26:
|
||||
m_mixer.data = (m_mixer.fm_vol[0] & 0xf0) | (m_mixer.fm_vol[1] >> 4);
|
||||
break;
|
||||
case 0x28:
|
||||
m_mixer.data = (m_mixer.cd_vol[0] & 0xf0) | (m_mixer.cd_vol[1] >> 4);
|
||||
break;
|
||||
case 0x2e:
|
||||
m_mixer.data = (m_mixer.line_vol[0] & 0xf0) | (m_mixer.line_vol[1] >> 4);
|
||||
break;
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
m_mixer.data = m_mixer.main_vol[data & 1];
|
||||
break;
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
m_mixer.data = m_mixer.dac_vol[data & 1];
|
||||
break;
|
||||
case 0x34:
|
||||
case 0x35:
|
||||
m_mixer.data = m_mixer.fm_vol[data & 1];
|
||||
break;
|
||||
case 0x36:
|
||||
case 0x37:
|
||||
m_mixer.data = m_mixer.cd_vol[data & 1];
|
||||
break;
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
m_mixer.data = m_mixer.line_vol[data & 1];
|
||||
break;
|
||||
case 0x3a:
|
||||
m_mixer.data = m_mixer.mic_vol;
|
||||
break;
|
||||
case 0x3b:
|
||||
m_mixer.data = m_mixer.pc_speaker_vol;
|
||||
break;
|
||||
case 0x3c:
|
||||
m_mixer.data = m_mixer.output_ctl;
|
||||
break;
|
||||
case 0x3d:
|
||||
case 0x3e:
|
||||
m_mixer.data = m_mixer.input_ctl[(data + 1) & 1];
|
||||
break;
|
||||
case 0x3f:
|
||||
case 0x40:
|
||||
m_mixer.data = m_mixer.input_gain[(data + 1) & 1];
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
m_mixer.data = m_mixer.output_gain[(data + 1) & 1];
|
||||
break;
|
||||
case 0x43:
|
||||
m_mixer.data = m_mixer.agc;
|
||||
break;
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
m_mixer.data = m_mixer.treble[data & 1];
|
||||
break;
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
m_mixer.data = m_mixer.bass[data & 1];
|
||||
break;
|
||||
case 0x80:
|
||||
m_mixer.data = 0x12; // irq5
|
||||
break;
|
||||
case 0x81:
|
||||
m_mixer.data = 0x22; // dma1&5
|
||||
break;
|
||||
case 0x82:
|
||||
m_mixer.data = m_dsp.irq_active | 0x20;
|
||||
break;
|
||||
default:
|
||||
logerror("SB: Unimplemented mixer index %02x\n", data);
|
||||
m_mixer.status = data | 0x80;
|
||||
m_mixer.data = 0x0a;
|
||||
return;
|
||||
}
|
||||
logerror("SB: Unimplemented write mixer command %02x\n", m_mixer_index);
|
||||
m_mixer.status = data;
|
||||
return;
|
||||
}
|
||||
switch(m_mixer.status)
|
||||
{
|
||||
case 0x04:
|
||||
m_mixer.dac_vol[0] = (data & 0xf0) | 8;
|
||||
m_mixer.dac_vol[1] = (data << 4) | 8;
|
||||
break;
|
||||
case 0x0a:
|
||||
m_mixer.mic_vol = (data << 5) | 0x18;
|
||||
break;
|
||||
case 0x22:
|
||||
m_mixer.main_vol[0] = (data & 0xf0) | 8;
|
||||
m_mixer.main_vol[1] = (data << 4) | 8;
|
||||
break;
|
||||
case 0x26:
|
||||
m_mixer.fm_vol[0] = (data & 0xf0) | 8;
|
||||
m_mixer.fm_vol[1] = (data << 4) | 8;
|
||||
break;
|
||||
case 0x28:
|
||||
m_mixer.cd_vol[0] = (data & 0xf0) | 8;
|
||||
m_mixer.cd_vol[1] = (data << 4) | 8;
|
||||
break;
|
||||
case 0x2e:
|
||||
m_mixer.line_vol[0] = (data & 0xf0) | 8;
|
||||
m_mixer.line_vol[1] = (data << 4) | 8;
|
||||
break;
|
||||
case 0x30:
|
||||
case 0x31:
|
||||
m_mixer.main_vol[m_mixer.status & 1] = data & 0xf8;
|
||||
break;
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
m_mixer.dac_vol[m_mixer.status & 1] = data & 0xf8;
|
||||
break;
|
||||
case 0x34:
|
||||
case 0x35:
|
||||
m_mixer.fm_vol[m_mixer.status & 1] = data & 0xf8;
|
||||
break;
|
||||
case 0x36:
|
||||
case 0x37:
|
||||
m_mixer.cd_vol[m_mixer.status & 1] = data & 0xf8;
|
||||
break;
|
||||
case 0x38:
|
||||
case 0x39:
|
||||
m_mixer.line_vol[m_mixer.status & 1] = data & 0xf8;
|
||||
break;
|
||||
case 0x3a:
|
||||
m_mixer.mic_vol = data & 0xf8;
|
||||
break;
|
||||
case 0x3b:
|
||||
m_mixer.pc_speaker_vol = data & 0xc0;
|
||||
break;
|
||||
case 0x3c:
|
||||
m_mixer.output_ctl = data & 0x1f;
|
||||
break;
|
||||
case 0x3d:
|
||||
case 0x3e:
|
||||
m_mixer.input_ctl[(m_mixer.status + 1) & 1] = data & 0x7f;
|
||||
break;
|
||||
case 0x3f:
|
||||
case 0x40:
|
||||
m_mixer.input_gain[(m_mixer.status + 1) & 1] = data & 0xc0;
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
m_mixer.output_gain[(m_mixer.status + 1) & 1] = data & 0xc0;
|
||||
break;
|
||||
case 0x43:
|
||||
m_mixer.agc = data & 1;
|
||||
break;
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
m_mixer.treble[m_mixer.status & 1] = data & 0xf0;
|
||||
break;
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
m_mixer.bass[m_mixer.status & 1] = data & 0xf0;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
// don't support these yet
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
m_mixer.data = data;
|
||||
mixer_set();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -837,7 +1038,7 @@ void sb8_device::device_start()
|
||||
m_isa->install_device( 0x022e, 0x022f, 0, 0, read8_delegate(FUNC(sb_device::dsp_rbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_rbuf_status_w), this) );
|
||||
if(m_dsp.version >= 0x0301)
|
||||
{
|
||||
m_isa->install_device(0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb_device::mixer_r), this), write8_delegate(FUNC(sb_device::mixer_w), this));
|
||||
//m_isa->install_device(0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb8_device::mixer_r), this), write8_delegate(FUNC(sb8_device::mixer_w), this));
|
||||
m_isa->install_device(subdevice("ymf262"), 0x0388, 0x038b, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) );
|
||||
m_isa->install_device(subdevice("ymf262"), 0x0220, 0x0223, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) );
|
||||
m_isa->install_device(subdevice("ymf262"), 0x0228, 0x0229, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) );
|
||||
@ -874,7 +1075,7 @@ void isa8_sblaster1_5_device::device_start()
|
||||
void sb16_device::device_start()
|
||||
{
|
||||
m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("joy")));
|
||||
m_isa->install_device( 0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb_device::mixer_r), this), write8_delegate(FUNC(sb_device::mixer_w), this));
|
||||
m_isa->install_device( 0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb16_device::mixer_r), this), write8_delegate(FUNC(sb16_device::mixer_w), this));
|
||||
m_isa->install_device( 0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this));
|
||||
m_isa->install_device( 0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) );
|
||||
m_isa->install_device( 0x022c, 0x022d, 0, 0, read8_delegate(FUNC(sb_device::dsp_wbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_cmd_w), this) );
|
||||
@ -913,8 +1114,8 @@ void sb_device::device_reset()
|
||||
m_dsp.rbuf_status = 0;
|
||||
m_dsp.frequency = 8000; // per stereo-fx
|
||||
m_dsp.irq_active = 0;
|
||||
m_mixer_index = 0;
|
||||
m_dsp.dma_no_irq = false;
|
||||
mixer_reset();
|
||||
}
|
||||
|
||||
UINT8 sb_device::dack_r(int line)
|
||||
|
@ -53,6 +53,39 @@ struct sb8_dsp_state
|
||||
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];
|
||||
};
|
||||
|
||||
// ======================> sb8_device (parent)
|
||||
|
||||
class sb_device :
|
||||
@ -79,8 +112,6 @@ public:
|
||||
DECLARE_READ8_MEMBER(dsp_wbuf_status_r);
|
||||
DECLARE_WRITE8_MEMBER(dsp_rbuf_status_w);
|
||||
DECLARE_WRITE8_MEMBER(dsp_cmd_w);
|
||||
DECLARE_READ8_MEMBER(mixer_r);
|
||||
DECLARE_WRITE8_MEMBER(mixer_w);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -91,11 +122,11 @@ protected:
|
||||
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);
|
||||
|
||||
struct sb8_dsp_state m_dsp;
|
||||
UINT8 m_dack_out;
|
||||
UINT8 m_mixer_index;
|
||||
|
||||
emu_timer *m_timer;
|
||||
};
|
||||
@ -154,6 +185,8 @@ public:
|
||||
sb16_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, const char *name);
|
||||
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);
|
||||
@ -163,10 +196,13 @@ protected:
|
||||
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();
|
||||
private:
|
||||
UINT8 m_mpu_queue[16];
|
||||
UINT8 m_tail;
|
||||
UINT8 m_head;
|
||||
struct sb16_mixer m_mixer;
|
||||
};
|
||||
|
||||
class isa16_sblaster16_device : public sb16_device
|
||||
|
Loading…
Reference in New Issue
Block a user