Audio – How to use the direct write mode to write a simple SoundBlaster 16 driver for a hobby operating system?

I am developing a 32-bit, protected mode hobby operating system. Currently, I want to add simple sound support. For this, I want to use Sound Blaster 16 and write in direct mode Into the DAC (I want to avoid using DMA at all costs). However, when I output a simple square wave to the DAC (using command 0x10), there is no sound output from my computer speakers. I am looking for a solution to this problem. < p>

I tried to use the following algorithm to generate 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.

This 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 ", 20);
}

return;
}

void play_simple_sound(){

dsp_reset();

while(inb(DSP_WRITE));
print_term((uint8_t *)"Enabling speaker ", 18);
outb(0xD1, DSP_WRITE);

while(inb(DSP_WRITE));
print_term((uint8_t *)"Playing sound ", 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 several hundred hertz, and rct_read makes the program wait on rtc (Both programs work normally). dsp_reset can also be positive It often works, because when reading the output from the DSP, it returns 0xAA (indicating the presence of sounder 16).

Currently I am using Windows 10 64-bit to run Qemu that emulates the operating system. I am using “- “soundhw all” option set to run qemu. I am not sure if I can’t hear the sound due to a problem with the code I wrote or Qemu. My question is, what could be the problem, and what measures can I take to solve it? In addition, documentation and tutorials related to sb 16 will be greatly appreciated.

Under Qemu simulation, use Soundblaster 16 cannot use DAC directly. Direct ADC is not allowed. Check the source code found here to see the commands supported from line 390:

https://github.com/ qemu/qemu/blob/master/hw/audio/sb16.c

It seems that in order to use the sound transmitter card to output sound, you have to use DMA. Further, it seems that the SB16 emulation on Q16 is very lacking A series of commands supported by SB16 can be found here: http://the.earth.li/~tfm/oldpage/sb_dsp.html. Compare these commands with those supported by Qemu, only a small part of them are simulated .

Edit 2: Look at other emulators, Bochs does not support sb16 (see line 858: http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/sound/sb16 .cc), but DOSBox has very impressive SB16 support and supports direct DAC, but still does not support microphone direct ADC (see line 1611: http://dosbox-x.com/doxygen/html/sblaster_8cpp_source. html) )

I am developing a 32-bit, protected mode hobby operating system. Currently, I want to add simple sound support. For this, I want to use sound Shockwave 16 and write to the DAC using direct mode (I want to avoid using DMA at all costs). However, when I output a simple square wave to the DAC (using command 0x10), there is no sound output from my computer speakers. I am looking for The solution to this problem.

I tried to use the following algorithm to generate 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. Writ e 0x10 to 0x22C
6. Write 0xFF to 0x22C (To set the speaker to high)
7. Jump back to step 4 and repeat.

This is my code:< /p>

#define DSP_RESET 0x226
#define DSP_READ 0x22A
#define DSP_WRITE 0x22C
#define DSP_READ_STATUS 0x22E
#define DSP_INT_ACK 0x22F< br />
#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);< br /> rtc_read(0, 0, NULL, 0);
outb(0, DSP_RESET);

if(inb(DSP_READ) != 0xAA){
print_term( (uint8_t *)"Could not init sb16 ", 20);
}

return;
}

void play_simple_sound(){< br />
dsp_reset();

while(inb(DSP_WRITE));
print_term((uint8_t *)"Enabling speaker ", 18);
outb(0xD1, DSP_WRITE);< br />
while(inb(DSP_WRITE));
print_term((uint8_t *)"Playing sound ", 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 several hundred hertz, and rct_read makes the program in rtc Wait (both programs work normally). dsp_reset can also work normally, because when reading the output from the DSP, it returns 0xAA (indicating the presence of sounder 16).

Currently I am using Windows 10 64-bit to run Qemu emulating the operating system. I am running qemu with the “-soundhw all” option set. Due to the code I wrote or there is a problem with Qemu, I am not sure if I can’t hear the sound. My question is, the problem may be What is it and what can I do to solve this problem? In addition, documents and tutorials related to sb 16 will be greatly appreciated.

Under the Qemu simulation, the DAC cannot be used directly with the soundblaster 16. It is also not allowed to use direct ADC. Check the source code found here to see the commands supported from line 390:

https://github.com/qemu/qemu/blob/master/hw/audio/ sb16.c

It seems that in order to use the sound transmitter card to output sound, you must use DMA. Furthermore, it seems that the SB16 emulation on Q16 is very lacking. A series of real SB16 support can be found here Command: http://the.earth.li/~tfm/oldpage/sb_dsp.html. Compare these commands with the commands supported by Qemu and only simulate a small part.

Edit 2: Look Looking at other emulators, Bochs does not support sb16 (see line 858: http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/sound/sb16.cc), but DOSBox has very impressive SB16 supports, and supports direct DAC, but still does not support microphone direct ADC (see line 1611: http://dosbox-x.com/doxygen/html/sblaster_8cpp_source.html) )

< p>

Leave a Comment

Your email address will not be published.