TRS-80 Tips and Tricks – Graphics

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

Japanese Kana
(Default)
Click to Enlarge

Dingbats
Click to Enlarge

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.


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

5 thoughts to “TRS-80 Tips and Tricks – Graphics”

  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 am wondering myself. Seems to me, you would pack line by line using LF and BS I guess to make multi-line graphics?

  3. 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.

  4. Meanwhile I can do all the tricks of string and line packing. If I have a lot of time I could show it in a Youtube video.
    Of course the question is how many people are interested in it?

  5. Did you ever notice that the six bits of the 64 characters (if you start counting at ASCII 128, all nils) are formed in the way that each bit represents a “pixel”. So 6 Bits for 6 “Pixels” in a character. So 128 is “0 0 0 0 0 0”, all black, and 191 is “1 1 1 1 1 1”, all white. Want a character, where the upper left corner and the lower right corner are lit, the rest back? Well: set the first bit (0) and the last bit (5), that is 100001; now add 128 to it, that is: 10100001, and voila your character: 128 + 32 + 1 = 161. Confirm with a lookup to the above table 🙂

Leave a Reply to Andy Johnson Cancel reply

Your email address will not be published. Required fields are marked *