;       SCCSID = @(#)dosasert.asm	6.1 90/11/17
ifdef NEVERNEVER
;      SCCSID = @(#)dosasert.asm	13.7 90/09/17
TITLE	DOSASERT - Internal consistency checks
NAME	DOSASERT


.xlist
include dosseg.inc
include basemaca.inc
include osmaca.inc
include oldmaca.inc
include dossymc.inc
include buffer.inc
include devsym.inc
include protmode.inc
include sft.inc
include vpb.inc
.list

AsmVars <NET, Debug>

ReferGlobal	TaskData,WORD
;ReferGlobal	DPBhead,DWORD
ReferGlobal	sftFCB,WORD
ReferGlobal	CurrentPDB,WORD
ReferTask	TempSFT,BYTE
ReferTask	Force_Flg,BYTE
ReferTask	SysCallSfcn,WORD

EXTRN		DPRINTF:NEAR
EXTRN		SFFromSFN:NEAR
EXTRN		PointComp:NEAR

zfmt	MACRO	fmts,args
local	a,b
	PUSHF
	PUSH	AX
	PUSH	BP
TABLE	segment
a	db	fmts,0
TABLE	ends
	MOV	AX,OFFSET DOSGROUP:a
	PUSH	AX
	MOV	BP,SP
IRP item,<args>
IFIDN	<AX>,<item>
	MOV	AX,[BP+4]
ELSE
	MOV	AX,item
ENDIF
	PUSH	AX
ENDM
	call	DPRINTF
	MOV	SP,BP
	POP	AX			; discard format string
	POP	BP
	POP	AX
	popf
ENDM

TABLE	SEGMENT
;DPBMes DB  "DPB assertion failed: ",0
VPBMes	DB  "VPB assertion failed: ",0
BUFMes	DB  "BUF assertion failed: ",0
CURMes	DB  "CURBUF assertion failed: ",0
SFTMes	DB  "SFT assertion failed: ",0
TABLE	ENDS

	FARCODE LOW
CODE	SEGMENT

segFrame	struc
segbp		dw	?
segip		dw	?
segmes		dw	?
segtemp		dw	?
segax		dw	?
segcaller	dw	?
segFrame	ends

AstFrame	struc
Astbp		dw	?
Astip		dw	?
Astmes		dw	?
Astarg		dd	?
AstFrame	ends

BREAK	<SegCheck - validate segments in MSDOS>
;**	SegCheck - assure that segments are correctly set up
;
;	ENTRY	top of stack points to:
;		2-byte jump
;		byte flags 04h is ES 02h is DS 01 is CS/SS
;		offset asciz message
;
;	EXIT	message to debugging output
;
;	USES	Nothing (flags too)

	ASSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING

Procedure   SegCheck,NEAR
	SaveReg <bp>
	mov	bp,sp			; set up addressing
	pushf
	SaveReg <ax,bx,cx,dx>
	mov	al,byte ptr [bp].segtemp; get flags
	mov	cx,cs
	test	al,1			; shall we use CS or SS?
	jnz	SegUseCS		; use CS
	mov	cx,ss			; use SS instead
	push	ds
	DosContext ds
	cmp	cx,TaskData		; Validate SS value
	pop	ds
    ASSUME   DS:NOTHING
	jz	SegUseCS
	zfmt	<"SS not set to TASKAREA $s, called at $x\n">,<AX,BX>
SegUseCS:
	test	al,2			; do we check DS?
	jz	SegTestES		; no, go check ES
	mov	dx,ds
	cmp	cx,dx
	jz	SegTestES		; DS is valid, go check ES
	mov	ax,[bp].segmes
	mov	bx,[bp].segcaller
	zfmt	<"Assumed DS invalid $s, called at $x\n">,<AX,bx>
	mov	al,byte ptr [bp].segtemp; get flags
SegTestES:
	test	al,4			; do we check ES?
	jz	SegTestDone		; no, all done
	mov	dx,es
	cmp	cx,dx
	jz	SegTestDone		; ES is valid, all done
	mov	ax,[bp].segmes
	mov	bx,[bp].segcaller
	zfmt	<"Assumed ES invalid $s, called at $x\n">,<AX,bx>
SegTestDone:
	RestoreReg  <dx,cx,bx,ax>
	popf
	RestoreReg  <bp>
	ret	4			; release message, temp
EndProc SegCheck


;;**	DPBCheck - validate a supposed DPB pointer
;;
;;	ENTRY	Pushed arguments
;;	EXIT	Message to screen
;;	USES	none
;
;Procedure   DPBCheck,NEAR
;	MOV	Msg,OFFSET DOSGroup:DPBMes
;	SaveReg <BP>
;	MOV	BP,SP
;	PUSHF
;	SaveReg <AX,BX,DS,SI,ES,DI>
;	LES	DI,DPBHead
;	LDS	SI,[BP].Astarg
;DPBLoop:
;	CMP	DI,-1
;	JZ	Assert_Error
;	call	PointComp
;	JZ	VPBRet
;	LES	DI,ES:[DI.dpb_next_dpb]
;	JMP	DPBLoop
;EndProc DPBCheck

;**	xVPBCheck - validate a supposed VPB pointer
;
;	ENTRY	Pushed arguments
;	EXIT	Message to screen
;	USES	none

	ASSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING

Procedure   xVPBCheck,NEAR
	SaveReg <bp>
	mov	bp,sp
	pushf
	SaveReg <ax,bx,ds,si,es,di>
	mov	ax,es			; es:bp to ds:si
	mov	ds,ax
	mov	si,ss:[bp]
	dec	ax			; back up to arena header
	mov	es,ax
	cmp	es:[0Ah],si		; handle match?
	jnz	xVPB_err

; check sector size for reasonableness

	mov	ax,ds:[vpb_fsi.vpi_cbSector]
	test	ax,NOT (128+256+512+1024)
	jnz	xVPB_err

; check that cluster_mask is 2^cluster_shift - 1

	xor	ah,ah
	mov	al,ds:[vpb_fsd.vpdFAT_cluster_mask]
	push	cx
	mov	cl,ds:[vpb_fsd.vpdFAT_cluster_shift]
	inc	ax
	ror	ax,cl
	pop	cx
	cmp	ax,1
	jz	VPBRet
xVPB_err:
	mov	bx,offset DOSGROUP:VPBMes
Assert_Error:
	mov	ax,[bp].Astmes
	zfmt	<"$s$x:$x $s\n">,<bx,ds,si,AX>
	clI
a:	jmp	a			; slam the door.
VPBRet:
	RestoreReg <di,es,si,ds,bx,ax> ;   Done:
	popf
	RestoreReg <bp>
	ret	6
EndProc xVPBCheck

;**	SFTCheck - validate a supposed SFT pointer
;
;	ENTRY	Pushed arguments
;	EXIT	Message to screen
;	USES	none

	ASSUME	DS:NOTHING,ES:NOTHING,SS:TASKAREA

Procedure   SFTCheck,NEAR
	SaveReg <bp>
	mov	bp,sp
	pushf
	SaveReg <ax,bx,ds,si,es,di>
	lds	si,[bp].Astarg
	xor	bx,bx			;   i = 0;
SFTLoop:
	SaveReg <BX>
	call	SFFromSFN		;   while ((d=SF(i)) != NULL)
	RestoreReg  <BX>
	jc	sft1
	call	PointComp
	jz	VPBRet			;		goto Done;
SFTNext:
	inc	bx			;	    else
	jmp	SFTLoop			;		i++;
sft1:
	DosContext es
	mov	es,sftFCB
    ASSUME   ES:NOTHING
	mov	bx,es:[sft_count]
	mov	di,SIZE sft		; (es:di) -> sf entry array
sft2:
	call	PointComp
VPBRetj:
	jz	VPBRet
	add	di,size sf_entry
	dec	bx
	jnz	sft2
;
; The SFT is not in the allocated tables.  See if it is one of the static
; areas.
;
	TaskContext ES
	mov	di,offset TASKAREA:TempSFT
	call	PointComp
	jz	VPBRetj
	mov	bx,offset DOSGROUP:SFTMes
	jmp	Assert_Error
EndProc SFTCheck,NoCheck


;**	BUFCheck - validate a supposed BUF pointer
;
;	ENTRY	Pushed arguments
;	EXIT	Message to screen
;	USES	none

	ASSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING

Procedure   BUFCheck,NEAR
	SaveReg <bp>
	mov	bp,sP
	pushf
	SaveReg <ax,bx,ds,si,es,di>
bufch0:
	les	di,[bp].Astarg		; (ES:DI) = buffer to check
	BufferContext <ds>
	mov	si,ds:[bs_MRUHead]	; (DS:SI) = MRU buffer

	mov	ax,ds
	mov	bx,es
	cmp	ax,bx
	je	BUFcheck_err		; Not in buffer segment

     ASSUME  ES:NOTHING
BUFLoop:
	cmp	si,-1
	je	BUFcheck_err		; Hit end of list without match
	cmp	si,di
	jne	BufNext			; Found buffer
	jmp	VPBRet
BufNext:
	mov	si,ds:[si].buf_next	; (DS:SI) = next buffer
	jmp	BUFLoop
BUFcheck_err:
	mov	bx,offset DOSGROUP:BUFMes
	jmp	Assert_Error
EndProc BUFCheck,NoCheck


;**	CURBUFCheck - validate a supposed BUF pointer
;
;	ENTRY	Pushed arguments
;	EXIT	Message to screen
;	USES	none

	ASSUME	DS:NOTHING,ES:NOTHING,SS:TASKAREA

Procedure   CURBUFCheck,NEAR
	SaveReg <bp>
	mov	bp,sp
	pushf
	SaveReg <ax,bx,ds,si,es,di>
	lds	si,[bp].Astarg
	test	Force_Flg,FF_BUF		; is buffer assigned?
	LJZ	CURBUFcheck_err
	test	ds:[si].buf_flags,BUF_BUSY
	LJZ	CURBUFcheck_err
	jmp	bufch0
CURBUFcheck_err:
	mov	bx,offset DOSGROUP:CURMes
	jmp	Assert_Error
EndProc CURBUFCheck,NoCheck

CODE	ENDS
endif ; NEVERNEVER
	END
