A small reference database for keeping notes on magazine articles. Each entry has a publication name, a date and page number, and free text. Entries can be found by keyword, checked on screen and printed on the ZX printer, and any of the three fields can be edited, the text field with a full-screen character editor. The program saves itself to tape with the data included, so the file can be reloaded and added to later.
Program Analysis
Program Structure
A four-item menu (lines 100–350) leads to adding text (1000), keyword search (2000), saving to tape (3000) and editing (4000). All entries are kept in one string, A$. Within it each field ends with a separator byte: CHR$ 67 after the publication, CHR$ 68 after the date and page, and CHR$ 69 after the text. Codes 67–69 are not printable on the ZX81, so they cannot turn up in typed input.
Searching looks for the keyword anywhere in A$, remembering the position of the last CHR$ 69 it passed so that it knows where the matching entry starts. It then splits that entry into C$, D$ and E$ by scanning forward for each separator. If the entry shown is not the right one, the user can continue the search, and if it is, the entry can be sent to the printer with LPRINT. The editing routine at 4000 repeats the same search, then rebuilds A$ around the new value with string slicing.
Text Editor
Lines 5400–6820 make up a character editor for the text field. A block cursor is shown over the current character, and keys are identified by their codes: codes 112–115 are the cursor keys, and other shifted codes handle jumping to the start or end, moving eight characters at a time, inserting or deleting a character, inserting a 32-space line, deleting a 32-character line, and finishing the edit. The cursor’s row and column (C, D) are tracked separately from its position in the string (F).
Notable Techniques
- Saving is done with
SAVE B$from inside the running program (line 3040). When the tape is loaded again, execution carries on at line 3050 with every variable intact, including the database inA$. - Line 300 prints the menu prompt in normal characters and then in inverse at the same spot, so that it flickers while the program waits for a key.
Potential Issues
- Continuing a search after rejecting an entry picks up at the next character, so a keyword that appears twice in one entry shows that entry again.
- Because
A$lives in the program’s variables area, the whole file has to fit in RAM along with the program, so its size is limited by available memory.
Source Code
10 LET A$="0000"+CHR$ 69
20 DIM G$(32)
100 CLS
110 FAST
120 PRINT AT 0,10;"[I][N][F][O][F][I][L][E]"
130 PRINT AT 3,0;"TO ADD TEXT";TAB 30;1
140 PRINT AT 5,0;"KEYWORD SEARCH";TAB 30;2
150 PRINT AT 7,0;"SAVE ON TAPE";TAB 30;3
160 PRINT AT 9,0;"TO EDIT";TAB 30;4
200 SLOW
300 PRINT AT 21,6;"ENTER ONE OF ABOVE";AT 21,6;"[E][N][T][E][R]█[O][N][E]█[O][F]█[A][B][O][V][E]"
310 LET B$=INKEY$
320 IF CODE B$<29 OR CODE B$>32 THEN GOTO 300
330 FAST
340 CLS
350 GOTO VAL B$*1000
1000 PRINT "PUBLICATION?"
1005 SLOW
1010 INPUT B$
1020 IF B$="" THEN GOTO 100
1030 LET A$=A$+B$+CHR$ 67
1040 PRINT AT 0,0;"PUBLICATION IS (";B$;")"
1050 PRINT ,,"PUBLICATION DATE AND PAGE NO. IS?"
1060 INPUT B$
1070 PRINT AT 3,2;" (";B$;")"
1080 LET A$=A$+B$+CHR$ 68
1090 PRINT ,,"ENTER TEXT :::"
1100 INPUT B$
1110 LET A$=A$+B$+CHR$ 69
1120 CLS
1130 GOTO 1000
2000 PRINT ,,"WHAT IS THE KEYWORD"
2010 SLOW
2020 INPUT B$
2030 FAST
2040 FOR N=1 TO LEN A$-LEN B$+1
2050 IF A$(N)=CHR$ (69) THEN LET A=N
2060 IF A$(N TO N+LEN B$-1)=B$ THEN GOTO 2500
2070 NEXT N
2100 CLS
2110 PRINT ,,B$,"IS NOT IN THE","FILE :::"
2120 PRINT AT 21,0;"PRESS RETURN TO CONTINUE"
2130 PAUSE 40000
2140 GOTO 100
2500 FOR I=A+1 TO LEN A$
2510 IF A$(I)=CHR$ 67 THEN GOTO 2600
2520 NEXT I
2600 LET C$=A$(A+1 TO I-1)
2610 FOR J=I+1 TO LEN A$
2620 IF A$(J)=CHR$ (68) THEN GOTO 2700
2630 NEXT J
2700 LET D$=A$(I+1 TO J-1)
2710 FOR K=J+1 TO LEN A$
2720 IF A$(K)=CHR$ (69) THEN GOTO 2800
2730 NEXT K
2800 LET E$=A$(J+1 TO K-1)
2810 FAST
2820 CLS
2830 PRINT ,,C$
2840 PRINT D$
2850 PRINT E$
2860 PRINT AT 21,0;"IS THIS THE CORRECT TEXT?"
2870 PAUSE 40000
2880 IF INKEY$ ="N" THEN GOTO 2070
2890 PRINT AT 21,0;"DO YOU WANT HARD COPY? "
2900 PAUSE 40000
2910 IF INKEY$ ="N" THEN GOTO 100
2920 PRINT AT 21,0;"PREPARE PRINTER AND PRESS ENTER."
2930 PAUSE 40000
2940 LPRINT C$
2950 LPRINT " "
2960 LPRINT D$
2970 LPRINT " "
2980 LPRINT E$
2990 GOTO 100
3000 PRINT ,,"ENTER FILE NAME, PREPARE RECORDER, AND PRESS ENTER :::"
3010 SLOW
3020 INPUT B$
3030 FAST
3040 SAVE B$
3050 GOTO 100
4000 PRINT ,,"WHAT IS THE KEYWORD"
4010 SLOW
4020 INPUT B$
4030 FAST
4040 FOR N=1 TO LEN A$-LEN B$+1
4050 IF A$(N)=CHR$ (69) THEN LET A=N
4060 IF A$(N TO N+LEN B$-1)=B$ THEN GOTO 4500
4070 NEXT N
4080 GOTO 2100
4500 FOR I=A+1 TO LEN A$
4510 IF A$(I)=CHR$ 67 THEN GOTO 4600
4520 NEXT I
4600 LET C$=A$(A+1 TO I-1)
4610 FOR J=I+1 TO LEN A$
4620 IF A$(J)=CHR$ (68) THEN GOTO 4700
4630 NEXT J
4700 LET D$=A$(I+1 TO J-1)
4710 FOR K=J+1 TO LEN A$
4720 IF A$(K)=CHR$ (69) THEN GOTO 4800
4730 NEXT K
4800 LET E$=A$(J+1 TO K-1)
4810 FAST
4820 CLS
4830 PRINT C$,D$,E$
4840 PRINT AT 21,0;"IS THIS THE CORRECT TEXT?"
4850 PAUSE 40000
4860 IF INKEY$ ="N" THEN GOTO 4070
4890 PRINT AT 21,0;"WHICH ITEM TO BE EDITED (1,2,3)?"
4895 SLOW
4900 LET B$=INKEY$
4910 IF CODE B$<29 OR CODE B$>31 THEN GOTO 4900
4920 FAST
4930 CLS
4940 GOTO 4800+200*VAL B$
5000 PRINT "OLD PUBLICATION IS ::",C$
5010 PRINT "INPUT NEW PUBLICATION?"
5015 SLOW
5020 INPUT B$
5030 FAST
5040 LET A$=A$( TO A)+B$+A$(I TO LEN A$)
5050 GOTO 100
5200 PRINT "OLD DATE, PAGE NUMBER IS ::",D$
5210 PRINT "INPUT NEW DATA?"
5215 SLOW
5220 INPUT B$
5230 FAST
5240 LET A$=A$( TO I)+B$+A$(J TO LEN A$)
5250 GOTO 100
5400 PRINT "OLD TEXT IS :::",E$
5420 LET C=1
5440 LET D=0
5450 LET F=1
5460 SLOW
5470 PRINT AT C,D;"█";AT C,D;E$(F)
5480 LET F$=INKEY$
5490 IF F$="" THEN GOTO 5470
5495 FAST
5500 IF CODE F$=224 THEN GOTO 9000
5510 IF CODE F$=112 THEN GOTO 6000
5515 IF CODE F$=23 THEN GOTO 5420
5520 IF CODE F$=113 THEN GOTO 6100
5525 IF CODE F$=19 THEN GOTO 6300
5530 IF CODE F$=114 THEN GOTO 6200
5535 IF CODE F$=220 THEN GOTO 6600
5540 IF CODE F$=115 THEN GOTO 5600
5545 IF CODE F$=219 THEN GOTO 6700
5550 IF CODE F$=16 THEN GOTO 6400
5555 IF CODE F$=229 THEN GOTO 6800
5560 IF CODE F$=228 THEN GOTO 6500
5570 IF F=LEN E$ THEN GOTO 5460
5590 LET E$(F)=F$
5600 IF F+1>LEN E$ THEN GOTO 5460
5605 LET F=F+1
5610 LET D=D+1
5620 IF D<32 THEN GOTO 5990
5630 LET D=0
5640 LET C=C+1
5990 PRINT AT 1,0;E$;G$
5995 GOTO 5460
6000 IF F-32<1 THEN GOTO 5460
6010 LET C=C-1
6020 LET F=F-32
6030 GOTO 5460
6100 IF F+32>LEN E$ THEN GOTO 5460
6110 LET C=C+1
6120 LET F=F+32
6130 GOTO 5460
6200 IF F-1<1 THEN GOTO 5460
6210 LET F=F-1
6220 LET D=D-1
6230 IF D>0 THEN GOTO 6260
6240 LET D=D+32
6250 LET C=C-1
6260 GOTO 5460
6300 LET F=LEN E$
6310 LET C=1+INT (LEN E$/32)
6320 LET D=32*(LEN E$/32-INT (LEN E$/32))-1
6330 GOTO 5460
6400 IF F+1>LEN E$ THEN GOTO 5460
6410 LET E$=E$( TO F-1)+" "+E$(F TO LEN E$)
6420 GOTO 5990
6500 IF F<1 THEN GOTO 5460
6510 LET E$=E$( TO F-1)+E$(F+1 TO LEN E$)
6520 GOTO 5990
6600 IF F+8>LEN E$ THEN GOTO 5460
6610 LET F=F+8
6620 LET D=D+8
6630 IF D<32 THEN GOTO 6660
6640 LET D=D-32
6650 LET C=C+1
6660 GOTO 5460
6700 IF LEN E$>607 THEN GOTO 5460
6710 LET E$=E$( TO F)+G$+E$(F+1 TO LEN E$)
6720 GOTO 5990
6800 IF LEN E$-F<32 THEN GOTO 5460
6810 LET E$=E$( TO F)+E$(F+33 TO LEN E$)
6820 GOTO 5990
9000 FAST
9010 LET A$=A$( TO J)+E$+A$(K TO LEN A$)
9020 GOTO 100
9996 FAST
9997 CLS
9998 SAVE "INFOFIL[E]"
9999 RUNNote: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
