Multiply

Developer(s): George Chambers
Date: 1984
Type: Program
Platform(s): TS 2068

This program combines a multiplication drill with an arcade-style catching game called “Money Pail.” The player is prompted to enter upper bounds for the multiplier and multiplicand, then presented with a multiplication question displayed as a visual grid; a correct answer triggers the Money Pail game, where the player moves a pail (using Z and M keys) to catch falling dollar amounts while a BANK counter tracks their total. The program defines twelve UDGs (User Defined Graphics, chars \a through \m) via DATA statements at line 6040, covering pail graphics, a rocket/falling-object sprite, and animated bounce frames used during both the game and wrong-answer sequences. The TS2068-specific SOUND keyword is used at lines 450 and 530 for chip-sound effects, and POKE 23613 at line 30 manipulates the FRAMES system variable to seed pseudo-random behaviour, while POKE 23658,0 disables the CAPS SHIFT lock.


Program Structure

The program is divided into clearly separated functional blocks, called in sequence from the main entry point at line 10:

  1. GO SUB 6000 — UDG definition routine (lines 6000–9996)
  2. GO SUB 5000 — Title screen and parameter input (lines 5000–5400)
  3. GO SUB 4000 — Money Pail game instructions (lines 4010–4060)
  4. Lines 30–200 — Multiplication question setup and display
  5. Lines 220–230 — Input handling via GO SUB 700
  6. Lines 300–350 — Wrong-answer branch with animation
  7. Lines 400–510 — Correct-answer branch leading into Money Pail
  8. Lines 530–600 — Score/pail subroutines called from the game loop
  9. Lines 700–830 — Input validation subroutine
  10. Lines 1020–2150 — Money Pail game proper

There is no clean top-level loop. After a correct answer the program falls through to line 1000 (which does not appear in the listing — likely a missing or jump target line), and after the Money Pail game ends it GO TO 103 and GO TO 108, neither of which appears explicitly, suggesting they fall through to line 105 and 110 respectively by proximity, or are typos of those line numbers.

UDG Definitions

Lines 6000–6038 define twelve UDGs (\a through \m) by POKEing into USR "\x" addresses. Eight bytes are read per character from the DATA block at line 6040. The characters serve the following apparent roles:

UDGUsed atLikely appearance
\a540, 580, 1025, 1050, 1060Left side of pail
\c540, 580, 1025, 1050, 1060Middle of pail
\d540, 580, 1025, 1050, 1060Right side of pail
\e–\i6025–6032 (DATA only)Coin/bill animation frames
\j, \k, \l, \m310, 320Rocket/wrong-answer animation segments

The DATA at line 6040 encodes the left-column ramp pattern (192, 192… 255, 255) for the first three UDGs, giving graduated left/centre/right fills that form a pail silhouette. Lines 6045 onward supply coin and score-display glyphs using values 24, 36 (a circle pattern) and combined bitmasks.

Multiplication Question Display

The multiplier range is controlled by user inputs: u (high value of multiplier) and k (high value of multiplicand), with minima of 7 enforced at lines 5255 and 5325. The offsets g = u-7 and i = k-7 are used to generate a random question within [g, u] × [i, k] at lines 140–150. The multiplication table grid (lines 115–130) prints row and column headers derived from g and i, and line 170 draws a partial string of asterisks from z$ (31 asterisks, line 90) clipped to 4+((y-i)*3) characters to form a visual rectangle highlighting the answer cell.

Money Pail Game Loop

The game loop (lines 2000–2150) runs six rounds (FOR a=1 TO 6). Each round:

  • Selects a random dollar amount q (multiples of 10, $10–$90) and a random column c
  • Drops the amount string down the screen in a FOR b=h TO 20 loop with BEEP per row
  • Reads Z/M keypresses to move the pail position p, clamped to columns 1–27
  • Detects a catch when c=p+1 and score sc<5, calling GO SUB 530
  • Detects a bank visit when p=27, calling GO SUB 570 to add pail contents to total

The pail holds at most 5 bills (sc<5 guard in line 2120); line 530 increments sc and uses SOUND for a catch jingle. The bank subroutine (line 570) resets sc and x and updates the on-screen bank total. The bouncing-dollar display in lines 580–590 animates a dollar sign moving upward using a short FOR loop.

Input Validation Subroutine

The subroutine at line 700 performs digit-only validation of the answer string j$. It iterates over each character; if any character falls outside CHR$ 48CHR$ 57 (i.e. ‘0’–’9′) it branches to line 800, which prints an error message and waits for a keypress before restarting at line 100. Entering "q" as the first character of j$ causes an immediate RUN (line 700), providing a hidden quit/restart mechanism.

