	.title	'Available Hard Disk partitions for Hinet stations'
	.sbttl	'DIRNET'
version	==	2
revision==	0
        .pabs
	.phex
	.loc	100h
	sspd	saveSP	; save BDOS SP
	lxi	SP,stack; use our own SP
	call	MAIN	; call this program
	lda	4
	mov	C,A
	call	SELDSK	; restore disk selection
	lspd	saveSP	; restore BDOS SP
	ret
saveSP:	.word	0
	.blkw	16
stack:
;----------
; We will read the Disk Allocation Table into memory
; directly from the network. The partition names are
; then printed out in rows of three along with their
; respective sizes. The table in memory is then
; destroyed and we return to CP/M.
;					D. Stein
;					11/13/80
WBaddr	=	01h     ; Warm boot location
alloctab=	4000h	; addr of alloc table
usernum =	47h	; assigned user number loc
cr	=	0Dh	; Ascii carriage return
lf	=	0Ah	; Ascii line feed
;----------
; Print a greeting
MAIN:
	lxi	H,LOGmsg
	call	prtmsg
	mvi	C,0FFh
	call	SELDSK	; select net boot disk
	call	CPMMAP
	cpi	0C0h	; make sure assigned to net 0
	jrnz	NETdead	; No. Die.
;
; The Network is up OR we are on the network master.
; Read in the allocation table from the hard disk.
getTABL:
	lxi	B,0
	call	SETTRK	; track 0
	mvi	A,79h
	sta	cursec	; sector 79h
	lxi	H,alloctab
	shld	curDMA	; DMA address
..read:
	lda	cursec
	cpi	81h
	jz	PRTTABL
	moö	C,A
	inr	A
	sta	cursec
	call	SETSEC	; set sector
	lbcd	curdma
	call	SETDMA	; set DMA address
	call	READ	; read 128 bytes
	lhld	curdma
	lxi	B,128
	dad	B
	shld	curdma	; increment DMA address
	jmpr	..read
;----------
; Utility Exit Routine for Network down times.
NETdead:
	lxi	H,deadMSG
	call	prtmsg
	ret
deadMSG:.asciz	[cr][lf]'Not logged into HiNet.'
;----------
; Routine: PRTTABL
;
; Print the allocation table.
unit:	.byte	00h	; unit number of entry in table
size:	.byte	00h	; size of entry in stable
HEADmsg:.ascii	'                         '
	.ascii	' Current HiNet Partitions'
	.ascii	[cr][lf]'                         '
	.ascii	' ------------------------'
crlf:	.asciz	[cr][lf]
space3:	.asciz	'   '
space6:	.asciz	'      '
msg256K:.asciz	'  256K bytes'
msg512K:.asciz	'  512K bytes'
msg1M:	.asciz	'    1M bytes'
msg2M:	.asciz	'    2M bytes'
msg4M:	.asciz	'    4M bytes'
msg8M:	.asciz	'    8M bytes'
Qmsg:	.asciz	'    ???     '
;
prtTABL:
	mvi	A,1
	sta	unit		; re-initialize 
	lxi	H,crlf
	call	prtmsg		; and space down.
	lxi	H,HEADmsg
	call	prtmsg		; print table header

..1:	lxi	H,alloctab	; HL = addr of table
	mvi	B,16		; B = bytes per line
	lda	unit		; A = line to find
	call	ADDRfind	; HL returns with addr
	call	prtline		; Print a line in table
	jrc	exit		; Exit if prtline set
	lda	unit		; the carry bit.
	adi	3		; increment three lines
	sta	unit
	cpi	63		; 63 partitions checkd?
	jrc	..1		; No.  Loop back.
	lxi	H,crlf		; Yes.
	call	prtmsg		; space down a line
	lxi	H,crlf
	call	prtmsg		; space down a line
;
; All Disk Partitions printed out. Destroy Alloc table
; at userlist. Exit to CCP.
exit:	
	lxi	H,crlf
	call	prtmsg		; Space down a line and
	ret
