home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols100 / vol197 / unsq.a86 < prev    next >
Encoding:
Text File  |  1994-07-13  |  10.8 KB  |  472 lines

  1.  
  2. ;    ------------------------------------------------------------
  3. ;    UNSQ.A86 is similar to the program USQ.COM (SIG/M 58.27).
  4. ;    The latter appears to have been compiled from BDS "C" source
  5. ;    code, which is known to be from ten to twenty times more
  6. ;    voluminous than code derived from assembly language source.
  7. ;    UNSQ.A86 was written on the basis of information concerning
  8. ;    Huffman codes found in the literature, an inspection of a
  9. ;    disassembly of USQ.COM, and several experiments in which
  10. ;    test files were squeezed and the squeezed files then dumped.
  11. ;    UNSQ recovers the original unsqueezed file, which it places
  12. ;    on the same disk as output.
  13. ;
  14. ;             UNSQ.A86  Copyright (C) 1984
  15. ;            Universidad Autonoma de Puebla
  16. ;                July 16, 1984
  17. ;
  18. ;    [Harold V. McIntosh, 16 July 1984]
  19. ;    ------------------------------------------------------------
  20.  
  21. BDOS    equ    224            ;bdos interrupt
  22.  
  23. qfcb    equ    005CH            ;squeezed FCB
  24. tsiz    equ    0080H
  25. usiz    equ    0080H            ;size of .UNS buffer
  26. qsiz    equ    0080H            ;size of squeezed file buffer
  27. qbuf    equ    0080H            ;squeezed buffer
  28. csiz    equ    512            ;max chars in Huffman code
  29.  
  30. ;    Nongraphic characters.
  31.  
  32. LF    equ    0AH
  33. CR    equ    0DH
  34.  
  35. ;    -------------
  36.     org    0100H
  37. ;    -------------
  38.  
  39. begn:    mov    bx,(offset qfcb+1)    ;squeezed FCB
  40.     cmp    (byte ptr[bx]),' '
  41.     jnz    notu
  42.     mov    dx,(offset tuto)
  43. ferm:    call    mssg
  44. exit:    mov    dl,00
  45.     mov    cl,00
  46.     int    bdos
  47.  
  48. notu:    mov    uptr,(offset ubuf)    ;unsqueezed buffer
  49.     mov    qptr,(offset qbuf)    ;squeezed buffer
  50.  
  51.     mov    cx,0021H        ;33 00's
  52.     mov    bx,(offset ufcb)    ;unsqueezed FCB
  53.     call    fiuc            ;block fill
  54.  
  55.     mov    cx,200BH        ;11 blanks
  56.     mov    bx,(offset ufcb+1)    ;unsqueezed FCB
  57.     call    fiuc            ;block fill
  58.  
  59.     call    opef            ;open squeezed file
  60.  
  61.     mov    qctr,0000
  62.     mov    uctr,usiz+1        ;size of .UNS buffer
  63.     mov    roco,1
  64.  
  65. cota:    call    rwor            ;fetch one byte from input stream
  66.     cmp    bx,0FF76H
  67.     jz    rchk            ;read checksum
  68.     mov    dx,(offset nsqz)    ;'not a squeezed file'
  69.     jmp    ferm            ;final (error) message
  70.  
  71. ;    The "squeezed" marker is followed by a two-byte checksum,
  72. ;    which is the simple sum of all the one-byte characters in
  73. ;    the source file, carried as a two byte sum modulo 2**16.
  74.  
  75. rchk:    call    rwor            ;fetch two bytes from input stream
  76.     mov    cksm,bx            ;checksum
  77.  
  78. ;    Unsqueezed file name. It is an ASCII sequence, may be lower
  79. ;    case if SQ.UNS received it in response to a prompt, ending
  80. ;    with a zero byte. Some trash may be present if SQ.UNS wasn't
  81. ;    used correctly.
  82.  
  83.     mov    cx,8
  84.     mov    bx,(offset ufcb+1)    ;unsqueezed FCB
  85. luup:    call    rbyt            ;fetch one byte from input stream
  86.     or    al,al
  87.     jz    luuw            ;load code dictionary
  88.     cmp    al,'.'
  89.     jz    luuw
  90.     call    ucfo
  91.     mov    [bx],al
  92.     inc    bx
  93.     call    cona
  94.     loop    luup
  95. luuz:    call    rbyt
  96.     or    al,al
  97.     jz    ldic
  98.     cmp    al,'.'
  99.     jnz    luuz
  100. luuw:    call    cona
  101.     mov    cx,3
  102.     mov    bx,(offset ufcb+9)    ;unsqueezed FCB
  103. luur:    call    rbyt
  104.     or    al,al
  105.     jz    ldic
  106.     call    ucfo
  107.     mov    [bx],al
  108.     inc    bx
  109.     call    cona
  110.     loop    luur
  111. luus:    call    rbyt
  112.     or    al,al
  113.     jnz    luus
  114.  
  115. ;    Load code dictionary. It is preceded by its two-byte length,
  116. ;    and consists of a series of pairs of two-byte addresses. For
  117. ;    each bit in the code, select the first element (0) or the
  118. ;    second (1) element of the pair. If the pair is positive, it
  119. ;    is the table entry (code + 4*index) at which to continue with
  120. ;    the next bit. If the pair is negative, it is the complement
  121. ;    of the coded ASCII character (low order byte except for [end]).
  122.  
  123. ldic:    call    rwor            ;fetch two bytes from input stream
  124.     cmp    bx,(csiz+1)
  125.     jc    ldii
  126.     mov    dx,(offset ntab)    ;'insufficient dictionary space'
  127.     jmp    ferm            ;final (error) message
  128.  
  129. ldii:    add    bx,bx
  130.     add    bx,bx
  131.     mov    cx,bx
  132.     mov    si,(offset code)    ;decoding table
  133. luuq:    call    rbyt            ;fetch one byte from input stream
  134.     mov    [si],al
  135.     inc    si
  136.     loop    luuq
  137.  
  138.     call    crlf            ;type CR,LF
  139.  
  140.     mov    cl,26            ;(1A) set DMA address
  141.     mov    dx,(offset ubuf)    ;unsqueezed buffer
  142.     int    BDOS
  143.  
  144.     mov    dx,(offset ufcb)    ;unsqueezed FCB
  145.     mov    cl,17            ;(11) search for file
  146.     int    BDOS
  147.     inc    al
  148.     jz    nexi
  149.     mov    dx,(offset yexi)    ;'file already exists'
  150.     jmp    ferm            ;final (error) message
  151.  
  152. nexi:    mov    dx,(offset ufcb)    ;unsqueezed FCB
  153.     mov    cl,22            ;(16) create file
  154.     int    BDOS
  155.  
  156.     mov    dx,(offset ufcb)    ;unsqueezed FCB
  157.     mov    cl,15            ;(0F) open file
  158.     int    BDOS
  159.     cmp    al,0FFH
  160.     mov    dx,(offset nodi)    ;'no more directory'
  161.     jnz G14 ! jmp ferm ! G14:    ;final (error) message
  162.  
  163.     call    cbuz            ;clear output buffer to zeroes
  164.  
  165. ;    Type unsqueezed code. Beware of the [end] marker,
  166. ;    and also the repeat marker 90H which occurs in the
  167. ;    combination <char><90H><count>. When count is zero,
  168. ;    90H itself is intended; otherwise <char> is to be
  169. ;    repeated <count> times, including the occurrence just
  170. ;    before 90H was seen.
  171.  
  172. tusq:    call    dnch            ;decode next character
  173.     jnc G15 ! jmp chek ! G15:    ;verify the checksum
  174.     cmp    al,090H            ;repeat last character
  175.     jnz    tusu            ;normal character
  176.     call    dnch            ;decode next character
  177.     or    al,al
  178.     jnz    tusr
  179.     mov    al,090H
  180.     call    tpye
  181.     jmp    tusq
  182.  
  183. tusr:    dec    al            ;get count, adjust it
  184.     mov    ch,al            ;set count aside
  185. tust:    mov    al,lach            ;last character typed
  186.     call    tpye            ;type char & add to checksum
  187.     dec    ch            ;update count
  188.     jnz    tust            ;repeat until exhausted
  189.     jmp    tusq            ;type unsqueezed code
  190.  
  191. tusu:    mov    lach,al            ;last character typed
  192.     call    tpye            ;type char & add to checksum
  193.     jmp    tusq            ;type unsqueezed code
  194.  
  195. ;    Decode next character.
  196.  
  197. dnch:    mov    bx,(offset code)    ;decoding table
  198. dncr:    call    rbit            ;read next bit
  199.     jnc    dncs            ;skip for 1, stay for 0
  200.     inc    bx
  201.     inc    bx
  202. dncs:    mov    ax,[bx]            ;get next offset
  203.     cmp    ax,0FEFFH
  204.     jz    dnct
  205.     or    ax,ax
  206.     jns    dncu            ;p means new offset
  207.     not    al
  208.     stc
  209.     cmc
  210.     ret
  211.  
  212. dnct:    stc                ;flag [end] with carry bit
  213.     ret
  214.  
  215. ;    Calculate <code>+4*<offset>.
  216.  
  217. dncu:    mov    bx,(offset code)    ;decoding table
  218.     add    ax,ax
  219.     add    ax,ax
  220.     add    bx,ax
  221.     jmp    dncr
  222.  
  223. ;    Type CR, LF.
  224.  
  225. crlf:    mov    al,CR
  226.     call    cona            ;type character at console
  227.     mov    al,LF
  228.     jmp    cona            ;type character at console
  229.  
  230. ;    Type unsqueezed text and accumulate checksum.
  231.  
  232. tpye:    push    bx
  233.     push    dx
  234.     push    cx
  235.     push    ax
  236.     mov    bx,(offset cksm)    ;checksum
  237.     mov    ch,al
  238.     mov    al,(byte ptr[bx])
  239.     sub    al,ch
  240.     mov    [bx],al
  241.     inc    bx
  242.     mov    al,(byte ptr[bx])
  243.     sbb    al,0
  244.     mov    [bx],al
  245.     mov    al,ch
  246.     call    wbyt            ;send character to .COM file
  247.     pop    ax
  248.     pop    cx
  249.     pop    dx
  250.     pop    bx
  251.     ret
  252.  
  253. ;    Upper case fold.
  254.  
  255. ucfo:    cmp    al,'a'
  256.     jc    ucfr
  257.     cmp    al,'{'
  258.     jnc    ucfr
  259.     and    al,5FH
  260. ucfr:    ret
  261.  
  262. ;    Send character in accumulator to console.
  263.  
  264. cona:    push    bx
  265.     push    dx
  266.     push    cx
  267.     mov    cl,2            ;(02) char to console
  268.     mov    dl,al
  269.     int    BDOS
  270.     pop    cx
  271.     pop    dx
  272.     pop    bx
  273.     ret
  274.  
  275. ;    Send message to the console.
  276.  
  277. mssg:    mov    cl,9            ;(09) print buffer
  278.     int    BDOS
  279.     ret
  280.  
  281. ;    Verify the checksum.
  282.  
  283. chek:    mov    bx,cksm            ;checksum
  284.     mov    al,bh
  285.     or    al,bl
  286.     jnz G24 ! jmp clof ! G24:    ;close the file
  287.  
  288.     mov    cl,19            ;(13) delete file
  289.     mov    dx,(offset ufcb)    ;unsqueezed FCB
  290.     int    BDOS
  291.  
  292.     mov    dx,(offset chno)    ;'Checksum failure.'
  293.     call    ferm            ;final (error) message
  294.  
  295. ;    Open squeezed file.
  296.  
  297. opef:    mov    bx,(offset qfcb+32)
  298.     mov    (byte ptr[bx]),00    ;squeezed FCB
  299.     mov    dx,(offset qfcb)    ;squeezed FCB
  300.     mov    cl,15            ;(0F) open file
  301.     int    BDOS
  302.     inc    al
  303.     jz G25 ! ret ! G25:
  304.     mov    dx,(offset nfil)    ;'requested file not found'
  305.     jmp    ferm            ;final (error) message
  306.  
  307. ;    Close unsqueezed file.
  308.  
  309. clof:    mov    al,uctr            ;occupancy of .UNS buffer
  310.     cmp    al,usiz            ;size of .UNS buffer
  311.     jz G26 ! call wrdi ! G26:
  312.     mov    cl,16            ;(10) close file
  313.     mov    dx,(offset ufcb)    ;unsqueezed FCB
  314.     int    BDOS
  315.     cmp    al,0FFH
  316.     mov    dx,(offset nclo)    ;'cannot close file'
  317.     jnz G27 ! jmp ferm ! G27:    ;final (error) message
  318.     jmp    exit
  319.  
  320. ;    Read one bit at a time.
  321.  
  322. rbit:    push    bx
  323.     dec    roco            ;rotation count
  324.     jnz    rbiu
  325.     mov    roco,8
  326.     call    rbyt            ;fetch one byte from input stream
  327.     mov    roby,al            ;rotating byte
  328. rbiu:    rcr    roby,1            ;rotating byte
  329.     pop    bx
  330.     ret
  331.  
  332. ;    Read one word.
  333.  
  334. rwor:    call    rbyt            ;fetch one byte from input stream
  335.     push    ax
  336.     call    rbyt            ;fetch one byte from input stream
  337.     pop    bx
  338.     mov    bh,al
  339.     ret
  340.  
  341. ;    Read one byte, refill buffer as needed.
  342.  
  343. rbyt:    push    bx
  344.     mov    bx,qctr            ;byte counter - input buffer
  345.     mov    al,bl
  346.     or    al,bh
  347.     jnz    rbyu
  348.     call    rdsk
  349.     mov    bx,(offset qbuf)    ;squeezed buffer
  350.     mov    qptr,bx            ;byte pointer - input buffer
  351.     mov    bx,(offset qsiz)    ;size of squeezed file buffer
  352. rbyu:    dec    bx
  353.     mov    qctr,bx            ;byte counter - input buffer
  354.     mov    bx,qptr            ;byte pointer - input buffer
  355.     mov    al,(byte ptr[bx])
  356.     inc    bx
  357.     mov    qptr,bx            ;byte pointer - input buffer
  358.     pop    bx
  359.     ret
  360.  
  361. ;    Insert byte in .UNS buffer.
  362.  
  363. wbyt:    push    bx
  364.     mov    bx,(offset uctr)    ;occupancy of .UNS buffer
  365.     dec    (byte ptr[bx])
  366.     jnz    wbyy
  367.     mov    (byte ptr[bx]),usiz    ;size of .UNS buffer
  368.     push    ax
  369.     mov    bx,(offset ubuf)    ;unsqueezed buffer
  370.     mov    uptr,bx            ;pointer to .UNS buffer
  371.     call    wrdi
  372.     call    cbuz            ;clear output buffer to zeroes
  373.     pop    ax
  374. wbyy:    mov    bx,uptr            ;pointer to .UNS buffer
  375.     mov    [bx],al
  376.     inc    bx
  377.     mov    uptr,bx            ;pointer to .UNS buffer
  378.     pop    bx
  379.     ret
  380.  
  381. ;    Send ubuf to disk.
  382.  
  383. wrdi:    mov    cl,26            ;(1A) set DMA address
  384.     mov    dx,(offset ubuf)    ;unsqueezed buffer
  385.     int    BDOS
  386.  
  387.     mov    cl,21            ;(15) write one record
  388.     mov    dx,(offset ufcb)    ;unsqueezed DCB
  389.     int    BDOS
  390.     cmp    al,00H
  391.     mov    dx,(offset werr)    ;'disk write'
  392.     jz G31 ! jmp ferm ! G31:    ;final (error) message
  393.     ret
  394.  
  395. rdsk:    push    bx
  396.     push    dx
  397.     push    cx
  398.  
  399.     mov    cl,26            ;(1A) set DMA address
  400.     mov    dx,(offset qbuf)    ;squeezed buffer
  401.     int    BDOS
  402.  
  403.     mov    cl,20            ;(14) read one record
  404.     mov    dx,(offset qfcb)    ;squeezed FCB
  405.     int    BDOS
  406.  
  407.     pop    cx
  408.     pop    dx
  409.     pop    bx
  410.     ret
  411.  
  412. ;    Fill ubuf with zeroes.
  413.  
  414. cbuz:    xor    al,al
  415.     mov    ch,1            ;one sector in buffer
  416.     mov    bx,(offset ubuf)    ;unsqueezed buffer
  417. cbuy:    mov    cl,tsiz            ;record size
  418. cbux:    mov    [bx],al
  419.     inc    bx
  420.     dec    cl
  421.     jnz    cbux
  422.     dec    ch
  423.     jnz    cbuy
  424.     ret
  425.  
  426. ;    Block fill with C B's starting at (HL).
  427.  
  428. fiuc:    mov    (byte ptr[bx]),ch
  429.     inc    bx
  430.     dec    cl
  431.     jnz    fiuc            ;block fill
  432.     ret
  433.  
  434. logo    db    '          UNSQ/ICUAP',CR,LF
  435.     db    'Universidad Autonoma de Puebla',CR,LF
  436.     db    '        July 16, 1984',CR,LF,'$'
  437.  
  438. tuto    db    'UNSQ.A86 will restore files which have been squeezed',CR,LF
  439.     db    'by SQ.COM or some similar program.',CR,LF,CR,LF
  440.     db    '    UNSQ [X:]FILE[.QQQ]',CR,LF
  441.     db    CR,LF
  442.     db    'will read [X:]FILE.SQZ to produce [X:]FILE.UNS.',CR,LF
  443.     db    '$'
  444.  
  445. werr    db    CR,LF,'Disk write error.$'
  446. nfil    db    CR,LF,'Requested file not present.$'
  447. yexi    db    CR,LF,'Unsqueezed file already exists.$'
  448. ntab    db    CR,LF,'Insufficient space for dictionary.$'
  449. nsqz    db    CR,LF,'Not a squeezed file.$'
  450. chno    db    CR,LF,'Checksum failure.$'
  451. nopn    db    CR,LF,'Can''t open source.$'
  452. nodi    db    CR,LF,'Disk or Directory full.$'
  453. nclo    db    CR,LF,'Cannot close file.$'
  454.  
  455. ufcb    rb    21H            ;unsqueezed FCB
  456. uctr    rb    1            ;occupancy of .UNS buffer
  457. uptr    rw    1            ;pointer to .UNS buffer
  458. ubuf    rb    usiz            ;unsqueezed buffer
  459. reco    rb    1            ;record counter
  460. rbrk    rw    1            ;record breakpoint
  461. lach    rb    1            ;last character typed
  462. roco    rb    1            ;rotating bit counter
  463. roby    rb    1            ;rotating byte
  464. qctr    rw    1            ;byte counter - input buffer
  465. qptr    rw    1            ;byte pointer - input buffer
  466. cksm    rw    1            ;checksum
  467. code    rb    4*csiz            ;decoding table
  468.     rb    100
  469. stak    rw    1            ;stackend
  470.  
  471.     end
  472.