nakada@husc7.HARVARD.EDU (Paul Nakada) (04/21/88)
Comments: Originally-From: Grant Delaney <delaney@wnre.aecl.cdn> Subject: Printer for freeWriter F R E E P R I N T E R by Elliot Lifson [72767,3352] NINCOMPUTE LTD. This program is presented as a machine language alternative to the "PRINT.LUTUS" program elsewhere in this Data Library. It was designed to work as a text printer to accompany Paul Lutus' FREEWRITER program, also in this data library. While performing the functions of the PRINT.LUTUS program, it also supports many of the APPLEWRITER imbedded print commands, which adds to its usefulness. In addition, it can be used as a quick screen or printer dump for sequential text files (which was my original intent when writing it, oddly enough. It grew, sort of!) Initially, the downloaded FREPRT.EXE text-file should be converted to ProDOS, if it is not in that form already, then EXECuted. The binary file created (FREEPRINTER) is not a SYSTEM file and should be BRUN from the Applesoft prompt. (The "-" DASH command may be used, of course.) The program resides between $8000 and $8E05, and uses $9000-$90FF as a utility buffer. There are two buffer areas into which text is loaded before it is formatted and displayed. The buffers are contiguous, and as FREEPRINTER is supplied they occupy $F00-$7FFF; however, this space can be reduced to one as small as $300 bytes. Thus, FREEPRINTER could conceivably be co-resident with a rather large Applesoft program, as long as HIMEM is set correctly. BRUNning the program will initialize the Ampersand Vector, and start the program. After exiting, an Ampersand (&) from the keyboard will restart the program for further passes, without modifying the printer parameters you have established. All characters after the Ampersand will be ignored, except for an uppercase "Q" which will restore the original contents of the Ampersand Vector and terminate the program. The program will prompt you for the name of a textfile. Normal ProDOS protocol is used here; the prefix will be retrieved if you don't supply one, and created from the default slot & drive if ProDOS doesn't have one stored away. A null entry will return you to Applesoft. As a time-saver for repeated use, entering an equal sign ("=") instead of a filename will cause the program to use the last filename you entered, recovered from its buffer at $9000. The program will test the validity of a stored pathname, and if the pathname is not valid you will have to re-enter the pathname from scratch. Note that the program checks to make sure that your filename refers to a text file. Currently, only normal TXT files (ID byte = $04) are supported, but you may add whatever file types you like to this list. (See the section on CUSTOMIZING, below.) The program then loads your text file (or as much of it as it can fit into its main buffer), and displays the default printer parameters. We will discuss the parameters and how to set them in the section on PARAMETERS, below; however, to accept the parameters, press the <RETURN> key. You are then given a final chance to change your mind. Press a "Y" to indicate that all is okay. Then you are given a few on-screen reminders: a keypress will freeze and restart the display, and a <CTRL-C> will abort the listing. If you are not printing (printing is defined as output to a slot other than 0 or 3), provision is made to slow the rate of the screen dump; see the section on CUSTOMIZING. As supplied, FREEPRINTER screen-dumps somewhet slower than full speed. After the file has been dumped, a press of any key will return you to Applesoft, with 80-column firmware off and all files closed. PARAMETERS OVERVIEW The parameters are pretty straight forward. The default is my idea of a quick screen dump of a textfile: Left margin = 0, Right margin = 78, Output to Slot 3, and Page Interval = 0. To change a parameter from the menu, merely type in its two-letter mnemonic followed by an argument, if required. All numeric arguments are treated modulo 256; the only time a negative argument is permitted is with the Paragraph Margin (PM) command. Here, a negative argument less than -128 will give you strange and wonderful results, but probably not the value you wanted. FREEPRINTER uses the 2-letter mnemonics that it does because they correspond to the traditional APPLEWRITER mnemonics. This lets FREEPRINTER work with APPLEWRITER documents which may already exist, and greatly expands the usefulness of both this program and the FREEWRITER program. To imbed a printer command in your document, merely start a paragraph with a period followed by the mnemonic and argument. Invalid commands and/or anything on the line following a valid command will be ignored. Entering <CTRL-C> <RETURN> in the menu routine instead of a mnemonic will permit you to abort the program. PARAMETERS LEFT MARGIN (LM) defines the column in which the line's first character is printed. While it can be set to just about anything, practically speaking it won't be greater than 60 or so, and must be set so the total of LM and PM is at most 5 less than RM, or you will get an error. (LM + PM + 5 <= RM) RIGHT MARGIN (RM) defines the last possible column into which the line may extend. If the margin comes in the middle of a word, the word is moved to the beginning of the next line. RM must be at least 5 more than LM + PM; this provides a minimum line length of 5 characters. Please note that if you are dumping text to screen, a RM of 39 or more (on a 40-column screen) or 79 or more (on an 80-column screen) will generate an extra carriage return if the number of characters on that line is 40 or more (or 80 or more), due to the Moniter routine's automatic scrolling action; therefore, use instead a RM of 38 (or 78) at these times. (If that seems confusing, remember that FREEPRINTER, like APPLEWRITER, starts counting screen columns with 0; a left margin of zero and a right margin of 79 implies that the first character is printed in the first column (column zero), and the last character in the 80th column (column 79). The auto-scroll is triggered when printing a character in column 79; so to avoid it, set RM so the last column printed to is column 78.) PARAGRAPH MARGIN (PM) is the number of spaces added to or subtracted from LM at the beginning of a new paragraph. (i.e. after a carriage return, or as the first line of a new document.) PM can be positive or negative; if the sum of LM and PM equals a number less than zero, printing starts at the left edge of the page (column zero). As stated above, if LM + PM + 5 exceeds RM, an error will be generated. The Paragraph Margin is only executed if text is Left-Justified, (See PRINT MODES, below), but the validity of the value is always error-checked. EXAMPLE: With a LM of five and PM of 0, each line will begin at column 5, whether it begins a paragraph or not. With LM=5 and PM=5, the first line of each paragraph begins at column 10 (5+5=10), with subsequent lines starting at column 5. If PM is now set to -4, the first line of each paragraph will start at column 1 (5+(-4)=1), with subsequent lines starting at column 5. Finally, if pm is set to -6, an error will NOT be generated; the first line of the paragraph will merely be printed at column zero. (Again, please note that because the first column is numbered as column zero, column 5 is actually the 6th column, column 10 is actually the 11th column, etc.) OUTPUT TO WHAT SLOT (Printer Destination, or PD in the APPLEWRITER convention) is as you would expect it; Slot 0 is the 40-column screen, 3 is normally for 80-column screens. Output to a slot number greater than 7 generates an error. NOTE: This program is specifically written for an Apple compatible 80-column card in the AUX slot; (that is, it prints an ASCII CTRL-U through COUT to turn off the card.) It should do no harm if the program is run entirely in 80-column mode, if your card is not compatible. Also, I'll be happy to supply the source code for this program if anyone would like to modify it for their own particular 80-column card. N.B. If output is directed to Slot 0 or 3, the program assumes a screen dump is taking place; if output goes to any other slot, the program assumes it is feeding a printer. This determines the outcome of certain decisions made at run-time. A PAGE INTERVAL (PI) of zero forces continuous output; no page formatting takes place. A non-zero value here defines how many lines there are on your page (normally 66 for a standard 8-1/2 by 11 page, or 72 lines for 8-1/2 by 14). If PI is zero, the Page Length (PL), Top Margin (TM), and Top Line (TL commands will do nothing when dumping text, no matter what they are set for, and their values are not checked for validity. Also, an imbedded Form Feed (FF) command will have no effect. PRINTED LINES PER PAGE (PL) determines how many lines of text to print and, by extension, how many blank lines at the top and bottom of the page. On every page, half of the difference of PI - PL lines are skipped at the top, PL lines of text are printed, and half the difference of PI - PL lines are skipped at the bottom. This will center the number of printed lines on the page. EXAMPLE: A PI of 66 and a PL of 60 will first print 3 blank lines at the top of the page, then a sequence of 60 text lines, followed by 3 blank lines at the bottom of the page, over and over, until the document is completed. PL must be set no lower than 3, and no greater than PI, or an error will be generated. SPACES AFTER TOP LINE (TM, or Top Margin in the APPLEWRITER convention) provides control over how many lines to skip after the Header line is printed. (The Header Line, if used, is the first text line printed after the top-of-form spaces described above in the PL section.) This value may not exeed PL - 2, or an error will occur. (This guarantees at least one text line printed per page.) If there is no Header line entered, the TM value is irrelevant and is not checked for validity. SINGLE PAGE (SP) lets you use a single sheet printer by prompting you to insert a new sheet of paper after each page is completed. A zero value defeats this feature, and a non-zero value enables it. A non-zero value entered will always be displayed as "1". SCREEN FORMAT (SF, not an APPLEWRITER command) permits you the option of letting your screen dump ignore or implement imbedded text commands. If the value is 0, your textfile is dumped to the screen as-is; only the formatting commands you entered from the menu are in effect. If SF is non-zero, imbedded commands are implemented, and you can see their affect. Remember though, this command only affects SCREEN dumps; Printer dumps always do the imbedded commands. As in the Single Page command, a non-zero SF value is always displayed as "1". PRINT MODE (LJ/RJ/CJ/FJ): These four commands determine the formatting of your document. Left Justification (LJ) means all lines start at the left margin, leaving you a ragged right margin. Right Justification (RJ) means each line's last character is printed at the right margin, with a ragged left margin. Center Justification (CJ) means all lines will be centered between left and right margins, leaving ragged ends on both sides. Full Justification (FJ) forces extra spaces to be inserted between words to make each line start at the left margin and end at the right margin. If the line ends in a carriage return, it is left justified. NOTE: If your document has imbedded printer control characters or escape sequences, a screen dump will display them as inverse characters, but a printer dump will faithfully transmit them to the printer. Unlike APPLEWRITER however, when dumping to printer, non-printing characters are taken into account when justification calculations are made. Therefore, lines containing underlining commands, for example, will center correctly without need for special margin settings. As supplied, FREEPRINTER will justify correctly for all imbedded control characters, and for escape sequences consisting of the Escape Character followed by one non-control charcter. (Provision is made for the user to modify this to the Escape Character followed by two or three non-control characters; see the section on CUSTOMIZING, below.) The HEADER LINE (TOP LINE, or TL in the APPLEWRITER convention) can be any character string you would like printed at the top of each page. If the "#" character is imbedded, the page number will be substituted when the document is printed. This line can be centered between LM and RM, or printed at the left or right margin, depending upon the number of leading astericks. One or no leading astericks forces a left-justified Header line; 2 leading astericks causes a centered Header line; 3 or more causes a right-justified Header line. EXAMPLE: You have a LM of 5 and a RM of 75; you would like the header to say "PAGE #". Entering TLPAGE # or TL*PAGE # will print the header at column 5; entering tl**PAGE # will center it between column 5 and column 75 and TL***PAGE # will print it so the last character is in column 75. You may optionally insert any number of spaces after the mnemonic, intermixed with the astericks, or before the first letter of actual Header text, and they will be ignored. Unlike APPLEWRITER, you may not have separate texts justified left, center, and right at the same time; also, unlike APPLEWRITER, a trailing asterick will be printed as part of the text. If the length of the Header Line (after "#" has been converted to a page number) exceeds RM-LM, the Header Line will be left-justified despite the number of astericks, and it will not wrap at RM; it will continue until the output device wraps it. If you wish to remove a Header Line entry without replacing it, enter TL<RETURN>. The FORM-FEED (FF) command doesn't appear on the menu, but is supported as an imbedded command. This forces the remainder of the current page to be skipped, and printing resumed at the top of the next page. ERROR-TRAPPING As noted above, bad combinations of parameters will generate an error message. If the bad parameters are entered from the menu, you will not be able to exit the menu routine until the errors have been reconciled. However, this doesn't prevent errors caused by bad imbedded commands. If an error is generated while a screen dump takes place, execution halts and the appropriate message is displayed. This is not the case, though, when dumping to printer. Before printing commences, the current "good" values of parameters are stored in a memory table. Whenever a single imbedded command (or a block of imbedded commands in sequence) is executed, the validity of the parameters is re-checked. If all is okay, the parmameters are implemented, and the stored table of parameters is updated. However, if an error is discovered, no indication is given; the last-stored table of values is merely reloaded, and execution continues. This can be confusing if you don't expect it; therefore, to avoid surprises, it is advisable to dump your document to the screen at least once before printing it, just to see what (if any) errors ar generated. ERROR MESSAGES The following messages may be displayed upon discovery of bad parameter values: "At least 5 characters per line." This is generated if LM + PM + 5 is greater than RM. If generated during a screen-dump, it usually means you re-defined LM too high without lowering PM. "Bad Slot." An attempt was made to assign a value greater than 7 to PD. The following 2 errors can only be generated if the value of PI is greater than zero. "Bad PRINTED LINES value." This is generated if PL is less than 3 or greater than the value of PI. "Top Margin too large." This rarely happens, but is generated if you are running with a very low PL. Then, if TM is greater than PL-2, no lines of text would be printed, just a Header line and skipped spaces; so, an error is generated instead. In addition, the message: "Invalid file type." will occur if the filetype of the file you are trying to load is not on the internal look-up table. See CUSTOMIZING, immediately following. CUSTOMIZING FREEPRINTER FREEPRINTER was designed to be flexible; there are a number of user- modifications possible. To implement them, all you need do is BLOAD FREEPRINTER from Applesoft, enter the Moniter with a CALL -151, and make your changes. Exit back to Applesoft with 3D0G. Once modified, you may execute FREEPRINTER immediately by issuing a CALL 32768, (you should not use the Ampersand command to execute the program until this call has been made at least once.) Should you decided to make your changes permanent, though, the command BSAVE FREEPRINTER, A$8000, L$E06 will accomplish this; none of the modifications will change the length of the program. You might save your changed program to a different disk, or under a different filename so that you can have different versions available for your needs. ADDING FILETYPES: Currently only the ID byte for TXT-type files (ID byte =$04) is stored in the 10-byte look-up table at memory locations $807E-8087. There is room for 9 more file-types. Merely poke their ID values into the table, replacing the zeroes starting at $807F. Use up the zeroes in order; a zero-byte indicates End-of-Table. (The first byte following the table is the low byte of the address of the Main Buffer; as such, it should always be zero, and will act as End-of-Table if you really use all ten bytes.) Note: FREEPRINTER was designed to look only at sequential text files; it assumes a zero-byte in the file indicates the End-of-File, so looking at a random text file for instance, would be unrewarding at best. SCREEN DUMP SPEED: The speed of the screen dump is controlled by the value of the byte at $8098; the byte's current value is $40. Setting this byte to 0 maximizes the display speed. A value of $FF takes FOREVER! DEFAULT PARAMETERS: The display parameters you get when you load FREEPRINTER are stored in a table starting at $80A2. They are as follows: ADDRESS PARAMETER CURRENT VALUE ______________________________________________ $80A2 Left Margin $0 $80A3 Right Margin $4E (78 decimal) $80A4 Paragraph Margin $0 $80A5 Printer Destination $3 $80A6 Page Interval $0 $80A7 Printed Lines $0 $80A8 Top Margin $0 $80A9 Single Page? $0 $80AA Screen Format? $0 $80AB Print Mode $0 (LJ=0, RJ=1, CJ=2, FJ=3) In addition, the value of the first page number printed ($1) is stored at $80DA; this can be made higher if you are printing a document from the middle. For your own information, the stored pathname starts at $9001 with a length byte at $9000, and the Top Line is stored at $9081, with a length byte at $9080. BUFFER SIZE: FREEPRINTER is supplied to use as much memory as possible, for this reduces the number of disk-drive reads required; as suppplied, its main file buffer starts at $1000, extending to $7FFF. Another page of memory is always required preceeding the main buffer (here $F00 to $FFF). As mentioned in the introduction, the size of this pair of buffers is variable. To change it, merely poke the HIGH BYTE of the first page of your buffer in location $8089. For example, poking $30 into $8089 will force the main buffer to begin at $3000, with the preceeding 1-page buffer at $2F00. All bytes below $2F00 will be untouched. Because of this feature, the possibility exists of using FREEPRINTER from within a co-resident Applesoft program. FREEPRINTER can operate successfully with a main buffer as small as 2 pages (poke $7E into $8084) leaving locations $800 to $7CFF untouched. A co-resident program under these circumstances would have available $7500 bytes at most. Note 1: Because of ProDOS' general-purpose file buffer, if your co-resident program makes any kind of disk access at all, or if you even wish to catalog a disk from immediate mode, HIMEM must be set $400 bytes lower than the beginning of the 1-page pre-buffer. (Example: Main buffer starting at $7000: poke $70 into $8089 (POKE 32905,112). The pre-buffer starts at $6F00; HIMEM should be set for $6B00 (27392 decimal.) FREEPRINTER sets HIMEM for you, according to whatever buffer space you have selected, and restores HIMEM to $9600 (normal) upon exiting with the "&Q" command. Note 2: To use FREEPRINTER from a co-resident Applesoft program, you must BLOAD FREEPRINTER as its first line. (DO NOT DEFINE ANY STRINGS UNTIL AFTER FREEPRINTER INITIALIZES ITSELF, specifically Control-D's!) Immediately after bloading, poke the high byte of the address of the main buffer (should you wish to change it) into 39205 ($8089, as explained above). Poke 2 into location 513 ($201, to inform the program that you wish to exit upon initialization), and CALL 32768 to do the actual initialization. To print a file, You must POKE the letters of the COMPLETE pathname of the file (including LEADING and TRAILING slashes) in "positive" ASCII into the buffer at $9001, poking the length of the pathname into $9000. Then poke 1 into 513 ($201) to tell the program to skip its routine to get the filename from you, poke 0 into 36992 ($9080, which performs a minor bit of initialization that the above poke unfortunately causes to be skipped) and issue an Ampersand. The following sample code will accomplish this, configuring FREEPRINTER for its minimum size. 10 PRINT CHR$(4)"BLOAD /VOLUME/FREEPRINTER" 20 POKE 39205, 126 : Rem Buffer begins at $7E00. 30 POKE 513,2 : Rem Exit after initialization. 40 CALL 32768 : Rem Initialize program & set HIMEM. Your program goes here. Then, to print a text file: 100 NM$ = "/VOLUME/SUBDIR/MYFILE/" 110 FOR X = 1 TO LEN (NM$) 120 POKE 36864 + X, ASC ( MID$ (NM$,X,1)) : Rem 36864 = $9000 130 NEXT X 140 POKE 36864, LEN (NM$) 150 POKE 513,1 : Rem 513 = $201 160 POKE 36992,0 : Rem 36992 = $9080 170 & The routine will exit back to your program, where you left off. Note that lines 10-40 should only be executed once; repeated attempts to BLOAD FREEPRINTER will fail, as the bit-map has been marked to show that memory is occupied in the loading area, and you'll merely generate the ever-popular NO BUFFERS AVAILABLE error. The exit routine (&Q) will warm-start ProDOS, and may not be used from within a program, except as the last line. To use it from within a program, poke 513 with 81 (uppercase "Q") and issue an ampersand. 500 POKE 513,81 505 & Note 3: When using FREEPRINTER from within an Applesoft program, all errors that would result in program termination are directed back into the Applesoft program, so that normal ONERR GOTO routines will work. For UNTRAPPED errors, if the generated error is a FREEPRINTER error (as opposed to a ProDOS error), BASIC.SYSTEM still wants to print one of its own error messages after the FREEPRINTER error message. So, to avoid confusion caused by two successive error messages, FREEPRINTER tells BASIC.SYSTEM to display Apple Computer's copyright notice instead. The error code for any FREEPRINTER-generated error is 126. ($7E) Note 4: As alluded to above, FREEPRINTER sets the ProDOS Memory Bit-map to protect itself when loaded. The Bit-map is set during initialization, when FREEPRINTER is first BRUN. Exiting FREEPRINTER using "&Q" will restore the Bit-map to its normal configuration. Should you wish FREEPRINTER not to modify the Bit-map and HIMEM, the following two patches may be used. The first jumps past the initialization, and the second jumps past the restoration: 8024:4C B4 80 (replacing 8024:A9 00 A8) 804B:4C 60 80 (replacing 8046:A9 00 A8) Make these changes only to a COPY of the FREEPRINTER program, not to your original downloaded version. IMBEDDED ESCAPE SEQUENCES: Correct centering and justification is maintained for imbedded escape sequences consisting of the Escape character and one non-control character. Because of the wide variety of command structures required for all the different printers on the market, full support is beyond the scope of this program. However, if your printer has commands with the structure of Escape Character followed by two or three non-control characters, you may modify 6 bytes of code starting at $863F to correct this. Currently these bytes are NOPs (hex $EA). To permit a second non-control character, insert (from the Moniter) 863F:CE 9D 80 For a third character, repeat the sequence again at $8642. As mentioned earlier, this program is designed to be flexible. The source code is rather lengthy, so I've elected not to upload it at the moment. If you would like to modify FREEPRINTER for your own purposes however, I'd be happy to make it available. Just drop me an easyplex, or a note on the BB. While the program SHOULD work on any APPLE // that can run ProDOS and display lower case text, it's only been tested on an enhanced //e with 128k and APPLE compatible 80 column card. If you have any problems using it on your system, I'd like to know about it; there could be any number of implementation details I've overlooked which, if I were aware of, I'd correct.