7

我正在开发一个 32 位、保护模式的爱好操作系统。目前,我正在寻找添加简单的声音支持。为此,我希望使用 Sound blaster 16 并使用直接模式写入 DAC(我想不惜一切代价避免 DMA)。但是,当我向 DAC 输出一个简单的方波(使用命令 0x10)时,我的计算机扬声器没有声音输出。我正在寻找解决这个问题的方法。

我正在尝试使用以下算法来产生声音:

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.

这是我的代码:

#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 将 rtc 频率设置为几百赫兹,而 rct_read 使程序在 rtc 上等待(这两个程序都可以正常工作)。dsp_reset 也可以正常工作,因为从 DSP 读取输出时,会返回 0xAA(这表明存在 soundblaster 16)。

目前我正在使用 Windows 10 64 位来运行模拟操作系统的 Qemu。我正在运行带有“-soundhw all”选项集的 qemu。我不确定是否因为我编写的代码而无法听到声音,或者 Qemu 是否有问题。我的问题是,问题可能是什么,我可以采取哪些步骤来解决这个问题?此外,与 sb 16 相关的文档和教程将不胜感激。

4

1 回答 1

4

在 Qemu 仿真下,无法使用 Soundblaster 16 进行直接 DAC。也不允许使用直接 ADC。查看此处找到的源代码,查看从第 390 行开始支持的命令:

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

看来要使用 Sound Blaster 卡输出声音,您必须使用 DMA。更进一步,Qemu 上的 SB16 仿真似乎非常缺乏。可以在此处找到真正的 SB16 支持的命令列表:http: //the.earth.li/~tfm/oldpage/sb_dsp.html。将这些命令与 Qemu 支持的命令进行比较,只模拟了一小部分。

编辑 2:查看其他模拟器,Bochs 不支持 sb16(参见第 858 行: http: //bochs.sourceforge.net/cgi-bin/lxr/source/iodev/sound/sb16.cc),但 DOSBox 令人印象深刻SB16 支持,并且确实支持直接 DAC,但仍然不支持麦克风直接 ADC(参见第 1611 行: http: //dosbox-x.com/doxygen/html/sblaster_8cpp_source.html

于 2018-11-14T21:32:24.107 回答