home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / squsq / fcrlzh11.lbr / FCRLZH11.MYC / FCRLZH11.MYC
Text File  |  1989-12-12  |  21KB  |  924 lines

  1. title    'FCRLZH multi-file LZH encoder'
  2. ;
  3. ver        equ    11
  4. ;
  5. ; Based on FCRUNCH (see below)
  6. ;
  7. ; 1.1   (89/09/08) No previous revision.  Output file name uses
  8. ;       'Y', rather than 'Z'.
  9. ;
  10. ;--------------------FCRUNCH DOCS FOLLOW------------------------
  11. ;
  12. ; Crunch file 1 to file 2.  By C.B. Falconer.
  13. ;
  14. ;   d>FCRUNCH [-[c][k][p][q]] [d[u]:]afnin.aft [d[u]:][afnout.aft]
  15. ;        crunches afnin.aft to afnout.aft
  16. ;        (with full du addressing, across users, drives)
  17. ; the (optional) -c causes confirmation per file crunched
  18. ;         -k causes no existing files to be erased
  19. ;         -p causes existing output file erasure
  20. ;         -q suppresses running messages
  21. ; Default output name is input with a middle Z in filetype.
  22. ;
  23. ; 1.1    (86/12/20) Only version # changed, relinked to CRN v25, which
  24. ;    allows for trapping of particular output sequences.  This now
  25. ;    traps the sequence <0dh>,<040h> (with possible high bits set)
  26. ;    and injects a nulcode to output.  This avoids problems with
  27. ;    Telenet/PcPursuit (or so I am told).  CRN can be configured
  28. ;    to trap any 2 byte sequence, by reassembly.    - cbf
  29. ;
  30. ; Created as a modification of FCOPY 1.1.  Needs BUFFLIB v1.4 up
  31. ;
  32. ; ASSEMBLY    (rmac is not usable without changes)
  33. ;    A>m80 fcrlzh11,=fcrlzh11
  34. ; or
  35. ;    A>slrmac fcrlzh11/r        (much faster)
  36. ;
  37. ;    CAUTION - nnnn/mmmm numbers below are examples, can change
  38. ;
  39. ; LINKING with L80  (slowest by far)
  40. ;
  41. ;    A>l80 /p:100,/d:4000,fcrlzh11,crlzh,bufflib/s,/u,/r
  42. ;
  43. ;    Link-80  3.44   . . . . 
  44. ;    Data    4000    405A    <   90>
  45. ;    Program 0100    0ADD    < dddd>
  46. ;
  47. ;    */p:100,/d:nnnn,fcrlzh11,crlzh,bufflib/s,fcrlzh11/n,/e
  48. ;            ^ using nnnn = 0ADD from above line (example)
  49. ;
  50. ; LINKING with SLRNK
  51. ;
  52. ;    A>slrnk /p:100,/d:4000,fcrlzh11,crlzh,bufflib/s,/u,/r
  53. ;
  54. ;    Superlinker . . . .
  55. ;    0100-0ADC  (09DD)       973E left
  56. ;    Superlinker . . . .
  57. ;
  58. ;    %/p:100,/d:mmmm,fcrlzh11,crlzh,bufflib/s,fcrlzh11/n,/e
  59. ;            ^ using mmmm = 0ADD, i.e. 0ADC + 1 (example)
  60. ;
  61. ; LINKING with SLRNK+  (fastest and easiest, no copying numbers)
  62. ;
  63. ;A>slrnk+ /a:100,/j,fcrlzh11,crlzh,bufflib/s,fcrlzh11/n,/e
  64. ;                        (does it all)
  65. ; Externals in BUFFLIB.    See BUFFERS.DOC
  66.     extrn    .getusr,  .xltusr, .setusr;    user parsing
  67.     extrn    .wildx,      .wldck,  .pfnmdu;    file parsing
  68.     extrn    .options, .skipblks;        command parsing
  69.     extrn    .fncpy,      .nxtout, .nxtfn;    fname operations
  70.     extrn    .dos;                bdos(a), save regs
  71.     extrn    .idiv,      .imul,   .dcmp
  72.     extrn    .tdzs,      .tfnam,  .crlf;    utility
  73.     extrn    .couta,      .tdzsf,  .blk
  74.     extrn    .initfcb, .drvlock
  75.     extrn    .bfwopen, .bfclose;        write opens/close
  76.     extrn    .bfropen;            read opens
  77.     extrn    .bfgetc,  .bfputc;        buffered file i/o
  78.     extrn    b.ohead;            ext. constants
  79.     extrn    .bver;                library version
  80.     extrn    .endata;            Available memory area
  81. ;
  82.     extrn    crlzh;                crunch package
  83.  
  84.     entry    glzhen, plzhen;            crlzh i/o
  85. ;
  86. buflibver    equ    14;        minimum to link
  87. stkmargin    equ    5*1400h + 256;    bytes for crlzh & stack
  88. ;
  89. boot    equ    0
  90. bdos    equ    boot+5
  91. tfcb    equ    boot+05ch;    used to hold outname template
  92. defdma    equ    boot+080h
  93. ;
  94. cr    equ    0dh
  95. lf    equ    0ah
  96. t    equ    09h
  97. crnchid    equ    076fdh;        Standard header
  98. stpmax    equ    40;        max size (+1) of any stamp
  99. ;
  100. ; errors
  101. xhelp    equ    0;        no error, give help
  102. xempty    equ    1;        file empty
  103. xcrn    equ    2;        file already crunched/squeezed
  104. xstkovf    equ    3;        memory overflow
  105. xwild    equ    4;        incompatible wildcards
  106. xtoself    equ    5;        copying into self
  107. xnodir    equ    6;        fcreate failure
  108. xwrterr    equ    7;        write error
  109. xusrabt    equ    8;        user abort
  110. xbadlib    equ    9;        linked to wrong library
  111. xsaved    equ    10;        Old file not eraseable
  112. xbadnam    equ    11;        Unable to create new name
  113. xnofile    equ    12;        input file not found
  114. xok    equ    13;        done, without errors
  115. ;
  116. ; Dos function calls
  117. cin    equ    1
  118. pstrg    equ    9
  119. csta    equ    11
  120. @fopen    equ    15
  121. @purge    equ    19
  122. ;
  123. ; Initialize
  124. begin:    jmp    bgn
  125. ;
  126. ; Option image.  Zero locations to pre-set.
  127. ; Make letters lower case to forbid setting.
  128. optimg:    db    '-',optlgh
  129.     db    'C';        Confirm "crunch this file" option
  130.     db    'K';        Keep pre-existing output files
  131.     db    'P';        purge pre-existing output files
  132.     db    'Q';        Quiet option.
  133. optlgh    equ    $-optimg-2
  134. ;
  135. ; Start up here
  136. bgn:    lhld    bdos+1
  137.     mvi    l,0;        set stack at top of memory
  138.     sphl
  139.     call    .getusr
  140.     sta    entryusr
  141.     call    .bver;        This also ensures the lib version
  142.     cpi    buflibver;    module is linked and identified
  143.     mvi    a,xbadlib
  144.     jc    exeunt;        linked to wrong library
  145.     lxi    h,0
  146.     shld    filesdone;    zero count of files processed
  147.     shld    stamp;        default empty stamp
  148.     lxi    d,defdma
  149.     call    markeol;    of input command line
  150.     inx    d
  151.     lxi    b,optimg
  152.     lxi    h,options
  153.     call    .options;    from de^
  154. ;    "    "
  155. ; parse in/out file names
  156.     lxi    h,fcbout
  157.     call    .initfcb
  158.     lxi    h,fcbin
  159.     call    .initfcb;    init in and out fcbs
  160.     call    .pfnmdu
  161.     mov    a,b;        is 0 for default, else usr+1
  162.     call    usrlok;        now 1..max
  163.     sta    inuser
  164.     lxi    h,tfcb
  165.     call    .initfcb
  166.     mvi    b,0;        in case no 2nd file parsed
  167.     call    .skipblks
  168.     cpi    '['
  169.     cnz    .pfnmdu;    no 2nd spec, reached the stamp
  170.     push    d;        save input parse pointer
  171.     mov    a,b
  172.     call    usrlok;        now 1..max, no defaults left
  173.     sta    outuser
  174.     lxi    d,fcbin;    ensure locked to drive for compare
  175.     call    .drvlock;     else default and specific drives
  176.     lxi    d,tfcb;         may erroneously appear different
  177.     call    .drvlock
  178.     ldax    d
  179.     sta    fcbout;        set output drive id
  180.     lda    fcbin+1
  181.     pop    d;        get input parse pointer back
  182.     sui    ' '
  183.     jz    exeunt;        a=0, help message
  184. ;    "    "
  185. ; Parse the remaining tail into the stamp buffer
  186.     call    rstamp;        from de^
  187. ;    "    "
  188. ; Set default output names, check compatible wild cards
  189.     lxi    h,fcbin
  190.     lxi    d,tfcb
  191.     call    sdefault;    if no output, make same as input
  192.     call    .wldck;        Check wild cards compatible
  193.     mvi    a,xwild
  194.     jc    exeunt;        Incompatible wildcards
  195. ;    "    "
  196. ; Expand any wild cards
  197.     lxi    h,.endata
  198.     shld    fnptr
  199.     lda    inuser
  200.     dcr    a
  201.     call    .setusr
  202.     lxi    d,fcbin
  203.     call    .wildx;        expand fcbin into wild list
  204.     mvi    a,xstkovf
  205.     jc    exeunt;        Ran out of memory
  206.     shld    @outbuff;    mark available memory
  207.     xchg;            de := @outbuff
  208.     mov    l,c
  209.     mov    h,b
  210.     shld    fncount;    number of files matched
  211. ;    "    "
  212. ; Calculate space available for buffers and allocate them
  213.     lxi    h,b.ohead+b.ohead
  214.     dad    d
  215.     xchg;            adjust base of storage
  216.     lxi    h,-stkmargin
  217.     dad    sp
  218.     mvi    a,0;        round down to page boundary
  219.     sub    e
  220.     mov    e,a
  221.     mov    a,h
  222.     sbb    d
  223.     mov    d,a;        form buffer size available
  224.     xchg
  225.     lxi    d,0;        0 extend
  226.     lxi    b,3
  227.     call    .idiv;        one third for outbuffer
  228.     xchg
  229.     mov    a,l
  230.     ani    080h;        round down to multiple of 128
  231.     mov    l,a
  232.     shld    bufsize
  233.     ora    h
  234.     mvi    a,xstkovf
  235.     jz    exeunt;        0 size buffers just wont do
  236.     lxi    d,b.ohead
  237.     dad    d;        space needed for complete buffer
  238.     xchg
  239.     lhld    @outbuff
  240.     dad    d
  241.     shld    @inbuff;    locate past output buffer
  242.     lxi    d,b.ohead
  243.     dad    d
  244.     xchg
  245.     lhld    bufsize
  246.     dad    h;        double, two thirds for input buffer
  247.     dad    d
  248.     shld    @freemem;    and locate available memory
  249. ;    "    "
  250. ; Now tfcb holds output file pattern, fnptr points to next input file
  251. ; name, and fncount holds file count to process.  @outbuff points just
  252. ; above the file list and is allocated, @inbuff is allocated, memory
  253. ; from @freemem up, less an allowance for stack use, is available.
  254. copy:    lhld    fncount
  255.     mov    a,h
  256.     ora    l
  257.     dcx    h
  258.     shld    fncount
  259.     jz    done;        no more files
  260.     call    setfiles;    setup input/output file names
  261.     mvi    a,xbadnam
  262.     push    psw
  263.     call    showf;        file names set up
  264.     pop    psw
  265.     jc    exeunt;        Can't setup this name
  266.     lda    confirm
  267.     ora    a
  268.     cz    askcfm
  269.     jz    copy;        ignore, try next
  270.     lhld    outuser;    to l
  271.     lda    inuser
  272.     cmp    l
  273.     lxi    h,fcbout
  274.     lxi    d,fcbin
  275.     cz    cmpfns;        users same, compare file names/drv
  276.     mvi    a,xtoself
  277.     jz    exeunt;        can't copy to self
  278.     lhld    bufsize
  279.     dad    h;        * 2 for input
  280.     mov    c,l
  281.     mov    b,h
  282.     lhld    @inbuff
  283.     lxi    d,fcbin
  284.     lda    inuser
  285.     call    .bfropen;    open buffered input system
  286.     mvi    a,xnofile
  287.     jc    exeunt;        input file not found
  288.     lxi    d,fcbout
  289.     lda    purge
  290.     ora    a
  291.     lda    outuser
  292.     cnz    chkpurge;    Check for erasure of old file
  293.     mvi    a,xsaved
  294.     jnz    copy2;        and treat NO as an error
  295.     call    .crlf
  296.     lda    outuser
  297.     lhld    bufsize
  298.     mov    c,l
  299.     mov    b,h
  300.     lhld    @outbuff
  301.     call    .bfwopen;    open buffered output file
  302.     mvi    a,xnodir
  303.     jc    exeunt;        fopen error
  304.     call    crnch
  305.     jc    copy1
  306.     lhld    filesdone
  307.     inx    h
  308.     shld    filesdone
  309.     jmp    copy;        no error
  310. ;
  311. ; error (a).  If non-terminal delete output file and continue, 
  312. ; otherwise abort everything.
  313. copy1:    call    delout
  314. copy2:    cpi    xstkovf
  315.     jz    exeunt;        abort everything
  316.     call    msgptr
  317.     call    tstr
  318.     jmp    copy
  319. ;
  320. ; purge output file
  321. delout:    push    psw
  322.     push    d
  323.     lda    outuser
  324.     dcr    a
  325.     call    .setusr
  326.     lxi    d,fcbout
  327.     mvi    a,@purge
  328.     call    .dos;        remove the partial file
  329.     pop    d
  330.     pop    psw
  331.     ret
  332. ;
  333. done:    lhld    filesdone
  334.     mov    a,h
  335.     ora    l
  336.     mvi    a,xnofile
  337.     jz    exeunt;        no files found
  338.     call    .crlf
  339.     call    .tdzs
  340.     mvi    a,xok
  341. ;    "    "
  342. ; output message index (a) and exit
  343. exeunt:    call    msgptr
  344.     call    tstr
  345.     lda    entryusr;    restore user at entry
  346.     call    .setusr
  347.     jmp    boot
  348. ;
  349. ; convert error index (a) into pointer (de) to error message
  350. ; a,f,d,e,h,l
  351. msgptr:    lxi    h,errtbl
  352.     add    a
  353.     add    l
  354.     mov    l,a;        point to msgtable entry (a)
  355.     adc    h
  356.     sub    l
  357.     mov    h,a
  358.     mov    e,m;        get pointer to message
  359.     inx    h
  360.     mov    d,m
  361.     ret
  362. ;
  363. ; messages for error codes 0 up
  364. ;        ERROR MESSAGES        ERROR CODES (0 up)
  365. errtbl:    dw    helpmsg,   emptymsg;    xhelp,     xempty
  366.     dw    xcrnmsg,   nomemsg;    xcrn,     xstkovf
  367.     dw    wildmsg,   selfmsg;    xwild,     xtoself
  368.     dw    nodirmsg,  wrterrmsg;    xnodir,     xwrterr
  369.     dw    abtmsg,    badlibmsg;    xusrabt, xbadlib
  370.     dw    ignoremsg, badnamsg;    xsaved,     xbadnam
  371.     dw    nofind,    filesmsg;    xnofile, xok
  372. ;
  373. helpmsg:
  374. db 'FCRLZH v', ver/10 + '0', '.', ver MOD 10 + '0',cr,lf
  375. db    ' Portions by C.B. Falconer',cr,lf
  376. db    ' LZH encoding by R. Warren',cr,lf,lf
  377. ;   1234567-1234567-1234567-1234567-1234567-1234567-1234567-
  378. db '      keep old   quiet  input file',t, 'output file',cr,lf
  379. db t,      '     \     \',t, t,    ' \',t,  t,     '\',cr,lf
  380. db 'FCRLZH  {-{c}{k}{p}{q}} {d{u}:}afnin.aft {d{u}:}{afout.aft} {[id]}'
  381. db cr,lf
  382. db t,      '  /     /',t,   ' /',t, t,     '  /',t, t,     '     /'
  383. db cr,lf
  384. db '   confirm   purge   source',t,'destination',t,t,      'idstring'
  385. db cr,lf,lf
  386. ;   1234567-1234567-1234567-1234567-1234567-1234567-1234567-1234567-
  387. db t,'[idstring] is anything enclosed in []',cr,lf
  388. db t,'default destination is source name with modified "typ"',cr,lf,lf
  389. db 'ex: FCRLZH -p b5:fcopy.* c6:',t,'(LZH encodes to C6: and erases)'
  390. db cr,lf,'$'
  391. xcrnmsg:    db    'File already squeezed/crunched/LZH encoded',cr,lf,'$'
  392. emptymsg:    db    'Empty file',cr,lf,'$'
  393. nomemsg:    db    cr,lf,'Insufficient memory, '
  394. abtmsg:        db    '..ABORTED..$'
  395. wildmsg:    db    'Incompatible wild cards, from/to$'
  396. selfmsg:    db    'Can''t process file to itself$'
  397. nodirmsg:    db    'Can''t create, directory full?$'
  398. wrterrmsg:    db    'Write error, disk full?$'
  399. badlibmsg:    db    'Linked to obsolete library$'
  400. ignoremsg:    db    ' Not erased..',cr,lf,'$'
  401. badnamsg:    db    ' Rename this input file$'
  402. nofind:        db    ' Not found, no'
  403. filesmsg:    db    ' files processed$'
  404. ;
  405. ; mark end-of-line with nul, text buffer de^
  406. ; a,f,h,l
  407. markeol:
  408.     ldax    d
  409.     mov    l,a
  410.     xra    a
  411.     mov    h,a
  412.     dad    d
  413.     inx    h
  414.     mov    m,a;        mark eol
  415.     ret
  416. ;
  417. ; Check for existance of file de^, user a.  If found, query for
  418. ; erasure. Return z flag if not found, or if erasure permitted
  419. ; a,f
  420. chkpurge:
  421.     dcr    a;        Using buffers variant for user
  422.     call    .setusr
  423.     mvi    a,@fopen
  424.     call    .dos
  425.     inr    a
  426.     rz;            not found, all well
  427.     lda    keepem
  428.     ora    a
  429.     jz    chkpg1;        0 is not a Y, no purge
  430.     push    d
  431.     lxi    d,query
  432.     call    tstr
  433.     pop    d
  434.     call    cupsft
  435. chkpg1:    cpi    'Y';        Z flag for permission
  436.     ret
  437. ;
  438. query:    db    ' Exists, ok to purge (y/N) ? $'
  439. qcnfm:    db    ' LZH Encode it (Y/n) ? $'
  440. ;
  441. ; ask to confirm squeezing this file.  Z flag for no
  442. ; a,f
  443. askcfm:    push    d
  444.     lxi    d,qcnfm
  445.     call    tstr
  446.     pop    d
  447. ;    "    "
  448. ; Console input char and kludgy upshift.  Compared to 'N'
  449. ; a,f
  450. cupsft:    mvi    a,cin
  451.     call    .dos
  452.     ani    05fh
  453.     cpi    'N'
  454.     ret
  455. ;
  456. ; make file de^ same name as hl^ (name/ext only) if no spec
  457. ; a,f
  458. sdefault:
  459.     inx    d
  460.     ldax    d
  461.     sui    ' '
  462.     sta    outspec;    non-zero means output specified
  463.     ldax    d
  464.     dcx    d
  465.     rnz
  466.     jmp    .fncpy;        no specification, copy it
  467. ;
  468. ; Column header for noisy display
  469. colhdr:    lxi    d,colmsg
  470. ;    "    "
  471. ; String de^ to console
  472. ; a,f
  473. tstr:    mvi    a,pstrg
  474.     jmp    .dos
  475.  
  476. colmsg:    db    '    in   out ratio    ca    cr',cr,lf
  477.     db    '    ==   === =====    ==    ==',cr,lf,'$'
  478. ;
  479. ; All files open, and buffers assigned.
  480. ; Crunch fcbin to fcbout byte by byte.
  481. crnch:    lda    quiet
  482.     ora    a
  483.     cnz    colhdr
  484.     lxi    h,0
  485.     shld    cksum
  486.     dad    sp
  487.     shld    savesp;        in case of error
  488.     call    header;        Make the standard header
  489.     lxi    h,0;        Zero for..
  490.     shld    incnt;        Input count
  491.     shld    incnt+2;    Input count
  492.     shld    outcnt;        Output count
  493.     shld    outcnt+2;    Output count
  494.     shld    nxtcod;        Needed by display stuff
  495.     shld    ttotal;        Needed by display stuff
  496.  
  497.     lhld    @freemem;    Where to put the tables
  498.     mvi    a,00;        use checksum
  499.     call    crlzh;        invoke
  500.     rc;            error exit
  501.     lhld    cksum
  502.     mov    a,l
  503.     call    outbyt
  504.     mov    a,h
  505.     call    outbyt;        include the checksum
  506.     lhld    @outbuff
  507.     call    .bfclose;    close the output file
  508.     lhld    xtraout
  509.     inx    h
  510.     inx    h
  511.     shld    xtraout;    allow for checksum
  512.     lda    quiet
  513.     ora    a
  514.     rz
  515.     call    show
  516.     call    .blk
  517.     mvi    a,'('
  518.     call    .couta
  519.     call    inout;        hl := input; de := output rcds
  520.     xchg
  521.     call    .dcmp;        flags on hl-de
  522.     xchg
  523.     cnc    chksav;        not smaller
  524.     jnc    crnch8;        not saved, de has message ptr.
  525.     call    dvd8hl;        rounding up
  526.     call    .tdzs;        input kbytes
  527.     xchg
  528.     lxi    d,ktok
  529.     call    tstr
  530.     call    dvd8hl
  531.     call    .tdzs;        output kbytes
  532.     lxi    d,kend
  533. crnch8:    call    tstr
  534.     xra    a;        no error
  535.     ret
  536. ;
  537. ktok:    db    'k --> $'
  538. kend:    db    'k)',cr,lf,'$'
  539. nosave:    db    'Not smaller, not saved)',cr,lf,'$'
  540. ;
  541. ; Check for save of output file.  Forced to no save here
  542. ; Set carry if file to be saved.
  543. ; Reset carry if file purged, when de is message pointer.
  544. ; a,f (de if no save only)
  545. chksav:    call    delout
  546.     ora    a
  547.     lxi    d,nosave
  548.     ret
  549.  
  550. ; setup input/output file names in fcbin/fcbout, using the globals
  551. ; fnptr, tfcb.  Carry if unable to create a suitable file name.
  552. ; a,f,b,c,d,e,h,l
  553. setfiles:
  554.     lxi    d,fcbin
  555.     lhld    fnptr
  556.     call    .nxtfn;        load the next file name
  557.     lxi    d,16
  558.     dad    d
  559.     shld    fnptr;        advance source name pointer
  560.     lxi    d,fcbout;    setup fcbout by
  561.     lxi    h,tfcb;         copying template
  562.     lxi    b,fcbin;     and replacing wild loc'ns
  563.     call    .nxtout
  564.     lda    outspec
  565.     ora    a
  566.     rnz;            file specified
  567. ;    "    "
  568. ; Now modify the output file type
  569.     lxi    h,fcbout+9
  570.     mov    a,m
  571.     cpi    ' '
  572.     jz    setf1;        no extension, make it YYY
  573.     inx    h
  574.     mov    a,m
  575.     cpi    'Y'
  576.     jnz    setf2;        Revised file type to xYx
  577.     mvi    m,'Y'
  578.     inx    h
  579.     mov    a,m
  580.     cpi    'Y'
  581.     jnz    setf2;        xYY does it
  582.     mvi    m,'Y'
  583.     dcx    h
  584.     dcx    h
  585.     mov    a,m
  586.     cpi    'Y'
  587.     jnz    setf2;        YYY does it
  588.     stc
  589.     ret;            Can't rename this file
  590. setf1:    mvi    m,'Y'
  591.     inx    h
  592.     mvi    m,'Y'
  593.     inx    h
  594. setf2:    mvi    m,'Y'
  595.     ora    a;        clear any carry
  596.     ret    
  597. ;
  598. ; show file to be transferred
  599. ; a,f,b,c,d,e,h,l
  600. showf:    lda    quiet
  601.     ora    a
  602.     cnz    .crlf
  603.     lda    inuser
  604.     dcr    a;        to cpm usage
  605.     lxi    d,fcbin
  606.     call    .tfnam;        input file id
  607.     lxi    d,xfrtomsg
  608.     call    tstr;        '==>'
  609.     lda    outuser
  610.     dcr    a;        to cpm usage
  611.     lxi    d,fcbout
  612.     call    .tfnam;        output file id
  613. ;    "    "
  614. ; Check for user abort
  615. ; a,f
  616. ckabt:    mvi    a,csta
  617.     call    .dos
  618.     rz;            no console interrupt
  619.     mvi    a,cin
  620.     call    .dos
  621.     cpi    3
  622.     mvi    a,xusrabt
  623.     jz    exeunt;        user abort
  624.     ret
  625. ;
  626. xfrtomsg:    db    ' ==> $'
  627. ;
  628. ; check fcbs de^ and hl^ are different names, else zero flag
  629. ; a,f
  630. cmpfns:    push    b
  631.     push    d
  632.     push    h
  633.     dcx    h;        pre-decrement
  634.     dcx    d
  635.     mvi    b,12;        names and drive ids
  636. cmpfn1:    inx    h
  637.     inx    d
  638.     ldax    d
  639.     xra    m
  640.     ani    07fh;        ignore attributes
  641.     jnz    cmpfn2
  642.     dcr    b
  643.     jnz    cmpfn1
  644. cmpfn2:    pop    h
  645.     pop    d
  646.     pop    b
  647.     ret
  648. ;
  649. ; Make a standard crunched file header
  650. header:    mvi    a,crnchid shr 8
  651.     ora    a;        set nz, no display yet
  652.     call    outbyt
  653.     mvi    a,crnchid AND 0ffh
  654.     ora    a;        set nz, no display yet
  655.     call    outbyt
  656.     lxi    h,3;        2 already, 0 byte coming
  657.     xchg
  658.     lxi    h,fcbin
  659.     call    outnm;        mark the source file id
  660.     lxi    h,stamp
  661.     call    outstg;        emit the user stamp
  662.     xchg
  663.     shld    xtraout;    save string size etc.
  664.     ori    0ffh;        reset z flag
  665.     mvi    a,0;        emit the 0 string terminator
  666. ;    "    "
  667. ; output a to buffered output file.  Savesp initialized. 
  668. ; Input Z flag triggers display mechanism.  CRN module linkage
  669. ; a,f,c
  670. plzhen:
  671.     push    psw;        save
  672.     push    h
  673.     lhld    outcnt
  674.     inx    h
  675.     shld    outcnt
  676.     mov    a,h
  677.     ora    l
  678.     jnz    obm1
  679.     lhld    outcnt+2
  680.     inx    h
  681.     shld    outcnt+2
  682. obm1:    pop    h;        restore
  683.     pop    psw
  684. outbyt:    mov    c,a
  685.     push    h
  686.     cz    show;        display statistics etc.
  687.     lhld    @outbuff
  688.     call    .bfputc
  689.     pop    h
  690.     rnc;            no error
  691.     lhld    savesp
  692.     sphl
  693.     mvi    a,xwrterr
  694.     jmp    exeunt;        i/o error
  695. ;
  696. ; Linkage for crn module
  697. ; a,f,h,l
  698. glzhen:
  699.     push    psw;        Save it
  700.     lhld    incnt
  701.     inx    h
  702.     shld    incnt
  703.     mov    a,h
  704.     ora    l
  705.     jnz    glzhcr
  706.     lhld    incnt+2
  707.     inx    h
  708.     shld    incnt+2
  709. glzhcr:    pop    psw;        Restore it
  710. getchr:    lhld    @inbuff
  711.     call    .bfgetc;    get a byte.  Carry for eof.
  712.     rc;            no checksum update at eof
  713.     lhld    cksum
  714.     push    psw
  715.     add    l
  716.     mov    l,a
  717.     adc    h
  718.     sub    l
  719.     mov    h,a
  720.     shld    cksum
  721.     pop    psw
  722.     ret
  723. ;
  724. ; Output string hl^ until 0 byte. Countem in de
  725. ; a,f,c,h,l
  726. outstg:    mov    a,m
  727.     ora    a
  728.     rz
  729.     inx    d;        count chars
  730.     call    outbyt;        nz flag, will not trip display
  731.     inx    h
  732.     jmp    outstg
  733. ;
  734. ; Output file name hl^.  Full blank fill the type field
  735. outnm:    push    b
  736.     mvi    b,8;        max chars in file name
  737.     push    h;        save start point
  738. outnm1:    inx    h
  739.     mov    a,m
  740.     inx    d;        count chars emitted
  741.     cpi    ' '
  742.     jz    outnm2;        done file name
  743.     call    outbyt;        nz, no display trip
  744.     dcr    b
  745.     jnz    outnm1
  746.     inx    d;        for coming '.'
  747. outnm2:    mvi    a,'.'
  748.     ora    a;        nz, prevent display
  749.     call    outbyt
  750.     pop    h;        get start point back
  751.     lxi    b,8;        point to type field
  752.     dad    b
  753.     mvi    b,3
  754. outnm3:    inx    h
  755.     mov    a,m
  756.     inx    d
  757.     ora    a;        nz, prevent display
  758.     call    outbyt
  759.     dcr    b
  760.     jnz    outnm3
  761.     pop    b
  762.     ret
  763. ;
  764. ; Get input/output records to hl, de respectively
  765. ; a,f,d,e,h,l
  766. inout:    lhld    incnt+1;    LS byte is zero
  767.     dad    h;        double, in records
  768.     lda    incnt
  769.     add    a
  770.     jnc    inout1;        not an extra record
  771.     inx    h
  772. inout1:    adi    252;        2 * (127-1). EOF was counted at end.
  773.     jnc    inout2;        no partial record to round up
  774.     inx    h
  775. inout2:    push    h
  776.     lhld    outcnt;        only useful at end
  777.     mvi    h,0
  778.     xchg
  779.     lhld    xtraout
  780.     dad    d
  781.     lxi    d,127;        round up to records
  782.     dad    d
  783.     dad    h;        double, records to h
  784.     mov    a,h;        additional
  785.     lhld    outcnt+1;    LS byte is zero
  786.     dad    h;        double, to records
  787.     add    l
  788.     mov    l,a;        + the extra bits
  789.     adc    h
  790.     sub    l
  791.     mov    h,a;        form records emitted (rounded up)
  792.     xchg
  793.     pop    h
  794.     ret
  795. ;
  796. ; Show any statistics etc.
  797. ; a,f,h,l
  798. show:    call    ckabt;        check for user abort
  799.     lda    quiet
  800.     ora    a
  801.     rz;            in quiet mode
  802.     push    b
  803.     push    d
  804.     mvi    a,cr
  805.     call    .couta
  806.     call    inout;        get input/output records
  807.     call    tdzs6f;        show input records
  808.     push    h
  809.     xchg
  810.     call    tdzs6f;        show output records
  811.     xchg
  812.     lxi    b,200;        for rounding
  813.     call    .imul;        dehl := de*bc
  814.     pop    b
  815.     call    .idiv;        de := dehl/bc = input/output*200
  816.     xchg
  817.     inx    h;        round result
  818.     call    dvd2hl;        divide / 2 (for 200 above)
  819.     mvi    a,5
  820.     call    .tdzsf
  821.     mvi    a,'%'
  822.     call    .couta
  823.     lhld    nxtcod
  824.     call    tdzs6f
  825.     lhld    ttotal
  826.     call    tdzs6f
  827.     pop    d
  828.     pop    b
  829.     ret
  830. ;
  831. ; Shift hl right 3 (divide by 8), rounding up
  832. ; a,f,h,l
  833. dvd8hl:    push    d
  834.     lxi    d,7
  835.     dad    d
  836.     pop    d
  837.     call    dvd2hl
  838.     call    dvd2hl
  839. ;    "    "
  840. ; Shift hl right 1.  RH bit to carry
  841. ; a,f,h,l
  842. dvd2hl:    mov    a,h
  843.     ora    a
  844.     rar
  845.     mov    h,a
  846.     mov    a,l
  847.     rar
  848.     mov    l,a
  849.     ret
  850. ;
  851. ; Write hl (dec) in 6 char. field. with at least 1 leading blank
  852. ; a,f
  853. tdzs6f:    mvi    a,6
  854.     jmp    .tdzsf
  855. ;
  856. ; Parse the command tail into the stamp buffer
  857. ; a,f,b,d,e,h,l
  858. rstamp:    lxi    h,stamp
  859.     call    .skipblks
  860.     rc;            EOL, no tail
  861.     cpi    '['
  862.     rnz;            not a valid marker
  863.     mvi    b,stpmax-1
  864. rstp1:    dcr    b
  865.     jz    rstp2;        max storage used
  866.     mov    m,a
  867.     inx    h
  868.     cpi    ']'
  869.     jz    rstp3
  870.     inx    d;        (CCP+ can allow lc command tails)
  871.     ldax    d;        not .nextch, don't upshift
  872.     cpi    ' '
  873.     jnc    rstp1
  874. rstp2:    mvi    m,']';        jam in the missing ']'
  875.     inx    h
  876. rstp3:    mvi    m,0;        default EOL
  877.     ret
  878. ;
  879. ; Lock the user # (0 means default) to an absolute value.
  880. ; Returns in range 1..maxuser, and cpm calls use this -1.
  881. ; This is because the buffer system can record "default user"
  882. ; as distinct from "specified user".
  883. ; a,f
  884. usrlok:    call    .xltusr;    now range 0..maxuser
  885.     inr    a;        now 0 is forbidden.
  886.     ret
  887. ;
  888.         dseg;    LINK AFTER all code areas
  889. incnt:        ds    4;    Input count
  890. outcnt:        ds    4;    Output count
  891. nxtcod:        ds    2;    Needed by display stuff
  892. ttotal:        ds    2;    Needed by display stuff
  893. options:    ds    2;    Standard header
  894. confirm:    ds    1;    Flog for confirmation per file
  895. keepem:        ds    1;    Flag to keep old files
  896. purge:        ds    1;    Flag for copy verification
  897. quiet:        ds    1;    flag for quiet operation
  898.     if    ($-options)-2 ne optlgh
  899.      +++ Error in option storage assignment +++
  900.     endif
  901. ;
  902. entryusr:    ds    1;    User in effect at startup
  903. outspec:    ds    1;    non-zero if output file specified
  904. ;
  905. ; inuser/outuser are 0 for current user, user+1 if specified
  906. inuser:        ds    1;    User # for fcbin
  907. outuser:    ds    1;    User # for fcbout
  908. ;
  909. fcbin:        ds    36;    Input fcb
  910. fcbout:        ds    36;    Output fcb
  911. bufsize:    ds    2;    space available for outbuff
  912. @inbuff:    ds    2;    pointer to input buffer, 2 * bufsize
  913. @outbuff:    ds    2;    pointer to output buffer, 1 * bufsize
  914. @freemem:    ds    2;    pointer to available memory
  915. cksum:        ds    2;    for checksum accumulation
  916. filesdone:    ds    2;    count of files processed
  917. fncount:    ds    2;    count of files to process
  918. fnptr:        ds    2;    pointer to NEXT file to process
  919. savesp:        ds    2;    for aborts during writes
  920. xtraout:    ds    2;    keep track of overhead bytes added
  921. stamp:        ds    stpmax;    User entered stamp
  922.         end
  923.