Datastore() and Datafetch(): Two Larken DOS Procedures for Hisoft Pascal

See all articles from Update April 1991
Author(s): David Solly
Publication: Update Magazine
Pub Details: Update April 1991
Date: April 1991
Pages: 4-9

PROGRAM AND ARTICLE BY DAVID SOLLY

When you have become spoiled by having a disk drive system on your Timex/Sinclair 2068, such as I have, you soon begin to wonder what use is there in having a compiler which allows you to write programs which are easy to maintain and run like wildfire when compiled but grind snail’s pace when they have to access the cassette drive to store or fetch data. This has been the problem with HiSoft Pascal compiler for the Timex/ Sinclair 2068; however, with the new procedures DataStore() and DataFetch() variable data can be stored to and fetched from disk under LARKEN DOS.

How the Procedures Work

All versions of Pascal use a stack in one form or another to keep track of parameter passing amongst procedures and functions. HiSoft Pascal uses the IX register to perform this function. In the case of DataStore() and DataFetch(), thirteen bytes, starting from IX+2, become reserved in the IX register when the procedure is called. Depending upon whether it is the DataStore() or DataFetch() procedure that is being called, the first two bytes contain the number of bytes which are to be transferred to or from the disk. This number is usually passed to the procedure through the function SIZE().(1) The next two bytes contain the start address of the segment to be transferred to disk or to where it is to be placed in RAM. This address is usually supplied through the function ADDR(). The remaining nine bytes contain the name under which the data will be stored to, or, fetched from the disk. In the demonstration program the variables Name and FileName have been created of the user defined type iostring to pass the file name from where it is read from the keyboard to the procedures. Once the required information has been passed to the procedure being called, the INLINE routine in turn transfers the information to certain memory locations in the LARKEN DOS cartridge and invokes the proper routines within LARKEN DOS to store or fetch the data.

Demo Program(2)

The demonstration program creates a small telephone directory in which you can store ten names and ten numbers. The program will ask you to enter ten names and numbers to fill the directory. Next it will ask for a name under which to store all the data which you have entered into the variable Directory to the disk. Finally it will ask for the file name of the data to retrieve from the disk. When you first run the program you will have to reuse the name you just used to store the data or the program may crash. If you run the program several times and create a number of files on the disk under different names you can then use any of these names and the data stored under the name selected will be retrieved and displayed.

Program Listing

