“On Your Mark!” is a horse-race simulation in which eight numbered runners advance across the screen driven by a random number generator. Two UDG characters are defined at startup — one representing a running figure (UDG “m”) and one an alternate pose (UDG “a”) — whose pixel patterns are loaded from DATA statements using BIN literals. Each of the eight racers occupies its own pair of thousand-numbered subroutine lines (1000–8000), and the dispatcher at line 220 uses the arithmetic expression `R*1000` to jump directly to the correct block. A BEEP and BORDER color change accompany each random step, providing audio-visual feedback. The player enters a number (1–8) as their bet, and the program announces a win or loss with FLASH and INK attributes when any racer crosses column 32.
Program Analysis
Program Structure
The program is organized into four logical phases:
- Initialization (lines 5–40): Two UDGs are defined by POKEing pixel data from DATA statements.
- Track setup (lines 100–135): Eight numbered lanes are drawn with UDG “a” separators, a finish line is PLOTted, and the player’s bet is collected via INPUT.
- Race loop (lines 200–8030): A random racer is chosen each iteration, dispatched via computed GO TO, advanced one column, and checked for the finish.
- Result display (lines 9500–9530): Win/loss is shown with FLASH and INK attributes; the player is offered a replay.
UDG Definition
Lines 10–40 define two UDGs using a FOR/READ/POKE loop. UDG "\m" (character 157, the moving runner) and UDG "\a" (character 144, the lane separator figure) each receive eight bytes of pixel data expressed as BIN literals, making the bitmaps human-readable in the listing. USR "\m" and USR "\a" return the base addresses of those UDG entries in RAM, and adding the loop variable X (0–7) addresses each row.
Computed GO TO Dispatch
The core dispatch mechanism at line 220 is:
GO TO R*1000
where R is an integer 1–8. This routes execution to lines 1000, 2000, … 8000, each handling one racer. This avoids a long IF/THEN chain and is an efficient BASIC dispatch table idiom. Each racer block is structurally identical: print the runner UDG at the current column, increment the position variable, check for column 32 (finish), and loop back to 210.
Race Variables and Finish Logic
Each racer’s horizontal position is tracked by a dedicated variable (A through H — note I is initialized at line 200 but never used, as only eight racers exist at lines 1000–8000). When any position variable reaches 32, the program jumps to line 9500 or 9050. Notably, racers 1 (variable A) and 7 (G) and 8 (H) jump to line 9500, while racers 2–6 jump to line 9050, which does not exist in the listing — this is a latent bug that would cause a “Line does not exist” error if any of racers 2–6 wins.
Track Drawing
Lines 100–125 draw the starting grid. The FOR X=2 TO 16 STEP 2 loop prints lane numbers (1–8 via X/2) and a row of UDG “a” characters as lane separators. Line 125 uses PLOT 248,Y in a loop from Y=31 to 159 to draw a vertical finish line at pixel column 248, which corresponds to screen column 31 — one column before the winning condition of position 32.
Audio-Visual Feedback
Each race step triggers BEEP .05,R and BORDER R-1 at line 215, so both the pitch and the border color vary with the randomly chosen racer, giving continuous audio and visual feedback during the race without any deliberate delay loop.
Notable Techniques and Anomalies
- Computed GO TO:
R*1000as the target expression is a clean dispatch table pattern. - BIN literals in DATA: Using
BINin DATA statements makes UDG bitmaps self-documenting. - Unused variable I:
Iis initialized at line 200 but no racer block at line 9000 exists; only eight racers (lines 1000–8000) are implemented. - Bug — missing line 9050: Racers 2 through 6 branch to
GO TO 9050on winning, but line 9050 is absent; this would cause a runtime error if any of those racers finishes first. - Bet stored as a number vs. string:
BETis collected viaINPUTas a numeric variable, and the win check at line 9505 usesR=BET; this works correctly as long as the player enters a digit 1–8. - Replay via RUN: Line 9520 uses
RUN(notGO TO 200), which re-executes the entire program from line 5, redrawing the track and redefining UDGs each time.
Variable Summary
| Variable | Role |
|---|---|
X | Loop counter for UDG POKE and track draw |
Y | Loop counter for finish-line PLOT |
A–H | Horizontal position of racers 1–8 |
I | Initialized but unused |
R | Random racer selected each step (1–8) |
BET | Player’s chosen racer number |
A$ | Player’s replay response (“Y”/”y”) |
Content
Source Code
5 REM *On your Mark!* \* Fred Blechman 1983
7 BORDER 7: CLS
10 FOR X=0 TO 7: READ N: POKE USR "\m"+X,N: NEXT X
20 DATA BIN 00001100,BIN 00001100,BIN 11111000,BIN 10011111,BIN 00011000,BIN 00011110,BIN 01110010,BIN 01000011
30 FOR X=0 TO 7: READ N: POKE USR "\a"+X,N: NEXT X
40 DATA BIN 00001100,BIN 00001100,BIN 01111000,BIN 01011110,BIN 01011010,BIN 00011000,BIN 00100100,BIN 00100100
100 FOR X=2 TO 16 STEP 2
110 PRINT AT X,0;X/2;"_\a";"_____________________________"
120 NEXT X
125 FOR Y=31 TO 159: PLOT 248,Y: NEXT Y
130 PRINT AT 0,0;" ";: INPUT "Who do you bet on?? ";BET: PRINT "....You bet on ";BET;"....."
135 GO TO 200
200 RANDOMIZE : LET A=3: LET B=3: LET C=3: LET D=3: LET E=3: LET F=3: LET G=3: LET H=3: LET I=3
210 LET R=INT (RND*8+1)
215 BEEP .05,R: BORDER R-1
220 GO TO R*1000
1000 PRINT AT 2,A-1;"_\m";
1020 LET A=A+1: IF A=32 THEN GO TO 9500
1030 GO TO 210
2000 PRINT AT 4,B-1;"_\m";
2020 LET B=B+1: IF B=32 THEN GO TO 9050
2030 GO TO 210
3000 PRINT AT 6,C-1;"_\m";
3020 LET C=C+1: IF C=32 THEN GO TO 9050
3030 GO TO 210
4000 PRINT AT 8,D-1;"_\m";
4020 LET D=D+1: IF D=32 THEN GO TO 9050
4030 GO TO 210
5000 PRINT AT 10,E-1;"_\m";
5020 LET E=E+1: IF E=32 THEN GO TO 9050
5030 GO TO 210
6000 PRINT AT 12,F-1;"_\m";
6020 LET F=F+1: IF F=32 THEN GO TO 9050
6030 GO TO 210
7000 PRINT AT 14,G-1;"_\m";
7020 LET G=G+1: IF G=32 THEN GO TO 9500
7030 GO TO 210
8000 PRINT AT 16,H-1;"_\m";
8020 LET H=H+1: IF H=32 THEN GO TO 9500
8030 GO TO 210
9500 IF R<>BET THEN PRINT AT 18,0; INK 2; FLASH 1;".....Sorry the winner is ";R;" !!!"; FLASH 0
9505 IF R=BET THEN PRINT AT 18,0; INK 1; FLASH 1;".....Good guess YOU WIN!!!"; FLASH 0
9510 BORDER 7: INPUT "TRY AGAIN? ";A$
9520 IF A$="Y" OR A$="y" THEN RUN
9530 STOP
9997 STOP
9998 SAVE "ON YOUR MA" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

