Classic Computer Magazine Archive COMPUTE! ISSUE 77 / OCTOBER 1986 / PAGE 10

IBM Custom Characters

The Commodore 64 character set can be customized by changing the contents of a particular memory location (which normally points to character data in ROM) to point to an area in RAM where your redefined characters are stored. Is it possible to customize the IBM PC character set, and if so, how?

Benito Franqui

Yes, you can redefine the character set on the IBM PC as well as on the PCjr. However, there are a couple of restrictions. First, on both machines, redefined characters must be printed on one of the graphics screens to be seen. Second, on the PC, only the upper half of the character set (characters numbered 128-255) can be changed. The following program shows how to redefine CHR$(128) as an alien shape. It runs on both the PC and PCjr, and displays the custom character on SCREEN 1.

10 DEF SEG = 0
20 POINTER = &H7C : REM For characters 0-127 on PCjr only, POINTER = &H110
30 FOR VECTOR = 0 TO 3 : OLDVEC(VECTOR) = PEEK (POINTER + VECTOR) : NEXT : REM S ave default pointers
40 DEF SEG = &H1700 : REM Put character data at &H1700
50 For DOTPOS = 0 TO 7 : READ DOT DATA : POKE DOTPOS, DOTDATA : NEXT
60 DEF SEG = 0 : REM Restore segment
70 SCREEN 1 : CLS
80 FOR VECTOR = 0 TO 2 : POKE (POINTER + VECTOR), 0 : NEXT : POKE POINTER + 3, &H17 : REM Set character data pointers to &H1700
90 PRINT CHR$(128)
100 FOR VECTOR = 0 TO 3 : POKE (POINTER + VECTOR), OLDVEC(VECTOR) : NEXT : REM Restore character data pointers
110 DATA 60, 126, 90, 126, 60, 36, 66, 129 : REM alien shape

Just as with the 64, you make the computer look to RAM rather than ROM for its character data. If you have at least 128K of RAM in your PC or PCjr, memory above 96K is unused by BASIC and is thus a safe place to store the custom character data. Line 40 of the program accesses this area with the statement DEF SEG = &H1700. In line 50, the program puts the alien shape data in the area beginning at &H1700. Line 110 contains the data.

To make the PC/PCjr fetch its character data from the segment at &H1700, we must change certain pointers at the bottom of memory. These pointers are four bytes long. The first two bytes represent an offset to the segment address contained in the third and fourth bytes. On both the PC and the PCjr, the pointer to data for the built-in graphics and foreign language characters (numbered 128–255) is at location &H7C. Since our program redefines a character in this range—CHR$(128)—we've used this pointer value in line 20. On the PCjr, you can redefine characters in the range 0–127 using the pointer at location &H110. In order to access either character data pointer, you must set DEFSEG to zero since the pointers are at the bottom of memory. The program does this in lines 10 and 60.

Before the program ends, the character data pointers must be restored to their default values. If you end the program with the character pointers still modified, the computer can't recognize the custom characters and will fail to respond to any commands (this is unlike the Commodore, which lets you use modified characters as usual, no matter what their shape). Before modifying the characters, save the default character set pointers (line 30). When you're done printing the custom characters, restore the pointers to their original values (line 100). You can find more information on this subject in COMPUTE!'s First Book of IBM, written by Sheldon Leemon and available from COMPUTE! Books.