1000 {$L-}
1010 PROGRAM STRDIR;
1020
1030
1040 CONST
1050
1060 MaxLen = 32;
1070 MaxEnt = 5;
1080
1090
1100 TYPE
1110
1120 iostring = ARRAY[1..9] OF CHAR;
1130
1140
1150
1160 String = RECORD
1170 CharStr : ARRAY [1..MaxLen] OF CHAR;
1180 Len : INTEGER
1190 END;
1200
1210 Entry = RECORD
1220 Name : String;
1230 Number : String;
1240 END;
1250
1260
1270
1280 VAR
1290
1300 Directory : ARRAY [1..MaxEnt] OF Entry;
1310 I : INTEGER;
1320 Ans : CHAR;
1330 FileName : iostring;
1340
1350
1360
1370 PROCEDURE StrRead (VAR EntryData : String);
1380
1390 BEGIN
1400
1410 EntryData.Len := 0;
1420 IF EOLN THEN READLN; {Clear the buffer}
1430
1440 WHILE NOT EOLN DO
1450
1460 BEGIN
1470 EntryData.Len := EntryData.Len + 1;
1480 READ(EntryData.CharStr[EntryData.Len])
1490 END;
1500
1510
1520 READLN; {Required after READ}
1530
1540 END;
1550
1560
1570
1580 PROCEDURE StrWrite(VAR PrintData : String);
1590
1610
1620 VAR
1630
1640 Letter : INTEGER;
1650
1660 BEGIN
1670
1680 FOR Letter := 1 TO PrintData.Len DO
1690
1700 WRITE(PrintData.CharStr[Letter])
1710
1720 END;
1730
1740
1750
1760
1770 PROCEDURE ReadData;
1780
1790 BEGIN
1800
1810
1820 PAGE;
1830
1840 FOR I := 1 TO MaxEnt DO
1850
1860 BEGIN
1870
1880 WITH Directory[I] DO
1890
1900 BEGIN
1910 WRITE('Enter Name ',I:2,', Please >');
1920 StrRead(Name);
1930 WRITELN;
1940 WRITE('Enter Number, Please >');
1950 StrRead(Number);
1960 END;
1970
1980 END;
1990
2000 END;
2010
2020
2030 PROCEDURE PrintData;
2040
2050
2060 BEGIN
2070
2080 FOR I := 1 TO MaxEnt DO
2090
2100 BEGIN
2110
2120 WITH Directory[I] DO
2130
2140 BEGIN
2150
2160 StrWrite(Name);
2170 WRITE(' ');
2180 StrWrite(Number);
2190 WRITELN
2200
2210 END
2220
2230 END
2240
2250 END;
2260
2270
2280 PROCEDURE DataStore (Name : iostring;
2290 Start, Bytes : INTEGER);
2300
2310 BEGIN
2320
2330 INLINE (
2340
2350 #F3, #CD, #62, #00, #3E, #0B, #32, #02,
2360 #20, #DD, #E5, #21, #22, #20, #06, #09,
2370 #DD, #7E, #06, #FE, #00, #20, #02, #3E,
2380 #20, #77, #23, #DD, #23, #10, #F1, #DD,
2390 #E1, #CD, #CC, #00, #DD, #6E, #04, #DD,
2400 #66, #05, #22, #33, #20, #DD, #6E, #02,
2410 #DD, #66, #03, #22, #31, #20, #CD, #CF,
2420 #00, #3A, #64, #00, #FB
2430
2440 )
2450
2460 END;
2470
2480
2490
2500 PROCEDURE DataFetch (Name : iostring; Start, Bytes : INTEGER);
2510 BEGIN
2520
2530 INLINE(
2540
2550 #F3, #CD, #62, #00, #3E, #64, #32, #B0,
2560 #5C, #3E, #0B, #32, #02, #20, #DD, #E5,
2570 #21, #22, #20, #06, #09, #DD, #7E, #06,
2580 #FE, #00, #20, #02, #3E, #20, #77, #23,
2590 #DD, #23, #10, #F1, #DD, #E1, #CD, #C6,
2600 #00, #3A, #B0, #5C, #FE, #65, #28, #15,
2610 #DD, #6E, #04, #DD, #66, #05, #22, #33,
2620 #20, #DD, #6E, #02, #DD, #66, #03, #22,
2630 #31, #20, #CD, #C9, #00, #3A, #64, #00,
2640 #FB
2650
2660 )
2670 END;
2680 BEGIN {MAIN PROGRAM}
2690
2700 PAGE;
2710
2720 WRITELN('The object of this program is to demonstrate');
2730 WRITELN('how type may be developed to emulate the');
2740 WRITELN('type String which is found in other versions');
2750 WRITELN('of Pascal and also to demonstrate how data');
2760 WRITELN('stored within records and arrays may be');
2770 WRITELN('transferred to and from the LARKEN Disk');
2780 WRITELN('system using the new procedures "DataStore()" and');
2790 WRITELN('"DataFetch()".');
2800
2810 WRITELN;
2820 WRITELN;
2830 WRITELN('Hit any key when ready.');
2840 READLN;
2850 READ(Ans);
2860 ReadData;
2870 PAGE;
2880 WRITELN('Now to store the data to disk');
2890 WRITELN;
2900 WRITE('Enter a name for disk storeage >');
2910 READLN;
2920 READ(FileName);
2930 DataStore(FileName,ADDR(Directory),SIZE(Directory));
2940 PAGE;
2950 WRITE('Data Stored.');
2960 WRITELN;
2970 WRITELN('Now to fetch the data from the disk.');
2980 WRITELN;
2990 WRITELN('Enter a name for disk fetch >');
2995 READLN;
3000 READ(FileName);
3010 READLN;
3020 DataFetch(FileName,ADDR(Directory),SIZE(Directory));(3)
3030 PAGE;
3040 PrintData;
3050 WRITELN;
3060 WRITELN;
3070 WRITELN('End of Demonstration') (4)
3080

(1) The DataStore() and DataFetch() procedures, like their tape counterparts DIN() and DOUT(), can be used to transfer virtually any section of RAM, including the screen buffer, on or off the disk by supplying the start and length parameters in the locations occupied by ADDR() and SIZE().

(2) Based in part on the HiSoft Pascal demonstration program Tape.

(3) DataFetch(), unlike its tape counterpart DIN(), requires both the start and length parameter in its argument.

(4) This program source code is available from Sir Clive’s Castle BBS, Ottawa, Canada at (613)745-8838. The file is called STRDIR.PS.

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.