home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol099
/
help2.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
31KB
|
1,489 lines
*
* PROGRAM NAME: HELP2
* AUTHOR: RICHARD CONN
* DATE: 14 JAN 83
* VERSION: 4.0
* PREVIOUS VERSIONS: 3.2 (6 JAN 83)
* PREVIOUS VERSIONS: 3.1 (8 DEC 82), 3.0 (11 OCT 82), 2.0 (30 OCT 81)
* PREVIOUS VERSIONS: 1.8 (18 OCT 81), 1.7 (10 SEP 81), 1.6 (9 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)
* NOTE: FOR USE WITH ZCPR 2.0 AND LATER
*
VERS EQU 40
;
; This program is Copyright (c) 1982, 1983 by Richard Conn
; All Rights Reserved
;
; ZCPR2 and its utilities, including this one, are released
; to the public domain. Anyone who wishes to USE them may do so with
; no strings attached. The author assumes no responsibility or
; liability for the use of ZCPR2 and its utilities.
;
; The author, Richard Conn, has sole rights to this program.
; ZCPR2 and its utilities may not be sold without the express,
; written permission of the author.
;
;
; HELP supports an online documentation system under ZCPR2. Refer
; to the file HELP.HLP for more details.
;
;
; CP/M Constants
;
FALSE EQU 0
TRUE EQU NOT FALSE
UDFLAG EQU 4 ; ADDRESS OF USER/DISK FLAG
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
;
; HELP Control Characters
;
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
;
; Lines/Screen on CRT
;
LINES$PER$SCREEN EQU 24 ; ASSUME 24 LINES/SCREEN
;
; Number of File Names per Line
;
NAMES$PER$LINE EQU 6 ; 6 NAMES (SPACE = 6*11 COLS)
;
; Set this to TRUE if all files must be of type HLP
;
FORCE$HLP EQU TRUE ; TRUE IF FILES MUST BE OF TYPE HLP
;
; Number of Nodes (Levels) in Help File Tree
;
HELP$MAX EQU 10 ; DEFAULT = 10 (SPACE=11*HELP$MAX)
;
; MACROS TO PROVIDE Z80 EXTENSIONS
; MACROS INCLUDE:
;
$-MACRO ;FIRST TURN OFF THE EXPANSIONS
;
; JR - JUMP RELATIVE
; JRC - JUMP RELATIVE IF CARRY
; JRNC - JUMP RELATIVE IF NO CARRY
; JRZ - JUMP RELATIVE IF ZERO
; JRNZ - JUMP RELATIVE IF NO ZERO
; DJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO
; LDIR - MOV @HL TO @DE FOR COUNT IN BC
; LXXD - LOAD DOUBLE REG DIRECT
; SXXD - STORE DOUBLE REG DIRECT
;
;
;
; @GENDD MACRO USED FOR CHECKING AND GENERATING
; 8-BIT JUMP RELATIVE DISPLACEMENTS
;
@GENDD MACRO ?DD ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
IF (?DD GT 7FH) AND (?DD LT 0FF80H)
DB 100H ;Displacement Range Error on Jump Relative
ELSE
DB ?DD
ENDIF
ENDM
;
;
; Z80 MACRO EXTENSIONS
;
JR MACRO ?N ;;JUMP RELATIVE
DB 18H
@GENDD ?N-$-1
ENDM
;
JRC MACRO ?N ;;JUMP RELATIVE ON CARRY
DB 38H
@GENDD ?N-$-1
ENDM
;
JRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY
DB 30H
@GENDD ?N-$-1
ENDM
;
JRZ MACRO ?N ;;JUMP RELATIVE ON ZERO
DB 28H
@GENDD ?N-$-1
ENDM
;
JRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO
DB 20H
@GENDD ?N-$-1
ENDM
;
DJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
DB 10H
@GENDD ?N-$-1
ENDM
;
LDIR MACRO ;;LDIR
DB 0EDH,0B0H
ENDM
;
LDED MACRO ?N ;;LOAD DE DIRECT
DB 0EDH,05BH
DW ?N
ENDM
;
LBCD MACRO ?N ;;LOAD BC DIRECT
DB 0EDH,4BH
DW ?N
ENDM
;
SDED MACRO ?N ;;STORE DE DIRECT
DB 0EDH,53H
DW ?N
ENDM
;
SBCD MACRO ?N ;;STORE BC DIRECT
DB 0EDH,43H
DW ?N
ENDM
;
; END OF Z80 MACRO EXTENSIONS
;
ORG 100H
;
; Branch to Start of Program
;
jmp start
;
;******************************************************************
;
; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
;
; This data block precisely defines the data format for
; initial features of a ZCPR2 system which are required for proper
; initialization of the ZCPR2-Specific Routines in SYSLIB.
;
;
; EXTERNAL PATH DATA
;
EPAVAIL:
DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
EPADR:
DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
;
; INTERNAL PATH DATA
;
INTPATH:
DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT
; DISK = 1 FOR A, '$' FOR CURRENT
; USER = NUMBER, '$' FOR CURRENT
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT
DB 0 ; END OF PATH
;
; MULTIPLE COMMAND LINE BUFFER DATA
;
MCAVAIL:
DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
MCADR:
DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
;
; DISK/USER LIMITS
;
MDISK:
DB 4 ; MAXIMUM NUMBER OF DISKS
MUSER:
DB 31 ; MAXIMUM USER NUMBER
;
; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
;
DOK:
DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
UOK:
DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
;
; PRIVILEGED USER DATA
;
PUSER:
DB 10 ; BEGINNING OF PRIVILEGED USER AREAS
PPASS:
DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS
DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
;
; CURRENT USER/DISK INDICATOR
;
CINDIC:
DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS)
;
; DMA ADDRESS FOR DISK TRANSFERS
;
DMADR:
DW 80H ; TBUFF AREA
;
; NAMED DIRECTORY INFORMATION
;
NDRADR:
DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
NDNAMES:
DB 64 ; MAX NUMBER OF DIRECTORY NAMES
DNFILE:
DB 'NAMES ' ; NAME OF DISK NAME FILE
DB 'DIR' ; TYPE OF DISK NAME FILE
;
; REQUIREMENTS FLAGS
;
EPREQD:
DB 0FFH ; EXTERNAL PATH?
MCREQD:
DB 000H ; MULTIPLE COMMAND LINE?
MXREQD:
DB 000H ; MAX USER/DISK?
UDREQD:
DB 000H ; ALLOW USER/DISK CHANGE?
PUREQD:
DB 000H ; PRIVILEGED USER?
CDREQD:
DB 000H ; CURRENT INDIC AND DMA?
NDREQD:
DB 000H ; NAMED DIRECTORIES?
Z2CLASS:
DB 5 ; CLASS 5
DB 'ZCPR2'
DS 10 ; RESERVED
;
; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
;
;******************************************************************
;
;
; DEFAULT FILE NAME
;
DEFFN:
DB 'HELP '
DEFTYP:
DB 'HLP'
;
; Start of Program
;
START:
LXI H,0 ; GET SP
DAD SP
SHLD STACK
LXI SP,STACK ; NEW STACK
MVI E,0FFH ; GET CURRENT USER NUMBER
MVI C,32
CALL BDOS
STA CUR$USER ; CURRENT USER NUMBER
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?
JRNZ START1
* INSERT 'HELP.HLP' INTO FCB OR CLEAR FCB
LXI D,DEFFN ; PT TO DEFAULT NAME
MVI B,11 ; 11 BYTES
XCHG
CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES
MVI A,1 ; TURN ON DEFAULT FILE FLAG
STA DFFLG
* 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
DJNZ FCB$FILL
* CHECK FOR WILD CARDS IN FILE NAME -- ERROR IF SO
LXI H,FCB+1 ; PT TO FIRST BYTE OF FILE NAME
MVI B,11 ; 11 BYTES
FCB$WILD$CK:
MOV A,M ; GET BYTE
ANI 7FH ; MASK
CPI '?' ; WILD?
JRZ FCB$WILD$ERROR
INX H ; PT TO NEXT
DJNZ FCB$WILD$CK
* CHECK FOR FILE TYPE
LXI H,FCB+9 ; CHECK FOR FILE TYPE
IF NOT FORCE$HLP ; IF FILE TYPE MAY NOT BE HLP
MOV A,M ; CHECK FOR FILE TYPE SPECIFIED
CPI ' ' ; NONE?
JRNZ START2
ENDIF
* PLACE DEFAULT FILE TYPE OF '.HLP' IN FCB
DEFAULT$EXT:
LXI D,DEFTYP ; DEFAULT FILE TYPE
MVI B,3
XCHG
CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES
* OPEN FILE
START2:
LDA DFFLG ; CHECK FOR DEFAULT
ORA A ; 0=NO
JNZ HELP$DEF ; DISPLAY DEFAULT HELP INFO WITH FILE NAMES
LXI H,INTPATH ; SET BASE ADDRESS OF PATH
LDA EPAVAIL ; EXTERNAL PATH AVAILABLE
ORA A ; 0=NO
JRZ START2A
LHLD EPADR ; GET ADDRESS OF EXTERNAL PATH
START2A:
LXI D,FCB ; PT TO FCB
CALL FNDFILE ; SEARCH FOR FILE
JNZ START3 ; FILE FOUND, SO PROCESS
LDA EPAVAIL ; SEARCH ALONG EXTERNAL PATH?
ORA A ; 0=NO
JRZ START2B
LXI H,INTPATH ; SELECT INTERNAL PATH THEN
LXI D,FCB ; PT TO FCB
CALL FNDFILE ; SEARCH
JNZ START3 ; FILE FOUND
* FILE NOT FOUND -- FATAL ERROR
START2B:
LXI D,ERR1 ; FILE NOT FOUND
CALL PRINT$MESSAGE
JMP HELP$EXIT
* FILE CONTAINS WILD CARDS -- FATAL ERROR
FCB$WILD$ERROR:
LXI D,WILD$ERR ; WILD CARD
CALL PRINT$MESSAGE
JMP HELP$EXIT
*
* DISPLAY DEFAULT HELP FILE INFORMATION
*
HELP$DEF:
LXI D,HELP$DEF$MSG ; PRINT MESSAGE
CALL PRINT$MESSAGE
CALL SET$COUNT ; SET COUNTER
CALL RESET$SYSTEM ; RETURN HOME
CALL PRINT$HELP$FILES ; PRINT HELP FILES AT HOME
LDA EPAVAIL ; EXTERNAL PATH?
LHLD EPADR ; EXTERNAL PATH ADDRESS
ORA A ; 0=NO EXTERNAL PATH
CNZ HDFF1
CALL RESET$SYSTEM ; RETURN HOME
LXI H,INTPATH ; FOLLOW INTERNAL PATH
CALL HDFF1 ; SEARCH IT
CALL RESET$SYSTEM ; RESET CALLING DISK/USER NUMBER
LXI D,HELP$EDEF$MSG ; PRINT END MESSAGE
CALL PRINT$MESSAGE
CALL CHAR$IN ; GET ANY CHAR FOR RESPONSE
CPI CTRLC ; ABORT?
JZ HELP$EXIT
XRA A ; TURN OFF DEFAULT
STA DFFLG
LXI H,DEFFN ; SET DEFAULT FILE NAME
LXI D,FCB+1
MVI B,11 ; 11 BYTES
CALL MOVE
JMP START2 ; PROCESS DEFAULT HELP FILE
;
; MAIN SEARCH LOOP
;
HDFF1:
LDA CINDIC ;GET CURRENT DISK INDICATOR
MOV B,A ;... IN B
MOV A,M ;GET DRIVE
ANI 7FH ;MASK MSB
ORA A ;0=DONE=COMMAND NOT FOUND
RZ ;END OF PATH?
;
; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
;
CMP B
JRNZ HDFF2 ;SKIP DEFAULT DRIVE SELECTION IF SO
LDA UDFLAG ;GET DEFAULT USER/DISK
ANI 0FH ;MASK FOR DEFAULT DISK
INR A ;PREP FOR FOLLOWING DCR A
HDFF2:
DCR A ;ADJUST PATH 1 TO 0 FOR A, ETC
MOV E,A ;DISK NUMBER IN E
MVI C,14 ;SELECT DISK FCT
CALL BENTRY ;SELECT DRIVE
INX H ;PT TO USER NUMBER
MOV A,M ;GET USER NUMBER
INX H ;PT TO NEXT PATH ELEMENT
ANI 7FH ;MASK OUT MSB
CMP B
JRNZ HDFF3 ;DO NOT SELECT CURRENT USER IF SO
LDA CUR$USER ;GET ORIGINAL USER NUMBER
HDFF3:
MOV E,A ;SELECT USER
MVI C,32
CALL BENTRY
PUSH H ;SAVE PATH PTR
CALL PRINT$HELP$FILES
POP H ;GET PATH PTR
JR HDFF1
*
* SET FILE NAME COUNTER
*
SET$COUNT:
MVI A,NAMES$PER$LINE ; NUMBER OF FILE NAMES/LINE
STA NAME$COUNT
RET
*
* PRINT NAMES OF HELP FILES
*
PRINT$HELP$FILES:
LXI H,FCB ; MAKE FCB = *.HLP
MVI M,0 ; BEGINNING 0 FOR DEFAULT DISK
MVI B,8 ; FILL 8 ?'S
INX H ; PT TO FIRST CHAR
PHF1:
MVI M,'?' ; '?' FILL
INX H ; PT TO NEXT
DJNZ PHF1
LXI D,DEFTYP ; COPY DEFAULT FILE TYPE
MVI B,3 ; 3 BYTES
XCHG ; EXCHANGE
CALL MOVE ; COPY
XCHG ; RESTORE PTR
MVI B,24 ; FILL REST WITH 0'S
PHF2:
MVI M,0 ; 0 FILL
INX H ; PT TO NEXT
DJNZ PHF2
* SEARCH FOR FIRST FILE
LXI D,FCB ; PT TO FCB
MVI C,17 ; SEARCH FOR FIRST
CALL BDOS
CPI 0FFH ; NONE?
RZ ; DONE IF SO
* PRINT CURRENT AND SEARCH FOR NEXT
PHF3:
CALL PRINT$HFN ; PRINT HELP FILE NAME
LXI D,FCB ; PT TO FCB
MVI C,18 ; SEARCH FOR NEXT
CALL BDOS
CPI 0FFH ; DONE?
JRNZ PHF3
RET
*
* PRINT NAME OF FILE WHOSE BUFF OFFSET IS IN A
*
PRINT$HFN:
RRC ; A=A*32
RRC
RRC ; RATHER THAN 5 LEFT, I DO 3 RIGHT (NEAT, HUH?)
ANI 60H ; MASK ALL BUT INTERESTING PART
LXI H,BUFF ; PT TO BUFFER
ADD L ; PT TO ENTRY
MOV L,A
MOV A,H
ACI 0
MOV H,A ; HL PTS TO ENTRY
INX H ; HL PTS TO HELP FILE NAME
MVI B,8 ; 8 CHARS
PHFN1:
MOV A,M ; GET CHAR
ANI 7FH ; MASK
INX H ; PT TO NEXT
CALL CHAR$OUT ; PRINT IT
DJNZ PHFN1
MVI A,' ' ; TRAILING SPACES
CALL CHAR$OUT ; 3 OF THEM
CALL CHAR$OUT
CALL CHAR$OUT
LDA NAME$COUNT ; COUNT DOWN
DCR A
STA NAME$COUNT
RNZ
CALL SET$COUNT ; RESET COUNT
CALL CRLF ; NEW LINE
RET
*
* LOAD HELP FILE INFORMATION
*
START3:
LXI D,FCB ; OPEN FILE
MVI C,15 ; BDOS FILE OPEN
CALL BDOS
LXI H,HELP$BUF ; PT TO BUFFER
SHLD NEXT$ADR ; SET PTR
* READ RECORDS UNTIL EOF
START4:
CALL READ$RECORD ; READ INFO
JRZ START4 ; NOT DONE IF ZERO RETURN
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
JRNZ 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
JRZ 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:
CALL RESET$SYSTEM ; RESET CALLING DISK/USER NUMBER
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
JRZ 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
JRZ 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
JRZ BAD$RESPONSE
JRNC HELP2
* INVALID RESPONSE
BAD$RESPONSE:
LXI D,ERR2 ; INVALID RESPONSE
CALL PRINT$MESSAGE
JR 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?
JRNC BAD$RESPONSE
LHLD FIRST$ENTRY ; GET PTR TO FIRST ENTRY
* PRINT INFORMATION WHEN COUNT IS ZERO
HELP3:
DJNZ HELP4
CALL PRINT$INFO ; PRINT INFO PTED TO BY HL
JR 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)?
JRZ HELP5
CPI CR ; <CR>?
JRNZ HELP4
INX H ; 1ST BYTE OF NEXT LINE
HELP5:
MOV A,M ; GET CHAR
ANI 7FH ; MASK OUT MSB
CPI SECT$CHAR ; NEW SECTION?
JRZ HELP3 ; CONTINUE LOOP IF SO
CPI CTRLZ ; EOF?
JRNZ 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
*
RESET$SYSTEM:
LDA UDFLAG ; GET DISK
ANI 0FH ; GET DISK NUMBER
MOV E,A ; DISK IN E
MVI C,14 ; SELECT DISK
CALL BDOS
LDA CUR$USER ; SET USER
MOV E,A ; USER IN E
MVI C,32 ; SET USER CODE
CALL BDOS
RET
*
* FNDFILE -- LOOK FOR FILE ALONG ZCPR2 PATH
* INPUT PARAMETERS: HL = BASE ADDRESS OF PATH, DE = PTR TO FCB OF FILE
* OUTPUT PARAMETERS: A=0 AND ZERO FLAG SET IF NOT FOUND, NZ IF FOUND
*
FNDFILE:
SHLD PATH ;SAVE PATH BASE ADDRESS
MVI C,17 ;SEARCH FOR FIRST
CALL BENTRY ;LOOK FOR FILE
INR A ;SET FLAG
JRNZ FF5 ;FOUND IT -- RETURN FOUND FLAG
XCHG ;HL=FCB PTR
SHLD FCBPTR ;SAVE IT
LHLD PATH ;PT TO PATH FOR FAILURE POSSIBILITY
;
; MAIN SEARCH LOOP
;
FF1:
LDA CINDIC ;GET CURRENT USER/DISK INDICATOR
MOV B,A ;... IN B
MOV A,M ;GET DRIVE
ANI 7FH ;MASK MSB
ORA A ;0=DONE=COMMAND NOT FOUND
JRNZ FF2 ;NO ERROR ABORT?
;
; FILE NOT FOUND ERROR
;
XRA A ;ZERO FLAG MEANS NOT FOUND
RET
;
; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
;
FF2:
CMP B ;CURRENT DISK?
JRNZ FF3 ;SKIP DEFAULT DRIVE SELECTION IF SO
LDA UDFLAG ;GET DEFAULT USER/DISK
ANI 0FH ;MASK FOR DEFAULT DISK
INR A ;PREP FOR FOLLOWING DCR A
FF3:
DCR A ;ADJUST PATH 1 TO 0 FOR A, ETC
MOV E,A ;DISK NUMBER IN E
MVI C,14 ;SELECT DISK FCT
CALL BENTRY ;SELECT DRIVE
INX H ;PT TO USER NUMBER
MOV A,M ;GET USER NUMBER
ANI 7FH ;MASK OUT MSB
INX H ;PT TO NEXT ENTRY IN PATH
CMP B ;CURRENT USER?
JRNZ FF4 ;DO NOT SELECT CURRENT USER IF SO
LDA CUR$USER ;GET ORIGINAL USER NUMBER
FF4:
MOV E,A ;SELECT USER
MVI C,32
CALL BENTRY
XCHG ;SAVE PTR TO NEXT PATH ELEMENT IN DE
LHLD FCBPTR ;GET PTR TO FCB
XCHG ;... IN DE, PATH PTR IN HL
MVI C,17 ;SEARCH FOR FIRST
CALL BENTRY ;LOOK FOR FILE
INR A ;SET FLAG
JRZ FF1 ;CONTINUE PATH SEARCH IF SEARCH FAILED
;
; FILE FOUND -- PERFORM SYSTEM TEST AND PROCEED IF APPROVED
;
FF5:
MVI A,0FFH ;SET OK RETURN
ORA A
RET
;
; BDOS ROUTINE
;
BENTRY:
PUSH H ;SAVE REGS
PUSH D
PUSH B
CALL BDOS
POP B ;GET REGS
POP D
POP H
RET
* BUFFERS
FCBPTR:
DS 2 ;POINTER TO FCB FOR FILE SEARCH
PATH:
DS 2 ;BASE ADDRESS OF PATH
*
* 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
DJNZ 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
MVI M,CTRLZ ; STORE ENDING CTRLZ IN CASE OF EOF
POP PSW ; GET RETURN CODE
ORA A ; DONE? <>0 IF SO
* READ DONE -- SAVE PTR TO NEXT BLOCK
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?
JRZ CRLF
CPI LF ; LINE FEED? (WS FILE)
JRZ CRLF0
CPI CTRLZ ; END OF FILE?
JRZ CRLFC ; DONE IF SO
CALL CHAR$OUT ; PRINT CHAR
INX H ; PT TO NEXT
JR 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
JRZ 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
MVI A,1 ; RESET FRAME COUNT
STA FRAME$NUMBER
JMP FRAME$RESUME ; CONTINUE PROCESSING
* BACK UP TO PREVIOUS FRAME
FRAME$BACKUP:
CALL BOI$CHECK ; AT BEGINNING OF INFORMATION?
JRNZ 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
JRZ 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
JMP CHAR$OUT
*
* 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
JRZ 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
JR 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?
JRZ PI2
CPI SECT$CHAR ; NEXT SECTION
JRZ PI2
CPI FF ; FORM FEED?
JRNZ PI1
INX H ; PT TO CHAR AFTER FORM FEED
CALL FORM$FEED ; FEED SCREEN
JR 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
DJNZ 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
JRNZ 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
JRZ 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
JMP SET$LINE$CNT ; RESET LINE COUNT IN CASE OF ALL
* JUMP TO START OF INFO
PI2$START:
LHLD START$OF$INFO ; PT TO START OF INFO
CALL FRAME$RESUME ; RESET POINTERS
MVI A,1 ; RESET FRAME COUNT
STA FRAME$NUMBER
JMP PI1 ; CONTINUE PROCESSING
* BACK UP TO PREVIOUS FRAME
PI2$BACKUP:
CALL BOI$CHECK ; AT BEGINNING OF INFORMATION?
JZ 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?
JRNZ 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
JRZ LOAD$FCB$FILL
CPI ' '+1 ; DONE IF < <SP>
JRC LOAD$FCB$FILL
CALL CAPS ; CAPITALIZE
CALL CHAR$OUT ; PRINT FILE NAME AND TYPE
STAX D ; STORE CHAR
INX D ; PT TO NEXT
DJNZ 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
DJNZ 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
JR GORET
*
* RETURN TO PREVIOUS HELP LEVEL
*
LEVEL$RETURN:
LDA HELP$LEVEL ; ARE WE AT THE LOWEST LEVEL?
ORA A ; 0=YES
JRNZ 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
JRZ GORET$NAME0
CALL CHAR$OUT ; PRINT FILE NAME
DJNZ GORET$NAME
JMP GORET$NAME1
GORET$NAME0:
DCR B ; COUNT DOWN
JRZ GORET$NAME1
INX H ; SKIP NEXT SPACE
JR 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
DJNZ 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?
JRZ 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
JRC PDEC2
INR C ; INCREMENT VALUE
JR 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
JRNZ PDEC3
MOV A,C ; GET DIGIT
STA LD$SPACE ; NEW FLAG
ORA A ; ZERO?
JRNZ PDEC3 ; PRINT BYTE IN C
MVI A,' ' ; PRINT LEADING SPACE
JR PDEC4
PDEC3:
MOV A,C ; GET VALUE
ADI '0' ; CONVERT TO ASCII
PDEC4:
CALL CHAR$OUT ; PRINT CHAR
MOV A,B ; RESTORE A
RET
*********************************************************
* MESSAGE AND BUFFER SECTION *
*********************************************************
HELPMS:
DB 'HELP for ZCPR2, Version '
DB (VERS/10)+'0','.',(VERS MOD 10)+'0',CR,LF,'$'
HELP$DEF$MSG:
DB CR,LF,'Default HELP Facility Invoked'
DB CR,LF,' Available HELP Files are --',CR,LF,'$'
HELP$EDEF$MSG:
DB CR,LF,' Type Any Character for Default Info (^C to Abort) - $'
SELECTMS:
DB CR,LF,' HELP File Selections are --',CR,LF,'$'
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 $'
WILD$ERR:
DB CR,LF,'HELP FATAL ERROR -- File Name Contains Wild Card$'
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,'$'
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 $'
CUR$USER:
DS 1 ; NUMBER OF CURRENT USER
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
NAME$COUNT:
DS 1 ; COUNT OF FILE NAMES/LINE
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
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
*
* Help Files are Loaded Here
*
HELP$BUF equ $
END