Classic Computer Magazine Archive ANTIC VOL. 2, NO. 10 / JANUARY 1984

ROTATING FONTS

Printing with different fonts on the NEC

by SOL GUBER

Having purchased a printer recently, I was very anxious to use it as soon as possible. The printer itself worked well, but because I had designed custom fonts for some of my programs (using the common technique of character graphics) a few problems developed. I discovered that my printer, a NEC 8023A-C, could normally only print English or Japanese characters (since I don't know Japanese, this wasn't much of a selling point). The following program was designed to get around this problem. If your computer can use a particular font, this program will allow you to print it out on your printer, as long as it has an individually-addressable pin configuration (such as the Epson with Graftrax or the NEC).

The program is set up specifically for the NEC 8023A-C printer; modifications are needed to make it work for other printers. It has two parts. The first is a utility that rotates the letters in the present character font; the second, also a utility, reads the characters on the screen in Graphics 0 notation and sends them to the printer using dot-matrix notation. I'll deal with each of these utilities individually.

DOTS ON THE SCREEN

The first utility is required because of the different structures of the printer and the monitor screen. Each letter on the screen is composed of an eight-by-eight square of dots (or pixels). When the dots in the square are lit up in a certain pattern, your eye sees a letter. Figure 1 shows how the upper-case letter "A" appears on the screen.

To show which of the pixals on the screen are lighted, I have used a one to represent lighted dots and a zero for unlighted dots. In the computer's memory, each of the eight horizontal lines of coding that makes up the square of dots is stored in one byte. The code for each line is in binary notation, so that 00011000, for example, equals 24. Each of the pixels is so small that when all eight lines are seen together they appear to form a continues letter on the screen against the darker background.

This same kind of information can be transmitted to the printer and used to generate a printed letter, if the proper dot-image graphics mode is selected. The NEC 8023A-C features dot-matrix printing mode that can be selected by using the "ESC-S" code and a four-digit number that signifies how many bytes of information are to be transferred.

HORIZONTAL VS. VERTICAL

However, there is one problem that needs to be resolved before this information can be transferred to the printer. On the screen, the byte information is read horizontally (that is, each line of eight dots (see Figure 1) is read from side to side across the screen. But the pins on the NEC printer and on any pin-addressable printer are vertical. As a result, the same information that is read correctly on the screen will appear to be "sideways" to the printer.

Of the eight vertical pins on the NEC printer, the least significant bit (LSB) is the top pin, and the most significant bit (MSB) is the bottom pin. Thus, the data "1" will cause the top pin to print a dot, while the data "128" will prompt the bottom pin to do so.

binary---------hexidecimal--decimal
00000000----00--------------0
00011000----18--------------24
00111100----3C--------------60
01100110----66--------------102
01100110----66--------------102
01100110----66--------------102
01111110----77--------------121
01100110----66--------------102
Figure 1

ROTATING SUBROUTINE

Because the information that the printer needs is different in form from that the computer itself uses, a subroutine had to be written to "rotate" it so that the printer could print the characters correctly. It is possible to use Graphics Mode 8 to create characters that are sideways or upside-down, and in this case something similar must be done to modify the letters in the computers memory. Figure 2 shows an example of this.

binary--------hexadecimal--decimal
00000000----00--------------0
11111000----F8--------------248
11111100----FC--------------252
01000110----46--------------70
01000110----46--------------70
11111100----FC--------------252
11111000----F8--------------248
00000000----00--------------0
Figure 2

Memory location 756 contains a pointer that tells the computer where to find the character set that is to be used. This inter can be used to modify the letters in the character set, and we will do so to create our modified font.

The subroutine in lines 1000-1080 is used to rotate the present font to make it conform to the needs of the printer. Line 1000 determines the address of the present font, which is stored in memory location 756. Many calculations will be needed at this point, so we need to turn the screen off. To do this, POKE 0 to location 559.

Next, a loop for all of the letters (taken a byte at a time) is started. In line 1110, two variables are initialized. These are the low bit in the byte (N) and the current offset within the the eight bytes that makes up the letter (U1).

Line 1120 determines the value in the memory location. KK is the bit that will be placed in each byte if a one is found there. Line 1125 sets the memory location of the new font, and includes a pointer to the exact spot where the new font is located. Line 1130 determines if there is a one in the rightmost bit of the byte used for a letter. If there is a one present, N is added to the value already there. Line 1140 then removes the right-most bit and decrements KK. If all eight bits in the byte have not yet been processed, lines 1130-1140 need to be repeated. If the byte has been finished, line 1150 doubles the value in N and increments U.

If all eight bytes for a letter have not yet been processed, the next byte in the letter needs to be handled in this manner. If the letter is finished, process the next letter. If all 128 characters have been processed, turn the screen back on by POKEing 559 with 34, and return to the main program. This program takes about three minutes to work.

TRANSMITTING TO THE PRINTER

The second part of this program, also a utility, uses information in screen memory to transmit information to the printer. The method it uses is similar to that used by the Operating System (OS), and it saves several steps because of this.

The Atari system uses a portion of memory as the location for the screen memory. The information that is stored there is put onto the screen by the ANTIC chip. This area can be checked to determine what is on the screen, and can be directly modified without going through PRINT statements. A pointer at locations 88 and 89 shows the beginning of screen memory. And locations 87 tells ANTIC which of the BASIC graphics modes has been used to code the information in screen memory. As a result, the same memory information can be used to signify letters -- as well as colors - on the screen, if the proper decoding scheme is used.

The OS uses the pointer to locate the first byte of screen memory. It then takes this information and decides how to decode it. Since we're using Graphics Mode 0, the decoding is rather straightforward. The OS simply takes the value in the byte and multiplies it by eight. It then adds this value to the start of the character memory to find the next eight bytes of information. These will be used to determine the shape and form of the letter. (The OS then determines where to put these eight bytes on the screen, but I haven't yet discovered what system it uses to do this.)