;----------
;Subroutine:	prtline
; Regs  in:	HL=addr in the name/pass  table
; Regs out:	HL=next addr in the name/pass  table
;Destroyed:	A,B,C
;Used by prtname to print one line in the table.
;Halt print out if a console chr is found.
;Resume print out when 2nd console chr is found.
prtline:
	push	H	; save name/pass  table address
	call	CONSTAT	; is console chr ready?
	jrnc	..4	; NO.
	call	CONIN	; eat the chr
..3:	call	CONSTAT ; is 2nd console chr ready?
	jrnc	..3	; wait for it
	call	CONIN	; eat the chr, and proceed

; Test the first byte in each line of the table.
; Halt print and return immediately if the size is 0.

;----------
; Check the first of three entries.
..4:	pop	H	; restore name/pass  tabl addr
	mov	A,M		; get the size
	sta	size		; store the size
	cpi	0		; Entry on this line?
	stc			; Set carry in case
	rz			; No. Return
;Table line is assumed ok.  Print it
	push	H
	lxi	H,crlf		; space down a line
	call	prtmsg
	lxi	H,space3
	call	prtmsg		; and space over 3.
	pop	H		; HL = size byte addr
	inx	H		; HL = 8 chr name addr
	mvi	B,8
	call	prtchr		; print 8 chr name
	call	prtSIZ		; print the size
;----------
; Check/Print the next entry
	lxi	D,8		; move to next line
	dad	D
	mov	A,M		; get size
	cpi	0		; Is it 0?
	stc			; Set carry in case
	rz			; Yes. Return
	inx	H		; No. Get to name addr
	sta	size		; and store the size
;Table line is assumed ok.  Print it
	push	H
	lxi	H,space6	; space over 4 spaces
	call	prtmsg
	pop	H
	mvi	B,8
	call	prtchr		; print 8 chr name
	call	prtSIZ
;----------
; Check/Print the next entry
	lxi	D,8
	dad	D
	mov	A,M		; get size
	cpi	0		; Is it 0?
	stc			; Set carry in case
	rz			; Yes. Return
	inx	H		; No. Get to name addr
	sta	size		; and store the size
;Table line is assumed ok.  Print it
	push	H
	lxi	H,space6	; space over 4 spaces
	call	prtmsg
	pop	H
	mvi	B,8
	call	prtchr		; print 8 chr name
	call	prtSIZ		; print the size
	inx	H		; No. Get to name addr
	ora	A		; No. Reset carry flag
	ret			; and return.

;---------
; Subroutine: prtSIZ
; Regs in:	none
; Regs out:	none
; Destroyed	A
;
; Print the size of the current entry in the table
prtSIZ:
	push	H		; save currnt tabl addr
	lda	size		; get the entry size

	lxi	H,msg256K
	cpi	1		; is size 1?
	cz	prtmsg		; Yes. Print 256K msg
	jrz	..return	; and return.

	lxi	H,msg512K
	cpi	2		; is size 2?
	cz	prtmsg		; Yes. Print 512K msg
	jrz	..return	; and return.

	lxi	H,msg1M
	cpi	3		; is size 3?
	cz	prtmsg		; Yes. Print 1 Meg msg
	jrz	..return	; and return.

	lxi	H,msg2M
	cpi	4		; is size 4?
	cz	prtmsg		; Yes. Print 2 Meg msg
	jrz	..return	; and return.

	lxi	H,msg4M
	cpi	5		; is size 5?
	cz	prtmsg		; Yes. Print 256K msg
	jrz	..return	; and return.

	lxi	H,msg8M
	cpi	6		; is size 6?
	cz	prtmsg		; Yes. Print 8 Meg msg
	jrz	..return	; and return.

	lxi	H,Qmsg		; No valid size found.
	call	prtmsg		; Print ??? msg,
..return:
	pop	H		; restore table address
	ret			; and return.

