On Your Mark

Developer(s): Fred Blechman
Date: 1983
Type: Program
Platform(s): TS 2068
Tags: Game

“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:

  1. Initialization (lines 5–40): Two UDGs are defined by POKEing pixel data from DATA statements.
  2. 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.
  3. 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.
  4. 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*1000 as the target expression is a clean dispatch table pattern.
  • BIN literals in DATA: Using BIN in DATA statements makes UDG bitmaps self-documenting.
  • Unused variable I: I is 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 9050 on 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: BET is collected via INPUT as a numeric variable, and the win check at line 9505 uses R=BET; this works correctly as long as the player enters a digit 1–8.
  • Replay via RUN: Line 9520 uses RUN (not GO TO 200), which re-executes the entire program from line 5, redrawing the track and redefining UDGs each time.

Variable Summary

VariableRole
XLoop counter for UDG POKE and track draw
YLoop counter for finish-line PLOT
A–HHorizontal position of racers 1–8
IInitialized but unused
RRandom racer selected each step (1–8)
BETPlayer’s chosen racer number
A$Player’s replay response (“Y”/”y”)

Content

Related Products

Related Articles

Related Content

Image Gallery

On Your Mark

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.

Scroll to Top