home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol009 / crck10-6.asm < prev    next >
Assembly Source File  |  1984-04-29  |  11KB  |  495 lines

  1. ;
  2. ;        CRCK.ASM version 4.2
  3. ;          by Keith Petersen, W8SDZ
  4. ;         (revised 10/6/80)
  5. ;
  6. ;----> NOTE: MUST BE ASSEMBLED BY MAC <----
  7. ;
  8. ;CRCK is a program to read any CP/M file and print
  9. ;a CYCLIC-REDUNDANCY-CHECK number based on the
  10. ;CCITT standard polynominal:
  11. ;   X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
  12. ;
  13. ;Useful for checking accuracy of file transfers.
  14. ;More accurate than a simple checksum.
  15. ;
  16. ;Optionally will write an output file to the default
  17. ;drive, listing the CRC's of all files checked in a
  18. ;single session.
  19. ;
  20. ;COMMANDS:   CRCK [drive:]<filename.filetype> [F]
  21. ;
  22. ;Examples:
  23. ;    CRCK MYFILE.ASM    ;CHECK ONLY MYFILE.ASM
  24. ;    CRCK *.ASM    ;CHECK ALL .ASM FILES
  25. ;    CRCK *.* F    ;CHECK ALL FILES, MAKE FILE OF RESULTS
  26. ;
  27. ;Program updates/fixes (these are written in reverse
  28. ;order to minimize reading time to find latest update):
  29. ;
  30. ;10/06/80 FIX TO ERASE TEMPORARY FILE WHEN OUTPUT FILE IS
  31. ;      REQUESTED AND NAME NOT FOUND IN DIRECTORY. (KBP)
  32. ;
  33. ;10/05/80 FIX ABORT ROUTINE TO CHECK FOR FILE REQUEST
  34. ;      AND TO CLOSE INCOMPLETE FILE BEFORE ERASING
  35. ;      IT. ADDED TESTS FOR NO FILE NAME AND FILE
  36. ;      READ ERROR.  (KBP)
  37. ;
  38. ;10/04/80 ADD ROUTINE TO GIVE OPTION TO MAKE
  39. ;      DISK FILE OF CRC's. FIXED MFA ROUTINE
  40. ;      SO FIRST-TIME FLAG NOW SHOWS IF NO FILE
  41. ;      FOUND.  (KBP)
  42. ;
  43. ;04/21/80 ADD MULTIPLE FILENAME FEATURE, PRINT
  44. ;      NAME OF CURRENT FILE BEING READ, AND
  45. ;      ALLOW OPERATOR ABORT. (KBP)
  46. ;
  47. ;08/20/79 FIX BUG IN READIT ROUTINE WHICH
  48. ;      SHOWED UP ONLY ON ALTCPM OPTION. (KBP)
  49. ;
  50. ;08/19/79 ADD CONDITIONAL ASSEMBLY FOR CP/M
  51. ;      ON H8 OR TRS-80.  (KBP)
  52. ;
  53. ;06/27/79 FIRST WRITTEN BY KEITH PETERSEN, W8SDZ
  54. ;
  55. ;Define true and false
  56. ;
  57. FALSE    EQU    0
  58. TRUE    EQU    NOT FALSE
  59. ;
  60. ;Conditional assembly switches
  61. ;
  62. STDCPM    EQU    TRUE    ;TRUE IS STANDARD CP/M
  63. ALTCPM    EQU    FALSE    ;TRUE IS H8 OR TRS-80
  64. NOSYS    EQU    FALSE    ;TRUE IF SYS FILES NOT WANTED
  65. ;
  66. ;System equates
  67. ;
  68. BASE    SET    0
  69.     IF    ALTCPM
  70. BASE    SET    4200H
  71.     ENDIF        ;ALTCPM
  72. ;
  73. ;Define write buffer size (presently set for 8k)
  74. ;
  75. BSIZE    EQU    8*1024    ;DISK WRITE BUFFER SIZE
  76. ;
  77. ;BDOS equates
  78. ;
  79. RDCON    EQU    1
  80. WRCON    EQU    2
  81. PRINT    EQU    9
  82. CSTAT    EQU    11
  83. OPEN    EQU    15
  84. SRCHF    EQU    17
  85. SRCHN    EQU    18
  86. READ    EQU    20
  87. STDMA    EQU    26
  88. BDOS    EQU    BASE+5
  89. FCB    EQU    BASE+5CH 
  90. FCBEXT    EQU    FCB+12
  91. FCBRNO    EQU    FCB+32
  92. FCB2    EQU    BASE+6CH
  93. ;
  94. ;Program starts here
  95. ;
  96.     ORG    BASE+100H
  97. ;
  98.     MACLIB    SEQIO    ;DEFINE MACRO LIBRARY USED
  99. ;
  100. CRCK:    JMP    BEGIN    ;JUMP AROUND IDENTIFICATION
  101.     DB    'CRCK.COM 4.2 10/6/80'
  102. ;
  103. BEGIN:    LXI    H,0    ;GET STACK...
  104.     DAD    SP    ;POINTER SO WE CAN...
  105.     SHLD    STACK    ;SAVE IT
  106.     LXI    SP,STACK ;INITIALIZE LOCAL STACK
  107.     CALL    CRLF    ;TURN UP A NEW LINE
  108.     LDA    FCB+1
  109.     CPI    ' '    ;SEE IF NAME THERE
  110.     JNZ    BEGIN2    ;YES, CONTINUE
  111.     CALL    ERXIT    ;PRINT MSG, THEN EXIT
  112.     DB    '++NO FILE NAME SPECIFIED++',CR,LF,'$'
  113. ;
  114. BEGIN2:    CALL    ILPRT    ;PRINT:
  115.     DB    'CRCK ver 4.2',CR,LF
  116.     DB    'CTL-S pauses, CTL-C aborts',CR,LF,0
  117.     LDA    FCB2+1    ;GET OPTION
  118.     STA    FFLAG    ;SAVE IT FOR LATER
  119.     CPI    'F'    ;FILE WANTED?
  120.     JNZ    AGAIN    ;NO, SKIP FILE INIT
  121. ;
  122. ;'Declare' FCB for output file
  123. ;(temporarily named CRCKLIST.$$$)
  124. ;
  125.     FILE    OUTFILE,CRCFILE,,CRCKLIST,$$$,BSIZE
  126. ;
  127. AGAIN:    LXI    SP,STACK ;RE-INIT STACK POINTER
  128.     CALL    MFNAME    ;SEARCH FOR NAMES
  129.     JNC    NAMTST    ;ANOTHER FOUND, PRINT NAME
  130.     LDA    MFFLG1    ;NOTHING FOUND, CHECK...
  131.     ORA    A    ;... FIRST TIME FLAG
  132.     JZ    DONE    ;AT LEAST ONE WAS FOUND
  133.     CALL    ABEXIT    ;PRINT MSG, THEN EXIT
  134.     DB    '++FILE NOT FOUND++$'
  135. ;
  136. DONE:    LDA    FFLAG    ;SEE IF WE'RE MAKING FILE
  137.     CPI    'F'
  138.     JNZ    DONE2    ;NO, SKIP THE FILE STUFF
  139. ;
  140. ;Close CRCKLIST.$$$
  141.     FINIS    CRCFILE
  142. ;
  143. ;Build FCB for final name of CRCKLIST.CRC
  144.     FILE    SETFILE,FINAL,,CRCKLIST,CRC
  145. ;
  146. ;Erase any existing old file
  147.     ERASE    FINAL
  148. ;
  149. ;Rename CRCKLIST.$$$ to CRCKLIST.CRC
  150.     RENAME    FINAL,CRCFILE
  151. ;
  152. ;Now exit to CP/M
  153. DONE2:    CALL    MSGEXIT    ;PRINT DONE, THEN EXIT
  154.     DB    CR,LF,'DONE$'
  155. ;
  156. ;Test for names to ignore
  157. ;
  158. NAMTST:    IF    NOSYS
  159.     LDA    FCB+10    ;GET SYS ATTRIBUTE
  160.     ANI    80H    ;IS IT SYS?
  161.     JNZ    AGAIN    ;YES, IGNORE THIS FILE
  162.     ENDIF        ;NOSYS
  163. ;
  164. ;Ignore files with .$$$ filetype (they are usually
  165. ;zero-length and clutter up our display.  We also
  166. ;want to ignore our own CRCKLIST.$$$ temporary file).
  167. ;
  168.     LXI    H,FCB+9    ;POINT TO FILETYPE IN FCB
  169.     CALL    TSTBAD    ;CHECK FOR .$$$ FILES
  170.     JZ    AGAIN    ;IF ZERO FLAG, IGNORE THEM
  171. ;
  172. ;Move 8 characters from FCB+1 to FNAME
  173.     LXI    H,FCB+1
  174.     LXI    D,FNAME
  175.     LXI    B,8
  176.     CALL    MOVER
  177. ;Move 3 characters from FCB+9 to FNAME+9
  178.     LXI    H,FCB+9
  179.     LXI    D,FNAME+9
  180.     LXI    B,3
  181.     CALL    MOVER
  182. ;Now print filename.type
  183.     CALL    ILPRT    ;PRINT:
  184.     DB    CR,LF,'--> FILE:  '
  185. FNAME:    DB    'XXXXXXXX.XXX',TAB,TAB,'CRC = ',0
  186. ;
  187. ;Open the file
  188.     LXI    D,FCB
  189.     MVI    C,OPEN
  190.     CALL    BDOS
  191.     INR    A
  192.     JNZ    RDINIT
  193.     CALL    ABEXIT
  194.     DB    '++OPEN FAILED++$'
  195. ;
  196. ;Initialize CRC to zero and set BUFAD to cause initial read
  197. RDINIT:    LXI    H,0
  198.     SHLD    REM    ;INIT REMAINDER TO ZERO
  199.     LXI    H,BASE+100H
  200.     SHLD    BUFAD    ;INIT BUFFER ADRS
  201. ;
  202. ;This is the read loop
  203. READIT:    LHLD    BUFAD
  204.     MOV    A,H    ;TIME TO READ?
  205.     CPI    BASE SHR 8
  206.     JZ    NORD    ;NO READ
  207.     MVI    C,CSTAT
  208.     CALL    BDOS    ;CHECK FOR OPERATOR ABORT
  209.     ORA    A
  210.     JZ    READ2    ;NOTHING FROM OPERATOR
  211.     MVI    C,RDCON
  212.     CALL    BDOS    ;GET CHARACTER INPUTTED
  213.     CPI    'C'-40H    ;CONTROL C?
  214.     JZ    ABEXT2    ;YES EXIT
  215. ;
  216. READ2:    LXI    D,FCB
  217.     MVI    C,READ    ;READ ANOTHER SECTOR OF FILE
  218.     CALL    BDOS
  219.     ORA    A    ;CHECK RETURN CODE
  220.     JNZ    FINISH    ;ERROR OR EOF
  221.     LXI    H,BASE+80H ;BUFFER LOCATION
  222. ;
  223. NORD:    MOV    A,M    ;GET FILE CHARACTER
  224.     STA    MESS    ;SAVE FOR DIVP
  225.     INX    H
  226.     SHLD    BUFAD    ;UPDATE BUFFER ADR
  227.     CALL    DIVP    ;CALCULATE NEW CRC
  228.     JMP    READIT    ;GO READ MORE CHARACTERS
  229. ;
  230. FINISH:    CPI    1    ;NORMAL END-OF-FILE?
  231.     JNZ    FILERR    ;NO, IT WAS A READ ERROR
  232.     LDA    REM+1    ;GET MSP OF CRC
  233.     CALL    HEXO    ;PRINT IT
  234.     MVI    A,' '
  235.     CALL    TYPE    ;TYPE A SPACE
  236.     LDA    REM    ;GET LSP OF CRC
  237.     CALL    HEXO    ;PRINT IT
  238.     CALL    CRLF    ;TURN UP NEW LINE
  239.     JMP    AGAIN    ;SEE IF MORE FILES TO DO
  240. ;
  241. FILERR:    CALL    ABEXIT    ;ABORT BECAUSE OF FILE READ ERROR
  242.     DB    '++FILE READ ERROR++$'
  243. ;
  244. ;---------------------------------------------
  245. ;An 8080 routine for generating a CYCLIC-
  246. ;REDUNDANCY-CHECK.  Character leaves that
  247. ;character in location REM.  By Fred Gutman.
  248. ;From 'EDN' magazine, June 5, 1979 issue, page 84.
  249. ;
  250. DIVP:    LHLD    REM    ;GET REMAINDER
  251.     MOV    A,H
  252.     ANI    128    ;Q-BIT MASK
  253.     PUSH    PSW    ;SAVE STATUS
  254.     DAD    H    ;2 X R(X)
  255.     LDA    MESS    ;MESSAGE BIT IN LSB
  256.     ADD    L
  257.     MOV    L,A
  258.     POP    PSW
  259.     JZ    QB2    ;IF Q-BIT IS ZERO
  260. ;
  261. QB:    MOV    A,H
  262.     XRI    0A0H    ;MS HALF OF GEN. POLY
  263.     MOV    H,A
  264.     MOV    A,L
  265.     XRI    97H    ;LS HALF OF GEN. POLY
  266.     MOV    L,A
  267. ;
  268. QB2:    SHLD    REM
  269.     RET
  270. ;--------------------------------------------
  271. ;
  272. ;Hex output
  273. ;
  274. HEXO:    PUSH    PSW    ;SAVE FOR RIGHT DIGIT
  275.     RAR        ;RIGHT..
  276.     RAR        ;..JUSTIFY..
  277.     RAR        ;..LEFT..
  278.     RAR        ;..DIGIT..
  279.     CALL    NIBBL    ;PRINT LEFT DIGIT
  280.     POP    PSW    ;RESTORE RIGHT
  281. ;
  282. NIBBL:    ANI    0FH    ;ISOLATE DIGIT
  283.     CPI    10    ;IS IS <10?
  284.     JC    ISNUM    ;YES, NOT ALPHA
  285.     ADI    7    ;ADD ALPHA BIAS
  286. ;
  287. ISNUM:    ADI    '0'    ;MAKE PRINTABLE
  288.     JMP    TYPE    ;PRINT IT, THEN RETURN
  289. ;
  290. ;Inline print routine
  291. ;
  292. ILPRT:    XTHL        ;SAVE HL, GET MSG
  293. ;
  294. ILPLP:    MOV    A,M    ;GET CHAR
  295.     CALL    TYPE    ;OUTPUT IT
  296.     INX    H    ;POINT TO NEXT
  297.     MOV    A,M    ;TEST
  298.     ORA    A    ;..FOR END
  299.     JNZ    ILPLP
  300.     XTHL        ;RESTORE HL, RET ADDR
  301.     RET        ;RET PAST MSG
  302. ;
  303. ;Send carriage return, line feed to output
  304. ;
  305. CRLF:    MVI    A,CR    ;CARRIAGE RETURN
  306.     CALL    TYPE
  307.     MVI    A,LF    ;LINE FEED, FALL INTO 'TYPE'
  308. ;
  309. ;Send character in A register to output
  310. ;
  311. TYPE:    PUSH    B
  312.     PUSH    D
  313.     PUSH    H
  314.     ANI    7FH    ;STRIP PARITY BIT
  315.     MOV    E,A
  316.     PUSH    D
  317.     CALL    WRFILE    ;WRITE TO FILE IF REQUESTED
  318.     POP    D
  319.     MVI    C,WRCON    ;SEND CHARACTER TO CONSOLE
  320.     CALL    BDOS
  321.     POP    H
  322.     POP    D
  323.     POP    B
  324.     RET
  325. ;
  326. ;Write character in E register to output file
  327. ;
  328. WRFILE:    LDA    FFLAG    ;GET FILE TRIGGER
  329.     CPI    'F'    ;IS IT SET?
  330.     RNZ        ;NO, RETURN
  331.     MOV    A,E    ;GET CHARACTER BACK
  332.     PUT    CRCFILE ;SEND IT TO THE FILE
  333.     RET
  334. ;
  335. ;Multi-file access subroutine.  Allows processing
  336. ;of multiple files (i.e. *.ASM) from disk.  This
  337. ;routine builds the proper name in the FCB each
  338. ;time it is called. Carry is set if no more names
  339. ;can be found. The routine is commented in Pseudo
  340. ;code, each Pseudo code statement is in <<...>>
  341. ;
  342. MFNAME:    ;<<init DMA addr and FCB>>
  343.     MVI    C,STDMA
  344.     LXI    D,BASE+80H
  345.     CALL    BDOS
  346.     XRA    A
  347.     STA    FCBEXT
  348.     STA    FCBRNO
  349. ;<<if first time>>
  350.     LDA    MFFLG1
  351.     ORA    A
  352.     JZ    MFN01
  353. ;<<save the requested name>>
  354. ;Save orig request
  355.     LXI    H,FCB
  356.     LXI    D,MFREQ
  357.     LXI    B,12
  358.     CALL    MOVER
  359.     LDA    FCB
  360.     STA    MFCUR    ;SAVE DISK IN CURR FCB
  361. ;<<SRCHF requested name>>
  362.     LXI    H,MFREQ
  363.     LXI    D,FCB
  364.     LXI    B,12
  365.     CALL    MOVER
  366.     MVI    C,SRCHF
  367.     LXI    D,FCB
  368.     CALL    BDOS
  369. ;<<else>>
  370.     JMP    MFN02
  371. ;
  372. MFN01:    ;<<SRCHF current name>>
  373.     LXI    H,MFCUR
  374.     LXI    D,FCB
  375.     LXI    B,12
  376.     CALL    MOVER
  377.     MVI    C,SRCHF
  378.     LXI    D,FCB
  379.     CALL    BDOS
  380. ;<<SRCHN requested name>>
  381.     LXI    H,MFREQ
  382.     LXI    D,FCB
  383.     LXI    B,12
  384.     CALL    MOVER
  385.     MVI    C,SRCHN
  386.     LXI    D,FCB
  387.     CALL    BDOS
  388. ;<<endif>>
  389. MFN02:    ;<<return carry if not found>>
  390.     INR    A
  391.     STC
  392.     RZ
  393. ;<<move name found to current name>>
  394.     DCR    A
  395.     ANI    3
  396.     ADD    A
  397.     ADD    A
  398.     ADD    A
  399.     ADD    A
  400.     ADD    A
  401.     ADI    81H
  402.     MOV    L,A
  403.     MVI    H,BASE SHR 8
  404.     PUSH    H    ;SAVE NAME POINTER
  405.     LXI    D,MFCUR+1
  406.     LXI    B,11
  407.     CALL    MOVER
  408. ;<<move name found to FCB>>
  409.     POP    H
  410.     LXI    D,FCB+1
  411.     LXI    B,11
  412.     CALL    MOVER
  413. ;<<setup FCB>>
  414.     XRA    A
  415.     STA    FCBEXT
  416.     STA    FCBRNO
  417.     STA    MFFLG1    ;TURN OFF 1ST TIME SW
  418. ;<<return>>
  419.     RET
  420. ;------------------------------------------------
  421. ;
  422. ;Check for .$$$ files
  423. ;
  424. TSTBAD:    CALL    TESTIT    ;CHECK FIRST ONE FOR '$'
  425.     RNZ        ;NO, RETURN
  426.     CALL    TESTIT    ;CHECK SECOND ONE
  427.     RNZ        ;NO, RETURN
  428.             ;FALL INTO TESTIT TO CHECK THIRD
  429. ;
  430. TESTIT:    MOV    A,M
  431.     ANI    7FH    ;STRIP ATTRIBUTE
  432.     CPI    '$'    ;CHECK FOR $ FILETYPE
  433.     INX    H
  434.     RET
  435. ;
  436. ;Move (BC) bytes from (HL) to (DE)
  437. ;
  438. MOVER:    MOV    A,M
  439.     STAX    D
  440.     INX    H
  441.     INX    D
  442.     DCX    B
  443.     MOV    A,B
  444.     ORA    C
  445.     JNZ    MOVER
  446.     RET
  447. ;
  448. ;Aborted - print reason.  If making output file,
  449. ;close the incomplete file to update CP/M's bit map,
  450. ;then erase it.
  451. ;
  452. ABEXIT:    POP    D    ;GET MSG ADRS
  453.     MVI    C,PRINT
  454.     CALL    BDOS    ;PRINT MSG
  455. ;
  456. ABEXT2:    LDA    FFLAG    ;SEE IF WE ARE MAKING FILE
  457.     CPI    'F'
  458.     JNZ    ABEXT3    ;NO FILE, SKIP FILE STUFF
  459.     FINIS    CRCFILE    ;CLOSE INCOMPLETE FILE
  460.     ERASE    CRCFILE    ;ERASE INCOMPLETE FILE
  461. ;
  462. ABEXT3:    CALL    ERXIT    ;PRINT MSG, EXIT
  463.     DB    CR,LF,CR,LF,'++ABORTED++$'
  464. ;
  465. ;Exit with message
  466. ;
  467. MSGEXIT:EQU    $    ;EXIT W/"INFORMATIONAL" MSG
  468. ERXIT:    POP    D    ;GET MSG
  469.     MVI    C,PRINT
  470.     CALL    BDOS
  471. ;
  472. ;Exit, restoring stack and return to CCP
  473. ;
  474. EXIT:    LHLD    STACK
  475.     SPHL
  476.     RET        ;TO CCP
  477. ;
  478. ;Program storage area
  479. ;
  480. FFLAG:    DB    0    ;FILE WRITE REQUEST FLAG
  481. REM:    DW    0    ;CRC REMAINDER STORAGE
  482. MESS:    DB    0    ;CRC MESSAGE CHAR GOES HERE
  483. MFFLG1:    DB    1    ;1ST TIME SWITCH
  484. MFREQ:    DS    12    ;REQUESTED NAME
  485. MFCUR:    DS    12    ;CURRENT NAME
  486. BUFAD:    DS    2    ;READ BUFFER ADDRESS
  487.     DS    60    ;STACK AREA
  488. STACK:    EQU    $
  489. OLDSTK:    DS    2    ;OLD STACK POINTER SAVED HERE
  490. ;
  491. ;Define location of file write buffer
  492. BUFFERS:EQU    $
  493. ;
  494.     END    CRCK
  495.