Classic Computer Magazine Archive COMPUTE! ISSUE 86 / JULY 1987 / PAGE 105

Smooth-Scrolling Billboard

For Commodore 64

Paul W. Carlson

This program turns your Commodore 64 into an electronic billboard, smoothly scrolling large, multicolored messages across the screen.

Would you like to be able to glide a message across the Commodore 64's screen in giant, multicolored letters? The program with this article makes it easy. Or perhaps you're a machine language programmer interested in smooth-scrolling techniques. This article explains how it's done.

Jumbo Billboard

To see smooth scrolling in action, type in, save, and run the program. The program takes a few seconds to read the machine language in the DATA statements and then asks if you want multicolored letters. Respond by pressing Y (yes) or N (no); do not press RETURN. The upper part of the screen fills with arrow symbols, with the cursor positioned over the first arrow symbol. Starting at the cursor, type in the text that you want to scroll across the screen. Your text will replace the arrow symbols as you type. Any nongraphics characters can be used (although lowercase letters will scroll as uppercase). You can make changes to your text by overtyping the unwanted letters or by using the DEL key.

Press RETURN when you have entered the entire message. The program reads all of the text up to the first arrow symbol. If the program doesn't find an arrow symbol, it uses the first 250 characters (including blanks) of the message. After you press RETURN, the billboard immediately starts to scroll. The message continues to scroll with two spaces separating the end of the text from the beginning. If you want more separation, add extra spaces at the end of your text. To stop the program, press any key while the text is scrolling.

Changing Colors

You can easily modify the program to display colors of your own choosing. The numbers in lines 70–90 can be changed to any legal color number (0–15). When multicolor letters are in use, the program uses the color numbers in lines 160–230 instead of the foreground color in line 80. The color numbers in lines 160–230 can also be changed to any legal color number. This allows you to match the colors to the content of your message. For example, the letters in a patriotic message might have alternating red and white stripes against a blue background.

If you simply want to use the program, you needn't read any further. The remainder of this article discusses techniques which machine language programmers may find interesting.

Text Input

In order to work, this program must pass a long string—the text of your message—to a machine language subroutine. You may wonder why a simple INPUT statement isn't used to enter the message. After all, that's what INPUT is designed to do. There are two reasons why it isn't used. First, certain characters that you might want to use in your text, such as quotation marks, colons, and commas, can cause problems with INPUT. Second, INPUT can only handle strings up to 80 characters in length, but you might want to display a longer message.

The same limitations apply to the INPUT# statement. In fact, the program takes advantage of the way that INPUT# responds to a colon as input. The INPUT# statement in line 280 halts the program, reads data from the keyboard buffer, and continues execution when you press RETURN. Before we execute that INPUT#, however, the program manipulates the keyboard buffer to prevent INPUT# from processing the text that you type. Line 240 POKEs four values into the keyboard buffer, where they will be found by the INPUT# in line 280. The four values are the ASCII codes for a colon, left cursor, arrow symbol, and left cursor. The colon, because it is a delimiter, causes INPUT# to disregard anything that follows. This allows you to type anything you want without causing an error message. When INPUT# is executed, anything in the keyboard buffer is displayed. The left cursor, arrow symbol, and left cursor are placed in the keyboard buffer to restore the screen by overwriting the colon with an arrow symbol and moving the cursor back to the first screen location.

Smooth Scrolling

As you can see by looking carefully, the large letters move horizontally one pixel (screen dot) at a time, making for very smooth movement. The 64's VIC (Video Interface Controller) chip can instantly position the screen at any one of eight pixel positions. This, combined with the VIC's ability to instantly change the location screen memory, allows you to scroll shapes one pixel at a time. For machine language programmers, here are the steps this programs uses for smooth scrolling:

1. Set aside two 1000-byte memory areas for screen data. One of these can be the normal screen memory area, which starts at location 1024 ($0400). Next, set up pointers in zero-page memory to the two screen memory locations. We'll refer to these locations as SRCE and DEST (for source and destination). In this program, the two screen memory locations are 1024 ($0400) and 15360 ($3C00). It makes no difference which location is initially SRCE or DEST.

2. Clear both screens and fill color memory at locations 55296–56295 ($D800–$DFE7). The four high-order bits of location 53272 ($D018) control which screen is active. Make DEST the active screen. Set the screen size to 38 columns by clearing bit three of location 53270 ($D016). Set the scroll position to seven by setting the three low-order bits of 53270 ($D016).

3. Swap the pointers to SRCE and DEST and copy columns 1–39 of the SRCE screen to columns 0–38 of the DEST screen.

4. Fill column 39 of the DEST screen with new data.

