; CRCK v4.4         CYCLIC REDUNDANCY CHECK               10/17/82
;
                               by
;
;                   KEITH B. PETERSEN, W8SDZ
;
;
; NOTE TO SYSOPS:   SET FILEOK: AND SYSOK: (0103 AND 0104) BOTH TO '0'
;                   TO PREVENT REMOTE USERS FROM CREATING A FILE OR TO
;                   FIND RESTRICTED '.SYS' FILES.
;
; *     *     *     *     *     *     *     *     *     *     *     *
;
; 10/17/82 v4.4  -  Made buffer size automatic to make all transient
;                   area memory available for the disk file.  Should
;                   handle the largest Winchester disk directory.
;                   Modest changes for appearance.         - Irv Hoff
;
; 08/17/82 v4.3  -  Removed need for SEQIO.LIB so can now assemble with
;                   'ASM.COM' or other assemblers.  Used some of Kelly
;                   Smith' previous work to help in removing SEQIO.LIB.
;                                                          - Irv Hoff
;
; 06/03/82 v4.2B -  Added 2 RCPM aids:  Patch location label 'FILEOK' to
;                   FALSE (zero) to disallow CRC output file.  Patch
;                   label 'SYSOK' to FALSE (zero) to treat '.SYS' files
;                   the same as "NO FILE FOUND" to help hide them from
;                   those phoning in.  Previous version said 'DONE' with
;                   no report if '.SYS' or '.$$$' files were skipped. If
;                   you want to know what is there, patch the label or
;                   use 'STAT'.  
;                                 FILEOK = 0103H
;                                 SYSOK  = 0104H
;
; 04/02/82 v4.2A -  Make serially re-entrant to allow ZCPR "GO" again.
;                   Remove exta CR-LF to get mre CRC's on screen at one
;                   time.  Use name specified in 2nd FCB with '.CRC'
;                   extension instead of CRCKLIST.CRC for more operator
;                   convenience.
;
;
; 10/06/80 v4.2  -  Fix to erase temporary file when output flie is re-
;                   quested and name not found in directory.
;
; 06/27/79 v4.2  -  Written by Keith B. Petersen, W8SDZ
;
;
; *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
;
;
; CRCK can read any CP/M file then print a CRC (CYCLIC-REDUNDANCY-CHECK)
; number based on the CCITT standard polynominal:
;
;           X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
;
; Useful for checking accuracy of file transfers. More accurate than a
; simple checksum.  It will Optionally write an output file to the de-
; fault drive, listing the CRC's of all files requested.
;
;
; COMMANDS:  CRCK [drive:]<filename.filetype> [F]
;
; Examples:
;            CRCK B:HELLO.ASM    check only HELLO.ASM
;            CRCK *.ASM          check all .ASM  files
;            CRCK *.* FILE       check all files, make disk
;                                  file (FILE.CRC) of results
;                                  (use any file name desired)
;
; *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
;
;
; DEFINE TRUE AND FALSE
;
FALSE	EQU	0
TRUE	EQU	NOT FALSE
;
;
; CONDITIONAL ASSEMBLY SWITCHES
;
STDCPM	EQU	TRUE		;TRUE FOR STANDARD CP/M
ALTCPM	EQU	FALSE		;TRUE FOR H8 OR TRS-80
;
;
; SYSTEM EQUATES
;
BASE	SET	0		;FOR STANDARD CP/M USERS
;
	IF	ALTCPM		;FOR H8 OR TRS-80
BASE	SET	4200H
	ENDIF