Notable Techniques and Idioms

  • POKE 23613, PEEK 23613 - 2 at line 30 decrements the low byte of the FRAMES counter, subtly altering the RNG seed without zeroing it, a common Spectrum randomisation trick.
  • POKE 23658, 0 at line 135 clears the FLAGS2 system variable bit that locks CAPS SHIFT, preventing accidental uppercase mode during answer entry.
  • VAL a$(2) at line 550 extracts the tens digit of the dollar string (e.g. “$70” → ‘7’) and converts it to a number to add to the pail total x.
  • The wrong-answer animation (lines 310–320) moves a multi-segment UDG sprite (\j, \k, \l, \m) upward and erases its tail, simulating a rocket launching in response to an error.
  • The SOUND keyword (TS2068 extension) drives the AY chip directly at lines 450 and 530 with envelope/channel register writes, producing richer audio than BEEP alone.

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

Multiply

Source Code

    1 REM 
    2 REM 
    4 REM    An original program   
    5 REM      by G F Chambers
    6 REM       January  1984
    7 REM 
    8 REM 
   10 GO SUB 6000
   15 GO SUB 5000
   20 GO SUB 4000
   30 LET v1=PEEK 23613-2: POKE 23613,v1
   40 LET a$="00"
   50 LET t=0: LET p=14: LET sc=0: LET x=0
   90 LET z$="*******************************"
  105 PAPER 6: CLS 
  110 LET d=10: LET d=3: LET h=3
  112 LET x=g: LET y=i
  115 FOR n=1 TO 8
  120 PRINT AT (n*2),0;x;AT 18,(n*3)+3;y: LET x=x+1: LET y=y+1
  130 NEXT n
  135 POKE 23658,0
  140 LET x=INT (g+(RND*(u-g))+.5)
  150 LET y=INT (i+(RND*(k-i))+.5)
  170 PRINT AT 2+(x-g)*2,2;z$( TO 4+((y-i)*3))
  180 FOR n=2+(x-g)*2 TO 17: PRINT AT n,6+((y-i)*3);"*"
  190 NEXT n
  194 IF t<0 THEN PRINT AT 0,2;"YOU OWE ";ABS t;"$": GO TO 196
  195 IF t>0 THEN PRINT AT 0,2;"YOU NOW HAVE  $";t
  200 PRINT AT 21,7; FLASH 1;"MULTIPLY ";x;" X ";y
  220 INPUT j$
  225 GO SUB 700
  230 LET a=VAL j$: IF a=x*y THEN GO TO 400
  300 CLS : PRINT AT 10,7; FLASH 1;"WRONG WRONG WRONG": PAUSE 50:
  310 LET r=28: FOR n=1 TO 18: BEEP .005,n: PRINT AT n,r; PAPER 8;"\j": NEXT n
  320 FOR n=16 TO 0 STEP -1: BEEP .005,n: BEEP .005,n+5: PRINT AT n,r; PAPER 8;"\j";AT n+1,r;"\k";AT n+2,r;"\l";AT n+3,r;"\m";AT n+4,r;" ": NEXT n
  330 PAUSE 20: PRINT AT 10,5;"THE CORRECT ANSWER IS ";AT 12,15; FLASH 1; INK 2;X*Y
  340 PRINT 'TAB 11;x;" X ";y;" = ";x*y
  345 PRINT '"YOU LOSE $200"
  347 LET t=t-200
  350 PAUSE 200: CLS : GO TO 108
  400 CLS : PRINT AT 10,3; FLASH 1;"HURRAH HURRAH";AT 12,5;"YOUR ANSWER IS CORRECT"
  410 PAUSE 100
  450 FOR z=30 TO 10 STEP -1: SOUND 6,x;7,7;8,16;9,16;10,16;12,140;13,1: NEXT z
  505 BEEP .3,20
  510 GO TO 1000
  530 LET sc=sc+1: SOUND 6,6;7,7;8,16;9,16;10,16;12,56;13,8: PAUSE 10: SOUND 8,0;9,0;10,0
  540 LET b$=CHR$ 144+CHR$ (147+sc)+CHR$ 147
  550 LET x=x+10*VAL a$(2): PRINT AT 0,7;x
  560 RETURN 
  570 LET sc=0: LET t=t+x: LET x=0: PRINT AT 0,7;"00 ";AT 0,27;"    ";AT 0,27;t: BEEP .05,48: BEEP .07,44
  580 LET b$="\a\c\d": PRINT AT 21,28;b$
  590 FOR e=12 TO 2 STEP -2: PRINT AT e,29;"$";AT e+2,29;" ": NEXT e: PRINT AT 2,29;" "
  600 RETURN 
  700 IF j$(1)="q" THEN RUN 
  705 LET v=0: FOR z=1 TO LEN j$: IF j$(z)<CHR$ 48 OR j$(z)>CHR$ 57 THEN GO TO 800
  710 NEXT z
  720 RETURN 
  800 CLS : PRINT AT 17,0;"You have entered a wrong number"
  810 PRINT '"Please press any key to restart"
  820 IF INKEY$="" THEN GO TO 820
  830 CLS : GO TO 100
 1020 BORDER 2: PAPER 7: INK 0: CLS 
 1025 LET b$="\a\c\d"
 1030 PRINT AT 15,29;"B";TAB 29;"A";TAB 29;"N";TAB 29;"K";AT 21,29;AT 20,29;"^"
 1040 LET sc=0: LET x=0: PRINT AT 0,7;"00 ";AT 0,27;t: BEEP .05,48: BEEP .07,44
 1050 PRINT AT 21,p;b$
 1060 PRINT AT 0,0;"▐PAIL▌$00";TAB 10;"▐BILLS▌0";TAB 20;"▐BANK▐$";t
 2000 REM DROP
 2010 FOR a=1 TO 6
 2040 LET q=10*(INT (RND*9)+1): LET a$="$"+CHR$ (q/10+48)+"0": LET c=INT (RND*22)+3: PRINT AT 0,17;6-a;" "
 2060 REM GO
 2070 FOR b=h TO 20: PRINT AT b,c;a$: BEEP d/100,b: LET p=p-(INKEY$="z")+(INKEY$="m"): LET p=p+(p=0)-(p=28): PRINT AT 21,p;" ";b$;" ";AT b,c;"   ": NEXT b
 2110 REM HIT
 2115 IF p=27 THEN GO SUB 570
 2120 IF c=p+1 AND sc<5 THEN GO SUB 530
 2140 NEXT a
 2150 PAUSE 200: CLS : GO TO 103
 3000 REM END
 4010 INK 0: PAPER 7: BORDER 2: CLS 
 4020 PRINT AT 2,9;"▗▄▄▄▄▄▄▄▄▄▄▖";TAB 9;"▐MONEY PAIL▌";TAB 9;"▝▀▀▀▀▀▀▀▀▀▀▘"
 4030 PRINT AT 7,1;"If there were tens of dollars   falling from the sky, how much  of it could you catch with a    small pail?";AT 12,1;"NOTE: Your pail only holds 5          bills. Take your money         to the bank and come            back for more.";AT 18,1;" USE KEYS M & Z TO MOVE PAIL "
 4040 PRINT AT 21,4;"Press ENTER to continue"
 4050 PAUSE 0: CLS 
 4060 RETURN 
 5000 PRINT AT 1,5;"MULTIPLICATION DRILL"
 5010 PRINT ''"This program is a multiplicationdrill.  Getting a correct answerwill result in the  display of  the game ""MONEY PAIL"".   A wrong answer will result in   another multiplication test."
 5030 PRINT '"  To start it is  necessary  to enter the upper level of the    multiplier and the multiplicand to be used in this particular   exercise."
 5040 PRINT '''"Enter the values when requested."
 5250 INPUT "Enter high value of multiplier";u
 5255 IF u<7 THEN LET u=7
 5260 LET g=u-7
 5320 INPUT "Enter high value of multiplicand";k
 5325 IF k<7 THEN LET k=7
 5330 LET i=k-7
 5400 RETURN 
 6000 RESTORE 6040
 6005 FOR n=0 TO 7: READ l: POKE USR "\a"+n,l: NEXT n
 6015 FOR n=0 TO 7: READ r: POKE USR "\c"+n,r: NEXT n
 6020 FOR n=0 TO 7: READ e: POKE USR "\d"+n,e: NEXT n
 6025 FOR n=0 TO 7: READ y: POKE USR "\e"+n,y: NEXT n
 6027 FOR n=0 TO 7: READ o: POKE USR "\f"+n,o: NEXT n
 6029 FOR n=0 TO 7: READ u: POKE USR "\g"+n,u: NEXT n
 6030 FOR n=0 TO 7: READ y: POKE USR "\h"+n,y: NEXT n
 6032 FOR n=0 TO 7: READ y: POKE USR "\i"+n,y: NEXT n
 6034 FOR n=0 TO 7: READ y: POKE USR "\j"+n,y: NEXT n
 6036 FOR n=0 TO 7: READ y: POKE USR "\k"+n,y: NEXT n
 6037 FOR n=0 TO 7: READ y: POKE USR "\l"+n,y: NEXT n
 6038 FOR n=0 TO 7: READ y: POKE USR "\m"+n,y: NEXT n
 6040 DATA 192,192,192,192,192,192,255,255,0,0,0,0,0,0,255,255,3,3,3,3,3,3,255,255,0,0,0,0,0,255,255,255,0,0,0,0,255,255,255,255,0,0,0,255,255,255,255,255,0,0,255,255,255,255,255,255,0,255,255,255,255,255,255,255
 6045 DATA 24,36,36,36,36,36,24,0,24,36,24,16,8,4,36,24,56,56,16,238,254,198,222,222,198,124,68,84,84,84,84,238
 9996 RETURN 
 9997 STOP 
 9998 SAVE "MULTIPLY" LINE 10
 9999 CLS : INPUT ;"Do you wish to verify?(Y/N)";a$: IF a$="y" THEN VERIFY ""

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top