5. Using a time delay, decrement 53270 ($D016) until the three low-order bits are zero. The time delay is approximately equal to the execution time of steps 3 and 4 to prevent jerking.

6. Wait until location 53266 ($D012) equals zero (indicating raster line zero), and then make the inactive screen the active screen and immediately set the scroll position to seven. Go to step 3.

Steps 3 and 4 are performed only on screen rows 9–17 in this program, since these are the only rows that change. In many programs that use smooth scrolling, the time delay between each decrement of 53270 ($D016) in step 5 would be replaced with routines that move sprites, check for collisions, and so on. When this is the case, a time delay loop will usually be needed at the end of step 4 to make the execution time of steps 3 and 4 equal the execution time between decrements of 53270 ($D016).

Smooth scrolling is not as difficult as you may think. The VIC chip does much of your work for you. This article has described only horizontal smooth scrolling, but that's the most difficult direction to scroll. Vertical smooth scrolling is much easier. If you've never tried smooth scrolling, I hope that this article will encourage you to do so. You can find more information about scrolling in Programming the 64 by Raeto West, and Mapping the 64 and 64C by Sheldon Leemon; both books are available from COMPUTE! Books.

Smooth-Scrolling Billboard

For instructions on entering this program, please refer to "COMPUTEI's Guide to Typing In Programs" elsewhere in this issue.

