Port SB16 ASP chip internal RAM and more 8051 RAM emulation from DOSBox-X

This commit is contained in:
Alexander Babikov
2021-12-22 06:33:35 +05:00
parent 3e404fad05
commit 095f6fcf5c
2 changed files with 80 additions and 21 deletions

View File

@@ -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;

View File

@@ -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));
}