Multiply 2

This file is part of and ISTUG Public Domain Library 5. Download the collection to get this file.
Developer(s): George Chambers
Date: 1984
Type: Program
Platform(s): TS 2068

This program combines a multiplication drill with a money-catching arcade mini-game called “Money Pail.” The player is prompted to enter upper bounds for the multiplier and multiplicand, then must answer randomly generated multiplication problems; correct answers unlock the Money Pail game, while wrong answers deduct $200 from a running cash balance. In the arcade segment, dollar bills fall from the top of the screen and the player moves a pail left and right using the Z and M keys to catch up to five bills before banking them. The program defines several UDG (User Defined Graphic) characters via a DATA/POKE loop starting at line 890, loading custom graphics into UDG slots beginning at character 144 (\c), used for the pail and bill sprites. The TS2068 SOUND statement is used for feedback tones, and INPUT validation at line 470–540 checks each character of the entered string to ensure only digits are accepted.


Program Analysis

Program Structure

The program divides into several logical sections connected by GO SUB calls and direct GO TO branches. The main flow initializes variables, displays instructions, accepts multiplication parameters, then loops between the multiplication drill (lines 80–380) and the Money Pail arcade game (lines 550–700). Two setup subroutines handle the introduction text and the UDG sprite definitions.

  1. Lines 10–60: Initialization, POKE 23613 scroll adjustment, variable setup
  2. Lines 70–330: Multiplication question display, input, scoring, and wrong-answer handling
  3. Lines 340–460: Correct answer celebration and Money Pail score/bank subroutines
  4. Lines 470–540: Input validation subroutine
  5. Lines 550–710: Money Pail arcade game loop
  6. Lines 720–770: Money Pail rules screen subroutine
  7. Lines 780–880: Multiplication parameter entry subroutine
  8. Lines 890–940: UDG definition subroutine via RESTORE/READ/POKE
  9. Lines 950–980: Optional VERIFY and SAVE block

UDG Sprite Definitions

Lines 890–940 define custom graphics by reading byte values from DATA statements and writing them to UDG memory with POKE USR "\c"+n,l. The loop at line 900 skips bytes 8–15 (IF n=8 THEN LET n=16), effectively jumping over the second UDG slot, which suggests UDG \d is intentionally left undefined or uses default data. The DATA uses the variable l as a placeholder throughout — since l is never explicitly initialized, it reads as 0 in numeric context, so all l entries in the DATA lines produce zero bytes. This means many rows of the UDG bitmaps are blank (zero), giving the sprites simple silhouettes defined only by their non-zero values.

Money Pail Arcade Mechanic

The arcade section (lines 620–700) drops six bills per round. For each bill, a random column c and denomination q are chosen, and the bill falls from row h to row 20 via a FOR b loop at line 650. During the fall, INKEY$ is polled directly inside the loop to move the pail position p left (Z key) or right (M key), with boundary clamping using an elegant idiom: LET p=p+(p=0)-(p=28), which exploits the fact that Boolean expressions evaluate to 1 (true) or 0 (false) in Sinclair BASIC.

Notable Techniques

  • Boolean arithmetic for boundary clamping: LET p=p+(p=0)-(p=28) wraps pail movement without any IF statements.
  • Score display via UDG string: Line 400 builds b$ from CHR$ 144, CHR$ (147+sc), and CHR$ 147 to display a composite UDG-based score graphic that advances with sc.
  • Input validation loop: Lines 480–500 iterate over each character of the entered string, rejecting anything outside ASCII 48–57 (digits ‘0’–’9′), providing rudimentary numeric checking.
  • POKE 23613 scroll fix: Line 40 subtracts 2 from the system variable at address 23613 (DF_SZ, display file size), reducing the lower BASIC prompt area to gain screen space.
  • VAL "number" in PAUSE/GO TO: Used in lines 260, 290, 330, 350, 700 as a common memory-saving optimization for numeric literals.
  • PI as a small integer: INT PI = 3 is used implicitly in several AT and TAB expressions (lines 120, 340, 570, 750, 760), exploiting the fact that Sinclair BASIC accepts floating-point where integers are required.
  • TS2068 SOUND statements: Lines 360 and 390 use multi-parameter SOUND syntax (e.g., SOUND 6,x;7,7;8,16;9,16;10,16;12,140;13,1) to program the AY chip registers directly for sound effects.

