; PROGRAM NAME: HELP ; AUTHOR: RICHARD CONN ; DATE: 04 February 1984 ; VERSION: 1.5 - 86 ; PREVIOUS VERSIONS, Latest version first: ; ; ; 29/Feb/84 Run through XLT86 to create CP/M-86 version. ; Used GENCMD HELP15 DATA[MFFF] when creating CMD ; file. One of the easiest XLT's I've ever done! ; Bill Bolton, Software Tools RCPM, Australia ; ; 04/Feb/84 Added wildcard check to filename, end of TPA buffer ; check added. Version 1.5, Bill Bolton, Software Tools RCPM ; ; 16/Jul/82 Changed default HLP file to QUICK and modified ; internal messages for RCPM use. Version 1.4. Bill Bolton ; ; 06/Jun/82 Modifications for RCPM system use. Line noise ; was resulting in false answers to "go on" prompts. ; Test for response changed to accept only . ; Messages tightened up and an alternative end of ; category message added for the "all categories" ; condition. Console input changed to Direct Console ; I/O (BDOS 6) making CP/M 2.2 or later mandatory. ; Version 1.3. Bill Bolton, Software Tools RCPM ; ; 22/Jun/81 Added code for standard or modified CP/M. Changed "*" ; in Col 1 to ";". Changed labels so that the program would ; assemble with other assemblers. Version 1.2 Ted Shapin. ; ; 06/Oct/80 Version 1.1 (changes undocumented). Richard Conn. ; ; 18/Nov/79 Version 1.0 Original release. Richard Conn. ; ; ;**************************************************************** ;* * ;* HELP -- DISPLAY HELP FILE INFORMATION TO USER ON CON: * ;* * ;* THE HELP COMMAND IS OF THE GENERAL FORM: * ;* HELP . * ;* * ;* . IS OPTIONAL; IF OMITTED COMPLETELY, * ;* 'QUICK.HLP' IS ASSUMED; IF JUST IS OMITTED, * ;* EXTENSION IS ASSUMED TO BE '.HLP' * ;* * ;* 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. * ;* 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 LENFCB EQU 11 ; Length of filename in FCB CR EQU 0DH ; LF EQU 0AH ; FF EQU 'L'-40H ; CTRL-L = FORM FEED CTRLZ EQU 'Z'-40H ; CTRL-Z CTRLC EQU 'C'-40H ; CTRL-C ; M EQU Byte Ptr 0[BX] ; ;**************************************************************** ;* CHARACTER WHICH MARKS START OF INFORMATION SECTION * ;**************************************************************** ; SECT@CHAR EQU ':' ; DEFINED TO BE COLON ALL@CHAR EQU '*' ; ALL OF HELP FILE DESIGNATOR ; ;**************************************************************** ;* USER CUSTOMIZATION -- LINES PER SCREEN DISPLAY * ;**************************************************************** ; LINES@PER@SCREEN EQU 24 ; ASSUME 24 LINES/SCREEN ; ;**************************************************************** ;* START OF PROGRAM * ;**************************************************************** ; CSEG START: XOR AL,AL ; TURN OFF DEFAULT FILE FLAG MOV Byte Ptr DFFLG,AL MOV DX,(Offset HELPMS) ; PRINT OPENING MSG CALL PRINT@MESSAGE MOV BX,FCB+1 ; CHECK FOR FILE NAME MOV AL,M CMP AL,' ' ; NONE? JZ DEFAULT@FN OR AL,AL ; ALSO NONE JNZ START1 ; ; INSERT 'QUICK.HLP' INTO FCB ; DEFAULT@FN: DEC BX ; PT TO FCB MOV DX,(Offset DEFFN) MOV CH,12 ; 12 BYTES XCHG BX,DX CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES MOV AL,1 ; TURN ON DEFAULT FILE FLAG MOV Byte Ptr DFFLG,AL JMPS START2 ; ; CHECK FOR EXTENSION TO FILE NAME ; START1: MOV BX,FCB+9 ; CHECK FOR EXTENSION MOV AL,M CMP AL,' ' ; NONE? JZ DEFAULT@EXT OR AL,AL ; NONE ALSO JNZ START2 ; ; PLACE DEFAULT EXTENSION OF '.HLP' IN FCB ; DEFAULT@EXT: MOV DX,(Offset DEFEXT) MOV CH,3 XCHG BX,DX CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES ; ; OPEN FILE ; START2: MOV BX,FCB+1 ;Point to FCB MOV CL,LENFCB PARSE: MOV AL,M ;Get a character from FCB CMP AL,'?' ;Is it a wildcard? JZ WILDEXIT ;Yes INC BX ;Point to next character DEC CL ;No, done yet JNZ PARSE ;No MOV DX,FCB ;Yes, Point to fcb MOV CL,15 ; OPEN FILE INT 224 CMP AL,0FFH ; NOT PRESENT? JNZ START3 ; ; CHECK FOR DEFAULT FILE SEARCH ; MOV AL,Byte Ptr DFFLG ; GET DEFAULT FILE FLAG OR AL,AL ; 1=YES, SEARCH FOR DEFAULT FAILED JNZ HELP ; DISPLAY DEFAULT HELP FILE INFORMATION ; ; FILE NOT FOUND -- FATAL ERROR ; MOV DX,(Offset ERR1) ; FILE NOT FOUND CALL PRINT@MESSAGE JMPS HELP@EXIT ; WILDEXIT: MOV DX,(Offset ERR1A) ; Wildcard error message CALL PRINT@MESSAGE JMPS HELP@EXIT ; ; LOAD HELP FILE INFORMATION ; START3: MOV BX,(Offset HELP@BUF) ; PT TO BUFFER MOV Word Ptr NEXT@ADR,BX ; SET PTR ; ; READ RECORDS UNTIL EOF ; START4: CALL READ@RECORD ; READ INFO OR AL,AL ; DONE? 0=NO JZ START4 ; ; START OF HELP PROGRAM ; HELP: MOV BX,(Offset HELP@BUF) ; PT TO BUFFER MOV AL,M ; NO HEADER SECTION? CMP AL,SECT@CHAR JNZ HELP1 ; HEADER SECTION EXISTS CALL PRINT@INFO ; PRINT HELP INFO PTED TO BY HL ; ; EXIT POINT FOR ANY EXIT FROM THE REST OF THE HELP PROGRAM ; HELP@EXIT: MOV DX,0 MOV CX,0 INT 224 ; ; PRINT HEADER INFORMATION AND SELECT AN OPTION ; HELP1: MOV AL,0 MOV Byte Ptr ALLFLAG,AL ; RESET ALL CATEGORIES FLAG CALL PRINT@HEADER ; PRINT HEADER MOV DX,(Offset PROMPT@MESSAGE) ; PRINT PROMPT CALL PRINT@MESSAGE CALL CHAR@IN ; GET RESPONSE CMP AL,CTRLC ; RETURN TO CP/M JZ HELP@EXIT CALL CHAR@OUT ; DISPLAY ENTERED CHAR CMP AL,ALL@CHAR ; ALL OF HELP FILE? JZ HELP@ALL AND AL,0DFH ; CAPITALIZE LAHF ; SAVE CHAR XCHG AL,AH PUSH AX CALL CRLF1 POP AX ; GET CHAR XCHG AL,AH SUB AL,'A'-1 ; ADJUST FOR COUNT MOV CH,AL ; SAVE COUNT JZ BAD@RESPONSE JNB HELP2 ; ; INVALID RESPONSE ; BAD@RESPONSE: MOV DX,(Offset ERR2) ; INVALID RESPONSE CALL PRINT@MESSAGE JMPS HELP1 ; ; VALID RESPONSE -- LOOK FOR AND PRINT INFORMATION SECTION ; HELP2: INC CL ; 1 MORE THAN NUMBER OF POSSIBLE SELECTIONS CMP AL,CL ; GREATER THAN NUMBER OF POSSIBLE SELECTIONS? JNB BAD@RESPONSE MOV BX,Word Ptr FIRST@ENTRY ; GET PTR TO FIRST ENTRY ; ; PRINT INFORMATION WHEN COUNT IS ZERO ; HELP3: DEC CH ; COUNT DOWN JNZ HELP4 LAHF ; SKIP OVER COLON INC BX SAHF CALL PRINT@INFO ; PRINT INFO PTED TO BY HL JMPS HELP1 ; ; LOCATE NEXT INFORMATION SECTION ; HELP4: MOV AL,M ; ? INC BX ; PT TO NEXT BYTE CMP AL,CTRLZ JZ HELP@ERR ; HELP FILE FORMAT ERROR CMP AL,LF ; LINE FEED (WS FILE)? JZ HELP5 CMP AL,CR ; ? JNZ HELP4 INC BX ; 1ST BYTE OF NEXT LINE HELP5: MOV AL,M ; GET CHAR CMP AL,SECT@CHAR ; NEW SECTION? JZ HELP3 ; CONTINUE LOOP IF SO CMP AL,CTRLZ ; EOF? JNZ HELP4 ; CONTINUE IF NOT ; ; ERROR -- REACHED END OF HELP FILE ; HELP@ERR: MOV DX,(Offset ERR3) ; FORMAT ERROR CALL PRINT@MESSAGE JMP HELP1 ; ; PRINT ALL OF HELP FILE ; HELP@ALL: MOV Byte Ptr ALLFLAG,AL ; FOR LATER CALL CRLF1 ; START ON NEW LINE MOV BX,Word Ptr FIRST@ENTRY ; PT TO FIRST ENTRY CALL SET@LINE@CNT ; SET LINE COUNT ; ; EXECUTE UNTIL A CTRL-Z IS ENCOUNTERED ; HA1: INC BX ; SKIP OVER COLON CALL PI1 ; PRINT INFO W/OUT LINE CNT INFO MOV AL,M ; GET LAST CHAR CMP AL,CTRLZ JNZ HA1 JMP HELP ; ;******************************************************** ;* * ;* HELP SUPPORT ROUTINE SECTION * ;* * ;******************************************************** ; ; INPUT CHAR; CHAR IS IN AL ; CHAR@IN: PUSH CX PUSH DX PUSH BX MOV CL,6 ; DIRECT CONSOLE I/O MOV DL,0FFH ; INPUT INT 224 POP BX POP DX POP CX OR AL,AL ; CHARACTER? JZ CHAR@IN ; NO, KEEP LOOKING RET ; ; PRINT CHAR IN AL ON CON: ; CHAR@OUT: LAHF XCHG AL,AH PUSH AX XCHG AL,AH PUSH CX PUSH DX PUSH BX MOV CL,2 ; WRITE MOV DL,AL ; CHAR IN DL INT 224 POP BX POP DX POP CX POP AX XCHG AL,AH SAHF RET ; ; PRINT ERROR MSG PTED TO BY DE; ENDS IN '$' ; PRINT@MESSAGE: PUSH CX PUSH DX PUSH BX MOV CL,9 ; PRINT BUFFER INT 224 POP BX POP DX POP CX RET ; ; MOVE BYTES PTED TO BY BX TO AREA PTED TO BY DX; CH BYTES TO MOVE ; MOVE: MOV AL,M ; GET BYTE AND AL,7FH ; MASK OFF MSB -- IN CASE A WS FILE MOV SI,DX ; PUT BYTE MOV [SI],AL LAHF ; PT TO NEXT INC BX SAHF LAHF INC DX SAHF DEC CH ; 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: MOV CL,20 ; READ NEXT RECORD MOV DX,FCB ; PT TO FCB INT 224 LAHF ; SAVE RETURN CODE XCHG AL,AH PUSH AX MOV BX,Word Ptr NEXT@ADR ; PT TO LOAD ADDRESS ; MOV AL,Byte Ptr TPA@END ;Get end of TPA buffer ; CMP AL,BH ;Same page? ; JZ READ@ERROR ;Yes MOV DX,BUFF ; No, point to buffer to load from MOV CH,128 ; NUMBER OF BYTES TO MOVE XCHG BX,DX CALL MOVE XCHG BX,DX MOV Word Ptr NEXT@ADR,BX ; PT TO NEXT LOAD ADDRESS POP AX ; GET RETURN CODE XCHG AL,AH SAHF RET ; READ@ERROR: MOV DX,(Offset 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 AL,M ; GET CHAR CMP AL,CR ; EOL? JZ CRLF CMP AL,LF ; LINE FEED? (WS FILE) JZ CRLF0 CALL CHAR@OUT ; PRINT CHAR INC BX ; PT TO NEXT JMPS PRINT@LINE ; ; PRINT CRLF, PT TO FIRST CHAR OF NEXT LINE, AND PAGE IF NECESSARY ; CRLF: LAHF ; PT TO LF INC BX SAHF CRLF0: LAHF ; PT TO 1ST CHAR OF NEXT LINE INC BX SAHF CRLFC: CALL CRLF1 ; PRINT CRLF MOV AL,Byte Ptr LINE@CNT ; GET LINE COUNT DEC AL MOV Byte Ptr LINE@CNT,AL JZ L_1 RET ; OK -- CONTINUE L_1: MOV DX,(Offset PAGEMS) CALL PRINT@MESSAGE ; PRINT PAGE MESSAGE NXTLOOP: CALL CHAR@IN ; GET RESPONSE AND AL,0DFH ; CAPITALIZE CMP AL,'A' ; ABORT? JNZ L_2 JMP HELP ; YES, START OVER L_2: CMP AL,CTRLC ; CP/M ABORT JNZ L_3 JMP HELP@EXIT L_3: CMP AL,CR ; NEXT PAGE? JNZ NXTLOOP ; NO, TRY AGAIN CALL SET@LINE@CNT CALL CRLF1 ; NEW LINE RET ; ; PRINT CR AND LF ONLY ; CRLF1: MOV AL,CR ; PRINT CR CALL CHAR@OUT MOV AL,LF ; PRINT LF CALL CHAR@OUT RET ; ; SET LINE$CNT VARIABLE TO SCREEN SIZE ; SET@LINE@CNT: MOV AL,LINES@PER@SCREEN-1 MOV Byte Ptr LINE@CNT,AL RET ; ; PRINT THE HEADER SECTION AND LOAD FIRST$ENTRY PTR ; PRINT@HEADER: MOV BX,(Offset HELP@BUF) CALL SET@LINE@CNT MOV AL,'A' ; INIT SELECTION CHAR MOV Byte Ptr SEL@CHAR,AL MOV DX,(Offset SELECTMS) CALL PRINT@MESSAGE MOV CL,0 ; COUNT NUMBER OF SELECTIONS ; ; PRINT LINE UNTIL FIRST INFORMATION SECTION FOUND ; PH1: MOV AL,M ; GET CHAR CMP AL,SECT@CHAR JZ PH2 CMP AL,CTRLZ ; EOF? -- ABORT JNZ L_4 JMP HELP@EXIT L_4: INC CL ; INCREMENT SELECTION COUNT MOV AL,Byte Ptr SEL@CHAR ; DISPLAY SELECTION CHAR CALL CHAR@OUT INC AL ; INCR CHAR MOV Byte Ptr SEL@CHAR,AL MOV AL,'.' CALL CHAR@OUT MOV AL,' ' CALL CHAR@OUT CALL PRINT@LINE ; PRINT HEADER LINE JMPS PH1 ; ; SAVE PTR TO FIRST ENTRY ; PH2: MOV Word Ptr FIRST@ENTRY,BX RET ; ; PRINT AN INFORMATION SECTION ; PRINT@INFO: CALL SET@LINE@CNT PI1: CALL PRINT@LINE ; PRINT LINE FROM INFO FILE MOV AL,M ; DONE? CMP AL,CTRLZ ; EOF? JZ PI2 CMP AL,SECT@CHAR ; NEXT SECTION JZ PI2 CMP AL,FF ; FORM FEED? JNZ PI1 CALL FORM@FEED ; FEED SCREEN JMPS PI1 ; ; FORM FEED SCREEN ; FORM@FEED: MOV AL,Byte Ptr LINE@CNT ; GET LINE COUNT MOV CH,AL ; ... IN B FEED@LOOP: PUSH CX ; SAVE B CALL CRLFC ; NEW LINE POP CX ; GET B DEC CH ; COUNT DOWN JNZ FEED@LOOP RET ; ; END OF INFO ; PI2: CALL CRLF1 ; NEW LINE MOV AL,Byte Ptr LINE@CNT ; COUNT DOWN DEC AL MOV Byte Ptr LINE@CNT,AL JNZ PI2 MOV AL,Byte Ptr ALLFLAG OR AL,AL ; DISPLAY ALL CATEGORIES? MOV DX,(Offset CONTMS) JNZ PI2CONT ; YES MOV DX,(Offset ENDMS) ; PRINT END OF INFORMATION MSG PI2CONT: CALL PRINT@MESSAGE PI2LOOP: CALL CHAR@IN ; GET ANY CHAR CMP AL,CTRLC ; CP/M ABORT JNZ L_5 JMP HELP@EXIT L_5: CMP AL,CR ; BACK TO MENU JNZ PI2LOOP ; NO, KEEP LOOKING CALL CRLF1 ; NEW LINE CALL SET@LINE@CNT ; RESET LINE COUNT IN CASE OF ALL RET DSEG ORG 100H ; ;******************************************************** ;* MESSAGE AND BUFFER SECTION * ;******************************************************** ; HELPMS RS 0 DB 'HELP V1.5',CR,LF,'$' ENDMS RS 0 DB '+ End of Category +' DB ' Type CTRL-C=CP/M, =Menu --$' CONTMS RS 0 DB '+ End of Category +' DB ' Type CTRL-C=CP/M, =Next Category -$' SELECTMS RS 0 DB CR,LF,' HELP File Selections are --',CR,LF,'$' DEFFN RS 0 DB 1,'QUICK ' DEFEXT RS 0 DB 'HLP' PAGEMS RS 0 DB ' Type "A"=Abort, CTRL-C=CP/M, =More -$' ERR1 RS 0 DB CR,LF,'FATAL ERROR -- File not Found',CR,LF,'$' ERR1A RS 0 DB CR,LF,'FATAL ERROR -- Wildcard not allowed in filename',CR,LF,'$' ERR2 RS 0 DB CR,LF,'HELP ERROR -- Invalid Response',CR,LF,'$' ERR3 RS 0 DB CR,LF,'HELP ERROR -- EOF on HELP File',CR,LF,'$' READERR RS 0 DB CR,LF,'FATAL ERROR -- Not Enough Room for HELP File',CR,LF,'$' PROMPT@MESSAGE RS 0 DB CR,LF,'Type CTRL-C to exit to CP/M, "*" to select' DB ' all, or category -$' ALLFLAG RS 0 RS 1 ; DISPLAY ALL CATEGORIES FLAG SEL@CHAR RS 0 RS 1 ; SELECTION TABLE OPTION CHAR FIRST@ENTRY RS 0 RS 2 ; PTR TO FIRST ENTRY OF INFORMATION SECTION LINE@CNT RS 0 RS 1 ; LINE COUNT BUFFER DFFLG RS 0 RS 1 ; DEFAULT FILE FLAG (0=NOT SEARCH FOR, 1=YES) NEXT@ADR RS 0 RS 2 ; NEXT LOAD ADDRESS ; ; DEFAULT HELP MESSAGE ; HELP@BUF RS 0 DB ':The HELP Subsystem for Online Documentation',CR,LF DB ' This is HELP, the Online Documentation Subsystem. The',CR,LF DB 'purpose of HELP is to allow you to interactively query the',CR,LF DB '*.HLP files on this system to get information summaries and',CR,LF DB 'various aspects of the system, CP/M, applications programs and',CR,LF DB 'languages.',CR,LF DB CR,LF DB ' When you type ''HELP'', a search is done for the file',CR,LF DB '''QUICK.HLP''. If found, the contents of this HELP File are',CR,LF DB 'displayed for you; if not found, the HELP Information you are',CR,LF DB 'now reading is displayed.',CR,LF DB CR,LF DB ' If you desire information on a specific topic and have',CR,LF DB 'found a HELP File in the system directory with a promising',CR,LF DB 'name (ie, CPM.HLP is a HELP File on CP/M), try the command:',CR,LF DB CR,LF DB ' HELP d:topic',CR,LF DB 'Where:',CR,LF DB ' "d:" is the disk the HELP File resides on (optional)',CR,LF DB ' "topic" is the name of the HELP File (like CPM.HLP).',CR,LF DB CR,LF DB 'Please refer to the HELP File "HELP.HLP" for more information',CR,LF DB CTRLZ ; END OF FILE END