From 095f6fcf5ce2f42fd532622930fd05ba49bcf067 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 22 Dec 2021 06:33:35 +0500 Subject: [PATCH] Port SB16 ASP chip internal RAM and more 8051 RAM emulation from DOSBox-X --- src/include/86box/snd_sb_dsp.h | 5 ++ src/sound/snd_sb_dsp.c | 96 ++++++++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f4626890d..2e6e7eb8f 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -66,6 +66,11 @@ typedef struct sb_dsp_t int sb_irqm8, sb_irqm16, sb_irqm401; uint8_t sb_asp_regs[256]; + uint8_t sb_asp_mode; + + uint8_t sb_asp_ram[2048]; + int sb_asp_ram_index; + uint8_t sb_8051_ram[256]; int sbenable, sb_enable_i; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index bbbc90d9e..d41467bb5 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -46,7 +46,7 @@ static int sbe2dat[4][9] = { static int sb_commands[256]= { - -1, 2,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, + -1, 2,-1, 0, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, @@ -61,7 +61,7 @@ static int sb_commands[256]= 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1, 0,-1,-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 }; @@ -314,12 +314,14 @@ sb_doreset(sb_dsp_t *dsp) sb_commands[8] = 1; sb_commands[9] = 1; } else { - if ((dsp->sb_type >= SB16) && (dsp->sb_type < SBAWE64)) + if (dsp->sb_type >= SB16) sb_commands[8] = 1; else sb_commands[8] = -1; } + dsp->sb_asp_mode = 0; + dsp->sb_asp_ram_index = 0; for (c = 0; c < 256; c++) dsp->sb_asp_regs[c] = 0; @@ -472,13 +474,20 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command); + + /* Update 8051 ram with the current DSP command. + See https://github.com/joncampbell123/dosbox-x/issues/1044 */ + if (dsp->sb_type >= SB16) + dsp->sb_8051_ram[0x20] = dsp->sb_command; + switch (dsp->sb_command) { case 0x01: /* ???? */ if (dsp->sb_type >= SB16) dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; break; case 0x03: /* ASP status */ - sb_add_data(dsp, 0); + if (dsp->sb_type >= SB16) + sb_add_data(dsp, 0); break; case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); @@ -581,6 +590,8 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_timei = dsp->sb_timeo; if (dsp->sb_freq != temp && dsp->sb_type >= SB16) recalc_sb16_filter(0, dsp->sb_freq); + dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; + dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; } break; case 0x48: /* Set DSP block transfer size */ @@ -767,7 +778,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x07: case 0xFF: /* No, that's not how you program auto-init DMA */ break; - case 0x08: /* ASP get version */ + case 0x08: /* ASP get version / AZTECH type/EEPROM access */ if (IS_AZTECH(dsp)) { if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55)&& dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ @@ -791,35 +802,76 @@ 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 */ break; } - if (dsp->sb_type >= SB16) + if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + sb_add_data(dsp, 0xFF); + else if (dsp->sb_type >= SB16) sb_add_data(dsp, 0x18); break; case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { 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_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; + + if (dsp->sb_asp_mode & 2) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } + sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } break; case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { + 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) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; + + if (dsp->sb_asp_mode & 1) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } else if (dsp->sb_data[0] == 0x83) { + dsp->sb_asp_regs[0x83] = 0x18; + } sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); + sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); + } break; case 0xF8: if (dsp->sb_type < SB16) sb_add_data(dsp, 0); break; - case 0xF9: - if (dsp->sb_type >= SB16) { + case 0xF9: /* SB16 8051 RAM read */ + if (dsp->sb_type >= SB16) sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); - } break; - case 0xFA: - if (dsp->sb_type >= SB16) { + case 0xFA: /* SB16 8051 RAM write */ + if (dsp->sb_type >= SB16) dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; + break; + case 0x04: /* ASP set mode register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_mode = dsp->sb_data[0]; + if (dsp->sb_asp_mode & 4) + dsp->sb_asp_ram_index = 0; + sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); } break; - case 0x04: case 0x05: + case 0x05: /* ASP set codec parameter */ + if (dsp->sb_type >= SB16) + sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); break; - case 0x09: /*AZTECH mode set*/ + case 0x09: /* AZTECH mode set */ if (IS_AZTECH(dsp)) { if (dsp->sb_data[0] == 0x00) { sb_dsp_log("AZT2316A: WSS MODE!\n"); @@ -847,11 +899,11 @@ sb_exec_command(sb_dsp_t *dsp) */ } - if (dsp->sb_type >= SB16) { - /* Update 8051 ram with the last DSP command. - See https://github.com/joncampbell123/dosbox-x/issues/1044 */ + + /* Update 8051 ram with the last DSP command. + See https://github.com/joncampbell123/dosbox-x/issues/1044 */ + if (dsp->sb_type >= SB16) dsp->sb_8051_ram[0x30] = dsp->sb_command; - } } @@ -1065,11 +1117,13 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) recalc_sb16_filter(0, 3200*2); recalc_sb16_filter(1, 44100); - /* Initialize SB16 8051 RAM */ - memset(dsp->sb_8051_ram, 0, 256); + /* Initialize SB16 8051 RAM and ASP internal RAM */ + memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); dsp->sb_8051_ram[0x0e] = 0xff; dsp->sb_8051_ram[0x0f] = 0x07; dsp->sb_8051_ram[0x37] = 0x38; + + memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); }