home *** CD-ROM | disk | FTP | other *** search
- *
- * PROGRAM NAME: HELP2
- * AUTHOR: RICHARD CONN
- * DATE: 23 MAY 83
- * VERSION: 4.1
- * PREVIOUS VERSIONS: 4.0 (14 JAN 83), 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 41
-
- ;
- ; 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 EXIT
- LEVEL$RET$CHAR EQU '^' ; RETURN TO PREVIOUS HELP LEVEL
- ROOT$CHAR EQU '.' ; RETURN TO ROOT OF HELP
- PRINT$CHAR EQU 'P' ; PRINT CURRENT INFORMATION SECTION
-
- ;
- ; 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 ; EXIT
- 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 ; ABORT TO OS
- JZ HELP$EXIT
- CPI PRINT$CHAR ; PRINT INFO SECTION?
- JZ LIST1$INFO
- 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
- LDA LINE$CNT
- DCR A
- STA 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
- LDA LINE$CNT ; GET COUNT OF REMAINING LINES
- MOV B,A ; ... IN B
- ORA A ; ANY LEFT?
- RZ
- PH3:
- CALL CRLF1 ; NEW LINE
- DJNZ PH3
- 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 ; ABORT TO OS
- JZ HELP$EXIT
- CPI PRINT$CHAR ; PRINT INFORMATION SECTION?
- JZ LIST1$INFO
- 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
-
- **************************************************************
- * THIS BODY OF CODE LISTS INFORMATION FROM HELP2 TO THE
- * PRINTER
- **************************************************************
-
- *
- * LIST ONE LINE OF INFO SECTION; HL PTS TO LINE UPON ENTRY;
- * HL PTS TO FIRST CHAR OF NEXT LINE UPON EXIT
- *
- LIST$LINE:
- MOV A,M ; GET CHAR
- ANI 7FH ; MASK OUT MSB
- CPI CR ; EOL?
- JRZ LCRLF
- CPI LF ; LINE FEED? (WS FILE)
- JRZ LCRLF0
- CPI CTRLZ ; END OF FILE?
- JRZ LCRLFC ; DONE IF SO
- CALL LST$OUT ; PRINT CHAR
- RZ ; ABORT
- INX H ; PT TO NEXT
- JR LIST$LINE
-
- *
- * LIST CRLF, PT TO FIRST CHAR OF NEXT LINE, AND PAGE IF NECESSARY
- *
- LCRLF:
- INX H ; PT TO LF
- LCRLF0:
- INX H ; PT TO 1ST CHAR OF NEXT LINE
- LCRLFC:
- CALL LCRLF1 ; PRINT CRLF
- LDA LINE$CNT ; GET LINE COUNT
- DCR A
- STA LINE$CNT
- JRNZ LNOABT ; OK -- CONTINUE
- LCRLF1:
- MVI A,CR ; SEND <CRLF> TO PRINTER
- CALL LST$OUT
- RZ ; ABORT
- MVI A,LF ; FALL THRU TO LST$OUT
-
- * PRINT CHARACTER IN A ON PRINTER; AFFECT NO REGISTERS
- LST$OUT:
- PUSH H ; SAVE REGS
- PUSH D
- PUSH B
- MOV E,A ; CHAR IN E
- MVI C,5 ; BDOS PRINTER OUTPUT ROUTINE
- CALL BDOS
- MVI E,0FFH ; CONDITIONAL INPUT
- MVI C,6 ; DIRECT CONSOLE I/O
- CALL BDOS
- POP B ; RESTORE REGS
- POP D
- POP H
- CPI CTRLC ; ABORT?
- RET
- LNOABT:
- MVI A,0FFH ; SET NO ABORT RETURN
- ORA A ; SET FLAGS
- RET
-
- *
- * LIST THE CURRENT INFORMATION SECTION
- * INFORMATION SECTION IS PTED TO BY START$OF$INFO
- *
- LIST1$INFO:
- LXI D,PRINT$WAIT$MSG
- CALL PRINT$MESSAGE
- LHLD START$OF$INFO ; PREPARE TO LIST ENTIRE INFO SECTION
- XRA A ; CLEAR FRAME LIST FLAG
- STA LFR$FLAG
- CALL CHAR$IN ; GET USER INPUT
- CPI 'S' ; SCREEN DISPLAY ONLY
- JRNZ LIST2$INFO
- LHLD START$OF$FRAME ; LIST CURRENT FRAME ONLY
- MVI A,0FFH ; SET FLAG
- STA LFR$FLAG ; LIST FRAME ONLY
- LIST2$INFO:
- CPI CTRLC ; CHECK FOR ^C TO ABORT
- CNZ LIST$INFO ; DO PRINTOUT
- LHLD START$OF$FRAME ; RETURN TO FRAME WE WERE ON
- CALL FRAME$RESUME
- LDA FRAME$NUMBER ; ADJUST FRAME NUMBERING
- DCR A
- STA FRAME$NUMBER
- JMP PI1 ; RESUME AT PI1
- *
- LIST$INFO:
- LXI D,PRINT$LMSG ; PRINT ABORT OPTION MESSAGE
- CALL PRINT$MESSAGE
- CALL SET$LINE$CNT
- LI1:
- CALL LIST$LINE ; LIST LINE FROM INFO FILE
- CPI CTRLC ; ABORT?
- RZ
- MOV A,M ; DONE?
- ANI 7FH ; MASK OUT MSB
- CPI CTRLZ ; EOF?
- RZ ; RESUME IF AT END OF INFO
- CPI SECT$CHAR ; NEXT SECTION
- RZ ; RESUME IF AT END OF INFO
- CPI FF ; FORM FEED?
- JRNZ LI1
- INX H ; PT TO CHAR AFTER FORM FEED
- CALL LFORM$FEED ; FEED PRINTER
- LDA LFR$FLAG ; LIST FRAME ONLY?
- ORA A ; 0=NO
- RNZ
- JR LI1
-
- * FORM FEED SCREEN
- LFORM$FEED:
- CALL LCRLFC ; NEW LINE
- RET
-
- **************************************************************
- * END OF BODY OF CODE WHICH LISTS INFORMATION FROM HELP2 TO
- * THE PRINTER
- **************************************************************
-
- *
- * 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=Exit $' ; 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 PRINT$CHAR,'=Print ' ; PRINT CURRENT INFO SECTION
- ; DB 'CR=Next '
- DB '$'
- PRINT$LMSG:
- DB 'Printing in Progress -- Strike ^C to Abort $'
- PRINT$WAIT$MSG:
- DB 'Please Set Top-of-Form on Printer'
- DB CR,LF,' Strike S to Print this Screen Only, ^C to Abort, or'
- DB CR,LF,'Any Other Char to Print Entire Information Section - $'
- 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=Exit$'
- 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 $'
-
- LFR$FLAG:
- DS 1 ; LIST FRAME ONLY FLAG (FOR PRINT FUNCTION)
- 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
-
-