*
* CHKDISK: File system allocaton and disk media check.
*
* Copyright 1983-2005 Dave Dunfield
* All rights reserved.
*
DIRLOC	EQU	0		DIRECTORY LOCATION
LNKLOC	EQU	1		LINK SECTOR LOCATION
* DIRECTORY STRUCTURE
	ORG	0
DPREFIX	RMB	8		PREFIX
DNAME	RMB	8		FILENAME
DTYPE	RMB	3		FILE TYPE
DDADR	RMB	2		DISK ADDRESS
DRADR	RMB	2		RUN ADDRESS
DATTR	RMB	1		FILE ATTRIBUTES
*
	ORG	OSRAM		PUT IT HERE
CHKDISK	CMPA	#'?'		HELP REQUEST?
	BNE	QUAL		NO, DO FSCK
	SSR	25
	FCCZ	'Use: CHKDISK[/NOALLOC/NOMEDIA/QUIET/REBUILD] <drive>'
ABORT	SSR	0		RETURN TO DOS
* EVALUATE QUALIFIERS
QUAL	LDA	,Y		GET CHAR
	CMPA	#'/'		QUALIFIER?
	BNE	MAIN		NO QUALIFIERS
	LDX	#QTABLE		PT TO TABLE
	SSR	18		LOOK IT UP
	CMPB	#QMAX		OVER?
	BHS	QERR		INVALID
	LDX	#QFLAGS		PT TO FLAGS
	CLR	B,X		ZAP IT
	BRA	QUAL		CONTINUE
QERR	SSR	24		MESSAGE
	FCCZ	/Invalid qualifier: '/
	LDA	,Y+		GET CHAR
QERR1	SSR	33		OUTPUT
	SSR	5		GET NEXT CHAR
	BEQ	QERR2		END, EXIT
	CMPA	#'/'		NEXT QUALIFIER
	BNE	QERR1		ITS OK
QERR2	SSR	25
	FCCZ	/'/
	LDA	#1		INDICATE INVALID OPERAND
	BRA	ABORT		ERROR
*
* PERFORM TESTS
*
MAIN	SSR	88		CLEAN DISK
	SSR	16		GET DRIVE ID
	BNE	ABORT		INVALID OPERAND
	SSR	76		SELECT DRIVE
	SSR	82		GET ITS SIZE
	STD	>DRVSIZ		SAVE DRIVE SIZE
	SUBD	#1		ACTUAL HIGEST SECTOR
	INCA			(D/256+1 FOR PARTIAL)
	STA	>LNKSIZ		SAVE IT
* FIRST, LOAD IN LINK SECTORS
	LDX	#WRKSPC		PT TO WORK AREA
	LBSR	LDLINK		LOAD LINK SECTS
	STX	>DATSPC		SAVE PTR TO IT
	LBSR	LDLINK		READ AGAIN
* PERFORM ALLOCATION TABLE CHECK
	LDA	>ALLOC		DO ALLOCATION
	LBEQ	NOALL		NO
	LDA	>QUIET		BEING QUIET?
	BEQ	MAIN1		YES
	SSR	25		NEW LINE
	FCCZ	'Checking Allocation...'
* RELEASE DIRECTORY SECTORS
MAIN1	LDD	#DIRLOC		GET DIR LOC
	LBSR	UNCHAIN		RELEASE IT
* RELEASE LINK SECTORS
	INC	>SECTYP		INDICATE DOING LINKS
	LDD	#LNKLOC		GET LINK LOCATION
	LBSR	UNCHAIN		RELEASE LINKS
* READ DIRECTORY, RELEASING ALL FILE CHAINS
	INC	>SECTYP		ANDICATE DOING FILES
	LDD	#DIRLOC		PT TO DIRECTORY LOCATION
MAIN2	STD	>DIRSEC		SAVE PTR
	SSR	84		READ WORK SECTOR
	TFR	X,D		GET ADDRESS
	ADDD	#512		CALCULATE END
	STD	>TEMP		SAVE INDICATOR
MAIN3	LDA	,X		FILE IN USE?
	BEQ	MAIN4		YES, RELEASE IT
* FILE EXISTS, RELEASE ITS LINKS
	LDD	DDADR,X		GET DISK ADDRESS
	LBSR	UNCHAIN		RELEASE SECTOR CHAIN
MAIN4	LEAX	32,X		NEXT ENTRY
	CMPX	>TEMP		OVER?
	BLO	MAIN3		NO, KEEP LOOKING
	JSR	TQUIT		TEST FOR EXIT
	LDD	>DIRSEC		GET CURRENT SECTOR
	SSR	77		LOOK UP ITS LINK
	BEQ	MAIN5		END OF FILE, STOP
	CMPD	#0		INSURE DIRECTORY IS NOT CORRUPT
	BNE	MAIN2		CONTINUE
