* PROGRAM NAME: HELP * AUTHOR: RICHARD CONN Update for USQ by Dave Rand * DATE: 12 OCT 83 * VERSION: 1.8 * PREVIOUS VERSIONS: 1.6 (9 SEP 81), 1.7 (10 SEP 81) * PREVIOUS VERSIONS: 1.5 (9 SEP 81), 1.4 (8 SEP 81), 1.3 (8 SEP 81) * PREVIOUS VERSIONS: 1.2 (7 SEP 81), 1.1 (6 OCT 80), 1.0 (18 NOV 79) VERS EQU 18 ; VERSION NUMBER ***************************************************************** * * * HELP -- DISPLAY HELP FILE INFORMATION TO USER ON CON: * * * * -- Command Format -- * * THE HELP COMMAND IS OF THE GENERAL FORM: * * HELP <FILENAME>.<TYP> * * * * <FILENAME>.<TYP> IS OPTIONAL; IF OMITTED COMPLETELY, * * 'HELP.HLP' IS ASSUMED; IF JUST <TYP> IS OMITTED, FILE TYPE * * IS ASSUMED TO BE '.HLP' * * * * -- Basic Background Information -- * * THE HELP COMMAND DISPLAYS THE INFORMATION IN A HELP * * FILE TO THE USER. THERE ARE TWO BASIC TYPES OF HELP FILES -- * * (1) INDEXED AND (2) NON-INDEXED. INDEXED HELP FILES ARE * * THOSE WHICH CONTAIN SEVERAL SECTIONS; THE INDIVIDUAL MAY * * READ ALL OF SUCH A HELP FILE OR JUST SELECTED SECTIONS OF * * THIS FILE. NON-INDEXED HELP FILES CONTAIN ONLY ONE SECTION. * * STRUCTURALLY SPEAKING, HELP FILES CONSIST OF TWO PARTS: * * THE HEADER PART AND THE INFORMATION PART. THE INFORMATION * * PART OF A HELP FILE BEGINS WITH A LINE WHOSE FIRST CHARACTER * * IS A COLON. THE TITLE OF THE INFORMATION SECTION IS ON THIS * * LINE. THE INFORMATION SECTION CONTINUES UNTIL THE NEXT * * INFORMATION SECTION (LINE STARTING WITH A COLON) OR THE END * * OF THE FILE IS ENCOUNTERED. THE HEADER PART CONSISTS OF A * * GROUP OF LINES BEFORE THE FIRST INFORMATION SECTION. IF THE * * FIRST LINE OF A HELP FILE STARTS WITH A COLON, THEN THERE IS * * NO HEADER PART, AND THE HELP FILE IS DUMPED AS ONE * * INFORMATION SECTION. * * THE INFORMATION SECTION IS ITSELF DIVIDED INTO PARTS, * * CALLED FRAMES. A FRAME IS ONE SCREEN DISPLAY, THE SIZE OF * * WHICH IS SET BY AN EQUATE. IF THE HELP FILE CONTAINS A FORM * * FEED CHARACTER, THEN THE CURRENT FRAME IS ABRUPTLY TERMINATED * * AND THE RESET OF THE SCREEN DISPLAY IS FILLED WITH BLANK * * LINES. OTHERWISE, WHEN THE INDICATED NUMBER OF LINES HAVE * * BEEN DISPLAYED, THE HELP PROGRAM PAUSES TO ALLOW THE USER TO * * VIEW THE INFORMATION AND SELECT THE NEXT DIRECTION IN WHICH * * TO GO. * * * * -- Traversing the HELP File -- * * WHILE IN THE HELP SYSTEM, THE USER IS GIVEN SEVERAL * * OPTIONS AT ALL TIMES AS TO WHAT HE CAN DO. * * AT THE MENU LEVEL OF INDEXED HELP FILES, THE USER CAN * * MOVE IN THE FOLLOWING DIRECTIONS: * * 1. SELECTION OF A MENU ITEM, IN WHICH CASE * * HE ENTERS THAT INFORMATION SECTION * * 2. MOVE UP TO THE PREVIOUS LEVEL. IF THE HELP * * FILE THE USER IS IN WAS REACHED THROUGH ANOTHER HELP FILE, * * THE USER CAN RETURN TO THAT HELP FILE (MOVE UP A LEVEL). * * IF THE USER WAS IN THE "SELECT ALL ITEMS" MODE, HE CONTINUES * * WITH THE PREVIOUS HELP FILE WHERE HE LEFT OFF; IF THE USER * * WAS LOOKING AT A SPECIFIC MENU ITEM (WHICH CALLED THE HELP * * FILE HE IS IN NOW), HE IS RETURNED TO THE MENU OF THE CALLING * * HELP FILE. * * 3. EXIT TO CP/M. AT ALL TIMES, THE USER IS * * ALLOWED TO RETURN TO CP/M. * * WHILE IN AN INFORMATION SECTION, THE USER MAY * * MOVE IN THE FOLLOWING DIRECTIONS: * * 1. FORWARD TO THE NEXT FRAME. IF AT THE END * * OF THE INFORMATION SECTION, THIS RETURNS THE USER TO THE * * MENU IF IT IS AN INDEXED HELP FILE, TO CP/M IF THE USER IS * * IN A NON-INDEXED HELP FILE AT LEVEL 0 (NOT CALLED BY ANOTHER * * HELP FILE), OR TO THE CALLING HELP FILE IF NOT AT LEVEL 0. * * 2. BACKWARD TO THE PREVIOUS FRAME. IF AT THE * * BEGINNING OF AN INFORMATION SECTION, AN ERROR MESSAGE IS * * PRINTED. * * 3. TO THE MENU IF IN AN INDEXED HELP FILE. * * 4. TO THE START OF THE CURRENT INFORMATION * * SECTION DIRECTLY. * * 5. TO THE PREVIOUS LEVEL (CALLING HELP FILE). * * * * -- Nodes and Help File Nesting -- * * AN INFORMATION SECTION MAY BEGIN WITH A DOUBLE COLON * * (::), AND THIS DESIGNATOR IS FOLLOWING BY THE FILE NAME OF A * * HELP FILE WHICH IS TO BE LOADED AS A NODE. NODES TO THE HELP * * PROGRAM ARE COMPLETE HELP FILES IN THEMSELVES, AND THEY MAY * * REFER TO OTHER NODES AS WELL. IN THIS WAY, A TREE STRUCTURE * * MAY BE DESIGNED BY THE AUTHOR OF A HELP FILE, EACH NODE OF * * THE TREE BEING A HELP FILE IN ITS OWN RIGHT (WHICH MAY BE * * ACCESSED INDEPENDENTLY). NODES MAY BE NESTED A NUMBER OF * * LEVELS, SPECIFIED BY THE HELP$MAX EQUATE. * * TO VIEW THIS CONCEPT MORE CLEARLY, THE FOLLOWING DIAGRAM* * IS OFFERED: * * -- Basic HELP File -- * * :Info Sect 1 :Info Sect 2 :Info Sect 3 :Info Sect 4 : * * : Text : HELP File : Text : HELP File : * * / \ / \ * * -- SubHelp File 1 -- -- SubHelp File 2 --* * :Info Sect 1 :Info Sect 2 : :Info Sect 1 :Info Sect2* * : Text : HELP File : : Text : Text * * / \ * * -- SubSubHelp File 1 -- * * :Info Sect 1 :Info Sect 2 :Info Sect 3 : * * : Text : HELP File : HELP File : * * / \ / \ * * -- Sub3Help File 1 -- -- Sub3Help File 2 -- * * :Info Sect : :Info Sect 1 :Info Sect 2: * * : Text : : Text : HELP File : * * / \ * * -- Sub4Help File -- * * :Info Sect 1 :Info Sect 2: * * : Text : Text : * * * * AS THE USER CAN SEE, TREE STRUCTURES ARE NOW POSSIBLE. * * ONE HELP FILE CAN REFERENCE ANOTHER WHICH INTURN REFERENCES * * ANOTHER AND SO ON. THERE IS A LIMIT TO HOW DEEP THE NESTING * * MAY GO, AND THAT IS SPECIFIED IN THE EQUATE FOR HELP$MAX. * * * * -- What Help Can Do -- * * SINCE A HELP FILE MUST BE MEMORY RESIDENT, THIS IS * * CONVENIENT IN TWO WAYS: (1) "MASTER" HELP FILES MAY BE * * CREATED WHICH REFERENCE OTHER HELP FILES, AND THE INFORMATION * * ACCESSED FROM A MASTER HELP FILE MAY ENCOMPASS ALL OF THE * * USER'S HELP FILE AND (2) IF THE USER NEEDS INFORMATION * * IN A SPECIFIC SUBJECT AREA AND KNOWS WHICH HELP FILE REFERS * * TO THE INFORMATION HE NEEDS, HE NEED NOT LOAD THE MASTER * * AND THEN TRAVERSE THE TREE TO THE INFORMATION HE NEEDS; HE * * MAY SPECIFY THE SPECIFIC HELP FILE DIRECTLY. * * * * -- Command-Search Hierarchy -- * * ONE OTHER POINT TO NOTE IS THAT THE HELP PROGRAM NOW * * EMPLOYS A COMMAND-SEARCH HIERARCHY IN LOCATING A REFERENCED * * HELP FILE. ONCE A FILE SPECIFICATION IS GIVEN, THE HELP * * PROGRAM SEARCHES THE CURRENT USER AREA ON THE CURRENT DISK FOR* * THE FILE; IF NOT FOUND, IT DROPS TO USER AREA 0 (MAY BE * * CHANGED) ON THE CURRENT DISK IF THE USER IS NOT ALREADY THERE * * AND LOOKS FOR THE FILE; IF NOT FOUND THIS TIME, IT DROPS TO * * USER AREA 0 OF THE DISK ON DRIVE A: AND SEARCHES FOR THE FILE.* * IF NOT FOUND AT THIS POINT, HELP CHECKS TO SEE IF THE REFER- * * ENCED FILE WAS HELP.HLP, IN WHICH CASE IT PRESENTS THE BUILT- * * IN DOCUMENTATION (SEE END OF PROGRAM); FINALLY, IF NONE OF THE* * ABOVE ARE TRUE, HELP ABORTS WITH AN ERROR MESSAGE. * * * * -- HELP File Structure Warning -- * * THERE MUST BE THE SAME NUMBER OF LINES IN THE HEADER * * PART AS THERE ARE INFORMATION SECTIONS. IF NOT, A HELP * * FILE ERROR WILL BE ISSUED IF THE HELP COMMAND ATTEMPTS TO * * READ BEYOND THE END OF THE HELP FILE IN ITS SEARCH FOR AN * * INFORMATION SECTION. * * * ***************************************************************** ***************************************************************** * * * THE HELP PROGRAM IS COMPLETELY TRANSPORTABLE BETWEEN CP/M * * SYSTEMS. * * * ***************************************************************** ***************************************************************** * CP/M AND BASIC CHARACTER DEFINITIONS * ***************************************************************** BDOS EQU 5 ; ADDRESS OF BDOS ENTRY POINT FCB EQU 5CH ; ADDRESS OF FILE CONTROL BLOCK BUFF EQU 80H ; ADDRESS OF DMA BUFFER CR EQU 0DH ; <CR> LF EQU 0AH ; <LF> FF EQU 'L'-40H ; CTRL-L = FORM FEED CTRLZ EQU 'Z'-40H ; CTRL-Z CTRLC EQU 'C'-40H ; CTRL-C ***************************************************************** * SPECIAL CONTROL CHARACTERS WHICH MAY BE RESET BY USER * ***************************************************************** SECT$CHAR EQU ':' ; DEFINED TO BE COLON BACKUP$CHAR EQU 'L' ; BACK UP TO PREVIOUS FRAME CHAR START$CHAR EQU 'S' ; JUMP TO START OF INFORMATION CHAR MENU$CHAR EQU 'M' ; CHAR TO ABORT TO MENU CPM$ABORT$CHAR EQU CTRLC ; CHAR TO ABORT TO CP/M LEVEL$RET$CHAR EQU '^' ; RETURN TO PREVIOUS HELP LEVEL ROOT$CHAR EQU '.' ; RETURN TO ROOT OF HELP ***************************************************************** * USER CUSTOMIZATION -- LINES PER SCREEN DISPLAY * ***************************************************************** LINES$PER$SCREEN EQU 24 ; ASSUME 24 LINES/SCREEN ***************************************************************** * USER CUSTOMIZATION -- DEFAULT USER NUMBER * ***************************************************************** DEFAULT$USER EQU 0 ; DEFAULT USER NUMBER = 0 ***************************************************************** * USER CUSTOMIZATION -- DEFAULT DISK * ***************************************************************** DEFAULT$DISK EQU 'A' ; DEFAULT DISK = A: ***************************************************************** * USER CUSTOMIZATION -- NUMBER OF NODES (LEVELS) IN HELP TREE * ***************************************************************** HELP$MAX EQU 10 ; DEFAULT = 10 (SPACE=11*HELP$MAX) ***************************************************************** * START OF PROGRAM * ***************************************************************** ORG 100H START: LXI H,0 ; GET SP DAD SP SHLD STACK LXI SP,STACK ; NEW STACK LDA BDOS+2 ; BASE PAGE OF BDOS SUI 10 ; 2K + 2 PAGES STA TPA$END XRA A ; A=0 STA DFFLG ; TURN OFF DEFAULT FILE FLAG STA HELP$LEVEL ; SET HELP LEVEL TO 0 (NO RETURN FILE) LXI D,HELPMS ; PRINT OPENING MSG CALL PRINT$MESSAGE LXI H,FCB+1 ; CHECK FOR FILE NAME MOV A,M CPI ' ' ; NONE? JZ DEFAULT$FN ORA A ; ALSO NONE JNZ START1 * INSERT 'HELP.HLP' INTO FCB DEFAULT$FN: DCX H ; PT TO FCB LXI D,DEFFN MVI B,12 ; 12 BYTES XCHG CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES MVI A,1 ; TURN ON DEFAULT FILE FLAG STA DFFLG JMP START2 * START/RESTART HELP PROGRAM (START ON INITIAL ENTRY, RESTART ON NODE LOAD) START1: LXI SP,STACK ; SET STACK POINTER * CLEAR NON-NAME/TYPE BYTES IN FCB LXI H,FCB ; INITIAL ZERO MVI M,0 ; STORE 0 FOR DRIVE (CURRENT LOGGED-IN) LXI D,12 ; SKIP TO EXTENT DAD D MVI B,24 ; FILL 24 BYTES FCB$FILL: MVI M,0 ; ZERO FILL INX H ; PT TO NEXT DCR B ; COUNT DOWN JNZ FCB$FILL * CHECK FOR FILE TYPE LXI H,FCB+9 ; CHECK FOR FILE TYPE MOV A,M CPI ' ' ; NONE? JZ DEFAULT$EXT ORA A ; NONE ALSO JNZ START2 * PLACE DEFAULT FILE TYPE OF '.HLP' IN FCB DEFAULT$EXT: LXI D,DEFTYP MVI B,3 XCHG CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES * OPEN FILE START2: MVI A,0FFH ; SET NO CHANGE FLAG STA CUR$USER ; SET NO USER CHANGE STA CUR$DISK ; SET NO DISK CHANGE * OPTION 1: TRY TO OPEN FILE IN CURRENT USER NUMBER ON CURRENT DISK LXI D,FCB ; PT TO FCB MVI C,15 ; OPEN FILE CALL BDOS CPI 255 ; NOT PRESENT? JNZ START3 MVI C,12 ; GET VERSION NUMBER CALL BDOS MOV A,H ; CP/M 1.X? ORA L JZ START2$DISK ; CHECK FOR DEFAULT DISK IF SO * OPTION 2: TRY TO OPEN FILE IN USER 0 ON CURRENT DISK MVI E,0FFH ; GET CURRENT USER NUMBER MVI C,32 ; GET/SET USER CODE CALL BDOS CPI DEFAULT$USER ; CHECK IF AT USER 0 (OR DEFAULT USER) JZ START2$DISK ; DON'T TRY IF AT USER 0 STA CUR$USER ; SAVE FOR LATER MVI E,DEFAULT$USER ; SET USER 0 (OR DEFAULT USER) MVI C,32 ; GET/SET USER CODE CALL BDOS LXI D,FCB ; TRY TO OPEN FILE AGAIN MVI C,15 ; OPEN FILE CALL BDOS CPI 255 ; NOT PRESENT? JNZ START3 * OPTION 3: TRY TO OPEN FILE IN USER 0 ON DEFAULT DISK IF NOT CURRENT DISK START2$DISK: MVI C,25 ; DETERMINE CURRENT DISK CALL BDOS CPI DEFAULT$DISK-'A' ; ON DEFAULT DISK? JZ START2$DEFAULT STA CUR$DISK ; SAVE DISK NUMBER IN BYTE MVI E,DEFAULT$DISK-'A' ; SELECT DISK A: MVI C,14 ; SELECT DISK CALL BDOS LXI D,FCB ; TRY TO OPEN FILE ONE LAST TIME MVI C,15 ; OPEN FILE CALL BDOS CPI 255 ; NOT PRESENT? JNZ START3 * CHECK FOR DEFAULT FILE SEARCH START2$DEFAULT: CALL RESET$SYSTEM ; RESTORE CURRENT DISK AND USER IF CHANGED * File not found, look for HQP files lxi h,fcb+1+8+1 ;see if already Q mov a,m ani 127 mvi m,'Q' cpi 'Q' jnz start2 ;skip back, and try again LDA DFFLG ; GET DEFAULT FILE FLAG ORA A ; 1=YES, SEARCH FOR DEFAULT FAILED JNZ HELP ; DISPLAY DEFAULT HELP FILE INFORMATION * FILE NOT FOUND -- FATAL ERROR LXI D,ERR1 ; FILE NOT FOUND CALL PRINT$MESSAGE JMP HELP$EXIT * LOAD HELP FILE INFORMATION START3: LXI H,HELP$BUF ; PT TO BUFFER SHLD NEXT$ADR ; SET PTR lda fcb+1+8+1 ;see if sq file ani 127 cpi 'Q' jnz start4 call usq jmp start4a * READ RECORDS UNTIL EOF START4: CALL READ$RECORD ; READ INFO ORA A ; DONE? 0=NO JZ START4 start4a: LXI D,FCB ; CLOSE FILE MVI C,16 ; CLOSE CALL BDOS CALL RESET$SYSTEM ; RESTORE CURRENT DISK AND USER IF CHANGED * * START OF HELP PROGRAM * HELP: LXI SP,STACK ; RESET STACK MVI A,0 ; SET NO FRAME STA FRAME$NUMBER LXI H,HELP$BUF ; PT TO BUFFER MOV A,M ; NO HEADER SECTION? ANI 7FH ; MASK OUT MSB CPI SECT$CHAR JNZ HELP1 ; HEADER SECTION EXISTS CALL PRINT$INFO ; PRINT HELP INFO PTED TO BY HL LDA HELP$LEVEL ; CHECK TO SEE IF WE ARE NOT AT LEVEL 0 ORA A ; 0=LEVEL 0 JZ HELP$EXIT ; ABORT IF SO JMP LEVEL$RETURN ; GO TO PREVIOUS LEVEL IF NOT * EXIT POINT FOR ANY EXIT FROM THE REST OF THE HELP PROGRAM HELP$EXIT: LHLD STACK ; GET CP/M SP SPHL RET ; DONE * PRINT HEADER INFORMATION AND SELECT AN OPTION HELP1: CALL PRINT$HEADER ; PRINT HEADER PUSH B ; SAVE C (NUMBER OF VALID SELECTIONS) CALL CRLF1 ; NEW LINE CALL PR$LEVEL ; PRINT LEVEL NUMBER LXI D,PROMPT1$MESSAGE ; PRINT PROMPT CALL PRINT$MESSAGE LXI D,PROMPT2$MESSAGE ; LEVEL COMMAND LDA HELP$LEVEL ; CURRENT LEVEL = 0? ORA A ; SET FLAGS JZ HELP1A CALL PRINT$MESSAGE HELP1A: LXI D,PROMPT3$MESSAGE CALL PRINT$MESSAGE POP B ; GET C CALL CHAR$IN ; GET RESPONSE CPI CTRLC ; RETURN TO CP/M JZ HELP$EXIT CPI ROOT$CHAR ; GO TO ROOT JZ GO$ROOT CPI LEVEL$RET$CHAR ; RETURN TO PREVIOUS LEVEL JZ LEVEL$RETURN PUSH PSW ; SAVE CHAR CALL CRLF1 POP PSW ; GET CHAR SUI 'A'-1 ; ADJUST FOR COUNT MOV B,A ; SAVE COUNT JZ BAD$RESPONSE JNC HELP2 * INVALID RESPONSE BAD$RESPONSE: LXI D,ERR2 ; INVALID RESPONSE CALL PRINT$MESSAGE JMP HELP1 * VALID RESPONSE -- LOOK FOR AND PRINT INFORMATION SECTION HELP2: INR C ; 1 MORE THAN NUMBER OF POSSIBLE SELECTIONS CMP C ; GREATER THAN NUMBER OF POSSIBLE SELECTIONS? JNC BAD$RESPONSE LHLD FIRST$ENTRY ; GET PTR TO FIRST ENTRY * PRINT INFORMATION WHEN COUNT IS ZERO HELP3: DCR B ; COUNT DOWN JNZ HELP4 CALL PRINT$INFO ; PRINT INFO PTED TO BY HL JMP HELP1 * LOCATE NEXT INFORMATION SECTION HELP4: MOV A,M ; <CTRL-Z>? ANI 7FH ; MASK OUT MSB INX H ; PT TO NEXT BYTE CPI CTRLZ JZ HELP$ERR ; HELP FILE FORMAT ERROR CPI LF ; LINE FEED (WS FILE)? JZ HELP5 CPI CR ; <CR>? JNZ HELP4 INX H ; 1ST BYTE OF NEXT LINE HELP5: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI SECT$CHAR ; NEW SECTION? JZ HELP3 ; CONTINUE LOOP IF SO CPI CTRLZ ; EOF? JNZ HELP4 ; CONTINUE IF NOT * ERROR -- REACHED END OF HELP FILE HELP$ERR: LXI D,ERR3 ; FORMAT ERROR CALL PRINT$MESSAGE JMP HELP1 ********************************************************* * * * HELP SUPPORT ROUTINE SECTION * * * ********************************************************* * * RESTORE CURRENT DISK AND CURRENT USER IF CHANGED * RESET$SYSTEM: LDA CUR$DISK ; CHECK DISK CPI 0FFH ; 0FFH=NO CHANGE JZ RESET$SYS1 MOV E,A ; DISK IN E MVI C,14 ; SELECT DISK CALL BDOS RESET$SYS1: LDA CUR$USER ; CHECK USER CPI 0FFH ; 0FFH=NO CHANGE RZ MOV E,A ; USER IN E MVI C,32 ; GET/SET USER CODE CALL BDOS RET * * INPUT CHAR; CHAR IS IN A * CHAR$IN: PUSH B ! PUSH D ! PUSH H MVI C,1 ; READ CHAR CALL BDOS POP H ! POP D ! POP B PUSH PSW ; SAVE CHAR CALL CRLF1 POP PSW ; RESTORE CHAR * * CAPITALIZE CHAR IN A * CAPS: ANI 7FH ; MASK OUT MSB CPI 61H ; LESS THAN SMALL A? RC CPI 7BH ; LESS THAN LEFT BRACE? RNC ANI 5FH ; CAPITALIZE RET * * PRINT CHAR IN A ON CON: * CHAR$OUT: PUSH PSW ! PUSH B ! PUSH D ! PUSH H MVI C,2 ; WRITE MOV E,A ; CHAR IN E CALL BDOS POP H ! POP D ! POP B ! POP PSW RET * * PRINT ERROR MSG PTED TO BY DE; ENDS IN '$' * PRINT$MESSAGE: PUSH B ! PUSH D ! PUSH H MVI C,9 ; PRINT BUFFER CALL BDOS POP H ! POP D ! POP B RET * * MOVE BYTES PTED TO BY HL TO AREA PTED TO BY DE; B BYTES TO MOVE * MOVE: MOV A,M ; GET BYTE ANI 7FH ; MASK OFF MSB -- IN CASE A WS FILE STAX D ; PUT BYTE INX H ; PT TO NEXT INX D DCR B ; COUNT DOWN JNZ MOVE RET * * READ RECORD FROM DISK; NEXT$ADR CONTAINS ADDRESS TO READ TO * ON RETURN, BDOS ERROR CODE IS IN A (0=NO ERROR) * READ$RECORD: MVI C,20 ; READ NEXT RECORD LXI D,FCB ; PT TO FCB CALL BDOS PUSH PSW ; SAVE RETURN CODE LHLD NEXT$ADR ; PT TO LOAD ADDRESS LDA TPA$END ; CHECK AGAINST END PAGE OF TPA CMP H ; IF AT SAME PAGE, YES JZ READ$ERROR LXI D,BUFF ; PT TO BUFFER TO LOAD FROM MVI B,128 ; NUMBER OF BYTES TO MOVE XCHG CALL MOVE XCHG POP PSW ; GET RETURN CODE ORA A ; DONE? JZ READ$DONE ; RETURN IF NOT * CHECK FOR CTRLZ PUSH H ; SAVE PTR TO NEXT ADDRESS LHLD NEXT$ADR ; PT TO BEGINNING OF BLOCK MVI B,128 ; CHECK 128 BYTES CTRLZ$CHECK: MOV A,M ; GET BYTE ANI 7FH ; MASK OUT MSB INX H ; PT TO NEXT CPI CTRLZ ; EOF? JZ CTRLZ$FOUND DCR B ; COUNT DOWN JNZ CTRLZ$CHECK LXI D,CTRLZERR CALL PRINT$MESSAGE ; NO CTRLZ ERROR JMP HELP$EXIT * FILL REST OF BLOCK WITH CTRLZ CTRLZ$FOUND: DCR B ; COUNT DOWN JZ CTRLZ$DONE MVI M,CTRLZ ; FILL REST OF BLOCK WITH CTRLZ INX H ; PT TO NEXT JMP CTRLZ$FOUND CTRLZ$DONE: POP H ; PT TO NEXT BLOCK ADDRESS * READ OK -- SAVE PTR TO NEXT BLOCK READ$DONE: SHLD NEXT$ADR ; SET NEXT ADDRESS RET READ$ERROR: LXI D,READERR CALL PRINT$MESSAGE JMP HELP$EXIT * * PRINT ONE LINE OF INFO SECTION; HL PTS TO LINE UPON ENTRY; * HL PTS TO FIRST CHAR OF NEXT LINE UPON EXIT * PRINT$LINE: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI CR ; EOL? JZ CRLF CPI LF ; LINE FEED? (WS FILE) JZ CRLF0 CPI CTRLZ ; END OF FILE? JZ CRLFC ; DONE IF SO CALL CHAR$OUT ; PRINT CHAR INX H ; PT TO NEXT JMP PRINT$LINE * * PRINT CRLF, PT TO FIRST CHAR OF NEXT LINE, AND PAGE IF NECESSARY * CRLF: INX H ; PT TO LF CRLF0: INX H ; PT TO 1ST CHAR OF NEXT LINE CRLFC: CALL CRLF1 ; PRINT CRLF LDA LINE$CNT ; GET LINE COUNT DCR A STA LINE$CNT RNZ ; OK -- CONTINUE MOV A,M ; SET MSB OF FIRST CHAR OF NEXT LINE ORI 80H MOV M,A ; MSB IS SET FOR LATER BACKUP FRAME$PAUSE: CALL PR$LEVEL ; PRINT LEVEL NUMBER LDA FRAME$NUMBER ; INCREMENT FRAME NUMBER INR A STA FRAME$NUMBER LXI D,PAGEMS CALL PRINT$MESSAGE ; PRINT PAGE MESSAGE LXI D,PAGE1MS ; NOT LEVEL 0? LDA HELP$LEVEL ; GET LEVEL NUMBER ORA A ; SET FLAGS JZ FP1 CALL PRINT$MESSAGE FP1: LXI D,PAGE2MS CALL PRINT$MESSAGE CALL CHAR$IN ; GET RESPONSE CPI MENU$CHAR ; ABORT? JZ HELP ; START OVER IF SO CPI CPM$ABORT$CHAR ; CP/M ABORT JZ HELP$EXIT CPI ROOT$CHAR ; GO TO ROOT JZ GO$ROOT CPI LEVEL$RET$CHAR ; RETURN TO HIGHER LEVEL JZ LEVEL$RETURN CPI BACKUP$CHAR ; BACK UP? JZ FRAME$BACKUP CPI START$CHAR ; JUMP TO START OF INFO JZ INFO$START FRAME$RESUME: SHLD START$OF$FRAME CALL SET$LINE$CNT CALL CRLF1 ; NEW LINE RET * JUMP TO START OF INFORMATION INFO$START: LHLD START$OF$INFO ; PT TO START OF INFO JMP FRAME$RESUME ; CONTINUE PROCESSING * BACK UP TO PREVIOUS FRAME FRAME$BACKUP: CALL BOI$CHECK ; AT BEGINNING OF INFORMATION? JNZ FB1 ; CONTINUE IF NOT JMP FRAME$PAUSE FB1: DCX H ; BACK UP UNTIL BYTE WITH MSB SET IS FOUND MOV A,M ; GET BYTE ANI 80H JZ FB1 LDA FRAME$NUMBER ; DECREMENT FRAME NUMBER DCR A ; BACK UP TO CURRENT FRAME NUMBER DCR A ; BACK UP TO PREVIOUS FRAME NUMBER STA FRAME$NUMBER JMP FRAME$RESUME ; CONTINUE PROCESSING * * PRINT CR AND LF ONLY * CRLF1: MVI A,CR ; PRINT CR CALL CHAR$OUT MVI A,LF ; PRINT LF CALL CHAR$OUT RET * * SET LINE$CNT VARIABLE TO SCREEN SIZE * SET$LINE$CNT: MVI A,LINES$PER$SCREEN-1 STA LINE$CNT RET * * PRINT THE HEADER SECTION AND LOAD FIRST$ENTRY PTR * ON RETURN, C=NUMBER OF POSSIBLE SELECTIONS * PRINT$HEADER: MVI A,0 ; SET NO FRAME STA FRAME$NUMBER LXI H,HELP$BUF CALL SET$LINE$CNT MVI A,'A' ; INIT SELECTION CHAR STA SEL$CHAR LXI D,SELECTMS CALL PRINT$MESSAGE MVI C,0 ; COUNT NUMBER OF SELECTIONS * PRINT LINE UNTIL FIRST INFORMATION SECTION FOUND PH1: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI SECT$CHAR JZ PH2 CPI CTRLZ ; EOF? -- ABORT JZ HELP$EXIT INR C ; INCREMENT SELECTION COUNT LDA SEL$CHAR ; DISPLAY SELECTION CHAR CALL CHAR$OUT INR A ; INCR CHAR STA SEL$CHAR MVI A,'.' CALL CHAR$OUT MVI A,' ' CALL CHAR$OUT CALL PRINT$LINE ; PRINT HEADER LINE JMP PH1 * SAVE PTR TO FIRST ENTRY PH2: SHLD FIRST$ENTRY RET * * PRINT AN INFORMATION SECTION * INFORMATION SECTION IS PTED TO BY HL * PRINT$INFO: SHLD START$OF$INFO ; SET START OF INFORMATION POINTER CALL LOAD$NODE ; LOAD NEW NODE IF DUAL SECT$CHAR SHLD START$OF$FRAME ; SET FRAME POINTER MOV A,M ; SET MSB ORI 80H MOV M,A CALL SET$LINE$CNT MVI A,1 ; A=1 STA FRAME$NUMBER ; SET FRAME NUMBER PI1: CALL PRINT$LINE ; PRINT LINE FROM INFO FILE MOV A,M ; DONE? ANI 7FH ; MASK OUT MSB CPI CTRLZ ; EOF? JZ PI2 CPI SECT$CHAR ; NEXT SECTION JZ PI2 CPI FF ; FORM FEED? JNZ PI1 INX H ; PT TO CHAR AFTER FORM FEED CALL FORM$FEED ; FEED SCREEN JMP PI1 * FORM FEED SCREEN FORM$FEED: LDA LINE$CNT ; GET LINE COUNT MOV B,A ; ... IN B FEED$LOOP: PUSH B ; SAVE B CALL CRLFC ; NEW LINE POP B ; GET B DCR B ; COUNT DOWN JNZ FEED$LOOP RET * END OF INFO PI2: MOV A,M ; SET MSB OF NEXT BYTE ORI 80H MOV M,A PI2A: CALL CRLF1 ; NEW LINE LDA LINE$CNT ; COUNT DOWN DCR A STA LINE$CNT JNZ PI2A PI2$MSG: CALL PR$LEVEL ; PRINT LEVEL NUMBER LDA FRAME$NUMBER ; INCREMENT FRAME NUMBER INR A STA FRAME$NUMBER LXI D,ENDMS ; PRINT END OF INFORMATION MSG CALL PRINT$MESSAGE LXI D,PAGE1MS ; PRINT LEVEL UP MESSAGE OPTIONALLY LDA HELP$LEVEL ; GET CURRENT HELP LEVEL ORA A ; SET FLAGS JZ PI2$MSG1 CALL PRINT$MESSAGE PI2$MSG1: LXI D,PAGE2MS ; PRINT REST OF INFO MESSAGE CALL PRINT$MESSAGE CALL CHAR$IN ; GET ANY CHAR CPI MENU$CHAR ; MENU ABORT JZ HELP CPI CPM$ABORT$CHAR ; CP/M ABORT JZ HELP$EXIT CPI ROOT$CHAR ; GO TO ROOT JZ GO$ROOT CPI LEVEL$RET$CHAR ; RETURN TO HIGHER LEVEL JZ LEVEL$RETURN CPI BACKUP$CHAR ; BACK UP FROM EOI? JZ PI2$BACKUP CPI START$CHAR ; START OF INFO? JZ PI2$START CALL SET$LINE$CNT ; RESET LINE COUNT IN CASE OF ALL RET * JUMP TO START OF INFO PI2$START: LHLD START$OF$INFO ; PT TO START OF INFO CALL FRAME$RESUME ; RESET POINTERS JMP PI1 ; CONTINUE PROCESSING * BACK UP TO PREVIOUS FRAME PI2$BACKUP: CALL BOI$CHECK ; AT BEGINNING OF INFORMATION? JNZ PI2$BACK ; CONTINUE IF NOT JMP PI2$MSG PI2$BACK: CALL FB1 ; BACK UP TO PREVIOUS FRAME JMP PI1 ; CONTINUE PROCESSING * * CHECK FOR POSITION AT BEGINNING OF INFORMATION SECTION * IF SO, PRINT BACKUP ERROR MESSAGE AND RETURN W/ZERO SET * BOI$CHECK: LHLD START$OF$INFO ; START ADDRESS XCHG ; ... IN DE LHLD START$OF$FRAME ; FRAME ADDRESS MOV A,D ; EQUAL? CMP H RNZ MOV A,E CMP L RNZ LXI D,BACKERR ; BACKUP ERROR CALL PRINT$MESSAGE XRA A ; ZERO FLAG SET STA FRAME$NUMBER ; SET FRAME NUMBER RET * * AT THE BEGINNING OF AN INFORMATION SECTION (HL PTS TO FIRST CHAR) * CHECK TO SEE IF ANOTHER SECT$CHAR FOLLOWS, AND, IF SO, LOAD THE * SPECIFIED FILE AS A NEW NODE AND BEGIN PROCESSING IT * LOAD$NODE: INX H ; PT TO POSSIBLE 2ND SECT$CHAR MOV A,M ; GET IT DCX H ; PREP FOR RETURN ANI 7FH ; MASK MSB CPI SECT$CHAR ; ANOTHER ONE? RNZ ; PROCESS NORMALLY IF NOT * WE HAVE A NEW NODE -- CHECK TO SEE IF WE CAN NEST AGAIN LDA HELP$LEVEL ; GET CURRENT HELP LEVEL CPI HELP$MAX ; AT MAXIMUM? JNZ LOAD$NODE1 LXI D,LEVELERR ; LEVEL ERROR MESSAGE CALL PRINT$MESSAGE JMP HELP$EXIT * WE HAVE NOT REACHED LEVEL LIMIT, SO CONTINUE * AT THIS TIME, A=HELP LEVEL INDEX AND HL = PTR TO CURRENT SECTION (::) LOAD$NODE1: * SAVE CURRENT HELP FILE NAME FOR RETURN INX H ; PT TO SECTION SECT$CHAR INX H ; NOW POINTING TO FILE NAME PUSH H ; SAVE PTR CALL COMP$HELP$NAME$PTR ; HL=POINTER TO STACK ELT INDEXED BY A XCHG ; DE=ADDRESS OF NEXT ELEMENT * COPY CURRENT NODE ELEMENT NAME INTO NEXT STACK ELEMENT LXI H,FCB+1 ; PT TO FILE NAME MVI B,11 ; 11 BYTES CALL MOVE * INCREMENT HELP LEVEL LDA HELP$LEVEL ; GET OLD LEVEL INR A ; SET NEW LEVEL STA HELP$LEVEL * SET UP FCB FOR NEW FILE LXI D,LOADING$MSG CALL PRINT$MESSAGE POP H ; GET PTR TO NEW FILE NAME LXI D,FCB+1 ; PT TO FCB NAME MVI B,8 ; 8 CHARS MAX CALL LOAD$FCB ; PLACE INTO FCB WITH ERROR CHECKING MVI A,'.' ; DECIMAL BETWEEN FILE NAME AND TYPE CALL CHAR$OUT MVI B,3 ; 3 CHARS MAX FOR TYPE CALL LOAD$FCB ; PLACE INTO FCB WITH ERROR CHECKING CALL CRLF1 ; NEW LINE JMP START1 ; LOAD NEW HELP FILE * * LOAD FCB PTED TO BY DE WITH "NORMAL" FILE NAME PTED TO BY HL FOR B BYTES * LOAD$FCB: MOV A,M ; GET CHAR INX H ; PT TO NEXT CPI '.' ; DONE IF DECIMAL JZ LOAD$FCB$FILL CPI ' '+1 ; DONE IF < <SP> JC LOAD$FCB$FILL CALL CAPS ; CAPITALIZE CALL CHAR$OUT ; PRINT FILE NAME AND TYPE STAX D ; STORE CHAR INX D ; PT TO NEXT DCR B ; COUNT DOWN JNZ LOAD$FCB MOV A,M ; CHECK FOR ERROR ANI 7FH ; MASK MSB INX H ; PT TO NEXT CHAR CPI '.' ; OK IF '.' RZ CPI ' '+1 ; OK IF <SP> RC LXI D,LOADERR CALL PRINT$MESSAGE JMP HELP$EXIT LOAD$FCB$FILL: MOV C,A ; SAVE CHAR THAT TERMINATED STRING LOAD$FCB$LOOP: MVI A,' ' ; <SP> FILL REST OF FCB STAX D ; STORE <SP> INX D ; PT TO NEXT DCR B ; COUNT DOWN JNZ LOAD$FCB$LOOP MOV A,C ; GET CHAR THAT TERMINATED STRING RET * * GO TO ROOT * GO$ROOT: LDA HELP$LEVEL ; AT ROOT? ORA A ; 0=YES JZ HELP ; RETURN TO HELP MVI A,0 ; SET ROOT INDEX JMP GORET * * RETURN TO PREVIOUS HELP LEVEL * LEVEL$RETURN: LDA HELP$LEVEL ; ARE WE AT THE LOWEST LEVEL? ORA A ; 0=YES JNZ LRET LXI D,LRETERR CALL PRINT$MESSAGE JMP HELP * SET NEW HELP LEVEL LRET: DCR A ; DOWN 1 * GO TO HELP LEVEL INDEXED IN A GORET: STA HELP$LEVEL ; SET NEW HELP LEVEL CALL COMP$HELP$NAME$PTR ; HL=POINTER TO TARGET HELP FILE NAME PUSH H ; SAVE PTR TO FILE NAME LXI D,LOADING$MSG ; PRINT NAME OF FILE TO BE LOADED CALL PRINT$MESSAGE MVI B,8 ; 8 CHARS TO FILE NAME GORET$NAME: MOV A,M ; GET CHAR CPI ' ' ; END OF NAME? INX H ; PT TO NEXT JZ GORET$NAME0 CALL CHAR$OUT ; PRINT FILE NAME DCR B ; DONE? JNZ GORET$NAME JMP GORET$NAME1 GORET$NAME0: DCR B ; COUNT DOWN JZ GORET$NAME1 INX H ; SKIP NEXT SPACE JMP GORET$NAME0 GORET$NAME1: MVI A,'.' ; PRINT DECIMAL CALL CHAR$OUT MVI B,3 ; PRINT FILE TYPE GORET$NAME2: MOV A,M ; GET CHAR INX H ; PT TO NEXT CALL CHAR$OUT ; PRINT IT DCR B ; COUNT DOWN JNZ GORET$NAME2 CALL CRLF1 ; NEW LINE POP H ; GET PTR TO FILE NAME LXI D,FCB+1 ; COPY ELEMENT INTO FCB MVI B,11 ; 11 BYTES CALL MOVE JMP START1 ; LOAD ENTRY * * COMPUTE POINTER TO HELP NAME ENTRY INDEXED BY HELP LEVEL IN A * COMP$HELP$NAME$PTR: CALL COMP$OFFSET ; COMPUTE OFFSET IN TABLE LXI D,HELP$NAME$STACK ; PT TO BASE OF HELP NAMES DAD D ; ADD IN OFFSET RET * * COMPUTE OFFSET INTO TABLE BASED ON INDEX A * OFFSET = A * 11 * COMP$OFFSET: MOV L,A ; VALUE IN HL MVI H,0 MOV E,L ; DE=HL MOV D,H DAD H ; *2 DAD H ; *4 DAD H ; *8 DAD D ; *9 DAD D ; *10 DAD D ; *11 RET * * PRINT LEVEL NUMBER * PR$LEVEL: LDA HELP$LEVEL ; DON'T PRINT LEVEL 0 ORA A ; 0? JZ PR$FRAME LXI D,LEVEL$MESSAGE ; PRINT HEADER CALL PRINT$MESSAGE LDA HELP$LEVEL ; GET NUMBER CALL PR$DEC ; PRINT AS DECIMAL LXI D,LEVEL2$MESSAGE ; PRINT END HEADER CALL PRINT$MESSAGE PR$FRAME: LDA FRAME$NUMBER ; GET CURRENT FRAME NUMBER ORA A ; SET FLAGS RZ ; NO FRAME? CALL PR$DEC ; PRINT AS DECIMAL LXI D,LEVEL3$MESSAGE CALL PRINT$MESSAGE RET * PRINT A AS DECIMAL PR$DEC: PUSH PSW ; SAVE VALUE XRA A STA LD$SPACE POP PSW ; GET VALUE MVI B,100 ; PRINT 100'S CALL PDEC MVI B,10 ; PRINT 10'S CALL PDEC ADI '0' ; PRINT 1'S JMP CHAR$OUT PDEC: MVI C,0 ; SET VALUE PDEC1: SUB B ; SUBTRACT POWER JC PDEC2 INR C ; INCREMENT VALUE JMP PDEC1 PDEC2: ADD B ; ADD POWER BACK IN MOV B,A ; SAVE A IN B LDA LD$SPACE ; GET LEADING <SP> FLAG ORA A ; NON-ZERO=PRINT JNZ PDEC3 MOV A,C ; GET DIGIT STA LD$SPACE ; NEW FLAG ORA A ; ZERO? JNZ PDEC3 ; PRINT BYTE IN C MVI A,' ' ; PRINT LEADING SPACE JMP PDEC4 PDEC3: MOV A,C ; GET VALUE ADI '0' ; CONVERT TO ASCII PDEC4: CALL CHAR$OUT ; PRINT CHAR MOV A,B ; RESTORE A RET ******************************************************* * USQ support code * * Added 10/12/83 by Dave Rand * ******************************************************* eof: equ 1ah dle: equ 090h ;this is start of baseline USQ code usq: xra a ;force init char read sta numlft sta rcnt ;and zero repeats lhld lastmem shld sob shld eob call getw usq1: call getw ;get cksum, and store shld filecrc usq2: call get1 jnz help$exit ora a jnz usq2 usq3a: call getw shld numvals lxi d,258 call cmpdehl jc usq3b call errext db 13,10,'Files has illegal decode size. Aborting.',0 usq3b: lxi d,table usq4: shld max mov a,h ora l jz usq5 push d call getw pop d xchg mov m,e inx h mov m,d inx h push h call getw xchg pop h mov m,e inx h mov m,d inx h xchg lhld max dcx h jmp usq4 usq5: lxi h,0 usq6: push h call getnxt pop h jnz usq8 mov e,a mvi d,0 dad d push h push psw LHLD NEXT$ADR ; PT TO LOAD ADDRESS LDA TPA$END ; CHECK AGAINST END PAGE OF TPA CMP H ; IF AT SAME PAGE, YES JZ READ$ERROR pop psw mov m,a inx h shld next$adr pop h jmp usq6 usq8: xchg lhld filecrc call cmpdehl usq9: rz call ilprt db 13,10,'ERROR - Checksum error in file ',0 jmp help$exit errext: pop h mov a,m ora a jz help$exit inx h push h call conout jmp errext conout: ani 127 mov e,a mvi c,2 call bdos ret cmpdehl: mov a,h cmp d rnz mov a,l cmp e ret ilprt: pop h mov a,m ora a inx h push h rz call conout jmp ilprt get1: lhld eob xchg lhld sob call cmpdehl jz get1r mov a,m inx h shld sob cmp a ret get1r: mvi a,'.' call conout lhld lastmem shld sob shld eob get1r1: push h xchg mvi c,26 call bdos lxi d,fcb mvi c,20 call bdos pop h ora a jnz get1r2 lxi d,128 dad d xchg lhld endmem call cmpdehl xchg jnc get1r1 get1r2: shld eob xchg lhld sob call cmpdehl jnz get1 mvi a,255 ora a ret getw: call get1 jnz badr push psw call get1 jnz badr mov h,a pop psw mov l,a ret badr: call ilprt db 13,10,'Premature EOF on file... aborted.',0 jmp 0 getnxt: lda rcnt ;see if in the middle of ora a ;repeat sequence... jz getn7 dcr a sta rcnt lda last cmp a ret getn7: call getn4 cpi dle jnz getn5 call getn4 ora a jnz getn6 mvi a,dle ;dle is encoded as dle,0 cmp a ret getn6: dcr a dcr a sta rcnt lda last cmp a ret getn5: sta last cmp a ret getn4: lxi d,0 ;pointer @ sot lda char mov c,a getn1: lda numlft ora a jnz getn2 push d call get1 jnz badr pop d mov c,a mvi a,8 getn2: dcr a sta numlft mov a,c rrc mov c,a lxi h,table jnc getn3 inx h inx h ;add 2 to point to right node getn3: dad d dad d dad d dad d ;ok.. pointing close to right plc.. mov e,m inx h mov d,m mov a,d ani 128 jz getn1 mov a,c sta char mov a,d cpi 254 ;is special eof? mvi a,eof jz geteof ;yup mov a,e cma cmp a ret geteof: pop h ora a ret ;end of baseline USQ code ********************************************************* * MESSAGE AND BUFFER SECTION * ********************************************************* HELPMS: DB 'HELP Version ',(VERS/10)+'0','.',(VERS MOD 10)+'0',CR,LF,'$' SELECTMS: DB CR,LF,' HELP File Selections are --',CR,LF,'$' DEFFN: DB 0,'HELP ' DEFTYP: DB 'HLP' ENDMS: DB 'EOI ' PAGEMS: DB '^C=CP/M $' ; ABORT TO CP/M CHAR PAGE1MS: DB LEVEL$RET$CHAR,'=Level ' ; RETURN TO HIGHER NODE DB ROOT$CHAR,'=Root $' ; RETURN TO ROOT PAGE2MS: DB MENU$CHAR,'=Menu ' ; ABORT TO MENU CHAR DB START$CHAR,'=Start ' ; JUMP TO START OF INFORMATION CHAR DB BACKUP$CHAR,'=Last ' ; BACK UP TO PREVIOUS FRAME CHAR DB 'CR=Next $' ERR1: DB CR,LF,'HELP FATAL ERROR -- File not Found$' ERR2: DB CR,LF,'HELP ERROR -- Invalid Response',CR,LF,'$' ERR3: DB CR,LF,'HELP ERROR -- EOF on HELP File',CR,LF,'$' BACKERR: DB CR,LF,'HELP ERROR -- Not Possible to Backup Before Start of ' DB 'Info',CR,LF,'$' LEVELERR: DB CR,LF,'HELP ERROR -- Node Level Limit Reached -- Aborting' DB CR,LF,'$' LOADERR: DB CR,LF,'HELP ERROR -- Invalid File Name in Load',CR,LF,'$' LRETERR: DB CR,LF,'HELP ERROR -- No Higher Level to Return to',CR,LF,'$' READERR: DB CR,LF,'HELP ERROR -- Not Enough Room for HELP File',CR,LF,'$' CTRLZERR: DB CR,LF,'HELP ERROR -- HELP File NOT Terminated by ^Z',CR,LF,'$' LEVEL$MESSAGE: DB 'Level $' LEVEL2$MESSAGE: DB '/ $' LEVEL3$MESSAGE: DB ': $' PROMPT1$MESSAGE: DB 'Type ^C=CP/M$' PROMPT2$MESSAGE: DB ' ',LEVEL$RET$CHAR,'=Level ' DB ROOT$CHAR,'=Root$' PROMPT3$MESSAGE: DB ' or Enter Selection $' LOADING$MSG: DB CR,LF,'Loading HELP File $' lastmem: dw buff endmem: dw buff+127 sob: dw buff eob: dw buff CUR$DISK: DS 1 ; NUMBER OF CURRENT DISK IF CHANGED OR 0FFH=NO CHANGE CUR$USER: DS 1 ; NUMBER OF CURRENT USER IF CHANGED OR 0FFH=NO CHANGE TPA$END: DS 1 ; END PAGE ADDRESS OF TPA START$OF$INFO: DS 2 ; PTR TO START OF CURRENT INFORMATION BLOCK START$OF$FRAME: DS 2 ; PTR TO START OF CURRENT FRAME SEL$CHAR: DS 1 ; SELECTION TABLE OPTION CHAR FIRST$ENTRY: DS 2 ; PTR TO FIRST ENTRY OF INFORMATION SECTION LINE$CNT: DS 1 ; LINE COUNT BUFFER DFFLG: DS 1 ; DEFAULT FILE FLAG (0=NOT SEARCH FOR, 1=YES) NEXT$ADR: DS 2 ; NEXT LOAD ADDRESS LD$SPACE: DS 1 ; LEADING SPACE FLAG FOR DECIMAL PRINT HELP$LEVEL: DS 1 ; NUMBER OF HELP LEVEL CURRENT NODE IS AT (0=BOTTOM) FRAME$NUMBER: DS 1 ; NUMBER OF CURRENT FRAME numlft: ds 1 rcnt: ds 1 filecrc:ds 2 last: ds 1 char: ds 1 numvals:ds 2 max: ds 2 table: ds 258*4 HELP$NAME$STACK: DS 11*HELP$MAX ; STACK OF HELP FILE NAMES OF EACH LEVEL DS 80 ; STACK SPACE STACK: DS 2 ; CP/M STACK PTR * * DEFAULT HELP MESSAGE * HELP$BUF: DB ':The HELP Subsystem for Online Documentation' DB CR,LF,' This is HELP, the Online Documentation Subsystem.' DB CR,LF,'The purpose of HELP is to allow the user to ' DB 'interactively' DB CR,LF,'query the *.HLP files of the system in order to receive' DB CR,LF,'information summaries on various aspects of the user''s' DB CR,LF,'working environment, such as the language systems he is' DB CR,LF,'using and certain subsystems available to him.' DB CR,LF,LF,' When the user types ''HELP'', a search is done' DB CR,LF,'for the file ''HELP.HLP''. If found, the contents of' DB CR,LF,'this HELP File is displayed to the user; if not found,' DB CR,LF,'the HELP Information you are now reading is displayed.' DB CR,LF,LF,' If the user desires information on a specific' DB CR,LF,'topic and he has a HELP File of that name (ie, CPM.HLP' DB CR,LF,'is a HELP File on CP/M), he may issue of HELP Command' DB CR,LF,'of the form --' DB CR,LF,' HELP d:topic' DB CR,LF,'where "d:" is the disk the HELP File resides on' DB ' (optional)' DB CR,LF,'and "topic" is the name of the HELP File (topic.HLP,' DB CR,LF,'like CPM.HLP).' DB CR,LF,' Please refer to the HELP File "HELP.HLP" for' DB ' more information.' DB CR,LF,CTRLZ ; END OF FILE END