diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index 1ab94c9e1..b26c5f06e 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -142,6 +142,7 @@ typedef struct ess_mixer_t { double mic_r; double auxb_l; double auxb_r; + double speaker; /*see sb_ct1745_mixer for values for input selector*/ int32_t input_selector; /* extra values for input selector */ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f5905ccc2..a00f512a3 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -7,11 +7,10 @@ #define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ #define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_ESS_ES688 3 /* ESS Technology ES688 */ -#define SB_SUBTYPE_ESS_ES1688 4 /* ESS Technology ES1688 */ +#define SB_SUBTYPE_ESS_ES1688 3 /* ESS Technology ES1688 */ /* ESS-related */ -#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES688 || (dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ +#define IS_ESS(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_ESS_ES1688) /* check for future ESS cards here */ /* aztech-related */ #define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) /* check for future AZT cards here */ @@ -149,13 +148,15 @@ typedef struct sb_dsp_t { uint8_t ess_extended_mode; uint8_t ess_reload_len; uint32_t ess_dma_counter; - int ess_irq_generic; - int ess_irq_dmactr; - // ESPCM + /* IRQ status flags (0x22C) */ + uint8_t ess_irq_generic; + uint8_t ess_irq_dmactr; + + /* ESPCM */ fifo64_t *espcm_fifo; - int espcm_fifo_reset; - int espcm_mode; + uint8_t espcm_fifo_reset; + uint8_t espcm_mode; /* see ESPCM in "NON-PCM SAMPLE FORMATS" deflist in snd_sb_dsp.c */ uint8_t espcm_sample_idx; uint8_t espcm_range; uint8_t espcm_byte_buffer[4]; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index c36ec4160..78cbec11d 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -42,7 +42,6 @@ typedef struct { int8_t flags; int8_t pad; - uint16_t port; uint8_t status; uint8_t timer_ctrl; uint16_t timer_count[2]; @@ -269,14 +268,12 @@ esfm_drv_read(uint16_t port, void *priv) static void esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) { - uint16_t p = dev->port; - - ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); + uint16_t p = dev->opl.addr_latch & 0x07ff; if (dev->opl.native_mode) { p -= 0x400; - p &= 0x1ff; } + p &= 0x1ff; switch (p) { case 0x002: /* Timer 1 */ @@ -304,6 +301,8 @@ esfm_drv_write_buffered(esfm_drv_t *dev, uint8_t val) default: break; } + + ESFM_write_reg_buffered_fast(&dev->opl, dev->opl.addr_latch, val); } static void @@ -321,14 +320,12 @@ esfm_drv_write(uint16_t port, uint8_t val, void *priv) esfm_drv_write_buffered(dev, val); else { ESFM_write_port(&dev->opl, port & 3, val); - dev->port = dev->opl.addr_latch & 0x07ff; } } else { if ((port & 0x0001) == 0x0001) esfm_drv_write_buffered(dev, val); else { ESFM_write_port(&dev->opl, port & 3, val); - dev->port = dev->opl.addr_latch & 0x01ff; } } } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 61dbc8c7a..f26fba1eb 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -89,6 +89,11 @@ static const double sb_att_2dbstep_4bits[] = { 164.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 }; + +/* Attenuation table for ESS 3-bit PC speaker volume. */ +static const double sb_att_3dbstep_3bits[] = { + 0.0, 4125.0, 5826.0, 8230.0, 11626.0, 16422.0, 23197.0, 32767.0 +}; // clang-format on static const uint16_t sb_mcv_addr[8] = { 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270 }; @@ -730,12 +735,10 @@ sb_get_music_buffer_ess(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - { - out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; - out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; - if (ess->opl_mix && ess->opl_mixer) - ess->opl_mix(ess->opl_mixer, &out_l, &out_r); - } + out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; + out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375; + if (ess->opl_mix && ess->opl_mixer) + ess->opl_mix(ess->opl_mixer, &out_l, &out_r); /* TODO: recording from the mixer. */ out_l *= mixer->master_l; @@ -1421,11 +1424,12 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x26] = mixer->regs[0x28] = 0xee; mixer->regs[0x2e] = 0x00; - /* Initialize ESS regs. */ - mixer->regs[0x14] = mixer->regs[0x32] = 0x88; - mixer->regs[0x36] = 0x88; - mixer->regs[0x38] = 0x88; + /* Initialize ESS regs + * Defaulting to 0dB instead of the standard -11dB. */ + mixer->regs[0x14] = mixer->regs[0x32] = 0xff; + mixer->regs[0x36] = mixer->regs[0x38] = 0xff; mixer->regs[0x3a] = 0x00; + mixer->regs[0x3c] = 0x05; mixer->regs[0x3e] = 0x00; sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); @@ -1460,6 +1464,14 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->input_selector = INPUT_MIC; break; } + mixer->input_filter = !(mixer->regs[0xC] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xC] & 0x8) == 0) ? 3200 : 8800; + break; + + case 0x0E: + mixer->output_filter = !(mixer->regs[0xE] & 0x20); + mixer->stereo = mixer->regs[0xE] & 2; + sb_dsp_set_stereo(&ess->dsp, val & 2); break; case 0x14: @@ -1495,8 +1507,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ case 0x30: - mixer->regs[mixer->index - 0x10] = (val & 0xee); - break; case 0x32: case 0x36: case 0x38: @@ -1505,15 +1515,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x3a: + case 0x3c: break; case 0x00: case 0x04: break; - case 0x0e: - break; - case 0x64: mixer->regs[mixer->index] &= ~0x8; break; @@ -1587,19 +1595,13 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->fm_r = sb_att_2dbstep_4bits[mixer->regs[0x36] & 0x0F] / 32767.0; mixer->cd_l = sb_att_2dbstep_4bits[(mixer->regs[0x38] >> 4) & 0x0F] / 32767.0; mixer->cd_r = sb_att_2dbstep_4bits[mixer->regs[0x38] & 0x0F] / 32767.0; - mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; - mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; mixer->auxb_l = sb_att_2dbstep_4bits[(mixer->regs[0x3a] >> 4) & 0x0F] / 32767.0; mixer->auxb_r = sb_att_2dbstep_4bits[mixer->regs[0x3a] & 0x0F] / 32767.0; + mixer->line_l = sb_att_2dbstep_4bits[(mixer->regs[0x3e] >> 4) & 0x0F] / 32767.0; + mixer->line_r = sb_att_2dbstep_4bits[mixer->regs[0x3e] & 0x0F] / 32767.0; + mixer->speaker = sb_att_3dbstep_3bits[mixer->regs[0x3c] & 0x07] / 32767.0; - mixer->output_filter = !(mixer->regs[0xe] & 0x20); - mixer->input_filter = !(mixer->regs[0xc] & 0x20); - mixer->in_filter_freq = ((mixer->regs[0xc] & 0x8) == 0) ? 3200 : 8800; - mixer->stereo = mixer->regs[0xe] & 2; - if (mixer->index == 0xe) - sb_dsp_set_stereo(&ess->dsp, val & 2); - - /* TODO: pcspeaker volume? Or is it not worth? */ + /* TODO: PC Speaker volume */ } } diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index ad6209fb5..332299c4f 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -29,11 +29,13 @@ #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +/* NON-PCM SAMPLE FORMATS */ #define ADPCM_4 1 #define ADPCM_26 2 #define ADPCM_2 3 #define ESPCM_4 4 #define ESPCM_3 5 +/* ESPCM_2? */ #define ESPCM_1 7 #define ESPCM_4E 8 // for differentiating between 4-bit encoding and decoding modes @@ -1596,10 +1598,6 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_subtype) { default: break; - case SB_SUBTYPE_ESS_ES688: - sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x04); - break; case SB_SUBTYPE_ESS_ES1688: // Determined via Windows driver debugging. sb_add_data(dsp, 0x68); @@ -1792,11 +1790,11 @@ sb_read(uint16_t a, void *priv) } uint8_t busy_flag = dsp->wb_full ? 0x80 : 0x00; uint8_t data_rdy = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x40; - uint8_t fifo_full = 0; // Unimplemented - uint8_t fifo_empty = 0; - uint8_t fifo_half = 0; + uint8_t fifo_full = 0; /* Unimplemented */ + uint8_t fifo_empty = 0; /* (this is for the 256-byte extended mode FIFO, */ + uint8_t fifo_half = 0; /* not the standard 64-byte FIFO) */ uint8_t irq_generic = dsp->ess_irq_generic ? 0x04 : 0x00; - uint8_t irq_fifohe = 0; // Unimplemented + uint8_t irq_fifohe = 0; /* Unimplemented (ditto) */ uint8_t irq_dmactr = dsp->ess_irq_dmactr ? 0x01 : 0x00; return busy_flag | data_rdy | fifo_full | fifo_empty | fifo_half | irq_generic | irq_fifohe | irq_dmactr;