According to the SB programmers guide, and several web sites that I've seen, the SB16 sends an interrupt (IRQ 5 on VirtualBox) when the audio buffer has finished playing, and it sets a flag in mixer register 82h. The driver/interrupt handler is supposed to acknowledge the interrupt by reading 1 byte from the base I/O Port + 0Fh (in 16-bit mode). So far, so good.
The problem is that the interrupt flag (bit 1) on register 82h is never cleared, even after the I/O port has been read. I was using this flag to determine when to re-fill the DMA buffer, but after it is set the first time, it is never cleared, so it always appears that an interrupt just occurred. I tried several things to clear this flag -- reading from 0Fh, writing to 0Fh, writing to register 82h, etc, but I can't find any way to clear the flag. I would assume the flag should be cleared after the 16-bit status port is read (0Fh), but the documentation doesn't mention this anywhere, and I can't find any references to this being a problem on google.
Would anyone happen to know if this is actual SB16 (DSP 4+) behavior, or if this is a bug in VirtualBox?
Right now, I'm just using the interrupt to fill the buffer, and ignoring the interrupt flag (but still sending the acknowledge by reaing 0Fh). But if any other device ever uses the same IRQ, this will become an issue real quick.
I may try digging through the VirtualBox source and see if I can figure out what is going on.
Thanks guys.
EDIT: After looking through the source, I found this:
Code: Select all
1164 case 0x0e: /* data available status | irq 8 ack */
1165 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1166 if (s->mixer_regs[0x82] & 1) {
1167 ack = 1;
1168 s->mixer_regs[0x82] &= 1; // PROBLEM!
1169#ifndef VBOX
1170 qemu_irq_lower (s->pic[s->irq]);
1171#else
1172 PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
1173#endif
1174 }
1175 break;
1176
1177 case 0x0f: /* irq 16 ack */
1178 retval = 0xff;
1179 if (s->mixer_regs[0x82] & 2) {
1180 ack = 1;
1181 s->mixer_regs[0x82] &= 2; // PROBLEM!!
1182#ifndef VBOX
1183 qemu_irq_lower (s->pic[s->irq]);
1184#else
1185 PDMDevHlpISASetIrq(s->pDevIns, s->irq, 0);
1186#endif
1187 }
1188 break;
Anyone able to submit this fix to the VBox repository, or should I just put in a bug report. Is there a way I can submit this bug fix without downloading the entire project?
Thanks guys.
EDIT: Submitted ticket: https://www.virtualbox.org/ticket/13769