diff mbox

sb16: fix interrupt acknowledgement

Message ID 1421771028-5251-1-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini Jan. 20, 2015, 4:23 p.m. UTC
SoundBlaster 16 emulation is very broken and consumes a lot of CPU, but a
small fix was suggested offlist and it is enough to fix some games.  I
got Epic Pinball to work with the "SoundBlaster Clone" option.

The processing of the interrupt register is wrong due to two missing
"not"s.  This causes the interrupt flag to remain set even after the
Acknowledge ports have been read (0x0e and 0x0f).

The line was introduced by commit 85571bc (audio merge (malc), 2004-11-07),
but the code might have been broken before because I did not look closely
at the huge patches from 10 years ago.

Reported-by: Joshua Bair <j_bair@bellsouth.net>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/audio/sb16.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Michael Tokarev Jan. 21, 2015, 9:32 a.m. UTC | #1
20.01.2015 19:23, Paolo Bonzini wrote:
> --- a/hw/audio/sb16.c
> +++ b/hw/audio/sb16.c
> @@ -999,7 +999,7 @@ static IO_READ_PROTO (dsp_read)
>          retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
>          if (s->mixer_regs[0x82] & 1) {
>              ack = 1;
> -            s->mixer_regs[0x82] &= 1;
> +            s->mixer_regs[0x82] &= ~1;

Shouldn't it be ~1u instead?

/mjt
Paolo Bonzini Jan. 21, 2015, 10 a.m. UTC | #2
On 21/01/2015 10:32, Michael Tokarev wrote:
>> > --- a/hw/audio/sb16.c
>> > +++ b/hw/audio/sb16.c
>> > @@ -999,7 +999,7 @@ static IO_READ_PROTO (dsp_read)
>> >          retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
>> >          if (s->mixer_regs[0x82] & 1) {
>> >              ack = 1;
>> > -            s->mixer_regs[0x82] &= 1;
>> > +            s->mixer_regs[0x82] &= ~1;
> Shouldn't it be ~1u instead?

It's the same since mixer_regs is an array of uint8_t.

I'm not a fan of unsigned suffixes, especially after ~ where most of the
time they're wrong.  For example if x is uint64_t:

   x &= ~1            is right
   x &= ~1ull         is right
   x &= ~1u           also clears bits 32...64
   x &= ~1ul          also clears bits 32...64 on 32-bit machines

Paolo
Gerd Hoffmann Jan. 22, 2015, 9:56 a.m. UTC | #3
On Di, 2015-01-20 at 17:23 +0100, Paolo Bonzini wrote:
> SoundBlaster 16 emulation is very broken and consumes a lot of CPU, but a
> small fix was suggested offlist and it is enough to fix some games.  I
> got Epic Pinball to work with the "SoundBlaster Clone" option.
> 
> The processing of the interrupt register is wrong due to two missing
> "not"s.  This causes the interrupt flag to remain set even after the
> Acknowledge ports have been read (0x0e and 0x0f).
> 
> The line was introduced by commit 85571bc (audio merge (malc), 2004-11-07),
> but the code might have been broken before because I did not look closely
> at the huge patches from 10 years ago.

Looks sane, picked up.

thanks,
  Gerd
diff mbox

Patch

diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index bda26d0..444eb9e 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -999,7 +999,7 @@  static IO_READ_PROTO (dsp_read)
         retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
         if (s->mixer_regs[0x82] & 1) {
             ack = 1;
-            s->mixer_regs[0x82] &= 1;
+            s->mixer_regs[0x82] &= ~1;
             qemu_irq_lower (s->pic);
         }
         break;
@@ -1008,7 +1008,7 @@  static IO_READ_PROTO (dsp_read)
         retval = 0xff;
         if (s->mixer_regs[0x82] & 2) {
             ack = 1;
-            s->mixer_regs[0x82] &= 2;
+            s->mixer_regs[0x82] &= ~2;
             qemu_irq_lower (s->pic);
         }
         break;