MIMICKING THE OS

My second utility uses a similar method for sending information to the printer. It determines the beginning of screen memory and puts this number at the start of a FOR/NEXT loop. The program then finds the value of the screen memory. Next, it multiplies this value by eight and adds the product to the beginning of the NEWFONT memory. Then the program takes the next eight bytes and puts them into a string that will output this information to the printer. This is done forty times, for the forty letters on the screen. Then it goes on to the next line. After 23 lines, the subroutine returns to the major portion of the program.

PROGRAM DETAILS

Let me go through the main portion of the program now in more detail. Lines 1 -5 initiate some of the variables that will be used in the program (the use of variables, rather than constants, speeds the program up significantly). Line 20 dimensions FONT$. This is a space in which to put the rotated font. It is needed as a backup in case of an accident (such as a change in the graphics mode) so that the information will not be lost. NFONT is the address in memory for the start of FONT$. It's used in the rotation subroutine.

Line 30 zeroes FONT$. Line 95 goes to the rotation subroutine. Line 100 dimensions the string used to output to the printer. Line 120 ddetermines the start of screen memory. Line 200 lists part of the program so that you will have something to print out on the printer (as a test of the program).

Line 330 sets K to the location of the first spot of screen memory. Line 350 contains the FOR/NEXT loop that gets the value at the memory location (CHAR) and puts it into the string OUT$ in the proper place. The program determines which information to use by multiplying the value in CHAR by eight and using the next eight bytes in FONT$. Line 350 prints the new value using the NEC's proper dot-matrix notation. Then line 500 determines if all 23 lines have been checked and if the system is finished. If so, the program stops.

binary--------hexadecimal--decimal
00000000----00--------------00
00011111----1F--------------31
00111111----3F--------------63
01100010----62--------------98
01100010----62--------------98
00111111----3F--------------63
00011111----1F--------------31
00000000----00--------------0
Figure 3

MODIFICATIONS FOR OTHER PRINTERS

This program should work on any printer with addressable pins that handles graphics output the way the NEC does. For printers that use a pin configuration that is the reverse of the NEC's, however, the program will require modification. These printers require bytes in memory (for each letter) that look like the configuration in Figure 3. This necessitates two changes to the program. Lines 1110-1150 should be changed to the following for use with such printers:

1110 N = C128:U = C0
1120 AB = PEEK(OLDFONT + J + U):KK = CO
1125 SP = NFONT +J + KK
1130 IF AB/C2 <> INT(AB/C2) THEN POKE SP,PEEK (SP)+N
1140 AB = INT(AB/C2):KK = KK + C1: IF KK>C7 THEN GOTO C1125
1150 N = N/C2:U = U + C1: IF U < C8 THEN GOTO C1120

When a different font is used, this program may need to be modified so that the letters are enlarged, because there is more spacing on a printer than on the screen.

Download ROTFONT.BAS Download