home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / compress / ql40.arc / QL.001 < prev    next >
Text File  |  1991-08-11  |  54KB  |  2,463 lines

  1. ;.......................
  2. ;
  3. ; QL v4.0   14 August 1988
  4. ;
  5. QLVERS    EQU    40        ; <=== version #, keep up to date!
  6.  
  7. ;==============================================================================
  8. ;
  9. ; Ascii equates
  10. ;
  11. NULL    EQU    0
  12. CTRLC    EQU    'C'-40H
  13. CTRLK    EQU    'K'-40H
  14. CTRLX    EQU    'X'-40H
  15. BELL    EQU    7
  16. BS    EQU    8
  17. TAB    EQU    9
  18. LF    EQU    10
  19. FF    EQU    12
  20. CR    EQU    13
  21. EOF    EQU    1AH
  22. ESC    EQU    1BH
  23.  
  24. ;==============================================================================
  25. ;
  26. ; BDOS function equates
  27. ;
  28. CONOUT    EQU    2        ; Console Output
  29. DIRIO    EQU    6        ; Direct Console I/O
  30. RDBUFF    EQU    10        ; Console Read String
  31. OPEN    EQU    15        ; File Open
  32. CLOSE    EQU    16        ; File Close
  33. SRCH1ST    EQU    17        ; Search 1st
  34. SRCHNXT    EQU    18        ; Search Next
  35. ERASE    EQU    19        ; File Erase
  36. READSEQ    EQU    20        ; File Read  [Sequential]
  37. WRITSEQ    EQU    21        ; File Write [Sequential]
  38. CREAT    EQU    22        ; File Create
  39. GETDSK    EQU    25        ; Get Current Disk
  40. SETDMA    EQU    26        ; Set Direct Memory Address
  41. SGUSER    EQU    32        ; Set/Get User
  42. RANDOM    EQU    33        ; File Read [Random]
  43.  
  44. ;==============================================================================
  45. ;
  46. ; Page zero equates
  47. ;
  48. BDOSEV    EQU    0005        ; BDOS Entry Vector
  49. FCB1    EQU    005CH        ; File Control Block 1
  50. FCB1FN    EQU    FCB1+01        ; FCB1 Filename
  51. FCB1EXT    EQU    FCB1+09        ; FCB1 Extension
  52. FCB1R0    EQU    FCB1+21H    ; Rec number for sizing & lbr random access
  53. FCB1R2    EQU    FCB1+23H    ; 0'd before random read
  54.  
  55. ;==============================================================================
  56. ;
  57. ; Derived Equates
  58. ;
  59.      IF    M80        ; Non-syntax specific implementation of
  60. Z1    EQU    FALSE        ; - mutual exclusion
  61.      ELSE
  62. Z1    EQU    TRUE
  63.      ENDIF
  64.  
  65.      IF    Z1
  66.     NLIST    S        ; No source listing
  67.     LIST    C        ; Gen com file directly
  68.      ENDIF
  69.  
  70.      IF    Z1
  71. CTRLDUMMY EQU    .NOT.(CTRLWORDSTAR.OR.CTRLDIMVID)
  72.      ELSE
  73. CTRLDUMMY EQU    NOT (CTRLWORDSTAR OR CTRLDIMVID)
  74.      ENDIF
  75.  
  76. ;==============================================================================
  77. ;
  78. ; "assumed equates"
  79. ;
  80. ; Adjustable screen height and width is only partially implemented in the
  81. ; current version, so for now these should remain at 24 and 80 respectively.
  82. ;
  83. LINES    EQU    24        ; Terminal console lines.
  84. COLUMNS    EQU    80        ; Terminal console columns.
  85.  
  86. ;==============================================================================
  87. ;
  88.      IF    ZCPR3
  89.     CSEG
  90.      ELSE
  91.     ASEG
  92.     ORG    100H
  93.      ENDIF
  94. ;.....
  95. ;
  96.      IF    ZCPR3
  97.     PUBLIC    $MEMRY
  98.     EXTRN    Z3VINIT,TINIT,DINIT
  99.     EXTRN    CLS,STNDOUT,STNDEND
  100.     EXTRN    Z3LOG,GETWHL,GETSPEED,GETCRT,GETVID
  101.     EXTRN    COUT,GETUD,PUTUD
  102.     EXTRN    RETUD,LOGUD
  103.      ENDIF
  104.  
  105. ; set the number of lines we can display (don't change)
  106.  
  107. DISPLY    EQU    LINES-LINEOVERLAP-1 ; Display page size = 23
  108. NL    EQU    LINES-6
  109.  
  110. ;=====================================================================
  111. ;    Entry Point
  112. ;=====================================================================
  113.  
  114. QL:    JP    MAIN        ; <=== entry
  115.  
  116.      IF    ZCPR3
  117.     DB    'Z3ENV',1
  118. Z3EADR:    DW    0
  119.      ENDIF
  120. ;..............................................................................
  121. ;
  122. ; embedded copyright message simplified & moved near beginning (for dump)
  123. ; since it is no longer displayed at runtime
  124.  
  125.     DB    'by Nick Dobrinich and Ross Presser '
  126.     DB    'Sections Copyright (c) 1986 '
  127.     DB    'Steven Greenberg and C.B. Falconer '
  128.     DB    'May be reproduced for non-profit use only.'
  129.  
  130. SIGNON:    CALL    MSG
  131.  
  132.     DB    'QL v',QLVERS/10+'0','.'
  133.     DB    (QLVERS-((QLVERS/10)*10))+'0'
  134.  
  135.      IF    ZCPR3        ;
  136.     DB    ' /Z3'        ;
  137.      ENDIF            ;
  138.  
  139.     DB    '  14 August 1988'
  140.  
  141.     DB    CR,LF,LF
  142.     DB    '  --- While viewing ---           --- Toggle Commands ---',CR,LF
  143.     DB    CR,LF
  144.     DB    '<cr>    Forward one page          A   Display ASCII / HEX:  '
  145. ASTATE:    DB    'ASCII',CR,LF
  146.     DB    '<sp>    Forward one line          T   Truncate long lines:    '
  147. TSTATE:    DB    'YES',CR,LF
  148.     DB    '<##>    Go to any page ##         C   Case sensitive find:    '
  149. CSTATE:    DB    ' NO',CR,LF
  150.     DB    ' B      Backward one page',CR,LF
  151.     DB    ' H      Home (Top of file)',CR,LF
  152.     DB    ' E      End  (Bot of file)',CR,LF,LF
  153. ;;
  154.     DB    ' F      Find text or hex byte',CR,LF
  155.     DB    ' R      Repeat find',CR,LF
  156.     DB    ' X      Exit viewing',CR,LF,LF,0
  157.     RET
  158.  
  159. REQCMD:    CALL    MSG
  160.     DB    CR,LF,LF,'Command, or <ret> to resume Viewing: ',0
  161.     RET
  162.  
  163. ;=====================================================================
  164. ;    Main Program
  165. ;=====================================================================
  166.  
  167. MAIN:
  168.     LD    (OLDSP),SP    ; Save old sp if no warm boot needed
  169.     LD    SP,STACK    ; Set up local stack
  170. ;................................
  171.                 ;
  172.      IF    ZCPR3        ; ZCPR3 initialization stuff
  173.     LD    HL,(Z3EADR)    ;
  174.     CALL    Z3VINIT        ;
  175.     CALL    TINIT        ;
  176.     CALL    GETCRT        ;
  177.     INC    HL        ;
  178.     INC    HL        ;
  179.     LD    A,(HL)        ; Get #of lines on CRT
  180.     LD    (NLINES),A    ; Keep that there
  181.     SUB    LINEOVERLAP+1    ;
  182.     LD    (DISPLAY),A    ; # of lines per screen
  183.     CALL    PUTUD        ; Save orig DU for exit
  184.     CALL    RETUD        ; Get orig logged DU
  185.     LD    (DEFDU),BC    ; Save that here
  186.     LD    DE,FCB1        ; Log to the file spec'd on the cmnd line
  187.     CALL    Z3LOG        ;
  188.     CALL    RETUD        ; Get the filenames DU
  189.     LD    (LBRDU),BC    ; And save that here..
  190.     LD    HL,($MEMRY)    ; Get addr of free memory
  191. ;...............................;
  192.  
  193. ;................................
  194.                 ; French vanilla CP/M
  195.      ELSE            ;
  196.     ld    A,LINES        ;
  197.     ld    (NLINES),a    ; Init screen size
  198.     LD    A,DISPLY    ;
  199.     LD    (DISPLAY),A    ; Init lines/pg-1
  200.     LD    C,GETDSK    ;
  201.     CALL    BDOSEV        ;
  202.     LD    (DEFDU+1),A    ; Keep default drive here ( 0 = "A")
  203.     LD    (LBRDU+1),A    ; Assume that the spec'd filename is same
  204.     LD    A,(FCB1+0)    ; Get the filename's drive spec
  205.     OR    A        ;
  206.     JR    Z,ISSAME    ; If zero, it is indeed the same
  207.     DEC    A        ; Else reduce the fcb+0 value so "A = 0"
  208.     LD    (LBRDU+1),A    ; And use that
  209.                 ;
  210. ISSAME:    LD    C,SGUSER    ; Now for user area stuff. For the regular
  211.     LD    E,0FFH        ; - CP / M version there is only one user#
  212.     CALL    BDOSEV        ;
  213.     LD    (DEFDU+0),A    ; So keep default user here (for display)
  214.     LD    (LBRDU+0),A    ; And a copy here as well
  215.     LD    HL,ENDPROG    ; Get addr of free memory
  216.      ENDIF            ;
  217. ;...............................;
  218.  
  219. ;................................
  220.                 ; New dynamic memory allocation.
  221.     LD    (@PTRTBL),HL    ; Assign beg of free memory to 1k "PTRTBL"
  222.     LD    DE,1024        ;
  223.     ADD    HL,DE        ;
  224.     LD    (@BUFFER),HL    ; And everything above that to "BUFFER"
  225. ;...............................;
  226.  
  227.     CALL    INI1MEM        ; Init all memory from "init1" - "end1init"
  228.     CALL    INI2MEM        ; Init all memory from "init2" - "end2init"
  229.                 ; (also initializes "ptrtbl")
  230.  
  231.     LD    A,40        ; Init Console String Buffer
  232.     LD    (STRMAX),A    ;
  233.  
  234.      IF    USEBIOSCONOUT    ; Using faster BIOS rtn
  235.     LD    HL,(1)        ; BIOS + 3 warm start ep
  236.     LD    DE,9        ; Bias to BIOS conout jp
  237.     ADD    HL,DE
  238.     LD    (BIOSCONOUT),HL    ; Save adr for fast putc
  239.      ENDIF
  240.  
  241.     LD    HL,(@BUFFER)    ; **
  242.     LD    (BUFPTR),HL    ; Set buffer ptr
  243.     XOR    A        ; Zero a
  244.     LD    (FRSTFL),A    ;
  245.     LD    (FCB1R2),A    ; For random reads
  246. ;..............................................................................
  247. ;
  248. ; Check for existence of BYE5.
  249. ; Note that "remote operation" is assumed if BYE is detected.
  250. ;
  251.     LD    C,SGUSER    ; BDOS set/get user call
  252.     LD    E,0FFH        ; First get current value
  253.     CALL    BDOSEV        ;
  254.     PUSH    AF        ; Save current value
  255.                 ;
  256.     LD    C,SGUSER    ; BDOS set/get user call
  257.     LD    E,241        ; Magic number to see if bye is resident
  258.     CALL    BDOSEV        ; Look for special result from "set/get" user
  259.     CP    77        ; Magic return # if BYE is there
  260.     JR    NZ,NOBYE    ; Nope..
  261.     LD    HL,-0800H    ; Flag "BYE5" as resident by puttin -800h here
  262.     LD    (BYE5FLAG),HL    ; (otherwise is zero from init above)
  263.                 ;
  264. NOBYE:    POP    AF        ; Get orig user # back
  265.     LD    C,SGUSER    ; BDOS set/get user call
  266.     LD    E,A        ; Put user# in E
  267.     CALL    BDOSEV        ;
  268.  
  269. ;..............................................................................
  270. ;
  271.     CALL    CHKSUMCCP    ; Do simple chksum of CCP for quit
  272.     LD    (CCPCHKSUM),A
  273.  
  274. ; Do all calculations relating to available Memory right here...
  275.  
  276.     LD    HL,(BDOSEV+1)    ; Get BDOS base
  277.     LD    DE,(BYE5FLAG)    ; (-2k) if CCP to be saved, else zero
  278.     ADD    HL,DE        ; Add, ie subtract, that
  279.     LD    (BDOSBASE),HL    ; Take future requests for (BDOS+1) from here
  280.  
  281. ; open the file if one given
  282. ; try open 1st with given name, then as .lbr
  283. ;................................
  284.                 ;
  285.     LD    HL,FCB1FN    ; See if command tail is blank
  286.     LD    A,'/'        ; Chk for help invocation
  287.     CP    (HL)        ;
  288.     JP    Z,USAGE        ;
  289.     LD    A,' '        ;
  290.     CP    (HL)        ;
  291.     JR    NZ,SOMETH    ; Br if something was specified
  292.     LD    B,11        ; Else convert to *.*
  293.                 ;
  294. QUESLP:    LD    (HL),'?'    ;
  295.     INC    HL        ;
  296.     DJNZ    QUESLP        ;
  297.     JR    SWPAMBIG    ; Go "sweep" all matching filenames
  298. ;...............................;
  299.  
  300. ; check if ambig file specified
  301.  
  302. SOMETH:    LD    BC,11        ; Length (HL already set)
  303.     LD    A,'?'        ; Find a ?
  304.     CPIR            ; Search
  305.     JR    Z,SWPAMBIG    ; If ambiguous, sweep 'em
  306.  
  307. ;..............................................................................
  308. ;
  309. OPENSOMEFILE:            ;
  310.     LD    HL,FCB1FN    ; Src
  311.     LD    DE,FNEXT    ; Dst
  312.     LD    BC,11        ; Len
  313.     LDIR            ; Copy filename.ext
  314.  
  315.     LD    C,OPEN
  316.     CALL    BDOSCALL    ; Open file
  317.     JP    P,OPENOK    ; Open ok >= 0
  318.     LD    A,(LIBRARY)
  319.     OR    A        ;
  320.     JR    NZ,NONE        ; Error, couldn't find reg or lbr w/ that name
  321.  
  322. ; see if there's a lbr by same name to get member listing
  323.  
  324. OPENLIB:
  325.     LD    A,0FFH
  326.     LD    (LIBRARY),A    ; Library flag
  327.     LD    HL,FCB1EXT
  328.     LD    (HL),'L'    ; Add 'lbr' extension
  329.     INC    HL
  330.     LD    (HL),'B'
  331.     INC    HL
  332.     LD    (HL),'R'
  333.  
  334. ; now try to open the library
  335.  
  336.     JR    OPENSOMEFILE
  337.  
  338. ;..............................................................................
  339. ;
  340. ; The routines to handle ambigous file specifications follow (ie arrive
  341. ;  here if at least one ? in filename).
  342. ;
  343. ; Note: In this case an LBR will always be opened as a library.
  344. ;  In the less than likely event the user wants to examine the guts
  345. ;  of an LBR file, he may still do so by typing the full command line, eg.
  346. ;  "QL FILE.LBR" - but "QL FILE" or "QL *.LBR" or almost anything else
  347. ;  will treat LBR files as libraries).
  348.  
  349. ; We accumulate filenames at the start of the buffer, resetting BUFPTR
  350. ; and ask the user to choose one. After selection, we open the file as
  351. ; if it had been fully specified.
  352.  
  353. ; After the user is finished with the file (or entire library if an LBR),
  354. ; QLEXIT returns to SWEEP, so he can examine another one.  The filenames
  355. ; are protected by the resetting of BUFPTR.
  356.  
  357. ; first preserve ambiguous filename
  358.  
  359. SWPAMBIG:
  360.     LD    DE,(BUFPTR)    ; Dest for fnames
  361.     LD    (FILPTR),DE    ; Save as start of fname table
  362.     LD    HL,FCB1FN    ; Src
  363.     LD    BC,11        ; Len
  364.     LDIR
  365.     PUSH    DE        ; Save ptr
  366.  
  367.     LD    DE,80H        ; Set default DMA
  368.     LD    C,SETDMA
  369.     CALL    BDOSCALL
  370.  
  371.     LD    C,SRCH1ST    ; Search for first
  372.     CALL    BDOSCALL
  373.     INC    A        ; A match found?
  374.     JR    NZ,SWP1        ; Yep
  375.  
  376. NONE:    CALL    MSG        ; Display error msg
  377.     DB    CR,LF,'++ No matching files found ++',CR,LF,0
  378.     JR    USAGE
  379. ;..............................................................................
  380. ;
  381. SWP1:    LD    IX,0        ; Matches
  382.     POP    DE        ; Dest for fnames
  383.  
  384. SWPLP:    DEC    A        ; Un-INC
  385.     ADD    A,A        ; A<<5
  386.     ADD    A,A
  387.     ADD    A,A
  388.     ADD    A,A
  389.     ADD    A,A
  390.     ADD    A,81H        ; +DMA points to fn
  391.     LD    L,A        ; Move to HL
  392.     LD    H,0
  393.  
  394. ;................................
  395.                 ; System security stuff
  396.     PUSH    HL        ; WHLCHK destroys (not any more!)
  397.     CALL    WHLCHK        ;
  398.     JR    NZ,SWPOK    ; If wheel is set, it's ok
  399.     LD    A,L        ; Else check SYS attr
  400.     ADD    A,9        ;
  401.     LD    L,A        ;
  402.     BIT    7,(HL)        ;
  403.     JR    NZ,SWPNXT    ; If set, pretend it wasn't found
  404.     DEC    HL        ; Next check if online COM file
  405.     LD    A,(HL)        ;
  406.     AND    7FH        ;
  407.     CP    'C'        ;
  408.     JR    NZ,SWPOK    ;
  409.     INC    HL        ;
  410.     LD    A,(HL)        ;
  411.     CP    'O'        ; (we know SYS is not set)
  412.     JR    NZ,SWPOK    ;
  413.     INC    HL        ;
  414.     LD    A,(HL)        ;
  415.     AND    7FH        ;
  416.     CP    'M'        ;
  417.     JR    Z,SWPNXT    ; If so, pretend it wasn't found
  418.  
  419. ;.....
  420. ;                ; File is good, use it
  421. SWPOK:    POP    HL        ; Source
  422.     LD    B,11        ; Chars in filename
  423.  
  424. LDIRLP:    LD    A,(HL)        ; Move it - strip any hi-bits
  425.     AND    7FH        ; (can't use LDIR, oh well...)
  426.     LD    (DE),A        ;
  427.     INC    HL        ;
  428.     INC    DE        ;
  429.     DJNZ    LDIRLP        ;
  430.  
  431.  
  432.     INC    IX        ; Count it
  433.     JR    SWPNX2        ; (don't pop HL again)
  434. ;.....
  435. ;                ; File is not authorized, go onto next
  436. SWPNXT:    POP    HL        ; Make sure HL gets popped anyway
  437. SWPNX2:    LD    C,SRCHNXT    ; Search for next
  438.     CALL    BDOSCALL
  439.     INC    A        ; Match?
  440.     JR    NZ,SWPLP    ; Yes, go get it
  441.  
  442.     PUSH    IX        ; Get count in HL
  443.     POP    HL
  444.     LD    A,H        ; >255 files?
  445.     OR    A        ; Better be zero!
  446.     JR    Z,SWP2        ;
  447.  
  448.     CALL    MSG        ; Display error msg
  449.     DB    CR,LF,'++ Error: Too many matching files ++',0
  450. USAGE:    CALL    MSG
  451.     DB    CR,LF,LF,' Usage:  QL <afn>'
  452.     DB    CR,LF
  453.     DB    ' where <afn> should not match more than 255 files.'
  454.     DB    CR,LF,LF,0
  455.     JP    QLEXIT        ; Exit
  456.  
  457. SWP2:
  458.     LD    A,L        ; Get file cnt
  459.     OR    A        ; Zero files?
  460.     JP    Z,NONE        ; Err msg & exit
  461.  
  462.     LD    (FILCNT),A    ; Save it
  463.     LD    (BUFPTR),DE    ; Protect filenames
  464.  
  465. ; If there was only one file, don't sweep
  466.  
  467.     LD    A,(FILCNT)    ; Only 1 file?
  468.     DEC    A
  469.     JR    NZ,SORTEM    ; If not, sort them alphabetically
  470.     LD    B,1        ; If so...
  471.     JP    LOOKUP        ; Go get it
  472.  
  473. SORTEM:    CALL    SORT        ; Sort the files into alphabetical order
  474.  
  475. ;.....
  476. ;
  477. ; Arrive here when ready to choose next file to view.
  478. ;
  479. SWEEP:    XOR    A
  480.     LD    HL,FCB1FN    ; Reset entire fcb except drive code
  481.     LD    DE,FCB1FN+1
  482.     LD    BC,34
  483.     LD    (HL),A
  484.     LDIR
  485.  
  486.     CALL    INI2MEM        ; Init all memory from "init2" to "end2init"
  487.                 ; (also initializes "ptrtbl")
  488.  
  489.     CALL    DFNS        ; Display 'Files Matching: DU <afn>'
  490.  
  491.     XOR    A        ;
  492.     LD    (SCRNUM),A    ; Init "screen#" to zero (goes, 0,72,144..)
  493.  
  494. NSCR:    LD    A,(FILCNT)    ; Count of files
  495.     LD    (HIPG),A    ; Set hipg so can deduce when enuf
  496.     INC    A        ; Count +1
  497.     LD    D,A        ; Max #of files +1 goes into D
  498.  
  499.     LD    E,1        ; E is line#, (init to 1)
  500.  
  501. ;................................
  502.                 ;
  503. LINLP:    LD    B,4        ; Outer loop for NL lines
  504.     LD    A,(SCRNUM)    ;
  505.     ADD    A,E        ; 1st file# in each line = line# + scrn#
  506.     LD    C,A        ;
  507. ;................................
  508.                 ; Inner loop, 4/line
  509. LP4:    LD    A,C        ; File#
  510.     CP    D        ; Compare to max
  511.     JR    NC,OUT4        ; If greater, done w/ this line
  512.     CALL    C11HL        ; Convert file # in c to pointer to name in HL
  513.     CALL    PRNUMFN        ; Print xxx:filename.ext
  514.     LD    A,C        ;
  515.     ADD    A,NL        ; Next file, if any, is prev# plus NL
  516.     LD    C,A        ;
  517.     DJNZ    LP4        ;
  518. ;...............................;
  519.  
  520. OUT4:    CALL    CRLF        ;
  521.     LD    A,E        ; Advance to next line
  522.     INC    A        ;
  523.     LD    E,A        ;
  524.     CP    NL+1        ;
  525.     JR    C,LINLP        ;
  526. ;...............................;
  527.  
  528.     LD    A,(SCRNUM)    ;
  529.     ADD    A,72        ;
  530.     JR    NC,NOVF72    ;
  531.     LD    A,255        ;
  532. NOVF72:    LD    (SCRNUM),A    ;
  533.     LD    C,A        ;
  534.     CP    D        ;
  535.     JR    NC,CHOOSE    ;
  536.     CALL    MSG        ;
  537.     DB    CR,LF,'File number or <ret> for more selections: ',0
  538.  
  539.     XOR    A        ; "duplicate code starts here (subr?)
  540.     LD    (JUMPTO),A    ; Init jumpto for get
  541.     CALL    GETCHNUM    ; Get user member choice
  542.  
  543.     LD    C,A        ;
  544.     LD    A,(JUMPTO)    ; Did he enter a number?
  545.     OR    A        ;
  546.     JP    NZ,CHKFIL    ; Go check it
  547.  
  548.     LD    A,C        ;
  549.     CP    CR        ;
  550.     JR    Z,NXTSCR    ;
  551.  
  552.     CALL    CHEXIT        ; ^C or ^K will exit direct to CP/M
  553.     JP    Z,QLEXIT    ; Other 'exit' type characters
  554.  
  555. NXTSCR:    CALL    DFNS        ; Else continue with next screen
  556.     JP    NSCR        ;
  557.  
  558. ;................................
  559.                 ;
  560. C11HL:    PUSH    DE        ; Save for caller
  561.     LD    H,0        ;
  562.     LD    L,C        ;
  563.     PUSH    HL        ; Temp save '1x' value
  564.     ADD    HL,HL        ; 2x val
  565.     ADD    HL,HL        ; 4x val
  566.     PUSH    HL        ; Save temporarily
  567.     ADD    HL,HL        ; 8x value
  568.     POP    DE        ; Pop 4x val into de...
  569.     ADD    HL,DE        ; Now have 12x
  570.     POP    DE        ; Get back 1x
  571.     SBC    HL,DE        ; (carry certainly clear from prev addition)
  572.     LD    DE,(FILPTR)    ; Offset to beg of filenames (indirect)
  573.     ADD    HL,DE        ;
  574.     POP    DE        ; Restore caller's DE
  575.     RET            ; Return pointer to filename
  576. ;...............................;
  577.  
  578. ;.....
  579. ;
  580. ; Let user choose his selection
  581. ;
  582. CHOOSE:    CALL    OFFHALF        ;
  583.     CALL    MSG
  584.     DB    CR,LF,'Select file (1-',0
  585.     LD    A,(FILCNT)    ; Get count
  586.     LD    (HIPG),A    ; Set hipg so can deduce when enuf
  587.     LD    L,A
  588.     LD    H,0
  589.     CALL    B2DEC
  590.     CALL    MSG
  591.     DB    '),',0
  592.     CALL    WHLCHK
  593.     JR    Z,SKPDMP
  594.     LD    A,(FRSTFL)
  595.     OR    A
  596.     JR    NZ,SKPDMP
  597.     CALL    MSG
  598.     DB    ' <D>ump memory,',0
  599. SKPDMP:    CALL    MSG
  600.     DB    ' or <ret> to exit: ',0
  601.  
  602. BADCHAR:
  603.     XOR    A
  604.     LD    (JUMPTO),A    ; Init jumpto for get
  605.     CALL    GETCHNUM    ; Get user member choice
  606.  
  607.     LD    C,A        ;
  608.     LD    A,(JUMPTO)    ; Did he enter a number?
  609.     OR    A        ;
  610.     JR    NZ,CHKFIL    ; Go check it
  611.  
  612.     LD    A,C        ;
  613.     CALL    UCASE        ; Possibly upcase his character response
  614.     LD    C,A        ;
  615.  
  616.     CALL    WHLCHK        ; (kills A)
  617.     JR    Z,SKPD2        ;
  618.     LD    A,(FRSTFL)    ;
  619.     OR    A        ;
  620.     JR    NZ,SKPD2    ;
  621.     LD    A,C        ;
  622.     CP    'D'        ;
  623.     JR    Z,COREDM    ; Go do a memory dump
  624.  
  625. SKPD2:    LD    A,C        ;
  626.     CALL    CHEXIT        ; ^C or ^K will exit direct to CP/M
  627.     JP    Z,QLEXIT    ; Other 'exit' type characters
  628.     JR    BADCHAR        ;
  629.  
  630. ;..............................................................................
  631. ;
  632. ; Chk for file # too big
  633. ;
  634. CHKFIL:    LD    B,A        ; B = jumpto
  635.     LD    A,(FILCNT)
  636.     CP    B        ; Cy if filcnt < jumpto
  637.     JP    C,SWEEP        ; Display files again
  638.  
  639.     CALL    CRLF
  640.     XOR    A
  641.     LD    (JUMPTO),A    ; Rst jumpto
  642.     DEC    A
  643.     LD    (SWEEPING),A    ; Set sweeping flag
  644.     LD    (FRSTFL),A    ;
  645.  
  646. ; Lookup member number
  647.  
  648. LOOKUP:    LD    L,B        ; Move jumpto to HL
  649.     LD    H,0
  650.     PUSH    HL        ; Save *1
  651.     ADD    HL,HL
  652.     PUSH    HL        ; Save *2
  653.     ADD    HL,HL
  654.     ADD    HL,HL        ; HL=*8
  655.     POP    DE        ; Rst *2
  656.     ADD    HL,DE        ; HL=*10
  657.     POP    DE        ; Rst *1
  658.     ADD    HL,DE        ; HL=*11
  659.     LD    DE,(FILPTR)    ; Start of file table
  660.     ADD    HL,DE        ; *hl = selected file
  661.  
  662.     LD    DE,FCB1FN    ; Dest
  663.     LD    BC,11        ; Length
  664.     LDIR
  665.  
  666.                 ;
  667.     CALL    ISLBR        ; If LBR, open as one, else don't
  668.     JP    NZ,OPENSOMEFILE    ;
  669.     JP    OPENLIB        ;
  670.  
  671. ; Subrtn to check if FCB1 extension matches "LBR"
  672. ; destroys A,HL  -- Z set if match
  673.  
  674. ISLBR:    LD    HL,FCB1EXT    ; See if FCB1EXT is 'LBR'
  675.     LD    A,(HL)
  676.     AND    7FH
  677.     CP    'L'
  678.     RET    NZ
  679.     INC    HL
  680.     LD    A,(HL)
  681.     AND    7FH
  682.     CP    'B'
  683.     RET    NZ
  684.     INC    HL
  685.     LD    A,(HL)
  686.     AND    7FH
  687.     CP    'R'
  688.     RET
  689.  
  690. ;=============================================================================
  691. ;
  692. ; Come here if a "core dump" was requested
  693. ;
  694. COREDM:    LD    A,0FFH        ; 0ffh
  695.     LD    (CORE),A    ; Set flag
  696.     LD    (HIPG),A    ;
  697.     LD    HL,0FFFFH    ; Of all of memory
  698.     LD    (EOFADR),HL
  699.     LD    (FILELEN),HL
  700.     XOR    A
  701.     LD    (PAGE),A    ; Set init pg 0
  702.     LD    (AFLAG),A    ; Allow hex/ascii disp only
  703.     CALL    TOGLA        ; (flip from 0 [ascii] to ff [hex])
  704.     LD    HL,(@PTRTBL)    ;
  705.     INC    HL        ;
  706.     XOR    A        ;
  707.     LD    B,A        ; 256 pgs
  708.  
  709. SETMEMPP:
  710.     LD    (HL),A
  711.     INC    A
  712.     INC    HL
  713.     INC    HL
  714.     DJNZ    SETMEMPP
  715.     JP    PRPG        ; Display hex/ascii of pg 0
  716.  
  717. ;=============================================================================
  718. ;
  719. ; compute simple 1 byte chksum of entire CCP
  720. ; ret in a
  721. ;
  722. CHKSUMCCP:
  723.     LD    HL,(6)
  724.     LD    DE,CCPSIZE+6    ; Size of CCP
  725.     XOR    A        ;
  726.     SBC    HL,DE        ; *CCP
  727.     LD    BC,CCPSIZE    ; Chksum entire CCP
  728.  
  729. CHK1SUM:
  730.     ADD    A,(HL)
  731.     CPI            ; HL++,BC--
  732.     RET    PO        ; Chksum in A
  733.     JR    CHK1SUM
  734.  
  735. ILLEGAL:
  736.     CALL    MSG        ; Display error and exit
  737.     DB    CR,LF,'++ Can''t display that ++',CR,LF,0
  738.  
  739. QLEXIT:
  740.     LD    SP,STACK    ; Stack may be questionable upon arrival here
  741.  
  742.      IF    ZCPR3
  743.     CALL    GETVID
  744.     CALL    NZ,DINIT
  745.     CALL    GETUD
  746.      ENDIF
  747.  
  748.     LD    A,(PUTCABRT)    ; Did we abort from PUTC?
  749.     OR    A
  750.     JR    NZ,QLOUT    ; Yep, don't re-sweep
  751.  
  752.     LD    A,(SWEEPING)    ; If in sweep mode, return to sweeper
  753.     OR    A        ;
  754.     JR    Z,QLOUT        ; If not
  755.     JP    SWEEP        ; And return to 'sweeper'
  756.  
  757. QLOUT:    CALL    CRLF
  758.     CALL    CHKSUMCCP
  759.     LD    B,A        ; Ccp chksum now
  760.     LD    A,(CCPCHKSUM)    ; Orig CCP chksum
  761.     XOR    B
  762.     JP    NZ,0        ; Warm boot if CCP was overlaid
  763.     LD    SP,(OLDSP)    ; Else just ret to CCP
  764.     RET
  765.  
  766. ;-----------------------------------------------------------------------------
  767. ;
  768. QUIT:
  769. QUITNOSUM:
  770.     LD    SP,STACK    ; Extracting may foul stack
  771.     LD    A,(LIBRARY)
  772.     OR    A        ; Working with lbr?
  773.     JR    Z,QLEXIT    ; No lbr, so exit
  774.  
  775. ; working with lbr: list all members and let user choose next
  776. ;
  777.     LD    HL,0
  778.     LD    (FCB1R0),HL    ; Set lbr rec 0
  779.     CALL    SEEK        ; Position to lbr tof and fall thru
  780.  
  781. ; System security related stuff
  782. ;
  783. OPENOK:    CALL    WHLCHK        ; If wheel is set, skip all this
  784.     JR    NZ,LEGAL    ;
  785.     LD    HL,FCB1EXT+1    ; Else check if file has SYS attribute
  786.     BIT    7,(HL)        ;
  787.     JP    NZ,NONE        ; If it does, pretend file doesn't exist
  788.                 ;
  789.     DEC    HL        ; More system security: no examing online
  790.     LD    A,(HL)        ; COM files. if they're in a lbr, ok, else
  791.     AND    7FH        ; They should be named OBJ or CZM.
  792.     CP    'C'        ;
  793.     JR    NZ,LEGAL    ;
  794.     INC    HL        ;
  795.     LD    A,(HL)        ;
  796.     CP    'O'        ; We know that SYS is not set
  797.     JR    NZ,LEGAL    ;
  798.     INC    HL        ;
  799.     LD    A,(HL)        ;
  800.     AND    7FH        ;
  801.     CP    'M'        ;
  802.     JP    Z,ILLEGAL    ;
  803.  
  804. LEGAL:    LD    A,(LIBRARY)    ; Access OK, continue
  805.     OR    A
  806.     JP    Z,CHKIFCOMPRESSED ; Not working with a library
  807.  
  808. ; read 1st lbr directory sector to see how big lbr dir is
  809.  
  810.     LD    DE,(BUFPTR)    ; Set dma to buffer
  811.     LD    HL,1
  812.     LD    (NSECTS),HL
  813.     CALL    READFILE
  814.     LD    A,(MTFLAG)    ; Zero if readfile read nothing
  815.     OR    A        ;
  816.     JP    Z,LBRERROR    ; We'll call an empty LBR file a library error
  817.     LD    IX,(BUFPTR)    ; Point to buffer
  818.     LD    L,(IX+14)    ; Dir sects low
  819.     LD    H,(IX+15)    ; Dir sects high
  820.     DEC    HL        ; We already read the 1st
  821.     LD    A,H
  822.     OR    L
  823.     JR    Z,PRLBRDIR    ; Lbr dir is only 1 sect long
  824.     LD    (NSECTS),HL
  825.     CALL    READFILE    ; Read the rest of the lbr dir
  826.     JP    Z,LBRERROR
  827.  
  828. ; print "du:lib.LBR" header for lbr directory
  829.  
  830. PRLBRDIR:            ;
  831.     CALL    CLEARSCREEN
  832.     CALL    MSG
  833.     DB    CR,LF,'Members in library ',0
  834.  
  835.     PUSH    DE
  836.     CALL    PRNDFN        ; Print DU:<filename>
  837.     POP    DE
  838.  
  839.     CALL    CRLF        ;
  840.  
  841. ; print active member names of lbr
  842. ; *.C?m files in optional half intensity
  843. ; DE is next dma adr = last byte read + 1
  844.  
  845.     EX    DE,HL
  846.     LD    (HL),0FFH    ; Add lbr dir eof
  847.  
  848.     CALL    CRLF
  849.     LD    HL,(BUFPTR)
  850.     LD    C,0        ; Count active lbr dir entries
  851.  
  852. PRNXTMEMBER:
  853.     LD    DE,32        ; Lbr dir incr
  854.     ADD    HL,DE        ; *next dir entry
  855.  
  856.     LD    A,(HL)
  857.     OR    A        ; 0 = active member?
  858.     JR    Z,ISACTIVE
  859.     CP    0FEH        ; Deleted member?
  860.     JR    Z,PRNXTMEMBER    ; Skip it
  861.     JP    LBRDIREOF
  862.  
  863. ISACTIVE:
  864.     INC    C        ; Incr member# counter
  865.     INC    HL        ; (must point to name for prnumfn call)
  866.     CALL    PRNUMFN        ; Print xxx: filename.typ
  867.     LD    A,C        ; * add a crlf after each 4th name *
  868.     AND    03H        ; *mskval ?? **
  869.     CALL    Z,CRLF        ;
  870.     DEC    HL        ;
  871.     JR    PRNXTMEMBER    ; Loop
  872.  
  873. ;................................
  874.                 ; Display 'Files Matching: DU <afn>'
  875. DFNS:    PUSH    BC        ;
  876.     PUSH    DE        ;
  877.     PUSH    HL        ;
  878.                 ;
  879.     CALL    CLEARSCREEN    ;
  880.     CALL    MSG        ;
  881.     DB    CR,LF,'Files matching ',0
  882.     CALL    PRFDU        ; Print appropriate DU:
  883.     LD    HL,(FILPTR)    ; Start of table
  884.     CALL    PRNFN        ; Print ambig filespec
  885.     CALL    CRLF        ;
  886.     CALL    CRLF        ;
  887.     POP    HL        ;
  888.     POP    DE        ;
  889.     POP    BC        ;
  890.     RET            ;
  891. ;...............................;
  892.  
  893. ;.....................................
  894. ;
  895. ; Print filename "C", pointed to by HL
  896. ;
  897. PRNUMFN:
  898.     PUSH    BC        ;
  899.     PUSH    DE        ;
  900.     PUSH    HL        ;
  901.     CALL    CKABRT        ; Chk for abort 1/filename
  902.                 ; - (fixes stack and exits direct if requested)
  903.     PUSH    BC        ; Save everything ("chkext" destroys)
  904.     PUSH    DE        ;
  905.     PUSH    HL        ;
  906.     LD    DE,8        ; Set de to point to the filename ext (hl+8)
  907.     ADD    HL,DE        ;
  908.     EX    DE,HL        ;
  909.     CALL    CHKEXT        ; Check if filename ext is COM, REL, etc.
  910.     JR    C,DIMMIT    ; If so, use half-intensity
  911.     CALL    OFFHALF        ; Else guarantee full intensity
  912.     JR    POPPEM        ;
  913. DIMMIT:    CALL    ONHALF        ; If so, do half intensity
  914. POPPEM:    POP    HL        ;
  915.     POP    DE        ;
  916.     POP    BC        ;
  917.  
  918.     PUSH    BC        ;
  919.     PUSH    DE        ; Save everything("B2DEC" destroys)
  920.     PUSH    HL        ;
  921.     LD    A,C        ;
  922.     CP    100        ;
  923.     CALL    C,SPACE        ;
  924.     LD    A,C        ; ("b2dec" left justifies)
  925.     CP    10        ;
  926.     CALL    C,SPACE        ;
  927.     LD    L,C        ; Get member's #, still in C
  928.     LD    H,0        ; Put it in HL
  929.     CALL    B2DEC        ; Display it
  930.     CALL    MSG        ;
  931.     DB    '. ',0
  932.     POP    HL        ;
  933.     POP    DE        ; Restore registers
  934.     POP    BC        ;
  935.  
  936.     CALL    PRNFN        ; Type the LBR name pointed to by HL
  937.     CALL    OFFHALF
  938.     CALL    MSG
  939.     DB    ' |',0
  940.  
  941.     POP    HL        ;
  942.     POP    DE        ;
  943.     POP    BC        ;
  944.     RET            ; End of PRNUMFN: subr
  945. ;...............................;
  946.  
  947. ;................................
  948.                 ; Subr to type filename pointed to by HL
  949.                 ;
  950. PRNFN:    LD    A,(CORE)    ; A core dump never has a filename
  951.     OR    A        ;
  952.     RET    NZ        ; So forget about it
  953.                 ;
  954.     LD    B,8        ; Display first 8 chars in fn
  955.                 ;
  956. PRNXT:    LD    A,(HL)        ; Get char of member name
  957.     INC    HL        ; *char++
  958.     AND    7FH        ; (make sure 'dcase' works right)
  959.                 ;
  960.      IF    LOWERCASE    ;
  961.     CALL    DCASE        ; "downcase" the character
  962.      ENDIF            ; Lowercase
  963.                 ;
  964.     CALL    PUTC        ; Print it
  965.     DJNZ    PRNXT        ; Loop 8 times
  966.                 ;
  967.     LD    A,'.'        ; Now display a "."
  968.     CALL    PUTC        ;
  969.                 ;
  970.     LD    B,3        ; Same as above 3 more times for ext
  971.                 ;
  972. PRNXT2:    LD    A,(HL)        ;
  973.     INC    HL        ;
  974.     AND    7FH        ;
  975.                 ;
  976.      IF    LOWERCASE    ;
  977.     CALL    DCASE        ; "downcase" the character
  978.      ENDIF            ; Lowercase
  979.                 ;
  980.     CALL    PUTC        ;
  981.     DJNZ    PRNXT2        ; Loop 3 times
  982.     RET            ;
  983. ;...............................;
  984.  
  985. ;................................
  986.                 ;
  987. PRFDU:    LD    HL,(LBRDU)    ; Type the filename's (FCB1's) DU:
  988.     JR    PDU        ;
  989.                 ;
  990. PRDDU:    LD    HL,(DEFDU)    ; Type the originally logged (default) DU
  991.                 ;
  992. PDU:    LD    A,'A'        ;
  993.     ADD    A,H        ; Convert that to ascii
  994.     CALL    PUTC        ; And display it
  995.     LD    H,0        ; User# already in "L", so just zero H
  996.     CALL    B2DEC        ; Print the user#
  997.     LD    A,':'        ;
  998.     CALL    PUTC        ; Print a colon
  999.     RET            ;
  1000. ;...............................;
  1001.  
  1002. ;................................
  1003.                 ; Print DU:<filename> for the FCB1 filename
  1004. PRNDFN:    CALL    PRFDU        ; Print DU:
  1005.     LD    HL,FCB1+1    ; Point to filename
  1006.     CALL    PRNFN        ; Print it and return
  1007.     RET            ;
  1008. ;...............................;
  1009.  
  1010. LBRDIREOF:
  1011.     LD    A,C
  1012.     LD    (NMEMBERS),A    ; Save # of active members, counted in C
  1013.  
  1014.     CALL    OFFHALF        ;
  1015.     CALL    CRLF        ;
  1016.     CALL    CRLF        ;
  1017.     CALL    PRDDU        ; Type the default DU to the screen
  1018.  
  1019.     LD    A,(EXTRACTING)    ; Check flag
  1020.     OR    A        ;
  1021.     JR    Z,VIEWPROMPT    ; 0: viewing - no special prompt
  1022.  
  1023.     CALL    MSG        ;
  1024.     DB    '> Extract',0    ;
  1025.     JR    PROMPT        ;
  1026.  
  1027. VIEWPROMPT:            ;
  1028.     CALL    MSG        ;
  1029.     DB    '> View',0    ;
  1030. PROMPT:                ;
  1031.     CALL    MSG        ;
  1032.     DB    ' member (1-',0
  1033.  
  1034.     LD    A,(NMEMBERS)    ; # of active members
  1035.     LD    L,A
  1036.     LD    H,0
  1037.     CALL    B2DEC
  1038.  
  1039.     CALL    WHLCHK
  1040.     JR    NZ,WHOK
  1041.     CALL    MSG
  1042.     DB    ')  or <ret>: ',0 ; Rest of prompt if no wheel
  1043.     JR    GETRSP        ; ** more effecient??
  1044.  
  1045. WHOK:    LD    A,(EXTRACTING)
  1046.     OR    A
  1047.     JR    NZ,EXTPR
  1048.  
  1049.     CALL    MSG        ; Rest of prompt while in View mode
  1050.     DB    '), ''E'' for Extract',0
  1051.     JR    RESTPR        ; Still more below
  1052.  
  1053. EXTPR:    CALL    MSG        ; Rest of prompt while in Extract mode
  1054.     DB    '), ''V'' for View',0
  1055.  
  1056. RESTPR:    CALL    MSG
  1057.     DB    ' mode, or <ret>: ',0
  1058.  
  1059. GETRSP:    XOR    A
  1060.     LD    (JUMPTO),A    ; Init jumpto for get
  1061.     LD    A,(NMEMBERS)
  1062.     LD    (HIPG),A    ; Set hipg so get can deduce when enuf
  1063.     CALL    GETCHNUM    ; Get user member choice
  1064.  
  1065.     LD    C,A        ;
  1066.     LD    A,(JUMPTO)    ; Did he enter a number
  1067.     OR    A        ;
  1068.     JP    NZ,CHKNUM    ; Go check it
  1069.  
  1070.     LD    A,C        ;
  1071.     CALL    UCASE        ; Possibly upcase a character in A
  1072.  
  1073.     CALL    CHEXIT        ; ^C or ^K will exit direct to CP/M
  1074.     JP    Z,QLEXIT    ; Other 'exit' type characters
  1075.  
  1076.     LD    B,A        ;
  1077.     CALL    WHLCHK        ; Nothing else legal if wheel isn't set
  1078.     LD    A,B        ;
  1079.     JR    Z,GETRSP    ;
  1080.  
  1081.     CP    'E'
  1082.     JR    Z,EXTRMODE
  1083.     CP    'V'        ;
  1084.     JR    NZ,GETRSP    ; Try again
  1085.  
  1086.     XOR    A        ; Flag for view mode
  1087.     JR    MODESET
  1088. EXTRMODE:            ;
  1089.     LD    A,1        ; Flag for extract mode
  1090. MODESET:            ;
  1091.     LD    (EXTRACTING),A    ; Set the mode
  1092.                 ; Fall thru, redisplay w/ new prompt
  1093.  
  1094.     CALL    CLEARSCREEN    ;
  1095.     JP    QUITNOSUM    ;
  1096.  
  1097. ;................................
  1098.                 ;
  1099. CHEXIT:    CP    CTRLC        ; ^C or ^K exit right to CP/M
  1100.     JP    Z,SYSTEM    ; (stack gets fixed)
  1101.     CP    CTRLK        ;
  1102.     JP    Z,SYSTEM    ;
  1103.                 ;
  1104.     CP    'X'        ; Other exit chars rtn w/ zero stat
  1105.     RET    Z        ;
  1106.     CP    'Q'        ;
  1107.     RET    Z        ;
  1108.     CP    ESC        ;
  1109.     RET    Z        ;
  1110.     CP    CTRLX        ;
  1111.     RET    Z        ;
  1112.     CP    CR        ;
  1113.     RET            ;
  1114. ;...............................;
  1115.  
  1116. ;=============================================================================
  1117.  
  1118. ; Hre we prepare to extract (and possibly decompress) to disk.
  1119. ; Most of the work is done by the routines for ordinary reading, with
  1120. ; the few differences being invoked by the setting of the EXTRACTING flag.
  1121. ;
  1122. EXTCHK:    LD    A,(EXTRACTING)    ; Return Z flag for EXTRACTING
  1123.     OR    A
  1124.     RET
  1125.  
  1126. EXTRDONE:
  1127. ; When we get here, all except last (partial) buffer has been written
  1128. ; *(DE-1) is last addr used.
  1129.     LD    A,127        ; Include last sector
  1130.     ADD    A,E
  1131.     LD    E,A
  1132.     LD    A,D
  1133.     ADC    A,0
  1134.     LD    D,A
  1135.     CALL    OUTFLUSH    ; Write the last buffer
  1136.     LD    C,CLOSE        ; Close the file
  1137.     LD    DE,FCB3
  1138.     CALL    BDOSEV
  1139.  
  1140.      IF    ZCPR3
  1141.     LD    BC,(LBRDU)    ;
  1142.     CALL    LOGUD        ;
  1143.      ENDIF            ; ZCPR3
  1144.  
  1145.     LD    HL,(FLSECTS)    ;
  1146.     PUSH    HL
  1147.     CALL    MSG
  1148.     DB    CR,LF,'Wrote ',0
  1149.     CALL    B2DEC        ; Print # of sectors
  1150.     CALL    MSG
  1151.     DB    ' sectors (',0
  1152.     POP    HL        ; = # sectors
  1153.     XOR    A        ; Clear carry & byte
  1154.     LD    B,3
  1155. ROLP:    RR    H        ; Divide by 8 & keep frac
  1156.     RR    L
  1157.     RR    A
  1158.     DJNZ    ROLP
  1159.     OR    A        ; Any fraction?
  1160.     JR    Z,NOFRAC
  1161.     INC    HL        ; Yep, count as 1K
  1162. NOFRAC:    CALL    B2DEC        ; Print # of K
  1163.     CALL    MSG
  1164.     DB    'K)',CR,LF,0
  1165.     CALL    DELAY8
  1166.     JP    QUITNOSUM    ; Display lbr dir again
  1167.  
  1168. ;...............................;
  1169. ; This code segment takes the filename from FCB3+16
  1170. ; and parses it into the destination file at FCB3.
  1171. ; For uncompressed files, we simply move it.
  1172. ; For squeezed/crunched files, we have to find the period etc.
  1173. ;
  1174. EXTCRFILE: LD    HL,FCB3+17    ; Point to member fn
  1175.     LD    DE,FCB3+1    ; Point to disk fcb
  1176.     LD    BC,8        ; 8 chars in first segment
  1177. EXTCR0:    LD    A,(HL)        ; Get next char
  1178.     AND    127        ; ASCII mask (no file attributes!)
  1179.     JR    Z,EXTCR1    ; If zero, was end of string char
  1180.     CP    '.'        ; Dot yet?
  1181.     JR    Z,EXTCR1
  1182.     LDI            ; Transfer char
  1183.     JP    PE,EXTCR0    ; Loop if not done
  1184. ; if we get here, the filename may be too long.  We ignore bytes until we find
  1185. ; a dot or null.
  1186. EXTSKIP:LD    A,(HL)
  1187.     OR    A        ; Null?
  1188.     JR    Z,EXTCR2
  1189.     CP    '.'        ; Dot?
  1190.     JR    Z,EXTCR2
  1191.     INC    HL        ; Test next char
  1192.     JR    EXTSKIP
  1193.  
  1194. EXTCR1:    LD    A,' '        ; Fill remaining part of first segment
  1195.     LD    (DE),A        ; With spaces
  1196.     INC    DE
  1197.     DEC    C
  1198.     JR    NZ,EXTCR1
  1199. EXTCR2:    INC    HL        ; Bump past dot
  1200.     LD    BC,3        ; Three more chars
  1201.  
  1202. EXTC2B:    LD    A,(HL)        ; Get char
  1203.     OR    A        ; Null means we fill with space
  1204.     JR    NZ,EXTCR4
  1205.     LD    A,' '        ; Fill with space
  1206. EXTCR3:    LD    (DE),A
  1207.     INC    DE
  1208.     DEC    C
  1209.     JR    NZ,EXTCR3
  1210.     JR    EXTFIL
  1211.  
  1212. EXTCR4:    LDI            ; Transfer char
  1213.     JP    PE,EXTC2B    ; Loop
  1214.     JR    EXTFIL
  1215.  
  1216. EXTUCFILE: LD    HL,MEMBER    ; Point to member fn
  1217.     LD    DE,FCB3+1    ; Point to disk fcb
  1218.     LD    BC,11
  1219.     LDIR
  1220.  
  1221. EXTFIL:    LD    HL,FCB3+12    ; Gotta zero rest of fcb3
  1222.     INC    DE        ; Points to FCB3+13
  1223.     LD    (HL),0
  1224.     LD    BC,20
  1225.     LDIR
  1226.     LD    (FLSECTS),BC    ; Reset the sectors-written counter
  1227.  
  1228.      IF    ZCPR3
  1229.     CALL    GETUD        ;
  1230.      ENDIF            ; ZCPR3
  1231.  
  1232.     LD    C,OPEN        ; Attempt to open file
  1233.     LD    DE,FCB3
  1234.     CALL    BDOSEV
  1235.     INC    A        ; Success means it already exists
  1236.     JR    Z,LEXT4
  1237.  
  1238.     CALL    MSG
  1239.     DB    CR,LF,LF,' ==> File exists; purge (y/N)? ',0
  1240.     LD    C,1
  1241.     CALL    BDOSEV
  1242.     AND    1FH        ; Y, y, or ^Y OK
  1243.     CP    19H
  1244.     PUSH    AF        ; ***
  1245.     CALL    CRLF
  1246.     POP    AF        ; ***
  1247.     JP    NZ,QUITNOSUM    ; Abort if he said no
  1248.     LD    C,ERASE        ; Erase if he said yes
  1249.     LD    DE,FCB3
  1250.     CALL    BDOSEV
  1251.  
  1252. LEXT4:    LD    C,CREAT        ; Create the file
  1253.     LD    DE,FCB3
  1254.     CALL    BDOSEV
  1255.     INC    A        ; Failure means no dir space
  1256.     RET    NZ        ; If it succeeded go back to reading-in code
  1257.     CALL    MSG
  1258.     DB    ' ++ Directory full ++ ',CR,LF,0
  1259. LWAIT0:    CALL    DELAY8
  1260.     JP    QUITNOSUM
  1261.  
  1262. ;................................
  1263.                 ;
  1264. DELAY8:    CALL    DELAY4        ;
  1265. DELAY4:    CALL    DELAY2        ;
  1266. DELAY2:    CALL    DELAY1        ;
  1267. DELAY1:    LD    BC,0        ;
  1268.                 ;
  1269. LWAIT:    NOP            ;
  1270.     DJNZ    LWAIT        ;
  1271.     DEC    C        ;
  1272.     JR    NZ,LWAIT    ;
  1273.     RET            ;
  1274. ;...............................;
  1275.  
  1276. ; Buffer flush failed; disk is full.
  1277. NOSPACE:
  1278.     CALL    MSG
  1279.     DB    ' ++ Disk Full ++',CR,LF,0
  1280.     LD    C,ERASE        ; Erase the file
  1281.     LD    DE,FCB3
  1282.     CALL    BDOSEV
  1283.     JR    LWAIT0
  1284.  
  1285. ; chk for too big a member #
  1286.  
  1287. CHKNUM:    LD    B,A        ; B = jumpto
  1288.     LD    A,(NMEMBERS)
  1289.     CP    B        ; Cy if nmembers < jumpto
  1290.     JP    C,QUITNOSUM    ; Display lbr dir again
  1291.  
  1292.     XOR    A
  1293.     LD    (JUMPTO),A    ; Rst jumpto
  1294.  
  1295. ; go to member number & display it
  1296.  
  1297.     LD    HL,(BUFPTR)
  1298.     LD    DE,32        ; Dir incr
  1299.  
  1300. MEMCNT:    ADD    HL,DE
  1301.  
  1302. ; chk for deleted not at eof
  1303.  
  1304.     LD    A,0FEH        ; Deleted marker
  1305.     CP    (HL)
  1306.     JR    Z,MEMCNT    ; Skip if deleted
  1307.     DJNZ    MEMCNT
  1308.  
  1309.     INC    HL        ; *fn[1]
  1310.  
  1311. ; copy full fn        ext to member name string and to fnext string
  1312. ;
  1313.     PUSH    HL        ; Save *fn[1]
  1314.     LD    DE,MEMBER
  1315.     LD    BC,11
  1316.     LDIR            ; Copy to member $
  1317.  
  1318.     POP    HL        ; Rst *fn[1]
  1319.     LD    DE,FNEXT
  1320.     LD    BC,11
  1321.     LDIR            ; Copy to fnext $
  1322.  
  1323.     LD    E,(HL)        ; HL = *member start
  1324.     INC    HL
  1325.     LD    D,(HL)        ; DE = starting sect of member
  1326.     LD    (FCB1R0),DE    ; Fill in lbr r0,r1 fld for seek to member
  1327.     INC    HL        ; HL = *member len
  1328.     LD    E,(HL)
  1329.     INC    HL
  1330.     LD    D,(HL)        ; DE = len in sects to read after seek
  1331.     LD    (NSECTS),DE
  1332.  
  1333. ; chk for zero len, maybe a lbr date file
  1334.  
  1335.     LD    A,D
  1336.     OR    E
  1337.     JP    Z,MT        ; If member is empty (zero-length)
  1338.  
  1339. ; position to member within lbr at fcb1r0
  1340.  
  1341. SEEKMEMBER:
  1342.     CALL    SEEK
  1343.     JP    CHKIFCOMPRESSED
  1344.  
  1345. ; assumes fcb1r0 is set to rec to seek to
  1346. ; set fcb1 r2 fld to 0
  1347.  
  1348. SEEK:    XOR    A
  1349.     LD    (FCB1R2),A    ; 0 lbr r2 fld
  1350.     LD    C,RANDOM
  1351.     CALL    BDOSCALL
  1352.     RET    Z        ; Seek ok
  1353.     POP    HL        ; Destroy ret adr
  1354.  
  1355. LBRERROR:
  1356.     CALL    MSG
  1357.     DB    'LBR read error',0
  1358.     JP    QLEXIT
  1359. ;.....
  1360. ;
  1361. SUMMARY:
  1362.     CALL    ONHALF        ; Dim videp
  1363.  
  1364.     CALL    MSG        ;
  1365.     DB    CR,LF,'  File: ',0 ;
  1366.     CALL    PRNDFN        ; Print DU:<filename>
  1367.     CALL    CRLF
  1368.  
  1369.     LD    A,(LIBRARY)    ;
  1370.     OR    A        ;
  1371.     JR    Z,NLBR2        ;
  1372.     CALL    MSG        ;
  1373.     DB    'Member: ',0    ;
  1374.     LD    HL,MEMBER    ;
  1375.     CALL    PRNFN        ;
  1376.     CALL    CRLF        ;
  1377.  
  1378. NLBR2:    LD    A,(INCOMPLETE)    ; Was read complete?
  1379.     OR    A
  1380.     JR    Z,DOSUMMARY    ; If so, we know file size
  1381.  
  1382. WARNING:
  1383.     CALL    MSG
  1384.     DB    CR,LF,'( ** Entire file does NOT FIT in Memory ** )',0
  1385.     CALL    OFFHALF
  1386.     RET
  1387.  
  1388. ; report file size
  1389.  
  1390. DOSUMMARY:
  1391.     CALL    MSG        ;
  1392.     DB    '  Size: ',0    ;
  1393.     LD    HL,(FILELEN)    ; In bytes
  1394.     PUSH    HL
  1395.     CALL    B2DEC
  1396.     CALL    MSG
  1397.     DB    ' bytes (',0
  1398.  
  1399.     POP    HL        ; HL = filelen
  1400.     SRL    H
  1401.     SRL    H        ; Shift to kilobytes
  1402.     INC    H        ; For overflow lsb
  1403.     LD    L,H
  1404.     LD    H,0
  1405.     CALL    B2DEC
  1406.     CALL    MSG
  1407.     DB    'k)',CR,LF,0
  1408.  
  1409. ; skip line count for non-text files
  1410.  
  1411.     LD    A,(AFLAG)
  1412.     OR    A
  1413.     JR    NZ,RETSUM    ; &ret, no line summary
  1414.  
  1415.     CALL    MSG
  1416.     DB    'Approx: ',0
  1417.     LD    A,(HIPG)
  1418.     DEC    A        ; Don't count last pg lines yet
  1419.     LD    B,A
  1420.     LD    HL,0
  1421.     JR    Z,ONLY1PG    ; Only 1 pg, nothing to add
  1422.     LD    A,(DISPLAY)    ; Actual lines per pg
  1423.     LD    E,A
  1424.     LD    D,L
  1425.  
  1426. CNTLINES:
  1427.     ADD    HL,DE
  1428.     DJNZ    CNTLINES
  1429.  
  1430. ONLY1PG:
  1431.     LD    A,(LASTPGLINES)
  1432.     LD    E,A
  1433.     LD    D,0
  1434.     ADD    HL,DE        ; Add in last pg lines
  1435.     CALL    B2DEC
  1436.     CALL    MSG
  1437.     DB    ' lines, ',0
  1438.  
  1439. ; added word counting code
  1440. ; words are any seq of chars >= '0' (30h) and < 80h
  1441. ; handle ws doc by ascii mask
  1442.  
  1443. ; count space between words
  1444.  
  1445.     LD    HL,(BUFPTR)
  1446.     LD    D,FALSE        ; Inword = false
  1447.  
  1448. ; reg E is temp storage for curr ch
  1449.  
  1450.     LD    IX,0        ; Word count
  1451.     LD    BC,(FILELEN)    ; Get actual file len
  1452.  
  1453. CNT:    LD    E,(HL)        ; Save ch
  1454.     INC    HL
  1455.     DEC    BC
  1456.     LD    A,B
  1457.     OR    C
  1458.     JR    Z,CNTALLDONE
  1459.     LD    A,E        ; Get ch
  1460.     AND    7FH        ; Mask to ascii
  1461.     CP    '0'        ; Cy if < '0'
  1462.     JR    C,ISWHITESP
  1463.  
  1464. ; ch is valid in word
  1465.  
  1466.     XOR    A        ; False
  1467.     OR    D        ; Inword == false?
  1468.     JR    NZ,CNT        ; No
  1469.     LD    D,0FFH        ; In a word now
  1470.     INC    IX        ; Word count++
  1471.     JR    CNT
  1472.  
  1473. ISWHITESP:
  1474.     LD    D,FALSE        ; Inword = false
  1475.     JR    CNT
  1476.  
  1477. CNTALLDONE:
  1478.     PUSH    IX
  1479.     POP    HL
  1480.     CALL    B2DEC
  1481.     CALL    MSG
  1482.     DB    ' words.',CR,LF,0
  1483.  
  1484. RETSUM:    CALL    OFFHALF
  1485.     RET            ; End summary
  1486.  
  1487. ;------------------------------------------------------------------------------
  1488. ;
  1489. ; may be compressed by squeezing or crunching
  1490. ;
  1491. CHKIFCOMPRESSED:
  1492.     XOR    A
  1493.     LD    (INCOMPLETE),A    ; Set read not incomplete yet
  1494.  
  1495.     LD    A,(EXTRACTING)    ;
  1496.     AND    02H        ; Bit 1 set means do not decompress
  1497.     JR    NZ,NORMAL    ;
  1498.  
  1499.     LD    A,(LIBRARY)
  1500.     OR    A        ; Working fr lbr?
  1501.     LD    A,(FCB1EXT+1)    ; Chk 2nd letter of file ext
  1502.     JR    Z,ISITQZ    ; If not lbr
  1503.     LD    A,(MEMBER+9)    ; Else, 2nd letter of member ext
  1504.  
  1505. ISITQZ:    CP    'Q'
  1506.     JP    Z,SQUEEZED
  1507.  
  1508. ; chk for crunched file
  1509.  
  1510.     CP    'Z'
  1511.     JP    Z,CRUNCHED
  1512.  
  1513. ; else it's a normal uncompressed file
  1514. ; we also come back here for *.azm files after uncr fails
  1515.  
  1516. NORMAL:
  1517.     CALL    CRLF
  1518. NORML2:    CALL    EXTCHK        ; If extracting, handle files here
  1519.     CALL    NZ,EXTUCFILE    ; (the UnCompressed file routine)
  1520.     LD    DE,(BUFPTR)    ; Read into buffer til eof or mem full
  1521.     LD    A,(LIBRARY)
  1522.     OR    A
  1523.     JR    NZ,NRMLBR    ; Nsects already set for lbr member
  1524.     LD    HL,512        ; Force read to eof or up to BDOS
  1525.     LD    (NSECTS),HL
  1526.  
  1527. NRMLBR:    CALL    MSG
  1528.     DB    CR,'    Reading',0 ; (extra CR in case of overwrite)
  1529.     CALL    READFILE
  1530.     JP    Z,TOOLARGE    ; Set incomplete read flag
  1531.     LD    A,(MTFLAG)    ; Else check if ANYTHING was read
  1532.     OR    A        ;
  1533.     JP    NZ,FINDEOF    ; If so, ok
  1534.  
  1535. MT:    CALL    MSG        ; Else complain
  1536.     DB    CR,LF,'===> File Empty.',CR,LF,0
  1537.     CALL    DELAY8        ;
  1538.     JP    QUITNOSUM    ;
  1539.  
  1540. ; rewritten for clarity?
  1541. ; DE should pt to 1st dma adr on entry
  1542. ; DE pts to last dma adr used on exit
  1543. ; seq read of uncompressed file or lbr member or lbr dir into buffer
  1544. ; reads entire file (up to BDOS) or nsects of a lbr dir or member
  1545. ; nsects should be set for max sects to read
  1546. ; NZ if read ok
  1547. ; Z  if too large for mem
  1548.  
  1549. READFILE:
  1550.     XOR    A        ; If subr returns w/ mtflag=0, nothing was read
  1551.     LD    (MTFLAG),A
  1552.  
  1553. REEDFILP:
  1554.     LD    C,SETDMA
  1555.     CALL    BDOSCALL
  1556.     LD    C,READSEQ
  1557.     CALL    BDOSCALL
  1558.     RET    NZ        ; Read to eof ok
  1559.  
  1560.     LD    A,0FFH        ; If at least 1 sec read, set this flag
  1561.     LD    (MTFLAG),A    ;
  1562.  
  1563. ; pt to start of next dma
  1564.  
  1565.     LD    HL,128
  1566.     ADD    HL,DE        ; Dma += 128
  1567.     EX    DE,HL        ; DE=next dma adr
  1568.  
  1569. ; chk next dma adr < BDOS
  1570.  
  1571.     LD    A,(BDOSBASE+1)    ; [possibly adjusted] BDOS hi adr
  1572.     DEC    A        ; 256 byte BDOS safety cushion
  1573.     CP    D        ; Curr hi dma adr
  1574.     JR    NZ,OKNEXT    ; File about to crash into BDOS
  1575.  
  1576.     CALL    EXTCHK
  1577.     RET    Z        ; Nope, give up
  1578.  
  1579.     LD    DE,BDOSBASE    ; Pass end-of-buffer addr
  1580.     CALL    OUTFLUSH    ; Flush the buffer
  1581.                 ; On return, DE points to start of buffer again
  1582.  
  1583. ; chk if spec # of sects read
  1584.  
  1585. OKNEXT:    LD    HL,(NSECTS)
  1586.     DEC    HL        ; Nsects--
  1587.     LD    (NSECTS),HL
  1588.     LD    A,H
  1589.     OR    L        ; Spec # of sects read?
  1590.     JR    NZ,REEDFILP    ; No
  1591.  
  1592.     INC    A        ; Set nz for nsects read ok
  1593.     RET
  1594.  
  1595. ; C must be set for correct BDOS fn (open, readseq, readrandom) on fcb1
  1596. ; we stick setdma fn call in here as well to save code space
  1597. ; saves & restores all regs except af which has ret code
  1598. ; set z if a = 0
  1599.  
  1600. BDOSCALL:
  1601.     PUSH    BC
  1602.     PUSH    DE
  1603.     PUSH    HL
  1604.     LD    A,C
  1605.  
  1606.      IF    DOSPLUS
  1607.     CP    211        ; DOS+ binary to decimal printer
  1608.     JR    Z,DEISSET
  1609.      ENDIF
  1610.  
  1611.     CP    SETDMA        ; Fn call is setdma?
  1612.     JR    Z,DEISSET    ; If so, DE already set
  1613.  
  1614.     LD    DE,FCB1
  1615.  
  1616. DEISSET:
  1617.     CALL    BDOSEV
  1618.     OR    A        ; Set z for read ok
  1619.     POP    HL
  1620.     POP    DE
  1621.     POP    BC
  1622.     RET
  1623.  
  1624. ; unsqueezing code setup
  1625.  
  1626. SQUEEZED:
  1627.     LD    HL,(BDOSBASE)    ; [possibly adjusted] BDOS addr
  1628.     LD    (WORKAREA),HL    ; Workarea is all mem up to BDOS for unsq
  1629.  
  1630.     LD    HL,STACK
  1631.     LD    (SPSAVE),HL    ; Set default stk if too large
  1632.  
  1633. ; set *sq and *unsq
  1634.  
  1635.     LD    HL,100H        ; Src ptr for getbyt, forcing read
  1636.     LD    DE,(BUFPTR)    ; Dst ptr for out
  1637.  
  1638.     LD    (UNCRSRC),HL
  1639.     LD    (UNCRDST),DE
  1640.  
  1641.     CALL    MSG
  1642.     DB    CR,LF,LF,'Unsqueezing: ',0
  1643.  
  1644.     CALL    GETBYT
  1645.     CP    76H        ; Compressed file marker (halt inst)
  1646.     JP    NZ,NOTCOMPRESSED
  1647.  
  1648.     CALL    GETBYT
  1649.     CP    0FFH        ; Squeezed file marker
  1650.     JP    NZ,NOTCOMPRESSED
  1651.  
  1652.     CALL    GETBYT
  1653.     CALL    GETBYT        ; Skip 2 chksum bytes
  1654.  
  1655.     LD    DE,FCB3+17    ; Place to put unsqueezed fn
  1656.  
  1657. ; print the unsqueezed file name
  1658.  
  1659. NXTSQFNCHAR:
  1660.     CALL    GETBYT
  1661.  
  1662.     LD    (DE),A        ; Save in find string area
  1663.     INC    DE
  1664.  
  1665.     OR    A        ; '\0' $ term?
  1666.     JR    Z,SQFNDONE
  1667.     CALL    PUTC
  1668.     JR    NXTSQFNCHAR
  1669.  
  1670. SQFNDONE:
  1671.     CALL    EXTCHK        ; If we're extracting, time to open the file
  1672.     CALL    NZ,EXTCRFILE    ; (the CompRessed file routine)
  1673.  
  1674.     CALL    GETBYT        ; Get # of 4 byte transl pairs
  1675.     LD    L,A
  1676.     CALL    GETBYT
  1677.     LD    H,A
  1678.  
  1679. ; times 4 for number of bytes in transl tbl
  1680.  
  1681.     ADD    HL,HL
  1682.     ADD    HL,HL
  1683.     LD    B,H
  1684.     LD    C,L
  1685.  
  1686. ; copy unsq transl tbl over ptrtbl temporarily
  1687.  
  1688.     LD    HL,(@PTRTBL)    ;
  1689.  
  1690. COPYUNSQTT:
  1691.     CALL    GETBYT
  1692.     LD    (HL),A        ; Store into tt
  1693.     INC    HL
  1694.     DEC    BC        ; Ctr--
  1695.     LD    A,B
  1696.     OR    C
  1697.     JR    NZ,COPYUNSQTT
  1698.  
  1699.     LD    B,0        ; Init bit ctr
  1700.  
  1701. ; drive the unsqueezer
  1702.  
  1703. UNSQNEXT:
  1704.     CALL    UNSQ        ; Unsq 1 char
  1705.     JR    C,UNSQDONE    ; Eof
  1706.     CP    90H        ; Repeat count follows
  1707.     JR    Z,REPCHAR    ; Don't save 90h repeat ch
  1708.     LD    (LASTUNSQCH),A    ; Save in case of repeat count
  1709.     CALL    OUT        ; Put unsq char into buffer
  1710.     JR    UNSQNEXT
  1711.  
  1712. REPCHAR:
  1713.     CALL    UNSQ        ; Get repeat count
  1714.     JR    C,UNSQDONE    ; Eof
  1715.     OR    A        ; 0 cnt?
  1716.     JR    Z,SEND90H    ; Then send real 90h
  1717.     PUSH    BC        ; Save bit ctr B
  1718.     LD    B,A        ; Repeat ctr
  1719.     DEC    B        ; Actual cnt is 1 less
  1720.     JR    Z,UNSQNEXT
  1721.     LD    A,(LASTUNSQCH)
  1722.  
  1723. REPLOOP:
  1724.     PUSH    AF
  1725.     CALL    OUT        ; Out last ch B times
  1726.     POP    AF
  1727.     DJNZ    REPLOOP
  1728.     POP    BC        ; Rst bit ctr B
  1729.     JR    UNSQNEXT
  1730.  
  1731. SEND90H:
  1732.     LD    A,90H
  1733.     CALL    OUT
  1734.     JR    UNSQNEXT
  1735.  
  1736. UNSQDONE:
  1737.     CALL    OUT        ; Save eof marker
  1738.     LD    HL,(UNCRSRC)
  1739.     LD    DE,(UNCRDST)
  1740.     JP    FINDEOF
  1741.  
  1742. ; B = bitstogo mod 8 ctr
  1743. ; C = curr sq ch, maybe partially shifted
  1744. ; DE = curr transl tbl incr
  1745. ; HL = *sq transl tbl
  1746.  
  1747. UNSQ:    LD    DE,0        ; DE=curr tbl incr
  1748.     XOR    A
  1749.     OR    B        ; Chk bits to go = 0
  1750.     JR    NZ,NEWINDEX    ; Nz is sq char in progress
  1751.  
  1752. ; else start with a new sq char
  1753.  
  1754. NXTSQCHAR:
  1755.     CALL    GETBYT        ; Fetch a sq char
  1756.     LD    C,A        ; Save in C
  1757.     LD    B,8        ; 8 bits per char shift ctr
  1758.  
  1759. ; this code is from lt18 unsqueezer
  1760.  
  1761. NEWINDEX:
  1762.     LD    HL,(@PTRTBL)    ;
  1763.  
  1764. ; mult curr incr in DE by 4 by repeated adding
  1765.  
  1766.     ADD    HL,DE
  1767.     ADD    HL,DE
  1768.     ADD    HL,DE
  1769.     ADD    HL,DE
  1770.  
  1771. ; shift out lsb of sq char & chk it
  1772.  
  1773.     LD    A,C        ; Get sq char back
  1774.     SRL    A        ; Shift bit 0 into cy
  1775.     LD    C,A        ; Save sq ch again
  1776.     JR    NC,NOTSET    ; Use odd pair
  1777.     INC    HL        ; To even pair if bit was set in sq char
  1778.     INC    HL
  1779.  
  1780. NOTSET:    LD    E,(HL)        ; New incr for DE if not transl
  1781.     INC    HL
  1782.     LD    D,(HL)        ; > 7fh if valid transl
  1783.     BIT    7,D        ; Bit 7 set if valid
  1784.     JR    Z,NOTTRANSL    ; Hi bit not set: E is not a transl
  1785.  
  1786.     DEC    B        ; Bit ctr--
  1787.     LD    A,0FEH        ; End of transl tbl
  1788.     CP    D        ; Set z flag if eof
  1789.     LD    A,1AH        ; Get eof marker
  1790.     SCF            ; Mark this as the eof return
  1791.     RET    Z        ; Since 1ah could be repeat count
  1792.  
  1793.     LD    A,E        ; Else get char transl
  1794.     CCF            ; No carry if not eof
  1795.     CPL            ; Extract char by inversion
  1796.     RET            ; Ret the unsq ch
  1797.  
  1798. NOTTRANSL:
  1799.     DJNZ    NEWINDEX
  1800.     JR    NXTSQCHAR
  1801.  
  1802. ; uncrunching i/o code
  1803.  
  1804. CRUNCHED:
  1805.     CALL    MSG
  1806.     DB    CR,LF,LF,'Uncrunching: ',0
  1807.     LD    HL,100H        ; Src ptr for getbyt, dummy end of sect
  1808.     LD    DE,(BUFPTR)    ; Dst ptr for out
  1809.     LD    (UNCRSRC),HL
  1810.     LD    (UNCRDST),DE
  1811.  
  1812. ; chk to see if header is correct for crunched file
  1813. ; we do this here in order to abort gracefully if it's an uncrunched .azm file
  1814.  
  1815.     CALL    GETBYT
  1816.     CP    76H
  1817.     JR    NZ,NOTCOMPRESSED
  1818.     CALL    GETBYT
  1819.     CP    0FEH
  1820.     JR    NZ,NOTCOMPRESSED
  1821.  
  1822. ; crunched header ok
  1823. ; now output the file name
  1824. ;
  1825. ; Do not print data which may be after end of filename, but before the
  1826. ; zero (system dependent data allowed here; CR23d uses this). We will
  1827. ; print the chars if they are between "[" and "]", however.
  1828. ;
  1829.     LD    B,12        ; Loop limit for 11 chars plus "."
  1830.     LD    DE,FCB3+17    ; Place to put uncrunched filename
  1831.  
  1832. SAYLP:    CALL    GETBYT        ; Next filename char
  1833.  
  1834.     LD    (DE),A        ; Save fn for extracting
  1835.     INC    DE
  1836.  
  1837.     CP    '.'        ; Dot?
  1838.     JR    NZ,NOTDOT    ; If not
  1839.     LD    B,4        ; If we hit the dot, only 4 (dot+3) chars left
  1840.  
  1841. NOTDOT:    OR    A        ; A zero terminates, as always
  1842.     JR    Z,CRHDRDONE    ; Yes, done
  1843.     CALL    PUTC        ; Output the char
  1844.     DJNZ    SAYLP        ; Loop a limited number of times
  1845.  
  1846.     CALL    EXTCHK        ; If we're extracting, time to open the file
  1847.     CALL    NZ,EXTCRFILE    ; (the CompRessed file routine)
  1848.  
  1849.     CALL    GETBYT        ; This part's optional- print "[..]" text
  1850.     OR    A        ; End-of-header?
  1851.     JR    Z,CRHDRDONE    ; If so..
  1852.     CP    '['        ; Beg of comment?
  1853.     JR    NZ,FNDEOH    ; Forget it, skip junk and continue
  1854.     LD    B,A        ; Save that "["
  1855.     LD    A,' '        ; Space btwn filename and comment looks better
  1856.     CALL    PUTC        ;
  1857.     LD    A,B        ; Get that "[" bak again
  1858.  
  1859. CMNTLP:    CALL    PUTC        ; Ok, start typing comment
  1860.     CALL    GETBYT        ; Next char
  1861.     OR    A        ; In case of missing "]"
  1862.     JR    Z,CRHDRDONE    ;
  1863.     CP    ']'        ; End of comment?
  1864.     JR    NZ,CMNTLP    ; Loop for more chars if not
  1865.     CALL    PUTC        ; Print closing bracket
  1866.  
  1867. ; now (finally!) make sure we are at the zero marked eoh
  1868.  
  1869. FNDEOH:    CALL    GETBYT
  1870.     OR    A
  1871.     JR    NZ,FNDEOH
  1872.  
  1873. ; set workarea 24k below BDOS.
  1874.  
  1875. ; "UNC", in it's present configuration, checks that the address of free
  1876. ; memory supplied to it in HL allows FULLY 24k (or more). It does this
  1877. ; after rounding up the value supplied to the next even page boundary. So
  1878. ; we have to add in an extra 256 bytes to allow for this rounding process.
  1879.  
  1880. CRHDRDONE:
  1881.     LD    HL,(BDOSBASE)    ; [possibly adjusted] BDOS addr
  1882.     LD    DE,24*1024+256    ; 24k + one page for "rounding"
  1883.     XOR    A
  1884.     SBC    HL,DE
  1885.     LD    (WORKAREA),HL    ; Save for debug only
  1886.  
  1887.     CALL    UNC        ; Join uncrel after filename scanned
  1888.  
  1889.     LD    HL,(UNCRSRC)
  1890.     LD    DE,(UNCRDST)
  1891.  
  1892.     JR    C,CHKUNCRERRS
  1893.  
  1894. ; file was successfully uncrunched
  1895.  
  1896.     PUSH    DE        ; DE pts to last out+1
  1897.     EX    DE,HL        ; HL now pts to last out+1
  1898.     LD    DE,(BUFPTR)    ; Start of uncr text
  1899.     XOR    A
  1900.     SBC    HL,DE        ; Len of uncr text
  1901.     LD    (FILELEN),HL
  1902.     POP    DE        ; Last out+1 for findeof
  1903.  
  1904.     JP    FINDEOF        ; Treat like all others
  1905.  
  1906. CHKUNCRERRS:
  1907.     CP    2        ; Error 2 is file not crunched
  1908.     JR    NZ,CHK1ERROR
  1909.  
  1910. ; we can handle this error:
  1911. ; force top of file again, then treat as normal text
  1912.  
  1913. NOTCOMPRESSED:
  1914.     LD    HL,0
  1915.     LD    (FCB1R0),HL
  1916.     LD    C,RANDOM
  1917.     CALL    BDOSCALL    ; Read at tof
  1918.     JP    NORML2        ; (Will overwrite "Uncrunching" msg)
  1919.  
  1920. CHK1ERROR:
  1921.     PUSH    AF
  1922.     CALL    CRLF
  1923.     POP    AF
  1924.     CP    1
  1925.     JR    Z,ERR1
  1926.     CP    5
  1927.     JR    NZ,CHK3ERROR
  1928.  
  1929. ERR1:    CALL    MSG
  1930.     DB    'Unknown crunched format',0
  1931.     JP    QUITNOSUM
  1932.  
  1933. CHK3ERROR:
  1934.     CP    3
  1935.     JR    NZ,CHK4ERROR
  1936.     CALL    MSG
  1937.     DB    '++ File is corrupt ++',0
  1938.     JP    QUITNOSUM
  1939.  
  1940. CHK4ERROR:
  1941.     CP    4
  1942.     JR    NZ,UNCRUNKERROR
  1943.     CALL    MSG
  1944.     DB    '++ Out of memory ++',0
  1945.     JP    QUITNOSUM
  1946.  
  1947. UNCRUNKERROR:
  1948.     PUSH    AF
  1949.     CALL    MSG
  1950.     DB    '++ Uncrunch error: ',0
  1951.     POP    AF
  1952.     ADD    A,'0'        ; Make an ascii #
  1953.     CALL    PUTC
  1954.     JP    QUITNOSUM
  1955.  
  1956. ; i/o rtns for uncrel.azm
  1957. ; these are also used by unsq code
  1958.  
  1959. GETBYT:    PUSH    BC        ; Save working regs
  1960.     PUSH    HL
  1961.     LD    HL,(UNCRSRC)
  1962.  
  1963.     LD    A,H
  1964.     CP    1        ; At 100h?
  1965.     JR    C,STILLINSECT
  1966.  
  1967. ; read another sector of the file
  1968.  
  1969.     PUSH    DE        ; Save dst ptr fr BDOS destruction
  1970.  
  1971.     LD    C,SETDMA
  1972.     LD    DE,80H        ; Use default buffer
  1973.     CALL    BDOSCALL
  1974.  
  1975.     LD    C,READSEQ
  1976.     CALL    BDOSCALL    ; Read next sector into it
  1977.     POP    DE        ; Restore DE
  1978.  
  1979.     LD    HL,80H        ; Set ptr to start of this sector
  1980.  
  1981. STILLINSECT:
  1982.     LD    A,(HL)        ; Get a char to uncr
  1983.     INC    HL        ; *ch++
  1984.  
  1985.     LD    (UNCRSRC),HL
  1986.     POP    HL        ; Restore working regs
  1987.     POP    BC
  1988.     RET
  1989.  
  1990. OUT:    PUSH    AF
  1991.     PUSH    DE        ; Save working regs
  1992.     LD    DE,(UNCRDST)
  1993.     LD    (DE),A
  1994.     INC    DE
  1995.  
  1996. ; chk for DE > workarea
  1997.  
  1998.     LD    A,(WORKAREA+1)
  1999.     CP    D        ; Hi bytes only
  2000.     JR    NZ,OUTOK
  2001.  
  2002. ; else, uncr/unsq text is about to run into workarea
  2003. ; so if we are extracting from a library, we flush the buffer now
  2004.  
  2005.     CALL    EXTCHK        ; Are we indeed extracting?
  2006.     JR    NZ,OUT0
  2007.  
  2008.     LD    SP,(SPSAVE)    ; Restore our sp
  2009.     CALL    CRLF
  2010.     DEC    DE        ; DE pts to last byte uncr
  2011.     JR    TOOLARGE
  2012.  
  2013. OUTFLUSH:
  2014.     PUSH    HL        ; Save last 2 working regs
  2015.     PUSH    BC        ;
  2016.     LD    HL,(BUFPTR)    ;
  2017.     EX    DE,HL        ; Put last sector used addr in HL
  2018.     OR    A        ; Clear carry for 16-bit subtract
  2019.     SBC    HL,DE        ; HL is now length of full buffer
  2020.     PUSH    HL        ; Save it
  2021. ;;;;    ADD    HL,HL        ; H has sector count ==> NO!! not if HL > 8000H
  2022.                 ; V4.0 must use 2-byte sector count!!
  2023.     LD    B,0        ; BC will be sector counter
  2024.     LD    C,H        ;
  2025.     SLA    L        ;
  2026.     RL    C        ;
  2027.     RL    B        ; Now BC has correct sector count
  2028.  
  2029. OUTF0:    PUSH    DE
  2030.     PUSH    BC
  2031.     LD    C,SETDMA    ; Set DMA to this sector
  2032.     CALL    BDOSEV
  2033.     LD    C,WRITSEQ    ; Write sector
  2034.     LD    DE,FCB3        ; Extraction FCB
  2035.     CALL    BDOSEV
  2036.     OR    A        ; Out of space?
  2037.     JP    NZ,NOSPACE
  2038.     LD    HL,(FLSECTS)    ; Count one more sector flushed
  2039.     INC    HL
  2040.     LD    (FLSECTS),HL
  2041.     POP    BC
  2042.     POP    DE
  2043.     LD    HL,80H        ; Point to next sector
  2044.     ADD    HL,DE
  2045.     EX    DE,HL        ; Swap into DE
  2046.  
  2047.     DEC    BC        ; V4.0 need 2-byte loop counter, as mentioned
  2048.     LD    A,B        ;
  2049.     OR    C        ;
  2050.     JR    NZ,OUTF0    ;
  2051.  
  2052.     POP    HL        ; Get back orig buffer length
  2053.     LD    A,L        ; Low byte
  2054.     AND    127        ; This many bytes were not flushed
  2055.     LD    C,A        ; Move to BC
  2056.     LD    B,0
  2057.     EX    DE,HL        ; Point to unflushed bytes
  2058.     LD    DE,(BUFPTR)    ; Point to start of buffer
  2059.     JR    Z,OUTF1        ; If there were no bytes, skip it
  2060.     LDIR
  2061.  
  2062. OUTF1:
  2063.     POP    BC        ; Restore regs
  2064.     POP    HL
  2065.     RET            ; And DE points to first free location
  2066.  
  2067. OUT0:    LD    DE,(WORKAREA)    ; Pass ptr to buffer top in DE
  2068.     LD    E,0
  2069.     CALL    OUTFLUSH
  2070.  
  2071. OUTOK:    LD    (UNCRDST),DE    ; Reset destination ptr
  2072.     POP    DE        ; Rst working regs
  2073.     POP    AF
  2074.     RET
  2075.  
  2076. ;..............................................................................
  2077. ;
  2078. TOOLARGE:
  2079.     LD    A,0FFH        ; Flag incomplete read
  2080.     LD    (INCOMPLETE),A
  2081.  
  2082. ;.....
  2083. ;
  2084. ; we're no longer working with a compressed file
  2085. ; normal, unsq    & uncr all come here
  2086. ; if we were extracting, go finish up, else
  2087. ; find eof marker: only look in last sector read
  2088. ; if no eof found, put one in at end of last sector
  2089. ;
  2090. FINDEOF:
  2091.     LD    A,(EXTRACTING)    ; Were we extracting?
  2092.     OR    A
  2093.     JP    NZ,EXTRDONE    ; ***
  2094.  
  2095.     EX    DE,HL        ; Last dma now in HL
  2096.     LD    BC,128
  2097.     XOR    A        ; Clr cy
  2098.     SBC    HL,BC        ; HL=start of last sector read
  2099.     LD    A,EOF
  2100.     CPIR            ; Look for eof thru 128 bytes
  2101.     JR    Z,GOTEOF    ; Eof found
  2102.     LD    (HL),A        ; Else put in our own eof marker
  2103.                 ; Probably leaves some garbage at eof
  2104.  
  2105. GOTEOF:    LD    (EOFADR),HL    ; Save highest used adr
  2106.     XOR    A        ; Clr cy
  2107.     LD    DE,(BUFPTR)
  2108.     SBC    HL,DE
  2109.     LD    (FILELEN),HL    ; Save actual file len in bytes
  2110.  
  2111. ; chk if we really have a text file
  2112. ; assume it's text:
  2113. ;   IF the 1st byte is between 20h and 7fh or cr, lf or tab or formfeed
  2114. ;   AND 90% of 1st 100 chars are printable (for wordstar hi bits)
  2115. ; if text, set ptrs to 1 char past every 22nd lf in buffer
  2116. ; else, set up for hex/ascii dumping instead of chaos of earlier versions
  2117. ;   by setting ptrs to every 256 bytes of buffer
  2118. ;
  2119. ; 1st see if we really have a text file
  2120. ;
  2121.     LD    HL,(BUFPTR)
  2122.     LD    A,(HL)
  2123.     CALL    CHKOKCTRLS    ; Cr,lf,tab?
  2124.     JR    Z,CHKTEXT    ; Text so far
  2125.     CP    ' '
  2126.     JR    C,ISNONTEXT    ; Ctrl char 1st
  2127.     CP    7FH+1        ; This screens common init 0c3h
  2128.     JR    NC,ISNONTEXT
  2129.  
  2130. CHKTEXT:
  2131.     LD    B,100        ; # to scan
  2132.     LD    C,0        ; Count of non-text chars
  2133.  
  2134. WASTEXT:
  2135.     LD    A,(HL)
  2136.     INC    HL
  2137.     AND    7FH        ; Mask to ascii
  2138.     CALL    CHKOKCTRLS
  2139.     JR    Z,TEXTCH
  2140.     CP    ' '        ; Some kind of ctrl char?
  2141.     JR    NC,TEXTCH
  2142.     INC    C        ; Non-text++
  2143.  
  2144. TEXTCH:    DJNZ    WASTEXT
  2145.  
  2146.     LD    A,C        ; Non-text count
  2147.     CP    10        ; If < 10/100 are non-text,
  2148.     JR    C,ISTEXT    ; It really is a text file
  2149.  
  2150. ;.....
  2151. ;
  2152. ; setup for a non-text file
  2153. ;
  2154. ISNONTEXT:
  2155.     XOR    A
  2156.     LD    (AFLAG),A
  2157.     CALL    TOGLA
  2158.  
  2159.     LD    HL,(FILELEN)
  2160.     LD    A,L
  2161.     OR    A
  2162.     LD    A,H        ; # of 256 byte pgs
  2163.     JR    Z,EVENPG    ; Even page boundary
  2164.     INC    A        ; For overage
  2165.  
  2166. EVENPG:    LD    (HIPG),A
  2167.  
  2168. ; set pg ptrs to every 256 bytes of buffer
  2169.  
  2170.     LD    B,A
  2171.     LD    DE,(BUFPTR)
  2172.     DEC    DE
  2173.     LD    HL,(@PTRTBL)
  2174.  
  2175. SETPP:    LD    (HL),E
  2176.     INC    HL
  2177.     LD    (HL),D
  2178.     INC    HL
  2179.     INC    D        ; += 256 bytes
  2180.     DJNZ    SETPP
  2181.  
  2182.     JP    STICKINEOF    ; Stick in eof adr for last pg finds
  2183.                 ; -  and print page 1
  2184.  
  2185. ;................................
  2186. ;                ;
  2187. CHKOKCTRLS:            ; Subr to chk for ctrl chars ok in a text file
  2188.     CP    TAB        ; Ret with Z set if tab,cr,lf, or ff
  2189.     RET    Z        ;
  2190.     CP    CR        ;
  2191.     RET    Z        ;
  2192.     CP    FF        ;
  2193.     RET    Z        ;
  2194.     CP    LF        ;
  2195.     RET    Z        ;
  2196.     CP    1AH        ;
  2197.     RET            ;
  2198. ;...............................;
  2199.  
  2200. ;.....
  2201. ;
  2202. ; Setup for a text file
  2203. ;
  2204. ; distinguish ws doc files by looking for 1st page break: 8ah
  2205. ; if prev ch is 0dh or 8dh, assume it to be ws doc
  2206. ;
  2207. ISTEXT:    LD    A,0FFH        ;
  2208.     LD    (AFLAG),A    ; Mark non-text flag false
  2209.     CALL    TOGLA        ;
  2210.     LD    (WSDOC),A    ;
  2211.  
  2212.     LD    HL,(BUFPTR)
  2213.     LD    BC,(FILELEN)
  2214.     LD    A,8AH        ; 1st possible ws doc pg break
  2215.     CPIR
  2216.     JP    PO,NOPGBRK    ; None found
  2217.     DEC    HL
  2218.  
  2219. STILLLF:
  2220.     DEC    HL        ; Back up to prev cr
  2221.     LD    A,(HL)
  2222.     AND    7FH
  2223.     CP    LF
  2224.     JR    Z,STILLLF    ; Skip if dbl sp
  2225.  
  2226.     CP    CR
  2227.     JR    NZ,NOPGBRK    ; 8ah not preceded by 0dh or 8dh
  2228.  
  2229. ; it's a real pg brk: go thru file and chg all 8ah to temp 0ah
  2230. ; push adrs on stk so we can restore later
  2231.  
  2232.     LD    A,0FFH
  2233.     LD    (WSDOC),A
  2234.  
  2235.     LD    HL,0
  2236.     PUSH    HL        ; Flag top of stk
  2237.  
  2238.     LD    HL,(BUFPTR)
  2239.     LD    BC,(FILELEN)
  2240.     LD    A,8AH
  2241.  
  2242. FIND8AHNEXT:
  2243.     CPIR            ; Look for 8ah to chg
  2244.     JP    PO,NOPGBRK    ; All 8ah chg to 0ah
  2245.     DEC    HL        ; HL now *8ah
  2246.     PUSH    HL        ; Save adr on stk for later
  2247.                 ; No stk overflow chking done??
  2248.     LD    (HL),LF        ; Chg to real lf
  2249.     INC    HL
  2250.     JR    FIND8AHNEXT
  2251.  
  2252. ; set pg ptrs to ch following every 22nd lf
  2253.  
  2254. NOPGBRK:
  2255.     LD    DE,(BUFPTR)    ;
  2256.     LD    HL,(@PTRTBL)    ;
  2257.     LD    (HL),E        ;
  2258.     INC    HL        ;
  2259.     LD    (HL),D        ;
  2260.     INC    HL        ;
  2261.     EX    DE,HL        ;
  2262.     LD    HL,(BUFPTR)    ;
  2263.  
  2264.     LD    BC,(FILELEN)    ; Get actual file len
  2265.     LD    IX,0        ; Pg ctr
  2266.  
  2267. SET1:    LD    A,(DISPLAY)    ; Usually every 22 lines
  2268.  
  2269. SET2:    PUSH    AF        ; Save line ctr
  2270.     LD    A,LF
  2271.     CPIR            ; Look for lf
  2272.     JP    PO,SETDONE    ; BC = 0 = last lf before eof
  2273.     POP    AF        ; Line ctr
  2274.     DEC    A        ; Is this the 22nd line?
  2275.     JR    NZ,SET2        ; Not a pg break
  2276.  
  2277. ; at pg break, store adr of start of next pg
  2278.  
  2279.     EX    DE,HL        ; DE=adr to store, HL=*ptrtbl
  2280.     LD    (HL),E        ; Store lo adr of pg ptr
  2281.     INC    HL
  2282.     LD    (HL),D        ; Store hi adr
  2283.     INC    HL
  2284.     EX    DE,HL        ; Rst ptrs
  2285.  
  2286.     INC    IX        ; Pg++
  2287.  
  2288. ; chk for > 255 pgs NOT implemented
  2289.  
  2290.     JR    SET1
  2291.  
  2292. SETDONE:
  2293.     POP    BC        ; B = line ctr fr stk
  2294.     LD    A,(DISPLAY)
  2295.     SUB    B        ; 22-last line
  2296.     JR    NZ,PARTIALPG    ;
  2297.     LD    A,B        ; Display - 1
  2298.     JR    NOPARTIALPG    ; This partial is really a full pg
  2299. PARTIALPG:            ;
  2300.     INC    IX        ; For last partial pg
  2301.  
  2302. NOPARTIALPG:
  2303.     LD    (LASTPGLINES),A    ; Moved down to here
  2304.     PUSH    IX        ; Pg ctr
  2305.     POP    HL
  2306.     LD    A,L        ; Max 255 pgs allowed
  2307.     LD    (HIPG),A    ; Save highest pg #
  2308.  
  2309. ; stick in eof adr for last pg finds
  2310.  
  2311.     LD    HL,(EOFADR)
  2312.     EX    DE,HL
  2313.  
  2314. STICKINEOF:
  2315.     LD    (HL),E
  2316.     INC    HL
  2317.     LD    (HL),D
  2318.  
  2319.     LD    A,(AFLAG)
  2320.     OR    A
  2321.     JR    NZ,PRPG1    ; Skip this text stuff if in non-text
  2322.  
  2323. ; if ws doc, restore 8ah removed before, adrs on stk
  2324.  
  2325.     LD    A,(WSDOC)
  2326.     OR    A
  2327.     JR    Z,PRPG1        ; Not ws doc
  2328.  
  2329. ; do the restore until we pop 0000 flag
  2330.  
  2331.     LD    B,8AH
  2332.  
  2333. POP8AHNEXT:
  2334.     POP    HL        ; Adr where 8ah was before
  2335.     LD    A,H
  2336.     OR    L        ; At top of stk flag?
  2337.     JR    Z,PRPG1        ; Yes, done
  2338.     LD    (HL),B        ; Replace 8ah
  2339.     JR    POP8AHNEXT
  2340.  
  2341. PRPG1:    LD    A,1
  2342.     LD    (PAGE),A    ; Force pg 1 & print it
  2343.  
  2344. ; print the current page
  2345.  
  2346. PRPG:    CALL    CLEARSCREEN
  2347.  
  2348. ; chk for pg # beyond eof
  2349.  
  2350.     LD    A,(HIPG)
  2351.     LD    B,A        ; B=hipg
  2352.     LD    A,(PAGE)
  2353.     CP    B        ; Pg # too big?
  2354.     JR    C,PGNUMOK    ; No
  2355.     LD    A,B
  2356.     LD    (PAGE),A    ; Else, set highest pg num
  2357.  
  2358. ; chk if doing hex/ascii dump
  2359.  
  2360. PGNUMOK:
  2361.     LD    A,(AFLAG)
  2362.     OR    A        ; Non-text mode?
  2363.     LD    A,(PAGE)
  2364.     JR    Z,PRTEXT    ; No, do text
  2365.     CALL    HEXASCII    ; Else, dump 256 bytes like ddt
  2366.     JP    GETCMD
  2367.  
  2368. PRTEXT:    LD    L,A
  2369.     LD    H,0
  2370.     DEC    HL        ; Pg 1 is ptd to by 0'th ptr
  2371.     ADD    HL,HL        ; *2 for word adr
  2372.     LD    DE,(@PTRTBL)    ;
  2373.     ADD    HL,DE        ; *start adr of pg we want
  2374.     LD    E,(HL)        ; Lo pg adr
  2375.     INC    HL
  2376.     LD    D,(HL)        ; Hi pg adr
  2377.     EX    DE,HL        ; HL = adr of pg we want
  2378.     ld    a,(NLINES)    ;
  2379.     LD    B,A        ; Lines/pg ctr, faster than cp adrs
  2380.     DEC    B
  2381.  
  2382. ; B has # of lines to dump
  2383.  
  2384. PUTNEXT:
  2385.     LD    A,(FOUND)
  2386.     OR    A        ; Are we marking found $?
  2387.     JR    Z,PUT1NEXT    ; No
  2388.  
  2389.     CALL    ATMATCHADR    ; Are we at the found $ yet?
  2390.     JR    NZ,PUT1NEXT    ; No
  2391.  
  2392. ; start hilite of found $
  2393.  
  2394.     PUSH    BC        ; Save line ctr
  2395.     CALL    ONHILITE    ;
  2396.     CALL    Z,USEALT    ; (if that failed, use alternate method)
  2397.  
  2398.     LD    A,(STRLEN)
  2399.     LD    B,A
  2400.  
  2401. ; dump ch of found $ in reverse video
  2402.  
  2403. INREVID:
  2404.     LD    A,(HL)
  2405.     INC    HL
  2406.     CALL    PUTC        ; In rev vid
  2407.     DJNZ    INREVID
  2408.  
  2409. ; stop hilite of found $
  2410.  
  2411.     CALL    OFFHILITE
  2412.     CALL    Z,USEALT
  2413.     XOR    A
  2414.     LD    (FOUND),A    ; Took care of that match
  2415.     PUSH    HL        ; Save buffer ptr
  2416.     CALL    FINDAGAIN    ; Look for next occur of find$
  2417.     POP    HL        ; Buffer ptr
  2418.     POP    BC        ; Line ctr
  2419.     JR    PUTNEXT
  2420.  
  2421. ; dump non-find $ chars
  2422.  
  2423. PUT1NEXT:
  2424.     LD    A,(HL)        ; Get char
  2425.     INC    HL        ; *char++
  2426.     AND    7FH        ; Mask in case ws doc
  2427.     CP    LF
  2428.     JR    Z,FOUNDLF
  2429.     CP    EOF        ; Is it eof?
  2430.     JR    Z,HITEOF
  2431.  
  2432. ; all truncation logic removed to putc:
  2433.  
  2434. SENDCH:    CALL    PUTC
  2435.     JR    PUTNEXT
  2436.  
  2437. FOUNDLF:
  2438.     DJNZ    SENDCH        ; Line ctr--
  2439.     LD    (CURRLINE),HL    ; *current line lf
  2440.  
  2441.     LD    A,(LINEBYLINE)
  2442.     OR    A        ; Going line by line?
  2443.     JR    Z,GETCMD    ; No
  2444.     LD    A,CR        ; Else, don't put pg #
  2445.     CALL    PUTC
  2446.     JR    GET1
  2447.  
  2448. HITEOF:    DEC    HL        ; Back up to prev lf
  2449.     LD    (CURRLINE),HL
  2450.  
  2451. SAYEOF:    LD    A,(INCOMPLETE)
  2452.     OR    A
  2453.     JR    Z,REALEOF
  2454.     CALL    WARNING        ; Too big to fit
  2455.     JR    GETCMD
  2456.  
  2457. REALEOF:
  2458.     CALL    MSG
  2459.     DB    CR,LF,'*** End of File ***',0
  2460.  
  2461. ; (Second half, QL.002 follows....)
  2462. ;..............................................................................
  2463.