;***************************************************************************;
;									    ;
;				UltraStat 3.x				    ;
;			    DEVICE STATUS SCREEN			    ;
;									    ;
;***************************************************************************;
;Copyright (C) 1988 UltraSoft Corporation.  All Rights Reserved.
;
;Written by: David Pallmann
;
;All edit history for USTAT is in USYM.M68.

	ASMMSG	"== UltraStat 3.x (DEVICE) =="
	AUTOEXTERN

;--- Include files

	SEARCH	SYS
	SEARCH	SYSSYM
	SEARCH	TRM
	COPY	DSKINF.CPY
	COPY	USYM/L

;--- Device Scanning Loop

DEV.SCAN::
	MOV	DEVTBL,A0		; point to base of job table
	LEA	DIB,DT.TBL(MEM)
	MOVB	JOB.ROW(MEM),ROW(MEM)	; set starting job row
	CLRB	JOB.UPDATE(MEM)		; clear new arrow row
	CLRW	DEV.COUNT(MEM)		; 

DEV.BYPASS:
	MOVWL	JOB.OFFSET(MEM),D0
	BEQ	DEV.LOOP
10$:	TST	DV.NXT(A0)
	JEQ	SNOOZE
	MOV	DV.NXT(A0),A0
	ADD	#DT.SIZ,DIB
	INCW	DEV.COUNT(MEM)		; 
	SOB	D0,10$

DEV.LOOP:
	KEY	GET.COMMAND
	BIT	#F$UPDATE,FLAGS(MEM)
	BEQ	10$
	OR	#DT$NEW,DT.FLG(DIB)
10$:	MOV	A0,DCB

;--- Handle a device

UPDATE.DEVICE:
	CALL	DEV.NAME
	KEY	10$
	CALL	DEV.SIZE
	KEY	10$
	CALL	DEV.INUSE
	KEY	10$
	CALL	DEV.NOTES
	AND	#^C<DT$NEW>,DT.FLG(DIB)
10$:	CALL	ARROW

DEV.NEXT::
	INCW	DEV.COUNT(MEM)		; 
	TST	DV.NXT(A0)
	JEQ	SNOOZE
	ADD	#DT.SIZ,DIB
	MOV	DV.NXT(A0),A0
	INCB	ROW(MEM)		; increment display row
	CMMB	ROW(MEM),LAST.ROW(MEM)	; end of page?
	JLOS	DEV.LOOP		;  no - on to next device
	JMP	SNOOZE

;--- Update device name (three letter code and unit)

DEV.NAME:
	MOVW	DV.DEV(DCB),D0
	MOVW	DV.UNT(DCB),D2
	BIT	#DT$NEW,DT.FLG(DIB)
	BNE	10$
	CMPW	D0,DT.DEV(DIB)
	BNE	10$
	CMPW	D2,DT.DRV(DIB)
	REQ
10$:	MOVW	D0,DT.DEV(DIB)
	MOVW	D2,DT.DRV(DIB)
	MOVW	DV.FLG(DCB),DT.NOT(DIB)
	CURSOR	ROW(MEM),#2
	HIGH
	OUTDEV	DT.DEV(DIB)
	MOVWL	D2,D1
	DCVT	0,OT$TRM
	TYPESP	:
	MOVB	ROW(MEM),JOB.UPDATE(MEM)
	CALL	LOCATE.DRIVER
	RTN

LOCATE.DRIVER:
	CLR	DT.DVR(DIB)
	CMPW	DT.DEV(DIB),#[DSK]
	BEQ	10$
	MOVW	DT.DEV(DIB),TEMP(MEM)
	CLRW	TEMP+2(MEM)
	MOVW	#[DVR],TEMP+4(MEM)
	SRCH	TEMP(MEM),A6
	BEQ	20$
	RTN
10$:	MOV	ZSYDSK,A6
20$:	MOV	A6,DT.DVR(DIB)
	RTN

;--- Update device size

DEV.SIZE:
	CLR	D0
	BITW	#DV$MNT,DT.NOT(DIB)
	BEQ	10$
	MOV	DT.DVR(DIB),D6
	BEQ	10$
	MOV	D6,A6
	MOV	DD.DSZ(A6),D0
10$:	BIT	#DT$NEW,DT.FLG(DIB)
	BNE	20$
	CMP	D0,DT.MAX(DIB)
	REQ