Bugs and Anomalies

LineIssue
90LET d=10: LET d=3d is set to 10 then immediately overwritten with 3, making the first assignment dead code. h=d then initializes the fall start row to 3.
290X*Y uses uppercase X and Y, which in Sinclair BASIC are the same variables as lowercase x and y — no practical bug, but inconsistent style.
430PRINT AT 0,27,AT 0,27;t — the comma between the two AT clauses is a syntax oddity; the first AT 0,27 has no output item associated with it before the comma, which may cause a syntax issue depending on interpreter strictness.
920–930The variable l is used inside DATA statements. In Sinclair BASIC, DATA items are evaluated at READ time; since l is uninitialized it evaluates to 0, so these are effectively zeros — almost certainly intended to be the literal digit 0, suggesting a transcription error where the numeral 0 was replaced by the letter l.
670The hit detection IF p=27 checks a specific hardcoded column rather than comparing p to c, meaning banking only triggers at column 27 regardless of where the bill fell — this appears to be a logic error in the catch/bank mechanic.

Content

Appears On

Library tape of the Indiana Sinclair Timex User’s Group.

Related Products

Related Articles

Related Content

Image Gallery

Multiply 2

Source Code

   10 REM        An original program    by G F Chambers,    1-84
   20 GO SUB 890: GO SUB 780
   30 GO SUB 720
   40 POKE 23613,PEEK 23613-2
   50 LET a$="00"
   60 LET t=0: LET p=14: LET sc=t: LET x=t
   70 LET z$="*******************************"
   80 PAPER 6: CLS 
   90 LET d=10: LET d=3: LET h=d
  100 LET x=g: LET y=i
  110 FOR n=1 TO 8
  120 PRINT AT (n*2),0;x;AT 18,(n*3)+PI;y: LET x=x+1: LET y=y+1
  130 NEXT n
  140 POKE 23658,0
  150 LET x=INT (g+(RND*(u-g))+.5)
  160 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
  200 IF t<0 THEN PRINT AT 0,2;"YOU OWE ";ABS t;"$": GO TO 220
  210 IF t>0 THEN PRINT AT 0,2;"YOU NOW HAVE  $";t
  220 PRINT AT 21,7;"MULTIPLY ";x;" X ";y;""
  230 INPUT j$
  240 GO SUB 470
  250 LET a=VAL j$: IF a=x*y THEN GO TO 340
  260 CLS : PRINT AT 10,7;"WRONG WRONG WRONG": PAUSE VAL "50"
  270 LET r=28: FOR n=1 TO 18: BEEP .005,n: PRINT AT n,r; PAPER 8;"\j": NEXT n
  280 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
  290 PAUSE VAL "20": PRINT AT 10,5;"THE CORRECT ANSWER IS ";AT 12,15; FLASH 1; INK 2;X*Y
  300 PRINT 'TAB 11;x;" X ";y;" = ";x*y
  310 PRINT '"YOU LOSE $200"
  320 LET t=t-200
  330 PAUSE VAL "200": CLS : GO TO 90
  340 CLS : PRINT AT 10,PI;"HURRAH HURRAH";AT 12,5;"YOUR ANSWER IS CORRECT"
  350 PAUSE VAL "100"
  360 FOR z=30 TO 10 STEP -1: SOUND 6,x;7,7;8,16;9,16;10,16;12,140;13,1: NEXT z
  370 BEEP .3,20
  380 GO TO 550
  390 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
  400 LET b$=CHR$ 144+CHR$ (147+sc)+CHR$ 147
  410 LET x=x+10*VAL a$(2): PRINT AT 0,7;x
  420 RETURN 
  430 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
  440 LET b$="\a\c\d": PRINT AT 21,28;b$
  450 FOR e=12 TO 2 STEP -2: PRINT AT e,29;"$";AT e+2,29;" ": NEXT e: PRINT AT 2,29;" "
  460 RETURN 
  470 IF j$(1)="q" THEN RUN 
  480 LET v=0: FOR z=1 TO LEN j$: IF j$(z)<CHR$ 48 OR j$(z)>CHR$ 57 THEN GO TO 510
  490 NEXT z
  500 RETURN 
  510 CLS : PRINT AT 17,0;"You have entered a wrong number"
  520 PRINT '"Please press any key to restart"
  530 IF INKEY$="" THEN GO TO 530
  540 CLS : GO TO 80
  550 BORDER 2: PAPER 7: INK 0: CLS 
  560 LET b$="\a\c\d"
  570 PRINT AT 15,29;"B";TAB 29;"A";TAB 29;"N";TAB 29;"K";AT 21,29;AT 20,29;"^"
  580 LET sc=0: LET x=0: PRINT AT 0,7;"00 ";AT 0,27;t: BEEP .05,48: BEEP .07,44
  590 PRINT AT 21,p;b$
  600 PRINT AT 0,0;"\ :PAIL\: $00";TAB 10;"\ :BILLS\: 0";TAB 20;"\ :BANK\ :$";t
  610 REM DROP
  620 FOR a=1 TO 6
  630 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;" "
  640 REM GO
  650 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
  660 REM HIT
  670 IF p=27 THEN GO SUB 430
  680 IF c=p+1 AND sc<5 THEN GO SUB 390
  690 NEXT a
  700 PAUSE VAL "200": CLS : GO TO 80
  710 REM END
  720 INK NOT PI: PAPER 7: BORDER 2: CLS 
  730 PRINT '''TAB 9;"\ .\..\..\..\..\..\..\..\..\..\..\. ";TAB 9;"\ :MONEY PAIL\: ";TAB 9;"\ '\''\''\''\''\''\''\''\''\''\''\' "
  740 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?"''"NOTE: Your pail only holds 5          bills. Take your money          to the bank and come            back for more."'''" USE KEYS z & m TO MOVE PAIL "
  750 PRINT AT 21,PI;" Press ENTER to continue"
  760 PAUSE NOT PI: CLS 
  770 RETURN 
  780 CLS : PRINT AT SGN PI,PI;"  MULTIPLICATION DRILL"
  790 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."
  800 PRINT '"  To start it is  necessary  to enter the upper level of the    multiplier and the multiplicand to be used in this particular   exercise."
  810 PRINT '''"Enter the values when requested."
  820 INPUT "Enter high value of multiplier";u
  830 IF u<7 THEN LET u=7
  840 LET g=u-7
  850 INPUT "Enter high value of multiplicand";k
  860 IF k<7 THEN LET k=7
  870 LET i=k-7
  880 RETURN 
  890 RESTORE 920
  900 FOR n=0 TO 103: IF n=8 THEN LET n=16
  910 READ l: POKE USR "\c"+n,l: NEXT n
  920 DATA 192,l,l,l,l,l,255,l,0,l,l,l,l,l,255,l,3,l,l,l,l,l,255,l,0,l,l,l,l,255,l,l,0,l,l,l,255,l,l,l,0,l,l,255,l,l,l,l,0,l,255,l,l,l,l,l,0,255,l,l,l,l,l,l
  930 DATA 24,36,l,l,l,l,24,0,24,36,24,16,8,4,36,24,56,l,16,238,254,198,222,l,198,124,68,84,l,l,l,238
  940 RETURN 
  950 CLS : INPUT ;"Do you wish to verify?(Y/N)";a$
  960 IF a$="y" THEN VERIFY ""
  970 STOP 
  980 SAVE "MULTIPLY" LINE 10

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

Scroll to Top