home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpmhelp / help18u.asm < prev    next >
Assembly Source File  |  1994-07-27  |  37KB  |  1,534 lines

  1. *  PROGRAM NAME:  HELP
  2. *  AUTHOR:  RICHARD CONN  Update for USQ by Dave Rand
  3. *  DATE:  12 OCT 83
  4. *  VERSION:  1.8
  5. *  PREVIOUS VERSIONS:  1.6 (9 SEP 81), 1.7 (10 SEP 81)
  6. *  PREVIOUS VERSIONS:  1.5 (9 SEP 81), 1.4 (8 SEP 81), 1.3 (8 SEP 81)
  7. *  PREVIOUS VERSIONS:  1.2 (7 SEP 81), 1.1 (6 OCT 80), 1.0 (18 NOV 79)
  8.  
  9. VERS    EQU    18    ; VERSION NUMBER
  10.  
  11. *****************************************************************
  12. *                                *
  13. *  HELP -- DISPLAY HELP FILE INFORMATION TO USER ON CON:    *
  14. *                                *
  15. *  -- Command Format --                        *
  16. *    THE HELP COMMAND IS OF THE GENERAL FORM:        *
  17. *        HELP <FILENAME>.<TYP>                *
  18. *                                *
  19. *    <FILENAME>.<TYP> IS OPTIONAL; IF OMITTED COMPLETELY,    *
  20. * 'HELP.HLP' IS ASSUMED; IF JUST <TYP> IS OMITTED, FILE TYPE    *
  21. * IS ASSUMED TO BE '.HLP'                    *
  22. *                                *
  23. *  -- Basic Background Information --                *
  24. *    THE HELP COMMAND DISPLAYS THE INFORMATION IN A HELP    *
  25. * FILE TO THE USER.  THERE ARE TWO BASIC TYPES OF HELP FILES --    *
  26. * (1) INDEXED AND (2) NON-INDEXED.  INDEXED HELP FILES ARE     *
  27. * THOSE WHICH CONTAIN SEVERAL SECTIONS; THE INDIVIDUAL MAY    *
  28. * READ ALL OF SUCH A HELP FILE OR JUST SELECTED SECTIONS OF    *
  29. * THIS FILE.  NON-INDEXED HELP FILES CONTAIN ONLY ONE SECTION.    *
  30. *    STRUCTURALLY SPEAKING, HELP FILES CONSIST OF TWO PARTS:    *
  31. * THE HEADER PART AND THE INFORMATION PART.  THE INFORMATION    *
  32. * PART OF A HELP FILE BEGINS WITH A LINE WHOSE FIRST CHARACTER    *
  33. * IS A COLON.  THE TITLE OF THE INFORMATION SECTION IS ON THIS    *
  34. * LINE.  THE INFORMATION SECTION CONTINUES UNTIL THE NEXT    *
  35. * INFORMATION SECTION (LINE STARTING WITH A COLON) OR THE END    *
  36. * OF THE FILE IS ENCOUNTERED.  THE HEADER PART CONSISTS OF A    *
  37. * GROUP OF LINES BEFORE THE FIRST INFORMATION SECTION.  IF THE    *
  38. * FIRST LINE OF A HELP FILE STARTS WITH A COLON, THEN THERE IS    *
  39. * NO HEADER PART, AND THE HELP FILE IS DUMPED AS ONE        *
  40. * INFORMATION SECTION.                        *
  41. *    THE INFORMATION SECTION IS ITSELF DIVIDED INTO PARTS,    *
  42. * CALLED FRAMES.  A FRAME IS ONE SCREEN DISPLAY, THE SIZE OF    *
  43. * WHICH IS SET BY AN EQUATE.  IF THE HELP FILE CONTAINS A FORM    *
  44. * FEED CHARACTER, THEN THE CURRENT FRAME IS ABRUPTLY TERMINATED    *
  45. * AND THE RESET OF THE SCREEN DISPLAY IS FILLED WITH BLANK    *
  46. * LINES.  OTHERWISE, WHEN THE INDICATED NUMBER OF LINES HAVE    *
  47. * BEEN DISPLAYED, THE HELP PROGRAM PAUSES TO ALLOW THE USER TO    *
  48. * VIEW THE INFORMATION AND SELECT THE NEXT DIRECTION IN WHICH    *
  49. * TO GO.                            *
  50. *                                *
  51. *  -- Traversing the HELP File --                *
  52. *    WHILE IN THE HELP SYSTEM, THE USER IS GIVEN SEVERAL    *
  53. * OPTIONS AT ALL TIMES AS TO WHAT HE CAN DO.            *
  54. *    AT THE MENU LEVEL OF INDEXED HELP FILES, THE USER CAN    *
  55. * MOVE IN THE FOLLOWING DIRECTIONS:                *
  56. *        1. SELECTION OF A MENU ITEM, IN WHICH CASE    *
  57. * HE ENTERS THAT INFORMATION SECTION                *
  58. *        2. MOVE UP TO THE PREVIOUS LEVEL.  IF THE HELP    *
  59. * FILE THE USER IS IN WAS REACHED THROUGH ANOTHER HELP FILE,    *
  60. * THE USER CAN RETURN TO THAT HELP FILE (MOVE UP A LEVEL).    *
  61. * IF THE USER WAS IN THE "SELECT ALL ITEMS" MODE, HE CONTINUES    *
  62. * WITH THE PREVIOUS HELP FILE WHERE HE LEFT OFF; IF THE USER    *
  63. * WAS LOOKING AT A SPECIFIC MENU ITEM (WHICH CALLED THE HELP    *
  64. * FILE HE IS IN NOW), HE IS RETURNED TO THE MENU OF THE CALLING    *
  65. * HELP FILE.                            *
  66. *        3. EXIT TO CP/M.  AT ALL TIMES, THE USER IS    *
  67. * ALLOWED TO RETURN TO CP/M.                    *
  68. *    WHILE IN AN INFORMATION SECTION, THE USER MAY        *
  69. * MOVE IN THE FOLLOWING DIRECTIONS:                *
  70. *        1. FORWARD TO THE NEXT FRAME.  IF AT THE END    *
  71. * OF THE INFORMATION SECTION, THIS RETURNS THE USER TO THE    *
  72. * MENU IF IT IS AN INDEXED HELP FILE, TO CP/M IF THE USER IS    *
  73. * IN A NON-INDEXED HELP FILE AT LEVEL 0 (NOT CALLED BY ANOTHER    *
  74. * HELP FILE), OR TO THE CALLING HELP FILE IF NOT AT LEVEL 0.    *
  75. *        2. BACKWARD TO THE PREVIOUS FRAME.  IF AT THE    *
  76. * BEGINNING OF AN INFORMATION SECTION, AN ERROR MESSAGE IS    *
  77. * PRINTED.                            *
  78. *        3. TO THE MENU IF IN AN INDEXED HELP FILE.    *
  79. *        4. TO THE START OF THE CURRENT INFORMATION    *
  80. * SECTION DIRECTLY.                        *
  81. *        5. TO THE PREVIOUS LEVEL (CALLING HELP FILE).    *
  82. *                                *
  83. *  -- Nodes and Help File Nesting --                *
  84. *    AN INFORMATION SECTION MAY BEGIN WITH A DOUBLE COLON    *
  85. * (::), AND THIS DESIGNATOR IS FOLLOWING BY THE FILE NAME OF A    *
  86. * HELP FILE WHICH IS TO BE LOADED AS A NODE.  NODES TO THE HELP    *
  87. * PROGRAM ARE COMPLETE HELP FILES IN THEMSELVES, AND THEY MAY    *
  88. * REFER TO OTHER NODES AS WELL.  IN THIS WAY, A TREE STRUCTURE    *
  89. * MAY BE DESIGNED BY THE AUTHOR OF A HELP FILE, EACH NODE OF    *
  90. * THE TREE BEING A HELP FILE IN ITS OWN RIGHT (WHICH MAY BE    *
  91. * ACCESSED INDEPENDENTLY).  NODES MAY BE NESTED A NUMBER OF    *
  92. * LEVELS, SPECIFIED BY THE HELP$MAX EQUATE.            *
  93. *    TO VIEW THIS CONCEPT MORE CLEARLY, THE FOLLOWING DIAGRAM*
  94. * IS OFFERED:                            *
  95. *        -- Basic HELP File --                *
  96. * :Info Sect 1    :Info Sect 2    :Info Sect 3    :Info Sect 4 :    *
  97. * : Text    : HELP File    : Text        : HELP File  :    *
  98. *           /      \               /    \    *
  99. *        -- SubHelp File 1 --        -- SubHelp File 2 --*
  100. *    :Info Sect 1 :Info Sect 2 :    :Info Sect 1 :Info Sect2*
  101. *    : Text         : HELP File  :    : Text         : Text    *
  102. *            /    \                    *
  103. *        -- SubSubHelp File 1 --                *
  104. *    :Info Sect 1 :Info Sect 2 :Info Sect 3 :        *
  105. *    : Text         : HELP File  : HELP File  :        *
  106. *            /  \         /    \            *
  107. *    -- Sub3Help File 1 --  -- Sub3Help File 2 --        *
  108. *    :Info Sect :        :Info Sect 1 :Info Sect 2:    *
  109. *    : Text     :        : Text         : HELP File :    *
  110. *                        /    \        *
  111. *                    -- Sub4Help File --    *
  112. *                :Info Sect 1 :Info Sect 2:    *
  113. *                : Text         : Text     :    *
  114. *                                *
  115. *    AS THE USER CAN SEE, TREE STRUCTURES ARE NOW POSSIBLE.    *
  116. * ONE HELP FILE CAN REFERENCE ANOTHER WHICH INTURN REFERENCES    *
  117. * ANOTHER AND SO ON.  THERE IS A LIMIT TO HOW DEEP THE NESTING    *
  118. * MAY GO, AND THAT IS SPECIFIED IN THE EQUATE FOR HELP$MAX.    *
  119. *                                *
  120. *  -- What Help Can Do --                    *
  121. *    SINCE A HELP FILE MUST BE MEMORY RESIDENT, THIS IS    *
  122. * CONVENIENT IN TWO WAYS:  (1) "MASTER" HELP FILES MAY BE    *
  123. * CREATED WHICH REFERENCE OTHER HELP FILES, AND THE INFORMATION    *
  124. * ACCESSED FROM A MASTER HELP FILE MAY ENCOMPASS ALL OF THE    *
  125. * USER'S HELP FILE AND (2) IF THE USER NEEDS INFORMATION    *
  126. * IN A SPECIFIC SUBJECT AREA AND KNOWS WHICH HELP FILE REFERS    *
  127. * TO THE INFORMATION HE NEEDS, HE NEED NOT LOAD THE MASTER    *
  128. * AND THEN TRAVERSE THE TREE TO THE INFORMATION HE NEEDS; HE    *
  129. * MAY SPECIFY THE SPECIFIC HELP FILE DIRECTLY.            *
  130. *                                *
  131. *  -- Command-Search Hierarchy --                *
  132. *    ONE OTHER POINT TO NOTE IS THAT THE HELP PROGRAM NOW    *
  133. * EMPLOYS A COMMAND-SEARCH HIERARCHY IN LOCATING A REFERENCED    *
  134. * HELP FILE.  ONCE A FILE SPECIFICATION IS GIVEN, THE HELP    *
  135. * PROGRAM SEARCHES THE CURRENT USER AREA ON THE CURRENT DISK FOR*
  136. * THE FILE; IF NOT FOUND, IT DROPS TO USER AREA 0 (MAY BE    *
  137. * CHANGED) ON THE CURRENT DISK IF THE USER IS NOT ALREADY THERE    *
  138. * AND LOOKS FOR THE FILE; IF NOT FOUND THIS TIME, IT DROPS TO    *
  139. * USER AREA 0 OF THE DISK ON DRIVE A: AND SEARCHES FOR THE FILE.*
  140. * IF NOT FOUND AT THIS POINT, HELP CHECKS TO SEE IF THE REFER-    *
  141. * ENCED FILE WAS HELP.HLP, IN WHICH CASE IT PRESENTS THE BUILT-    *
  142. * IN DOCUMENTATION (SEE END OF PROGRAM); FINALLY, IF NONE OF THE*
  143. * ABOVE ARE TRUE, HELP ABORTS WITH AN ERROR MESSAGE.        *
  144. *                                *
  145. *  -- HELP File Structure Warning --                *
  146. *    THERE MUST BE THE SAME NUMBER OF LINES IN THE HEADER    *
  147. * PART AS THERE ARE INFORMATION SECTIONS.  IF NOT, A HELP    *
  148. * FILE ERROR WILL BE ISSUED IF THE HELP COMMAND ATTEMPTS TO    *
  149. * READ BEYOND THE END OF THE HELP FILE IN ITS SEARCH FOR AN    *
  150. * INFORMATION SECTION.                        *
  151. *                                *
  152. *****************************************************************
  153.  
  154.  
  155. *****************************************************************
  156. *                                *
  157. *  THE HELP PROGRAM IS COMPLETELY TRANSPORTABLE BETWEEN CP/M    *
  158. *  SYSTEMS.                            *
  159. *                                *
  160. *****************************************************************
  161.  
  162.  
  163.  
  164. *****************************************************************
  165. *  CP/M AND BASIC CHARACTER DEFINITIONS                *
  166. *****************************************************************
  167.  
  168. BDOS        EQU    5    ; ADDRESS OF BDOS ENTRY POINT
  169. FCB        EQU    5CH    ; ADDRESS OF FILE CONTROL BLOCK
  170. BUFF        EQU    80H    ; ADDRESS OF DMA BUFFER
  171.  
  172. CR        EQU    0DH    ; <CR>
  173. LF        EQU    0AH    ; <LF>
  174. FF        EQU    'L'-40H    ; CTRL-L = FORM FEED
  175. CTRLZ        EQU    'Z'-40H    ; CTRL-Z
  176. CTRLC        EQU    'C'-40H    ; CTRL-C
  177.  
  178. *****************************************************************
  179. *  SPECIAL CONTROL CHARACTERS WHICH MAY BE RESET BY USER    *
  180. *****************************************************************
  181.  
  182. SECT$CHAR    EQU    ':'    ; DEFINED TO BE COLON
  183. BACKUP$CHAR    EQU    'L'    ; BACK UP TO PREVIOUS FRAME CHAR
  184. START$CHAR    EQU    'S'    ; JUMP TO START OF INFORMATION CHAR
  185. MENU$CHAR    EQU    'M'    ; CHAR TO ABORT TO MENU
  186. CPM$ABORT$CHAR    EQU    CTRLC    ; CHAR TO ABORT TO CP/M
  187. LEVEL$RET$CHAR    EQU    '^'    ; RETURN TO PREVIOUS HELP LEVEL
  188. ROOT$CHAR    EQU    '.'    ; RETURN TO ROOT OF HELP
  189.  
  190. *****************************************************************
  191. *  USER CUSTOMIZATION -- LINES PER SCREEN DISPLAY        *
  192. *****************************************************************
  193.  
  194. LINES$PER$SCREEN    EQU    24    ; ASSUME 24 LINES/SCREEN
  195.  
  196. *****************************************************************
  197. *  USER CUSTOMIZATION -- DEFAULT USER NUMBER            *
  198. *****************************************************************
  199.  
  200. DEFAULT$USER        EQU    0    ; DEFAULT USER NUMBER = 0
  201.  
  202. *****************************************************************
  203. *  USER CUSTOMIZATION -- DEFAULT DISK                *
  204. *****************************************************************
  205.  
  206. DEFAULT$DISK        EQU    'A'    ; DEFAULT DISK = A:
  207.  
  208. *****************************************************************
  209. *  USER CUSTOMIZATION -- NUMBER OF NODES (LEVELS) IN HELP TREE    *
  210. *****************************************************************
  211.  
  212. HELP$MAX        EQU    10    ; DEFAULT = 10 (SPACE=11*HELP$MAX)
  213.  
  214.  
  215.  
  216. *****************************************************************
  217. *  START OF PROGRAM                        *
  218. *****************************************************************
  219.  
  220.     ORG    100H
  221.  
  222. START:
  223.     LXI    H,0    ; GET SP
  224.     DAD    SP
  225.     SHLD    STACK
  226.     LXI    SP,STACK    ; NEW STACK
  227.     LDA    BDOS+2    ; BASE PAGE OF BDOS
  228.     SUI    10    ; 2K + 2 PAGES
  229.     STA    TPA$END
  230.     XRA    A    ; A=0
  231.     STA    DFFLG    ; TURN OFF DEFAULT FILE FLAG
  232.     STA    HELP$LEVEL    ; SET HELP LEVEL TO 0 (NO RETURN FILE)
  233.     LXI    D,HELPMS    ; PRINT OPENING MSG
  234.     CALL    PRINT$MESSAGE
  235.     LXI    H,FCB+1    ; CHECK FOR FILE NAME
  236.     MOV    A,M
  237.     CPI    ' '    ; NONE?
  238.     JZ    DEFAULT$FN
  239.     ORA    A    ; ALSO NONE
  240.     JNZ    START1
  241.  
  242. *  INSERT 'HELP.HLP' INTO FCB
  243. DEFAULT$FN:
  244.     DCX    H    ; PT TO FCB
  245.     LXI    D,DEFFN
  246.     MVI    B,12    ; 12 BYTES
  247.     XCHG
  248.     CALL    MOVE    ; MOVE (HL) TO (DE) FOR (B) BYTES
  249.     MVI    A,1    ; TURN ON DEFAULT FILE FLAG
  250.     STA    DFFLG
  251.     JMP    START2
  252.  
  253. *  START/RESTART HELP PROGRAM (START ON INITIAL ENTRY, RESTART ON NODE LOAD)
  254. START1:
  255.     LXI    SP,STACK    ; SET STACK POINTER
  256.  
  257. *  CLEAR NON-NAME/TYPE BYTES IN FCB
  258.     LXI    H,FCB    ; INITIAL ZERO
  259.     MVI    M,0    ; STORE 0 FOR DRIVE (CURRENT LOGGED-IN)
  260.     LXI    D,12    ; SKIP TO EXTENT
  261.     DAD    D
  262.     MVI    B,24    ; FILL 24 BYTES
  263. FCB$FILL:
  264.     MVI    M,0    ; ZERO FILL
  265.     INX    H    ; PT TO NEXT
  266.     DCR    B    ; COUNT DOWN
  267.     JNZ    FCB$FILL
  268.  
  269. *  CHECK FOR FILE TYPE
  270.     LXI    H,FCB+9    ; CHECK FOR FILE TYPE
  271.     MOV    A,M
  272.     CPI    ' '    ; NONE?
  273.     JZ    DEFAULT$EXT
  274.     ORA    A    ; NONE ALSO
  275.     JNZ    START2
  276.  
  277. *  PLACE DEFAULT FILE TYPE OF '.HLP' IN FCB
  278. DEFAULT$EXT:
  279.     LXI    D,DEFTYP
  280.     MVI    B,3
  281.     XCHG
  282.     CALL    MOVE    ; MOVE (HL) TO (DE) FOR (B) BYTES
  283.  
  284. *  OPEN FILE
  285. START2:
  286.     MVI    A,0FFH    ; SET NO CHANGE FLAG
  287.     STA    CUR$USER    ; SET NO USER CHANGE
  288.     STA    CUR$DISK    ; SET NO DISK CHANGE
  289.  
  290. *  OPTION 1:  TRY TO OPEN FILE IN CURRENT USER NUMBER ON CURRENT DISK
  291.     LXI    D,FCB    ; PT TO FCB
  292.     MVI    C,15    ; OPEN FILE
  293.     CALL    BDOS
  294.     CPI    255    ; NOT PRESENT?
  295.     JNZ    START3
  296.     MVI    C,12    ; GET VERSION NUMBER
  297.     CALL    BDOS
  298.     MOV    A,H    ; CP/M 1.X?
  299.     ORA    L
  300.     JZ    START2$DISK    ; CHECK FOR DEFAULT DISK IF SO
  301.  
  302. *  OPTION 2:  TRY TO OPEN FILE IN USER 0 ON CURRENT DISK
  303.     MVI    E,0FFH    ; GET CURRENT USER NUMBER
  304.     MVI    C,32    ; GET/SET USER CODE
  305.     CALL    BDOS
  306.     CPI    DEFAULT$USER    ; CHECK IF AT USER 0 (OR DEFAULT USER)
  307.     JZ    START2$DISK    ; DON'T TRY IF AT USER 0
  308.     STA    CUR$USER    ; SAVE FOR LATER
  309.     MVI    E,DEFAULT$USER    ; SET USER 0 (OR DEFAULT USER)
  310.     MVI    C,32    ; GET/SET USER CODE
  311.     CALL    BDOS
  312.     LXI    D,FCB    ; TRY TO OPEN FILE AGAIN
  313.     MVI    C,15    ; OPEN FILE
  314.     CALL    BDOS
  315.     CPI    255    ; NOT PRESENT?
  316.     JNZ    START3
  317.  
  318. *  OPTION 3:  TRY TO OPEN FILE IN USER 0 ON DEFAULT DISK IF NOT CURRENT DISK
  319. START2$DISK:
  320.     MVI    C,25    ; DETERMINE CURRENT DISK
  321.     CALL    BDOS
  322.     CPI    DEFAULT$DISK-'A'    ; ON DEFAULT DISK?
  323.     JZ    START2$DEFAULT
  324.     STA    CUR$DISK    ; SAVE DISK NUMBER IN BYTE
  325.     MVI    E,DEFAULT$DISK-'A'    ; SELECT DISK A:
  326.     MVI    C,14    ; SELECT DISK
  327.     CALL    BDOS
  328.     LXI    D,FCB    ; TRY TO OPEN FILE ONE LAST TIME
  329.     MVI    C,15    ; OPEN FILE
  330.     CALL    BDOS
  331.     CPI    255    ; NOT PRESENT?
  332.     JNZ    START3
  333.  
  334. *  CHECK FOR DEFAULT FILE SEARCH
  335. START2$DEFAULT:
  336.     CALL    RESET$SYSTEM    ; RESTORE CURRENT DISK AND USER IF CHANGED
  337.  
  338. * File not found, look for HQP files
  339.  
  340.     lxi    h,fcb+1+8+1    ;see if already Q
  341.     mov    a,m
  342.     ani    127
  343.     mvi    m,'Q'
  344.     cpi    'Q'
  345.     jnz    start2        ;skip back, and try again
  346.  
  347.  
  348.     LDA    DFFLG    ; GET DEFAULT FILE FLAG
  349.     ORA    A    ; 1=YES, SEARCH FOR DEFAULT FAILED
  350.     JNZ    HELP    ; DISPLAY DEFAULT HELP FILE INFORMATION
  351.  
  352.  
  353.  
  354. *  FILE NOT FOUND -- FATAL ERROR
  355.  
  356.     LXI    D,ERR1    ; FILE NOT FOUND
  357.     CALL    PRINT$MESSAGE
  358.     JMP    HELP$EXIT
  359.  
  360. *  LOAD HELP FILE INFORMATION
  361. START3:
  362.     LXI    H,HELP$BUF    ; PT TO BUFFER
  363.     SHLD    NEXT$ADR    ; SET PTR
  364.  
  365.     lda    fcb+1+8+1    ;see if sq file
  366.     ani    127
  367.     cpi    'Q'
  368.     jnz    start4
  369.     call    usq
  370.     jmp    start4a
  371.  
  372. *  READ RECORDS UNTIL EOF
  373. START4:
  374.     CALL    READ$RECORD    ; READ INFO
  375.     ORA    A    ; DONE? 0=NO
  376.     JZ    START4
  377. start4a:
  378.     LXI    D,FCB    ; CLOSE FILE
  379.     MVI    C,16    ; CLOSE
  380.     CALL    BDOS
  381.     CALL    RESET$SYSTEM    ; RESTORE CURRENT DISK AND USER IF CHANGED
  382.  
  383. *
  384. *  START OF HELP PROGRAM
  385. *
  386. HELP:
  387.     LXI    SP,STACK    ; RESET STACK
  388.     MVI    A,0    ; SET NO FRAME
  389.     STA    FRAME$NUMBER
  390.     LXI    H,HELP$BUF    ; PT TO BUFFER
  391.     MOV    A,M    ; NO HEADER SECTION?
  392.     ANI    7FH    ; MASK OUT MSB
  393.     CPI    SECT$CHAR
  394.     JNZ    HELP1    ; HEADER SECTION EXISTS
  395.     CALL    PRINT$INFO    ; PRINT HELP INFO PTED TO BY HL
  396.     LDA    HELP$LEVEL    ; CHECK TO SEE IF WE ARE NOT AT LEVEL 0
  397.     ORA    A    ; 0=LEVEL 0
  398.     JZ    HELP$EXIT    ; ABORT IF SO
  399.     JMP    LEVEL$RETURN    ; GO TO PREVIOUS LEVEL IF NOT
  400.  
  401. *  EXIT POINT FOR ANY EXIT FROM THE REST OF THE HELP PROGRAM
  402. HELP$EXIT:
  403.     LHLD    STACK    ; GET CP/M SP
  404.     SPHL
  405.     RET        ; DONE
  406.  
  407. *  PRINT HEADER INFORMATION AND SELECT AN OPTION
  408. HELP1:
  409.     CALL    PRINT$HEADER    ; PRINT HEADER
  410.     PUSH    B    ; SAVE C (NUMBER OF VALID SELECTIONS)
  411.     CALL    CRLF1    ; NEW LINE
  412.     CALL    PR$LEVEL    ; PRINT LEVEL NUMBER
  413.     LXI    D,PROMPT1$MESSAGE    ; PRINT PROMPT
  414.     CALL    PRINT$MESSAGE
  415.     LXI    D,PROMPT2$MESSAGE    ; LEVEL COMMAND
  416.     LDA    HELP$LEVEL    ; CURRENT LEVEL = 0?
  417.     ORA    A    ; SET FLAGS
  418.     JZ    HELP1A
  419.     CALL    PRINT$MESSAGE
  420. HELP1A:
  421.     LXI    D,PROMPT3$MESSAGE
  422.     CALL    PRINT$MESSAGE
  423.     POP    B    ; GET C
  424.     CALL    CHAR$IN        ; GET RESPONSE
  425.     CPI    CTRLC        ; RETURN TO CP/M
  426.     JZ    HELP$EXIT
  427.     CPI    ROOT$CHAR    ; GO TO ROOT
  428.     JZ    GO$ROOT
  429.     CPI    LEVEL$RET$CHAR    ; RETURN TO PREVIOUS LEVEL
  430.     JZ    LEVEL$RETURN
  431.     PUSH    PSW    ; SAVE CHAR
  432.     CALL    CRLF1
  433.     POP    PSW    ; GET CHAR
  434.     SUI    'A'-1        ; ADJUST FOR COUNT
  435.     MOV    B,A        ; SAVE COUNT
  436.     JZ    BAD$RESPONSE
  437.     JNC    HELP2
  438.  
  439. *  INVALID RESPONSE
  440. BAD$RESPONSE:
  441.     LXI    D,ERR2    ; INVALID RESPONSE
  442.     CALL    PRINT$MESSAGE
  443.     JMP    HELP1
  444.  
  445. *  VALID RESPONSE -- LOOK FOR AND PRINT INFORMATION SECTION
  446. HELP2:
  447.     INR    C    ; 1 MORE THAN NUMBER OF POSSIBLE SELECTIONS
  448.     CMP    C    ; GREATER THAN NUMBER OF POSSIBLE SELECTIONS?
  449.     JNC    BAD$RESPONSE
  450.     LHLD    FIRST$ENTRY    ; GET PTR TO FIRST ENTRY
  451.  
  452. *  PRINT INFORMATION WHEN COUNT IS ZERO
  453. HELP3:
  454.     DCR    B    ; COUNT DOWN
  455.     JNZ    HELP4
  456.     CALL    PRINT$INFO    ; PRINT INFO PTED TO BY HL
  457.     JMP    HELP1
  458.  
  459. *  LOCATE NEXT INFORMATION SECTION
  460. HELP4:
  461.     MOV    A,M    ; <CTRL-Z>?
  462.     ANI    7FH    ; MASK OUT MSB
  463.     INX    H    ; PT TO NEXT BYTE
  464.     CPI    CTRLZ
  465.     JZ    HELP$ERR    ; HELP FILE FORMAT ERROR
  466.     CPI    LF    ; LINE FEED (WS FILE)?
  467.     JZ    HELP5
  468.     CPI    CR    ; <CR>?
  469.     JNZ    HELP4
  470.     INX    H    ; 1ST BYTE OF NEXT LINE
  471. HELP5:
  472.     MOV    A,M    ; GET CHAR
  473.     ANI    7FH    ; MASK OUT MSB
  474.     CPI    SECT$CHAR    ; NEW SECTION?
  475.     JZ    HELP3    ; CONTINUE LOOP IF SO
  476.     CPI    CTRLZ    ; EOF?
  477.     JNZ    HELP4    ; CONTINUE IF NOT
  478.  
  479. *  ERROR -- REACHED END OF HELP FILE
  480. HELP$ERR:
  481.     LXI    D,ERR3    ; FORMAT ERROR
  482.     CALL    PRINT$MESSAGE
  483.     JMP    HELP1
  484.  
  485.  
  486. *********************************************************
  487. *                            *
  488. *  HELP SUPPORT ROUTINE SECTION                *
  489. *                            *
  490. *********************************************************
  491.  
  492. *
  493. *  RESTORE CURRENT DISK AND CURRENT USER IF CHANGED
  494. *
  495. RESET$SYSTEM:
  496.     LDA    CUR$DISK    ; CHECK DISK
  497.     CPI    0FFH    ; 0FFH=NO CHANGE
  498.     JZ    RESET$SYS1
  499.     MOV    E,A    ; DISK IN E
  500.     MVI    C,14    ; SELECT DISK
  501.     CALL    BDOS
  502. RESET$SYS1:
  503.     LDA    CUR$USER    ; CHECK USER
  504.     CPI    0FFH    ; 0FFH=NO CHANGE
  505.     RZ
  506.     MOV    E,A    ; USER IN E
  507.     MVI    C,32    ; GET/SET USER CODE
  508.     CALL    BDOS
  509.     RET
  510.  
  511. *
  512. *  INPUT CHAR; CHAR IS IN A
  513. *
  514. CHAR$IN:
  515.     PUSH B ! PUSH D ! PUSH H
  516.     MVI    C,1    ; READ CHAR
  517.     CALL    BDOS
  518.     POP H ! POP D ! POP B
  519.     PUSH    PSW    ; SAVE CHAR
  520.     CALL    CRLF1
  521.     POP    PSW    ; RESTORE CHAR
  522. *
  523. *  CAPITALIZE CHAR IN A
  524. *
  525. CAPS:
  526.     ANI    7FH    ; MASK OUT MSB
  527.     CPI    61H    ; LESS THAN SMALL A?
  528.     RC
  529.     CPI    7BH    ; LESS THAN LEFT BRACE?
  530.     RNC
  531.     ANI    5FH    ; CAPITALIZE
  532.     RET
  533.  
  534. *
  535. *  PRINT CHAR IN A ON CON:
  536. *
  537. CHAR$OUT:
  538.     PUSH PSW ! PUSH B ! PUSH D ! PUSH H
  539.     MVI    C,2    ; WRITE
  540.     MOV    E,A    ; CHAR IN E
  541.     CALL    BDOS
  542.     POP H ! POP D ! POP B ! POP PSW
  543.     RET
  544.  
  545. *
  546. *  PRINT ERROR MSG PTED TO BY DE; ENDS IN '$'
  547. *
  548. PRINT$MESSAGE:
  549.     PUSH B ! PUSH D ! PUSH H
  550.     MVI    C,9    ; PRINT BUFFER
  551.     CALL    BDOS
  552.     POP H ! POP D ! POP B
  553.     RET
  554.  
  555. *
  556. *  MOVE BYTES PTED TO BY HL TO AREA PTED TO BY DE; B BYTES TO MOVE
  557. *
  558. MOVE:
  559.     MOV    A,M    ; GET BYTE
  560.     ANI    7FH    ; MASK OFF MSB -- IN CASE A WS FILE
  561.     STAX    D    ; PUT BYTE
  562.     INX    H    ; PT TO NEXT
  563.     INX    D
  564.     DCR    B    ; COUNT DOWN
  565.     JNZ    MOVE
  566.     RET
  567.  
  568. *
  569. *  READ RECORD FROM DISK; NEXT$ADR CONTAINS ADDRESS TO READ TO
  570. *    ON RETURN, BDOS ERROR CODE IS IN A (0=NO ERROR)
  571. *
  572. READ$RECORD:
  573.     MVI    C,20    ; READ NEXT RECORD
  574.     LXI    D,FCB    ; PT TO FCB
  575.     CALL    BDOS
  576.     PUSH    PSW    ; SAVE RETURN CODE
  577.     LHLD    NEXT$ADR    ; PT TO LOAD ADDRESS
  578.     LDA    TPA$END    ; CHECK AGAINST END PAGE OF TPA
  579.     CMP    H    ; IF AT SAME PAGE, YES
  580.     JZ    READ$ERROR
  581.     LXI    D,BUFF    ; PT TO BUFFER TO LOAD FROM
  582.     MVI    B,128    ; NUMBER OF BYTES TO MOVE
  583.     XCHG
  584.     CALL    MOVE
  585.     XCHG
  586.     POP    PSW    ; GET RETURN CODE
  587.     ORA    A    ; DONE?
  588.     JZ    READ$DONE    ; RETURN IF NOT
  589.  
  590. *  CHECK FOR CTRLZ
  591.     PUSH    H    ; SAVE PTR TO NEXT ADDRESS
  592.     LHLD    NEXT$ADR    ; PT TO BEGINNING OF BLOCK
  593.     MVI    B,128    ; CHECK 128 BYTES
  594. CTRLZ$CHECK:
  595.     MOV    A,M    ; GET BYTE
  596.     ANI    7FH    ; MASK OUT MSB
  597.     INX    H    ; PT TO NEXT
  598.     CPI    CTRLZ    ; EOF?
  599.     JZ    CTRLZ$FOUND
  600.     DCR    B    ; COUNT DOWN
  601.     JNZ    CTRLZ$CHECK
  602.     LXI    D,CTRLZERR
  603.     CALL    PRINT$MESSAGE    ; NO CTRLZ ERROR
  604.     JMP    HELP$EXIT
  605.  
  606. *  FILL REST OF BLOCK WITH CTRLZ
  607. CTRLZ$FOUND:
  608.     DCR    B    ; COUNT DOWN
  609.     JZ    CTRLZ$DONE
  610.     MVI    M,CTRLZ    ; FILL REST OF BLOCK WITH CTRLZ
  611.     INX    H    ; PT TO NEXT
  612.     JMP    CTRLZ$FOUND
  613. CTRLZ$DONE:
  614.     POP    H    ; PT TO NEXT BLOCK ADDRESS
  615.  
  616. *  READ OK -- SAVE PTR TO NEXT BLOCK
  617. READ$DONE:
  618.     SHLD    NEXT$ADR    ; SET NEXT ADDRESS
  619.     RET
  620.  
  621. READ$ERROR:
  622.     LXI    D,READERR
  623.     CALL    PRINT$MESSAGE
  624.     JMP    HELP$EXIT
  625.  
  626. *
  627. *  PRINT ONE LINE OF INFO SECTION; HL PTS TO LINE UPON ENTRY;
  628. *    HL PTS TO FIRST CHAR OF NEXT LINE UPON EXIT
  629. *
  630. PRINT$LINE:
  631.     MOV    A,M    ; GET CHAR
  632.     ANI    7FH    ; MASK OUT MSB
  633.     CPI    CR    ; EOL?
  634.     JZ    CRLF
  635.     CPI    LF    ; LINE FEED? (WS FILE)
  636.     JZ    CRLF0
  637.     CPI    CTRLZ    ; END OF FILE?
  638.     JZ    CRLFC    ; DONE IF SO
  639.     CALL    CHAR$OUT    ; PRINT CHAR
  640.     INX    H    ; PT TO NEXT
  641.     JMP    PRINT$LINE
  642.  
  643. *
  644. *  PRINT CRLF, PT TO FIRST CHAR OF NEXT LINE, AND PAGE IF NECESSARY
  645. *
  646. CRLF:
  647.     INX    H    ; PT TO LF
  648. CRLF0:
  649.     INX    H    ; PT TO 1ST CHAR OF NEXT LINE
  650. CRLFC:
  651.     CALL    CRLF1    ; PRINT CRLF
  652.     LDA    LINE$CNT    ; GET LINE COUNT
  653.     DCR    A
  654.     STA    LINE$CNT
  655.     RNZ        ; OK -- CONTINUE
  656.     MOV    A,M    ; SET MSB OF FIRST CHAR OF NEXT LINE
  657.     ORI    80H
  658.     MOV    M,A    ; MSB IS SET FOR LATER BACKUP
  659. FRAME$PAUSE:
  660.     CALL    PR$LEVEL    ; PRINT LEVEL NUMBER
  661.     LDA    FRAME$NUMBER    ; INCREMENT FRAME NUMBER
  662.     INR    A
  663.     STA    FRAME$NUMBER
  664.     LXI    D,PAGEMS
  665.     CALL    PRINT$MESSAGE    ; PRINT PAGE MESSAGE
  666.     LXI    D,PAGE1MS    ; NOT LEVEL 0?
  667.     LDA    HELP$LEVEL    ; GET LEVEL NUMBER
  668.     ORA    A    ; SET FLAGS
  669.     JZ    FP1
  670.     CALL    PRINT$MESSAGE
  671. FP1:
  672.     LXI    D,PAGE2MS
  673.     CALL    PRINT$MESSAGE
  674.     CALL    CHAR$IN    ; GET RESPONSE
  675.     CPI    MENU$CHAR    ; ABORT?
  676.     JZ    HELP    ; START OVER IF SO
  677.     CPI    CPM$ABORT$CHAR    ; CP/M ABORT
  678.     JZ    HELP$EXIT
  679.     CPI    ROOT$CHAR    ; GO TO ROOT
  680.     JZ    GO$ROOT
  681.     CPI    LEVEL$RET$CHAR    ; RETURN TO HIGHER LEVEL
  682.     JZ    LEVEL$RETURN
  683.     CPI    BACKUP$CHAR    ; BACK UP?
  684.     JZ    FRAME$BACKUP
  685.     CPI    START$CHAR    ; JUMP TO START OF INFO
  686.     JZ    INFO$START
  687. FRAME$RESUME:
  688.     SHLD    START$OF$FRAME
  689.     CALL    SET$LINE$CNT
  690.     CALL    CRLF1    ; NEW LINE
  691.     RET
  692.  
  693. *  JUMP TO START OF INFORMATION
  694. INFO$START:
  695.     LHLD    START$OF$INFO    ; PT TO START OF INFO
  696.     JMP    FRAME$RESUME    ; CONTINUE PROCESSING
  697.  
  698. *  BACK UP TO PREVIOUS FRAME
  699. FRAME$BACKUP:
  700.     CALL    BOI$CHECK    ; AT BEGINNING OF INFORMATION?
  701.     JNZ    FB1        ; CONTINUE IF NOT
  702.     JMP    FRAME$PAUSE
  703. FB1:
  704.     DCX    H    ; BACK UP UNTIL BYTE WITH MSB SET IS FOUND
  705.     MOV    A,M    ; GET BYTE
  706.     ANI    80H
  707.     JZ    FB1
  708.     LDA    FRAME$NUMBER    ; DECREMENT FRAME NUMBER
  709.     DCR    A        ; BACK UP TO CURRENT FRAME NUMBER
  710.     DCR    A        ; BACK UP TO PREVIOUS FRAME NUMBER
  711.     STA    FRAME$NUMBER
  712.     JMP    FRAME$RESUME    ; CONTINUE PROCESSING
  713. *
  714. *  PRINT CR AND LF ONLY
  715. *
  716. CRLF1:
  717.     MVI    A,CR    ; PRINT CR
  718.     CALL    CHAR$OUT
  719.     MVI    A,LF    ; PRINT LF
  720.     CALL    CHAR$OUT
  721.     RET
  722.  
  723. *
  724. *  SET LINE$CNT VARIABLE TO SCREEN SIZE
  725. *
  726. SET$LINE$CNT:
  727.     MVI    A,LINES$PER$SCREEN-1
  728.     STA    LINE$CNT
  729.     RET
  730.  
  731. *
  732. *  PRINT THE HEADER SECTION AND LOAD FIRST$ENTRY PTR
  733. *    ON RETURN, C=NUMBER OF POSSIBLE SELECTIONS
  734. *
  735. PRINT$HEADER:
  736.     MVI    A,0    ; SET NO FRAME
  737.     STA    FRAME$NUMBER
  738.     LXI    H,HELP$BUF
  739.     CALL    SET$LINE$CNT
  740.     MVI    A,'A'    ; INIT SELECTION CHAR
  741.     STA    SEL$CHAR
  742.     LXI    D,SELECTMS
  743.     CALL    PRINT$MESSAGE
  744.     MVI    C,0    ; COUNT NUMBER OF SELECTIONS
  745.  
  746. * PRINT LINE UNTIL FIRST INFORMATION SECTION FOUND
  747. PH1:
  748.     MOV    A,M    ; GET CHAR
  749.     ANI    7FH    ; MASK OUT MSB
  750.     CPI    SECT$CHAR
  751.     JZ    PH2
  752.     CPI    CTRLZ    ; EOF? -- ABORT
  753.     JZ    HELP$EXIT
  754.     INR    C    ; INCREMENT SELECTION COUNT
  755.     LDA    SEL$CHAR    ; DISPLAY SELECTION CHAR
  756.     CALL    CHAR$OUT
  757.     INR    A    ; INCR CHAR
  758.     STA    SEL$CHAR
  759.     MVI    A,'.'
  760.     CALL    CHAR$OUT
  761.     MVI    A,' '
  762.     CALL    CHAR$OUT
  763.     CALL    PRINT$LINE    ; PRINT HEADER LINE
  764.     JMP    PH1
  765.  
  766. *  SAVE PTR TO FIRST ENTRY
  767. PH2:
  768.     SHLD    FIRST$ENTRY
  769.     RET
  770.  
  771. *
  772. *  PRINT AN INFORMATION SECTION
  773. *    INFORMATION SECTION IS PTED TO BY HL
  774. *
  775. PRINT$INFO:
  776.     SHLD    START$OF$INFO    ; SET START OF INFORMATION POINTER
  777.     CALL    LOAD$NODE    ; LOAD NEW NODE IF DUAL SECT$CHAR
  778.     SHLD    START$OF$FRAME    ; SET FRAME POINTER
  779.     MOV    A,M    ; SET MSB
  780.     ORI    80H
  781.     MOV    M,A
  782.     CALL    SET$LINE$CNT
  783.     MVI    A,1        ; A=1
  784.     STA    FRAME$NUMBER    ; SET FRAME NUMBER
  785. PI1:
  786.     CALL    PRINT$LINE    ; PRINT LINE FROM INFO FILE
  787.     MOV    A,M    ; DONE?
  788.     ANI    7FH    ; MASK OUT MSB
  789.     CPI    CTRLZ    ; EOF?
  790.     JZ    PI2
  791.     CPI    SECT$CHAR    ; NEXT SECTION
  792.     JZ    PI2
  793.     CPI    FF    ; FORM FEED?
  794.     JNZ    PI1
  795.     INX    H    ; PT TO CHAR AFTER FORM FEED
  796.     CALL    FORM$FEED    ; FEED SCREEN
  797.     JMP    PI1
  798.  
  799. *  FORM FEED SCREEN
  800. FORM$FEED:
  801.     LDA    LINE$CNT    ; GET LINE COUNT
  802.     MOV    B,A    ; ... IN B
  803. FEED$LOOP:
  804.     PUSH    B    ; SAVE B
  805.     CALL    CRLFC    ; NEW LINE
  806.     POP    B    ; GET B
  807.     DCR    B    ; COUNT DOWN
  808.     JNZ    FEED$LOOP
  809.     RET
  810.  
  811. *  END OF INFO
  812. PI2:
  813.     MOV    A,M    ; SET MSB OF NEXT BYTE
  814.     ORI    80H
  815.     MOV    M,A
  816. PI2A:
  817.     CALL    CRLF1    ; NEW LINE
  818.     LDA    LINE$CNT    ; COUNT DOWN
  819.     DCR    A
  820.     STA    LINE$CNT
  821.     JNZ    PI2A
  822. PI2$MSG:
  823.     CALL    PR$LEVEL    ; PRINT LEVEL NUMBER
  824.     LDA    FRAME$NUMBER    ; INCREMENT FRAME NUMBER
  825.     INR    A
  826.     STA    FRAME$NUMBER
  827.     LXI    D,ENDMS        ; PRINT END OF INFORMATION MSG
  828.     CALL    PRINT$MESSAGE
  829.     LXI    D,PAGE1MS    ; PRINT LEVEL UP MESSAGE OPTIONALLY
  830.     LDA    HELP$LEVEL    ; GET CURRENT HELP LEVEL
  831.     ORA    A    ; SET FLAGS
  832.     JZ    PI2$MSG1
  833.     CALL    PRINT$MESSAGE
  834. PI2$MSG1:
  835.     LXI    D,PAGE2MS    ; PRINT REST OF INFO MESSAGE
  836.     CALL    PRINT$MESSAGE
  837.     CALL    CHAR$IN    ; GET ANY CHAR
  838.     CPI    MENU$CHAR    ; MENU ABORT
  839.     JZ    HELP
  840.     CPI    CPM$ABORT$CHAR    ; CP/M ABORT
  841.     JZ    HELP$EXIT
  842.     CPI    ROOT$CHAR    ; GO TO ROOT
  843.     JZ    GO$ROOT
  844.     CPI    LEVEL$RET$CHAR    ; RETURN TO HIGHER LEVEL
  845.     JZ    LEVEL$RETURN
  846.     CPI    BACKUP$CHAR    ; BACK UP FROM EOI?
  847.     JZ    PI2$BACKUP
  848.     CPI    START$CHAR    ; START OF INFO?
  849.     JZ    PI2$START
  850.     CALL    SET$LINE$CNT    ; RESET LINE COUNT IN CASE OF ALL
  851.     RET
  852.  
  853. *  JUMP TO START OF INFO
  854. PI2$START:
  855.     LHLD    START$OF$INFO    ; PT TO START OF INFO
  856.     CALL    FRAME$RESUME    ; RESET POINTERS
  857.     JMP    PI1    ; CONTINUE PROCESSING
  858.  
  859. *  BACK UP TO PREVIOUS FRAME
  860. PI2$BACKUP:
  861.     CALL    BOI$CHECK    ; AT BEGINNING OF INFORMATION?
  862.     JNZ    PI2$BACK    ; CONTINUE IF NOT
  863.     JMP    PI2$MSG
  864. PI2$BACK:
  865.     CALL    FB1    ; BACK UP TO PREVIOUS FRAME
  866.     JMP    PI1    ; CONTINUE PROCESSING
  867.  
  868. *
  869. *  CHECK FOR POSITION AT BEGINNING OF INFORMATION SECTION
  870. *    IF SO, PRINT BACKUP ERROR MESSAGE AND RETURN W/ZERO SET
  871. *
  872. BOI$CHECK:
  873.     LHLD    START$OF$INFO    ; START ADDRESS
  874.     XCHG            ; ... IN DE
  875.     LHLD    START$OF$FRAME    ; FRAME ADDRESS
  876.     MOV    A,D        ; EQUAL?
  877.     CMP    H
  878.     RNZ
  879.     MOV    A,E
  880.     CMP    L
  881.     RNZ
  882.     LXI    D,BACKERR    ; BACKUP ERROR
  883.     CALL    PRINT$MESSAGE
  884.     XRA    A        ; ZERO FLAG SET
  885.     STA    FRAME$NUMBER    ; SET FRAME NUMBER
  886.     RET
  887.  
  888. *
  889. *  AT THE BEGINNING OF AN INFORMATION SECTION (HL PTS TO FIRST CHAR)
  890. *    CHECK TO SEE IF ANOTHER SECT$CHAR FOLLOWS, AND, IF SO, LOAD THE
  891. *    SPECIFIED FILE AS A NEW NODE AND BEGIN PROCESSING IT
  892. *
  893. LOAD$NODE:
  894.     INX    H    ; PT TO POSSIBLE 2ND SECT$CHAR
  895.     MOV    A,M    ; GET IT
  896.     DCX    H    ; PREP FOR RETURN
  897.     ANI    7FH    ; MASK MSB
  898.     CPI    SECT$CHAR    ; ANOTHER ONE?
  899.     RNZ        ; PROCESS NORMALLY IF NOT
  900.  
  901. *  WE HAVE A NEW NODE -- CHECK TO SEE IF WE CAN NEST AGAIN
  902.     LDA    HELP$LEVEL    ; GET CURRENT HELP LEVEL
  903.     CPI    HELP$MAX    ; AT MAXIMUM?
  904.     JNZ    LOAD$NODE1
  905.     LXI    D,LEVELERR    ; LEVEL ERROR MESSAGE
  906.     CALL    PRINT$MESSAGE
  907.     JMP    HELP$EXIT
  908.  
  909. *  WE HAVE NOT REACHED LEVEL LIMIT, SO CONTINUE
  910. *  AT THIS TIME, A=HELP LEVEL INDEX AND HL = PTR TO CURRENT SECTION (::)
  911. LOAD$NODE1:
  912.  
  913. *  SAVE CURRENT HELP FILE NAME FOR RETURN
  914.     INX    H    ; PT TO SECTION SECT$CHAR
  915.     INX    H    ; NOW POINTING TO FILE NAME
  916.     PUSH    H    ; SAVE PTR
  917.     CALL    COMP$HELP$NAME$PTR    ; HL=POINTER TO STACK ELT INDEXED BY A
  918.     XCHG        ; DE=ADDRESS OF NEXT ELEMENT
  919.  
  920. *  COPY CURRENT NODE ELEMENT NAME INTO NEXT STACK ELEMENT
  921.     LXI    H,FCB+1    ; PT TO FILE NAME
  922.     MVI    B,11    ; 11 BYTES
  923.     CALL    MOVE
  924.  
  925. *  INCREMENT HELP LEVEL
  926.     LDA    HELP$LEVEL    ; GET OLD LEVEL
  927.     INR    A    ; SET NEW LEVEL
  928.     STA    HELP$LEVEL
  929.  
  930. *  SET UP FCB FOR NEW FILE
  931.     LXI    D,LOADING$MSG
  932.     CALL    PRINT$MESSAGE
  933.     POP    H    ; GET PTR TO NEW FILE NAME
  934.     LXI    D,FCB+1    ; PT TO FCB NAME
  935.     MVI    B,8    ; 8 CHARS MAX
  936.     CALL    LOAD$FCB    ; PLACE INTO FCB WITH ERROR CHECKING
  937.     MVI    A,'.'    ; DECIMAL BETWEEN FILE NAME AND TYPE
  938.     CALL    CHAR$OUT
  939.     MVI    B,3    ; 3 CHARS MAX FOR TYPE
  940.     CALL    LOAD$FCB    ; PLACE INTO FCB WITH ERROR CHECKING
  941.     CALL    CRLF1    ; NEW LINE
  942.     JMP    START1    ; LOAD NEW HELP FILE
  943.  
  944. *
  945. *  LOAD FCB PTED TO BY DE WITH "NORMAL" FILE NAME PTED TO BY HL FOR B BYTES
  946. *
  947. LOAD$FCB:
  948.     MOV    A,M    ; GET CHAR
  949.     INX    H    ; PT TO NEXT
  950.     CPI    '.'    ; DONE IF DECIMAL
  951.     JZ    LOAD$FCB$FILL
  952.     CPI    ' '+1    ; DONE IF < <SP>
  953.     JC    LOAD$FCB$FILL
  954.     CALL    CAPS    ; CAPITALIZE
  955.     CALL    CHAR$OUT    ; PRINT FILE NAME AND TYPE
  956.     STAX    D    ; STORE CHAR
  957.     INX    D    ; PT TO NEXT
  958.     DCR    B    ; COUNT DOWN
  959.     JNZ    LOAD$FCB
  960.     MOV    A,M    ; CHECK FOR ERROR
  961.     ANI    7FH    ; MASK MSB
  962.     INX    H    ; PT TO NEXT CHAR
  963.     CPI    '.'    ; OK IF '.'
  964.     RZ
  965.     CPI    ' '+1    ; OK IF <SP>
  966.     RC
  967.     LXI    D,LOADERR
  968.     CALL    PRINT$MESSAGE
  969.     JMP    HELP$EXIT
  970. LOAD$FCB$FILL:
  971.     MOV    C,A    ; SAVE CHAR THAT TERMINATED STRING
  972. LOAD$FCB$LOOP:
  973.     MVI    A,' '    ; <SP> FILL REST OF FCB
  974.     STAX    D    ; STORE <SP>
  975.     INX    D    ; PT TO NEXT
  976.     DCR    B    ; COUNT DOWN
  977.     JNZ    LOAD$FCB$LOOP
  978.     MOV    A,C    ; GET CHAR THAT TERMINATED STRING
  979.     RET
  980.  
  981. *
  982. *  GO TO ROOT
  983. *
  984. GO$ROOT:
  985.     LDA    HELP$LEVEL    ; AT ROOT?
  986.     ORA    A    ; 0=YES
  987.     JZ    HELP    ; RETURN TO HELP
  988.     MVI    A,0    ; SET ROOT INDEX
  989.     JMP    GORET
  990.  
  991. *
  992. *  RETURN TO PREVIOUS HELP LEVEL
  993. *
  994. LEVEL$RETURN:
  995.     LDA    HELP$LEVEL    ; ARE WE AT THE LOWEST LEVEL?
  996.     ORA    A    ; 0=YES
  997.     JNZ    LRET
  998.     LXI    D,LRETERR
  999.     CALL    PRINT$MESSAGE
  1000.     JMP    HELP
  1001.  
  1002. *  SET NEW HELP LEVEL
  1003. LRET:
  1004.     DCR    A    ; DOWN 1
  1005.  
  1006. *  GO TO HELP LEVEL INDEXED IN A
  1007. GORET:
  1008.     STA    HELP$LEVEL    ; SET NEW HELP LEVEL
  1009.     CALL    COMP$HELP$NAME$PTR    ; HL=POINTER TO TARGET HELP FILE NAME
  1010.     PUSH    H    ; SAVE PTR TO FILE NAME
  1011.     LXI    D,LOADING$MSG    ; PRINT NAME OF FILE TO BE LOADED
  1012.     CALL    PRINT$MESSAGE
  1013.     MVI    B,8    ; 8 CHARS TO FILE NAME
  1014. GORET$NAME:
  1015.     MOV    A,M    ; GET CHAR
  1016.     CPI    ' '    ; END OF NAME?
  1017.     INX    H    ; PT TO NEXT
  1018.     JZ    GORET$NAME0
  1019.     CALL    CHAR$OUT    ; PRINT FILE NAME
  1020.     DCR    B    ; DONE?
  1021.     JNZ    GORET$NAME
  1022.     JMP    GORET$NAME1
  1023. GORET$NAME0:
  1024.     DCR    B    ; COUNT DOWN
  1025.     JZ    GORET$NAME1
  1026.     INX    H    ; SKIP NEXT SPACE
  1027.     JMP    GORET$NAME0
  1028. GORET$NAME1:
  1029.     MVI    A,'.'    ; PRINT DECIMAL
  1030.     CALL    CHAR$OUT
  1031.     MVI    B,3    ; PRINT FILE TYPE
  1032. GORET$NAME2:
  1033.     MOV    A,M    ; GET CHAR
  1034.     INX    H    ; PT TO NEXT
  1035.     CALL    CHAR$OUT    ; PRINT IT
  1036.     DCR    B    ; COUNT DOWN
  1037.     JNZ    GORET$NAME2
  1038.     CALL    CRLF1    ; NEW LINE
  1039.     POP    H    ; GET PTR TO FILE NAME
  1040.     LXI    D,FCB+1    ; COPY ELEMENT INTO FCB
  1041.     MVI    B,11    ; 11 BYTES
  1042.     CALL    MOVE
  1043.     JMP    START1    ; LOAD ENTRY
  1044.  
  1045. *
  1046. *  COMPUTE POINTER TO HELP NAME ENTRY INDEXED BY HELP LEVEL IN A
  1047. *
  1048. COMP$HELP$NAME$PTR:
  1049.     CALL    COMP$OFFSET    ; COMPUTE OFFSET IN TABLE
  1050.     LXI    D,HELP$NAME$STACK    ; PT TO BASE OF HELP NAMES
  1051.     DAD    D    ; ADD IN OFFSET
  1052.     RET
  1053.  
  1054. *
  1055. *  COMPUTE OFFSET INTO TABLE BASED ON INDEX A
  1056. *    OFFSET = A * 11
  1057. *
  1058. COMP$OFFSET:
  1059.     MOV    L,A    ; VALUE IN HL
  1060.     MVI    H,0
  1061.     MOV    E,L    ; DE=HL
  1062.     MOV    D,H
  1063.  
  1064.     DAD    H    ; *2
  1065.     DAD    H    ; *4
  1066.     DAD    H    ; *8
  1067.     DAD    D    ; *9
  1068.     DAD    D    ; *10
  1069.     DAD    D    ; *11
  1070.     RET
  1071.  
  1072. *
  1073. *  PRINT LEVEL NUMBER
  1074. *
  1075. PR$LEVEL:
  1076.     LDA    HELP$LEVEL    ; DON'T PRINT LEVEL 0
  1077.     ORA    A    ; 0?
  1078.     JZ    PR$FRAME
  1079.     LXI    D,LEVEL$MESSAGE    ; PRINT HEADER
  1080.     CALL    PRINT$MESSAGE
  1081.     LDA    HELP$LEVEL    ; GET NUMBER
  1082.     CALL    PR$DEC        ; PRINT AS DECIMAL
  1083.     LXI    D,LEVEL2$MESSAGE    ; PRINT END HEADER
  1084.     CALL    PRINT$MESSAGE
  1085. PR$FRAME:
  1086.     LDA    FRAME$NUMBER    ; GET CURRENT FRAME NUMBER
  1087.     ORA    A    ; SET FLAGS
  1088.     RZ        ; NO FRAME?
  1089.     CALL    PR$DEC    ; PRINT AS DECIMAL
  1090.     LXI    D,LEVEL3$MESSAGE
  1091.     CALL    PRINT$MESSAGE
  1092.     RET
  1093. *  PRINT A AS DECIMAL
  1094. PR$DEC:
  1095.     PUSH    PSW    ; SAVE VALUE
  1096.     XRA    A
  1097.     STA    LD$SPACE
  1098.     POP    PSW    ; GET VALUE
  1099.     MVI    B,100    ; PRINT 100'S
  1100.     CALL    PDEC
  1101.     MVI    B,10    ; PRINT 10'S
  1102.     CALL    PDEC
  1103.     ADI    '0'    ; PRINT 1'S
  1104.     JMP    CHAR$OUT
  1105. PDEC:
  1106.     MVI    C,0    ; SET VALUE
  1107. PDEC1:
  1108.     SUB    B    ; SUBTRACT POWER
  1109.     JC    PDEC2
  1110.     INR    C    ; INCREMENT VALUE
  1111.     JMP    PDEC1
  1112. PDEC2:
  1113.     ADD    B    ; ADD POWER BACK IN
  1114.     MOV    B,A    ; SAVE A IN B
  1115.     LDA    LD$SPACE    ; GET LEADING <SP> FLAG
  1116.     ORA    A    ; NON-ZERO=PRINT
  1117.     JNZ    PDEC3
  1118.     MOV    A,C    ; GET DIGIT
  1119.     STA    LD$SPACE    ; NEW FLAG
  1120.     ORA    A    ; ZERO?
  1121.     JNZ    PDEC3    ; PRINT BYTE IN C
  1122.     MVI    A,' '    ; PRINT LEADING SPACE
  1123.     JMP    PDEC4
  1124. PDEC3:
  1125.     MOV    A,C    ; GET VALUE
  1126.     ADI    '0'    ; CONVERT TO ASCII
  1127. PDEC4:
  1128.     CALL    CHAR$OUT    ; PRINT CHAR
  1129.     MOV    A,B    ; RESTORE A
  1130.     RET
  1131.  
  1132.  
  1133.  
  1134. *******************************************************
  1135. * USQ support code                                    *
  1136. * Added 10/12/83 by Dave Rand                         *
  1137. *******************************************************
  1138.  
  1139.  
  1140. eof:        equ    1ah
  1141. dle:        equ    090h
  1142.  
  1143.  
  1144. ;this is start of baseline USQ code
  1145.  
  1146. usq:        xra    a        ;force init char read
  1147.         sta    numlft
  1148.         sta    rcnt        ;and zero repeats
  1149.         lhld    lastmem
  1150.         shld    sob
  1151.         shld    eob
  1152.         call    getw
  1153. usq1:        call    getw        ;get cksum, and store
  1154.         shld    filecrc
  1155. usq2:        call    get1
  1156.         jnz    help$exit
  1157.         ora    a
  1158.         jnz    usq2
  1159.  
  1160. usq3a:        call    getw
  1161.         shld    numvals
  1162.         lxi    d,258
  1163.         call    cmpdehl
  1164.         jc    usq3b
  1165.         call    errext
  1166.         db    13,10,'Files has illegal decode size. Aborting.',0
  1167. usq3b:        lxi    d,table
  1168. usq4:        shld    max
  1169.         mov    a,h
  1170.         ora    l
  1171.         jz    usq5
  1172.         push    d
  1173.         call    getw
  1174.         pop    d
  1175.         xchg
  1176.         mov    m,e
  1177.         inx    h
  1178.         mov    m,d
  1179.         inx    h
  1180.         push    h
  1181.         call    getw
  1182.         xchg
  1183.         pop    h
  1184.         mov    m,e
  1185.         inx    h
  1186.         mov    m,d
  1187.         inx    h
  1188.         xchg
  1189.         lhld    max
  1190.         dcx    h
  1191.         jmp    usq4
  1192.  
  1193. usq5:        lxi    h,0
  1194. usq6:        push    h
  1195.         call    getnxt
  1196.         pop    h
  1197.         jnz    usq8
  1198.         mov    e,a
  1199.         mvi    d,0
  1200.         dad    d
  1201.         push    h
  1202.     push    psw
  1203.     LHLD    NEXT$ADR    ; PT TO LOAD ADDRESS
  1204.     LDA    TPA$END    ; CHECK AGAINST END PAGE OF TPA
  1205.     CMP    H    ; IF AT SAME PAGE, YES
  1206.     JZ    READ$ERROR
  1207.     pop    psw
  1208.     mov    m,a
  1209.     inx    h
  1210.     shld    next$adr
  1211.  
  1212.         pop    h
  1213.         jmp    usq6
  1214.  
  1215. usq8:        xchg
  1216.         lhld    filecrc
  1217.         call    cmpdehl
  1218.  
  1219. usq9:        rz
  1220.         call    ilprt
  1221.         db    13,10,'ERROR - Checksum error in file ',0
  1222.         jmp    help$exit
  1223.  
  1224.  
  1225. errext:        pop    h
  1226.         mov    a,m
  1227.         ora    a
  1228.         jz    help$exit
  1229.         inx    h
  1230.         push    h
  1231.         call    conout
  1232.         jmp    errext
  1233.  
  1234. conout:        ani    127
  1235.         mov    e,a
  1236.         mvi    c,2
  1237.         call    bdos
  1238.         ret
  1239.  
  1240.  
  1241. cmpdehl:    mov    a,h
  1242.         cmp    d
  1243.         rnz
  1244.         mov    a,l
  1245.         cmp    e
  1246.         ret
  1247.  
  1248. ilprt:        pop    h
  1249.         mov    a,m
  1250.         ora    a
  1251.         inx    h
  1252.         push    h
  1253.         rz
  1254.         call    conout
  1255.         jmp    ilprt
  1256.  
  1257. get1:        lhld    eob
  1258.         xchg
  1259.         lhld    sob
  1260.         call    cmpdehl
  1261.         jz    get1r
  1262.         mov    a,m
  1263.         inx    h
  1264.         shld    sob
  1265.         cmp    a
  1266.         ret
  1267.  
  1268. get1r:        mvi    a,'.'
  1269.         call    conout
  1270.         lhld    lastmem
  1271.         shld    sob
  1272.         shld    eob
  1273. get1r1:        push    h
  1274.         xchg
  1275.         mvi    c,26
  1276.         call    bdos
  1277.         lxi    d,fcb
  1278.         mvi    c,20
  1279.         call    bdos
  1280.         pop    h
  1281.         ora    a
  1282.         jnz    get1r2
  1283.         lxi    d,128
  1284.         dad    d
  1285.         xchg
  1286.         lhld    endmem
  1287.         call    cmpdehl
  1288.         xchg
  1289.         jnc    get1r1
  1290. get1r2:        shld    eob
  1291.         xchg
  1292.         lhld    sob
  1293.         call    cmpdehl
  1294.         jnz    get1
  1295.         mvi    a,255
  1296.         ora    a
  1297.         ret
  1298.  
  1299.  
  1300.  
  1301. getw:        call    get1
  1302.         jnz    badr
  1303.         push    psw
  1304.         call    get1
  1305.         jnz    badr
  1306.         mov    h,a
  1307.         pop    psw
  1308.         mov    l,a
  1309.         ret
  1310.  
  1311. badr:        call    ilprt
  1312.         db    13,10,'Premature EOF on file... aborted.',0
  1313.         jmp    0
  1314.  
  1315. getnxt:        lda    rcnt        ;see if in the middle of
  1316.         ora    a        ;repeat sequence...
  1317.         jz    getn7
  1318.         dcr    a
  1319.         sta    rcnt
  1320.         lda    last
  1321.         cmp    a
  1322.         ret
  1323. getn7:        call    getn4
  1324.         cpi    dle
  1325.         jnz    getn5
  1326.         call    getn4
  1327.         ora    a
  1328.         jnz    getn6
  1329.         mvi    a,dle        ;dle is encoded as dle,0
  1330.         cmp    a
  1331.         ret
  1332. getn6:        dcr    a
  1333.         dcr    a
  1334.         sta    rcnt
  1335.         lda    last
  1336.         cmp    a
  1337.         ret
  1338. getn5:        sta    last
  1339.         cmp    a
  1340.         ret
  1341.  
  1342.  
  1343. getn4:        lxi    d,0        ;pointer @ sot
  1344.         lda    char
  1345.         mov    c,a
  1346. getn1:        lda    numlft
  1347.         ora    a
  1348.         jnz    getn2
  1349.         push    d
  1350.         call    get1
  1351.         jnz    badr
  1352.         pop    d
  1353.         mov    c,a
  1354.         mvi    a,8
  1355. getn2:        dcr    a
  1356.         sta    numlft
  1357.         mov    a,c
  1358.         rrc
  1359.         mov    c,a
  1360.         lxi    h,table
  1361.         jnc    getn3
  1362.         inx    h
  1363.         inx    h        ;add 2 to point to right node
  1364. getn3:        dad    d
  1365.         dad    d
  1366.         dad    d
  1367.         dad    d        ;ok.. pointing close to right plc..
  1368.         mov    e,m
  1369.         inx    h
  1370.         mov    d,m
  1371.         mov    a,d
  1372.         ani    128
  1373.         jz    getn1
  1374.         mov    a,c
  1375.         sta    char
  1376.         mov    a,d
  1377.         cpi    254        ;is special eof?
  1378.         mvi    a,eof
  1379.         jz    geteof        ;yup
  1380.         mov    a,e
  1381.         cma
  1382.         cmp    a
  1383.         ret
  1384.  
  1385. geteof:        pop    h
  1386.         ora    a
  1387.         ret
  1388.  
  1389.  
  1390. ;end of baseline USQ code
  1391.  
  1392. *********************************************************
  1393. *  MESSAGE AND BUFFER SECTION                *
  1394. *********************************************************
  1395.  
  1396. HELPMS:
  1397.     DB    'HELP  Version ',(VERS/10)+'0','.',(VERS MOD 10)+'0',CR,LF,'$'
  1398. SELECTMS:
  1399.     DB    CR,LF,'  HELP File Selections are --',CR,LF,'$'
  1400. DEFFN:
  1401.     DB    0,'HELP    '
  1402. DEFTYP:
  1403.     DB    'HLP'
  1404. ENDMS:
  1405.     DB    'EOI '
  1406. PAGEMS:
  1407.     DB    '^C=CP/M $'        ; ABORT TO CP/M CHAR
  1408. PAGE1MS:
  1409.     DB    LEVEL$RET$CHAR,'=Level '    ; RETURN TO HIGHER NODE
  1410.     DB    ROOT$CHAR,'=Root $'        ; RETURN TO ROOT
  1411. PAGE2MS:
  1412.     DB    MENU$CHAR,'=Menu '    ; ABORT TO MENU CHAR
  1413.     DB    START$CHAR,'=Start '    ; JUMP TO START OF INFORMATION CHAR
  1414.     DB    BACKUP$CHAR,'=Last '    ; BACK UP TO PREVIOUS FRAME CHAR
  1415.     DB    'CR=Next $'
  1416. ERR1:
  1417.     DB    CR,LF,'HELP FATAL ERROR -- File not Found$'
  1418. ERR2:
  1419.     DB    CR,LF,'HELP ERROR -- Invalid Response',CR,LF,'$'
  1420. ERR3:
  1421.     DB    CR,LF,'HELP ERROR -- EOF on HELP File',CR,LF,'$'
  1422. BACKERR:
  1423.     DB    CR,LF,'HELP ERROR -- Not Possible to Backup Before Start of '
  1424.     DB    'Info',CR,LF,'$'
  1425. LEVELERR:
  1426.     DB    CR,LF,'HELP ERROR -- Node Level Limit Reached -- Aborting'
  1427.     DB    CR,LF,'$'
  1428. LOADERR:
  1429.     DB    CR,LF,'HELP ERROR -- Invalid File Name in Load',CR,LF,'$'
  1430. LRETERR:
  1431.     DB    CR,LF,'HELP ERROR -- No Higher Level to Return to',CR,LF,'$'
  1432. READERR:
  1433.     DB    CR,LF,'HELP ERROR -- Not Enough Room for HELP File',CR,LF,'$'
  1434. CTRLZERR:
  1435.     DB    CR,LF,'HELP ERROR -- HELP File NOT Terminated by ^Z',CR,LF,'$'
  1436. LEVEL$MESSAGE:
  1437.     DB    'Level $'
  1438. LEVEL2$MESSAGE:
  1439.     DB    '/ $'
  1440. LEVEL3$MESSAGE:
  1441.     DB    ': $'
  1442. PROMPT1$MESSAGE:
  1443.     DB    'Type  ^C=CP/M$'
  1444. PROMPT2$MESSAGE:
  1445.     DB    ' ',LEVEL$RET$CHAR,'=Level '
  1446.     DB    ROOT$CHAR,'=Root$'
  1447. PROMPT3$MESSAGE:
  1448.     DB    ' or Enter Selection $'
  1449. LOADING$MSG:
  1450.     DB    CR,LF,'Loading HELP File $'
  1451.  
  1452. lastmem:    dw    buff
  1453. endmem:        dw    buff+127
  1454. sob:        dw    buff
  1455. eob:        dw    buff
  1456.  
  1457. CUR$DISK:
  1458.     DS    1    ; NUMBER OF CURRENT DISK IF CHANGED OR 0FFH=NO CHANGE
  1459. CUR$USER:
  1460.     DS    1    ; NUMBER OF CURRENT USER IF CHANGED OR 0FFH=NO CHANGE
  1461. TPA$END:
  1462.     DS    1    ; END PAGE ADDRESS OF TPA
  1463. START$OF$INFO:
  1464.     DS    2    ; PTR TO START OF CURRENT INFORMATION BLOCK
  1465. START$OF$FRAME:
  1466.     DS    2    ; PTR TO START OF CURRENT FRAME
  1467. SEL$CHAR:
  1468.     DS    1    ; SELECTION TABLE OPTION CHAR
  1469. FIRST$ENTRY:
  1470.     DS    2    ; PTR TO FIRST ENTRY OF INFORMATION SECTION
  1471. LINE$CNT:
  1472.     DS    1    ; LINE COUNT BUFFER
  1473. DFFLG:
  1474.     DS    1    ; DEFAULT FILE FLAG (0=NOT SEARCH FOR, 1=YES)
  1475. NEXT$ADR:
  1476.     DS    2    ; NEXT LOAD ADDRESS
  1477. LD$SPACE:
  1478.     DS    1    ; LEADING SPACE FLAG FOR DECIMAL PRINT
  1479. HELP$LEVEL:
  1480.     DS    1    ; NUMBER OF HELP LEVEL CURRENT NODE IS AT (0=BOTTOM)
  1481. FRAME$NUMBER:
  1482.     DS    1    ; NUMBER OF CURRENT FRAME
  1483.  
  1484. numlft:    ds    1
  1485. rcnt:    ds    1
  1486. filecrc:ds    2
  1487. last:    ds    1
  1488. char:    ds    1
  1489. numvals:ds    2
  1490. max:    ds    2
  1491. table:    ds    258*4
  1492.  
  1493.  
  1494. HELP$NAME$STACK:
  1495.     DS    11*HELP$MAX    ; STACK OF HELP FILE NAMES OF EACH LEVEL
  1496.  
  1497.     DS    80    ; STACK SPACE
  1498. STACK:
  1499.     DS    2    ; CP/M STACK PTR
  1500.  
  1501.  
  1502. *
  1503. *  DEFAULT HELP MESSAGE
  1504. *
  1505. HELP$BUF:
  1506.     DB    ':The HELP Subsystem for Online Documentation'
  1507.     DB    CR,LF,'     This is HELP, the Online Documentation Subsystem.'
  1508.     DB    CR,LF,'The purpose of HELP is to allow the user to '
  1509.     DB    'interactively'
  1510.     DB    CR,LF,'query the *.HLP files of the system in order to receive'
  1511.     DB    CR,LF,'information summaries on various aspects of the user''s'
  1512.     DB    CR,LF,'working environment, such as the language systems he is'
  1513.     DB    CR,LF,'using and certain subsystems available to him.'
  1514.     DB    CR,LF,LF,'     When the user types ''HELP'', a search is done'
  1515.     DB    CR,LF,'for the file ''HELP.HLP''.  If found, the contents of'
  1516.     DB    CR,LF,'this HELP File is displayed to the user; if not found,'
  1517.     DB    CR,LF,'the HELP Information you are now reading is displayed.'
  1518.     DB    CR,LF,LF,'     If the user desires information on a specific'
  1519.     DB    CR,LF,'topic and he has a HELP File of that name (ie, CPM.HLP'
  1520.     DB    CR,LF,'is a HELP File on CP/M), he may issue of HELP Command'
  1521.     DB    CR,LF,'of the form --'
  1522.     DB    CR,LF,'               HELP d:topic'
  1523.     DB    CR,LF,'where "d:" is the disk the HELP File resides on'
  1524.     DB    ' (optional)'
  1525.     DB    CR,LF,'and "topic" is the name of the HELP File (topic.HLP,'
  1526.     DB    CR,LF,'like CPM.HLP).'
  1527.     DB    CR,LF,'     Please refer to the HELP File "HELP.HLP" for'
  1528.     DB    ' more information.'
  1529.  
  1530.     DB    CR,LF,CTRLZ    ; END OF FILE
  1531.  
  1532.  
  1533.     END
  1534.