;
; 
; BDOS EUATES
; 
RDCON	EQU	1
WRCON	EQU	2
PRINT	EQU	9
CSTAT	EQU	11
OPEN	EQU	15
CLOSE	EQU	16
SRCHF	EQU	17
SRCHN	EQU	18
DELET	EQU	19
READ	EQU	20
WRITE	EQU	21
MAKE	EQU	22
RENAM	EQU	23
STDMA	EQU	26
;
;
; FILE HANDLING EQUATES
;
BUF$SIZ	EQU	80H		;BUFFER SIZE (128 BYTES)
BDOS	EQU	BASE+5
FCB	EQU	BASE+5CH 
FCB2	EQU	BASE+6CH
FCBEXT	EQU	FCB+12
FCBRNO	EQU	FCB+32
TBUF	EQU	BASE+80H	;TEMPORARY BUFFER (DEFAULT) ADDRESS
;
;
; CONTROL CHARACTERS
;
CTLC	EQU	'C'-40H		;CONTROL-C CHARACTER
EOF	EQU	'Z'-40H		;END-OF-FILE CHARACTER
LF	EQU	'J'-40H		;LINE FEED CHARACTER
CR	EQU	'M'-40H		;CARRIAGE RETURN CHARACTER
TAB	EQU	'I'-40H		;TAB CHARACTER
;
;
; *   *   *   *   *   *   *   *   *   *   *   *  *   *   *   *   *   *
;
;
	ORG	BASE+100H
;
;
CRCK:	JMP	BEGIN		;JUMP AROUND PATCH PARAMETERS
;
;
FILEOK:	DB	1	;0 = No, 1 = Yes  TO ALLOW DISK FILE OF RESULTS
SYSOK:	DB	1	;0 = No, 1 = Yes  TO ALLOW HANDLING '.SYS' FILES
SOM:	DB	CR,LF,'CRCK version 4.4 of 10/17/82'
        DB    CR,LF,'(Ctl-C aborts, Ctl-S pauses)',CR,LF,LF,'$'
;
;
;***********************************************************************
;                                                                      ;
;                     PROGRAM STARTS HERE                              ;
;                                                                      ;
;***********************************************************************
;
;
BEGIN:	LXI	H,0		;GET STACK...
	DAD	SP		;POINTER SO WE CAN...
	SHLD	STACK		;SAVE IT
	LXI	SP,STACK	;INITIALIZE LOCAL STACK
	MVI	A,1
	STA	MFFLG1		;INIT 1ST TIME SWITCH
	STA	FOUND		;NO FILES FOUND YET
	MVI	A,' '		;NO OUTPUT FILE YET
	STA	FFLAG
	LXI	D,SOM		;PRINT SIGNON MESSAGE
	MVI	C,PRINT
	CALL	BDOS
	LDA	FCB+1
	CPI	' '		;SEE IF NAME THERE
	JNZ	BEGIN2		;YES, CONTINUE
;
	CALL	ERXIT		;PRINT MSG, THEN EXIT
;
	DB	CR,LF,LF,TAB,'++No file name specified++'
	DB	CR,LF,LF,LF,LF,TAB
	DB	'COMMANDS:  CRCK [drive:]<filename.filetye> FILE'
	DB	CR,LF,LF,LF,TAB
	DB	'Examples:  CRCK B:HELLO.ASM     check only HELLO.ASM'
	DB	CR,LF,TAB,TAB
	DB	'   CRCK *.ASM           check only .ASM files'
	DB	CR,LF,TAB,TAB
	DB	'   CRCK *.* FILE        check all files, make disk'
	DB	CR,LF,TAB,TAB
	DB	'                          file (FILE.CRC) of results'
	DB	CR,LF,TAB,TAB
	DB	'                          (use any file name desired)'
	DB	CR,LF,LF,LF,LF,LF,'$'
;
;
; FIND AMOUNT OF SPACE FOR BUFFER
;
BEGIN2:	LXI	D,FILEADR	;START OF BUFFER ADDRESS
	LDA	BDOS+2		;GET 'BDOS' ADDRESS
	SUI	8		;PROTECT 'CCP'
	MOV	H,A		;GET THE MAIN PAGE
	XRA	A		;CLEAR CARRY IF SET
;
;
; CALCULATE THE DIFFERENCE TO GET SPACE AVAILABLE
;
	SUB	E
	MOV	L,A
