;	BIGBOARD SCAN PROGRAM    VER. 2    19/11/82
;
	BDOS	EQU 0005H
	STREG	EQU 010H	;STATUS REG.
	TREG	EQU 011H	;TRACK REG.
	SEREG	EQU 012H	;SECTOR REG.
	IOPTR	EQU 0FF71H	;LABEL 'IOPTR' IN PFM
	SECVAL	EQU 0FF6EH	;LABEL 'SECTOR' IN PFM
	RTYCT	EQU 0FF70H	;LABEL 'RETRY' IN PFM
	CMDTYP	EQU 0FF6FH	;LABEL 'CMDTYP' IN PFM
	RW1	EQU 0F73CH	;LABEL 'RW1' IN PFM
	SELECT	EQU 0F6B1H	;LABEL 'SELECT' IN PFM
	BIOS	EQU 0E800H	;START OF BIOS
	HOME	EQU BIOS+24	;HOME VECTOR
	SETTRK	EQU BIOS+30	;SET TRACK VECTOR
;
;
	ORG	100H
SAVCUR:	MVI	C,25		;GET LOGGED DISK #
	CALL	BDOS
	STA	LDSK		;SAVE IT
;
DRSEL:	LDA	05DH
	CPI	' '		;CHECK FOR EXPLICIT DRIVE REQ.
	JNZ	SEL1		;YES, GO SEE IF VALID
	XRA	A
	STA	DRV		;SET UP TO USE CURRENT DRIVE
	JMP	START
;
SEL1:	ANI	05FH		;CONVERT TO UPPER CASE
	CPI	'A'
	JC	SELERR
	CPI	'D'+1
	JNC	SELERR
	SUI	'A'-1		;CONVERT TO BINARY
	STA	DRV		;SAVE DRIVE CODE
;
START:	MVI	C,9
	LXI	D,MSG1		;PRINT MOUNT MSG
	CALL	BDOS
	MVI	C,1
	CALL	BDOS		;WAIT FOR RESPONSE
	ANI	'G'		;CONV. TO UPPER CASE
	CPI	'G'
	JNZ	EXIT
;
	LDA	DRV		;GET DRIVE CODE
	ORA	A
	JZ	STEP1		;USE CURRENT DRIVE
	DCR	A		;CONVT TO TRUE CODE
	MOV	C,A
	CALL	SELECT		;GO SELECT DRIVE
	ORA	A		;SET FLAGS
	JZ	STEP1		;JUMP IF SELECT OK
	LXI	D,NRDY
	MVI	C,9
	CALL	BDOS		;PRINT NOT READY MSG
RESP:	MVI	C,1
	CALL	BDOS		;GET RESPONSE
	JMP	SEL1
;
SELERR:	LXI	D,SELMSG
	MVI	C,9
	CALL	BDOS		;PRINT INV SELECTION MSG
	JMP	RESP		;GO ASK FOR DRIVE CODE
;
STEP1:	MVI	C,2		;PREPARE TO READ DIRECTORY
	CALL	SETTRK		;SEEK TO TRACK 2
	LXI	H,VTOC		;INIT BUFFER ADDRESS
	SHLD	BUFAD
	MVI	A,1		;INIT SECTOR VALUE
	STA	SECT
LOOP1:	LHLD	BUFAD
	MOV	B,H
	MOV	C,L
	CALL	SETDMA
	LDA	SECT
	MOV	C,A
	CALL	SETSEC
	MVI	A,10		;SET RETRY COUNT TO 10
	CALL	READ
	LHLD	BUFAD
	LXI	D,80H
	DAD	D
	SHLD	BUFAD
	LDA	SECT
	CPI	14
	JZ	STEP2
	ADI	6
	CPI	31
	JNZ	TEST2
	MVI	A,5
TEST2:	CPI	29
	JNZ	TEST3
	MVI	A,3
TEST3:	CPI	27
	JNZ	STSEC
	MVI	A,2
STSEC:	STA	SECT
	JMP	LOOP1
