; I/OS 'BIG' DISK INIT PROGRAM
;
	NAM	IOS017
;
;	REV 00.03 KRS 04/16/80	SET BIG DIRECTORY
;	REV 00.04 KRS 05/07/80	DISK BIT MAP
;	REV 00.05 KRS 07/80	INTERLEAVED WRITE BUG
;	REV 00.06 KRS 07/80	LOG/UNLOG/FLUSH PROBLEM
;	REV 00.07 KRS 08/80	OTHER PROBLEMS!
;	REV 00.08 KRS 08/80	SIZE PROBLEM FIX
;	REV 00.09 KRS 04/20/81	BIT MAP BUGS
;	REV 00.10 KRS 06/01/81	SUB-DIR LOGIC
;	REV 00.11 KRS 06/16/81	DIR NAMES, ACTIVE TASK FIX
;	REV 00.12 KRS 06/19/81	BUG IN DIR NAME LOGIC
;	REV 00.13 KRS 07/13/81	IGNORE DELETED SUBS
;	REV 00.14 KRS 07/13/81	SPLIT OUT BIT-MAP LOGIC
;	REV 00.15 KRS 07/16/81	FIX BUG IN NEW BIT MAP LOGIC
;	REV 00.16 KRS 07/20/81	USE BIGMAP VER 00.15
;	REV 00.17 SCJ 06/17/82	Add command line for rebuild ONLY
;	          SCJ 12/01/82	Change ICL to reference $:(DCOM)
;
	ENT	XSCAL,LBLSV,NOTBG,DSKTYP		;00.16
;
	EXT	NEGHL,DIV16,BIGMP,MAXU,MSDT,XPSDT,BITMP	;00.14
	EXT	PSDT0,BITS,MAPRC,BMNUM,DIRX,PSDT,EDIR	;00.14
	EXT	SETIT,MAXUX,LOGIT			;00.14
;
	ICL	$:BMPDEF
	ROG
	LST	NASC
;
UFCB1	EQU	5CH
SPC	EQU	20H
DOS	EQU	5
CR	EQU	13
LF	EQU	10
DLR	EQU	'$'
;
;  SYSTEM DISK TABLE -> MAX DISKS
;	MAX DISKS * CURRENT SDT ENTRY
;
SDTFB	EQU	0	; FLAG BITS (1)
SDTSB	EQU	1	; STATUS BITS  (1)
SDTUN	EQU	2	; UNIT NUMBER  (1)
SDTTK	EQU	3	; TRACK NUMBER (1)
SDTCSZ	EQU	4	; CLUSTER SIZE (1)
SDTDUB	EQU	5	; DUCB (UNIT CONTROL BLK) (2)
SDTMDR	EQU	7	; MASTER DIR START BLK (2)
SDTMLN	EQU	9	; MSTR DIR LENGTH (ENTRIES) (1)
SDTMCL	EQU	10	; MSTR DIR LENGTH (CLUSTERS)(1)
SDTDTY	EQU	11	; CURR DIR TYPE	 (1)
SDTNAM	EQU	12	; DISK VOLUME NAME (8)
SDTMAP	EQU	20	; ALLOCATION MAP PTR  <CLUSTRS*8> (2)
SDTPTR	EQU	22	; SPECIAL AREA POINTER	  (2)
SDTCPR	EQU	24	; CURR DIR PTR (2)
SDTNCL	EQU	26	; NUMBER OF CLUSTERS ON DISK (2)
;
SDTLEN	EQU	28
;
;	FILE CONTROL BLOCK
;
FCBFT	EQU	9	; FILE TYPE
FCBEX	EQU	12	; FILE EXTENT
FCBDE	EQU	14	; DIRECTORY ENTRY NUMBER
FCBRC	EQU	15	; RECORD COUNT
FCBDM	EQU	16	; DISK MAP
FCBNR	EQU	32	; NEXT RECORD
FCBRR	EQU	33	; RANDOM RECORD (CP/M 2.0)	 02.20
;
;  DIR BYTE 0 FLAGS IN BIG DIRECTORY
;
BIGFLG	EQU	02H	; FILE IS BIG FILE		 02.14
WHALF	EQU	04H	; WHICH DM HALF IS IN FCB	 02.14
BIGFIL	EQU	02H	; THIS ENTRY IS BIG FILE	 02.14
;
;  SDT.DIRTYP FLAGS
;
BIGDIR	EQU	01H	; THIS DIR IS BIG DIR
SUBDIR	EQU	80H	; THIS IS A SUB-DIRECTORY
DBLDIR	EQU	40H	; THIS IS A DOUBLE-SIDED DISKETTE
LBLDIR	EQU	10H	; THIS DISK HAS A LABEL		 02.20
;
	EJECT
