home *** CD-ROM | disk | FTP | other *** search
-
- ; -------------------------------------------------------------
- ; UNSQ.LIB is a library file to be used with Digital Research's
- ; ED.CMD to insert the set of subroutines which it contains
- ; into another program. The purpose of these subroutines is to
- ; read text from a file which has been squeezed by a program
- ; such as SQ.COM (SIG/M 58.26).
- ;
- ; UNSQ.LIB is divided into several sections, which can be left
- ; as they are, or integrated into the host program, according
- ; to your sense of orderliness. There are two subroutines that
- ; will be most likely to be called upon - unii and onsq. The
- ; first should be called for initialization, because it reads
- ; in the code directory and sets it up. It also separates out
- ; the file's checksum and the unsqueezed file name. The second
- ; is to be called each time that a character is to be taken out
- ; of the squeezed file.
- ;
- ; UNSQ.LIB assumes that the host program contains the following
- ; three subroutines:
- ;
- ; ibyt - which will deliver one character from an
- ; external input stream each time it is called.
- ; the external stream can be taken from memory,
- ; from a buffer that is periodically replenished
- ; from disk, or whatever.
- ;
- ; ufil - which will dispose of the characters forming
- ; the unsqueezed file name one by one. It might
- ; ignore them, store them in some file control
- ; block, or make some other use of them.
- ;
- ; ferm - which will type a fatal error message on the
- ; console and then return to CP/M - or take any
- ; other action which is desired.
- ;
- ; UNSQ.LIB Copyright (C) 1984
- ; Universidad Autonoma de Puebla
- ; July 14, 1984
- ;
- ; [Harold V. McIntosh, 14 July 1984]
- ; -------------------------------------------------------------
-
- ; -------------------------------------------------------------
- ; Section 1. Equivalences defining constants.
- ;
- ; CR, LF are used in the messages, and are
- ; traditionally defined in each program.
- ;
- ; csiz is the expected maximum number of
- ; characters which have been coded; 256
- ; is appropriate if all possible bytes may
- ; have been encoded.
- ;
- ; <iden> = <FF76> but some other pair
- ; might sometimes be used to mark a squeezed
- ; file
-
- CR equ 0DH
- LF equ 0AH
-
- csiz equ 256
- iden equ 0FF76H
-
- ; -----------------------------------------------------------
- ; Section 2. Initialization.
- ;
- ; <call unii> will initialize two necessary variables
- ; (rcnt, roco), then start reading the squeezed file.
- ; This file must previously have been opened, and its
- ; suitability checked - eg that it has extension ?Q?.
- ; It may even have already been loaded into memory.
- ; All interaction with it is through <call ibyt>, and
- ; the only requirement is that ibyt start reading the
- ; file from the beginning.
- ;
- ; unii goes through the following sequence:
- ;
- ; check squeezed marker <FF76>
- ; read and store checksum
- ; read, make available name for original file
- ; check the length of the code dictionary
- ; load and store the code dictionary
- ;
- ; unii will offer a fatal error message if
- ;
- ; the marker <iden> is not present
- ; space will not accomodate the code table
- ;
- ; unii requires two host subroutines:
- ;
- ; ibyt returns the next byte from the source
- ; ufil disposes of the original file name
- ;
- ; No assumptions should be made concerning conservation
- ; of the 8080 registers by unii.
- ;
- ; unii will alter the following memory registers:
- ;
- ; rcnt - repeated character - set to 0
- ; roco - count bits/byte - set to 1
- ; cksm - checksum - set to file's checksum
- ; dode - code table - loaded with dictionary
-
- ; Initializations.
-
- unii: mov rcnt,0 ;repetition count
- mov roco,1 ;bit rotation counter
-
- ; Set up code table. Squeezed files seem to begin with the
- ; hexadecimal word (FF76) stored in Intel byte order, which
- ; would not be likely to start an unsqueezed file.
-
- cota: call iwor ;fetch one byte from input stream
- cmp bx,iden
- jz rchk ;mssg: 'not squeezed file'
- mov dx,(offset nsqz) ;'not a squeezed file'
- jmp ferm ;fatal 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 iwor ;fetch two bytes from input stream
- mov cksm,bx ;checksum
-
- ; Unsqueezed file name. It is an ASCII sequence, may be lower
- ; case if SQ.COM received it in response to a prompt, ending
- ; with a zero byte. Some trash may be present if SQ.COM wasn't
- ; used correctly. If the file name is to be used for something,
- ; such as defining an output file or checking the file type,
- ; this is the place to insert the appropriate code.
-
- luup: call ibyt ;fetch one byte from input stream
- push ax
- call ufil ;process unsqueezed filename
- pop ax
- or al,al
- jnz luup
-
- ; 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 iwor ;fetch two bytes from input stream
- cmp bx,(offset csiz)
- jc ldii
- jz ldii
- mov dx,(offset ntab) ;'insufficient dictionary'
- jmp ferm ;fatal error message
-
- ldii: add bx,bx
- add bx,bx
- mov cx,bx
- mov si,(offset code) ;decoding table
- ldij: push cx
- push si
- call ibyt ;fetch one byte from input stream
- mov [si],al
- pop si
- pop cx
- inc si
- loop ldij
- ret
-
- ; ----------------------------------------------------------
- ; Section 3. Read next unsqueezed byte.
- ;
- ; <call onby> will withdraw a sufficient
- ; number of bits from the source file to
- ; generate one byte, returning it in the
- ; accumulator. The end of the source file
- ; will be signified by c = 1; otherwise
- ; c = 0 will prevail. Reading of the source
- ; file may terminate before this condition
- ; is reached, for example if the source
- ; was an ASCII file terminating with ^Z,
- ; or a HEX file terminated by a final line.
- ;
- ; The preservation of registers cannot be
- ; guaranteed; surround <call onby> with
- ; pushes and pops is such continuity is
- ; required.
- ;
- ; onby will solicit the fatal error message
- ; subroutine if the [eof] marker signified
- ; by c = 1 has been reached without the
- ; checksum having balanced. This protection
- ; can be secured for files that were not
- ; read in their entirity by reading out the
- ; remaining bytes in a dummy loop.
- ;
- ; onby alters the following memory registers:
- ;
- ; lach - last character deposited
- ; rcnt - repetition count
- ; roco - rotating bit counter
- ; roby - rotating byte
- ; cksm - checksum
-
- ; 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.
-
- onsq: mov al,rcnt ;repetition count
- or al,al
- jnz onsr
- call dnch ;decode next character
- jc vchk ;verify the checksum
- cmp al,090H ;repeat last character
- jnz onsu ;normal character
- call dnch ;decode next character
- or al,al
- jz onss
- dec al
- onsr: dec al
- mov rcnt,al ;repetition count
- mov al,lach
- jmp achk
-
- onss: mov al,090H
- jmp achk
-
- onsu: mov lach,al ;last character typed
- ; jmp achk
-
- ; Accumulate checksum.
-
- achk: mov ah,0
- sub cksm,ax
- stc
- cmc
- achr: ret
-
- ; Verify the checksum.
-
- vchk: cmp cksm,0000 ;checksum
- stc
- jz achr
- mov dx,(offset chno) ;'Checksum failure.'
- jmp ferm ;fatal error message
-
- ; Decode next character.
-
- dnch: mov bx,(offset code) ;decoding table
- dncr: call ibit ;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 ;FEFF means [end]
- jz dnct
- or ax,ax
- jns dncu ;p means new offset
- not al ;m means complemented char
- 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
-
- ; Read one bit at a time.
-
- ibit: dec roco ;bit rotation counter
- jnz ibiu
- mov roco,8
- call ibyt ;fetch one byte from input stream
- mov roby,al ;rotating byte
- ibiu: rcr roby,1 ;rotating byte
- ret
-
- ; Read one word.
-
- iwor: call ibyt ;fetch one byte from input stream
- mov bl,al
- push bx
- call ibyt ;fetch one byte from input stream
- pop bx
- mov bh,al
- ret
-
- ; -----------------------------------------------------------
- ; Section 4. Host subroutines.
- ;
- ; The following subroutines must be provided
- ; by the host program:
- ;
- ; ibyt - deliver the next byte from
- ; the source program, in register A,
- ; on each call. Need not preserve any
- ; 8080 registers.
- ;
- ; ufil - must absorb one byte from
- ; register A on each call. These bytes
- ; will be the information that is
- ; nominally the name of the source
- ; file, SOURCE.EXT, including the dot.
- ; ufil should be prepared for possible
- ; variants, however. ufil will be given
- ; final zero byte to signal the end of
- ; the bytestream it will receive. Of
- ; course, ufil could be imbedded in
- ; place of a call to it.
- ;
- ; ferm - send a fatal error message to
- ; the console. Normally control would
- ; return to CP/M, but some other action
- ; may be taken.
-
- ibyt: ret ;fetch byte from the input stream
- ufil: ret ;process unsqueezed filename
- ferm: ret ;fatal error message
-
- ; -------------------------------------------------------------
- ; Section 5. Messages and memory locations used by the program.
-
- ntab db CR,LF,'Insufficient dictionary space.$'
- nsqz db CR,LF,'Not a squeezed file.$'
- chno db CR,LF,'Checksum failure.$'
-
- lach rb 1 ;last character typed
- rcnt rb 1 ;repetition count
- roco rb 1 ;rotating bit counter
- roby rb 1 ;rotating byte
- cksm rw 1 ;checksum
- code rb 4*csiz ;decoding table
-
- end
-