Multiprogram Demo is a collection of demo versions of programs from the “Fun and Games” 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:
- Lines 1–8: REM headers (containing embedded data) and a
GOTO VAL "2000"entry point. - Lines 10–30: A subroutine that POKEs values into address 16609 and calls
USR 16608twice, likely a display or border effect routine. - Lines 1325–1335: A CLEAR/SAVE/RUN block for chaining to the next program on tape (
SYNCWARS-4K). - 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.
- Lines 2001–2890: Main game initialization and game loop for SYNCWARS.
- Lines 2910–2968: Sprite-drawing and position-calculation subroutines.
- Lines 3000–3020: A short delay loop subroutine.
- Lines 9300–9350: End-of-game display subroutine.
- Lines 9995–9998: A secondary loader block using
RAND USR 20480to 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= 5O0= 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:
- Calls
GOSUB 2950to randomly position the SYNCLOID (D,E,G) and SYNCLON (H,I,K) on screen, ensuring they don’t share the same slot. - Draws the SYNCLOID sprite (visible) via
USR 16567andGOSUB 2910. - Waits for a keypress in an inner loop; the available time decreases as
Cincreases (O0-C/N3). - If the player hits the SYNCLOID’s key (
A$(H+N1)), transitions to phase 2 (reveal/destroy the SYNCLON viaGOSUB 2920). - 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). - A miss displays a “
>[*]<” marker and gives a brief second-chance window (lines 2850–2858). - 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 indexE = INT(D/10)— row zone (0–3)G = (D - 10*E)*3 + E— column offset with spacingE = 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 1500but 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.
Content
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

