home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / KAYPRO / KBSHW321.LBR / KBSHW321.AQM / KBSHW321.ASM
Assembly Source File  |  2000-06-30  |  40KB  |  1,483 lines

  1. ;  Kaypro BISHOW v3.21 - buffered bi-directional file scroll utility
  2. ;
  3. ; KPBISHOW is now completely compatible with standard Wordstar control
  4. ; keys and uses the Kaypro arrow keys for +/- scrolling and right and
  5. ; left margin control
  6. ;
  7. ; Ver 3.21, 8 Dec 84, Steve Sanders, Tampa, FL
  8. ;       - Oops, my mistake with the filename printing twice.
  9. ;         Removed (sic) code that I had added (it was late folks).
  10. ;         Call status line in one shot now like it should be.
  11. ;         Future rev planned to display current memory page number
  12. ;         and allow going directly to any given page number with
  13. ;         a CTRL-G nn  command.  Also go all the way to the back
  14. ;         of the file.
  15. ;
  16. ; Ver 3.20, 8 Dec 84, Steve Sanders, Tampa, FL
  17. ;       - Added the name of file being displayed on 25th line
  18. ;         
  19. ; Ver 3.10, 5 Dec 84, Steve Sanders, Tampa, Fl
  20. ;       - Added 25th line display of program name, vers #, and
  21. ;         "enter ? for help menu".  Stripped out all non-Kaypro
  22. ;         equates and short version code.
  23. ;
  24. ; Ver 3.00kp, 2 Dec 84, Steve Sanders, Tampa, Fl
  25. ;       - This version is for video-able Kaypros only
  26. ;         Made command structure the same as Wordstar for scrolling
  27. ;         forward and backward and also for advancing one line forward
  28. ;         or backward.  Text scroll is completely controlled by the
  29. ;         Kaypro cursor keys now - up, down, left, and right.
  30. ;         Changed help menu accordingly, added commands to menu that
  31. ;         were always in the old code but not documented.  Removed the
  32. ;         GRAF toggles as there are no line drawing routines for the
  33. ;         Kaypro used and other graphics don't need the GRAF byte toggled.
  34. ; Ver 2.09KP, 25 Sep 84, Jim Gronek, Phoenix, Arizona 
  35. ;    - Added equates for Kaypro 2/4/10, reverse video codes on help
  36. ;      command (?), modified exit routines to re-enable cursor
  37. ;         even if filename not specified to BISHOW, added automatic
  38. ;      toggle for GRAF byte with ZCPR2/3 on K10's
  39. ;
  40. ; Ver 2.09, 7 Jan 84, Frans van Duinen, Toronto, Ont
  41. ;    - Modified USQ routines for higher speed (+10%) and
  42. ;     less memory usage.
  43. ;    - made USQ code optional through conditional assembly
  44. ;    - fixed a bug introduced with 2.08 and SHORT=TRUE 
  45. ;      (resulted from ASM's inability to nest IF/ENDIF) 
  46. ;    - fixed a bug  that reset FCBEX after open, whenever
  47. ;      sector 0 was read, (this resulted in BDOS assuming that
  48. ;      the current extent, whose allocation group nos were still
  49. ;      in the FCB, was the correct one. 
  50. ;    - Changed exit to clear screen only on Q or ^C exit,
  51. ;      to leave any messages visible
  52. ;    - Made wait after clear screen a cond assembly option
  53. ;
  54. ; Ver 2.08, 2 Jan 84, Frans van Duinen, Toronto, Ont
  55. ;    - added squeezed file capability
  56. ;    - added sidewise scrolling on ^I, ^L, steps of 8
  57. ;    - Osborne support for cursor keys, clr scr & scr size
  58. ;    - Changed FILBAK rtn to recognize top of file
  59. ;    - Set up flag to avoid unnecessary re-reading of
  60. ;      top of file 
  61. ;
  62. ;    The unsqueeze code was lifted from the USQ base code
  63. ;    by Dave Rand (Edmonton, Alberta) as adapted for LTYPE1
  64. ;    by S.Kluger (El Paso,Texas)
  65. ;    The code was lifted to allow continued use of ASM.COM 
  66. ;
  67. ; ** Original program code written by Phil Cary  23 Aug 82
  68. ;
  69. ; BISHOW is a  buffered,  bidirectional  version  of  SHOW.ASM
  70. ; which first appeared in Interface Age, November, 1981.  That
  71. ; program  could  only  scroll  forward  in  a  file, and read
  72. ; sectors from disk one at a time as they  were  sent  to  the
  73. ; console.   I  used SHOW frequently to take a quick look at a
  74. ; file without loading a  big  text  editor,  and  to  examine
  75. ; another  file  with the RUN command while in Wordstar.  TYPE
  76. ; does not work since it is not a file that Wordstar can  load
  77. ; and run.
  78. ;
  79. ; It was annoying when I went past the point I was looking for
  80. ; in a file with SHOW, and could not go backwards.  Thus, this
  81. ; bidirectional  version  which  uses  random access reads. In
  82. ; addition, buffering was added so that  the  number  of  disk
  83. ; reads  would  be  reduced,  and  moving  back and forth in a
  84. ; moderate sized file would be speeded up.  There is  a  trade
  85. ; off between the size of the buffer and the length of time it
  86. ; takes to refill the buffer which should be set to the user's
  87. ; preference.
  88. ;
  89. ; There are several customizing items in this program.  One is 
  90. ; the equate "maxsec" which sets the buffer size.   Another is 
  91. ; the  string  in the subroutine "clrscr" just after  the  org 
  92. ; statement.   This should be changed to erase the screen  and 
  93. ; home  the cursor for the user's terminal.   The program,  as 
  94. ; written,  requires a terminal with an erase screen and  home 
  95. ; cursor  function.   Some  terminals  do not allow  the  80th 
  96. ; column  to be filled without going to the  next  line.   For 
  97. ; this reason, the screen width ("maxchr") initially is set to 
  98. ; 79.   The screen sizes can be changed using the "S" (screen) 
  99. ; command.  The parameters that can be changed are the maximum 
  100. ; column  displayed ("maxchr"),  the minimum column  displayed 
  101. ; (allowing  you  to "window" the output),  and the number  of 
  102. ; lines ("scroln").   A zero for the maximum column  displayed 
  103. ; will  give and unlimited screen width.   The maximum  column 
  104. ; displayed  and  the number of lines can be set when  calling 
  105. ; BISHOW,  e.g.,  "BISHOW file.nam 79 24" will give 79 columns 
  106. ; and 24 lines,  and "BISHOW file.nam 79" will give 79 columns 
  107. ; with the default number of lines.  The last customizing item 
  108. ; is the "short" equate.   If this is chosen, the multiplicity 
  109. ; of command forms is not allowed (see the beginning to change 
  110. ; the  commands  used),  and certain messages  are  shortened.  
  111. ; This will allow BISHOW to fit into a 1K area.  If "short" is 
  112. ; false, the program is slightly over 1K.  Finally, direct I/O 
  113. ; to the console is used to avoid echoing the commands to  the 
  114. ; console as the CP/M write console function does.
  115. ;
  116. ; Just  a  small contribution to the public domain software as
  117. ; partial payment for the many fine and  educational  programs
  118. ; the system has given me.  Phil Cary.
  119. ;.........
  120. ;
  121. FALSE    EQU    0
  122. TRUE    EQU    NOT FALSE
  123. ;
  124. ; this code is now for Kaypro only -
  125. ;
  126. KAYPRO    EQU    TRUE        ;assemble for Kaypro 2/4/10
  127. ;
  128. SQUEEZE    EQU    TRUE        ;Generate code to handle squeezed files 
  129. NOWAIT    EQU    TRUE        ;Do not wait after clear screen
  130. ;
  131. ;    Operational equates
  132. ;
  133. MAXSEC    EQU    32        ;number of sectors in buffer
  134. SIGNAT    EQU    0FF76H        ;Signature for SQ files
  135. DLE    EQU    090H        ;Char flag for run compression (SQ)
  136. ;
  137. ;
  138.     IF    KAYPRO
  139. SCROLN    EQU    24        ;number of lines per scroll
  140. MAXCHR    EQU    79        ;number of characters per line
  141. ARWLFT    EQU    08H        ;Cursor left key (backspace)
  142. ARWUP    EQU    0BH        ;Cursor up key (vert tab)
  143. arwdwn    equ    0ah        ;cursor down key (linefeed)
  144. ARWRT    EQU    0CH        ;Cursor right key (formfeed)
  145.     ENDIF
  146. ;
  147. ;
  148. BASE    EQU    0        ;standard zero base CP/M
  149. ;
  150. ;    BDOS functions
  151. ;
  152. CONOUT    EQU    2        ;console write
  153. OPEN    EQU    15        ;open file
  154. CLOSE    EQU    16        ;close file
  155. READR    EQU    33        ;read file random access
  156. STDMA    EQU    26        ;set dma address
  157. ;
  158. ;    Page zero equates
  159. ;
  160. WBOOT    EQU    BASE        ;warm boot entry point
  161. BDOS    EQU    WBOOT+5        ;BDOS entry point
  162. FCB    EQU    WBOOT+5CH    ;default fcb drive number
  163. CMDTAIL    EQU    WBOOT+80H    ;location of command tail
  164. FCBFN    EQU    FCB+1        ;start of filename
  165. FCBFT    EQU    FCB+9        ;start of filetype
  166. FCBEX    EQU    FCB+12        ;current extent number
  167. FCBCRR    EQU    FCB+33        ;current record number, random access
  168. TPA    EQU    WBOOT+100H    ;transient program area
  169. ;
  170. ;    ASCII equates
  171. ;
  172. ENDMSG    EQU    0        ;null
  173. BELL    EQU    7        ;bell
  174. BS    EQU    8        ;Backspace
  175. TAB    EQU    9        ;tab
  176. LF    EQU    0AH        ;line feed
  177. CR    EQU    0DH        ;carriage return
  178. EOF    EQU    1AH        ;end of file
  179. ESC    EQU    1BH        ;escape
  180. SPACE    EQU    20H        ;space
  181. ;
  182. ;
  183.     ORG    TPA
  184. ;
  185.     JMP    START        ;skip over next subroutine
  186. ;
  187. CLRSCR: CALL    CDISP        ;command to home cursor and clear to
  188.     DB    1EH,17H,ENDMSG    ;end of screen for Kaypro 2/4/10
  189. ;
  190.     IF    NOWAIT
  191. ;
  192. WAIT:    MVI    B,0        ;waste time (may or may not be necessary)
  193. ;
  194. WAIT1:    XTHL            ;good time gobbeler!
  195.     XTHL
  196.     DCR    B
  197.     JNZ    WAIT1
  198.     RET            ;return from clrscr
  199. ;
  200.     ENDIF
  201. ;
  202. HELP2:    ; very fancy graphical help menu for the Kaypro
  203.     CALL    CDISP
  204.     DB    cr,lf
  205.     DB    ESC,'B0'
  206.     db    '     KPBISHOW v 3.21   Available Commands (same as Wordstar)   '
  207.     db    '  ',cr,lf,' ',esc,'B1'
  208.     db    ' ^C,Space bar,F, or C/R=forward a page     ^R or B=back 1 page '
  209.     DB    esc,'C1',' ',cr,lf,' ',esc,'B1'
  210.     DB    ' ^Z,+,arrow-down=forward 1 line      ^W,-,arrow-up=back 1 line '
  211.     db    esc,'C1',' ',cr,lf,' ',esc,'B1'
  212.     db    ' ^L or arrow-right=8 cols right   ^H or arrow-left=8 cols left '
  213.     db    esc,'C1',' ',cr,lf,' ',esc,'B1' 
  214.     db    ' ^S or S=set the screen parameters       Q or X=exits program  '
  215.     DB    ESC,'C1',' ',cr,lf,' ',esc,'B1'
  216.     db    '      Any other keys pressed will display this help menu       '
  217.     db    esc,'C1',' ',cr,lf
  218.     db    '                 Steven L. Sanders   08 Dec 84                 '
  219.     db    '  '
  220.     DB    esc,'C0',CR,LF,ENDMSG
  221.     JMP    GETCMD
  222. ;
  223. STATUS:        ; status line display for the Kaypro
  224.     CALL    CDISP
  225.     DB    ESC,'C7',1AH    ;disable status line and clear screen
  226.     DB    ESC,'B6'    ;save cursor position
  227.     DB    ESC,'B7'    ;enable status line
  228.     DB    ESC,'=8 '    ;position cursor to 25,0
  229.     DB    ESC,'B0'    ;inverse video mode
  230.     DB    ESC,'B1'    ;dim mode
  231.     DB    ' *KPBISHOW* '
  232.     DB    ESC,'C1'    ;dim off
  233.     DB    ' Viewing file:'
  234.     DB    endmsg
  235.  
  236. ; print filename routine
  237. ;
  238.     lxi    h,cmdtail    ;get filename from command tail
  239.     mov    b,m        ;get number of chrs
  240.     inx    h        ;point at first chr
  241.     inr    b
  242. prtfn1: mov    a,m        ;get the chr
  243.     call    co        ;output it
  244.     inx    h        ;move pointer
  245.     dcr    b        ;decrement the b reg
  246.     jnz    prtfn1        ;if not 0 then loop till done
  247. ;
  248.     call    cdisp        ;now finish rest of status line
  249.     db    ' '
  250.     db    esc,'B1'    ;dim mode
  251.     db    esc,'B2'    ;blink on 
  252.     db    '   ? for help '
  253.     db    esc,'C2'    ;blink off
  254.     db    '  S. Sanders  12/08/84 '
  255.     db    esc,'C1'    ;dim off
  256.     DB    ESC,'C0'    ;inverse video off
  257.     DB    ESC,'C6'    ;recall cursor position
  258.     DB    ENDMSG
  259.     ret
  260.  
  261. ;
  262. ; start of program (finally)
  263. ;
  264. START:    LXI    H,0        ;get ccp's stack
  265.     DAD    SP
  266.     SHLD    STACK        ;save old stack for later
  267.     LXI    SP,STACK    ;set new stack
  268.     LXI    H,CMDTAIL    ;point to command tail
  269.     MOV    B,M        ;get number of char in tail
  270.     INX    H        ;point to first character
  271.     INR    B
  272. ;
  273. EATSP:    MOV    A,M        ;get character if there is one
  274.     INX    H
  275.     DCR    B        ;b=number of characters left
  276.     JZ    OPENF        ;no more characters
  277.     CPI    SPACE        ;ignore spaces
  278.     JZ    EATSP
  279. ;
  280. FILNAM:    MOV    A,M        ;get characters in file name
  281.     INX    H
  282.     DCR    B        ;b=number of characters left
  283.     JZ    OPENF        ;only file name in tail
  284.     CPI    SPACE        ;wait for next space
  285.     JNZ    FILNAM
  286.     LXI    D,CHRMAX    ;point to chr/line
  287.     CALL    GETNBR        ;get number of characters/line
  288.     JC    HELP        ;invalid number
  289.     LXI    D,LINMAX    ;point to number of lines
  290.     CNZ    GETNBR        ;call only if characters still in
  291.                 ;__command tail
  292.     JC    HELP        ;invalid number
  293. ;
  294. OPENF:    CALL    OPNFIL        ;open file in default fcb
  295. ;
  296.     CALL    STATUS        ;display status line if file open ok
  297. ;
  298. OPENF1:
  299.     IF    SQUEEZE
  300. ;
  301.     CALL    CHKSQ        ;Check for squeezed, init if
  302. ;
  303.     ENDIF
  304. ;
  305. WRTFWD:    XRA    A        ;get a 0
  306.     STA    LINCNT        ;store in line count
  307.     STA    CHRCNT        ;store in character count
  308. ;                Do not reset the current extent!!!
  309. ;                BDOS will switch extents only if the no
  310. ;                specified ( <FCBEX> ) does NOT agree with
  311. ;                the wanted no <FCBCRR>. 
  312.     STA    FCBCRR        ;zero current record
  313.     STA    FCBCRR+1    ;__both bytes
  314.     STA    FCBCRR+2    ;__and the overflow
  315.     CALL    CLRSCR        ;erase the screen
  316. ;
  317. WRTFW0:    CALL    FILBUF        ;fill the disk buffer
  318. WRTFW3:
  319.     LXI    H,DSKBUF    ;point to beginning of buffer
  320. ;
  321. WRTFW1:
  322.     MOV    A,M        ;get a character
  323.     CPI    EOF        ;see if eof
  324.     JZ    GETCMD        ;yes, wait for command
  325.     INX    H        ;bump pointer
  326.     ANI    7FH        ;strip high bit
  327.     CPI    'L'-40H        ;filter form-feeds
  328.     JZ    FILTER        ;__commonly found in .PRN files
  329.     CALL    CO1        ;put it on console
  330.     CPI    CR        ;see if end of line
  331.     JZ    FWDCNT        ;yes, adjust line count
  332. ;
  333. WRTFW2:    LXI    D,ENDBUF    ;get end of buffer address
  334.     CALL    cmphlde        ;Is HL> gt DE> (end of buff)
  335. ;                ; Note test is LT now, not NE (v1.81)
  336.     JNC    WRTFW0        ;refill buffer and start over
  337.     JMP    WRTFW1        ;else, continue with next character
  338. ;
  339. HELP:    CALL    CDISP
  340.     DB    1ah,ESC,'B0'
  341.     DB    '  Kaypro BISHOW vers 3.21  '
  342.     DB    ESC,'C0',CR,LF,LF
  343.     DB    'Usage:  BISHOW d:filename.typ [cols [lines]]',CR,LF,cr,lf
  344.     DB    'Specify entire filename.typ - no wildcards allowed',cr,lf,lf
  345.     DB    'Columns default to  79',cr,lf
  346.     DB    'Lines per screen to 24',cr,lf
  347.     DB    ENDMSG
  348.     JMP    EXIT1
  349. ;
  350. FILTER:    PUSH    PSW        ;save status
  351.     MVI    A,'^'        ;print '^' in front
  352.     CALL    CO1        ;__of control character
  353.     POP    PSW        ;restore status
  354.     ADI    40H        ;mask into displayable char
  355.     CALL    CO1        ;display filtered control char
  356. ;
  357. FWDCNT:    LDA    LINCNT        ;get number of lines displayed
  358.     INR    A        ;bump it
  359.     STA    LINCNT        ;__and store it
  360.     MOV    D,A        ;save lincnt
  361.     LDA    LINMAX        ;get max number of line
  362.     CMP    D        ;compare with line count
  363.     JNZ    WRTFW2        ;if not there, continue, else get command
  364.     XRA    A        ;zero the
  365.     STA    LINCNT        ;__line count
  366. ;
  367. GETCMD:    PUSH    H
  368.     PUSH    D
  369.     PUSH    B
  370. ;
  371.     IF    KAYPRO
  372.     CALL    CDISP
  373.     DB    ESC,'C4',ENDMSG    ;disable cursor
  374.     ENDIF
  375. ;
  376. GETCM1:    MVI    C,6        ;direct console I/O
  377.     MVI    E,0FFH        ;__set up for input
  378.     CALL    BDOS
  379.     ORA    A        ;loop till char avail
  380.     JZ    GETCM1
  381.     POP    B
  382.     POP    D
  383.     POP    H
  384.     CPI    'a'        ;change command to
  385.     JC    GETCM2        ;__upper case
  386.     CPI    'z'+1
  387.     JNC    GETCM2
  388.     XRI    20H        ;is lower case, make upper case
  389. ;
  390. GETCM2:        ; get the command from keyboard
  391. ;
  392. ; go to top of the file?
  393. ;
  394.     CPI    '1'        ; 1 means goto 1st line
  395.     JZ    WRTTOP        ;Test if top in buffer
  396. ;
  397. ; help?
  398. ;
  399.     CPI    '?'        ;help request
  400.     JZ    HELP2
  401. ;
  402. ; forward a page ( Space bar, F, ^C, or C/R )
  403. ;
  404.     CPI    ' '        ;more use space
  405.     JZ    WRTFW1
  406.     CPI    'F'        ;scroll forward?
  407.     JZ    WRTFW1        ;br if yes
  408.     CPI    'C'-40H        ;wordstar uses ^C
  409.     JZ    WRTFW1
  410.     cpi    cr        ;also c/r goes forward a page
  411.     jz    wrtfw1
  412. ;
  413. ; back a page ( B or ^R )
  414. ;
  415.     CPI    'B'        ;scroll backward?
  416.     JZ    WRTBAK
  417.     CPI    'R'-40H        ;wordstar uses ^R
  418.     JZ    WRTBAK
  419. ;
  420. ; next line forward ( +, ^Z, or Arrow-down key )
  421. ;
  422.     cpi    '+'        ;1 for 1 more line?
  423.     jz    wrtnxt
  424.     cpi    'Z'-40H        ;wordstar uses ^Z
  425.     JZ    WRTNXT
  426.     cpi    arwdwn        ;cursor down?
  427.     jz    wrtnxt
  428. ;
  429. ; back a line ( -, ^W, or Arrow-up key )
  430. ;
  431.     cpi    '-'        ;minus key?
  432.     jz    wrtprv
  433.     CPI    'W'-40H        ;scroll prev line?
  434.     JZ    WRTPRV
  435.     CPI    ARWUP        ;Cursor up?
  436.     JZ    WRTPRV        ;yes, back-up a line
  437. ;
  438. ;
  439. ; exit program, clear screen ( Q or X )
  440. ;
  441.     CPI    'Q'        ;Q for quit?
  442.     JZ    EXITCL
  443.     cpi    'X'        ;was it an X
  444.     jz    exitcl
  445. ;
  446. ; set new screen paramaters ( S or ^S )
  447. ;
  448.     CPI    'S'        ;set screen parameters
  449.     JZ    SETSCR
  450.     cpi    'S'-40H
  451.     jz    setscr
  452. ;
  453. ; adjust margins ( Arrow-left, Arrow-right, or M )
  454. ;
  455.     CPI    ARWLFT        ;Cursor left?
  456.     JZ    ADJMM
  457.     CPI    ARWRT        ;Cursor right?
  458.     JZ    ADJMM
  459.     cpi    'M'        ; m for margins?
  460.     jz    adjmm
  461. ;
  462.     JMP    HELP2        ;if none of these, display built-in help menu
  463. ;
  464. ;...........
  465. ;            Go to top of file
  466. WRTTOP:
  467.     LDA    TOPBUF        ;Get top in buffer flag
  468.     ORA    A
  469.     JNZ    WRTFWD        ;No - the hard way
  470.     CALL    CLRSCR        ;erase the screen
  471. WRTTO1:
  472.     XRA    A
  473.     STA    LINCNT        ;Clear lines put so far
  474.     JMP    WRTFW3        ;Buffer contains top sectors
  475. ;
  476. ;            Write one more line
  477. WRTNXT:    LDA    LINMAX
  478.     DCR    A        ;fool wrtfw1 to only write one line
  479.     STA    LINCNT
  480.     JMP    WRTFW1
  481. ;            Back up one line
  482. WRTPRV:    LDA    LINMAX        ;back up one screen + 1 line
  483.     INR    A
  484.     JMP    WRTBK0
  485. ;            Back up full screen
  486. WRTBAK:    LDA    LINMAX        ;get screen line count
  487.     ADD    A        ;__multiply by 2
  488. ;
  489. WRTBK0:    INR    A        ;__and add 1
  490.     STA    LINCNT        ;__to backup to previous page
  491.     CALL    CLRSCR        ;clear the screen
  492. ;
  493. WRTBK1:    LXI    D,DSKBUF    ;get address of start of buffer start
  494.     CALL    cmphlde        ;Is HL> LT DE> (start of buff)
  495. ;                ; Note test is LT now, not NE (v1.81)
  496.     JC    FILBAK        ;Go refill buffer
  497. ;
  498. WRTBK2:    MOV    A,M        ;get a character
  499.     ANI    7FH        ;strip high bit
  500.     DCX    H        ;decrement buffer
  501.     CPI    CR        ;see if end of line
  502.     JZ    BAKCNT        ;__or form-feed
  503.     CPI    'L'-40H        ;__and adjust line count if so
  504.     JNZ    WRTBK1        ;else, loop if not
  505. ;
  506. BAKCNT:    LDA    LINCNT        ;else, get number of lines to move back
  507.     DCR    A        ;__and decrement it
  508.     STA    LINCNT        ;__store it
  509.     JNZ    WRTBK1        ;__and loop if not there
  510.     INX    H        ;else bump pointer
  511.     INX    H        ;__to account for dcx
  512.     JMP    WRTFW1        ;and go write a screen
  513. ;
  514. FILBAK:
  515. ;            Test for top of file
  516.     LDA    TOPBUF        ;Get top in buffer flag
  517.     ORA    A
  518.     JZ    WRTTO1        ;Yes - start of file in buffer
  519. ;            Start of file not in buffer, step back
  520.     LHLD    SECCNT        ;Get no of sectors last read
  521.     LXI    D,MAXSEC    ;get the buffer size
  522.     DAD    D        ;add them
  523.     XCHG            ;__and put them in DE
  524.     LDA    FCBCRR        ;subtract low order byte 
  525.     SUB    E        ;__from current record count
  526.     STA    FCBCRR        ;__and store in current record count
  527.     LDA    FCBCRR+1    ;same with high order byte
  528.     SBB    D        ;__but with borrow
  529.     JM    WRTFWD        ;if beyond beginning of file, start over
  530.     STA    FCBCRR+1    ;else, store high order byte
  531.     CALL    FILBUF        ;fill the buffer
  532.     LXI    H,ENDBUF    ;__and point to end of buffer
  533.     CALL    CLRSCR        ;clear the screen
  534.     JMP    WRTBK2        ;continue moving back in file
  535. ;
  536. ;            ;Fill buffer from spec'd sector
  537. FILBUF:
  538.     MVI    B,MAXSEC    ;number of sectors to resd
  539. FILB1S:
  540.     LXI    D,DSKBUF    ;load start of disk buffer
  541.     LXI    H,0        ;zero out the
  542.     SHLD    SECCNT        ;__number of sectors in buffer
  543.     LHLD    FCBCRR        ;Is this top of file?
  544.     MOV    A,H
  545.     ORA    L
  546.     STA    TOPBUF        ;Set top of file in buffer flag
  547. ;                ; Z - top, NZ - not top 
  548.     IF    SQUEEZE
  549.     LDA    SQFLG        ;Is this a squeezed file
  550.     ORA    A
  551.     JNZ    FILSQ        ;Yes -
  552.     ENDIF
  553. ;
  554. FILBU1:    PUSH    H        ;save all
  555.     PUSH    D        ;__registers from
  556.     PUSH    B        ;__BDOS clobber
  557.     MVI     C,STDMA        ;set dma to
  558.     CALL    BDOS        ;__disk buffer
  559.     LXI    D,FCB        ;set up to read
  560.     MVI    C,READR        ;__a record
  561.     CALL    BDOS        ;do it
  562.     ORA    A        ;read OK?
  563.     LHLD    FCBCRR        ;get current record number
  564.     INX    H        ;__bump it
  565.     SHLD    FCBCRR        ;__and save it
  566.     LHLD    SECCNT        ;get sectors in buffer
  567.     INX    H        ;bump it
  568.     SHLD    SECCNT        ;store it
  569.     POP    B
  570.     POP    D
  571.     POP    H
  572.     JNZ    RDERR        ;no, last sector read
  573.     DCR    B        ;decrement it
  574.     RZ            ;if done return
  575.     LXI    H,128        ;else, add 128 to
  576.     DAD    D        ;__dma address
  577.     XCHG            ;put it in de
  578.     JMP    FILBU1        ;read another sector
  579. ;
  580.     IF    SQUEEZE
  581. ;
  582. ;            Fill buffer from squeezed file
  583. ;            This rtn handles mapping from unsq sector #
  584. ;            to sector, byte & bit in sq stream
  585. ;            on input FCBCRR contains wanted sector no,
  586. ;            ( no allowance made for sectors # over 65535)
  587. ;            <B> contains no of sectors wanted
  588. ;            DE> buffer where sectors wanted,
  589. ;             ignored in this version, always full DSKBUF
  590. FILSQ:
  591.     LHLD    FCBCRR        ;Get # for 1st sector wanted
  592.     XCHG
  593.     PUSH    D        ;Save to restore after unsq
  594.     LHLD    NXTSEC        ; & 1st sector after buffered ones  
  595.     CALL    cmphlde        ;Consecutive?
  596.     JZ    USQNXT        ;Yes - fine
  597.     JNC    USQBAK        ;No - lower
  598. ;            ;Next sect after latest but not consec
  599.     CALL    CDISP
  600.     DB    CR,LF,'Program failure, non-contiguous sectors requested'
  601.     DB    CR,LF,'from unsqueeze rtn',CR,LF,0
  602.     JMP    EXIT        ;Should never happen
  603. USQBAK:            ;Going backward
  604.     MOV    A,D        ;All the way?
  605.     ORA    E
  606.     JNZ    USQNO1        ;No - MUST be prev!!!
  607.     LXI    H,SQMAP+2+8    ;Yes - reset SQMAP index to #3
  608.     SHLD    SQMAP
  609. USQNO1:
  610.     LHLD    SQMAP        ;Get index into mapping table
  611.     LXI    D,-8        ;Step back from next, past current to prev
  612.     DAD    D
  613.     SHLD    SQMAP        ; & save updated index for next
  614.     MOV    E,M        ;Get SQ sector no
  615.     INX    H
  616.     MOV    D,M
  617.     INX    H
  618.     MOV    C,M        ;Get byte offset
  619.     INX    H
  620.     MOV    A,M        ; & bit offset
  621.     STA    bitlft
  622.     XRA    A
  623.     STA    rcnt        ;No runs in progress
  624. ;                (assumption)
  625.     STA    SQBYT+1        ;Set offset 1st data byte
  626.     MOV    A,C
  627.     STA    SQBYT        ;For now offset within sector only
  628.     LHLD    SQBSC1        ;Get no of first SQ sector now in buffer
  629.     XCHG            ;<HL> wanted 1st sector, <DE> actual 1st
  630.     CALL    cmphlde        ;Is 1st buffer sector low/equal 1st data sect?
  631.     JNC    USQ1OK        ;Yes - first wanted sector SQ in buffer
  632. ;                 Max header 1035 bytes + file name)
  633. ;            Force reload of SQ buffer
  634.     SHLD    NXTSQS        ;No - 1st data sector b/4 1st buffer sect
  635. ;                 (note is probab not sector 0
  636. ;                 because of header, eg decoding tree)
  637.     MVI    A,1        ;Set rewind with I/O
  638.     STA    SQREWD        ;Set rewind flag
  639. ;                 SQBYT contains offset of 1st data byte
  640.     XRA    A
  641.     STA    SQEOF        ;Reset end of file on SQ
  642. ;                Leave current extent alone. This is how
  643. ;                BDOS knows how to switch extents. It checks
  644. ;                if the current extent no agrees with
  645. ;                the wanted record.
  646.     STA    FCBCRR+2    ; & count overflow, should not be necessary
  647.     MOV    D,A
  648.     JMP    USQNX1        ;Go adj buffer pointer
  649. ;                (NOP since <DE>=0
  650. ;            ;SQ text still in buffer
  651. USQ1OK:
  652. ;                <DE> # of 1st sector in SQ buf
  653. ;                <HL> # of wanted SQ sector 
  654. ;                (Max 100H SQ sectors in buffer)
  655.     MOV    A,L
  656.     SUB    E
  657.     RAR            ;Convert to pages (100H)
  658. ;                 Know Cy=0 in
  659. ;                 leaves Cy if odd no of sects
  660.     MOV    D,A
  661.     MVI    A,0        ;Do not disturb Cy
  662.     RAR            ;Pu carry (now 80H or 00H) 
  663. USQNX1:
  664.     MOV    E,A
  665.     LHLD    SQBYT        ;Get offset of 1st data byte in wanted sect
  666.     DAD    D        ; --> offset in buffer
  667.     LXI    D,SQBUF
  668.     DAD    D        ;Convert to absolute addr
  669.     SHLD    inbufs        ;& set as next byte to unsqueeze
  670. ;
  671. USQNXT:            ;Next sector consecutive
  672.     LHLD    NXTSQS        ;Get no of next SQ sector 
  673. ;                (in case read reqd)
  674.     SHLD    FCBCRR
  675. ;            Build mapping table entry
  676.     LHLD    inbufs        ;Calc offset in buffer
  677.     LXI    D,-SQBUF
  678.     DAD    D
  679.     MOV    C,L        ;Keep offset within sector
  680.     LDA    bitlft        ;Get bit offset
  681.     MOV    B,A
  682.     ORA    A        ;On byte boundary?
  683.     MOV    A,C
  684.     JNZ    NOTBBY        ;No -
  685.     INR    A        ;Yes - no adj reqd
  686. NOTBBY:
  687.     ANI    7FH        ;Ensure sector relative
  688.     DAD    H        ;Convert to sector no
  689.     ORA    A        ;Is next byte at start of sect?
  690.     JNZ    SECTOK
  691.     DCR    H        ;Yes - step back one sector
  692. SECTOK:
  693.     DCR    A
  694.     ANI    7FH        ;& adj byte index
  695.     MOV    E,H
  696.     MVI    D,0
  697.     LHLD    SQBSC1        ;# of 1st sector in buffer
  698.     DAD    D
  699.     XCHG            ;<D> absolute SQ sector no
  700.     LHLD    SQMAP        ;Get index
  701.     MOV    M,E        ;Save abs SQ sector no
  702.     INX    H
  703.     MOV    M,D
  704.     INX    H
  705.     MOV    M,A        ;Save sector relative byte offset
  706.     INX    H
  707.     MOV    M,B        ;Save bitlft
  708.     INX    H
  709.     SHLD    SQMAP        ;Save new index
  710.     CALL    CDISP        ;Show msg where is
  711.     DB    '>>> Unsqueezing text <<<',ENDMSG
  712. ;                Corrupts display if aft CR but b/4 LF
  713.     CALL    filusq        ;Fill unsq buffer
  714. ;                returns NZ on EOF
  715. ;                SQEOF set as well then
  716.     CALL    CDISP        ;Remove msg just displayed,
  717. ;                 assumes BS across start of line if reqd
  718.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS
  719.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS
  720.     DB    '                        '
  721.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS
  722.     DB    BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,BS,0
  723.     LHLD    FCBCRR        ;Get no of next SQ sector
  724.     SHLD    NXTSQS
  725.     LHLD    nxtadr        ;Calc # of unsq sectors in buf
  726.     LXI    D,-DSKBUF    ;(as neg no)
  727.     DAD    D        ;Calc length
  728.     DAD    H        ; & convert to sectors in <H>
  729.     MOV    L,H
  730.     MVI    H,0
  731.     SHLD    SECCNT        ;Save # of sectors in DSKBUF
  732.     POP    D        ;Get FCBCRR as passed by calling rtn
  733.     DAD    D        ; & calc new one
  734.     SHLD    FCBCRR
  735.     SHLD    NXTSEC
  736.     RET
  737. ;
  738.     ENDIF
  739. ;
  740. ;
  741. ;We only get here if end of file
  742. ;
  743. RDERR:    MVI    A,EOF        ;get bogus eof
  744.     STAX    D        ;save at buffer end in case no eof in file
  745.     XRA    A        ;get a zero to direct to start of buffer
  746.     RET            ;__on ret
  747. ;
  748. OPNFIL:    LDA    FCBFN        ;point to first letter of filename
  749.     CPI    ' '        ;anything there?
  750.     JZ    HELP        ;no, give help message
  751.     XRA    A        ;get a 0
  752.     STA    FCBEX        ;zero current extent
  753. ;                MUST open file on extent zero
  754.     LXI    D,FCB        ;file name in default fcb
  755.     MVI    C,OPEN        ;set up to open
  756.     CALL    BDOS        ;do it
  757.     INR    A        ;open OK?
  758.     RNZ            ;yes
  759.     CALL    CDISP        ;else, give error msg and quit
  760.     DB    cr,lf,'File not found - check the DIR',7,cr,lf,ENDMSG
  761.     JMP    EXIT1        ;leave msg on screen on exit
  762. ;
  763. GETNBR:    MOV    A,M        ;get first digit
  764.     INX    H
  765.     DCR    B        ;b=number of characters left in buffer
  766.     RZ            ;no digit
  767.     CPI    SPACE
  768.     JZ    GETNBR        ;wait until next non-space
  769.     PUSH    D        ;save location to save number
  770.     MVI    D,0        ;initialize number
  771. ;
  772. GNUM1:    SUI    30H        ;change ASCII to number
  773.     JC    INVNUM        ;not a number
  774.     CPI    10
  775.     CMC
  776.     JC    INVNUM        ;not a number
  777.     PUSH    PSW        ;save number
  778.     MOV    A,D        ;multiply old number by 10
  779.     ADD    A        ;*2
  780.     ADD    A        ;*4
  781.     ADD    A        ;*8
  782.     ADD    D        ;*9
  783.     ADD    D        ;*10
  784.     MOV    D,A
  785.     POP    PSW        ;restore new digit
  786.     ADD    D
  787.     MOV    D,A
  788.     MOV    A,M        ;get next digit
  789.     INX    H
  790.     DCR    B
  791.     JZ    ENDNUM        ;end of number
  792.     CPI    SPACE
  793.     JNZ    GNUM1
  794. ;
  795. ENDNUM:    MOV    A,D        ;save number
  796.     DCR    A        ;correct number for co routines
  797.     XCHG            ;set to restore save location
  798.     POP    H        ;restore save location
  799.     MOV    M,A        ;save digit
  800.     XCHG            ;put buffer location where it belongs
  801.     MOV    A,B        ;see if any characters left in buffer
  802.     ORA    A        ;zero if no characters in buffer
  803.     RET
  804. ;
  805. INVNUM:    POP    D        ;correct stack
  806.     RET
  807. ;
  808. ASCIIN:    MVI    B,100        ;divide by 100, then change
  809.     CALL    DIVIDE        ;__digit to ASCII and store at hl
  810.     MVI    B,10        ;divide by 10, then change
  811.     CALL    DIVIDE        ;__digit to ASCII and store at hl+1
  812.     MVI    B,30H        ;change ones place number
  813.     ADD    B        ;__to ASCII and store at hl+2
  814.     MOV    M,A
  815. ;
  816. CDISP:    XTHL            ;exchange top of stack and HL
  817. ;
  818. CDIS1:    MOV    A,M        ;HL now pointing to db message
  819.     ORA    A        ;see if 0 at end of message
  820.     INX    H
  821.     JZ    CDIS2        ;yes, restore stack and return
  822.     CALL    CO        ;no, print the character
  823.     JMP    CDIS1        ;__and loop
  824. ;
  825. CDIS2:    XTHL            ;get return address on top of stack
  826.     RET            ;__and return
  827. ;
  828. CO:    PUSH    B        ;Save the registers
  829.     PUSH    D        ;__from bdos
  830.     PUSH    H        ;__clobber
  831. CO2:    PUSH    PSW
  832. CO4:    MOV    E,A        ;set up character
  833.     MVI    C,CONOUT    ;__to send to console
  834.     CALL    BDOS        ;do it
  835. CO3:    POP    PSW
  836. CO5:    POP    H        ;restore
  837.     POP    D        ;__the registers
  838.     POP    B
  839.     RET
  840. ;
  841. CO1:    PUSH    B        ;Save the registers
  842.     PUSH    D
  843.     PUSH    H
  844.     PUSH    PSW
  845.     LXI    H,CHRCNT    ;Get address of character count
  846.     CPI    CR        ;see if end of line
  847.     JZ    ENDLIN        ;update line information
  848.     CPI    LF        ;ignore linefeed
  849.     JZ    CO4
  850.     LDA    CHRMAX        ;get maximum characters per line
  851.     CMP    M        ;see if too many char
  852.     JC    CO3        ;don't print character
  853.     POP    PSW        ;__and print character
  854.     CPI    TAB        ;fix chrcnt for tabs
  855.     JZ    TABFIX
  856.     INR    M        ;increment character count
  857.     MOV    E,A
  858.     LDA    CHRMIN        ;see if up to minimum display yet
  859.     CMP    M
  860.     MOV    A,E        ;restore character
  861.     JNC    CO5        ;do not display character
  862.     JMP    CO2        ;finally, display character
  863. ;
  864. ENDLIN:    MVI    M,0        ;reset character count
  865.     JMP    CO4        ;print cr
  866. ;
  867. TABFIX:    MVI    A,08H        ;fix chrcnt for tabs
  868.     ADD    M        ;increment to next 8-count
  869.     ANI    0F8H        ;make into multiple of 8
  870. ;
  871. TAB2:    SUB    M        ;get number of space to go
  872.     MOV    B,A
  873. ;
  874. TAB1:    MVI    A,SPACE        ;expand tab
  875.     CALL    CO1
  876.     DCR    B
  877.     JNZ    TAB1        ;still more spaces
  878.     JMP    CO5        ;exit routine
  879. ;
  880. SETSCR:    PUSH    H
  881.     PUSH    D
  882.     PUSH    B
  883. ;
  884. GETMAX:    LDA    CHRMAX        ;get maximum number of characters
  885.     INR    A
  886.     LXI    H,HUNS
  887.     CALL    ASCIIN        ;put ASCII number in message        
  888. ;
  889.     DB    CR,LF,'Maximum Column: '
  890. ;
  891. HUNS:    DB    30H
  892.     DB    30H
  893.     DB    30H
  894.     DB    ' New? ',ENDMSG
  895.     CALL    GETINP        ;read input from console
  896.     LXI    D,CHRMAX    ;set new chrmax in memory
  897.     CALL    GETNBR
  898.     JC    GETMAX        ;if error, repeat last message
  899. ;
  900. GETMIN:    LDA    CHRMIN        ;get minimum character display
  901.     INR    A
  902.     LXI    H,HUN
  903.     CALL    ASCIIN        ;put ASCII number in message        
  904. ;
  905.     DB    LF,'Minimum Column: '
  906. ;
  907. HUN:    DB    30H
  908.     DB    30H
  909.     DB    30H
  910.     DB    ' New? ',ENDMSG
  911.     CALL    GETINP        ;read input from console
  912.     LXI    D,CHRMIN    ;set new chrmax in memory
  913.     CALL    GETNBR
  914.     JC    GETMIN        ;if error, repeat last message
  915. ;
  916. GETLIN:    LDA    LINMAX        ;get number of lines per display
  917.     LXI    H,HUND
  918.     CALL    ASCIIN        ;put ASCII number in message        
  919.     DB    LF,'Lines Displayed: '
  920. ;
  921. HUND:    DB    30H
  922.     DB    30H
  923.     DB    30H
  924.     DB    ' New? ',ENDMSG
  925.     CALL    GETINP        ;read input from console
  926.     LXI    D,LINMAX    ;set new chrmax in memory
  927.     CALL    GETNBR
  928.     JC    GETLIN        ;if error, repeat last message
  929.      POP    B
  930.     POP    D
  931.     POP    H
  932. ;
  933. WRTSAM:    LDA    LINMAX        ;write the same screen
  934.     JMP    WRTBK0
  935. ;
  936. ;
  937. GETINP:    MVI    A,5        ;get set to read new maximum column
  938.     STA    CMDTAIL
  939.     MVI    C,0AH
  940.     LXI    D,CMDTAIL
  941.     CALL    BDOS        ;get maximum column
  942.     LXI    H,CMDTAIL+1    ;now, change to ASCII
  943.     MOV    B,M
  944.     INX    H
  945.     INR    B
  946.     RET            ;return with input in buffer
  947. ;
  948. ;            Adjust char min/max on cursor left/rt
  949. ADJMM:
  950.     PUSH    H
  951.     CPI    ARWLFT        ;Move left (decrease)?
  952.                 ; set flag
  953.     LDA    CHRMAX        ;What is last char on line t/b displ
  954.     MOV    H,A
  955.     LDA    CHRMIN        ; & 1st char to display
  956.     MVI    L,8        ;Scroll by 8
  957.     JZ    ADJMMD        ;Yes - adjust down
  958.     ADD    L        ;No - increase min, no limit
  959.     PUSH    PSW
  960.     MOV    A,L
  961.     ADD    H        ; & max
  962.     JMP    ADJMMS
  963. ADJMMD:
  964.     SUB    L        ;Display more to the left
  965.     PUSH    PSW
  966.     MOV    A,H
  967.     SUB    L
  968. ADJMMS:
  969.     MOV    H,A        ;<H> max
  970.     POP    PSW        ;<A> min
  971.     CMP    H        ;Wrap, (max< min)
  972.     JNC    ADJMMX        ;Yes - leave unchanged
  973.     STA    CHRMIN
  974.     MOV    A,H
  975.     STA    CHRMAX
  976. ADJMMX:
  977.     POP    H
  978.     JMP    WRTSAM        ;Go write same screen
  979. ;
  980. DIVIDE:    MVI    C,'0'-1        ;extract dividend of a div c
  981. ;
  982. DIV1:    INR    C        ;__and store in location pointed
  983.     SUB    B        ;__to by hl
  984.     JNC    DIV1
  985.     ADD    B
  986.     MOV    M,C        ;save ASCII digit
  987.     INX    H        ;bump pointer to next location
  988.     RET
  989. ;
  990. EXITCL:
  991. ;            Clear screen only on reg exit
  992.     CALL    CLRSCR        ;clear the screen
  993. ;
  994. EXIT:    MVI    E,0FFH        ;clear console of characters
  995.     MVI    C,6        ;direct console I/O
  996.     CALL    BDOS        ;__get any waiting characters
  997. ;
  998.     IF    KAYPRO
  999.     CALL    CDISP
  1000.     DB    ESC,'C7'    ;disable status line
  1001.     DB    ESC,'B4',ENDMSG    ;enable cursor display
  1002.     CALL    CLRSCR        ;now clear whole screen
  1003.     ENDIF
  1004. ;
  1005.     LXI    D,FCB        ;close file
  1006.     MVI    C,CLOSE        ;--in case this is MP/M
  1007.     CALL    BDOS
  1008. ;
  1009. EXIT1:
  1010.         IF    KAYPRO
  1011.     CALL    CDISP        ;re-enable cursor even if no file
  1012.     DB    ESC,'B4',ENDMSG    ;specified to BISHOW
  1013.         ENDIF
  1014. ;
  1015.     LHLD    STACK        ;get old stack
  1016.     SPHL
  1017.     RET            ;return to CCP
  1018. ;
  1019. ;
  1020. ;            Compare <HL> to <DE>
  1021. ;             Z - equal; C - <HL> less than <DE> 
  1022. cmphlde:
  1023.     mov    a,h
  1024.     cmp    d
  1025.     rnz
  1026.     mov    a,l
  1027.     cmp    e
  1028.     ret
  1029. ;
  1030.     IF    SQUEEZE
  1031. *******************************************************
  1032. * USQ support code                      *
  1033. * 10/12/83 by Dave Rand                      *
  1034. *******************************************************
  1035. ;
  1036. ;            Check for SQ file, init tree if so
  1037.  CHKSQ:
  1038. ;            Initialize
  1039.     xra    a
  1040.     mov    l,a
  1041.     mov    h,l        ;clear <hl>
  1042.     STA    SQFLG        ;Make sure not set as squeezed yet 
  1043.     sta    SQEOF        ; end of file on SQ
  1044.     sta    SQREWD        ;Clear "rewinding" SQ file 
  1045.     sta    bitlft        ;force init char read
  1046.     sta    rcnt        ;and zero repeats
  1047.     shld    FCBCRR        ;Clear next record
  1048.     sta    FCBCRR+2    ; and overflow
  1049.     shld    numvals        ;Clear # nodes
  1050. ;
  1051.     lxi    h,SQBUF        ;Set to input (squeezed) buffer 
  1052.     shld    inbufs
  1053.     shld    inbufu
  1054.     lxi    d,128
  1055.     dad    d
  1056.     shld    SQBUFE        ;Force exit on full buff aft 1 sect
  1057. ;                 causes the SQ buffer to contain
  1058. ;                 sectors 1+ only (not zero),
  1059. ;                 normally fine since sector 0 contains only
  1060. ;                 header info. Sector 0 will be reread
  1061. ;                 if contains data and needed  
  1062.     call    usqsig        ;Read & val signature word
  1063.     RNZ            ;Not SQ
  1064.     STA    SQFLG        ;Yes - set flag
  1065.     lhld    0006        ;Get top of memory
  1066.     lxi    d,sqbuf+100H*128 ;Limit buffer to max 100H
  1067.     call    cmphlde        ; sectors (FILBUF uses 8 bit count <B>)
  1068.     JC    toplow        ;use top
  1069.     xchg            ;use limit 
  1070. toplow:
  1071.     shld    SQBUFE        ;& store as full address 
  1072.     call    namlp        ;Skip past name
  1073.     call    usqtbl        ;Validate & load decoding tree
  1074.     jz    oak        ;tree ok
  1075.     call    CDISP
  1076.     db    cr,lf,'Invalid decode tree size',cr,lf,0
  1077.     jmp    EXIT
  1078. oak:
  1079.     lxi    h,SQMAP+2    ;Point to 1st entry 
  1080.     shld    SQMAP        ;Set to 1at entry in SQ mapper
  1081.     ret
  1082. ;            Read and validate signature word
  1083. usqsig:
  1084.     call    getw        ;Read  1st word in file
  1085.     lxi    d,signat    ;Get expected value
  1086.     call    cmphlde
  1087.     mvi    a,1        ;Set code in case of error
  1088.     ret            ;Exit with Z/NZ
  1089. ;
  1090. ;            Read & save checksum
  1091. rdchks:
  1092.     call    getw        ;get cksum, and store
  1093.     shld    filchks
  1094.     ret
  1095. ;            Read & skip name
  1096. namlp:    call    getc        ;Loop to skip name
  1097.     jnz    erext        ;I/O error or unexpected EOF
  1098.     ora    a
  1099.     jnz    namlp        ;Not yet end of name
  1100.     ret
  1101. ;
  1102. ;            Load decoding tree
  1103. ;            This version uses 1 byte abslute node indices
  1104. ;            (1-ffH) and is thus limited to 255 nodes and 255
  1105. ;            characters represented in the squeezed file.
  1106. ;            (All different characters present in the original
  1107. ;            file as well as any added through run encoding.
  1108. ;            Runs of 3 or more consecutive identical characters
  1109. ;            are encoded as char, DLE, count, where count
  1110. ;            is a one byte field 00 - FFH) 
  1111. ;
  1112. usqtbl:
  1113.      call    getw        ;Get no of nodes
  1114.     mov    a,h
  1115.     ora    l
  1116.     jz    nzexit        ;Null tree
  1117.     shld    numvals
  1118.     mov    a,h        ;Max 257, 256 char & spec eof
  1119. ;                in this version allow for only 256
  1120. ;                diff codes, every ASCII and non-ASCII
  1121. ;                char would have to be present, or
  1122. ;                run repeat counts 128-255 (every one)
  1123.     ora    a        ;H/o byte should be zero
  1124.     jnz    nzexit
  1125.     lxi    d,SQTREE    ;Set to decoding tree
  1126. nodelp:    shld    nxtadr        ;Save no of nodes
  1127.     mov    a,h
  1128.     ora    l
  1129.     rz            ;Done all nodes
  1130.     call    cvnode        ;get node, falg byte in <H>,
  1131. ;                 index/char in <L>
  1132.     push    h
  1133.     call    cvnode        ;get second child/char
  1134.     pop    b
  1135.     mov    a,b
  1136.     ral            ;Shift flags to 8, 4 posns 
  1137.     ora    h        ;Combine in 1st child flags 
  1138.     xchg            ;HL> SQTREE, <A>,<C>,<E> node 
  1139.     mov    m,a        ;Store flags in table
  1140.     inx    h
  1141.     mov    m,c
  1142.     inx    h
  1143.     mov    m,e
  1144.     inx    h
  1145.     xchg            ;DE> SQTREE
  1146.     lhld    nxtadr        ;Nodes remaining
  1147.     dcx    h
  1148.     jmp    nodelp
  1149. ;            Get encoded node
  1150. ;            Our nodes contain 3 bytes:
  1151. ;            - flag byte,
  1152. ;            - left child index/char
  1153. ;            - right child index/char
  1154. ;            Nodes on input are 4 bytes,
  1155. ;            with each half containing
  1156. ;            an index (1-100h) or character,
  1157. ;            where characters are encoded as
  1158. ;            negative values -(char+1)
  1159. ;            Eof is encoded as -(100h+1)
  1160. cvnode:
  1161.     push    d
  1162.     call    getw        ;Get word, chld ptr or char
  1163.     pop    d
  1164.     mov    a,h
  1165.     ora    a
  1166.     rz            ;Child index, <H>=0,<L>=index
  1167.     mov    a,l
  1168.     cma
  1169.     mov    l,a        ;convert char to reg form
  1170.     mov    a,h        ;get h/o byte again
  1171.     cma
  1172.     inr    a        ;Conv to 1 if char, 2 if EOF
  1173.     mov    h,a
  1174.     cpi    1        ;Was that reg char?
  1175.     rz            ;Yes - complete
  1176.     adi    3        ;No convert EOF flag to 0100
  1177.     mov    h,a
  1178.     ret
  1179.  
  1180. ;            Exit with NZ flag
  1181. nzexit:
  1182.     mvi    a,2        ;tree error
  1183.     ora    a        ;Set NZ flag
  1184.     ret
  1185.  
  1186. ;
  1187. ;
  1188. ;            Fill output buffer (unsqueezed char)
  1189. ;
  1190. filusq:
  1191.     lda    SQREWD        ;Rewinding SQ input?
  1192.     ora    a
  1193.     jz    norewd        ;No
  1194. ;            Reload SQ buffer
  1195.     lhld    inbufs
  1196.     push    h        ;getrf resets
  1197.     call    getrf        ;Yes - reload buffer & get 1st 8 bits
  1198.     pop    h
  1199.     shld    inbufs        ;Set to first data byte to use
  1200. badj:
  1201.     mov    c,a
  1202.     lda    bitlft        ;Get preset 1st wanted bit no
  1203.     mov    c,a
  1204.     mvi    a,8
  1205.     sub    b        ; Calc adjmt reqd  
  1206. badjlp:
  1207.     dcr    a
  1208.     jz    badjfn        ; bit adjust finished
  1209.     mov    b,a
  1210.     mov    a,c
  1211.     rrc
  1212.     mov    c,a
  1213.     mov    a,b
  1214.     jmp    badjlp
  1215. badjfn:
  1216.     sta    bitbuf
  1217.     xra    a
  1218.     sta    SQREWD        ; & clear rewind flag
  1219. norewd:
  1220.     lxi    h,DSKBUF    ;reset buffer pointer
  1221.     xra    a
  1222. buflp:
  1223.     shld    nxtadr        ;Save as next byte in buffer
  1224.     rnz            ;End of file (NZ flag)
  1225. ;                 as set by GETNXT rtn below
  1226.     lxi    d,SQTREE    ;Get end of input
  1227.     call    cmphlde        ;buffer full (de < hl - not full)
  1228.     jnc    full        ;buffer is full
  1229.     call    getnxt        ;Get next decoded char
  1230.                 ;No checksum taken
  1231.     lhld    nxtadr        ;Next out buffer posn
  1232.     mov    m,a        ;Store char returned, may be EOF char
  1233.     inx    h
  1234.     jmp    buflp
  1235. ;
  1236. full:
  1237.     xra    a        ;Ensure Z
  1238.     ret            ;Return on full buffer
  1239. ;
  1240. ;
  1241. ;            Get next decoded character
  1242. ;
  1243. getnxt:    lda    rcnt        ;see if in the middle of
  1244.     ora    a        ;repeat sequence...
  1245.     jz    norpt
  1246.     dcr    a        ;Yes - reduce repeat remaining 
  1247.     sta    rcnt
  1248.     lda    last        ;Get latest char again
  1249.     cmp    a
  1250.     ret            ;Return with Z for ok
  1251. norpt:    call    decode
  1252.     rnz            ;EOF? <A>=1AH
  1253.     cpi    dle        ;Run encoding flag?
  1254.     jnz    norun
  1255. ;            Handle DLE
  1256.     call    decode        ;get count
  1257.     rnz            ;EOF? (is really error after DLE)
  1258.     ora    a
  1259.     jnz    run        ;Non-zero, real run 
  1260.     mvi    a,dle        ;dle is encoded as dle,0
  1261.     cmp    a
  1262.     ret
  1263. ;            ;Run encoding found
  1264. run:    dcr    a        ;Allow for char already retnd
  1265.     dcr    a        ; & this one
  1266.     sta    rcnt        ;Keep count yet to be retd
  1267.     lda    last        ;return second time
  1268.     cmp    a
  1269.     ret
  1270. ;            ;Normal char, no run active 
  1271. norun:    sta    last        ;This may be the start
  1272.     cmp    a
  1273.     ret
  1274. ;
  1275. ;
  1276. ;            Read bits and decode to char
  1277. ;             note this version uses 3 bytes per node
  1278. ;             not 4.
  1279. ;             The first byte in each node is a flag byte
  1280. ;              .... x... - left node contains EOF marker
  1281. ;              .... .x.. - right node contains EOF marker
  1282. ;              .... ..x. - left node contains char
  1283. ;              .... ...x - right node contains char
  1284. ;
  1285. decode:    lxi    d,0        ;Set to node zero in table
  1286.     lda    bitbuf        ;Get bits from bit buffer
  1287.     mov    c,a
  1288. bitlp:    lda    bitlft        ;Any bits remaining? 
  1289.     ora    a
  1290.     jnz    nxtbit        ;Yes - go use
  1291.     push    d
  1292.     call    getc        ;No - replenish bit buffer
  1293.     jnz    badr        ;Unexpected eof
  1294.     pop    d
  1295.     mov    c,a
  1296.     mvi    a,8        ;Set as 8 bits inbuffer 
  1297. nxtbit:    dcr    a
  1298.     sta    bitlft        ;Save no of bit remaining 
  1299.     lxi    h,SQTREE    ;Set to node 0, left child ptr
  1300.     dad    d
  1301.     dad    d
  1302.     dad    d        ;Add in node no (4 bytes/node)
  1303.     mov    b,m        ;Get flag byte
  1304.     inx    h        ;Step to left child pointer
  1305.     mov    a,c        ;Get input bits 
  1306.     rrc            ;Shuffle LOW-ORDER bit to Carry
  1307.     mov    c,a
  1308.     mov    a,b        ;Get flag byte 
  1309.     jnc    getn3        ;Zero input bit,leave at left
  1310.     inx    h        ;add 1 to point to right child pointer
  1311.     add    b        ;Normalize wanted flags to .... x.x.
  1312. getn3:
  1313.     mov    e,m        ;Pick up child or char
  1314. ;                <D> should always remain zero 
  1315.     ani    1010B        ;Mask unwanted bits
  1316.     jz    bitlp        ;Reg child pointer
  1317. ;            Got to char or eof
  1318.     ani    1000B        ;End of file marker?
  1319.     jnz    goteof        ;Yes - get out with eof
  1320.     mov    a,c
  1321.     sta    bitbuf        ;Save bit buffer
  1322.     mov    a,e        ;Get decoded char (neg)
  1323.     ret
  1324. ;
  1325. ;            Exit on reg eof
  1326. goteof:
  1327.     mvi    a,eof
  1328.     ora    a
  1329.     ret
  1330. ;
  1331. ;            ;Get input word (lo/hi, unencoded)
  1332. getw:    call    getc
  1333.     jnz    badr        ;Unexpected eof
  1334.     push    psw
  1335.     call    getc
  1336.     jnz    badr        ;Unexpected eof
  1337.     mov    h,a
  1338.     pop    psw
  1339.     mov    l,a
  1340.     ret
  1341. ;
  1342. erext:
  1343. badr:    call    CDISP
  1344.     db    cr,lf,'Unexpected EOF on squeezed file',cr,lf,0
  1345.     jmp    EXIT
  1346. ;
  1347. ;            Get single (unencoded) char
  1348. getc:    lhld    inbufu
  1349.     xchg
  1350.     lhld    inbufs
  1351.     call    cmphlde        ;End of input buffer?
  1352.     jz    getrf        ;Yes
  1353. getc1:
  1354.     mov    a,m        ;No get next byte
  1355.     inx    h
  1356.     shld    inbufs        ;Save addr of next byte
  1357.     cmp    a
  1358.     ret
  1359. ;
  1360. ;            Refill input buffer
  1361. ;
  1362. getrf:
  1363.     lda    SQEOF        ;Is there anything else?
  1364.     ora    a
  1365.     jz    getok
  1366.     call    CDISP
  1367.     db    cr,lf,'Read past EOF on SQ file',cr,lf,0
  1368.     jmp    EXIT
  1369. getok:
  1370.     lhld    SECCNT        ;Save sector count (decoded buffer only)
  1371.     push    h
  1372.     lxi    h,SQBUF        ;Set input buffer as empty,
  1373.     shld    inbufs        ;_and start of buffer
  1374.     xchg            ;DE> buffer, next sector locn
  1375.     lhld    SQBUFE        ;End of input buffer
  1376.     shld    inbufu        ;Assume no end of file for now
  1377.     mov    a,l
  1378.     sub    e
  1379.     mov    l,a
  1380.     mov    a,h
  1381.     sbb    d        ;Calc buffer size
  1382.     mov    h,a
  1383.     dad    h        ;Convert to no of sectors
  1384.     mov    b,h        ;No of sectors to read
  1385. ;                # sectors limited to 100 max (<B>=0)
  1386.     lhld    FCBCRR        ;No of 1st sector to read
  1387.     shld    SQBSC1
  1388.     call    FILBU1        ;Read sector into SQBUF
  1389. ;                <B> no of sectors not read if eof
  1390. ;                HL> 128
  1391. ;                DE> last sector read, or after if eof
  1392.     lhld    FCBCRR        ;Get next SQ sector no
  1393.     shld    NXTSQS
  1394.     mov    a,b        ;Did we fill buffer?
  1395.     ora    a
  1396.     jz    getrf2        ;yes - no eof
  1397.     xchg            ;Eof, adjust buffer end marker
  1398.     shld    inbufu        ;Mark end of buffer used
  1399.     sta    SQEOF        ;& flag eof
  1400. ;
  1401. ;            Input buffer re-filled
  1402. getrf2:
  1403.     pop    h
  1404.     shld    SECCNT        ;Restore sector count (decoded buffer only)
  1405.     lhld    inbufu        ;Get end of buffer
  1406.     xchg
  1407.     lhld    inbufs        ;Get start of buffer
  1408.     call    cmphlde        ;Something there?
  1409.     jc    getc1        ;Yes - go for char
  1410.     jmp    erext        ;No - read past eof or empty file
  1411. ;
  1412. ;end of baseline USQ code
  1413. ;
  1414. otbufe:    dw    0        ;End of decoded char buffer
  1415. inbufs:    dw    0        ;Start of input buffer
  1416. inbufu:    dw    0        ;End of used part input buffer
  1417. SQBUFE:    dw    0        ;End of input buffer
  1418. ;
  1419. nxtadr:    dw    DSKBUF        ;Next byte in output buffer 
  1420.                 ; also used when loading tree
  1421. bitlft:    ds    1        ;No of bits left in bit buffer
  1422. rcnt:    ds    1        ;Run count remaining (DLE)
  1423. filchks:ds    2        ;Checksum read from file
  1424. last:    ds    1        ;Last reg char decoded
  1425. bitbuf:    ds    1        ;Latest 8 bits (encoded) from input file
  1426. numvals:ds    2        ;No of nodes in encodng tree
  1427. ;
  1428.     ENDIF
  1429. ;
  1430. ;    Memory allocation
  1431. ;
  1432. SECCNT:    DW    0        ;number of sectors read into buffer
  1433. LINMAX:    DB    SCROLN        ;number of to write lines on console
  1434. CHRMAX:    DB    MAXCHR-1    ;number of characters to display per line
  1435. CHRMIN:    DB    0        ;character to start displaying on line
  1436. CHRCNT:    DS    1        ;character number in line
  1437. LINCNT:    DS    1        ;line number on write or move back in buffer
  1438. TOPBUF:    DB    0        ;Top of file is now in buffer
  1439. ;                 Z - yes, NZ - no
  1440. ;
  1441.     IF    SQUEEZE
  1442. ;
  1443. NXTSEC:    DW    0        ;Next (unsqueezed) sector not yet in BSKBUF
  1444. ;                 set (and used) only by FILSQ
  1445. SQFLG:    DB    0        ;File is squeezed
  1446. SQEOF:    DB    0        ;End of file on squeezed file
  1447. SQREWD:    DB    0        ;Flag the SQ input file is being re-read
  1448. ;                 buffer refill rtn (getrf) to set inbufs
  1449. ;                 as per offset in SQBYT, and pre-load
  1450. ;                 bit buffer. Bit buffer to be adj
  1451. ;                 as per Bitlft
  1452. SQBYT:    DW    0        ;Offset of first data byte in SQ buffer
  1453. SQBSC1:    DW    0        ;No of 1st sector in SQ buffer
  1454. NXTSQS:    DW    0        ;No of last sector in SQ buffer
  1455. ;
  1456.     ENDIF
  1457. ;
  1458.     DS    60        ;stack area
  1459. STACK:    DS    2        ;old stack saved here
  1460. DSKBUF:    EQU    $        ;disk buffer area above the program
  1461. ;
  1462. ENDBUF    EQU    DSKBUF+MAXSEC*128
  1463. ;
  1464.     IF    SQUEEZE
  1465. ;
  1466. SQTREE    EQU    ENDBUF        ;Space for SQ decoding tree
  1467. SQMAP    EQU    SQTREE+257*3
  1468. ;                Space for SQ buffer mapping table
  1469. ;                contains sq sect #, sq byte & bit offset
  1470. ;                for every time DSKBUF was filled
  1471. ;                1st entry contains index to latest mapping
  1472. ;                triplet
  1473. ;                To handle run compr straddling buffer end,
  1474. ;                should also store rcnt & last 
  1475. SQBUF    EQU    SQMAP+100*4    ;(allows for 100 8k buffers)
  1476. ;                Input (squeezed) buffer
  1477. ;                Runs up to top of free mem 
  1478.     ENDIF
  1479. ;
  1480.     END    TPA
  1481.