home *** CD-ROM | disk | FTP | other *** search
-
- ; ------------------------------------------------------------
- ; UNSQ.A86 is similar to the program USQ.COM (SIG/M 58.27).
- ; The latter appears to have been compiled from BDS "C" source
- ; code, which is known to be from ten to twenty times more
- ; voluminous than code derived from assembly language source.
- ; UNSQ.A86 was written on the basis of information concerning
- ; Huffman codes found in the literature, an inspection of a
- ; disassembly of USQ.COM, and several experiments in which
- ; test files were squeezed and the squeezed files then dumped.
- ; UNSQ recovers the original unsqueezed file, which it places
- ; on the same disk as output.
- ;
- ; UNSQ.A86 Copyright (C) 1984
- ; Universidad Autonoma de Puebla
- ; July 16, 1984
- ;
- ; [Harold V. McIntosh, 16 July 1984]
- ; ------------------------------------------------------------
-
- BDOS equ 224 ;bdos interrupt
-
- qfcb equ 005CH ;squeezed FCB
- tsiz equ 0080H
- usiz equ 0080H ;size of .UNS buffer
- qsiz equ 0080H ;size of squeezed file buffer
- qbuf equ 0080H ;squeezed buffer
- csiz equ 512 ;max chars in Huffman code
-
- ; Nongraphic characters.
-
- LF equ 0AH
- CR equ 0DH
-
- ; -------------
- org 0100H
- ; -------------
-
- begn: mov bx,(offset qfcb+1) ;squeezed FCB
- cmp (byte ptr[bx]),' '
- jnz notu
- mov dx,(offset tuto)
- ferm: call mssg
- exit: mov dl,00
- mov cl,00
- int bdos
-
- notu: mov uptr,(offset ubuf) ;unsqueezed buffer
- mov qptr,(offset qbuf) ;squeezed buffer
-
- mov cx,0021H ;33 00's
- mov bx,(offset ufcb) ;unsqueezed FCB
- call fiuc ;block fill
-
- mov cx,200BH ;11 blanks
- mov bx,(offset ufcb+1) ;unsqueezed FCB
- call fiuc ;block fill
-
- call opef ;open squeezed file
-
- mov qctr,0000
- mov uctr,usiz+1 ;size of .UNS buffer
- mov roco,1
-
- cota: call rwor ;fetch one byte from input stream
- cmp bx,0FF76H
- jz rchk ;read checksum
- mov dx,(offset nsqz) ;'not a squeezed file'
- jmp ferm ;final (error) message
-
- ; The "squeezed" marker is followed by a two-byte checksum,
- ; which is the simple sum of all the one-byte characters in
- ; the source file, carried as a two byte sum modulo 2**16.
-
- rchk: call rwor ;fetch two bytes from input stream
- mov cksm,bx ;checksum
-
- ; Unsqueezed file name. It is an ASCII sequence, may be lower
- ; case if SQ.UNS received it in response to a prompt, ending
- ; with a zero byte. Some trash may be present if SQ.UNS wasn't
- ; used correctly.
-
- mov cx,8
- mov bx,(offset ufcb+1) ;unsqueezed FCB
- luup: call rbyt ;fetch one byte from input stream
- or al,al
- jz luuw ;load code dictionary
- cmp al,'.'
- jz luuw
- call ucfo
- mov [bx],al
- inc bx
- call cona
- loop luup
- luuz: call rbyt
- or al,al
- jz ldic
- cmp al,'.'
- jnz luuz
- luuw: call cona
- mov cx,3
- mov bx,(offset ufcb+9) ;unsqueezed FCB
- luur: call rbyt
- or al,al
- jz ldic
- call ucfo
- mov [bx],al
- inc bx
- call cona
- loop luur
- luus: call rbyt
- or al,al
- jnz luus
-
- ; Load code dictionary. It is preceded by its two-byte length,
- ; and consists of a series of pairs of two-byte addresses. For
- ; each bit in the code, select the first element (0) or the
- ; second (1) element of the pair. If the pair is positive, it
- ; is the table entry (code + 4*index) at which to continue with
- ; the next bit. If the pair is negative, it is the complement
- ; of the coded ASCII character (low order byte except for [end]).
-
- ldic: call rwor ;fetch two bytes from input stream
- cmp bx,(csiz+1)
- jc ldii
- mov dx,(offset ntab) ;'insufficient dictionary space'
- jmp ferm ;final (error) message
-
- ldii: add bx,bx
- add bx,bx
- mov cx,bx
- mov si,(offset code) ;decoding table
- luuq: call rbyt ;fetch one byte from input stream
- mov [si],al
- inc si
- loop luuq
-
- call crlf ;type CR,LF
-
- mov cl,26 ;(1A) set DMA address
- mov dx,(offset ubuf) ;unsqueezed buffer
- int BDOS
-
- mov dx,(offset ufcb) ;unsqueezed FCB
- mov cl,17 ;(11) search for file
- int BDOS
- inc al
- jz nexi
- mov dx,(offset yexi) ;'file already exists'
- jmp ferm ;final (error) message
-
- nexi: mov dx,(offset ufcb) ;unsqueezed FCB
- mov cl,22 ;(16) create file
- int BDOS
-
- mov dx,(offset ufcb) ;unsqueezed FCB
- mov cl,15 ;(0F) open file
- int BDOS
- cmp al,0FFH
- mov dx,(offset nodi) ;'no more directory'
- jnz G14 ! jmp ferm ! G14: ;final (error) message
-
- call cbuz ;clear output buffer to zeroes
-
- ; Type unsqueezed code. Beware of the [end] marker,
- ; and also the repeat marker 90H which occurs in the
- ; combination <char><90H><count>. When count is zero,
- ; 90H itself is intended; otherwise <char> is to be
- ; repeated <count> times, including the occurrence just
- ; before 90H was seen.
-
- tusq: call dnch ;decode next character
- jnc G15 ! jmp chek ! G15: ;verify the checksum
- cmp al,090H ;repeat last character
- jnz tusu ;normal character
- call dnch ;decode next character
- or al,al
- jnz tusr
- mov al,090H
- call tpye
- jmp tusq
-
- tusr: dec al ;get count, adjust it
- mov ch,al ;set count aside
- tust: mov al,lach ;last character typed
- call tpye ;type char & add to checksum
- dec ch ;update count
- jnz tust ;repeat until exhausted
- jmp tusq ;type unsqueezed code
-
- tusu: mov lach,al ;last character typed
- call tpye ;type char & add to checksum
- jmp tusq ;type unsqueezed code
-
- ; Decode next character.
-
- dnch: mov bx,(offset code) ;decoding table
- dncr: call rbit ;read next bit
- jnc dncs ;skip for 1, stay for 0
- inc bx
- inc bx
- dncs: mov ax,[bx] ;get next offset
- cmp ax,0FEFFH
- jz dnct
- or ax,ax
- jns dncu ;p means new offset
- not al
- stc
- cmc
- ret
-
- dnct: stc ;flag [end] with carry bit
- ret
-
- ; Calculate <code>+4*<offset>.
-
- dncu: mov bx,(offset code) ;decoding table
- add ax,ax
- add ax,ax
- add bx,ax
- jmp dncr
-
- ; Type CR, LF.
-
- crlf: mov al,CR
- call cona ;type character at console
- mov al,LF
- jmp cona ;type character at console
-
- ; Type unsqueezed text and accumulate checksum.
-
- tpye: push bx
- push dx
- push cx
- push ax
- mov bx,(offset cksm) ;checksum
- mov ch,al
- mov al,(byte ptr[bx])
- sub al,ch
- mov [bx],al
- inc bx
- mov al,(byte ptr[bx])
- sbb al,0
- mov [bx],al
- mov al,ch
- call wbyt ;send character to .COM file
- pop ax
- pop cx
- pop dx
- pop bx
- ret
-
- ; Upper case fold.
-
- ucfo: cmp al,'a'
- jc ucfr
- cmp al,'{'
- jnc ucfr
- and al,5FH
- ucfr: ret
-
- ; Send character in accumulator to console.
-
- cona: push bx
- push dx
- push cx
- mov cl,2 ;(02) char to console
- mov dl,al
- int BDOS
- pop cx
- pop dx
- pop bx
- ret
-
- ; Send message to the console.
-
- mssg: mov cl,9 ;(09) print buffer
- int BDOS
- ret
-
- ; Verify the checksum.
-
- chek: mov bx,cksm ;checksum
- mov al,bh
- or al,bl
- jnz G24 ! jmp clof ! G24: ;close the file
-
- mov cl,19 ;(13) delete file
- mov dx,(offset ufcb) ;unsqueezed FCB
- int BDOS
-
- mov dx,(offset chno) ;'Checksum failure.'
- call ferm ;final (error) message
-
- ; Open squeezed file.
-
- opef: mov bx,(offset qfcb+32)
- mov (byte ptr[bx]),00 ;squeezed FCB
- mov dx,(offset qfcb) ;squeezed FCB
- mov cl,15 ;(0F) open file
- int BDOS
- inc al
- jz G25 ! ret ! G25:
- mov dx,(offset nfil) ;'requested file not found'
- jmp ferm ;final (error) message
-
- ; Close unsqueezed file.
-
- clof: mov al,uctr ;occupancy of .UNS buffer
- cmp al,usiz ;size of .UNS buffer
- jz G26 ! call wrdi ! G26:
- mov cl,16 ;(10) close file
- mov dx,(offset ufcb) ;unsqueezed FCB
- int BDOS
- cmp al,0FFH
- mov dx,(offset nclo) ;'cannot close file'
- jnz G27 ! jmp ferm ! G27: ;final (error) message
- jmp exit
-
- ; Read one bit at a time.
-
- rbit: push bx
- dec roco ;rotation count
- jnz rbiu
- mov roco,8
- call rbyt ;fetch one byte from input stream
- mov roby,al ;rotating byte
- rbiu: rcr roby,1 ;rotating byte
- pop bx
- ret
-
- ; Read one word.
-
- rwor: call rbyt ;fetch one byte from input stream
- push ax
- call rbyt ;fetch one byte from input stream
- pop bx
- mov bh,al
- ret
-
- ; Read one byte, refill buffer as needed.
-
- rbyt: push bx
- mov bx,qctr ;byte counter - input buffer
- mov al,bl
- or al,bh
- jnz rbyu
- call rdsk
- mov bx,(offset qbuf) ;squeezed buffer
- mov qptr,bx ;byte pointer - input buffer
- mov bx,(offset qsiz) ;size of squeezed file buffer
- rbyu: dec bx
- mov qctr,bx ;byte counter - input buffer
- mov bx,qptr ;byte pointer - input buffer
- mov al,(byte ptr[bx])
- inc bx
- mov qptr,bx ;byte pointer - input buffer
- pop bx
- ret
-
- ; Insert byte in .UNS buffer.
-
- wbyt: push bx
- mov bx,(offset uctr) ;occupancy of .UNS buffer
- dec (byte ptr[bx])
- jnz wbyy
- mov (byte ptr[bx]),usiz ;size of .UNS buffer
- push ax
- mov bx,(offset ubuf) ;unsqueezed buffer
- mov uptr,bx ;pointer to .UNS buffer
- call wrdi
- call cbuz ;clear output buffer to zeroes
- pop ax
- wbyy: mov bx,uptr ;pointer to .UNS buffer
- mov [bx],al
- inc bx
- mov uptr,bx ;pointer to .UNS buffer
- pop bx
- ret
-
- ; Send ubuf to disk.
-
- wrdi: mov cl,26 ;(1A) set DMA address
- mov dx,(offset ubuf) ;unsqueezed buffer
- int BDOS
-
- mov cl,21 ;(15) write one record
- mov dx,(offset ufcb) ;unsqueezed DCB
- int BDOS
- cmp al,00H
- mov dx,(offset werr) ;'disk write'
- jz G31 ! jmp ferm ! G31: ;final (error) message
- ret
-
- rdsk: push bx
- push dx
- push cx
-
- mov cl,26 ;(1A) set DMA address
- mov dx,(offset qbuf) ;squeezed buffer
- int BDOS
-
- mov cl,20 ;(14) read one record
- mov dx,(offset qfcb) ;squeezed FCB
- int BDOS
-
- pop cx
- pop dx
- pop bx
- ret
-
- ; Fill ubuf with zeroes.
-
- cbuz: xor al,al
- mov ch,1 ;one sector in buffer
- mov bx,(offset ubuf) ;unsqueezed buffer
- cbuy: mov cl,tsiz ;record size
- cbux: mov [bx],al
- inc bx
- dec cl
- jnz cbux
- dec ch
- jnz cbuy
- ret
-
- ; Block fill with C B's starting at (HL).
-
- fiuc: mov (byte ptr[bx]),ch
- inc bx
- dec cl
- jnz fiuc ;block fill
- ret
-
- logo db ' UNSQ/ICUAP',CR,LF
- db 'Universidad Autonoma de Puebla',CR,LF
- db ' July 16, 1984',CR,LF,'$'
-
- tuto db 'UNSQ.A86 will restore files which have been squeezed',CR,LF
- db 'by SQ.COM or some similar program.',CR,LF,CR,LF
- db ' UNSQ [X:]FILE[.QQQ]',CR,LF
- db CR,LF
- db 'will read [X:]FILE.SQZ to produce [X:]FILE.UNS.',CR,LF
- db '$'
-
- werr db CR,LF,'Disk write error.$'
- nfil db CR,LF,'Requested file not present.$'
- yexi db CR,LF,'Unsqueezed file already exists.$'
- ntab db CR,LF,'Insufficient space for dictionary.$'
- nsqz db CR,LF,'Not a squeezed file.$'
- chno db CR,LF,'Checksum failure.$'
- nopn db CR,LF,'Can''t open source.$'
- nodi db CR,LF,'Disk or Directory full.$'
- nclo db CR,LF,'Cannot close file.$'
-
- ufcb rb 21H ;unsqueezed FCB
- uctr rb 1 ;occupancy of .UNS buffer
- uptr rw 1 ;pointer to .UNS buffer
- ubuf rb usiz ;unsqueezed buffer
- reco rb 1 ;record counter
- rbrk rw 1 ;record breakpoint
- lach rb 1 ;last character typed
- roco rb 1 ;rotating bit counter
- roby rb 1 ;rotating byte
- qctr rw 1 ;byte counter - input buffer
- qptr rw 1 ;byte pointer - input buffer
- cksm rw 1 ;checksum
- code rb 4*csiz ;decoding table
- rb 100
- stak rw 1 ;stackend
-
- end