home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / filutl / crck44.lbr / CRCK44.AQM / CRCK44.ASM
Assembly Source File  |  1985-06-13  |  18KB  |  887 lines

  1. ; CRCK v4.4         CYCLIC REDUNDANCY CHECK               10/17/82
  2. ;
  3. ;                               by
  4. ;
  5. ;                   KEITH B. PETERSEN, W8SDZ
  6. ;
  7. ;
  8. ; NOTE TO SYSOPS:   SET FILEOK: AND SYSOK: (0103 AND 0104) BOTH TO '0'
  9. ;                   TO PREVENT REMOTE USERS FROM CREATING A FILE OR TO
  10. ;                   FIND RESTRICTED '.SYS' FILES.
  11. ;
  12. ; *     *     *     *     *     *     *     *     *     *     *     *
  13. ;
  14. ; 10/17/82 v4.4  -  Made buffer size automatic to make all transient
  15. ;                   area memory available for the disk file.  Should
  16. ;                   handle the largest Winchester disk directory.
  17. ;                   Modest changes for appearance.         - Irv Hoff
  18. ;
  19. ; 08/17/82 v4.3  -  Removed need for SEQIO.LIB so can now assemble with
  20. ;                   'ASM.COM' or other assemblers.  Used some of Kelly
  21. ;                   Smith' previous work to help in removing SEQIO.LIB.
  22. ;                                                          - Irv Hoff
  23. ;
  24. ; 06/03/82 v4.2B -  Added 2 RCPM aids:  Patch location label 'FILEOK' to
  25. ;                   FALSE (zero) to disallow CRC output file.  Patch
  26. ;                   label 'SYSOK' to FALSE (zero) to treat '.SYS' files
  27. ;                   the same as "NO FILE FOUND" to help hide them from
  28. ;                   those phoning in.  Previous version said 'DONE' with
  29. ;                   no report if '.SYS' or '.$$$' files were skipped. If
  30. ;                   you want to know what is there, patch the label or
  31. ;                   use 'STAT'.  
  32. ;                                 FILEOK = 0103H
  33. ;                                 SYSOK  = 0104H
  34. ;
  35. ; 04/02/82 v4.2A -  Make serially re-entrant to allow ZCPR "GO" again.
  36. ;                   Remove exta CR-LF to get mre CRC's on screen at one
  37. ;                   time.  Use name specified in 2nd FCB with '.CRC'
  38. ;                   extension instead of CRCKLIST.CRC for more operator
  39. ;                   convenience.
  40. ;
  41. ;
  42. ; 10/06/80 v4.2  -  Fix to erase temporary file when output flie is re-
  43. ;                   quested and name not found in directory.
  44. ;
  45. ; 06/27/79 v4.2  -  Written by Keith B. Petersen, W8SDZ
  46. ;
  47. ;
  48. ; *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
  49. ;
  50. ;
  51. ; CRCK can read any CP/M file then print a CRC (CYCLIC-REDUNDANCY-CHECK)
  52. ; number based on the CCITT standard polynominal:
  53. ;
  54. ;           X^16 + X^15 + X^13 + X^7 + X^4 + X^2 + X + 1
  55. ;
  56. ; Useful for checking accuracy of file transfers. More accurate than a
  57. ; simple checksum.  It will Optionally write an output file to the de-
  58. ; fault drive, listing the CRC's of all files requested.
  59. ;
  60. ;
  61. ; COMMANDS:  CRCK [drive:]<filename.filetype> [F]
  62. ;
  63. ; Examples:
  64. ;            CRCK B:HELLO.ASM    check only HELLO.ASM
  65. ;            CRCK *.ASM          check all .ASM  files
  66. ;            CRCK *.* FILE       check all files, make disk
  67. ;                                  file (FILE.CRC) of results
  68. ;                                  (use any file name desired)
  69. ;
  70. ; *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
  71. ;
  72. ;
  73. ; DEFINE TRUE AND FALSE
  74. ;
  75. FALSE    EQU    0
  76. TRUE    EQU    NOT FALSE
  77. ;
  78. ;
  79. ; CONDITIONAL ASSEMBLY SWITCHES
  80. ;
  81. STDCPM    EQU    TRUE        ;TRUE FOR STANDARD CP/M
  82. ALTCPM    EQU    FALSE        ;TRUE FOR H8 OR TRS-80
  83. ;
  84. ;
  85. ; SYSTEM EQUATES
  86. ;
  87. BASE    SET    0        ;FOR STANDARD CP/M USERS
  88. ;
  89.     IF    ALTCPM        ;FOR H8 OR TRS-80
  90. BASE    SET    4200H
  91.     ENDIF
  92. ;
  93. ; BDOS EUATES
  94. RDCON    EQU    1
  95. WRCON    EQU    2
  96. PRINT    EQU    9
  97. CSTAT    EQU    11
  98. OPEN    EQU    15
  99. CLOSE    EQU    16
  100. SRCHF    EQU    17
  101. SRCHN    EQU    18
  102. DELET    EQU    19
  103. READ    EQU    20
  104. WRITE    EQU    21
  105. MAKE    EQU    22
  106. RENAM    EQU    23
  107. STDMA    EQU    26
  108. ;
  109. ;
  110. ; FILE HANDLING EQUATES
  111. ;
  112. BUF$SIZ    EQU    80H        ;BUFFER SIZE (128 BYTES)
  113. BDOS    EQU    BASE+5
  114. FCB    EQU    BASE+5CH 
  115. FCB2    EQU    BASE+6CH
  116. FCBEXT    EQU    FCB+12
  117. FCBRNO    EQU    FCB+32
  118. TBUF    EQU    BASE+80H    ;TEMPORARY BUFFER (DEFAULT) ADDRESS
  119. ;
  120. ;
  121. ; CONTROL CHARACTERS
  122. ;
  123. CTLC    EQU    'C'-40H        ;CONTROL-C CHARACTER
  124. EOF    EQU    'Z'-40H        ;END-OF-FILE CHARACTER
  125. LF    EQU    'J'-40H        ;LINE FEED CHARACTER
  126. CR    EQU    'M'-40H        ;CARRIAGE RETURN CHARACTER
  127. TAB    EQU    'I'-40H        ;TAB CHARACTER
  128. ;
  129. ;
  130. ; *   *   *   *   *   *   *   *   *   *   *   *  *   *   *   *   *   *
  131. ;
  132. ;
  133.     ORG    BASE+100H
  134. ;
  135. ;
  136. CRCK:    JMP    BEGIN        ;JUMP AROUND PATCH PARAMETERS
  137. ;
  138. ;
  139. FILEOK:    DB    1    ;0 = No, 1 = Yes  TO ALLOW DISK FILE OF RESULTS
  140. SYSOK:    DB    1    ;0 = No, 1 = Yes  TO ALLOW HANDLING '.SYS' FILES
  141. SOM:    DB    CR,LF,'CRCK version 4.4 of 10/17/82'
  142.         DB    CR,LF,'(Ctl-C aborts, Ctl-S pauses)',CR,LF,LF,'$'
  143. ;
  144. ;
  145. ;***********************************************************************
  146. ;                                                                      ;
  147. ;                     PROGRAM STARTS HERE                              ;
  148. ;                                                                      ;
  149. ;***********************************************************************
  150. ;
  151. ;
  152. BEGIN:    LXI    H,0        ;GET STACK...
  153.     DAD    SP        ;POINTER SO WE CAN...
  154.     SHLD    STACK        ;SAVE IT
  155.     LXI    SP,STACK    ;INITIALIZE LOCAL STACK
  156.     MVI    A,1
  157.     STA    MFFLG1        ;INIT 1ST TIME SWITCH
  158.     STA    FOUND        ;NO FILES FOUND YET
  159.     MVI    A,' '        ;NO OUTPUT FILE YET
  160.     STA    FFLAG
  161.     LXI    D,SOM        ;PRINT SIGNON MESSAGE
  162.     MVI    C,PRINT
  163.     CALL    BDOS
  164.     LDA    FCB+1
  165.     CPI    ' '        ;SEE IF NAME THERE
  166.     JNZ    BEGIN2        ;YES, CONTINUE
  167. ;
  168.     CALL    ERXIT        ;PRINT MSG, THEN EXIT
  169. ;
  170.     DB    CR,LF,LF,TAB,'++No file name specified++'
  171.     DB    CR,LF,LF,LF,LF,TAB
  172.     DB    'COMMANDS:  CRCK [drive:]<filename.filetye> FILE'
  173.     DB    CR,LF,LF,LF,TAB
  174.     DB    'Examples:  CRCK B:HELLO.ASM     check only HELLO.ASM'
  175.     DB    CR,LF,TAB,TAB
  176.     DB    '   CRCK *.ASM           check only .ASM files'
  177.     DB    CR,LF,TAB,TAB
  178.     DB    '   CRCK *.* FILE        check all files, make disk'
  179.     DB    CR,LF,TAB,TAB
  180.     DB    '                          file (FILE.CRC) of results'
  181.     DB    CR,LF,TAB,TAB
  182.     DB    '                          (use any file name desired)'
  183.     DB    CR,LF,LF,LF,LF,LF,'$'
  184. ;
  185. ;
  186. ; FIND AMOUNT OF SPACE FOR BUFFER
  187. ;
  188. BEGIN2:    LXI    D,FILEADR    ;START OF BUFFER ADDRESS
  189.     LDA    BDOS+2        ;GET 'BDOS' ADDRESS
  190.     SUI    8        ;PROTECT 'CCP'
  191.     MOV    H,A        ;GET THE MAIN PAGE
  192.     XRA    A        ;CLEAR CARRY IF SET
  193. ;
  194. ;
  195. ; CALCULATE THE DIFFERENCE TO GET SPACE AVAILABLE
  196. ;
  197.     SUB    E
  198.     MOV    L,A
  199. ;
  200.     MOV    A,H
  201.     SBB    D
  202.     MOV    H,A
  203. ;
  204. ;
  205. ; FREE SPACE AVAILABLE NOW IN 'HL', SO STORE FOR BUFFER SIZE
  206. ;
  207.     SHLD    FILELEN        ;STORE BUFFER LENGTH
  208. ;
  209. ;
  210. ; DECLARE 'FCB' FOR  OUTPUT FILE (TEMPORARILY NAMED CRCKLIST.$$$)
  211. ;
  212.     LDA    FILEOK        ;OK TO MAKE A '.CRC' DISK FILE?
  213.     ORA    A
  214.     JZ    AGAIN        ;EXIT, IF NOT
  215. ;
  216.     LDA    FCB2+1        ;GET OPTION
  217.     STA    FFLAG        ;SAVE IT FOR LATER
  218.     CPI    ' '        ;FILE WANTED?
  219.     JZ    AGAIN        ;NO, SKIP FILE INITIALIZATION
  220. ;
  221. ;
  222.     XRA    A
  223.     STA    FCBFILE+12    ;CLEAR EXTENT
  224.     STA    FCBFILE+32    ;CLEAR CURRENT RECORD COUNT
  225.     LXI    H,0
  226.     SHLD    FILEPTR        ;RESET FILE POINTERS
  227.     MVI    C,DELET        ;'DELETE FILE' FUNCTION
  228.     LXI    D,FCBFILE    ;DELETE 'OLD' CRCKLIST FILE
  229.     CALL    BDOS
  230.     MVI    C,MAKE        ;'MAKE FILE' FUNCTON
  231.     LXI    D,FCBFILE    ;MAKE 'NEW' CRCKLIST FILE
  232.     CALL    BDOS
  233.     INR    A        ;MAKE THE NEW FILE OK?
  234.     JNZ    COPYNAME    ;COPY THE FILE NAME REQUESTED
  235. ;
  236.     MVI    C,PRINT        ;PRINT STRING FUNCTION
  237.     LXI    D,DIR$FULL    ;INDICATE THAT DIRECTORY IS FULL
  238.     CALL    BDOS
  239.     JMP    FILERR
  240. ;...
  241. ;
  242. ;
  243. COPYNAME:
  244.     LXI    H,FCB2
  245.     LXI    D,FCBFINAL
  246.     MVI    C,9        ;FILENAME IS 8 CHAR. PLUS .
  247. ;
  248. COPYNAME1:
  249.     MOV    A,M
  250.     STAX    D
  251.     INX    H
  252.     INX    D
  253.     DCR    C
  254.     JNZ    COPYNAME1
  255. ;...
  256. AGAIN:    LXI    SP,STACK    ;RE-INIT STACK POINTER
  257.     CALL    MFNAME        ;SEARCH FOR NAMES
  258.     JNC    NAMTST        ;ANOTHER FOUND, PRINT NAME
  259.     LDA    FOUND        ;NOTHING FOUND, CHECK...
  260.     ORA    A        ;... FIRST TIME FLAG
  261.     JZ    DONE        ;AT LEAST ONE WAS FOUND
  262.     CALL    ABEXIT        ;PRINT MSG, THEN EXIT
  263.     DB    '++File(s) not found++$'
  264. DONE:    LDA    FFLAG        ;MAKING A '.CRC' DISK FILE?
  265.     CPI    ' '
  266.     JZ    DONE2        ;NO, SKIP THE FILE STUFF
  267. ;
  268. ;
  269. ; CLOSE CRCKLIST.$$$
  270. ;
  271. CLOSEFILE:
  272.     LHLD    FILEPTR
  273.     MOV    A,L
  274.      ANI    07FH
  275.     JNZ    CLOSEFILE1
  276. ;
  277.     SHLD    FILELEN
  278. ;
  279. CLOSEFILE1:
  280.     MVI    A,EOF
  281.     PUSH    PSW
  282.     CALL    PUTFILE
  283.     POP    PSW
  284.     JNZ    CLOSEFILE
  285. ;
  286.     MVI    C,CLOSE
  287.     LXI    D,FCBFILE
  288.     CALL    BDOS
  289.     INR    A
  290.     JNZ    ERASE
  291. ;
  292.     MVI    C,PRINT
  293.     LXI    D,NO$CLOSE
  294.     CALL    BDOS
  295. ;
  296. ;
  297. ; ERASE ANY EXISTING OLD FILE
  298. ;
  299. ERASE:    MVI    C,DELET
  300.     LXI    D,FCBFINAL
  301.     CALL    BDOS
  302. ;
  303. ; RENAME CRCKLIST.$$$ TO CRCKLIST.CRC
  304. ;
  305.     LXI    H,FCBFILE
  306.     LXI    D,FCBFINAL
  307.     PUSH    H
  308.     LXI    B,16
  309.     DAD    B
  310. ;
  311. MOV$NAME:
  312.     LDAX    D
  313.     MOV    M,A
  314.     INX    D
  315.      INX    H
  316.     DCR    C
  317.     JNZ    MOV$NAME
  318.     POP    D
  319.     MVI    C,RENAM
  320.     CALL    BDOS
  321. ;
  322. ; NOW EXIT TO CP/M
  323. ;
  324. DONE2:    CALL    MSGEXIT        ;PRINT 'DONE' THEN EXIT
  325.     DB    CR,LF,'Done',CR,LF,'$'
  326. ;.....
  327. ;
  328. ; TEST FOR NAMES TO IGNORE
  329. NAMTST:    LDA    SYSOK        ;SEE IF '.SYS' FILES ALLOWED
  330.     ORA    A
  331.     JNZ    DOSYS        ;IF ALLOWED, EXIT
  332. ;
  333.     LDA    FCB+10        ;GET 'SYS' ATTRIBUTE
  334.     ANI    80H        ;IS IT 'SYS'?
  335.     JNZ    AGAIN        ;YES, IGNORE THIS FILE
  336. ;
  337. ;
  338. ; IGNORE FILES WITH .$$$ FILETYPE (THEY ARE USUALLY ZERO-LENGTH AND
  339. ; CLUTTER UP OUR DISPLAY.  WE ALSO WANT TO IGNORE OUR CRCKLIST.$$$
  340. ; TEMPORARY FILE).
  341. DOSYS:    LXI    H,FCB+9        ;POINT TO FILETYPE IN 'FCB'
  342.     CALL    TSTBAD        ;CHECK FOR .$$$ FILES
  343.     JZ    AGAIN        ;IF ZERO FLAG, IGNORE THEM
  344. ;
  345.     XRA    A        ;FOUND SOME NAMES
  346.     STA    FOUND
  347. ;
  348. ;
  349. ; MOVE 8 CHARACTERS FROM FCB+1 TO FNAME
  350. ;
  351.     LXI    H,FCB+1
  352.     LXI    D,FNAME
  353.     LXI    B,8
  354.     CALL    MOVER
  355. ;
  356. ;
  357. ; MOVE 3 CHARACTERS FROM FCB+9 TO FNAME+9
  358. ;
  359.     LXI    H,FCB+9
  360.     LXI    D,FNAME+9
  361.     LXI    B,3
  362.     CALL    MOVER
  363. ;
  364. ;
  365. ; NOW PRINT FILENAME.TYPE
  366. ;
  367.     CALL    ILPRT        ; PRINT:
  368. ;
  369.         DB    '---> '
  370. FNAME:    DB    'XXXXXXXX.XXX     CRC  =  ',0
  371. ;
  372. ;
  373. ; OPEN THE FILE
  374. ;
  375.     LXI    D,FCB
  376.     MVI    C,OPEN
  377.     CALL    BDOS
  378.     INR    A
  379.     JNZ    RDINIT
  380. ;
  381.     CALL    ABEXIT
  382.     DB    '++OPEN FAILED++$'
  383. ;
  384. ; INITIALIZE 'CRC' TO ZERO AND SET 'BUFAD' TO CAUSE INITIAL READ
  385. ;
  386. RDINIT:    LXI    H,0
  387.      SHLD    REM        ;INIT REMAINDER TO ZERO
  388.     LXI    H,BASE+100H
  389.     SHLD    BUFAD        ;INIT BUFFER ADRS
  390. ;
  391. ;
  392. ; THIS IS THE READ LOOP
  393. ;
  394. READIT:    LHLD    BUFAD
  395.     MOV    A,H        ;TIME TO READ?
  396.     CPI    BASE SHR 8
  397.     JZ    NORD        ;NO READ
  398.     MVI    C,CSTAT
  399.     CALL    BDOS        ;CHECK FOR OPERATOR ABORT
  400.     ORA    A
  401.     JZ    READ2        ;NOTHING TO READ, EXIT
  402. ;
  403.     MVI    C,RDCON
  404.     CALL    BDOS        ;GET CHARACTER INPUTTED
  405.     CPI    CTLC        ;CONTROL-C?
  406.     JZ    ABEXT2        ;YES EXIT
  407. ;
  408. READ2:    LXI    D,FCB
  409.     MVI    C,READ        ;READ ANOTHER SECTOR OF FILE
  410.     CALL    BDOS
  411.     ORA    A        ;CHECK RETURN CODE
  412.     JNZ    FINISH        ;ERROR OR 'EOF'
  413.     LXI    H,TBUF        ;BUFFER LOCATION
  414. ;
  415. NORD:    MOV    A,M        ;GET FILE CHARACTER
  416.     STA    MESS        ;SAVE FOR 'DIVP'
  417.     INX    H
  418.     SHLD    BUFAD
  419.     CALL    DIVP        ;CALCULATE NEW 'CRC'
  420.     JMP    READIT        ;GO READ MORE CHARACTERS
  421. ;.....
  422. ;
  423. ;
  424. FINISH:    CPI    1        ;NORMAL END-OF-FILE?
  425.     JNZ    FILERR        ;NO, IT WAS A READ ERROR
  426. ;
  427.     LDA    REM+1        ;GET MSP OF 'CRC'
  428.     CALL    HEXO        ;PRINT IT
  429.     MVI    A,' '        ;SEPARATE 'LSP' AND 'LST'
  430.     CALL    TYPE
  431.     LDA    REM        ;GET 'LSP' OF 'CRC'
  432.     CALL    HEXO        ;PRINT IT
  433.     CALL    CRLF        ;TURN UP NEW LINE
  434.     JMP    AGAIN        ;SEE IF MORE FILES TO DO
  435. ;.....
  436. ;
  437. FILERR:    CALL    ABEXIT        ; ABORT BECAUSE OF FILE READ ERROR
  438.     DB    '++File read error++$'
  439. ;.....
  440. ;
  441. ;
  442. ; 8080 ROUTINE FOR GENERATING A CYCLIC-REDUNDANCY-CHECK.  CHARACTER
  443. ; LEAVES THAT CHARACTER IN LOCATION 'REM'.  BY FRED GUTMAN.  FROM
  444. ; 'EDN' MAGAZINE, 5 JUNE 1979, PAGE 84.
  445. ;
  446. DIVP:    LHLD    REM        ;GET REMAINDER
  447.     MOV    A,H
  448.     ANI    128        ;Q-BIT MASK
  449.     PUSH    PSW        ;SAVE STATUS
  450.     DAD    H        ;2 * R(X)
  451.     LDA    MESS        ;MESSAGE BIT IN 'LSB'
  452.     ADD    L
  453.     MOV    L,A
  454.     POP    PSW
  455.     JZ    QB2        ;IF Q-BIT IS ZERO
  456. ;
  457. QB:    MOV    A,H
  458.     XRI    0A0H        ;'MS' HALF OF GENERAL POLYNOMINAL
  459.     MOV    H,A
  460.     MOV    A,L
  461.     XRI    97H        ;'LS' HALF OF GENERAL POLYNOMINAL
  462.     MOV    L,A
  463. ;
  464. QB2:    SHLD    REM
  465.     RET
  466. ;.....
  467. ;
  468. ; HEX OUTPUT
  469. HEXO:    PUSH    PSW        ;SAVE FOR RIGHT DIGIT
  470.     RAR            ;RIGHT..
  471.     RAR            ;..JUSTIFY..
  472.     RAR            ;..LEFT..
  473.     RAR            ;..DIGIT..
  474.     CALL    NIBBL        ;PRINT LEFT DIGIT
  475.     POP    PSW        ;RESTORE RIGHT
  476. NIBBL:    ANI    0FH        ;ISOLATE DIGIT
  477.     CPI    10        ;IS IS LESS THAN 10?
  478.     JC    ISNUM        ;YES, NOT ALPHA
  479.     ADI    7        ;ADD ALPHA BIAS
  480. ISNUM:    ADI    '0'        ;CONVERT FROM BINARY TO ASCII
  481.     JMP    TYPE        ;PRINT IT, THEN RETURN
  482. ;.....
  483. ;
  484. ;
  485. ; INLINE PRINT ROUTINE
  486. ;
  487. ILPRT:    XTHL            ;SAVE 'HL', GET MSG
  488. ILPLP:    MOV    A,M        ;GET CHAR
  489.     CALL    TYPE        ;OUTPUT IT
  490.     INX    H        ;POINT TO NEXT
  491.     MOV    A,M        ;TEST
  492.     ORA    A        ;..FOR END
  493.     JNZ    ILPLP
  494.     XTHL            ;RESTORE 'HL', RETURN ADDRESS
  495.     RET            ;RETURN PAST MSG
  496. ;.....
  497. ;
  498. ;
  499. ; SEND CARRIAGE RETURN, LINE FEED TO OUTPUT
  500. ;
  501. CRLF:    MVI    A,CR        ;CARRIAGE RETURN
  502.     CALL    TYPE
  503.     MVI    A,LF        ;LINE FEED, FALL INTO 'TYPE'
  504. ;
  505. ;
  506. ; SEND CHARACTER IN 'A' REGISTER TO OUTPUT
  507. TYPE:    PUSH    B
  508.     PUSH    D
  509.     PUSH    H
  510.     ANI    7FH        ;STRIP OFF ANY PARITY
  511.     MOV    E,A
  512.     PUSH    D
  513.     CALL    WRFILE        ;WRITE TO FILE IF REQUESTED
  514.     POP    D
  515.     MVI    C,WRCON        ;SEND CHARACTER TO CONSOLE
  516.     CALL    BDOS
  517.     POP    H
  518.     POP    D
  519.     POP    B
  520.     RET
  521. ;.....
  522. ;
  523. ;
  524. PUTFILE:
  525.     PUSH    PSW        ;SAVE OUTPUT CHARACTER
  526.     LHLD    FILELEN        ;GET CURRENT BUFFER LENGTH
  527.     XCHG            ;'DE' HAS LENGTH
  528.     LHLD    FILEPTR        ;LOAD NEXT TO GET/PUT TO 'HL'
  529.     MOV    A,L        ;COMPUTE CURRENT LENGTH
  530.     SUB    E     
  531.     MOV    A,H
  532.     SBB    D        ;CARRY IF NEXT < LENGTH
  533.     JC    PUTCRC4        ;CARRY IF LENGTH > CURRENT
  534. ;
  535.     LXI    H,0        ;END OF BUFFER, FILL (EMPTY) BUFFERS    
  536.     SHLD    FILEPTR        ;CLEAR NEXT TO GET/PUT
  537. ;
  538. PUTCRC1:            ;PROCESS NEXT DISK SECTOR
  539.     XCHG            ;FILE POINTER TO 'DE'
  540.     LHLD    FILELEN        ;'HL' IS MAXIMUM BUFFER LENGTH
  541.     MOV    A,E        ;COMPUTE NEXT LENGTH
  542.     SUB    L        ;TO GET CARRY, IF MORE FILL
  543.     MOV    A,D
  544.     SBB    H        
  545.     JNC    PUTCRC3
  546.     LHLD    FILEADR        ;GOT CARRY, MORE TO FILL YET
  547.     DAD    D        ;HL IS NEXT BUFFER ADDRESS
  548.     XCHG
  549.     MVI    C,STDMA        ;SET 'DMA' ADDRESS
  550.     CALL    BDOS
  551.     LXI    D,FCBFILE    ;'FCB' ADDRESS TO 'DE'
  552.     MVI    C,WRITE        ;FILE WRITE
  553.     CALL    BDOS
  554.     ORA    A        ;CHECK RETURN CODE
  555.     JNZ    PUTCRC2        ;END-OF-FILE YET?
  556.     LXI    D,BUF$SIZ    ;NOT 'EOF', INCREMENT LENGTH BY 128
  557.     LHLD    FILEPTR        ;NEXT TO FILL
  558.     DAD    D
  559.     SHLD    FILEPTR        ;SAVE NEW POINTER
  560.     JMP    PUTCRC1        ;PROCESS ANOTHER SECTOR
  561. ;...
  562. ;
  563. ;
  564. PUTCRC2:            ;GOT END-OF-FILE
  565.     MVI    C,PRINT        ;PRINT STRING FUNCTION
  566.     LXI    D,DSK$FULL    ;DISK IS FULL
  567.     CALL    BDOS
  568.     POP    PSW        ;CLEAN STACK
  569.     JMP    FILERR        ;FILE ERROR, EXIT
  570. ;...
  571. ;
  572. ;
  573. PUTCRC3:            ;END OF BUFFER, RESET 'DMA' AND POINTER
  574.     LXI    D,TBUF        ;POINT TO TEMPORARY BUFFER
  575.     MVI    C,STDMA        ;SET 'DMA' FUNCTION
  576.     CALL    BDOS
  577.     LXI    H,0        ;RESET POINTER FOR NEXT TO GET
  578.     SHLD    FILEPTR
  579. ;
  580. PUTCRC4:            ;PROCESS THE NEXT CHARACTER
  581.     XCHG            ;INDEX TO GET/PUT IN 'DE'
  582.     LHLD    FILEADR        ;BASE OF BUFFER
  583.     DAD    D        ;ADDRESS OF CHARACTER IN 'HL'
  584.     XCHG            ;AND SWAP TO 'DE'
  585.     POP    PSW        ;GET SAVE CHARACTER
  586.     STAX    D        ;CHARACTER TO BUFFER
  587.     LHLD    FILEPTR        ;INDEX TO GET/PUT
  588.     INX    H        ;AND UPDATE FOR NEXT CHARACTER
  589.     SHLD    FILEPTR
  590.     RET
  591. ;.....
  592. ;
  593. ;
  594. ; WRITE CHARACTER IN 'E' REGISTER TO OUTPUT FILE
  595. ;
  596. WRFILE:    LDA    FFLAG        ;GET FILE TRIGGER
  597.     CPI    ' '        ;IS IT SET?
  598.     RZ            ;NO, RETURN
  599. ;
  600.     MOV    A,E        ;GET CHARACTER BACK
  601.     CALL    PUTFILE
  602.     RET
  603. ;.....
  604. ;
  605. ; MULTI-FILE ACCESS SUBROUTINE.  ALLOWS PROCESSING OF MULTIPLE FILES
  606. ; (I.E., *.ASM) FROM DISK.  THIS ROUTINE BUILDS THE PROPER NAME IN THE
  607. ; FCB EACH TIME IT IS CALLED.  CARRY IS SET IF NO MORE NAMES CAN BE
  608. ; FOUND.
  609. MFNAME:    MVI    C,STDMA        ;INIT 'DMA' ADDRESS AND 'FCB'
  610.     LXI    D,TBUF
  611.     CALL    BDOS
  612.     XRA    A
  613.     STA    FCBEXT
  614.     STA    FCBRNO
  615. ;
  616. ;
  617. ; IF FIRST TIME
  618. ;
  619.     LDA    MFFLG1
  620.     ORA    A
  621.     JZ    MFN01
  622. ;
  623. ;
  624. ; SAVE THE REQUESTED NAME - SAVE ORIGINAL REQUEST
  625. ;
  626.     LXI    H,FCB
  627.     LXI    D,MFREQ
  628.     LXI    B,12
  629.      CALL    MOVER
  630.     LDA    FCB
  631.     STA    MFCUR        ;SAVE DISK IN CURRENT 'FCB'
  632. ;
  633. ; SEARCH FOR THE FIRT REQUESTED NAME
  634. ;
  635.     LXI    H,MFREQ
  636.     LXI    D,FCB
  637.     LXI    B,12
  638.     CALL    MOVER
  639.     MVI    C,SRCHF        ;SEARCH FOR FIRST NAME
  640.     LXI    D,FCB
  641.     CALL    BDOS
  642. ;
  643. ;
  644. ; ELSE
  645. ;
  646.     JMP    MFN02
  647. MFN01:
  648.     LXI    H,MFCUR
  649.     LXI    D,FCB
  650.     LXI    B,12
  651.     CALL    MOVER
  652.     MVI    C,SRCHF        ;SEARCH FOR FIRST NAME
  653.     LXI    D,FCB
  654.     CALL    BDOS
  655. ;
  656. ;
  657. ; SEARCH FOR NEXT REQUESTED NAME
  658. ;
  659.     LXI    H,MFREQ
  660.     LXI    D,FCB
  661.     LXI    B,12
  662.     CALL    MOVER
  663.     MVI    C,SRCHN        ;SEARCH FOR NEXT NAME
  664.     LXI    D,FCB
  665.     CALL    BDOS
  666. ;
  667. ; ENDIF
  668. ;
  669. MFN02:                ;RETURN CARRY IF NOT FOUND
  670.     INR    A
  671.     STC
  672.     RZ
  673. ;
  674. ;
  675. ; MOVE NAME FOUND TO CURRENT NAME
  676. ;
  677.     DCR    A
  678.     ANI    3
  679.     ADD    A
  680.     ADD    A
  681.     ADD    A
  682.     ADD    A
  683.     ADD    A
  684.     ADI    128+1
  685.     MOV    L,A
  686.     MVI    H,BASE SHR 8
  687.     PUSH    H        ;SAVE NAME POINTER
  688.     LXI    D,MFCUR+1
  689.     LXI    B,11
  690.     CALL    MOVER
  691. ;
  692. ;
  693. ; MOVE NAME FOUND TO FCB
  694. ;
  695.     POP    H
  696.     LXI    D,FCB+1
  697.     LXI    B,11
  698.     CALL    MOVER
  699. ;
  700. ;
  701. ; SETUP FCB
  702. ;
  703.      XRA    A
  704.     STA    FCBEXT
  705.     STA    FCBRNO
  706.     STA    MFFLG1        ;TURN OFF 1ST TIME SWITCH 
  707.     RET
  708. ;.....
  709. ;
  710. ; CHECK FOR .$$$ FILES
  711. TSTBAD:    CALL    TESTIT        ;CHECK FIRST ONE FOR '$'
  712.     RNZ            ;NO, RETURN
  713. ;
  714.     CALL    TESTIT        ;CHECK SECOND ONE
  715.     RNZ            ;NO, RETURN
  716. ;...
  717. ;
  718. ;
  719. TESTIT:    MOV    A,M
  720.     ANI    7FH        ;STRIP ATTRIBUTE
  721.     CPI    '$'        ;CHECK FOR $ FILETYPE
  722.     INX    H
  723.     RET
  724. ;.....
  725. ;
  726. ; MOVE (BC) BYTES FROM (HL) TO (DE)
  727. MOVER:    MOV    A,M
  728.     STAX    D
  729.     INX    H
  730.     INX    D
  731.     DCX    B
  732.     MOV    A,B
  733.     ORA    C
  734.     JNZ    MOVER
  735. ;
  736.     RET
  737. ;..... 
  738. ;
  739. ;
  740. ; ABORTED - PRINT REASON.  IF MAKING OUTPUT FILE, CLOSE THE INCOMPLETE
  741. ; FILE TO UPDATE CP/M'S BIT MAP, THEN ERASE IT.
  742. ABEXIT:    POP    D        ;GET MSG ADRS
  743.     MVI    C,PRINT
  744.     CALL    BDOS        ;PRINT MSG
  745. ABEXT2:    LDA    FFLAG        ;SEE IF WE ARE MAKING A DISK FILE
  746.     CPI    ' '
  747.     JZ    ABEXT5        ;IF NOT, EXIT
  748. ;
  749. ABEXT3:    LHLD    FILEPTR
  750.     MOV    A,L
  751.     ANI    07FH
  752.     JNZ    ABEXT4
  753.     SHLD    FILELEN
  754. ;
  755. ABEXT4:    MVI    A,EOF
  756.     PUSH    PSW
  757.     CALL    PUTFILE
  758.     POP    PSW
  759.     JNZ    ABEXT3
  760. ;
  761.      MVI    C,CLOSE
  762.     LXI    D,FCBFILE
  763.     CALL    BDOS
  764.     INR    A
  765.     JNZ    ERA$CRC
  766. ;
  767.     MVI    C,PRINT
  768.     LXI    D,NO$CLOSE
  769.     CALL    BDOS
  770. ;
  771. ;
  772. ; ERASE INCOMPLETE FILE
  773. ;
  774. ERA$CRC:
  775.     MVI    C,DELET
  776.     LXI    D,FCBFILE
  777.     CALL    BDOS
  778. ABEXT5:    CALL    ERXIT        ;PRINT MSG, EXIT
  779.     DB    CR,LF,LF,'++ABORTED++',CR,LF,'$'
  780. ;
  781. ;
  782. ; EXIT WITH MESSAGE
  783. MSGEXIT:
  784.     DS    0        ;EXIT WITH "INFORMATIONAL" MESSAGE
  785. ;
  786. ERXIT:    POP    D        ;GET MSG
  787.     MVI    C,PRINT
  788.     CALL    BDOS
  789. ; EXIT, RESTORING STACK AND RETURN TO 'CCP'
  790. EXIT:    LHLD    STACK                ;GET OLD STACK RETURN ADDRESS BACK
  791.     SPHL
  792.     RET            ;TO 'CCP'
  793. ;.....
  794. ;
  795. ;
  796. DIR$FULL:
  797.     DB    CR,LF
  798.     DB    '++NO DIRECTORY SPACE FOR CRC FILE++',CR,LF,'$'
  799. ;
  800. DSK$FULL:
  801.     DB    CR,LF
  802.     DB    '++NO DISK SPACE FOR CRC FILE++',CR,LF,'$'
  803. ;
  804. NO$CLOSE:
  805.     DB    CR,LF
  806.     DB    '++CANNOT CLOSE CRC FILE++',CR,LF,'$'
  807. ;
  808. ; PROGRAM STORAGE AREA
  809. BUFAD:    DB    0,0        ;READ BUFFER ADDRESS
  810. FFLAG:    DB    0        ;FILE WRITE REQUEST FLAG
  811. FOUND:    DB    0        ;SET TO ZERO IF FILE(S) FOUND
  812. MESS:    DB    0        ;'CRC' MESSAGE CHAR GOES HERE
  813. MFCUR:    DB    '            '    ;CURRENT NAME
  814. MFFLG1:    DB    1        ;1ST TIME SWITCH
  815. MFREQ:    DB    '            '    ;REQUESTED NAME
  816. OLDSTK:    DB    0,0        ;OLD STACK POINTER SAVED HERE
  817. REM:    DB    0,0        ;'CRC' REMAINDER STORAGE
  818. ;
  819. FILELEN:
  820.     DB    0,0        ;FILLED AUTOMATICALLY
  821. ;
  822. FILEPTR:
  823.     DB    0,0
  824. ;
  825. ;
  826. ; BUILD FCB FOR FINAL NAME OF CRCKLIST.CRC
  827. ;
  828. FCBFINAL:
  829.     DB    0,'CRCKLISTCRC'
  830.     DB    0
  831.     DS    20
  832. ;
  833. ;
  834. ; OUTPUT FILE (TEMPORARILY NAMED CRCKLIST.$$$)
  835. ;
  836. FCBFILE:
  837.     DB    0,'CRCKLIST$$$'
  838.     DB    0
  839.     DS    20
  840. ;
  841.     DS    80        ;MINIMUM STACK AREA
  842. ;
  843. SETEVEN EQU    ($+127)/128*128    ;SET BUFFER TO EVEN PAGE
  844. ;
  845. ;
  846.     ORG    SETEVEN
  847. ;
  848. STACK:    EQU    $-2        ;SAVE 2 BYTES FOR OLD STACK POINTER
  849. ;
  850. FILEADR:
  851.     DW    FILEADR+2    ;BUFFER ALL 'CRC' FILE DATA HERE
  852. ;
  853.     END
  854.