;
IOSINI:	LHLD	DOS+1		; ENTRY POINT
	SPHL
;
	LXI	D,BITS					;00.14
	LXI	H,BM$BT					;00.14
	DAD	D					;00.14
	SHLD	BITS$B					;00.14
	LXI	H,BM$CT					;00.14
	DAD	D					;00.14
	SHLD	BITS$C					;00.14
	LXI	H,BM$EN					;00.14
	DAD	D					;00.14
	SHLD	BITS$E					;00.14
	LXI	H,BM$ST					;00.14
	DAD	D					;00.14
	SHLD	BITS$S					;00.14
;
	MVI	C,25
	CALL	DOS		;GET CURRENT DISK
	STA	CURDK		;AND SAVE IT
;
;======= CODE ADDED AT 00.09 THROUGH MATCHING NOTE
	MVI	C,8DH		; GET VERSION
	CALL	DOS
	STA	OSTYP
	ORA	A
	JNZ	MUOS
	LXI	D,SUOSM
	JMP	SUMU
;
MUOS:	LXI	D,MUOSM
SUMU:	MVI	C,9
	CALL	DOS
	LXI	D,MSG1		; WHO WE ARE
	MVI	C,9		; WRITE LINE
	CALL	DOS
;
	LDA	OSTYP
	ORA	A
	JZ	SINGL
;	M/U - MUST BE ONLY TASK RUNNING!!!!!!!
	XRA	A
	MOV	B,A
	MOV	E,A
	MVI	C,0C4H		; GET STATUS CALL
NTA:	CALL	DOS
	ANI	80H					;00.11
	JZ	NA		; NOT ACTIVE
	INR	B		; COUNT ONE MORE
NA:	INR	E		; NEXT TO TRY
	MOV	A,E
	CPI	16		; ARE WE DUN?
	JNZ	NTA		; NO LOOP
	MVI	A,1
	CMP	B		; MUST BE ONE AND ONLY ONE
	JZ	SINGL		; OK - SINGLE
	LXI	D,MM1
	JMP	GOHOM1
;
MM1:	DB	'IOSINIT requires single-task operation',CR,LF,DLR
;
;====== END OF CODE ADDED AT 00.09
SINGL:	MVI	C,13
	CALL	DOS		; UNLOG ALL DISKS
	MVI	C,14
	LDA	CURDK
	MOV	E,A
	CALL	DOS		; RESELECT CURRENT DISK
	MVI	C,81H		; GET USER REG
	CALL	DOS
	LXI	H,5		; SDT -> OFFSET
	DAD	B
	MOV	E,M
	INX	H
	MOV	D,M		; NOW DE -> SDT
	LDAX	D		; GET NUMBER OF ENTRIES
	ADI	'@'		; CONVERT TO LETTER (PLUS 1 FOR CMP)
	STA	MSG4A
	INR	A
	STA	MAXU
	INX	D
	XCHG
	SHLD	XPSDT		; SAVE SDT PTR
;
	MVI	A,'B'	; assume bitmap rebuild		 00.17
	STA	T02	; store 'command'		 00.17
	LDA	UFCB1	; check drive specifier		 00.17
	ORA	A					;00.17
	JZ	ASKU	; disallow @: (current)		 00.17
; Allow command line drive specified bit map rebuild	 00.17
	LXI	H,MAXU					;00.17
	CMP	M	; compare drive with MAX	 00.17
	JLT	ASKU1					;00.17
	LXI	D,MSG5					;00.17
	MVI	C,9					;00.17
	CALL	DOS					;00.17
	LXI	H,-1	; ABORT: unit out of range	 00.17
	JMP	0
