; CHECK 8/17/85-12/21, A. B. Langdon›; Determine length, CRC and checksum of file.›; Also number of lines, for text file.›;SET $491=$4000 SET 14=$491^›BYTE JMP=[$4C]: CARD Entry›;INCLUDE "D:SYSLIB.ACT"›;INCLUDE "D:SYSIO.ACT"›; Using channel 1, Close caused "system error" with DOS 2.1 but not DOS XL.›; ACS bbs has a block read (BLKIO.ACT) in machine code segments that is›; smaller and has a general purpose call to CIO. Here, I'll leave mine›; as it illustrates use of the language and is just as fast.›; First global ARRAY, other than BYTE ARRAY of length less than 257,›; is placed AFTER rest of program (undocumented?).›BYTE ARRAY buffer(257) ; locate the buffer.›CARD FLen, ; File length up to 64K› i, CSum, NLines›BYTE OpOK, CSum0=CSum, CSum1=CSum+1, text›BYTE CIO_status ; global for CIO return value (per ACS convention)›INCLUDE "CRC.ACT"›CARD FUNC GetAD(BYTE chan CARD addr, len) ; Block read› TYPE IOCB=[BYTE hid,dno,com,sta› CARD badr,put,blen› BYTE aux1,aux2,aux3,aux4,aux5,aux6]› IOCB POINTER ic› BYTE chan16› BYTE POINTER b› chan16 = (chan&$07) LSH 4› ic = $340+chan16› ic.com = 7 ; read› ic.blen = len› ic.badr = addr› [$AE chan16 $20 $E456 $8C CIO_status] ; LDX chan, JSR CIO; STY CIO_status› FLen ==+ ic.blen ; this to RETURN is special to this application.› IF CIO_status = $88 THEN› EOF(chan)=1› IF (FLen&$FF) = 0 THEN ; likely last sector of› b = addr+ic.blen-1 ; a DOS 4 file.› WHILE b^ = 0 DO› b ==- 1› ic.blen ==- 1› FLen == -1› OD› FI› FI› b = addr› FOR i = 1 TO ic.blen DO› IF b^ = $9B THEN NLines ==+ 1 FI› CSum0 ==+ b^› CSum1 ==+ CSum0› updCRC(b^)› b ==+ 1› OD›RETURN (ic.blen)›CARD FUNC GetCD(BYTE chan) ; Read a word› CARD c› GetAD(chan,@c,2)›RETURN (c)›PROC FixFlSp(BYTE ARRAY FileSpec)› IF FileSpec(2)<>': AND FileSpec(3)<>': THEN ; prefix "D:" to file name› FileSpec^==+2› i=FileSpec^› WHILE i>2 DO› FileSpec(i)=FileSpec(i-2)› i==-1› OD› FileSpec(1)='D FileSpec(2)=':› FI›; Could also convert to upper case: if >$60 then subtract $20.›RETURN›PROC SysErr(BYTE errno)›PROC MyError(BYTE errno)› IF errno=$80 THEN Error=SysErr Error(errno) FI ; break quits› PrintF("error %I. Try again%E",errno)› OpOK=0›RETURN›PROC End=*() [$68$AA$68$CD$2E8$90$5$CD$2E6$90$F3 $48$8A$48$60]›; entry: PLA; TAX; PLA; CMP MEMLO+1; BCC lab; CMP MEMTOP+1; BCC entry;›; lab: PHA; TXA; PHA; RTS›; Trace back thru RTS's and return to cartridge or DOS.›; From ACS bulletin board.›PROC CHECK()› CHAR ARRAY FileSpec(20)› BYTE b, SHFLOK=$2BE› CARD fwa, lwa, BufLen, MEMTOP=$2E5, MEMLO=$2E7› BufLen=MEMTOP-$80-buffer› SysErr=Error› DO› Print("File Spec=")› SHFLOK=$40 ; upper case› InputS(FileSpec)› IF FileSpec^=0 THEN END() FI› FixFlSp(FileSpec)› Close(2)› OpOK=1 Error=MyError Open(2,FileSpec,4,0)› UNTIL OpOK OD› Error=SysErr› FLen=0 CSum=0 CRC=0 text=1 NLines=0›; With DOS 4, this artifice ensures ›; that each GetAD reads one byte into›; next sector, to anticipate EOF.› BufLen ==& $FF00› GetAD(2,buffer,1)› IF buffer(0) = $FF THEN text=0 FI› WHILE EOF(2) = 0 DO› GetAD(2,buffer,BufLen)› OD› updCRC(0) updCRC(0)› PrintF("End of file. %H bytes%E",FLen)› PrintF(" checksum=%H, CRC=%H%E",CSum,CRC)› IF text THEN› PrintF("%I lines%E",NLines)› FI› Close(2)›RETURN›PROC Main()› device=0 ; in case MAC/65 has been here› SetupCRC()› DO› CHECK()› PrintE(" (RETURN to end)")› OD›RETURN›SET Entry=Main›---------------------------------------------------------------------------›MODULE; CRC.ACT 12/21/85 A. B. Langdon›; Before use, do SetupCRC().›; For each data set, first set global CRC=0.›; After calling updCRC(data) with all›; data bytes, do updCRC(0) twice.›; If CRCx is the CRC of a byte string,›; then the CRC of that string, followed by›; the hi and lo bytes of CRCx, is zero.›CARD CRC: BYTE CRCl=CRC, CRCh=CRC+1›CARD ARRAY CRCtable(256)›;PROC updCRCa(BYTE b) ; Action version›; From C code by D. Krantz,›; Dr. Dobb's Journal, June 1985.›; Takes 99 jiffies for 2000 bytes.›; BYTE i›; CARD flag›; FOR i=0 TO 7 DO›; flag = CRC&$8000›; CRC ==LSH 1›; IF b&$80 THEN CRC ==% 1 FI›; IF flag THEN CRC ==XOR $1021 FI›; b ==LSH 1›; OD›;RETURN›PROC updCRC(BYTE b)›; Adaptation to this CRC of the algorithm›; by W.D.Schwaderer, PC Tech Journal, 4/85.›; Takes 14 jiffies for 2000 bytes.› CARD tem› BYTE teml=tem, temh=tem+1› teml = b› temh = CRCl› CRC = tem XOR CRCtable(CRCh)›RETURN›PROC updCRCx=*(BYTE b)›; Machine language for Dr. Dobb's routine.›; Takes 35 jiffies for 2000 bytes.› [$85$A0] ; STA $A0› [$A2$8] ; loop over 8 bits› [$26$A0] ; 3 byte shift of data› [$2E CRC $2E CRC+1] ; and CRC› [$90$10 $AD CRC $49$21 $8D CRC] ; if carry, then XOR› [$AD CRC+1 $49$10 $8D CRC+1] ; poly bits› [$CA $D0$E3] ; loop›RETURN›PROC SetupCRC()› FOR i=0 TO $FF DO ; set up CRC table› CRCl=0 CRCh=i› updCRCx(0)› CRCtable(i)=CRC› OD ; <0.1 sec.›RETURN›MODULE; end CRC›