dosgame1/system/dos/SoundBlaster.cpp

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;
}