pan069
Member
- Joined
- Jun 4, 2019
- Messages
- 38
Doing a bit more work this weekend on my Sound Blaster project. I seem to have the DMA setup working [1] however, I seem to be running into a problem running on real hardware.
The IRQ seemed to be triggered by the SB at the correct intervals, however, in my IRQ handler I was calling a callback function that would update my audio buffer. All this seems to work OK within DOSBox but the moment I am running on real hardware (286/16 + SoundBlaster 2.0 [1350B]) I get weird results and crashes. When I do everything directly from the interrupt hander it seems to work fine. Is it not possible to call a function inside an interrupt handler?
My code looks something like this (stripping it down to make it less verbose):
That is my callback handler that is called from the interrupt handler. I'm just updating the screen to get some visual feedback rather than using audio which can be less accurate to spot potential issues. The callback just starts filling the screen (text mode) first with 'a' characters (blue background, white foreground) and once the screen is full it restarts with 'b' characters and changes the background to green (+0x10), etc...
This is the actual interrupt handler:
The above code acknowledges the transfer to the Sound Blaster by reading the status register. It then calls the callback and finally acknowledges the interrupt.
The IRQ handler is initialised as follows:
And in my main function somewhere:
Oh, I am using OpenWatcom. I am targeting 16bit DOS. These are my compiler options:
Any ideas welcome...
[1] https://forum.vcfed.org/index.php?threads/dma-addressing.1241044/
The IRQ seemed to be triggered by the SB at the correct intervals, however, in my IRQ handler I was calling a callback function that would update my audio buffer. All this seems to work OK within DOSBox but the moment I am running on real hardware (286/16 + SoundBlaster 2.0 [1350B]) I get weird results and crashes. When I do everything directly from the interrupt hander it seems to work fine. Is it not possible to call a function inside an interrupt handler?
My code looks something like this (stripping it down to make it less verbose):
Code:
volatile unsigned char _vchar = 'a';
volatile unsigned char _vcol = 0x1f;
volatile unsigned short _voffset = 0;
void on_sb_event()
{
unsigned short far *v = (unsigned short far*)0xb8000000L;
v[_voffset++] = ((_vcol << 8) | _vchar);
if (_voffset > 80*25 - 1) {
_voffset = 0;
_vchar++;
_vcol += 0x10;
}
}
This is the actual interrupt handler:
Code:
void (* _on_event)(void);
void interrupt _sb_irq_handler()
{
inp(0x220 + SB_IO_READ_BUFFER_STATUS);
_on_event();
outp(0x20, 0x20);
}
The IRQ handler is initialised as follows:
Code:
void sb_irq_capture(int sb_irq, void (* on_event)(void))
{
_on_event = on_event;
_sb_old_irq = _dos_getvect(8 + sb_irq);
_dos_setvect(8 + sb_irq, _sb_irq_handler);
outp(0x21, inp(0x21) & !(1 << sb_irq));
}
void sb_irq_release(int sb_irq)
{
_dos_setvect(8 + sb_irq, _sb_old_irq);
outp(0x21, inp(0x21) & (1 << sb_irq));
}
And in my main function somewhere:
Code:
sb_irq_capture(sb_irq, &on_sb_event);
Oh, I am using OpenWatcom. I am targeting 16bit DOS. These are my compiler options:
Code:
wcc -w2 -e25 -zq -2 -d0 -zp=2 -mc -bt=dos -fo=build/$@ src/$*.c -i$(WATCOM)/h
Any ideas welcome...
[1] https://forum.vcfed.org/index.php?threads/dma-addressing.1241044/
Last edited: