The DATA-READ statement is the basic computer command for the efficient storage and use of data comprised of many values (bulk data) where data is to be used repetitively in a program or where data is to be retained for successive computer runs. Such data might consist of names and addresses, names and phone numbers, football scores, degree days, inventory part numbers, star brightness intensity, input from an RS232 port, and on and on and . . .
As we are aware, the ZX81 does not include these statements. The ZX81 Basic Programming manual by Steven Vickers suggests the use of LET X=N type statements to duplicate DATA statements. This, unfortunately, requires the extensive dedication of memory for data storage except for short programs. Another method of achieving a ZX81 DATA-READ capability would be through machine language. This would require a very thorough knowledge of the Z80 CPU assembly language. There is, however, a method of simulating DATA-READ statements on the ZX81 using string statements, slicing, and the LEN/VAL functions. This method does not require the use of machine language nor does it require excessive memory. Furthermore, it can be easily mastered if the use of string statements as presented in the ZX81 Basic Programming manual is understood.
The proposed method consists of entering data as a string statement, slicing the characters from the string which make up a data-set, converting the sliced substrings to a numerical value, if necessary, and then using these substrings as program variables.
The ZX81 DATA-READ simulation technique is generally developed in accordance with the following steps:
Step 1. Enter all data in a string statement (LET A$=”XXXX”) so that each data-set within the string can be identified repetitively by character position within the string.
Step 2. Set up an array which will permit each data-set to be assigned a unique address in the array as it is sliced from the string, or originate statements which will selectively slice data-sets from the string to be used directly as program variables.
Step 3. Read data-sets from the array or string as applicable, convert data to numeric values if necessary and use as program variables.
Since data entered in a program using this method is always directly addressable, there is no need for the RESTORE command which is usually associated with Basic DATA-READ commands.
To demonstrate the ZX81 DATA-READ simulation technique, five programs are presented of varying complexity showing first the DATA-READ program in Basic Language which is not usable with the ZX81 Computer, and then equivalent programs written for use with the ZX81. Program Listings 1A through 1E are all equivalent programs consisting of a data statement containing a number of data-sets from which data is read and then used in a simple arithmetic calculation. Program Listings 2A through 2C are all equivalent programs demonstrating a ZX81 DATA-READ simulation for data which is NON-NUMERIC. Program Listings 3A through 5B are a series of three similar programs of increasing complexity wherein a data-set counting program tallies the number of times a data-set of like value occurs in a data statement.
Program 1
Listing 1A is a program written in conventional Basic using DATA-READ statements which cannot be executed on a ZX81 Computer.
Listing 1A. Conventional Basic READ-DATA Program.
05 REM LISTING 1A
10 READ A,B,C,D
20 PRINT A+B,C+D
30 DATA 5,10,15,20
15 35
Listing 1B is a program, equivalent to listing 1A, which can be executed on a ZX81 Computer. The program simulates a DATA-READ capability by entering the data as a string statement with all data-sets expressed as two characters separated from other data-sets with commas for visibility (line 10).
Listing 1B. ZX81 Simulation of DATA-READ Statement Using a Fixed Size Addressable Array.
05 REM LISTING 1B
10 LET A$="05,10,15,20,"
20 DIM A(4)
30 LET X=1
40 FOR J=1 TO 4
50 LET Y=X+1
60 LET A(J)=VAL A$(X TO Y)
70 LET X=X+3
80 NEXT J
90 PRINT A(1)+A(2),A(3)+A(4)
15 35 0/90
An array is then dimensioned to accept the data-sets so that each can be addressed by name when used as a program variable (line 20). The data is sliced from the string and entered by value into the array (lines 30-80). Numerical calculations are then made using the data as addressed within the array (line 90).
Listing 1C is the same program as Listing 1B except that the array is not dimensioned for a fixed size but is set up equal in size to the number of data-sets existing in the program.
Listing 1C. ZX81 Simulation of DATA-READ Statement Using a Variable Size Addressable Array.
05 REM LISTING 1C
10 LET A$="05,10,15,20,"
20 DIM A(LEN A$/3)
30 LET X=1
40 FOR J=1 TO LEN A$/3
50 LET Y=X+1
60 LET A(J)=VAL A$(X TO Y)
70 LET X=X+3
80 NEXT J
90 PRINT A(1)+A(2),A(3)+A(4)
15 35 0/90
Each data-set, again, is expressed as two characters separated by a comma. Thus the array size must equal the total number of characters entered into the data string divided by 3 or LEN A$/3 (line 20). Since the size of the array will now adjust to the number of data-sets in the data string, the program loop entering the data into the array must likewise vary in length. This is accomplished by entering LEN A$/3 into the loop command (line 40).
Listing 1D is the same as Listing 1C except that new data has been added to the program in a new string command (line 901), the original A$ command has been adjusted to include the new B$ data (line 990) and the variable size array has accepted the new data without revision to the program. Thus new data has been added without need to re enter previous data or making any program deletions. It should be evident that additional new data entries can be made in like manner by entering up to 26 new data strings of any length, i.e., C$,D$, etc, and then including those strings in line 990. For example:
900 LET A$="05,10,15,20,"
901 LET B$="25,30,35,40,"
902 LET C$="45,50,"
903 LET D$="55,60,65,70,75,80,85,"
990 LET A$=A$+B$+C$+D$
999 GOTO 20
Listing 1D. ZX81 Simulation of DATA-READ Statement Using a Variable Size Addressable Array with New Data Addition.
05 REM LISTING 1D
10 GOTO 900
20 DIM A(LEN A$/3)
30 LET X=1
40 FOR J=1 TO LEN A$/3
50 LET Y=X+1
60 LET A(J)=VAL A$(X TO Y)
70 LET X=X+3
80 NEXT J
90 PRINT A(1)+A(2),A(3)+A(4),
A(5)+A(6),A(7)+A(8)
100 STOP
900 LET A$="05,10,15,20,"
901 LET B$="25,30,35,40,"
990 LET A$=A$+B$
999 GOTO 20
15 35 55 75 9/100
Listing 1E is the same program as Listing 1B except that the data is not addressable within an array but is rather sliced from the data string and used directly as substrings as program variables.
Listing 1E. ZX81 Simulation of DATA-READ Statement Using Data Directly Addressable within the Data String.
05 REM LISTING 1E
10 LET A$="05,10,15,20,"
20 PRINT VAL A$(1 TO 2)+VAL A$(4 TO 5),
VAL A$(7 TO 8)+VAL A$(10 TO 11)
15 35 0/20
Program 2
Listing 2A is a program show in the ZX81 BASIC Programming manual as an example of ZX81 incompatibility with conventional Basic DATA-READ statements.
Listing 2A. Conventional Basic DATA-READ Program.
05 REM LISTING 2A
10 REM THIS PROGRAM WILL NOT WORK
IN ZX81 BASIC
20 DIM M$(12,3)
30 FOR N=1 TO 12
40 READ M$(N)
50 NEXT N
60 DATA "JAN","FEB","MAR","APR"
70 DATA "MAY","JUN","JUL","AUG"
80 DATA "SEP","OCT","NOV","DEC"
Listing 2B is a program equivalent to Listing 2A which can be executed on a ZX81 Computer. The simulation of a ZX81 DATA-READ program follows the same technique as explained for Listing 1B except that the data is non-numeric and can therefore be used as a program variable as entered in the string without need for VAL function conversion. It should be noted that the commas used in the data string (line 10) are used only for making the data readable. For computer purposes, the commas as shown serve no purpose and could be deleted. However, it is possible to use such characters as data recognition flags. In this case they would be required.
Listing 2B. ZX81 Simulation of DATA-READ Statement Using a Fixed Size Addressable Array with Non-Numeric Data.
05 LISTING 2B
10 LET D$="JAN,FEB,MAR,APR,
MAY,JUN,JUL,AUG,
SEP,OCT,NOV,DEC,"
20 DIM M$(12,3)
30 LET X=1
40 FOR N=1 TO 12
50 LET Y=X+2
60 LET M$(N)=D$(X TO Y)
70 LET X=X+4
80 NEXT N
90 FOR N=1 TO 12
100 PRINT TAB (5*N)-3;M$(N)
110 NEXT N
JAN
FEB
MAR
APR
MAY
JUN
JUL
AUG
SEP
OCT
NOV
DEC
0/110
Listing 2C. ZX81 Simulation of DATA-READ Statement Using a Fixed Size Addressable Array with Non-Numeric Data and Array Content Printout within Loop.
05 REM LISTING 2C
10 LET D$="JAN,FEB,MAR,APR,
MAY,JUN,JUL,AUG,
SEP,OCT,NOV,DEC,"
20 DIM M$(12,3)
30 LET X=1
40 FOR N=1 TO 12
50 LET Y=X+2
60 LET M$(N)=D$(X TO Y)
70 PRINT "M$(";N;")=";M$(N)
80 LET X=X+4
90 NEXT N
M$(1)=JAN M$(2)=FEB M$(3)=MAR M$(4)=APR M$(5)=MAY M$(6)=JUN M$(7)=JUL M$(8)=AUG M$(9)=SEP M$)10)=OCT M$(11)=NOV M$(12)=DEC 0/90
Listing 2C is the same program as Listing 2B except that the data array is printed out as the data array loop is executed. This program routine is useful to display the contents of the array but does not serve any program need. If the print statement (line 70) is not executed, the data will still be entered in the array as program variables.
Program 3
Listing 3A is a program written in conventional Basic using DATA-READ statements which cannot be executed on a ZX81 Computer.
Listing 3A. Conventional Basic DATA-READ Program.
05 LISTING 3A
10 DIM C(2)
20 LET C(1)=0
30 LET C(2)=0
40 READ A
50 IF A=-1 THEN 80
60 LET C(A)=C(A)+1
70 GOTO 40
80 PRINT C(1),C(2)
900 DATA 1,1,2,1,1,2,2,1,1,1,-1
7 3
Listing 3B is a counting routine using a single-subscripted variable array. The array diagram is shown in Figure 1. As shown by the diagram, each data-set consists of one variable, “A”. A running total is made of data-sets equal in value to 1 or 2 which are addressed as variables C(1) and C(2) respectively. Thus, in the data string (line 40) there is a total of 20 characters. There are 10 data-sets, 7 of which are equal to 1, and 3 of which are equal to 2. The arrangement of data in the DATA STRING is as follows: 40 LET C$=”A,A,A,etc”
Listing 3B. ZX81 Simulation of DATA-READ Statement for Single-subscripted Variable Array in Data Count Program.
05 LISTING 3B
10 DIM C(2)
20 LET C(1)=0
30 LET C(2)=0
40 LET C$="1,1,2,1;1,2,2,1,1,1,"
45 PRINT "LENGTH OF C$=";LEN C$,,
"DATA COUNT =";LEN C$/2
50 LET D=2
60 LET A=1
70 LET X=1
75 FOR N=A TO LEN C$/D
80 LET J=VAL C$(X)
85 LET C(J)=C(J)+1
90 LET X=X+2
100 NEXT N
110 PRINT
120 PRINT "C(1)","C(2)"
130 PRINT C(1),C(2)
LENGTH OF C$=20 DATA COUNT=10 C(1) C(2) 7 3 0/130
[Figure: Figure 1. Array Diagram for Listing 3B.]
| A=1 | C(1) | | A=2 | C(2) |
Program 4
Listing 4A is a program written in conventional Basic using DATA-READ statements which cannot be executed on a ZX81 Computer.
Note: Lines are numbered as shown to save memory for 1K RAM.
Listing 4A. Conventional Basic DATA-READ Program.
05 REM LISTING 4A
10 DIM C(3,3)
20 FOR Y=1 TO 3
30 FOR Z=1 TO 3
40 LET C(Y,Z)=0
50 NEXT Y
60 NEXT Z
70 READ J,K
80 IF J=-1 THEN 110
90 LET C(J,K)=C(J,K)+1
100 GOTO 70
110 PRINT C(1,1),C(1,2),C(1,3)
120 PRINT C(2,1),C(2,2),C(2,3)
130 PRINT C(3,1),C(3,2),C(3,2)
900 DATA 1,2,1,1,2,1,2,2,3,3,3,1,2,3,
1,3,1,3,2,1,3,1, 3,3,3,3,-1,-1
1 1 2 2 1 1 2 0 3
Listing 4B is a counting routine program equivalent to Listing 4A using a double-subscripted variable array. The array diagram is shown in Figure 2. A running total of all like data values are entered and counted in the array addresses as shown in the array diagram.
Listing 4B. ZX81 Simulation of DATA-READ Statement for Double-Subscripted Variable Array in Data Count Program.
1 REM LISTING 4B
2 DIM C(3,3)
3 FOR Y=1 TO 3
4 FOR Z=1 TO 3
5 LET C(Y,Z)=0
6 NEXT Z
7 NEXT Y
8 LET C$="1,2;1,1;2,1;2,2;3,3;
3,1;2,3;1,3;1,3;2,1;
3,1;3,3;3,3;"
10 PRINT "DATA-SETS =";LEN C$/4
20 LET J=1
30 FOR N=1 TO LEN C$/4
40 LET K=J+2
50 LET Y=VAL C$(J)
60 LET Z=VAL C$(k)
70 LET C(Y,Z)=C(Y,Z)+1
80 LET J=J+4
90 NEXT N
95 PRINT C(1,1),C(1,2),C(1,3)
96 PRINT C(2,1),C(2,2),C(2,3)
97 PRINT C(3,1),C(3,2),C(3,3)
DATA-SETS =13 1 1 2 2 1 1 2 0 3 0/97
[Figure: Figure 2. Array Diagram for Listing 4B.]
B=1 B=2 B=3 A=1 C(1,1) C(1,2) C(1,3) A=2 C(2,1) C(2,2) C(2,3) A=3 C(3,1) C(3,2) C(3,3)
Each data-set consists of two data values (A and B), a data separating comma and a closing semi-colon. Thus in the data string (LINE 8) there are 13 data-sets consisting of 4 string characters each for a total string length of 52 characters (4 X 13 = 52). The data-set length for program commands (line 10 & line 30) is then LEN C$/4. The arrangement of data in the DATA STRING is as follows: 8 LET C$=”A,B;A,B;A,B; etc.”
Program 5
Listing 5A is a program written in conventional Basic using DATA-READ statements which cannot be executed on a ZX81 Computer.
Listing 5A. Conventional Basic DATA-READ Program.
05 REM LISTING 5A
10 DIM X(2,3)
20 DIM Y(2,3)
30 FOR I=1 TO 2
40 FOR J= 1 TO 3
50 LET X(I,J)=0
60 LET Y(I,J)=0
70 NEXT J
80 NEXT I
90 READ A,B,C
100 IF A=-1 THEN 180
110 IF A=1 THEN 150
120 LET X(1,B)=X(1,B)+1
130 LET X(2,C)=X(2,C)+1
140 GOTO 90
150 LET Y(1,B)=Y(1,B)+1
160 LET Y(2,C)=Y(2,C)+1
170 GOTO 90
180 FOR I=1 TO 2
190 FOR J=1 TO 3
200 PRINT X(I,J),Y(I,J)
210 NEXT J
220 NEXT I
900 DATA 0,1,2
901 DATA 1,2,3
902 DATA -1,0,0
1 0 0 1 0 0 0 0 1 0 0 1
Listing 5B is a counting routine program equivalent to listing 5A using double-subscripted/multi-dimensional array. The array diagram is shown in Figure 3. A running total of like data values are entered and counted in the array addresses as shown in the Figure 3 matrix. Each data-set consists of three data values (A,B,C), two separating commas and a closing semi-colon. Thus in the data string (line 2) there are 2 data-sets consisting of 6 string characters each for a total string length of 12 characters (6 X 2 = 12). The arrangement of data in the DATA STRING is as follows:
2 LET A$=”A,B,C;A,B,C;A,B,C; etc”
Listing 5B. ZX81 Simulation of DATA-READ Statement for Single-Subscripted/Multi-Dimensional Variable Array in Data Count Program.
1 REM LISTING 5B
2 LET A$="0,1,2;1,2,3;"
3 DIM X(2,3)
4 DIM Y(2,3)
5 FOR I=1 TO 2
6 FOR J=1 TO 3
7 LET X(I,J)=0
8 LET Y(I,J)=0
9 NEXT J
10 NEXT I
11 LET D=0
12 LET L=1
13 FOR N=1 TO LEN A$/6
15 LET S=VAL A$(L)
17 FOR J=1 TO 2
19 LET C=VAL A$(L+D+2)
21 IF S=1 THEN GOTO 27
23 LET X(J,C)=X(J,C)+1
25 GOTO 29
27 LET Y(J,C)=Y(J,C)+1
29 LET D=D+2
31 NEXT J
33 LET D=0
35 LET L=L+6
37 NEXT N
Note for 16K RAM: For 16K memory follow line 37 with lines 40 through 80. 1K memory will accept 16K program but memory will fill with a report 4/60 before the entire array is printed.
40 FOR I=1 TO 2
50 FOR J=1 TO 3
60 PRINT X(I,J),Y(I,J)
70 NEXT J
80 NEXT I
1 0 0 1 0 0 0 0 1 0 0 1 0/80
1K RAM: FOR 1K MEMORY ENTER EACH OF THE FOLLOWING LINE 39 ENTERIES IN SUCCESSION TO DISPLAY ALL MATRIX VALUES OF THE ARRAY:
39 PRINT X(1,1),X(2,1),Y(1,1),Y(2,1)
RUN (ENTER)
1 0 0 0 0/39
39 (ENTER)
39 PRINT X(1,2),X(2,2),Y(1,2),Y(2,2)
RUN (ENTER)
0 1 1 0 0/39
39 (ENTER)
39 PRINT X(1,3),X(2,3),Y(1,3),Y(2,3)
RUN (ENTER)
0 0 0 1 0/39
Note: For 16K RAM all line numbers may be entered with addition of a trailing 0.
[Figure: Figure 3. Array Diagram for Listing 5B.]
B=1 B=2 B=3 C=1 C=2 C=3 A=0 X(1,1) X(1,2) X(1,3) X(2,1) X(2,2) X(2,3) A=1 Y(1,1) Y(1,2) Y(1,3) Y(2,1) Y(2,2) Y(2,3)
Applying this method of simulating DATA-READ statements with the ZX81 should present no problem, provided the demonstration programs are followed line by line and the technique of string slicing is understood. The only major difficulty which may be encountered is in actually slicing the data from the string. For example, if a non-numeric character is included in data which is to be converted to a numeric expression, such as a comma, the program will not run. Of course in this case an error code will be displayed (C/xx) upon execution of the program. Sliced data can be checked for correctness, however, by simply executing a print command which displays the sliced data prior to its use as a variable. The check is made during the writing of the program by entering a command to print the sliced data, running the program, checking the data for accuracy, deleting the data print command and then proceeding with the writing of the remainder of the program. For example, the following data slicing check could be used for program Listing 1B after writing line 50:
Step 1: Enter new line.
55 PRINT A$(X TO Y)
Step 2: Enter new line.
56 PRINT VAL A$(X TO Y)
Step 3: RUN program.
Step 4: Check displayed data for accuracy. Correct slice commands if necessary.
Step 5: Delete lines 55 and 56.
Step 6: Continue writing program.
Other Uses of This Technique
Use of the proposed ZX81 string statement technique is not limited to simulating DATA-READ statements. This method can be used equally well to simulate other Basic Language statements which cannot be executed directly on the ZX81 Computer.
Program Listing 6A shows a Basic program using an ON X GOTO N,N,N statement which cannot be executed on the ZX81.
Listing 6A. Conventional Basic ON X GOTO n,n,n, Program.
05 REM LISTING 6A
10 LET X=INT (RND*6)+1
20 PRINT X;"#IS THE RANDOM NUMBER"
30 PRINT
40 ON X GOTO 100,200,300,400,500,600
100 PRINT "THE RANDOM NUMBER IS 1"
150 GOTO 700
200 PRINT "THE RANDOM NUMBER IS 2"
250 GOTO 700
300 PRINT "THE RANDOM NUMBER IS 3"
350 GOTO 700
400 PRINT "THE RANDOM NUMBER IS 4"
450 GOTO 700
500 PRINT "THE RANDOM NUMBER IS 5"
550 GOTO 700
600 PRINT "THE RANDOM NUMBER IS 6"
700 PRINT "END"
X IS THE RANDOM NUMBER THE RANDOM NUMBER IS X END
Listing 6B, however, shows the equivalent program structured for execution on the ZX81 using the same string statement technique previously described. The program generates a random number which is compared to the value of the first character of a data-set in the data string (line 40). When the string character value is read which equals the value of the random number, the remainder of the selected data set is also read to provide a GOTO line address. That line address then executes a print command which identifies the value of the random number. It should be noted that although Listing 6B is to demonstrate an ON X GOTO N,N statement, line 70 could execute any ZX81 command (PRINT, STOP, LET, etc).
Listing 6B. ZX81 Simulation of ON X GOTO n,n,n Statement.
05 REM LISTING 6B
10 LET X=INT (RND*6)+1
20 PRINT X;"#IS THE RANDOM NUMBER"
30 PRINT
40 LET A$="100,200,300,400,500,600,"
50 LET L=1
55 FOR N=1 TO LEN A$/4
60 LET S=VAL A$(L TO L+2)
65 PRINT "CYCLE NUMBER#";N
70 IF N=X THEN GOTO S
80 LET L=L+4
90 NEXT N
100 PRINT "THE RANDOM NUMBER IS 1"
150 GOTO 700
200 PRINT "THE RANDOM NUMBER IS 2"
250 GOTO 700
300 PRINT "THE RANDOM NUMBER IS 3"
350 GOTO 700
400 PRINT "THE RANDOM NUMBER IS 4"
450 GOTO 700
500 PRINT "THE RANDOM NUMBER IS 5"
550 GOTO 700
600 PRINT "THE RANDOM NUMBER IS 6"
700 PRINT "END"
Note: To have program recycle enter the following lines:
710 PAUSE 125
720 CLS
730 GOTO 10
X IS THE RANDOM NUMBER CYCLE NUMBER N THE RANDOM NUMBER IS X END 0/700
It appears, then, that the ZX81 has lots of Basic capability if you can use your programming imagination and just keep $TRINGING ALONG WITH THE ZX81.
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.