Для SB-совестимых звуковушек я делал так:
;Пример программы, проигрывающей файл C:\WINDOWS\MEDIA\TADA.WAV
;на звуковой плате при помощи DMA
FILESPEC equ "01.wav" ;Воспроизводимый файл
SBPORT equ 220h ;Адрес SB
SBIRQ equ 7
.model tiny
.code
.186
org 100h
start: call dsp_reset
jnc cont
ret
cont: mov byte ptr cs:state,0
mov bl,0D1h
call dsp_write
call open_file
call hook_sbirq
mov bl,40h
call dsp_write
mov bl,0D2h ;0D2h
call dsp_write
call program_dma
push dx
mov ah,9
mov dx,offset messagestrt
int 21h
pop dx
mov al,byte ptr cs:state
mov byte ptr cs:stat,al
push dx
mov ah,9
mov dx,offset countb
int 21h
mov ax,word ptr cs:bytes
mov al,ah
call outhex
mov ax,word ptr cs:bytes
call outhex
mov ah,9
mov dx,offset counte
int 21h
pop dx
mainlp:mov al,byte ptr finished_flag
cmp al,128
je mainen
mov al,byte ptr cs:state
cmp byte ptr cs:stat,al
je mainlp
mov byte ptr cs:stat,al
push dx
mov ah,9
mov dx,offset countb
int 21h
mov ax,word ptr cs:bytes
mov al,ah
call outhex
mov ax,word ptr cs:bytes
call outhex
mov ah,9
mov dx,offset counte
int 21h
mov dx,word ptr bytes
inc dx
mov word ptr bytes,dx
pop dx
push ds
mov bx,40h
mov ds,bx
mov bx,17h
mov al,byte ptr ds:[bx]
pop ds
and al,3h
jz mainlp
mov dx,offset messageend
jmp exit
mainen:mov dx,offset messagefin
exit: mov ah,9
int 21h
call restore_sbirq
mov bl,0D3h
call dsp_write
mov bl,0D0h
call dsp_write
mov bl,0DAh
call dsp_write
mov bl,0D0h
call dsp_write
int 20h
ret
;Переменные
old_sbirq dd ?
finished_flag db 0
filename db FILESPEC,0
bytes dw 0
stat db 0
countb db 0Dh, "Воспроизведение блока номер $"
counte db "H.$"
messagestrt db "Воспроизведение. Для остановки нажмите любой SHIFT."
db 0Dh, 0Ah, '$'
messageend db 0Dh, 0Ah, "Прервано пользователем.", 0Dh, 0Ah, '$'
messagefin db 0Dh, 0Ah, "Кончилось.", 0Dh, 0Ah, '$'
;Обработчик прерывания звуковой карты
;Устанавливает флаг finished_flag в 128 если кончился файл
sbirq_handler proc far
pusha
mov al,20h
out 20h,al
mov dx,SBPORT+0Eh
in al,dx
mov ax,word ptr cs:file
mov bx,ax
mov ah,3Fh
mov cx,4000h
push ds
mov dx,ds
and dx,0F000h
mov al,byte ptr cs:state
or al,al
jnz second
first: add dx,1000h
mov ds,dx
mov dx,0
int 21h
pop ds
jc close
cmp ax,0
je close
mov byte ptr cs:state,255
popa
iret
second:add dx,1400h
mov ds,dx
mov dx,0
int 21h
pop ds
jc close
cmp ax,0
je close
mov byte ptr cs:state,0
popa
iret
close: mov byte ptr cs:finished_flag,128
popa
iret
state db 0
file dw 0
sbirq_handler endp
;Процедура outhex
;Выводит al в HEX виде
outhex proc near
push ax
shr al,4
and al,15
cmp al,10
jc out0
add al,7
out0: add al,48
mov byte ptr txt,al
pop ax
and al,15
cmp al,10
jc out1
add al,7
out1: add al,48
mov byte ptr txt+1,al
push dx
mov ah,9
mov dx,offset txt
int 21h
pop dx
ret
txt db 0,0,'$'
outhex endp
;Процедура dsp_reset
;Сброс и инициализация DSP
dsp_reset proc near
mov dx,SBPORT+6
mov al,1
out dx,al
mov cx,40
dsp_loop: in al,dx
loop dsp_loop
mov al,0
out dx,al
add dx,8
mov cx,100
check_port:in al,dx
and al,80h
jz not_ready
sub dx,4
in al,dx
add dx,4
cmp al,0AAh
je good_reset
not_ready: loop check_port
stc
ret
good_reset:clc
ret
dsp_reset endp
;Процедура dsp_write
;Посылает байт из BL в DSP
dsp_write proc near
mov dx,SBPORT+0Ch
write_loop:in al,dx
and al,80h
jnz write_loop
mov al,bl
out dx,al
ret
dsp_write endp
;Процедура hook_sbirq
;Перехватывает прерывание звуковой карты и разрешает его
hook_sbirq proc near
mov ax,3508h+SBIRQ
int 21h
mov word ptr old_sbirq,bx
mov word ptr old_sbirq+2,es
mov ax,2508h+SBIRQ
mov dx,offset sbirq_handler
int 21h
mov cl,1
shl cl,SBIRQ
not cl
in al,21h
and al,cl
out 21h,al
ret
hook_sbirq endp
;Процедура restore_sbirq
;Восстанавливает обработчик и запрещает прерывание
restore_sbirq proc near
mov ax,3508h+SBIRQ
lds dx,dword ptr old_sbirq
int 21h
mov cl,1
shl cl,SBIRQ
in al,21h
or al,cl
out 21h,al
ret
restore_sbirq endp
;Процедура open_file
;Открывает файл и заполняет буфер
open_file proc near
mov ax,3D00h
mov dx,offset filename
int 21h
jc error_exit
mov word ptr cs:file,ax
mov bx,ax
mov ax,4200h
mov cx,0
mov dx,38h
int 21h
mov ah,3Fh
mov cx,8000h
push ds
mov dx,ds
and dx,0F000h
add dx,1000h
mov ds,dx
mov dx,0
int 21h
pop ds
ret
error_exit:
mov ah,9
mov dx,offset not_open_msg
int 21h
int 20h
;Сообщение об ошибке
not_open_msg db "Ошибка при открытии файла",0Dh,0Ah,'$'
open_file endp
;Процедура program_dma
;Настраивает 1 канал DMA
program_dma proc near
mov al,5
out 0Ah,al
xor al,al
out 0Ch,al
mov al,59h ;Для авто = 59h
out 0Bh,al
push cs
pop dx
and dh,0F0h
add dh,10h
xor ax,ax
out 02h,al
out 02h,al
mov al,dh
shr al,4
out 83h,al
mov ax,8000h
dec ax
out 03h,al
mov al,ah
out 03h,al
mov al,1
out 0Ah,al
mov bl,48h
call dsp_write
mov bx,4000h
dec bx
call dsp_write
mov bl,bh
call dsp_write
mov bl,01Ch
call dsp_write
ret
program_dma endp
end start
Файл - непожатая WAVка.