This program is a data-entry and printing tool for managing Illusionist spell lists in the tabletop role-playing game Dungeons & Dragons, designed for an 80-column printer. It collects spell names across seven levels (plus minor cantrips) through sequential INPUT prompts, packing three spells per 64-character string into arrays A$, B$, and C$. The arrays are dimensioned as two-dimensional strings (e.g., DIM A$(16,64)) and indexed by row, concatenating three 20-character sub-strings to fill each 64-character slot. An empty string array E$(1,20) is used as a blank template to reset working buffers F$, S$, T$, U$, V$, X$, Z$, and D$ after each row is stored. After data entry, the program halts at line 605 with instructions to GO TO 610 to print or GO TO 9900 to save, since line 3 warns never to RUN the program directly once data is loaded.
Program Analysis
Program Structure
The program is divided into five logical phases:
- Initialisation (lines 5–100): Dimensions all working string arrays and the three main data arrays.
- 1st–3rd level spell entry (lines 200–320): Loops 16 times, collecting three spell names per iteration and packing them into
A$(Z). - 4th–6th level spell entry (lines 350–440): Loops 12 times, packing three spells per row into
B$(Z). - 7th level + cantrip entry (lines 500–590): Loops 8 times, packing two names per row into
C$(Z). - Output phase (lines 600–800): Prompts for a keypress, then LPRINTs all three arrays; a separate SAVE branch at line 9900 stores the data file.
Array Design and String Packing
The three main arrays are declared with 64-character rows: DIM A$(16,64), DIM B$(12,64), and DIM C$(8,64). Working buffers are all dimensioned at 20 characters (DIM F$(1,20) etc.), and three such buffers are concatenated to fill a 60-character payload per row (3 × 20 = 60, fitting within the 64-character row with room to spare). This packing strategy reduces the number of array rows needed and makes each LPRINT statement output a neatly formatted line of up to three spell names side by side, suitable for an 80-column printer.
Buffer Clearing Idiom
After each row is stored, the working sub-strings are reset by assigning them the first (and only) row of the empty array E$(1,20), which was never written to and therefore contains spaces. For example, LET F$(1)=E$(1) at line 280 overwrites the buffer with 20 spaces. This is a tidy way to blank a fixed-length string without using a PRINT or a literal string of spaces, relying on the fact that a freshly DIMmed string array is zero-filled (space-padded).
Entry-Point Control
Line 3 contains a REM warning: NEVER RUN, USE GOTO 610. This is because RUNning the program after data has been SAVEd and reloaded would re-execute the DIM statements at lines 5–100, destroying all stored spell data. The intended workflow is to LOAD the saved file and then type GO TO 610 to proceed directly to printing, bypassing the data-entry and DIM sections entirely. Lines 603–605 reinforce this by printing navigation instructions and issuing a STOP at the end of data entry, leaving the user to choose between printing (GO TO 610) or saving (GO TO 9900).
Save and Reload Strategy
Line 9900 saves the program (including all populated array data held in the program’s variable area) with SAVE "1020...", then falls through to GOTO 610 so printing can continue immediately. Because BASIC SAVE on this platform stores the entire program together with its current variable area, all entered spell names are preserved in the saved file without any separate data file mechanism.
Notable Techniques and Observations
- The two-dimensional string DIM syntax (e.g.,
DIM A$(16,64)) uses the second dimension as the fixed string length for each element, which is standard Sinclair-family BASIC string array behaviour. PAUSE 4E4(pause for 40,000 frame units, approximately 11 minutes on a 50 Hz machine) at line 620 functions as a very long wait for any key rather than a timed pause, since the user is expected to press a key to continue.- Variable name
Zis reused as both the loop counter (lines 200–590) and as one of the working string array names (Z$), which is valid because the scalarZand the arrayZ$occupy different symbol table entries. - The 7th-level loop at lines 500–590 only packs two names per row (spell + cantrip = 2 × 20 = 40 characters) into the 64-character
C$rows, leaving 24 characters of padding, unlike the three-per-row scheme used for the earlier levels. - There is a minor asymmetry: the level labels passed to the user (“1ST LEVEL”, “2ND LEVEL”, “3RD LEVEL” in the first loop; “4TH”, “5TH”, “6TH” in the second; “7TH” and “MINOR CANTRIP” in the third) do not quite correspond to a standard AD&D Illusionist spell progression, but this does not affect the program’s operation.
Content
Source Code
0 REM %I%L%L%U%S%I%O%N%I%S%T% %S%P%E%L%L% %L%I%S%T BY ANTHONY WILLING 3-2-86 FOR DUNGEONS AND DRAGONS 80 COLUMN PRINTER REQUIRED
3 REM %N%E%V%E%R% %R%U%N%,% %U%S%E% %G%O%T%O% %6%1%0
5 DIM E$(1,20)
7 DIM D$(1,20)
10 DIM F$(1,20)
20 DIM S$(1,20)
30 DIM T$(1,20)
40 DIM U$(1,20)
50 DIM V$(1,20)
60 DIM X$(1,20)
70 DIM Z$(1,20)
80 DIM A$(16,64)
90 DIM B$(12,64)
100 DIM C$(8,64)
200 FOR Z=1 TO 16
210 PRINT "INPUT 1ST LEVEL SPELL ";Z
220 INPUT F$(1)
230 PRINT "INPUT 2ND LEVEL SPELL ";Z
240 INPUT S$(1)
250 PRINT "INPUT 3RD LEVEL SPELL ";Z
260 INPUT T$(1)
270 LET A$(Z)=F$(1)+S$(1)+T$(1)
280 LET F$(1)=E$(1)
290 LET S$(1)=E$(1)
300 LET T$(1)=E$(1)
310 CLS
320 NEXT Z
350 FOR Z=1 TO 12
360 PRINT "INPUT 4TH LEVEL SPELL ";Z
370 INPUT U$(1)
380 PRINT "INPUT 5TH LEVEL SPELL ";Z
390 INPUT V$(1)
391 PRINT "INPUT 6TH LEVEL SPELL ";Z
392 INPUT X$(1)
400 LET B$(Z)=U$(1)+V$(1)+X$(1)
410 LET U$(1)=E$(1)
420 LET V$(1)=E$(1)
425 LET X$(1)=E$(1)
430 CLS
440 NEXT Z
500 FOR Z=1 TO 8
530 PRINT "INPUT 7TH LEVEL SPELL ";Z
540 INPUT Z$(1)
541 PRINT "INPUT MINOR CANTRIP ";Z
542 INPUT D$(1)
550 LET C$(Z)=Z$(1)+D$(1)
560 LET Z$(1)=E$(1)
570 LET D$(1)=E$(1)
580 CLS
590 NEXT Z
600 CLS
603 PRINT "GOTO 610 FOR SPELL LIST"
604 PRINT "GOTO 9900 TO SAVE"
605 STOP
610 PRINT "PRESS ANY KEY",,"TO PRINT SPELL LISTS"
620 PAUSE 4E4
630 LPRINT "ILLUSIONISTS SPELLS"
650 LPRINT
660 LPRINT
670 FOR Z=1 TO 16
680 LPRINT A$(Z)
690 NEXT Z
700 LPRINT
710 LPRINT
720 FOR Z=1 TO 12
730 LPRINT B$(Z)
740 NEXT Z
750 LPRINT
760 LPRINT
770 FOR Z=1 TO 8
780 LPRINT C$(Z)
790 NEXT Z
800 STOP
9900 SAVE "1020%7"
9910 GOTO 610
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
