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 / CPMHELP / HJELP.LBR / HJELP.AQ6 / HJELP.A86
Text File  |  2000-06-30  |  37KB  |  1,629 lines

  1.  
  2. ;    --------------------------------------------------------------
  3. ;             HJELP.ASM Copyright (C) 1984
  4. ;            Universidad Autonoma de Puebla
  5. ;
  6. ;    [HELP.xxx (SIG/M xxx.xx) Richard Conn]
  7. ;    [HELP8080.ASM (SIG/M 122.03) = original model]
  8. ;    [squeezed HELP files - Harold V. McIntosh, July 20, 1984]
  9. ;    ["L" backs up to panel 1 - 20 Jul 84 - HVM]
  10. ;    [Library files - 5 October 1984]
  11. ;    --------------------------------------------------------------
  12.  
  13. CR    equ        0DH
  14. VT    equ        0CH
  15. LF    equ        0AH
  16. HT    equ        09H
  17.  
  18. bdos    equ    0E0H            ;bdos interrupt
  19.  
  20.     org    0005H
  21. X0005    rb    0            ;memory end
  22.  
  23.     org    005CH
  24. tfcb    rb    0            ;CP/M's file control block
  25.  
  26.     org    0080H
  27. tbuf    rb    0            ;CP/M's I-O buffer
  28.  
  29.  
  30.     org    4000H
  31. bred    rb    0            ;red screen area
  32.  
  33.     org    6000H
  34. bgrn    rb    0            ;green screen area
  35.  
  36.     org    8000H            ;blue screen area
  37. bblu    rb    0
  38.  
  39. NH    equ    6            ;number of HELP file names to print per line
  40. ND    equ    10            ;maximum node depth
  41. NS    equ    9            ;bytes to save for panel markers
  42.  
  43. csiz    equ    257
  44. psiz    equ    50*NS            ;textpointer pushdown size
  45.  
  46. ;    -------------
  47.     org    0100H
  48. ;    -------------
  49.  
  50. begn:    mov    X0D31,sp        ;save stack
  51.     mov    al,tfcb+1        ;TFCB+1
  52.     cmp    al,' '
  53.     jz G001 ! jmp nnul ! G001:
  54.     mov    dx,(offset tuto)    ;'tutorial'
  55. ferm:    call    mssg
  56. gbye:    mov    sp,X0D31        ;save stack
  57.     mov    cl,0
  58.     mov    dl,0
  59.     int    bdos
  60.  
  61. nnul:    mov    al,X0005+2
  62.     sub    al,0AH
  63.     mov    X0C63,al        ;memory pages
  64.     mov    bx,(offset nbuf+1)    
  65.     mov    (byte ptr [bx]),' '
  66.     xor    al,al
  67.     mov    X0C71,al        ;level #
  68.     mov    dx,(offset X08BE)    ;'signon'
  69.     call    mssg            ;message to console
  70.     mov    al,tfcb+1
  71.     cmp    al,'('
  72.     jz G002 ! jmp loop ! G002:
  73.     mov    bx,(offset tbuf)    
  74.     mov    ch,[bx]
  75.     pushf ! inc bx ! popf    
  76.     xchg    dx,bx
  77.     mov    bx,(offset obuf)    
  78.     mov    optr,bx
  79.     call    miuc
  80.     mov    (byte ptr [bx]),00
  81.     mov    dx,(offset lohf)    ;'loading HELP file'
  82.     call    mssg
  83.     call    pafr
  84.     mov    bx,(offset nbuf+1)    
  85.     mov    al,[bx]
  86.     cmp    al,' '
  87.     jz G003 ! jmp ymbr ! G003:
  88.     mov    dx,(offset tfcb+1)    
  89.     mov    ch,8
  90.     call    miuc
  91.     call    phlp
  92.     jmp    loop
  93.  
  94. ymbr:    mov    bx,(offset nbuf+9)    
  95.     mov    al,[bx]
  96.     cmp    al,' '
  97.     jnz G004 ! call phlp ! G004:
  98.  
  99. ;    Loop.
  100.  
  101. loop:    mov    sp,X0D31        ;stack
  102.     mov    bx,(offset tfcb+9)    
  103.     mov    al,[bx]
  104.     cmp    al,' '
  105.     jnz G005 ! call phlp ! G005:
  106.     mov    bx,(offset tfcb)        ;TFCB
  107.     mov    (byte ptr [bx]),000H
  108.     mov    dx,(offset 000CH)    
  109.     add    bx,dx
  110.  
  111. ;    Zero out tail of FCB.
  112.  
  113.     mov    ch,018H        ;24
  114. X01C9:    mov    (byte ptr [bx]),000H
  115.     pushf ! inc bx ! popf    
  116.     dec    ch
  117.     jz G006 ! jmp X01C9 ! G006:
  118.  
  119.     mov    bx,(offset 0FFFFH)    
  120.     mov    mlen,bx
  121.  
  122. ldfi:    call    opef
  123.     call    sefl
  124.     mov    (byte ptr [bx]),1AH        ;^Z
  125.     call    desq
  126.     jmp    gogo
  127.  
  128. sefl:    mov    bx,(offset X0D33)        ;beginning of free memory
  129. sefm:    mov    al,X0C63
  130.     cmp    al,bh
  131.     jnz G007 ! jmp X04D1 ! G007:    ;'not enough room'
  132.     call    rerb
  133.     jnc G008 ! jmp sefn ! G008:
  134.     mov    [bx],al
  135.     pushf ! inc bx ! popf    
  136.     jmp    sefm
  137.  
  138. sefn:    mov    X0C6E,bx    ;ptr end of text
  139.     ret
  140.  
  141. ;    ------------------------------------
  142. ;    opef will open file even within .LBR
  143. ;    ofil will open a normal file
  144.  
  145. ;    Test for .LBR file.
  146.  
  147. opef:    mov    al,nbuf+1
  148.     cmp    al,' '
  149.     jnz G009 ! jmp ofil ! G009:
  150.  
  151. ;    -----------------------------------------
  152. ;    Open a .LBR file to the member specified
  153. ;    at nbuf+1 of the .LBR file referenced by
  154. ;    tfcb. Termination results if either item
  155. ;    cannot be found, otherwise the next read
  156. ;    will pick up the desired member.
  157. ;    ----------------------------------------
  158.  
  159. ;    Open .LBR file, read first record.
  160.  
  161. olbr:    mov    cl,15        ;(0F) open file
  162.     mov    dx,(offset tfcb)    
  163.     int bdos    
  164.  
  165.     inc    al
  166.     jz G010 ! jmp fopn ! G010:
  167.     mov    dx,(offset nlib)        ;'requested library not found'
  168.     jmp    ferm        ;send message to console
  169.  
  170. fopn:    mov    bx,(offset tfcb+32)    
  171.     mov    (byte ptr [bx]),00
  172.     mov    bx,(offset 0000)    
  173.     mov    mctr,bx    ;counter for tbuf
  174.     pushf ! dec bx ! popf    
  175.     mov    mlen,bx    ;length (records) of member
  176.  
  177.     call    afil        ;fill "A" buffer
  178.     mov    bx,abff+14        ;length of LBR dir
  179.     mov    mlen,bx    ;length (records) of member
  180.     add    bx,bx
  181.     add    bx,bx
  182.     mov    rlen,bx    ;length (32-byte lines) of directory
  183.  
  184. ;    Library member was requested, so look it up in directory.
  185.  
  186. tmem:    mov    bx,rlen        ;length (32-byte lines) of directory
  187.     pushf ! dec bx ! popf    
  188.     mov    rlen,bx    ;length (32-byte lines) of directory
  189.     mov    al,bh
  190.     or    al,bl
  191.     jz G011 ! jmp tmen ! G011:
  192.     mov    dx,(offset nfil)        ;'requested file not present'
  193.     call    ferm        ;message to console
  194.  
  195. tmen:    call    afil        ;read a directory line
  196.     mov    ch,11
  197.     mov    dx,(offset abuf+1)    
  198.     mov    bx,(offset nbuf+1)    ;member name buffer
  199.     call    ciuc        ;block compare
  200.     jz G012 ! jmp tmem ! G012:
  201.  
  202. ;    Record length and whether 'Q' in extension.
  203.  
  204.     mov    bx,abff+14
  205.     mov    mlen,bx    ;length (records) of member
  206.     mov    bx,(offset dens)        ;z/nz=un/squeezed
  207.     mov    (byte ptr [bx]),0
  208.     mov    al,abuf+10
  209.     cmp    al,'Q'
  210.     jz G013 ! jmp sefi ! G013:
  211.     dec    (byte ptr [bx])
  212.  
  213. ;    Advance to the proper section of the library.
  214. ;    This is not an elegant way to do it, but it avoids
  215. ;    computing with CP/M extents and record sizes.
  216.  
  217. sefi:    mov    cl,15        ;(0F) open file
  218.     mov    dx,(offset tfcb)    
  219.     int bdos    
  220.     xor    al,al
  221.     mov    tfcb+32,al
  222.  
  223. ;    Skip up to (but don't read) beginning of member.
  224.  
  225. sefj:    mov    bx,abff+12
  226.     mov    al,bh
  227.     or    al,bl
  228.     jnz G014 ! jmp sefk ! G014:
  229.     pushf ! dec bx ! popf    
  230.     mov    abff+12,bx
  231.     mov    cl,20        ;(14) read one record
  232.     mov    dx,(offset tfcb)    
  233.     int bdos    
  234.     jmp    sefj
  235.  
  236. sefk:    mov    bx,(offset 0000)    
  237.     mov    mctr,bx
  238.     ret
  239.  
  240. ;    Fill the "A" buffer, which holds .LBR directory lines.
  241.  
  242. afil:    mov    cl,20H
  243.     mov    bx,(offset abuf)    ;"A" buffer = line of LBR dir
  244. afim:    call    rerb
  245.     mov    [bx],al
  246.     pushf ! inc bx ! popf    
  247.     dec    cl
  248.     jz G015 ! jmp afim ! G015:
  249.     ret
  250.  
  251. ;    Read a byte from tbuf, replenishing as necessary.
  252. ;    Carry signifies End of File.
  253.  
  254. rerb:    push    bx
  255.     mov    bx,mctr        ;counter for tbuf
  256.     mov    al,bh
  257.     or    al,bl
  258.     stc
  259.     jnz G016 ! call rerx ! G016:    ;read one record
  260.     cmc
  261.     pushf ! dec bx ! popf    
  262.     mov    mctr,bx    ;counter for tbuf
  263.     mov    bx,mptr        ;pointer for tbuf
  264.     mov    al,[bx]
  265.     pushf ! inc bx ! popf    
  266.     mov    mptr,bx    ;pointer for tbuf
  267.     pop    bx
  268.     ret
  269.  
  270. ;    Read another record, but don't read past the number
  271. ;    allocated to the member. Likewise, we have to be careful
  272. ;    about an ASCII file which ends exactly on a record boundary.
  273.  
  274. rerx:    mov    bx,mlen        ;length (records) of member
  275.     mov    al,bh
  276.     or    al,bl
  277.     jnz G017 ! jmp rery ! G017:
  278.     pushf ! dec bx ! popf    
  279.     mov    mlen,bx    ;length (records) of member
  280.     push    cx
  281.     push    dx
  282.     mov    cl,20        ;(14) read one record
  283.     mov    dx,(offset tfcb)    
  284.     int bdos    
  285.     pop    dx
  286.     pop    cx
  287.     or    al,al
  288.     jz G018 ! jmp rery ! G018:
  289.     mov    bx,(offset tbuf)    
  290.     mov    mptr,bx    ;pointer for tbuf
  291.     mov    bx,(offset 0080H)    
  292.     stc
  293.     ret
  294.  
  295. ;    Squeezed files should end with a special end
  296. ;    of file marker (non-1-byte 100H), which has to be seen
  297. ;    to terminate the file. ASCII files normally terminate with
  298. ;    a ^Z, but this may be implicit if the file exactly fills a
  299. ;    record.
  300.  
  301. rery:    mov    bx,(offset tbuf)    
  302.     mov    mptr,bx
  303.     mov    (byte ptr [bx]),1AH        ;^Z
  304.     mov    bx,(offset 0001H)    
  305.     stc
  306.     cmc
  307.     ret
  308.  
  309. ;    Open an ordinary file. If not found, try for a squeezed
  310. ;    version instead.
  311.  
  312. ofil:    mov    bx,(offset 0000)    
  313.     mov    mctr,bx
  314.     pushf ! dec bx ! popf    
  315.     mov    mlen,bx
  316.     xor    al,al
  317.     mov    tfcb+32,al
  318.     mov    dens,al
  319. ofim:    mov    dx,(offset tfcb)        ;TFCB
  320.     mov    cl,15        ;(0F) open file
  321.     int bdos    ; B D O S
  322.     inc    al
  323.     jz G019 ! ret ! G019:
  324.     mov    bx,(offset tfcb+10)    
  325.     mov    al,[bx]
  326.     mov    (byte ptr [bx]),'Q'
  327.     cmp    al,[bx]
  328.     jz G020 ! jmp ofim ! G020:
  329.     mov    dx,(offset nfil)        ;'no file'
  330.     jmp    ferm
  331.  
  332. ;    ------------------------
  333.  
  334. ;    Decide whether it is a squeezed file.
  335.  
  336. desq:    mov    bx,(offset X0D33)    
  337.     mov    tptr,bx    ;text pointer
  338.     mov    xptr,bx    ;ptr to bgn of HELP file
  339.     mov    bx,(offset dens)        ;z/nz = normal/squeezed file
  340.     mov    (byte ptr [bx]),0
  341.     mov    bx,(offset wflg)        ;z/nz = no/byte left waiting by abyt
  342.     mov    (byte ptr [bx]),0
  343.     call    gbyt        ;one byte, direct or through onsq
  344.     cmp    al,076H
  345.     jz G021 ! jmp unjj ! G021:
  346.     call    gbyt        ;one byte, direct or through onsq
  347.     cmp    al,0FFH
  348.     jnz G022 ! jmp unii ! G022:
  349. unjj:    mov    bx,(offset X0D33)    
  350.     mov    tptr,bx    ;text pointer
  351.     ret
  352.  
  353. ;    Squeezed, so go through initialization
  354.  
  355. unii:    mov    bx,(offset rcnt)        ;repetition count
  356.     mov    (byte ptr [bx]),0
  357.     mov    bx,(offset roco)        ;bit rotation counter
  358.     mov    (byte ptr [bx]),1
  359.  
  360. ;    The "squeezed" marker is followed by a two-byte checksum,
  361. ;    which is the simple sum of all the one-byte characters in
  362. ;    the source file, carried as a two byte sum modulo 2**16.
  363.  
  364. rchk:    call    iwor        ;fetch two bytes from input stream
  365.     mov    cksm,bx    ;checksum
  366.  
  367. ;    Unsqueezed file name. It is an ASCII sequence, may be lower
  368. ;    case if SQ.COM received it in response to a prompt, ending
  369. ;    with a zero byte.
  370.  
  371. luup:    call    gbyt        ;fetch one byte from input stream
  372.     or    al,al
  373.     jz G023 ! jmp luup ! G023:
  374.  
  375. ;    Load code dictionary. It is preceded by its two-byte length,
  376. ;    and consists of a series of pairs of two-byte addresses. For
  377. ;    each bit in the code, select the first element (0) or the
  378. ;    second (1) element of the pair. If the pair is positive, it
  379. ;    is the table entry (code + 4*index) at which to continue with
  380. ;    the next bit. If the pair is negative, it is the complement
  381. ;    of the coded ASCII character (low order byte except for [end]).
  382.  
  383. ldic:    call    iwor        ;fetch two bytes from input stream
  384.     add    bx,bx
  385.     add    bx,bx
  386.     xchg    dx,bx
  387.     mov    bx,tptr        ;text pointer
  388.     mov    cptr,bx    ;Huffman code table
  389.     add    bx,dx
  390.     mov    tptr,bx    ;text pointer
  391.     mov    xptr,bx    ;ptr to bgn of HELP file
  392.     mov    bx,(offset dens)    
  393.     mov    (byte ptr [bx]),0FFH
  394.     ret
  395.  
  396. ;    Scan the HELP text to find and record the section headings.
  397.  
  398. gogo:    mov    bx,(offset pudl)    
  399.     mov    pptr,bx    ;pushdown pointer
  400.     mov    bx,(offset mopt)    
  401.     mov    (byte ptr [bx]),'A'        ;A, not @, to make <cmp m, jnc> work
  402.     call    abyt        ;lookahead one byte
  403.     cmp    al,':'
  404.     jnz G024 ! jmp gogu ! G024:
  405. gugu:    call    rbyt        ;fetch one byte
  406.     cmp    al,LF
  407.     jz G025 ! jmp gigi ! G025:
  408.     call    rbyt        ;fetch one byte
  409.     cmp    al,':'
  410.     jnz G026 ! jmp gege ! G026:
  411. gigi:    cmp    al,1AH
  412.     jnz G027 ! jmp gogu ! G027:
  413.     jmp    gugu
  414.  
  415. gege:    call    pupu
  416.     mov    bx,(offset mopt)        ;maximum option
  417.     inc    (byte ptr [bx])
  418.     jmp    gugu
  419.  
  420. gogu:    mov    bx,pptr        ;pushdown pointer
  421.     mov    zptr,bx    ;ptr to bgn of info sect
  422.     mov    bx,xptr        ;ptr to bgn of HELP file
  423.     mov    tptr,bx    ;text pointer
  424.     mov    bx,(offset roco)        ;bit rotation counter
  425.     mov    (byte ptr [bx]),1
  426.     mov    bx,(offset wflg)        ;z/nz = no/byte left waiting by abyt
  427.     mov    (byte ptr [bx]),0
  428.  
  429. ;    Display menu. Here we distinguish between a simple HELP
  430. ;    file which begins with a colon and has only one section,
  431. ;    and an indexed HELP file, which starts out with a list of
  432. ;    section descriptors.
  433.  
  434. X0342:    mov    sp,X0D31        ;stack
  435.     mov    al,000H
  436.     mov    X0C72,al        ;panel #
  437.     call    abyt            ;lookahead one byte
  438.     cmp    al,'!'
  439.     jnc G028 ! jmp xxxx ! G028:
  440.     cmp    al,':'
  441.     jz G029 ! jmp X036A ! G029:    ;show menu, request option
  442.     call    rbyt            ;fetch one byte
  443. xxxx:    call    X05E5            ;initialize new section
  444.     mov    al,X0C71        ;level #
  445.     or    al,al
  446.     jnz G030 ! jmp gbye ! G030:    ;return to CP/M
  447.     jmp    X07ED            ;go up one level
  448.  
  449. ;    Return to CP/M
  450.  
  451. ;    Show menu, request option.
  452.  
  453. X036A:    call    X058D        ;run through the menu
  454.     push    cx
  455.     call    crlf        ;CR,LF
  456.     call    X0859        ;type level I.D.
  457.     mov    dx,(offset X0C19)        ;'Type [^C]'
  458.     call    mssg        ;message to console
  459.     mov    dx,(offset X0C27)        ;'Type [level or root]'
  460.     mov    al,X0C71        ;level #
  461.     or    al,al
  462.     jnz G031 ! jmp X0387 ! G031:
  463.     call    mssg        ;message to console
  464. X0387:    mov    dx,(offset X0C37)        ;'Enter Selection'
  465.     call    mssg        ;message to console
  466.     pop    cx
  467.     call    X046B        ;read char from console
  468.     cmp    al,003H        ;^C
  469.     jnz G032 ! jmp gbye ! G032:    ;return to CP/M
  470.     cmp    al,'.'
  471.     jnz G033 ! jmp X07E1 ! G033:    ;back to root
  472.     cmp    al,'^'
  473.     jnz G034 ! jmp X07ED ! G034:    ;go up one level
  474.     lahf ! xchg ah,al ! push ax ! xchg ah,al
  475.     call    crlf        ;CR,LF
  476.     pop ax ! xchg ah,al ! sahf
  477.     mov    bx,(offset mopt)        ;maximum option
  478.     cmp    al,[bx]
  479.     jc G035 ! jmp X03AE ! G035:
  480.     sub    al,'@'
  481.     jnc G036 ! jmp X03AE ! G036:
  482.     jnz G037 ! jmp X03AE ! G037:
  483.     call    anth        ;access nth option
  484.     call    X05E5        ;initialize new section
  485.     jmp    X036A        ;show menu, request option
  486.  
  487. X03AE:    mov    dx,(offset X0AC6)        ;'Invalid Response'
  488.     call    mssg        ;message to console
  489.     jmp    X036A        ;show menu, request option
  490.  
  491. ;    Insert extension .HLP
  492.  
  493. phlp:    mov    (byte ptr [bx]),'H'
  494.     pushf ! inc bx ! popf    
  495.     mov    (byte ptr [bx]),'L'
  496.     pushf ! inc bx ! popf    
  497.     mov    (byte ptr [bx]),'P'
  498.     ret
  499.  
  500. ;    Read a character from the console.
  501.  
  502. X046B:    push    cx
  503.     push    dx
  504.     push    bx
  505.     mov    cl,1        ;(01) console input
  506.     int bdos    ; B D O S
  507.     pop    bx
  508.     pop    dx
  509.     pop    cx
  510.     lahf ! xchg ah,al ! push ax ! xchg ah,al
  511.     call    crlf        ;CR,LF
  512.     pop ax ! xchg ah,al ! sahf
  513. X047B:    and    al,07FH        ;upper case fold
  514.     cmp    al,'a'
  515.     jnc G038 ! ret ! G038:
  516.     cmp    al,'{'
  517.     jc G039 ! ret ! G039:
  518.     and    al,05FH
  519.     ret
  520.  
  521. ;    CR, LF.
  522.  
  523. crlf:    mov    al,CR
  524.     call    cona        ;char to console
  525.     mov    al,LF
  526.     jmp    cona        ;char to console
  527.  
  528. ;    Character to console.
  529.  
  530. cona:    lahf ! xchg ah,al ! push ax ! xchg ah,al
  531.     push    cx
  532.     push    dx
  533.     push    bx
  534.     mov    cl,2        ;(02) console output
  535.     mov    dl,al
  536.     int bdos    ; B D O S
  537.     pop    bx
  538.     pop    dx
  539.     pop    cx
  540.     pop ax ! xchg ah,al ! sahf
  541.     ret
  542.  
  543. ;    Message to Console.
  544.  
  545. mssg:    push    cx
  546.     push    dx
  547.     push    bx
  548.     mov    cl,9        ;(09) print string to $
  549.     int bdos    ; B D O S
  550.     pop    bx
  551.     pop    dx
  552.     pop    cx
  553.     ret
  554.  
  555. ;    Type file name.
  556.  
  557. tyfn:    mov    al,[bx]
  558.     cmp    al,' '
  559.     jnz G040 ! ret ! G040:
  560.     mov    ch,8
  561.     call    tyfo
  562.     mov    al,[bx]
  563.     cmp    al,' '
  564.     jnz G041 ! ret ! G041:
  565.     mov    al,'.'
  566.     call    cona
  567.     mov    ch,3
  568. tyfo:    mov    al,[bx]
  569.     pushf ! inc bx ! popf    
  570.     cmp    al,' '
  571.     jz G042 ! call cona ! G042:
  572.     dec    ch
  573.     jz G043 ! jmp tyfo ! G043:
  574.     ret
  575.  
  576. ;    Compare B bytes between (HL) and (DE)
  577.  
  578. ciuc:    xchg dx,bx ! mov al,[bx] ! xchg dx,bx
  579.     cmp    al,[bx]
  580.     jz G044 ! ret ! G044:
  581.     pushf ! inc dx ! popf    
  582.     pushf ! inc bx ! popf    
  583.     dec    ch
  584.     jz G045 ! jmp ciuc ! G045:
  585.     ret
  586.  
  587. ;    Move B bytes from (DE) to (HL).
  588.  
  589. miuc:    xchg dx,bx ! mov al,[bx] ! xchg dx,bx
  590.     mov    [bx],al
  591.     pushf ! inc dx ! popf    
  592.     pushf ! inc bx ! popf    
  593.     dec    ch
  594.     jz G046 ! jmp miuc ! G046:
  595.     ret
  596.  
  597. ;    Move B bytes from (HL) to (DE)
  598.  
  599. mduc:    pushf ! dec bx ! popf    
  600.     pushf ! dec dx ! popf    
  601.     mov    al,[bx]
  602.     xchg dx,bx ! mov [bx],al ! xchg dx,bx
  603.     dec    ch
  604.     jz G047 ! jmp mduc ! G047:
  605.     ret
  606.  
  607. ;    Initialize pudl.
  608.  
  609. izpu:    mov    ch,NS
  610.     mov    dx,(offset lach)    
  611.     mov    bx,zptr        ;ptr to bgn of info sect
  612.     call    miuc
  613.     mov    yptr,bx    ;zptr+NS
  614.     mov    pptr,bx    ;pushdown pointer
  615.     mov    bx,(offset X0C72)        ;panel #
  616.     mov    (byte ptr [bx]),1
  617.     ret
  618.  
  619. ;    Restore to the head of pudl.
  620.  
  621. rspu:    mov    ch,NS
  622.     mov    bx,yptr        ;zptr+NS
  623.     mov    pptr,bx    ;pushdown pointer
  624.     mov    dx,(offset lach+NS)    
  625.     call    mduc
  626.     mov    bx,(offset X0C72)        ;panel #
  627.     mov    (byte ptr [bx]),0
  628.     ret
  629.  
  630. ;    Access nth option.
  631.  
  632. anth:    mov    dl,al
  633.     mov    dh,0
  634.     mov    bl,dl
  635.     mov    bh,dh
  636.     add    bx,bx
  637.     add    bx,bx
  638.     add    bx,bx
  639.     add    bx,dx
  640.     mov    dx,(offset pudl)    
  641.     add    bx,dx
  642.     mov    dx,(offset lach+NS)    
  643.     mov    ch,NS
  644.     call    mduc
  645.     mov    bx,zptr        ;ptr to bgn of info sect
  646.     mov    pptr,bx    ;pushdown pointer
  647.     mov    bx,(offset X0C72)    
  648.     mov    (byte ptr [bx]),1
  649.     ret
  650.  
  651. ;    Push state onto pudl.
  652.  
  653. pupu:    mov    bx,pptr        ;pushdown pointer
  654.     mov    dx,(offset pudl+psiz)    
  655.     mov    al,bl
  656.     sub    al,dl
  657.     mov    al,bh
  658.     sbb    al,dh
  659.     jc G048 ! ret ! G048:
  660.     mov    ch,NS
  661.     mov    dx,(offset lach)    
  662.     call    miuc
  663.     mov    pptr,bx    ;pushdown pointer
  664.     mov    bx,(offset X0C72)        ;panel #
  665.     inc    (byte ptr [bx])
  666.     ret
  667.  
  668. ;    Pop state from pudl.
  669.  
  670. popu:    mov    bx,zptr
  671.     xchg    dx,bx
  672.     mov    bx,pptr        ;pushdown pointer
  673.     mov    al,dl
  674.     sub    al,bl
  675.     mov    al,dh
  676.     sbb    al,bh
  677.     jc G049 ! ret ! G049:
  678.     mov    ch,NS
  679.     mov    dx,(offset lach+NS)    
  680.     call    mduc
  681.     mov    pptr,bx    ;pushdown pointer
  682.     mov    bx,(offset X0C72)        ;panel #
  683.     mov    al,[bx]
  684.     or    al,al
  685.     jnz G050 ! ret ! G050:
  686.     dec    (byte ptr [bx])
  687.     ret
  688.  
  689. X04D1:    mov    dx,(offset X0BDC)        ;'Not Enough Room'
  690.     jmp    ferm
  691.  
  692. onsq:    mov    al,rcnt        ;repetition count
  693.     or    al,al
  694.     jz G051 ! jmp onsr ! G051:
  695.     call    dnch        ;decode next character
  696.     jnc G052 ! jmp vchk ! G052:    ;verify the checksum
  697.     cmp    al,090H        ;repeat last character
  698.     jz G053 ! jmp onsu ! G053:    ;normal character
  699.     call    dnch        ;decode next character
  700.     or    al,al
  701.     jnz G054 ! jmp onss ! G054:
  702.     dec    al
  703. onsr:    dec    al
  704.     mov    rcnt,al    ;repetition count
  705.     mov    al,lach
  706.     jmp    achk
  707.  
  708. onss:    mov    al,090H
  709.     jmp    achk
  710.  
  711. onsu:    mov    lach,al    ;last character typed
  712.     jmp    achk
  713.  
  714. ;    Decode next character.
  715.  
  716. dnch:    mov    bx,cptr        ;Huffman code table
  717. dncr:    call    ibit        ;read next bit
  718.     jc G055 ! jmp dncs ! G055:    ;skip for 1, stay for 0
  719.     pushf ! inc bx ! popf    
  720.     pushf ! inc bx ! popf    
  721. dncs:    mov    dl,[bx]    ;get next offset
  722.     pushf ! inc bx ! popf    
  723.     mov    dh,[bx]
  724.     mov    al,dh
  725.     cmp    al,0FEH        ;FEFF means [end]
  726.     jnz G056 ! jmp dnct ! G056:
  727.     or    al,al
  728.     js G057 ! jmp dncu ! G057:    ;p means new offset
  729.     mov    al,dl    ;m means complemented char
  730.     not    al
  731.     stc
  732.     cmc
  733.     ret
  734.  
  735. dnct:    stc    ;flag [end] with carry bit
  736.     ret
  737.  
  738. ;    Calculate <code>+4*<offset>.
  739.  
  740. dncu:    mov    bx,cptr        ;Huffman code table
  741.     add    bx,dx
  742.     add    bx,dx
  743.     add    bx,dx
  744.     add    bx,dx
  745.     jmp    dncr
  746.  
  747. ;    Read one bit at a time.
  748.  
  749. ibit:    push    bx
  750.     mov    bx,(offset roco)        ;bit rotation counter
  751.     dec    (byte ptr [bx])
  752.     jz G058 ! jmp ibiu ! G058:
  753.     mov    (byte ptr [bx]),8
  754.     call    ibyt        ;fetch one byte from input stream
  755.     mov    roby,al    ;rotating byte
  756. ibiu:    mov    al,roby        ;rotating byte
  757.     rcr    al,1
  758.     mov    roby,al    ;rotating byte
  759.     pop    bx
  760.     ret
  761.  
  762. ;    Read one word.
  763.  
  764. iwor:    call    ibyt        ;fetch one byte from input stream
  765.     mov    bl,al
  766.     push    bx
  767.     call    ibyt        ;fetch one byte from input stream
  768.     pop    bx
  769.     mov    bh,al
  770.     ret
  771.  
  772. ;    Accumulate checksum.
  773.  
  774. achk:    mov    bx,(offset cksm)    
  775.     mov    ch,al
  776.     mov    al,[bx]
  777.     sub    al,ch
  778.     mov    [bx],al
  779.     pushf ! inc bx ! popf    
  780.     mov    al,[bx]
  781.     sbb    al,0
  782.     mov    [bx],al
  783.     mov    al,ch
  784.     stc
  785.     cmc
  786.     ret
  787.  
  788. ;    Verify the checksum.
  789.  
  790. vchk:    mov    bx,cksm        ;checksum
  791.     mov    al,bl
  792.     or    al,bh
  793.     stc
  794.     jnz G059 ! ret ! G059:    ;return to CP/M
  795.     mov    dx,(offset chno)        ;'Checksum failure.'
  796.     jmp    ferm        ;fatal error message
  797.  
  798. abyt:    push    bx
  799.     mov    bx,(offset wflg)        ;z/nz = no/byte left waiting by abyt
  800.     mov    al,[bx]
  801.     or    al,al
  802.     jnz G060 ! jmp abyy ! G060:
  803.     mov    al,wbyt        ;byte left waiting by abyt
  804.     jmp    abyr
  805. abyy:    dec    (byte ptr [bx])
  806.     call    gbyt        ;one byte, direct or through onsq
  807.     mov    wbyt,al    ;byte left waiting by abyt
  808. abyr:    pop    bx
  809.     ret
  810.  
  811. rbyt:    mov    al,wflg        ;z/nz = no/byte left waiting by abyt
  812.     or    al,al
  813.     jnz G061 ! jmp gbyt ! G061:    ;one byte, direct or through onsq
  814.     mov    al,0
  815.     mov    wflg,al    ;z/nz = no/byte left waiting by abyt
  816.     mov    al,wbyt        ;byte left waiting by abyt
  817.     ret
  818.  
  819. gbyt:    mov    al,dens        ;one byte, direct or through onsq
  820.     or    al,al
  821.     jnz G062 ! jmp ibyt ! G062:
  822.     push    bx
  823.     call    onsq        ;one byte from squeezed file
  824.     pop    bx
  825.     ret
  826.  
  827. ibyt:    push    bx    ;fetch byte from the input stream
  828.     push    dx
  829.     mov    bx,X0C6E        ;ptr end of text
  830.     xchg    dx,bx
  831.     mov    bx,tptr        ;text pointer
  832.     mov    al,bl
  833.     sub    al,dl
  834.     mov    al,bh
  835.     sbb    al,dh
  836.     mov    al,[bx]
  837.     pushf ! inc bx ! popf    
  838.     mov    tptr,bx    ;text pointer
  839.     cmc
  840.     pop    dx
  841.     pop    bx
  842.     ret
  843.  
  844. ;    Type line, solicit option.
  845.  
  846. X04DA:    call    rbyt        ;fetch one byte
  847.     cmp    al,CR
  848.     jnz G063 ! jmp X04F4 ! G063:    ;type options at bottom of panel
  849.     cmp    al,LF
  850.     jnz G064 ! jmp X04F5 ! G064:    ;type options at bottom of panel
  851.     cmp    al,01AH        ;^Z
  852.     jnz G065 ! jmp X04F5 ! G065:    ;type options at bottom of panel
  853.     call    cona        ;char to console
  854.     jmp    X04DA        ;type line, solicit option
  855.  
  856. ;    Type the options at bottom of panel.
  857. ;    Entry point according to how line ended.
  858.  
  859. X04F4:    call    rbyt        ;decomission following LF
  860. X04F5:    call    crlf        ;CR,LF
  861.     mov    bx,(offset X0C6B)        ;console remaining lines
  862.     dec    (byte ptr [bx])
  863.     jz G066 ! ret ! G066:
  864.  
  865. ;    Solicit options (without marking or incrementing line).
  866.  
  867. X0504:    call    X0859        ;type level I.D.
  868.     mov    dx,(offset X097A)        ;'^C = Exit'
  869.     call    mssg        ;message to console
  870. X050D:    mov    dx,(offset X0983)        ;'[level, root]'
  871.     mov    al,X0C71        ;level #
  872.     or    al,al
  873.     jnz G067 ! jmp X0521 ! G067:
  874.     call    mssg        ;message to console
  875. X0521:    mov    dx,(offset X0993)        ;'[option list]'
  876.     call    mssg        ;message to console
  877.     call    X046B        ;read char from console
  878.     mov    char,al    ;char read from console
  879.     cmp    al,'M'
  880.     jz G068 ! jmp pnla ! G068:
  881.     jmp    X0342        ;display menu
  882.  
  883. pnla:    cmp    al,003H        ;^C
  884.     jz G069 ! jmp pnlb ! G069:
  885.     jmp    gbye        ;return to CP/M
  886.  
  887. pnlb:    cmp    al,'P'
  888.     jz G070 ! jmp pnlc ! G070:
  889.     jmp    X06FE        ;fulfil PRINT request
  890.  
  891. pnlc:    cmp    al,'.'
  892.     jz G071 ! jmp pnld ! G071:
  893.     jmp    X07E1        ;back to root
  894.  
  895. pnld:    cmp    al,'^'
  896.     jz G072 ! jmp pnle ! G072:
  897.     jmp    X07ED        ;go up one level
  898.  
  899. pnle:    cmp    al,'L'
  900.     jz G073 ! jmp pnlf ! G073:
  901.     call    popu
  902.     call    popu
  903.     jmp    pnlg
  904.  
  905. pnlf:    cmp    al,'S'
  906.     jz G074 ! jmp pnlg ! G074:
  907.     call    rspu        ;restore start of info section
  908. pnlg:    call    pupu        ;save reference to section head
  909.     call    X0587        ;reset line count
  910.     jmp    crlf        ;CR,LF
  911.  
  912. ;    Reset line count.
  913.  
  914. X0587:    mov    al,23        ;lines per screen panel
  915.     mov    X0C6B,al    ;console remaining lines
  916.     ret
  917.  
  918. ;    Run through the menu.
  919.  
  920. X058D:    mov    al,000H
  921.     mov    X0C72,al    ;panel #
  922.     mov    bx,xptr        ;ptr to bgn of HELP file
  923.     mov    tptr,bx    ;text pointer
  924.     mov    bx,(offset roco)        ;bit rotation counter
  925.     mov    (byte ptr [bx]),1
  926.     mov    bx,(offset wflg)        ;z/nz = no/byte left waiting by abyt
  927.     mov    (byte ptr [bx]),0
  928.     call    X0587        ;reset line count
  929.     mov    bx,(offset X0C6B)        ;console remaining lines
  930.     dec    (byte ptr [bx])
  931.     mov    al,'A'
  932.     mov    X0C68,al    ;option letter
  933.     mov    dx,(offset X0954)        ;'Selections are ...'
  934.     call    mssg        ;message to console
  935.     mov    cl,000H
  936. X05AC:    call    abyt        ;lookahead one byte
  937.     cmp    al,':'
  938.     jnz G075 ! jmp X05D4 ! G075:    ;finish panel w/CR,LF's
  939.     cmp    al,01AH        ;^Z
  940.     jnz G076 ! jmp gbye ! G076:    ;return to CP/M
  941.     inc    cl
  942.     mov    al,X0C68        ;option letter
  943.     call    cona        ;char to console
  944.     inc    al
  945.     mov    X0C68,al    ;option letter
  946.     mov    al,'.'
  947.     call    cona        ;char to console
  948.     mov    al,' '
  949.     call    cona        ;char to console
  950.     call    X04DA        ;type line, solicit option
  951.     jmp    X05AC
  952.  
  953. ;    Finish out panel with CR, LF's.
  954.  
  955. X05D4:    mov    al,X0C6B        ;console remaining lines
  956.     mov    ch,al
  957.     or    al,al
  958.     jnz G077 ! ret ! G077:
  959. X05DD:    call    crlf        ;CR,LF
  960.     dec    ch
  961.     jz G078 ! jmp X05DD ! G078:
  962.     ret
  963.  
  964. ;    A loop which will print out an information section. It calls
  965. ;    X04DA, which will count out lines as it types them. If the
  966. ;    line it has just typed is the last one of the panel, it
  967. ;    will pause for the panel to be read, having solicited some
  968. ;    indication of whether it should procede, repeat the last panel,
  969. ;    go back to the beginning, or go back to the menu.
  970.  
  971. X05E5:    call    X075D        ;is section disk file?
  972.     call    izpu
  973.     call    X0587        ;reset line count
  974. X05FA:    call    abyt        ;lookahead one byte
  975.     cmp    al,01AH        ;^Z
  976.     jnz G079 ! jmp X0624 ! G079:    ;mark panel, type legend, read option
  977.     cmp    al,':'
  978.     jnz G080 ! jmp X0624 ! G080:    ;mark panel, type legend, read option
  979.     cmp    al,VT        ;form feed
  980.     jnz G081 ! jmp X05FB ! G081:
  981.     call    X04DA
  982.     jmp    X05FA
  983.  
  984. X05FB:    call    rbyt        ;fetch one byte
  985.     mov    al,X0C6B        ;console remaining lines
  986. X061A:    lahf ! xchg ah,al ! push ax ! xchg ah,al
  987.     call    X04F5        ;type options at bottom of panel
  988.     pop ax ! xchg ah,al ! sahf
  989.     dec    al
  990.     jz G082 ! jmp X061A ! G082:
  991.     jmp    X05FA
  992.  
  993. ;    Mark panel, type legend, select option.
  994.  
  995. X0624:    call    rbyt        ;fetch one byte
  996. X0628:    call    crlf        ;CR,LF
  997.     mov    bx,(offset X0C6B)        ;console remaining lines
  998.     dec    (byte ptr [bx])
  999.     jz G083 ! jmp X0628 ! G083:
  1000. X0635:    call    X0859        ;type level I.D.
  1001.     mov    dx,(offset X0976)        ;'EOI & ^C'
  1002.     call    mssg        ;message to console
  1003.     call    X050D
  1004.     mov    al,char        ;char read from console
  1005.     cmp    al,'L'
  1006.     jnz G084 ! jmp X05FA ! G084:
  1007.     cmp    al,'S'
  1008.     jnz G085 ! jmp X05FA ! G085:
  1009.     cmp    al,'P'
  1010.     jnz G086 ! jmp X05FA ! G086:
  1011.     ret
  1012.  
  1013. ;    Send line to LST:, check for interrupt request.
  1014.  
  1015. X06B3:    call    rbyt        ;fetch one byte
  1016.     cmp    al,CR
  1017.     jnz G087 ! jmp X06CE ! G087:    ;list CR, LF's at end of line
  1018.     cmp    al,LF
  1019.     jnz G088 ! jmp X06CF ! G088:    ;list CR, LF's at end of line
  1020.     cmp    al,01AH        ;^Z
  1021.     jnz G089 ! jmp X06CF ! G089:    ;list CR, LF's at end of line
  1022.     call    X06E4        ;list output, read status
  1023.     jz G090 ! jmp X06B3 ! G090:    ;line to LST:
  1024.     ret
  1025.  
  1026. ;    Type CR, LF at end of line. Entry point according
  1027. ;    to whether CR, LF, or ^Z was encountered.
  1028.  
  1029. X06CE:    call    rbyt        ;decomission following LF
  1030. X06CF:    mov    al,CR
  1031.     call    X06E4        ;list output, read status
  1032.     jnz G091 ! ret ! G091:    ;to catch a ^C between CR, LF
  1033.     mov    al,LF
  1034. X06E4:    push    bx
  1035.     push    dx
  1036.     push    cx
  1037.     mov    dl,al
  1038.     mov    cl,5        ;(05) list output
  1039.     int bdos    ; B D O S
  1040.     mov    dl,0FFH
  1041.     mov    cl,6        ;(06) direct console I/O
  1042.     int bdos    ; B D O S
  1043.     pop    cx
  1044.     pop    dx
  1045.     pop    bx
  1046.     cmp    al,003H
  1047.     ret
  1048.  
  1049. ;    Respond to PRINT request.
  1050.  
  1051. X06FE:    mov    dx,(offset X09DE)        ;'Set Top-of-Form'
  1052.     call    mssg        ;message to console
  1053.     xor    al,al
  1054.     mov    X0C61,al    ;z/nz = panel/section (P)
  1055.     call    popu
  1056.     call    pupu
  1057.     call    X046B        ;read char from console
  1058.     cmp    al,003H        ;^Z
  1059.     jnz G092 ! jmp X071B ! G092:
  1060.     cmp    al,'S'
  1061.     jnz G093 ! jmp X0718 ! G093:
  1062.     call    rspu
  1063.     call    pupu
  1064.     mov    al,0FFH
  1065.     mov    X0C61,al    ;z/nz = panel/section (P)
  1066. X0718:    call    X0730
  1067. X071B:    call    popu
  1068.     jmp    pnlg
  1069.  
  1070. X0730:    mov    dx,(offset X09B2)        ;'Printing in Progress ...'
  1071.     call    mssg        ;message to console
  1072.     call    X0587        ;reset line count
  1073. X0739:    call    X06B3        ;line to LST:
  1074.     cmp    al,003H        ;^C
  1075.     jnz G094 ! ret ! G094:
  1076.     call    abyt        ;lookahead one byte
  1077.     cmp    al,01AH        ;^Z
  1078.     jnz G095 ! ret ! G095:
  1079.     cmp    al,':'
  1080.     jnz G096 ! ret ! G096:
  1081.     cmp    al,VT        ;Form Feed
  1082.     jnz G097 ! call X06CF ! G097:    ;list CR, LF's at end of line
  1083.     mov    al,X0C61        ;z/nz = panel/section (P)
  1084.     or    al,al
  1085.     jz G098 ! jmp X0739 ! G098:
  1086.     mov    bx,(offset X0C6B)        ;console remaining lines
  1087.     dec    (byte ptr [bx])
  1088.     jz G099 ! jmp X0739 ! G099:
  1089.     ret
  1090.  
  1091. ;    Check whether section is a disk file.
  1092.  
  1093. X075D:    call    abyt        ;lookahead one byte
  1094.     cmp    al,':'
  1095.     jz G100 ! ret ! G100:
  1096.     call    rbyt
  1097.     mov    al,X0C71        ;level #
  1098.     cmp    al,ND        ;maximum node depth
  1099.     jz G101 ! jmp X0776 ! G101:    ;read file, type name
  1100.     mov    dx,(offset X0B4A)        ;'Node Limit'
  1101.     call    mssg        ;message to console
  1102.     jmp    gbye        ;return to CP/M
  1103.  
  1104. ;    Type name, read file.
  1105.  
  1106. X0776:    call    X0845        ;locate file name on stack
  1107.     mov    dx,(offset tfcb+1)    ;TFCB+1
  1108.     mov    ch,11        ;bytes in file name
  1109.     call    miuc
  1110.     mov    ch,11
  1111.     mov    dx,(offset nbuf+1)    
  1112.     call    miuc
  1113.     mov    bx,(offset X0C71)        ;level #
  1114.     inc    (byte ptr [bx])
  1115.  
  1116. ;    If there can be several color overlays and the like,
  1117. ;    we have to set aside the panel defining them so that
  1118. ;    the space it occupies can be used for loading.
  1119.  
  1120.     mov    ch,0
  1121.     mov    dx,(offset 0000)    
  1122.     mov    bx,(offset obuf)    
  1123.     mov    optr,bx
  1124. olay:    call    rbyt
  1125.     jnc G102 ! jmp loaz ! G102:
  1126.     cmp    al,1AH        ;^Z
  1127.     jnz G103 ! jmp loaz ! G103:
  1128.     cmp    al,':'
  1129.     jz G104 ! jmp olax ! G104:
  1130.     mov    al,LF
  1131.     cmp    al,ch
  1132.     jnz G105 ! jmp loaz ! G105:
  1133.     mov    al,':'
  1134. olax:    mov    [bx],al
  1135.     mov    ch,al
  1136.     pushf ! inc dx ! popf    
  1137.     pushf ! inc bx ! popf    
  1138.     cmp    al,':'
  1139.     jz G106 ! jmp olay ! G106:
  1140.     call    rbyt
  1141.     cmp    al,':'
  1142.     jz G107 ! jmp loaz ! G107:
  1143.     jmp    olay
  1144.  
  1145. loaz:    xchg    dx,bx
  1146.     mov    octr,bx
  1147.     jmp    colo
  1148.  
  1149. ;    Subroutine which will read out the bytes saved from
  1150. ;    the instruction panel when overlays are to be used.
  1151.  
  1152. obyt:    push    bx
  1153. ;    lhld    octr
  1154. ;    mov    a,h
  1155. ;    ora    l
  1156. ;    jz    obyz
  1157. ;    dcx    h
  1158. ;    shld    octr
  1159.     mov    bx,optr
  1160.     mov    al,[bx]
  1161.     pushf ! inc bx ! popf    
  1162.     mov    optr,bx
  1163. obyz:    pop    bx
  1164.     ret
  1165.  
  1166. ;    Load any requested overlays.
  1167.  
  1168. colo:    mov    dx,(offset lohf)        ;'Loading HELP File'
  1169.     call    mssg        ;message to console
  1170.  
  1171.     mov    bx,(offset dest)    
  1172.     mov    (byte ptr [bx]),' '
  1173.  
  1174.     call    pafr        ;parse file reference.
  1175.     jmp    coov        ;execute it
  1176.  
  1177. ;    Parse a file reference, and type it.
  1178.  
  1179. pafr:    mov    al,' '
  1180.     mov    nbuf+1,al
  1181. paff:    call    obyt
  1182.     cmp    al,' '
  1183.     jnz G108 ! jmp paff ! G108:
  1184.     cmp    al,'('
  1185.     jnz G109 ! jmp ylbr ! G109:
  1186.     mov    bx,(offset tfcb)    
  1187.     call    pars
  1188.     cmp    al,')'
  1189.     jnz G110 ! jmp wlbr ! G110:
  1190.     mov    bx,(offset tfcb+1)    
  1191.     jmp    tyfn
  1192.  
  1193. ylbr:    mov    bx,(offset tfcb)    
  1194.     call    part
  1195. wlbr:    mov    bx,(offset nbuf)    
  1196.     call    part
  1197.  
  1198. ;    Insert extension .LBR if none was given.
  1199.  
  1200.     mov    bx,(offset tfcb+9)    
  1201.     mov    al,[bx]
  1202.     cmp    al,' '
  1203.     jz G111 ! jmp ylbs ! G111:
  1204.     mov    (byte ptr [bx]),'L'
  1205.     pushf ! inc bx ! popf    
  1206.     mov    (byte ptr [bx]),'B'
  1207.     pushf ! inc bx ! popf    
  1208.     mov    (byte ptr [bx]),'R'
  1209.  
  1210. ylbs:    mov    al,'('
  1211.     call    cona
  1212.     mov    bx,(offset tfcb+1)    
  1213.     call    tyfn
  1214.     mov    al,')'
  1215.     call    cona
  1216.     mov    al,' '
  1217.     call    cona
  1218.     mov    bx,(offset nbuf+1)    
  1219.     jmp    tyfn
  1220.  
  1221. ;    Check for color overlay.
  1222.  
  1223. coov:    mov    bx,(offset dest)    
  1224.     mov    al,[bx]
  1225.     mov    (byte ptr [bx]),' '
  1226.     cmp    al,[bx]
  1227.     jz G112 ! jmp coow ! G112:
  1228.     call    crlf
  1229.     jmp    loop        ;loop
  1230.  
  1231. coow:    cmp    al,'R'
  1232.     jz G113 ! jmp gree ! G113:
  1233.     call    opef
  1234.     call    sefl
  1235.     call    desq
  1236.     mov    bx,(offset bred)        ;red screen area
  1237.     call    lcbf
  1238.     jmp    colo
  1239.  
  1240. gree:    cmp    al,'G'
  1241.     jz G114 ! jmp blue ! G114:
  1242.     call    opef
  1243.     call    sefl
  1244.     call    desq
  1245.     mov    bx,(offset bgrn)        ;green screen area
  1246.     call    lcbf
  1247.     jmp    colo
  1248.  
  1249. blue:    cmp    al,'B'
  1250.     jz G115 ! jmp colo ! G115:
  1251.     call    opef
  1252.     call    sefl
  1253.     call    desq
  1254.     mov    bx,(offset bblu)        ;blue screen area
  1255.     call    lcbf
  1256.     jmp    colo
  1257.  
  1258. ;    Load color buffer. HL designates the buffer.
  1259.  
  1260. lcbf:    mov    al,oper
  1261.     cmp    al,'='
  1262.     jz G116 ! jmp ocbf ! G116:
  1263. ldbf:    call    rbyt
  1264.     jnc G117 ! jmp colo ! G117:
  1265.     mov    [bx],al
  1266.     pushf ! inc bx ! popf    
  1267.     jmp    ldbf
  1268.  
  1269. ocbf:    cmp    al,'+'
  1270.     jz G118 ! jmp xcbf ! G118:
  1271. odbf:    call    rbyt
  1272.     jnc G119 ! jmp colo ! G119:
  1273.     or    al,[bx]
  1274.     mov    [bx],al
  1275.     pushf ! inc bx ! popf    
  1276.     jmp    odbf
  1277.  
  1278. xcbf:    cmp    al,'-'
  1279.     jz G120 ! jmp colo ! G120:
  1280. xdbf:    call    rbyt
  1281.     jnc G121 ! jmp colo ! G121:
  1282.     xor    al,[bx]
  1283.     mov    [bx],al
  1284.     pushf ! inc bx ! popf    
  1285.     jmp    xdbf
  1286.  
  1287. ;    ---------------------------------------------
  1288. ;    Parse disk, filename, extension. HL points to
  1289. ;    FCB, new characters arrive via <call obyt>.
  1290. ;    ---------------------------------------------
  1291.  
  1292. ;    Pass over leading blanks.
  1293. ;      <call part> to ignore A
  1294. ;      <call pars> to test A first
  1295.  
  1296. part:    call    obyt
  1297. pars:    cmp    al,' '
  1298.     jz    part
  1299.  
  1300.     call    term
  1301.     jnz G123 ! ret ! G123:        ;null buffer
  1302.  
  1303. ;    Insert filename field. If a disk unit is specified,
  1304. ;    record it in the first byte of the FCB, then try again
  1305. ;    for the filename. Likewise, if a destination is given,
  1306. ;    note it.
  1307.  
  1308.     mov    (byte ptr [bx]),0
  1309. infn:    inc    bx
  1310. infi:    push    bx
  1311.     mov    ch,8
  1312.     call    stof
  1313.     call    oprn
  1314.     jnz    dsku
  1315.     mov    oper,al
  1316.     pop    bx
  1317.     mov    al,[bx]
  1318.     mov    dest,al
  1319.     call    obyt
  1320.     cmp    al,'('
  1321.     jnz    infi
  1322.     call    obyt
  1323.     jmp    infi
  1324.  
  1325. dsku:    cmp    al,':'
  1326.     jnz    inxt
  1327.     pop    bx
  1328.     mov    al,[bx]
  1329.     sub    al,'@'
  1330.     mov    [bx],al
  1331.     dec    bx
  1332.     call    obyt
  1333.     jmp    infn
  1334.  
  1335. ;    Insert extension field.
  1336.  
  1337. inxt:    inc    sp
  1338.     inc    sp
  1339.     mov    ch,3
  1340.     cmp    al,'.'
  1341.     jnz    shof
  1342.     call    obyt
  1343.  
  1344. ;    Store field.
  1345.  
  1346. stof:    mov    [bx],al
  1347.     inc    bx
  1348.     dec    ch
  1349.     jz    lonf
  1350.     call    obyt
  1351.     call    term            ;z=terminator
  1352.     jnz    stof
  1353.  
  1354. ;    Complete short field with blanks.
  1355.  
  1356. shof:    mov    (byte ptr [bx]),' '
  1357.     inc    bx
  1358.     dec    ch
  1359.     jnz    shof
  1360.     ret
  1361.  
  1362. ;    Ignore remainder of long field.
  1363.  
  1364. lonf:    call    obyt
  1365.     call    term            ;z=terminator
  1366.     jnz    lonf
  1367.     ret
  1368.  
  1369. ;    Check for a field terminator (z).
  1370. ;    Check for an operation (z).
  1371.  
  1372. term:    cmp    al,'.'
  1373.     jz    G132
  1374.     cmp    al,' '
  1375.     jz    G132
  1376.     cmp    al,':'
  1377.     jz    G132
  1378.     cmp    al,')'
  1379.     jz    G132
  1380.     cmp    al,CR
  1381.     jz    G132
  1382.     or    al,al
  1383.     jz    G132
  1384. oprn:    cmp    al,'='
  1385.     jz    G132
  1386.     cmp    al,'+'
  1387.     jz    G132
  1388.     cmp    al,'-'
  1389. G132:    ret
  1390.  
  1391. ;    ------------------------
  1392.  
  1393. ;    Go back to root.
  1394.  
  1395. X07E1:    mov    al,X0C71        ;level #
  1396.     or    al,al
  1397.     jnz G140 ! jmp X0342 ! G140:    ;display menu
  1398.     mov    al,000H
  1399.     jmp    X07FE
  1400.  
  1401. ;    Go up one level.
  1402.  
  1403. X07ED:    mov    al,X0C71        ;level #
  1404.     or    al,al
  1405.     jz G141 ! jmp X07FD ! G141:    ;revert to last level
  1406.     mov    dx,(offset X0BAD)        ;'No Higher Level'
  1407.     call    mssg        ;message to console
  1408.     jmp    X0342        ;display menu
  1409.  
  1410. ;    Revert to upper level, type name.
  1411.  
  1412. X07FD:    dec    al
  1413. X07FE:    mov    X0C71,al    ;level #
  1414.     call    X0845        ;locate file name on stack
  1415.     push    bx
  1416.     mov    dx,(offset lohf)        ;'Loading HELP File'
  1417.     call    mssg        ;message to console
  1418.     call    tyfn        ;type filename
  1419.     call    crlf
  1420.     pop    dx
  1421.     mov    bx,(offset tfcb+1)    ;TFCB+1
  1422.     mov    ch,11        ;bytes in file name
  1423.     call    miuc
  1424.     mov    ch,11
  1425.     mov    bx,(offset nbuf+1)    
  1426.     call    miuc
  1427.     jmp    loop        ;loop
  1428.  
  1429. ;    Locate file name on stack.
  1430.  
  1431. X0845:    call    X084D        ;HL=A*22
  1432.     mov    dx,(offset X0C73)        ;PDL for HELP file names
  1433.     add    bx,dx
  1434.     ret
  1435.  
  1436. ;    HL = A*22
  1437.  
  1438. X084D:    mov    bl,al
  1439.     mov    bh,000H
  1440.     mov    dl,bl
  1441.     mov    dh,bh
  1442.     add    bx,bx
  1443.     add    bx,bx
  1444.     add    bx,bx
  1445.     add    bx,dx
  1446.     add    bx,dx
  1447.     add    bx,dx
  1448.     add    bx,bx
  1449.     ret
  1450.  
  1451. ;    Type level identification.
  1452.  
  1453. X0859:    mov    al,X0C71        ;level #
  1454.     or    al,al
  1455.     jnz G142 ! jmp X0872 ! G142:
  1456.     mov    dx,(offset X0C0C)        ;'Level 1'
  1457.     call    mssg        ;message to console
  1458.     mov    al,X0C71        ;level #
  1459.     call    X0881        ;translate level # to ASCII
  1460.     mov    dx,(offset X0C13)        ;'/ '
  1461.     call    mssg        ;message to console
  1462. X0872:    mov    al,X0C72        ;panel #
  1463.     or    al,al
  1464.     jnz G143 ! ret ! G143:
  1465.     call    X0881        ;translate level # to ASCII
  1466.     mov    dx,(offset X0C16)        ;': '
  1467.     call    mssg        ;message to console
  1468.     ret
  1469.  
  1470. ;    Translate level number to ASCII string.
  1471.  
  1472. X0881:    lahf ! xchg ah,al ! push ax ! xchg ah,al
  1473.     xor    al,al
  1474.     mov    X0C70,al    ;z/nz = 1/2 digit number
  1475.     pop ax ! xchg ah,al ! sahf
  1476.     mov    ch,100        ;one hundred
  1477.     call    X0896        ;type A as decimal number
  1478.     mov    ch,10        ;ten
  1479.     call    X0896        ;type A as decimal number
  1480.     add    al,'0'
  1481.     jmp    cona        ;char to console
  1482.  
  1483. ;    Type A as decimal number.
  1484.  
  1485. X0896:    mov    cl,000H
  1486. X0898:    sub    al,ch
  1487.     jnc G144 ! jmp X08A0 ! G144:
  1488.     inc    cl
  1489.     jmp    X0898
  1490.  
  1491. X08A0:    add    al,ch
  1492.     mov    ch,al
  1493.     mov    al,X0C70        ;z/nz = 1/2 digit number
  1494.     or    al,al
  1495.     jz G145 ! jmp X08B6 ! G145:
  1496.     mov    al,cl
  1497.     mov    X0C70,al    ;z/nz = 1/2 digit number
  1498.     or    al,al
  1499.     jz G146 ! jmp X08B6 ! G146:
  1500.     mov    al,' '
  1501.     jmp    X08B9
  1502.  
  1503. X08B6:    mov    al,cl
  1504.     add    al,'0'
  1505. X08B9:    call    cona        ;char to console
  1506.     mov    al,ch
  1507.     ret
  1508.  
  1509. X08BE    db    'HJELP/ICUAP/05-OCT-84',CR,LF,'$'
  1510. tuto    db    'Many systems feature HELP files containing information',CR,LF
  1511.     db    'about the usage or characteristics of the system itself',CR,LF
  1512.     db    'or the programs which it contains. HELP files are often',CR,LF
  1513.     db    'structured, and require an auxiliary program which will',CR,LF
  1514.     db    'facilitate their consultation. HJELP.COM satisfies this',CR,LF
  1515.     db    'requirement, even if the HELP files have been squeezed',CR,LF
  1516.     db    'or have been placed in a library.',CR,LF
  1517.     db    '        HJELP FILE',CR,LF
  1518.     db    'will display either FILE.HLP or FILE.HQP, using a menu',CR,LF
  1519.     db    'of information sections and a series of prompts which',CR,LF
  1520.     db    'are largely self-explanatory.',CR,LF
  1521.     db    '        HJELP (LIBR) FILE',CR,LF
  1522.     db    'will display FILE.HLP, taken from the library LIBR.LBR.',CR,LF
  1523.     db    'Finally,',CR,LF
  1524.     db    '        HJELP (FILE)',CR,LF
  1525.     db    'will assume that FILE.HLP is a member of FILE.LBR. Such',CR,LF
  1526.     db    'a construction presupposes that FILE.LBR contains many',CR,LF
  1527.     db    'additional files which are referenced through FILE.HLP.',CR,LF
  1528.     db    'In all cases, an explicitly given extension will be',CR,LF
  1529.     db    'respected, even when it is different from the default.',CR,LF
  1530.     db    '$'
  1531. X0954    db    CR,LF,'  HELP File Selections are --',CR,LF,'$'
  1532. X0976    db    'EOI '
  1533. X097A    db    '^C=Exit $'
  1534. X0983    db    '^=Level .=Root $'
  1535. X0993    db    'M=Menu S=Start L=Last P=Print $'
  1536. X09B2    db    'Printing in Progress -- Strike ^C to Quit $'
  1537. X09DE    db    'Please Set Top-of-Form on Printer',CR,LF
  1538.     db    '  Strike S to Print this Screen Only,'
  1539.     db    ' ^C to Quit, or',CR,LF
  1540.     db    '  Any Other Char to Print Entire Information Section - $'
  1541. X0AC6    db    CR,LF,'% -- Invalid Response',CR,LF,'$'
  1542. X0AE9    db    CR,LF,'% -- EOF on HELP File',CR,LF,'$'
  1543. X0B4A    db    CR,LF,'% -- Node Level Limit Reached'
  1544.     db    ' -- Returning to CP/M',CR,LF,'$'
  1545. X0B81    db    CR,LF,'% -- Invalid File Name in Load',CR,LF,'$'
  1546. X0BAD    db    CR,LF,'% -- No Higher Level to Return to',CR,LF,'$'
  1547. X0BDC    db    CR,LF,'% -- Not Enough Room for HELP File',CR,LF,'$'
  1548. X0C0C    db    'Level $'
  1549. X0C13    db    '/ $'
  1550. X0C16    db    ': $'
  1551. X0C19    db    'Type  ^C=Exit$'
  1552. X0C27    db    ' ^=Level .=Root$'
  1553. X0C37    db    ' or Enter Selection $'
  1554. lohf    db    CR,LF,'Loading HELP File $'
  1555. chno    db    CR,LF,'Checksum failure.$'
  1556. nlib    db    CR,LF,'Requested library not present.$'
  1557. rerr    db    CR,LF,'Read error.$'
  1558. nfil    db    CR,LF,'Requested file not present.$'
  1559.  
  1560. mlen    rw    1    ;length (records) of member
  1561. rlen    rw    1    ;length (32-byte lines) of directory
  1562. actr    rw    1
  1563. aptr    rw    1
  1564. abff    rw    0    ;word version of abuf
  1565. abuf    rb    32
  1566. nbuf    rb    12
  1567. mctr    rw    1
  1568. mptr    rw    1
  1569. oper    rb    1        ;color operation
  1570. dest    rb    1        ;color area
  1571. octr    rw    1
  1572. optr    rw    1
  1573. obuf    rb    80H
  1574. X0C61    rb    1        ;z/nz = panel/section (P)
  1575. X0C62    rb    1        ;user code
  1576. X0C63    rb    1        ;memory pages
  1577. X0C68    rb    1        ;option letter
  1578. X0C6B    rb    1        ;console remaining lines
  1579. X0C6E    rw    1        ;ptr end of text
  1580. X0C70    rb    1        ;z/nz = 1/2 digit number
  1581. X0C71    rb    1        ;level #
  1582. X0C72    rb    1        ;panel #
  1583. X0C73    rb    ND*22+100    ;PDL for HELP file names/stack
  1584. X0D31    rw    1        ;save stack pointer
  1585. cksm    rw    1        ;checksum
  1586. lach    rb    1        ;%; last character typed    S
  1587. rcnt    rb    1        ;%; repetition count        E
  1588. roco    rb    1        ;%; rotating bit counter    Q
  1589. roby    rb    1        ;%; rotating byte        U
  1590. dens    rb    1        ;%; z/nz=normal/squeezed file    E
  1591. wflg    rb    1        ;%; z/nz=no/byte awaiting abyt    N
  1592. wbyt    rb    1        ;%; byte left waiting by abyt    C
  1593. tptr    rw    1        ;%; text pointer        E
  1594. xptr    rw    1        ;ptr to bgn of HELP file
  1595. yptr    rw    1        ;zptr+NS
  1596. zptr    rw    1        ;ptr to bgn of info sect
  1597. cptr    rw    1        ;Huffman code table
  1598. pptr    rw    1        ;pushdown pointer
  1599. mopt    rb    1        ;maximum option
  1600. char    rb    1        ;char read from console
  1601. pudl    rb    NS*50        ;pushdown for section heads
  1602. X0D33    rb    0        ;free memory
  1603.  
  1604. ;    Layout of pudl and pointers:
  1605. ;
  1606. ;        pudl:    menu
  1607. ;            ...
  1608. ;            menu
  1609. ;        zptr->    panel 1
  1610. ;        yptr->    panel 2
  1611. ;            ...
  1612. ;        pptr->    panel n
  1613. ;            x
  1614. ;            x
  1615. ;            x
  1616. ;        X0D33:    x
  1617. ;            x
  1618. ;        cptr->    Huffman code
  1619. ;            x
  1620. ;            x
  1621. ;        xptr->    HELPfile text
  1622. ;            x
  1623. ;            x
  1624. ;        tptr->    x
  1625. ;            x
  1626. ;            x
  1627.  
  1628.     end
  1629.