;--------------------------------------------------------------------------- ; SB_DSP.ASM -- Programmer's library for the Sound Blaster DSP interface ; ver 1.0 (Thursday, March 12, 1992) ;--------------------------------------------------------------------------- ; Copyright (C) 1992, Heath I Hunnicutt ;--------------------------------------------------------------------------- ; By: heathh@cco.caltech.edu -or- heathh@tybalt.cco.caltech.edu ; aka hihunn@through.ugcs.caltech.edu (NOT preferred) ;--------------------------------------------------------------------------- ; Requires: Sound Blaster sound card or compatible ; Turbo Assembler from Borland ; A DMA library such as dma_code.asm by me ;--------------------------------------------------------------------------- ; Warning: Be sure that there is a card installed before calling these ; routines. ;--------------------------------------------------------------------------- IDEAL MODEL medium DATASEG SB_IO_Port DW 0220h ;These values are kept here to avoid add DSP_Reset DW 0226h ;instructions in code that may be time- DSP_RDData DW 022Ah ;sensitive. DSP_Command DW 022Ch DSP_RDAvail DW 022Eh DSP_WRData EQU DSP_Command ;Aliases for the same variable name DSP_Status EQU DSP_Command CODESEG PUBLIC _dsp_reset,_dsp_voice,_set_SB_address,_dsp_dma_prepare,_dsp_time MACRO await_DSP LOCAL @@Wait_Ready push ax dx @@Wait_Ready: mov dx,[DSP_Status] in al,dx and al,128 jnz @@Wait_Ready pop dx ax ENDM MACRO MACRO ten_microsec_delay LOCAL @@KT ;If you know of a better, more accurate, push cx ;more reliable, just plain smarter, way mov cx,20000 ;to do this, PLEASE TELL ME. @@KT: ; nop ;(The idea is to kill 10 microseconds.) loop @@KT ; pop cx ;email: heathh@cco.caltech.edu ENDM ten_microsec_delay ;--------------------------------------------------------------------------- ; void far dsp_time(int pacing) ;--------------------------------------------------------------------------- ; pacing = 255 - (1,000,000 / frequency) ;--------------------------------------------------------------------------- PROC _dsp_time FAR ARG delay:WORD push bp mov bp,sp push ax dx await_DSP mov dx,[DSP_Command] mov al,040h out dx,al await_DSP mov dx,[DSP_Command] mov ax,[delay] out dx,al pop dx ax pop bp ret ENDP _dsp_time ;--------------------------------------------------------------------------- ; int far dsp_reset(void) ;--------------------------------------------------------------------------- PROC _dsp_reset FAR mov dx,[DSP_Reset] mov al,1 ; Send a reset pulse out dx,al ten_microsec_delay mov al,0 out dx,al mov cx,200 ; Check 200 times before failing @@Wait_Ready: mov dx,[DSP_RDAvail] in al,dx and al,128 jz @@Not_Ready mov dx,[DSP_RDData] in al,dx cmp al,0AAh je @@Found_SB @@Not_Ready: loop @@Wait_Ready mov ax,0 ; Return false ret @@Found_SB: mov ax,165 push ax call _dsp_time pop ax ; ax!=0 so returns true ret ENDP _dsp_reset ;--------------------------------------------------------------------------- ; void far dsp_dma_prepare(int Dir,int Length) ;--------------------------------------------------------------------------- ; Dir = 0 for Microphone Input, 1 for Speaker Output ; Length = Length of data to be sampled/played ;--------------------------------------------------------------------------- PROC _dsp_dma_prepare FAR ARG Dir:WORD,Len:WORD push bp mov bp,sp push ax dx await_DSP mov al,24h cmp [Dir],0 jz @@Is_Read mov al,14h @@Is_Read: mov dx,[DSP_Command] out dx,al await_DSP mov ax,[Len] out dx,al await_DSP mov al,ah out dx,al pop dx ax pop bp ret ENDP _dsp_dma_prepare ;--------------------------------------------------------------------------- ; void far dsp_voice(Activity) ;--------------------------------------------------------------------------- ; Activity = 0 for silent, 1 for audible ;--------------------------------------------------------------------------- PROC _dsp_voice FAR ARG Which:WORD push bp mov bp,sp push dx ax await_DSP mov ax,[Which] and al,1 ;Want a 1/0 parameter xor al,1 shl al,1 or al,0D1h mov dx,[DSP_Command] out dx,al pop ax dx pop bp ret ENDP _dsp_voice ;--------------------------------------------------------------------------- ; void far set_SB_address(int base) ;--------------------------------------------------------------------------- ; Sets base port of SoundBlaster that other functions refer to. ; Most likely value (and the default): 0x220 ;--------------------------------------------------------------------------- PROC _set_SB_address FAR ARG Port:WORD push bp mov bp,sp push ax mov ax,[Port] mov [SB_IO_Port],ax add ax,6 mov [DSP_Reset],ax add ax,4 mov [DSP_RDData],ax add ax,2 mov [DSP_Command],ax add ax,2 mov [DSP_RDAvail],ax pop ax pop bp ret ENDP _set_SB_address END