20$:	MOV	D0,DT.MAX(DIB)
	CURSOR	ROW(MEM),#9.
	HIGH
	MOV	D0,D1
	BEQ	30$
	DCVT	7,OT$TRM!OT$ZER
	BR	40$
30$:	TYPE	<       >
40$:	MOVB	ROW(MEM),JOB.UPDATE(MEM)
	RTN

;--- Update device blocks in use (and, blocks free)

DEV.INUSE:
	CLR	D0
	TST	DT.DVR(DIB)		; do we know address of driver?
	BEQ	100$			;  no - forget about bitmap
	BITW	#DV$MNT,DT.NOT(DIB)	; is this device mounted?
	BEQ	100$			;  no - forget about bitmap
	MOV	DT.MAX(DIB),D2		; get #blocks into D2
	CALL	READ.BITMAP		; point A1 to bitmap
	BNE	100$			;  failed
;[116]	CLR	D5			; clear #blocks
;[116]10$:	MOV	#8.-1,D3
;[116]	MOVB	(A1)+,D1
;[116]	MOV	#1,D4
;[116]20$:	MOVB	D1,D7
;[116]	ANDB	D4,D7
;[116]	BEQ	30$
;[116]	INC	D5			; add 1 to count
;[116]30$:	ASL	D4			; update bit to test
;[116]	DEC	D2
;[116]	BEQ	40$
;[116]	DBF	D3,20$			; loop
;[116]	BR	10$
;[116]40$:	MOV	D5,D0
	MOV	INFO+DI.USE(MEM),D0	; get blocks in use		[116]
	MOV	D0,D5			; 				[116]

;D0 now contains zero (non-disk or non-mounted device), or number of blocks
;in use

100$:	BIT	#DT$NEW,DT.FLG(DIB)
	BNE	110$
	CMP	D0,DT.INU(DIB)
	REQ
110$:	MOV	D0,DT.INU(DIB)
	MOVB	ROW(MEM),JOB.UPDATE(MEM)
	CURSOR	ROW(MEM),#17.
	HIGH
	MOV	D0,D1
	BNE	120$
	TYPE	<              >
	BR	DEV.FREE
120$:	DCVT	7,OT$TRM!OT$ZER
	TST	DT.MAX(DIB)
	JEQ	DEV.FREE
	MOV	DT.INU(DIB),D0
	MUL	D0,#100.
	MOV	DT.MAX(DIB),D2
	DIV	D0,D2
	AND	#177777,D0
	TYPE	< (>
	MOV	D0,D1
	CMP	D1,#100.
	BNE	130$
	CLR	D1
	TYPE	1
130$:	DCVT	2,OT$TRM!OT$ZER
	TYPESP	%)

DEV.FREE:
	CLR	D0
	TST	DT.INU(DIB)
	BEQ	10$
	MOV	DT.MAX(DIB),D0
	SUB	DT.INU(DIB),D0
10$:	MOV	D0,DT.FRE(DIB)
	CURSOR	ROW(MEM),#31.
	HIGH
	MOV	D0,D1
	BNE	20$
	TYPE	<              >
	RTN
20$:	DCVT	7,OT$TRM!OT$ZER
	TST	DT.MAX(DIB)
	REQ
	MOV	DT.FRE(DIB),D0
	MUL	D0,#100.
	MOV	DT.MAX(DIB),D2
	DIV	D0,D2
	AND	#177777,D0
	TYPE	< (>
	MOV	D0,D1
	CMP	D1,#100.
	BNE	30$
	CLR	D1
	TYPE	1
30$:	DCVT	2,OT$TRM!OT$ZER
	TYPESP	%)
	RTN

;RETURN BITMAP ADDR IN A1 FOR DEVICE @DCB
;determine if bitmap is paged or not.  If it is paged, we must read the
;bitmap from disk to insure that we have the right one.  If bitmap is not
;paged, we can speed things up tremendously by directly accessing the bitmap
;already in memory.

READ.BITMAP:
	SAVE	A0,A2-A5,D0-D5
