如何使用直接写入模式为业余爱好操作系统编写简单的 Soundblaster 16 驱动程序?

问题描述 投票:0回答:2

我正在开发一个 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 相关的文档和教程将不胜感激。

audio x86 operating-system osdev hobby-os
2个回答
4
投票

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

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

看来为了使用声卡输出声音,必须使用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


0
投票

我现在正在尝试在一个简单的爱好操作系统上做和你一样的事情。晚了几年,但想知道你们是否都找到了解决方法实施?或者你最终实施了 DMA?

© www.soinside.com 2019 - 2024. All rights reserved.