A few bug fixes according to docs and fw

Also skeleton support for DSP versions
This commit is contained in:
Jasmine Iwanek
2025-01-09 01:07:26 -05:00
parent a2edcbfbba
commit a044223362
7 changed files with 137 additions and 109 deletions

View File

@@ -29,15 +29,19 @@
enum { enum {
SADLIB = 1, /* No DSP */ SADLIB = 1, /* No DSP */
SB1, /* DSP v1.05 */ SB_DSP_105, /* DSP v1.05, Original CT1320 (Also known as CT1310) */
SB15, /* DSP v2.00 */ SB_DSP_200, /* DSP v2.00 */
SB2, /* DSP v2.01 - needed for high-speed DMA */ SB_DSP_201, /* DSP v2.01 - needed for high-speed DMA, Seen on CT1350B with CT1336 */
SBPRO, /* DSP v3.00 */ SB_DSP_202, /* DSP v2.02 - Seen on CT1350B with CT1336A */
SBPRO2, /* DSP v3.02 + OPL3 */ SBPRO_DSP_300, /* DSP v3.00 */
SB16, /* DSP v4.05 + OPL3 */ SBPRO2_DSP_302, /* DSP v3.02 + OPL3 */
SBAWE32, /* DSP v4.12 + OPL3 */ SB16_DSP_404, /* DSP v4.05 + OPL3 */
SBAWE32PNP, /* DSP v4.13 + OPL3 */ SB16_DSP_405, /* DSP v4.05 + OPL3 */
SBAWE64 /* DSP v4.16 + OPL3 */ SB16_DSP_406, /* DSP v4.06 + OPL3 */
SB16_DSP_411, /* DSP v4.11 + OPL3 */
SBAWE32_DSP_412, /* DSP v4.12 + OPL3 */
SBAWE32_DSP_413, /* DSP v4.13 + OPL3 */
SBAWE64_DSP_416 /* DSP v4.16 + OPL3 */
}; };
/* SB 2.0 CD version */ /* SB 2.0 CD version */

View File

@@ -1238,7 +1238,7 @@ azt_init(const device_t *info)
fm_driver_get(FM_YMF262, &azt2316a->sb->opl); fm_driver_get(FM_YMF262, &azt2316a->sb->opl);
sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1); sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1);
sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); sb_dsp_init(&azt2316a->sb->dsp, SBPRO2_DSP_302, azt2316a->type, azt2316a);
sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr);
sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq);
sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma);

View File

@@ -497,7 +497,7 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv)
/* Set TDMA channels if auto-detection is enabled. */ /* Set TDMA channels if auto-detection is enabled. */
if ((dev->io_regs[0x27] & 0x01) && (mixer->index == 0x81)) { if ((dev->io_regs[0x27] & 0x01) && (mixer->index == 0x81)) {
dev->tdma_8 = dev->sb->dsp.sb_8_dmanum; dev->tdma_8 = dev->sb->dsp.sb_8_dmanum;
if (dev->sb->dsp.sb_type >= SB16) if (dev->sb->dsp.sb_type >= SB16_DSP_404)
dev->tdma_16 = dev->sb->dsp.sb_16_dmanum; dev->tdma_16 = dev->sb->dsp.sb_16_dmanum;
} }
} else { } else {
@@ -879,7 +879,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
dev->sb->dsp.sbleftright_default = !!(val & 0x02); dev->sb->dsp.sbleftright_default = !!(val & 0x02);
/* Enable or disable SB16 mode. */ /* Enable or disable SB16 mode. */
dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16; dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2_DSP_302 : SB16_DSP_405;
break; break;
case 0x22: case 0x22:

View File

@@ -394,7 +394,7 @@ optimc_init(const device_t *info)
optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262;
sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B); sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B);
sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc); sb_dsp_init(&optimc->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, optimc);
sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr);
sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq);
sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma);

View File

@@ -2314,7 +2314,7 @@ pas16_init(const device_t *info)
pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f); pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f);
fm_driver_get(FM_YMF262, &pas16->opl); fm_driver_get(FM_YMF262, &pas16->opl);
sb_dsp_set_real_opl(&pas16->dsp, 1); sb_dsp_set_real_opl(&pas16->dsp, 1);
sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); sb_dsp_init(&pas16->dsp, SB_DSP_201, SB_SUBTYPE_DEFAULT, pas16);
pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t));
memset(pas16->mpu, 0, sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t));
mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));

View File