;
	MOV	A,H
	SBB	D
	MOV	H,A
;
;
; FREE SPACE AVAILABLE NOW IN 'HL', SO STORE FOR BUFFER SIZE
;
	SHLD	FILELEN		;STORE BUFFER LENGTH
;
;
; DECLARE 'FCB' FOR  OUTPUT FILE (TEMPORARILY NAMED CRCKLIST.$$$)
;
	LDA	FILEOK		;OK TO MAKE A '.CRC' DISK FILE?
	ORA	A
	JZ	AGAIN		;EXIT, IF NOT
;
	LDA	FCB2+1		;GET OPTION
	STA	FFLAG		;SAVE IT FOR LATER
	CPI	' '		;FILE WANTED?
	JZ	AGAIN		;NO, SKIP FILE INITIALIZATION
;
;
	XRA	A
	STA	FCBFILE+12	;CLEAR EXTENT
	STA	FCBFILE+32	;CLEAR CURRENT RECORD COUNT
	LXI	H,0
	SHLD	FILEPTR		;RESET FILE POINTERS
	MVI	C,DELET		;'DELETE FILE' FUNCTION
	LXI	D,FCBFILE	;DELETE 'OLD' CRCKLIST FILE
	CALL	BDOS
	MVI	C,MAKE		;'MAKE FILE' FUNCTON
	LXI	D,FCBFILE	;MAKE 'NEW' CRCKLIST FILE
	CALL	BDOS
	INR	A		;MAKE THE NEW FILE OK?
	JNZ	COPYNAME	;COPY THE FILE NAME REQUESTED
;
	MVI	C,PRINT		;PRINT STRING FUNCTION
	LXI	D,DIR$FULL	;INDICATE THAT DIRECTORY IS FULL
	CALL	BDOS
	JMP	FILERR
;...
;
;
COPYNAME:
	LXI	H,FCB2
	LXI	D,FCBFINAL
	MVI	C,9		;FILENAME IS 8 CHAR. PLUS .
;
COPYNAME1:
	MOV	A,M
	STAX	D
	INX	H
	INX	D
	DCR	C
	JNZ	COPYNAME1
;...
; 
AGAIN:	LXI	SP,STACK	;RE-INIT STACK POINTER
	CALL	MFNAME		;SEARCH FOR NAMES
	JNC	NAMTST		;ANOTHER FOUND, PRINT NAME
	LDA	FOUND		;NOTHING FOUND, CHECK...
	ORA	A		;... FIRST TIME FLAG
	JZ	DONE		;AT LEAST ONE WAS FOUND
	CALL	ABEXIT		;PRINT MSG, THEN EXIT
	DB	'++File(s) not found++$'
; 
DONE:	LDA	FFLAG		;MAKING A '.CRC' DISK FILE?
	CPI	' '
	JZ	DONE2		;NO, SKIP THE FILE STUFF
;
;
; CLOSE CRCKLIST.$$$
;
CLOSEFILE:
	LHLD	FILEPTR
	MOV	A,L
 	ANI	07FH
	JNZ	CLOSEFILE1
;
	SHLD	FILELEN
;
CLOSEFILE1:
	MVI	A,EOF
	PUSH	PSW
	CALL	PUTFILE
	POP	PSW
	JNZ	CLOSEFILE
;
	MVI	C,CLOSE
	LXI	D,FCBFILE
	CALL	BDOS
	INR	A
	JNZ	ERASE
;
	MVI	C,PRINT
	LXI	D,NO$CLOSE
	CALL	BDOS
;
;
; ERASE ANY EXISTING OLD FILE
;
ERASE:	MVI	C,DELET
	LXI	D,FCBFINAL
	CALL	BDOS
;
; 
; RENAME CRCKLIST.$$$ TO CRCKLIST.CRC
;
	LXI	H,FCBFILE
	LXI	D,FCBFINAL
	PUSH	H
	LXI	B,16
	DAD	B
