;[]-------------------------------------------------------------------------[]
;|	Program name: 5_3_4.ASM                                              |
;|	Image   file: 5_3_4.COM                                              |
;|	Note        : Hole Lock protection program.                          |
;|                    ( The TSR routine will check the MCB )                 |
;[]-------------------------------------------------------------------------[]


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

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

no_use		db	?
mark		db	'HoleLock'
old_int13	dd	?
old_int01	dd	?
old_int03	dd	?
old_int60	dd	?
old_int61	dd	?
err_msg		db	'No effect!',0DH,0AH,'$'
ter_msg		db	'TSR ok!',0DH,0AH,'$'
PSP		dw	0

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

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

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

new_int60	proc	far

	assume	cs:cseg,ds:nothing	; Override segment

	sti
	pushr	<ax,dx,ds>

	set_int	01H,<word ptr old_int01>,<word ptr old_int01[2]>
	set_int	03H,<word ptr old_int03>,<word ptr old_int03[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

;------- Check MCB in memory -----------

check_mcb	proc	near

	assume	cs:cseg,ds:cseg

	mov	di,0
	mov	cx,0
	mov	bx,3FFH

;=======================================
; Find the first MCB
;=======================================

@@1:	inc	bx
	mov	es,bx
	cmp	byte ptr es:[di],'M'
	jz	@@2
	cmp	byte ptr es:[di],'Z'
	jnz	@@1

@@2:	mov	ax,es
	mov	dx,es
@@3:	inc	dx
	cmp	dx,psp
	jz	@@4
	add	dx,es:[di+3]
	jc	@@1
	cmp	dx,0A000H
	ja	@@1
	mov	es,dx
	jmp	@@3

;=======================================
; Count the quantity of the processes
;=======================================

@@4:	mov	es,ax
	cmp	word ptr es:[di+1],0
	jz	@@5
	cmp	word ptr es:[di+1],8
	jz	@@5
	mov	bx,ax
	inc	bx
	cmp	es:[di+1],bx
	jnz	@@5
	inc	cx

@@5:	add	ax,es:[di+3]
	inc	ax
	cmp	ax,0A000H
	jnz	@@4

;=======================================
; Check the count
;=======================================

	mov	dx,offset ter_msg
	cmp	cx,2
	je	@@6
	pop	dx			; discard return address
	mov	dx,offset err_msg
@@6:	mov	ah,09H
	int	21H
	ret

check_mcb	endp

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

initialize:

	assume	cs:cseg,ds:cseg

	mov	cs:PSP,ds
	call	check_mcb

	get_int	13H,old_int13
	get_int	01H,old_int01
	set_int	01H,<offset new_int60>
	get_int	03H,old_int03
	set_int	03H,<offset new_int60>
	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 check_mcb	; Terminate and stay resident
	int	27H

cseg	ends
	end	start
