home *** CD-ROM | disk | FTP | other *** search
/ norge.freeshell.org (192.94.73.8) / 192.94.73.8.tar / 192.94.73.8 / pub / computers / pcjr / arc / ARCV117.LZH / ARCV117.ASM next >
Assembly Source File  |  1987-01-27  |  18KB  |  885 lines

  1.     page    80,132
  2.     title    ARCV - Verbose ARC directory listing
  3.  
  4. ; history:
  5. ;    version 1.00 - 1/5/86
  6. ;    version 1.03 - 1/10/86
  7. ;        released for general use
  8. ;    version 1.04 - 1/19/86
  9. ;        make displays MS-DOS compatible
  10. ;    version 1.05 - 1/23/86
  11. ;        supports ARC 5.0 new formats
  12. ;    version 1.06 - 1/26/86
  13. ;        correct total SF
  14. ;    version 1.07 - 3/22/86
  15. ;        change open for input only
  16. ;    version 1.08 - 3/28/86
  17. ;        correct zero divide problem
  18. ;    version 1.09 - 4/08/86
  19. ;        check SF for funny archives
  20. ;    version 1.10 - 4/18/86
  21. ;        correct divide overflow problem
  22. ;    version 1.11 - 4/23/86
  23. ;        correct stowage factor
  24. ;    version 1.12 - 4/26/86
  25. ;        correct sending totals for no files
  26. ;    version 1.13 - 5/11/86
  27. ;        expand search for header arcmark
  28. ;    version 1.14 - 5/21/86
  29. ;        change for 'No files found' error on clones
  30. ;    version 1.15 - 6/14/86
  31. ;        use 'filename' if no files found to use DPATH
  32. ;    version 1.16 - 12/31/86
  33. ;        add entry for type 9 format, squashing
  34. ;    version 1.17 - 1/27/86
  35. ;        add DOS 3.x file sharing
  36.  
  37.     .xlist
  38. print    macro    name            ; display a field
  39.     mov    dx,offset name
  40.     call    prints
  41.     endm
  42.  
  43. printl    macro    text            ; display a literal
  44.     local    txt,nxt
  45.     mov    dx,offset txt
  46.     call    prints
  47.     jmp    nxt
  48. txt    db    cr,lf,text
  49.     db    stopper
  50. nxt    equ    $
  51.     endm
  52.  
  53. beep    macro                ; sound the horn
  54.     mov    dl,7
  55.     mov    ah,2
  56.     int    21h
  57.     endm
  58.     .list
  59.  
  60. header    struc                ; archive header
  61. mbrcode db    0            ;  compression code
  62. mbrname db    13 dup (0)        ;  file name
  63. mbrsize dw    0,0            ;  file size in archive
  64. mbrdate dw    0            ;  creation date
  65. mbrtime dw    0            ;  creation time
  66. mbrcrc    dw    0            ;  cyclic redunancy check
  67. mbrlen    dw    0,0            ;  true file size, bytes
  68. header    ends
  69.  
  70.  
  71. cseg    segment public para 'CODE'
  72.     assume    cs:cseg,ds:cseg,es:cseg
  73.     org    100h
  74.  
  75. arcv    proc    far
  76.     mov    stkptr,sp        ; save stack ptr
  77.     mov    ah,30h            ; get dos version
  78.     int    21h
  79.     mov    dosver,al        ; save for open checks
  80.     cmp    al,2            ; version 2 or later?
  81.     jb    badver            ; no, gotta quit
  82.     jmp    start            ; do our thing
  83.  
  84. ;    return with error
  85.  
  86. badver: print    vermsg            ; version 2 red'q
  87. error:    mov    ax,cs            ; insure seg regs
  88.     mov    ds,ax            ;  for proper exit
  89.     mov    sp,cs:stkptr
  90.     mov    errlvl,1        ; set bad return code
  91.     beep
  92.     jmp    arcv2a            ; produce totals anyway
  93.  
  94. ;    set DOS error level and exit
  95.  
  96. exit:    mov    sp,cs:stkptr        ; just in case
  97.     mov    al,errlvl        ; return code
  98.     mov    ah,4ch            ; exit function
  99.     int    21h
  100.  
  101.     subttl    '--- constants, equates and work areas'
  102.     page
  103.  
  104. cr    equ    13
  105. lf    equ    10
  106. bel    equ    7
  107. tab    equ    9
  108.  
  109. stopper equ    0        ; end of display line indicator
  110. arcmark equ    26        ; special archive marker
  111. arcver    equ    9        ; highest compression code used
  112.  
  113. stkptr    dw    0        ; stack pointer upon entry
  114. errlvl    db    0        ; dos error level returned
  115. flags    db    0        ; find-first return code
  116. dosver    db    0        ; major dos version
  117. archdl    dw    0        ; file handle
  118.  
  119. arctitl db    cr,lf,'Archive:  '
  120. arcname db    76 dup (stopper)
  121.  
  122. fileptr dw    0        ; ptr to filename part of arcname
  123.  
  124.     subttl    '--- i/o control variables'
  125.     page
  126.  
  127. usage    db    cr,lf
  128.     db    'ARCV 1.17 - Verbose ARC directory display - V.Buerg'
  129.     db    cr,lf,lf,'  Usage:  arcv [d:][\path\]filespec[.ARC]'
  130.     db    cr,lf,stopper
  131.  
  132. vermsg    db    cr,lf,'Wrong DOS version',cr,lf,stopper
  133.  
  134. inbufsz equ    30        ; size of input buffer, seems best
  135. inadr    dw    offset inbuf    ; offset to input buffer
  136. inptr    dw    offset inbuf    ; offset to current byte
  137. insize    dw    inbufsz     ; size of input buffer
  138. inlen    dw    0        ; bytes left in buffer
  139.  
  140. ;    display lines for verbose
  141.  
  142. vhdr    db    cr,lf
  143.     db    cr,lf,'Name          Length    Stowage    SF   Size now  Date       Time    CRC '
  144.     db    cr,lf,'============  ========  ========  ====  ========  =========  ======  ===='
  145.     db    stopper
  146.  
  147. vline    db    cr,lf
  148. vname    db    14 dup (' ')
  149. vlength db    '       0  '    ; length in archive
  150. vstyle    db    '          '    ; compression method
  151. vfactor db    ' xx%  '        ; compression factor
  152. vsize    db    10 dup (' ')    ; actual file bytes
  153. vdate    db    'dd '           ; creation date
  154.  vmonth db    'mmm '
  155.  vyear    db    'yy  '
  156.  vtime    db    'hh:mm   '      ; creation time
  157.  vcrc    db    'xxxx'          ; crc in hex
  158.     db    stopper
  159.  
  160. hundred dw    100        ; for computing percentages
  161. totsf    dw    0,0        ; average stowage factor
  162. totlen    dw    0,0        ; total of file lengths
  163. totsize dw    0,0        ; total of file sizes
  164. totmbrs dw    0        ; total number of files
  165.  
  166. ;    final totals line
  167.  
  168. vthdr    db    cr,lf,'*total    '
  169.  vtmbrs db    '    '
  170.  vtlen    db    8 dup (' '),'  '
  171.     db    10 dup (' ')
  172.  vtsf    db    '   %  '
  173.  vtsize db    8 dup (' ')
  174.     db    cr,lf        ; for tom
  175.     db    stopper
  176.  sign    db    ' '
  177.  
  178. styles    db    '  ----- '      ; 1 = old, no compression
  179.     db    '  ----- '      ; 2 = new, no compression
  180.     db    ' Packed '      ; 3 = dle for repeat chars
  181.     db    'Squeezed'      ; 4 = huffman encoding
  182.     db    'crunched'      ; 5 = lz, no dle
  183.     db    'crunched'      ; 6 = lz with dle
  184.     db    'Crunched'      ; 7 = lz with readjust
  185.     db    'Crunched'      ; 8 = lz with readjust and dle
  186.     db    'Squashed'      ; 9 = modified lzw, no dle
  187.  
  188. months    db    'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec '
  189.  
  190.     subttl    '--- mainline processing'
  191.     page
  192. ;
  193. ;    determine if command line or menu driven mode
  194.  
  195. start:
  196.     mov    si,80h            ; offset to command line
  197.     sub    cx,cx
  198.     or    cl,byte ptr [si]    ; any operand?
  199.     jnz    parm1
  200.     print    usage
  201.     jmp    exit
  202.  
  203. ;    copy firt command line operand
  204.  
  205. parm1:    inc    si            ; point to operand
  206. parm2:    lodsb                ; strip leading blanks
  207.     cmp    al,' '
  208.     loope    parm2
  209.     mov    di,offset arcname
  210.     stosb
  211. parm3:    lodsb                ; copy filename
  212.     cmp    al,cr            ; end of name?
  213.     je    parm4
  214.     cmp    al,' '                  ; don't know why this is here
  215.     je    parm4
  216.     stosb
  217.     loop    parm3
  218. parm4:
  219.     mov    si,offset arcname+75    ; end of filename stuff
  220.     std
  221.     mov    cl,76            ; search for last path
  222. parm5:
  223.     lodsb
  224.     cmp    al,'/'                  ; funny path delimiter?
  225.     je    parm6
  226.     cmp    al,'\'                  ; normal path delimiter?
  227.     je    parm6
  228.     cmp    al,':'                  ; bumped into drive?
  229.     je    parm6
  230.     loop    parm5
  231.     dec    si
  232. parm6:
  233.     cld
  234.     add    si,2            ; point to where filename goes
  235.     mov    fileptr,si        ; and save for later
  236.  
  237. ;    add default ARC extension if necessary
  238.  
  239.     mov    si,fileptr        ; start of filespec
  240.     mov    cx,13
  241. parm10:
  242.     lodsb
  243.     cmp    al,0            ; end of name?
  244.     je    parm11
  245.     cmp    al,'.'                  ; got extension?
  246.     je    parm12
  247.     loop    parm10
  248. parm11:
  249.     mov    di,si            ; ptr to end of name
  250.     dec    di
  251.     mov    ax,'A.'                 ; default extension
  252.     stosw
  253.     mov    ax,'CR'
  254.     stosw
  255.     mov    ax,0FF00h        ; append stoppers
  256.     stosw
  257. parm12:
  258.  
  259. ;    find first matching file
  260.  
  261. getfirst:
  262.     mov    dx,offset dta        ; set local dta for murkers
  263.     mov    ah,1ah
  264.     int    21h
  265.  
  266.     mov    dx,offset arcname    ; find first matching file
  267.     sub    cx,cx            ; normal attribute
  268.     mov    ah,4eh
  269.     int    21h
  270.     mov    flags,al        ; indicate find-first status
  271.     or    ax,ax            ; any return code?
  272.     jz    parm7
  273.     jmp    not_found        ; in case of DPATH utility
  274. nofiles:
  275.     printl    'No file(s) found'
  276.     jmp    error
  277.  
  278. getnext:
  279.     mov    ah,4fh            ; get next file name
  280.     int    21h
  281.     jc    alldone
  282.     or    ax,ax
  283.     jz    parm7
  284. alldone:
  285.     jmp    exit
  286.  
  287. ;    set up next matching file name
  288.  
  289. parm7:
  290.     mov    si,offset dta+30    ; point to filename found
  291.     mov    di,fileptr        ; and overlay old name
  292.     mov    cx,13
  293.     rep    movsb
  294.  
  295. ;    re-initialize
  296.  
  297. not_found:
  298.     sub    ax,ax            ; reset totals counters
  299.     mov    totmbrs,ax
  300.     mov    totsize,ax
  301.     mov    totsize+2,ax
  302.     mov    totlen,ax
  303.     mov    totlen+2,ax
  304.     mov    totsf,ax
  305.     mov    inlen,ax
  306.     mov    dx,offset inbuf
  307.     mov    inptr,dx
  308.  
  309.     call    openarc         ; see if archive exists
  310.     jnc    arcv1
  311.     ret
  312.  
  313.     page
  314. ;
  315. ;    process next archive header entry
  316.  
  317. arcv1:    print    arctitl
  318.     print    vhdr
  319.  
  320. arcvnext:
  321.     call    gethdr            ; load next header
  322.     jnc    arcv2
  323.     jmp    exit            ; all done
  324.  
  325. arcv2:    cmp    archdr.mbrcode,0    ; archive eof?
  326.     je    arcv2a
  327.     jmp    arcvgo
  328.  
  329. arcv2a:
  330.     mov    ax,totmbrs        ; total files
  331.     or    ax,ax            ; are there any?
  332.     jnz    format_totals
  333.     jmp    skip_totals
  334.  
  335. format_totals:
  336.     sub    dx,dx
  337.     mov    si,offset vtmbrs-4
  338.     call    format
  339.  
  340.     mov    dx,totlen+2        ; total actual file size
  341.     mov    ax,totlen
  342.     mov    si,offset vtlen
  343.     call    format
  344.  
  345.     mov    dx,totsize+2        ; total achive file size
  346.     mov    ax,totsize
  347.     mov    si,offset vtsize
  348.     call    format
  349.  
  350. ; reduce the total size/length to word values
  351.  
  352.     mov    bx,totlen        ; get actual file size
  353.     mov    ax,totlen+2
  354.     mov    cx,totsize        ; length of file in archive
  355.     mov    dx,totsize+2
  356. arcv2b: or    ax,ax            ; big number?
  357.     jz    arcv2c            ; nope, can use it
  358.     shr    ax,1            ; yup, divide by two
  359.     rcr    bx,1
  360.     shr    dx,1
  361.     rcr    cx,1
  362.     jmp    short arcv2b
  363.  
  364. arcv2c: mov    si,offset vtsf-5    ; format stowage factor
  365.     mov    ax,bx
  366.     mov    sign,' '                ; whata kludge
  367.     cmp    ax,cx            ; arc is bigger than orig?
  368.     jb    arcv2c1
  369.     sub    ax,cx            ; amount saved
  370.     jmp    short arcv2f
  371. arcv2c1:
  372.     sub    ax,cx
  373.     neg    ax
  374.     mov    sign,'-'
  375. arcv2f:
  376.     mul    hundred         ; to percentage
  377.     add    ax,50
  378.     adc    dx,0            ; round up percent
  379.     or    bx,bx            ; empty file?
  380.     jnz    arcv2d
  381.     mov    ax,100
  382.     jmp    short arcv2e
  383.  
  384. arcv2d: div    bx
  385. arcv2e: sub    dx,dx
  386.     call    format
  387.  
  388.     mov    al,sign
  389.     mov    vtsf,al
  390.     print    vthdr            ; display totals
  391.  
  392. skip_totals:
  393.     call    closarc
  394.     jmp    getnext
  395.  
  396.     page
  397. ;
  398. ;    format single line for each member
  399.  
  400. arcvgo:
  401.     mov    di,offset vname     ; copy file name
  402.     mov    si,offset archdr.mbrname
  403.     mov    cx,13
  404. arcv3:
  405.     lodsb
  406.     cmp    al,0            ; end of name?
  407.     je    arcv4
  408.     stosb
  409.     loop    arcv3
  410.     jmp    short arcv5
  411. arcv4:
  412.     mov    al,' '                  ; pad with blanks
  413.     rep    stosb
  414. arcv5:
  415.     inc    totmbrs
  416.  
  417. ; reduce the size/length to word values
  418.  
  419.     mov    bx,archdr.mbrlen    ; get actual file size
  420.     mov    ax,archdr.mbrlen+2
  421.  
  422.     mov    cx,archdr.mbrsize    ; length of file in archive
  423.     mov    dx,archdr.mbrsize+2
  424.  
  425. arcv51: or    ax,ax            ; big number?
  426.     jz    arcv52            ; nope, can use it
  427.     shr    ax,1            ; yup, divide by two
  428.     rcr    bx,1
  429.     shr    dx,1
  430.     rcr    cx,1
  431.     jmp    short arcv51
  432.  
  433. arcv52: mov    si,offset vfactor-5    ; format stowage factor
  434.     mov    ax,bx            ; low word of actual size
  435.     mov    sign,' '
  436.     cmp    ax,cx            ; arc member is larger?
  437.     jb    arcv520
  438.     sub    ax,cx            ; amount saved
  439.     jmp    arcv56
  440. arcv520:
  441.     sub    ax,cx
  442.     neg    ax
  443.     mov    sign,'-'
  444. arcv56:
  445.     mul    hundred         ; to percentage
  446.     add    ax,50
  447.     adc    dx,0            ; round up percent
  448.     or    bx,bx            ; empty file?
  449.     jnz    arcv53
  450.     mov    ax,100
  451.     jmp    short arcv54
  452.  
  453. arcv53: div    bx
  454. arcv54: sub    dx,dx
  455.     cmp    ax,100            ; archive fouled?
  456.     jbe    arcv55
  457.     sub    ax,ax
  458. arcv55:
  459.     call    format
  460.     mov    al,sign
  461.     mov    vfactor,al
  462.  
  463.     sub    bx,bx            ; determine style
  464.     mov    bl,archdr.mbrcode
  465.     mov    cl,3            ; eight bytes each entry
  466.     shl    bx,cl
  467.     lea    si,styles-8[bx]     ; get ptr to style name
  468.     mov    di,offset vstyle
  469.     mov    cx,8
  470.     rep    movsb
  471.  
  472.     mov    si,offset vsize     ; format file size
  473.     mov    dx,archdr.mbrsize+2
  474.     mov    ax,archdr.mbrsize
  475.     add    totsize,ax
  476.     adc    totsize+2,dx
  477.     call    format
  478.  
  479.     mov    si,offset vlength    ; format file length
  480.     mov    dx,archdr.mbrlen+2
  481.     mov    ax,archdr.mbrlen
  482.     add    totlen,ax
  483.     adc    totlen+2,dx
  484.     call    format
  485.  
  486.     mov    ax,archdr.mbrdate    ; format file date
  487.     call    getdate
  488.  
  489.     mov    ax,archdr.mbrtime    ; format file time
  490.     call    gettime
  491.  
  492.     mov    ax,archdr.mbrcrc    ; format crc in hex
  493.     mov    di,offset vcrc
  494.     call    cvh
  495.  
  496.     print    vline            ; display this file info
  497.  
  498.     mov    cx,word ptr archdr.mbrsize+2
  499.     mov    dx,word ptr archdr.mbrsize
  500.     sub    dx,inlen        ; less bytes read/unprocessed
  501.     sbb    cx,0
  502.     mov    ax,4201h        ; skip over file data
  503.     mov    bx,archdl
  504.     int    21h
  505.     mov    inlen,0         ; reset read buffer
  506.     jmp    arcvnext
  507.  
  508.     subttl    ' - miscellaneous subroutines'
  509.     page
  510.  
  511. openarc proc    near            ; open new archive
  512.     push    bx
  513.     mov    dx,offset arcname
  514.     mov    ax,3d00h        ; for input
  515.     cmp    dosver,3        ; can we share?
  516.     jb    noshare
  517.     or    al,40h            ; yes, deny none
  518. noshare:
  519.     int    21h            ; issue open
  520.     jc    openerr
  521.     mov    archdl,ax        ; save file handle
  522.     clc
  523.     pop    bx
  524.     ret
  525. openerr:
  526.     cmp    flags,0         ; find-first or open?
  527.     je    open_err
  528.     jmp    nofiles
  529. open_err:
  530.     printl    'Unable to open archive: '
  531.     print    arcname
  532.     jmp    error
  533. openarc endp
  534.  
  535.  
  536. closarc proc    near
  537.     push    bx
  538.     mov    bx,archdl        ; previous handle
  539.     or    bx,bx            ; already open?
  540.     jz    closed
  541.     mov    ah,3eh            ; yes, so close it
  542.     int    21h
  543. closed: mov    archdl,0
  544.     pop    bx
  545.     ret
  546. closarc endp
  547.  
  548. ;
  549. ;    print string like int 21h function 9
  550.  
  551. prints    proc    near            ; dx has offset to string
  552.     push    si            ;  ending in char x'ff'
  553.     push    bx
  554.     push    cx
  555.     mov    si,dx
  556.     sub    cx,cx
  557. ps1:    lodsb
  558.     cmp    al,stopper        ; ending hex ff?
  559.     je    ps9
  560.     inc    cx            ; incr text length
  561.     jmp    ps1
  562.  
  563. ps9:    mov    ah,40h            ; write to file
  564.     mov    bx,1            ; using std out
  565.     int    21h
  566.  
  567.     pop    cx            ; recover registers
  568.     pop    bx
  569.     pop    si
  570.     ret
  571. prints    endp
  572.  
  573.     page
  574. ;
  575. ;    format the time
  576.  
  577. time    record    hour:5,min:6,sec:5    ;packed time
  578.  
  579. gettime proc    near            ;format the date
  580.     mov    di,offset vtime
  581.     or    ax,ax            ;it is zero?
  582.     jz    gottime
  583.     push    ax            ;save date
  584.     and    ax,mask hour        ;get hour part
  585.     mov    cl,hour         ;bits to shift
  586.     shr    ax,cl
  587.     call    cnvrt1
  588.     stosw
  589.     mov    al,':'
  590.     stosb
  591.  
  592. gt3:    pop    ax            ;get the time back
  593.     and    ax,mask min        ;get min part
  594.     mov    cl,min            ;bits to shift
  595.     call    cnvrt
  596.     stosw
  597. gottime:ret
  598. gettime endp
  599.  
  600. cnvrt2    proc    near            ;convert to ascii
  601.     call    cnvrt
  602.     cmp    al,'0'                  ;suppress leading zero
  603.     jne    cnvrtd
  604.     mov    al,' '
  605.     ret
  606.  
  607. cnvrt:    shr    ax,cl
  608. cnvrt1: aam                ;make al into bcd
  609.     or    ax,'00'                 ; and to ascii
  610.     xchg    al,ah
  611. cnvrtd: ret
  612. cnvrt2    endp
  613.  
  614.     page
  615. ;
  616. ;    format the date
  617.  
  618. date    record    yr:7,mo:4,dy:5        ;packed date
  619.  
  620. getdate proc    near            ;format the date
  621.     or    ax,ax            ;is it zero?
  622.     jz    gotdate
  623.     push    ax            ;save date
  624.     and    ax,mask yr        ;get year part
  625.     mov    cl,yr            ;bits to shift
  626.     call    cnvrt
  627.     mov    di,offset vyear
  628.     or    al,'8'                  ;adjust for base year
  629.     stosw
  630.  
  631.     pop    bx            ;get the date back
  632.     push    bx            ;save it
  633.     and    bx,mask mo        ;get month part
  634.     mov    cl,mo            ;bits to shift
  635.     shr    bx,cl
  636.     add    bx,bx            ; form month table index
  637.     add    bx,bx
  638.     lea    si,word ptr months-4[bx]
  639.     mov    cx,3
  640.     mov    di,offset vmonth
  641.     rep    movsb
  642.  
  643.     pop    ax            ;get the date back
  644.     and    ax,mask dy        ;get day part
  645.     mov    cl,dy            ;bits to shift
  646.     call    cnvrt
  647.     mov    di,offset vdate
  648.     stosw
  649. gotdate:ret
  650. getdate endp
  651.  
  652.     page
  653. ;
  654. ; ripped from sdir.asm. how does this work?
  655.  
  656. ddptr    dw    0
  657.  
  658. format    proc    near    ;formats a 32 bit integer in dx:ax
  659.     push    bp    ; to ds:si
  660.     push    bx
  661.     push    di
  662.     push    si
  663.     mov    ddptr,si    ;addr of target field
  664.     mov    di,dx        ;routine uses di:si
  665.     mov    si,ax
  666.     call    printdd
  667.     pop    si
  668.     pop    di
  669.     pop    bx
  670.     pop    bp
  671.     ret
  672.  
  673. printdd:
  674.     xor    ax,ax        ;zero out the
  675.     mov    bx,ax        ; working
  676.     mov    bp,ax        ; registers.
  677.     mov    cx,32        ;# bits of precision
  678. j1:    shl    si,1
  679.     rcl    di,1
  680.     xchg    bp,ax
  681.     call    j6
  682.     xchg    bp,ax
  683.     xchg    bx,ax
  684.     call    j6
  685.     xchg    bx,ax
  686.     adc    al,0
  687.     loop    j1
  688.     mov    cx,1710h
  689.     mov    ax,bx
  690.     call    j2
  691.     mov    ax,bp
  692. j2:    push    ax
  693.     mov    dl,ah
  694.     call    j3
  695.     pop    dx
  696. j3:    mov    dh,dl
  697.     shr    dl,1        ;move high
  698.     shr    dl,1        ; nibble to
  699.     shr    dl,1        ; the low
  700.     shr    dl,1        ; position.
  701.     call    j4
  702.     mov    dl,dh
  703. j4:    and    dl,0fh        ;mask low nibble
  704.     jz    j5        ;if not zero
  705.     mov    cl,0
  706. j5:    dec    ch
  707.     and    cl,ch
  708.     or    dl,'0'          ;fold in ascii zero
  709.     sub    dl,cl
  710.     mov    bx,ddptr
  711.     mov    [bx],dl     ;ptr to next target field
  712.     inc    ddptr
  713.     ret
  714.  
  715. j6:    adc    al,al
  716.     daa
  717.     xchg    al,ah
  718.     adc    al,al
  719.     daa
  720.     xchg    al,ah
  721.     ret
  722. format    endp
  723.  
  724.     page
  725. cvh    proc    near        ; convert 16-bit binary word in ax
  726.     push    di        ; to hex ASCII string at ds:di
  727.     push    bx        ; save registers
  728.     push    cx
  729.     push    dx
  730.  
  731.     mov    dx,ax        ; save 16-bits
  732.  
  733.     mov    bl,dh        ; third nibble
  734.     mov    cl,4
  735.     shr    bl,cl
  736.     mov    al,hexchar[bx]
  737.     stosb
  738.  
  739.     mov    bl,dh        ; last nibble
  740.     and    bl,0fh
  741.     mov    al,hexchar[bx]
  742.     stosb
  743.  
  744.     mov    bl,dl        ; first nibble
  745.     mov    cl,4
  746.     sub    bh,bh
  747.     shr    bl,cl        ; isolate
  748.     mov    al,hexchar[bx]
  749.     stosb
  750.  
  751.     mov    bl,dl        ; second nibble
  752.     and    bl,0fh        ; isolate
  753.     mov    al,hexchar[bx]
  754.     stosb
  755.     pop    dx        ; restore registers
  756.     pop    cx
  757.     pop    bx
  758.     pop    di
  759.     ret            ; return
  760.  
  761. hexchar db    '0123456789ABCDEF'
  762. cvh    endp
  763.  
  764.     subttl    ' - i/o subroutines'
  765.     page
  766.  
  767. getc    proc    near            ; return next byte in al
  768.     push    si            ;  or cf=1 for eof
  769. getc1:
  770.     dec    inlen            ; any left in buffer
  771.     jl    getc2            ; yes, pick it up
  772.     mov    si,inptr        ; offset to next byte
  773.     lodsb
  774.     mov    inptr,si
  775.     pop    si
  776.     ret
  777. getc2:
  778.     call    getblk            ; read next block
  779.     jnc    getc1
  780.     pop    si            ; return cf=1 at eof
  781.     ret
  782. getc    endp
  783.  
  784.  
  785. getblk    proc    near            ; read next block
  786.     push    bx
  787.     push    cx
  788.     push    dx
  789.     mov    ah,3fh            ; read from handle
  790.     mov    bx,archdl        ; arc file handle
  791.     mov    cx,inbufsz        ; input buffer size
  792.     mov    dx,offset inbuf     ; offset to input buffer
  793.     mov    inptr,dx
  794.     int    21h
  795.     jc    getblkr         ; oops
  796.     or    ax,ax            ; anything read?
  797.     jnz    getblka
  798.     stc                ; no, set cf=1 for eof
  799.     jmp    short getblkx        ; and exit
  800. getblka:
  801.     mov    inlen,ax        ; return count of bytes read
  802. getblkx:
  803.     pop    dx
  804.     pop    cx
  805.     pop    bx
  806.     ret
  807.  
  808. getblkr:
  809.     printl    'I/O error reading '
  810.     print    arcname
  811.     jmp    error            ; gotta quit
  812. getblk    endp
  813.  
  814.     subttl    '--- load next archive header'
  815.     page
  816.  
  817. gethdr    proc    near
  818.     mov    cx,512            ; gotta look for the damn thing
  819. gethdr2:
  820.     call    getc            ; get next file byte
  821.     jc    gethdrr1        ; premature eof
  822.     cmp    al,arcmark        ; start of header?
  823.     je    gethdr3         ; yup, let's start cookin
  824.     loop    gethdr2
  825. gethdrr1:
  826.     printl    'Invalid archive format!'
  827.     jmp    error
  828.  
  829. gethdr3:
  830.     call    getc            ; get version code
  831.     jc    gethdrr1
  832.     mov    archdr.mbrcode,al
  833.     cmp    al,arcver        ; reasonable code?
  834.     ja    gethdrr1        ; nope, funny stuff
  835.     cmp    al,0            ; archive eof?
  836.     je    gethdr9         ; yup done
  837.  
  838.     mov    cx,13            ; get member name
  839.     mov    di,offset archdr.mbrname
  840. gethdr4:
  841.     call    getc
  842.     jc    gethdrr1
  843.     stosb
  844.     loop    gethdr4
  845. gethdr5:
  846.     mov    cx,10            ; length remaining
  847.     cmp    archdr.mbrcode,1    ; old format?
  848.     je    gethdr6         ; yes, it's short
  849.     mov    cl,14
  850. gethdr6:
  851.     mov    di,offset archdr.mbrsize
  852. gethdr7:
  853.     call    getc
  854.     jc    gethdrr1
  855.     stosb
  856.     loop    gethdr7
  857. gethdr8:
  858.     cmp    archdr.mbrcode,1    ; old format?
  859.     jne    gethdr9         ; if so, it's short
  860.     mov    si,offset mbrsize
  861.     mov    di,offset mbrlen
  862.     mov    cx,4
  863.     rep    movsb
  864. gethdr9:
  865.     clc
  866.     ret
  867.  
  868. gethdrr2:
  869.     printl    'Invalid archive header'
  870.     jmp    error
  871. gethdr    endp
  872.  
  873.     subttl    '--- i/o data areas'
  874.     page
  875.  
  876. arcv    endp
  877.  
  878. dta    equ    $        ; data transfer area
  879.  
  880. archdr    equ    dta + 48    ; i/o area for a header
  881.  
  882. inbuf    equ    archdr + 64    ; read i/o buffer
  883. cseg    ends
  884.     end    arcv
  885.