; ; PROGRAM: HELPPR ; AUTHOR: Richard Conn ; VERSION: 1.0 ; DATE: 18 May 84 ; PREVIOUS VERSIONS: None ; DERIVATION: PHELP 2.0 (28 Apr 83) ; VERS equ 10 z3env SET 0f400h FALSE EQU 0 TRUE EQU NOT FALSE timeok equ FALSE ;TRUE if TIME enabled, FALSE if not ; ; HELPPR is used to print out a HLP file. It breaks pages on each ; information section and ignores form feeds, so the data is presented ; in a sequential fashion. It is very convenient to provide online ; documentation in the form of HLP files, and this utility allows the user ; to readily print out this documentation. HELPPR is preferred over PRINT ; for printing HLP files because of its knowledge of their structure and ; its special way of handling them. ; ; HELPPR is invoked by a command line of the following form: ; HELPPR file1,file2,...,filen o... ; where each "filen" is an ambiguous file name and "o" is zero or more of ; the following options: ; H@head@ Heading Text ; The user may specify the text of the heading to ; appear at the top of every page ; I Inspect Files ; The user approves each file to be printed ; before the printing process begins ; L Toggle Line Numbering ; Each line may or may not begin with a line number ; Snnnn Skip to Specified Page ; Printing begins at the indicated page ; T Toggle Time Display ; Time/Date information is optionally included ; in the page header ; ; ; BASIC SYSLIB ROUTINES NEEDED BY HELPPR ; C$ESIZE EQU 16 ; SIZE OF DIR ENTRY (FROM SYSLIB DIRF ROUTINE) EXT DIRQS ; DIRECTORY PROCESSOR EXT Z3INIT ; INIT BUFFERS EXT ZFNAME ; FILE NAME PROCESSOR EXT Z3LOG ; LOG INTO DIR EXT INITFCB ; INIT FCB EXT RETUD ; RETURN CURRENT USER/DISK EXT PUTUD ; SAVE CURRENT USER/DISK EXT GETUD ; RESTORE CURRENT USER/DISK EXT EPRINT ; PRINT STRING PTED TO BY RET ADR EXT PADC ; PRINT A AS DECIMAL CHARS EXT COUT ; CONSOLE OUTPUT ROUTINE EXT CST ; CONSOLE STATUS ROUTINE EXT CIN ; CONSOLE INPUT ROUTINE EXT CAPS ; CAPITALIZE ROUTINE EXT CRLF ; NEW LINE ROUTINE EXT CODEND ; CODE END COMPUTATION ROUTINE EXT F$OPEN ; FILE OPEN EXT F$READ ; BLOCK READ EXT F$CLOSE ; FILE CLOSE ext getprt ext eval10 ext lcrlf ext lpstr ext lprint ext lout ext lhldc ext condin ext moveb ; if timeok ext time endif ; ; ; Insert Function-Required Library References Here ; ; ; CP/M EQUATES ; CPM EQU 0 ; WARM BOOT BDOSE EQU CPM+5 ; BDOS ENTRY FCB EQU CPM+5CH ; FCB TBUFF EQU CPM+80H ; INPUT LINE BUFFER DEL EQU 7FH ; CR EQU 13 ; FF EQU 12 ; LF EQU 10 ; CTRLC EQU 'C'-'@' ; ^C CTRLG EQU 'G'-'@' CTRLH EQU 'H'-'@' CTRLI EQU 'I'-'@' CTRLS EQU 'S'-'@' CTRLX EQU 'X'-'@' CTRLZ EQU 'Z'-'@' eold equ 0FFH ;End of Load Indicator ; ; 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 jmp startx ; ; **** Special Initial Value Area for User Installation ; LWIDTH: DB 132 ; PRINTER LINE WIDTH LTPP: DB 44 ; LINES OF TEXT PER PAGE LSPP: DB 5 ; LINES TO SKIP PER PAGE LFF: DB 1 ; FORM FEED FLAG ; ; NOTE: LTPP + LSPP + 2 (HEADER SIZE) = TOTAL LINES PER PAGE ON PRINTER ; DLNUMFL: DB 0 ; LINE NUMBER FLAG (DEFAULT TO NO) DTIMEPFL: DB 0FFH ; TIME PRINT FLAG (DEFAULT TO YES) DINSPECT: DB 0 ; INSPECT FILES (DEFAULT TO NO) ; ; WORKING BUFFERS ; LNUMFL: DB 0 ; LINE NUMBER FLAG TIMEPFL: DB 0FFH ; TIME PRINT FLAG INSPECT: DB 0 ; INSPECT FLAG SKIPFL: DB 0 ; SKIP FLAG (DEFAULT TO NO) SKIPNUM: DS 2 ; PAGE NUMBER TO SKIP TO LNUM: DS 2 ; CURRENT LINE NUMBER PNUM: DS 2 ; CURRENT PAGE NUMBER HBUF: DS 2 ; BUFFER FOR HEADING ; if timeok TIMEBF: DS 100 ; BUFFER FOR TIME STAMP endif ; ; Start of Program ; STARTX: LXI H,0 ; GET STACK PTR DAD SP SHLD V$STACK ; SAVE IT XRA A ; A=0 STA V$INSPECT ; TURN OFF FILE INSPECTION CALL PUTUD ; SAVE CURRENT USER/DISK AWAY call codend ; determine free space shld V$CMDLNE ; set command line ptr lxi d,100h ; arbitrary size dad d shld HBUF ; ptr to heading buffer dad d shld dirbuf ; ptr to dir buffer sphl ; new stack ; ; Save Command Line ; lhld V$CMDLNE ; save command line LXI D,TBUFF+1 ; SAVE COMMAND LINE xchg mvi b,80h ; 128 bytes call moveb ; ; Setup Printer Data ; call getprt mov a,m ;get width sta lwidth inx h inx h mov a,m ;get lines of text per page sta ltpp mov b,a ;save in B dcx h mov a,m ;get lines per page sub b ;compute difference sta lspp ;lines to skip per page inx h inx h mov a,m ;get form feed flag sta lff ; ; Banner of Program ; CALL BANNER ; PRINT BANNER ; ; Check for Help Request ; LDA FCB+1 ; GET FIRST CHAR OF FILE NAME CPI ' ' ; NO FILE SPEC? JZ T$HELPENT CPI '/' ; OPTION CAUGHT? JNZ T$ECONT ; ; Print Help Information ; T$HELPENT: CALL HELP ; PRINT PROGRAM'S HELP MESSAGE ; ; RETURN TO OS ; T$RETURN: CALL DINIT ; DEINIT PROGRAM LHLD V$STACK ; GET OLD STACK SPHL ; SET IT RET ; ; PROGRAM'S INIT ROUTINE ; T$ECONT: CALL INIT ; PROG INIT ROUTINE ; ; EXTRACT FLAGS IF PRESENT ; LXI H,0 ; SET FILE COUNT SHLD V$FILECNT LHLD V$CMDLNE ; PT TO BUFFER ; ; SKIP TO FILE NAME STRING ; CALL T$SBLANK ; SKIP OVER BLANKS ; ; SKIP TO END OF FILE NAME STRING ; CALL T$SNBLANK ; SKIP OVER NON-BLANKS ; ; CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO ; T$OPT: CPI '/' ; OPTION CHAR? JNZ T$OPTION INX H ; SKIP SLASH ; ; PROCESS LIST OF OPTIONS ; T$OPTION: MOV A,M ; GET BYTE ORA A ; DONE? JZ T$DSPEC INX H ; PT TO NEXT CHAR CPI ' ' ; SKIP OVER SPACES JZ T$OPTION MOV C,A ; COMMAND IN C LXI D,OPTAB ; PT TO OPTION TABLE T$OPTL: LDAX D ; GET OPTION LETTER ORA A ; END OF TABLE? JZ T$HELPENT ; HELP IF SO CMP C ; MATCH? JZ T$OPTM ; PROCESS IF SO INX D ; PT TO NEXT ENTRY INX D INX D JMP T$OPTL ; ; PROCESS OPTION ; T$OPTM: PUSH H ; SAVE HL ON STACK LXI H,T$OPTION ; GET RETURN ADDRESS XTHL ; ... ON STACK AND RESTORE HL INX D ; PT TO ADDRESS LDAX D ; GET ADDRESS LOW MOV B,A ; ... IN B INX D LDAX D ; GET ADDRESS HIGH MOV D,A ; ... IN D MOV E,B ; LOW IN E PUSH D ; PUT ADDRESS ON STACK MOV A,C ; COMMAND IN A RET ; "CALL" OPTION ROUTINE ; ; BEGIN MOVING THROUGH FILE NAMES, SEPARATED BY COMMAS ; T$DSPEC: LHLD V$CMDLNE ; PT TO FIRST BYTE CALL T$SBLANK ; SKIP TO NON-BLANK ; ; MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS ; HL PTS TO FIRST BYTE OF NEXT FILE SPEC ; T$DSPEC1: shld hltemp ; save HL lhld dirbuf ; reset stack sphl lhld hltemp ; restore HL CALL GETUD ; RESET USER IF NECESSARY LXI D,V$NTFCB ; PT TO FCB IN DE, PT TO 1ST CHAR OF FN IN HL MVI A,0 ; DIR before DU CALL ZFNAME ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER push b ;save disk/user push h ;save others push d lxi h,hlptyp ;optionally set default HLP type lxi d,V$NTFCB+9 ;check for any specified ldax d ;' ' means none cpi ' ' jnz hlpskp mvi b,3 ;3 chars call moveb hlpskp: pop d ;restore others pop h pop b ;restore disk/user SHLD V$NEXTCH ; SAVE PTR TO DELIMITER WHICH ENDED SCAN ; ; LOAD DIRECTORY AND PERFORM FUNCTION ; T$FCT: LXI D,V$NTFCB ; PT TO FCB CALL Z3LOG ; LOG INTO ACCOUNT LHLD DIRBUF ; PT TO DIR BUFFER MVI A,11000000B ; SELECT SYS AND NON-SYS FILES LXI D,V$NTFCB ; PT TO FCB CALL INITFCB ; INIT THE FCB CALL DIRQS ; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE ; ; DETERMINE BEGINNING OF SCRATCH AREA (SCRATCH) AND SIZE IN PAGES (BCNT) ; PUSH H ; SAVE PTR AND COUNT PUSH B LXI D,C$ESIZE ; SET PTR TO NEXT FREE BLOCK T$FCTFRE: MOV A,B ; DONE? ORA C JZ T$FCTFR1 DAD D ; PT TO NEXT DCX B ; COUNT DOWN JMP T$FCTFRE T$FCTFR1: INR H ; NEXT PAGE MVI L,0 SHLD V$SCRATCH ; SET PTR TO SCRATCH AREA XCHG ; PTR IN DE LHLD BDOSE+1 ; COMPUTE BLOCK BUFFER SIZE MOV A,H ; ADJUST FOR ZCPR3 SUI 10 SUB D ; A=SIZE IN BLOCKS STA V$BCNT ; SET BLOCK COUNT POP B ; RESTORE AND SAVE REGS POP H ; ; ALLOW USER TO INSPECT FILES ; PUSH H PUSH B CALL T$ICHECK ; CHECK FOR INSPECT OPTION AND INSPECT IF SET POP B ; RESTORE COUNT AND PTR POP H ; ; PERFORM FUNCTION; HL PTS TO FILE AND BC CONTAINS NUMBER OF FILES ; T$FCTL: MOV A,B ; CHECK FOR COMPLETION (COUNT = 0) ORA C JZ T$FCTL1 DCX B ; COUNT DOWN SHLD HLTEMP ; SET STACK LHLD DIRBUF SPHL LHLD HLTEMP PUSH B ; SAVE COUNT AND PTR PUSH H MOV A,M ; SELECTED FILE? ORA A ; 0=YES CZ FUNCTION ; PERFORM FUNCTION ; ; ENTRY POINT TO SKIP TO NEXT FILE IN LIST ; E$FCTLNXT: LHLD DIRBUF ; RESTORE STACK LXI D,-4 ; 4 DOWN DAD D SPHL POP H ; RESTORE PTR POP B ; RESTORE COUNT LXI D,C$ESIZE ; PT TO NEXT ENTRY DAD D JMP T$FCTL ; ; CHECK FOR NEXT FILE SPEC ; T$FCTL1: CALL GETUD ; RETURN TO BASE USER/DISK LHLD V$NEXTCH ; GET PTR MOV A,M ; GET DELIM CPI ',' ; ANOTHER FILE? JNZ T$RETURN INX H ; PT TO CHAR AFTER COMMA JMP T$DSPEC1 ; CONTINUE PROCESSING ; ; INSPECT FILES -- THIS ROUTINE IS TO PERFORM A FILE INSPECTION ; ON INPUT, HL PTS TO FIRST 16-BYTE ENTRY AND BC=NUMBER OF ENTRIES ; T$ICHECK: MOV A,B ;ANY FILES? ORA C ;0=NO RZ PUSH H ;SAVE PTRS PUSH B LXI D,C$ESIZE ;SIZE OF ENTRY T$ICHK1: MVI M,0 ;CLEAR MSBYTES DAD D ;PT TO NEXT DCX B ;COUNT DOWN MOV A,B ;DONE? ORA C JNZ T$ICHK1 POP B ;RESTORE PTRS POP H LDA V$INSPECT ;INSPECT? ORA A ;0=NO RZ CALL EPRINT DB CR,LF,' File Inspect Mode' db cr,lf,' Cmd Function Cmd Function' DB CR,LF,' Y(def) Select File Q Select Rest of Files' DB CR,LF,' N Don''t Select S Skip Rest of Files' db cr,lf,0 T$ICHK2: CALL EPRINT DB CR,LF,'Select ',0 CALL E$PRFN ;PRINT FILE NAME CALL EPRINT DB ' -- (Y/N/Q/S)? ' DB 0 CALL CIN ;GET RESPONSE CALL CAPS ;CAPITALIZE CALL COUT ;ECHO CPI 'Q' ;SELECT REST? JZ T$ICHKYR CPI 'S' ;SKIP REST JZ T$ICHKNR CPI 'N' ;NO TO THIS ONE? JNZ T$ICHK3 MVI M,0FFH ;SET NO FLAG IN FILE FCB T$ICHK3: DAD D ;PT TO NEXT ONE DCX B ;COUNT DOWN MOV A,B ;DONE? ORA C JNZ T$ICHK2 RET ; CHECK REST OF FILES AS SELECTED T$ICHKYR: CALL EPRINT DB CR,LF,' Rest of Files Selected',0 RET ; CHECK REST OF FILES AS NOT SELECTED T$ICHKNR: MVI M,0FFH ;SET NO FLAG DAD D ;PT TO NEXT DCX B ;COUNT DOWN MOV A,B ;DONE? ORA C JNZ T$ICHKNR CALL EPRINT DB CR,LF,' Rest of Files NOT Selected',0 RET ; ; UTILITIES ; T$SBLANK -- SKIP BLANKS PTED TO BY HL UNTIL NON-BLANK ENCOUNTERED; HL ; T$SNBLANK -- SKIP NON-BLANKS PTED TO BY HL UNTIL BLANK OR EOL; HL ; E$PRFN -- PRINT FILE NAME PTED TO BY HL; AFFECT NOTHING ; ; SKIP UNTIL NON-BLANK ; T$SBLANK: MOV A,M ; LOOK FOR BLANK INX H ; PT TO NEXT CPI ' ' ; BLANK? JZ T$SBLANK DCX H ; BACK UP RET ; ; SKIP UNTIL BLANK OR EOL ; T$SNBLANK: MOV A,M ; GET CHAR INX H ; PT TO NEXT CPI ' ' ; BLANK? JZ T$SNB1 ORA A ; EOL? JNZ T$SNBLANK T$SNB1: DCX H ; BACK UP RET ; ; PRINT FILE NAME PTED TO BY HL ; OUTPUT TO CON: ; E$PRFN: PUSH H ; SAVE REGS PUSH B CALL RETUD ; GET CURRENT USER/DISK MOV A,B ; GET DISK NUMBER ADI 'A' ; CONVERT TO LETTER CALL COUT ; PRINT LETTER MOV A,C ; GET USER NUMBER CALL PADC ; PRINT USER NUMBER CALL EPRINT DB ': ',0 INX H ; PT TO FILE NAME MVI B,8 ; PRINT NAME CALL T$PRNT MVI A,'.' ; DECIMAL CALL COUT MVI B,3 ; PRINT TYPE CALL T$PRNT POP B ; GET REGS POP H RET ; ; PRINT CHARS PTED TO BY HL FOR B BYTES ; OUTPUT TO CON: ; T$PRNT: MOV A,M ; GET CHAR CALL COUT INX H ; PT TO NEXT DCR B ; COUNT DOWN JNZ T$PRNT RET ;*********************************************** ;* Application-Specific Section ;*********************************************** ;**************************************************** ;* ;* Function-Specific Routines ;* These routines need to be customized for the ;* specific function being performed. These, in ;* effect, implement the function. Other Entry Points ;* useful to the programmer are: ;* E$FCTLNXT -- Clean Abort of Current ;* Processing and Skip ;* to Next File in List; ;* This is a Clean Way to ;* Abort FUNCTION for the ;* Next File ;* E$PRFN -- Print File Name Pted to ;* by HL; No Regs Affected ;* ;**************************************************** ; ; **** EMERGENCY ABORT ; ABORT: CALL EPRINT db cr,lf,' HELPPR Abort' DB 0 mvi a,cr ; new line call lout mvi a,lf call lout CALL GETUD ; RETURN HOME JMP T$RETURN ; ; **** BANNER -- PRINT BANNER FOR PROGRAM (PROGRAM NAME ET AL) ; BANNER: CALL EPRINT db 'HELPPR Version ' db (vers/10)+'0','.',(vers mod 10)+'0' DB 0 RET ; ; **** HELP -- PRINT PROGRAM'S HELP MESSAGE ; HELP: CALL EPRINT db cr,lf,'Syntax:' db cr,lf,' HELPPR afn1,afn2,... o...' db cr,lf,'Options:' db cr,lf,' H@head@ -- Use "head" as header on every page' db cr,lf,' I -- Inspect Files for Printing' db cr,lf,' L -- Number Each Line' db cr,lf,' Onn -- Offset Each Line by nn Spaces' db cr,lf,' Snn -- Skip to Page nn and Start Printing' db cr,lf,' T -- Toggle Time Display' DB 0 RET ; ; **** PROGRAM INIT ROUTINE ; THIS ROUTINE IS USED BY THE PROGRAM TO PERFORM ANY NECESSARY ; INITIALIZATIONS ; INIT: lxi h,dlnumfl ;copy defaults into buffers lxi d,lnumfl mvi b,3 ;3 bytes call moveb xra a ;A=0 sta skipfl ;set no skip sta offset ;set no offset push h lhld hbuf ;pt to heading buffer mov m,a ;store zero to set no heading pop h ; if timeok call time ;get time string lxi d,timebf ;store in buffer initt: mov a,m ;get byte stax d inx h ;pt to next inx d ora a ;done? jnz initt endif ; RET ; ; **** FUNCTION COMPLETE -- CLEANUP AND EXIT ; FILL THIS IN WITH CLEANUP CODE FOR EXIT ; DINIT: RET ; ; **** OPTION TABLE USED TO PROCESS COMMAND LINE ; EACH OPTION IS A CAPITAL LETTER OR SPECIAL CHAR FOLLOWED BY ; AN ADDRESS; THE TABLE IS TERMINATED BY A BINARY ZERO ; OPTAB: DB 'I' ; FILE INSPECTION OPTION DW OPTINSP ; REMOVE THESE TWO LINES AND THE FOLLOWING ROUTINE ; IF YOU DO NOT WANT FILE INSPECTION OPTION IN ; COMMAND LINE db 'H' ;heading dw opthead db 'L' ;line numbers dw optln db 'O' ;offset dw optoffs db 'S' ;skip dw optskip ; if timeok db 'T' ;time display dw opttime endif ; DB 0 ; END OF TABLE ; ; **** OPTION ROUTINES ; EACH ROUTINE IS PROVIDED THE OPTION CHARACTER IN THE A REGISTER ; AND A POINTER TO THE NEXT CHARACTER IN THE COMMAND LINE IN THE ; HL REGISTER PAIR; ONLY HL NEED TO BE PRESERVED (WITH OPTIONAL ; ADVANCEMENT TO THE NEXT OPTION) ON EXIT ; OPTINSP: MVI A,0FFH ; TURN ON FILE INSPECTION OPTION STA V$INSPECT ; THIS IS PROVIDED AS A SAMPLE ROUTINE ; AND FOR THE INDICATED FUNCTION RET ; ; Set Page Offset ; optoffs: call eval10 ;get number mov a,e ;get low-order byte sta offset ;set offset ret ; ; Option: H (Set Heading) ; opthead: xchg lhld hbuf ;pt to heading buffer xchg mov a,m ;get delim ora a ;none? rz mov b,a ;delim in B inx h ;pt to next char opthd1: mov a,m ;get next char ora a ;done? jz opthd3 cmp b ;done? jz opthd2 stax d ;save char inx h ;pt to next inx d jmp opthd1 opthd2: inx h ;skip over delim opthd3: xra a ;store ending 0 stax d ret ; ; Option: L (Set Line Numbering) ; optln: lda lnumfl ;flip flag cma sta lnumfl ret ; ; Option: S (Skip Lines) ; optskip: mvi a,0ffh ;set flag sta skipfl call eval10 ;get number xchg shld skipnum ;set page number to skip to xchg ;HL pts to next char mov a,d ;see if page number was zero ora e rnz xra a ;if zero, turn off skip flag sta skipfl ret ; if timeok ; ; Set Time Flag ; opttime: lda timepfl ;flip flag cma sta timepfl ret ; endif ; ; **** FUNCTION -- MAIN FUNCTION OF TEMPLATE ; ON ENTRY, HL PTS TO NAME OF FILE (16 BYTES) AND USER IS LOGGED INTO ; DIRECTORY CONTAINING INDICATED FILE ; FUNCTION: ; ; HELP FILE PRINT Routine -- Print the Help File Whose Name is Pointed to by ; HL; we are already logged into the correct directory ; call prinit ;init print buffers call fload ;load buffer initially call prhead ;print heading line lhld V$SCRATCH ;pt to first char in file shld nxtln ;set pointer to next line mvi a,0ffh ;first line sta firstf call prline ;print first line (special case) xra a ;not first line now sta firstf fprloop: call prline ;print line of file jnz fprloop ;done if EOF call page ;advance to top of next page ret ; ; Init Print Buffers and Print File Name ; prinit: lxi d,tfcb ;set up FCB mvi b,12 ;12 bytes call moveb lxi h,0 ;HL=0 shld lnum ;set line number inx h ;HL=1 shld pnum ;set page number lda ltpp ;set line count sta lcount call eprint db cr,lf,' Printing Help File ',0 lxi h,tfcb ;pt to FCB call e$prfn ;print file name ret ; ; FILE LOAD (FLOAD) Routine -- Initial Load of memory buffer ; fload: lxi d,tfcb ;pt to file fcb call initfcb ;init file's fcb call f$open ;open file for input jz fload1 ;open was OK call eprint db cr,lf,' File ',0 xchg ;HL pts to FCB call e$prfn ;print file name call eprint db ' NOT Found',0 pop d ;clear return address ret ;abort printout of this file ; ; This is an entry point for further memory loads of the file ; fload1: lda V$BCNT ;get number of blocks to load mov c,a ;... in C lhld V$SCRATCH ;get address of first block to load into shld nxtblk ;set pointer to next block to load fload2: call rdblk ;read a block (128 bytes) jnz eof ;eof encountered? call rdblk ;read another block (128 bytes) jnz eof ;eof encountered? dcr c ;count down jnz fload2 lhld nxtblk ;pt to next byte to load mvi m,eold ;mark end of load ret eof: lxi d,tfcb ;close file call f$close lhld nxtblk ;ensure ^Z mvi m,ctrlz ret rdblk: lxi d,tfcb ;pt to FCB call f$read ;read next block ora a ;error? rnz lhld nxtblk ;get ptr to next block xchg ; as dest lxi h,tbuff ;ptr to DMA address mvi b,128 ;copy 128 bytes rdblk1: mov a,m ;get byte ani 7fh ;mask out msb stax d ;put byte inx h ;pt to next inx d dcr b ;count down jnz rdblk1 xchg ;new nxtblock shld nxtblk ret ; ; Line Print Routine ; Print Next Line with Optional Disk Load ; Input Parameter is NXTLN, which is the address of the first char ; on the next line ; Output Parameter is Zero Flag, with Z meaning done with print, NZ ; meaning more yet to print ; prline: lhld lnum ;increment line number inx h shld lnum prl0: lhld nxtln ;pt to first char of next line lda firstf ;first char? ora a ;0=no jnz prl01 mov a,m ;get first char of line cpi ':' ;new information section? cz page ;page eject with heading prl01: call proffs ;print offset mvi c,0 ;init char count mov a,m ;get first char of line cpi ctrlz ;EOF? cnz prlnum ;print line number (optional) prl1: mov a,m ;get char cpi eold ;end of load? jz prload cpi ctrlz ;eof? jz prexit inx h ;pt to next char cpi ctrli ;tab? jz prtab cpi cr ;? jz prldn cpi ff ;form feed? jz prldn cpi lf ;end of line? jz prl1 cpi ctrlh ;back space? jz prbs cpi ctrlg ;ring bell? jz prbell cpi del ;delete char? jz prl1 ;skip it cpi ' ' ;other control char? jc prl1 ;skip if other control char call prout ;print char inr c ;increment char count call eoltest ;check to see if at end of line and newline if so jmp prl1 ; ; End of Load Reached -- Load More of File from Disk ; prload: push b ;save char count call fload1 ;use load routine pop b ;get char count lhld V$SCRATCH ;next byte is here jmp prl1 ;continue processing ; ; Tabulate ; prtab: mvi a,' ' ;space call prout inr c ;new char call eoltest ;process EOL mov a,c ;done? ani 7 jnz prtab ;continue tabulation jmp prl1 ;continue processing ; ; Exit with Zero Flag Set if Done ; prexit: xra a ;set zero flag ret ; ; Carriage Return -- End of Routine ; prldn: mov a,m ;skip to non-LF cpi lf jnz prldn1 inx h ;skip to first char of next line prldn1: mvi a,cr ;output call prout mvi a,lf ;output call prout ;echo LF to printer shld nxtln ;set ptr to first char of next line mvi a,0ffh ;set not done ora a ;set flags ret ; ; Backspace on Printer ; prbs: mov a,c ;check for beginning of line ora a jz prl1 ;continue if at BOL mvi a,ctrlh ;backspace call prout dcr c ;back up char position jmp prl1 ;continue ; ; Ring Bell on Printer ; prbell: call prout ;ring the bell jmp prl1 ;continue without advancing char position ; ; Test for End of Line and Process if so ; eoltest: lda offset ;get offset mov b,a ;... in B lda lwidth ;get line width sub b ;subtract offset sui 4 ;4 chars less for continuation mark mov b,a ;result in B lda lnumfl ;line numbering (lines are 7 chars shorter if so) ora a ;0=no jz eolt1 mov a,b ;reduce by 7 for line numbers sui 7 mov b,a eolt1: mov a,b ;get line width cmp c ;there? rnz ;continue if not mov a,m ;get next char cpi cr ;new line next? rz ;continue if so cpi ctrlh ;backspace next? rz ;continue if so mvi b,3 ;look ahead 3 chars push h eolt2: inx h ;pt to next mov a,m ;get char cpi cr ;EOL? jz eolt3 dcr b ;count down jnz eolt2 jmp eolt4 eolt3: pop h ;restore ptr ret eolt4: pop h ;restore ptr mvi a,' ' ;print continuation chars call prout mvi a,'<' call prout mvi a,'<' call prout mvi a,cr ;new line call prout mvi a,lf call prout mvi c,0 ;reset char position lda skipfl ;skipping? ora a ;0=no rnz call proffs ;print offset lda lnumfl ;printing line numbers? ora a ;0=no rz call lprint db ' : ',0 ret ; ; Output a character to the printer ; A = Character ; prout: mov b,a ;char in B call condin ;check for abort jz prout1 cpi ctrlc ;abort? jz abort cpi ctrlx ;abort this one file? jz cxabort prout1: lda skipfl ;skipping? ora a ;set flags (Z=no skip=print char) mov a,b ;restore char cz lout ;send character to printer cpi lf ;special tests if it is a line feed rnz ;done if non-LF char lda lcount ;decrement line counter dcr a sta lcount rnz ; ; Paging Required ; Skip to top of next page; reset LCOUNT (Lines Left on Page Count); ; print header ; prout0: lda ltpp ;get number of text lines per page sta lcount ;set as new line count push h ;save ptr lhld pnum ;increment page number inx h shld pnum lda lspp ;get number of lines to skip per page call lineskp ;skip lines pop h ;restore ptr mov a,m ;check next character cpi ctrlz ;EOF? cnz prhead ;print 2-line heading if NOT EOF ret ; ; Abort current file with final page eject ; cxabort: lda lcount ;get count of remaining lines call lineskp ;skip lines lda lff ;form feed? ora a ;NZ=yes jnz e$fctlnxt ;continue with next file since already FF lda lspp ;number of lines to skip per page call lineskp ;skip lines jmp e$fctlnxt ;continue with next file ; ; Skip out rest of page ; Form Feed Function ; page: lda lff ;form feed? ora a ;NZ=yes jnz prout0 ;PROUT0 will FF lda lcount ;get count of remaining lines call lineskp ;skip lines jmp prout0 ;process top of new page ; ; Skip out lines on page ; A = number of lines to skip ; lineskp: mov b,a ;line count in B ora a ;any? rz lda skipfl ;skipping? ora a rnz lda lff ;form feed? ora a ;NZ=yes jnz lines2 lines1: mvi a,cr ;output new line to printer call lout mvi a,lf call lout dcr b ;count down jnz lines1 ret lines2: mvi a,cr ;output new line call lout mvi a,ff ;output form feed jmp lout ; ; Print Line Number (optional) ; prlnum: lda skipfl ;skipping? ora a ;0=no rnz lda lnumfl ;get flag ora a ;0=don't number lines rz push h ;save ptr lhld lnum ;get line number call lhldc ;print line number call lprint ;print separator db ': ',0 pop h ;restore ptr ret ; ; Print 2-line heading and control skipping ; prhead: push h ;save ptr lda skipfl ;currently skipping? ora a ;0=no cnz skiptst ;test for shut off call proffs ;print offset call prpnum ;print page heading and number call e$prfname ;print file name ; if timeok ;time available? lda timepfl ;print time? ora a ;0=no cnz prtime ;print time endif ; push h ;get first char of heading lhld hbuf mov a,m pop h ora a ;0=no cnz prhdg ;print heading pop h ;restore ptr lda skipfl ;skipping? ora a rnz call lcrlf ;new line jmp lcrlf ; ; Test for completion of skipping ; skiptst: lhld pnum ;get page number xchg ;... in DE lhld skipnum ;get page to skip to mov a,h ;compare them cmp d rnz mov a,l cmp e rnz xra a ;A=0 to stop skipping sta skipfl ;set flag ret ; ; Print Page Number ; prpnum: lda skipfl ;skipping? ora a rnz call lprint ;print header db 'Page ',0 lhld pnum ;print current page number call lhldc ;print as decimal ret ; ; Print File Name ; e$prfname: lda skipfl ;skipping? ora a rnz call lprint ;print separator db ' -- Help File: ',0 lxi h,tfcb+1 ;pt to first char mvi b,8 ;8 chars call lfn1 mvi a,'.' call lout mvi b,3 ;3 chars call lfn1 ret lfn1: mov a,m ;get char ani 7fh ;mask call lout ;send to printer inx h ;pt to next dcr b ;count down jnz lfn1 ret ; ; Print Separator ; prdash: call lprint db ' -- ',0 ret ; if timeok ; ; Print Time ; prtime: lda skipfl ;skipping? ora a rnz call prdash ;print separator lxi h,timebf ;pt to time stamp call lpstr ;print ret ; endif ; ; Print Header ; prhdg: lda skipfl ;skipping? ora a rnz call prdash ;print separator lhld hbuf ;pt to heading call lpstr ;print ret RET ; ; Print Line Offset ; proffs: lda skipfl ;skipping? ora a rnz push b ;save BC lda offset ;get offset ora a ;any? jz proff2 mov c,a ;offset in C proff1: mvi a,' ' ;space over call prout dcr c ;count down jnz proff1 proff2: pop b ret ; ; **** HELPPR BUFFERS ; offset: ds 1 ;line offset hltemp: ds 2 ;temporary save area for HL dirbuf: ds 2 ;ptr to directory firstf: ds 1 ;first line in file flag tfcb: ds 36 ;FCB for current file nxtblk: ds 2 ;ptr to next block to load nxtln: ds 2 ;ptr to next line to read lcount: ds 1 ;count of text lines left on page hlptyp: db 'HLP' ;file type of HLP file ;*********************************************** ;* End of Application-Specific Section ;*********************************************** ; ; BUFFERS ; V$DISK: DS 1 ; HOME DISK NUMBER V$USER: DS 1 ; HOME USER NUMBER V$CDISK: DS 1 ; CURRENT DISK NUMBER V$CUSER: DS 1 ; CURRENT USER NUMBER V$CMDLNE: DS 2 ; PTR TO COMMAND LINE STRING V$NEXTCH: DS 2 ; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE V$FILECNT: DS 2 ; COUNT OF NUMBER OF FILES RENAMED V$SCRATCH: DS 2 ; ADDRESS OF FIRST BYTE OF SCRATCH AREA V$BCNT: DS 1 ; NUMBER OF PAGES IN SCRATCH AREA V$INSPECT: DS 1 ; INSPECT FLAG V$NTFCB: DS 36 ; FCB FOR NEW FILE ; ; Stack ; V$STACK: DS 2 ; OLD STACK PTR END