Create-A-Font

24K Cassette or Disk
by Vince Erceg


The ability to create alternate character sets is an extremely powerful feature of the Atari computer. The method for creating such a set is relatively easy. I say "relatively" because if you don't have a program such as the one that follows this article, then the process becomes rather complicated, involving large amounts of arithmetic. Fortunately, the program that I present here requires nothing but a joystick and an active imagination.

If you want to skip my explanation of how altered character sets work, just type in Listing 1 and RUN it. The operating commands are self-explanatory.

How do you create an alternate character set? First, you must set aside some memory space (1024 bytes for a full set or 512 bytes for a half-set). Then you either copy the Atari's ROM-based character set into the space, or fill it with your own revised character data. Finally, you tell the Atari where you have placed your set with one simple POKE to location 756 ($2F4 hex).

Details-Details.

Each letter, number, or graphics figure in a character set is created by 64 individual pixels (the size of a dot in GRAPHICS 8), arranged in an eight by eight grid. The way that the actual character appears depends on which pixels are "on" or "off." Figure 1 shows Atari's pixel representation of the letter "A."

Figure 1
     BITS
7 6 5 4 3 2 1 0
                0
      X X       1  B
    X X X X     2  Y
  X X     X X   3  T
  X X     X X   4  E
  X X X X X X   5  S
  X X     X X   6
                7

As you can see, there are eight bits per byte and eight bytes per character. Since there are 128 separate characters in a complete character set, and each requires eight bytes, that means we must reserve 128 X 8 or 1024 bytes of RAM for our new set. If you are using GRAPHICS modes 1 or 2, then you need reserve only 512 bytes since you can only display half of the set in either of these modes at a time.

How are pixel patterns actually stored in memory? Figure 2 shows how the position of a pixel is converted into a number.

Figure 2
             BITS
  7   6   5   4   3   2   1   0

128  64  32  16   8   4   2   1

The decimal value of each pixel position in a byte is shown under its respective bit number (0-7). The total value of the byte is obtained by adding together the decimal values of all of the bits that are "ON," or set. If all of the bits are set, the value of the byte is 128+64+32+16+8 +4+2+ 1, or 255. (255 is the maximum number that a byte can hold, and also the maximum number that can be POKED using BASIC.) If bits 7 and 0 alone were set, the byte value would be 128+1, or 129. Remember, when a bit is set it equals 1. It does NOT equal zero.

Referring back to Figures 1 and 2, let's figure out the byte values of the letter "A."

Byte #Bits OnByte Value
1 0 = 0
2 16+8 = 24
3 32+16+8+4 = 60
4 64+32+4+2 = 102
5 64+32+4+2 = 102
6 64+32+16+8+4+2 = 126
7 64+32+4+2 = 102
8 0 = 0

Now we are ready to relocate the character set. When you create your own character set and plan to store it in memory, you must reserve at least 1K (1024 bytes) for a full set and you must make sure that it begins on a memory address that is evenly divisible by 1024 (such as 38912). An easy way to do this is:

POKE 106,PEEK(106)-4

Always execute a GRAPHICS command after POKEing location 106 so that screen memory will be location 756 will be the value found in location

Archiver's Note: That last paragraph comes directly from the magazine. I'm not sure what the author meant to say.

If you are using GR.1 or GR.2, you need only reserve 512 bytes of RAM. This area must start at an address that is evenly divisible by 512 (such as 38912, again). This memory can be reserved by:

POKE 106,PEEK(106)-2

The location of your new character set will now begin at PEEK(106)*256. The number to poke in location in 756 will be the value found in location 106. That's about all there is to it, except for a few things that must (unfortunately) be considered at all times:

  1. Make sure that your new character set does not overlap player/missile data.
  2. Scrolling the text window in a graphics mode scrolls up to 800 bytes past the top of memory! This effectively ruins your character set. The easiest way around this is not to scroll the text window.
  3. Hitting SYSTEM RESET or executing a DOS command will reset the character set pointer at 756 to 224. You must remember to change it back to your value if any one of these things happens.

Any easy way to avert danger from steps two or three is to simply subtract an extra four pages from location 106. It wastes memory, but it relieves you of some of the worries of possibly destroying your set. The beginning of your character set will then reside at (PEEK(106)+4)-256.

