home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug078.arc / UNCR.ZZ0 / UNCR.Z80
Text File  |  1979-12-31  |  38KB  |  1,083 lines

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