home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol096 / crck-51.a86 < prev    next >
Text File  |  1984-04-29  |  17KB  |  827 lines

  1.  
  2. ;    CRCK.ASM Version 5.1 (Originally by: Keith Petersen, W8SDZ)
  3. ; CRCK  is  a  program to read any CP/M file and  print  a  cyclic-
  4. ; redundancy-check number based on the CCITT standard polynominal:
  5. ;           x^16 + x^15 + x^13 + x^7 + x^4 + x^2 + x + 1
  6. ; Useful for checking accuracy of file transfers, and more accurate 
  7. ; than a simple checksum.   Optionally will write an output file to 
  8. ; the  default drive,  listing the CRC's of all files checked in  a 
  9. ; single session.
  10. ; Commands:   crck [drive:]<filename.filetype> [f]<cr>
  11. ; Examples:
  12. ; crck myfile.asm<cr>      (check only myfile.asm)
  13. ; crck *.asm<cr>           (check all .asm files
  14. ; crck *.* f<cr>           (check all files, make file of results)
  15. ; Program  updates/fixes  (these  are written in reverse  order  to 
  16. ; minimize reading time to find latest update):
  17. ; 04/10/82 version 5.1, Kelly Smith 
  18. ; Removed requirement for MAC.ASM and SEQIO.LIB for assembly
  19. ; 11/27/81 version 5.0, Dave Barker
  20. ; All  earlier  versions of CRCK.ASM (up to at least  Ver.  4.2  of 
  21. ; 10/06/80)  seen by this writer (DAB) have a serious flaw  in  the 
  22. ; algorithm  used to generate the CRC value.   Mr.  Petersen used a 
  23. ; routine from "EDN" magazine,  June 5, 1979.  Although the routine 
  24. ; published  in  EDN was a workable one,  the way in which  it  was 
  25. ; applied in CRCK.ASM was incorrect (i.e.  the routine should  have 
  26. ; been called 8 times per byte,  each time with only one bit of the 
  27. ; message in the A register,  then,  at the end of the file, 2 null 
  28. ; bytes  should  have  been processed as if they were part  of  the 
  29. ; file). The method that is used in CRCK.ASM Version 5.0 is a table 
  30. ; lookup method.  Instead of calling a routine 8 times each byte of 
  31. ; the  message  is processed in one short piece  of  straight  line 
  32. ; code.    The table that is used in this method is first generated 
  33. ; during initialization.
  34. ;                           - Validity -
  35. ; Version 5.0 generates exactly the same CRC value that the earlier 
  36. ; versions  would  have  generated if they had correctly  used  the 
  37. ; algorithm.   The message (the file) is processed in the order: MS 
  38. ; bit  of the MS byte first (if the file were to be processed as  a 
  39. ; serial  data transmission,  then the LS bit of the MS byte  would 
  40. ; come  first  --> the order in which it is transmitted  through  a 
  41. ; UART).
  42. ; Note:   Usually, the CRC of a message is appended to the end of a 
  43. ; message  when it is sent.   This causes the resultant CRC at  the 
  44. ; receiving  end  to be zero (this is the reason that the  2  dummy 
  45. ; null  bytes are added to the end of the message when the  CRC  is 
  46. ; generated or checked).
  47. ;
  48. ;
  49. ; define true and false
  50. false    EQU    0
  51. true    EQU    not false
  52. ; conditional assembly switches
  53. stdcpm    EQU    true            ; true is standard cp/m
  54. altcpm    EQU    false            ; true is h8 or trs-80
  55. nosys    EQU    false            ; true if sys files not wanted
  56. ;
  57. M    EQU    Byte Ptr 0[BX]
  58. ; system equates
  59. base    EQU    0
  60. ; define write buffer size (presently set for 8k)
  61. bsize    EQU    8*1024            ; disk write buffer size
  62. ; bdos equates
  63. rdcon    EQU    1
  64. wrcon    EQU    2
  65. print    EQU    9
  66. cstat    EQU    11
  67. open    EQU    15
  68. close    EQU    16
  69. srchf    EQU    17
  70. srchn    EQU    18
  71. delet    EQU    19
  72. read    EQU    20
  73. write    EQU    21
  74. make    EQU    22
  75. renam    EQU    23
  76. stdma    EQU    26
  77. stbas    EQU    51
  78. ;
  79. bdos    EQU    base+5
  80. ;
  81. fcb    EQU    base+5ch
  82. fcbext    EQU    fcb+12
  83. fcbrno    EQU    fcb+32
  84. fcb2    EQU    base+6ch
  85. ;
  86. tbuf    EQU    base+80h        ; temporary buffer (default) address
  87. buf@siz    EQU    80h            ; buffer size (128 bytes)
  88. ;
  89. crcfilesiz EQU    2000h
  90. ;
  91. tab    EQU    09h            ; tab character
  92. lf    EQU    0ah            ; line feed character
  93. cr    EQU    0dh            ; carriage return character
  94. eof    EQU    'Z'-40h            ; end-of-file character
  95. ;
  96. ; CCIT CRC polynomial mask bytes
  97. ;
  98. himsk    EQU    0a0h            ; high mask byte
  99. lomsk    EQU    097h            ; low mask byte
  100. ;
  101. ;
  102. ; program starts here
  103.      ORG    base+100h
  104. begin:    MOV    SP,(offset stktop)    ; make local stack
  105.     CALL    crlf            ; turn up a new line
  106.     MOV    AL,Byte Ptr .fcb+1
  107.     CMP    AL,' '            ; see if name there
  108.     JNZ    begin2            ; yes, continue
  109.     CALL    erxit            ; print msg, then exit
  110.     DB    '++No File Name Specified++',cr,lf,'$'
  111. begin2:    CALL    ilprt            ; print:
  112.     DB    '--------- CRCK Ver 5.1 ---------'
  113.     DB    cr,lf
  114.     DB    'CTRL-S to Pause, CTRL-C to Abort'
  115.     DB    cr,lf,cr,lf,0
  116. ;
  117. ; generate the lookup table for fast crc
  118. ;
  119.     MOV    BX,(Offset hitab)
  120.     MOV    CL,0            ; the table index
  121. gloop:    XCHG    BX,DX
  122.     MOV    BX,0            ; init the crc
  123.     MOV    AL,CL
  124.     CALL    lcrc
  125.     XCHG    BX,DX            ; de now has the crc, hl pointing into table
  126.     MOV    M,DH            ; store the high byte of crc
  127.     INC    BH
  128.     MOV    M,DL            ; store the low byte
  129.     DEC    BH
  130.     INC    BX            ; move to next table entry
  131.     INC    CL            ; next index
  132.     JNZ    gloop
  133.     MOV    AL,Byte Ptr .fcb2+1    ; get option
  134.     MOV    Byte Ptr fflag,AL    ; save it for later
  135.     CMP    AL,'F'            ; file wanted?
  136.     JZ    L_1    
  137.     JMP    again            ; no, skip file init
  138. L_1:
  139.     XOR    AL,AL
  140.     MOV    Byte Ptr fcbcrcfile+12,AL    ; clear extent
  141.     MOV    Byte Ptr fcbcrcfile+32,AL    ; clear current record count
  142.     MOV    BX,crcfilesiz        ; set buffer size
  143.     MOV    Word Ptr crcfilelen,BX
  144.     MOV    BX,0            ; set next to fill
  145.     MOV    Word Ptr crcfileptr,BX
  146.     MOV    CL,delet        ; delete file function
  147.     MOV    DX,(Offset fcbcrcfile)    ; delete 'old' crcklist file
  148.     INT    224
  149.     MOV    CL,make            ; make file function
  150.     MOV    DX,(Offset fcbcrcfile)    ; make 'new' crcklist file
  151.     INT    224
  152.     INC    AL            ; make ok?
  153.     JZ    L_2    
  154.     JMP    again
  155. L_2:
  156.     MOV    CL,print        ; print string function
  157.     MOV    DX,(Offset dir@full)    ; indicate that directory is full
  158.     INT    224
  159.     JMP    filerr
  160. ;
  161. ;
  162. ;
  163. putcrcfile:
  164. ;
  165.     LAHF                ; save output character
  166.     XCHG    AL,AH
  167.     PUSH    AX
  168.     MOV    BX,Word Ptr crcfilelen    ; get current buffer length
  169.     XCHG    BX,DX            ; de has length
  170.     MOV    BX,Word Ptr crcfileptr    ; load next to get/put to hl
  171.     MOV    AL,BL            ; compute current length
  172.     SUB    AL,DL
  173.     MOV    AL,BH
  174.     SBB    AL,DH            ; carry if next < length
  175.     JB    putcrc4            ; carry if length > current
  176.     MOV    BX,0            ; end of buffer, fill (empty) buffers    
  177.     MOV    Word Ptr crcfileptr,BX    ; clear next to get/put
  178. ;
  179. putcrc1:                ; process next disk sector
  180. ;
  181.     XCHG    BX,DX            ; file pointer to de
  182.     MOV    BX,Word Ptr crcfilelen    ; hl is maximum buffer length
  183.     MOV    AL,DL            ; compute next length
  184.     SUB    AL,BL            ; to get carry, if more fill
  185.     MOV    AL,DH
  186.     SBB    AL,BH
  187.     JNB    putcrc3
  188.     MOV    BX,Word Ptr crcfileadr    ; got carry, more to fill yet
  189.     ADD    BX,DX            ; hl is next buffer address
  190.     XCHG    BX,DX
  191.     MOV    CL,stdma        ; set dma address
  192.     INT    224
  193.     MOV    CL,stbas        ; set dma base
  194.     MOV    DX,DS
  195.     INT    224
  196.     MOV    DX,(Offset fcbcrcfile)    ; fcb address to de
  197.     MOV    CL,write        ; file write
  198.     INT    224
  199.     OR    AL,AL            ; check return code
  200.     JNZ    putcrc2            ; end-of-file yet?
  201.     MOV    DX,buf@siz        ; not eof, increment length by 128
  202.     MOV    BX,Word Ptr crcfileptr    ; next to fill
  203.     ADD    BX,DX
  204.     MOV    Word Ptr crcfileptr,BX    ; save new pointer
  205.     JMPS    putcrc1            ; process another sector
  206. ;
  207. putcrc2:                ; got end-of-file
  208. ;
  209.     MOV    CL,print        ; print string function
  210.     MOV    DX,(Offset dsk@full)    ; disk is full
  211.     INT    224
  212.     POP    AX            ; clean stack
  213.     XCHG    AL,AH
  214.     JMP    filerr            ; file error, exit
  215. ;
  216. putcrc3:                ; end of buffer, reset dma and pointer
  217. ;
  218.     MOV    DX,tbuf            ; point to temporary buffer
  219.     MOV    CL,stdma        ; set dma function
  220.     INT    224
  221.     MOV    CL,stbas        ; set dma base
  222.     MOV    DX,DS
  223.     INT    224
  224.     MOV    BX,0            ; reset pointer for next to get
  225.     MOV    Word Ptr crcfileptr,BX
  226. ;
  227. putcrc4:                ; process the next character
  228. ;
  229.     XCHG    BX,DX            ; index to get/put in de
  230.     MOV    BX,Word Ptr crcfileadr    ; base of buffer
  231.     ADD    BX,DX            ; address of character in hl
  232.     XCHG    BX,DX            ; and swap to de
  233.     POP    AX            ; get save character
  234.     XCHG    AL,AH
  235.     SAHF
  236.     MOV    DI,DX            ; character to buffer
  237.     MOV    [DI],AL
  238.     MOV    BX,Word Ptr crcfileptr    ; index to get/put
  239.     LAHF                ; and update for next character
  240.     INC    BX
  241.     SAHF
  242.     MOV    Word Ptr crcfileptr,BX
  243.     RET
  244. again:    MOV    SP,(offset stktop)    ; make local stack
  245.     CALL    mfname            ; search for names
  246.     JNAE    L_3    
  247.     JMP    namtst            ; another found, print name
  248. L_3:
  249.     MOV    AL,Byte Ptr mfflg1    ; nothing found, check...
  250.     OR    AL,AL            ; ... first time flag
  251.     JZ    done            ; at least one was found
  252.     CALL    abexit            ; print msg, then exit
  253.     DB    '++File Not Found++$'
  254. done:    MOV    AL,Byte Ptr fflag    ; see if we're making file
  255.     CMP    AL,'F'
  256.     JNZ    done2            ; no, skip the file stuff
  257. ; close crcklist.$$$
  258. ;
  259. closecrc:
  260. ;
  261.     MOV    BX,Word Ptr crcfileptr
  262.     MOV    AL,BL
  263.     AND    AL,07fh
  264.     JNZ    close1
  265.     MOV    Word Ptr crcfilelen,BX
  266. close1:    MOV    AL,eof
  267.     LAHF
  268.     XCHG    AL,AH
  269.     PUSH    AX
  270.     XCHG    AL,AH
  271.     CALL    putcrcfile
  272.     POP    AX
  273.     XCHG    AL,AH
  274.     SAHF
  275.     JNZ    closecrc
  276.     MOV    CL,close
  277.     MOV    DX,(Offset fcbcrcfile)
  278.     INT    224
  279.     INC    AL
  280.     JNZ    erase
  281.     MOV    CL,print
  282.     MOV    DX,(Offset no@close)
  283.     INT    224
  284. ; erase any existing old file
  285. ;
  286. erase:    MOV    CL,delet
  287.     MOV    DX,(Offset fcbfinal)
  288.     INT    224
  289. ; rename crcklist.$$$ to crcklist.crc
  290. ;
  291.     MOV    BX,(Offset fcbcrcfile)
  292.     MOV    DX,(Offset fcbfinal)
  293.     PUSH    BX
  294.     MOV    CX,16
  295.     LAHF
  296.     ADD    BX,CX
  297.     RCR    SI,1
  298.     SAHF
  299.     RCL    SI,1
  300. ;
  301. mov@name:
  302. ;
  303.     MOV    SI,DX
  304.     MOV    AL,[SI]
  305.     MOV    M,AL
  306.     LAHF
  307.     INC    DX
  308.     SAHF
  309.     LAHF
  310.     INC    BX
  311.     SAHF
  312.     DEC    CL
  313.     JNZ    mov@name
  314.     POP    DX
  315.     MOV    CL,renam
  316.     INT    224
  317. ; now exit to cp/m
  318. ;
  319. done2:    CALL    erxit            ; print done, then exit
  320.     DB    cr,lf,'Done$'
  321. ; test for names to ignore
  322. namtst:    
  323. ;
  324.     if    nosys            ; if $SYS file, ignore it
  325.     MOV    AL,Byte Ptr .fcb+10    ; get $SYS file attribute
  326.     AND    AL,080h            ; is it $SYS?
  327.     JNZ    again            ; yes, ignore this file
  328.     endif                ; nosys 
  329. ; ignore files with .$$$ filetype (they are usually
  330. ; zero-length and clutter up our display.  we also
  331. ; want to ignore our own crcklist.$$$ temporary file).
  332.     MOV    BX,fcb+9        ; point to filetype in fcb
  333.     CALL    tstbad            ; check for .$$$ files
  334.     JNZ    L_4    
  335.     JMP    again            ; if zero flag, ignore them
  336. L_4:
  337. ; move 8 characters from fcb+1 to fname
  338. ;
  339.     MOV    BX,fcb+1
  340.     MOV    DX,(Offset fname)
  341.     MOV    CX,8
  342.     CALL    mover
  343. ;
  344. ; move 3 characters from fcb+9 to fname+9
  345. ;
  346.     MOV    BX,fcb+9
  347.     MOV    DX,(Offset fname)+9
  348.     MOV    CX,3
  349.     CALL    mover
  350. ;
  351. ; now print filename.type
  352. ;
  353.     CALL    ilprt            ; print:
  354. ;
  355. fname    DB    'xxxxxxxx.xxx',tab,'CRC = ',0
  356. ; open the file
  357. ;
  358.     MOV    DX,fcb
  359.     MOV    CL,open
  360.     INT    224
  361.     INC    AL
  362.     JNZ    rdinit
  363.     CALL    abexit
  364.     DB    '++Open Failed++$'
  365. ; initialize crc to zero and set bufad to cause initial read
  366. ;
  367. rdinit:    MOV    BX,0
  368.     MOV    Word Ptr rem,BX        ; init remainder to zero
  369.     MOV    BX,base+100h
  370.     MOV    Word Ptr bufad,BX    ; init buffer adrs
  371. ; this is the read loop
  372. ;
  373. readit:    MOV    BX,Word Ptr bufad
  374.     MOV    AL,BH            ; time to read?
  375.     CMP    AL,base shr 8
  376.     JZ    nord            ; no read
  377.     MOV    CL,cstat
  378.     INT    224            ; check for operator abort
  379.     OR    AL,AL
  380.     JZ    read2            ; nothing from operator
  381.     MOV    CL,rdcon
  382.     INT    224            ; get character inputted
  383.     CMP    AL,'C'-40h        ; control c?
  384.     JNZ    L_5    
  385.     JMP    abext2            ; yes exit
  386. L_5:
  387. read2:    MOV    DX,fcb
  388.     MOV    CL,read            ; read another sector of file
  389.     INT    224
  390.     OR    AL,AL            ; check return code
  391.     JNZ    finish            ; error or eof
  392.     MOV    BX,tbuf            ; buffer location
  393. nord:    MOV    AL,M            ; get file character
  394.     INC    BX
  395.     MOV    Word Ptr bufad,BX
  396.     MOV    BX,Word Ptr rem        ; pick up the partial remainder
  397. ; table lookup method for crc generation
  398. ;
  399.     XCHG    BX,DX            ; de now has the partial
  400.     MOV    CH,0
  401.     XOR    AL,DH
  402.     MOV    CL,AL
  403.     MOV    BX,(Offset hitab)
  404.     ADD    BX,CX
  405.     MOV    AL,M
  406.     XOR    AL,DL
  407.     MOV    DH,AL
  408.     INC    BH
  409.     MOV    DL,M
  410.     XCHG    BX,DX
  411.     MOV    Word Ptr rem,BX
  412.     JMPS    readit            ; go read more characters
  413. ;
  414. ;
  415. finish:    CMP    AL,1            ; normal end-of-file?
  416.     JNZ    filerr            ; no, it was a read error
  417.     MOV    AL,Byte Ptr rem+1    ; get msp of crc
  418.     CALL    hexo            ; print it
  419.     MOV    AL,Byte Ptr rem        ; get lsp of crc
  420.     CALL    hexo            ; print it
  421.     CALL    crlf            ; turn up new line
  422.     JMP    again            ; see if more files to do
  423. filerr:    CALL    abexit            ; abort because of file read error
  424.     DB    '++File Read Error++$'
  425. ;  hl contains the partial, a the character to be crc'd
  426. lcrc:    PUSH    CX
  427.     MOV    CH,8
  428.     XOR    AL,BH
  429.     MOV    BH,AL
  430. loop:    SHL    BX,1
  431.     JNB    skip
  432.     MOV    AL,himsk
  433.     XOR    AL,BH
  434.     MOV    BH,AL
  435.     MOV    AL,lomsk
  436.     XOR    AL,BL
  437.     MOV    BL,AL
  438. skip:    DEC    CH
  439.     JNZ    loop
  440.     POP    CX
  441.     RET
  442. ; hex output
  443. hexo:    LAHF                ; save for right digit
  444.     XCHG    AL,AH
  445.     PUSH    AX
  446.     XCHG    AL,AH
  447.     RCR    AL,1            ; right..
  448.     RCR    AL,1            ; ..justify..
  449.     RCR    AL,1            ; ..left..
  450.     RCR    AL,1            ; ..digit..
  451.     CALL    nibbl            ; print left digit
  452.     POP    AX            ; restore right
  453.     XCHG    AL,AH
  454. nibbl:    AND    AL,0fh            ; isolate digit
  455.     CMP    AL,10            ; is is <10?
  456.     JB    isnum            ; yes, not alpha
  457.     ADD    AL,7            ; add alpha bias
  458. isnum:    ADD    AL,'0'            ; make printable
  459.     JMPS    display            ; print it, then return
  460. ;
  461. ;
  462. ; inline print routine
  463. ilprt:    MOV    BP,SP            ; save hl, get msg
  464.     XCHG    BX,[BP]
  465. ilplp:    MOV    AL,M            ; get char
  466.     CALL    display            ; output it
  467.     INC    BX            ; point to next
  468.     MOV    AL,M            ; test
  469.     OR    AL,AL            ; ..for end
  470.     JNZ    ilplp
  471.     INC    BX            ; bump pointer for return address
  472.     MOV    BP,SP            ; restore hl, ret addr
  473.     XCHG    BX,[BP]
  474.     RET                ; ret past msg
  475. ;
  476. ;
  477. ; send carriage return, line feed to output
  478. crlf:    MOV    AL,cr            ; carriage return
  479.     CALL    display
  480.     MOV    AL,lf            ; line feed, fall into 'type'
  481. ; send character in a register to output
  482. display:
  483. ;
  484.     PUSH    CX
  485.     PUSH    DX
  486.     PUSH    BX
  487.     AND    AL,7fh            ; strip parity bit
  488.     MOV    DL,AL
  489.     PUSH    DX
  490.     CALL    wrfile            ; write to file if requested
  491.     POP    DX
  492.     MOV    CL,wrcon        ; send character to console
  493.     INT    224
  494.     POP    BX
  495.     POP    DX
  496.     POP    CX
  497.     RET
  498. ;
  499. ;
  500. ; write character in e register to output file
  501. wrfile:    MOV    AL,Byte Ptr fflag    ; get file trigger
  502.     CMP    AL,'F'            ; is it set?
  503.     JZ    L_6    
  504.     RET                ; no, return
  505. L_6:
  506.     MOV    AL,DL            ; get character back
  507.     CALL    putcrcfile
  508.     RET
  509. ; multi-file access subroutine.  allows processing
  510. ; of multiple files (i.e. *.asm) from disk.  this
  511. ; routine builds the proper name in the fcb each
  512. ; time it is called. carry is set if no more names
  513. ; can be found.
  514. mfname:                ; init dma addr and fcb
  515.     MOV    CL,stdma
  516.     MOV    DX,tbuf
  517.     INT    224
  518.     MOV    CL,stbas        ; set dma base
  519.     MOV    DX,DS
  520.     INT    224
  521.     XOR    AL,AL
  522.     MOV    Byte Ptr .fcbext,AL
  523.     MOV    Byte Ptr .fcbrno,AL
  524. ;
  525. ; if first time
  526. ;
  527.     MOV    AL,Byte Ptr mfflg1
  528.     OR    AL,AL
  529.     JZ    mfn01
  530. ;
  531. ; save the requested name
  532. ;
  533.     MOV    BX,fcb
  534.     MOV    DX,(Offset mfreq)
  535.     MOV    CX,12
  536.     CALL    mover
  537.     MOV    AL,Byte Ptr .fcb
  538.     MOV    Byte Ptr mfcur,AL    ; save disk in curr fcb
  539. ;
  540. ; srchf requested name
  541. ;
  542.     MOV    BX,(Offset mfreq)
  543.     MOV    DX,fcb
  544.     MOV    CX,12
  545.     CALL    mover
  546.     MOV    CL,srchf
  547.     MOV    DX,fcb
  548.     INT    224
  549. ;
  550. ; else
  551. ;
  552.     JMPS    mfn02
  553. mfn01:                    ; srchf current name
  554.     MOV    BX,(Offset mfcur)
  555.     MOV    DX,fcb
  556.     MOV    CX,12
  557.     CALL    mover
  558.     MOV    CL,srchf
  559.     MOV    DX,fcb
  560.     INT    224
  561. ;
  562. ; srchn requested name
  563. ;
  564.     MOV    BX,(Offset mfreq)
  565.     MOV    DX,fcb
  566.     MOV    CX,12
  567.     CALL    mover
  568.     MOV    CL,srchn
  569.     MOV    DX,fcb
  570.     INT    224
  571. ;
  572. ; endif
  573. ;
  574. mfn02:                    ; return carry if not found
  575.     INC    AL
  576.     STC
  577.     JNZ    L_7
  578.     RET
  579. L_7:
  580. ;
  581. ; move name found to current name
  582. ;
  583.     DEC    AL
  584.     AND    AL,3
  585.     ADD    AL,AL
  586.     ADD    AL,AL
  587.     ADD    AL,AL
  588.     ADD    AL,AL
  589.     ADD    AL,AL
  590.     ADD    AL,81h
  591.     MOV    BL,AL
  592.     MOV    BH,0
  593.     PUSH    BX            ; save name pointer
  594.     MOV    DX,(Offset mfcur)+1
  595.     MOV    CX,11
  596.     CALL    mover
  597. ;
  598. ; move name found to fcb
  599. ;
  600.     POP    BX
  601.     MOV    DX,fcb+1
  602.     MOV    CX,11
  603.     CALL    mover
  604. ;
  605. ; setup fcb
  606. ;
  607.     XOR    AL,AL
  608.     MOV    Byte Ptr .fcbext,AL
  609.     MOV    Byte Ptr .fcbrno,AL
  610.     MOV    Byte Ptr mfflg1,AL    ; turn off 1st time sw
  611.     RET
  612. ;
  613. ;
  614. ; check for .$$$ files
  615. tstbad:    CALL    testit            ; check first one for '$'
  616.     JZ    L_8    
  617.     RET                ; no, return
  618. L_8:
  619.     CALL    testit            ; check second one
  620.     JZ    L_9    
  621.     RET                ; no, return
  622. L_9:
  623. testit:    MOV    AL,M
  624.     AND    AL,7fh            ; strip attribute
  625.     CMP    AL,'$'            ; check for $ filetype
  626.     LAHF
  627.     INC    BX
  628.     SAHF
  629.     RET
  630. ;
  631. ;
  632. ; move (bc) bytes from (hl) to (de)
  633. mover:    MOV    AL,M
  634.     MOV    SI,DX
  635.     MOV    [SI],AL
  636.     INC    BX
  637.     INC    DX
  638.     DEC    CX
  639.     MOV    AL,CH
  640.     OR    AL,CL
  641.     JNZ    mover
  642.     RET
  643. ;
  644. ;
  645. ; aborted - print reason.  if making output file,
  646. ; close the incomplete file to update cp/m's bit map,
  647. ; then erase it.
  648. abexit:    POP    DX            ; get msg adrs
  649.     MOV    CL,print
  650.     INT    224            ; print msg
  651. abext2:    MOV    AL,Byte Ptr fflag    ; see if we are making file
  652.     CMP    AL,'F'
  653.     JNZ    abext5            ; no file, skip file stuff
  654. abext3:    MOV    BX,Word Ptr crcfileptr
  655.     MOV    AL,BL
  656.     AND    AL,07fh
  657.     JNZ    abext4
  658.     MOV    Word Ptr crcfilelen,BX
  659. abext4:    MOV    AL,eof
  660.     LAHF
  661.     XCHG    AL,AH
  662.     PUSH    AX
  663.     XCHG    AL,AH
  664.     CALL    putcrcfile
  665.     POP    AX
  666.     XCHG    AL,AH
  667.     SAHF
  668.     JNZ    abext3
  669.     MOV    CL,close
  670.     MOV    DX,(Offset fcbcrcfile)
  671.     INT    224
  672.     INC    AL
  673.     JNZ    era@crc
  674.     MOV    CL,print
  675.     MOV    DX,(Offset no@close)
  676.     INT    224
  677. ;
  678. ; erase incomplete file
  679. ;
  680. era@crc:
  681. ;
  682.     MOV    CL,delet
  683.     MOV    DX,(Offset fcbcrcfile)
  684.     INT    224
  685. abext5:    CALL    erxit            ; print msg, exit
  686.     DB    cr,lf,cr,lf,'++Aborted++$'
  687. ;
  688. ; exit with message
  689. erxit:    POP    DX            ; get msg
  690.     MOV    CL,print
  691.     INT    224
  692. ; exit, via system warm boot
  693. exit:    mov    cl,0    ; warm boot to cp/m
  694.     mov    dl,0
  695.     int 224
  696. ;
  697. ;
  698. ;
  699. dir@full DB    cr,lf
  700.     DB    '++No Directory Space for CRC File++'
  701.     DB    '$'
  702. ;
  703. dsk@full DB    cr,lf
  704.     DB    '++No Disk Space for CRC File++'
  705.     DB    '$'
  706. ;
  707. no@close DB    cr,lf
  708.     DB    '++Cannot Close CRC File++'
  709.     DB    '$'
  710.  
  711. ; program storage area
  712.     RS    64        ; 32 level local stack
  713. stktop    equ    $        ; top of local stack
  714. ;
  715. fflag    DB    0            ; file write request flag
  716. rem    DW    0            ; crc remainder storage
  717. mess    DB    0            ; crc message char goes here
  718. mfflg1    DB    1            ; 1st time switch
  719. mfreq    RS    12            ; requested name
  720. mfcur    RS    12            ; current name
  721. bufad    RS    2            ; read buffer address
  722. ;
  723. hitab    RS    512            ; the 2 tables for crc lookup
  724. ;
  725. crcfilelen    DW    crcfilesiz
  726. ;
  727. crcfileptr    RS    2
  728. ; build fcb for final name of crcklist.crc
  729. ;
  730. fcbfinal    DB    0,'CRCKLISTCRC'
  731.         DB    0
  732.         RS    20
  733. ;
  734. ; 'declare' fcb for output file (temporarily named crcklist.$$$)
  735. ;
  736. fcbcrcfile    DB    0,'CRCKLIST$$$'
  737.         DB    0
  738.         RS    20
  739. ;
  740. crcfileadr    DW    crcfileadr+2    ; buffer all crc file data here
  741.         RS    02000h        ; force buffer area
  742.         DB    0        ; tag 'end' for GENCMD
  743. ;
  744. ;
  745.     END
  746.