Atari Diskfile Tutorial - Part I

Jerry White


Many new computer owners are anxious to learn how to write their own useful programs. After reading the literature packed with the machine, the new owner is often overwhelmed. Realizing that one does not learn any programming language overnight, a seemingly endless period of trial and error usually follows. The "hacker" is often seen burning the midnight oil and arguing with a defenseless TV or monitor.

If he perseveres long enough, reasonably simple programs are written. The new programmer is now ready for bigger and better things.

Assuming he has a disk drive, our "hacker" gains experience with DOS and the loading and saving of programs. Now he is ready to write a database program.

The datafile may consist of a simple list of record albums for a start, to be followed by the inevitable Personal Finance System. If you are at this point in your programming career, or think you might be in the near future, read on.

Start with something very simple. Don't try to write that financial package yet. There is much to learn first about file structure and I/O. I/O stands for Input/ Output. Input is data being read by a program. Output is data being created by a program. A file consists of one or more records, and a record is an item within a file. Records may be broken down further into fields. We will be using simple records containing a single 20-character field as our record, and create a sample 10-record datafile.

To understand data processing techniques, it is often easier to grasp reality than it is to learn by reading. I have found that doing is the best way to learn, and that Atari Basic can be easy to understand if it is explained in English.

Atari Basic allows variable names of any length, plus REM or remark statements. Remarks or comments within a program help identify routines and explain exactly what the program is doing.

Meaningful variable names also make program reading much easier. For example, the sample Diskfile program uses the variable RECNUM to store the current total of records. RECNUM is an abbreviation I used to mean record number. So why didn't I use the variable RECORDNUMBER you ask? RECNUM is a compromise between that 12-letter name and the other extreme which could have been R.

The RECNUM variable is used often. The tradeoff is readability against the programmer's keystrokes and sometimes program efficiency. If R is used instead of RECORDNUMBER, and that variable is used ten times, using R saves 110 keystrokes. In a tutorial program such as this one, RECNUM is the acceptable compromise.

The Diskfile tutorial program demonstrates many of the common functions required in a simple database type program. By using the program and studying the program code, you will learn how datafiles may be handled in Atari Basic. Once you have entered the program and corrected any typing errors, run through each of the options beginning with number one.

It is important to understand the terminology used here. CREATE means just that. In this case it means create from scratch. Note that the create routine actually begins at line 1000 and that line 1010 contains an OPEN command. The number 8 in that command means write only. If a file is opened using this variable, and a file with the exact same name is found on your diskette, the old file will be deleted automatically.

Using option two, a file is read from disk and displayed on the screen. This does not in any way alter the disk file.

Option three is used to ADD data to an existing disk file only. The term APPEND is often used in this case. In plain English, the term APPEND means, "add to the end of this file."

Option four is used to UPDATE the records of an existing file. This means you will alter, correct, or change a record. This procedure is a bit more complicated than the others since we do not know in advance which record the user may choose to update. The technique used in this demo program is known as Random Access Updating. An index consisting of SECTOR and BYTE locations is created and stored in an array. This gives us the exact spot at which each record begins.

Since we are using fixed length records of 20 characters each, we can read a specific record into a string, change it in the string, then rewrite the string onto the disk. This becomes a real time saver when many records must be updated in a large disk file.

Option five is used to READ and display a specific file called the DIRECTORY FILE. This DOS-generated file contains the table of contents of your diskette. This file is also known as the VTOC or Volume Table Of Contents. For display only, this routine does the same thing as DOS option A.

Although some error trapping has been built in, many possible error conditions are not corrected or fully explained by this program. Error trapping and human engineering account for a great deal of planning and program code. This is not a cop out on my part. I plan to cover this subject in a future article. The point here is to provide an example of diskfile handling. Accounting for all possible errors could easily double the size of the program.

That's about it for now. I suggest you use my program as is, then experiment by making minor changes and noting the results. When you're ready to write your own diskfile handling program, feel free to use these routines.