* EXAMINE TABLE FOR ALLOCATED/UNUSED BLOCKS
MAIN5	LDX	#WRKSPC		PT TO WORK AREA
	LDU	>DATSPC		GET DATA AREA
	LDY	#0		START WITH SECTOR ZERO
	STY	>TEMP		ZERO COUNTERS
EXAM	LDD	,X		IS IT FREE
	BEQ	EXAM2		YES
	CLR	>FLAG		INDICATE CHANGED
	CLR	,U		ZERO LOW
	CLR	1,U		ZERO HIGH
	LDD	>ERRORS		GET TOTAL
	ADDD	#1		ADVANCE
	STD	>ERRORS		RESAVE
	LDA	>TEMP		GET FLAG
	BNE	EXAM1		ALREADY SET
	DEC	>TEMP		SET FLAG
	SSR	25
	FCCZ	'Blocks allocated, but not used:'
EXAM1	SSR	21		SPACE
	TFR	Y,D		GET SECTOR ID
	SSR	27		OUTPUT
	INC	>TEMP+1		ADVANCE COUNTER
	LDA	>TEMP+1		GET VALUE
	BITA	#7		PAST END?
	BNE	EXAM2		NO
	SSR	22		NEW LINE
EXAM2	LEAY	1,Y		NEXT SECTOR
	LEAX	2,X		NEXT RAM LOC
	LEAU	2,U		NEXT IN REAL SECTORS
	CMPY	>DRVSIZ		OVER?
	BLO	EXAM		NO, TRY AGAIN
	LDA	>TEMP+1		GET COUNT
	BITA	#7		NEW LINE
	BEQ	EXAM3		NOT NESSARY
	SSR	22		NEW LINE
* HAVE REPORTED THEM ALL
EXAM3	LDA	>QUIET
	BEQ	NOALL		BE QUIET
	LDD	>ERRORS		GET TOTAL
	SSR	26		DISPLAY
	SSR	25		MESSAGE
	FCCZ	' allocation error(s)'
NOALL	LDA	>MEDIA		DO MEDIA TEST?
	LBEQ	NOMED		NO, NO MEDIA TEST
	LDA	>QUIET
	BEQ	QUI2		BE QUIET
	SSR	25		MESSAGE
	FCCZ	'Checking Media...'
QUI2	CLRA
	CLRB
	STD	>ERRORS		CLEAR COUNT
MED1	STD	>DIRSEC		SAVE SECTOR ID
	LDX	#WRKSPC		PT TO WORK AREA
	SSR	92		READ THE DISK
	BEQ	MED3		OK, DO NEXT
	LDD	>ERRORS
	ADDD	#1		ADVANCE COUNT
	STD	>ERRORS
	SSR	24		MESSAGE
	FCCZ	'Media error in sector '
	LDD	>DIRSEC		GET SECTOR
	SSR	26		DISPLAY
	LDD	>DIRSEC		GET SECTOR BACK
	LDX	>DATSPC		ADVANCE
	LSLB
	ROLA			X2 FOT TWO BYTE ENTRIES
	LEAX	D,X		ADVANCE TO IT
	LDD	,X		GET IT
	BNE	MED2		ALLOCATED
	LDD	#$FFFF
	STD	,X		MARK AS BUSY
	CLR	>FLAG		INDICATE CHANGE
	SSR	25		MESSAGE
	FCCZ	' - MARKED'
	BRA	MED3		CONTINUE
MED2	SSR	25
	FCCZ	' - ***ALREADY ALLOCATED***'
MED3	JSR	TQUIT		TEST FOR EXIT
	LDD	>DIRSEC		GET SECTOR
	ADDD	#1		NEXT SECTOR
	CMPD	>DRVSIZ		COMPARE WITH DISK
	LBLO	MED1		KEEP GOING
	LDA	>QUIET		KEEPING QUIET?
	BEQ	NOMED		YES
	LDD	>ERRORS
	SSR	26
	SSR	25
	FCCZ	' media error(s)'
* PERFORM UPDATES IF NESSARY
NOMED	LDA	>FLAG		ANY CHANGES
	BNE	NOREB		NO, SKIP IT
	LDA	>REBUILD	REBUILD AUTOMATICALLY?
	BEQ	GOREB		YES
	SSR	24		MESSAGE
	FCCZ	'Write updated link table?'
	SSR	34		GET CHAR
	SSR	33		ECHO
	SSR	22		NEW LINE
	ANDA	#$5F		CONVERT
	CMPA	#'Y'		YES?
	BNE	NOREB		DON'T REBUILD
GOREB	LDX	>DATSPC		PT TO AREA
	LBSR	SALINK		SAVE IT OUT
	LDA	>QUIET
	BEQ	NOREB
	SSR	25
	FCCZ	'Disk allocation rebuilt'
NOREB	CLRA			ZERO RC
	SSR	0		BACK TO DOS
TQUIT	SSR	35
	CMPA	#$1B
	BNE	GORET
	SSR	25
	FCCZ	'<Aborted>'
	BRA	NOREB