BUFAD:	DS	2
MSG1:	DB 0DH,0AH,'MOUNT DESIRED DISK AND TYPE ''G''',0DH,0AH,'$'
STEP2:	CALL HOME
	MVI A,0		;INITIALIZE TRACK COUNTER
	STA TRK
	MVI A,1		; INITIALIZE SECTOR COUNTER
	STA SECT
LOOP2:	LDA TRK		; GET TRACK NO.
	CPI 77		; LAST TRACK?
	JZ FIN
	MOV C,A		; TRACK NO. TO C
	CALL SETTRK	; GO SEEK
LOOP3:	LDA SECT	; GET SECTOR NO.
	CPI 27		; LAST SECTOR?
	JZ NXTRK	; IF YES, INCR. TRK
	MOV C,A
	CALL SETSEC	; SET SECTOR
	MVI C,80H
	MVI B,0
	CALL SETDMA	; SET DMA ADDR.
	MVI	A,1	;DISABLE RETRIES BY PFM
	CALL READ	; GO READ SECTOR
	CNZ ERR		; PROCESS STATUS IF NON-ZERO
	LXI H,SECT
	INR M		; INCR. SECTOR COUNT
	JMP LOOP3
NXTRK:	LXI H,TRK
	INR M		; INCR. TRACK COUNT
	MVI A,1
	STA SECT	; RESET SECTOR COUNT
	JMP LOOP2
FIN:	LXI D,COMP	; PRINT ENDING MSG
	MVI C,9
	CALL BDOS
	JMP START	; REQUEST ANOTHER DISKETTE
			;
			;
TRK:	DB 0
SECT:	DB 1
			;
ERR:	CALL CONVT	; CONVERT TO ASCII
	SHLD STATUS
	IN TREG		; READ 1771 TRACK REG
	CALL CONVT
	SHLD TRACK
	IN SEREG	; READ 1771 SECTOR REG
	CALL CONVT
	SHLD SECTOR
	IN TREG
	SUI 2
	JM PRTCPM	;ERROR IS IN CPM AREA
	MOV B,A
	RLC		;MULTIPLY
	ANI 0FEH	;TRACK
	ADD B		;BY 3
	MOV C,A		;SAVE IN C
	MOV A,B
	RRC		;DIVIDE
	RRC		;TRACK BY 4
	MOV B,A		;SAVE IN B
	ANI 3FH		;CLEAR EXCESS BITS
	ADD C		;A=INT(TRACK*3.25)
	STA BLK1	;SAVE IT
	MOV A,B
	ANI 0C0H		;A=FRAC(TRACK*3.25)
	STA BLK2	;SAVE IT
	LXI H,STABL	;SET UP SECTOR TABLE ADDRESS
	LXI B,20H	;B-C SET TO 1/8 OF A BLOCK
	IN SEREG	;CURRENT SECTOR IN A
TEST5:	CMP M		;DOES CURRENT SECT.= SECTOR IN TABLE?
	JZ SCH		;IF SO, GO FIND FILENAME
	INX H		;INCR. POINTER TO SECTOR TABLE
	XCHG		;SAVE IN D-E
	LHLD BLK2	;BLOCK NO. TO H-L
	DAD B		;INCR. BY 1/8
	SHLD BLK2	;SAVE RESULT
	XCHG		;RESTORE H-L FROM D-E
	JMP TEST5	;GO COMPARE NEXT TABLE ENTRY
STABL:	DB 1,7,13,19
	DB 25,5,11,17
	DB 23,3,9,15
	DB 21,2,8,14
	DB 20,26,6,12
	DB 18,24,4,10
	DB 16,22
BLK2:	DS 1
BLK1:	DS 1
SCH:	LDA BLK1
	CPI 0
	JZ PRTDIR
	CPI 1
	JZ PRTDIR
	LXI H,VTOC
	LXI D,20H
	MVI A,0E5H
	MVI B,64
LOOP4:	SHLD ASAVE
	CMP M
	JNZ MATCH
	DAD D
COUNT:	DCR B
	JNZ LOOP4
	LXI H,MSG4
	SHLD MSG3
	JMP ERENT
MATCH:	LXI D,10H
	DAD D
	LDA BLK1
TEST7:	CMP M
	JZ FOUND
	INX H
	DCR E
	JNZ TEST7
	MVI A,0E5H
	LXI D,20H
	JMP COUNT
