I am developing a 32 bit, protected mode hobby operating system. At the moment, I am looking to add simple sound support. To do this, I'm looking to use the sound blaster 16 and use the direct mode to write to the DAC (I want to avoid DMA at all costs). However, when I output a simple square wave to the DAC (using command 0x10), no sound is output from my computer's speakers. I'm looking for a solution to this problem.
I am trying to use the following algorithm to produce sound:
1. Reset DSP
2. Enable the speakers
3. Write 0x10 to 0x22C (direct mode DAC write command)
4. Write 0x00 to 0x22C (To set the speaker to low)
5. Write 0x10 to 0x22C
6. Write 0xFF to 0x22C (To set the speaker to high)
7. Jump back to step 4 and repeat.
Here is my code:
#define DSP_RESET 0x226
#define DSP_READ 0x22A
#define DSP_WRITE 0x22C
#define DSP_READ_STATUS 0x22E
#define DSP_INT_ACK 0x22F
#define REG_ADDR 0x224
#define REG_DATA 0x225
#define DIRECT_DAC 0x10
#define ENABLE_SPEAKER 0xD1
void dsp_reset(){
uint32_t buf[4];
*buf = 128;
rtc_write(0, buf, 4);
outb(1, DSP_RESET);
rtc_read(0, 0, NULL, 0);
outb(0, DSP_RESET);
if(inb(DSP_READ) != 0xAA){
print_term((uint8_t *)"Could not init sb16\n", 20);
}
return;
}
void play_simple_sound(){
dsp_reset();
while(inb(DSP_WRITE));
print_term((uint8_t *)"Enabling speaker\n", 18);
outb(0xD1, DSP_WRITE);
while(inb(DSP_WRITE));
print_term((uint8_t *)"Playing sound\n", 14);
outb(0xF0, DSP_WRITE);
while(1){
while(inb(DSP_WRITE));
outb(0x10, DSP_WRITE);
outb(0x00, DSP_WRITE);
rtc_read(0, 0, NULL, 0);
while(inb(DSP_WRITE));
outb(0x10, DSP_WRITE);
outb(0xFF, DSP_WRITE);
rtc_read(0, 0, NULL, 0);
}
return;
}
rtc_write sets the rtc frequency to a couple hundred hertz, and rct_read makes the program wait on the rtc (both these programs work correctly). The dsp_reset also works correctly, because when reading the output from the DSP, 0xAA is returned (which shows that a soundblaster 16 exists).
At the moment I am using windows 10 64 bit to run Qemu which emulates the operating system. I am running qemu with the "-soundhw all" option set. I am unsure whether I am unable to hear sound because of the code I have written or if there is something wrong with Qemu. My question is, what could the issue possibly be, and what are the steps I can take to fix this? Also, documentation and tutorials related to the sb 16 would be appreciated.
volatile
or you clobber a register without telling the compiler. – Gougeinb
/outb
are fine, but wrong constraints to inline asm can happen to work depending on the surrounding code. Working in other contexts does not prove that your definition is safe. – Gougeoutw
to write a 16-bit integer? But yeah, I have no idea what the mixer defaults would be, whether it maybe defaults to muted or low volume. – Gouge