;
; Ask console for unit (drive specifier)
;
ASKU:	LXI	D,MSG4		; ASK FOR UNIT
	MVI	C,9
	CALL	DOS		; GET UNIT
	MVI	C,1		; ONE CHARACTER WITH ECHO
	CALL	DOS
	CPI	03
	JZ	GOHOM
	ANI	0FFH-20H	;FORCE UC
	STA	T02		; SAVE
	LXI	D,CRLF
	MVI	C,9		; ECHO CR-LF
	CALL	DOS
	LDA	T02
	CPI	'A'		; VALID UNITS ARE A-?
	JLT	BADU
	LXI	H,MAXU
	CMP	M
	JGE	BADU
	SUI	'@'
;
ASKU1:	STA	MAXUX		; SAVE WITHOUT BIT	00.05
	ORI	80H		; SAY INTERLEAVED	00.05
	STA	MAXU		; NOW DESIRED UNIT
	ANI	7FH		;			00.05
	LXI	D,SDTLEN		; LENGTH OF SDT ENTRY
	LHLD	XPSDT		; POINTER TO FIRST
;
DCRIT:	DCR	A
	JZ	DADED
	DAD	D
	JMP	DCRIT
DADED:	SHLD	XPSDT		; NOW POINTER TO DESIRED ONE
	JMP	GOTU
;
BADU:	LXI	D,MSG5		; SAY NO GOOD
	MVI	C,9
	CALL	DOS
	JMP	ASKU		; TRY AGAIN
;
; Get function from user
;
GOTU:	LDA	UFCB1					;00.17
	ORA	A					;00.17
	JNZ	SHOWL	; Skip user query if command line00.17
	LXI	D,MSGFN		; ASK FUNCTION
	MVI	C,9
	CALL	DOS
	MVI	C,1
	CALL	DOS
	ANI	0FFH-20H	;FORCE UC
	STA	T02
	CPI	03H
	JZ	GOHOM
	LXI	D,CRLF
	MVI	C,9		; ECHO CR-LF
	CALL	DOS
	LDA	T02
	CPI	'B'
	JZ	SHOWL
	CPI	'L'
	JZ	SHOWL
	CPI	'F'
	JNZ	GOTU
	LXI	D,REALLY			;00.13
	MVI	C,9				;00.13
	CALL	DOS				;00.13
	MVI	C,1				;00.13
	CALL	DOS				;00.13
	ANI	0FFH-20H			;00.13
	CPI	'Y'				;00.13
	JEQ	FULLI				;00.13
	JMP	GOTU
;
SHOWL:	CALL	SETIT				;00.05
	CALL	LOGIT				;00.05
;
	LXI	D,DIRX
	MVI	C,1AH		;SET IO ADDR
	CALL	DOS
;
	LHLD	PSDT		;DIR START
	XCHG			; BAK
	LDA	MAXU
	MOV	B,A		; UNIT
	XRA	A
	MVI	C,83H		;READ
	CALL	DOS
	LXI	H,DIRX						;00.14
	INX	H		; DIRX+1			 00.14
	LXI	D,LBLSV
	MVI	B,8
SHOW1:	MOV	A,M
	STAX	D		;MOVE CURRENT LABEL TO SAVE AREA
	INX	H
	INX	D
	DCR	B
	JNZ	SHOW1
	LXI	D,LBLMS
	MVI	C,9
	CALL	DOS		;SHOW CURRENT LABEL
	LDA	T02
	CPI	'B'
	JZ	BITMPX		;GO DO BIT MAP IF NOT L
;
FULLI:	LXI	D,MSGLB		; ASK FOR DISK LABEL
	MVI	C,9
	CALL	DOS
	LXI	D,INBUF
	MVI	C,10		; READ LINE
	CALL	DOS
	MVI	C,2		; WRITE CHAR
	MVI	E,10		; LINE FEED
	CALL	DOS
	LXI	H,INBUF+1
	MOV	E,M
	MVI	D,0
	DAD	D		; POINT TO LAST CHAR
	INX	H
	MVI	M,' '		; BLANK AFTER
	LXI	H,INBUF+2	; INPUT
	MVI	B,8		; SIZE
	LXI	D,LBLSV
