TITLE 'CRCK.A86 Version 6.3' ; ; A file CRC checking and generating utility for CP/M-86, ; MP/M-86 and Concurrent PCDOS ; ; This version by Bill Bolton, ; Software Tools RCPM, ; P.O. Box 357, ; Kenmore, ; Queensland, 4069 ; Australia ; ;International 61-7-378-9530+ ;Domestic (07) 378-9530 300 bps CCITT V.21 Standard ; ; ; This is a fairly literal translation by XLT86, ; most of the hard work in preparing the 16 bit version ; was done at the 8 bit code level before presenting to ; XLT86. From even a cursory examination I can see quite ; a lot of code that could be made much more efficent by ; using new 8086 instructions to replace the mechanical ; translations from 8080 instructions that XLT86 performs. ; However the program works as it is, which is what I was ; after, so its up to someone else to make it "elegent" ; in 8086 code terms. Bill Bolton ; ; *********** NOTE WELL ************ ; ; This version uses the "old" CRC polynomial code as ; incorrectly described in EDN all those years back ; and generates the same CRCKs as most other CRC programs, ; including the CRC options in YAM, MODEM and MEX. I have ; incremented the version number to 6 to get away from ; the "new" CRC polynomial version of CRCK which, although ; a technically correct implementation of the polynomial, ; produces entirely different CRC values than those found in ; the CRCKLIST, CRCKFILE and -CATALOG files on most public ; domain disks. Even though the "old" polynomial code doesn't ; implement the polynomial correctly, it still works just as ; effectively as the correct polynomial for the purposes of ; identifying the integrity of files on a disk. ; ; Assemble this program with ASM86 ; ; GENCMD CRC7 ; ; ;CREDITS ; ; The 8 bit version of the program was originally ; conceived by Keith Petersen, W8SDZ, to whom all ; glory and honour. ; ;The CYCLIC-REDUNDANCY-CHECK number used is based on the ;CCITT standard polynominal: ; ; X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1 ; ; (well almost, see comments above) ; ;Useful for checking accuracy of file transfers. ;More accurate than a simple checksum. ; ;This utility will optionally will write an output file to the ;default drive, listing the CRC's of all files checked in a ;single session. See CRCBUILD.A86 for a companion utility which ;will build -CATALOG files with embedded CRCs which can be ;checked with this CRC.CMD utility. ; ;COMMANDS: CRCK [drive:] [F] ; ;Examples: ; CRCK MYFILE.ASM ;CHECK ONLY MYFILE.ASM ; CRCK *.ASM ;CHECK ALL .ASM FILES ; CRCK *.* F ;CHECK ALL FILES, MAKE FILE OF RESULTS ; ; WITH NAME F.CRC ; CRCK ;Will attempt to find CRCKLIST.??? ; ; or CRCKFILE.??? or -CATALOG.??? ; ; and try to match recorded CRC values ; ; in that file with values calculated ; ; on the fly for files on the disk. ; ; ;VERSION LIST, most recent version first ; ;30/Oct/84 Added CLOSE to file read routines, as Concurrent DOS ; was reporting "Too many Files Open" error when CRCing ; disks with lots of directory entries. Made the same ; changes to the 8 bit versions. ; CP/M-86/Concurrent version 6.4. Bill Bolton ; ;10/Oct/84 Fixed CP/M-86 version to also work with Concurrent PCDOS, ; and MP/M-86. The "?" in the OPEN function calls was ; upsetting them. CP/M-86/Concurrent version 6.3. Bill Bolton ; ;09/Oct/84 XLT86 translation of 8 bit source code version, massaged ; by hand to make it assemble with ASM86 for CP/M-86. ; CP/M-86 version 6.2. Bill Bolton ; ;07/Oct/84 Tightened 8 bit disassembly considerably and moved all ; the data together preparatory to XLT86ing for CP/M-86. ; CP/M-80 version 6.2. Bill Bolton ; ;04/Oct/84 Disassembled CRC version 5.0 as distributed for some years ; on SIG/M disks, but no source has even been available from ; SIG/M. This version checks the -CATALOG files built with ; CRCBUILD as well as CRCKLIST and CRCKFILE. Obviously used ; SEQIO macros for much of the file I/O but as the aim is ; translation to CP/M-86 I left the macros expanded. Lifted ; recognisable bits of code (like MFNAME) from other sources ; to get comments. Version number 6.1. ; Bill Bolton, Software Tools RCPM, Brisbane Australia ; ; BDOS EQU 224 ; RDCON EQU 1 ;BDOS console input WRCON EQU 2 ;BDOS console output PRINT EQU 9 ;BDOS display string CSTAT EQU 11 ;BDOS console status OPEN EQU 15 ;BDOS file open CLOSE EQU 16 ;BDOS file close SRCHF EQU 17 ;BDOS search for first SRCHN EQU 18 ;BDOS search for next DELETE EQU 19 ;BDOS delete file READ EQU 20 ;BDOS read file WRITE EQU 21 ;BDOS write file MAKE EQU 22 ;BDOS create file RENAME EQU 23 ;BDOS rename existing file SETDMA EQU 26 ;BDOS set transfer address ; FCB EQU 5CH ;Default file control block FCBEXT EQU FCB+12 FCB2 EQU FCB+16 FCBRNO EQU 7CH SECTBUFF EQU 80H ;Defualt transfer buffer ; TAB EQU 09H ;ASCII modulo 8 tab ALF EQU 0AH ;ASCII line feed ACR EQU 0DH ;ASCII carriage returnq EOF EQU 1AH ;CP/M end of file marker ; BUFSIZE EQU 4000H ;File buffers ; M EQU Byte Ptr 0[BX] ;XLT86 strikes again ; CSEG ; START: MOV AX,DS MOV SS,AX MOV SP,(Offset STACK) ;start local stack CALL CRLF MOV DX,(Offset SIGNON) ;Tell them who we are CALL DISPLAY MOV AL,Byte Ptr .FCB+1 ;Point to file name CMP AL,' ' ;Is it there? JZ CONTINUE JMP FILE@OUT@CHECK ;Yes ; CONTINUE: MOV DX,(Offset SRCH@LIST) ;Searching for CRCKLIST.??? file CALL DISPLAY CALL OPENCRCFILE JZ PROCESSIT MOV DX,(Offset SRCH@FILE) CALL DISPLAY ;Searching for CRCKFILE.??? file MOV DX,(Offset FCBCRCFILE)+1 MOV BX,(Offset FIRST@TRY) MOV CX,11 CALL MOVER CALL OPENCRCFILE JZ PROCESSIT JMP CATCHECK ; PROCESSIT: MOV SP,(Offset STACK) ;Reinitialise stack CALL FINDCRC JZ PROCESS2 JMP ABEXT2 ; PROCESS2: MOV DX,(Offset ARROW) MOV BX,(Offset BUFFER) MOV CX,11 CALL COMPARE JNZ NONSENSE CALL ISNAME JNZ NONSENSE MOV DX,(Offset EQUALS) MOV CL,31 CALL COMPARE JNZ NONSENSE CALL STORECRC JNZ NONSENSE MOV BX,(Offset BUFFER)+11 CALL SHOWNAME JMPS PROCESSIT ; NONSENSE: CALL NOPARSE JMPS PROCESSIT ; READFILE: MOV BX,Word Ptr CRCFILELEN XCHG BX,DX MOV BX,Word Ptr CRCFILEPTR MOV AL,BL SUB AL,DL MOV AL,BH SBB AL,DH JB READABYTE MOV BX,0 MOV Word Ptr CRCFILEPTR,BX READLOOP: XCHG BX,DX MOV BX,Word Ptr CRCFILELEN MOV AL,DL SUB AL,BL MOV AL,DH SBB AL,BH JNB READASEC MOV BX,Word Ptr CRCFILEADR ADD BX,DX XCHG BX,DX MOV CL,SETDMA INT BDOS MOV DX,(Offset FCBCRCFILE) MOV CL,READ INT BDOS OR AL,AL JNZ LASTREAD MOV DX,SECTBUFF MOV BX,Word Ptr CRCFILEPTR ADD BX,DX MOV Word Ptr CRCFILEPTR,BX JMPS READLOOP ; LASTREAD: MOV BX,Word Ptr CRCFILEPTR MOV Word Ptr CRCFILELEN,BX READASEC: MOV DX,SECTBUFF MOV CL,SETDMA INT BDOS MOV BX,0 MOV Word Ptr CRCFILEPTR,BX READABYTE: XCHG BX,DX MOV BX,Word Ptr CRCFILEADR ADD BX,DX XCHG BX,DX MOV BX,Word Ptr CRCFILELEN MOV AL,BL OR AL,BH MOV AL,EOF JNZ READBYTE1 RET ; READBYTE1: MOV SI,DX MOV AL,[SI] MOV BX,Word Ptr CRCFILEPTR LAHF INC BX SAHF MOV Word Ptr CRCFILEPTR,BX RET ; OPENCRCFILE: XOR AL,AL MOV Byte Ptr FCBCRCFILE+12,AL MOV Byte Ptr FCBCRCFILE+32,AL MOV BX,BUFSIZE MOV Word Ptr CRCFILELEN,BX MOV Word Ptr CRCFILEPTR,BX MOV BX,(Offset FCBCRCFILE) ;CCP/M doesn't like "?" in MOV DX,(Offset FCB) ; OPEN function calls, so MOV CX,12 ; since we already have CALL MOVER ; MFNAME in the code, use it to CALL MFNAME ; get a definitive filename JB OPENFAIL ; to attempt an open. Only MOV BX,(Offset FCB) ; the first matching name is MOV DX,(Offset FCBCRCFILE) ; tried for an open, but this is all MOV CX,12 ; the orginal code achieved anyway. CALL MOVER MOV CL,OPEN MOV DX,(Offset FCBCRCFILE) INT BDOS INC AL JNZ FILEMATCH OPENFAIL: MOV CL,PRINT MOV DX,(Offset NOFILECRC) INT BDOS JMP FILERR ; FILEMATCH: MOV BX,(Offset FCBCRCFILE)+1 MOV DX,(Offset BUFFER) MOV CX,8 CALL MOVER MOV AL,'.' MOV SI,DX MOV [SI],AL INC DX MOV CX,3 CALL MOVER XOR AL,AL MOV SI,DX MOV [SI],AL MOV DX,(Offset CHECKING) ;Show which file we are checking CALL DISPLAY MOV BX,(Offset BUFFER) MATCHLOOP: MOV AL,M OR AL,AL JZ MATCHINIT CALL TYPER INC BX JMPS MATCHLOOP ; MATCHINIT: CALL CRLF CALL CRLF XOR AL,AL MOV Byte Ptr MATCHNO,AL MOV Byte Ptr NOMATCH,AL MOV Byte Ptr FAILED,AL MOV Byte Ptr FILES,AL RET ; FINDCRC: MOV BX,(Offset BUFFER) MOV AL,0 MOV Byte Ptr CURSOR,AL ;Reset cursor counter to start of line FINDCRC1: PUSH BX CALL READFILE POP BX CMP AL,EOF JNZ FINDCRC2 MOV AL,Byte Ptr CURSOR OR AL,AL JNZ FINDDONE MOV AL,Byte Ptr CRCENTRY OR AL,AL JNZ FINDCRC1A JMP DONEIT ; FINDCRC1A: MOV DX,(Offset NOFIND) ;File not found CALL DISPLAY MOV AL,EOF OR AL,AL RET ; FINDCRC2: AND AL,07FH ;Make sure its ASCII CMP AL,ACR ;End of line? JZ ENDOFLINE ;Yes CMP AL,ALF ;End of line? JZ ENDOFLINE ;Yes MOV M,AL ;No INC BX MOV AL,Byte Ptr CURSOR ;Bump cursor pointer INC AL MOV Byte Ptr CURSOR,AL CMP AL,80 ;End of line? JB FINDCRC1 ;No ENDOFLINE: MOV AL,Byte Ptr CURSOR OR AL,AL JZ FINDCRC FINDDONE: MOV M,0 XOR AL,AL RET ; NOPARSE: MOV DX,(Offset CANTPARSE) ;Cant parse string CALL DISPLAY MOV BX,(Offset BUFFER) PARSELOOP: MOV AL,M OR AL,AL JZ SHOWERR CALL TYPER INC BX JMPS PARSELOOP ; SHOWERR: CALL CRLF MOV BX,(Offset BUFFER) INC CH DEC CH JZ SHOWERR3 SHOWERR1: MOV AL,TAB CMP AL,M JZ SHOWERR2 MOV M,' ' SHOWERR2: INC BX DEC CH JNZ SHOWERR1 SHOWERR3: MOV M,'^' INC BX MOV M,0 MOV BX,(Offset BUFFER) SHOWERR4: MOV AL,M OR AL,AL JZ RECORDERR CALL TYPER INC BX JMPS SHOWERR4 ; RECORDERR: MOV BX,(Offset FAILED) INC M CALL CRLF RET ; COMPARE: MOV SI,DX MOV AL,[SI] CMP AL,M JZ COMPARE1 RET ; COMPARE1: INC BX INC DX INC CH MOV AL,CH CMP AL,CL JNZ COMPARE2 RET ; COMPARE2: JMPS COMPARE ; SHOWNAME: PUSH BX MOV DX,FCB+1 MOV CX,8 CALL MOVER INC BX MOV CX,3 MOV DX,FCB+9 CALL MOVER XOR AL,AL MOV M,AL POP BX SHOWLOOP: MOV AL,M OR AL,AL JZ SHOWDONE CALL TYPER INC BX JMPS SHOWLOOP ; SHOWDONE: MOV AL,1 MOV Byte Ptr MFFLG1,AL MOV DX,(Offset DASH) ;Display delimiter CALL DISPLAY CALL MFNAME JNB TRYMATCH MOV DX,(Offset NOFIND2) CALL DISPLAY MOV BX,(Offset FILES) INC M XOR AL,AL INC AL RET ; TRYMATCH: MOV AL,1 MOV Byte Ptr MATCHFLG,AL ;We found some filenames to check CALL OPENIT JZ TRYMATCH1 RET ; TRYMATCH1: MOV AL,Byte Ptr OLDCRC+1 MOV CH,AL MOV AL,Byte Ptr REM CMP AL,CH JNZ MISMATCH MOV AL,Byte Ptr OLDCRC MOV CH,AL MOV AL,Byte Ptr REM+1 CMP AL,CH JNZ MISMATCH MOV DX,(Offset MATCHMSG) ;**Match** CALL DISPLAY XOR AL,AL MOV Byte Ptr CRCENTRY,AL MOV BX,(Offset MATCHNO) INC M XOR AL,AL RET ; MISMATCH: MOV DX,(Offset ISWAS) ; <--is, was --> CALL DISPLAY MOV AL,Byte Ptr OLDCRC CALL HEXO MOV AL,' ' CALL TYPER MOV AL,Byte Ptr OLDCRC+1 CALL HEXO CALL CRLF XOR AL,AL MOV Byte Ptr CRCENTRY,AL MOV BX,(Offset NOMATCH) INC M XOR AL,AL INC AL RET ; STORECRC: CALL HEXBIN JZ STORECRC0 RET ; STORECRC0: MOV Byte Ptr OLDCRC,AL MOV AL,M INC BX CMP AL,' ' JZ STORECRC1 MOV DX,(Offset NOTSPACE) ;No space between CRC values CALL DISPLAY XOR AL,AL INC AL RET ; STORECRC1: CALL HEXBIN JZ STORECRC2 RET ; STORECRC2: MOV Byte Ptr OLDCRC+1,AL MOV CH,AL XOR AL,AL RET ; CATCHECK: MOV DX,(Offset SRCH@CAT) ;Searching -CATALOG file CALL DISPLAY MOV DX,(Offset FCBCRCFILE)+1 MOV BX,(Offset CATALOG) MOV CX,11 CALL MOVER CALL OPENCRCFILE JZ PARSELINE JMP ABEXT2 ; PARSELINE: CALL FINDCRC JZ PARSE2 JMP ABEXT2 ; PARSE2: MOV CH,0 MOV BX,(Offset BUFFER) ;Point to catalog entry CALL THREENUM ;Check for 3 digit volume number JNZ TRYAGAIN MOV AL,'.' ;Followed by separator CMP AL,M JNZ TRYAGAIN LAHF INC BX SAHF INC CH CALL TWONUM ;Check for 2 digit entry number JNZ TRYAGAIN CALL ISWHITE ;Skip over white space JNZ TRYAGAIN CALL ISNAME ;Check for valid file name JNZ TRYAGAIN CALL ISWHITE ;Skip over white space JNZ NOGOOD CALL ISNUM ;Check for first digit of filesize JNZ NOGOOD SKIP: CALL ISNUM JZ SKIP CMP AL,'K' ;Filesize ends in K JNZ NOGOOD CALL ISWHITE ;Skip over white space JNZ NOGOOD CALL STORECRC ;Now we should be at the CRC JNZ NOGOOD MOV BX,Word Ptr POINTER CALL SHOWNAME JMPS PARSELINE ; TRYAGAIN: MOV AL,Byte Ptr CRCENTRY OR AL,AL JNZ PARSELINE NOGOOD: CALL NOPARSE JMP PARSELINE ; ISNAME: MOV Word Ptr POINTER,BX CALL ISALPHA ;Check first character JZ ISNAME0 RET ; ISNAME0: MOV CL,7 ;7 left in rest of filename ISNAME1: CALL ISALPHA JZ ISNAME2 CMP AL,' ' ;Maybe padded with spaces? JZ ISNAME2 RET ; ISNAME2: DEC CL ;Done? JNZ ISNAME1 ;No MOV AL,M ;Yes INC BX INC CH CMP AL,'.' ;Valid separator? JZ ISNAME3 RET ; ISNAME3: MOV CL,3 ;3 in filetype ISNAME4: CALL ISALPHA JZ ISNAME5 CMP AL,' ' ;Padded with spaces JZ ISNAME5 RET ; ISNAME5: DEC CL ;Done? JNZ ISNAME4 ;No RET ;Yes ; ISWHITE: MOV AL,M CMP AL,' ' ;Space? JZ WHITELOOP ;Yes, check some more CMP AL,TAB ;No, maybe a TAB? JZ WHITELOOP RET ;No, something else ; WHITELOOP: INC BX ;Point to next char INC CH MOV AL,M CMP AL,' ' ;Space? JZ WHITELOOP ;Yes, check some more CMP AL,TAB ;No, maybe a TAB? JZ WHITELOOP ;Yes, check some more CMP AL,AL ;No, something else RET ; THREENUM: CALL TWONUM JZ THREENUM1 RET ; THREENUM1: CALL ISNUM JNZ THREENUM2 RET ; THREENUM2: CMP AL,'.' JZ THREENUM3 RET ; THREENUM3: DEC BX DEC CH CMP AL,AL RET ; TWONUM: CALL ISNUM JZ ISNUM RET ; ISNUM: MOV AL,M INC BX INC CH CMP AL,'0' JB NOTNUM CMP AL,'9'+1 JNB NOTNUM CMP AL,AL RET ; NOTNUM: CMP AL,'0' RET ; ISALPHA: MOV AL,M INC BX INC CH CMP AL,' '+1 JB ALPHA1 CMP AL,07FH JNB ALPHA1 CMP AL,AL RET ; ALPHA1: CMP AL,'A' RET ; HEXBIN: CALL MAKEBIN JZ HEXBIN1 RET ; HEXBIN1: ROL AL,1 ROL AL,1 ROL AL,1 ROL AL,1 MOV CL,AL CALL MAKEBIN JZ HEXBIN2 RET ; HEXBIN2: MOV CH,AL MOV AL,CL OR AL,CH CMP AL,AL RET ; MAKEBIN: MOV AL,M INC BX INC CH CMP AL,'0' JB MAKEBIN2 SUB AL,'0' CMP AL,10 JB MAKEBIN1 AND AL,1FH SUB AL,7H CMP AL,10 JB MAKEBIN2 CMP AL,16 JNB MAKEBIN2 MAKEBIN1: CMP AL,AL ;Return zero flag not set RET ; MAKEBIN2: OR AL,AL ;Return zero flag set RET ; FILE@OUT@CHECK: MOV AL,Byte Ptr .FCB2+1 ;Point to possible file write command MOV Byte Ptr FFLAG,AL ;Save as a flag CMP AL,'F' ;Is it the correct one? JZ FILE@OUT@CHK JMP AGAIN ;Yes FILE@OUT@CHK: JMP MAKEOUTFILE ;No ; PUTCRCFILE: LAHF XCHG AL,AH PUSH AX MOV BX,Word Ptr OUTFILELEN XCHG BX,DX MOV BX,Word Ptr OUTFILEPTR MOV AL,BL SUB AL,DL MOV AL,BH SBB AL,DH JB WRITEABYTE MOV BX,0 MOV Word Ptr OUTFILEPTR,BX PUTCRCLOOP: XCHG BX,DX MOV BX,Word Ptr OUTFILELEN MOV AL,DL SUB AL,BL MOV AL,DH SBB AL,BH JNB STARTASEC MOV BX,Word Ptr OUTFILEADR ADD BX,DX XCHG BX,DX MOV CL,SETDMA INT BDOS MOV DX,(Offset FCBOUTFILE) MOV CL,WRITE INT BDOS OR AL,AL JNZ FULLDISK MOV DX,SECTBUFF MOV BX,Word Ptr OUTFILEPTR ADD BX,DX MOV Word Ptr OUTFILEPTR,BX JMPS PUTCRCLOOP ; FULLDISK: MOV CL,PRINT MOV DX,(Offset DISKFULL) INT BDOS POP AX XCHG AL,AH JMP FILERR ; STARTASEC: MOV DX,SECTBUFF MOV CL,SETDMA INT BDOS MOV BX,0 MOV Word Ptr OUTFILEPTR,BX WRITEABYTE: XCHG BX,DX MOV BX,Word Ptr OUTFILEADR ADD BX,DX XCHG BX,DX POP AX XCHG AL,AH SAHF MOV SI,DX MOV [SI],AL MOV BX,Word Ptr OUTFILEPTR LAHF INC BX SAHF MOV Word Ptr OUTFILEPTR,BX RET ; MAKEOUTFILE: XOR AL,AL MOV Byte Ptr FCBOUTFILE+12,AL MOV Byte Ptr FCBOUTFILE+32,AL MOV BX,BUFSIZE MOV Word Ptr OUTFILELEN,BX MOV BX,0 MOV Word Ptr OUTFILEPTR,BX MOV CL,DELETE MOV DX,(Offset FCBOUTFILE) INT BDOS MOV CL,MAKE MOV DX,(Offset FCBOUTFILE) INT BDOS INC AL JNZ AGAIN MOV CL,PRINT MOV DX,(Offset NODIRSPACE) INT BDOS JMP FILERR ; AGAIN: MOV SP,(Offset STACK) ;Reinit stack pointer MOV AL,0 MOV Byte Ptr MATCHFLG,AL CALL MFNAME JNAE AGAIN1 JMP DOFILECRC ; AGAIN1: MOV AL,Byte Ptr MFFLG1 OR AL,AL JZ DONE MOV DX,(Offset NOFIND3) MOV CL,PRINT INT BDOS JMP ABEXT2 ; DONE: MOV AL,Byte Ptr FFLAG CMP AL,'F' JNZ DONEIT CLEANUP: MOV BX,Word Ptr OUTFILEPTR MOV AL,BL AND AL,07FH JNZ CLOSEIT MOV Word Ptr OUTFILELEN,BX CLOSEIT: ;Close CRCKLIST.$$$ MOV AL,EOF LAHF XCHG AL,AH PUSH AX XCHG AL,AH CALL PUTCRCFILE POP AX XCHG AL,AH SAHF JNZ CLEANUP MOV CL,CLOSE MOV DX,(Offset FCBOUTFILE) INT BDOS INC AL JNZ ERASEIT MOV CL,PRINT MOV DX,(Offset CANTCLOSE) INT BDOS JMPS ERASEIT ; ERASEIT: ;Erase any existing CRCKLIST.CRC file MOV CL,DELETE MOV DX,(Offset FCBFINAL) INT BDOS MOV BX,(Offset FCBOUTFILE) MOV DX,(Offset FCBFINAL) PUSH BX MOV CX,16 ADD BX,CX RENLOOP: MOV SI,DX MOV AL,[SI] MOV M,AL INC DX INC BX DEC CL JNZ RENLOOP POP DX MOV CL,RENAME ;Rename CRCKLIST.$$$ to CRCKLIST.CRC INT BDOS DONEIT: MOV DX,(Offset FINITO) JMP SIGNOFF ; DOFILECRC: MOV BX,FCB+9 CALL TSTBAD JNZ DOFILECRC1 JMP AGAIN ; DOFILECRC1: MOV BX,FCB+1 MOV DX,(Offset FNAME) MOV CX,8 CALL MOVER MOV BX,FCB+9 MOV DX,(Offset FNAME)+9 MOV CX,3 CALL MOVER MOV DX,(Offset ACRALF) CALL DISPLAY CALL OPENIT JNZ DOFILECRC3 JMP AGAIN ; DOFILECRC3: JMP ABEXT2 ; OPENIT: MOV DX,FCB MOV CL,OPEN INT BDOS INC AL JNZ RDINIT MOV DX,(Offset BADOPEN) CALL DISPLAY XOR AL,AL INC AL RET ; RDINIT: MOV BX,0 MOV Word Ptr REM,BX MOV BX,256 ;100H MOV Word Ptr BUFAD,BX READIT: MOV BX,Word Ptr BUFAD MOV AL,BH ;Time to read? CMP AL,0 JZ NORD ;No MOV CL,CSTAT ;Check for operator abort INT BDOS OR AL,AL JZ READ2 ;Nothing from operator MOV CL,RDCON INT BDOS CMP AL,'C' - 40H ;Control-C ? JNZ READ2 JMP ABEXT2 ; READ2: MOV DX,FCB MOV CL,READ ;Read another sector of file INT BDOS OR AL,AL ;Check return code JNZ FINISH MOV BX,SECTBUFF NORD: MOV AL,M ;Get a character MOV Byte Ptr MESS,AL ;Save for DIVP INC BX MOV Word Ptr BUFAD,BX ;Update buffer address CALL DIVP ;Calculate new CRC JMPS READIT ;Read some more characters ; FINISH: CMP AL,1 ;Normal end of file? JZ FINISH1 ;Yes CALL CLOSER JMP FILERR ;No, it was a read error FINISH1: MOV AL,Byte Ptr REM+1 ;Get MSP of CRC CALL HEXO ;Display it MOV AL,' ' CALL TYPER MOV AL,Byte Ptr REM ;Get LSP of CRC CALL HEXO ;Display it CALL CLOSER XOR AL,AL RET ; FILERR: MOV DX,(Offset READERR) CALL DISPLAY XOR AL,AL INC AL RET ; CLOSER: MOV DX,FCB MOV CL,CLOSE INT BDOS RET ; ;--------------------------------------------- ;An 808& routine for generating a CYCLIC- ;REDUNDANCY-CHECK. Character leaes that ;character in location REM. By Fred Gutman. ;From 'EDN' magazine, June 5, 1979 issue, page 84. ; DIVP: MOV BX,Word Ptr REM ;GET REMAINDER MOV AL,BH AND AL,128 ;Q-BIT MASK LAHF ;SAVE STATUS XCHG AL,AH PUSH AX SHL BX,1 ;2 X R(X) MOV AL,Byte Ptr MESS ;MESSAGE BIT IN LSB ADD AL,BL MOV BL,AL POP AX XCHG AL,AH SAHF JZ QB2 ;IF Q-BIT IS ZERO ; QB: MOV AL,BH XOR AL,0A0H ;MS HALF OF GEN. POLY MOV BH,AL MOV AL,BL XOR AL,97H ;LS HALF OF GEN. POLY MOV BL,AL ; QB2: MOV Word Ptr REM,BX RET ; ;-------------------------------------------- ; ;Hex output ; HEXO: LAHF ;SAVE FOR RIGHT DIGIT XCHG AL,AH PUSH AX XCHG AL,AH RCR AL,1 ;RIGHT.. RCR AL,1 ;..JUSTIFY.. RCR AL,1 ;..LEFT.. RCR AL,1 ;..DIGIT.. CALL NIBBL ;PRINT LEFT DIGIT POP AX ;RESTORE RIGHT XCHG AL,AH ; NIBBL: AND AL,0FH ;ISOLATE DIGIT CMP AL,10 ;IS IS <10? JB NOTALPHA ;YES, NOT ALPHA ADD AL,7 ;ADD ALPHA BIAS ; NOTALPHA: ADD AL,'0' ;MAKE PRINTABLE JMPS TYPER ;PRINT IT, THEN RETURN ; DISPLAY: PUSH BX XCHG BX,DX ILPLP: MOV AL,M CALL TYPER INC BX MOV AL,M OR AL,AL JNZ ILPLP POP BX RET ; CRLF: MOV AL,ACR CALL TYPER MOV AL,ALF TYPER: PUSH CX PUSH DX PUSH BX AND AL,07FH ;ASCII mask MOV DL,AL PUSH DX CALL WRFLAG ;Write to file if needed POP DX MOV CL,WRCON INT BDOS POP BX POP DX POP CX RET ; WRFLAG: MOV AL,Byte Ptr FFLAG CMP AL,'F' ;Write to file? JZ WRFLAG1 RET ;No ; WRFLAG1: MOV AL,DL ;Yes CALL PUTCRCFILE 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. The routine is commented in Pseudo ;code, each Pseudo code statement is in <<...>> ; MFNAME: ;<> MOV CL,SETDMA MOV DX,SECTBUFF INT BDOS XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV Byte Ptr .FCBRNO,AL ;<> MOV AL,Byte Ptr MFFLG1 OR AL,AL JZ MFN01 ;<> ;Save orig request MOV BX,FCB MOV DX,(Offset MFREQ) MOV CX,12 CALL MOVER MOV AL,Byte Ptr .FCB MOV Byte Ptr MFCUR,AL ;SAVE DISK IN CURR FCB ;<> MOV BX,(Offset MFREQ) MOV DX,FCB MOV CX,12 CALL MOVER MOV CL,SRCHF MOV DX,FCB INT BDOS ;<> JMPS MFN02 ; MFN01: ;<> MOV BX,(Offset MFCUR) MOV DX,FCB MOV CX,12 CALL MOVER MOV CL,SRCHF MOV DX,FCB INT BDOS ;<> MOV BX,(Offset MFREQ) MOV DX,FCB MOV CX,12 CALL MOVER MOV CL,SRCHN MOV DX,FCB INT BDOS ;<> MFN02: ;<> INC AL STC JNZ MFN03 RET ; ;<> MFN03: DEC AL AND AL,3 ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,AL ADD AL,81H MOV BL,AL MOV BH,0 PUSH BX ;SAVE NAME POINTER MOV DX,(Offset MFCUR)+1 MOV CX,11 CALL MOVER ;<> POP BX MOV DX,FCB+1 MOV CX,11 CALL MOVER ;<> XOR AL,AL MOV Byte Ptr .FCBEXT,AL MOV Byte Ptr .FCBRNO,AL MOV Byte Ptr MFFLG1,AL ;TURN OFF 1ST TIME SW ;<> RET ; TSTBAD: CALL TESTIT ;Check first one for $ JZ TSTBAD1 RET ; TSTBAD1: CALL TESTIT ;Check second on JZ TESTIT RET ; TESTIT: ;Fall through to test third MOV AL,M AND AL,07FH CMP AL,'$' LAHF INC BX SAHF RET ; MOVER: MOV AL,M MOV SI,DX MOV [SI],AL INC BX INC DX DEC CX MOV AL,CH OR AL,CL JNZ MOVER RET ; ABEXT2: MOV AL,Byte Ptr FFLAG CMP AL,'F' ;Writing to file? JNZ ABEXT3 ;No ABEXT2A: ;Close incomplete file MOV BX,Word Ptr OUTFILEPTR MOV AL,BL AND AL,07FH JNZ ABEXT2B MOV Word Ptr OUTFILELEN,BX ABEXT2B: MOV AL,EOF LAHF XCHG AL,AH PUSH AX XCHG AL,AH CALL PUTCRCFILE POP AX XCHG AL,AH SAHF JNZ ABEXT2A MOV CL,CLOSE MOV DX,(Offset FCBOUTFILE) INT BDOS INC AL JNZ ABEXT2C MOV CL,PRINT MOV DX,(Offset ABTEXT) INT BDOS JMPS ABEXT2C ; ABEXT2C: MOV CL,DELETE MOV DX,(Offset FCBOUTFILE) INT BDOS ABEXT3: MOV DX,(Offset ABORT) SIGNOFF: MOV CL,PRINT INT BDOS MOV AL,Byte Ptr MATCHFLG OR AL,AL JZ EXIT XOR AL,AL MOV Byte Ptr FFLAG,AL CALL CRLF MOV DX,(Offset CRCMATCH) CALL DISPLAY MOV AL,Byte Ptr MATCHNO CALL DECIMAL MOV AL,Byte Ptr NOMATCH OR AL,AL JZ PARSE CALL CRLF MOV DX,(Offset CRCNOMATCH) CALL DISPLAY MOV AL,Byte Ptr NOMATCH CALL DECIMAL PARSE: MOV AL,Byte Ptr FAILED OR AL,AL JZ NOTFOUND CALL CRLF MOV DX,(Offset BADPARSE) CALL DISPLAY MOV AL,Byte Ptr FAILED CALL DECIMAL NOTFOUND: MOV AL,Byte Ptr FILES OR AL,AL JZ EXIT CALL CRLF MOV DX,(Offset QTYNOFIND) CALL DISPLAY MOV AL,Byte Ptr FILES CALL DECIMAL EXIT: MOV CX,0 MOV DX,0 INT BDOS ;We're off to see the wizard... ; DECIMAL: MOV DL,0 MOV CH,064H CALL DEC1 MOV CH,10 CALL DEC1 ADD AL,'0' JMP TYPER ; DEC1: MOV CL,0FFH DEC2: INC CL SUB AL,CH JNB DEC2 ADD AL,CH MOV DH,AL MOV AL,CL OR AL,DL JZ DEC3 OR AL,'0' CALL TYPER MOV DL,'0' DEC3: MOV AL,DH RET ; DSEG ; ORG 100H ; FIRST@TRY DB 'CRCKFILE???',0 ; SIGNON DB 'CRC, CP/M-86 Ver 6.4, 30/Oct/84, Bill Bolton',ACR,ALF DB 'CTL-S pauses, CTL-C aborts',ACR,ALF,0 ; SRCH@LIST DB '++Searching for CRCKLIST file++',0 ; SRCH@FILE DB 'Now searching for "CRCKFILE" file++',0 ; NOFILECRC DB ACR,ALF DB 'NO FILECRC FILE$' ; CHECKING DB TAB,'Checking with file - ',0 ; NOFIND DB '***No CRC Files found***$',0 ; CANTPARSE DB 'Can not parse string',ACR,ALF,0 ; DASH DB ' - ',0 ; NOFIND2 DB 'File not found',ACR,ALF,0 ; MATCHMSG DB ' *Match*',ACR,ALF,0 ; ISWAS DB ' <-- is, was --> ',0 ; NOTSPACE DB 'Not a space between CRC values',0 ; SRCH@CAT DB '++ Now searching for "-CATALOG" file++',0 ; DISKFULL DB ACR,ALF DB 'DISK FULL: CRCFILE$' ; NODIRSPACE DB ACR,ALF DB 'NO DIR SPACE: CRCFILE$' ; NOFIND3 DB '++FILE NOT FOUND++$' ; CANTCLOSE DB ACR,ALF DB 'CANNOT CLOSE CRCFILE$' ; FINITO DB ACR,ALF DB 'DONE$' ; ACRALF DB ACR,ALF ARROW DB '--> FILE: ' FNAME DB 'XXXXXXXX.XXX' EQUALS DB TAB,TAB,'CRC = ',0 ; BADOPEN DB '++OPEN FAILED++',0 ; READERR DB TAB,TAB,'++FILE READ ERROR++',ACR,ALF,0 ; ABTEXT DB ACR,ALF DB 'CANNOT CLOSE CRCFILE$' ; ABORT DB ACR,ALF,ACR,ALF DB '++ABORTED++$' ; CRCMATCH DB 'Quantity of file CRC that matched - ',0 ; CRCNOMATCH DB 'Quantity of file CRC that did not match - ',0 ; BADPARSE DB 'Quantity of lines failed parse test - ',0 ; QTYNOFIND DB 'Quantity of file(s) not found - ',0 ; FCBCRCFILE DB 0,'CRCKLIST???',0 DB 0,'CRCKFILE???',0 RS 7 CRCFILEADR DW (Offset CRCFILEBUF) CRCFILELEN DW BUFSIZE CRCFILEPTR RS 2 ; FCBOUTFILE DB 0,'CRCKLIST$$$' DB 0 RS 20 OUTFILEADR DW (Offset OUTFILEBUF) OUTFILELEN DW BUFSIZE OUTFILEPTR RS 2 ; CATALOG DB '-CATALOG???',0 ; FCBFINAL DB 0,'CRCKLISTCRC',0 RS 20 ; POINTER RS 2 MATCHNO RS 1 NOMATCH RS 1 FAILED RS 1 FILES RS 1 FFLAG RS 1 REM RS 2 OLDCRC RS 2 MESS RS 1 MFFLG1 DB 1 CRCENTRY DW 1 MFREQ RS 12 MFCUR RS 12 MATCHFLG RS 1 BUFAD RS 2 CURSOR RS 2 BUFFER RB 80 ; RB 96 STACK DB 0 ; CRCFILEBUF RB BUFSIZE OUTFILEBUF RB BUFSIZE ; END