;
; GRDB
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; INTS.ASM
;
; Function: Interrupt table management
;
	.model small
	.386
	
include eoptions.inc
include eprints.inc

	public SetRMInts,IntSnapShot, UnLoadInts, ReleaseRMInts
	public SetVectAttrib, IntPage, int21adr, orgpic, int20adr

	.data
intpage	dw	0	; segment of interrupt save page
orgpic dw	0	; original pic masks (high byte = 21h)

	.code
int20adr	dd	0	;NOT fully implemented
int21adr	dd	0	; their version of int 21h
;
; keep the VECTLIST upper bit in sync with the options code
;
SetVectAttrib	PROC
	mov	ah,al
	lodsb
	add	si,2
	xchg	al,ah
	cmp	ah,0ffh
	jz	tv_End
	and	ah,7fh
	cmp	al,ah
	jnz	SetVectAttrib
	shl	bl,7
	and	byte ptr [si-3],7fh
	xor	bl,80h
	or	byte ptr [si-3],bl
tv_end:
	ret
SetVectAttrib	ENDP
;
; read vectlist and insert all our interrupts
;
; they are ONLY there during GO, tracing will bypass them
; and they won't be visible during idles
;
SetRMInts	PROC
	sub	ax,ax
	mov	fs,ax
	cli
mi_lp:
	lodsb             		; vect num & addr
	movzx	bx,al
	lodsw
	or	bl,bl
	js	testdone		; high bit means, don't modify
	shl	bx,2  			; else overwrite
	mov	fs:[bx],ax
	mov	fs:[bx+2],cs
	jmp	mi_lp
testdone:
	cmp	bl,0ffh
	jnz	mi_lp
	sti
	ret
SetRMInts	ENDP
;
; read vectlist and restore the old interrupts from the int page
;
ReleaseRMInts	PROC
	sub	ax,ax
	mov	fs,ax
	mov	gs,[intpage]
	cli
rmi_lp:
	lodsb  				; vect num & addr
	movzx	bx,al
	lodsw
	or	bl,bl
	js	rtestdone		; high bit means, don't write
	shl	bx,2                    ; else overrwrite
	mov	ax,gs:[bx]
	mov	fs:[bx],ax
	mov	ax,gs:[bx+2]
	mov	fs:[bx+2],ax
	jmp	rmi_lp
rtestdone:
	cmp	bl,0ffh
	jnz	rmi_lp
	mov	eax,cs:[int20adr]	; now restore int20h in case they
	mov	fs:[20h*4],eax   	; changed it
	mov	eax,cs:[int21adr]	; now restore int21h in case they
	mov	fs:[21h*4],eax   	; changed it
	sti
	ret
ReleaseRMInts	ENDP
;
; take a snapshot of all interrupts at program start
;
; we will unload EVERYTHING when we exit or when the program ends
;
IntSnapShot PROC
	mov	bx,40h
	mov	ah,48h
	int	21h
	jc	isn_err
	mov	[intpage],ax
	in	al,21h			; get pic masks
	xchg	al,ah
	in	al,0a1h
	mov	[orgpic],ax
	sub	di,di
	mov	bx,[intpage]
	sub	si,si
	push	ds
	push	es
	mov	es,bx
	mov	ds,si
	mov	cx,100h
	rep	movsd
	mov	eax,ds:[21h*4]		; now back up int 21h
	mov	cs:[int21adr],eax	; to the changeable address
	mov	eax,ds:[20h*4]		; now back up int 21h
	mov	cs:[int20adr],eax	; to the changeable address
	pop	es
	pop	ds
	clc
isn_err:
	ret
IntSnapShot ENDP
;
; unload everything.  There is a generic resource release routine
; that will later release the memory
; 
UnLoadInts	PROC
	push	ds
	push	es
	sub	di,di
	sub	si,si
	mov	es,di
	mov	ds,[intpage]
	mov	cx,100h
	rep	movsd
	pop	es
	pop	ds
	mov	ax,[orgpic]	; restore pic mask
	out	0a1h,al
	xchg	al,ah
	out	21h,al
	ret
UnLoadInts	ENDP
	end