From 3bf216d645d2c6e12e649e93e72cc9c98e70fdf2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Apr 2021 08:51:39 +0200 Subject: [PATCH] Rewrote the Sound Blaster IRQ system because the old one was designed with a level-triggered IRQ in mind while these are ISA cards with edge-triggered IRQ's. --- src/include/86box/snd_sb_dsp.h | 2 +- src/sound/snd_sb.c | 5 +---- src/sound/snd_sb_dsp.c | 37 ++++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 263897711..060b3835a 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -117,6 +117,6 @@ void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); void sb_dsp_update(sb_dsp_t *dsp); -void sb_update_irq(sb_dsp_t *dsp); +void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401); #endif /* SOUND_SND_SB_DSP_H */ \ No newline at end of file diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index c68c062ab..2dc147285 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -858,10 +858,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) case 0x83: /* Interrupt mask. */ - sb->dsp.sb_irqm8 = !(val & 0x01); - sb->dsp.sb_irqm16 = !(val & 0x02); - sb->dsp.sb_irqm401 = !(val & 0x04); - sb_update_irq(&sb->dsp); + sb_update_mask(&sb->dsp, !(val & 0x01), !(val & 0x02), !(val & 0x04)); break; case 0x84: diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 4c0bcf6ab..6203def85 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -178,17 +178,21 @@ recalc_sb16_filter(int c, int playback_freq) void -sb_update_irq(sb_dsp_t *dsp) +sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401) { - int irq_pending; + int clear = 0; - irq_pending = (dsp->sb_irq8 && !dsp->sb_irqm8) || - (dsp->sb_irq16 && !dsp->sb_irqm16) || - (dsp->sb_irq401 && !dsp->sb_irqm401); + if (!dsp->sb_irqm8 && irqm8) + clear |= 1; + dsp->sb_irqm8 = irqm8; + if (!dsp->sb_irqm16 && irqm16) + clear |= 1; + dsp->sb_irqm16 = irqm16; + if (!dsp->sb_irqm401 && irqm401) + clear |= 1; + dsp->sb_irqm401 = irqm401; - if (irq_pending) - picint(1 << dsp->sb_irqnum); - else + if (clear) picintc(1 << dsp->sb_irqnum); } @@ -196,20 +200,28 @@ sb_update_irq(sb_dsp_t *dsp) void sb_update_status(sb_dsp_t *dsp, int bit, int set) { + int masked = 0; + switch (bit) { case 0: default: dsp->sb_irq8 = set; + masked = dsp->sb_irqm8; break; case 1: dsp->sb_irq16 = set; + masked = dsp->sb_irqm16; break; case 2: dsp->sb_irq401 = set; + masked = dsp->sb_irqm401; break; } - sb_update_irq(dsp); + if (set && !masked) + picint(1 << dsp->sb_irqnum); + else if (!set) + picintc(1 << dsp->sb_irqnum); } @@ -258,8 +270,8 @@ sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu) void sb_dsp_reset(sb_dsp_t *dsp) { - midi_clear_buffer(); - + midi_clear_buffer(); + timer_disable(&dsp->output_timer); timer_disable(&dsp->input_timer); @@ -271,9 +283,8 @@ sb_dsp_reset(sb_dsp_t *dsp) dsp->sb_irq8 = 0; dsp->sb_irq16 = 0; dsp->sb_irq401 = 0; - sb_update_irq(dsp); dsp->sb_16_pause = 0; - dsp->sb_read_wp = dsp->sb_read_rp = 0; + dsp->sb_read_wp = dsp->sb_read_rp = 0; dsp->sb_data_stat = -1; dsp->sb_speaker = 0; dsp->sb_pausetime = -1LL;