Dot-Matrix Bit Graphics

Author(s): Robert Hartung
Publication: SyncWare News
Pub Details: SyncWare News v4 n6 (Volume 4, Issue 6)
Date: July/August 1987
Pages: 22-23

A current ad for a book about dot-matrix printers states that 80% of the users only make use of about 20% of the features available to them. Whether this is an accurate estimate or not, it is likely that when we unpacked our new printer the most of us did not spend much time on the bit-graphics part of the manual, especially if it had lost something in the translation from an Oriental language.

If the print-wires in your printer fire in a vertical configuration (as opposed to some jet printers that use a series of horizontal dot-sweeps) some of the things I have learned in my own experimentation may be of interest to you and, hopefully, more informative than confusing! Please note that all listings as given are for a C. Itoh 8510 driven by the printer routine in Tom Woods‘ ProFile which uses the “↑” (SS/H) character and 1Bh as ESC command delimiters, so revisions will be needed to use them with other printers and driving software.

Bit-graphic gets its name from the printing of one dot on paper or the setting of one pixel in the display to correspond with each bit of data that is set to 1. A 0 bit prints or sets a dot-space. A pseudo bit-graphic routine was given in my Jan. 1986 SWN article which demonstrates the principle. It will work with daisy-wheel as well as dot-matrix printers by using a period (.) instead of a graphic dot. For those who missed that issue, here is a version that will make a full-page screen dump with most printers when done in proportional mode with a very small line-feed increment. Shorten the H/V loops if over-printing occurs.

10 FOR H=0 TO 255: REM Horizontal scan
20 FOR V=0 TO 175: REM Vertical scan
30 IF POINT (H,V) THEN LPRINT ".";
40 IF NOT POINT (H,V) THEN LPRINT " ";
60 NEXT V
70 LPRINT
80 NEXT H

Listing #1

While a full screen-dump or copy in normal or enlarged format is fine for some purposes such as hi-res drawings or graphs, it is desirable at times to selectively scan and copy parts of the display. For example, the following routine will read in sequence the very top pixel-row followed by the 9th pixel-row, then the 2nd row followed by the 10th, and so on. The accumulated data for each pair of pixel-rows is held in the printer buffer along with one bit-space between each bit-dot (line 70) or else two bit-spaces if a scanned pixel is not set or 0 (line 80). When the line 100 LPRINT occurs, the buffer is dumped to print out in 64-column format whatever is displayed in the T/S font, or as UDGs, or custom-font characters in the top two lines of the screen.

In line 30, the ESC S0002 command tells my printer to read the next two bytes as a two-bit-row graphic character. Think of the 01h as setting the top bit in an 8-bit vertical row or just one dot-bit. The 00h then sets none of the bits in the bit-row of the second character-byte. Actually, the other 7 bits

1 CLS : PRINT "This two-line 32-column display will be copied as one 64-column."
5 LPRINT "↑1BP↑1B!↑1BT01"
10 FOR V=175 TO 168 STEP -1
20 FOR H=0 TO 255
30 IF POINT (H,V) THEN LPRINT "↑1BS0002↑01↑00";
40 IF NOT POINT (H,V) THEN LPRINT "↑1B2";
50 NEXT H
60 FOR H=0 TO 255
70 IF POINT (H,V-8) THEN LPRINT "↑1BS0002↑01↑00";
80 IF NOT POINT (H,V-8) THEN LPRINT "↑1B2";
90 NEXT H
100 LPRINT
110 NEXT V

Listing #2

overprint with the line 5 LF command of 1/144″ but as bit-spaces nothing is printed. If the first byte is defined as 03h (a character two dots high) the LF increment may be increased by 1 for an enlarged copy. Sprites may printed by careful horizontal and vertical character alignment on consecutive print-lines. The time required to do all this scanning in Basic is about two minutes for each 64-column line of copy and about one minute in compiled code.

Alternatively, we could fully define each 8-bit-row element before it is sent to the printer. This is done in LISTING 3 by first doing a scan from top to bottom of the left-most column of pixels in display-line 0 and storing it as a BIN value in B$. Line 80 converts this to a one-byte character and stores it in P$. The same is done with line 1, then the next column of line 0 and so on until all the bytes are stored in P$. Lines 110-140 provide options of two or one or no bit-spaces between dot-columns to change character size. Making line 10 FOR N=0 TO 0 would scan only the top line, while making it FOR N=0 TO 2 would scan the top three lines and print them out as one line. The routine is placed at the beginning of the listing so the FOR-NEXT loops will run as fast as possible, but again about two minutes are required per 64-column line of printout.

5 LET P$=""
10 FOR N=0 TO 1
20 LET V1=175-N*8-7: LET V2=175-N*8
30 FOR H=0 TO 255
40 LET B$="BIN "
50 FOR V=V1 TO V2
60 LET B$=B$+STR$ (POINT (H,V))
70 NEXT V
80 LET P$=P$+CHR$ VAL B$
90 NEXT H
100 NEXT N
110 PRINT #0;"Key 1 for condensed--2 for elite--3 for expanded (pica)": PAUSE 0: GO TO 120+10*(INKEY$="2")+20*(INKEY$="3")
120 FOR n=1 TO 512: LPRINT "↑1BS0001";P$(N);: NEXT N: LPRINT : RETURN : REM Condensed
130 FOR n=1 TO 512: LPRINT "↑1BS0001";P$(N);"↑1B1";: NEXT N: LPRINT : RETURN : REM Elite
140 FOR n=1 TO 512: LPRINT "↑1BS0001";P$(N);"↑1B2";: NEXT N: LPRINT : RETURN : REM Pica
9000 CLS : PRINT AT 0,0;"This line will be copied (along with any UDGs) by top subroutine"
9010 GO SUB 5

