; ; PROGRAM NAME: HELP ; AUTHOR: RICHARD CONN ; DATE: 18 MAY 84 ; VERSION: 5.0 ; PREVIOUS VERSIONS: None ; DERIVATION: HELP2.ASM 4.1 (23 MAY 83) ; NOTE: FOR USE WITH ZCPR3 ONLY ; VERS EQU 50 Z3ENV SET 0F400H ; ; HELP supports an online documentation system under ZCPR3. Refer ; to the file HELP.HLP for more details. ; FALSE EQU 0 TRUE EQU NOT FALSE ; ; USER EQUATES: ; Set this to TRUE if all files must be of type HLP ; FORCEHLP EQU TRUE ; TRUE IF FILES MUST BE OF TYPE HLP ; ; Directory of Help Files if HELP Directory not found ; HDISK EQU 'A'-'A' ; DISK HUSER EQU 15 ; USER ; ; Enter/Exit Standout Mode (Recommended that these values not be changed) ; DIM EQU 'A'-'@' ; ^A TO ENTER STANDOUT NOTDIM EQU 'B'-'@' ; ^B TO EXIT STANDOUT ; ; SYSLIB ROUTINES ; EXT Z3VINIT,CLS,STNDOUT,STNDEND EXT GETCRT,GETPRT,PFIND,Z3LOG,DIRTDU EXT CODEND EXT LOGUD,RETUD,PUTUD,GETUD EXT EPSTR,EPRINT,COUT,CIN,CAPS,PFN2,PAFDC EXT INITFCB,F$EXIST,F$OPEN,F$READ,F$CLOSE ; ; CP/M Constants ; 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 ; LF EQU 0AH ; BEL EQU 'G'-'@' ; ^G FF EQU 'L'-'@' ; ^L = FORM FEED CTRLZ EQU 'Z'-'@' ; ^Z CTRLC EQU 'C'-'@' ; ^C ; ; HELP Control Characters ; IHCHAR EQU ';' ; FLAG INDICATING INDEXED BY USER SECTCHAR EQU ':' ; DEFINED TO BE COLON BACKUPCHAR EQU 'L' ; BACK UP TO PREVIOUS FRAME CHAR STRTCHAR EQU 'S' ; JUMP TO START OF INFORMATION CHAR MENUCHAR EQU 'M' ; CHAR TO ABORT TO MENU CPMABORTCHAR EQU CTRLC ; CHAR TO EXIT LRCHAR EQU '^' ; RETURN TO PREVIOUS HELP LEVEL ROOTCHAR EQU '.' ; RETURN TO ROOT OF HELP PRCHAR EQU 'P' ; PRINT CURRENT FRAME CPRCHAR EQU 'P'-'@' ; PRINT CURRENT INFORMATION SECTION ; ; Environment Definition ; if z3env ne 0 ; ; External ZCPR3 Environment Descriptor ; jmp start db 'Z3ENV' ;This is a ZCPR3 Utility db 1 ;External Environment Descriptor z3eadr: dw z3env start: lhld z3eadr ;pt to ZCPR3 environment ; else ; ; Internal ZCPR3 Environment Descriptor ; MACLIB Z3BASE.LIB MACLIB SYSENV.LIB z3eadr: jmp start SYSENV start: lxi h,z3eadr ;pt to ZCPR3 environment endif ; ; Start of Program -- Initialize ZCPR3 Environment ; call z3vinit ;initialize the ZCPR3 Env and the VLIB Env jmp startx ; ; DEFAULT FILE NAME ; HELPDIR: DEFFN: DB 'HELP ' ; BOTH HELP FILE AND HELP DIR SAME NAME DEFTYP: DB 'HLP' ; ; Start of Program ; STARTX: LXI H,0 ; GET SP DAD SP SHLD STACK CALL CODEND ; DETERMINE FREE MEMORY SPACE SHLD HLPNSTK ; SET PTR TO HELP NAME STACK LXI D,200H ; ALLOW 25+ ELEMENT HELP NAME STACK AND LARGE STACK DAD D SHLD HLPBUF SPHL ; SET STACK LDA BDOS+2 ; BASE PAGE OF BDOS SUI 10 ; 2K + 2 PAGES STA TPAEND XRA A ; A=0 STA HLPLVL ; SET HELP LEVEL TO 0 (NO RETURN FILE) LXI D,FCB ; PT TO FCB CALL Z3LOG ; LOG INTO IT FOR DEFAULT CALL PUTUD ; SAVE HOME LXI H,FCB+1 ; CHECK FOR FILE NAME MOV A,M CPI '/' ; OPTION CAUGHT? JZ STRT0 CPI ' ' ; NONE? JNZ STRT1 ; ; INSERT 'HELP.HLP' INTO FCB OR CLEAR FCB ; STRT0: LXI D,DEFFN ; PT TO DEFAULT NAME MVI B,11 ; 11 BYTES XCHG CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES ; ; START/RESTART HELP PROGRAM (START ON INITIAL ENTRY, RESTART ON NODE LOAD) ; STRT1: LHLD HLPBUF ; RESET STACK SPHL ; ; 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 FCBWCK: MOV A,M ; GET BYTE ANI 7FH ; MASK CPI '?' ; WILD? JZ FCBWERR INX H ; PT TO NEXT DCR B JNZ FCBWCK ; ; CHECK FOR FILE TYPE ; LXI H,FCB+9 ; CHECK FOR FILE TYPE IF NOT FORCEHLP MOV A,M ; CHECK FOR FILE TYPE SPECIFIED CPI ' ' ; NONE? JNZ STRT2 ENDIF ; ; PLACE DEFAULT FILE TYPE OF '.HLP' IN FCB ; LXI D,DEFTYP ; DEFAULT FILE TYPE MVI B,3 XCHG CALL MOVE ; MOVE (HL) TO (DE) FOR (B) BYTES ; ; FIND FILE ; STRT2: ; ; LOOK INTO DIRECTORY PTED TO BY USER (OR CURRENT IF USER DID NOT SPEC ONE) ; LXI D,FCB ; PT TO FCB ; CALL Z3LOG ; LOG INTO DIRECTORY CALL INITFCB ; RESET FCB CALL RETUD ; GET HOME LOCATION CALL F$EXIST ; IS FILE THERE? JNZ STRT3 ; ; LOOK ALONG PATH FROM CURRENT DIR (NOT INCLUDING CURRENT) ; CALL GETUD ; RETURN HOME LXI D,FCB ; PT TO FCB MVI A,0 ; DON'T SEARCH CURRENT DIR ALSO CALL PFIND ; SEARCH FOR FILE JNZ STRT3 ; FILE FOUND, SO PROCESS ; ; LOOK IN HELP FILE DIRECTORY ; LXI H,HELPDIR ; LOOK FOR HELP DIRECTORY CALL DIRTDU ; CONVERT TO DU IN BC JNZ LOGHLP ; LOG INTO DU IN BC IF FOUND MVI B,HDISK ; LOG INTO HELP DIRECTORY MVI C,HUSER LOGHLP: CALL LOGUD LXI D,FCB ; PT TO FCB CALL F$EXIST ; LOOK FOR FILE JNZ STRT3 ; FILE FOUND ; ; FILE NOT FOUND ; CALL EPRINT DB CR,LF,' File Not Found',0 JMP HLPEXIT ; ; FILE CONTAINS WILD CARDS ; FCBWERR: CALL EPRINT DB CR,LF,' AFN Not Allowed',0 JMP HLPEXIT ; ; LOAD HELP FILE INFORMATION ; ON INPUT, BC=DIRECTORY ; STRT3: CALL LOGUD ; LOG INTO DIRECTORY LXI D,FCB ; OPEN FILE CALL F$OPEN LHLD HLPBUF ; PT TO BUFFER SHLD NEXTADR ; SET PTR ; ; READ RECORDS UNTIL EOF ; STRT4: CALL READ ; READ INFO JZ STRT4 ; NOT DONE IF ZERO RETURN LXI D,FCB ; CLOSE FILE CALL F$CLOSE CALL GETUD ; RESTORE CURRENT DISK AND USER IF CHANGED ; ; START OF HELP PROGRAM ; HELP: LHLD HLPBUF ; PT TO BUFFER SPHL ; SET STACK MVI A,0 ; SET NO FRAME STA FRNUM MOV A,M ; NO HEADER SECTION? ANI 7FH ; MASK OUT MSB CPI SECTCHAR JNZ HELP1 ; HEADER SECTION EXISTS CALL CLS ; NEW SCREEN CALL PRINFO ; PRINT HELP INFO PTED TO BY HL LDA HLPLVL ; CHECK TO SEE IF WE ARE NOT AT LEVEL 0 ORA A ; 0=LEVEL 0 JZ HLPEXIT ; ABORT IF SO JMP LRURN ; GO TO PREVIOUS LEVEL IF NOT ; ; EXIT POINT FOR ANY EXIT FROM THE REST OF THE HELP PROGRAM ; HLPEXIT: CALL GETUD ; RESET CALLING DISK/USER NUMBER LHLD STACK ; GET CP/M SP SPHL RET ; DONE ; ; PRINT HEADER INFORMATION AND SELECT AN OPTION ; HELP1: CALL PRHEADER ; PRINT HEADER PUSH B ; SAVE C (NUMBER OF VALID SELECTIONS) CALL CRLF1 ; NEW LINE CALL STNDOUT ; GOTO DIM CALL PRLEVEL ; PRINT LEVEL NUMBER CALL EPRINT DB 'Enter Selection ',0 CALL PRP1 ; PRINT LEVEL MOVEMENT PROMPT CALL STNDEND ; GOTO BRIGHT POP B ; GET C CALL CIN ; GET RESPONSE CALL CAPS ; CAPITALIZE PUSH PSW CALL CLS ; CLEAR SCREEN POP PSW CPI CTRLC ; EXIT JZ HLPEXIT CPI ROOTCHAR ; GO TO ROOT JZ GOROOT CPI LRCHAR ; RETURN TO PREVIOUS LEVEL JZ LRURN MOV B,A ; USER INPUT IN B LDA HTYPE ; TYPE OF HELP FILE CPI IHCHAR ; INDEXED BY USER? JZ HELP5 ; FIND INFORMATION SECTION VIA INDEX SCAN MOV A,B ; FIND INFORMATION SECITON VIA COUNT SUI 'A'-1 ; ADJUST FOR COUNT MOV B,A ; SAVE COUNT JZ BADRESPONSE JNC HELP2 ; ; INVALID RESPONSE ; BADRESPONSE: CALL SAK ; RING BELL 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 BADRESPONSE LHLD FIRSTENTRY ; GET PTR TO FIRST ENTRY ; ; PRINT INFORMATION WHEN COUNT IS ZERO ; HELP3: DCR B ; COUNT DOWN SELECTIONS JNZ HELP4 CALL PRINFO ; PRINT INFO PTED TO BY HL JMP HELP1 ; ; LOCATE NEXT INFORMATION SECTION ; HELP4: CALL FINDI ; SKIP TO NEXT INFORMATION SECTION CPI CTRLZ ; END OF FILE? JNZ HELP3 ; CONTINUE LOOPING IF NOT ELSE FALL THRU TO HELPERR ; ; ERROR -- REACHED END OF HELP FILE ; HELPERR: CALL EPRINT DB CR,LF,' EOF on Help File',0 JMP HELP1 ; ; LOCATE NEXT INFORMATION SECTION VIA INDEX SCAN ; HELP5: LHLD FIRSTENTRY ; PT TO FIRST ENTRY ; ; LOOK FOR USER INDEX ; HELP6: PUSH H ; SAVE PTR TO THIS LINE HELP7: INX H ; SKIP OVER SECTION CHAR MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CALL CAPS ; CAPITALIZE CPI ' ' ; SKIP SPACES JZ HELP7 CPI SECTCHAR ; NEW SECTION? JZ HELP8 ; FIND NEXT SECTION CPI CR ; END OF LINE? JZ HELP8 ; FIND NEXT SECTION CPI CTRLZ ; EOF? JZ HELP8 CMP B ; CHECK FOR USER INPUT JNZ HELP7 POP H ; FOUND IT -- PRINT IT INX H ; SKIP OVER SECTION CHAR HELP7A: MOV A,M ; SKIP TO BEGINNING FOR 1ST LINE INX H ; PT TO NEXT ANI 7FH CPI CTRLZ ; TRAP EOF JZ BADRESPONSE CPI SECTCHAR ; FILE SPECIFIED? JZ HELP7B ; PROCESS IT CPI LF ; BEGIN NEW LINE JZ HELP7C CPI CR ; AT END OF INDEX LINE? JNZ HELP7A MOV A,M ; GET LF ANI 7FH CPI LF ; SKIP FOLLOWING LF IF ANY JNZ HELP7C INX H ; SKIP LF JMP HELP7C ; ; LOAD NEXT HELP LEVEL ; HELP7B: DCX H ; PT TO SECTION CHAR DCX H ; PT TO BEFORE SECTION CHAR FOR PRINFO ; ; PROCESS HELP LEVEL OR LOAD AND PROCESS NEXT LEVEL PTED TO BY HL ; HELP7C: CALL PRINFO ; PRINT INFORMATION SECTION JMP HELP1 ; RESUME HELP8: POP H ; PT TO INFO SECTION CALL FINDI ; FIND NEXT INFO SECTION CPI CTRLZ ; EOF? JNZ HELP6 ; KEEP LOOKING JMP BADRESPONSE ; ; SKIP TO NEXT INFORMATION SECTIONS ; RETURN WITH A=SECTCHAR IF FOUND OR A=^Z IF NOT ; FINDI: MOV A,M ; ? ANI 7FH ; MASK OUT MSB INX H ; PT TO NEXT BYTE CPI CTRLZ RZ CPI LF ; LINE FEED? JZ FINDI1 CPI CR ; ? JNZ FINDI MOV A,M ; MAKE SURE LF ANI 7FH CPI LF JNZ FINDI1 INX H ; SKIP OVER LF FINDI1: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI SECTCHAR ; NEW SECTION? JNZ FINDI ; CONTINUE LOOPING RET ; ; HELP SUPPORT ROUTINE SECTION ; ; ; PRINT ERROR MSG PTED TO BY DE; ENDS IN 0 ; PRMSG: XCHG ; MSG PTED TO BY HL CALL EPSTR XCHG 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 JNZ MOVE RET ; ; READ RECORD FROM DISK; NEXTADR CONTAINS ADDRESS TO READ TO ; ON RETURN, BDOS ERROR CODE IS IN A (0=NO ERROR) ; READ: LXI D,FCB ; PT TO FCB CALL F$READ ; READ NEXT RECORD PUSH PSW ; SAVE RETURN CODE LHLD NEXTADR ; PT TO LOAD ADDRESS LDA TPAEND ; CHECK AGAINST END PAGE OF TPA CMP H ; IF AT SAME PAGE, YES JZ READERROR 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 NEXTADR ; SET NEXT ADDRESS RET READERROR: CALL EPRINT DB CR,LF,' Mem Full',0 JMP HLPEXIT ; ; PRINT ONE LINE OF INFO SECTION; HL PTS TO LINE UPON ENTRY; ; HL PTS TO FIRST CHAR OF NEXT LINE UPON EXIT ; PRLINE: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI CR ; EOL? JZ CRLF CPI LF ; LINE FEED? (WS FILE) JZ CRLF0 CPI CTRLZ ; END OF FILE? JZ CRLFC ; DONE IF SO INX H ; PT TO NEXT CPI DIM ; GOTO STANDOUT MODE? JZ PRLDIM CPI NOTDIM ; GOTO NORMAL MODE? JZ PRLNDIM CALL COUT ; PRINT CHAR JMP PRLINE PRLDIM: CALL STNDOUT ; ENTER STANDOUT MODE JMP PRLINE PRLNDIM: CALL STNDEND ; END STANDOUT MODE JMP PRLINE ; ; 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 LCOUNT ; GET LINE COUNT DCR A STA LCOUNT 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 CALL PRPROMPT ; PRINT PROMPT AND PROCESS COMMON OPTIONS CPI BACKUPCHAR ; BACK UP? JZ FBACKUP CPI STRTCHAR ; JUMP TO START OF INFO JZ INFOSTRT FRESUME: SHLD STRTFRAME JMP SETLCOUNT ; ; PRINT PROMPT AND PROCESS COMMON OPTIONS ; PRPROMPT: CALL STNDOUT ; GOTO DIM CALL PRLEVEL ; PRINT LEVEL NUMBER LDA FRNUM ; INCREMENT FRAME NUMBER INR A STA FRNUM CALL PRP1 ; PRINT FUNDAMENTAL LEVEL DATA PROMPT CALL EPRINT DB MENUCHAR,'=Menu ' ; ABORT TO MENU CHAR DB STRTCHAR,'=Start ' ; JUMP TO START OF INFORMATION CHAR DB BACKUPCHAR,'=Last ' ; BACK UP TO PREVIOUS FRAME CHAR DB PRCHAR,'=Print ' ; PRINT CURRENT FRAME DB 0 CALL STNDEND ; GOTO BRIGHT CALL CIN ; GET RESPONSE CALL CAPS PUSH PSW CALL CLS ; CLEAR SCREEN POP PSW POP D ; CLEAR STACK CPI MENUCHAR ; ABORT? JZ HELP ; START OVER IF SO CPI CPMABORTCHAR ; ABORT TO OS JZ HLPEXIT CPI PRCHAR ; PRINT FRAME? JZ LIST0INFO CPI CPRCHAR ; PRINT INFORMATION SECTION? JZ LIST1INFO CPI ROOTCHAR ; GO TO ROOT JZ GOROOT CPI LRCHAR ; RETURN TO HIGHER LEVEL JZ LRURN PUSH D ; RESTORE STACK RET ; ; PRINT FUNDAMENTAL LEVEL PROMPT ; PRP1: LDA HLPLVL ; DON'T PRINT IF AT LEVEL 0 ORA A RZ CALL EPRINT DB LRCHAR,'=Level ' ; RETURN TO HIGHER NODE DB ROOTCHAR,'=Root ' ; RETURN TO ROOT DB 0 RET ; ; JUMP TO START OF INFORMATION ; INFOSTRT: LHLD STRTINFO ; PT TO START OF INFO MVI A,1 ; RESET FRAME COUNT STA FRNUM JMP FRESUME ; CONTINUE PROCESSING ; ; BACK UP TO PREVIOUS FRAME ; FBACKUP: CALL BOICHECK ; AT BEGINNING OF INFORMATION? JZ INFOSTRT FB1: DCX H ; BACK UP UNTIL BYTE WITH MSB SET IS FOUND MOV A,M ; GET BYTE ANI 80H JZ FB1 LDA FRNUM ; DECREMENT FRAME NUMBER DCR A ; BACK UP TO CURRENT FRAME NUMBER DCR A ; BACK UP TO PREVIOUS FRAME NUMBER STA FRNUM JMP FRESUME ; CONTINUE PROCESSING ; ; PRINT CR AND LF ONLY ; CRLF1: MVI A,CR ; PRINT CR CALL COUT MVI A,LF ; PRINT LF JMP COUT ; ; SET LCOUNT VARIABLE TO SCREEN SIZE ; SETLCOUNT: PUSH H ; SAVE HL CALL GETCRT ; GET CRT DATA INX H ; PT TO LINE COUNT MOV A,M ; GET LINE COUNT POP H ; RESTORE HL DCR A ; 1 LESS FOR PROMPT STA LCOUNT RET ; ; PRINT THE HEADER SECTION AND LOAD FIRSTENTRY PTR ; ON RETURN, C=NUMBER OF POSSIBLE SELECTIONS ; PRHEADER: MVI A,0 ; SET NO FRAME STA FRNUM CALL SETLCOUNT LDA LCOUNT SUI 3 ; -3 lines for top and bottom STA LCOUNT MVI A,'A' ; INIT SELECTION CHAR STA SELCHAR CALL CLS ; CLEAR SCREEN CALL EPRINT DB 'HELP ' db (vers/10)+'0','.',(vers mod 10)+'0' DB ' ',0 LXI D,FCB+1 ; PT TO FCB CALL PFN2 ; PRINT WITH NO SPACES CALL EPRINT db ' Index',CR,LF,CR,LF,0 MVI C,0 ; COUNT NUMBER OF SELECTIONS LHLD HLPBUF ; PT TO BUFFER MOV A,M ; GET FIRST CHAR STA HTYPE ; SET TYPE OF HELP FILE CPI IHCHAR ; INDEXED HELP TYPE? JNZ PH1 INX H ; SKIP OVER INDEX HELP TYPE FLAG ; ; PRINT LINE UNTIL FIRST INFORMATION SECTION FOUND ; PH1: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI SECTCHAR JZ PH2 CPI CTRLZ ; EOF? -- ABORT JZ HLPEXIT INR C ; INCREMENT SELECTION COUNT LDA HTYPE ; CHECK FOR INDEX CPI IHCHAR JZ PH1A ; SKIP LETTERS IF INDEXED LDA SELCHAR ; DISPLAY SELECTION CHAR CALL COUT INR A ; INCR CHAR STA SELCHAR CALL EPRINT DB '. ',0 PH1A: CALL PRLINE ; PRINT HEADER LINE JMP PH1 ; ; SAVE PTR TO FIRST ENTRY ; PH2: SHLD FIRSTENTRY LDA LCOUNT ; GET COUNT OF REMAINING LINES MOV B,A ; ... IN B ORA A ; ANY LEFT? RZ PH3: CALL CRLF1 ; NEW LINE DCR B JNZ PH3 RET ; ; PRINT AN INFORMATION SECTION ; INFORMATION SECTION IS PTED TO BY HL ; PRINFO: SHLD STRTINFO ; SET START OF INFORMATION POINTER CALL LDNOD ; LOAD NEW NODE IF DUAL SECTCHAR SHLD STRTFRAME ; SET FRAME POINTER MOV A,M ; SET MSB ORI 80H MOV M,A CALL SETLCOUNT MVI A,1 ; A=1 STA FRNUM ; SET FRAME NUMBER PI1: CALL PRLINE ; PRINT LINE FROM INFO FILE MOV A,M ; DONE? ANI 7FH ; MASK OUT MSB CPI CTRLZ ; EOF? JZ PI2 CPI SECTCHAR ; NEXT SECTION JZ PI2 CPI FF ; FORM FEED? JNZ PI1 INX H ; PT TO CHAR AFTER FORM FEED CALL FORMFEED ; FEED SCREEN JMP PI1 ; ; FORM FEED SCREEN ; FORMFEED: LDA LCOUNT ; GET LINE COUNT MOV B,A ; ... IN B FEEDLOOP: PUSH B ; SAVE B CALL CRLFC ; NEW LINE POP B ; GET B DCR B JNZ FEEDLOOP RET ; ; END OF INFO ; PI2: MOV A,M ; SET MSB OF NEXT BYTE ORI 80H MOV M,A PI2A: CALL CRLF1 ; NEW LINE LDA LCOUNT ; COUNT DOWN DCR A STA LCOUNT JNZ PI2A PI2MSG: CALL EPRINT ; PRINT END OF INFORMATION INDICATOR DB 'EOI ',0 CALL PRPROMPT ; PRINT PROMPT AND PROCESS COMMON OPTIONS CPI BACKUPCHAR ; BACK UP FROM EOI? JZ PI2BACKUP CPI STRTCHAR ; START OF INFO? JZ PI2STRT JMP SETLCOUNT ; RESET LINE COUNT IN CASE OF ALL ; ; JUMP TO START OF INFO FROM EOI ; PI2STRT: LHLD STRTINFO ; PT TO START OF INFO CALL FRESUME ; RESET POINTERS MVI A,1 ; RESET FRAME COUNT STA FRNUM JMP PI1 ; CONTINUE PROCESSING ; ; BACK UP TO PREVIOUS FRAME FROM EOI ; PI2BACKUP: CALL BOICHECK ; AT BEGINNING OF INFORMATION? JZ PI2STRT PI2BACK: CALL FB1 ; BACK UP TO PREVIOUS FRAME JMP PI1 ; CONTINUE PROCESSING ; ; CHECK FOR POSITION AT BEGINNING OF INFORMATION SECTION ; IF SO, PRINT BACKUP ERROR MSG AND RETURN W/ZERO SET ; BOICHECK: LHLD STRTINFO ; START ADDRESS XCHG ; ... IN DE LHLD STRTFRAME ; FRAME ADDRESS MOV A,D ; EQUAL? CMP H RNZ MOV A,E CMP L RNZ CALL SAK ; ERROR BELL XRA A ; ZERO FLAG SET STA FRNUM ; 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 ; LISTLINE: MOV A,M ; GET CHAR ANI 7FH ; MASK OUT MSB CPI CR ; EOL? JZ LCRLF CPI LF ; LINE FEED? (WS FILE) JZ LCRLF0 CPI CTRLZ ; END OF FILE? JZ LCRLFC ; DONE IF SO CALL LSTOUT ; PRINT CHAR RZ ; ABORT INX H ; PT TO NEXT JMP LISTLINE ; ; 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 LCOUNT ; GET LINE COUNT DCR A STA LCOUNT JNZ LNOABT ; OK -- CONTINUE CALL LFORMFEED ; ADVANCE TO NEXT PAGE SETPLC: PUSH H ; SAVE HL CALL GETPRT ; GET PRINTER DATA INX H ; PT TO TEXT LINE COUNT INX H MOV A,M ; GET TEXT LINE COUNT STA LCOUNT ; SET LINE COUNT POP H ; RESTORE HL RET LCRLF1: MVI A,CR ; SEND TO PRINTER CALL LSTOUT RZ ; ABORT MVI A,LF ; FALL THRU TO LSTOUT ; ; PRINT CHARACTER IN A ON PRINTER; AFFECT NO REGISTERS ; LSTOUT: PUSH H ; SAVE REGS PUSH D PUSH B MOV E,A ; CHAR IN E MVI C,5 ; BDOS PRER 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 STRTINFO ; ; LIST0INFO -- LIST CURRENT FRAME ONLY ; LIST1INFO -- LIST CURRENT INFORMATION SECTION ; LIST0INFO: LHLD STRTFRAME ; LIST CURRENT FRAME ONLY MVI A,0FFH ; SET FLAG STA LFRFLAG ; LIST FRAME ONLY JMP LIST2INFO LIST1INFO: LHLD STRTINFO ; PREPARE TO LIST ENTIRE INFO SECTION XRA A ; CLEAR FRAME LIST FLAG STA LFRFLAG LIST2INFO: CALL LISTINFO ; DO PRINT CALL CLS ; CLEAR SCREEN CALL LFORMFEED ; FORM FEED PRINTER LHLD STRTFRAME ; RETURN TO FRAME WE WERE ON CALL FRESUME LDA FRNUM ; ADJUST FRAME NUMBERING DCR A STA FRNUM JMP PI1 ; RESUME AT PI1 ; ; MAIN PRINT ROUTINE ; LISTINFO: CALL CLS ; PRINT FRAME OR INFO SECTION CALL EPRINT DB CR,LF,' Printing ',0 CALL SETPLC ; SET PRINTER LINE COUNT LI1: CALL LISTLINE ; LIST LINE FROM INFO FILE CPI CTRLC ; ABORT? RZ ; FEED PRINTER AND EXIT MOV A,M ; DONE? ANI 7FH ; MASK OUT MSB CPI CTRLZ ; EOF? RZ ; RESUME IF AT END OF INFO CPI SECTCHAR ; NEXT SECTION RZ ; RESUME IF AT END OF INFO CPI FF ; FORM FEED? JNZ LI1 LDA LFRFLAG ; LIST FRAME ONLY? ORA A ; 0=NO RNZ INX H ; PT TO CHAR AFTER FORM FEED CALL LCRLFC ; NEW LINE MVI B,10 ; PRINT SEPARATOR LI2: MVI A,'-' ; DASHES CALL LSTOUT RZ ; ABORT? DCR B ; COUNT DOWN JNZ LI2 CALL LCRLFC ; 2 NEW LINES CALL LCRLFC JMP LI1 ; ; FORM FEED PRINTER ; LFORMFEED: CALL LCRLF1 ; NEW LINE MVI A,FF ; OUTPUT FORM FEED CALL LSTOUT JMP SETPLC ; RESET LINE COUNT ; ; 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 SECTCHAR FOLLOWS, AND, IF SO, LOAD THE ; SPECIFIED FILE AS A NEW NODE AND BEGIN PROCESSING IT ; LDNOD: INX H ; PT TO POSSIBLE 2ND SECTCHAR MOV A,M ; GET IT DCX H ; PREP FOR RETURN ANI 7FH ; MASK MSB CPI SECTCHAR ; ANOTHER ONE? RNZ ; PROCESS NORMALLY IF NOT ; ; WE HAVE A NEW NODE -- CHECK TO SEE IF WE CAN NEST AGAIN ; LDA HLPLVL ; GET CURRENT HELP LEVEL CPI 25 ; AT MAXIMUM? JNZ LDNOD1 CALL CLS ; NEW SCREEN CALL EPRINT db cr,lf,' Node Level Limit',0 JMP HLPEXIT ; ; WE HAVE NOT REACHED LEVEL LIMIT, SO CONTINUE ; AT THIS TIME, A=HELP LEVEL INDEX AND HL = PTR TO CURRENT SECTION (::) ; LDNOD1: ; ; SAVE CURRENT HELP FILE NAME FOR RETURN ; INX H ; PT TO SECTION SECTCHAR INX H ; NOW POINTING TO FILE NAME PUSH H ; SAVE PTR CALL COMPTR ; 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 HLPLVL ; GET OLD LEVEL INR A ; SET NEW LEVEL STA HLPLVL ; ; SET UP FCB FOR NEW FILE ; POP H ; GET PTR TO NEW FILE NAME LXI D,FCB+1 ; PT TO FCB NAME MVI B,8 ; 8 CHARS MAX CALL LDFCB ; PLACE INTO FCB WITH ERROR CHECKING MVI B,3 ; 3 CHARS MAX FOR TYPE CPI '.' ; CONTINUE IF FILE TYPE PRESENT CZ LDFCB ; PLACE INTO FCB WITH ERROR CHECKING ; ; PRINT LOADING HELP FILE MESSAGE ; PLHFM: CALL EPRINT DB CR,LF,' Loading HELP File ',0 LXI D,FCB+1 ; PRINT FILE NAME CALL PFN2 JMP STRT1 ; LOAD NEW HELP FILE ; ; LOAD FCB PTED TO BY DE WITH "NORMAL" FILE NAME PTED TO BY HL FOR B BYTES ; LDFCB: MOV A,M ; GET CHAR INX H ; PT TO NEXT CPI '.' ; DONE IF DECIMAL JZ LDFCB2 CPI ' '+1 ; DONE IF <= JC LDFCB2 CALL CAPS ; CAPITALIZE STAX D ; STORE CHAR INX D ; PT TO NEXT DCR B JNZ LDFCB LDFCB1: MOV A,M ; CHECK FOR ERROR ANI 7FH ; MASK MSB INX H ; PT TO NEXT CHAR CPI '.' ; OK IF '.' RZ CPI ' '+1 ; OK IF <= RC JMP LDFCB1 LDFCB2: MOV C,A ; SAVE CHAR THAT TERMINATED STRING LDFCB3: MVI A,' ' ; FILL REST OF FCB STAX D ; STORE INX D ; PT TO NEXT DCR B JNZ LDFCB3 MOV A,C ; GET CHAR THAT TERMINATED STRING RET ; ; GO TO ROOT ; GOROOT: LDA HLPLVL ; AT ROOT? ORA A ; 0=YES JZ HELP ; RETURN TO HELP MVI A,0 ; SET ROOT INDEX JMP GORET ; ; RETURN TO PREVIOUS HELP LEVEL ; LRURN: LDA HLPLVL ; ARE WE AT THE LOWEST LEVEL? ORA A ; 0=YES JNZ LRET CALL SAK ; ERROR BELL JMP HELP ; ; SET NEW HELP LEVEL ; LRET: DCR A ; DOWN 1 AND FALL THRU TO GORET ; ; GO TO HELP LEVEL INDEXED IN A ; GORET: STA HLPLVL ; SET NEW HELP LEVEL CALL COMPTR ; HL=POINTER TO TARGET HELP FILE NAME LXI D,FCB+1 ; COPY ELEMENT INTO FCB MVI B,11 ; 11 BYTES CALL MOVE JMP PLHFM ; PRINT LOADING MESSAGE AND LOAD ; ; COMPUTE POINTER TO HELP NAME ENTRY INDEXED BY HELP LEVEL IN A ; COMPTR: MOV L,A ; VALUE IN HL MVI H,0 ; COMPUTE OFFSET AS INDEX*11 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 XCHG ; RESULT IN DE LHLD HLPNSTK ; PT TO BASE OF HELP NAMES DAD D ; ADD IN OFFSET RET ; ; PRINT LEVEL NUMBER ; PRLEVEL: LDA HLPLVL ; DON'T PRINT LEVEL 0 ORA A ; 0? JZ PRFRAME CALL EPRINT DB 'Level ',0 LDA HLPLVL ; GET NUMBER CALL PAFDC ; PRINT AS DECIMAL LDA FRNUM ; GET FRAME NUMBER ORA A ; SET FLAGS MVI A,'/' ; PREP TO PRINT SLASH CNZ COUT ; PRINT SLASH IF FRAME IS NON-ZERO PRFRAME: LDA FRNUM ; GET NUMBER ORA A MVI A,' ' ; PREP TO PRINT SPACE ON EXIT JZ COUT LDA FRNUM ; GET FRAME NUMBER AGAIN CALL PAFDC ; PRINT AS DECIMAL CALL EPRINT DB ': ',0 RET ; ; RING ERROR BELL ; SAK: MVI A,BEL JMP COUT ; ; BUFFER SECTION ; HTYPE: DS 1 ; TYPE OF HELP FILE (IF = IHCHAR, IT IS INDEXED BY USR) LFRFLAG: DS 1 ; LIST FRAME ONLY FLAG (FOR PRINT FUNCTION) TPAEND: DS 1 ; END PAGE ADDRESS OF TPA STRTINFO: DS 2 ; PTR TO START OF CURRENT INFORMATION BLOCK STRTFRAME: DS 2 ; PTR TO START OF CURRENT FRAME SELCHAR: DS 1 ; SELECTION TABLE OPTION CHAR FIRSTENTRY: DS 2 ; PTR TO FIRST ENTRY OF INFORMATION SECTION LCOUNT: DS 1 ; LINE COUNT BUFFER NEXTADR: DS 2 ; NEXT LOAD ADDRESS HLPLVL: DS 1 ; NUMBER OF HELP LEVEL CURRENT NODE IS AT (0=BOTTOM) FRNUM: DS 1 ; NUMBER OF CURRENT FRAME HLPNSTK: DS 2 ; PTR TO STACK OF HELP FILE NAMES OF EACH LEVEL HLPBUF: DS 2 ; PTR TO HELP BUFFER STACK: DS 2 ; OPSYS STACK PTR END