All About The TI Character Set
Michael A Covington
This brief outline of the TI character set explains how the computer recognizes each character. The author discusses some uses of the characters' numeric codes and indicates which characters' graphic representations can be assigned or changed.
Chances are you've never given your computer's character set much thought. You press keys on the keyboard and the characters appear on the screen; that's all there is to it, or so it seems. But there's a lot more going on than meets the eye.
Inside the computer, each character is represented by a numeric code – a number between 0 and 255 inclusive. For instance, the code for capital E is 69; the code for an exclamation mark is 33; the code for a blank (a blank is a character just like all the others) is 32. To associate these codes with the characters you see on the screen, the computer has to know two more things about each of them: a graphic representation that describes how the character is supposed to look on the screen, and a key assignment that indicates what key or combination of keys you can hit on the keyboard to type the character. For instance, the character string "HELLO THERE!" (not counting the quotation marks) involves the following:
|Key assignment:||H Key||E Key||L Key||L Key||O Key||space bar||T Key||H Key||E Key||R Key||E Key||Shift & 1 keys|
Statements Using Numeric Codes
Normally (when you type characters in response to a string INPUT statement or when you type them as part of a program) you enter characters by hitting the keys that correspond to them. That is, you access them by means of their key assignments, and within the program you treat them as character-string data. But there are ways of referring to characters by their numeric codes and treating them as numbers. For instance, the CALL HCHAR and CALL VCHAR statements, which you meet at an early stage as you work through the manuals that come with the computer, refer to characters by their numbers. The statement
CALL HCHAR(3, 3, 69, 20)
will place a row of 20 capital E's (character number 69) on the screen beginning at row 3, column 3.
Also, you can input characters as numeric codes. The CALL KEY statement senses whether a particular key on the keyboard is up or down; when a key is pressed, CALL KEY gives you the numeric code corresponding to it. For instance, here is a program which will tell you the numeric code of any key on the keyboard:
10 PRINT "PRESS ANY KEY..." 20 CALL KEY(5, CODE, STATUS) 30 IF STATUS < > 1 THEN 20 40 PRINT CODE 50 GO TO 10
The heart of the program is lines 20 and 30. Line 20 tells the CALL KEY subroutine to look at the keyboard and report what's going on. The variable STATUS will equal 1 only if the condition of the keyboard has changed since the last time the routine looked at it. If STATUS does not equal 1, we simply go back to line 20, since we don't want to do anything more if the user hasn't pressed a key or hasn't yet let go of the one already looked at. The variable CODE contains the numeric code associated with the key being pressed, if any. (The first parameter of CALL KEY, the number 5, simply indicates that we want the usual BASIC set of codes; specifying other numbers there instructs the computer to use other sets of key assignments for various special purposes.)
The ASC and CHR$ functions allow you to convert back and forth between numeric codes and character strings. If A$ is a character string, ASC(A$) is the numeric code of its first character; thus ASC("E") is 69. Conversely, if N is a number, CHR$(N) is a one-character string of which N is the numeric code; thus CHR$(69) is E. If we want the program above to print the characters themselves rather than their codes, we can convert the codes into characters by changing line 40 to:
40 PRINT CHR$(CODE)
The CALL CHAR subroutine allows you to alter graphic representations using a hexadecimal code that the manual describes in detail. For instance, if you want to change the dollar sign ($) into a British pound sign (£), just execute the statement:
CALL CHAR(36, "001C22207C20207E")
That will do it, at least as long as the program is running: the key assignment and numeric code will be the same, but the dollar sign will look like a pound sign. (It will revert to its original appearance when your program stops executing.)
What's Not In The Manual
Those are the preliminaries; now we get to the really interesting part (the part that isn't in the manual, at least not entirely). Internally, the computer can use any number from 0 to 255 as a character code; any such code can be an element in a character string and can be referred to by CALL VCHAR, CALL HCHAR, and CHR$. (In fact, CALL VCHAR, CALL HCHAR, and CHR$ will actually take numbers up to 32767; multiples of 256 are subtracted as necessary to get a number in the 0-to-255 range.) But not all the codes have key assignments or graphic representations. The breakdown (by numeric codes) is as follows:
0 - Undefined (no key assignment, no graphic representation).
1 to 15 - Function keys (Table 1). Most of these characters can be input by means of the CALL KEY statement, but they cannot be typed in normal contexts (for example, in response to an INPUT) because there they are interpreted as requests to perform cursor movements or the like. They have no graphic representations (if you print them, you get blanks or garbled patches).
16 to 29 - Undefined (like 0, these codes have no key assignments and no graphic representations, and there is no straightforward way of giving them either).
30 - The graphic representation of this character is the black square that marks the cursor; thus, CHR$(30) is handy if you want a black square. No key is assigned to it.
31 - This is the screen border character – a blank that is the color of the border rather than the typing area. No key is assigned to it.
32 to 126 - Standard ASCII characters (Table 2). These are the characters you use every day, including the alphabet, the numbers, and all the punctuation marks and mathematical symbols. Their graphic representations can be changed with CALL CHAR but will revert to their original form when the program ends.
127 to 159 - User-defined characters (Table 3). These start out with no graphic representations, but you can define them with CALL CHAR, and, contrary to what the TI manual says, such definitions remain in effect after the program stops running (though most are disrupted when another program is loaded).
What most people don't realize is that these characters can be typed – they have key assignments and are acceptable in the same context as any other character (that is, in response to an INPUT or CALL KEY, or within quotes in a program). All but one of them require you to hold down the CTRL key (at the lower-left corner of the keyboard) when typing them; character number 127 uses the FCTN key instead.
160 to 175-Undefined.
176 to 198-These characters have key assignments (Table 4), but no graphic representations and no direct way of giving them any. They can be used as special function keys of some sort (in response to either CALL KEY or INPUT), but not as displayable characters.
199 to 255-Undefined.
Even the "undefined" character codes (those that cannot be typed on the keyboard or displayed on the screen) are not completely useless. You can refer to them by means of CHR$ and ASC and use them as special markers of various kinds when manipulating character strings. They also may come into play when you are transmitting data to other devices (for example, printers or other computers) that have definitions for characters that are undefined on the TI-99.
Finally, consider this possibility. Each character in a character string has a code between 0 and 255 inclusive, accessible through CHR$ and ASC. Also, the SEG$ function allows you to address individual characters in a string, and the & (concatenation) operator allows you to construct strings out of individual characters. This means that a character string gives you a compact way of storing a set of integers between 0 and 255 – each element occupies only one byte in memory, as compared to the eight bytes normally needed to store a number. So if you have a program that needs to keep track of thousands of small integers – more than will fit in available memory in numeric form – then character strings may be the answer.