48 lines
1.4 KiB
C++
48 lines
1.4 KiB
C++
#include "../SoundBlaster.h"
|
|
|
|
#include <go32.h>
|
|
|
|
SoundBlaster soundblaster;
|
|
|
|
void soundblasterIsr() {
|
|
soundblaster.onInterrupt();
|
|
}
|
|
|
|
SoundBlaster::SoundBlaster() {
|
|
// Allocate twice the amount needed and select one half depending on whether it crosses a 64k boundary
|
|
_dmaBuffer.size = (SB_DMA_BUFFER_SIZE + 15) >> (4-1);
|
|
_go32_dpmi_allocate_dos_memory(&_dmaBuffer);
|
|
|
|
auto physFirst = (_dmaBuffer.rm_segment << 4) + _dmaBuffer.rm_offset;
|
|
auto physSecond = physFirst + SB_DMA_BUFFER_SIZE;
|
|
auto pageFirst = physFirst >> 16;
|
|
auto pageSecond = physSecond >> 16;
|
|
|
|
if (pageFirst == pageSecond) {
|
|
// Use first half
|
|
_buffers = reinterpret_cast<decltype(_buffers)>(physFirst);
|
|
_dmaPage = pageFirst;
|
|
_dmaOffset = physFirst & 0xFFFF;
|
|
} else {
|
|
// Use second half
|
|
_buffers = reinterpret_cast<decltype(_buffers)>(physSecond);
|
|
_dmaPage = pageSecond;
|
|
_dmaOffset = physSecond & 0xFFFF;
|
|
}
|
|
}
|
|
|
|
SoundBlaster::~SoundBlaster() {
|
|
_go32_dpmi_free_dos_memory(&_dmaBuffer);
|
|
}
|
|
|
|
void SoundBlaster::onInterrupt() {
|
|
// No data available - should not happen, but let's force generate a block
|
|
if (_nextBufferReadIndex == _nextBufferWriteIndex) {
|
|
generateSamples();
|
|
}
|
|
|
|
dosmemput(_buffers, SB_BUFFER_SIZE, (_dmaBuffer.rm_segment << 4) + _nextBufferReadIndex * SB_BUFFER_SIZE);
|
|
_nextBufferReadIndex = (_nextBufferReadIndex + 1) & 3;
|
|
}
|
|
|