; ; PROGRAM NAME: HELPCK ; AUTHOR: RICHARD CONN ; DATE: 18 MAY 84 ; VERSION: 1.0 ; PREVIOUS VERSIONS: None ; DERIVATION: HELP.MAC 5.0 (18 MAY 84) ; NOTE: FOR USE WITH ZCPR3 ONLY ; VERS EQU 10 Z3ENV SET 0F400H ; ; HELPCK performs a syntax check on HLP files. 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 ; ; Address of Help File Buffer (Make Same as HELP.COM Buffer) ; Used to Test for Memory Overflow ; HLPBUF EQU 0F00H ; I GOT THIS BY PEEKING AT MEM ; AFTER RUNNING HELP ON A FILE ; ; SYSLIB ROUTINES ; EXT Z3INIT,Z3LOG,GETPRT EXT PUTUD,GETUD EXT SCTLFL,SPRINT,SOUT,CAPS,SADC,SHLDC,LOUT,SFN2 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 FCB2 EQU 6CH ; 2ND FCB 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 PRCHAR EQU 'P' ; PRINTER OUTPUT ; ; 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 z3init ;initialize the ZCPR3 Env and the VLIB Env MVI A,1 ; SELECT CONSOLE ONLY STA SCTLFL ; SET SWITCHED OUTPUT FLAG LDA FCB2+1 ; LOOK FOR PRINT OPTION CPI 'P' JNZ START1 MVI A,81H ; SELECT CONSOLE AND PRINTER STA SCTLFL START1: LDA BDOS+2 ; BASE PAGE OF BDOS SUI 10 ; 2K + 2 PAGES STA TPAEND XRA A ; A=0 STA ITYPE ; SET NON-INDEXED FOR TYPE OF FILE CALL PUTUD ; SAVE HOME CALL SPRINT DB 'HELPCK Version ' db (vers/10)+'0','.',(vers mod 10)+'0',0 LXI H,FCB+1 ; CHECK FOR FILE NAME MOV A,M CPI '/' ; OPTION CAUGHT? JZ STRT0 CPI ' ' ; NONE? JNZ STRT1 ; ; PRINT HELP MESSAGE ; STRT0: CALL SPRINT DB CR,LF,'Syntax:' DB CR,LF,' HELPCK dir:filename.typ o <-- Check File' DB CR,LF,' HELPCK dir:filename o <-- Check filename.HLP' DB CR,LF,'Options:' DB CR,LF,' P = Output to Printer' DB 0 RET ; ; BEGIN HELP CHECK PROGRAM ; STRT1: ; ; 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 ; ; READ IN FILE ; STRT2: CALL SPRINT DB ' Help File: ',0 LXI D,FCB+1 ; PT TO NAME CALL SFN2 LXI D,FCB ; PT TO FCB CALL Z3LOG ; LOG INTO DIRECTORY CALL INITFCB ; RESET FCB CALL F$EXIST ; IS FILE THERE? JNZ STRT3 ; ; FILE NOT FOUND ; CALL SPRINT DB CR,LF,' File Not Found',0 RET ; ; FILE CONTAINS WILD CARDS ; FCBWERR: CALL SPRINT DB CR,LF,' AFN Not Allowed',0 RET ; ; LOAD HELP FILE INFORMATION ; STRT3: LXI D,FCB ; OPEN FILE CALL F$OPEN LXI H,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: MVI A,1 ; SET NUMBER OF INFO SECTION STA INFONUM LXI H,HLPBUF ; PT TO FIRST CHAR MOV A,M ; NO HEADER SECTION? ANI 7FH ; MASK OUT MSB CPI SECTCHAR JNZ HELP1 ; HEADER SECTION EXISTS ; ; CHECK NON-INDEXED HELP FILE ; CALL SPRINT DB CR,LF,' Help File is Not Indexed',0 CALL CKINFO ; CHECK HELP INFO PTED TO BY HL RET ; ; CHECK INDEXED HELP FILE ; HELP1: STA ITYPE ; SET INDEX TYPE CPI IHCHAR ; INDEXED BY USER? JNZ HELP1A CALL SPRINT DB CR,LF,' Help File is User-Indexed',0 JMP HELP1B HELP1A: CALL SPRINT DB CR,LF,' Help File is Indexed by HELP',0 HELP1B: CALL CKHEADER ; CHECK HEADER ; ; CHECK INFORMATION SECTIONS OF INDEXED HELP FILE ; HELP2: CALL CKINFO ; CHECK INFO SECTION PUSH PSW ; SAVE FLAG LDA INFONUM ; INCREMENT NUMBER OF INFORMATION SECTION INR A STA INFONUM POP PSW CPI CTRLZ ; DONE? JNZ HELP2 LDA ITYPE ; USER INDEXED? CPI IHCHAR JZ HELP3 LDA INFONUM ; GET COUNT OF INFO SECTIONS DCR A ; ADJUST TO CORRECT NUMBER MOV B,A ; SAVE IN B CALL SPRINT DB CR,LF,CR,LF,' Information Section Count is ',0 LDA IDXNUM ; GET NUMBER OF INDEX ENTRIES CMP B JZ HELP2A CALL SPRINT DB 'Incorrect',0 JMP HELP3 HELP2A: CALL SPRINT DB 'Correct',0 HELP3: CALL SPRINT DB CR,LF,' HELPCK Done',CR,LF,0 LDA SCTLFL ; CHECK FOR PRINTER SELECTED ANI 80H RZ ; DONE IF NO PRINTER OUTPUT CALL GETPRT ; GET PRINTER DATA INX H ; PT TO FF FLAG INX H INX H MOV A,M ; GET FLAG ORA A ; 0=NO FF RZ MVI A,FF ; OUTPUT FF JMP LOUT ; ; 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: POP PSW ; CLEAR PSW POP PSW ; CLEAR RET ADR CALL SPRINT DB CR,LF,' Memory Full',0 RET ; ; CHECK HEADER ; CKHEADER: MVI A,0 ; SET LINE COUNT STA IDXNUM CKH1: MOV A,M ; CHECK FOR DONE CPI SECTCHAR ; DONE? JZ CKH2 CPI CTRLZ ; EOF? JZ CKH3 CALL SKPLINE ; SKIP TO NEXT LINE LDA IDXNUM ; INCREMENT LINE COUNT INR A STA IDXNUM JMP CKH1 CKH2: CALL SPRINT DB CR,LF,' Lines in Header: ',0 LDA IDXNUM ; GET COUNT CALL SADC RET CKH3: CALL SPRINT DB CR,LF,' Premature EOF at Header',0 RET ; ; CHECK INFORMATION SECTION PTED TO BY HL ; CKINFO: CALL SPRINT DB CR,LF,CR,LF,' Information Section ',0 LDA INFONUM ; GET NUMBER OF INFO SECTION CALL SADC ; PRINT IT MOV A,M ; CHECK FOR VALID SECTION CHAR ANI 7FH CPI SECTCHAR JZ CKINFO1 CALL SPRINT DB CR,LF,' Info Section Does Not Begin with :',0 CKINFO1: INX H ; PT TO FIRST CHAR LDA ITYPE ; TYPE OF INFO SECTION CPI IHCHAR ; USER-INDEXED? JZ CKINFO2 MOV A,M ; CHECK FOR EXTERNAL FILE REFERENCE CPI SECTCHAR JNZ CKINFO1C INX H ; PT TO FIRST CHAR OF FILE NAME CKIHF: CALL SPRINT DB CR,LF,' External Help File: ',0 PUSH H ; SAVE HL CKINFO1A: MOV A,M ; GET CHAR INX H ; PT TO NEXT ANI 7FH CALL CAPS CPI ' '+1 ; CHECK FOR RANGE JC CKINFO1B CALL SOUT ; PRINT CHAR JMP CKINFO1A CKINFO1B: POP H ; RESTORE HL CALL SKPLINE ; SKIP TO EOL JMP CKINFO3 CKINFO1C: CALL SKPLINE ; SKIP TO EOL CALL EMPCK ; CHECK FOR EMPTY JMP CKINFO3 CKINFO2: CALL SPRINT DB CR,LF,' User Indices: ',0 CKI2A: MOV A,M ; GET CHAR ANI 7FH INX H ; PT TO NEXT CPI SECTCHAR ; EXTERNAL HELP FILE? JZ CKIHF CPI LF JZ CKI2C CPI ' ' JZ CKI2A CPI CR JZ CKI2B CALL CAPS ; CAPITALIZE CALL SOUT ; PRINT INDEX MVI A,' ' ; FOLLOWING SPACE CALL SOUT JMP CKI2A CKI2B: MOV A,M ; CHECK FOR LF ANI 7FH CPI LF JZ CKI2C INX H ; SKIP LF CKI2C: CALL EMPCK ; CHECK FOR EMPTY CKINFO3: PUSH H LXI H,1 ; SET LINE COUNTER SHLD LCOUNT POP H CKINFO4: MOV A,M ; CHECK FOR NEW INFO SECTION CPI SECTCHAR JZ CKISUM CPI CTRLZ ; EOF? JZ CKISUM CALL SKPLINE ; SKIP TO NEXT LINE PUSH H ; INCREMENT LINE COUNT LHLD LCOUNT INX H SHLD LCOUNT POP H JMP CKINFO4 CKISUM: PUSH H CALL SPRINT DB CR,LF,' Number of Lines: ',0 LHLD LCOUNT CALL SHLDC POP H RET ; ; CHECK TO SEE IF AT EOF OR INFO SECTION AND PRINT EMPTY MESSAGE IF SO ; EMPCK: MOV A,M ; GET CHAR ANI 7FH CPI CTRLZ ; EOF? JZ EMPCK1 CPI SECTCHAR RNZ EMPCK1: CALL SPRINT DB CR,LF,' Information Section is Empty',0 RET ; ; SKIP TO END OF CURRENT LINE ; SKPLINE: MOV A,M ; GET CHAR ANI 7FH ; MASK CPI CTRLZ ; EOF? RZ INX H ; PT TO NEXT CPI LF RZ JMP SKPLINE ; ; BUFFER SECTION ; DEFTYP: DB 'HLP' ; DEFAULT TYPE OF HELP FILE ITYPE: DS 1 ; TYPE OF HELP FILE (IF = IHCHAR, IT IS INDEXED BY USR) TPAEND: DS 1 ; END PAGE ADDRESS OF TPA LCOUNT: DS 2 ; LINE COUNTER INFONUM: DS 1 ; INFORMATION SECTION NUMBER IDXNUM: DS 1 ; INDEX NUMBER FIRSTENTRY: DS 2 ; PTR TO FIRST ENTRY OF INFORMATION SECTION NEXTADR: DS 2 ; NEXT LOAD ADDRESS END