DMA_ADDR equ 02h
DMA_COUNT equ 03h
DMA_MASK equ 0ah
DMA_MODE equ 0bh
DMA_BPTR equ 0ch
DMA_PAGE equ 83h
REG_RST equ 226h
REG_RDATA equ 22ah
REG_WDATA equ 22ch
REG_WSTAT equ 22ch
REG_RSTAT equ 22eh
REG_INTACK equ 22eh
CMD_PAUSE8 equ 0d0h
CMD_EXIT8 equ 0dah
CMD_START8 equ 0c0h
CMD_SETRATE equ 41h
bits 16
section code
..start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, stacktop
call reset_dsp
mov ax, 0900h
mov dx, msg_rstok
int 21h
cli
mov ax, 350dh
int 21h
mov [prev_isr_seg], es
mov [prev_isr_off], bx
mov dx, intr_handler
push ds
mov ax, cs
mov ds, ax
mov ax, 250dh
int 21h
pop ds
sti
call prog_dma
mov ax, 22050
call set_rate
mov ax, pcmdata_end - pcmdata
call prog_dsp
mainloop:
in al, 60h
dec al
jnz mainloop
cli
push ds
mov ax, [prev_isr_seg]
mov ds, ax
mov dx, [prev_isr_off]
mov ax, 250dh
int 21h
pop ds
sti
exit:
mov ax, 4c00h
int 21h
reset_dsp:
mov dx, REG_RST
mov al, 1
out dx, al
xor al, al
out 80h, al
out 80h, al
out 80h, al
out dx, al
mov dx, REG_RSTAT
.waitdata:
in al, dx
and al, 80h
jz .waitdata
mov dx, REG_RDATA
.waitaa:
in al, dx
cmp al, 0aah
jnz .waitaa
ret
pause_dsp8:
mov al, CMD_PAUSE8
call write_dsp
ret
write_dsp:
push dx
mov ah, al
mov dx, REG_WSTAT
.wait:
in al, dx
and al, 80h
jnz .wait
mov al, ah
out dx, al
pop dx
ret
read_dsp:
push dx
mov dx, REG_RSTAT
.wait:
in al, dx
and al, 80h
jz .wait
mov dx, REG_RDATA
in al, dx
pop dx
ret
prog_dsp:
push cx
dec ax
mov cx, ax
mov al, CMD_START8
call write_dsp
xor al, al
call write_dsp
mov al, cl
call write_dsp
mov al, ch
call write_dsp
pop cx
ret
intr_handler:
pusha
call pause_dsp8
mov dx, REG_INTACK
in al, dx
mov al, 20h
out 20h, al
popa
iret
set_rate:
push cx
mov cx, ax
mov al, CMD_SETRATE
call write_dsp
mov al, ch
call write_dsp
mov al, cl
call write_dsp
pop cx
ret
prog_dma:
push dx
mov dx, DMA_MASK
mov al, 5
out dx, al
mov dx, DMA_BPTR
out dx, al
mov dx, DMA_MODE
mov al, 49h
out dx, al
xor ebx, ebx
mov bx, data
shl ebx, 4
xor eax, eax
mov ax, pcmdata
add eax, ebx
mov ebx, eax
mov dx, DMA_ADDR
out dx, al
mov al, ah
out dx, al
mov dx, DMA_PAGE
mov eax, ebx
shr eax, 16
out dx, al
mov ax, pcmdata_end - pcmdata - 1
mov dx, DMA_COUNT
out dx, al
mov al, ah
out dx, al
mov dx, DMA_MASK
mov al, 1
out dx, al
pop dx
ret
section data
msg_rstok db 'DSP reset',13,10,'$'
prev_isr_seg resw 1
prev_isr_off resw 1
align 16384
pcmdata:
incbin "click.pcm"
pcmdata_end:
segment stack stack
resb 64
stacktop: