Merge pull request #5111 from jriwanek-forks/soundblaster

Cleanups and improvements to SB1.x and 2.0
This commit is contained in:
Miran Grča
2025-01-09 04:05:54 +01:00
committed by GitHub
2 changed files with 143 additions and 243 deletions

View File

@@ -43,6 +43,10 @@
#include <86box/snd_sb.h> #include <86box/snd_sb.h>
#include <86box/plat_unused.h> #include <86box/plat_unused.h>
#define SB_1 0
#define SB_15 1
#define SB_2 2
#define SB_16_PNP_NOIDE 0 #define SB_16_PNP_NOIDE 0
#define SB_16_PNP_IDE 1 #define SB_16_PNP_IDE 1
@@ -415,7 +419,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv)
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
const int dsp_rec_pos = sb->dsp.record_pos_write; const int dsp_rec_pos = sb->dsp.record_pos_write;
double bass_treble; double bass_treble;
const int32_t *opl_buf = NULL; const int32_t *opl_buf = NULL;
if (sb->opl_enabled) if (sb->opl_enabled)
opl_buf = sb->opl.update(sb->opl.priv); opl_buf = sb->opl.update(sb->opl.priv);
@@ -1808,8 +1812,8 @@ sb_mcv_read(int port, void *priv)
void void
sb_mcv_write(int port, uint8_t val, void *priv) sb_mcv_write(int port, uint8_t val, void *priv)
{ {
uint16_t addr; uint16_t addr = 0;
sb_t *sb = (sb_t *) priv; sb_t *sb = (sb_t *) priv;
if (port < 0x102) if (port < 0x102)
return; return;
@@ -1872,8 +1876,8 @@ sb_pro_mcv_read(int port, void *priv)
static void static void
sb_pro_mcv_write(int port, uint8_t val, void *priv) sb_pro_mcv_write(int port, uint8_t val, void *priv)
{ {
uint16_t addr; uint16_t addr = 0;
sb_t *sb = (sb_t *) priv; sb_t *sb = (sb_t *) priv;
if (port < 0x102) if (port < 0x102)
return; return;
@@ -1943,8 +1947,8 @@ sb_16_reply_mca_read(int port, void *priv)
static void static void
sb_16_reply_mca_write(const int port, const uint8_t val, void *priv) sb_16_reply_mca_write(const int port, const uint8_t val, void *priv)
{ {
uint16_t addr; uint16_t addr = 0;
sb_t *sb = (sb_t *) priv; sb_t *sb = (sb_t *) priv;
if (port < 0x102) if (port < 0x102)
return; return;
@@ -2812,182 +2816,62 @@ ess_chipchat_mca_write(int port, uint8_t val, void *priv)
} }
void * void *
sb_1_init(UNUSED(const device_t *info)) sb_init(UNUSED(const device_t *info))
{ {
/* SB1/2 port mappings, 210h to 260h in 10h steps /* SB1.x port mappings, 210h to 260h in 10h steps:
2x0 to 2x3 -> CMS chip (SB2 port mappings are 220h or 240h)
2x6, 2xA, 2xC, 2xE -> DSP chip 2x0 to 2x3 -> CMS chip
2x8, 2x9, 388 and 389 FM chip */ 2x6, 2xA, 2xC, 2xE -> DSP chip
sb_t *sb = malloc(sizeof(sb_t)); 2x8, 2x9, 388 and 389 FM chip
const uint16_t addr = device_get_config_hex16("base"); SB2 "CD version" also uses 250h or 260h:
memset(sb, 0, sizeof(sb_t)); 2x0 to 2x3 -> CDROM interface
2x4 to 2x5 -> Mixer interface */
sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
/* DSP I/O handler is activated in sb_dsp_setaddr */
if (sb->opl_enabled) {
io_sethandler(addr + 8, 0x0002,
sb->opl.read, NULL, NULL,
sb->opl.write, NULL, NULL,
sb->opl.priv);
io_sethandler(0x0388, 0x0002,
sb->opl.read, NULL, NULL,
sb->opl.write, NULL, NULL,
sb->opl.priv);
}
sb->cms_enabled = 1;
memset(&sb->cms, 0, sizeof(cms_t));
io_sethandler(addr, 0x0004,
cms_read, NULL, NULL,
cms_write, NULL, NULL,
&sb->cms);
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
return sb;
}
void *
sb_15_init(UNUSED(const device_t *info))
{
/* SB1/2 port mappings, 210h to 260h in 10h steps
2x0 to 2x3 -> CMS chip
2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip */
sb_t *sb = malloc(sizeof(sb_t));
const uint16_t addr = device_get_config_hex16("base");
memset(sb, 0, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
/* DSP I/O handler is activated in sb_dsp_setaddr */
if (sb->opl_enabled) {
io_sethandler(addr + 8, 0x0002,
sb->opl.read, NULL, NULL,
sb->opl.write, NULL, NULL,
sb->opl.priv);
io_sethandler(0x0388, 0x0002,
sb->opl.read, NULL, NULL,
sb->opl.write, NULL, NULL,
sb->opl.priv);
}
sb->cms_enabled = device_get_config_int("cms");
if (sb->cms_enabled) {
memset(&sb->cms, 0, sizeof(cms_t));
io_sethandler(addr, 0x0004,
cms_read, NULL, NULL,
cms_write, NULL, NULL,
&sb->cms);
}
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
return sb;
}
void *
sb_mcv_init(UNUSED(const device_t *info))
{
/* SB1/2 port mappings, 210h to 260h in 10h steps
2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip */
sb_t *sb = malloc(sizeof(sb_t));
memset(sb, 0, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, 0);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
/* I/O handlers activated in sb_mcv_write */
mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb);
sb->pos_regs[0] = 0x84;
sb->pos_regs[1] = 0x50;
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
return sb;
}
void *
sb_2_init(UNUSED(const device_t *info))
{
/* SB2 port mappings, 220h or 240h.
2x0 to 2x3 -> CMS chip
2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip
"CD version" also uses 250h or 260h for
2x0 to 2x3 -> CDROM interface
2x4 to 2x5 -> Mixer interface */
/* My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is disabled when the /* My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is disabled when the
CMS chips are present. CMS chips are present.
This mirror may also exist on SB 1.5 & MCV, however I am unable to test this. It shouldn't This mirror may also exist on SB 1.5 & MCV, however I am unable to test this. It shouldn't
exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror
for music to play.*/ for music to play. */
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
uint16_t addr = device_get_config_hex16("base"); const uint16_t addr = device_get_config_hex16("base");
uint16_t mixer_addr = device_get_config_int("mixaddr"); uint16_t mixer_addr = 0x0000;
uint8_t model = 0;
memset(sb, 0, sizeof(sb_t)); switch (info->local) {
default:
case SB_1:
model = SB1;
sb->cms_enabled = 1;
break;
case SB_15:
model = SB15;
sb->cms_enabled = device_get_config_int("cms");
break;
case SB_2:
model = SB2;
sb->cms_enabled = device_get_config_int("cms");
mixer_addr = device_get_config_int("mixaddr");
break;
}
sb->opl_enabled = device_get_config_int("opl"); sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled) if (sb->opl_enabled)
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, SB2, SB_SUBTYPE_DEFAULT, sb); sb_dsp_init(&sb->dsp, model, 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"));
if (mixer_addr > 0x000)
if (mixer_addr > 0x0000)
sb_ct1335_mixer_reset(sb); sb_ct1335_mixer_reset(sb);
sb->cms_enabled = device_get_config_int("cms");
/* 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) {
if (!sb->cms_enabled) { // TODO: See if this applies to the SB1.5 as well
if ((!sb->cms_enabled) && (model == SB2)) {
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,
@@ -3019,6 +2903,7 @@ sb_2_init(UNUSED(const device_t *info))
sb); sb);
} else } else
sb->mixer_enabled = 0; sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb); sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled) if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb); music_add_handler(sb_get_music_buffer_sb2, sb);
@@ -3030,6 +2915,41 @@ sb_2_init(UNUSED(const device_t *info))
return sb; return sb;
} }
void *
sb_mcv_init(UNUSED(const device_t *info))
{
/* SB1/2 port mappings, 210h to 260h in 10h steps
2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip */
sb_t *sb = calloc(1, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled)
fm_driver_get(FM_YM3812, &sb->opl);
sb_dsp_set_real_opl(&sb->dsp, 1);
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, 0);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
sb->mixer_enabled = 0;
sound_add_handler(sb_get_buffer_sb2, sb);
if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sb2, sb);
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
/* I/O handlers activated in sb_mcv_write */
mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb);
sb->pos_regs[0] = 0x84;
sb->pos_regs[1] = 0x50;
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
return sb;
}
static uint8_t static uint8_t
sb_pro_v1_opl_read(uint16_t port, void *priv) sb_pro_v1_opl_read(uint16_t port, void *priv)
{ {
@@ -3059,9 +2979,8 @@ sb_pro_v1_init(UNUSED(const device_t *info))
2x6, 2xA, 2xC, 2xE -> DSP chip 2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip (9 voices) 2x8, 2x9, 388 and 389 FM chip (9 voices)
2x0+10 to 2x0+13 CDROM interface. */ 2x0+10 to 2x0+13 CDROM interface. */
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
uint16_t addr = device_get_config_hex16("base"); uint16_t addr = device_get_config_hex16("base");
memset(sb, 0, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl"); sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled) { if (sb->opl_enabled) {
@@ -3122,9 +3041,8 @@ sb_pro_v2_init(UNUSED(const device_t *info))
2x6, 2xA, 2xC, 2xE -> DSP chip 2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip (9 voices) 2x8, 2x9, 388 and 389 FM chip (9 voices)
2x0+10 to 2x0+13 CDROM interface. */ 2x0+10 to 2x0+13 CDROM interface. */
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
uint16_t addr = device_get_config_hex16("base"); uint16_t addr = device_get_config_hex16("base");
memset(sb, 0, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl"); sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled) if (sb->opl_enabled)
@@ -3176,8 +3094,7 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
2x4 to 2x5 -> Mixer interface 2x4 to 2x5 -> Mixer interface
2x6, 2xA, 2xC, 2xE -> DSP chip 2x6, 2xA, 2xC, 2xE -> DSP chip
2x8, 2x9, 388 and 389 FM chip (9 voices) */ 2x8, 2x9, 388 and 389 FM chip (9 voices) */
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
memset(sb, 0, sizeof(sb_t));
sb->opl_enabled = 1; sb->opl_enabled = 1;
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
@@ -3205,8 +3122,7 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
static void * static void *
sb_pro_compat_init(UNUSED(const device_t *info)) sb_pro_compat_init(UNUSED(const device_t *info))
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
memset(sb, 0, sizeof(sb_t));
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
@@ -3219,8 +3135,7 @@ sb_pro_compat_init(UNUSED(const device_t *info))
if (sb->opl_enabled) if (sb->opl_enabled)
music_add_handler(sb_get_music_buffer_sbpro, sb); music_add_handler(sb_get_music_buffer_sbpro, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, 1); mpu401_init(sb->mpu, 0, 0, M_UART, 1);
sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -3230,12 +3145,10 @@ sb_pro_compat_init(UNUSED(const device_t *info))
static void * static void *
sb_16_init(UNUSED(const device_t *info)) sb_16_init(UNUSED(const device_t *info))
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
const uint16_t addr = device_get_config_hex16("base"); const uint16_t addr = device_get_config_hex16("base");
const uint16_t mpu_addr = device_get_config_hex16("base401"); const uint16_t mpu_addr = device_get_config_hex16("base401");
memset(sb, 0x00, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl"); sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled) if (sb->opl_enabled)
fm_driver_get((int) (intptr_t) info->local, &sb->opl); fm_driver_get((int) (intptr_t) info->local, &sb->opl);
@@ -3277,8 +3190,7 @@ sb_16_init(UNUSED(const device_t *info))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
if (mpu_addr) { if (mpu_addr) {
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART, mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART,
device_get_config_int("receive_input401")); device_get_config_int("receive_input401"));
} else } else
@@ -3298,8 +3210,7 @@ sb_16_init(UNUSED(const device_t *info))
static void * static void *
sb_16_reply_mca_init(UNUSED(const device_t *info)) sb_16_reply_mca_init(UNUSED(const device_t *info))
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
memset(sb, 0x00, sizeof(sb_t));
sb->opl_enabled = 1; sb->opl_enabled = 1;
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
@@ -3318,8 +3229,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
if (device_get_config_int("control_pc_speaker")) if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -3353,8 +3263,7 @@ sb_16_pnp_ide_available(void)
static void * static void *
sb_16_pnp_init(UNUSED(const device_t *info)) sb_16_pnp_init(UNUSED(const device_t *info))
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
memset(sb, 0x00, sizeof(sb_t));
sb->pnp = 1; sb->pnp = 1;
@@ -3373,8 +3282,7 @@ sb_16_pnp_init(UNUSED(const device_t *info))
if (device_get_config_int("control_pc_speaker")) if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -3457,8 +3365,7 @@ sb_vibra16xv_available(void)
static void * static void *
sb_vibra16_pnp_init(UNUSED(const device_t *info)) sb_vibra16_pnp_init(UNUSED(const device_t *info))
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
memset(sb, 0x00, sizeof(sb_t));
sb->pnp = 1; sb->pnp = 1;
@@ -3479,8 +3386,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
if (device_get_config_int("control_pc_speaker")) if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -3558,8 +3464,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
static void * static void *
sb_16_compat_init(const device_t *info) sb_16_compat_init(const device_t *info)
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
memset(sb, 0, sizeof(sb_t));
fm_driver_get(FM_YMF262, &sb->opl); fm_driver_get(FM_YMF262, &sb->opl);
@@ -3574,7 +3479,7 @@ sb_16_compat_init(const device_t *info)
sound_add_handler(sb_get_buffer_sb16_awe32, sb); sound_add_handler(sb_get_buffer_sb16_awe32, sb);
music_add_handler(sb_get_music_buffer_sb16_awe32, sb); music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local); mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local);
sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -3637,7 +3542,7 @@ sb_awe64_gold_available(void)
static void * static void *
sb_awe32_init(UNUSED(const device_t *info)) sb_awe32_init(UNUSED(const device_t *info))
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
uint16_t addr = device_get_config_hex16("base"); uint16_t addr = device_get_config_hex16("base");
uint16_t mpu_addr = device_get_config_hex16("base401"); uint16_t mpu_addr = device_get_config_hex16("base401");
uint16_t emu_addr = device_get_config_hex16("emu_base"); uint16_t emu_addr = device_get_config_hex16("emu_base");
@@ -3687,7 +3592,7 @@ sb_awe32_init(UNUSED(const device_t *info))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
if (mpu_addr) { if (mpu_addr) {
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t)); memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART, mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART,
device_get_config_int("receive_input401")); device_get_config_int("receive_input401"));
@@ -3710,11 +3615,9 @@ sb_awe32_init(UNUSED(const device_t *info))
static void * static void *
sb_goldfinch_init(const device_t *info) sb_goldfinch_init(const device_t *info)
{ {
goldfinch_t *goldfinch = malloc(sizeof(goldfinch_t)); goldfinch_t *goldfinch = calloc(1, sizeof(goldfinch_t));
int onboard_ram = device_get_config_int("onboard_ram"); int onboard_ram = device_get_config_int("onboard_ram");
memset(goldfinch, 0x00, sizeof(goldfinch_t));
wavetable_add_handler(sb_get_wavetable_buffer_goldfinch, goldfinch); wavetable_add_handler(sb_get_wavetable_buffer_goldfinch, goldfinch);
emu8k_init(&goldfinch->emu8k, 0, onboard_ram); emu8k_init(&goldfinch->emu8k, 0, onboard_ram);
@@ -3758,11 +3661,9 @@ sb_goldfinch_init(const device_t *info)
static void * static void *
sb_awe32_pnp_init(const device_t *info) sb_awe32_pnp_init(const device_t *info)
{ {
sb_t *sb = malloc(sizeof(sb_t)); sb_t *sb = calloc(1, sizeof(sb_t));
int onboard_ram = device_get_config_int("onboard_ram"); int onboard_ram = device_get_config_int("onboard_ram");
memset(sb, 0x00, sizeof(sb_t));
sb->pnp = 1; sb->pnp = 1;
sb->opl_enabled = 1; sb->opl_enabled = 1;
@@ -3783,8 +3684,7 @@ sb_awe32_pnp_init(const device_t *info)
if (device_get_config_int("control_pc_speaker")) if (device_get_config_int("control_pc_speaker"))
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401"));
sb_dsp_set_mpu(&sb->dsp, sb->mpu); sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -4211,7 +4111,8 @@ static const device_config_t sb_config[] = {
}, },
{ {
.description = "0x260", .description = "0x260",
.value = 0x260 }, .value = 0x260
},
{ .description = "" } { .description = "" }
} }
}, },
@@ -4260,7 +4161,7 @@ static const device_config_t sb_config[] = {
.description = "DMA 3", .description = "DMA 3",
.value = 3 .value = 3
}, },
{ "" } { .description = "" }
} }
}, },
{ {
@@ -4314,8 +4215,7 @@ static const device_config_t sb15_config[] = {
.description = "0x260", .description = "0x260",
.value = 0x260 .value = 0x260
}, },
{ { .description = "" }
.description = "" }
} }
}, },
{ {
@@ -4408,10 +4308,6 @@ static const device_config_t sb2_config[] = {
.description = "0x240", .description = "0x240",
.value = 0x240 .value = 0x240
}, },
{
.description = "0x260",
.value = 0x260
},
{ .description = "" } { .description = "" }
} }
}, },
@@ -4428,14 +4324,6 @@ static const device_config_t sb2_config[] = {
.description = "Disabled", .description = "Disabled",
.value = 0 .value = 0
}, },
{
.description = "0x220",
.value = 0x220
},
{
.description = "0x240",
.value = 0x240
},
{ {
.description = "0x250", .description = "0x250",
.value = 0x250 .value = 0x250
@@ -5769,8 +5657,8 @@ const device_t sb_1_device = {
.name = "Sound Blaster v1.0", .name = "Sound Blaster v1.0",
.internal_name = "sb", .internal_name = "sb",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = 0, .local = SB_1,
.init = sb_1_init, .init = sb_init,
.close = sb_close, .close = sb_close,
.reset = NULL, .reset = NULL,
.available = NULL, .available = NULL,
@@ -5783,8 +5671,8 @@ const device_t sb_15_device = {
.name = "Sound Blaster v1.5", .name = "Sound Blaster v1.5",
.internal_name = "sb1.5", .internal_name = "sb1.5",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = 0, .local = SB_15,
.init = sb_15_init, .init = sb_init,
.close = sb_close, .close = sb_close,
.reset = NULL, .reset = NULL,
.available = NULL, .available = NULL,
@@ -5811,8 +5699,8 @@ const device_t sb_2_device = {
.name = "Sound Blaster v2.0", .name = "Sound Blaster v2.0",
.internal_name = "sb2.0", .internal_name = "sb2.0",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = 0, .local = SB_2,
.init = sb_2_init, .init = sb_init,
.close = sb_close, .close = sb_close,
.reset = NULL, .reset = NULL,
.available = NULL, .available = NULL,

View File

@@ -78,7 +78,19 @@ static int sb_commands[256] = {
}; };
char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 }; uint16_t sb_dsp_versions[] = {
0, /* Pad */
0, /* SADLIB - No DSP */
0x105, /* SB1 - DSP v1.05 */
0x200, /* SB15 - DSP v2.00 */
0x201, /* SB2 - DSP v2.01 - needed for high-speed DMA */
0x300, /* SBPRO - DSP v3.00 */
0x302, /* SBPRO2 - DSP v3.02 + OPL3 */
0x405, /* SB16 - DSP v4.05 + 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] = {
@@ -1836,31 +1848,31 @@ sb_do_reset(sb_dsp_t *dsp, const uint8_t v)
} }
void void
sb_write(uint16_t a, uint8_t v, void *priv) sb_write(uint16_t addr, uint8_t val, void *priv)
{ {
sb_dsp_t *dsp = (sb_dsp_t *) priv; sb_dsp_t *dsp = (sb_dsp_t *) priv;
sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v); 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) || ((a & 0xF) != 0xE))) if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE)))
a &= 0xfffe; addr &= 0xfffe;
switch (a & 0xF) { switch (addr & 0xF) {
case 6: /* Reset */ case 6: /* Reset */
sb_do_reset(dsp, v); sb_do_reset(dsp, val);
if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { if (!(val & 2) && (dsp->espcm_fifo_reset & 2)) {
fifo_reset(dsp->espcm_fifo); fifo_reset(dsp->espcm_fifo);
} }
dsp->espcm_fifo_reset = v; dsp->espcm_fifo_reset = val;
dsp->uart_midi = 0; dsp->uart_midi = 0;
dsp->uart_irq = 0; dsp->uart_irq = 0;
dsp->onebyte_midi = 0; dsp->onebyte_midi = 0;
return; return;
case 0xC: /* Command/data write */ case 0xC: /* Command/data write */
if (dsp->uart_midi || dsp->onebyte_midi) { if (dsp->uart_midi || dsp->onebyte_midi) {
midi_raw_out_byte(v); midi_raw_out_byte(val);
dsp->onebyte_midi = 0; dsp->onebyte_midi = 0;
return; return;
} }
@@ -1873,8 +1885,8 @@ sb_write(uint16_t a, uint8_t v, void *priv)
return; return;
} }
if (dsp->sb_data_stat == -1) { if (dsp->sb_data_stat == -1) {
dsp->sb_command = v; dsp->sb_command = val;
if (v == 0x01) if (val == 0x01)
sb_add_data(dsp, 0); sb_add_data(dsp, 0);
dsp->sb_data_stat++; dsp->sb_data_stat++;
if (IS_AZTECH(dsp)) { if (IS_AZTECH(dsp)) {
@@ -1901,7 +1913,7 @@ sb_write(uint16_t a, uint8_t v, void *priv)
} }
} }
} else { } else {
dsp->sb_data[dsp->sb_data_stat++] = v; dsp->sb_data[dsp->sb_data_stat++] = val;
} }
if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) {
sb_exec_command(dsp); sb_exec_command(dsp);
@@ -1920,17 +1932,17 @@ sb_write(uint16_t a, uint8_t v, void *priv)
} }
uint8_t uint8_t
sb_read(uint16_t a, void *priv) sb_read(uint16_t addr, void *priv)
{ {
sb_dsp_t *dsp = (sb_dsp_t *) priv; sb_dsp_t *dsp = (sb_dsp_t *) 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) || ((a & 0xF) != 0xF))) if ((dsp->sb_type < SB16) && (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 */
a &= 0xfffe; addr &= 0xfffe;
switch (a & 0xf) { switch (addr & 0xf) {
case 0x6: case 0x6:
if (IS_ESS(dsp)) { if (IS_ESS(dsp)) {
ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0); ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0);