; PROGRAM: PRINT III (PRINT) ; VERSION: 2.3 ; DATE: 8 Mar 91 ; Version Author: Bruce Morgen ; AUTHOR: RICHARD CONN ; PREVIOUS VERSIONS: 2.2 (28 Dec 88) ; PREVIOUS VERSION: 2.1 (May, 1985) (see PRINT.HST) ; PREVIOUS VERSIONS: 2.0 (18 May 84), 1.3 (17 May 83) ; PREVIOUS VERSIONS: 1.2 (26 Apr 83), 1.1 (26 Apr 83), 1.0 (22 Apr 83) vers equ 23 .xlist include print.hdr ; MACLIB PRINT ;some assemblers require this form. The ; Name of PRINT.HDR must then be changed ; To 'PRINT.LIB' .list ; Start of Program print: jp start db 'Z3ENV' ; This is a ZCPR3 Utility db 1 ; External Environment Descriptor z3eadr: dw 0 ; Gets filled in by Z33/4 or Z3INST dw print ; Reserved for type 3/4 env use ;====================================================== ; Configuration Parameters for PRINT program defaults db 'PRINT' ; PROGRAM ID STRING for configuration overlay ds 4,0 ; Allow for up to 8 char plus null terminator ;the following 12 bytes are copied into the block at lnumfl dlnumfl: db 0 ; LINE NUMBER FLAG (DEFAULT TO NO) dpnumfl: db 0ffh ; PAGE NUMBER FLAG (DEFAULT TO YES) dexact: db 0 ; EXACT PRINT FLAG (DEFAULT TO NO) dfnpfl: db 0ffh ; FILE NAME PRINT FLAG (DEFAULT TO YES) dtimepfl: db 0ffh ; TIME PRINT FLAG (DEFAULT TO YES) dmultfl: db 0ffh ; MULTIPLE RUN FLAG (DEFAULT TO YES) dinspect: db 0 ; INSPECT FILES (DEFAULT TO NO) doffset: db 0 ; INITIAL COLUMN OFFSET (DEFAULT TO NO COLUMNS) ;default page format parameters, used only if ;data from Z3ENV is not available or not used. ;These values are defined exactly the same as ;the values in the ZCPR3 Environment Descriptor ;for printers, and are used identically. Note ;that PRINT reserves 2 lines for a header, and ;that there should be lines reserved before and ;after the text lines. Thus, the lines of text ;per page should be at least 5 less than Total ;lines per page. (The same is true of the values ;in the Z3 environment!) dlwid: db 80 ; Width of Printer page db 66 ; Total lines per page db 58 ; Lines of text per page db -1 ; Form feed flag (0=no) ;NOTE: dLTPP + dLSPP + 2 (HEADER SIZE) = TOTAL LINES PER PAGE ON PRINTER ;====================================================== ; Start of Program start: ; Initialize ZCPR3 Environment ld hl,(z3eadr) ; Pt to ZCPR3 environment call z3init ; Initialize the ZCPR3 Env and the VLIB Env ld a,h or l ld (z3flag),a ; If 0, not Z3. if NZ, then Z3 is present ld (stack),sp ; Save callers stack call greet ; Send banner, service HELP if required call alloc ; Allocate buffers & memory use ; Returns hl->top of allocated stack ;the stack uses the upper portion of the time buffer. up to 256 bytes. ld sp,hl ; SET TOP OF STACK call init ; Prog init routine call getopt ; Set options, if present ;======================================================== ; BEGIN MOVING THROUGH FILE NAMES, SEPARATED BY COMMAS dspec: ld hl,(cmdlne) ; PT TO FIRST BYTE call sblank ; SKIP TO NON-BLANK ; MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS ; HL PTS TO FIRST BYTE OF NEXT FILE SPEC dspec1: ld (nextch),hl ; SAVE PTR TO NEXT CHAR ld hl,(dirbuf) ; RESET STACK ld sp,hl call getud ; RESET USER IF NECESSARY ld de,fcb ; PT TO FCB IN DE, PT TO FIRST CHAR OF FILE NAME IN HL ld hl,(nextch) ; GET PTR TO NEXT CHAR call z33chk ; Is CCP parser there? jr nz,dspec2 ; No, uses Z3LIB's call z33fname ; Yes, use it jr dspec3 dspec2: xor a ; SELECT DIR BEFORE DU call zfname ; EXTRACT FILE NAME INTO FCB, GET DISK AND USER dspec3: ld (nextch),hl ; SAVE PTR TO DELIMITER WHICH ENDED SCAN ; LOAD DIRECTORY AND PERFORM FUNCTION fct: call z3log ; LOG IN call initfcb ; INIT THE FCB ld hl,(dirbuf) ; PT TO DIR BUFFER AREA ld a,11000000b ; SELECT SYS AND NON-SYS FILES ld c,00000001b ; Normal sort, check DS & P2DOS call ddirqs ; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE ; DETERMINE BEGINNING OF SCRATCH AREA (SCRATCH) AND SIZE IN PAGES (BCNT) push hl ; SAVE PTR AND COUNT push bc ld de,esize ; SET PTR TO NEXT FREE BLOCK fctfre: ld a,b ; DONE? or c jr z,fctfr1 add hl,de ; PT TO NEXT dec bc ; COUNT DOWN jr fctfre fctfr1: inc h ; NEXT PAGE ld l,0 ld (scratch),hl ; SET PTR TO SCRATCH AREA ex de,hl ; PTR IN DE ld hl,(bdose+1) ; COMPUTE BLOCK BUFFER SIZE ld a,h ; ADJUST FOR ZCPR3 sub 10 sub d ; A=SIZE IN BLOCKS ld (bcnt),a ; SET BLOCK COUNT pop bc ; RESTORE AND SAVE REGS pop hl ; ALLOW USER TO INSPECT FILES push hl push bc call icheck ; CHECK FOR INSPECT OPTION AND INSPECT IF SET pop bc ; RESTORE COUNT AND PTR pop hl ;======================================================== ; PERFORM FUNCTION; HL PTS TO FILE AND BC CONTAINS NUMBER OF FILES fctl: ld a,b ; CHECK FOR COMPLETION (COUNT = 0) or c jr z,fctl1 dec bc ; COUNT DOWN ld (nfptr),hl ld (nfcnt),bc ld de,esize-5 add hl,de call ascidt call nc,time ; Get hl->ASCII time string ld de,(timebf) ; Destination for time string initt: ld a,(hl) ; Get byte ld (de),a ; Put byte inc hl ; Pt to next inc de or a ; Done? jr nz,initt ld hl,(nfptr) ; PT TO FILE call function ; PERFORM FUNCTION fctlnxt: ld sp,(dirbuf) ; RESET STACK ld bc,(nfcnt) ; RESET FILE COUNT ld hl,(nfptr) ; RESET FILE PTR ld de,esize ; PT TO NEXT ENTRY add hl,de jr fctl ;======================================================== ; CHECK FOR NEXT FILE SPEC fctl1: call getud ; RETURN TO HOME USER/DISK ld hl,(nextch) ; GET PTR ld a,(hl) ; GET DELIM cp ',' ; ANOTHER FILE? jp nz,dreturn inc hl ; PT TO CHAR AFTER COMMA jp 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 icheck: ld a,b ; Any files? or c ret z push hl ; Save ptrs push bc ld de,esize ; Size of entry ichk1: ld (hl),0 ; Clear MSBytes add hl,de ; Pt to next dec bc ; Count down ld a,b ; Done? or c jr nz,ichk1 pop bc ; Restore ptrs pop hl ld a,(inspect) ; Inspect? or a ; 0=no ret z call eprint db cr,lf,'--- PRINT File Inspect Mode ---' db cr,lf,' Option Function' db cr,lf,' Y (def) Select File' db cr,lf,' N Don''t Select File' db cr,lf,' Q Select Rest of Files' db cr,lf,' S Skip Rest of Files' db cr,lf,0 ichk2: call eprint db cr,lf,'Select ',0 call prfn ; Print file name call eprint db ' -- (Y/N/Q/S)? ',0 call cin ; Get response call caps ; Capitalize call cout ; Echo cp 'Q' ; Select rest? jr z,ichkyr cp 'S' ; Skip rest jr z,ichknr cp 'N' ; No to this one? jr nz,ichk3 ld (hl),0ffh ; Set NO flag in file FCB ichk3: add hl,de ; Pt to next one dec bc ; Count down ld a,b ; Done? or c jr nz,ichk2 ret ;======================================================== ; Check Rest of Files as Selected ichkyr: call eprint db cr,lf,' Rest of Files Selected',0 ret ;======================================================== ; Check Rest of Files as NOT Selected ichknr: ld (hl),0ffh ; Set NO flag add hl,de ; Pt to next dec bc ; Count down ld a,b ; Done? or c jr nz,ichknr call eprint db cr,lf,' Rest of Files NOT Selected',0 ret ;======================================================== ; **** 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: ; FILE PRINT Routine -- Print the File Whose Name is Pointed to by ; HL; we are already logged into the correct directory ld a,(hl) ; File selected? or a ; 0=yes ret nz ld a,(multfl) ; Multiple runs? or a ; 0=no jr nz,fprint ; Go right into function call eprint db cr,lf,'File: ',0 call prfn ; Print file name call eprint db ' -- Set Top of Form ',0 call cin ; Get response cp ctrlc ; Abort? jp z,abort cp ctrlx ret z fprint: call prinit ; Init print buffers call fload ; Load buffer initially call prhed ; Print heading line ld hl,(scratch) ; Pt to first char in file ld (nxtln),hl ; Set pointer to next line fprloop: call prline ; Print line of file jr nz,fprloop ; Done if EOF ld a,(ltpp) ; Check for new page ld b,a ld a,(lcount) ; LTPP and Line Count are Equal if New Page cp b ; Equal? jr nz,fprlp1 call lcrlf ; Advance 2 lines call lcrlf fprlp1: jp page ; Advance to top of next page (call!ret) ;======================================================== ; Init Print Buffers and Print File Name prinit: ld de,tfcb ; Set up FCB ld b,12 ; 12 bytes call moveb ld hl,0 ; HL=0 ld (lnum),hl ; Set line number inc hl ; HL=1 ld (pnum),hl ; Set page number ld a,(ltpp) ; Set line count ld (lcount),a call eprint db cr,lf,'Printing File ',0 ld hl,tfcb ; Pt to FCB jp prfn ; Print file name (call!ret) ;======================================================== ; FILE LOAD (FLOAD) Routine -- Initial Load of memory buffer fload: ex de,hl ld hl,tbuff call setdma ex de,hl ld de,tfcb ; Pt to file fcb call initfcb ; Init file's fcb call f$open ; Open file for input jr z,fload1 ; Open was OK call eprint db cr,lf,'File ',0 ex de,hl ; HL pts to FCB call prfn ; Print file name call eprint db ' NOT Found',0 pop de ; Clear return address ret ; Abort printout of this file ;======================================================== ; This is an entry point for further memory loads of the file fload1: ld a,(bcnt) ; Get number of blocks to load ld c,a ; In C ld hl,(scratch) ; Get address of first block to load into ld (nxtblk),hl ; Set pointer to next block to load fload2: call rdblk ; Read a block (128 bytes) jr nz,eof ; Eof encountered? call rdblk ; Read another block (128 bytes) jr nz,eof ; Eof encountered? dec c ; Count down jr nz,fload2 ld hl,(nxtblk) ; Pt to next byte to load ld (hl),eold ; Mark end of load ret eof: ld de,tfcb ; Close file call f$close ld hl,(nxtblk) ; Ensure ^Z ld (hl),ctrlz ret rdblk: ld de,tfcb ; Pt to FCB call f$read ; Read next block or a ; Error? ret nz ld hl,(nxtblk) ; Get ptr to next block ex de,hl ; As dest ld hl,tbuff ; Ptr to DMA address ld b,128 ; Copy 128 bytes rdblk1: ld a,(hl) ; Get byte and 7fh ; Mask out msb ld (de),a ; Put byte inc hl ; Pt to next inc de djnz rdblk1 ; Count down ex de,hl ; New nxtblock ld (nxtblk),hl xor a ; Caller need Z flag 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: call proffs ; Print offset ld hl,(lnum) ; Increment line number inc hl ld (lnum),hl ld hl,(nxtln) ; Pt to first char of next line ld c,0 ; Init char count ld a,(hl) ; Get first char of line cp ctrlz ; EOF? call nz,prlnum ; Print line number (optional) prl1: ld a,(hl) ; Get char cp eold ; End of load? jr z,prload cp ctrlz ; Eof? jr z,prexit inc hl ; Pt to next char cp ctrli ; Tab? jr z,prtab cp cr ; ? jr z,prcr cp ff ; Form feed? jr z,prff cp lf ; End of line? jr z,prldn cp ctrlh ; Back space? jr z,prbs cp ctrlg ; Ring bell? jr z,prbell cp del ; Delete char? jr z,prl1 ; Skip it cp ' ' ; Other control char? jr c,prl1 ; Skip if other control char call prout ; Print char inc c ; Increment char count call eoltest ; Check to see if at end of line and newline if so jr prl1 ;======================================================== ; End of Load Reached -- Load More of File from Disk prload: push bc ; Save char count call fload1 ; Use load routine pop bc ; Get char count ld hl,(scratch) ; Next byte is here jr prl1 ; Continue processing ;======================================================== ; Tabulate prtab: ld a,' ' ; Space call prout inc c ; New char call eoltest ; Process EOL ld a,c ; Done? and 7 jr nz,prtab ; Continue tabulation jr prl1 ; Continue processing ;======================================================== ; Exit with Zero Flag Set if Done prexit: xor a ; Set zero flag ret ;======================================================== ; Carriage Return -- Reset Character Count and Continue prcr: call prout ; Send CR to printer ld c,0 ; Reset char count jr prl1 ; Continue processing ;======================================================== ; Form Feed -- Advance to Top of Next Page prff: call page ; Page eject with heading ld c,0 ; Reset char count jr prl1 ; Continue processing ;======================================================== ; Line Feed -- End of Routine prldn: call prout ; Echo LF to printer ld (nxtln),hl ; Set ptr to first char of next line ld a,0ffh ; Set not done or a ; Set flags ret ;======================================================== ; Backspace on Printer prbs: ld a,c ; Check for beginning of line or a jr z,prl1 ; Continue if at BOL ld a,ctrlh ; Backspace call prout dec c ; Back up char position jr prl1 ; Continue ;======================================================== ; Ring Bell on Printer prbell: call prout ; Ring the bell jr prl1 ; Continue without advancing char position ;======================================================== ; Test for End of Line and Process if so eoltest: ld a,(offset) ; Get offset ld b,a ; In B ld a,(lwidth) ; Get line width sub b ; Compute remaining width sub 4 ; 4 chars less for continuation mark ld b,a ; Result in B ld a,(lnumfl) ; Line numbering (lines are 7 chars shorter if so) or a ; 0=no jr z,eolt1 ld a,b ; Reduce by 7 for line numbers sub 7 ld b,a eolt1: ld a,b ; Get line width cp c ; There? ret nz ; Continue if not ld a,(hl) ; Get next char cp cr ; New line next? ret z ; Continue if so ld b,3 ; See if CR is one of next 3 chars push hl eolt2: inc hl ; Pt to next ld a,(hl) ; Get char cp cr jr z,eolt2a ; Yes, it is djnz eolt2 ; Count down pop hl ; Restore HL jr eolt3 eolt2a: pop hl ; Restore HL ret ; Allow to continue eolt3: cp ctrlh ; Backspace next? ret z ; Continue if so ld a,' ' ; Print continuation chars call prout ld a,'<' call prout ld a,'<' call prout ld a,cr ; New line call prout ld a,lf call prout ld c,0 ; Reset char position ld a,(skipfl) ; Skipping? or a ; 0=no ret nz call proffs ; Print offset if any ld a,(lnumfl) ; Printing line numbers? or a ; 0=no ret z call lprint ; Print blank for line number db ' : ',0 ret ;======================================================== ; Output a character to the printer ; A = Character prout: ld b,a ; Char in B call condin ; Check for abort jr z,prout1 cp ctrlc ; Abort? jp z,abort cp ctrlx ; Abort this one file? jr z,cxabort prout1: ld a,(skipfl) ; Skipping? or a ; Set flags (Z=no skip=print char) ld a,b ; Restore char call z,lout ; Send character to printer cp lf ; Special tests if it is a line feed ret nz ; Done if non-LF char ld a,(lcount) ; Decrement line counter dec a ld (lcount),a ret nz ;======================================================== ; Paging Required ; Skip to top of next page; reset LCOUNT (Lines Left on Page Count); ; print header prout0: ld a,(ltpp) ; Get number of text lines per page ld (lcount),a ; Set as new line count push hl ; Save ptr ld hl,(pnum) ; Increment page number inc hl ld (pnum),hl ld a,(lspp) ; Get number of lines to skip per page call lineskp ; Skip lines pop hl ; Restore ptr ld a,(hl) ; Check next character cp ctrlz ; EOF? jr nz,prhed ; Print 2-line heading if NOT EOF ret ;======================================================== ; Abort current file with final page eject cxabort: ld a,(lcount) ; Get count of remaining lines call lineskp ; Skip lines ld a,(lff) ; Form feed done? or a ; 0=no ld a,(lspp) ; Number of lines to skip per page call z,lineskp ; Skip lines if no previous FF jp fctlnxt ; Continue with next file ;======================================================== ; Skip out rest of page ; Form Feed Function page: ld a,(lff) ; Form feed in use or a ; 0=no jr nz,prout0 ; Process top of new page if form feed in use ld a,(lcount) ; Get count of remaining lines call lineskp ; Skip lines jr prout0 ; Process top of new page ; Skip out lines on page ; A = number of lines to skip lineskp: ld b,a ; Line count in B or a ; Any? ret z ld a,(skipfl) ; Skipping? or a ret nz ld a,(lff) ; Form feed available? or a ; 0=no jr nz,lines2 lines1: call lcrlf ; New line djnz lines1 ; Count down ret lines2: call lcrlf ; New line ld a,ff ; Output form feed to printer jp lout ;======================================================== ; Print Line Number (optional) prlnum: ld a,(skipfl) ; Skipping? or a ; 0=no ret nz ld a,(lnumfl) ; Get flag or a ; 0=don't number lines ret z push hl ; Save ptr ld hl,(lnum) ; Get line number call lhldc ; Print line number call lprint ; Print separator db ': ',0 pop hl ; Restore ptr ret ;======================================================== ; Print 2-line heading and control skipping prhed: push hl ; Save ptr ld a,(skipfl) ; Currently skipping? or a ; 0=no call nz,skiptst ; Test for shut off ld a,(exact) ; Exact says no heading or a ; 0FFH=yes jr nz,prhed1 call proffs ; Print offset ld a,(pnumfl) ; Number pages? or a ; 0=no call nz,prpnum ; Print page heading and number ld a,(fnpfl) ; Print file name? or a ; 0=no call nz,prfname ; Print file name ld a,(timepfl) ; Print time? or a ; 0=no call nz,prtime ; Print time push hl ld hl,(hbuf) ; Pt to heading buffer ld a,(hl) ; Print heading? pop hl or a ; 0=no call nz,prhdg ; Print heading prhed1: pop hl ; Restore ptr prhed2: ld a,(skipfl) ; Skipping? or a ret nz call lcrlf ; New line jp lcrlf ;======================================================== ; Test for completion of skipping skiptst: ld hl,(pnum) ; Get page number ex de,hl ; In DE ld hl,(skipnum) ; Get page to skip to ld a,h ; Compare them cp d ret nz ld a,l cp e ret nz xor a ; A=0 to stop skipping ld (skipfl),a ; Set flag ret ;======================================================== ; Print Line Offset proffs: ld a,(skipfl) ; Skipping? or a ret nz push bc ; Save BC ld a,(offset) ; Get offset or a ; Any? jr z,proff2 ld c,a ; Offset in B proff1: ld a,' ' ; Space over call prout dec c ; Count down jr nz,proff1 proff2: pop bc ret ;======================================================== ; Print Page Number prpnum: ld a,(skipfl) ; Skipping? or a ret nz call lprint ; Print header db 'Page ',0 ld hl,(pnum) ; Print current page number call lhldc ; Print as decimal ret ;======================================================== ; Print File Name prfname: ld a,(skipfl) ; Skipping? or a ret nz call prdash ; Print separator ld hl,tfcb+1 ; Pt to first char ld b,8 ; 8 chars call lfn1 ld a,'.' call lout ld b,3 ; 3 chars call lfn1 ret lfn1: ld a,(hl) ; Get char inc hl ; Pt to next and 7fh ; Mask cp spc call nz,lout ; Send to printer if not blank djnz lfn1 ; Count down ret ; Print Separator prdash: call lprint db ' -- ',0 ret ;======================================================== ; Print Time prtime: ld a,(skipfl) ; Skipping? or a ret nz call prdash ; Print separator ld hl,(timebf) ; Pt to time stamp jp lpstr ; Print (call!ret) ;======================================================== ; Print Header prhdg: ld a,(skipfl) ; Skipping? or a ret nz call prdash ; Print separator ld hl,(hbuf) ; Pt to heading jp lpstr ; Print (call!ret) ;======================================================== ;Allocate buffers. Exit with HL -> end of the Time Buffer, ;which is 100H bytes long. Since the time string only uses ;10 or 20 bytes (depending on implementation), most of this ;space is available for stack. Plenty, even for the sort. alloc: call codend ; Returns start of free memory in hl ld (cmdlne),hl ; Save ptr to command line ld de,100h ; Buffer size add hl,de ld (hbuf),hl ; Buffer for heading add hl,de ld (timebf),hl ; Buffer for time data add hl,de ld (dirbuf),hl ; Ptr to dir buffer ret ;======================================================== ; **** PROGRAM INIT ROUTINE ; Save current DU, and command tail ; Initialize parameters from the configuration ; data area. Initialize internal parameters before ; using possible command line options. init: call gt_osd ; Get Operating System descriptor ; Including pointers to RTC access ; ld (osdata),hl ; Save the pointer (not used...) call putud ; SAVE CURRENT USER/DISK AWAY ld hl,(cmdlne) ; PT TO COMMAND LINE SAVE AREA ld de,tbuff+1 ; SAVE COMMAND LINE ex de,hl ld b,80h ; SIZE OF BUFFER call moveb ld hl,dlnumfl ; Copy defaults into buffers ld de,lnumfl ld b,8 ; 8 bytes call moveb ; Do copy xor a ; A=0 ld (skipfl),a ; Set no skip ld hl,(hbuf) ; Pt to heading ld (hl),a ; Set no heading ld hl,dlwid ; ->printer parms used if no ENV call initpf ; Convert to PRINT parameters ld a,(z3flag) or a ; Z3 present? ret z ; Done if not call getprt ; Get printer data initpf: ld a,(hl) ; GET PRINTER WIDTH ld (lwidth),a inc hl inc hl ld a,(hl) ; GET NUMBER OF LINES OF TEXT ld (ltpp),a ld b,a ; IN B dec hl ld a,(hl) ; GET NUMBER OF LINES ON PAGE sub 2 sub b ; ADJUST FOR PAGING DATA ld (lspp),a ; NUMBER OF LINES TO SKIP PER PAGE inc hl inc hl ld a,(hl) ; GET FORM FEED FLAG ld (lff),a ret ;======================================================== ;Operating System and RTC data ;osdata: ds 2 ; Pointer to following data structure ; (not referenced) ;data structure for OS ;offset ;0 db 0 ;Compatible CP/M version #, binary ; ;for CP/M v2.2, this is 16h (22 decimal) ;1 db 0 ;D = DateStamper, else 0 ;2 db 0 ;Actual DOS version #, binary ;3 db 0 ;single character identifies DOS ;DOS identifying characters ; 0 = Unknown Dos 3 = CPM 3.0 ; C = CP/M M = MP/M O = ZOS ; R = ZRDOS S = ZSDOS D = ZDDOS ;RTC access parameters. ;4 db 0 ;value in C during dos call for DT ;5 dw 0 ;address of clock routine - fills DT buffer ; ;if this word=0000, then no RTC is defined ;7 dw dtbuf ;address of buffer for DT ;dtbuf is always valid, and may be changed once a call to gt_osd ;has returned the pointer to this data structure ;end of data structure for OS ;rtcbuf: ; ds 2 ; Pointer to BCD yymmddhhmmss ; (Commented out, not referenced anywhere) ;======================================================== greet: call eprint ; **** Banner of Program db 'PRINT III, Version ' db vers/10+'0','.',[vers mod 10]+'0',0 ; Check for Help Request ld a,(fcb+1) ; GET FIRST CHAR OF FILE NAME cp ' ' ; NO FILE SPEC? jr z,help cp '/' ; OPTION CAUGHT? ret nz ; **** Print Help Information help: call eprint db cr,lf,' PRINT file1,file2,...,filen o...' db cr,lf,'Options:' db cr,lf,' E Exact Print (expand tabs, form feed, no line' db cr,lf,' or page numbers, no heading)' db cr,lf,' F Toggle File Name Display' db cr,lf,' H@head@ Specify Page Heading (@ is any printing char)' db cr,lf,' I Inspect and Select Files First' db cr,lf,' L Toggle Numbering of Each Line' db cr,lf,' M Toggle Multiple Runs (MR=No TOF Msg)' db cr,lf,' N Toggle Numbering of Each Page' db cr,lf,' Onn Offset Printout by nn Characters from Left' db cr,lf,' Snnnn Skip to Specified Page before Printing' db cr,lf,' T Toggle Date/Time Display in header' db cr,lf,' (file stamp if available, system time if not)' db cr,lf,'Examples:' db cr,lf,' PRINT MYFILE.TXT,*.MAC LH''SAMPLE''' db cr,lf,' -- Number Lines, SAMPLE is Heading' db cr,lf,' PRINT MYFILE.* S25E' db cr,lf,' -- Skip to Page 25, Exact Print' db cr,lf,'At any time, ^C aborts PRINT and ^X skips to next ' db 'file' db 0 jp return ;======================================================== ; EXTRACT OPTION FLAGS IF PRESENT getopt: ld hl,(cmdlne) ; PT TO BUFFER ; SKIP TO FILE NAME STRING call sblank ; SKIP OVER BLANKS ; SKIP TO END OF FILE NAME STRING call snblank ; SKIP OVER NON-BLANKS ; SKIP TO OPTION CHAR call sblank ; CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO opt: cp '/' ; OPTION CHAR? jr nz,option inc hl ; SKIP SLASH ; PROCESS LIST OF OPTIONS option: ld a,(hl) ; GET BYTE or a ; DONE? jp z,dspec ; Normal exit from option processing inc hl ; PT TO NEXT CHAR cp ' ' ; SKIP OVER SPACES jr z,option ld c,a ; COMMAND IN C ld de,optab ; PT TO OPTION TABLE optl: ld a,(de) ; GET OPTION LETTER or a ; END OF TABLE? jp z,help ; HELP IF SO cp c ; MATCH? jr z,optm ; PROCESS IF SO inc de ; PT TO NEXT ENTRY inc de inc de jr optl ; PROCESS OPTION optm: push hl ; SAVE HL ON STACK ld hl,option ; GET RETURN ADDRESS ex (sp),hl ; ON STACK AND RESTORE HL inc de ; PT TO ADDRESS ld a,(de) ; GET ADDRESS LOW ld b,a ; IN B inc de ld a,(de) ; GET ADDRESS HIGH ld d,a ; IN D ld e,b ; LOW IN E push de ; PUT ADDRESS ON STACK ld a,c ; COMMAND IN A ret ; "CALL" OPTION ROUTINE ;======================================================== ; **** OPTION TABLE ; EACH OPTION IS A CAPITAL LETTER OR SPECIAL CHAR FOLLOWED BY ; AN ADDRESS; THE TABLE IS TERMINATED BY A BINARY ZERO optab: db 'E' dw optexact db 'F' dw optfn db 'H' dw opthd db 'I' dw optinsp db 'L' dw optln db 'M' dw optmult db 'N' dw optpn db 'O' dw optoffs db 'S' dw optskip db 'T' dw opttime db 0 ; End of table ; Option: E (Toggle exact mode) optexact: ld a,(exact) ; Get flag cpl ; Flip it ld (exact),a ; Put flag ret ; Option: F (Toggle file name display) optfn: ld a,(fnpfl) ; Get flag cpl ; Flip it ld (fnpfl),a ; Put flag ret ; Option: H (Set Heading) opthd: ex de,hl ld hl,(hbuf) ; Pt to heading buffer ex de,hl ld a,(hl) ; Get delim or a ; None? ret z ld b,a ; Delim in B inc hl ; Pt to next char opthd1: ld a,(hl) ; Get next char or a ; Done? jr z,opthd3 cp b ; Done by trailing delim? jr z,opthd2 ld (de),a ; Save char inc hl ; Pt to next inc de jr opthd1 opthd2: inc hl ; Skip over delim opthd3: xor a ; Store ending 0 ld (de),a ret ; Toggle Inspect Option optinsp: ld a,(inspect) ; Flip flag cpl ld (inspect),a ret ; Toggle Line Number Flag optln: ld a,(lnumfl) ; Flip flag cpl ld (lnumfl),a ret ; Toggle Multiple Run Flag optmult: ld a,(multfl) ; Flip flag cpl ld (multfl),a ret ; Toggle Page Numbering Flag optpn: ld a,(pnumfl) ; Flip flag cpl ld (pnumfl),a ret ; Set Page Offset ; optoffs: call eval10 ; Get number ld (offset),a ; Set offset ret ; Set Skip Flag and get number optskip: ld a,0ffh ; Set flag ld (skipfl),a call eval10 ; Get number ld (skipnum),de ; Set page number to skip to or d ; See if page number was zero ret nz ld (skipfl),a ; If zero, just turn off skip flag ret ; Toggle Time Flag opttime: ld a,(timepfl) ; Flip flag cpl ld (timepfl),a ret ;======================================================== ; **** EMERGENCY ABORT abort: call eprint db cr,lf,'** PRINT Abort **',cr,lf,0 call getud ; RETURN HOME AND FALL THRU TO DRETURN ; **** FUNCTION COMPLETE -- CLEANUP AND EXIT ; FILL THIS IN WITH CLEANUP CODE FOR EXIT dreturn: ;======================================================== return: ; MAIN EXIT TO OS ld sp,(stack) ; Get callers stack ret ; And return without W/Boot ;======================================================== ; UTILITIES ; SBLANK -- SKIP BLANKS PTED TO BY HL UNTIL NON-BLANK ENCOUNTERED; HL ; SNBLANK -- SKIP NON-BLANKS PTED TO BY HL UNTIL BLANK OR EOL; HL ; PRFN -- PRINT FILE NAME PTED TO BY HL; AFFECT NOTHING ; SKIP UNTIL NON-BLANK sblank: ld a,(hl) ; LOOK FOR BLANK inc hl ; PT TO NEXT cp ' ' ; BLANK? jr z,sblank dec hl ; BACK UP ret ; SKIP UNTIL BLANK OR EOL snblank: ld a,(hl) ; GET CHAR inc hl ; PT TO NEXT cp ' ' ; BLANK? jr z,snb1 or a ; EOL? jr nz,snblank snb1: dec hl ; BACK UP ret ; PRINT FILE NAME PTED TO BY HL ; OUTPUT TO CON: prfn: push hl ; SAVE REGS push bc call retud ; GET CURRENT USER/DISK ld a,b ; PRINT DISK add 'A' ; LETTER call cout ld a,c ; PRINT USER call padc call eprint db ': ',0 inc hl ; PT TO FILE NAME ld b,8 ; PRINT NAME call prnt ld a,'.' ; DECIMAL call cout ld b,3 ; PRINT TYPE call prnt pop bc ; GET REGS pop hl ret ; PRINT CHARS PTED TO BY HL FOR B BYTES ; OUTPUT TO CON: prnt: ld a,(hl) ; GET CHAR call cout inc hl ; PT TO NEXT djnz prnt ; COUNT DOWN ret ;====================================================== dseg ; BUFFERS cmdlne: ds 2 ; PTR TO COMMAND LINE STRING dirbuf: ds 2 ; PTR TO DIRECTORY BUFFER nfptr: ds 2 ; PTR TO NEXT FILE nfcnt: ds 2 ; NEXT FILE COUNT nextch: ds 2 ; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE scratch: ds 2 ; ADDRESS OF FIRST FREE BYTE bcnt: ds 1 ; NUMBER OF PAGES IN SCRATCH AREA z3flag: ds 1 ; NZ=Z3/33/34, Z= no Z3 facilities present ;--------------------------- ;the next 8 bytes are initialized ;from the block at dnumfl by a block move lnumfl: ds 1 ; DB 0; LINE NUMBER FLAG (DEFAULT TO NO) pnumfl: ds 1 ; DB 0FFH; PAGE NUMBER FLAG (DEFAULT TO YES) exact: ds 1 ; DB 0; EXACT PRINT FLAG (DEFAULT TO NO) fnpfl: ds 1 ; DB 0FFH; FILE NAME PRINT FLAG (DEFAULT TO YES) timepfl: ds 1 ; DB 0FFH; TIME PRINT FLAG (DEFAULT TO YES) multfl: ds 1 ; DB 0FFH; MULTIPLE RUN FLAG (DEFAULT TO YES) inspect: ds 1 ; DB 0; INSPECT FILES (DEFAULT TO NO) offset: ds 1 ; DB 0; column OFFSET ON PAGE (left margin) ;These four bytes are derived from the Z3env printer ;parameters or from the parameters at DLWID in the ;configuration block. They are put here by INITPF. lwidth: ds 1 ; DB 0; WIDTH OF LINE ltpp: ds 1 ; DB 0; LINES OF TEXT PER PAGE lspp: ds 1 ; DB 0; LINES TO SKIP PER PAGE lff: ds 1 ; DB 0; FORM FEED FLAG (0=NO) ; NOTE: LTPP + LSPP + 2 (HEADER SIZE) = TOTAL LINES PER PAGE ON PRINTER ;--------------------------- skipfl: ds 1 ; DB 0; SKIP FLAG for 'skip to page...' skipnum: ds 2 ; PAGE NUMBER TO SKIP TO lnum: ds 2 ; CURRENT LINE NUMBER pnum: ds 2 ; CURRENT PAGE NUMBER hbuf: ds 2 ; PTR TO BUFFER FOR HEADING timebf: ds 2 ; PTR TO BUFFER FOR TIME STAMP ; PRINT3 Buffers tfcb: ds 36 ; FCB for current file nxtblk: ds 2 ; Pointer to next block to load nxtln: ds 2 ; Pointer to next line to read lcount: ds 1 ; Count of text lines left on page ; Stack stack: ds 2 ; Old stack ptr end