Classic Computer Magazine Archive COMPUTE! ISSUE 51 / AUGUST 1984 / PAGE 130

Hi-Res VIC Drawing

Jeff Wise

There comes a time when programmers want more subtle graphics than can be achieved with characters and low resolution. Do you ever feel like creating swirling, intricate webs of delicate, slender lines? Here's how to achieve high resolution on the VIC.

The designers of the VIC-20 thoughtfully included in the VIC chip a special programmable character generator. Though mainly intended for creating custom alphabets and symbols, it can also be used to generate an entire high-resolution screen.

Each character that the VIC puts on the screen, whether user-defined or standard, is stored in eight bytes of memory. Each byte defines one of the eight rows that comprises a VIC character. Furthermore, each of the rows is split up into eight sections corresponding to the eight bits in that row's byte. If a bit is on (there is a 1 in its location), then its chunk of the row is lit up. If a bit is off (it contains a 0), then its chunk of the row is blank.

Character Matrices

"Microdraw" sets up a matrix of 12 X 15 custom characters, all of which are initially made blank (by POKEing 0 into the defining bytes). Since each character is defined by eight bytes of eight bits each, we have a total of 11,520 bits, or dots, on the screen which we can turn on or off at will. To light up a dot, simply POKE a 1 into its corresponding bit.

Such high resolution comes at a price. In order to use custom characters, we first must set the character memory apart from the BASIC program area. Since we are using so many characters, a lot of memory is consumed—1.5K, nearly half the memory available in an unexpanded VIC.

Now that we've covered the theory, it's time to enjoy your VIC's hi-res capability. Type in Microdraw, save it, then run it. Plug in your joy­stick, if you have one. Select the foreground and background colors for the drawing area by pressing the number key with the appropriate color on it. The program will then set up the drawing area and display the cursor. You control the cursor by moving the joystick in the direction you want the cursor to go.

Initially, the cursor is in the erase mode, which means that the cursor does not create a line as it travels and will erase any line it comes in contact with. In this mode the TV speaker emits a low beeping tone.

To change to the drawing mode, press the fire button on the joystick. The TV speaker will then beep in a higher-pitched tone, and the cursor will leave a line as it travels. To change back to the erase mode, simply press the fire button once again.

The SAVE Function

The function keys offer three additional options: The fl key erases the drawing screen and leaves the cursor in position; f3 starts the program from the beginning and resets all variables; and f5 causes the program to jump to a screen-saving routine. The saving routine is self-explanatory, as is the retrieval routine. To replay the data you have stored, choose selection 2 ("load an old one").

If you do not have a joystick, a simple modification will allow you to use the keyboard instead. Delete lines 330 and 340, and change line 320 to read:

320 A = PEEK(197) : J0 = -(A=44): J1 = -(A=36):J2= -(A = 20) : J3 = -(A = 12) : IF A = 32 THEN B = ABS(B -1) rem  155

Now the cursor's up, down, left, and right motions are controlled by the I, M, J, and K keys, respectively. To change modes, press the space bar instead of the fire button. It is not necessary to hit the control keys repeatedly; the cursor will move as long as the key is held down. If no key is pressed, the cursor will stop. In all other respects, the program works as before.

Microdraw
10 POKE 36869, 240 : POKE 52, 24 : POKE 56, 24 :
   POKE 36879, 27 : CLR					: rem 84
40 PRINT " {CLR}{3 DOWN}l) DRAW A NEW PICTURE.
   {DOWN}2) LOAD AN OLD  ONE. " : POKE 198, 0 	: rem 105
60 GET A$ : IF A$ < > " 1 " AND
   A$ < > " 2 " THEN 60				: rem 133
70 IF A$ = " 2 " THEN 450					: rem 214
80 PRINT "{CLR}{3 DOWN} BORDER COLOR?" : GOSUB 100 :
   G = VAL(A$) - 1						: rem 123
90 PRINT "{3 DOWN)BACKGROUND COLOR?" : GOSUB 100 :
   H = VAL (A$): GOTO 120					: rem 180
100 GET A$:IF A$ < " 1 " OR A$ > " 8 "
    THEN 100							: rem 53
110 RETURN							: rem 114
120 POKE 36879, G + 16 * H - 8: PRINT "{CLR}"	: rem 77
130 FOR X = 0 TO 21 : FOR Y = 0 TO 22 : POKE 7680 + X + 22 * Y,
    160 : POKE 38400 + X + 22 * Y, G : NEXT		: rem 44
140 IF W = 1 THEN 160					: rem 175
150 FOR I = 6144 TO 7679 : POKE I, 0 : NEXT : FOR I = 742
    4 TO 7431 : POKE I,255 : NEXT			: rem 182
160 C = 0 : POKE 36869, 254: FOR X = 5 TO 16 : FOR Y = 3 TO 18 :
    IF X + Y = 34 THEN NEXT : GOTO 180			: rem 53
170 C = C + 1 : POKE 7680 + X + 22 * Y, C :
    NEXT : NEXT						: rem 235