FOUND:	LHLD ASAVE
	INX H
	LXI D,MSG5
	MVI B,8
	CALL LOOP5
	INX D
	MVI B,3
	CALL LOOP5
	LXI H,MSG5
	SHLD MSG3
	JMP ERENT
LOOP5:	MOV A,M
	STAX D
	DCR B
	INX H
	INX D
	JNZ LOOP5
	RET
PRTCPM:	LXI H,MSG6
	SHLD MSG3
	JMP ERENT
PRTDIR:	LXI H,MSG7
	SHLD MSG3
ERENT:	XRA A
RETRY:	STA ERRCT	; INIT RETRY COUNT
	MVI A,1		;DISABLE RETRY BY PFM
	CALL READ	; RE-READ SECTOR
	JZ TMP		; IF OK IT'S TEMPORARY
	LDA ERRCT	; GET RETRY COUNT
	INR A
	CPI 9		; LIMIT REACHED ?
	JNZ RETRY	; TRY AGAIN IF NOT
	LXI D,PERM	; PRINT PERM. ERROR
	MVI C,9
	CALL BDOS
	JMP PRINT	; GO PRINT STATUS INFO
TMP:	LXI D,TEMP	; PRINT TEMP. ERROR
	MVI C,9
	CALL BDOS
PRINT:	LXI D,MSG2
	MVI C,9
	CALL BDOS	; GO PRINT MSG
	LHLD MSG3
	XCHG
	MVI C,9
	CALL BDOS
	RET
CONVT:	MOV C,A
	CALL CONV1
	MOV H,A
	MOV A,C
	RAR
	RAR
	RAR
	RAR
	CALL CONV1
	MOV L,A
	RET
CONV1:	ANI 0FH		; STRIP OFF HIGH 4 BITS
	ORI 30H		; ADD ASCII PREFIX
	CPI 3AH		; IS IT 0-9 ?
	RM		; FINISHED IF YES
	ADI 7		; MODIFY PREFIX FOR A-F
	RET
ERRCT	DB 0
ASAVE:	DS 2
MSG3:	DS 2
PTR:	DS 2
OFFS1:	DS 2
OFFS2:	DS 2
;
SETSEC:	MOV	A,C
	STA	SECVAL		;SET UP PFM'S SECTOR VALUE
	RET
SETDMA:	MOV	L,C
	MOV	H,B		;DMA ADDRESS TO H-L
	SHLD	IOPTR		;SET UP PFM'S BUFFER POINTER
	RET
READ:	STA	RTYCT		;SET UP RETRY COUNT FOR PFM
	MVI	A,88H		;READ COMMAND
	STA	CMDTYP		;PASS IT TO PFM
	JMP	RW1		;GO TO PFM TO READ & RETURN
;
EXIT:	LDA	LDSK		;RESTORE LOGGED DISK
	MOV	C,A
	JMP	SELECT		;SELECT IT & GO TO CP/M
;
LDSK:	DS 1
;
DRV:	DS 1		;DRIVE SELECT CODE
NRDY:	DB 0DH,0AH,'DRIVE NOT READY '
	DB 0DH,0AH,'MAKE IT READY OR SELECT ANOTHER, '
	DB 0DH,0AH,'THEN REPLY WITH DRIVE NUMBER : $'
SELMSG:	DB 0DH,0AH,'INVALID DRIVE NUMBER. RE-ENTER (A-D) : $'
TEMP:	DB 0DH,0AH,'TEMP $'
PERM:	DB 0DH,0AH,'PERM $'
MSG2:	DB 'ERROR AT TRACK '
TRACK:	DB 0,0,', SECTOR '
SECTOR:	DB 0,0,'. STATUS = '
STATUS:	DB 0,0,'     $'
MSG4:	DB 'UNALLOCATED $'
MSG5:	DB '            $'
MSG6:	DB 'CP/M REGION $'
MSG7:	DB 'DIRECTORY   $'
COMP:	DB 0DH,0AH,'SCAN COMPLETE$'
VTOC:	DS	2048	;DIRECTORY BUFFER AREA
	END	100H
