--- title: "Circuit Board Scramble" id: 51715 type: "computer_media" slug: "circuit-board-scramble" url: "http://localhost/computer_media/circuit-board-scramble/" markdown_url: "http://localhost/computer_media/circuit-board-scramble.md" published_at: "2023-08-13T23:14:28+00:00" modified_at: "2026-03-30T21:57:44+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2023/08/SCR-20260330-psbz.png" excerpt: "Navigate a circuit board maze to repair computer components in this two-phase action game that blends BASIC gameplay logic with heavy machine code assistance." 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: "Timex Computer Corporation" slug: "timex-computer-corporation" taxonomy: "post_tag" url: "http://localhost/tag/timex-computer-corporation/" - 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: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Circuit Board Scramble (1984)(Timex)(US)(TS2068)(Program).zip" mediadate: "1984" producer_company: - id: 11401 title: "Timex Computer Corporation" type: "company" url: "http://localhost/company/timex-computer-corporation/" images: - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260330-psbz.png" - url: "http://localhost/wp-content/uploads/2023/08/SCR-20260330-przi.png" - url: "http://localhost/wp-content/uploads/2021/01/CircuitBoardScramble.jpg" related_products: - id: 12151 title: "Circuit Board Scramble" type: "product" url: "http://localhost/product/circuit-board-scramble/" media_type_tags: "Game" --- # Circuit Board Scramble Circuit Board Scramble is a maze-navigation game in which the player guides a character around a circuit board diagram to reach target components such as the voltage regulator, ULA, RAM, ROM, CPU, and edge connector. The program loads machine code from tape at addresses 39694 and 51450, using USR calls throughout to handle joystick input, sound, scoring, and sprite movement. Player position and score are tracked via POKEs and PEEKs into specific machine code data areas around address 40000–40800, with the high score stored at addresses 39800–39802 across sessions using INPUT prompts. The keyboard control option lets the player define four custom keys, whose character codes are POKEd directly into the machine code routine at addresses 39844–39859. A scrolling ticker-tape message at line 3030–3070 is implemented in BASIC by printing successive 8-character substrings of a padded string. *** ## Program Analysis ### Program Structure The program is divided into several functional regions that do not follow a simple top-to-bottom flow. The loader block (lines 8000–8090 in the first group) sets up the screen, loads a splash graphic and a main BASIC/code file, then saves a combined loader. The main game logic occupies lines 1–4660, with high-numbered lines (8000–8640) reserved for diagnostics, error handling, and keyboard configuration. Control flow is driven entirely by `GO TO` and `GO SUB` rather than structured loops. ### Loading Sequence On startup the loader displays a progress bar of colored block characters (line 2, using `\::` █ graphics in six ink colors), then loads two machine code blocks: “pc” CODE at address 51450 for 14000 bytes, and “code” CODE at 39694 for 5106 bytes. An `ON ERR GO TO 8200` at line 37 guards the second load. After loading, a flashing “TURN OFF TAPE PLAYER” notice is shown for about seven seconds (`PAUSE 350`). ### Machine Code Integration Almost all real-time activity is delegated to machine code via `USR` calls. The key entry points are: - `USR 51470` — screen/display refresh (called as `c1=USR 51470` or `l=USR 51470`) - `USR 39694` — joystick read, returns direction code stored in `i` - `USR 39840` — keyboard handler (called when `INKEY$<>""`) - `USR 40363` — collision/pickup sound effect - `USR 40381` — component connection sound/score update - `USR 40420` — timer encoding helper (packs `t` or `e` into a 16-bit POKE pair first) - `USR 44490`, `USR 44520` — level-transition effects - `USR 58420` — transition to circuit-board sub-game The return value of most `USR` calls is assigned to a throwaway variable (`l`, `c1`, `n`, `c`, `m`) simply to satisfy BASIC’s expression syntax; the real effect is a side effect inside the machine code. ### Game Phases The game has two distinct phases. Phase 1 (lines 995–1080) is a countdown timer maze: the player navigates toward screen position `x=14, y=11` while a timer `t` counts down. Phase 2 (lines 1990–2090 and 1500–1598) is a circuit-board component hunt: a randomly selected target component flashes on screen and the player must reach it. Transition between phases is managed by score thresholds checked at line 2705/2710 and by the `co` counter reaching 350 (line 2042). ### Movement Dispatch Player movement does not use a conventional `IF i=... THEN` block. Instead, the joystick/keyboard machine code routine at `USR 39694` or `USR 39840` appears to directly `GO TO` one of four handler lines by manipulating the BASIC interpreter’s program counter. The four directional handlers for Phase 1 are at lines 1101, 1141, 1181, and 1221; for Phase 2 at 2101, 2141, 2181, and 2221; for the circuit-board sub-game at 1600, 1640, 1680, and 1720. Each handler updates `x` or `y`, checks the cell attribute for the value `59` (INK 3, PAPER 7, BRIGHT 1 — a highlighted tile), prints the appropriate UDG character, erases the previous cell, then jumps back to the main loop. ### UDG Characters Four UDG characters are used for the player sprite, referenced as `\a` (left-facing), `\b` (down-facing), `\c` (right-facing), and `\e` (up-facing). Their bitmaps are defined by the machine code POKEd at startup — the BASIC listing never calls `POKE USR` directly in visible lines, implying the UDGs are set up inside the loaded machine code block. ### Score and High Score Storage The live score is maintained in machine code memory: address pair `40418`/`40419` holds the current score as a 16-bit little-endian value, read via `PEEK 40418+256*PEEK 40419`. The high score is stored at `39801`/`39800` (note reversed byte order for the high score vs. score) and the associated level at `39802`. On game start the player is prompted to enter the previous high score, which is split into low and high bytes and POKEd manually (line 43). ### Difficulty and Timer Lines 131–136 map the chosen difficulty level (0–5) to a starting timer value `t` ranging from 550 to 800. At line 3500, each time the player completes 350 component connections (`co>349`), the timer is reduced by 50 to a minimum of 450, increasing difficulty progressively. The level value is also POKEd into a range of machine code addresses (40301 to 40391, step 9) at lines 100–120. ### Scrolling Message Ticker When a random component task is assigned (`r < 10`, line 2044), a subroutine at line 3000 builds a long string `a$` describing the target. Lines 3030–3070 pad it with spaces and scroll it across 8 columns at row 8 by printing successive substrings `a$(w TO w+7)` with a `PAUSE 10` between each, a clean software ticker-tape effect entirely in BASIC. ### Keyboard Configuration Lines 8600–8635 allow the player to define custom keys for all four directions. Each key’s `CODE` value is POKEd directly into the machine code at hardcoded addresses: left=39844, down=39849, up=39854, right=39859. This means the machine code reads key codes from RAM rather than having them compiled in, providing a simple but effective remapping mechanism. ### Error Handling Lines 8200–8230 implement a retry loop for tape-load errors using `ON ERR`: on error the system is reset via `ON ERR RESET`, pauses briefly, then re-arms the error trap and resumes with `ON ERR CONTINUE`. This guards the potentially unreliable tape load of “code” at line 37. ### Anomalies and Notes - Line `1340` uses `GO TO 1320`, but line 1320 does not exist in the listing; this creates a tight busy-wait loop that effectively polls `INKEY$` at lines 1330/1334 until a key is pressed, which is an intentional (if undocumented) technique. - Line `2700` is targeted by `GO TO 2700` at lines 1075 and 1596, but the listing shows line `2705` as the first line in that region — line 2700 does not appear, so execution falls through to 2705, which is the intended behavior. - The diagnostic block at the second set of lines 8000–8030 (which conflicts with the loader’s 8000–8090 line numbers) prints raw PEEK values for addresses 30390–30460 and then STOPs — this appears to be a debugging fragment left in the listing. - The 16-bit score is stored with the low byte at 40418 and high byte at 40419, but the high score uses reversed addressing (low byte at 39801, high byte at 39800), an asymmetry that would cause the high score display to be byte-swapped relative to the live score if both exceed 255. ## Source Code ``` 8000 INK 0 8010 PAPER 0 8020 BORDER 0 8030 PRINT AT 15,0;" " 8040 CLEAR 39799 8050 LOAD "zman"SCREEN$ 8060 PRINT INK 1;AT 16,9;"\::" 8070 LOAD "zman" 8080 PRINT AT 15,0;" " 8090 SAVE "cb" LINE 8000 1 GO TO 40 2 PRINT INK 2;AT 16,10;"\::"; INK 3;AT 16,11;"\::"; INK 4;AT 16,12;"\::" 13 LOAD "pc"CODE 51450,14000 16 PRINT INK 5;AT 16,13;"\::"; INK 6;AT 16,14;"\::"; INK 7;AT 16,15;"\::" 37 LOAD "code"CODE 39694,5106: ON ERR GO TO 8200 38 PRINT INK 0; PAPER 7; BRIGHT 1; FLASH 1;AT 15,8;"TURN OFF";AT 16,7;"TAPE PLAYER" 39 PAUSE 350 40 LET c1=USR 51470 42 INPUT "PREVIOUS HIGH SCORE ";hs 43 POKE 39801,hs-(INT (hs/256))*256: POKE 39800,INT (hs/256) 44 INPUT "LEVEL OF PLAY 0 - 5 ";lp 45 POKE 39802,lp 48 INK 2 50 PAPER 7 56 BORDER 1 59 CLS 60 LET c1=USR 51470 65 POKE 40418,0: POKE 40419,0 70 LET e=0 80 LET score=0 89 POKE 40403,1 90 INPUT "INPUT YOUR LEVEL 0 - 5 ";dur 100 FOR f=40301 TO 40391 STEP 9 110 POKE f,dur 120 NEXT f 131 IF dur=0 THEN LET t=550 132 IF dur=1 THEN LET t=600 133 IF dur=2 THEN LET t=650 134 IF dur=3 THEN LET t=700 135 IF dur=4 THEN LET t=750 136 IF dur=5 THEN LET t=800 141 IF dur>5 OR dur<0 THEN GO TO 90 150 LET time=t 160 LET retime=t 200 INPUT "ENTER JOYSTICK j KEYS k "; LINE m$ 205 IF m$="j" THEN GO TO 250 208 IF m$="k" THEN GO TO 8600 210 GO TO 200 240 REM 1983 by Ken Frink 250 GO TO 950 900 LET t=retime 910 INK 2 912 PAPER 7 914 BORDER 1 916 CLS 920 LET l=USR 51470 930 LET score=0 940 POKE 40418,0: POKE 40419,0 950 FOR f=1 TO 200 960 NEXT f 970 GO SUB 4500 995 POKE 40793,0 997 POKE 40403,1 1000 LET y=12 1005 LET x=20 1010 PRINT AT y-2,x-2;"\c" 1020 LET t=t-1 1021 IF t<1 THEN GO TO 1250 1022 PRINT INK 0;AT 20,18;"\::";t;"\::" 1025 IF INKEY$<>"" THEN LET l=USR 39840 1030 IF m$="j" THEN LET i=USR 39694 1060 PRINT AT 20,4;PEEK 40418+256*PEEK 40419 1070 IF (PEEK 40418+256*PEEK 40419)-score>=287 THEN POKE 40793,1 1075 IF x=14 AND y=11 THEN GO TO 2700 1080 GO TO 1020 1101 LET x=x-1: IF ATTR (y-2,x-2)=59 THEN LET l=USR 40363 1105 PRINT AT y-2,x-2;"\a";AT y-2,x-1;" ": GO TO 1020 1141 LET y=y+1: IF ATTR (y-2,x-2)=59 THEN LET l=USR 40363 1145 PRINT AT y-2,x-2;"\b";AT y-3,x-2;" ": GO TO 1020 1181 LET y=y-1: IF ATTR (y-2,x-2)=59 THEN LET l=USR 40363 1185 PRINT AT y-2,x-2;"\e";AT y-1,x-2;" ": GO TO 1020 1221 LET x=x+1: IF ATTR (y-2,x-2)=59 THEN LET l=USR 40363 1225 PRINT AT y-2,x-2;"\c";AT y-2,x-3;" ": GO TO 1020 1250 FOR f=1 TO 20 1260 LET c1=USR 51470 1270 CLS 1280 NEXT f 1282 PRINT AT 5,5;"PREVIOUS HIGH ";PEEK 39801+256*PEEK 39800;AT 6,12;"LEVEL ";PEEK 39802 1285 PRINT AT 9,5;"YOUR SCORE IS ";PEEK 40418+256*PEEK 40419;AT 10,12;"LEVEL ";dur 1290 IF PEEK 40418+256*PEEK 40419>PEEK 39801+256*PEEK 39800 THEN POKE 39801,PEEK 40418: POKE 39800,PEEK 40419: POKE 39802,dur: PRINT AT 13,8;"CONGRATULATIONS"," YOU HAVE JUST BECOME"," CHAMP OF THE CHIPS": GO TO 1310 1310 PRINT AT 17,0;" PRESS THE G KEY FOR ANOTHER GO" 1315 PRINT AT 19,0;" PRESS THE B KEY TO CHANGE GAME" 1330 IF INKEY$="g" THEN GO TO 900 1334 IF INKEY$="b" THEN GO TO 48 1340 GO TO 1320 1350 GO TO 900 1400 REM CIRCUIT BOARD SCRAMBLE \* 1983 BY KEN FRINK 1500 PAPER 7 1510 BORDER 1 1520 LET l=USR 51470 1525 GO SUB 4600 1530 LET y=12: LET x=20 1535 PRINT AT 20,4;PEEK 40418+256*PEEK 40419 1540 PRINT AT y-2,x-2;"\c" 1542 POKE 40793,0 1545 PRINT INK 2; BRIGHT 1; FLASH 1;AT te-2,as-2;"*" 1550 LET e=e-1: IF e<1 THEN GO TO 1250 1560 PRINT INK 0;AT 20,18;"\::";e;"\::" 1570 IF INKEY$<>"" THEN LET l=USR 39840 1580 LET i=USR 39694 1595 IF x=as AND y=te THEN POKE 40793,1 1596 IF x=14 AND y=11 THEN GO TO 2700 1598 GO TO 1550 1600 LET x=x-1: PRINT AT y-2,x-2;"\a";AT y-2,x-1;" ": GO TO 1550 1640 LET y=y+1: PRINT AT y-2,x-2;"\b";AT y-3,x-2;" ": GO TO 1550 1680 LET y=y-1: PRINT AT y-2,x-2;"\e";AT y-1,x-2;" ": GO TO 1550 1720 LET x=x+1: PRINT AT y-2,x-2;"\c";AT y-2,x-3;" ": GO TO 1550 1990 LET p=1100 2000 POKE 40426,t-256*INT (t/256): POKE 40427,INT (t/256): LET m=USR 40420: LET t=0 2001 INK 2 2002 PAPER 6 2004 BORDER 3 2005 LET y=23: LET x=18 2007 POKE 40403,2 2010 PRINT INK 2;AT y-2,x-2;"\e" 2015 POKE 39869,240: POKE 39870,122: POKE 39901,126: POKE 39902,123: POKE 39960,18: POKE 39961,124: POKE 39931,166: POKE 39932,124: POKE 39990,58: POKE 39991,125: POKE 39998,41: POKE 39999,164 2030 PRINT PAPER 6; FLASH 1;AT 21,15;"\::" 2040 LET p=p-1: LET e=e-1: LET r=INT (RND*1500) 2041 IF p<1 THEN GO TO 1250 2042 IF co>349 THEN GO TO 3500 2044 IF r<10 THEN GO SUB 3000 2050 IF INKEY$<>"" THEN LET l=USR 39840 2060 IF m$="j" THEN LET i=USR 39694 2080 PRINT INK 0; PAPER 7; BRIGHT 1;AT 13,13;PEEK 40418+256*PEEK 40419 2085 IF y=23 AND x=17 THEN GO TO 2500 2090 GO TO 2040 2101 LET x=x-1: IF ATTR (y-2,x-2)=52 THEN LET n=USR 40381: LET co=co+1 2105 PRINT AT y-2,x-2;"\a";AT y-2,x-1;" ": GO TO 2040 2141 LET y=y+1: IF ATTR (y-2,x-2)=52 THEN LET n=USR 40381: LET co=co+1 2145 PRINT AT y-2,x-2;"\b";AT y-3,x-2;" ": GO TO 2040 2181 LET y=y-1: IF ATTR (y-2,x-2)=52 THEN LET n=USR 40381: LET co=co+1 2185 PRINT AT y-2,x-2;"\e";AT y-1,x-2;" ": GO TO 2040 2221 LET x=x+1: IF ATTR (y-2,x-2)=52 THEN LET n=USR 40381: LET co=co+1 2225 PRINT AT y-2,x-2;"\c";AT y-2,x-3;" ": GO TO 2040 2500 LET c=USR 44520 2530 GO TO 1500 2705 IF (PEEK 40418+256*PEEK 40419)-score>289 THEN LET c=USR 44490: GO TO 2730 2710 IF (PEEK 40418+256*PEEK 40419)-score<288 THEN LET c=USR 58420: LET co=0: GO TO 1990 2730 POKE 40426,e-256*INT (e/256): POKE 40427,INT (e/256): LET m=USR 40420: LET e=0 2740 GO TO 2001 3000 LET b$="*** GO TO CIRCUIT BOARD AND CHECK " 3001 IF r=0 THEN LET a$=b$+"VOLTAGE REGULATOR ***": LET as=33: LET te=18 3002 IF r=1 THEN LET a$=b$+"UNCOMMITTED LOGIC ARRAY ***": LET as=14: LET te=3 3003 IF r=2 THEN LET a$=b$+"32 K RANDOM ACCESS MEMORY ***": LET as=2: LET te=23 3004 IF r=3 THEN LET a$=b$+"READ ONLY MEMORY ***": LET as=29: LET te=3 3005 IF r=4 THEN LET a$=b$+"CENTRAL PROCESSOR UNIT ***": LET as=25: LET te=3 3006 IF r=5 THEN LET a$=b$+"TV MODULATOR ***": LET as=2: LET te=2 3007 IF r=6 THEN LET a$=b$+"LOUDSPEAKER ***": LET as=33: LET te=23 3008 IF r=7 THEN LET a$=b$+"9 VOLT INPUT ***": LET as=33: LET te=5 3009 IF r=8 THEN LET a$=b$+"EDGE CONNECTOR ***": LET as=31: LET te=2 3010 IF r=9 THEN LET a$=b$+"CASSETTE INPUT ***": LET as=9: LET te=2 3015 PRINT PAPER 7;AT 13,12;" " 3020 PRINT INK 2; PAPER 7; BRIGHT 1; FLASH 1;AT 13,14;p 3030 LET a$=" "+a$+" " 3040 LET e=150: LET b=LEN (a$)-8 3050 FOR w=1 TO b 3060 PRINT INK 2; PAPER 7; BRIGHT 1;AT 8,12;a$(w TO w+7): PAUSE 10 3070 NEXT w 3075 PRINT PAPER 7;AT 13,12;" " 3080 RETURN 3500 LET t=time-50 3505 LET time=t 3510 IF t<450 THEN LET t=450 3520 LET c1=USR 51470 3530 LET score=PEEK 40418+256*PEEK 40419 3540 INK 2 3550 PAPER 7 3555 BORDER 1 3557 GO SUB 4500 3560 GO TO 995 4500 POKE 39869,252: POKE 39870,110 4510 POKE 39901,190: POKE 39902,111 4520 POKE 39960,67: POKE 39961,112 4530 POKE 39931,200: POKE 39932,112 4540 POKE 39990,77: POKE 39991,113 4550 POKE 39998,129: POKE 39999,159 4560 RETURN 4600 POKE 39869,94: POKE 39870,118 4610 POKE 39901,185: POKE 39902,118 4620 POKE 39960,9: POKE 39961,119 4630 POKE 39931,89: POKE 39932,119 4640 POKE 39990,169: POKE 39991,119 4650 POKE 39998,129: POKE 39999,159 4660 RETURN 8000 FOR f=30390 TO 30460 8010 PRINT f;" ";PEEK f 8020 NEXT f 8030 STOP 8200 ON ERR RESET 8210 PAUSE 100 8220 ON ERR GO TO 8200 8230 ON ERR CONTINUE 8400 IF INKEY$<>"" THEN LET i=USR 39840 8500 DIM s(2) 8510 DIM d(11,14) 8530 STOP 8600 INPUT "KEY FOR UP MOTION ";U$ 8605 POKE 39854,CODE U$ 8610 INPUT "KEY FOR DOWN MOTION ";D$ 8615 POKE 39849,CODE D$ 8620 INPUT "KEY FOR LEFT MOTION ";L$ 8625 POKE 39844,CODE L$ 8630 INPUT "KEY FOR RIGHT MOTION ";R$ 8635 POKE 39859,CODE R$ 8640 GO TO 250 ```