code_seg        segment
        assume  cs:code_seg
        org     100h
        jmp     start
;----------------------------------
;B/C Software                        ;Author
;520 North Stateline Rd
;Sharon, Pa 16146
;----------------------------------
delay    dw     0                    ;place to store our delay count
message1 db     'press Esc to Quit',0dh,0ah,'$'     ;Esc to end phone_tone
message2 db     'press any other key to play$'      ;or to go again
;----------------------------------
start   proc    near
        mov     ah,9                 ;DOS function number to print string
        mov     dx,offset message1   ;the message
        int     21h                  ;DOS interrupt
        mov     ah,9                 ;DOS function number to print string
        mov     dx,offset message2   ;the message
        int     21h                  ;DOS interrupt
begin:  mov     ah,0                 ;BIOS function wait for key press
        int     16h                  ;BIOS interrupt
        cmp     ah,1                 ;Esc scan code 
        jz      done                 ;do we stop ?
        call    phone_tone           ;no call phone_tone
        jmp     begin                ;go see if we do it again
done:   mov     ax,4c00h             ;no exit back to DOS
        int     21h                  ;DOS interrupt
start   endp
;----------------------------------
phone_tone      proc    near
        cli                     ;lets not allow interrupts
go_2:   mov     si,2            ;do the - two six pulse groups - two times
mainx:  mov     di,2            ;do group of six pulses two times
mainy:  mov     dx,6            ;do six pulses of each tone
mainz:  mov     bx,2000         ;frequency of first tone
        call    workman         ;go set timer chip and send (bx) to port
        mov     delay,1         ;place first delay count in (delay)       
        call    delayer         ;wait a bit before next tone
        mov     bx,1600         ;frequency of second tone
        call    workman         ;go set timer chip and send (bx) to port
        mov     delay,1         ;place first delay count in (delay)
        call    delayer         ;wait a bit before next time
        dec     dx              ;decrement pulse count
        jnz     mainz           ;have we done six pulses
        dec     di              ;yes go do second group of six pulses
        jnz     mainy           ;have we done two groups
        in      al,61h          ;yes - turn speaker off  
        and     al,11111100xb   ;this number turns speaker off
        out     61h,al          ;send it to port
        mov     delay,30        ;place second delay count in delay
        call    delayer         ;wait a while  
        dec     si              ;if si not 0
        jnz     mainx           ;go do two more - six pulse - groups
        sti                     ;time to enable interrupts
        ret                     ;go see if user wants to go again
phone_tone      endp
;----------------------------------
delayer proc    near
        push    ax           ;save these registers
        push    bx
        push    dx
        mov     ah,0         ;want to read time
        int     01ah         ;get initial tick count
        add     dx,delay     ;add our count to tick count  
        mov     bx,dx        ;place it in bx            
delay_it:                  
        int     01ah         ;get reading again
        cmp     dl,bl        ;compare reading to delay count
        jne     delay_it     ;go back and repeat if not equal
        pop     dx
        pop     bx
        pop     ax           ;restore used registers
        ret
delayer endp
;--------------------------------------
workman proc  near
        mov     al,10110110xb  ;channel 2
        out     43h,al         ;operation mode 3
        mov     ax,bx          ;place freqrency in ax
        out     42h,al         ;send LSB first
        mov     al,ah          ;place MSB in al
        out     42h,al         ;send it next
        in      al,61h         ;get 8255 port contents
        or      al,00000011xb  ;this number turns speaker on
        out     61h,al         ;turn it on now
        ret
workman         endp
;----------------------------------
code_seg        ends


