home *** CD-ROM | disk | FTP | other *** search
- data segment
- c equ 523 ;tone frequencies
- d equ 587
- e equ 659
- f equ 698
- g equ 784
- a equ 880
- h equ 988
-
- Song: dw c,250, d,250, e,250, f,250, g,500, g,500
- dw a,250, a,250, a,250, a,250, g,500
- dw a,250, a,250, a,250, a,250, g,500
- dw f,250, f,250, f,250, f,250, e,500, e,500
- dw d,250, d,250, d,250, d,250, c,500
- dw 0 ;always terminate with 0
-
- oldInt dd 0 ;pointer to old handler
- counter dw 0 ;counter, decremented once per ms
- data ends
-
- code segment
- assume cs:code,ds:data
-
- handler proc far ;new IRQ 0 handler
- pushf
- call dword ptr oldint ;call old handler
- mov ax,data ;enable data segment access
- mov ds,ax
- dec word ptr counter ;decrement counter
- iret
- handler endp
-
- prepare proc near ;prepares timer and speaker
- mov dx,61h ;load control port
- in al,dx
- or al,3 ;set lower bits (enable speaker)
- out dx,al
-
- mov al,36h ;write access timer 0
- mov cx,04a9h ;interrupt distance 1 ms
- out 43h,al ;send command
- mov al,cl
- out 40h,al ;send timer value
- mov al,ch
- out 40h,al
-
- mov ax,3508h ;read old interrupt vector
- int 21h
- mov word ptr oldint,bx ;store vector
- mov word ptr oldint+2,es
- push ds
- mov ax,cs ;vector to handler in ds:dx
- mov ds,ax
- lea dx,handler
- mov ax,2508h ;and set new vector
- int 21h
- pop ds
- ret
- prepare endp
-
- close proc near ;sets back timer and speaker
- push ds
- lds dx,oldint ;restore old vector
- mov ax,2508h
- int 21h
-
- mov al,36h ;reset timer
- out 43h,al
- xor al,al
- out 40h,al ;to 18.2 interrupts per second
- out 40h,al
-
- mov dx,61h ;speaker off
- in al,dx
- and al,not 3 ;(clear speaker enable)
- out dx,al
- pop ds
- ret
- close endp
-
- delay proc near ;waits (time in ms in ax)
- mov counter,ax ;load counter
- wait1:
- cmp counter,0 ;wait until interrupt
- jne wait1 ;has counted counter to 0
- ret
- delay endp
-
- sound proc near
- mov bx,ax ;frequency to bx
- mov al,0b6h ;program timer 2 to rectangle
- out 43h,al
- mov dx,0012h ;1.193 MHz input frequency
- mov ax,34ddh
- div bx ;calculate timer value
- out 42h,al ;low byte to timer 2
- mov al,ah
- out 42h,al ;high byte to timer 2
- ret
- sound endp
-
- start proc
- mov ax,data ;enable access to data segment
- mov ds,ax
-
- call prepare ;initialize timer and speaker
-
- lea si,song ;pointer to frequencies
-
- continue:
- lodsw ;get frequency
- or ax,ax
- je finished ;close byte found ?
- call sound ;output sound
- lodsw ;load duration
- call delay ;and wait
- jmp continue
-
- finished:
- call close ;reset timer and interrupts
- mov ah,4ch ;end program
- int 21h
- start endp
-
- code ends
- end start
-