;
MOV$NAME:
	LDAX	D
	MOV	M,A
	INX	D
 	INX	H
	DCR	C
	JNZ	MOV$NAME
	POP	D
	MVI	C,RENAM
	CALL	BDOS
;
; 
; NOW EXIT TO CP/M
;
DONE2:	CALL	MSGEXIT		;PRINT 'DONE' THEN EXIT
	DB	CR,LF,'Done',CR,LF,'$'
;.....
;
; 
; TEST FOR NAMES TO IGNORE
; 
NAMTST:	LDA	SYSOK		;SEE IF '.SYS' FILES ALLOWED
	ORA	A
	JNZ	DOSYS		;IF ALLOWED, EXIT
;
	LDA	FCB+10		;GET 'SYS' ATTRIBUTE
	ANI	80H		;IS IT 'SYS'?
	JNZ	AGAIN		;YES, IGNORE THIS FILE
;
;
; IGNORE FILES WITH .$$$ FILETYPE (THEY ARE USUALLY ZERO-LENGTH AND
; CLUTTER UP OUR DISPLAY.  WE ALSO WANT TO IGNORE OUR CRCKLIST.$$$
; TEMPORARY FILE).
; 
DOSYS:	LXI	H,FCB+9		;POINT TO FILETYPE IN 'FCB'
	CALL	TSTBAD		;CHECK FOR .$$$ FILES
	JZ	AGAIN		;IF ZERO FLAG, IGNORE THEM
;
	XRA	A		;FOUND SOME NAMES
	STA	FOUND
;
;
; MOVE 8 CHARACTERS FROM FCB+1 TO FNAME
;
	LXI	H,FCB+1
	LXI	D,FNAME
	LXI	B,8
	CALL	MOVER
;
;
; MOVE 3 CHARACTERS FROM FCB+9 TO FNAME+9
;
	LXI	H,FCB+9
	LXI	D,FNAME+9
	LXI	B,3
	CALL	MOVER
;
;
; NOW PRINT FILENAME.TYPE
;
	CALL	ILPRT		; PRINT:
;
        DB    '---> '
FNAME:	DB	'XXXXXXXX.XXX     CRC  =  ',0
;
;
; OPEN THE FILE
;
	LXI	D,FCB
	MVI	C,OPEN
	CALL	BDOS
	INR	A
	JNZ	RDINIT
;
	CALL	ABEXIT
	DB	'++OPEN FAILED++$'
;
; 
; INITIALIZE 'CRC' TO ZERO AND SET 'BUFAD' TO CAUSE INITIAL READ
;
RDINIT:	LXI	H,0
 	SHLD	REM		;INIT REMAINDER TO ZERO
	LXI	H,BASE+100H
	SHLD	BUFAD		;INIT BUFFER ADRS
;
;
; THIS IS THE READ LOOP
;
READIT:	LHLD	BUFAD
	MOV	A,H		;TIME TO READ?
	CPI	BASE SHR 8
	JZ	NORD		;NO READ
	MVI	C,CSTAT
	CALL	BDOS		;CHECK FOR OPERATOR ABORT
	ORA	A
	JZ	READ2		;NOTHING TO READ, EXIT
;
	MVI	C,RDCON
	CALL	BDOS		;GET CHARACTER INPUTTED
	CPI	CTLC		;CONTROL-C?
	JZ	ABEXT2		;YES EXIT
;
READ2:	LXI	D,FCB
	MVI	C,READ		;READ ANOTHER SECTOR OF FILE
	CALL	BDOS
	ORA	A		;CHECK RETURN CODE
	JNZ	FINISH		;ERROR OR 'EOF'
	LXI	H,TBUF		;BUFFER LOCATION
;
NORD:	MOV	A,M		;GET FILE CHARACTER
	STA	MESS		;SAVE FOR 'DIVP'
	INX	H
	SHLD	BUFAD
	CALL	DIVP		;CALCULATE NEW 'CRC'
	JMP	READIT		;GO READ MORE CHARACTERS