*
* LOAD DISK LINK TABLE INTO MEMORY(X)
*
LDLINK	LDA	>LNKSIZ		GET SIZE
	STA	>TEMP		SET UP
	LDD	#LNKLOC		START OF LINK SECTORS
LDLNK1	SSR	92		READ SECTOR
	BNE	ABORT1		ERROR
	ADDD	#1		ADVANCE SECTOR ID
	LEAX	512,X		NEXT LOCATION
	DEC	>TEMP		TEST NUMBER
	BNE	LDLNK1		LOAD EM ALL
GORET	RTS
ABORT1	SSR	0
*
* SAVE DISK LINK TABLE FROM MEMORY(X)
*
SALINK	SSR	88		PURGE DOS WORK SECTOR
	LDA	>LNKSIZ		GET SIZE
	STA	>TEMP		SET UP
	LDD	#LNKLOC		START OF LINK SECTORS
SALNK1	SSR	93		READ SECTOR
	BNE	ABORT1		ERROR
	ADDD	#1		ADVANCE SECTOR ID
	LEAX	512,X		NEXT LOCATION
	DEC	>TEMP		TEST NUMBER
	BNE	SALNK1		LOAD EM ALL
	RTS
*
* UNCHAIN SECTORS FROM RAM TABLE
*
UNCHAIN	PSHS	X		SAVE 'X'
UNC1	LSLB			X 2
	ROLA			FOR ENTRIES
	ADDD	#WRKSPC		OFFSET TO WORKSPACE
	TFR	D,Y		COPY IT TO INDEX
	LDD	,Y		GET NEXT SECTOR
	BEQ	UNC2		GO LOOSE SOMEHOW
	CLR	,Y		CLEAR LOW
	CLR	1,Y		CLEAR HIGH
	CMPD	>DRVSIZ		IN RANGE?
	BLO	UNC1		YES, ITS OK
	CMPD	#$FFFF		END OF FILE?
	BEQ	UNC7		ALL IS OK
* LINK CHAIN POINTS BEYOND FILESYSTEM
	LDU	#OVRMSG		PT TO MESSAGE
	BRA	UNC3		AND CONTINUE
* LINK CHAIN ENDED WITH ZERO
UNC2	LDU	#ZERMSG		PT TO MESSAGE
UNC3	LDD	>ERRORS
	ADDD	#1		ADVANCE ERROR COUNT
	STD	>ERRORS
	SSR	24		ERROR MESSAGE
	FCCZ	'Allocation error in '
	LDA	>SECTYP		GET SECTOR TYPE
	BNE	UNC4		NO, NOT DIRECTORY
	SSR	24
	FCCZ	'DIRECTORY'
	BRA	UNC6
UNC4	DECA			IS IT LINKS?
	BNE	UNC5		NO, NOT LINKS.
	SSR	24
	FCCZ	'LINK TABLE'
	BRA	UNC6
UNC5	SSR	31		DISPLAY FILENAME
UNC6	SSR	24		DISPLAY MESSAGE
	FCCZ	', block '
	TFR	Y,D		GET BLOCK ID
	SUBD	#WRKSPC		CONVERT
	LSRA			/2
	RORB			FOR ACTUAL ID
	SSR	26		OUTPUT IN DECIMAL
	SSR	22		NEW LINE
	TFR	U,X		GET PTR TO MESSAGE
	SSR	23		DISPLAY MESSAGE
	SSR	22		NEW LINE
UNC7	PULS	X,PC		RESTORE & RETURN
ZERMSG	FCCZ	'Chain ends in unallocated (0) link'
OVRMSG	FCCZ	'Link exceeds filesystem bounds'
* QUALIFIER TABLES
QTABLE	FCB	$84
	FCC	'/NOALLOC'
	FCB	$84
	FCC	'/NOMEDIA'
	FCB	$82
	FCC	'/QUIET'
	FCB	$82
	FCC	'/REBUILD'
	FCB	$80
QMAX	EQU	4		# QUALIFIERS
QFLAGS	EQU	*
ALLOC	FCB	$FF		ALLOCATION TEST
MEDIA	FCB	$FF		MEDIA TEST
QUIET	FCB	$FF		QUIET MODE
REBUILD	FCB	$FF		REBUILD MAP
* MISC LOCAL VARIABLES
FLAG	FCB	$FF		INDICATES CHANGED SECTOR
ERRORS	FDB	0		ERROR COUNT FLAG
SECTYP	FCB	0		SECTOR TYPE BEING RELEASED
DIRSEC	RMB	2		CURRENT DIRECTORY SECTOR
DRVSIZ	RMB	2		DISK SIZE (IN SECTORS)
LNKSIZ	RMB	1		SIZE OF LINK MAP (IN SECTORS)
DATSPC	RMB	2		PTR TO DATA RAM
TEMP	RMB	2		TEMPORARY STORAGE
* WORK AREA
WRKSPC	EQU	*
