This program simulates a nine-lane racing game with betting mechanics, where the player wagers dollars on one of nine numbered racers. It defines six UDG characters (spanning character slots “a” through “m” and “h”) by POKEing 48 bytes of bitmap data to represent racer sprites, track graphics, and animation frames. The main race loop uses computed GO TO via the expression `r*1000` to dispatch randomly to one of nine racer-advance routines (lines 1000–9030), each of which moves a different racer across its screen row until it reaches column 31. SOUND commands with multiple channel parameters provide engine noise and race atmosphere, while BEEP produces pitch-varying tones tied to each racer’s current position. A world-record timer tracks elapsed tenths-of-seconds, and a short melody plays from DATA statements at race end using a READ/BEEP loop.
Program Analysis
Program Structure
The program divides into several logical phases:
- Initialization (lines 1–110): Sets paper/border/bright attributes, then POKEs UDG bitmap data for six character definitions covering slots
"a"through"f"(48 bytes, 6 UDGs),"m"(8 bytes), and"h"(8 bytes). - Track setup and betting (lines 132–138): Draws lane dividers with dashes, prompts for a chosen racer (1–9), and accepts a wager with a guard preventing over-betting.
- Race animation intro (lines 140–208): Displays a starting grid graphic, animates a flashing start sequence using UDG characters with SOUND effects, plots side boundary lines, and draws lane numbers.
- Main race loop (lines 209–220): Maintains a seconds/tenths timer, plays tick sounds, and uses
GO TO r*1000to randomly dispatch to one of nine racer routines. - Racer advance routines (lines 1000–9030): Nine blocks, each handling one racer lane, advancing its sprite one column and checking for a finish at column 32.
- Finish sequence and scoring (lines 9500–9730): Announces the winner, plays a melody from DATA, checks/updates the world record, evaluates the bet, and offers replay.
UDG Definitions
Three separate FOR/READ/POKE loops load custom character bitmaps:
| Loop (lines) | Slots covered | Bytes |
|---|---|---|
| 10–70 | "a" through "f" | 48 |
| 80–90 | "m" | 8 |
| 100–110 | "h" | 8 |
The DATA statements use a variable n at several positions, but n is never initialized before the READ loops execute. This is a latent bug: n will default to 0 in most implementations, so those entries silently become 0, likely giving correct zero-byte rows intentionally or by convention.
Computed GO TO Dispatch
The core routing mechanism at line 220 is GO TO r*1000, where r is an integer from 1 to 9 produced by INT(RND*9+1) at line 210. This jumps to lines 1000, 2000, …, 9000 — one block per racer. Each block prints the racer’s UDG sprite at its current column, increments the column counter, checks for reaching column 32 (finish), and loops back to line 210. This is an efficient alternative to a long IF/THEN chain.
Race Timer
Lines 209–214 implement a software timer. Variable t counts tenths and s counts whole seconds. Each pass through the main loop increments t; when t reaches 9, it resets and s increments. The elapsed time is assembled at line 9508 as rt = s + (t/10), giving a single decimal value used for world-record comparison and display.
SOUND and BEEP Usage
SOUND commands appear extensively with multi-channel parameters (channels 6–13) to produce engine noise during race startup and running. BEEP is used for per-tick clicks and for the victory melody. The melody at lines 9521–9528 reads pairs of duration/pitch values from DATA, divides the duration by 16 to get fractional seconds, and calls BEEP in a loop until sentinel value 999 is encountered. The DATA spans five lines (9524–9528) covering two melodic phrases plus a terminating 999,999.
Betting and Scoring
The player’s bankroll is held in o (initialized to 10 at line 1). Variable l is the bet amount, validated at line 137. Winnings are calculated at line 9515 as b = INT((l*5) - (3*RND)), giving approximately 5× the stake with slight random variation. Line 9600 adds winnings if the chosen racer k equals r; line 9601 deducts the bet otherwise. Line 9610 stops the program if o drops to zero or below.
World Record Tracking
Variables wr (initialized to 100) and w track the best race time and winning racer number across games. Line 9530 updates the record if the current race time rt beats wr. The condition at line 9520 (IF wr>=rt THEN GO SUB 9509) triggers a celebratory UDG animation routine whenever a record is equaled or beaten.
Notable Techniques and Anomalies
- Line 132 uses
FOR x=PI TO 19 STEP 2, starting the loop at approximately 3.14159. Since the loop variable is used only as an AT row index, this effectively starts at row 3 (truncated), which is an unusual but functional choice. - The
RESTORE 9529/GO TO 9529/RESTORE 9524sequence at lines 9529 means the melody DATA is re-read from line 9524 after the first play, enabling replay across multiple race rounds. - Line 9511 contains
NEXT g: RETURN, but the FOR loop forgat line 9509 has no corresponding NEXT that would be reached normally — line 9510 NEXTs and line 9511’s NEXT would fire only if control falls through, which it cannot due to PAUSE. The RETURN suggests this block was intended as a subroutine, but it is only ever reached via GO SUB 9509 which calls into the middle of a FOR loop structure — a structural oddity. - The replay loop at lines 9720–9730 animates a wipe effect then prints 350 space-asterisk pairs before clearing the screen and saving the program with
SAVE "RACER" LINE 1, ensuring auto-restart on reload. - Variable reuse is notable:
f,g, andbare used both as racer position counters in the mid-race routines and as general loop/calculation variables in the finish sequence, relying on the race being over before those variables are reused.
Content
Source Code
1 LET o=10: LET wr=100
5 PAPER 7: BORDER 7: BRIGHT 0: CLS
10 FOR x=0 TO 47: READ n: POKE USR "a"+x,n: NEXT x
20 DATA 12,n,120,94,90,48,36,n
30 DATA 48,n,30,120,90,24,36,n
40 DATA 48,n,31,249,24,120,78,194
50 DATA 24,n,189,219,24,n,n,60
60 DATA 153,n,255,24,n,36,66,195
70 DATA 28,12,8,60,n,254,24,60
80 FOR x=0 TO 7: READ n: POKE USR "m"+x,n: NEXT x
90 DATA 12,n,248,159,24,30,114,67
100 FOR x=0 TO 7: READ n: POKE USR "h"+x,n: NEXT x
110 DATA 0,6,n,60,n,36,228,132
132 FOR x=PI TO 19 STEP 2: PRINT AT x,0; BRIGHT 0; INK 0;"------------------------------": NEXT x
134 INPUT "Who do you want to win 1 TO 9 ";k
135 PRINT AT 0,0;"You have ";o;" dollars to bet.",,,
136 INPUT "PLACE YOUR BETTS ";l
137 IF l>o THEN GO TO 135
138 PRINT AT 1,0;"YOU BET ";l;" on ";k;" ",
140 PRINT AT 0,0; BRIGHT 0; INK 2;"\: \..\..\..\: \..\..\..\..\..\..\: \..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:\:.\..\..\..\..\.:\..\..\..\..\.:\..\..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:\..\..\..\.:": PAUSE 100
190 RANDOMIZE : LET j=3: LET a=j: LET b=j: LET c=j: LET d=j: LET e=j: LET f=j: LET g=j: LET h=j: LET i=j
200 FOR x=30 TO 0 STEP -1: SOUND 6,20;7,7;8,16-(x/2);9,16-(x/2);10,16-(x/2);12,255;13,1: PAUSE 10
201 PAPER 6: PRINT AT 0,x;"\c";AT 1,30-x;"\a": PAUSE 5: PRINT AT 0,x;"\d";AT 1,30-x;"\d": PRINT AT 1,30-x*RND;"\f";AT 0,x*RND;"\f";AT 0,30-x*RND;"\f";AT 1,x*RND;"\f": NEXT x
202 FOR x=1 TO 31: PAPER 6: BRIGHT 1: PRINT AT 0,x*RND;"\f";AT 1,x*RND;"\f": RANDOMIZE : PRINT AT 0,x*RND;"\f";AT 1,x*RND;"\f": NEXT x
203 PRINT AT 0,0; BRIGHT 0; PAPER 6;"\:.\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\.:";AT 1,0;"\:.\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\f\.:_"
205 FOR x=2 TO 18 STEP 2: PRINT AT x,0; INK x/6; PAPER 7; BRIGHT 1;x/2;" \d",,: PAUSE 5: NEXT x
206 FOR y=10 TO 159: PLOT 24,y: PLOT 245,y: NEXT y
207 FOR x=2 TO 18 STEP 2: PRINT AT x,0; INK x/6; PAPER 7; BRIGHT 1;x/2;" \h": NEXT x
208 PAUSE 40: SOUND 6,15;7,7;8,16;9,16;10,16;12,10;13,0
209 LET t=0: LET s=t
210 LET r=INT (RND*9+1)
211 LET t=t+1: IF t=9 THEN LET t=0: LET s=s+1
212 PRINT AT 20,0;"SEC. TENTHS "
213 PRINT AT 21,0;" \.'";s;" : ";t;"\.'"
214 IF t=9 THEN LET t=0: LET s=s+1
215 BEEP .001,50
216 SOUND 6,20;7,7;8,5;9,3;10,8;12,255;13,1:
217 PRINT AT 0,31*RND; BRIGHT 0; PAPER 6; FLASH 1;"\f";AT 1,31*RND;"\f"
218 PRINT AT 0,31*RND; BRIGHT 0; PAPER 6; FLASH 0;"\f";AT 1,31*RND;"\f"
220 GO TO r*1000
1000 PAPER 7: BRIGHT 1: INK 0: PRINT AT 2,a-1;"\m": BEEP .001,60-a: PRINT AT 2,a-1;" \a"
1020 LET a=a+1: IF a=32 THEN GO TO 9500
1030 GO TO 210
2000 INK 3: PAPER 7: BRIGHT 1: PRINT AT 4,b-1;"\m": BEEP .001,60-b: PRINT AT 4,b-1;" \a"
2020 LET b=b+1: IF b=32 THEN GO TO 9500
2030 GO TO 210
3000 INK 1: PAPER 7: BRIGHT 1: PRINT AT 6,c-1;"\m": BEEP .001,60-c: PRINT AT 6,c-1;" \a"
3020 LET c=c+1: IF c=32 THEN GO TO 9500
3030 GO TO 210
4000 INK 3: PAPER 7: BRIGHT 1: PRINT AT 8,d-1;"\m": BEEP .001,40: PRINT AT 8,d-1; INK 0;" \a"
4020 LET d=d+1: IF d=32 THEN GO TO 9500
4030 GO TO 210
5000 INK 0: PAPER 7: BRIGHT 1: PRINT AT 10,e-1;"\m": BEEP .001,45: PRINT AT 10,e-1;" \a"
5020 LET e=e+1: IF e=32 THEN GO TO 9500
5030 GO TO 210
6000 PAPER 7: INK 2: BRIGHT 1: PRINT AT 12,f-1;"\m": BEEP .001,35: PRINT AT 12,f-1;" \a"
6020 LET f=f+1: IF f=32 THEN GO TO 9500
6030 GO TO 210
7000 INK 1: PAPER 7: BRIGHT 1: PRINT AT 14,g-1;"\m": BEEP .001,60: PRINT AT 14,g-1;" \a"
7020 LET g=g+1: IF g=32 THEN GO TO 9500
7030 GO TO 210
8000 INK 3: PAPER 7: BRIGHT 1: PRINT AT 16,h-1;"\m": BEEP .001,50-h: PRINT AT 16,h-1;" \a"
8020 LET h=h+1: IF h=32 THEN GO TO 9500
8030 GO TO 210
9000 PAPER 7: BRIGHT 1: PRINT AT 18,j-1; INK 2;"\m": BEEP .001,60-j: PRINT AT 18,j-1;" \a"
9020 LET j=j+1: IF j=32 THEN GO TO 9500
9030 GO TO 210
9500 BEEP .1,45: PRINT AT r*2,31; FLASH 1;"\m": PAUSE 30
9501 PRINT AT r*2,31;" ": LET x=r*2: FOR u=x TO 21
9502 BEEP .001,u+30: PRINT AT u,31;"\m": PAUSE 10: BEEP .001,u+33: PRINT AT u,31;"\a": BEEP .001,50: PAUSE 10: PRINT AT u,31;" "
9505 NEXT u
9507 FOR y=30 TO 16 STEP -1: PRINT AT 21,y;"\b ": BEEP .001,y+30: PAUSE 10: PRINT AT 21,y;"\c ": BEEP .001,40: PAUSE 10: NEXT y
9508 LET rt=s+(t/10): GO TO 9512
9509 PRINT AT 0,0;"\a";:: FOR g=0 TO 17: PRINT ; INK RND*3; PAPER 6; BRIGHT 1*RND; FLASH 1*RND;"\a\b\e \c\c\a\m\c \a\b\c\d\e\d\c \b\b \b\b\c\c\d\d\a\a\e\m\a\e\b\d\a";
9510 PAUSE 10: SOUND 6,13;7,7;8,16;9,16;10,16;12,255;13,1: NEXT g
9511 PAUSE 10: SOUND 6,15;7,7;8,16;9,16;10,16;12,255;13,1: NEXT g: RETURN
9512 LET rt=s+(t/10)
9514 FOR f=1 TO 10: PRINT AT 20,16;"\e";AT 21,16;" ": BEEP .1,20+(f*3): PRINT AT 21,0;".The winner is \d ";r;" in ";rt;"sec";AT 20,16;" ": BEEP .1,40: NEXT f
9515 LET b=INT ((l*5)-(3*RND))
9520 IF wr>=rt THEN GO SUB 9509
9521 READ d,p: LET d=d/16
9522 IF p=999 THEN GO TO 9529
9523 BEEP d,p: GO TO 9521
9524 DATA 4,7,8,7,2,4,4,4,4,7,8,7,2,2,4,2,4,4,4,5,4,7,4,9,4,11,8,7,8,69
9525 DATA 4,7,8,7,2,4,4,4,4,7,8,7,2,2,4,2,4,14,4,13,4,14,4,16,4,9,8,14,8,69
9526 DATA 4,7,8,16,2,16,4,14,4,12,8,12,2,11,4,11,4,12,4,14,4,11,4,9,4,7,8,12,8,69
9527 DATA 4,12,8,12,2,9,4,9,4,12,8,12,2,7,4,7,4,7,4,9,4,12,4,7,4,14,16,12
9528 DATA 999,999
9529 RESTORE 9524: PAUSE 100
9530 IF wr>rt THEN LET wr=rt: PRINT AT 19,0; FLASH 1;"#";r;" has set a World Record": LET w=r
9540 PRINT AT 20,0;"The WORLD RECORD IS ";wr;" by #";w: PAUSE 200
9600 IF r=k THEN PRINT AT 0,0;"YOU HAVE WON- ";b;" ": LET o=o+b
9601 IF r<>k THEN PRINT AT 0,0;"You lost $";l;".You have ";o-l;" left.": LET o=o-l
9610 IF o<=0 THEN PRINT AT 0,10; FLASH 1;"You are busted!!!": STOP
9700 INPUT "Do you want to play again? ";i$
9711 IF i$="n" THEN STOP
9720 PRINT AT 21,0; INK 2;"________________"
9721 FOR y=16 TO 0 STEP -1: PRINT AT 21,y;"\b ": BEEP .001,y+30: PAUSE 10: PRINT AT 21,y;"\c ": BEEP .001,40: PAUSE 10: NEXT y:
9730 PRINT AT 0,0;" ";: FOR x=0 TO 350: PRINT " *";: BEEP .001,50: NEXT x: CLS
9740 SAVE "RACER" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