One last thing. When altering a character set, remember that the characters are not in ATASCII order; rather, they are in the hardware's own internal order. To change the character data in the new set, look at the internal code table and find the character (see the Atari BASIC Reference Manual, page 55) and its associated value on the left. Multiply this value by eight and add it to the start of your set. The following demo program will show you what I mean.

10 CH=57344:REM Start of the ROM set
20 START=PEEK(106)-5
30 CHBAS=(START+1)*256;
40 POKE 106,START:GRAPHICS 0
50 FOR X=0 TO 1023:REM Move ROM set
60 POKE CHBAS+X,PEEK(CH+X):NEXT X
70 POKE 756,CHBAS/256
80 FOR X=CHBAS+33*8 TO CHBAS+33*8+7
90 POKE X,255:NEXT X

This program changes the letter 'A' to an inverse blank (cursor).

The program.

Now that you're familiar with how a character set works, type in Listing 1. After pressing START and a small delay, you will be facing the main display screen. In the upper right is an 8 X 8 grid with the heart character (CTRL/comma) enlarged. Pressing the joystick button will cause the pixel under the flashing dot to be toggled. (If it's on it will be turned off, and vice-versa.) You will notice that this has a visible effect on the character located in the middle of the screen. Any action that affects the enlarged display will also affect the same character anywhere it appears. You can move the cursor around with the joystick and change the shape of any character as you please.

Next to the blown-up image of the character being "edited," you will find the main menu. Here is a summary of all options and their functions:

The Antic 4/5 command changes the display list so that the characters are now in mode 4. Pressing A again will switch you back to the original display.

Most of the characters in mode 4 are indistinguishable because they are only four pixels wide instead of eight. This loss of resolution is the price that you must pay in order to get multicolored characters. Not only did the display list change, but the editing grid did also. This was done because the color that is displayed depends upon which binary number you place in each pixel. These numbers are related to the Atari's color registers as follow:

00Background
01Playfield 0
10Playfield 1
11Playfield 2

Playfield 3 can be used (binary 11), but only with an inverse character.

If you are in the "printing" (START) mode and you choose GRAPHICS 1 or 2, you may view each half of the character set alternately by repeatedly pressing RETURN.

When using "K"olor change, you must specify both color and luminance. The luminance can be any even value between 0 and 14; the color values range from 0-15, and are interpreted as follows:

0Grey 8 Med. Blue
1Gold 9 Dk. Blue
2Orange10Blue-Grey
3Red 11Olive
4Pink 12Med. Green
5Purple13Dk. Green
6Blue 14Orange Green
7Blue 15Orange

GTIA colors may be significantly different.

Listing 1

CRFONT.LST is available in ATASCII format.

This BASIC listing uses an image to display special characters






Checksum Data
10 DATA 609,253,228,257,336,739,580,95
4,221,386,605,540,605,798,457,7568
130 DATA 623,45,108,254,372,233,666,14
7,679,821,735,56,627,652,987,7005
250 DATA 287,206,206,117,110,100,93,57
9,623,17,221,996,906,786,624,5871
400 DATA 945,697,986,874,690,10,492,96
5,222,791,381,758,924,733,492,9960
520 DATA 428,836,133,668,409,841,358,7
36,487,981,178,524,756,220,538,8093
640 DATA 48,595,261,21,386,985,805,500
,312,737,585,823,555,972,573,8158
770 DATA 26,787,922,173,495,703,975,60
4,313,52,41,100,101,565,653,6510
920 DATA 929,541,987,668,722,849,537,3
18,28,722,155,597,605,237,644,8539
1070 DATA 305,71,348,941,936,669,269,7
23,661,823,596,259,232,65,224,7122
1200 DATA 444,172,902,303,697,948,783,
142,7,179,61,824,637,200,673,6972
1310 DATA 74,593,373,81,679,759,100,66
3,788,283,23,545,900,911,129,6901
1480 DATA 995,737,819,343,647,156,798,
4495

Previous | Contents | Next

Original text copyright 1984 by ANALOG Computing. Reprinted with permission by the Digital ANALOG Archive.