| ECE291 | Computer Engineering II | Plavcan, Summer 1997 |
Lecture X

DSP controlled via commands to I/O ports.
Port |
Function |
| BASE+6 | Reset |
| BASE+Ah | Read data port |
| BASE+Ch | Write data port |
| BASE+Ch | Status port |
| BASE+Eh | Data Available register |
| BASE+Fh | Acknowledge (SB16 only) |
DSPWRITE macro x ; write x to DSP chip local notrdy push ax mov dx,cs:sb_addr add dx,STATUS ; poll status register notrdy: ; STATUS=0Ch in al,dx test al,80h jnz notrdy pop ax push ax mov al,x out dx,al pop ax endm |
DSPREAD macro ; read from DSP chip local notrdy mov dx,cs:sb_addr add dx,AVAIL ; poll data available register notrdy: ; AVAIL=0Eh in al,dx test al,80h jz notrdy add dx,READ-AVAIL in al,dx ; byte read in al endm |
To reset the DSP:
; ; Reset SoundBlaster ; return value (AL): ; 0 - reset unsuccessful, wrong port?/no card found? ; AA - card found and reset successfully ; dsp_reset proc near mov dx,sb_addr add dx,RESET mov al,1 ; send 1 to reset reg. out dx,al add dx,AVAIL-RESET mov cx,8 burn1: in al,dx ;wait 3 us loop burn1 add dx,RESET-AVAIL mov al,0 ; send 0 to reset out dx,al add dx,AVAIL-RESET mov cx,400 burn2: in al,dx ;wait 100+ us loop burn2 in al,dx test al,80h ; test data available mov al,0 jz rstdn mov dx,sb_addr add dx,READ in al,dx rstdn: ret dsp_reset endp |
Once the DSP is reset, you may issue commands (only a few are listed, see the SoundBlaster Reference for complete list):
Command |
Value |
Notes |
| Speaker On | 0D1h | |
| Speaker Off | 0D3h | |
| Set timing constant | 040h | Then write 256 - 1,000,000/Freq Example: write 165 for 11KHz |
| Play 8-bit DMA | 01Vh | where V=4 for 8-bit mono Example: write 14h to play 8-bit mono. |
| Record 8-bit DMA | 02Vh | |
| Pause 8-bit DMA | 0D0h | |
| Continue 8-bit DMA | 0D4h | |
| Stop 8-bit DMA | 0DAh |
First, find the page and page offset of the sample we wish to play/record.
To get the page #, we calculate our linear (absolute) address. The upper
4 bits are the page:

To set up a transfer, perform the following steps
See Lecture Z for more details on how to program the 8237 DMA controller.
See "Sound Blaster Hardware Programmers Guide" (Creative
Labs) for more information on the DSP chips in various versions of the
SoundBlaster.
; ; Generic ISR to acknowledge sound interrupt to PIC ; dsp_irqdone proc far push ax push dx mov dx,cs:sb_addr ; sb_addr is port address add dx,AVAIL ; AVAIL=0Eh, data available port cmp cs:dma_type,8 je ack add dx,INT16-AVAIL ; INT16=0Fh, 16-bit acknowledge(SB16 only) ack: in al,dx ; ack interrupt for DSP with dummy read mov al,20h out 20h,al ; write EOI to 8259A cmp cs:sb_irq,8 ; do we need to ack slave PIC? (IRQ>7) jb idone out 0A0h,al ; write EOI to 8259B idone: pop dx pop ax iret dsp_irqdone endp |
Stero sound is accomplies by setting up the DMA transfer for stereo, and the data is in the format:

The SoundBlaster DSP only provides a single channel of irregular waveform playback. If we have a fairly simple sound, we can use the Adlib FM synthesis chip (modern version: Yamaha OPL) to provide up to 20 different intrsuments to playback music. It is common to use the DSP for sound effects that cannot be produced by the FM chip, and use the FM chip to play background music.
The base ports for the FM chip are388h for mono sound, and 220h (222h=right channel) for stereo sound. The data registers lie at BASE+1.The ports are read only, except for the status port (BASE+0).
Like the DSP, there is a delay that needs to be observed for writing to early sound cards (modern ones are much faster):
; outfmport - access adlib ports, with proper delays ; inputs: ; ah - port index to be written ; al - byte to be written ; dx - port base address ; outfmport proc near push ax push cx mov al,ah out dx,al cmp cs:opl,3 ; ignore delay if new card je skip1 mov cx,6 lp1: in al,dx loop lp1 skip1: pop ax push ax inc dx out dx,al dec dx cmp cs:opl,3 ; ignore delay for new cards je skip2 mov cx,35 lp2: in al,dx loop lp2 skip2: pop cx pop ax ret outfmport endp |
The FM cards supports operators that may be used independently, or combined to create complex sounds. In addition, a set of percussion effects have been hardcoded into the chip. Using these effects will disable certain voices (6,7,8). The operators are each controlled by a set of registers:
Register
|
Function |
| 20-35 | Amplitude Modulation/Vibrato/Frequency Multiplier |
| 40-55 | Key Scaling/Operator Output Level |
| 60-75 | Attack/Decay reate |
| 80-95 | Sustain/Release Rates |
| A0-A8 | Frequency (8 LSBs) |
| B0-B8 | Key On/Octave/Frequency(2 MSBs) |
| C0-C8 | Feedback strength/Stereo enable/Operator Connection |
| E0-F5 | Wavefrom select |
Refer to the OPL3 documentaion for a complete description of the bits and functions of the regsiters.
Stereo sound is only supported by OPL3. However, many sound cards used a pair of OPL2 ships, mapped to ports 220h and 222h, which acts similar to the OPL3 chip. For OPL2, the voices are controlled independently. For OPL3, you must use bits 4 and 5 in the feedback register of the operator to enable left and right channels (per operator). The OPL3 command must be enabled by setting bit 0 of register 5.
Advanced sound cards conatin a mixer chip that can control the volume levels of the sounds produced by the CDROM,DSP, FM, Microphone,etc., even controlling the balance between left and right channels. The Mixer on SoundBlaster compatible cards lies at port BASE+4 (index) and BASE+5 (data):
Channel |
Value |
| Master | 22h |
| Microphone | 0Ah |
| CD-ROM | 28h |
| DSP | 04h |
| FM | 26h |
| Line In | 2Eh |
