home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 172 / CRUNCH24.ZIP / CRUNCH24.ARK / UNCR.Z80 < prev    next >
Text File  |  1990-05-26  |  41KB  |  1,192 lines

  1. ;***********************************************************************
  2. ;*                                       *
  3. ;*                 UNCRunch v2.4                   *
  4. ;*                  15 Sept 1987                   *
  5. ;*                        - Steven Greenberg     *
  6. ;*                                       *
  7. ;***********************************************************************
  8.  
  9.     .Z80
  10.     .SALL
  11.     TITLE 'UNCRrunch v2.4  15 Sept 1987'
  12.  
  13.     EXTRN    UNCR1,PARSEU,USQREL
  14.     ENTRY    GETBYT,OUT
  15.  
  16.     CSEG
  17. ;
  18. ;=======================================================================
  19. ;
  20. MEMPAG    EQU    1C00H        ; <=== set! [see comment near end of program]
  21. ;
  22. ;=======================================================================
  23. ;
  24. ;.......................................................................
  25. ;
  26. ; v2.4    Update Note:  As explained in the CRUNCH24 general release .LBR,
  27. ; v2.4 will generate identical    files  (except    embedded  revision level
  28. ; byte) to  CRUNCH v2.3.  The great  majority of  the  changes    are user
  29. ; interface related,  and are described  in the  CRUNCH24  documentation
  30. ; files.  Some changes were made  in the implementation of the "core" of
  31. ; the algorithms  for both CRUNCH and UNCRunch - in the case  of CRUNCH,
  32. ; conditionals were removed by    splitting into three separate loops.  In
  33. ; the case  of UNCRunch, an  unnecessary  chase to  the  end  of"virtual
  34. ; links" was eliminated by aborting  the search as soon as  an available
  35. ; reassignments lot  is found.    Other performance  improving changes in-
  36. ; clude less  time updating  the screen and  dynamic I/O  buffer sizing.
  37. ; Non-time-critical  "user-interface" changes (eg. the "tag  mode" code,
  38. ; etc.)  were  coded in as straightforward  a manner  as  possible, with
  39. ; little regard to code space minimization and even less to speed.
  40. ;
  41. ; While some documentation  of the code  has been cleaned up in the sev-
  42. ; eral month interim between the CRUNCH24.LBR release and the release of
  43. ; this source code, I have been very careful to  avoid any temptation to
  44. ; change any of the code itself, thus insuring that this source code can
  45. ; be used to create the identical COM files included in the v2.4 release
  46. ; of CRUNCH.
  47. ;
  48. ;.......................................................................
  49. ;
  50. NO    EQU    0
  51. YES    EQU    NOT NO
  52. CRUNCH    EQU    NO        ; Yes for CRUNCH, no for UNCR (for common)
  53.  
  54. REV    EQU    24H        ; Program revision level
  55. SIGREV    EQU    20H        ; "Significant" revision level (compatibility)
  56.  
  57. NOPRED    EQU    0FFFFH        ; "No predecessor"
  58. IMPRED    EQU    07FFFH        ; Pred that can't be matched or bumped
  59.  
  60. SCRUPT1    EQU    01H        ; Screen update speeds
  61. SCRUPT2    EQU    07H
  62. ;
  63. ; --- Reserved codes ---
  64. ;
  65. EOFCOD    EQU    100H        ; EOF code
  66. RSTCOD    EQU    101H        ; Adaptive reset code
  67. NULCOD    EQU    102H        ; Null code
  68. SPRCOD    EQU    103H        ; Spare code
  69. ;
  70. ; --- ASCII equates ---
  71. ;
  72. CTRLC    EQU    03H        ; ^c
  73. BELL    EQU    07H        ; Beep
  74. BS    EQU    08H        ; Backspace
  75. LF    EQU    0AH        ; Linefeed
  76. CR    EQU    0DH        ; Carriage return
  77. ;
  78. ; --- CP/M address equates ---
  79. ;
  80. DFCB    EQU    5CH        ; Default FCB #1
  81. DFCB2    EQU    6CH        ; Default FCB #2
  82. DDMA    EQU    80H        ; Default DMA address
  83. BDOS    EQU    0005H        ; BDOS entry point
  84. ;
  85. ; --- BDOS function equates ---
  86. ;
  87. CONIN    EQU    1        ; Input a character from the console
  88. CONOUT    EQU    2        ; Output single char to console
  89. PRTSTR    EQU    9        ; Print string to console
  90. CONST    EQU    11        ; Get console status
  91. GETVER    EQU    12        ; Get CP/M version#
  92. SELDSK    EQU    14        ; Select disk
  93. OPEN    EQU    15        ; Open file
  94. CLOSE    EQU    16        ; Close file
  95. SFIRST    EQU    17        ; Search for first file
  96. SNEXT    EQU    18        ; Search for next file
  97. ERASE    EQU    19        ; Erase file
  98. READ    EQU    20        ; Read file (sequential)
  99. WRITE    EQU    21        ; Write file (sequential)
  100. MAKE    EQU    22        ; Make file
  101. GETDSK    EQU    25        ; Get currently logged drive
  102. SETDMA    EQU    26        ; Set DMA address
  103. GSUSER    EQU    32        ; Get/set user code
  104. RSTDRV    EQU    37        ; Reset drive
  105. SETMS    EQU    44        ; Set multi-sector count (cp/m+ only)
  106. ;
  107. ;_______________________________________________________________________
  108. ;
  109. ; Macros to facilitate "horizontal" movement through the table.
  110. ; See "Table structure" comment near "initbl" for more information.
  111. ;
  112. RIGHT1     MACRO
  113.     LD    A,H        ; }
  114.     ADD    A,10H        ; } move "right" one column (same row)
  115.     LD    H,A        ; }
  116.      ENDM
  117. ;
  118. ;=======================================================================
  119. ;
  120. START:    JP    STRT        ; <--- entry
  121. ;
  122. ;=======================================================================
  123. ;
  124.     DB    'Z3ENV',01H    ; ZCPR3 environment descriptor
  125.  
  126. Z3ED:    DB    00H,00H
  127. ;
  128. ;-----------------------------------------------------------------------
  129. ;
  130. Z3FLG:    DB    0        ; ZCPR flag
  131. SPFLG:    DB    0        ; Spare flag (archive mode for crunch)
  132. INSREV:    DB    23H        ; Program rev for install program reference
  133. QUIFL:    DB    0        ; Quiet mode flag
  134. NPROFL:    DB    0        ; No prompt before overwrite flag
  135. TRBOFL:    DB    0        ; Defeat multi-sector i/o flag
  136. CNFRFL:    DB    0        ; Confirm every file flag
  137. WRMFLG:    DB    0        ; Warm boot flag
  138. BIGFLG:    DB    0        ; Override larger file question flag
  139. MAXDRV:    DB    0FFH        ; Max drive
  140. MAXUSR:    DB    0FFH        ; Max user
  141. SPARFL:    DB    0        ; Spare flag or value
  142.  
  143. EXTBL:    DB    0,0,0,0,0,0    ; Room for the "exclusion list". used in
  144.     DB    0,0,0,0,0,0    ; - CRUNCH, but want compatible overlays.
  145.     DB    0,0,0,0,0,0    ; (enough for 10 3-letter filname extensions)
  146.     DB    0,0,0,0,0,0
  147.     DB    0,0,0,0,0,0
  148. ;
  149. ;=*=-=*=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=
  150. ;
  151. CPYRT:    DB    CR,LF,LF
  152.     DB    'UNCR  v2.4   Copyright (c)   S. Greenberg  09/15/87'
  153.     DB    CR,LF
  154.     DB    'May be reproduced for non-profit use only','$'
  155.     DB    ' 201-670-8724'
  156. ;
  157. ;=*=-=*=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=
  158. ;
  159. STRT:    SUB    A        ; Z-80 test [RAF]
  160.     JP    PO,Z80
  161.     LD    DE,WRNGUP    ; "Program requires z-80 processor"
  162.     JP    MESS80        ; No frills exit w/ message
  163.  
  164. Z80:    LD    (OLDSTK),SP    ; Save os's stack
  165.     LD    SP,TOPSTK    ; Set local stack
  166.  
  167.     CALL    STRTUP        ; Does a lot of stuff
  168. ;
  169. ;=======================================================================
  170. ;
  171. ;    *****    Re-enter here for each matching file *****
  172. ;
  173. ; General wildcard operation:  When the program is first invoked, a ll
  174. ; matching filenames are put end to end in FNBUFF, 12 bytes each, in
  175. ; alalphabetical order.  Since a filename is only 11 characters long,
  176. ; the spare byte, which precedes each filename, is used as a "tag/flag".
  177. ; By the time file processing starts (now), a number of routines have
  178. ; already run (parts  of the STRTUP routine).  These routines set the
  179. ; tag-flag which indicates to us now in what manner the file should be
  180. ; processed:  "00" = "skip it", "01" = process it", "02" = "perform a
  181. ; direct copy (if possible)", "FF" = "no more files".
  182. ;
  183. NXTFIL:    LD    SP,TOPSTK    ; 'just in case'
  184.     LD    A,(QUIFM)    ; conditional CR/LF depending on "quiet mode"
  185.     OR    A
  186.     CALL    Z,CRLF
  187.  
  188.     LD    DE,INFCB    ; Input file fcb
  189.     CALL    CLRFCB        ; Init it to blanks and zeroes
  190.     INC    DE        ; Leave "DE" pointing at infcb+1 for below
  191.  
  192.     LD    HL,(BUFPTR)    ; Pntr to name of next file from expansion bfr
  193. NXTSEL:    LD    A,(HL)
  194.     OR    A        ; If zero, the file is "unselected"
  195.     JR    NZ,ISSEL    ; Br if it is selected
  196.     LD    BC,12        ; Else just quietly skip to the next file
  197.     ADD    HL,BC
  198.     LD    (BUFPTR),HL
  199.     JR    NXTSEL
  200. ;
  201. ;...............................
  202. ;
  203. ISSEL:    CP    0FFH        ; An "FF" means done
  204.     JP    Z,RETCCP    ; Br if that is the case
  205.  
  206.     PUSH    AF        ; Save stat (to see if file is "excluded" blw)
  207.  
  208.     PUSH    DE
  209.     LD    DE,DASHES    ; "-----" for visual separation
  210.     CALL    MESAG2
  211.     POP    DE
  212.     INC    HL        ; Skip to 1st filename char
  213.     LD    BC,11        ; Filename character count
  214.     LDIR            ; Put next file name into input fcb
  215.     LD    (BUFPTR),HL    ; Save new pointer for next file
  216.     CALL    INTRAM        ; Initialize all ram
  217.     LD    A,80H        ; (init'd by "INTRAM", but must be init'd
  218.     LD    (CSAVE),A    ; - differently for CRUNCH & UNCRunch)
  219.     POP    AF        ; Get file's status byte back again
  220.     CP    02H        ; 02 if file matched the "exclusion" list
  221.     JR    NZ,COPNIN    ; If not, definitly attempt to uncompress it
  222.     LD    A,(WLDFLG)    ; If so, see if prgm was invoked w/ wildcards
  223.     OR    A        ;
  224.     JP    NZ,COPY9    ; If so, do not uncompress; do a straight copy
  225. ;
  226. ;.......................................................................
  227. ;
  228. ; Now open the input file.  A failure here is unusual, since the file
  229. ; existed at the time the filename expansion took place.  There are
  230. ; "normal" series of events which could lead up to this, however.
  231. ;
  232. COPNIN:    CALL    OPNIN        ; Attempt to open the next input file "INFCB"
  233.     JR    NC,OPOK        ; Br if ok
  234.     LD    DE,ERR1        ; "input file not found"
  235.     JP    SKIP1        ; Skip to next file
  236. ;
  237. ;.......................................................................
  238. ;
  239. ; If we got here, the input file is open.  The output file is not
  240. ;
  241. OPOK:    LD    DE,OUTFCB    ; Now for the output fcb
  242.     CALL    CLRFCB        ; Clear it
  243.     INC    DE        ; Leave "DE" pointing at filename area
  244.     LD    A,' '        ; For proper alignment
  245.     CALL    TYPE
  246.     LD    HL,INFCB    ; Print input filename to console
  247.     CALL    PRNFIL
  248.     XOR    A        ; Init 1st char of date stamp bfr to zero
  249.     LD    (STAMP),A    ; (nulls the buffer; zero is the eof char)
  250.     CALL    GETCHR        ; Get a char from the input stream
  251.     JR    NC,NTMT        ; If carry set on first byte, file is empty
  252.     LD    DE,ERR0        ; "[ file empty ]"
  253.     JR    NCR2        ; Treat same as "Not compressed"
  254.  
  255. NTMT:    CP    76H        ; Check for crunched file header "76FE"
  256.     JR    NZ,NCRNCH    ; Br if not
  257.     CALL    GETCHR
  258.     CP    0FEH
  259.     JR    Z,YCRNCH
  260.     CP    0FFH        ; Squeezed?
  261.     JR    Z,YESQZ        ; Br if so
  262.  
  263. NCRNCH:    CALL    CLSIN        ; Not squeezed or crunched; close input file
  264.     LD    DE,MSG43    ; "[not compressed]"
  265.  
  266. NCR2:    CALL    MESAG2
  267.     LD    A,(WLDFLG)    ; Invoked w/ wildcards?
  268.     OR    A
  269.     JP    NZ,COPY9    ; Do straight copy ("copy" chks for diff du)
  270.     JP    NXTFIL        ; Else go on to next file
  271. ;
  272. ;...............................
  273. ;
  274. YESQZ:    LD    (SQZFLG),A    ; Flag file as squeezed using ff already in a
  275.     CALL    GETCHR        ; Get checksum byte #1
  276.     LD    L,A        ; Hold that
  277.     CALL    GETCHR        ; Checksum byte #2
  278.     LD    H,A
  279.     LD    (SQCKSM),HL    ; Save for later reference
  280.  
  281. YCRNCH:    LD    DE,OUTFCB+1    ; Where output filename will be copied to
  282.     LD    B,12        ; Loop limiter (11 char filename + ".")
  283.  
  284. EATLP:    CALL    GETCHR        ; Get next char
  285.     OR    A        ; A zero byte indicates end of filename
  286.     JR    Z,ATEIT        ; Br when that is encountered
  287.     AND    7FH        ; Force valid ascii (should be already)
  288.     CALL    UCASE        ; Upcase the char- (may be lc if squeezed)
  289.     CP    '.'        ; Check for name / ext division char
  290.     JR    Z,ISDOT        ; Br when encountered
  291.     LD    (DE),A        ; Else copy char to output fcb
  292.     INC    DE        ; And incr that pointer
  293.     DJNZ    EATLP        ; Continue, but not past end of filename
  294.     JR    IGNORE        ; If no 0 detected, ignore following info
  295. ;
  296. ;.......................................................................
  297. ;
  298. ; When "." is encountered, skip to the file extension bytes of the out-
  299. ; put FCB.  Any remaining non-extension bytes were init'd to blank).  Do
  300. ; not copy the "." to the output FCB.
  301. ;
  302. ISDOT:    LD    DE,OUTFCB+9    ; Skip...
  303.     LD    B,3        ; Update loop limiter counter
  304.     JR    EATLP        ; And continue
  305. ;
  306. ;...............................
  307. ;
  308. IGNORE:    LD    A,(SQZFLG)    ; For squeezed files, nothing else to do
  309.     OR    A
  310.     JP    NZ,USQZIT    ; Go to it
  311.  
  312. IGNRLP:    CALL    GETCHR        ; Loop absorbs extraneous header info
  313.     JR    C,NCRNCH    ; Circumvent possible hangup (eof before 0)
  314.     OR    A        ; Wait for the terminating zero
  315.     JR    Z,ATEIT        ; If terminating zero is reached
  316.     CP    '['        ; Else check for date stamp bof char
  317.     JR    NZ,IGNRLP    ; Other chars are extraneous at this point
  318. ;
  319. ;...............................
  320. ;
  321.     LD    DE,STAMP    ; Start copying file stamp info to this buffer
  322.     JR    ENTSLP
  323.  
  324. STMPLP:    CALL    GETCHR        ; Get a char
  325.     JR    C,NCRNCH    ; Circumvent hangup
  326. ENTSLP:    LD    (DE),A        ; Put char in dest
  327.     INC    DE        ; Incr dest pntr
  328.     OR    A
  329.     JR    NZ,STMPLP    ; Loop till zero is reached
  330. ;
  331. ;...............................
  332. ;
  333. ATEIT:    CALL    GETCHR        ; Get revision level, do nothing with it
  334.     CALL    GETCHR        ; Get significant revision level
  335.     CP    SIGREV        ; Compare to this prog
  336.     JP    C,OLDTYP    ; Br if old type1x crunched file
  337.     JR    Z,SIGOK        ; If equal, ok, else...
  338.     LD    DE,ERR5        ; "can't uncrunch that file. newer revision of
  339.     JP    SKIP2        ; - this program needed" or some such remark
  340.  
  341. SIGOK:    CALL    GETCHR        ; Get checksum flag
  342.     LD    (CKSMFL),A    ; Put it there
  343.     CALL    GETCHR        ; Get spare byte, do nothing with it
  344.     CALL    OPNOUT        ; Open output file & type "--->  <filename>"
  345.     PUSH    AF        ; Save stat from above
  346.     CALL    PRNID        ; Type any embedded date stamp info also
  347.     POP    AF
  348.     JP    C,SKIP2A    ; If user wants to skip it
  349. ;
  350. ;.......................................................................
  351. ;
  352. ; Now both files are open.  Eventually either both will be closed, or
  353. ; the input file will be closed and the output deleted.
  354. ;
  355.     LD    A,(QUIFM)    ; Skip column headings if in quiet mode
  356.     OR    A
  357.     JR    NZ,QUIET1
  358.     LD    DE,HEADNG    ; Type all the "in / out  ca  cr" stuff
  359.     CALL    MESAGE
  360.  
  361. QUIET1:    CALL    INITB2        ; Initialize the lzw table
  362.     LD    DE,NOPRED    ; Init to "NOPRED" (null value)
  363. ;
  364. ;=======================================================================
  365. ;
  366. ;         *** Main Decoding loop(s). ***
  367. ;
  368. ;=======================================================================
  369. ;
  370. MAINLP:    LD    (LASTPR),DE    ; Always keep a copy of the last "pred" here
  371.     CALL    GETCOD        ; Get bits to form a a new code in "DE"
  372.     JP    C,DUN        ; Br if eof node or physical end-of-file
  373.     PUSH    DE        ; Push a copy of the new pred
  374.     CALL    DECODE        ; Decode new pred
  375.     LD    HL,ENTFLG    ; Flag is "01" if "decode" made the entry
  376.     SRL    (HL)        ; Check (and zero) the flag
  377.     JR    C,NOENTR    ; Don't make the same entry twice!
  378.     LD    HL,(LASTPR)    ; Get old pred
  379.     LD    A,(CHAR)    ; And suffix char generated from the new pred
  380.     CALL    ENTERX        ; Make new table entry from those two
  381.  
  382. NOENTR:    POP    DE        ; Get newest pred again (not that new anymore)
  383.     LD    A,(FULFLG)    ; Monitor the table full flag
  384.     OR    A
  385.     JR    Z,MAINLP    ; Continue decoding & entering 'till full
  386. ;
  387. ;...............................
  388. ;
  389.     CP    0FEH        ; When this becomes "FF", we are done
  390.     JR    NZ,FASTLP    ; First it will become "FE", though. in that
  391.     INC    A        ; - case perf 1 more loop & change it to "FF"
  392.     LD    (FULFLG),A    ;
  393.     JR    MAINLP        ; One more!
  394. ;
  395. ;.......................................................................
  396. ;
  397. FASTLP:    LD    (LASTPR),DE    ; Table full loop similar to above ,except
  398.     CALL    GETCOD        ; - don't bother checking table full flag
  399.     JP    C,DUN        ; - call "ENTFIL", not "ENTERX" (for possible
  400.     PUSH    DE        ; - code reassignment
  401.     CALL    DECODE        ; Call to actually decode chars
  402.     LD    HL,(LASTPR)    ; Get old pred
  403.     LD    A,(CHAR)    ; And suffix char generated from the new pred
  404.     CALL    ENTFIL        ; Possibly make new table entry from those two
  405.     POP    DE
  406.     JR    FASTLP        ; Continue in code reassignment mode
  407. ;
  408. ;        *** End of Main Processing Loop(s)
  409. ;_______________________________________________________________________
  410. ;
  411. ; Come here when one of the special codes is encountered (we may not
  412. ; really be "dun").  Actually, a null code should have been intercepted
  413. ; by the GET12 routine, leaving only EOF (actually done) or adaptive
  414. ; reset.
  415. ;
  416. DUN:    LD    A,E        ; Some kind of special code encountered
  417.     CP    LOW(EOFCOD)    ; Actually done?
  418.     JR    Z,DUNDUN    ; Br if do
  419.     CP    LOW(RSTCOD)    ; Else better be reset (null was intercepted)
  420.     JP    NZ,FATBAD    ; File is invalid
  421. ;
  422. ;.......................................................................
  423. ;
  424. ; --- Perform an adaptive reset ---
  425. ;
  426.     LD    HL,0000        ; Reset entry# prior to table re-initialization
  427.     LD    (ENTRY),HL
  428.     LD    (TTOTAL),HL    ; Reset "codes reassigned"
  429.     XOR    A
  430.     LD    (FULFLG),A    ; Reset  "table full" flag
  431.     CALL    INITB2        ; Reset the entire table
  432.     LD    A,9        ; Reset the code length to "9"
  433.     LD    (CODLEN),A
  434.     LD    A,02H        ; Reset the target mask value accordingly
  435.     LD    (TRGMSK),A
  436.  
  437.     LD    DE,NOPRED    ; Set pred to "nopred"
  438.     LD    A,1        ; 1st entry is always a special case
  439.     LD    (ENTFLG),A    ; (trick it to make no table entry)
  440.     JP    MAINLP        ; And continue where we left off
  441. ;
  442. ;_______________________________________________________________________
  443. ;
  444. ; --- Actually done, close things up ---
  445. ;
  446. DUNDUN:    CALL    GETCHR        ; Get the checksum, always next
  447.     LD    E,A
  448.     CALL    GETCHR        ; Get checksum (hi-byte)
  449.     LD    D,A        ; Checksum (from input file) now in "DE"
  450.     LD    A,(CKSMFL)    ; Checksum override flag (not currently used)
  451.     AND    A        ; Check flag, also clear carry for below
  452.     JR    NZ,CHKSOK    ; If flag > 0, don't check checksum
  453.  
  454. DUNDUQ:    LD    HL,(CHKSUM)    ; Checksum (as computed)
  455.     SBC    HL,DE        ; Else check by subtraction
  456.     JR    Z,CHKSOK    ; Br if match
  457.     LD    DE,BADCHK    ; Bad checksum, issue warning
  458.     CALL    MESAGE
  459. ;
  460. ;...............................
  461. ;
  462. CHKSOK:    CALL    DONE        ; Write out remaining output buffer
  463.  
  464. CLOSE2:    CALL    CLSOUT        ; Close output file
  465.     CALL    CLSIN        ; Close input file
  466.     JR    NEXT
  467. ;
  468. ;.......................................................................
  469. ;
  470. COPY9:    CALL    COPY        ; Perform a straight copy
  471.     JP    C,NXTFIL    ; If copy didn't take place, don't count it
  472.  
  473. NEXT:    LD    HL,NFP        ; If we got here, the file has been "processed"
  474.     INC    (HL)        ; So incr the "files processed" counter
  475.     JP    NXTFIL        ; Go start next file
  476. ;
  477. ;.......................................................................
  478. ;
  479. ;...............................
  480. ;
  481. SKIP1:    CALL    MESAGE        ; Entry if neither in nor output files open yet
  482.  
  483. SKIP1A:    JP    NXTFIL        ; (Entry here if no error text desired)
  484. ;
  485. ;...............................
  486. ;
  487. SKIP2:    CALL    MESAGE        ; Entry here if input file open only
  488.  
  489. SKIP2A:    CALL    CLSIN        ; (Entry here for no message)
  490.     JP    NXTFIL
  491. ;
  492. ;...............................
  493. ;
  494. SKIP3:    CALL    MESAGE        ; Entry here if in & output files to be closed
  495.  
  496. SKIP3A:    CALL    CLSOUT        ; (Rest is same as above)
  497.     CALL    CLSIN        ;
  498.     JP    NXTFIL
  499. ;
  500. ;...............................
  501. ;
  502. SKIP4:    CALL    MESAGE        ; Entry here to erase output & close input file
  503.  
  504. SKIP4A:    CALL    CLSOUT        ; (Entry here for no message)
  505.     LD    DE,OUTFCB    ; Erase ouptut file, already started
  506.     LD    C,ERASE
  507.     CALL    BDOSAV
  508.     CALL    CLSIN        ; Close input file as well
  509.     JP    NXTFIL
  510. ;
  511. ;...............................
  512. ;
  513. ;.......................................................................
  514. ;
  515. ; The following routine actually performs the decoding.  The top section
  516. ; "DECODE" flags the entry as "referenced".  It then calls the recursive
  517. ; section below it, "DECODR", to do the actual work.
  518. ;
  519. DECODE:    PUSH    DE        ; Save code. the code provides us an immediate
  520.     EX    DE,HL        ;   index into the main logical table
  521.  
  522.     LD    A,H        ; (Add offset to beg of table, of course)
  523.     ADD    A,TABLHI
  524.     LD    H,A
  525.     SET    5,(HL)        ; Set bit 5 of pred (hi) to flag entry as
  526.     POP    DE        ; - "referenced" (ie not bumpable)
  527. ;
  528. ;.......................................................................
  529. ;
  530. DECODR    EQU    $        ; Decode and output the index supplied in "DE"
  531. ;
  532.     LD    IY,STKLIM    ; Stack overflow check as a safety precaution
  533.     ADD    IY,SP        ; (limit allows extra for this invocation lvl)
  534.     JP    NC,STKOVF    ; Br on overflow (shouldn't happen)
  535.  
  536.     PUSH    HL        ; Only "HL" need be saved
  537.  
  538.     LD    A,D        ; Convert index in "DE" to address in "HL"
  539.     ADD    A,TABLHI
  540.     LD    H,A
  541.     LD    L,E        ; Address now in "HL"
  542.  
  543.     LD    A,(HL)        ; Make sure the entry exists
  544.     AND    0DFH
  545.     CP    80H        ; (Value for a vacant entry)
  546.     JR    NZ,OK1        ; Br if so (normal case)
  547. ;
  548. ;...............................
  549. ;
  550.     LD    A,01H        ; The "ugly" exception, wswsw
  551.     LD    (ENTFLG),A    ; Set flag so entry isn't made twice
  552.     PUSH    HL        ; Save current stuff.
  553.     LD    HL,(LASTPR)    ; Get the last pred..
  554.     LD    A,20H        ; (setting this flag will flag the entry as
  555.     LD    (FFFLAG),A    ; - referenced,)
  556.     LD    A,(CHAR)    ; Get the last char
  557.     CALL    ENTERX        ; Make an on the fly entry...
  558.     XOR    A
  559.     LD    (FFFLAG),A    ; Put this back to normal
  560.     POP    HL        ; And presto...
  561.     LD    A,(HL)        ; It had better exist now!
  562.     CP    80H
  563.     JR    Z,FATBAD    ; *** else file is fatally invalid ***
  564. ;
  565. ;...............................
  566. ;
  567. OK1:    LD    D,(HL)        ; Normal code- get "pred" (hi)
  568.     RIGHT1            ; Move to "pred" (lo)
  569.     LD    E,(HL)        ; Get that. if MSB of hi byte is set, val must
  570.     BIT    7,D        ; - be "FF" (nopred) because it isn't "80H"
  571.     JR    NZ,TERM        ; If so, branch. this terminates recursion.
  572.     RES    5,D        ; Else clear flag bit & decode pred we found
  573.     CALL    DECODR        ; Decode and output the "pred" (recursive call)
  574.     RIGHT1            ; Move pointer ahead to the "suffix" byte
  575.     LD    A,(HL)        ; Get it
  576.  
  577. SAMABV:    CALL    SEND        ; Output the "suffix" byte
  578.     POP    HL        ; Restore reg and return
  579.     RET
  580.  
  581. TERM:    RIGHT1            ; Move pointer ahead to the suffix byte
  582.     LD    A,(HL)        ; Get it & save it. it is the 1st char of the
  583.     LD    (CHAR),A    ; - decoded string, and will be used later to
  584.     JR    SAMABV        ; - attempt to make a new table entry.
  585.                 ; (rest is same as above)
  586. ;
  587. ;_______________________________________________________________________
  588. ;
  589. FATBAD:    LD    DE,ERR4        ; "invalid crunched file"
  590.     JP    CHKSOK        ; Write out whatever we have, then next file
  591.                 ; (Stack gets reloaded before next file)
  592. ;
  593. ;_______________________________________________________________________
  594. ;
  595. ; Enter { <pred>, <suffix> } into the table, as defined in { HL, A }
  596. ;
  597. ENTERX:    PUSH    AF        ; Save the suffix till we're ready to enter it
  598.     PUSH    HL        ; Save pred, xferred to "DE" just below
  599.     CALL    FIGURE        ; Puts result in "phyloc" only, affects nothing
  600.     POP    DE        ; Put pred in "DE" (pushed as "HL" above)
  601.     LD    HL,(ENTRY)    ; Get next avail entry#
  602.     LD    A,H        ; Convert that to an address
  603.     ADD    A,TABLHI
  604.     LD    H,A
  605. ;
  606. ; Entries are made here, but not normally flagged as "referenced" until
  607. ; the are received by "DECODE".  Until they are flagged as referenced,
  608. ; theyare "bumpable" i.e., available for code reassignment.  If "FFFLAG"
  609. ; is set to 20H, however, they will be flagged now.  This only occurs
  610. ; during initialization (bumping an atomic entry would be most unfortu-
  611. ; nate) and when a WsWsW string encounter initiates an emergency entry,
  612. ; despite the code never having been received by "DECODE".
  613. ;
  614.     LD    A,(FFFLAG)    ; Normally zero, as described above
  615.     OR    D
  616.     LD    (HL),A        ; Make the entry- pred (hi) first
  617.     RIGHT1            ; Move to pred (lo) position
  618.     LD    (HL),E        ; Put that in
  619.     RIGHT1            ; Move to suffix position
  620.     POP    AF        ; Retrieve the suffix, saved on entry
  621.     LD    (HL),A        ; Stick it in
  622.     LD    HL,(ENTRY)    ; Increment the entry# counter
  623.     INC    HL
  624.     LD    (ENTRY),HL
  625.     INC    HL        ; See if a new code length is indicated. the
  626.     LD    A,(TRGMSK)    ; - extra inc "HL" above is to account for
  627.     CP    H        ; - skew delays of uncruncher vs. cruncher
  628.     RET    NZ        ; Normally just return
  629.  
  630.     SLA    A        ; Change to a new code length
  631.     LD    (TRGMSK),A    ; This will be the next target mask
  632.     LD    A,(CODLEN)    ; Get the old code length, as a #of bits
  633.     INC    A        ; Increment it, too
  634.     CP    13        ; Check for overflow (12 bits is the max)
  635.     JR    Z,FLGFUL    ; If so, flag table as full
  636.     LD    (CODLEN),A    ; Else this is the new code length
  637.     RET
  638. ;
  639. ;...............................
  640. ;
  641. FLGFUL:    LD    A,0FEH        ; Flag table as full
  642.     LD    (FULFLG),A
  643.     RET
  644. ;
  645. ;.......................................................................
  646. ;
  647. ; Get the next code by stripping the appropriate #of bits off the input
  648. ; stream, based on the current code length "CODLEN".  If the code is
  649. ; "NULL", don't even return; just get another one.  If the code is one
  650. ; of the other special codes, return with the carry flag set. "Spare" is
  651. ; actually treated like a "null" for the time being, since it's use has
  652. ; yet to be defined.
  653. ;
  654. GETCOD:    LD    DE,0000        ; Init "shift register" to zero
  655.     LD    A,(CODLEN)    ; Get current code length
  656.     LD    B,A        ; Will be used as a loop counter
  657.     LD    A,(CSAVE)    ; "leftover" bits
  658.  
  659. GETLP:    SLA    A        ; Shift out a bit
  660.     CALL    Z,REF        ; Refill when necessary
  661.     RL    E        ; Shift in the bit shifted out
  662.     RL    D        ; Likewise
  663.     DJNZ    GETLP        ; Loop for #of bits needed
  664.  
  665.     LD    (CSAVE),A    ; Save "leftover" bits for next time
  666.     LD    A,D        ; If hi-byte = "01", we may have a special code
  667.     DEC    A        ; Set z if it was "1"
  668.     AND    A        ; Clr carry
  669.     RET    NZ        ; Rtn w/ clr carry if byte wasn't "01"
  670. ;
  671. ;...............................
  672. ;
  673.     LD    A,E        ; Else further analysis necessary
  674.     CP    4        ; Set carry on 100, 101, 102, 103
  675.     RET    NC        ; Else code is normal, rtn with clr carry
  676.     CP    LOW(NULCOD)    ; Is it the "NULL" code?
  677.     JR    Z,GETCOD    ; If so, just go get another code
  678.     CP    LOW(SPRCOD)    ; (treat the unimplemented "spare" like a null)
  679.     JR    Z,GETCOD    ; As above
  680.  
  681.     SCF            ; < rtn with carry set indicating special code
  682.     RET            ; (presumably "EOF" or "reset")
  683. ;
  684. ;_______________________________________________________________________
  685. ;
  686. ; Routine to reload "A" with more bits from the input stream.  Note we
  687. ; pre-shift out the next bit, shifting in a "1" from the left.    Since
  688. ; the leftmost bit in the reg is a guaranteed "1", testing the zero
  689. ; stat of the  accumulator later is a necessary and sufficient condition
  690. ; for determining that all the bits in the accumulator have been used.
  691. ;
  692. ; The only things to be careful of is that the last bit is NOT used la-
  693. ; ter, and that the bit now in the carry flag IS used upon return from
  694. ; this    subroutine.  (This is the identical scheme used in USQFST.  An
  695. ; exact complement to it is incorporated for shifting bits out in the
  696. ; CRUNCH program).
  697. ;
  698. REF:    CALL    GETCHR        ; Get the char
  699.     JR    C,PHYEOF    ; Br if unexpected physical eof encountered
  700.     SCF            ; To shift in the "1" from the right
  701.     RLA            ; Do that, shifting out a "real" bit
  702.     RET            ; Rtn (with that real bit in the carry flag)
  703. ;
  704. ;_______________________________________________________________________
  705. ;
  706. PHYEOF:    LD    SP,TOPSTK    ; "Emergency exit"- reset stack
  707.     LD    DE,UNXEOF    ; "Unexpected eof."
  708.     CALL    MESAGE
  709.     JP    CHKSOK        ; Write out what we have, then continue
  710. ;
  711. ;_______________________________________________________________________
  712. ;
  713. ; Send character to the output buffer, plus related processing
  714. ;
  715. SEND:    EXX            ; Alt regs used for output processing
  716.     SRL    B        ; If reg is "1", repeat flag is set
  717.                 ; (note, clears itself automatically)
  718.     JR    C,REPEAT    ; Go perf the repeat
  719.     CP    90H        ; Else see if char is the repeat spec
  720.     JR    Z,SETRPT    ; Br if so
  721.     LD    C,A        ; Else nothing special- but always keep
  722.     EXX            ; Back to normal regs
  723.     CALL    OUTC        ; Else just output the char;
  724.     RET
  725. ;
  726. ;.......................................................................
  727. ;
  728. ; Set repeat flag; count value will come as the next byte. (Note: don't
  729. ; clobber C with the "90H"- it still has the prev character, the one to
  730. ; be repeated)
  731. ;
  732. SETRPT:    INC    B        ; Set flag
  733.     EXX            ; Switch to primary regs & return.
  734.     RET
  735. ;
  736. ;.......................................................................
  737. ;
  738. ; Repeat flag was previously set; current byte in a is a count value.
  739. ; A zero count is a special case which means send 90H itself.  Otherwise
  740. ; use B (was the flag) as a counter. The byte itself goes in A.
  741. ;
  742. REPEAT:    OR    A        ; Check for special case
  743.     JR    Z,SND90H    ; Jump if so
  744.     DEC    A        ; Compute "count-1"
  745.     LD    B,A        ; Juggle registers
  746.     PUSH    BC        ; The count and the char
  747.     LD    B,0        ; Zero the count in advance
  748.     EXX
  749.     POP    BC
  750.  
  751. AGAIN:    LD    A,C
  752.     PUSH    BC
  753.     CALL    OUTC        ; Repeat b occurrences of byte in 'c'
  754.     POP    BC
  755.     DJNZ    AGAIN        ; Leaves b, the rpt flag, 0 as desired
  756.     RET
  757. ;
  758. ;...............................
  759. ;
  760. SND90H:    LD    A,90H        ; Special case code to send the byte 90h
  761.     EXX
  762.     CALL    OUTC
  763.     RET
  764. ;
  765. ;.......................................................................
  766. ;
  767. ; Send the char in "A" to the output buffer and add it to the running
  768. ; checksum.
  769. ;
  770. OUT    EQU    $
  771. OUTC:    CALL    OUTB        ; Output it
  772.     CALL    CKSUM        ; Add to the checksum
  773.     RET
  774. ;
  775. ;_______________________________________________________________________
  776. ;
  777. ; Convert the middle letter of the filename extension to a "Z" if it is
  778. ; "?", AND "difdu" = 0.  If we are uncrunching to a different DU:, get
  779. ; all files.
  780. ;
  781. FIXFCB:    LD    A,(DIFDU)
  782.     OR    A
  783.     RET    NZ        ; If this flag is set, leave ext char untouched
  784.     LD    HL,INFCB+10    ; Point to middle letter of extension
  785.     LD    A,'?'
  786.     CP    (HL)        ; See if it is ambiguous
  787.     RET    NZ        ; If not, we'll allow any letter (rev v1.2)
  788.     LD    (HL),'Z'    ; Else force it to "Z". this is mainly so
  789.     RET            ; The command line uncr *.* will work well
  790. ;
  791. ;_______________________________________________________________________
  792. ;
  793. ; Flag files to be copied, not uncompressed
  794. ;
  795. EXCLUD:    LD    BC,12        ; Leave 12 in bc for incrementing ix
  796.     LD    IX,FNBUFF    ; Points to beg of filenames
  797.  
  798. OUTLP:    LD    A,(IX+0)    ; Get flag byte for this entry
  799.     CP    0FFH        ; Final [non-] entry?
  800.     RET    Z        ; (return if so)
  801.  
  802.     OR    A        ; Is it an untagged filename?
  803.     JR    Z,NXTFN        ; If so, leave it that way & move to next
  804.     LD    A,(IX+10)    ; Otherwise check middle letter of fn ext
  805.     CP    'Z'        ;
  806.     JR    Z,NXTFN        ; If 'z', do not exclude it
  807.     CP    'Q'        ;
  808.     JR    Z,NXTFN        ; Likewise 'q', else "exclude" it
  809. ;
  810. ;-----------------------------------------------------------------------
  811. ;
  812. AUTOM3:    LD    A,02H        ; Flag file as "excluded"
  813.     LD    (IX+0),A
  814.  
  815. NXTFN:    ADD    IX,BC        ; Move to next filename in "fnbuff"
  816.     JR    OUTLP
  817. ;
  818. ;_______________________________________________________________________
  819. ;
  820. ; Type the stuff in the "stamp" buffer to the console.
  821. ;
  822. PRNID:    LD    DE,SPACE3    ; Precede with 3 spaces
  823.     CALL    MESAG2
  824.     LD    HL,STAMP    ; Point to that buffer
  825.     LD    B,40        ; Practical limit of 40 char "stamp"
  826.  
  827. PRFILP:    LD    A,(HL)        ; Get a character
  828.     OR    A        ; Zero terminates the field
  829.     RET    Z        ; Return when encountered
  830.     CALL    TYPE        ; Else type the char
  831.     CP    ']'        ; This terminates stamp also (after typing it)
  832.     RET    Z        ; Return if that happened
  833.     INC    HL        ; Else incr pointer
  834.     DJNZ    PRFILP        ; And loop
  835.     RET
  836. ;
  837. ;_______________________________________________________________________
  838. ;
  839. STKOVF:    LD    DE,ERR6        ; "*** stack overflow ***"
  840.     LD    SP,TOPSTK    ; Shouldn't happen, but we're still in control
  841.     JP    FATBAD        ; Reset and continue with next file, if any
  842. ;
  843. ;_______________________________________________________________________
  844. ;
  845. ; Initialize the table to contain the 256 "atomic" entries - { "NOPRED",
  846. ; <char> },  for all values of <char> from 0 thru 255
  847. ;
  848. INITB2:    CALL    PRESE2        ; "pre-initializes" the table (mostly zeroes)
  849.     LD    A,20H
  850.     LD    (FFFLAG),A
  851.     XOR    A        ; Start with a suffix of zero
  852.     LD    HL,NOPRED    ; Pred for all 256 atomic entries
  853.  
  854. INILP:    PUSH    HL
  855.     PUSH    AF
  856.     CALL    ENTERX
  857.     POP    AF
  858.     POP    HL
  859.     INC    A        ; Next suffix
  860.     JR    NZ,INILP    ; Loop 256 times
  861. ;
  862. ;.......................................................................
  863. ;
  864. ; Now reserve the four reserved codes 100H - 103H (EOF, RESET, NULL, and
  865. ; SPARE.  This is easily achieved by inserting values in the table which
  866. ; cannot possibly be matched, and insuring that they cannot be reas-
  867. ; signed.  An occurrence of any of these codes is possible only when the
  868. ; cruncher explicitely outputs them for the special cases for which they
  869. ; are designated.
  870. ;
  871.     LD    B,4        ; Loop counter for the 4 reserved entries
  872.  
  873. RSRVLP:    PUSH    BC
  874.     LD    HL,IMPRED    ; An "impossible" pred
  875.     XOR    A        ; Any old suffix will do
  876.     CALL    ENTERX        ; Make the entry
  877.     POP    BC
  878.     DJNZ    RSRVLP        ; Loop 4 times
  879.  
  880.     XOR    A        ; Now restore this flag to its normal value
  881.     LD    (FFFLAG),A
  882.     RET
  883. ;
  884. ;.......................................................................
  885. ;
  886. ; Low-level table preset called before initialization above. This rou-
  887. ; tine presets the main table as follows: (see description of table
  888. ; elsewhere):  Column 1: 4096 x 80H, Columns 2 and 3: 4096 x 00H
  889. ;
  890. PRESE2:    LD    HL,TABLE    ; Beginning of main table, 4096 rows x 3 columns
  891.     LD    DE,TABLE+1
  892.     LD    BC,1000H
  893.     LD    (HL),80H
  894.     LDIR            ; Put in 1000h "80H"'s
  895.     LD    (HL),0        ;
  896.     LD    BC,2*1000H-1    ; Note "-1"
  897.     LDIR            ; And 2000h more "00H"'s
  898. ;
  899. ;.......................................................................
  900. ;
  901. ; The auxiliary physical translation table is 5003 rows 2 columns
  902. ; (logically speaking).  Actually 5120 rows, 2 columns are allocated.
  903. ; All entries are initialized to 80H.
  904. ;
  905.     LD    HL,XLATBL    ; Physical <--> logical xlation table
  906.     LD    DE,XLATBL+1
  907.     LD    BC,2800H    ; Total entries = 1400h x 2
  908.     LD    (HL),80H
  909.     LDIR
  910.     LD    A,7FH
  911.     LD    (XLATBL+0),A
  912.     RET
  913. ;
  914. ;_______________________________________________________________________
  915. ;
  916. ; Figure out what physical location the cruncher put its entry by repro-
  917. ; ducing the hashing process.  Insert the entry# into the corresponding
  918. ; physical location in XLATBL.
  919. ;
  920. FIGURE:    LD    B,A        ; < suffix supplied goes into B
  921.     CALL    HASH        ; Get initial hash value into  "HL"
  922.  
  923. PHYLP:    LD    C,H        ; C  <-- extra copy of h
  924.     LD    A,(HL)        ; Check if any entry exists at that location
  925.     CP    80H        ; Value for a vacant spot
  926.     JR    Z,ISMT        ; Br if vacant
  927.     CALL    NM        ; Else find next in chain
  928.     JR    PHYLP        ; And continue
  929. ;
  930. ;...............................
  931. ;
  932. ISMT:    LD    DE,(ENTRY)    ; Get the logical entry#
  933.     LD    (HL),D        ; Stick in hi-byte
  934.     LD    A,H        ; Move "right1" for this table
  935.     ADD    A,14H
  936.     LD    H,A
  937.     LD    (HL),E        ; Low-byte goes there
  938.     RET
  939. ;
  940. ;...............................
  941. ;
  942. NM    EQU    $        ; No match yet... find next "link" in chain
  943. ;
  944.     LD    DE,(DISP)    ; Secondary probe- add disp computed by "HASH"
  945.     ADD    HL,DE
  946.     LD    A,H
  947.     CP    XLATBH        ; Check for loop around
  948.     JR    NC,NC9        ; Br if not
  949.     LD    DE,5003        ; Else loop
  950.     ADD    HL,DE
  951.  
  952. NC9:    RET
  953. ;
  954. ;.......................................................................
  955. ;
  956. ENTFIL    EQU    $        ; Try to enter the pred/suffix in HL|A
  957. ;
  958.     CALL    HASH        ; Get initial hash value into  "HL"
  959. ;
  960. ;.......................................................................
  961. ;
  962. PHYLP2:    LD    A,(HL)        ; Check if any entry exists at that location
  963.     CP    80H        ;
  964.     RET    Z        ; End of chain, return w/o reassignment
  965. ;
  966. ;...............................
  967. ;
  968.     PUSH    HL        ; Save physical table pointer
  969.     LD    D,(HL)        ; Get entry#, hi
  970.     LD    A,H        ; }
  971.     ADD    A,14H        ; } right 1 for this table
  972.     LD    H,A        ; }
  973.     LD    L,(HL)        ; Entry#, lo byte
  974.     LD    A,D
  975.     ADD    A,TABLHI    ; Convert to an addr in "HL"
  976.     LD    H,A
  977.     BIT    5,(HL)        ; See if entry is bumpable
  978.     JR    Z,MAKIT        ; If so bumpable, go do it
  979.     POP    HL        ; Else restore physical tbl pointer
  980.     CALL    NM        ; Find next "link" in chain
  981.     JR    PHYLP2        ; And continue
  982. ;
  983. ;.......................................................................
  984. ;
  985. ; Reassign the entry pointed to by "avail", if any. Re-define the "last
  986. ; pred entered" and "last suffix" variables.
  987. ;
  988. MAKIT:    POP    DE        ; Get rid of extraneous physical pointer
  989.     LD    DE,(TTOTAL)    ; Increase user's display count
  990.     INC    DE
  991.     LD    (TTOTAL),DE
  992.     LD    DE,(LASTPR)    ; Get the pred
  993.     LD    A,(CHAR)    ; And suffix
  994.     LD    B,A        ; Put suffix here, ("right1" kills a)
  995.     LD    (HL),D        ; Actually make the entry
  996.     RIGHT1
  997.     LD    (HL),E        ; [pred(lo)]
  998.     RIGHT1
  999.     LD    (HL),B        ; [suffix]
  1000.     RET            ; Done
  1001. ;
  1002. ;.......................................................................
  1003. ;
  1004. ; For additional details about the hashing algorithm, see CRUNCH.
  1005. ;
  1006. HASH    EQU    $
  1007. ;
  1008.     LD    E,L        ; Save so low-nybble of pred can be used below
  1009.     ADD    HL,HL
  1010.     ADD    HL,HL
  1011.     ADD    HL,HL
  1012.     ADD    HL,HL        ; Shift whole pred value left 4 bits
  1013.     XOR    H        ; Xor hi-byte of that with suffix
  1014.     LD    L,A        ; Goes there as lo-byte of result
  1015.     LD    A,E        ; Get pred(lo) saved above
  1016.     AND    0FH        ; Want only low nybble of that
  1017.     ADD    A,XLATBH    ; Convenient time to add in table offset
  1018.     LD    H,A        ; Goes here as hi-byte of result
  1019.     INC    HL        ; Except add one. this eliminates poss. of 0.
  1020.     PUSH    HL        ; Save hash val for return
  1021.     LD    DE,-5003-XLATBL    ; Compute displacement value, - (5003-hash)
  1022.     ADD    HL,DE        ; (displacement has table offset removed again)
  1023.     LD    (DISP),HL    ; Secondary hashing value, a negative number.
  1024.     POP    HL        ; Get back orig hash address
  1025.     RET            ; And return it
  1026. ;
  1027. ;=======================================================================
  1028. ;
  1029. ; For old style (v1.x) type crunched files, simply call the "UNCR1"
  1030. ; module.  Squeezed files are handled identically, except call "USQREL"
  1031. ; module.  All I/O will be done by this program - UNCR1 will get and
  1032. ; feed data through calls to entry points "GETBYT" and "OUT".
  1033. ;
  1034. OLDTYP:    CALL    GETCHR        ; Get checksum flag
  1035.     LD    (CKSMFL),A    ; Put it there
  1036.     CALL    GETCHR        ; Get spare byte, do nothing with it *** nec??
  1037.  
  1038. USQZIT:    LD    A,0FFH        ; Flag this as an old style uncrunch
  1039.     LD    (OLDFLG),A    ; (controls type of screen updating)
  1040.     CALL    OPNOUT        ; Open output file & type "--->  <filename>"
  1041.     PUSH    AF        ; Save stat from abv call
  1042.     LD    A,(SQZFLG)    ; *** necessary?
  1043.     OR    A
  1044.     CALL    Z,PRNID        ; Type any embedded date stamp info also
  1045.     POP    AF        ; Get back carry stat
  1046.     JP    C,SKIP2A    ; If user wants to skip it
  1047.     CALL    CRLF        ; More aesthetics
  1048.     EXX            ; Go back to start of file (already read some)
  1049.     LD    HL,IBUF
  1050.     EXX
  1051.  
  1052. FIX21:    LD    HL,SECNT    ; Bugger up the sector count since we just
  1053.     INC    (HL)        ; - reset the input pointer
  1054.     LD    HL,(INCTR)    ; [rev 2.1 fix]
  1055.     DEC    HL        ; Decr "inctr" for same reason
  1056.     LD    (INCTR),HL
  1057.     LD    A,'0'        ; [Rev 2.1 fix]
  1058.     LD    (PROGBF+5),A    ; Reset ascii display to zero
  1059.     LD    HL,TABLE    ; Point to large data area for uncr1
  1060.     LD    A,(SQZFLG)
  1061.     OR    A
  1062.     JR    NZ,USESQZ    ; If squeezed, call usqrel rather than uncr1
  1063.     CALL    UNCR1        ; Uncrunch the whole thing
  1064.  
  1065. ABVQ:    JP    NC,DUNDUN    ; A "normal" return
  1066.     JP    FATBAD        ; Any other error falls under "invalid.."
  1067.  
  1068. USESQZ:    CALL    USQREL        ;
  1069.     LD    DE,(SQCKSM)    ; Get checksum read at beginning of file
  1070.     JP    NC,DUNDUQ    ; Terminate similarly (w/o reading cksm bytes)
  1071.     JP    FATBAD
  1072. ;
  1073. ;_______________________________________________________________________
  1074. ;
  1075. PRCSTM:    LD    DE,PRSER1    ; "invalid argument" (no stamps allowed)
  1076.     JP    FATALU
  1077. ;
  1078. ;_______________________________________________________________________
  1079. ;
  1080. UCASE:    CP    'a'        ; Upper-case character in A
  1081.     RET    C
  1082.     SUB    20H        ; (Note "{","|","}",and "~" cannot occur)
  1083.     RET
  1084. ;
  1085. ;_______________________________________________________________________
  1086. ;
  1087. VUNITS    EQU    (REV/16)+'0'      ; Version, units dig, in ascii
  1088. VTNTHS    EQU    (REV AND 0FH)+'0' ; Version, tenths dig, in ascii
  1089.  
  1090. INTRO:    DB    'GEL Uncruncher v',VUNITS,'.',VTNTHS,CR,LF,'$'
  1091. BADCHK:    DB    'Checksum error detected.',CR,LF,'$'
  1092. MSG43:    DB    '    [ Not compressed ]',CR,LF,'$'
  1093. ERR4:    DB    'Invalid Crunched File.',CR,LF,'$'
  1094. ERR5:    DB    'File requires newer program rev.',CR,LF,'$'
  1095. ERR6:    DB    'Stack Overflow.',CR,LF,'$'
  1096. SPACE3:    DB    '   $'
  1097. UNXEOF:    DB    'Unexpected EOF.',CR,LF,'$'
  1098.  
  1099. USAGE:    DB    CR,LF,'Usage:',CR,LF,LF
  1100.  
  1101.     DB    '                Filename   (space)',CR,LF
  1102.     DB    '               /            |',CR,LF
  1103.     DB    ' UNCR  {du:}<afn>  {du:}   { /<options> }',CR,LF
  1104.     DB    '         \           \             \',CR,LF
  1105.     DB    '          Source      Destination   Option letters'
  1106.     DB    CR,LF,LF
  1107.     DB    ' <options> is up to 3 letters immediately following a " /".',CR,LF
  1108.     DB    ' "Q" = Quiet mode  "C" = Confirm (tag) mode  "O" = Overwrite mode',CR,LF
  1109.     DB    ' Option letters toggle (reverse) the corresponding default setup.',CR,LF
  1110.     DB    CR,LF
  1111.     DB    ' Both "du:" are of form DU:, UD:, D:, or U:',CR,LF
  1112.     DB    CR,LF
  1113.     DB    '  Everything is optional except filename.',CR,LF,LF,'$'
  1114. ;
  1115. ;_______________________________________________________________________
  1116.  
  1117.     INCLUDE    COMMON.LIB
  1118. ;_______________________________________________________________________
  1119. ;
  1120. ; Additional miscellaneous ram locations which need not be initialized
  1121. ; or are initialized by the routines which use them.
  1122. ;
  1123. CKSMFL:    DS    1        ; Skip checksum if flag non-zero
  1124. CHAR:    DS    1        ; Last char of the previously decoded string
  1125. FFFLAG:    DS    1
  1126. CSAVE:    DS    1
  1127. SQCKSM:    DS    2
  1128. ;
  1129. ;...............................
  1130. ;
  1131. STKSZ    EQU    8        ; Minimum stack size (pages)
  1132. IBUFSZ    EQU    8        ; Input buffer size (pages)
  1133. ;
  1134. ;=======================================================================
  1135. ;
  1136. ; ===>    All tables will begin at "MEMPAG", defined at the top of the
  1137. ;    program.  This should be set to a page aligned value i.e., ad-
  1138. ;    dress that ends  in "00", which is ABOVE the end all program
  1139. ;    and data segments.  You may have to do one test link to deter-
  1140. ;    mine the proper value (changing "MEMPAG" will not change the
  1141. ;    length of the segments on the subsequent link).
  1142. ;
  1143. ; "MEMPAG" is defined at the beginning of this program to remind you to
  1144. ; set it properly.  If you set it higher than necessary, there will be
  1145. ; no negative effect other than an increase in the TPA required to run
  1146. ; the program.    If you set it too low, you will be in big trouble.  The
  1147. ; value must be set manually because most linkers cannot resolve an
  1148. ; "and", "shift", or "hi" byte extraction at link time to determine the
  1149. ; page boundary.
  1150. ;
  1151. ;=======================================================================
  1152. ;
  1153. ; "MAXFLS" is  buffer size (in files) for wildcard expansions.    Room for
  1154. ; this many files will be allocated.
  1155. ;
  1156. MAXFLS    EQU    256
  1157.  
  1158. FNBUFF    EQU    MEMPAG           ; (= beg of wildcard expansion buffer)
  1159. ENDFNB    EQU    FNBUFF+(12*MAXFLS) ; End of expansion buffer
  1160.  
  1161. IBUF    EQU    ENDFNB           ; (= beg of input buffer)
  1162. EIBUF    EQU    IBUF+(IBUFSZ*256)  ; End of input buffer
  1163.  
  1164. TABLE    EQU    EIBUF           ; (= beg of table)
  1165. EOTBL    EQU    TABLE+(3*1000H)       ; End of table
  1166. XLATBL    EQU    EOTBL
  1167. EXLATB    EQU    XLATBL+(2*1400H)
  1168. STAMP    EQU    EXLATB           ; 80h bytes for "stamp" buffer
  1169. ESTAMP    EQU    STAMP+80H
  1170.  
  1171. SAFETY    EQU    ESTAMP           ; Safety region- beyond legal bottom of stack
  1172. BOTSTK    EQU    SAFETY+80H       ; "Legal" stack limit
  1173. TOPSTK    EQU    EXLATB+(STKSZ*256) ; Top of stack
  1174.  
  1175. ENDALL    EQU    TOPSTK           ; End of everything, except output buffer
  1176. OBUF    EQU    ENDALL           ; Beginning of dynamically sized output buffer
  1177. ;
  1178. ;.......................................................................
  1179. ;
  1180. STKLIM    EQU    0-BOTSTK    ; Negation of "botstk", used as safety check
  1181.  
  1182. IBUFHI    EQU    HIGH IBUF    ; Input bfr addr, hi byte (lo byte = 0)
  1183. EIBFHI    EQU    HIGH EIBUF    ; End of input bfr addr, hi byte, likewise
  1184. TABLHI    EQU    HIGH TABLE    ; Beg of table, hi byte, likewise
  1185. ETBLHI    EQU    HIGH EOTBL    ; End of table, hi byte, likewise
  1186. XLATBH    EQU    HIGH XLATBL
  1187. EFNBHI    EQU    HIGH ENDFNB    ; End of expansion buffer, likewise
  1188. ENDHI    EQU    HIGH ENDALL    ; End of everything, likewise
  1189. OBUFHI    EQU    HIGH OBUF    ; Output buffer address, hi byte likewise
  1190.  
  1191.     END
  1192.