MVLBL:	MOV	A,M		; GET CHARACTER
	STAX	D
	INX	H
	INX	D
	DCR	B
	JNZ	MVLBL
;
	LDA	T02
	CPI	'L'		;LABEL ONLY?
	JZ	DUIT2
	EJECT
;
	JMP	DUIT		; NOT YET!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
	LXI	D,MSGC		; ASK CLUSTER SIZE
	MVI	C,9
	CALL	DOS
	LXI	D,INBUF
	MVI	C,10		; READ LINE
	CALL	DOS
	MVI	C,2		; WRITE CHAR
	MVI	E,10		; LINE FEED
	CALL	DOS
	LXI	H,INBUF+1
	MOV	E,M
	MVI	D,0
	DAD	D		; POINT TO LAST CHAR
	INX	H
	MVI	M,' '		; BLANK AFTER
;
	EJECTþÿä%±I14(%5Y$%°ä4(%10%=L4(%10%MQ%P4(ì4)U%PÈè%1a$% ±1	1MX4(%1a$%±%I`$$$$$$ìÀÀ
	L14
	INX	D		; DIRX+1			 00.14
	MVI	B,8		;MOVE LABEL IN
NORD1:	MOV	A,M
	STAX	D
	INX	H
	INX	D
	DCR	B
	JNZ	NORD1
;
	LXI	D,DIRX
	MVI	C,1AH		;SET IO ADDR
	CALL	DOS
;
	LHLD	PSDT
	XCHG
	LDA	MAXU
	MOV	B,A
	XRA	A
	MVI	C,84H		; WRITE LOGICAL BLOCK
	CALL	DOS
	LDA	T02
	CPI	'L'
	JZ	DONEE
;
	LXI	H,128
LUPE1:	PUSH	H
	LXI	D,EDIR
	MVI	C,1AH
	CALL	DOS		; SET EMPTY DIR ADDRESS
	LHLD	PSDT
	INX	H
	SHLD	PSDT
	XCHG
	LDA	MAXU
	MOV	B,A
	XRA	A
	MVI	C,84H
	CALL	DOS
	POP	H
	DCX	H
	MOV	A,L
	ORA	H
	JNZ	LUPE1
;
	CALL	LOGIT
	EJECT
BITMPX:	CALL	BITMP					;00.14
;
	LHLD	PSDT0					;00.14
	XCHG
	LDA	MAXU
	MOV	B,A
	XRA	A
	MVI	C,83H	;REREAD DIR REC 0
	CALL	DOS
;
	LXI	D,BITS
	MVI	C,1AH
	CALL	DOS	;SET IO ADDRESS
;
	LXI	H,BIGMP
	MVI	B,1
	MVI	C,96
;
MOVMP:	PUSH	H					;00.14
	LHLD	BITS$B					;00.14
	XCHG						;00.14
	LHLD	BITS$C					;00.14
	MOV	M,C					;00.14
	POP	H					;00.14
MOVM1:	MOV	A,M
	STAX	D	;MOVE BIT MAP TO RECORD
	INX	H
	INX	D
	DCR	C
	JNZ	MOVM1
;
	PUSH	H		;SAVE POSITION
	LDA	MAPRC		;NUMBER OF RECORDS NEEDED
	CMP	B
	JZ	ENDAL		;DONE!
	CALL	WRTMP		;WRITE IT
	LHLD	BITS$E					;00.14
	MOV	E,M					;00.14
	INX	H					;00.14
	MOV	D,M					;00.14
	INX	D					;00.14
	LHLD	BITS$S					;00.14
	MOV	M,E					;00.14
	INX	H					;00.15
	MOV	M,D					;00.14
	LXI	H,959
	DAD	D		;WHICH IS 960 LONG
	XCHG						;00.14
	LHLD	BITS$E					;00.14
	MOV	M,E					;00.14
	INX	H					;00.14
	MOV	M,D					;00.14
	POP	H
	MVI	C,120
	JMP	MOVMP
;
ENDAL:	LHLD	BMNUM
	XCHG						;00.14
	LHLD	BITS$E					;00.14
	MOV	M,E					;00.14
	INX	H					;00.14
	MOV	M,D					;00.14
	LHLD	BITS$S					;00.14
	MOV	A,M					;00.14
	INX	H					;00.14
	MOV	H,M					;00.14
	MOV	L,A					;00.14
	DCX	H
	CALL	NEGHL
	DAD	D		;HL NOW NUMBER OF BITS LAST BLOCK
	LXI	D,8
	CALL	DIV16
	MOV	A,E
	ORA	D
	JZ	ENDA1
	INX	H		;SOME FRACTION LEFT OVER
ENDA1:	MOV	A,L
	LHLD	BITS$C		;STORE			 00.14
	MOV	M,A					;00.14
	MVI	A,80H
	STA	BITS		;FLAG AAS LAST
	CALL	WRTMP
;
	JMP	DONEE
;
WRTMP:	PUSH	B
	LXI	H,BITS
	MVI	C,128
	XRA	A
WRTM1:	XRA	M
	INX	H
	DCR	C
	JNZ	WRTM1
;
	DCX	H		;BACK TO CKSUM BYTE
	XRA	M
	MOV	M,A
;
	LHLD	MSDT
	XCHG
	LDA	MAXU
	MOV	B,A
	XRA	A
	MVI	C,84H		;WRITE THIS RECORD
	CALL	DOS
	LHLD	MSDT
	INX	H		;UPDATE FOR NEXT ONE
	SHLD	MSDT
	POP	B
	INR	B
	RET
;
XSCAL:	JMP	DOS					;00.14
;
NOTBG:	LXI	D,MSGNB
	JMP	GOHOM1					;00.09
;
DONEE:	CALL	LOGIT					;00.06
;
	LDA	CURDK
	MOV	E,A
	MVI	C,14
	CALL	DOS		;RELOG ORIGINAL
;
	LXI	D,DUN
	JMP	GOHOM1					;00.09
;
GOHOM:	LXI	D,MSGAB
GOHOM1:	MVI	C,9					;00.09
	CALL	DOS
QUIT:	LDA	CURDK
	MOV	E,A
	MVI	C,14
	CALL	DOS		;RELOG ORIG DISK
	MVI	C,0		; RETURN TO I/OS
	CALL	DOS
;
;
MSGNB:	DB	'Not a Big Directory - ABORTED',CR,LF,DLR
;
MSGLB:	DB	0DH,0AH,'Enter Disk Label (0 to 8 characters): ',DLR
;
MUOSM:	DB	CR,LF,'MultI/OS ',DLR
SUOSM:	DB	0DH,0AH,'I/OS ',DLR
MSG1:	DB	'Disk Initializer '
	DB	'(IOSINIT 00.17)',CR,LF,DLR
;
DUN:	DB	0DH,0AH,'Directory Initialized',CR,LF,DLR
;
MSG4:	DB	0DH,0AH,'Enter Disk Unit (A..'
MSG4A:	DB	'P) ',DLR
;
MSGFN:	DB	0DH,0AH,'Full Initialization (F), Bit Map'
	DB	' Rebuild (B),',0DH,0AH
	DB	'or Disk Label Change (L)? ',DLR
;
REALLY:	DB	0DH,0AH,'Full InitiaXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
	Lull Initialization, enter "Y" $'
;
MSGC:	DB	0DH,0AH,'Enter Cluster Size in K-bytes (1, 2, 4, or 8): ',DLR
;
MSG5:	DB	0DH,0AH,'Invalid Response',CR,LF,DLR
;
MSGAB:	DB	0DH,0AH,'Aborted by Operator',CR,LF,DLR
;
CRLF:	DB	CR,LF,DLR
;
INBUF:	DB	8,0,'          '
;
DSKTYP:	DB	0	; MUST BE ZERO FOR BIGMAP!!!	;00.16
OSTYP:	DB	0
T02:	DB	0
CURDK:	DB	0
BITS$B:	DW	0					;00.14
BITS$C:	DW	0					;00.14
BITS$E:	DW	0					;00.14
BITS$S:	DW	0					;00.14
;
LBLMS:	DB	0DH,0AH,'Disk Label is '
LBLSV:	DB	'        '
	DB	CR,LF,DLR
;
	END	IOSINIT
