;[]-------------------------------------------------------------------------[]
;|	Program name: 2_5_3.ASM                                              |
;|	Image   file: 2_5_3.COM                                              |
;|	Note        : This is a TSR program.                                 |
;|                    When you press the 'Print Screen' key, it will display |
;|                      a message to tell you the DOS state.                 |
;[]-------------------------------------------------------------------------[]


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

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

old_int05	dd	?
old_int60	dd	?
in_dos_seg	dw	?
in_dos_off	dw	?
msg1		db	'Dos idle!',0DH,0AH,0
msg2		db	'Dos busy!',0DH,0AH,0

;------- INT 05H -----------------------

new_int05	proc	far

	sti

	push	si			; Save register
	push	ds

	push	cs			; Set ds value
	pop	ds

	call	in_dos			; Check whether INT 21H is working now
	jne	i05_1			; If NZ then branch
	mov	si,offset msg1		; ZR, so it is idle
	jmp	i05_2
i05_1:	mov	si,offset msg2		; NZ, so it is busy
i05_2:	call	dstring			; Display message

	pop	ds			; Restore register
	pop	si

	iret

new_int05	endp

; display message subroutine
; ds:si point to the message

dstring		proc	near

	push	ax			; Save the register value
	push	bx

	mov	bh,1			; Displaying
	mov	ah,0EH
dis0:
	mov	al,[si]
	cmp	al,0
	je	dis1
	int	10H
	inc	si
	jmp	dis0
dis1:

	pop	bx			; Restore the register value
	pop	ax

	ret

dstring		endp

; in_dos checking subroutine
; if INT 21H is working, it will set ZR flag.

in_dos		proc	near

	push	bx			; Save register
	push	es

	mov	bx,cs:in_dos_seg	; Let es:bx point to in_dos
	mov	es,bx
	mov	bx,cs:in_dos_off
	cmp	byte ptr es:[bx],0	; Checking

	pop	es			; Restore register
	pop	bx

	ret

in_dos		endp

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

new_int60	proc	far

	sti

	push	ax
	push	dx
	push	ds

	mov	dx,cs:word ptr old_int05	; restore INT 05H
	mov	ds,cs:word ptr old_int05[2]
	mov	ax,2505H
	int	21H

	mov	dx,cs:word ptr old_int60	; restore INT 60H
	mov	ds,cs:word ptr old_int60[2]
	mov	ax,2560H
	int	21H

	pop	ds
	pop	dx
	pop	ax

	iret

new_int60	endp

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

initialize:

	mov	ah,34H			; Get in_dos address
	int	21H
	mov	in_dos_seg,es		; Save in_dos in in_dos_seg
	mov	in_dos_off,bx		; and in_dos_off

	mov	al,05H			; Get the INT 05H interrupt vector
	mov	ah,35H
	int	21H
	mov	word ptr old_int05,bx	; Save the vector in old_int05
	mov	word ptr old_int05[2],es

	mov	al,60H			; Get the INT 60H interrupt vector
	mov	ah,35H
	int	21H
	mov	word ptr old_int60,bx	; Save the vector in old_int60
	mov	word ptr old_int60[2],es

	mov	dx,offset new_int05	; Set the INT 05H interrupt vector
	mov	al,05H
	mov	ah,25H
	int	21H

	mov	dx,offset new_int60	; Set the INT 60H interrupt vector
	mov	al,60H
	mov	ah,25H
	int	21H

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

cseg	ends
	end	start
