Visiting
The
VIC-20 Video
Jim Butterfield, Associate Editor
VIC-20 Video
Jim Butterfield, Associate Editor
This is the second part in our exploration of the VIC-20 video, in which the traveler discovers that a character set is less important for its footage than its mileage.
It's worthwhile making an observation about the "minimum VIC" configuration here. We know that the video chip sees memory in an unusual way:
Some users have memory expansion permanently connected to their VIC machines. They don't want to plug and unplug the memory units. Yet some programs call for a "minimum VIC with only 5K." A few POKEs can reconfigure any machine to this minimum configuration.
First, we set the Limit-of-BASIC:
POKE 55,0:POKE 56,30:CLR
And then put the screen into place (Block 15.5):
POKE 36869,240:POKE 36866,150:PRINT CHR$(147)
This takes care of the high end of memory. It's not always necessary, but we can also set up the low end:
POKE 4096,0:POKE 43,1:POKE 44,16:NEW
Small Character Sets
A full character set, 256 characters, takes up 2048 bytes of memory; there are eight bytes for each character. We have tried copying over the whole set. On a small VIC, it takes up a lot of our available RAM and starts to cramp our program space. Can we omit some of the characters and save space? Yes, we can.
Our program may not need the reverse video characters. If so, there's a savings of 1024 bytes. Be careful: reverse video is used for flashing the cursor. If you give it up, the cursor may not work in quite the same way.
But there's more. Which are the characters that we use the most? Well, the alphabetic characters A to Z, the space character, of course, and the numbers 0 to 9. What luck! These characters are bunched together within the first 58 of the character set, including a few spares. 58 times 8 gives us 464 bytes of storage - not bad for a functional character set.
We could do better than this if we had a specialized display that could work from very few characters. For example, a game might use only four characters: a ball, a ninepin, a "gutter," and the all-important space character to give us blank space. Even so, we might be tempted to go the whole alphanumeric set - to display scores, instructions, and the like.
A little arithmetic shows us a convenient arrangement. The character set must start on a block boundary. Screen memory may start on a half-block boundary. If we put them one behind the other, this would give us 512 bytes for the character set, enough for 64 characters.
In fact, let's try this, with the partial character set at block 15 and the screen at its usual block 15.5. We can write a simple graphics demonstration program.
A Little Program
100
POKE 56,28:CLR (lower Limit-of-BASIC)
110 FOR J=0 TO 63 (copy 64 characters)
120 J1= J*8 (8 bytes per character)
130 FOR K=0 TO 7 (copy each byte)
140 POKE J1+K+7168,PEEK(Jl+K+32768)
150 NEXT K,J
110 FOR J=0 TO 63 (copy 64 characters)
120 J1= J*8 (8 bytes per character)
130 FOR K=0 TO 7 (copy each byte)
140 POKE J1+K+7168,PEEK(Jl+K+32768)
150 NEXT K,J
Here come our custom characters. We'll draw a ship in two characters: the left half in the character 27 and the right half in character 28. The "pixels" of the drawing are in the DATA statements:
160
DATA 0,0,4,4,127,63,31,0
170 DATA 0,0,192,192,252,248,240,0
180 FOR J=27 TO 28 (two specials)
190 J1= J*8
200 FOR K=0 TO 7
210 READ X:POKE J+K+7168,X
220 NEXT K,J
170 DATA 0,0,192,192,252,248,240,0
180 FOR J=27 TO 28 (two specials)
190 J1= J*8
200 FOR K=0 TO 7
210 READ X:POKE J+K+7168,X
220 NEXT K,J
Now we put our new character set in gear:
230
POKE 36869,255
240 POKE 36866,150
240 POKE 36866,150
And we'll draw our little ship with a simple demonstration program. Note that screen character 27 corresponds to ASCII character 91.
300
PRINT CHR$(147);"SHIP GRAPHIC"
310 FOR J=2 TO 18 (left to right)
320 PRINT CHR$(19)
330 PRINT TAB(J);CHR$(32);CHR$(91);CHR$(92)
340 FOR K=1 TO 99
350 NEXT K,J
360 GET X$:IF X$=" "GOTO 300
310 FOR J=2 TO 18 (left to right)
320 PRINT CHR$(19)
330 PRINT TAB(J);CHR$(32);CHR$(91);CHR$(92)
340 FOR K=1 TO 99
350 NEXT K,J
360 GET X$:IF X$=" "GOTO 300
The program ends here. Restore the regular character set:
370
POKE 36869,240
Run the program. After the initial pause for generating the new character set, a ship will move across the screen. You can adjust its speed by changing the value of 99 in line 340. The program will terminate if you hold down any key.
If you press RUN/STOP, the program will break with the custom character set still in place. You'll notice the lack of a cursor; apart from that, you can type most alphanumeric characters without problems. You might like to look around to find out which keys now represent left and right halves of the ship. When you are finished playing, type CONT to allow the program to continue, and then terminate by holding a key down.
You may notice that the program does not restore the 512 bytes that it takes for the character generator. So the character set is protected, and you can try going back to it if you wish with a POKE 36869,255. Eventually, you may wish to make the program complete by adding line 380, with a POKE 56 and a CLR. I'll leave you to work out the proper details.
Here's a question that may cross your mind: if the character generator starts at block 15, where would the video chip go for the reverse characters? They would be in the next block, but we don't have a block 16. What happens? The video chip address "wraps around," and we go to block 0. The characters in block zero are not reversed, of course, and that's why the cursor doesn't flash.
We can do some good work with a very small character set. It doesn't necessarily have to be big to be useful.
Another thing that we have spotted in this episode: we can build effective graphic pictures by using more than one character. Our program used two separate characters which together drew a ship, but we can use three, four, six, or more as needed.
Copyright © 1983 Jim Butterfield