;.....
;
;
FINISH:	CPI	1		;NORMAL END-OF-FILE?
	JNZ	FILERR		;NO, IT WAS A READ ERROR
;
	LDA	REM+1		;GET MSP OF 'CRC'
	CALL	HEXO		;PRINT IT
	MVI	A,' '		;SEPARATE 'LSP' AND 'LST'
	CALL	TYPE
	LDA	REM		;GET 'LSP' OF 'CRC'
	CALL	HEXO		;PRINT IT
	CALL	CRLF		;TURN UP NEW LINE
	JMP	AGAIN		;SEE IF MORE FILES TO DO
;.....
;
; 
FILERR:	CALL	ABEXIT		; ABORT BECAUSE OF FILE READ ERROR
	DB	'++File read error++$'
;.....
;
;
; 8080 ROUTINE FOR GENERATING A CYCLIC-REDUNDANCY-CHECK.  CHARACTER
; LEAVES THAT CHARACTER IN LOCATION 'REM'.  BY FRED GUTMAN.  FROM
; 'EDN' MAGAZINE, 5 JUNE 1979, PAGE 84.
;
DIVP:	LHLD	REM		;GET REMAINDER
	MOV	A,H
	ANI	128		;Q-BIT MASK
	PUSH	PSW		;SAVE STATUS
	DAD	H		;2 * R(X)
	LDA	MESS		;MESSAGE BIT IN 'LSB'
	ADD	L
	MOV	L,A
	POP	PSW
	JZ	QB2		;IF Q-BIT IS ZERO
;
QB:	MOV	A,H
	XRI	0A0H		;'MS' HALF OF GENERAL POLYNOMINAL
	MOV	H,A
	MOV	A,L
	XRI	97H		;'LS' HALF OF GENERAL POLYNOMINAL
	MOV	L,A
;
QB2:	SHLD	REM
	RET
;.....
;
; 
; HEX OUTPUT
; 
HEXO:	PUSH	PSW		;SAVE FOR RIGHT DIGIT
	RAR			;RIGHT..
	RAR			;..JUSTIFY..
	RAR			;..LEFT..
	RAR			;..DIGIT..
	CALL	NIBBL		;PRINT LEFT DIGIT
	POP	PSW		;RESTORE RIGHT
; 
NIBBL:	ANI	0FH		;ISOLATE DIGIT
	CPI	10		;IS IS LESS THAN 10?
	JC	ISNUM		;YES, NOT ALPHA
	ADI	7		;ADD ALPHA BIAS
; 
ISNUM:	ADI	'0'		;CONVERT FROM BINARY TO ASCII
	JMP	TYPE		;PRINT IT, THEN RETURN
;.....
;
;
; INLINE PRINT ROUTINE
;
ILPRT:	XTHL			;SAVE 'HL', GET MSG
; 
ILPLP:	MOV	A,M		;GET CHAR
	CALL	TYPE		;OUTPUT IT
	INX	H		;POINT TO NEXT
	MOV	A,M		;TEST
	ORA	A		;..FOR END
	JNZ	ILPLP
	XTHL			;RESTORE 'HL', RETURN ADDRESS
	RET			;RETURN PAST MSG
;.....
;
;
; SEND CARRIAGE RETURN, LINE FEED TO OUTPUT
;
CRLF:	MVI	A,CR		;CARRIAGE RETURN
	CALL	TYPE
	MVI	A,LF		;LINE FEED, FALL INTO 'TYPE'
;
;
; SEND CHARACTER IN 'A' REGISTER TO OUTPUT
; 
TYPE:	PUSH	B
	PUSH	D
	PUSH	H
	ANI	7FH		;STRIP OFF ANY PARITY
	MOV	E,A
	PUSH	D
	CALL	WRFILE		;WRITE TO FILE IF REQUESTED
	POP	D
	MVI	C,WRCON		;SEND CHARACTER TO CONSOLE
	CALL	BDOS
	POP	H
	POP	D
	POP	B
	RET