@@ -292,7 +292,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
if (!sb->opl_enabled) if (!sb->opl_enabled)
return; return;
if (sb->dsp.sb_type == SBPRO) { if (sb->dsp.sb_type == SBPRO_DSP_300) {
opl_buf = sb->opl.update(sb->opl.priv); opl_buf = sb->opl.update(sb->opl.priv);
opl2_buf = sb->opl2.update(sb->opl2.priv); opl2_buf = sb->opl2.update(sb->opl2.priv);
} else } else
@@ -304,7 +304,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
out_l = 0.0; out_l = 0.0;
out_r = 0.0; out_r = 0.0;
if (sb->dsp.sb_type == SBPRO) { if (sb->dsp.sb_type == SBPRO_DSP_300) {
/* Two chips for LEFT and RIGHT channels. /* Two chips for LEFT and RIGHT channels.
Each chip stores data into the LEFT channel only (no sample alternating.) */ Each chip stores data into the LEFT channel only (no sample alternating.) */
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
@@ -326,7 +326,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
} }
sb->opl.reset_buffer(sb->opl.priv); sb->opl.reset_buffer(sb->opl.priv);
if (sb->dsp.sb_type == SBPRO) if (sb->dsp.sb_type == SBPRO_DSP_300)
sb->opl2.reset_buffer(sb->opl2.priv); sb->opl2.reset_buffer(sb->opl2.priv);
} }
@@ -1161,7 +1161,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
break; break;
case 0xff: case 0xff:
if ((sb->dsp.sb_type > SBAWE32) && !sb->dsp.sb_16_dma_supported) { if ((sb->dsp.sb_type > SBAWE32_DSP_412) && !sb->dsp.sb_16_dma_supported) {
/* /*
Bit 5: High DMA channel enabled (0 = yes, 1 = no); Bit 5: High DMA channel enabled (0 = yes, 1 = no);
Bit 2: ????; Bit 2: ????;
@@ -1345,7 +1345,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv)
/* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */
const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) |
((sb->dsp.sb_irq401) ? 4 : 0); ((sb->dsp.sb_irq401) ? 4 : 0);
if (sb->dsp.sb_type >= SBAWE32) if (sb->dsp.sb_type >= SBAWE32_DSP_412)
ret = temp | 0x80; ret = temp | 0x80;
else else
ret = temp | 0x40; ret = temp | 0x40;
@@ -1390,7 +1390,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv)
- Register FF = FF: Volume playback normal. - Register FF = FF: Volume playback normal.
- Register FF = Not FF: Volume playback low unless - Register FF = Not FF: Volume playback low unless
bit 6 of 82h is set. */ bit 6 of 82h is set. */
if (sb->dsp.sb_type > SBAWE32) if (sb->dsp.sb_type > SBAWE32_DSP_412)
ret = mixer->regs[mixer->index]; ret = mixer->regs[mixer->index];
break; break;
@@ -2223,7 +2223,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void
break; break;
case 2: /* Reserved (16) / WaveTable (32+) */ case 2: /* Reserved (16) / WaveTable (32+) */
if (sb->dsp.sb_type > SB16) if (sb->dsp.sb_type >= SBAWE32_DSP_412)
emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
break; break;
@@ -2839,17 +2839,17 @@ sb_init(UNUSED(const device_t *info))
switch (info->local) { switch (info->local) {
default: default:
case SB_1: case SB_1:
model = SB1; model = SB_DSP_105;
sb->cms_enabled = 1; sb->cms_enabled = 1;
break; break;
case SB_15: case SB_15:
model = SB15; model = SB_DSP_200;
sb->cms_enabled = device_get_config_int("cms"); sb->cms_enabled = device_get_config_int("cms");
break; break;
case SB_2: case SB_2:
model = SB2; model = SB_DSP_201;
sb->cms_enabled = device_get_config_int("cms"); sb->cms_enabled = device_get_config_int("cms");
mixer_addr = device_get_config_int("mixaddr"); mixer_addr = device_get_config_int("mixaddr");
break; break;
@@ -2871,7 +2871,7 @@ sb_init(UNUSED(const device_t *info))
/* DSP I/O handler is activated in sb_dsp_setaddr */ /* DSP I/O handler is activated in sb_dsp_setaddr */
if (sb->opl_enabled) { if (sb->opl_enabled) {
// TODO: See if this applies to the SB1.5 as well // TODO: See if this applies to the SB1.5 as well
if ((!sb->cms_enabled) && (model == SB2)) { if ((!sb->cms_enabled) && ((model == SB_DSP_201) || (model == SB_DSP_202))) {
io_sethandler(addr, 0x0002, io_sethandler(addr, 0x0002,
sb->opl.read, NULL, NULL, sb->opl.read, NULL, NULL,
sb->opl.write, NULL, NULL, sb->opl.write, NULL, NULL,
@@ -2928,7 +2928,7 @@ sb_mcv_init(UNUSED(const device_t *info))
fm_driver_get(FM_YM3812, &sb->opl); fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SB_DSP_105, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, 0); sb_dsp_setaddr(&sb->dsp, 0);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
@@ -2991,7 +2991,7 @@ sb_pro_v1_init(UNUSED(const device_t *info))
} }
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SBPRO_DSP_300, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
@@ -3049,7 +3049,7 @@ sb_pro_v2_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
@@ -3100,7 +3100,7 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb);
sb_ct1345_mixer_reset(sb); sb_ct1345_mixer_reset(sb);
sb->mixer_enabled = 1; sb->mixer_enabled = 1;
@@ -3127,7 +3127,7 @@ sb_pro_compat_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb);
sb_ct1345_mixer_reset(sb); sb_ct1345_mixer_reset(sb);
sb->mixer_enabled = 1; sb->mixer_enabled = 1;
@@ -3154,7 +3154,7 @@ sb_16_init(UNUSED(const device_t *info))
fm_driver_get((int) (intptr_t) info->local, &sb->opl); fm_driver_get((int) (intptr_t) info->local, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32_DSP_413 : SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
@@ -3216,7 +3216,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1);
sb_ct1745_mixer_reset(sb); sb_ct1745_mixer_reset(sb);
@@ -3270,7 +3270,7 @@ sb_16_pnp_init(UNUSED(const device_t *info))
sb->opl_enabled = 1; sb->opl_enabled = 1;
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_ct1745_mixer_reset(sb); sb_ct1745_mixer_reset(sb);
@@ -3373,7 +3373,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb);
/* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */
sb_dsp_setdma16_supported(&sb->dsp, info->local != SB_VIBRA16XV); sb_dsp_setdma16_supported(&sb->dsp, info->local != SB_VIBRA16XV);
sb_ct1745_mixer_reset(sb); sb_ct1745_mixer_reset(sb);
@@ -3469,7 +3469,7 @@ sb_16_compat_init(const device_t *info)
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1);
sb_ct1745_mixer_reset(sb); sb_ct1745_mixer_reset(sb);
@@ -3555,7 +3555,7 @@ sb_awe32_init(UNUSED(const device_t *info))
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1); sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, SBAWE32_DSP_412, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
@@ -3670,7 +3670,7 @@ sb_awe32_pnp_init(const device_t *info)
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
sb_dsp_init(&sb->dsp, (info->local >= SB_AWE64_VALUE) ? sb_dsp_init(&sb->dsp, (info->local >= SB_AWE64_VALUE) ?
SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_supported(&sb->dsp, 1);
sb_ct1745_mixer_reset(sb); sb_ct1745_mixer_reset(sb);
@@ -3803,7 +3803,7 @@ ess_x688_init(UNUSED(const device_t *info))
fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl);
sb_dsp_set_real_opl(&ess->dsp, 1); sb_dsp_set_real_opl(&ess->dsp, 1);
sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setaddr(&ess->dsp, addr);
sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma"));
@@ -3914,7 +3914,7 @@ ess_x688_pnp_init(UNUSED(const device_t *info))
fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl);
sb_dsp_set_real_opl(&ess->dsp, 1); sb_dsp_set_real_opl(&ess->dsp, 1);
sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
sb_dsp_setdma16_supported(&ess->dsp, 0); sb_dsp_setdma16_supported(&ess->dsp, 0);
ess_mixer_reset(ess); ess_mixer_reset(ess);
@@ -4000,7 +4000,7 @@ ess_x688_mca_init(UNUSED(const device_t *info))
fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl);
sb_dsp_set_real_opl(&ess->dsp, 1); sb_dsp_set_real_opl(&ess->dsp, 1);
sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess);
sb_dsp_setdma16_supported(&ess->dsp, 0); sb_dsp_setdma16_supported(&ess->dsp, 0);
ess_mixer_reset(ess); ess_mixer_reset(ess);

