--- title: "Spellbug" id: 64658 type: "computer_media" slug: "spellbug" url: "http://localhost/computer_media/spellbug/" markdown_url: "http://localhost/computer_media/spellbug.md" published_at: "2026-03-06T15:17:42+00:00" modified_at: "2026-03-30T21:45:29+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A pixel-magnifying spelling game that renders scrambled letters as giant mosaics and lets you hunt them down with a joystick or type your answer at the keyboard." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Education" slug: "education" taxonomy: "genre" url: "http://localhost/type/education/" media_contents: - id: 64613 title: "CATS Library Tape 10" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-10/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Spellbug%20%281984%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" media_type_tags: "Education" --- # Spellbug Spellbug is an educational spelling game that displays each letter of a word as a magnified, pixel-mapped character on screen, then challenges the player to identify and reconstruct the word either via keyboard input or joystick control. The program reads up to 80 word-and-clue pairs from DATA statements beginning at line 8000 in 20-line increments, using RESTORE with a calculated address to jump to a randomly selected entry. A notable technique is the magnify routine (lines 500–1600), which uses POINT to sample individual pixels of a UDG character and then re-renders each lit pixel as a larger block on screen, storing coordinates in a three-dimensional array W(8,64,2) for later use by the “gobble-up” animation. The STICK function is used for joystick input throughout, and ON ERR (the { keyword) provides a clean mechanism to count word entries in the DATA block without knowing their number in advance. A machine code routine at address 65000, called via RANDOMIZE USR 65000, is invoked to produce a screen-vanish effect when the player answers correctly. *** ## Program Structure The program is divided into clearly commented subroutines and a main loop, with REM labels identifying each section: 1. **Initialisation / title screen** (lines 22–77): sets paper colour, displays the “SPELLBUG” title with `OVER 1` underline effect, prompts for clue mode, and detects joystick or keyboard preference. 2. **Main program / setup** (lines 3000–4720): on the first pass, dimensions all arrays, reads UDG key names and messages from DATA, counts available words using ON ERR, then on every pass selects a random word, assigns random screen positions to each letter, and calls the magnify routine 8 times. 3. **Magnify routine** (lines 500–1600): called as a subroutine; samples a UDG character pixel-by-pixel using `POINT` and prints a scaled block character at a computed screen position, storing coordinates for later animation. 4. **Answer loop** (lines 5090–6000): accepts keyboard input via the answer subroutine (lines 152–190) or joystick navigation (lines 80–145), then validates the response letter by letter. 5. **Gobble-up routine** (lines 1790–2000): animates the cursor “eating” a magnified letter by iterating through stored pixel coordinates. 6. **Error / correct routines** (lines 2195–2880 and 6020–6600): provide feedback with random messages, flashing colours, and scrolling displays of the correct word. 7. **Data block** (lines 6918–9500): contains UDG key names, three sets of five messages (wrong/right/suffix), and 80 word–clue pairs. ## Word Selection and DATA Access Rather than reading words sequentially, the program counts all entries at startup using an `ON ERR` trap around a READ loop (lines 3265–3280), storing the total in `WORDS`. Each game pass then picks a random index `W` and executes `RESTORE 7980+W*20` (line 3350) to position the DATA pointer directly at the chosen word’s line. This is an elegant use of the fixed 20-line DATA spacing to avoid any search loop. ## The Magnify Routine The routine at line 500 uses nested loops over columns (`C`, 0–7) and rows (`R`, 7–0) combined with `POINT (C,R)` to test each pixel of a UDG character. When a pixel is set, the corresponding screen position is computed as: - `CCOOR = COL - 4 + C + 1` (line 1300) - `RCOOR = ROW + 4 - R + 1` (line 1400) The block character `X$` is printed there, and the coordinates are stored in the 3-D array `W(H,PIXCT,1)` / `W(H,PIXCT,2)` for the gobble-up animation. The routine is called 8 times via a two-level loop (`G` and `J` in steps of 8, lines 4660–4720), once per letter of the word. ## UDG Characters as Display Blocks The variable `X$` is chosen randomly from entries in `C$()` (line 3260), which is populated with UDG characters `\a`–`\h` (chars 144–151) plus three block graphics (▀, ▐, ▚) and a standard UDG `\h`. The selection logic at lines 3315–3320 picks either a UDG (`CHAR ≤ 9.5`) or one of three block graphics (`CHAR > 9.5`), and the `INV` flag at line 3323 randomly applies `INVERSE 1` — except for `C$(9)` which always uses normal video (line 3324). ## Joystick Handling The `STICK` function is used throughout. `STICK(2,2)` reads the fire button; `STICK(1,2)` reads directional input with values decoded as a bitmask: | Value | Direction | | --- | --- | | 1, 5, 9 | Up | | 2, 6, 10 | Down | | 4, 5, 6 | Left | | 8, 9, 10 | Right | Movement is in steps of 2 screen rows/columns (lines 90–105), clamped to [0,31] horizontally and [0,15] vertically. In joystick mode, the cursor character `W$` is the UDG `\f` (char 149), and the previous cursor position is restored to a space before printing at the new location. ## Answer Checking In keyboard mode the answer string `Y$` is compared character-by-character with `A$(1)` at line 5150, accepting both upper and lower case by also testing `CODE A$(2,D) <> CODE A$(1,D)+32`. In joystick mode (line 5670), the player navigates the cursor to a magnified letter; the code at line 5120 converts the cursor’s screen coordinates back to a letter index via `INT(Y/8) + 4*INT(X/8) + 1`. ## Machine Code Call Line 6010 calls `RANDOMIZE USR 65000` inside a loop of 8 iterations to produce a screen-vanish effect after a correct answer. No POKE sequence for this routine appears in the listing; it must be pre-loaded externally or bundled with the saved file. The address 65000 falls in the upper RAM area. ## ON ERR Usage `ON ERR GO TO 3280` (line 3265) traps the “out of DATA” error that terminates the READ loop at line 3275. After the count is complete, `ON ERR RESET` (line 3280) restores normal error handling. This is a clean idiom for counting an unknown number of DATA items without a sentinel value. ## Array Dimensioning All arrays are allocated at first run (line 3010 gates on `FIRST`) to avoid re-dimensioning on subsequent rounds: - `A$(2,8)` — current word and player’s answer (2 strings × 8 chars) - `K(8,2)` — letter index and character code for each of 8 letters - `Z(8)` — occupancy flags for random position selection - `P(8)` — pixel count per letter - `W(8,64,2)` — pixel coordinates for gobble animation (8 letters × 64 pixels × row/col) - `M$(3,10,7)` — message strings (3 sets × 10 entries… only 5 used × 7 chars) - `G$(10,1)`, `C$(20,1)` — UDG key names and display character lookup ## Source Code ``` 10 REM *** PROGRAM SPELLBUG 15 REM *** UPDATED 2/3/84 PM 22 PAPER 6: CLS 24 PRINT AT 6,13;"THIS";AT 8,14;"IS";AT 10,11;"SPELLBUG"; OVER 1;AT 10,11;"________" 34 BEEP .5,8: PAUSE 90: BEEP .5,12: CLS 36 LET FIRST=0 40 PRINT AT 8,2;"To delete clues, press DELETE";AT 10,3;"Otherwise, press SPACE BAR" 42 IF INKEY$=" " THEN LET CLUES=0: BEEP .2,16: GO TO 50 45 IF INKEY$="0" THEN LET CLUES=1: BEEP .2,16: GO TO 50 46 GO TO 42 50 CLS : PAUSE 30: PRINT AT 8,3;"Joystick? Press FIRE BUTTON" 55 PRINT AT 10,4;"Keyboard? Press SPACE BAR" 60 IF STICK(2,2)=1 THEN LET JOY=1: BEEP .2,20: GO TO 77 65 IF INKEY$=" " THEN LET JOY=0: BEEP .2,20: GO TO 77 70 GO TO 60 77 PAPER 7: CLS : GO TO 3000 80 REM *** JOYSTICK ROUTINE 85 IF D=1 THEN LET X=15: LET USUBX=15: LET Y=16: LET USUBY=16: LET U$=" ": LET W$="\f": PRINT AT X,Y;W$ 90 IF STICK(1,2)=5 OR STICK(1,2)=1 OR STICK(1,2)=9 THEN LET X=X-2: BEEP .01,X 95 IF STICK(1,2)=6 OR STICK(1,2)=2 OR STICK(1,2)=10 THEN LET X=X+2: BEEP .01,X 100 IF STICK(1,2)=6 OR STICK(1,2)=5 OR STICK(1,2)=4 THEN LET Y=Y-2: BEEP .01,Y 105 IF STICK(1,2)=8 OR STICK(1,2)=9 OR STICK(1,2)=10 THEN LET Y=Y+2: BEEP .01,Y 110 IF Y>31 THEN LET Y=31 115 IF Y<0 THEN LET Y=0 120 IF X>15 THEN LET X=15 125 IF X<0 THEN LET X=0 130 IF SCREEN$ (X,Y)<>" " THEN IF SCREEN$ (X,Y)<>W$ THEN GO TO 142 140 IF X<>USUBX OR Y<>USUBY THEN PRINT AT USUBX,USUBY;" ": LET USUBX=X: LET USUBY=Y: LET U$=SCREEN$ (X,Y): PRINT AT X,Y;W$ 142 IF STICK(2,2)=1 THEN BEEP .2,10+INT (RND*10): GO TO 5120 145 GO TO 90 150 REM *** ANSWER ROUTINE 152 LET X=20: LET Y=12: LET Y$="": INK INT (RND*6)+1: PAPER 9 155 PRINT AT X,Y;"\f" 160 PAUSE 0: LET Z$=INKEY$ 165 IF Z$=CHR$ 13 AND Y$<>"" THEN GO TO 190 170 IF Z$=CHR$ 12 AND Y$<>"" THEN PRINT AT X,Y;CHR$ 32: LET Y=Y-1: LET Y$=Y$( TO LEN Y$-1): GO TO 155 175 IF Z$0 THEN GO TO 3300 3010 LET FIRST=1 3050 DIM A$(2,8): DIM K(8,2): DIM Z(8): DIM P(8): DIM W(8,64,2): DIM M$(3,10,7): DIM G$(10,1): DIM C$(20,1) 3162 RANDOMIZE 0 3163 REM *** READ USER-DEF. KEYS 3165 FOR J=1 TO 8 3170 READ G$(J): NEXT J 3178 REM *** READ 'ERROR' AND 3179 REM *** 'CORRECT' MESSAGES 3180 FOR S=1 TO 3 3185 FOR T=1 TO 5 3190 READ M$(S,T): NEXT T: NEXT S 3258 REM *** ASSIGN SPEC. CHARS. 3260 LET C$(1)="\a": LET C$(2)="\b": LET C$(3)="\c": LET C$(4)="\d": LET C$(5)="\e": LET C$(6)="\f": LET C$(7)="\g": LET C$(10)="▀": LET C$(11)="▐": LET C$(12)="▚": LET C$(8)="▜": LET C$(9)="\h" 3265 ON ERR GO TO 3280 3270 LET WORDS=0 3275 READ U$,V$: LET WORDS=WORDS+1: GO TO 3275 3280 ON ERR RESET 3300 FOR F=1 TO 5 3313 LET W=INT (RND*WORDS)+1 3315 LET CHAR=.5*(INT (RND*21)+2) 3318 IF CHAR>9.5 THEN LET X$=C$(10+INT (RND*3)) 3320 IF CHAR<=9.5 THEN LET X$=C$(INT (CHAR)) 3323 LET INV=INT (RND*2) 3324 IF X$=C$(9) THEN LET INV=0 3325 REM *** RANDOMLY SELECTS 3326 REM *** WHETHER TO 'GOBBLE' 3330 LET GOBBLE=INT (RND*2) 3340 IF JOY=1 THEN LET GOBBLE=1 3345 REM *** SET READ POINTER TO 3347 REM *** RANDOM WORD (FROM 3348 REM *** LINE 8000, BY 20) 3350 RESTORE 7980+W*20 3400 READ Q$,B$: LET A$(1)=Q$ 3450 IF CLUES=1 THEN LET B$=" " 3500 FOR Z=1 TO 8: LET Z(Z)=Z: NEXT Z 3800 LET K(1,1)=INT (RND*8)+1 3850 LET K(1,2)=CODE A$(1,K(1,1)) 3900 LET Z(K(1,1))=0 3995 REM *** Z() RECORDS WHETHER 3996 REM *** RANDOM PRINT LOC. 3997 REM *** IS ALREADY USED; 3998 REM *** Z(X)=0 IF OCCUPIED 4000 FOR H=2 TO 7 4100 LET K(H,1)=INT (RND*8)+1 4150 LET K(H,2)=CODE A$(1,K(H,1)) 4200 IF Z(K(H,1))=0 THEN GO TO 4100 4250 LET Z(K(H,1))=0: NEXT H 4300 FOR Z=1 TO 8 4400 IF Z(Z)=0 THEN NEXT Z 4500 LET K(8,1)=Z 4504 LET K(8,2)=CODE A$(1,K(8,1)) 4520 LET H=0 4658 REM *** PERFORM MAGNIFY 4659 REM *** ROUTINE 8 TIMES 4660 FOR G=0 TO 8 STEP 8 4680 FOR J=0 TO 24 STEP 8 4690 LET PIXCT=0: LET H=H+1 4700 IF A$(1,K(H,1))<>" " THEN GO SUB 500 4720 NEXT J: NEXT G: INK 0 4798 REM *** PRINT CLUE 4800 PRINT AT 18,0;B$ 4818 REM *** DRAW ANSWER BOX 4820 PLOT 88,20: DRAW 80,0: DRAW 0,-16: DRAW -80,0: DRAW 0,16 4900 LET X$=" " 5090 IF JOY=0 THEN GO SUB 152: LET A$(2)=Y$ 5097 REM *** CHECK ANSWER, ONE 5098 REM *** LETTER AT A TIME 5100 FOR D=1 TO 8 5102 IF A$(1,D)=" " THEN GO TO 6000 5110 IF JOY=1 THEN GO TO 85 5120 IF JOY=1 THEN LET LETTER=INT (Y/8)+4*INT (X/8)+1: GO TO 5200 5150 IF A$(2,D)<>A$(1,D) AND CODE A$(2,D)<>CODE A$(1,D)+32 THEN GO TO 2200 5195 REM *** DETERMINE RANDOM 5197 REM *** LOCATION OF PRINTED 5198 REM *** LETTER FOR 'GOBBLE' 5200 FOR E=1 TO 8 5300 IF K(E,1)<>D THEN NEXT E 5400 LET G=INT (E/4.1)*8 5500 LET J=(E-1)*8 5600 IF E>4 THEN LET J=(E-5)*8 5650 LET H=E 5670 IF JOY=1 THEN IF CODE A$(1,K(LETTER,1))<>K(H,2) THEN GO TO 2200 5680 IF JOY=1 THEN IF (LETTER<>H AND CODE A$(1,K(LETTER,1))=K(H,2)) THEN LET H=LETTER 5697 REM *** PERFORM MAGNIFY 5700 IF GOBBLE<>0 THEN GO SUB 1825 5750 INK 0 5800 PRINT AT 20,11+D;A$(2,D) 5810 IF JOY=1 THEN PRINT AT 20,11+D;A$(1,D) 5850 IF GOBBLE=0 THEN BEEP .2,D*2 5900 NEXT D 6000 IF JOY=0 THEN IF LEN Y$<>LEN Q$ THEN GO TO 2200 6005 REM *** SCREEN 'VANISH' 6010 IF GOBBLE=0 THEN FOR R=1 TO 8: PAUSE 10: RANDOMIZE USR 65000: NEXT R: BEEP .2,D*2: RANDOMIZE 0 6020 REM *** 'CORRECT' ROUTINE 6025 PAUSE 50: FLASH 1: INK 8 6057 FOR O=1 TO INT (RND*2)+1 6058 LET P$=M$(2,INT (RND*5)+1) 6059 LET J$=M$(3,INT (RND*5)+1) 6060 LET L1=INT (RND*20): LET L2=INT (RND*24) 6063 FOR M=1 TO 2 6075 PAPER 7: BORDER 7: CLS : PAPER INT (RND*6)+1 6077 BORDER INT (RND*6)+1: CLS 6195 REM *** PRINT RANDOM 6197 REM *** MESSAGES AT RANDOM 6198 REM *** LOCATIONS 6200 PRINT AT L1,L2;J$''TAB L2;P$ 6500 BEEP M*.45,INT (RND*13)*M 6600 NEXT M: NEXT O: FLASH 0: PAPER 7: BORDER 7: CLS 6660 REM *** READ NEXT WORD 6670 NEXT F 6680 GO TO 40 6918 REM *** USER-DEFINED KEYS 6920 DATA "A","B","C","D","E" 6925 DATA "F","G","H" 6938 REM *** MESSAGES 6940 DATA "NO! NO!" 6945 DATA " NOPE!!" 6950 DATA "WRONG!!" 6955 DATA " WHAT?!" 6960 DATA "NO WAY!" 6970 DATA " RIGHT!" 6975 DATA "CORRECT" 6980 DATA " OKAY! " 6985 DATA " GOOD! " 6990 DATA "NOT BAD" 6991 DATA " THAT'S" 6992 DATA " YOU'RE" 6993 DATA " YEAH! " 6994 DATA " RIGHT!"," " 7995 REM *** WORDS AND CLUES 7997 REM *** (START AT LINE 8000 7998 REM *** & INCREMENT BY 20) 8000 DATA "GABRIEL"," MY LITTLE HACKER'S NAME IS" 8020 DATA "MUFFINS"," HIGBEES SERVES DELICIOUS" 8040 DATA "COMPUTER"," THIS DEVICE IS CALLED A" 8060 DATA "KEYBOARD"," THESE KEYS ARE ON A --------" 8080 DATA "MUSEUM"," ART IS DISPLAYED IN A ------" 8100 DATA "BECCA"," MY LITTLE DAUGHTERS' NAME IS" 8120 DATA "CEREAL"," OATMEAL OR RAISIN BRAN" 8140 DATA "WHOLE","THIS DESCRIBES ALL OF SOMETHING" 8160 DATA "HOLE"," THE MIDDLE OF A DONUT OR BAGEL" 8180 DATA "BIG"," ANOTHER WORD FOR LARGE" 8200 DATA "FUNCTION"," WHAT YOU DEFINE WITH 'DEF FN'" 8220 DATA "MYSTERY"," NANCY DREW SOLVED A -------" 8240 DATA "OHIO"," CLEVELAND IS IN THE STATE OF" 8260 DATA "YOGURT"," WE LOVE DANNON© ------" 8280 DATA "MEMORY"," THIS PROGRAM USES ABOUT 20K OF" 8300 DATA "SCULPTOR"," HE CREATES WITH CLAY OR METAL" 8320 DATA "THOUGHT"," SOMETHING THAT YOU THINK" 8340 DATA "CERAMIC"," SOMETHING MADE OF CLAY IS" 8360 DATA "MODEM"," A COMMUNICATIONS INTERFACE" 8380 DATA "STOMACH"," WHERE YOUR FOOD GOES" 8400 DATA "CABBAGE"," ------- PATCH KIDS©" 8420 DATA "INTAGLIO","PRINTING PROCESS (IMAGE CUT IN)" 8440 DATA "RELIEF","PRINTING PROCESS (IMAGE RAISED)" 8460 DATA "CASSETTE"," TAPES USE A -------- RECORDER" 8480 DATA "SCHOOL"," JOSH & GABE GO TO CANTERBURY" 8500 DATA "COLUMNS"," A MATRIX CONTAINS ROWS AND" 8520 DATA "KUMQUAT"," A FRUIT, WITH JOSHS I.Q., IS A" 8540 DATA "QUOTIENT"," ANSWER IN A DIVISION PROBLEM" 8560 DATA "ANSWER","A QUESTION ALWAYS HAS AN ------" 8580 DATA "ANTIQUE"," EXPENSIVE NAME FOR OLD JUNK" 8600 DATA "HEIRLOOM"," HANDED DOWN FOR GENERATIONS" 8620 DATA "BECAUSE"," UNACCEPTABLE ANSWER TO 'WHY?'" 8640 DATA "SYMBOL","PICTURE, REPRESENTING SOMETHING" 8660 DATA "ISLAND","BODY OF LAND SURROUNDED BY WATER" 8680 DATA "SEPARATE","IF THEY'RE NOT TOGETHER, THEY'RE" 8700 DATA "VASARELY"," THE FATHER OF 'OPTIC ART'" 8720 DATA "CALENDAR","LOOK AT THE ------ FOR THE DATE" 8740 DATA "MACHINE","A MECHANICAL DEVICE IS A -------" 8760 DATA "ACCESS"," RANDOM ------ MEMORY" 8780 DATA "GRAPHICS"," PICTURES (AS IN 'G' MODE)" 8800 DATA "COMPILER","TRANSLATES INTO MACHINE LANGUAGE" 8820 DATA "SERIAL","TRANSMISSION, 1 BIT WIDE STRING" 8840 DATA "NUCLEAR","RELATING TO THE CORE OF AN ATOM" 8860 DATA "MERGE"," TO COMBINE THINGS INTO ONE" 8880 DATA "HEXAGON","A SIX-SIDED FIGURE IS A -------" 8900 DATA "HUNDREDS","DAD'S IQ IS WAY UP IN THE -----" 8920 DATA "FEBRUARY"," THE MONTH AFTER JANUARY IS" 8940 DATA "SCIENCE"," CHEMISTRY, ASTRONOMY, ETC." 8960 DATA "PROCESS"," A CPU WILL ------- INFORMATION" 8980 DATA "VARIABLE"," A VALUE THAT CAN CHANGE " 9000 DATA "PROGRAM"," A SET OF COMPUTER INSTRUCTIONS" 9020 DATA "BINARY","NUMBER SYSTEM USING ONLY 1 AND 0" 9040 DATA "DECIMAL"," NUMBER SYSTEM USING 10 DIGITS" 9060 DATA "RANDOM"," ------ ACCESS MEMORY (RAM)" 9080 DATA "SYSTEM"," THINGS ACTING TOGETHER ARE A" 9100 DATA "AMATEUR"," HE DOES SOMETHING AS A HOBBY" 9120 DATA "SYNTAX"," THE STRUCTURE OF A LANGUAGE" 9140 DATA "MATRIX","MADE OF ROWS & COLUMNS; AN ARRAY" 9160 DATA "CIRCUITS","COMPUTERS USE INTEGRATED -------" 9180 DATA "CARTOON"," INSPECTOR GADGET OR THE SMURFS" 9200 DATA "BICYCLE"," I LIKE TO RIDE MY -------" 9220 DATA "ELECTRIC"," YOU MUST PLUG IT IN IF IT'S" 9240 DATA "CURSOR","SHOWS YOUR POSITION ON TV SCREEN" 9260 DATA "MAGNETIC","TAPES & DISKS ARE ------ STORAGE" 9280 DATA "NUTRIENT","SOMETHING NUTRITIOUS CONTAINS A" 9300 DATA "OXYGEN","THE AIR WE BREATHE CONTAINS ----" 9320 DATA "PIXEL","WORD, MEANING 'PICTURE ELEMENT'" 9340 DATA "VERIFY","MAKE SURE THAT SOMETHING IS TRUE" 9360 DATA "AERIAL"," RELATING TO THE AIR OR FLYING" 9380 DATA "INDEX"," LOOK HERE TO LOCATE SOMETHING" 9400 DATA "SPECTRUM","A PRISM BREAKS LIGHT INTO A ----" 9420 DATA "PRISM","IT BREAKS LIGHT INTO A SPECTRUM" 9440 DATA "RECEIVE"," I LIKE TO ------- PRESENTS." 9460 DATA "PARALLEL"," TRANSMISSION, 8 BITS AT A TIME" 9480 DATA "DIGITIZE"," CONVERT TO NUMERIC INFORMATION" 9500 DATA "DELETE"," TO GET RID OF OR REMOVE" 9998 SAVE "SPELLING" LINE 1 ```