home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol084
/
help14.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
15KB
|
594 lines
; 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 <CR> response changed to accept only <CR>.
; 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 <FILENAME>.<EXT> *
;* *
;* <FILENAME>.<EXT> IS OPTIONAL; IF OMITTED COMPLETELY, *
;* 'THIS-SYS.HLP' IS ASSUMED; IF JUST <EXT> 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 ; <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
;****************************************************************
;* 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 ; <CTRL-Z>?
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
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, <CR>=Menu --$'
CONTMS:
DB '+ End of Category +'
DB ' Type CTRL-C=CP/M, <CR>=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, <CR>=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