;[]-------------------------------------------------------------------------[]
;|	Program name: 2_6_5.ASM                                              |
;|	Image   file: 2_6_5.COM                                              |
;|	Note        : This is a TSR program.                                 |
;|                    When you press any key, it will use INT 09H to beep.   |
;[]-------------------------------------------------------------------------[]


cseg	segment
	assume	cs:cseg,ds:cseg
	org	100H
start:
	jmp	initialize

;------- Data area ---------------------

old_int09	dd	?
old_int60	dd	?
old_int61	dd	?
busy_int09	db	0

;------- Include area ------------------

DEBUG	EQU	0
include	register.inc
include	interrup.inc
include	debug.inc

;------- INT 09H -----------------------

new_int09	proc	far

	pushf				; Execute Old INT 09H ISR
	call	cs:old_int09
	sti

	cmp	cs:busy_int09,1		; Test for nest interrupt
	je	done_int09		; If true, return to calling program

	mov	cs:busy_int09,1		; Set busy flag
	call	beep			; Let speaker beep
	mov	cs:busy_int09,0		; Reset busy flag

done_int09:
	iret

new_int09	endp

beep		proc	near

	pushr	<ax,cx>			; Save register

	mov	ah,7FH			; Beep time
	in	al,61H			; In data from 8255A
	jmp	$+2			; Wait for IN data
	and	al,0FCH			; Mask bit 2-7
b1:	xor	al,2			; Inverse bit 0,1
	out	61H,al			; Out data to 8255A
	mov	cx,7FH			; Delay time
b2:	loop	b2			; Delay loop
	dec	ah			; Beep loop
	jne	b1			;

	popr	<cx,ax>			; Restore register

	ret

beep		endp

;------- INT 60H -----------------------

new_int60	proc	far

	assume	cs:cseg,ds:nothing	; Override segment

	sti
	pushr	<ax,dx,ds>

	set_int	09H,<word ptr old_int09>,<word ptr old_int09[2]>
	set_int	60H,<word ptr old_int60>,<word ptr old_int60[2]>
	set_int	61H,<word ptr old_int61>,<word ptr old_int61[2]>

	popr	<ds,dx,ax>
	iret

new_int60	endp

;------- Main program ------------------

initialize:

	assume	cs:cseg,ds:cseg

	get_int	09H,old_int09
	set_int	09H,<offset new_int09>
	get_int	60H,old_int60
	set_int	60H,<offset new_int60>
	get_int	61H,old_int61
	set_int	61H,<offset new_int61>

	mov	dx,offset initialize	; Terminate and stay resident
	int	27H

cseg	ends
	end	start