;---------
;		Subroutine: ADDRfind
; Regs  in:    A = A line in table whose addr is needed
;	       B = Bytes per line of the table
;	       HL= addr of the start of the table
; Regs out:    HL= Addr of that line
;	          in the table 
;Destroyed:    A,B
;Find an addr of a line in a table
ADDRfind:
; A = line in table to find \  HL= start addr of table
	cpi	0	  ; first line of table?
	rz		  ; then were done
..1:	push	PSW	  ; save table line number
	mov	A,B	  ; incr table <Reg B> times 
..2:	inx	H
	dcr	A
	cpi	0	  ; Are we through this line?
	jrnz	..2	  ; No. continue incrementing
	pop	PSW	  ; Yes. Restore line counter
	dcr	A	  ; decr table line number
	cpi	0	  ; Are we all done?
	jrnz	..1	  ; No.incr to next line
	ret		  ; Yes. Return.


;----------
; SUBROUTINES
;----------
; Print a message on the console
;  Regs in:   HL = address of string (ended by null)
;  Regs out:  none
;  Destroyed: A, HL
prtmsg:
	mov	A,M
	ora	A
	rz
	call	CONOUT
	inx	H
	jmpr	prtmsg
;----------
;		Subroutine: prtchr
; Regs  in:	B =length of string
;		HL=addr of string
; Regs out:	HL=addr of last chr printed
;Destroyed:	B,A
;Print a specified number of chrs to the console
prtchr:
	mov	A,M
	push	B
	push	H
	call	CONOUT
	pop	H
	pop	B
	dcr	B
	mov	A,B
	cpi	0	; all B chrs printed?
	rz
	inx	H	; next chr addr
	jmpr	prtchr	

;----------
; Print a byte on the console
;  Regs in:   A = byte to be printed
;  Regs out:  none
;  Destroyed: A
prtbyt:
	push	PSW
	rrc
	rrc
	rrc
	rrc
	ani	0Fh	; don't print leading zeros
	jrz	..1
	call	prtnbl
..1:	pop	PSW
prtnbl:	ani	0Fh
	adi	'0'
	cpi	'9'+1
	jrc	CONOUT
	adi	'A'-('9'+1)
	jmpr	CONOUT
;----------
; Convert binary to BCD
;  Regs in:   A = byte to be converted
;  Regs out:  A = byte, in BCD format
;  Destroyed: B
cvtbcd:
	ora	A
	rz
	mov	B,A
	xra	A
..1:	inr	A
	daa
	djnz	..1
	ret
;----------
; Print a character on the console
;  Regs in:   A = character to be printed
;  Regs out:  none
;  Destroyed: C
CONOUT:
	mov	C,A
	lxi	D,09h
	lixd	1
	dadx	D
	pcix
;----------
;		Subroutine: CONIN
;Fetch a character from the console.
CONIN:	lded	1
	lxi	H,06h
	dad	D
	pchl

;----------
;		Subroutine: CONSTAT
; Regs  in:	none
; Regs out:	carry bit set if chr ready
; Destroyed:	
CONSTAT:
	lxi	H,..1
	push	H	; return to ..1
	lded	1
	lxi	H,03h
	dad	D
	pchl
..1:	rrc		; set parity bit if
	ret		;chr is ready.

LOGmsg: .ascii	[cr][lf]' DIRNET version '
	.byte	version+'0','.'
	.byte	revision/10+'0',revision@10+'0'
	.asciz	[cr][lf]

curdma:	.word	0	; current DMAaddr for disk I/O
curSEC:	.byte	00h	; current sector for disk I/O
	
SELDSK:
	lhld	1
	lxi	D,18h
	dad	D
	pchl

SETTRK:
	lhld	1
	lxi	D,1Bh
	dad	D
	pchl

SETSEC:
	lhld	1
	lxi	D,1Eh
	dad	D
	pchl

SETDMA:
	lhld	1
	lxi	D,21h
	dad	D
	pchl

READ:
	lhld	1
	lxi	D,24h
	dad	D
	pchl

CPMMAP:
	lhld	1
	lxi	D,60h
	dad	D
	pchl
.end