View File

@@ -77,25 +77,33 @@ static int sb_commands[256] = {
-1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0
}; };
#if 0
// Currently unused, here for reference if ever needed
char sb202_copyright[] = "COPYRIGHT(C) CREATIVE TECHNOLOGY PTE. LTD. (1991) "
#endif
char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
uint16_t sb_dsp_versions[] = { uint16_t sb_dsp_versions[] = {
0, /* Pad */ 0, /* Pad */
0, /* SADLIB - No DSP */ 0, /* SADLIB - No DSP */
0x105, /* SB1 - DSP v1.05 */ 0x105, /* SB_DSP_105 - SB1/1.5, DSP v1.05 */
0x200, /* SB15 - DSP v2.00 */ 0x200, /* SB_DSP_200 - SB1.5/2, DSP v2.00 */
0x201, /* SB2 - DSP v2.01 - needed for high-speed DMA */ 0x201, /* SB_DSP_201 - SB1.5/2, DSP v2.01 - needed for high-speed DMA */
0x300, /* SBPRO - DSP v3.00 */ 0x202, /* SB_DSP_202 - SB2, DSP v2.02 */
0x302, /* SBPRO2 - DSP v3.02 + OPL3 */ 0x300, /* SB_PRO_DSP_300 - SB Pro, DSP v3.00 */
0x405, /* SB16 - DSP v4.05 + OPL3 */ 0x302, /* SBPRO2_DSP_302 - SB Pro 2, DSP v3.02 + OPL3 */
0x40c, /* SBAWE32 - DSP v4.12 + OPL3 */ 0x404, /* SB16_DSP_404 - DSP v4.04 + OPL3 */
0x40d, /* SBAWE32PNP - DSP v4.13 + OPL3 */ 0x405, /* SB16_405 - DSP v4.05 + OPL3 */
0x410 /* SBAWE64 - DSP v4.16 + OPL3 */ 0x406, /* SB16_406 - DSP v4.06 + OPL3 */
0x40b, /* SB16_411 - DSP v4.11 + OPL3 */
0x40c, /* SBAWE32 - DSP v4.12 + OPL3 */
0x40d, /* SBAWE32PNP - DSP v4.13 + OPL3 */
0x410 /* SBAWE64 - DSP v4.16 + OPL3 */
}; };
/*These tables were 'borrowed' from DOSBox*/ /*These tables were 'borrowed' from DOSBox*/
int8_t scaleMap4[64] = { int8_t scaleMap4[64] = {
0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30,
4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
}; };
@@ -537,7 +545,7 @@ sb_doreset(sb_dsp_t *dsp)
sb_commands[8] = 1; sb_commands[8] = 1;
sb_commands[9] = 1; sb_commands[9] = 1;
} else { } else {
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
sb_commands[8] = 1; sb_commands[8] = 1;
else else
sb_commands[8] = -1; sb_commands[8] = -1;
@@ -1218,7 +1226,7 @@ sb_exec_command(sb_dsp_t *dsp)
/* Update 8051 ram with the current DSP command. /* Update 8051 ram with the current DSP command.
See https://github.com/joncampbell123/dosbox-x/issues/1044 */ See https://github.com/joncampbell123/dosbox-x/issues/1044 */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_8051_ram[0x20] = dsp->sb_command; dsp->sb_8051_ram[0x20] = dsp->sb_command;
} }
@@ -1244,15 +1252,15 @@ sb_exec_command(sb_dsp_t *dsp)
switch (dsp->sb_command) { switch (dsp->sb_command) {
case 0x01: /* ???? */ case 0x01: /* ???? */
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1;
break; break;
case 0x03: /* ASP status */ case 0x03: /* ASP status */
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
sb_add_data(dsp, 0); sb_add_data(dsp, 0);
break; break;
case 0x04: /* ASP set mode register */ case 0x04: /* ASP set mode register */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_asp_mode = dsp->sb_data[0]; dsp->sb_asp_mode = dsp->sb_data[0];
if (dsp->sb_asp_mode & 4) if (dsp->sb_asp_mode & 4)
dsp->sb_asp_ram_index = 0; dsp->sb_asp_ram_index = 0;
@@ -1260,7 +1268,7 @@ sb_exec_command(sb_dsp_t *dsp)
} /* else DSP Status (Obsolete) */ } /* else DSP Status (Obsolete) */
break; break;
case 0x05: /* ASP set codec parameter */ case 0x05: /* ASP set codec parameter */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]);
} }
break; break;
@@ -1290,9 +1298,9 @@ sb_exec_command(sb_dsp_t *dsp)
sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */
break; break;
} }
if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ if (dsp->sb_type == SBAWE64_DSP_416) /* AWE64 has no ASP or a socket for it */
sb_add_data(dsp, 0xFF); sb_add_data(dsp, 0xFF);
else if (dsp->sb_type >= SB16) else if (dsp->sb_type >= SB16_DSP_404)
sb_add_data(dsp, 0x18); sb_add_data(dsp, 0x18);
break; break;
case 0x09: /* AZTECH mode set */ case 0x09: /* AZTECH mode set */
@@ -1308,7 +1316,7 @@ sb_exec_command(sb_dsp_t *dsp)
} }
break; break;
case 0x0E: /* ASP set register */ case 0x0E: /* ASP set register */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1];
if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */
@@ -1327,7 +1335,7 @@ sb_exec_command(sb_dsp_t *dsp)
} }
break; break;
case 0x0F: /* ASP get register */ case 0x0F: /* ASP get register */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */
if (dsp->sb_asp_mode & 8) if (dsp->sb_asp_mode & 8)
dsp->sb_asp_ram_index = 0; dsp->sb_asp_ram_index = 0;
@@ -1371,11 +1379,11 @@ sb_exec_command(sb_dsp_t *dsp)
} }
break; break;
case 0x1C: /* 8-bit autoinit DMA output */ case 0x1C: /* 8-bit autoinit DMA output */
if (dsp->sb_type >= SB15) if (dsp->sb_type >= SB_DSP_200)
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
break; break;
case 0x1F: /* 2-bit ADPCM autoinit output */ case 0x1F: /* 2-bit ADPCM autoinit output */
if (dsp->sb_type >= SB15) { if (dsp->sb_type >= SB_DSP_200) {
sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
dsp->sb_8_length--; dsp->sb_8_length--;
@@ -1400,7 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0x28: /* Direct ADC, 8-bit (Burst) */ case 0x28: /* Direct ADC, 8-bit (Burst) */
break; break;
case 0x2C: /* 8-bit autoinit DMA input */ case 0x2C: /* 8-bit autoinit DMA input */
if (dsp->sb_type >= SB15) if (dsp->sb_type >= SB_DSP_200)
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
break; break;
case 0x30: /* MIDI Polling mode input */ case 0x30: /* MIDI Polling mode input */
@@ -1417,7 +1425,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0x33: /* MIDI Read Timestamp Interrupt */ case 0x33: /* MIDI Read Timestamp Interrupt */
break; break;
case 0x34: /* MIDI In poll */ case 0x34: /* MIDI In poll */
if (dsp->sb_type < SB2) if (dsp->sb_type < SB_DSP_200)
break; break;
sb_dsp_log("MIDI poll in\n"); sb_dsp_log("MIDI poll in\n");
dsp->midi_in_poll = 1; dsp->midi_in_poll = 1;
@@ -1425,7 +1433,7 @@ sb_exec_command(sb_dsp_t *dsp)
dsp->uart_irq = 0; dsp->uart_irq = 0;
break; break;
case 0x35: /* MIDI In irq */ case 0x35: /* MIDI In irq */
if (dsp->sb_type < SB2) if (dsp->sb_type < SB_DSP_200)
break; break;
sb_dsp_log("MIDI irq in\n"); sb_dsp_log("MIDI irq in\n");
dsp->midi_in_poll = 0; dsp->midi_in_poll = 0;
@@ -1444,7 +1452,7 @@ sb_exec_command(sb_dsp_t *dsp)
temp = 256 - dsp->sb_data[0]; temp = 256 - dsp->sb_data[0];
temp = 1000000 / temp; temp = 1000000 / temp;
sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho);
if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16_DSP_404))
recalc_sb16_filter(0, temp); recalc_sb16_filter(0, temp);
dsp->sb_freq = temp; dsp->sb_freq = temp;
if (IS_ESS(dsp)) { if (IS_ESS(dsp)) {
@@ -1453,7 +1461,7 @@ sb_exec_command(sb_dsp_t *dsp)
break; break;
case 0x41: /* Set output sampling rate */ case 0x41: /* Set output sampling rate */
case 0x42: /* Set input sampling rate */ case 0x42: /* Set input sampling rate */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8))));
sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho);
temp = dsp->sb_freq; temp = dsp->sb_freq;
@@ -1471,7 +1479,8 @@ sb_exec_command(sb_dsp_t *dsp)
case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ case 0x47: /* Continue Auto-Initialize DMA, 16-bit */
break; break;
case 0x48: /* Set DSP block transfer size */ case 0x48: /* Set DSP block transfer size */
dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); if (dsp->sb_type >= SB_DSP_200)
dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8);
break; break;
case 0x65: /* 4-bit ESPCM output with reference */ case 0x65: /* 4-bit ESPCM output with reference */
case 0x64: /* 4-bit ESPCM output */ case 0x64: /* 4-bit ESPCM output */
@@ -1546,7 +1555,7 @@ sb_exec_command(sb_dsp_t *dsp)
} }
break; break;
case 0x7D: /* 4-bit ADPCM autoinit output */ case 0x7D: /* 4-bit ADPCM autoinit output */
if (dsp->sb_type >= SB15) { if (dsp->sb_type >= SB_DSP_200) {
sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
dsp->sb_8_length--; dsp->sb_8_length--;
@@ -1554,7 +1563,7 @@ sb_exec_command(sb_dsp_t *dsp)
} }
break; break;
case 0x7F: /* 2.6-bit ADPCM autoinit output */ case 0x7F: /* 2.6-bit ADPCM autoinit output */
if (dsp->sb_type >= SB15) { if (dsp->sb_type >= SB_DSP_200) {
sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8));
dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv);
dsp->sb_8_length--; dsp->sb_8_length--;
@@ -1567,24 +1576,24 @@ sb_exec_command(sb_dsp_t *dsp)
timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho)); timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho));
break; break;
case 0x90: /* High speed 8-bit autoinit DMA output */ case 0x90: /* High speed 8-bit autoinit DMA output */
if (dsp->sb_type >= SB2) if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
break; break;
case 0x91: /* High speed 8-bit single cycle DMA output */ case 0x91: /* High speed 8-bit single cycle DMA output */
if (dsp->sb_type >= SB2) if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen);
break; break;
case 0x98: /* High speed 8-bit autoinit DMA input */ case 0x98: /* High speed 8-bit autoinit DMA input */
if (dsp->sb_type >= SB2) if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen);
break; break;
case 0x99: /* High speed 8-bit single cycle DMA input */ case 0x99: /* High speed 8-bit single cycle DMA input */
if (dsp->sb_type >= SB2) if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen);
break; break;
case 0xA0: /* Set input mode to mono */ case 0xA0: /* Set input mode to mono */
case 0xA8: /* Set input mode to stereo */ case 0xA8: /* Set input mode to stereo */
if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2)) if ((dsp->sb_type < SBPRO_DSP_300) || (dsp->sb_type > SBPRO2_DSP_302))
break; break;
/* TODO: Implement. 3.xx-only command. */ /* TODO: Implement. 3.xx-only command. */
break; break;
@@ -1596,7 +1605,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xB5: case 0xB5:
case 0xB6: case 0xB6:
case 0xB7: /* 16-bit DMA output */ case 0xB7: /* 16-bit DMA output */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1610,7 +1619,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xBD: case 0xBD:
case 0xBE: case 0xBE:
case 0xBF: /* 16-bit DMA input */ case 0xBF: /* 16-bit DMA input */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1624,7 +1633,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xC5: case 0xC5:
case 0xC6: case 0xC6:
case 0xC7: /* 8-bit DMA output */ case 0xC7: /* 8-bit DMA output */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1638,7 +1647,7 @@ sb_exec_command(sb_dsp_t *dsp)
case 0xCD: case 0xCD:
case 0xCE: case 0xCE:
case 0xCF: /* 8-bit DMA input */ case 0xCF: /* 8-bit DMA input */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0],
dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_data[1] + (dsp->sb_data[2] << 8));
dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8);
@@ -1650,20 +1659,20 @@ sb_exec_command(sb_dsp_t *dsp)
break; break;
case 0xD1: /* Speaker on */ case 0xD1: /* Speaker on */
if (IS_NOT_ESS(dsp)) { if (IS_NOT_ESS(dsp)) {
if (dsp->sb_type < SB15) { if (dsp->sb_type < SB_DSP_200) {
dsp->sb_8_pause = 1; dsp->sb_8_pause = 1;
sb_stop_dma(dsp); sb_stop_dma(dsp);
} else if (dsp->sb_type < SB16) } else if (dsp->sb_type < SB16_DSP_404)
dsp->muted = 0; dsp->muted = 0;
} }
dsp->sb_speaker = 1; dsp->sb_speaker = 1;
break; break;
case 0xD3: /* Speaker off */ case 0xD3: /* Speaker off */
if (IS_NOT_ESS(dsp)) { if (IS_NOT_ESS(dsp)) {
if (dsp->sb_type < SB15) { if (dsp->sb_type < SB_DSP_201) {
dsp->sb_8_pause = 1; dsp->sb_8_pause = 1;
sb_stop_dma(dsp); sb_stop_dma(dsp);
} else if (dsp->sb_type < SB16) } else if (dsp->sb_type < SB16_DSP_404)
dsp->muted = 1; dsp->muted = 1;
} }
dsp->sb_speaker = 0; dsp->sb_speaker = 0;
@@ -1673,26 +1682,28 @@ sb_exec_command(sb_dsp_t *dsp)
sb_resume_dma(dsp, 1); sb_resume_dma(dsp, 1);
break; break;
case 0xD5: /* Pause 16-bit DMA */ case 0xD5: /* Pause 16-bit DMA */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_16_pause = 1; dsp->sb_16_pause = 1;
sb_stop_dma(dsp); sb_stop_dma(dsp);
} }
break; break;
case 0xD6: /* Continue 16-bit DMA */ case 0xD6: /* Continue 16-bit DMA */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
dsp->sb_16_pause = 0; dsp->sb_16_pause = 0;
sb_resume_dma(dsp, 1); sb_resume_dma(dsp, 1);
} }
break; break;
case 0xD8: /* Get speaker status */ case 0xD8: /* Get speaker status */
sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); if (dsp->sb_type >= SB_DSP_200)
sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0);
break; break;
case 0xD9: /* Exit 16-bit auto-init mode */ case 0xD9: /* Exit 16-bit auto-init mode */
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
dsp->sb_16_autoinit = 0; dsp->sb_16_autoinit = 0;
break; break;
case 0xDA: /* Exit 8-bit auto-init mode */ case 0xDA: /* Exit 8-bit auto-init mode */
dsp->sb_8_autoinit = 0; if (dsp->sb_type >= SB_DSP_200)
dsp->sb_8_autoinit = 0;
break; break;
case 0xE0: /* DSP identification */ case 0xE0: /* DSP identification */
sb_add_data(dsp, ~dsp->sb_data[0]); sb_add_data(dsp, ~dsp->sb_data[0]);
@@ -1733,7 +1744,7 @@ sb_exec_command(sb_dsp_t *dsp)
sb_add_data(dsp, dsp->sbe2); sb_add_data(dsp, dsp->sbe2);
break; break;
case 0xE3: /* DSP copyright */ case 0xE3: /* DSP copyright */
if (dsp->sb_type >= SB16) { if (dsp->sb_type >= SB16_DSP_404) {
c = 0; c = 0;
while (sb16_copyright[c]) while (sb16_copyright[c])
sb_add_data(dsp, sb16_copyright[c++]); sb_add_data(dsp, sb16_copyright[c++]);
@@ -1794,15 +1805,15 @@ sb_exec_command(sb_dsp_t *dsp)
timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC)); timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC));
break; break;
case 0xF8: case 0xF8:
if (dsp->sb_type < SB16) if (dsp->sb_type < SB16_DSP_404)
sb_add_data(dsp, 0); sb_add_data(dsp, 0);
break; break;
case 0xF9: /* SB16 8051 RAM read */ case 0xF9: /* SB16 8051 RAM read */
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]);
break; break;
case 0xFA: /* SB16 8051 RAM write */ case 0xFA: /* SB16 8051 RAM write */
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1];
break; break;
case 0xFF: /* No, that's not how you program auto-init DMA */ case 0xFF: /* No, that's not how you program auto-init DMA */
@@ -1812,11 +1823,24 @@ sb_exec_command(sb_dsp_t *dsp)
* http://the.earth.li/~tfm/oldpage/sb_dsp.html * http://the.earth.li/~tfm/oldpage/sb_dsp.html
* http://www.synchrondata.com/pheaven/www/area19.htm * http://www.synchrondata.com/pheaven/www/area19.htm
* http://www.dcee.net/Files/Programm/Sound/ * http://www.dcee.net/Files/Programm/Sound/
* 0E3h DSP Copyright SBPro2??? * https://github.com/schlae/sb-firmware/blob/master/sbv202.asm
* 0F0h Sine Generator SB * 008h Halt (Infinate Loop) SB2???
* 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 * 018h DMA playback with auto init DMA. SB2???
* 0F2h IRQ Request, 8-bit SB * 028h Auto-init direct ADC SB2???
* 036h (Timestamp) SB???
* 037h (Timestamp) SB???
* 050h Stops playback of SRAM samples SB???
* 051h Plays back samples stored in SRAM. SB???
* 058h Load data into SRAM SB???
* 059h Fetches the samples and then immediately plays them back. SB???
* 078h Auto-init DMA ADPCM SB2???
* 07Ah 2.6-bit ADPCM SB???
* 0E3h DSP Copyright SBPro2??? (SBPRO2_DSP_302)
* 0F0h Sine Generator SB (SB_DSP_105, DSP20x)
* 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 (DSP20x, SBPRO2_DSP_302)
* 0F2h IRQ Request, 8-bit SB (SB_DSP_105, DSP20x)
* 0F3h IRQ Request, 16-bit SB16 * 0F3h IRQ Request, 16-bit SB16
* 0F4h Perform ROM checksum SB (SB_DSP_105, DSP20x)
* 0FBh DSP Status SB16 * 0FBh DSP Status SB16
* 0FCh DSP Auxiliary Status SB16 * 0FCh DSP Auxiliary Status SB16
* 0FDh DSP Command Status SB16 * 0FDh DSP Command Status SB16
@@ -1829,7 +1853,7 @@ sb_exec_command(sb_dsp_t *dsp)
/* Update 8051 ram with the last DSP command. /* Update 8051 ram with the last DSP command.
See https://github.com/joncampbell123/dosbox-x/issues/1044 */ See https://github.com/joncampbell123/dosbox-x/issues/1044 */
if (dsp->sb_type >= SB16) if (dsp->sb_type >= SB16_DSP_404)
dsp->sb_8051_ram[0x30] = dsp->sb_command; dsp->sb_8051_ram[0x30] = dsp->sb_command;
} }
@@ -1855,7 +1879,7 @@ sb_write(uint16_t addr, uint8_t val, void *priv)
sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, addr, val);
/* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */
if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE))) if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE)))
addr &= 0xfffe; addr &= 0xfffe;
switch (addr & 0xF) { switch (addr & 0xF) {
@@ -1938,7 +1962,7 @@ sb_read(uint16_t addr, void *priv)
uint8_t ret = 0x00; uint8_t ret = 0x00;
/* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */
if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xF))) if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xF)))
/* Exception: ESS AudioDrive does not alias port base+0xf */ /* Exception: ESS AudioDrive does not alias port base+0xf */
addr &= 0xfffe; addr &= 0xfffe;
@@ -1980,7 +2004,7 @@ sb_read(uint16_t addr, void *priv)
if (dsp->state == DSP_S_RESET_WAIT) if (dsp->state == DSP_S_RESET_WAIT)
dsp->state = DSP_S_NORMAL; dsp->state = DSP_S_NORMAL;
if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) { if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) {
if (dsp->sb_8_enable || dsp->sb_type >= SB16) if (dsp->sb_8_enable || dsp->sb_type >= SB16_DSP_404)
dsp->busy_count = (dsp->busy_count + 1) & 3; dsp->busy_count = (dsp->busy_count + 1) & 3;
else else
dsp->busy_count = 0; dsp->busy_count = 0;
@@ -2005,7 +2029,7 @@ sb_read(uint16_t addr, void *priv)
ret = 0x80; ret = 0x80;
} else { } else {
sb_dsp_log("SB Write Data Creative read 0xff\n"); sb_dsp_log("SB Write Data Creative read 0xff\n");
if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
ret = 0xaa; ret = 0xaa;
else else
ret = 0xff; ret = 0xff;
@@ -2015,7 +2039,7 @@ sb_read(uint16_t addr, void *priv)
ret = 0x00; ret = 0x00;
} else { } else {
sb_dsp_log("SB Write Data Creative read 0x7f\n"); sb_dsp_log("SB Write Data Creative read 0x7f\n");
if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
ret = 0x2a; ret = 0x2a;
else else
ret = 0x7f; ret = 0x7f;
@@ -2039,7 +2063,7 @@ sb_read(uint16_t addr, void *priv)
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80;
} else { } else {
sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff);
if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) if ((dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp))
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa; ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa;
else else
ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff;
@@ -2150,11 +2174,11 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
/* Default values. Use sb_dsp_setxxx() methods to change. */ /* Default values. Use sb_dsp_setxxx() methods to change. */
dsp->sb_irqnum = 7; dsp->sb_irqnum = 7;
dsp->sb_8_dmanum = 1; dsp->sb_8_dmanum = 1;
if (type >= SB16) if (type >= SB16_DSP_404)
dsp->sb_16_dmanum = 5; dsp->sb_16_dmanum = 5;
else else
dsp->sb_16_dmanum = 0xff; dsp->sb_16_dmanum = 0xff;
if ((type >= SB16) || IS_ESS(dsp)) if ((type >= SB16_DSP_404) || IS_ESS(dsp))
dsp->sb_16_8_dmanum = 0x1; dsp->sb_16_8_dmanum = 0x1;
dsp->mpu = NULL; dsp->mpu = NULL;
@@ -2186,7 +2210,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
a set frequency command is sent. */ a set frequency command is sent. */
recalc_sb16_filter(0, 3200 * 2); recalc_sb16_filter(0, 3200 * 2);
} }
if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2_DSP_302)) {
/* OPL3 or dual OPL2 is stereo. */ /* OPL3 or dual OPL2 is stereo. */
if (dsp->sb_has_real_opl) if (dsp->sb_has_real_opl)
recalc_opl_filter(FREQ_49716 * 2); recalc_opl_filter(FREQ_49716 * 2);