180 Y = 18 : FOR X = 3 TO 18 : POKE 7680 + X + 22 * Y,
    160 : NEXT : C = 90					: rem 191
190 IF J1 THEN F = F + 1 : IF F > 7 AND (C + l)/16 < >
    INT ((C+l)/l6)THEN F = 0 : C = C + l: GOTO 210	:rem 82
200 IF F > 7 THEN F = 7					: rem 197
210 IF J3 THEN F = F - 1 : IF F < 0 AND(C-1)/16 < >INT
    (( C-l)/l6) THEN F = 7 : C = C - l : GOTO 230	: rem 85
220 IF F < 0 THEN F = 0					: rem 183
230 IF J0 THEN E = E + 1 : IF E > 7 AND C < 177 THEN
    E = 0 : C = C + 16 : GOTO 250			: rem 222
240 IF E > 7 THEN E = 7					: rem 199
250 IF J2 THEN E = E - 1 : IF E < 0 AND C > 16 THEN E = 7 :
    C = C - 16 : GOTO 270					: rem 176
260 IF E < 0 THEN E = 0					: rem 185
270 POKE 6144 + (8 * C) + F, PEEK (6144 + (8 * C) + F) AND
    NOT(2↑(7 - E))						: rem 203
280 POKE 6144 + (8 * C) + F, PEEK (6144 + (8 * C) + F)
    OR 2↑(7 - E)					: rem 88
290 POKE 36878, 15 : POKE 36874 + 2 * B, 130 + INT
    (c/2.14): POKE 36878, 0				: rem 221
300 POKE 36874 + 2 * ABS (B - 1), 0			: rem 120
310 IF B = 0 THEN POKE 6144 + (8 * C) + F,
    PEEK (6144 + (8 * C) + F) - 2↑(7 - E)		: rem 75
320 POKE 37154, 127 : Z = 128 AND PEEK (37152) :
    J0 = - (Z = 0)						: rem 123
330 POKE 37154, 255 : Z = PEEK (37151)			: rem 217
340 Jl = - ((ZAND8) = 0) : J2 = - ((ZAND16) = 0) : J3 = - ((ZAND4 )=0) :
    J = -((ZAND32) = 0) : IF J THEN B = ABS(B - l)	: rem 91
350 GET A$ : IF A$ lt; > CHR$ (133) AND A$ < > CHR$134)
    AND A$ < > CHR$ (135) THEN 190			: rem 112
360 IF A$ = CHR$ (134) THEN 10				: rem 68
370 IF A$ = CHR$ (135) THEN 390				: rem 129
380 FOR I = 6144 TO 7423 : POKE I,0 : NEXT :
    FOR I = 7432 TO 7679: POKE I,0: NEXT : GOTO 190:rem 92
390 POKE 36869, 240 : POKE 36879, 27			: rem 172
400 PRINT "{CLR}{DOWN}{RVS}T{OFF}APE OR
    {RVS}D{OFF}ISK?" : POKE 198, 0			: rem 237
402 GET A$ : IF A$ < > " T " AND A$ < >
    " D " THEN 402						: rem 26
405 IF A$ = " T " THEN PRINT
    "REWIND TAPE"						: rem 85
415 PRINT "HIT A KEY WHEN READY"			: rem 33
420 B$ = " " : GET B$ : IF B$ < >
    " " THEN 420						: rem 175
425 IF A$ = " T " THEN OPEN 1, 1, 1			: rem 176
426 IF A$ = " D " THEN INPUT "FILENAME"; N$ :
    N$ = N$ + ", S, W" :D = 8 : OPEN l, 8, 5, N$	: rem 5
430 PRINT #1, G : PRINT # 1, H : FOR A = 6144 TO 7679 :
    PRINT # 1, PEEK (A) : NEXT : CLOSE l		: rem 192
440 PRINT "{CLR} YOUR PICTURE IS SAVED." :
    GOTO 10							: rem 120
450 PRINT "{DOWN}{RVS} T {OFF} APE OR
    {RVS}D{OFF}lSK?" : D = l : N$ = " "		: rem 17
455 GET A$ : IF A$ < > " T " AND A$ < >
     " D " THEN 455						: rem 42
460 IF A$ = " T " THEN PRINT "{3 DOWN} INSERT
    CASSETTE AND{3 SPACES} REWIND IT"			: rem 0
470 PRINT "{DOWN}WHEN YOU ARE READY HIT (SPACE).{DOWN}" :
     W = l : WAIT 198, l					: rem 71
475 IF A$ = " T " THEN OPEN 1, 1, 0			: rem 180
480 IF A$ = " D " THEN INPUT" FILE NAME";
    N$ : D = 8 : N$ = N$ + ", S, R" :
    OPEN 1,8,5, N$						: rem 0
490 INPUT #l, G : INPUT #l, H: FOR A = 6144 TO 7679 : INPUT #1,
    C : POKEA, C : NEXT : CLOSE 1			: rem 116
500 GOTO 120							: rem 97
10000 OPEN 15, 8, 15 : INPUT #15, A, B$, C, D :
      CLOSE 15						:rem 198