0 REM FILES (c) 1981 by Jerry White
1 REM ATARI DISKFILE TUTORIAL DEMO
2 REM
100 DIM DRIVE$(3),FILE$(12),DRIVEFILE$(15),RECORD$(10),ANSWER$(1)
110 DIM SECTOR(20),BYTE(20),DIRECTORY$(20):REM DIMENSION STRINGS AND ARRAYS
111 REM
120 GRAPHICS 0:POKE 82,2:POKE 83,39:REM CLEAR SCREEN AND SET MARGINS
130 POKE 201,5:REM SET PRINT TAB WIDTH TO 5 SPACES
140 ? :? "TYPE OPTION NUMBER THEN PRESS RETURN"
150 ? :? ,"(1) CREATE A DISK FILE ":REM GOTO 1000
160 ? :? ,"(2) READ A DISK FILE":REM GOTO 2000
170 ? :? ,"(3) ADD TO A DISK FILE":REM GOTO 3000
180 ? :? ,"(4) UPDATE A DISK FILE":REM GOTO 4000
190 ? :? ,"(5) DISPLAY DISK DIRECTORY":REM GOTO 5000
200 ? :? ,"(6) END PROGRAM":REM GOTO 9140
210 ? :? "YOUR CHOICE";:GOSUB 7000
220 TRAP 8000:LINE=120:HIGHNUMBER=6:NUMBER=VAL(ANSWER$)
230 IF NUMBER<1 OR NUMBER>6 THEN GOTO 8000
240 ON NUMBER GOTO 1000,2000,3000,4000,5000,9140
250 REM
1000 LINE=6100:GOSUB 7100:TRAP 9100:GRAPHICS 0
1010 CLOSE #1:OPEN #1,8,0,DRIVEFILE$
1020 ? :? "CREATING ";DRIVEFILE$:? :RECORD$="1234567890"
1030 FOR DEMO=1 TO 10
1040 ? #1;RECORD$
1050 ? "WRITING RECORD NUMBER ";DEMO
1060 NEXT DEMO
1070 ? :? "10 RECORD DEMO FILE CREATED"
1080 ? :? "CLOSING ";DRIVEFILE$
1090 CLOSE #1
1100 GOTO 6100
1110 REM
2000 LINE=6100:GOSUB 7100:TRAP 9100:GRAPHICS 0
2010 CLOSE #1:OPEN #2,4,0,DRIVEFILE$:RECNUM=0:LINE=6100
2020 INPUT #2,RECORD$
2030 RECNUM=RECNUM+1
2040 ? "RECORD NUMBER ";RECNUM;
2050 ? ,RECORD$
2060 GOTO 2020
2070 REM
3000 LINE=3000:GOSUB 7100:TRAP 9100:GRAPHICS 0
3010 CLOSE #3:OPEN #3,9,0,DRIVEFILE$
3020 GRAPHICS 0:? :? "ADD RECORD(S) ROUTINE:"
3030 ? :? "ENTER 10 CHARACER RECORD"
3040 ? :? ,"OR JUST PRESS RETURN TO EXIT":? :GOSUB 6000
3050 RECLEN=LEN(RECORD$):IF RECLEN=0 THEN 3200
3060 IF RECLEN=10 THEN 3090
3070 FOR BLANK=RECLEN+1 TO 10:RECORD$(LEN(RECORD$)+1)=" ":NEXT BLANK
3090 PRINT #3;RECORD$
3100 ? :? "PRESS START TO ENTER ANOTHER RECORD"
3110 ? :? "PRESS OPTION FOR OTHER OPTIONS...";
3120 IF PEEK(53279)=6 THEN 3020
3130 IF PEEK(53279)=3 THEN 3200
3140 GOTO 3120
3200 ? :? :? "ADDING RECORD(S) TO DISK":CLOSE #3:GOTO 120
3210 REM
4000 LINE=4100:GOSUB 7100:TRAP 9100:GRAPHICS 0
4010 CLOSE #4:OPEN #4,12,0,DRIVEFILE$:LINE=4100
4020 ? :? ,,"CREATING INDEX":RECNUM=0
4030 NOTE #4,SECTOR,BYTE
4040 RECNUM=RECNUM+1
4050 SECTOR(RECNUM)=SECTOR:BYTE(RECNUM)=BYTE
4060 INPUT #4,RECORD$:? ," RECORD ";RECNUM,RECORD$
4070 ? ,"SECTOR=";SECTOR,"BYTE=";BYTE
4080 ? :GOTO 4030
4100 RECNUM=RECNUM-1
4110 ? :? "PRESS START TO UPDATE A RECORD"
4120 ? :? "PRESS OPTION FOR OTHER OPTIONS";
4130 IF PEEK(53279)=6 THEN 4200
4140 IF PEEK(53279)=3 THEN CLOSE #4:GOTO 120
4150 GOTO 4130
4200 GRAPHICS 0:REM RANDOM ACCESS RECORD UPDATE ROUTINE
4210 ? :? "DISKFILE CONTAINS ";RECNUM;" RECORDS"
4220 ? :? "ENTER RECORD NUMBER TO BE UPDATED";
4230 TRAP 4220:INPUT UPDATE:TRAP 40000
4240 UPDATE=INT(UPDATE):IF UPDATE<1 OR UPDATE>RECNUM THEN 4230
4250 POINT #4,SECTOR(UPDATE),BYTE(UPDATE)
4260 INPUT #4,RECORD$:? :? RECORD$
4270 ? :? "ENTER NEW RECORD #";UPDATE$;:INPUT RECORD$
4280 RECLEN=LEN(RECORD$):IF RECLEN=10 THEN 4300
4290 FOR BLANK=RECLEN+1 TO 10:RECORD$(LEN(RECORD$)+1)=" ":NEXT BLANK
4300 POINT #4,SECTOR(UPDATE),BYTE(UPDATE)
4310 PRINT #4;RECORD$:? :? ,"RECORD HAS BEEN UPDATED"
4320 GOTO 4110
4330 REM
5000 GRAPHICS 0:POKE 201,10:? :? ," DISK DIRECTORY":? :TRAP 9100
5010 CLOSE #5:OPEN #5,6,0,"D:*.*":REM OPEN DISK DIRECTORY FOR ALL ENTRIES
5020 LINE=6100
5030 INPUT #5,DIRECTORY$
5040 ? ,DIRECTORY$
5050 GOTO 5030
5060 REM
6000 RECORD$="":POKE 764,255:REM RECORD STRING AND LAST KEY PRESSED-NULL
6010 INPUT RECORD$:RETURN
6020 REM
6100 FOR FILE=1 TO 5:CLOSE #FILE:NEXT FILE:REM CLOSE ALL FILES
6110 POKE 201,5:? :? "PRESS RETURN FOR OPTIONS";
6120 GOSUB 7000:GOTO 120:REM PAUSE TO READ SCREEN THEN GO TO OPTIONS
6130 REM
7000 ANSWER$="":POKE 744,255:INPUT ANSWER$:RETURN :REM 1 CHARACTER INPUT
7010 REM
7100 GRAPHICS 0:REM DRIVE NUMBER AND FILENAME INPUT ROUTINE
7110 ? :? "TYPE DISK DRIVE NUMBER (1-4)";:HIGHNUMBER=4:GOSUB 7000
7120 LINE=7110:TRAP 8000:NUMBER=VAL(ANSWER$):TRAP 9100
7130 IF NUMBER<1 OR NUMBER>4 THEN 8000
7140 DRIVE$="D":DRIVE$(LEN(DRIVE$)+1)=ANSWER$
7150 DRIVE$(LEN(DRIVE$)+1)=":"
7200 ? :? "TYPE FILE NAME;:INPUT FILE$:IF LEN(FILE$)=0 THEN 7200 "
7210 DRIVEFILE$=DRIVE$
7220 DRIVEFILE$(LEN(DRIVEFILE$)+1)=FILE$:RETURN
7230 REM
8000 ? :? "PLEASE TYPE A NUMBER FROM 1 THRU ";HIGHNUMBER:REM ERROR ROUTINE
8010 GOSUB 9000:GOTO LINE:REM GO BACK TO LINE NUMBER (LINE)
9000 ? CHR$(253):REM RING ERROR BELL
9010 FOR COUNT=1 TO 300:NEXT COUNT:RETURN
9020 REM
9100 IF PEEK(195)=136 THEN GOTO LINE:REM ERROR WAS END OF FILE
9110 REM DISPLAY ERROR NUMBER AND LINE AT WHICH ERROR OCCURRED THEN END
9120 ? :? "ERROR ";PEEK(195);" AT LINE ";PEEK(186)+PEEK(187)*256
9130 LIST PEEK(186)+PEEK(187)*256:GOSUB 9000
9140 TRAP 40000:END :REM ELIMINATE ANY PREVIOUSLY SET TRAP AND END PROGRAM

Jerry White, 18 Hickory Lane, Levittown, NY 11756.

Table of Contents
Previous Section: Atari DOS
Next Section: Atari Diskfile Tutorial Part II