;-------------------
;     From: Dana Holt
;  Subject: Beep statment
 
; Example program on how to program the timer ch 2 to sound the
; internal speaker...
;  
; Formula for calculating timer divisor word:
;
;          1,193,180
;        -------------- = divisor
;         Desired freq
;

LOW_TONE        equ        16000
HIGH_TONE       equ        100
STEP            equ        100


mov     bx,LOW_TONE        ; load bx with div

; this just loops through a bunch of different freqs and
; then exits

l1:

mov     cx,1              ; load cx with duration (in 1/18 of a sec)
push    bx
call    SPKR_ON
pop     bx
sub     bx,STEP
cmp     bx,HIGH_TONE
jge     l1

call    SPKR_OFF
mov     ax,4c00h
int     21h


;******************
;Turn speaker on and setup timer
; 
;BX holds divisor for timer on entry
;CX holds counter for tone duration
;******************

SPKR_ON     proc     near

; Set bits 0 and 1 in port 61h

in       al,61h
or       al,3
jmp      $+2        ; I/O delay
out      61h,al

; Program timer channel 2

mov      al,0b6h    ; 10110110
jmp      $+2
out      43h,al     ; send to 8253 command register

; Send divisor

mov      al,bl      ; LSB
jmp      $+2
out      42h,al     ; to timer ch 2
mov      al,bh      ; MSB
jmp      $+2
out      42h,al     ; to timer ch 2

; Now wait for CX 1/18ths of a sec

call     TIME_DELAY

ret

SPKR_ON     endp


;*****************
; Turn speaker off
;*****************

SPKR_OFF     proc        near

; Reset bits 0 and 1 of port 61h to turn off spkr

in     al,61h
and    al,0fch
jmp    $+2
out    61h,al

ret

SPKR_OFF     endp

;*******************
;TIME DELAY
; 
;CX holds number of 1/18 sec to wait (18 = 1 sec)
;*******************

TIME_DELAY     proc        near

; use time of day clock at int 1ah to cause a delay

mov     bx,cx    ; CX used by 1ah so let's move to BX

mov     ah,0
int     1ah      ; read clock



;DX = low-order byte of clock

add     bx,dx

DELAY_LOOP:
int     1ah
cmp     bx,dx
jge     DELAY_LOOP
ret

TIME_DELAY     endp

