I was wondering how to move a collection of characters (e.g. a box) across a Commodore 64 text screen. It’s rather easy to do this destructively. In Basic, I wrote something that horizontally moves a 3-by-3 character rectangle constructed out of PETSCII characters.


10 rem ***
11 rem *** setup
12 rem ***
20 restore:read w,h:for i=0 to w*h-1
30 read a(i):next i
40 data 3,3
50 data 112,64,110,93,32,93,109,64,125
60 te=200
100 rem ***
101 rem *** main loop
102 rem ***
110 os=0
120 for p=1024+12*40top+40-w
130 gosub 200:gosub 300:next p
140 os=w-1
150 for p=1024+13*40-w to p-39+w step-1
160 gosub 200:gosub 300:next p
170 goto 100
199 end
200 rem ***
201 rem *** draw a box
202 rem ***
210 for x=0 to w-1:for y=0 to h-1
220 poke p+y*40+x,a(y*w+x)
230 nexty:nextx:fort=0tote:nextt:return
300 rem ***
301 rem *** clear column
302 rem ***
310 for y=0toh-1:poke p+y*40+os,32:next
320 return

The program has to do some clean-up after it has drawn a box with the subroutine draw a box. It fills the box’s trailing text column with space characters (screen code 32). For instance, if the box moves to the right and the box has been drawn in its current position, the left-most text column of that box has to be “cleared” (filled with spaces). Otherwise it will leave behind box characters when the next position of the box is drawn—one position to the right. The main loop uses the variable os (offset) to determine which text column should be filled with spaces, using the same subroutine clear column when moving the text box to the left or to the right.

It’s all very limited in what this program can do. It can move the box either one character position to the right or the same to the left, nothing more.

For a more sophisticated draw a box subroutine, it has to know where it was before:

  • restore the original content of the previous position (if any)
  • read the current content where the box will appear and store it for later
  • draw the box onto its position on the text screen

We can do this in Basic as well, even though it’s rather slow and has clear visual artifacts. Here’s the code for the same 3 by 3 text box, now jumping to arbitrary positions on the screen, while keeping the screen intact.


10 rem ***
11 rem *** setup
12 rem ***
20 restore:read w,h:for i=0 to w*h-1
30 read a(i):next i
40 data 3,3
50 data 112,64,110,93,32,93,109,64,125
60 te=200
70 first = (1 = 1)
100 rem ***
101 rem *** main loop
102 rem ***
110 x=int(rnd(ti)*(40-w))
120 y=int(rnd(ti)*(25-h))
130 gosub 200
140 goto 100
199 end
200 rem ***
201 rem *** draw a box
202 rem ***
210 rem *** restore any orig'l content
211 rem ***
220 if first then first=(1=0):goto 300
230 for xx =0 to w-1:for yy=0 to h-1
240 poke p+yy*40+xx,a1(yy*w+xx)
250 nextyy:nextxx
300 rem ***
301 rem *** read current text content
302 rem ***
310 p=1024+40*y+x
320 for xx=0 to w-1:for yy=0 to h-1
330 a1(xx+yy*w)=peek(p+xx+yy*40):
340 nextyy:nextxx
400 rem ***
401 rem *** put box on screen
402 rem ***
410 for xx=0 to w-1:for yy=0 to h-1
420 poke p+yy*40+xx,a(yy*w+xx)
440 nextyy:nextxx
450 for t=0 to te:next
460 return

The long wait loop (which makes the program perform so slow) is so that you can spot the random 3-by-3 box, while also making the artifacts less noticeable. You can see the box long enough, so it disappearing from screen will feel less jarring. A better solution than waiting a while would be to use a screen buffer to do the drawing and switch screen buffers when all the drawing is done for the new position of the box.

I guess that would require some machine language I have yet to write.