;[116]	MOV	DV.BMP(DCB),D7		; address bitmap DDB+flags+buffer	[1.3]
;[116]	BEQ	20$			; no bitmap
;[116]	MOV	D7,A1
;[116]	BITW	#BM$PAG,D.DDB(A1)	; is bitmap paged?		[1.3]
;[116]	BNE	10$			;  yes, it is			[1.3]
;[116]	BITW	#BM$VLD,D.DDB(A1)	; is bitmap valid for this device?
;[116]	BEQ	10$			;  no
;[116]	ADD	#D.DDB+2,A1		;  no - point to in-memory bitmap
;[116]	TST	@A1			; is first lword zeroed?	[1.3]
;[116]	BEQ	10$			;  yes - load bitmap to be sure [1.3]
;[116]	REST	A0,A2-A5,D0-D5
;[116]	LCC	#PS.Z
;[116]	RTN				; return			[1.3]
;[116] 10$:
	MOVW	DV.DEV(DCB),DISK+D.DEV(MEM)
	MOVW	DV.UNT(DCB),DISK+D.DRV(MEM)
	CLR	DISK+D.FIL(MEM)
	CLRW	DISK+D.EXT(MEM)
	CLRW	DISK+D.PPN(MEM)
	MOV	DT.DVR(DIB),DISK+D.DVR(MEM) ; DEBUG			[116]

	LEA	A0,INFO(MEM)		; 				[116]
	CLEAR	@A0,DI.SIZ		; clear disk info area		[118]
	LEA	A2,DISK(MEM)		; 				[116]
	CALL	DSKINF			; 				[116]

;[116]	DSKBMR  DISK(MEM)		; read bitmap from disk		[1.3]
;[116]	MOV	DISK+D.ARG(MEM),A1	; point A1 to bitmap area	[1.3]
;[116]	ANDW	#^C<BM$LOK>,-2(A1)	; clear bitmap lock		[1.3]
	REST	A0,A2-A5,D0-D5
	LCC	#PS.Z
	RTN				; return			[1.3]
20$:	REST	A0,A2-A5,D0-D5
	LCC	#0
	RTN

;--- Update device notes

DEFINE	OUT1	FLAG,TEXT
	BITW	#FLAG,DT.NOT(DIB)
	BEQ	1$$
	TYPESP	TEXT
1$$:
	ENDM

DEV.NOTES:
	MOVWL	DV.FLG(DCB),D0
	AND	#DV$MNT!DV$LOG!DV$14D!DV$NAC!DV$ASN!DV$SHR,D0
	BIT	#DT$NEW,DT.FLG(DIB)
	BNE	10$
	CMPW	D0,DT.NOT(DIB)
	REQ
10$:	MOVW	D0,DT.NOT(DIB)
	HIGH
	CURSOR	ROW(MEM),#46.
	CLREOL
	OUT1	DV$SHR,sharable
	OUT1	DV$ASN,assigned to
	BITW	#DV$ASN,DT.NOT(DIB)
	BEQ	20$
	MOV	DV.JCB(DCB),A6
	OUTNAM	JOBNAM(A6)
20$:	OUT1	DV$MNT,mounted
;;	OUT1	DV$LOG,logical
	OUT1	DV$14D,extended
	OUT1	DV$NAC,private
	MOVB	ROW(MEM),JOB.UPDATE(MEM)
	CALL	DISK.LABEL
	RTN

;--- output disk label if (a) in wide mode, (b) device mounted, and (c)
;    driver located.

DISK.LABEL:
	BIT	#F$WIDE,FLAGS(MEM)
	REQ
	BITW	#DV$MNT,DT.NOT(DIB)
	REQ
	TST	DT.DVR(DIB)
	REQ
	MOVW	DT.DEV(DIB),DISK+D.DEV(MEM)
	MOVW	DT.DRV(DIB),DISK+D.DRV(MEM)
	MOV	DT.DVR(DIB),DISK+D.DVR(MEM)
	CLR	DISK+D.REC(MEM)
	READ	DISK(MEM)
	MOV	DISK+D.BUF(MEM),A2
	CURSOR	ROW(MEM),#78.
	HIGH
	CMPW	LB.HDR(A2),#125252	; labelled?
	BNE	10$			;  no
	CMPW	LB.HDR+2(A2),#52525	; labelled?
	BNE	10$			;  no
	TTYL	LB.VLN(A2)		; output volume name
	TSTB	LB.VID(A2)		; is there an Id?
	BEQ	10$			;  no - skip the parentheses
	TYPE	< (>
	TTYL	LB.VID(A2)		; volume Id
	TYPE	)
10$:	CLREOL
	RTN

	END