--- title: "Multiprogram Demo" id: 55906 type: "computer_media" slug: "multiprogram-demo" url: "http://localhost/computer_media/multiprogram-demo/" markdown_url: "http://localhost/computer_media/multiprogram-demo.md" published_at: "2024-07-08T11:06:44+00:00" modified_at: "2026-04-04T20:17:49+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/07/SCR-20240708-fhom.png" excerpt: "Defend your planet from invisible robot invaders by hitting the right key at the right moment in this tense keyboard-reflex arcade game with block-graphic alien sprites." 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: "SyncWare Co." slug: "syncware-co" taxonomy: "post_tag" url: "http://localhost/tag/syncware-co/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Fred Nachbaur" slug: "fred-nachbaur" taxonomy: "indiv" url: "http://localhost/indiv/fred-nachbaur/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" programmers: - name: "Fred Nachbaur" slug: "fred-nachbaur" taxonomy: "indiv" url: "http://localhost/indiv/fred-nachbaur/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Multiprogram%20Demo%20%281983%29%28SyncWare%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1983" producer_company: - id: 11370 title: "SyncWare Co." type: "company" url: "http://localhost/company/syncware-co/" images: - url: "http://localhost/wp-content/uploads/2024/07/SCR-20240708-fhom.png" - url: "http://localhost/wp-content/uploads/2024/07/SCR-20240708-fgqb.png" related_products: - id: 13400 title: "Multiprogram Demo" type: "product" url: "http://localhost/product/multiprogram-demo/" media_type_tags: "Game" --- # Multiprogram Demo Multiprogram Demo is a collection of demo versions of programs from the “[Fun and Games](http://localhost/product/fun-and-games-i/)” tape, with the main interactive piece being SYNCWARS, a keyboard-reflex game in which the player must destroy alien SYNCLOIDS and their hidden SYNCLON commanders by pressing the key corresponding to each enemy’s screen position. The game uses USR calls to machine code routines at addresses 16514, 16567, and 16608 for display and timing effects, and employs a position-calculation algorithm at line 2950 that maps random values to screen coordinates using division and modulo arithmetic. Enemy sprites are drawn using block graphics characters arranged in multi-line PRINT AT sequences, giving the illusion of structured alien figures. Numeric variables N0–N5 and O0 are pre-initialized via VAL literals as a memory-saving technique common in constrained BASIC programming. A SAVE command at line 1330 and CLEAR/RUN sequences suggest the tape contains a chained multi-program loader structure. *** ## Program Analysis ### Program Structure The listing is organized into several distinct functional regions, reflecting a multi-program loader design: 1. **Lines 1–8:** REM headers (containing embedded data) and a `GOTO VAL "2000"` entry point. 2. **Lines 10–30:** A subroutine that POKEs values into address 16609 and calls `USR 16608` twice, likely a display or border effect routine. 3. **Lines 1325–1335:** A CLEAR/SAVE/RUN block for chaining to the next program on tape (`SYNCWARS-4K`). 4. **Lines 1510–1570:** A subroutine (called from line 2880 when score equals 10) that cycles through screen rows, POKEing and USR-calling address 16514, and prints a “TOP SCORE” banner. 5. **Lines 2001–2890:** Main game initialization and game loop for SYNCWARS. 6. **Lines 2910–2968:** Sprite-drawing and position-calculation subroutines. 7. **Lines 3000–3020:** A short delay loop subroutine. 8. **Lines 9300–9350:** End-of-game display subroutine. 9. **Lines 9995–9998:** A secondary loader block using `RAND USR 20480` to jump to machine code at address 20480. ### Machine Code Usage The program makes extensive use of `USR` calls to pre-loaded machine code routines. The results are assigned to the dummy variable `M` since BASIC requires a value to be returned from `USR`: | Address | Usage | Context | | --- | --- | --- | | 16514 | `USR 16514` | Called in the top-score scroll (line 1540) and end-of-game sequence (line 9320) | | 16567 | `USR VAL "16567"` | Called after POKEing a character code to 16568, used for character output (lines 2070, 2680) | | 16608 | `USR 16608` | Called after POKEing to 16609, likely a border/display effect (lines 15, 25) | | 20480 | `RAND USR 20480` | Loader entry point at line 9996 | The POKE/USR pattern at lines 2050–2070 is particularly notable: a character code is POKEd to address 16568, then `USR 16567` is called — this is a classic technique for driving a machine code character-output routine from BASIC, iterating over the characters of `A$` to initialize some display or keyboard mapping table. ### Numeric Variable Optimization Lines 2001–2007 pre-initialize a set of short-name variables using `VAL "n"` literals: - `N0` = 0, `N1` = 1, `N2` = 2, `N3` = 3, `N5` = 5 - `O0` = 10 Using single- or two-character variable names with `VAL`-encoded literals reduces the per-token storage cost of numeric literals throughout the program. The `VAL "number"` idiom also prevents the interpreter from storing a floating-point five-byte value inline in the tokenized line, saving memory especially when a constant is used many times. ### Game Mechanics and Loop The core game loop runs from line 2625 to 2870, iterating `C` from 1 to 10 (one round per enemy). Each iteration: 1. Calls `GOSUB 2950` to randomly position the SYNCLOID (`D,E,G`) and SYNCLON (`H,I,K`) on screen, ensuring they don’t share the same slot. 2. Draws the SYNCLOID sprite (visible) via `USR 16567` and `GOSUB 2910`. 3. Waits for a keypress in an inner loop; the available time decreases as `C` increases (`O0-C/N3`). 4. If the player hits the SYNCLOID’s key (`A$(H+N1)`), transitions to phase 2 (reveal/destroy the SYNCLON via `GOSUB 2920`). 5. If the player hits the SYNCLON’s key directly (`A$(D+N1)`), the shot is still counted valid (line 2707 falls through to the Synclon phase). 6. A miss displays a “`>[*]<`” marker and gives a brief second-chance window (lines 2850–2858). 7. Too-slow response triggers the “TOO SLOW” message at line 2820. ### Position Calculation Subroutine Lines 2950–2969 convert a random integer in range 0–37 to row/column screen coordinates: - `D = INT(RND*38)` — random slot index - `E = INT(D/10)` — row zone (0–3) - `G = (D - 10*E)*3 + E` — column offset with spacing - `E = E*6 - 1` — final row coordinate The same formula is applied independently for `H/I/K` (SYNCLON), with a collision check at line 2962 re-rolling if `H=D`. This maps 38 discrete slots onto a grid spread across the display. ### Sprite Drawing All sprites are drawn with multi-line `PRINT AT row,col` sequences using `TAB` to re-position within the same PRINT statement, building up a 5-row block-graphic figure. For example, the SYNCLOID sprite (line 2910) prints five rows of three characters each using `TAB G` to align each row. The destruction animation (line 2940) replaces the sprite with asterisk/block-graphic “explosion” characters. ### Keyboard Mapping The string `A$` at line 2085 encodes the full keyboard layout in a single string: digits, then `QWERTY...` rows including `CHR$ 118` (ENTER/NEWLINE) and ending with `ZXCVBNM.`. Enemy positions are mapped to indices into this string, so pressing the key at the corresponding position in `A$` identifies a hit. ### Scoring and Chaining Score `F` is incremented for each successful destroy. At the end of 10 rounds (line 2875), the end-of-game screen is displayed. If `F=10` (perfect score), the top-score subroutine at line 1500 is called. After the end screen, the game loops back to line 2560 (the instructions/start prompt). Line 1330 provides a tape-chaining save point, saving the next program as `SYNCWARS-4K` and immediately running it, suggesting this demo is part of a larger chained tape sequence. ### Notable Anomalies - Line 2880 calls `GOSUB 1500` but the subroutine begins at line 1510; there is no line 1500, so execution falls through to 1510 — this is a deliberate technique, not a bug. - Line 2890 jumps to `VAL "2560"` but line 2560 does not exist in the listing; line 2570 is the next defined line. Execution would therefore continue from line 2570 (the “PUSH ANY KEY” prompt), which is the intended behavior for restarting the game. - The delay loop at lines 3000–3020 iterates only `O0` (10) times, making it extremely short — effectively just a brief synchronization pause rather than a perceptible delay. - Line 9998 (`PRINT PEEK 16412+256*PEEK 16413`) reads the system variable PROG and prints the start address of the BASIC program — likely a debugging remnant. ## Source Code ``` 1 REM E£RND▞;# RETURN#4▖▌COS /▀LEN █#7/ LET 5 T GOSUB #0RND GOSUB PI##TAN 2 REM SYNCWARS 3 REM Y[*]▞*:4NOT $TAB [X]RND▌TAB [V]RNDTAN 4 REM BY F.NACHBAUR 5 REM Y2 GOSUB #TAN 8 GOTO VAL "2000" 10 POKE 16609,14 15 LET M=USR 16608 20 POKE VAL "16609",30 25 LET M=USR 16608 30 RETURN 1325 CLEAR 1330 SAVE "SYNCWARS-4[K]" 1335 RUN 1510 FOR C=N1 TO N2 1520 FOR D=N1 TO VAL "24" 1530 POKE VAL "16518",D 1540 LET M=USR VAL "16514" 1545 IF D=VAL "18" THEN PRINT AT D,VAL "8";"***TOP SCORE***" 1547 IF D=VAL "17" OR D=VAL "19" THEN PRINT AT D,VAL "8";"===============" 1550 NEXT D 1560 NEXT C 1570 RETURN 2001 LET N0=VAL "0" 2002 LET N1=VAL "1" 2003 LET N2=VAL "2" 2004 LET N3=VAL "3" 2005 LET N5=VAL "5" 2007 LET O0=VAL "10" 2020 LET A$="[*][.][▒]*." 2030 POKE VAL "16418",N0 2040 FOR C=N1 TO LEN A$ 2050 POKE VAL "16568",CODE A$(C) 2060 PRINT AT N0,N0; 2070 LET M=USR VAL "16567" 2080 NEXT C 2085 LET A$="1234567890QWERTYUIOPASDFGHJKL"+CHR$ VAL "118"+"ZXCVBNM." 2090 LET E=N3 2092 LET G=VAL "28" 2094 LET I=VAL "18" 2095 LET K=VAL "16" 2100 GOSUB VAL "2910" 2110 GOSUB VAL "3000" 2130 GOSUB O0 2190 GOSUB VAL "2920" 2200 GOSUB VAL "3000" 2220 GOSUB O0 2230 GOSUB VAL "2940" 2410 GOSUB VAL "3000" 2430 POKE VAL "16518",VAL "25" 2440 GOSUB VAL "9310" 2450 PRINT AT N2,VAL "11";"SYNCWARS" 2470 GOSUB VAL "3000" 2475 GOSUB VAL "3000" 2490 PRINT AT N0,N3;"YOUR PLANET IS BEING INVADED BY 10 DREAD SYNCLONS AND THEIR ""INVISIBILITY FIELD"" ROBOTS, THESYNCLOIDS." 2501 LET G=O0 2503 LET I=N3 2504 GOSUB VAL "2910" 2505 GOSUB VAL "2930" 2510 PRINT TAB N5;"SYNCLOID SYNCLON",,, 2530 PRINT " AT FIRST ONLY THE SYNCLOID ROBOT APPEARS; YOU MUST DESTROY IT TO MAKE ENEMY SYNCLON VISIBLE(BY PRESSING KEY CORRESPONDING TO ITS POSITION), AND THENVAP- ORIZE THE SYNCLON TO SCORE. IF YOU MISS THE ROBOT, BUT HIT THE (HIDDEN) SYNCLON, YOUR SHOT IS STILL VALID." 2570 PRINT AT VAL "22",N0;"PUSH ANY KEY" 2580 PRINT " TO START." 2590 IF INKEY$ <>"" THEN GOTO VAL "2620" 2610 GOTO VAL "2590" 2620 LET F=N0 2625 FOR C=N1 TO O0 2630 CLS 2640 FOR A=N1 TO RND*VAL "40" 2650 NEXT A 2670 GOSUB 2950 2680 LET M=USR 16567 2690 GOSUB 2910 2700 FOR A=N1 TO O0-C/N3 2701 LET D$=INKEY$ 2702 IF D$="" THEN GOTO 2708 2703 GOSUB O0 2704 IF D$=A$(H+N1) THEN GOTO 2750 2705 IF D$<>A$(D+N1) THEN GOTO 2850 2707 GOTO 2710 2708 NEXT A 2709 GOTO 2810 2710 GOSUB 2920 2720 FOR A=N1 TO O0-C/N3 2721 LET D$=INKEY$ 2722 IF D$="" THEN GOTO 2728 2723 GOSUB O0 2724 IF D$<>A$(H+N1) THEN GOTO 2850 2727 GOTO 2750 2728 NEXT A 2730 GOTO 2810 2750 GOSUB 2940 2760 LET F=F+N1 2770 PRINT AT VAL "23",N0;"SCORE=";F 2780 GOSUB VAL "3000" 2790 GOTO 2870 2810 CLS 2820 PRINT AT O0,O0;"█[T][O][O]█[S][L][O][W]█" 2830 GOSUB VAL "3000" 2840 GOTO VAL "2870" 2850 PRINT AT I+N1,K;">[*]<" 2851 FOR A=N1 TO N5 2852 LET D$=INKEY$ 2853 IF D$="" THEN GOTO 2858 2854 GOSUB O0 2855 IF D$=A$(H+N1) THEN GOTO 2750 2857 GOTO 2870 2858 NEXT A 2870 NEXT C 2875 GOSUB VAL "9300" 2876 GOSUB VAL "3000" 2880 IF F=O0 THEN GOSUB 1500 2890 GOTO VAL "2560" 2910 PRINT AT E+N1,G;"> <";TAB G;"▛█▜";TAB G;"█▀█";TAB G;"▟█▙";TAB G;"▛ ▜" 2915 RETURN 2920 GOSUB 2936 2922 CLS 2925 GOSUB 2936 2930 PRINT AT I+N1,K;"> <";TAB K;"▛█▜";TAB K;"█[~~]█";TAB K;"▙▄▟";TAB K;"▟▀▙" 2935 RETURN 2936 PRINT AT E+N1,G;" / ";TAB G;"< <";TAB G;"▞▛*";TAB G;"▟█▙";TAB G;"▛ ▜" 2937 RETURN 2940 PRINT AT I+1,K;"[G][O][T]";TAB K;"▗*▖";TAB K;"***";TAB K;"▝*▘";TAB K;"[M][*][E]" 2945 RETURN 2950 LET D=INT (RND*VAL "38") 2952 LET E=INT (D/O0) 2955 LET G=(D-O0*E)*N3+E 2957 LET E=E*VAL "6"-N1 2960 LET H=INT (RND*VAL "38") 2962 IF H=D THEN GOTO VAL "2960" 2965 LET I=INT (H/O0) 2967 LET K=(H-O0*I)*N3+I 2968 LET I=I*VAL "6"-N1 2969 RETURN 3000 FOR A=N1 TO O0 3010 NEXT A 3020 RETURN 9300 PRINT AT VAL "12",VAL "8";" █[E][N][D]█[O][F]█[G][A][M][E][.]█ ",,,"FINAL SCORE=";F;" OUT OF 10" 9310 FOR A=N1 TO VAL "6" 9320 LET M=USR 16514 9330 NEXT A 9350 RETURN 9995 CLEAR 9996 RAND USR 20480 9997 RUN 9998 PRINT PEEK 16412+256*PEEK 16413 ```