This program implements a simple to-do list manager, storing up to 22 items of up to 30 characters each in a two-dimensional string array. It presents a menu-driven interface with six options: adding items, setting priorities (reordering), deleting items, clearing the file (via RUN), viewing the file, and saving to tape. Priority setting works by prompting the user to re-enter items in desired order into a second array B$, then copying back to A$. The program uses POKE 16418 to control the system’s display mode flag and exploits INKEY$ key codes (29–34, corresponding to digits 1–6) for menu navigation, dispatching via GOTO VAL Y$*1000.
Program Structure
The program is organised around a central menu loop at line 100–380 that dispatches to one of six routines based on the user’s keypress. Each routine ends with GOTO 100 (or GOTO VAL "1"*1000 etc.) to return to the menu. The overall flow is:
- Initialisation (10–40): Sets FAST mode, dimensions both string arrays, initialises record counter
R1=0. - Menu (100–380): Displays six options, waits for a keypress in range 1–6, dispatches via computed
GOTO. - Routines at ×1000: Lines 1000, 2000, 3000, 4000, 5000, 6000 implement each menu option.
- Display subroutine (2500–2540): Shared CLS + list-print used by options 2, 3, and 5.
Data Storage
Two DIMed arrays are used:
| Variable | Size | Purpose |
|---|---|---|
A$(22,30) | 22 rows × 30 chars | Primary to-do list storage |
B$(22,30) | 22 rows × 30 chars | Temporary buffer during priority reordering |
The variable R1 tracks how many items have been entered. Items are 1-indexed; the maximum list length is 22 entries.
Menu Dispatch Technique
The menu waits for a keypress at line 330 with LET Y$=INKEY$ inside a loop. Line 340 validates that CODE Y$ is between 29 and 34, which correspond to the ZX81 character codes for digits 1 through 6. Line 380 then uses GOTO VAL Y$*1000, converting the digit character to an integer and multiplying by 1000 to reach the correct routine — a compact dispatch idiom that avoids a chain of IF statements.
POKE 16418 Usage
Address 16418 (CDFLAG / the “slow/fast” flag in ZX81 RAM) is manipulated directly:
POKE 16418,0at line300— switches the display mode before entering the SLOW input loop.POKE 16418,2at line370— restores the flag after menu selection, before dispatching.
This is used alongside the FAST/SLOW keywords to control display flickering and input responsiveness.
Priority Reordering (Option 2)
The reorder routine (lines 2000–2130) works as follows:
- Display current list via subroutine at
2500. - For each position
Ifrom 1 toR1, ask user to input a source indexA. - Copy
A$(A)intoB$(I)and blank outA$(A). - After all selections, copy
B$back toA$and clearB$.
This approach has a notable bug: if the user enters the same source index twice, the second pick will copy a blank string (since A$(A) was cleared at line 2040 on the first pick). There is also no bounds checking on the entered index A.
Delete Routine (Option 3)
Deletion at lines 3000–3070 shifts all elements from position A+1 downward by one, then decrements R1. This is a correct in-place array compaction. After deletion, it falls through to the view routine at 5000 rather than going directly back to the menu.
Clear and Save
Option 4 (4000) simply executes RUN, which reinitialises all variables and restarts the program — an efficient way to clear all data without explicit array-zeroing code. Option 6 (6000) uses INPUT F$ to obtain a filename, then SAVE F$ to write the program and all current variable data (including the list arrays) to tape.
Copy / Print Option
Lines 2120 and 5040 both implement the same pattern: PAUSE 40000 followed by IF INKEY$="Z" THEN COPY. This gives the user approximately 40 seconds to press Z to trigger a printer copy of the displayed list before returning to the menu.
Content
Source Code
10 FAST
20 DIM A$(22,30)
30 DIM B$(22,30)
40 LET R1=0
100 FAST
110 CLS
120 PRINT AT 1,7;"% %T%H%I%N%G%S% %T%O% %D%O% "
130 PRINT AT 5,0;"TO CREATE OR ADD TO FILE;";TAB 30;1
140 PRINT AT 7,0;"TO SET PRIORITIES";TAB 30;2
150 PRINT AT 9,0;"TO DELETE FROM FILE";TAB 30;3
160 PRINT AT 11,0;"TO CLEAR FILE";TAB 30;4
170 PRINT AT 13,0;"TO SEE FILE";TAB 30;5
180 PRINT AT 15,0;"TO SAVE FILE ON TAPE";TAB 30;6
300 POKE 16418,0
310 SLOW
320 PRINT AT 22,3;"% %E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% ";AT 22,3;" ENTER ONE OF ABOVE "
330 LET Y$=INKEY$
340 IF CODE Y$<29 OR CODE Y$>34 THEN GOTO 320
350 FAST
360 CLS
370 POKE 16418,2
380 GOTO VAL Y$*1000
\n1000 PRINT AT 18,0;"ENTER ITEMS ONE BY ONE (30 CHAR.MAX. IF YOU HAVE NO MORE TO ENTER, JUST PRESS ENTER :::"
\n1005 SLOW
\n1010 FOR N=R1+1 TO 22
\n1020 SCROLL
\n1030 PRINT N;" ";
\n1040 INPUT A$(N)
\n1050 IF A$(N,1)=" " THEN GOTO 1100
\n1060 PRINT A$(N)
\n1070 NEXT N
\n1100 LET R1=N-1
\n1110 GOTO 100
\n2000 FOR I=1 TO R1
\n2010 GOSUB 2500
\n2015 SLOW
\n2020 INPUT A
\n2025 FAST
\n2030 LET B$(I)=A$(A)
\n2040 LET A$(A)=""
\n2050 NEXT I
\n2060 FOR N=1 TO R1
\n2070 LET A$(N)=B$(N)
\n2080 LET B$(N)=""
\n2090 NEXT N
\n2100 GOSUB 2500
\n2110 PAUSE 40000
\n2120 IF INKEY$="Z" THEN COPY
\n2130 GOTO 100
\n2500 CLS
\n2510 FOR N=1 TO R1
\n2520 PRINT N;" ";A$(N)
\n2530 NEXT N
\n2540 RETURN
\n3000 FAST
\n3003 GOSUB 2500
\n3005 SLOW
\n3010 INPUT A
\n3015 FAST
\n3020 FOR N=A TO R1-1
\n3030 LET A$(N)=A$(N+1)
\n3040 NEXT N
\n3050 LET R1=R1-1
\n3060 CLS
\n3070 GOTO 5000
\n4000 RUN
\n5000 GOSUB 2500
\n5030 PAUSE 40000
\n5040 IF INKEY$="Z" THEN COPY
\n5050 GOTO 100
\n6000 PRINT AT 10,0;"ENTER NAME OF FILE, PREPARE RECORDER AND PRESS ENTER :::"
\n6010 INPUT F$
\n6020 SAVE F$
\n6030 GOTO 100
\n9998 SAVE "TT%D"
\n9999 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