;.....
;
;
PUTFILE:
	PUSH	PSW		;SAVE OUTPUT CHARACTER
	LHLD	FILELEN		;GET CURRENT BUFFER LENGTH
	XCHG			;'DE' HAS LENGTH
	LHLD	FILEPTR		;LOAD NEXT TO GET/PUT TO 'HL'
	MOV	A,L		;COMPUTE CURRENT LENGTH
	SUB	E 	
	MOV	A,H
	SBB	D		;CARRY IF NEXT < LENGTH
	JC	PUTCRC4		;CARRY IF LENGTH > CURRENT
;
	LXI	H,0		;END OF BUFFER, FILL (EMPTY) BUFFERS	
	SHLD	FILEPTR		;CLEAR NEXT TO GET/PUT
;
PUTCRC1:			;PROCESS NEXT DISK SECTOR
	XCHG			;FILE POINTER TO 'DE'
	LHLD	FILELEN		;'HL' IS MAXIMUM BUFFER LENGTH
	MOV	A,E		;COMPUTE NEXT LENGTH
	SUB	L		;TO GET CARRY, IF MORE FILL
	MOV	A,D
	SBB	H		
	JNC	PUTCRC3
	LHLD	FILEADR		;GOT CARRY, MORE TO FILL YET
	DAD	D		;HL IS NEXT BUFFER ADDRESS
	XCHG
	MVI	C,STDMA		;SET 'DMA' ADDRESS
	CALL	BDOS
	LXI	D,FCBFILE	;'FCB' ADDRESS TO 'DE'
	MVI	C,WRITE		;FILE WRITE
	CALL	BDOS
	ORA	A		;CHECK RETURN CODE
	JNZ	PUTCRC2		;END-OF-FILE YET?
	LXI	D,BUF$SIZ	;NOT 'EOF', INCREMENT LENGTH BY 128
	LHLD	FILEPTR		;NEXT TO FILL
	DAD	D
	SHLD	FILEPTR		;SAVE NEW POINTER
	JMP	PUTCRC1		;PROCESS ANOTHER SECTOR
;...
;
;
PUTCRC2:			;GOT END-OF-FILE
	MVI	C,PRINT		;PRINT STRING FUNCTION
	LXI	D,DSK$FULL	;DISK IS FULL
	CALL	BDOS
	POP	PSW		;CLEAN STACK
	JMP	FILERR		;FILE ERROR, EXIT
;...
;
;
PUTCRC3:			;END OF BUFFER, RESET 'DMA' AND POINTER
	LXI	D,TBUF		;POINT TO TEMPORARY BUFFER
	MVI	C,STDMA		;SET 'DMA' FUNCTION
	CALL	BDOS
	LXI	H,0		;RESET POINTER FOR NEXT TO GET
	SHLD	FILEPTR
;
PUTCRC4:			;PROCESS THE NEXT CHARACTER
	XCHG			;INDEX TO GET/PUT IN 'DE'
	LHLD	FILEADR		;BASE OF BUFFER
	DAD	D		;ADDRESS OF CHARACTER IN 'HL'
	XCHG			;AND SWAP TO 'DE'
	POP	PSW		;GET SAVE CHARACTER
	STAX	D		;CHARACTER TO BUFFER
	LHLD	FILEPTR		;INDEX TO GET/PUT
	INX	H		;AND UPDATE FOR NEXT CHARACTER
	SHLD	FILEPTR
	RET
;.....
;
;
; WRITE CHARACTER IN 'E' REGISTER TO OUTPUT FILE
;
WRFILE:	LDA	FFLAG		;GET FILE TRIGGER
	CPI	' '		;IS IT SET?
	RZ			;NO, RETURN
