Classic Computer Magazine Archive COMPUTE! ISSUE 76 / SEPTEMBER 1986 / PAGE 68

Atari 130XE Automated RAM Disk

Stehphen J. Rockower

Offering high speed and instantaneous access to programs and files, the Atari 130XE's RAM disk is one of its most attractive features. Now it's even more effective with this utility that moves selected programs and files into the RAM disk automatically whenever you boot the system. Your system will be custom configured on power up. A floppy disk drive and Atari DOS 2.5 are required.


If you own an Atari 130XE,you may have a number of BASIC programs or other files which you like to put on the RAM disk whenever you boot up. Once in the RAM disk, those files are available almost instantly, but it's a tedious process to copy each file to RAM manually. "RAM Disk Loader" for the Atari 130XE automates that chore with a custom AUTORUN.SYS file. When you boot the system, it automatically transfers selected BASIC programs and text files from the default drive (D1:) to the RAM disk (D8:).

Typing Instructions

Here's how to create the RAM Disk Loader. First, boot your computer with DOS 2.5. Go to the DOS menu to select option L; then load SETUP.COM. Use option 2 to create an AUTORUN.SYS file named D1TOD8.SAV. Now go back to BASIC and type in the program.

Note that the DATA statement in line 30 should contain the names of the BASIC programs or text files that you want to transfer to the RAM disk on power-up. When adding these names, include the full name and extender (such as PROG.BAS), but not the drive specifier (don't put D1: at the beginning of the name). Every extender must be exactly three characters long; add extra spaces if necessary to pad the extender to the correct length. The last DATA item in this series must be END which acts as a marker for the end of the list of filenames.

When you type line 40, substitute the name of the program you want to run when the system boots. For example, if you want to run MYPROG.BAS from drive D1:, line 40 should look like this:

40 READ F$:IF F$="END" THEN RUN "D1:MYPROG.BAS"

Note that this program can be one of the programs you just put on the RAM disk (to run such a program, use the D8: drive prefix).

Be very careful when typing lines 290 and 560, which contain tiny machine language routines stored in strings. These strings must be typed correctly, or the computer will probably crash. The REM statements at the end of each line explain exactly which characters to type in the strings. After you finish typing in the program, be sure to save a copy to disk. For the program to work properly, you must use the same filename you specified when you created the AUTORUN.SYS file (D1TOD8.SAV). Now you are ready to boot up again. This time, all your programs and data will be on D8.

With only slight modifications, you can use this program to transfer programs from D1: to D2: (rather than to D8:) without having to copy each file manually. This modification allows you to do batch file copies from one drive to another. A second possibility is to eliminate the DATA line altogether and read the filenames from a previously created disk file rather than from DATA. With a statement like INPUT#1,STRING$, you can bring in the name of each file to be transferred. The file could terminate with the name of the next program to run (IF STRING$="END" THEN INPUT#1,STRING$:RUN STRING$).

Program Techniques

The program begins by READing filenames one at a time from the DATA statements in line 30. If the name is not END, the program loops through the directory sectors (361-368) one at a time in search of the file. When the file is found, FLEN holds its length.

The subroutine named GETBYTES determines whether this is a BASIC program or a file containing text or other data. Since the file header for a BASIC program always starts with two zeros, we assume that anything lacking two zeros in the header is not BASIC. The next six pairs of header bytes contain information about the size and location of certain memory pointers. We are interested in the last two bytes, which tell us how many more bytes must be loaded to find the end of the file (DEND). The computation in line 680 adjusts the total number for BASIC program files.

At this point, the program opens an IOCB (Input/Output Control Block) to read the bytes from FROM$ into the string ZZ$. Then ZZ$ is manipulated to allow for text/data (FLEN*125) or a BASIC program (actually held as a string of length BYTES). Before writing the string, we must find the true end of the data. If you think about it, a text file of FLEN characters will have fewer than FLEN*125 bytes. By eliminating the zero bytes—CHR$(0), the heart symbol—we arrive at the true length of the file. This feature, incidentally, makes the program unsuitable for use with machine language files, since ML programs often contain one or more zero bytes.

Once you have this program working, you're likely to find many uses for it. I use it to move a main menu program onto the RAM disk, along with a number of programs and files I use to manage our household accounts. This method takes 20 to 30 percent less time than loading in the same files manually.

Atari 130XE RAM Disk Loader

For instructions on entering this listing, please refer to "COMPUTE!'s Guide to Typing In Programs" in this issue of COMPUTE!.

CK 15 POKE 712,148:POKE 559,0:POKE 8,255:POKE 731,1
PP 20 DIM A$(128),ZZ$(125*150),F$(15),FROM$(15),RDISK$(15),B$(16),FNAME$(16)
DG 25 TRAP 710
KI 30 DATA JUNK.1  ,JUNK.2  ,D1TOD8.BXE,END
BL 40 READ F$:IF F$="END" THEN RUN "D1:NEXTPROG.SAV"
KK 50 FOR SNUM=361 TO 368
PM 60 CLOSE #1:FLEN=0
JJ 70 A$=CHR$(0):A$(128)=CHR$(0):A$(2)=A$
FC 90 DRIVE=1:TYPE=82:BUF=ADR(A$):GOSUB 260:REM "DISC" ROUTINE
ND 100 GOSUB 330:REM "DECODE" ROUTINE
JG 110 IF FLEN THEN SNUM=368
BF 120 NEXT SNUM
HI 130 REM
HA 140 FROM$="D1:":FROM$(LEN(FROM$)+1)=F$:RDISK$=FROM$:RDISK$(2,2)="8"
HF 150 GOSUB 600:REM "GETBYTES"
AB 170 INDEX=BYTES*(BYTES<>0)+FLEN*125*(BYTES=0)
IJ 180 ZZ$="":ZZ$(1)=CHR$(0):ZZ$(INDEX)=CHR$(0):ZZ$(2)=ZZ$
KO 190 OPEN #2,8,0,RDISK$:OPEN #1,4,0,FROM$
DC 200 IOCB=1:TYPE=7:BUF=ADR(ZZ$):GOSUB 500:REM "IOCB" FOR READ
NK 210 IF BYTES>0 THEN 220
EK 211 IF ZZ$(LEN(ZZ$))=CHR$(0) THEN ZZ$=ZZ$(1,LEN(ZZ$)-1):GOTO 211
FC 212 INDEX=LEN(ZZ$)
MP 220 IOCB=2:TYPE=11:BUF=ADR(ZZ$):GOSUB 500:REM "IOCB" FOR WRITE
GE 230 CLOSE #1:CLOSE #2
DD 240 GOTO 40
GO 250 END
IM 260 REM PROCEDURE "DISC"
KD 270 POKE 779,INT(SNUM/256):POKE 778,SNUM-256*INT(SNUM/256)
JA 280 POKE 769,DRIVE:POKE 773,INT(BUF/256):POKE 772,BUF-256*INT(BUF/256):
       POKE 770,TYPE
NC 290 X=USR(ADR("h Sd{.}")):REM D.104,32,83,228,96 or small h,
       space,Cap. S, inverse small d, ctrl-.
HD 300 RETURN
HB 310 REM TYPE=82 FOR READ, 87 FOR WRITE
HJ 320 REM
AL 330 REM PROCEDURE "DECODE"
CJ 340 FLEN=0
AJ 350 FOR A=1 TO 8
NN 360 B$=A$((A-1)*16+1,A*16):IF ASC(B$(1,1))>127 THEN GOTO 460
BB 370 FLEN=ASC(B$(2))+256*ASC(B$(3))
MF 380 FSTART=ASC(B$(4))+256*ASC(B$(5))
OB 390 FNAME$=B$(6,13)
KD 394 IF FNAME$(LEN(FNAME$))=" " THEN FNAME$=FNAME$(1,LEN(FNAME$)-1):GOTO 394
EP 400 FNAME$(LEN(FNAME$)+1)=".":FNAME$(LEN(FNAME$)+1)=B$(14,16)
EJ 410 IF FNAME$=F$ THEN A=8:GOTO 470
CK 440 FLEN=0
BL 470 NEXT A
HM 480 RETURN
IB 490 REM
ID 500 REM Procedure "IOCB"
BL 510 REM ASSUMES IOCB ALREADY OPEN FOR READ OR WRITE
LF 520 BLOCK=832+IOCB*16
AB 530 POKE BLOCK+2,TYPE:REM READ=7,WRITE=11
LJ 540 POKE BLOCK+5,INT(BUF/256):POKE BLOCK+4,BUF-256*INT(BUF/256)
JD 550 POKE BLOCK+9,INT(INDEX/256):POKE BLOCK+8,INDEX-256*INT(INDEX/256)
KA 560 I=USR(ADR("hhh*LVd"),IOCB*16):REM h,h,h,inverse *, L,V, inverse d
FC 570 CLOSE #IOCB
HN 580 RETURN
IC 590 REM
MO 600 REM PROCEDURE "GETBYTES"
FN 610 OPEN #1,4,0,FROM$
CF 620 GET #1,I:GET #1,J
OF 630 IF I<>0 OR J<>0 THEN BYTES=0:GOTO 690
CA 640 FOR X=1 TO 6
CI 650 GET #1,I:GET #1,J
DD 660 NEXT X
HK 670 DEND=256*J+I
NH 680 BYTES=DEND-256+14
GJ 690 CLOSE #1
HH 700 RETURN
HM 710 REM
PO 720 POKE 559,34
IL 730 ? "ERROR ";PEEK(195);" AT LINE ";PEEK(186)+256*PEEK(187)