PG 5 REM COPYRIGHT 1987 COMPUTE! PUBLICATIONS, INC {3 SPACES}ALL RIGHTS RESERVED.
RS 10 POKE55, 255: POKE56, 59: CLR: POKE53272,(PEEK(53272)AND15)OR16
RX 11 PRINT"{CLR}"
RS 12 PRINTTAB(12); "COPYRIGHT {SPACE}1987":PRINTTAB(6);"COMPUTE! PUBLICATIONS, INC.
JK 14 PRINTTAB(10);"ALL RIGHTS RESERVED."
PF 15 FOR X = 1TO1200:NEXT
KH 20 PRINTCHR$(147);"READING {SPACE}MACHINE CODE…": PRINT
BR 30 T = 0: FORN = 49152TO49640: READK: POKEN, K:T = T + K: NEXT
FF 40 IFT = 72434THEN70
XA 50 PRINT"***ERROR IN DATA STATEMENTS ***":END
RX 60 REM ** SCREEN	 COLORS **
XK 70 BG = 0 :REM BACKGROUND
CR 80 FG = 15:REM FOREGROUND
JF 90 BR = 0 :REM BORDER
KC 100 PRINT"MULTI-COLOR LETTERS (Y/N)? ";
MP 110 GETA$: IFA$ = ""THEN110
BM 120 PRINTA$:IF A$ <> "Y"ANDA$ <> "N"THEN 100
BK 130 IF A$ = "N" THENPOKE49649, 0: GOTO 240
DM 140 POKE49649, 1
EP 150 REM ** MULTI-COLOR LETTER COLORS **
MF 160 POKE49648, 4 :REM TOP
QJ 170 POKE49647, 2 :REM 2ND
GF 180 POKE49646, 8 :REM 3RD
HR 190 POKE49645, 7 :REM 4TH
XJ 200 POKE49644, 3 :REM 5TH
SR 210 POKE49643, 5 :REM 6TH
SD 220 POKE49642, 6 :REM 7TH
XS 230 POKE49641, 14 :REM 8TH
EK 240 POKE198, 4: POKE631,58: POKE632,157: POKE633,95: POKE634.157
BF 250 PRINTCHR$(147):FORN = 1TO12:PRINT:NEXT
EA 260 PRINT"{2 SPACES}ENTER TEXT AT CURSOR - PRESS [RETURN]{3 SPACES}WHEN FINISHED.";CHR$(19);
QC 270 FORN = 0TO250:PRINTCHR$(95);:NEXT:PRINTCHR$(19);
BG 280 OPEN1,0:INPUT#1,A$
CD 290 POKE53280,BR:POKE53281, BGsPOKE49261,FG
XH 300 SYS49152
BH 310 POKE53280,14:POKE53281, 6:PRINTCHR$(147);CHR$(154);
ER 320 POKE55,0:POKE56,160:CLR:END
JG 330 DATA 173, 14, 220, 41, 254, 141, 14, 220
DK 340 DATA 165, 1, 41, 251, 133, 1, 169, 0
HC 350 DATA 133, 251, 133, 253, 169, 208, 133, 252
RD 360 DATA 169, 196, 133, 254, 162, 2, 160, 0
XQ 370 DATA 177, 251, 145, 253, 200, 208, 249, 230
CG 380 DATA 252, 230, 254, 202, 208, 240, 165, 1
SS 390 DATA 9, 4, 133, 1, 173, 14, 220, 9
EM 400 DATA 1, 141, 14, 220, 162, 0, 160, 0
QR 410 DATA 189, 0, 4, 201, 31, 240, 11, 153
BS 420 DATA 0, 198, 232, 224, 250, 240, 3, 200
KE 430 DATA 208, 238, 169, 32, 153, 0, 198, 200
HB 440 DATA 153, 0, 198, 200, 169, 0, 153, 0
KF 450 DATA 198, 173, 241, 193, 208, 24, 133, 253
BQ 460 DATA 169, 216, 133, 254, 169, 14, 162, 4
BG 470 DATA 160, 0, 145, 253, 200, 208, 251, 230
JK 480 DATA 254, 202, 208, 246, 240, 38, 169, 104
MP 490 DATA 133, 253, 169, 217, 133, 254, 162, 8
JJ 500 DATA 160, 0, 189, 232, 193, 145, 253, 200
RX 510 DATA 192, 40, 208, 246, 165, 253, 24, 105
MA 520 DATA 40, 133, 253, 165, 254, 105, 0, 133
CG 530 DATA 254, 202, 208, 228, 169, 4, 133, 252
BA 540 DATA 169, 60, 133, 254, 169, 0, 133, 251
CM 550 DATA 133, 253, 162, 4, 160, 0, 169, 32
SH 560 DATA 145, 251, 145, 253, 200, 208, 249, 230
SK 570 	DATA 252, 230, 254, 202, 208, 242, 173, 22
HM 580 	DATA 208, 41, 247, 141, 22, 208, 169, 0
BH 590 	DATA 141, 250, 193, 172, 250, 193, 238, 250
CD 600 	DATA 193, 185, 0, 198, 240, 242, 133, 251
PR 610 	DATA 169, 0, 133, 252, 6, 251, 38, 252
EX 620 	DATA 6, 251, 38, 252, 6, 251, 38, 252
DA 630 	DATA 169, 196, 24, 101, 252, 133, 252, 160
PF 640 	DATA 0, 177, 251, 153, 242, 193, 200, 192
DJ 650 	DATA 8, 208, 246, 32, 228, 255, 201, 0
HA 660 	DATA 240, 27, 173, 22, 208, 9, 8, 141
SA 670 	DATA 22, 208, 173, 24, 208, 41, 15, 9
KM 680 	DATA 16, 141, 24, 208, 173, 22, 208, 41
FE 690 	DATA 248, 141, 22, 208, 96, 169, 61, 133
HA 700 	DATA 252, 169, 5, 133, 254, 169, 0, 141
DB 710 	DATA 251, 193, 165, 252, 164, 254, 133, 254
QQ 720 	DATA 132, 252, 169, 104, 133, 251, 133, 253
FC 730 	DATA 162, 8, 160, 39, 177, 251, 136, 145
KG 740 	DATA 253, 192, 0, 208, 247, 202, 240, 28
EG 750 	DATA 165, 251, 24, 105, 40, 133, 251, 165
FH 760 	DATA 252, 105, 0, 133, 252, 165, 253, 24
XX 770 	DATA 105, 40, 133, 253, 165, 254, 105, 0
DH 780 	DATA 133, 254, 208, 214, 198, 254, 169, 143
MD 790 	DATA 133, 253, 162, 0, 160, 0, 30, 242
XP 800 	DATA 193, 144, 4, 169, 160, 208, 2, 169
RQ 810 	DATA 32, 145, 253, 232, 165, 253, 24, 105
JR 820 	DATA 40, 133, 253, 165, 254, 105, 0, 133
CK 830 	DATA 254, 224, 8, 208, 225, 173, 22, 208
RP 840 	DATA 9, 7, 141, 22, 208, 162, 0, 160
AB 850 	DATA 6, 202, 208, 253, 136, 208, 250, 206
RB 860 	DATA 22, 208, 173, 22, 208, 41, 7, 208
ED 870 	DATA 236, 198, 252, 198, 254, 173, 24, 208
HS 880 	DATA 41, 15, 166, 254, 224, 61, 208, 4
PQ 890 	DATA 9, 240, 208, 2, 9, 16, 162, 0
EF 900 	DATA 236, 18, 208, 208, 251, 141, 24, 208
KH 910 	DATA 173, 22, 208, 9, 7, 141, 22, 208
DF 920 	DATA 174, 251, 193, 232, 224, 8, 240, 6
HM 930 	DATA 142, 251, 193, 76, 50, 193, 76, 211
SH 940 	DATA 192