VOCABUILDER 1000 Version 2.0 is a two-language vocabulary flashcard and testing program. It stores up to 100 word-pairs in a two-dimensional string array A$(2, W+1, 32), supporting add, edit, insert, and delete operations via a full-screen editor, plus two randomised test modes (random-only and random with language interchange). The program uses FAST/SLOW switching throughout to maximise display speed during computation and restore keyboard responsiveness for input. Results can be sent to a printer via LPRINT, and the vocabulary file is saved to tape with a deliberate PAUSE 420 leader-compensation delay before the SAVE command.
Program Structure
The program is divided into clearly separated modules, each residing at a round-number line block, dispatched from the main menu via the idiom GOTO A*1000 at line 250:
| Line block | Function |
|---|---|
| 90–250 | Initialisation and main menu |
| 1000–1710 | Edit / Add / Insert / Delete file viewer |
| 2000–2660 | Practice mode (menu option 2) |
| 3000–3530 | Test 1 – Random only; shared report subroutine |
| 4000–4050 | Test 2 – Random + Interchange |
| 5000–5120 | New file setup |
| 6000–6210 | Printer output |
| 7000–7200 | Save to tape |
| 9998–9999 | Bootstrap: saves program then re-runs from line 95 |
Lines 95 and 97 set the working constants W=100 (maximum slots) and N=1 (next free slot). Line 90 jumps over these so that a plain RUN preserves previously loaded data; line 9999 uses RUN 95 after the bootstrap save so defaults are always initialised fresh.
Data Model
All vocabulary is held in the three-dimensional string array A$(2, W+1, 32), dimensioned at line 5090. The first dimension selects the language (1 or 2), the second selects the word-pair slot, and the third is the 32-character string length. Language names are stored in N$(2, N) where N is computed as the length of the longer name, capped at 16 characters.
A parallel two-dimensional array B$(2, E) is used during tests to track per-slot state: a space character means untested/wrong (needs re-attempt), "1" means correctly answered in practice mode, and "X" records a wrong answer in test modes for the report.
Menu Dispatch and Input Validation
The main menu dispatch at line 250 uses GOTO A*1000, where A = VAL Y$. This is an elegant computed GOTO that requires no IF chain. Input validation at lines 220–225 prevents illegal choices and also blocks options 2–4 and 6 when fewer than two entries exist (N<2), since practice and testing are meaningless on an empty file.
Editor Navigation
The file editor at line 1000 displays five entries at a time (controlled by Y=5 at line 1040). Navigation commands entered as strings are parsed by their first character Z$=Y$(1):
C– Continue: advance by one slotB– Back: retreat by 9 slots (net −10 then +1 on next display)Snnn – Start from slot nnnInnn – Insert before slot nnn (shifts entries up)Dnnn – Delete slot nnn (shifts entries down)Ennn – Edit slot nnnA– Add at the end (next free slot)
Insert (lines 1310–1370) loops from N+1 down to the target slot+1 with STEP -1, copying each entry one place up — a correct in-place array shift. Delete (lines 1400–1470) loops forward, shifting entries down.
Test and Practice Logic
Practice mode (option 2) and Test 1 (option 3) share a GOSUB-based structure. The practice subroutine begins at line 2160 (screen clear and random pick) and is called from both 3050 and the practice main loop. The variable A (the original menu choice, 2, 3, or 4) is tested inside the subroutine at lines 2272 and 2300 to determine whether to branch back to the report or return to the caller — a non-obvious coupling between the subroutine and calling context.
Test 2 (option 4) selects a random language each round (L=INT(RND*2)+1) and after 10 consecutive failed attempts to find an untested slot (Z>10 at line 2203), switches to a sequential scan of remaining slots (lines 2600–2660).
FAST/SLOW Switching
The program switches to FAST mode before computation-heavy or display-heavy sections and returns to SLOW before every INPUT statement. This pattern appears at least a dozen times (e.g. lines 100, 205, 215, 1003, 1069, 1075, 2025, 2125, 2255, 2270) and is idiomatic for maximising display performance while keeping keyboard scanning reliable.
Tape Save Sequence
The save routine at line 7000 includes a PAUSE 420 (approximately 7 seconds at line 7087) before the SAVE command, explicitly described in the on-screen instructions as automatic tape-leader compensation. The variable array G$ is redimensioned to DIM G$(1) at line 7005 before saving, discarding any temporary quiz data that should not be persisted. The bootstrap block at lines 9998–9999 saves the program itself under the name "VOCAB 1000" (the %0 renders as the digit 0 via the inverse-character idiom) then restarts cleanly.
Notable Techniques and Idioms
NOT PIevaluates to 0 (since PI is non-zero, NOT returns 0), used as a portable zero constant in severalATandPRINTexpressions (lines4020,5040,6011, etc.).NOT (L-1)toggles between 0 and 1, used to select the opposite language index (lines2210,2220,2630).- Score calculation at line
3470uses the boolean expressions(A=3)and(2 AND A=4)to compute a multiplier of 1 for Test 1 or 2 for Test 2, avoiding anIFbranch. - The print format
"%S%L%O%T%S"uses inverse-video characters (the%prefix renders each following letter in inverse) to produce highlighted text in the menu header. LET S=PI/PIat line1000is an unnecessarily indirect way to setS=1, possibly written this way for novelty or to avoid a literal1.
Content
Source Code
90 GOTO 100
95 LET W=100
97 LET N=1
100 FAST
101 DIM B$(1)
102 DIM G$(32)
103 LET Q=0
104 LET F=Q
105 CLS
110 PRINT "\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':\: VOCABUILDER 1000 VERSION 2.0\ :\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
115 PRINT ,,"%S%L%O%T%S% %U%S%E%D ";N-1,"%S%L%O%T%S% %L%E%F%T ";W-N+1
120 PRINT AT 7,11;"**% %M%E%N%U% **"
130 PRINT AT 9,0;"<1> EDIT / ADD / CHECK FILE"
140 PRINT "<2> PRACTICE VOCABULARIES"
150 PRINT "<3> TEST 1--RANDOM ONLY"
160 PRINT "<4> TEST 2--RANDOM + INTERCHANGE"
170 PRINT "<5> SETUP NEW FILE"
180 PRINT "<6> HARD COPY--PRINTER OUTPUT"
190 PRINT "<7> SAVE ON TAPE"
200 PRINT AT 20,0;" INPUT YOUR CHOICE BY NUMBER ?",," \''\''\''\''\''\''\''\''\''"
205 SLOW
210 INPUT Y$
215 FAST
220 IF Y$="" OR Y$<"1" OR Y$>"7" THEN GOTO 205
225 IF VAL Y$>7 OR Y$<>"1" AND Y$<>"5" AND Y$<>"7" AND N<2 THEN GOTO 205
230 CLS
240 LET A=VAL Y$
250 GOTO A*1000
\n1000 LET S=PI/PI
\n1003 FAST
\n1004 LET Y=1
\n1005 FOR Z=S TO N
\n1010 PRINT "% %N%U%M%B%E%R% ";Z;"---"
\n1020 PRINT A$(1,Z)
\n1030 PRINT A$(2,Z)
\n1040 IF Y=5 THEN GOTO 1060
\n1045 LET Y=Y+1
\n1050 NEXT Z
\n1060 PRINT AT 16,0;"% % E%D%I%T% % % A%D%D% % % I%N%S%E%R%T% % % D%E%L%E%T%E% % % % C%O%N%T%I%N%U%E% % % B%A%C%K% % % S%T%A%R%T% %F%R%O%M% % "
\n1065 IF N>W THEN PRINT ,,,,,,"% %F%I%L%E% %F%U%L%L% "
\n1069 SLOW
\n1070 INPUT Y$
\n1075 FAST
\n1080 IF Y$="" THEN GOTO 100
\n1090 LET Z$=Y$(1)
\n1100 IF Z$="B" OR Z$="C" OR Z$="S" THEN GOTO 1200
\n1110 IF Z$="I" OR Z$="D" THEN GOTO 1300
\n1120 IF Z$="E" OR Z$="A" THEN GOTO 1500
\n1130 GOTO 1069
\n1200 IF Z$="C" THEN LET Z=Z+1
\n1210 IF Z$="B" THEN LET Z=Z-9
\n1215 IF Z$="S" AND LEN Y$=1 THEN GOTO 1069
\n1220 IF Z$="S" THEN LET Z=VAL Y$(2 TO )
\n1230 IF Z>N THEN LET Z=N-4
\n1240 IF Z<1 THEN LET Z=1
\n1245 LET S=Z
\n1250 CLS
\n1260 GOTO 1004
\n1300 IF LEN Y$=1 THEN GOTO 1069
\n1302 IF VAL Y$(2 TO )>=N OR VAL Y$(2 TO )<1 THEN GOTO 1069
\n1305 IF Z$="D" THEN GOTO 1400
\n1307 IF N>W THEN GOTO 1069
\n1310 FOR Q=N+1 TO VAL Y$(2 TO )+1 STEP -1
\n1320 LET A$(1,Q)=A$(1,Q-1)
\n1330 LET A$(2,Q)=A$(2,Q-1)
\n1340 NEXT Q
\n1350 LET Z$="E"
\n1360 LET N=N+1
\n1370 GOTO 1510
\n1400 FOR Q=VAL Y$(2 TO ) TO N
\n1410 LET A$(1,Q)=A$(1,Q+1)
\n1420 LET A$(2,Q)=A$(2,Q+1)
\n1430 NEXT Q
\n1440 IF N>1 THEN LET N=N-1
\n1450 LET S=VAL Y$(2 TO )-2
\n1455 IF S+4>N THEN LET S=N-4
\n1457 IF S<1 THEN LET S=1
\n1460 CLS
\n1470 GOTO 1003
\n1500 IF Z$="E" AND LEN Y$=1 THEN GOTO 1069
\n1510 IF Z$="E" THEN LET E=VAL Y$(2 TO )
\n1512 IF Z$="E" THEN IF E>N-1 THEN GOTO 1069
\n1515 IF Z$="A" AND N>W THEN GOTO 1069
\n1520 IF Z$="A" THEN LET E=N
\n1525 PRINT AT 16,0;"% % N%E%X%T% % % % % ""ENTER""% %T%O% %T%E%R%M%I%N%A%T%E% % % % % % % % % % % % %W%H%E%N% %"%>%"% %I%S% %S%H%O%W%I%N%G% % "
\n1530 PRINT AT 19,0;"% %N%U%M%B%E%R% ";E;TAB 14;"?>";N$(1)
\n1540 INPUT Y$
\n1545 IF Y$="N" THEN GOTO 1580
\n1550 IF Y$="" THEN GOTO 1700
\n1560 LET A$(1,E)=Y$
\n1570 PRINT A$(1,E)
\n1580 PRINT AT 19,15;" ";N$(2)
\n1590 INPUT Y$
\n1600 IF Y$="" OR Y$="N" THEN GOTO 1530
\n1610 LET A$(2,E)=Y$
\n1700 LET Y$=Z$+STR$ E
\n1705 IF Z$="A" THEN LET N=N+1
\n1710 GOTO 1450
\n2000 PRINT "***********% %P%R%A%C%T%I%C%E% ***********"
\n2010 PRINT AT 3,0;" INPUT LANGUAGE TO BE TESTED ? (BY NUMBER)"
\n2020 PRINT ,,"<1> ";N$(1);TAB 0;"<2> ";N$(2)
\n2022 PRINT AT 21,0;" INPUT ""0"" TO TERMINATE"
\n2025 SLOW
\n2030 INPUT L
\n2035 IF L<1 THEN GOTO 100
\n2040 IF L>2 THEN GOTO 2030
\n2050 PRINT AT 3,30;L
\n2060 PRINT AT 11,0;" INPUT STARTING NUMBER ? ";
\n2070 INPUT S
\n2080 IF S<1 THEN GOTO 100
\n2090 IF S>=N THEN LET S=N-1
\n2095 IF S<1 THEN LET S=1
\n2100 PRINT S
\n2110 PRINT ,," INPUT ENDING NUMBER ? "
\n2120 INPUT E
\n2125 FAST
\n2130 IF E<1 THEN GOTO 100
\n2135 IF E<S THEN LET E=S
\n2140 IF E>=N THEN LET E=N-1
\n2150 DIM B$(2,E)
\n2170 CLS
\n2195 LET Z=0
\n2200 LET R=INT (RND*(E-S+1))+S
\n2202 LET Z=Z+1
\n2203 IF A=4 AND Z>10 THEN GOTO 2600
\n2205 IF B$(L,R)<>" " THEN GOTO 2200
\n2207 LET B$(L,R)="1"
\n2210 PRINT "** ";N$(1+NOT (L-1))
\n2220 PRINT ,,A$(1+NOT (L-1),R)
\n2245 PRINT AT 20,3;"% %I%N%P%U%T% %S%H%I%F%T% %"%Q%"% %T%O% %Q%U%I%T% "
\n2250 PRINT AT 6,0;"PLEASE INPUT ";N$(L);" ?"
\n2252 PRINT TAB 13;"\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''"( TO LEN N$(1))
\n2255 SLOW
\n2260 INPUT G$
\n2270 FAST
\n2272 IF G$(1)="""" THEN GOTO (2380 AND A=2)+(3070 AND A>2)
\n2275 IF F=0 THEN PRINT G$
\n2280 LET F=0
\n2290 IF G$<>A$(L,R) THEN LET F=1
\n2300 IF A=3 OR A=4 THEN RETURN
\n2310 IF F=0 THEN GOTO 2360
\n2320 PRINT AT 10,10;"**% %W%R%O%N%G% **",,," THE CORRECT ANSWER IS..."
\n2330 PRINT ,,A$(L,R)
\n2340 PRINT ,,,,,,"PLEASE INPUT THE CORRECT ANSWER?\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''"
\n2345 LET B$(L,R)=" "
\n2350 GOTO 2255
\n2360 LET Q=Q+1
\n2365 IF B$(L,R)=" " THEN LET Q=Q-1
\n2370 IF Q<=E-S THEN GOTO 2160
\n2380 CLS
\n2390 PRINT AT 10,11;"% %F%I%N%I%S%H%E%D% "
\n2400 SLOW
\n2500 PAUSE 180
\n2510 GOTO 100
\n2600 FOR Z=S TO E
\n2610 IF B$(L,Z)=" " THEN GOTO 2650
\n2620 NEXT Z
\n2630 LET L=1+NOT (L-1)
\n2640 GOTO 2180
\n2650 LET R=Z
\n2660 GOTO 2207
\n3000 PRINT "************% %T%E%S%T% %1% ************"
\n3010 GOSUB 2010
\n3025 IF F=1 THEN LET B$(L,R)="X"
\n3030 LET Q=Q+1
\n3035 IF Q=(E-S+1)*(1+(A=4)) THEN GOTO 3070
\n3040 IF A=4 THEN LET L=INT (RND*2)+1
\n3050 GOSUB 2160
\n3060 GOTO 3020
\n3070 CLS
\n3080 PRINT "*********% %T%E%S%T% %R%E%P%O%R%T% **********"
\n3085 PRINT AT 3,11;"% %O%P%T%I%O%N%S% "
\n3090 PRINT ,,,,"<1> OUTPUT MISSED WORDS"
\n3100 PRINT "<2> OPTION <1> + PRINTER OUTPUT"
\n3110 PRINT "<3> SCORE REPORT--ONLY WHEN THE TEST WAS COMPLETED."
\n3120 PRINT "<4> RETURN TO MENU"
\n3130 PRINT AT 20,0;" INPUT YOUR CHOICE BY NUMBER ?",," \''\''\''\''\''\''\''\''\''"
\n3140 SLOW
\n3150 INPUT Q
\n3160 FAST
\n3170 IF Q<1 OR Q>4 OR Q=3 AND G$(1)="""" THEN GOTO 3140
\n3175 CLS
\n3180 IF Q=4 THEN GOTO 100
\n3190 IF Q=3 THEN GOTO 3400
\n3210 LET Y=1
\n3220 FOR Z=S TO E
\n3230 IF B$(1,Z)<>"X" AND B$(2,Z)<>"X" THEN GOTO 3290
\n3240 PRINT "% %N%U%M%B%E%R% ";Z;"---"
\n3250 PRINT A$(1,Z);A$(2,Z)
\n3260 IF Q=2 THEN LPRINT A$(1,Z);A$(2,Z),,
\n3270 IF Y=7 THEN GOTO 3300
\n3280 LET Y=Y+1
\n3290 NEXT Z
\n3300 POKE 16418,0
\n3310 PRINT AT 23,0;"PRESS ANY KEY TO CONTINUE"
\n3320 POKE 16418,2
\n3330 SLOW
\n3340 IF INKEY$="" THEN GOTO 3340
\n3345 FAST
\n3347 CLS
\n3350 IF Z>=E THEN GOTO 3070
\n3360 LET Y=1
\n3370 GOTO 3290
\n3400 LET Q=0
\n3410 FOR Z=S TO E
\n3420 IF B$(1,Z)="X" THEN LET Q=Q+1
\n3425 IF B$(2,Z)="X" THEN LET Q=Q+1
\n3430 NEXT Z
\n3440 PRINT "% %W%O%R%D%S% %T%E%S%T%E%D% ";(E-S+1)*((A=3)+(2 AND A=4))
\n3450 PRINT ,,"% %C%O%R%R%E%C%T% %A%N%S%W%E%R%S% ";(E-S+1)*((A=3)+(2 AND A=4))-Q
\n3460 PRINT ,,"% %W%R%O%N%G% %A%N%S%W%E%R%S% ";Q
\n3470 LET Z=INT ((1-Q/(E-S+1)/((A=3)+(2 AND A=4)))*100+.5)
\n3480 PRINT ,,,,"% %S%C%O%R%E% ";Z;" PERCENT"
\n3490 PRINT AT 20,0;"PRESS ANY KEY TO CONTINUE"
\n3500 SLOW
\n3510 IF INKEY$="" THEN GOTO 3510
\n3520 FAST
\n3530 GOTO 3070
\n4000 PRINT "************% %T%E%S%T% %2% ************"
\n4005 PRINT AT 4,6;"INTERCHANGE BETWEEN"
\n4007 PRINT AT 6,9;"TWO LANGUAGES"
\n4010 LET L=INT (RND*2)+1
\n4020 PRINT AT 21,NOT PI;" INPUT ""0"" TO TERMINATE"
\n4030 SLOW
\n4040 GOSUB 2060
\n4050 GOTO 3020
\n5000 PRINT "********% %N%E%W% %F%I%L%E% %S%E%T%U%P% ********";AT 20,0;"PRESS ""ENTER"" TO TERMINATE"
\n5010 PRINT AT 3,0;" INPUT FIRST LANGUAGE ?",
\n5015 SLOW
\n5020 INPUT Y$
\n5030 IF Y$="" THEN GOTO 100
\n5035 PRINT Y$
\n5040 PRINT AT 7,NOT PI;" INPUT SECOND LANGUAGE ?"
\n5050 INPUT Z$
\n5055 FAST
\n5060 IF Z$="" THEN GOTO 100
\n5070 LET N=(LEN Y$ AND LEN Y$>=LEN Z$)+(LEN Z$ AND LEN Z$>LEN Y$)
\n5075 IF N>16 THEN LET N=16
\n5080 DIM N$(2,N)
\n5083 LET N$(1)=Y$
\n5086 LET N$(2)=Z$
\n5090 DIM A$(2,W+1,32)
\n5100 LET N=1
\n5110 CLS
\n5120 GOTO 1000
\n6000 PRINT "********% %P%R%I%N%T%E%R% %O%U%T%P%U%T% ********"
\n6010 PRINT AT 3,NOT PI;" INPUT SELECTION ?","<1> ";N$(1);TAB 0;"<2> ";N$(2);TAB 0;"<3> BOTH"
\n6011 PRINT AT 21,NOT PI;" INPUT ""0"" TO TERMINATE MODE"
\n6012 SLOW
\n6013 INPUT Z
\n6014 IF Z<1 THEN GOTO 100
\n6015 IF Z>3 THEN GOTO 6012
\n6016 PRINT AT 3,18;Z
\n6017 PRINT AT 8,0;"SPACE BETWEEN EACH GROUP ? ";
\n6018 LET Z$=INKEY$
\n6019 IF Z$="" THEN GOTO 6018
\n6020 IF Z$="0" THEN GOTO 100
\n6021 IF Z$<>"Y" THEN LET Z$="N"
\n6022 PRINT Z$
\n6025 PRINT AT 12,0;" INPUT STARTING NUMBER ? ";
\n6030 INPUT S
\n6040 IF S<1 THEN GOTO 100
\n6050 IF S>N THEN GOTO 6030
\n6060 PRINT S
\n6070 PRINT AT 14,0;" INPUT ENDING NUMBER ? ";
\n6080 INPUT E
\n6090 IF E<1 THEN GOTO 100
\n6100 IF E<S THEN GOTO 6080
\n6105 IF E>N THEN LET E=N-1
\n6110 PRINT E
\n6120 PRINT AT 20,0;"PRESS ANY KEY TO PRINT OR "
\n6130 LET Y$=INKEY$
\n6140 IF Y$="" THEN GOTO 6130
\n6150 IF Y$="0" THEN GOTO 100
\n6155 FAST
\n6160 FOR Q=S TO E
\n6170 IF Z=1 OR Z=3 THEN LPRINT A$(1,Q)
\n6180 IF Z=2 OR Z=3 THEN LPRINT A$(2,Q)
\n6185 IF Z$="Y" THEN LPRINT
\n6190 NEXT Q
\n6200 SLOW
\n6210 GOTO 100
\n7000 PRINT "*************% %S%A%V%E% *************"
\n7005 DIM G$(1)
\n7010 PRINT AT 5,0;"<1> PREPARE RECORDER FOR ""SAVE"""
\n7020 PRINT "<2> REWIND TAPE"
\n7030 PRINT "<3> PRESS ""RECORD"" AND ""PLAY"""
\n7040 PRINT "<4> PRESS ANY KEY TO SAVE "," (TAPE LEADER IS"," AUTOMATICALLY COMPENSATED)"
\n7050 PRINT AT 21,5;"PRESS ""0"" TO TERMINATE"
\n7055 SLOW
\n7057 IF INKEY$<>"" THEN GOTO 7057
\n7060 LET Y$=INKEY$
\n7070 IF Y$="" THEN GOTO 7060
\n7080 IF Y$="0" THEN GOTO 100
\n7083 PRINT AT 15,10;"% %P%R%O%C%E%S%S%I%N%G% "
\n7085 PRINT AT 21,0;" "
\n7087 PAUSE 420
\n7088 FAST
\n7090 CLS
\n7100 SAVE "%V"
\n7110 PRINT "*******% %V%O%C%A%B%U%I%L%D%E%R% %1%0%0%0% *******"
\n7120 PRINT AT 6,11;"WRITTEN BY";AT 11,8;"\:'\''\''\''\''\''\''\''\''\''\''\''\''\''\''\':";TAB 8;"\: CHIA-CHI CHAO\ :";TAB 8;"\:.\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.:"
\n7135 SLOW
\n7140 FOR Q=1 TO 30
\n7150 NEXT Q
\n7200 GOTO 100
\n9998 SAVE "VOCAB 100%0"
\n9999 RUN 95
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

