General Overview of TRS-80 Graphics

The TRS-80 had very rudimentary graphics. Little rectangles could be displayed to a maximum of 128 squots (square dots) across by 48 down, always beginning with row 0.

Squots could be put onto the screen with the SET(X,Y) command, removed with the RESET(X, Y) command, and checked for on/off status with the POINT (X, Y) command.

However, using SET/RESET was the slowest way to manipulate graphics and to do anything approximating gaming one would need another method.

In addition to the SET/RESET to control each squot,the TRS-80 had a character set which would include a 2 x 3 squot matrix. These characters, from 128 through 191, ran the gamut from completely off/black (128) to completely on (191), and everything in between.

The 2 x 3 matrix running from 128 to 191 was actually an 8-bit binary representation of a 7 bit number “1xxxxxxx” so if you wanted the top two squots it would be “10000011”, the middle 2 squots would be “10001100”, etc. The actual CHR$(xx) representations appear below on this page.

But there’s more!! While you could use PRINT and PRINT@ to put those CHR$(xxx) matrices on the screen (putting up 6 squots at once), you could also pack them into strings and move those strings around. This is called “String Packing” and is virtually identical to the packing technique used in embedding machine language routines in BASIC programs. String Packing is explained on the String Packing page.

Character Sets

The TRS-80 Model III and 4 had alternate character sets built in, which included some characters that could be used in gaming. There were a couple of ways to access those:

  • CHR$(21) – Printing CHR$(21) would toggle the space compression codes from ASCII 192 – 255. The problem with using a toggle is that you would not be in a position to know which way those were set due to other programs which may have been run before yours. You could be trying to turn the codes on, but wind up turning them off.
  • CHR$(22) – Printing CHR$(22) would toggle between the Japanese Kana character set (the default) and the dingbats. Since this is a toggle, you have the same problem as you do for CHR$(21).
  • POKE 16912,x – 16912 is the mask location for port ECH. This port controlled a lot of things including CPU speed, the cassette motor, and the I/O bus. But it also controlled single and double width characters and the alternate character set. Since this was not a toggle, it could be set to reliable turn on or off those items. To control those, you needed to set the options at the bit level (more information can be found on the RAM Address page). Bit 2 would control the width (0=normal, 1=double) and Bit 3 would control the character set (0=Kana,1=Dingbat). For those less experienced, if you don’t mind having the cassette motor off, the width as normal, the I/O bus as disabled, disabled video waits, and 2mhz CPU speed, you would POKE 16912,8 (which is bit 4 on) to change to the dingbats and POKE 16912,0 (which is bit 4 off … well, its every bit off) to change to Japanese.

Japanese Kana Character Set (Default)


TRS-80 Graphic Worksheet

Click the image to download

Graphic Characters

Since the TRS-80 screen is black, each square represents what the screen would look like with that character on it. For example, 128 shows nothing and 191 shows a completely filled in block.

  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191


  1. Wow, string packing… where is the time.
    I remember an article from Leo Christopherson, who made Android Nim and The Dancing Demon, about line packing. So, it was assembly-code, not in a string but in a line of Basic code.
    Has anybody this article? Or where can I find this? Just for fun, I want to read this again.
    Grtz, Luc from Belgium.

  2. I remember finding a zine or newsletter once that intercepted the routine called by the BASIC interpreter when the LINE token was encountered. LINE was essentially unused in the TRS-80 BASIC that came with the Model I (aka Level 2), and had only a little use in the upgraded (Level 3 for disk systems) BASIC. There was Z80 assembly language that then checked for a SET or RESET token after LINE, then evaluated the following arguments into two pairs of X and Y screen coordinates (there may have been a TO between), and finally drew (or undrew) a line on the TRS-80 screen as directed. Because it was assembly language, it was incredibly fast compared to FOR/NEXT loops in BASIC to (un)draw the same line. While this did require loading some assembly language into memory first, or possibly it could have been done with DATA statements and POKEs much like string packing or the BASIC listing given, the speed increase was well worth it. I integrated this functionality with another routine that produced sound, and not only made a graphics and sound demo for my college programming class (which did use string packing for a blocky Enterprise that was shot with laser beams), I replaced the code in my copies of the Temple of Apshai games. This would have been sometime between 1980 and 1984.


Leave a Comment.