;
	MOV	A,E		;GET CHARACTER BACK
	CALL	PUTFILE
	RET
;.....
;
; 
; MULTI-FILE ACCESS SUBROUTINE.  ALLOWS PROCESSING OF MULTIPLE FILES
; (I.E., *.ASM) FROM DISK.  THIS ROUTINE BUILDS THE PROPER NAME IN THE
; FCB EACH TIME IT IS CALLED.  CARRY IS SET IF NO MORE NAMES CAN BE
; FOUND.
; 
MFNAME:	MVI	C,STDMA		;INIT 'DMA' ADDRESS AND 'FCB'
	LXI	D,TBUF
	CALL	BDOS
	XRA	A
	STA	FCBEXT
	STA	FCBRNO
;
;
; IF FIRST TIME
;
	LDA	MFFLG1
	ORA	A
	JZ	MFN01
;
;
; SAVE THE REQUESTED NAME - SAVE ORIGINAL REQUEST
;
	LXI	H,FCB
	LXI	D,MFREQ
	LXI	B,12
 	CALL	MOVER
	LDA	FCB
	STA	MFCUR		;SAVE DISK IN CURRENT 'FCB'
;
; SEARCH FOR THE FIRT REQUESTED NAME
;
	LXI	H,MFREQ
	LXI	D,FCB
	LXI	B,12
	CALL	MOVER
	MVI	C,SRCHF		;SEARCH FOR FIRST NAME
	LXI	D,FCB
	CALL	BDOS
;
;
; ELSE
;
	JMP	MFN02
; 
MFN01:
	LXI	H,MFCUR
	LXI	D,FCB
	LXI	B,12
	CALL	MOVER
	MVI	C,SRCHF		;SEARCH FOR FIRST NAME
	LXI	D,FCB
	CALL	BDOS
;
;
; SEARCH FOR NEXT REQUESTED NAME
;
	LXI	H,MFREQ
	LXI	D,FCB
	LXI	B,12
	CALL	MOVER
	MVI	C,SRCHN		;SEARCH FOR NEXT NAME
	LXI	D,FCB
	CALL	BDOS
;
; ENDIF
;
MFN02:				;RETURN CARRY IF NOT FOUND
	INR	A
	STC
	RZ
;
;
; MOVE NAME FOUND TO CURRENT NAME
;
	DCR	A
	ANI	3
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	ADI	128+1
	MOV	L,A
	MVI	H,BASE SHR 8
	PUSH	H		;SAVE NAME POINTER
	LXI	D,MFCUR+1
	LXI	B,11
	CALL	MOVER
;
;
; MOVE NAME FOUND TO FCB
;
	POP	H
	LXI	D,FCB+1
	LXI	B,11
	CALL	MOVER
;
;
; SETUP FCB
;
 	XRA	A
	STA	FCBEXT
	STA	FCBRNO
	STA	MFFLG1		;TURN OFF 1ST TIME SWITCH 
	RET
;.....
;
; 
; CHECK FOR .$$$ FILES
; 
TSTBAD:	CALL	TESTIT		;CHECK FIRST ONE FOR '$'
	RNZ			;NO, RETURN
;
	CALL	TESTIT		;CHECK SECOND ONE
	RNZ			;NO, RETURN
;...
;
;
TESTIT:	MOV	A,M
	ANI	7FH		;STRIP ATTRIBUTE
	CPI	'$'		;CHECK FOR $ FILETYPE
	INX	H
	RET
;.....
;
; 
; MOVE (BC) BYTES FROM (HL) TO (DE)
; 
MOVER:	MOV	A,M
	STAX	D
	INX	H
	INX	D
	DCX	B
	MOV	A,B
	ORA	C
	JNZ	MOVER
;
	RET
;..... 
;
;
; ABORTED - PRINT REASON.  IF MAKING OUTPUT FILE, CLOSE THE INCOMPLETE
; FILE TO UPDATE CP/M'S BIT MAP, THEN ERASE IT.
; 
ABEXIT:	POP	D		;GET MSG ADRS
	MVI	C,PRINT
	CALL	BDOS		;PRINT MSG
