; PROGRAM NAME: HELP ; AUTHOR: RICHARD CONN ; DATE: 6 July 1982 ; VERSION: 1.4 ; PREVIOUS VERSIONS, Latest version first: ; ; 16/Jul/82 Changed default HLP file to THIS-SYS 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 ; ; 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, * ;* 'THIS-SYS.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 * ;**************************************************************** BIAS EQU 0 ; STANDARD CP/M ;BIAS EQU 4200H ; OFFSET CP/M BDOS EQU 5+BIAS ; ADDRESS OF BDOS ENTRY POINT FCB EQU 5CH+BIAS ; ADDRESS OF FILE CONTROL BLOCK BUFF EQU 80H+BIAS ; ADDRESS OF DMA BUFFER 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 ;**************************************************************** ;* 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 * ;**************************************************************** ORG 100H + BIAS START: LXI H,0 ; GET SP DAD SP SHLD STACK XRA A ; TURN OFF DEFAULT FILE FLAG STA DFFLG 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 'THIS-SYS.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 ; CHECK FOR EXTENSION TO FILE NAME START1: LXI H,FCB+9 ; CHECK FOR EXTENSION MOV A,M CPI ' ' ; NONE? JZ DEFAULT$EXT ORA A ; NONE ALSO JNZ START2 ; PLACE DEFAULT EXTENSION OF '.HLP' IN FCB DEFAULT$EXT: LXI D,DEFEXT MVI B,3 XCHG CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES ; OPEN FILE START2: LXI D,FCB ; PT TO FCB MVI C,15 ; OPEN FILE CALL BDOS CPI 255 ; NOT PRESENT? JNZ START3 ; CHECK FOR DEFAULT FILE SEARCH 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 RET ; LOAD HELP FILE INFORMATION START3: LXI H,HELP$BUF ; PT TO BUFFER SHLD NEXT$ADR ; SET PTR ; READ RECORDS UNTIL EOF START4: CALL READ$RECORD ; READ INFO ORA A ; DONE? 0=NO JZ START4 ; ; START OF HELP PROGRAM ; HELP: LXI SP,STACK ; RESET STACK LXI H,HELP$BUF ; PT TO BUFFER MOV A,M ; NO HEADER SECTION? CPI 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: LHLD STACK ; GET CP/M SP SPHL RET ; DONE ; PRINT HEADER INFORMATION AND SELECT AN OPTION HELP1: MVI A,0 STA ALLFLAG ; RESET ALL CATEGORIES FLAG CALL PRINT$HEADER ; PRINT HEADER LXI D,PROMPT$MESSAGE ; PRINT PROMPT CALL PRINT$MESSAGE CALL CHAR$IN ; GET RESPONSE CPI CTRLC ; RETURN TO CP/M JZ HELP$EXIT CALL CHAR$OUT ; DISPLAY ENTERED CHAR CPI ALL$CHAR ; ALL OF HELP FILE? JZ HELP$ALL ANI 0DFH ; CAPITALIZE 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 INX H ; SKIP OVER COLON CALL PRINT$INFO ; PRINT INFO PTED TO BY HL JMP HELP1 ; LOCATE NEXT INFORMATION SECTION HELP4: MOV A,M ; ? 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 ; ? JNZ HELP4 INX H ; 1ST BYTE OF NEXT LINE HELP5 MOV A,M ; GET CHAR 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 ; PRINT ALL OF HELP FILE HELP$ALL: STA ALLFLAG ; FOR LATER CALL CRLF1 ; START ON NEW LINE LHLD FIRST$ENTRY ; PT TO FIRST ENTRY CALL SET$LINE$CNT ; SET LINE COUNT ; EXECUTE UNTIL A CTRL-Z IS ENCOUNTERED HA1: INX H ; SKIP OVER COLON CALL PI1 ; PRINT INFO W/OUT LINE CNT INFO MOV A,M ; GET LAST CHAR CPI CTRLZ JNZ HA1 JMP HELP ;******************************************************** ;* * ;* HELP SUPPORT ROUTINE SECTION * ;* * ;******************************************************** ; ; INPUT CHAR; CHAR IS IN A ; CHAR$IN: PUSH B PUSH D PUSH H MVI C,6 ; DIRECT CONSOLE I/O MVI E,0FFH ; INPUT CALL BDOS POP H POP D POP B ORA A ; CHARACTER? JZ CHAR$IN ; NO, KEEP LOOKING 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 LXI D,BUFF ; PT TO BUFFER TO LOAD FROM MVI B,128 ; NUMBER OF BYTES TO MOVE XCHG CALL MOVE XCHG SHLD NEXT$ADR ; PT TO NEXT LOAD ADDRESS POP PSW ; GET RETURN CODE RET ; ; 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 CPI CR ; EOL? JZ CRLF CPI LF ; LINE FEED? (WS FILE) JZ CRLF0 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 LXI D,PAGEMS CALL PRINT$MESSAGE ; PRINT PAGE MESSAGE NXTLOOP: CALL CHAR$IN ; GET RESPONSE ANI 0DFH ; CAPITALIZE CPI 'A' ; ABORT? JZ HELP ; YES, START OVER CPI CTRLC ; CP/M ABORT JZ HELP$EXIT CPI CR ; NEXT PAGE? JNZ NXTLOOP ; NO, TRY AGAIN CALL SET$LINE$CNT CALL CRLF1 ; NEW LINE RET ; ; 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 ; PRINT$HEADER: 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 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 ; PRINT$INFO: CALL SET$LINE$CNT PI1: CALL PRINT$LINE ; PRINT LINE FROM INFO FILE MOV A,M ; DONE? CPI CTRLZ ; EOF? JZ PI2 CPI SECT$CHAR ; NEXT SECTION JZ PI2 CPI FF ; FORM FEED? JNZ PI1 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: CALL CRLF1 ; NEW LINE LDA LINE$CNT ; COUNT DOWN DCR A STA LINE$CNT JNZ PI2 LDA ALLFLAG ORA A ; DISPLAY ALL CATEGORIES? LXI D,CONTMS JNZ PI2CONT ; YES LXI D,ENDMS ; PRINT END OF INFORMATION MSG PI2CONT: CALL PRINT$MESSAGE PI2LOOP: CALL CHAR$IN ; GET ANY CHAR CPI CTRLC ; CP/M ABORT JZ HELP$EXIT CPI 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 ;******************************************************** ;* MESSAGE AND BUFFER SECTION * ;******************************************************** HELPMS: DB 'HELP V1.4',CR,LF,'$' ENDMS: DB '+ End of Category +' DB ' Type CTRL-C=CP/M, =Menu --$' CONTMS: DB '+ End of Category +' DB ' Type CTRL-C=CP/M, =Next Category -$' SELECTMS: DB CR,LF,' HELP File Selections are --',CR,LF,'$' DEFFN: DB 0,'THIS-SYS' DEFEXT: DB 'HLP' PAGEMS: DB ' Type "A"=Abort, CTRL-C=CP/M, =More -$' 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,'$' PROMPT$MESSAGE: DB CR,LF,'Type CTRL-C to exit to CP/M, "*" to select' DB ' all, or category -$' ALLFLAG: DS 1 ; DISPLAY ALL CATEGORIES FLAG 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 DS 80 ; STACK SPACE STACK: DS 2 ; CP/M STACK PTR ; ; DEFAULT HELP MESSAGE ; HELP$BUF: 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 on',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 '''THIS-SYS.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