home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols100 / vol193 / bishow31.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  45.9 KB  |  1,867 lines

  1. ;    title    'BISHOW v3.01 - buffered bidirectional file scroll utility'
  2. ;
  3. ; Ver 3.01, 15 Jan 84, Frans van Duinen, Toronto, Ont
  4. ;    - made unsqueeze message optional
  5. ;    - added library capability
  6. ;    - fixed bug in conditional assembly of CLRSCR
  7. ;
  8. ; Ver 2.09, 7 Jan 84, Frans van Duinen, Toronto, Ont
  9. ;    - Modified USQ routines for higher speed (+10%) and
  10. ;     less memory usage.
  11. ;    - made USQ code optional through conditional assembly
  12. ;    - fixed a bug introduced with 2.08 and SHORT=TRUE 
  13. ;      (resulted from ASM's inability to nest IF/ENDIF) 
  14. ;    - fixed a bug  that reset FCBEX after open, whenever
  15. ;      sector 0 was read, (this resulted in BDOS assuming that
  16. ;      the current extent, whose allocation group nos were still
  17. ;      in the FCB, was the correct one. 
  18. ;    - Changed exit to clear screen only on Q or ^C exit,
  19. ;      to leave any messages visible
  20. ;    - Made wait after clear screen a cond assembly option
  21. ;
  22. ; Ver 2.08, 2 Jan 84, Frans van Duinen, Toronto, Ont
  23. ;    - added squeezed file capability
  24. ;    - added sidewise scrolling on ^I, ^L, steps of 8
  25. ;    - Osborne support for cursor keys, clr scr & scr size
  26. ;    - Changed FILBAK rtn to recognize top of file
  27. ;    - Set up flag to avoid unnecessary re-reading of
  28. ;      top of file 
  29. ;
  30. ;    The unsqueeze code was lifted from the USQ base code
  31. ;    by Dave Rand (Edmonton, Alberta) as adapted for LTYPE1
  32. ;    by S.Kluger (El Paso,Texas)
  33. ;    The code was lifted to allow continued use of ASM.COM 
  34. ;
  35. ; Ver 1.07, 1 Aug 83, Ted H. Emigh  ...!unc!tucc!emigh
  36. ;    - added screen width specification
  37. ;    - added screen definition commands (see notes below)
  38. ;
  39. ; Ver 1.06, 2 Jul 83, Chuck Forsberg
  40. ;    - added commands for more, mince, vi familiarity.
  41. ;      Bad cmd gives help
  42. ;
  43. ; Ver 1.051, 26 June 83, Dick Mead
  44. ;    - added "?" for help on commands.
  45. ;
  46. ; Ver 1.05, 31 May 83, Bruce Ratoff
  47. ;    - added 'N' (next line) and 'P' (previous line) cmds
  48. ;    - decreased buffer from 8k to 4k (8k takes too long)
  49. ;
  50. ; Ver 1.04, 15 May 83, Keith Petersen, W8SDZ
  51. ;    - fixed bug which caused display past end-of-file
  52. ;        and added bogus eof in case none at file end
  53. ;    - added strip of high-order bit in line count routine
  54. ;    - added exit clear of any left-over keyboard character
  55. ;
  56. ; Ver 1.03, 11 May 83, Keith Petersen, W8SDZ
  57. ;    - fixed to allow assembly with ASM.COM
  58. ;    - fixed screen clear bug when crossing read boundries
  59. ;    - added strip for high-order bit in character before
  60. ;        printing (needed for WordStar files)
  61. ;    - improved stack routines
  62. ;    - fixed bug in console input routine
  63. ;    - removed Z80 dependant code (now works on 8080 too)
  64. ;
  65. ; Ver 1.02, 06 May 83, Lucien Pan, Toronto, Canada
  66. ;     - fixed some minor bugs
  67. ;     - returns to ccp w/o warm boot
  68. ;     - filters form-feeds (useful in .PRN files)
  69. ;     - scrolls foward/backwards by same number of lines
  70. ;     - disable/enable cursor during scroll for H-19
  71. ;
  72. ; Ver 1.01, 30 Mar 83 - added BDOS function  6.  W.F.Mcgee
  73. ;
  74. ; Ver 1.00, 23 Aug 82 Phil Cary, 748 Kenilworth Parkway, Baton
  75. ; Rouge, LA  70808
  76. ;
  77. ; BISHOW is a  buffered,  bidirectional  version  of  SHOW.ASM
  78. ; which first appeared in Interface Age, November, 1981.  That
  79. ; program  could  only  scroll  forward  in  a  file, and read
  80. ; sectors from disk one at a time as they  were  sent  to  the
  81. ; console.   I  used SHOW frequently to take a quick look at a
  82. ; file without loading a  big  text  editor,  and  to  examine
  83. ; another  file  with the RUN command while in Wordstar.  TYPE
  84. ; does not work since it is not a file that Wordstar can  load
  85. ; and run.
  86. ;
  87. ; It was annoying when I went past the point I was looking for
  88. ; in a file with SHOW, and could not go backwards.  Thus, this
  89. ; bidirectional  version  which  uses  random access reads. In
  90. ; addition, buffering was added so that  the  number  of  disk
  91. ; reads  would  be  reduced,  and  moving  back and forth in a
  92. ; moderate sized file would be speeded up.  There is  a  trade
  93. ; off between the size of the buffer and the length of time it
  94. ; takes to refill the buffer which should be set to the user's
  95. ; preference.
  96. ;
  97. ; There are several customizing items in this program.  One is 
  98. ; the equate "maxsec" which sets the buffer size.   Another is 
  99. ; the  string  in the subroutine "clrscr" just after  the  org 
  100. ; statement.   This should be changed to erase the screen  and 
  101. ; home  the cursor for the user's terminal.   The program,  as 
  102. ; written,  requires a terminal with an erase screen and  home 
  103. ; cursor  function.   Some  terminals  do not allow  the  80th 
  104. ; column  to be filled without going to the  next  line.   For 
  105. ; this reason, the screen width ("maxchr") initially is set to 
  106. ; 79.   The screen sizes can be changed using the "S" (screen) 
  107. ; command.  The parameters that can be changed are the maximum 
  108. ; column  displayed ("maxchr"),  the minimum column  displayed 
  109. ; (allowing  you  to "window" the output),  and the number  of 
  110. ; lines ("scroln").   A zero for the maximum column  displayed 
  111. ; will  give and unlimited screen width.   The maximum  column 
  112. ; displayed  and  the number of lines can be set when  calling 
  113. ; BISHOW,  e.g.,  "BISHOW file.nam 79 24" will give 79 columns 
  114. ; and 24 lines,  and "BISHOW file.nam 79" will give 79 columns 
  115. ; with the default number of lines.  The last customizing item 
  116. ; is the "short" equate.   If this is chosen, the multiplicity 
  117. ; of command forms is not allowed (see the beginning to change 
  118. ; the  commands  used),  and certain messages  are  shortened.  
  119. ; This will allow BISHOW to fit into a 1K area.  If "short" is 
  120. ; false, the program is slightly over 1K.  Finally, direct I/O 
  121. ; to the console is used to avoid echoing the commands to  the 
  122. ; console as the CP/M write console function does.
  123. ;
  124. ; Just  a  small contribution to the public domain software as
  125. ; partial payment for the many fine and  educational  programs
  126. ; the system has given me.  Phil Cary.
  127. ;
  128. ;Define version number for help message
  129. VERS    EQU    3        ;Note current use in DB constrains VERS & 
  130. REVS    EQU    10        ; REVS to be one and two digits respectively
  131. ;
  132. FALSE    EQU    0
  133. TRUE    EQU    NOT FALSE
  134. ;
  135. HEATH    EQU    FALSE        ;assemble for H-19 terminal
  136. OSBORNE    EQU    TRUE        ;assemble for Osborne I
  137. SHORT    EQU    FALSE        ;set to true if you want the short version
  138.                 ;which is less than 1K
  139.                 ;Requires also that SQUEEZE is set false
  140. SQUEEZE    EQU    TRUE        ;Generate code to handle squeezed files 
  141. NOWAIT    EQU    TRUE        ;Do not wait after clear screen
  142. SILENT    EQU    TRUE        ;No "unsqueezing text" msg
  143. LIBRARY    EQU    TRUE        ;Optional handling of library type files
  144. ;
  145. ;    Operational equates
  146. ;
  147. MAXSEC    EQU    32        ;number of sectors in buffer
  148. SQSIGN    EQU    0FF76H        ;Signature for SQ files
  149. LBSIGN    EQU    2000H        ;Signature for library files
  150. DLE    EQU    090H        ;Char flag for run compression (SQ)
  151. ;
  152.     IF    NOT OSBORNE
  153. SCROLN    EQU    24        ;number of lines per scroll
  154. MAXCHR    EQU    79        ;number of characters per line
  155. ARWLFT    EQU    08H        ;Cursor left key (backspace)
  156. ARWRT    EQU    09H        ;Cursor right key (tab)
  157.     ENDIF
  158. ;
  159.     IF    OSBORNE
  160. SCROLN    EQU    24        ;number of lines per scroll
  161. MAXCHR    EQU    51        ;number of characters per line
  162. ARWLFT    EQU    08H        ;Cursor left key (backspace)
  163. ARWUP    EQU    0BH        ;Cursor up key (vert tab)
  164. ARWRT    EQU    0CH        ;Cursor right key (formfeed)
  165.     ENDIF
  166.  
  167. ;
  168. BASE    EQU    0        ;standard zero base CP/M
  169. ;
  170. ;    BDOS functions
  171. ;
  172. CONOUT    EQU    2        ;console write
  173. OPEN    EQU    15        ;open file
  174. CLOSE    EQU    16        ;close file
  175. READR    EQU    33        ;read file random access
  176. STDMA    EQU    26        ;set dma address
  177. ;
  178. ;    Page zero equates
  179. ;
  180. WBOOT    EQU    BASE        ;warm boot entry point
  181. BDOS    EQU    WBOOT+5        ;BDOS entry point
  182. FCB    EQU    WBOOT+5CH    ;default fcb drive number
  183. CMDTAIL    EQU    WBOOT+80H    ;location of command tail
  184. FCBFN    EQU    FCB+1        ;start of filename
  185. FCBFT    EQU    FCB+9        ;start of filetype
  186. FCBEX    EQU    FCB+12        ;current extent number
  187. FCBCRR    EQU    FCB+33        ;current record number, random access
  188. TPA    EQU    WBOOT+100H    ;transient program area
  189. ;
  190. ;    ASCII equates
  191. ;
  192. ENDMSG    EQU    0        ;null
  193. BELL    EQU    7        ;bell
  194. BS    EQU    8        ;Backspace
  195. TAB    EQU    9        ;tab
  196. LF    EQU    0AH        ;line feed
  197. CR    EQU    0DH        ;carriage return
  198. EOF    EQU    1AH        ;end of file
  199. ESC    EQU    1BH        ;escape
  200. SPACE    EQU    20H        ;space
  201. ;
  202. ; Equates for the short version
  203. ;
  204. ; Any invalid command gives help
  205. ; in addition to quit, ^C ends the program
  206. ; Be sure to change the help2 printout
  207. ;
  208. NXTPAG    EQU    SPACE        ;next page
  209. BACK    EQU    'B'        ;scroll backward
  210. NEXT    EQU    CR        ;next line
  211. PREV    EQU    '-'        ;previous line
  212. SCREEN    EQU    'S'        ;set screen parameters
  213. QUIT    EQU    'Q'        ;exit bishow
  214. FIRST    EQU    '1'        ;first page
  215. ;
  216.     ORG    TPA
  217. ;
  218.     JMP    START        ;skip over next subroutine
  219. ;
  220. CLRSCR:
  221.     CALL    CDISP        ;command to erase screen and home cursor
  222. ;
  223.     IF    NOT (HEATH OR OSBORNE)
  224.     DB    ESC,'+',ENDMSG    ;put your screen clear string here
  225.     ENDIF
  226. ;
  227.     IF    HEATH
  228.     DB    ESC,'E',ENDMSG    ;__for H/Z-19 terminal. change as required
  229.     ENDIF
  230. ;
  231.     IF    OSBORNE
  232.     DB    1AH,ENDMSG    ;__for Osborne (& Televideo?)
  233.     ENDIF
  234. ;
  235.     IF    NOT NOWAIT
  236. ;
  237. WAIT:    MVI    B,0        ;waste time (may or may not be necessary)
  238. ;
  239. WAIT1:    XTHL            ;good time gobbeler!
  240.     XTHL
  241.     DCR    B
  242.     JNZ    WAIT1
  243. ;
  244.     ENDIF
  245. ;
  246.     RET            ;return from clrscr
  247. HELP2:
  248.     CALL    CDISP
  249.     DB    CR,LF,'Commands:',CR,LF
  250. ;
  251.     IF    NOT SHORT
  252.     DB    '^F,F,^V,sp=next page, ^B,B=back page, '
  253.     DB    '^H=left, ^L=rite'
  254.     DB    CR,LF
  255.     DB    'CR,+,N=next line, '
  256.     DB    '-,P=back line, 1=1st line, ^C,Q=exit',CR,LF,ENDMSG
  257.     ENDIF
  258. ;
  259.     IF    SHORT
  260.     DB    'sp=next page, B=back page',CR,LF
  261.     DB    'CR=next line, '
  262.     DB    '-=back line, 1=1st line, ^C,Q=exit',CR,LF,ENDMSG
  263.     ENDIF
  264. ;
  265.     JMP    GETCMD
  266. ;
  267. START:    LXI    H,0        ;get ccp's stack
  268.     DAD    SP
  269.     SHLD    STACK        ;save old stack for later
  270.     LXI    SP,STACK    ;set new stack
  271.     LXI    H,CMDTAIL    ;point to command tail
  272.     MOV    B,M        ;get number of char in tail
  273.     INX    H        ;point to first character
  274.     INR    B
  275. ;
  276.     CALL    EATSP        ;Step to next non-bl in input
  277.     JZ    OPENF        ;no more characters
  278. ;
  279.     CALL    FILNAM        ;Skip file name, returns <B>=0 or <A>=20H
  280.     JZ    OPENF        ;only file name in tail
  281. ;
  282. ;            Check if there is a member name
  283. ;
  284.     CALL    EATSP        ;Step to next non-bl in input
  285.     JZ    OPENF        ;no more characters
  286.     CPI    '9'+1        ;Numeric?
  287.     JNC    MEMB        ;No -
  288.     CPI    '0'
  289.     JNC    NUMBER        ;Yes - must be width & heigth
  290. ;            Have member name (at FCB+11H)
  291. MEMB:
  292.     STA    MEMNAM        ;No - have member name
  293.     PUSH    H        ;Posn in command line 
  294.     PUSH    B        ;# of chars remaining
  295.     LXI    H,FCB+11H    ;Source
  296.     LXI    D,MEMFCB+1    ;Destination
  297.     MVI    B,11        ;Move name + type
  298.     CALL    MOVE 
  299. ;                add LBR suffix if required
  300.     LXI    H,FCB+9        ;Is there a suffix
  301.     MOV    A,M
  302.     CPI    SPACE
  303.     JNZ    NUMBR2        ;Yes - leave
  304.     MVI    M,'L'
  305.     INX    H
  306.     MVI    M,'B'
  307.     INX    H
  308.     MVI    M,'R'
  309. NUMBR2:
  310.     POP    B
  311.     POP    H
  312.     CALL    FILNAM        ;Skip member name, returns <B>=0 or <A>=20H
  313.     JZ    OPENF        ;end
  314. ;
  315. ;            Handle screen width & height
  316. NUMBER:
  317.     LXI    D,CHRMAX    ;point to chr/line
  318.     CALL    GETNBR        ;get number of characters/line
  319.     JC    HELP        ;invalid number
  320.     LXI    D,LINMAX    ;point to number of lines
  321.     CNZ    GETNBR        ;call only if characters still in
  322.                 ;__command tail
  323.     JC    HELP        ;invalid number
  324. ;
  325. OPENF:    CALL    OPNFIL        ;open file in default fcb
  326. ;
  327.     IF    SQUEEZE
  328. ;
  329.     CALL    CHKSQ        ;Check for squeezed, init if
  330. ;                ;Returns first word in file in <HL>
  331. ;
  332.     ENDIF
  333. ;
  334.     IF    LIBRARY
  335. ;
  336.     CALL    CLRSCR        ;erase the screen
  337.     CALL    FILBF0        ;fill the disk buffer with start of file
  338.     CALL    CHKLB        ;Check for library file
  339.     JMP    WRTFW0        ;Buffer contains top sectors
  340. ;
  341.     ENDIF    
  342. ;
  343. WRTFWD:
  344.     CALL    CLRSCR        ;erase the screen
  345.     CALL    FILBF0        ;fill the disk buffer with start of file
  346. WRTFW0:
  347.     LXI    H,DSKBUF    ;point to beginning of buffer
  348. ;
  349. WRTFW1:
  350.     MOV    A,M        ;get a character
  351.     CPI    EOF        ;see if eof
  352.     JZ    GETCMD        ;yes, wait for command
  353.     INX    H        ;bump pointer
  354.     ANI    7FH        ;strip high bit
  355.     CPI    'L'-40H        ;filter form-feeds
  356.     JZ    FILTER        ;__commonly found in .PRN files
  357.     CALL    CO1        ;put it on console
  358.     CPI    CR        ;see if end of line
  359.     JZ    FWDCNT        ;yes, adjust line count
  360. ;
  361. WRTFW2:    LXI    D,ENDBUF    ;get end of buffer address
  362.     CALL    cmphlde        ;Is HL> gt DE> (end of buff)
  363. ;                ; Note test is LT now, not NE (v1.81)
  364.     JC    WRTFW1        ;continue with next character
  365.     CALL    FILBUF        ;fill the disk buffer with next sectors
  366.     JMP    WRTFW0        ;start over
  367. ;
  368. HELP:    CALL    CDISP
  369.     DB    'BISHOW version '
  370.     DB    (VERS MOD 10)+'0','.'
  371.     DB    REVS/10+'0',(REVS MOD 10)+'0',CR,LF
  372.     DB    'Usage: d:bishow d:fn.ft '
  373. ;
  374.     IF    LIBRARY
  375. ;
  376.     DB    '[member] '
  377. ;
  378.     ENDIF
  379.     DB    '[cols [lines]]',CR,LF
  380.     DB    ENDMSG
  381.     JMP    EXIT1
  382. ;
  383. FILTER:    PUSH    PSW        ;save status
  384.     MVI    A,'^'        ;print '^' in front
  385.     CALL    CO1        ;__of control character
  386.     POP    PSW        ;restore status
  387.     ADI    40H        ;mask into displayable char
  388.     CALL    CO1        ;display filtered control char
  389. ;
  390. FWDCNT:    LDA    LINCNT        ;get number of lines displayed
  391.     INR    A        ;bump it
  392.     STA    LINCNT        ;__and store it
  393.     MOV    D,A        ;save lincnt
  394.     LDA    LINMAX        ;get max number of line
  395.     CMP    D        ;compare with line count
  396.     JNZ    WRTFW2        ;if not there, continue, else get command
  397.     XRA    A        ;zero the
  398.     STA    LINCNT        ;__line count
  399. ;
  400. GETCMD:    PUSH    H
  401.     PUSH    D
  402.     PUSH    B
  403. ;
  404.     IF    HEATH
  405.     CALL    CDISP
  406.     DB    ESC,'x5',ENDMSG    ;disable cursor
  407.     ENDIF
  408. ;
  409. GETCM1:    CALL    GETIN        ;Get input char if any
  410.     ORA    A        ;loop till char avail
  411.     JZ    GETCM1
  412.     POP    B
  413.     POP    D
  414.     POP    H
  415.     CPI    'a'        ;change command to
  416.     JC    GETCM2        ;__upper case
  417.     CPI    'z'+1
  418.     JNC    GETCM2
  419.     XRI    20H        ;is lower case, make upper case
  420. ;
  421. GETCM2:
  422.     IF    NOT SHORT
  423.     CPI    '1'        ; 1 means goto 1st line
  424.     JZ    WRTTOP        ;Test if top in buffer
  425.     CPI    '?'        ;help request
  426.     JZ    HELP2
  427.     CPI    ' '        ;more use space
  428.     JZ    WRTFW1
  429.     CPI    'F'        ;scroll forward?
  430.     JZ    WRTFW1        ;br if yes
  431.     CPI    'F'-40H        ;vi uses ^F
  432.     JZ    WRTFW1
  433.     CPI    'V'-40H        ;mince uses ^V
  434.     JZ    WRTFW1
  435.     CPI    'B'        ;scroll backward?
  436.     JZ    WRTBAK
  437.     CPI    'B'-40H        ;vi uses ^B
  438.     JZ    WRTBAK
  439.     CPI    'N'        ;scroll next line?
  440.     JZ    WRTNXT
  441.     CPI    '+'
  442.     JZ    WRTNXT
  443.     CPI    CR        ;scroll next line?
  444.     JZ    WRTNXT
  445.     CPI    LF
  446.     JZ    WRTNXT
  447.     CPI    'P'        ;scroll prev line?
  448.     JZ    WRTPRV
  449. ;
  450.     ENDIF
  451.     IF    OSBORNE AND NOT SHORT
  452. ;
  453.     CPI    ARWUP        ;Cursor up?
  454.     JZ    WRTPRV
  455. ;
  456.     ENDIF
  457.     IF    NOT SHORT
  458. ;
  459.     CPI    '-'
  460.     JZ    WRTPRV
  461.     CPI    'C'-40H        ;must be exit
  462.     JZ    EXITCL        ;return control to CCP if yes or
  463.     CPI    'Q'        ;more use q for quit
  464.     JZ    EXITCL
  465.     CPI    'S'        ;set screen parameters
  466.     JZ    SETSCR
  467.     CPI    ARWLFT        ;Cursor left?
  468.     JZ    ADJMM
  469.     CPI    ARWRT        ;Cursor right?
  470.     JZ    ADJMM
  471.     JMP    HELP2        ;else give a hint
  472.     ENDIF
  473. ;
  474.     IF    SHORT
  475.     CPI    FIRST        ; 1 means goto 1st line
  476.     JZ    WRTTOP
  477.     CPI    NXTPAG        ;scroll forward?
  478.     JZ    WRTFW1        ;br if yes
  479.     CPI    BACK        ;scroll backward?
  480.     JZ    WRTBAK
  481.     CPI    NEXT        ;scroll next line?
  482.     JZ    WRTNXT
  483.     CPI    PREV        ;scroll prev line?
  484.     JZ    WRTPRV
  485.     CPI    'C'-40H        ;must be exit
  486.     JZ    EXITCL        ;return control to CCP if yes or
  487.     CPI    QUIT        ;alternative quit
  488.     JZ    EXITCL
  489.     CPI    SCREEN        ;set screen parameters
  490.     JZ    SETSCR
  491.     JMP    HELP2        ;else give a hint
  492.     ENDIF
  493. ;
  494. ;            Go to top of file
  495. WRTTOP:
  496.     LDA    TOPBUF        ;Get top in buffer flag
  497.     ORA    A
  498.     JNZ    WRTFWD        ;No - the hard way
  499.     CALL    CLRSCR        ;erase the screen
  500. WRTTO1:
  501.     XRA    A
  502.     STA    LINCNT        ;Clear lines put so far
  503.     JMP    WRTFW0        ;Buffer contains top sectors
  504. ;
  505. ;            Write one more line
  506. WRTNXT:    LDA    LINMAX
  507.     DCR    A        ;fool wrtfw1 to only write one line
  508.     STA    LINCNT
  509.     JMP    WRTFW1
  510. ;            Back up one line
  511. WRTPRV:    LDA    LINMAX        ;back up one screen + 1 line
  512.     INR    A
  513.     JMP    WRTBK0
  514. ;            Back up full screen
  515. WRTBAK:    LDA    LINMAX        ;get screen line count
  516.     ADD    A        ;__multiply by 2
  517. ;
  518. WRTBK0:    INR    A        ;__and add 1
  519.     STA    LINCNT        ;__to backup to previous page
  520.     CALL    CLRSCR        ;clear the screen
  521. ;
  522. WRTBK1:    LXI    D,DSKBUF    ;get address of start of buffer start
  523.     CALL    cmphlde        ;Is HL> LT DE> (start of buff)
  524. ;                ; Note test is LT now, not NE (v1.81)
  525.     JC    FILBAK        ;Go refill buffer
  526. ;
  527. WRTBK2:    MOV    A,M        ;get a character
  528.     ANI    7FH        ;strip high bit
  529.     DCX    H        ;decrement buffer
  530.     CPI    CR        ;see if end of line
  531.     JZ    BAKCNT        ;__or form-feed
  532.     CPI    'L'-40H        ;__and adjust line count if so
  533.     JNZ    WRTBK1        ;else, loop if not
  534. ;
  535. BAKCNT:    LDA    LINCNT        ;else, get number of lines to move back
  536.     DCR    A        ;__and decrement it
  537.     STA    LINCNT        ;__store it
  538.     JNZ    WRTBK1        ;__and loop if not there
  539.     INX    H        ;else bump pointer
  540.     INX    H        ;__to account for dcx
  541.     JMP    WRTFW1        ;and go write a screen
  542. ;
  543. FILBAK:
  544. ;            Test for top of file
  545.     LDA    TOPBUF        ;Get top in buffer flag
  546.     ORA    A
  547.     JZ    WRTTO1        ;Yes - start of file in buffer
  548. ;            Start of file not in buffer, step back
  549.     LHLD    SECCNT        ;Get no of sectors last read
  550.     LXI    D,MAXSEC    ;get the buffer size
  551.     DAD    D        ;add them
  552.     XCHG            ;__and put them in DE
  553.     LDA    FCBCRR        ;subtract low order byte 
  554.     SUB    E        ;__from current record count
  555.     STA    FCBCRR        ;__and store in current record count
  556.     LDA    FCBCRR+1    ;same with high order byte
  557.     SBB    D        ;__but with borrow
  558.     JM    WRTFWD        ;if beyond beginning of file, start over
  559.     STA    FCBCRR+1    ;else, store high order byte
  560.     CALL    FILBUF        ;fill the buffer
  561.     LXI    H,ENDBUF    ;__and point to end of buffer
  562.     CALL    CLRSCR        ;clear the screen
  563.     JMP    WRTBK2        ;continue moving back in file
  564. ;
  565. ;            Fill buffer with top of file 
  566. FILBF0:
  567.     XRA    A        ;get a 0
  568.     STA    LINCNT        ;store in line count
  569.     STA    CHRCNT        ;store in character count
  570. ;                Do not reset the current extent!!!
  571. ;                BDOS will switch extents only if the no
  572. ;                specified ( <FCBEX> ) does NOT agree with
  573. ;                the wanted no <FCBCRR>. 
  574.     STA    FCBCRR        ;Reset to sector zero
  575. ;
  576.     IF    NOT LIBRARY
  577. ;
  578.     STA    FCBCRR+1    ;
  579.     STA    FCBCRR+2    ;__and clear the overflow
  580. ;
  581.     ENDIF
  582. ;
  583.     IF    LIBRARY
  584. ;
  585.     LHLD    SCZERO        ;Set to sector zero for file/member
  586.     SHLD    FCBCRR
  587. ;
  588.     ENDIF
  589. ;
  590. ;            ;Fill buffer from spec'd sector
  591. FILBUF:
  592.     MVI    B,MAXSEC    ;number of sectors to resd
  593. FILB1S:
  594. ;
  595.     IF    LIBRARY
  596. ;
  597.     LHLD    SCZERO        ;Get top sector for member
  598.     XCHG 
  599.     LHLD    FCBCRR        ;Is this top of file?
  600.     CALL    cmphlde        ;This it? (<A>=0 if equal)
  601. ;
  602.     ENDIF
  603.     IF    NOT LIBRARY    
  604.     LHLD    FCBCRR        ;Is this top of file?
  605.     MOV    A,H
  606.     ORA    L
  607. ;
  608.     ENDIF
  609. ;
  610.     STA    TOPBUF        ;Set top of file in buffer flag
  611.     LXI    D,DSKBUF    ;load start of disk buffer
  612.     LXI    H,0        ;zero out the
  613.     SHLD    SECCNT        ;__number of sectors in buffer
  614. ;                ; Z - top, NZ - not top 
  615.     IF    SQUEEZE
  616.     LDA    SQFLG        ;Is this a squeezed file
  617.     ORA    A
  618.     JNZ    FILSQ        ;Yes -
  619.     ENDIF
  620. ;
  621. FILBU1:
  622.     PUSH    H        ;save all
  623.     PUSH    D        ;__registers from
  624.     PUSH    B        ;__BDOS clobber
  625.     MVI     C,STDMA        ;set dma to
  626.     CALL    BDOS        ;__disk buffer
  627. ;
  628.     LXI    D,FCB        ;set up to read
  629.     MVI    C,READR        ;__a record
  630.     CALL    BDOS        ;do it
  631.     ORA    A        ;read OK?
  632.     LHLD    FCBCRR        ;get current record number
  633.     INX    H        ;__bump it
  634.     SHLD    FCBCRR        ;__and save it
  635.     LHLD    SECCNT        ;get sectors in buffer
  636.     INX    H        ;bump it
  637.     SHLD    SECCNT        ;store it
  638.     POP    B
  639.     POP    D
  640.     POP    H
  641.     JNZ    RDERR        ;no, last sector read
  642. ;
  643.     IF    LIBRARY
  644. ;
  645.     PUSH    D        ;Save sector buffer pointer
  646.     LHLD    FCBCRR        ;get current record number
  647.     XCHG
  648.     LHLD    SCLAST        ;& get last sector for member (or FFFF)
  649.     CALL    cmphlde        ;Are we within member 
  650.     POP    D
  651.     JC    RDERR        ;no, last sector read
  652. ;
  653.     ENDIF
  654. ;
  655.     DCR    B        ;decrement it
  656.     RZ            ;if done return
  657.     LXI    H,128        ;else, add 128 to
  658.     DAD    D        ;__dma address
  659.     XCHG            ;put it in de
  660.     JMP    FILBU1        ;read another sector
  661. ;
  662.     IF    SQUEEZE
  663. ;
  664. ;            Fill buffer from squeezed file
  665. ;            This rtn handles mapping from unsq sector #
  666. ;            to sector, byte & bit in sq stream
  667. ;            on input FCBCRR contains wanted sector no,
  668. ;            ( no allowance made for sectors # over 65535)
  669. ;            <B> contains no of sectors wanted
  670. ;            DE> buffer where sectors wanted,
  671. ;             ignored in this version, always full DSKBUF
  672. FILSQ:
  673.     LHLD    FCBCRR        ;Get # for 1st sector wanted
  674.     XCHG
  675.     PUSH    D        ;Save to restore after unsq
  676.     LHLD    NXTSEC        ; & 1st sector after buffered ones  
  677.     CALL    cmphlde        ;Consecutive?
  678.     JZ    USQNXT        ;Yes - fine
  679.     JNC    USQBAK        ;No - lower
  680. ;            ;Next sect after latest but not consec
  681.     CALL    CDISP
  682.     DB    CR,LF,'Program failure, non-contiguous sectors requested'
  683.     DB    CR,LF,'from unsqueeze rtn',CR,LF,0
  684.     JMP    EXIT        ;Should never happen
  685. USQBAK:            ;Going backward
  686. ;
  687.     ENDIF
  688.     IF    SQUEEZE AND LIBRARY
  689. ;
  690.     LHLD    SCZERO        ;Get 1st sector for member
  691.     CALL    cmphlde        ;All the way back to start?
  692. ;
  693.     ENDIF
  694.     IF    SQUEEZE AND NOT LIBRARY
  695. ;
  696.     MOV    A,D        ;All the way?
  697.     ORA    E
  698. ;
  699.     ENDIF
  700.     IF    SQUEEZE
  701. ;
  702.     JNZ    USQNO1        ;No - MUST be prev!!!
  703.     LXI    H,SQMAP+2+8    ;Yes - reset SQMAP index to #3
  704.     SHLD    SQMAP
  705. USQNO1:
  706.     LHLD    SQMAP        ;Get index into mapping table
  707.     LXI    D,-8        ;Step back from next, past current to prev
  708.     DAD    D
  709.     SHLD    SQMAP        ; & save updated index for next
  710.     MOV    E,M        ;Get SQ sector no
  711.     INX    H
  712.     MOV    D,M
  713.     INX    H
  714.     MOV    C,M        ;Get byte offset
  715.     INX    H
  716.     MOV    A,M        ; & bit offset
  717.     STA    bitlft
  718.     XRA    A
  719.     STA    rcnt        ;No runs in progress
  720. ;                (assumption)
  721.     STA    SQBYT+1        ;Set offset 1st data byte
  722.     MOV    A,C
  723.     STA    SQBYT        ;For now offset within sector only
  724.     LHLD    SQBSC1        ;Get no of first SQ sector now in buffer
  725.     XCHG            ;<HL> wanted 1st sector, <DE> actual 1st
  726.     CALL    cmphlde        ;Is 1st buffer sector low/equal 1st data sect?
  727.     JNC    USQ1OK        ;Yes - first wanted sector SQ in buffer
  728. ;                 Max header 1035 bytes + file name)
  729. ;            Force reload of SQ buffer
  730.     SHLD    NXTSQS        ;No - 1st data sector b/4 1st buffer sect
  731. ;                 (note is probab not sector 0
  732. ;                 because of header, eg decoding tree)
  733.     MVI    A,1        ;Set rewind with I/O
  734.     STA    SQREWD        ;Set rewind flag
  735. ;                 SQBYT contains offset of 1st data byte
  736.     XRA    A
  737.     STA    SQEOF        ;Reset end of file on SQ
  738. ;                Leave current extent alone. This is how
  739. ;                BDOS knows how to switch extents. It checks
  740. ;                if the current extent no agrees with
  741. ;                the wanted record.
  742.     STA    FCBCRR+2    ; & count overflow, should not be necessary
  743.     MOV    D,A
  744.     JMP    USQNX1        ;Go adj buffer pointer
  745. ;                (NOP since <DE>=0
  746. ;            ;SQ text still in buffer
  747. USQ1OK:
  748. ;                <DE> # of 1st sector in SQ buf
  749. ;                <HL> # of wanted SQ sector 
  750. ;                (Max 100H SQ sectors in buffer)
  751.     MOV    A,L
  752.     SUB    E
  753.     RAR            ;Convert to pages (100H)
  754. ;                 Know Cy=0 in
  755. ;                 leaves Cy if odd no of sects
  756.     MOV    D,A
  757.     MVI    A,0        ;Do not disturb Cy
  758.     RAR            ;Pu carry (now 80H or 00H) 
  759. USQNX1:
  760.     MOV    E,A
  761.     LHLD    SQBYT        ;Get offset of 1st data byte in wanted sect
  762.     DAD    D        ; --> offset in buffer
  763.     LXI    D,SQBUF
  764.     DAD    D        ;Convert to absolute addr
  765.     SHLD    inbufs        ;& set as next byte to unsqueeze
  766. ;
  767. USQNXT:            ;Next sector consecutive
  768.     LHLD    NXTSQS        ;Get no of next SQ sector 
  769. ;                (in case read reqd)
  770.     SHLD    FCBCRR
  771. ;            Build mapping table entry
  772.     LHLD    inbufs        ;Calc offset in buffer
  773.     LXI    D,-SQBUF
  774.     DAD    D
  775.     MOV    C,L        ;Keep offset within sector
  776.     LDA    bitlft        ;Get bit offset
  777.     MOV    B,A
  778.     ORA    A        ;On byte boundary?
  779.     MOV    A,C
  780.     JNZ    NOTBBY        ;No -
  781.     INR    A        ;Yes - no adj reqd
  782. NOTBBY:
  783.     ANI    7FH        ;Ensure sector relative
  784.     DAD    H        ;Convert to sector no
  785.     ORA    A        ;Is next byte at start of sect?
  786.     JNZ    SECTOK
  787.     DCR    H        ;Yes - step back one sector
  788. SECTOK:
  789.     DCR    A
  790.     ANI    7FH        ;& adj byte index
  791.     MOV    E,H
  792.     MVI    D,0
  793.     LHLD    SQBSC1        ;# of 1st sector in buffer
  794.     DAD    D
  795.     XCHG            ;<D> absolute SQ sector no
  796.     LHLD    SQMAP        ;Get index
  797.     MOV    M,E        ;Save abs SQ sector no
  798.     INX    H
  799.     MOV    M,D
  800.     INX    H
  801.     MOV    M,A        ;Save sector relative byte offset
  802.     INX    H
  803.     MOV    M,B        ;Save bitlft
  804.     INX    H
  805.     SHLD    SQMAP        ;Save new index
  806. ;
  807.     ENDIF
  808.     IF    SQUEEZE AND NOT SILENT
  809. ;
  810.     CALL    CDISP        ;Show msg where is
  811.     DB    '>>> Unsqueezing text <<<',ENDMSG
  812. ;                Corrupts display if aft CR but b/4 LF
  813. ;
  814.     ENDIF
  815. ;
  816. ;
  817.     CALL    filusq        ;Fill unsq buffer
  818. ;                returns NZ on EOF
  819. ;                SQEOF set as well then
  820. ;
  821.     IF    SQUEEZE AND NOT SILENT
  822. ;
  823.     CALL    CDISP        ;Remove msg just displayed, assumes
  824. ;                 BS works across start of line if reqd
  825.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS
  826.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS
  827.     DB    '                        '
  828.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS
  829.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,0
  830. ;
  831.     ENDIF
  832.     IF    SQUEEZE
  833. ;
  834.     LHLD    FCBCRR        ;Get no of next SQ sector
  835.     SHLD    NXTSQS
  836.     LHLD    nxtadr        ;Calc # of unsq sectors in buf
  837.     LXI    D,-DSKBUF    ;(as neg no)
  838.     DAD    D        ;Calc length
  839.     DAD    H        ; & convert to sectors in <H>
  840.     MOV    L,H
  841.     MVI    H,0
  842.     SHLD    SECCNT        ;Save # of sectors in DSKBUF
  843.     POP    D        ;Get FCBCRR as passed by calling rtn
  844.     DAD    D        ; & calc new one
  845.     SHLD    FCBCRR
  846.     SHLD    NXTSEC
  847.     RET
  848. ;
  849.     ENDIF
  850. ;
  851. ;
  852. ;We only get here if end of file
  853. ;
  854. RDERR:    MVI    A,EOF        ;get bogus eof
  855.     STAX    D        ;save at buffer end in case no eof in file
  856.     XRA    A        ;get a zero to direct to start of buffer
  857.     RET            ;__on ret
  858. ;
  859. OPNFIL:    LDA    FCBFN        ;point to first letter of filename
  860.     CPI    ' '        ;anything there?
  861.     JZ    HELP        ;no, give help message
  862.     XRA    A        ;get a 0
  863.     STA    FCBEX        ;zero current extent
  864. ;                MUST open file on extent zero
  865.     LXI    D,FCB        ;file name in default fcb
  866.     MVI    C,OPEN        ;set up to open
  867.     CALL    BDOS        ;do it
  868.     INR    A        ;open OK?
  869.     RNZ            ;yes
  870.     CALL    CDISP        ;else, give error msg and quit
  871.     DB    'file not found ',ENDMSG
  872.     JMP    EXIT1        ;leave msg on screen on exit
  873. ;
  874. GETNBR:    MOV    A,M        ;get first digit
  875.     INX    H
  876.     DCR    B        ;b=number of characters left in buffer
  877.     RZ            ;no digit
  878.     CPI    SPACE
  879.     JZ    GETNBR        ;wait until next non-space
  880.     PUSH    D        ;save location to save number
  881.     MVI    D,0        ;initialize number
  882. ;
  883. GNUM1:    SUI    30H        ;change ASCII to number
  884.     JC    INVNUM        ;not a number
  885.     CPI    10
  886.     CMC
  887.     JC    INVNUM        ;not a number
  888.     PUSH    PSW        ;save number
  889.     MOV    A,D        ;multiply old number by 10
  890.     ADD    A        ;*2
  891.     ADD    A        ;*4
  892.     ADD    A        ;*8
  893.     ADD    D        ;*9
  894.     ADD    D        ;*10
  895.     MOV    D,A
  896.     POP    PSW        ;restore new digit
  897.     ADD    D
  898.     MOV    D,A
  899.     MOV    A,M        ;get next digit
  900.     INX    H
  901.     DCR    B
  902.     JZ    ENDNUM        ;end of number
  903.     CPI    SPACE
  904.     JNZ    GNUM1
  905. ;
  906. ENDNUM:    MOV    A,D        ;save number
  907.     DCR    A        ;correct number for co routines
  908.     XCHG            ;set to restore save location
  909.     POP    H        ;restore save location
  910.     MOV    M,A        ;save digit
  911.     XCHG            ;put buffer location where it belongs
  912.     MOV    A,B        ;see if any characters left in buffer
  913.     ORA    A        ;zero if no characters in buffer
  914.     RET
  915. ;
  916. INVNUM:    POP    D        ;correct stack
  917.     RET
  918. ;
  919. ASCIIN:    MVI    B,100        ;divide by 100, then change
  920.     CALL    DIVIDE        ;__digit to ASCII and store at hl
  921.     MVI    B,10        ;divide by 10, then change
  922.     CALL    DIVIDE        ;__digit to ASCII and store at hl+1
  923.     MVI    B,30H        ;change ones place number
  924.     ADD    B        ;__to ASCII and store at hl+2
  925.     MOV    M,A
  926. ;
  927.     IF    NOT (SHORT AND HEATH)
  928.     DCX    H        ;delete leading zeroes
  929.     DCX    H        ;__in the number
  930.     MVI    C,SPACE        ;__and replace with spaces
  931.     MOV    A,B
  932.     CMP    M        ;check first digit for '0'
  933.     JNZ    CDISP        ;not zero
  934.     MOV    M,C        ;replace with space
  935.     INX    H
  936.     CMP    M        ;check second digit for '0'
  937.     JNZ    CDISP        ;not zero
  938.     MOV    M,C        ;replace with space
  939.     ENDIF
  940. ;
  941. CDISP:    XTHL            ;exchange top of stack and HL
  942. ;
  943. CDIS1:    MOV    A,M        ;HL now pointing to db message
  944.     ORA    A        ;see if 0 at end of message
  945.     INX    H
  946.     JZ    CDIS2        ;yes, restore stack and return
  947.     CALL    CO        ;no, print the character
  948.     JMP    CDIS1        ;__and loop
  949. ;
  950. CDIS2:    XTHL            ;get return address on top of stack
  951.     RET            ;__and return
  952. ;
  953. CO:    PUSH    B        ;Save the registers
  954.     PUSH    D        ;__from bdos
  955.     PUSH    H        ;__clobber
  956. CO2:    PUSH    PSW
  957.     MOV    E,A        ;set up character
  958.     MVI    C,CONOUT    ;__to send to console
  959.     CALL    BDOS        ;do it
  960.     POP    PSW
  961. CO5:    POP    H        ;restore
  962.     POP    D        ;__the registers
  963.     POP    B
  964.     RET
  965. ;
  966. CO1:    PUSH    B        ;Save the registers
  967.     PUSH    D
  968.     PUSH    H
  969.     MOV    E,A
  970.     LXI    H,CHRCNT    ;Get address of character count
  971.     CPI    CR        ;see if end of line
  972.     JZ    ENDLIN        ;update line information
  973.     CPI    LF        ;ignore linefeed
  974.     JZ    CO2
  975.     LDA    CHRMAX        ;get maximum characters per line
  976.     CMP    M        ;see if too many char
  977.     JC    CO5        ;don't print character
  978.     MOV    A,E        ;restore and print character
  979.     CPI    TAB        ;fix chrcnt for tabs
  980.     JZ    TABFIX
  981.     INR    M        ;increment character count
  982.     LDA    CHRMIN        ;see if up to minimum display yet
  983.     CMP    M
  984.     MOV    A,E        ;restore character
  985.     JNC    CO5        ;do not display character
  986.     JMP    CO2        ;finally, display character
  987. ;
  988. ENDLIN:    MVI    M,0        ;reset character count
  989.     JMP    CO2        ;print cr
  990. ;
  991. TABFIX:    MVI    A,08H        ;fix chrcnt for tabs
  992.     ADD    M        ;increment to next 8-count
  993.     ANI    0F8H        ;make into multiple of 8
  994. ;
  995. TAB2:    SUB    M        ;get number of space to go
  996.     MOV    B,A
  997. ;
  998. TAB1:    MVI    A,SPACE        ;expand tab
  999.     CALL    CO1
  1000.     DCR    B
  1001.     JNZ    TAB1        ;still more spaces
  1002.     JMP    CO5        ;exit routine
  1003. ;
  1004. SETSCR:    PUSH    H
  1005.     PUSH    D
  1006.     PUSH    B
  1007. ;
  1008. GETMAX:    LDA    CHRMAX        ;get maximum number of characters
  1009.     INR    A
  1010.     LXI    H,HUNS
  1011.     CALL    ASCIIN        ;put ASCII number in message        
  1012. ;
  1013.     IF    NOT SHORT
  1014.     DB    CR,LF,'Maximum Column: '
  1015.     ENDIF
  1016. ;
  1017.     IF    SHORT
  1018.     DB    CR,LF,'Max Column: '
  1019.     ENDIF
  1020. ;
  1021. HUNS:    DB    30H
  1022.     DB    30H
  1023.     DB    30H
  1024.     DB    ' New? ',ENDMSG
  1025.     CALL    GETINP        ;read input from console
  1026.     LXI    D,CHRMAX    ;set new chrmax in memory
  1027.     CALL    GETNBR
  1028.     JC    GETMAX        ;if error, repeat last message
  1029. ;
  1030. GETMIN:    LDA    CHRMIN        ;get minimum character display
  1031.     INR    A
  1032.     LXI    H,HUN
  1033.     CALL    ASCIIN        ;put ASCII number in message        
  1034. ;
  1035.     IF    NOT SHORT
  1036.     DB    LF,'Minimum Column: '
  1037.     ENDIF
  1038. ;
  1039.     IF    SHORT
  1040.     DB    LF,'Min Column: '
  1041.     ENDIF
  1042. ;
  1043. HUN:    DB    30H
  1044.     DB    30H
  1045.     DB    30H
  1046.     DB    ' New? ',ENDMSG
  1047.     CALL    GETINP        ;read input from console
  1048.     LXI    D,CHRMIN    ;set new chrmax in memory
  1049.     CALL    GETNBR
  1050.     JC    GETMIN        ;if error, repeat last message
  1051. ;
  1052. GETLIN:    LDA    LINMAX        ;get number of lines per display
  1053.     LXI    H,HUND
  1054.     CALL    ASCIIN        ;put ASCII number in message        
  1055.     DB    LF,'Lines Displayed: '
  1056. ;
  1057. HUND:    DB    30H
  1058.     DB    30H
  1059.     DB    30H
  1060.     DB    ' New? ',ENDMSG
  1061.     CALL    GETINP        ;read input from console
  1062.     LXI    D,LINMAX    ;set new chrmax in memory
  1063.     CALL    GETNBR
  1064.     JC    GETLIN        ;if error, repeat last message
  1065.      POP    B
  1066.     POP    D
  1067.     POP    H
  1068. ;
  1069. WRTSAM:    LDA    LINMAX        ;write the same screen
  1070.     JMP    WRTBK0
  1071. ;
  1072. ;
  1073. GETINP:    MVI    A,5        ;get set to read new maximum column
  1074.     STA    CMDTAIL
  1075.     MVI    C,0AH
  1076.     LXI    D,CMDTAIL
  1077.     CALL    BDOS        ;get maximum column
  1078.     LXI    H,CMDTAIL+1    ;now, change to ASCII
  1079.     MOV    B,M
  1080.     INX    H
  1081.     INR    B
  1082.     RET            ;return with input in buffer
  1083. ;
  1084.     IF    NOT SHORT
  1085. ;            Adjust char min/max on cursor left/rt
  1086. ADJMM:
  1087.     PUSH    H
  1088.     CPI    ARWLFT        ;Move left (decrease)?
  1089.                 ; set flag
  1090.     LDA    CHRMAX        ;What is last char on line t/b displ
  1091.     MOV    H,A
  1092.     LDA    CHRMIN        ; & 1st char to display
  1093.     MVI    L,8        ;Scroll by 8
  1094.     JZ    ADJMMD        ;Yes - adjust down
  1095.     ADD    L        ;No - increase min, no limit
  1096.     PUSH    PSW
  1097.     MOV    A,L
  1098.     ADD    H        ; & max
  1099.     JMP    ADJMMS
  1100. ADJMMD:
  1101.     SUB    L        ;Display more to the left
  1102.     PUSH    PSW
  1103.     MOV    A,H
  1104.     SUB    L
  1105. ADJMMS:
  1106.     MOV    H,A        ;<H> max
  1107.     POP    PSW        ;<A> min
  1108.     CMP    H        ;Wrap, (max< min)
  1109.     JNC    ADJMMX        ;Yes - leave unchanged
  1110.     STA    CHRMIN
  1111.     MOV    A,H
  1112.     STA    CHRMAX
  1113. ADJMMX:
  1114.     POP    H
  1115.     JMP    WRTSAM        ;Go write same screen
  1116. ;
  1117.     ENDIF
  1118. DIVIDE:    MVI    C,'0'-1        ;extract dividend of a div c
  1119. ;
  1120. DIV1:    INR    C        ;__and store in location pointed
  1121.     SUB    B        ;__to by hl
  1122.     JNC    DIV1
  1123.     ADD    B
  1124.     MOV    M,C        ;save ASCII digit
  1125.     INX    H        ;bump pointer to next location
  1126.     RET
  1127. ;
  1128. EXITCL:
  1129. ;            Clear screen only on reg exit
  1130.     CALL    CLRSCR        ;clear the screen
  1131. ;
  1132. EXIT:
  1133.     CALL    GETIN        ;__get any waiting characters
  1134.     CALL    GETIN        ; and any possible second char
  1135. ;
  1136.     IF    HEATH
  1137.     CALL    CDISP        ;re-enable cursor
  1138.     DB    ESC,'y5',ENDMSG
  1139.     ENDIF
  1140. ;
  1141.     LXI    D,FCB        ;close file
  1142.     MVI    C,CLOSE        ;--in case this is MP/M
  1143.     CALL    BDOS
  1144. ;
  1145. EXIT1:
  1146.     LHLD    STACK        ;get old stack
  1147.     SPHL
  1148.     RET            ;return to CCP
  1149. ;
  1150.     IF    LIBRARY
  1151. ;
  1152. ;            Check for Library file
  1153. ;
  1154. CHKLB:
  1155.     xra    a
  1156.     sta    memfcb
  1157.     sta    lbflg        ;Clear library flag
  1158.     LHLD    DSKBUF        ;Get 1st word in file
  1159.     lxi    d,lbsign    ;Get expected value
  1160.     call    cmphlde
  1161.     jz    islb
  1162. ;            Not library
  1163.     lda    memnam        ;Was member specified
  1164.     ora    a
  1165.     rz            ;No - ok
  1166.     call    CDISP
  1167.     db    cr,lf,'File is not a library',cr,lf,0
  1168.     jmp    EXIT        ;Get out to leave msg visible
  1169. ;            Is library
  1170. islb:
  1171.     mvi    a,1
  1172.     sta    LBFLG        ;Yes - set library flag
  1173.     LXI    H,DSKBUF+14    ;Set to dir size (in sectors)
  1174.     mov    a,m        ;Assume <255 entries
  1175.     RAL
  1176.     RAL            ;Convert # sectors to # entries
  1177.     DCR    A        ;Less 1 for file descriptor
  1178.     sta    dirsiz        ;directory size in entries
  1179.     mov    b,a        ;Save no of entries for loop
  1180. ;            If no member specified show directory,
  1181. ;            else find the member
  1182.     LDA    MEMNAM        ;Do we have member name on command line?
  1183.     ORA    A
  1184.     JNZ    NODISP        ;Yes
  1185.     CALL    CDISP        ;Note protects <B>
  1186.     DB    CR,LF,'Library file, containing:',CR,LF,LF,0
  1187. NODISP:
  1188.     LXI    H,DSKBUF+20H    ;Set 1st member entry
  1189. ;            Loop through directory entries
  1190. dirlp:
  1191.     push    b        ;Save no of entries remaining
  1192.     MOV    A,M        ;Get entry status
  1193.     ORA    A        ;Deleted?
  1194.     JNZ    nyet        ;Yes - skp to next
  1195.     LDA    MEMNAM        ;Do we have member name on command line?
  1196.     ORA    A
  1197.     JZ    DISPM        ;No - display all member names
  1198. ;            See if wanted member
  1199.     mvi    b,12        ;Length of names + 00H in front
  1200.     lxi    d,memfcb
  1201.     call    cpstr        ;Compare names
  1202.     jz    found
  1203.     jmp    nyet
  1204. ;            Display rather than look for
  1205. DISPM:
  1206.     mvi    b,11        ;Length of names
  1207.     push    h
  1208.     inx    h        ;Step to actual name
  1209. DSPMLP:
  1210.     mov    a,m
  1211.     call    CO        ;Display one char
  1212.     inx    h
  1213.     dcr    b        ;Reduce count remaining
  1214.     jz    nmend        ;end of name
  1215. ;
  1216.     ENDIF
  1217.     IF    LIBRARY AND NOT OSBORNE
  1218. ;                (Bypass for Ozzys narrow screen)
  1219.     mov    a,b
  1220.     cpi    3        ;only 3 more?
  1221.     jnz    DSPMLP        ;No -
  1222.     mvi    a,'.'        ;Yes - put out dot
  1223.     call    CO
  1224. ;
  1225.     ENDIF
  1226.     IF    LIBRARY 
  1227.     jmp    DSPMLP        ;Go for next char
  1228. ;
  1229. ;            ;Displayed full name
  1230. nmend:
  1231. ;                In later versions multiple across
  1232.     lxi    h,namexc    ;Max no of names across sofar
  1233.     mov    a,m
  1234.     inx    h        ;Step to names across sofar
  1235.     inr    m        ;Count current
  1236.     cmp    m        ;Over max?
  1237.     jnc    notmax        ;not yet
  1238.     mvi    m,0        ;Yes - reset
  1239.     call    CDISP
  1240.     DB    CR,LF,0
  1241.     jmp    nyet1
  1242. notmax:
  1243.     call    CDISP
  1244. ;
  1245.     ENDIF
  1246.     IF    LIBRARY AND NOT OSBORNE
  1247. ;                (Bypass for Ozzys narrow screen)
  1248.     DB    ' '
  1249. ;
  1250.     ENDIF
  1251.     IF    LIBRARY
  1252. ;
  1253.     DB    '| ',0
  1254. nyet1:
  1255.     POP    H        ;Reset to start of this entry
  1256. ;            
  1257. nyet:
  1258.     lxi    b,20h        ;Length of each entry
  1259.     dad    b        ;Step to next
  1260.     pop    b        ;Get entry count (remaining)
  1261.     dcr    b
  1262.     jnz    dirlp        ;More members
  1263.     LDA    MEMNAM        ;Do we have member name on command line?
  1264.     ORA    A
  1265.     JZ    EXIT        ;No - just get out after dsp directory
  1266. ;                in future may ask what member to display
  1267.     call    CDISP
  1268.     db    cr,lf
  1269.     db    'Member file not found in LBR directory',cr,lf,0
  1270.     jmp    EXIT
  1271. ;
  1272. ;            Found the member name
  1273. ;
  1274. found:
  1275.     pop    b        ;Clear stack
  1276.     lxi    d,12
  1277.     dad    d
  1278.     push    h        ;save pointer for now,
  1279.     inx    h        ;point to size
  1280.     inx    h
  1281.     mov    a,m        ;get low byte
  1282.     inx    h
  1283.     mov    h,m
  1284.     mov    l,a
  1285.     ora    h        ;if a=0 then file is 0k
  1286.     jz    nullen        ;go complain
  1287.     xthl            ;get pointer back, save size
  1288.     mov    a,m        ;get file address
  1289.     inx    h
  1290.     mov    h,m
  1291.     mov    l,a
  1292.     SHLD    SCZERO        ;Save as first file sector
  1293.     POP    D        ; & get size back
  1294.     DAD    D        ;Convert to last sector no (inclusive)
  1295.     SHLD    SCLAST
  1296. ;
  1297.     ENDIF
  1298.     IF    LIBRARY AND SQUEEZE
  1299.     LDA    SQFLG        ;Get SQ flag in case of double squeeze
  1300.     ORA    A
  1301.     JZ    NOLBSQ        ;Ok, library itself not squeezed
  1302.     CALL    CDISP
  1303.     DB    CR,LF,'Cannot display member in squeezed library',CR,LF,0
  1304.     JMP    EXIT
  1305. NOLBSQ:
  1306.     CALL    CHKSQ        ;Check if  member squeezed
  1307. ;
  1308.     ENDIF
  1309.     IF    LIBRARY
  1310. ;
  1311.     CALL    FILBF0        ;Refill buffer, now for member
  1312. ;                 (FILBUF handles member offset in library)
  1313.     ret
  1314. ;
  1315. ;            ;Member is empty
  1316. nullen:
  1317.     CALL    CDISP
  1318.     DB    CR,LF,'Member is empty',CR,LF,0
  1319.     JMP    EXIT
  1320. ;
  1321.     ENDIF
  1322. ;
  1323. ;            Get input if any
  1324. GETIN:
  1325.     MVI    C,6        ;direct console I/O
  1326.     MVI    E,0FFH        ;__set up for input
  1327.     JMP    BDOS        ;Get char, exit via BDOS
  1328. ;
  1329. ;            Compare strings HL> to DE> over <B> 
  1330. ;            <DE> and <B> are changed, <HL> kept     
  1331. cpstr:
  1332.     push    h
  1333. cp$lp:
  1334.     ldax    d
  1335.     cmp    m
  1336.     jnz    cp$ex        ;No match
  1337.     inx    d
  1338.     inx    h
  1339.     dcr    b
  1340.     jnz    cp$lp
  1341. cp$ex:
  1342.     pop    h
  1343.     ret
  1344.  
  1345. ;
  1346. ;            Compare <HL> to <DE>
  1347. ;             Z - equal; C - <HL> less than <DE> 
  1348. ;             if equal returns <A>=0
  1349. cmphlde:
  1350.     mov    a,h
  1351.     sub    d
  1352.     rnz
  1353.     mov    a,l
  1354.     sub    e
  1355.     ret
  1356. ;
  1357. ;            Skip blanks in input
  1358. ;
  1359. EATSP:    MOV    A,M        ;get character if there is one
  1360.     INX    H
  1361.     DCR    B        ;b=number of characters left
  1362.     RZ            ;no more characters
  1363.     CPI    SPACE        ;ignore spaces
  1364.     JZ    EATSP
  1365.     DCX    H        ;Step back to 1st non-blank
  1366.     INR    B
  1367.     ORA    A        ;Force NZ
  1368.     RET
  1369. ;
  1370. ;            Skip name in input
  1371. ;
  1372. FILNAM:    MOV    A,M        ;get characters in file name
  1373.     INX    H
  1374.     DCR    B        ;b=number of characters left
  1375.     RZ            ;only file name in tail
  1376.     CPI    SPACE        ;wait for next space
  1377.     JNZ    FILNAM
  1378.     ORA    A        ;Force NZ
  1379.     RET            ;Blank
  1380. ;
  1381. ;            Move from HL> to DE> over <B>
  1382. ;
  1383. MOVE:
  1384.     MOV    A,M
  1385.     STAX    D
  1386.     INX    H        ;Step to next source
  1387.     INX    D        ; & destination
  1388.     DCR    B        ;Reduce count (00=256)
  1389.     JNZ    MOVE
  1390.     RET
  1391. ;
  1392. ;
  1393.     IF    SQUEEZE
  1394. *******************************************************
  1395. * USQ support code                      *
  1396. * 10/12/83 by Dave Rand                      *
  1397. *******************************************************
  1398. ;
  1399. ;            Check for SQ file, init tree if so
  1400. CHKSQ:
  1401. ;            Initialize
  1402.     xra    a
  1403.     mov    l,a
  1404.     mov    h,l        ;clear <hl>
  1405.     STA    SQFLG        ;Make sure not set as squeezed yet 
  1406.     sta    SQEOF        ; end of file on SQ
  1407.     sta    SQREWD        ;Clear "rewinding" SQ file 
  1408.     sta    bitlft        ;force init char read
  1409.     sta    rcnt        ;and zero repeats
  1410.     sta    FCBCRR+2    ; and overflow
  1411.     shld    numvals        ;Clear # nodes
  1412. ;
  1413.     ENDIF
  1414.     IF    SQUEEZE AND LIBRARY
  1415. ;
  1416.     LHLD    SCZERO        ;Get 1st sector for member
  1417.     SHLD    NXTSEC        ;& save as next sector
  1418. ;
  1419.     ENDIF
  1420.     IF    SQUEEZE
  1421. ;
  1422.     shld    FCBCRR        ;Clear next record
  1423. ;
  1424.     lxi    h,SQBUF        ;Set to input (squeezed) buffer 
  1425.     shld    inbufs
  1426.     shld    inbufu
  1427.     lxi    d,128
  1428.     dad    d
  1429.     shld    SQBUFE        ;Force exit on full buff aft 1 sect
  1430. ;                 causes the SQ buffer to contain
  1431. ;                 sectors 1+ only (not zero),
  1432. ;                 normally fine since sector 0 contains only
  1433. ;                 header info. Sector 0 will be reread
  1434. ;                 if contains data and needed  
  1435. ;            Read and validate signature word
  1436.     call    getw        ;Read  1st word in file
  1437.     lxi    d,sqsign    ;Get expected value
  1438.     call    cmphlde
  1439.     rnz
  1440.     mvi    a,1
  1441.     STA    SQFLG        ;Yes - set flag
  1442.     lhld    0006        ;Get top of memory
  1443.     lxi    d,sqbuf+100H*128 ;Limit buffer to max 100H
  1444.     call    cmphlde        ; sectors (FILBUF uses 8 bit count <B>)
  1445.     JC    toplow        ;use top
  1446.     xchg            ;use limit 
  1447. toplow:
  1448.     shld    SQBUFE        ;& store as full address 
  1449.     call    namlp        ;Skip past name
  1450.     call    usqtbl        ;Validate & load decoding tree
  1451.     jz    oak        ;tree ok
  1452.     call    CDISP
  1453.     db    cr,lf,'Invalid decode tree size',cr,lf,0
  1454.     jmp    EXIT
  1455. oak:
  1456.     lxi    h,SQMAP+2    ;Point to 1st entry 
  1457.     shld    SQMAP        ;Set to 1at entry in SQ mapper
  1458.     ret
  1459. ;
  1460. ;            Read & save checksum
  1461. rdchks:
  1462.     call    getw        ;get cksum, and store
  1463.     shld    filchks
  1464.     ret
  1465. ;            Read & skip name
  1466. namlp:    call    getc        ;Loop to skip name
  1467.     jnz    erext        ;I/O error or unexpected EOF
  1468.     ora    a
  1469.     jnz    namlp        ;Not yet end of name
  1470.     ret
  1471. ;
  1472. ;            Load decoding tree
  1473. ;            This version uses 1 byte abslute node indices
  1474. ;            (1-ffH) and is thus limited to 255 nodes and 255
  1475. ;            characters represented in the squeezed file.
  1476. ;            (All different characters present in the original
  1477. ;            file as well as any added through run encoding.
  1478. ;            Runs of 3 or more consecutive identical characters
  1479. ;            are encoded as char, DLE, count, where count
  1480. ;            is a one byte field 00 - FFH) 
  1481. ;
  1482. usqtbl:
  1483.      call    getw        ;Get no of nodes
  1484.     mov    a,h
  1485.     ora    l
  1486.     jz    nzexit        ;Null tree
  1487.     shld    numvals
  1488.     mov    a,h        ;Max 257, 256 char & spec eof
  1489. ;                in this version allow for only 256
  1490. ;                diff codes, every ASCII and non-ASCII
  1491. ;                char would have to be present, or
  1492. ;                run repeat counts 128-255 (every one)
  1493.     ora    a        ;H/o byte should be zero
  1494.     jnz    nzexit
  1495.     lxi    d,SQTREE    ;Set to decoding tree
  1496. nodelp:    shld    nxtadr        ;Save no of nodes
  1497.     mov    a,h
  1498.     ora    l
  1499.     rz            ;Done all nodes
  1500.     call    cvnode        ;get node, falg byte in <H>,
  1501. ;                 index/char in <L>
  1502.     push    h
  1503.     call    cvnode        ;get second child/char
  1504.     pop    b
  1505.     mov    a,b
  1506.     ral            ;Shift flags to 8, 4 posns 
  1507.     ora    h        ;Combine in 1st child flags 
  1508.     xchg            ;HL> SQTREE, <A>,<C>,<E> node 
  1509.     mov    m,a        ;Store flags in table
  1510.     inx    h
  1511.     mov    m,c
  1512.     inx    h
  1513.     mov    m,e
  1514.     inx    h
  1515.     xchg            ;DE> SQTREE
  1516.     lhld    nxtadr        ;Nodes remaining
  1517.     dcx    h
  1518.     jmp    nodelp
  1519. ;            Get encoded node
  1520. ;            Our nodes contain 3 bytes:
  1521. ;            - flag byte,
  1522. ;            - left child index/char
  1523. ;            - right child index/char
  1524. ;            Nodes on input are 4 bytes,
  1525. ;            with each half containing
  1526. ;            an index (1-100h) or character,
  1527. ;            where characters are encoded as
  1528. ;            negative values -(char+1)
  1529. ;            Eof is encoded as -(100h+1)
  1530. cvnode:
  1531.     push    d
  1532.     call    getw        ;Get word, chld ptr or char
  1533.     pop    d
  1534.     mov    a,h
  1535.     ora    a
  1536.     rz            ;Child index, <H>=0,<L>=index
  1537.     mov    a,l
  1538.     cma
  1539.     mov    l,a        ;convert char to reg form
  1540.     mov    a,h        ;get h/o byte again
  1541.     cma
  1542.     inr    a        ;Conv to 1 if char, 2 if EOF
  1543.     mov    h,a
  1544.     cpi    1        ;Was that reg char?
  1545.     rz            ;Yes - complete
  1546.     adi    3        ;No convert EOF flag to 0100
  1547.     mov    h,a
  1548.     ret
  1549.  
  1550. ;            Exit with NZ flag
  1551. nzexit:
  1552.     mvi    a,2        ;tree error
  1553.     ora    a        ;Set NZ flag
  1554.     ret
  1555.  
  1556. ;
  1557. ;
  1558. ;            Fill output buffer (unsqueezed char)
  1559. ;
  1560. filusq:
  1561.     lda    SQREWD        ;Rewinding SQ input?
  1562.     ora    a
  1563.     jz    norewd        ;No
  1564. ;            Reload SQ buffer
  1565.     lhld    inbufs
  1566.     push    h        ;getrf resets
  1567.     call    getrf        ;Yes - reload buffer & get 1st 8 bits
  1568.     pop    h
  1569.     shld    inbufs        ;Set to first data byte to use
  1570. badj:
  1571.     mov    c,a
  1572.     lda    bitlft        ;Get preset 1st wanted bit no
  1573.     mov    c,a
  1574.     mvi    a,8
  1575.     sub    b        ; Calc adjmt reqd  
  1576. badjlp:
  1577.     dcr    a
  1578.     jz    badjfn        ; bit adjust finished
  1579.     mov    b,a
  1580.     mov    a,c
  1581.     rrc
  1582.     mov    c,a
  1583.     mov    a,b
  1584.     jmp    badjlp
  1585. badjfn:
  1586.     sta    bitbuf
  1587.     xra    a
  1588.     sta    SQREWD        ; & clear rewind flag
  1589. norewd:
  1590.     lxi    h,DSKBUF    ;reset buffer pointer
  1591.     xra    a
  1592. buflp:
  1593.     shld    nxtadr        ;Save as next byte in buffer
  1594.     rnz            ;End of file (NZ flag)
  1595. ;                 as set by GETNXT rtn below
  1596.     lxi    d,SQTREE    ;Get end of input
  1597.     call    cmphlde        ;buffer full (de < hl - not full)
  1598.     jnc    full        ;buffer is full
  1599.     call    getnxt        ;Get next decoded char
  1600.                 ;No checksum taken
  1601.     lhld    nxtadr        ;Next out buffer posn
  1602.     mov    m,a        ;Store char returned, may be EOF char
  1603.     inx    h
  1604.     jmp    buflp
  1605. ;
  1606. full:
  1607.     xra    a        ;Ensure Z
  1608.     ret            ;Return on full buffer
  1609. ;
  1610. ;
  1611. ;            Get next decoded character
  1612. ;
  1613. getnxt:    lda    rcnt        ;see if in the middle of
  1614.     ora    a        ;repeat sequence...
  1615.     jz    norpt
  1616.     dcr    a        ;Yes - reduce repeat remaining 
  1617.     sta    rcnt
  1618.     lda    last        ;Get latest char again
  1619.     cmp    a
  1620.     ret            ;Return with Z for ok
  1621. norpt:    call    decode
  1622.     rnz            ;EOF? <A>=1AH
  1623.     cpi    dle        ;Run encoding flag?
  1624.     jnz    norun
  1625. ;            Handle DLE
  1626.     call    decode        ;get count
  1627.     rnz            ;EOF? (is really error after DLE)
  1628.     ora    a
  1629.     jnz    run        ;Non-zero, real run 
  1630.     mvi    a,dle        ;dle is encoded as dle,0
  1631.     cmp    a
  1632.     ret
  1633. ;            ;Run encoding found
  1634. run:    dcr    a        ;Allow for char already retnd
  1635.     dcr    a        ; & this one
  1636.     sta    rcnt        ;Keep count yet to be retd
  1637.     lda    last        ;return second time
  1638.     cmp    a
  1639.     ret
  1640. ;            ;Normal char, no run active 
  1641. norun:    sta    last        ;This may be the start
  1642.     cmp    a
  1643.     ret
  1644. ;
  1645. ;
  1646. ;            Read bits and decode to char
  1647. ;             note this version uses 3 bytes per node
  1648. ;             not 4.
  1649. ;             The first byte in each node is a flag byte
  1650. ;              .... x... - left node contains EOF marker
  1651. ;              .... .x.. - right node contains EOF marker
  1652. ;              .... ..x. - left node contains char
  1653. ;              .... ...x - right node contains char
  1654. ;
  1655. decode:    lxi    d,0        ;Set to node zero in table
  1656.     lda    bitbuf        ;Get bits from bit buffer
  1657.     mov    c,a
  1658. bitlp:    lda    bitlft        ;Any bits remaining? 
  1659.     ora    a
  1660.     jnz    nxtbit        ;Yes - go use
  1661.     push    d
  1662.     call    getc        ;No - replenish bit buffer
  1663.     jnz    badr        ;Unexpected eof
  1664.     pop    d
  1665.     mov    c,a
  1666.     mvi    a,8        ;Set as 8 bits inbuffer 
  1667. nxtbit:    dcr    a
  1668.     sta    bitlft        ;Save no of bit remaining 
  1669.     lxi    h,SQTREE    ;Set to node 0, left child ptr
  1670.     dad    d
  1671.     dad    d
  1672.     dad    d        ;Add in node no (4 bytes/node)
  1673.     mov    b,m        ;Get flag byte
  1674.     inx    h        ;Step to left child pointer
  1675.     mov    a,c        ;Get input bits 
  1676.     rrc            ;Shuffle LOW-ORDER bit to Carry
  1677.     mov    c,a
  1678.     mov    a,b        ;Get flag byte 
  1679.     jnc    getn3        ;Zero input bit,leave at left
  1680.     inx    h        ;add 1 to point to right child pointer
  1681.     add    b        ;Normalize wanted flags to .... x.x.
  1682. getn3:
  1683.     mov    e,m        ;Pick up child or char
  1684. ;                <D> should always remain zero 
  1685.     ani    1010B        ;Mask unwanted bits
  1686.     jz    bitlp        ;Reg child pointer
  1687. ;            Got to char or eof
  1688.     ani    1000B        ;End of file marker?
  1689.     jnz    goteof        ;Yes - get out with eof
  1690.     mov    a,c
  1691.     sta    bitbuf        ;Save bit buffer
  1692.     mov    a,e        ;Get decoded char (neg)
  1693.     ret
  1694. ;
  1695. ;            Exit on reg eof
  1696. goteof:
  1697.     mvi    a,eof
  1698.     ora    a
  1699.     ret
  1700. ;
  1701. ;            ;Get input word (lo/hi, unencoded)
  1702. getw:    call    getc
  1703.     jnz    badr        ;Unexpected eof
  1704.     push    psw
  1705.     call    getc
  1706.     jnz    badr        ;Unexpected eof
  1707.     mov    h,a
  1708.     pop    psw
  1709.     mov    l,a
  1710.     ret
  1711. ;
  1712. erext:
  1713. badr:    call    CDISP
  1714.     db    cr,lf,'Unexpected EOF',cr,lf,0
  1715.     jmp    EXIT
  1716. ;
  1717. ;            Get single (unencoded) char
  1718. getc:    lhld    inbufu
  1719.     xchg
  1720.     lhld    inbufs
  1721.     call    cmphlde        ;End of input buffer?
  1722.     jz    getrf        ;Yes
  1723. getc1:
  1724.     mov    a,m        ;No get next byte
  1725.     inx    h
  1726.     shld    inbufs        ;Save addr of next byte
  1727.     cmp    a
  1728.     ret
  1729. ;
  1730. ;            Refill input buffer
  1731. ;
  1732. getrf:
  1733.     lda    SQEOF        ;Is there anything else?
  1734.     ora    a
  1735.     jz    getok
  1736.     call    CDISP
  1737.     db    cr,lf,'Read past EOF on SQ file',cr,lf,0
  1738.     jmp    EXIT
  1739. getok:
  1740.     lhld    SECCNT        ;Save sector count (decoded buffer only)
  1741.     push    h
  1742.     lxi    h,SQBUF        ;Set input buffer as empty,
  1743.     shld    inbufs        ;_and start of buffer
  1744.     xchg            ;DE> buffer, next sector locn
  1745.     lhld    SQBUFE        ;End of input buffer
  1746.     shld    inbufu        ;Assume no end of file for now
  1747.     mov    a,l
  1748.     sub    e
  1749.     mov    l,a
  1750.     mov    a,h
  1751.     sbb    d        ;Calc buffer size
  1752.     mov    h,a
  1753.     dad    h        ;Convert to no of sectors
  1754.     mov    b,h        ;No of sectors to read
  1755. ;                # sectors limited to 100 max (<B>=0)
  1756.     lhld    FCBCRR        ;No of 1st sector to read
  1757.     shld    SQBSC1
  1758.     call    FILBU1        ;Read sector into SQBUF
  1759. ;                <B> no of sectors not read if eof
  1760. ;                HL> 128
  1761. ;                DE> last sector read, or after if eof
  1762.     lhld    FCBCRR        ;Get next SQ sector no
  1763.     shld    NXTSQS
  1764.     mov    a,b        ;Did we fill buffer?
  1765.     ora    a
  1766.     jz    getrf2        ;yes - no eof
  1767.     xchg            ;Eof, adjust buffer end marker
  1768.     shld    inbufu        ;Mark end of buffer used
  1769.     sta    SQEOF        ;& flag eof
  1770. ;
  1771. ;            Input buffer re-filled
  1772. getrf2:
  1773.     pop    h
  1774.     shld    SECCNT        ;Restore sector count (decoded buffer only)
  1775.     lhld    inbufu        ;Get end of buffer
  1776.     xchg
  1777.     lhld    inbufs        ;Get start of buffer
  1778.     call    cmphlde        ;Something there?
  1779.     jc    getc1        ;Yes - go for char
  1780.     jmp    erext        ;No - read past eof or empty file
  1781. ;
  1782. ;end of baseline USQ code
  1783. ;
  1784. otbufe:    dw    0        ;End of decoded char buffer
  1785. inbufs:    dw    0        ;Start of input buffer
  1786. inbufu:    dw    0        ;End of used part input buffer
  1787. SQBUFE:    dw    0        ;End of input buffer
  1788. ;
  1789. nxtadr:    dw    DSKBUF        ;Next byte in output buffer 
  1790.                 ; also used when loading tree
  1791. bitlft:    ds    1        ;No of bits left in bit buffer
  1792. rcnt:    ds    1        ;Run count remaining (DLE)
  1793. filchks:ds    2        ;Checksum read from file
  1794. last:    ds    1        ;Last reg char decoded
  1795. bitbuf:    ds    1        ;Latest 8 bits (encoded) from input file
  1796. numvals:ds    2        ;No of nodes in encodng tree
  1797. ;
  1798.     ENDIF
  1799. ;
  1800. ;    Memory allocation
  1801. ;
  1802. SECCNT:    DW    0        ;number of sectors read into buffer
  1803. LINMAX:    DB    SCROLN        ;number of to write lines on console
  1804. CHRMAX:    DB    MAXCHR-1    ;number of characters to display per line
  1805. CHRMIN:    DB    0        ;character to start displaying on line
  1806. CHRCNT:    DS    1        ;character number in line
  1807. LINCNT:    DS    1        ;line number on write or move back in buffer
  1808. TOPBUF:    DB    0        ;Top of file is now in buffer
  1809. ;                 Z - yes, NZ - no
  1810. ;
  1811.     IF    SQUEEZE
  1812. ;
  1813. NXTSEC:    DW    0        ;Next (unsqueezed) sector not yet in BSKBUF
  1814. ;                 set (and used) only by FILSQ
  1815. SQFLG:    DB    0        ;File is squeezed
  1816. SQEOF:    DB    0        ;End of file on squeezed file
  1817. SQREWD:    DB    0        ;Flag the SQ input file is being re-read
  1818. ;                 buffer refill rtn (getrf) to set inbufs
  1819. ;                 as per offset in SQBYT, and pre-load
  1820. ;                 bit buffer. Bit buffer to be adj
  1821. ;                 as per Bitlft
  1822. SQBYT:    DW    0        ;Offset of first data byte in SQ buffer
  1823. SQBSC1:    DW    0        ;No of 1st sector in SQ buffer
  1824. NXTSQS:    DW    0        ;No of last sector in SQ buffer
  1825. ;
  1826.     ENDIF
  1827. ;
  1828. ;
  1829.     IF    LIBRARY
  1830. namexc:    db    (MAXCHR/11)-1    ;No of directory names across display
  1831.     db    0        ;No of names so far
  1832. dirsiz:    db    0        ;# of members possible in directory
  1833. memnam    db    0        ;Member name specified on command line
  1834. SCZERO:    DW    0        ;First sector for member
  1835. SCLAST:    DW    0FFFFH        ;Last sector for member (included in member)
  1836. ;                 SCZERO and SCLAST are relative in file
  1837. LBFLG:    DB    0        ;File is a library file
  1838. memfcb:    ds    12        ;Name of member file
  1839. ;
  1840.     ENDIF
  1841.     DS    60        ;stack area
  1842. STACK:    DS    2        ;old stack saved here
  1843. DSKBUF:    EQU    $        ;disk buffer area above the program
  1844. ;
  1845. ENDBUF    EQU    DSKBUF+MAXSEC*128
  1846. ;
  1847.     IF    SQUEEZE
  1848. ;
  1849. SQTREE    EQU    ENDBUF        ;Space for SQ decoding tree
  1850. SQMAP    EQU    SQTREE+256*3
  1851. ;                Space for SQ buffer mapping table
  1852. ;                contains sq sect #, sq byte & bit offset
  1853. ;                for every time DSKBUF was filled
  1854. ;                1st entry contains index to latest mapping
  1855. ;                triplet
  1856. ;                To handle run compr straddling buffer end,
  1857. ;                should also store rcnt & last 
  1858. SQBUF    EQU    SQMAP+100*4    ;(allows for 100 8k buffers)
  1859. ;                Input (squeezed) buffer
  1860. ;                Runs up to top of free mem 
  1861.     ENDIF
  1862. ;
  1863.     END    TPA
  1864.