Listing #3

Obviously, when written in Basic the approaches to bit-graphics we have looked at so far are not time-efficient, but they do allow a flexibility for doing printouts of anything that can be put into the top lines of the display. We could hurry things up a great deal if instead of scanning characters bit-by-bit to recreate them we read them directly from a predefined font table. The UDG file is such a table but unless pages of characters are moved in and out it is limited to 21 characters.

However, our TS2068 manual tells us in Appendix D that if we poke the two system variables for CHARS they can be used to point the computer to a user-defined character font in RAM instead of the one in ROM. To make it easier to switch from one font table to another, we need only POKE 23607, (MSByte-1) for an address 256 less than the beginning of the file location. The 256-byte offset is because character-codes 0 through 31 are not used by TS2068 characters (32 * 8 bytes per character = 256). The other end of the font table stops at character-code 127 or 760 bytes in all, including the curly brackets and copyright symbol. POKE 23607,60 returns us to the ROM table.

The hardest part of using alternate fonts is the defining of the characters themselves, unless you can lift the font table out of a program that contains the characters you want. To find where the table begins, look for a program line that pokes something other than 60 to 23607. Multiply this value plus 1 times 256 for the starting address (plus any value other than 0 if 23606 is also poked). To save, use SAVE “table”CODE (address),760.

Character-definition programs do not usually provide for rotating the characters 90 degrees clockwise from the upright position as required by many printers. The routine in LISTING 3 will do this with no strain or pain. It uses the display file for a series of decimal-to-binary conversions. These are stored in an 8 X 8 string array, from which BIN strings are stripped off and poked back as character bytes in the required order. If you want to observe the results, insert line 195 PRINT AT 0,5; CHR$ C: PAUSE 30. If you intend to also use your font tables for screen-copy routines, save a copy in normal position before rotating them.

5 LET F=(Font table MSB-1)
10 CLS : POKE 23607,F
20 LET file=(F+1)*256
30 FOR C=32 TO 127
40 PRINT AT 0,0;CHR$ C
50 DIM B$(8,8)
60 FOR N=1 TO 8: LET B$(N)="00000000": NEXT N
70 FOR V=168 TO 175
80 FOR H=0 TO 7
90 IF POINT (H,V) THEN LET B$(V-167,H+1)="1"
100 NEXT H
110 NEXT V
120 FOR K=1 TO 8
130 LET P$="BIN "
140 FOR N=1 TO 8
150 LET P$=P$+B$(N,K)
160 NEXT N
170 POKE file,VAL P$
180 LET file=file+1
190 NEXT K
200 NEXT C
210 POKE 23607,60

Listing #4

After all the preliminary work is done, a quite simple program such as LISTING 5 will read into the printer the normal LPRINT sequences and will also switch between font tables as well as the UDG file. The text-entry routine shown in lines 200-240 may be used to input 64-character lines into the T$ array. To stop input when INPUT LINE is used, key the down-cursor (CAPS SHIFT/6). Single quotation marks will be accepted. (This routine may be merged with the previous demo listings.)

Any word or phrase you want in a defined font is bracketed by inserting delimiter characters before and after it. As given, the listing calls for a GO SUB to the appropriate bit-graphic routine when it encounters a UDG character or a reverse-slash. Then during the subroutine a return will be made to normal LPRINT when it comes to the same delimiter character at the end of the word or phrase. If you wish an entire file to be printed in another font, the main printout routine may be altered to read all characters as in the subroutine, but without delimiter checks for faster running.

5 REM Table address 59904
10 FOR Y=N+1 TO 64
20 IF T$(U,Y)="" THEN LET N=Y: GO TO 8060
25 PRINT T$(U,Y);
30 FOR Z=0 TO 7
40 LPRINT "↑1BS0001";CHR$ (PEEK (59904+Z+(CODE T$(U,Y)-32)*8));"↑1B1";
50 NEXT Z
60 NEXT Y
70 GO TO 8060
100 FOR Z=0 TO 7
110 LPRINT "↑1BS0001";CHR$ (PEEK (65368+Z+(CODE T$(U,N)-144)*8));"↑1B1";
120 NEXT Z
130 GO TO 8060
200 REM Input routine
205 CLS : PRINT "Key down-cursor & GO TO 8000 forprintout"
210 LET LN=72: DIM T$(LN,64)
220 FOR N=1 TO LN
230 INPUT LINE T$(N)
240 NEXT N
8000 REM Printout
8010 FOR U=1 TO LN
8020 FOR N=1 TO 64
8030 INPUT "": PRINT T$(U,N);
8040 GO TO 8050-8040*(T$(U,N)="")-7950*(CODE T$(U,N)>143)
8050 LPRINT T$(U,N);
8060 NEXT N
8070 PRINT : LPRINT
8080 NEXT U
8090 PRINT : LPRINT

Listing #5

I hope these demonstrations will provide a springboard for ideas and refinements of your own to unlock more of the power that is in your printer.

"Byte Graphics" grinning-teeth cartoon
"Byte Graphics" grinning-teeth cartoon

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.