diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 7bf1ffdd9..ecabe426d 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -33,6 +33,10 @@ typedef struct sb_dsp_t { int sb_16_autolen; int sb_16_output; int sb_16_dmanum; + int sb_16_8_dmanum; + int sb_16_dma_enabled; + int sb_16_dma_supported; + int sb_16_dma_translate; int sb_pausetime; int (*dma_readb)(void *priv); int (*dma_readw)(void *priv); @@ -127,8 +131,6 @@ typedef struct sb_dsp_t { int16_t buffer[SOUNDBUFLEN * 2]; int pos; - uint8_t dma16through8; - uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; /* the eeprom in the Aztech cards is attached to the DSP */ mpu_t *mpu; @@ -146,7 +148,10 @@ extern void sb_dsp_close(sb_dsp_t *dsp); extern void sb_dsp_setirq(sb_dsp_t *dsp, int irq); extern void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); extern void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); -extern void sb_dsp_setdma16through8(sb_dsp_t *dsp, int dma16through8); +extern void sb_dsp_setdma16_8(sb_dsp_t *dsp, int dma); +extern void sb_dsp_setdma16_enabled(sb_dsp_t *dsp, int enabled); +extern void sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported); +extern void sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate); extern void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); extern void sb_dsp_speed_changed(sb_dsp_t *dsp); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index d620d73ad..bb889921b 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -939,10 +939,10 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) case 0xff: if (sb->dsp.sb_type >= SBAWE32) { - if (val & 0x20) - sb_dsp_setdma16(&sb->dsp, 4); - else - sb_dsp_setdma16(&sb->dsp, val & 0x07); + if (val != ISAPNP_DMA_DISABLED) + sb_dsp_setdma16_8(&sb->dsp, val & 0x07); + sb_dsp_setdma16_enabled(&sb->dsp, !(val & 0x20)); + sb_dsp_setdma16_translate(&sb->dsp, val != ISAPNP_DMA_DISABLED); } break; @@ -1691,8 +1691,14 @@ sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void * sb_dsp_setdma8(&sb->dsp, val); val = config->dma[1].dma; - if (val != ISAPNP_DMA_DISABLED) - sb_dsp_setdma16(&sb->dsp, val); + sb_dsp_setdma16_enabled(&sb->dsp, val != ISAPNP_DMA_DISABLED); + sb_dsp_setdma16_translate(&sb->dsp, val < ISAPNP_DMA_DISABLED); + if (val != ISAPNP_DMA_DISABLED) { + if (sb->dsp.sb_16_dma_supported) + sb_dsp_setdma16(&sb->dsp, val); + else + sb_dsp_setdma16_8(&sb->dsp, val); + } } break; @@ -2158,6 +2164,7 @@ sb_16_init(UNUSED(const device_t *info)) sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -2211,6 +2218,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; @@ -2252,6 +2260,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; @@ -2314,8 +2323,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ - if (info->local == 0) - sb_dsp_setdma16through8(&sb->dsp, 1); + sb_dsp_setdma16_supported(&sb->dsp, info->local != 0); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; @@ -2392,6 +2400,7 @@ sb_16_compat_init(const device_t *info) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; @@ -2464,6 +2473,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); if (sb->opl_enabled) { @@ -2524,6 +2534,7 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_init(&sb->dsp, ((info->local == 2) || (info->local == 3) || (info->local == 4)) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); sb->mixer_enabled = 1; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index f15c3f335..486d6eda6 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -423,6 +423,18 @@ sb_8_write_dma(void *priv, uint8_t val) return dma_channel_write(dsp->sb_8_dmanum, val) == DMA_NODATA; } +/* + Supported High DMA Translation Channel + ---------------------------------------------------- + 0 0 0 First 8-bit + 0 0 1 First 8-bit + 0 1 0 Second 8-bit + 0 1 1 Second 8-bit + 1 0 0 First 8-bit + 1 0 1 First 8-bit + 1 1 0 16-bit + 1 1 1 Second 8-bit + */ int sb_16_read_dma(void *priv) { @@ -430,8 +442,16 @@ sb_16_read_dma(void *priv) int temp, ret = 0; int dma_flags, dma_ch = dsp->sb_16_dmanum; - if (dsp->dma16through8 || (dsp->sb_16_dmanum == 4)) { - if (dma_ch == 4) + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_read(dma_ch); + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; temp = dma_channel_read(dma_ch); ret = temp; @@ -445,8 +465,7 @@ sb_16_read_dma(void *priv) ret |= (temp << 8) | dma_flags; } } - } else - ret = dma_channel_read(dsp->sb_16_dmanum); + } return ret; } @@ -458,8 +477,16 @@ sb_16_write_dma(void *priv, uint16_t val) int temp, ret = 0; int dma_ch = dsp->sb_16_dmanum; - if (dsp->dma16through8 || (dsp->sb_16_dmanum == 4)) { - if (dma_ch == 4) + if (dsp->sb_16_dma_enabled && dsp->sb_16_dma_supported && !dsp->sb_16_dma_translate) + ret = dma_channel_write(dma_ch, val) == DMA_NODATA; + else { + if (dsp->sb_16_dma_enabled) { + /* High DMA channel enabled, either translation is enabled or + 16-bit transfers are not supported. */ + if (dsp->sb_16_dma_translate || !dsp->sb_16_dma_supported) + dma_ch = dsp->sb_16_8_dmanum; + } else + /* High DMA channel disabled, always use the first 8-bit channel. */ dma_ch = dsp->sb_8_dmanum; temp = dma_channel_write(dma_ch, val & 0xff); ret = temp; @@ -467,8 +494,7 @@ sb_16_write_dma(void *priv, uint16_t val) temp = dma_channel_write(dma_ch, val >> 8); ret = temp; } - } else - ret = dma_channel_write(dsp->sb_16_dmanum, val) == DMA_NODATA; + } return ret; } @@ -479,24 +505,48 @@ sb_dsp_setirq(sb_dsp_t *dsp, int irq) dsp->sb_irqnum = irq; } -void -sb_dsp_setdma16through8(sb_dsp_t *dsp, int dma16through8) -{ - dsp->dma16through8 = dma16through8; -} - void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { + sb_dsp_log("8-bit DMA now: %i\n", dma); dsp->sb_8_dmanum = dma; } void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) { + sb_dsp_log("16-bit DMA now: %i\n", dma); dsp->sb_16_dmanum = dma; } +void +sb_dsp_setdma16_8(sb_dsp_t *dsp, int dma) +{ + sb_dsp_log("16-bit to 8-bit translation DMA now: %i\n", dma); + dsp->sb_16_8_dmanum = dma; +} + +void +sb_dsp_setdma16_enabled(sb_dsp_t *dsp, int enabled) +{ + sb_dsp_log("16-bit DMA now: %sabled\n", enabled ? "en" : "dis"); + dsp->sb_16_dma_enabled = enabled; +} + +void +sb_dsp_setdma16_supported(sb_dsp_t *dsp, int supported) +{ + sb_dsp_log("16-bit DMA now: %ssupported\n", supported ? "" : "not "); + dsp->sb_16_dma_supported = supported; +} + +void +sb_dsp_setdma16_translate(sb_dsp_t *dsp, int translate) +{ + sb_dsp_log("16-bit to 8-bit translation now: %sabled\n", translate ? "en" : "dis"); + dsp->sb_16_dma_translate = translate; +} + void sb_exec_command(sb_dsp_t *dsp) {