; 
ABEXT2:	LDA	FFLAG		;SEE IF WE ARE MAKING A DISK FILE
	CPI	' '
	JZ	ABEXT5		;IF NOT, EXIT
;
ABEXT3:	LHLD	FILEPTR
	MOV	A,L
	ANI	07FH
	JNZ	ABEXT4
	SHLD	FILELEN
;
ABEXT4:	MVI	A,EOF
	PUSH	PSW
	CALL	PUTFILE
	POP	PSW
	JNZ	ABEXT3
;
 	MVI	C,CLOSE
	LXI	D,FCBFILE
	CALL	BDOS
	INR	A
	JNZ	ERA$CRC
;
	MVI	C,PRINT
	LXI	D,NO$CLOSE
	CALL	BDOS
;
;
; ERASE INCOMPLETE FILE
;
ERA$CRC:
	MVI	C,DELET
	LXI	D,FCBFILE
	CALL	BDOS
; 
ABEXT5:	CALL	ERXIT		;PRINT MSG, EXIT
	DB	CR,LF,LF,'++ABORTED++',CR,LF,'$'
;
;
; EXIT WITH MESSAGE
; 
MSGEXIT:
	DS	0		;EXIT WITH "INFORMATIONAL" MESSAGE
;
ERXIT:	POP	D		;GET MSG
	MVI	C,PRINT
	CALL	BDOS
; 
; EXIT, RESTORING STACK AND RETURN TO 'CCP'
; 
EXIT:	LHLD	STACK                ;GET OLD STACK RETURN ADDRESS BACK
	SPHL
	RET			;TO 'CCP'
;.....
;
;
DIR$FULL:
	DB	CR,LF
	DB	'++NO DIRECTORY SPACE FOR CRC FILE++',CR,LF,'$'
;
DSK$FULL:
	DB	CR,LF
	DB	'++NO DISK SPACE FOR CRC FILE++',CR,LF,'$'
;
NO$CLOSE:
	DB	CR,LF
	DB	'++CANNOT CLOSE CRC FILE++',CR,LF,'$'
;
; 
; PROGRAM STORAGE AREA
; 
BUFAD:	DB	0,0		;READ BUFFER ADDRESS
FFLAG:	DB	0		;FILE WRITE REQUEST FLAG
FOUND:	DB	0		;SET TO ZERO IF FILE(S) FOUND
MESS:	DB	0		;'CRC' MESSAGE CHAR GOES HERE
MFCUR:	DB	'            '	;CURRENT NAME
MFFLG1:	DB	1		;1ST TIME SWITCH
MFREQ:	DB	'            '	;REQUESTED NAME
OLDSTK:	DB	0,0		;OLD STACK POINTER SAVED HERE
REM:	DB	0,0		;'CRC' REMAINDER STORAGE
;
FILELEN:
	DB	0,0		;FILLED AUTOMATICALLY
;
FILEPTR:
	DB	0,0
;
;
; BUILD FCB FOR FINAL NAME OF CRCKLIST.CRC
;
FCBFINAL:
	DB	0,'CRCKLISTCRC'
	DB	0
	DS	20
;
;
; OUTPUT FILE (TEMPORARILY NAMED CRCKLIST.$$$)
;
FCBFILE:
	DB	0,'CRCKLIST$$$'
	DB	0
	DS	20
;
	DS	80		;MINIMUM STACK AREA
;
SETEVEN EQU	($+127)/128*128	;SET BUFFER TO EVEN PAGE
;
;
	ORG	SETEVEN
;
STACK:	EQU	$-2		;SAVE 2 BYTES FOR OLD STACK POINTER
;
FILEADR:
	DW	FILEADR+2	;BUFFER ALL 'CRC' FILE DATA HERE
;
; 
	END
