Classic Computer Magazine Archive Article from Compute! magazine

Atari Disk Rx

Robert P. Dolan

"Disk Rx" is a utility which allows you to examine and repair damaged or deleted files. Here's nearly everything you need to cure sick disks. For singledensity (DOS 1 and DOS 2) disks only.


When most people first purchase a personal computer, they buy a cassette recorder to save programs. This is because disk drives are often more expensive than the computers they serve. I started out with an Atari 400 and 410 program recorder, and remember thinking "Who needs a disk drive anyway?"
    Well, I found out what all cassette users know. Programs can disappear for no reason at all. Since I was beginning to do a lot of programming, I wasted many hours from crashed cassettes.
    I now own an Atari 810 disk drive. This mysterious peripheral enabled me to save my work frequently and reliably. Then I discovered data bases and word processors. It seemed that the fun could go on forever. Well, it's not all fun. Disks do crash for the strangest reasons. At times their directories get impossible to decipher (for example, I didn't mean to delete that file ... ).
    Some of you have probably encountered these or other disasters. There is an excellent program called DISKEY, which can alleviate most of these problems. However, unless you are experienced or very careful, you can very easily lose files. DISKEY is good, but as far as I can tell it cannot do everything.

Reclaiming Files
Case in point: While using my data base, the program locked up and when I rebooted, the data file in which I had invested so many hours was all gone (error #170, #164, etc.). A friend who has DISKEY promised "no problem," and after several hours of trying, we gave up (maybe we didn't understand the manual-it is heavy reading). Determined not to reenter all that data, I set out to reclaim my file. After consulting COMPUTE!'s book Inside Atari DOS, I figured out how to get whatever was left of my file into a clean, closed, accessible file. This original routine was only 12 sectors long and now makes up the consecutive sector routine in "Disk Rx."
    The more I studied, the more ideas I had about fixes for common problems. These ideas were added to Disk Rx. The program has been thoroughly tested, but I highly recommend that you transfer all important files to a backup disk (if possible) before attempting to repair the problem disk. Also, once you've repaired a disk, to be safe you should back it up immediately and reformat it to start fresh and avoid any additional problems.

Serious Modifications
Since this program performs serious modifications to the disk directory, the utmost care must be taken when typing it in. Areas requiring special attention are string assignments, disk calls, and as usual, DATA statements. If you just don't want to bother typing it in, send a disk or cassette, a self-addressed, stamped mailer, and $3 to me, and I will make a copy for you which actually initializes faster (it uses strings instead of DATA statements for the machine language setup). My address is:

Robert P. Dolan
99 Meriden St.
Rochester, NY 14612

Disk Rx In Action
The main purpose of this utility is the examination and repair of disk files. Most damaged files can be put back together for normal loading or other access. There are also provisions for file modifications which are normally not allowed by DUP.SYS. These and other features of this program will be explained in detail in the following sections.
    The main menu of the program presents these options:

[1] FILE BUILDER
[2] SPECIAL DOS
[3] ACTIVE DIRECTORY
[4] SECTOR DIRECTORY

The functions of these options are as follows:

[1] File Builder
When you select this, a second menu is displayed which allows file reconstruction in two ways. First, if a file is in a known location with consecutive sectors, a range of sectors is specified for grouping and saving in a new named file. The other and more powerful of these functions is the file trace routine. This portion allows the examination of a file's chain link on the disk. Through this, much can be learned about a damaged file, as well as one that is intact.

[2] Special DOS
Basically, this routine provides certain directory modifications that DUP.SYS would normally challenge. When called, the user is presented with another menu from which to decide the particular function desired. The subroutines are Rename, Delete, and the life-saving Undelete. If a disk has not been written to much since the target file was deleted, the deleted file can be saved. The other two functions may not sound so special, but sometimes DUP.SYS will not allow their use. These functions will be further explained in the Special DOS section.

[3] Active Directory
This is a simple directory access which will present the files that DOS considers to be on the disk. Only these files can be accessed through normal means. This program puts any files existing on the disk into this listing. Therefore, the success of an operation performed on a file can be checked by calling this directory. Of course, the ultimate proof of success is only evident when a resurrected file has been normally accessed.

[4] Sector Directory
On this directory are all of the files which exist or have existed since the disk was last formatted (except that one or more old filenames may have been written over). With this, much information can be gained about the entire disk. When called, the following data is displayed: file number, filename, starting sector, number of sectors, and the current condition of the file (locked, unlocked, deleted, or undefined).

File Builder
In most cases, the reconstruction of a lost file can be accomplished only if the file were damaged by either of two causes. First, if the file was being accessed by another program and the calling program locked up, the called file would usually be left in an open state. Subsequent attempts to access this file would be unsuccessful. If this was a data file or a text file (such as a program saved with a LIST command), almost all of the file can be reconstructed. If the damaged file was created by a SAVE command, the outlook is not so good. The second way that a file can be lost is if it is mistakenly deleted. In that case, you'll have to use the Undelete function of the Special DOS option to retrieve it.
    When a file is left open, be sure not to write to this particular disk until you have a chance to try to correct the problem. Doing so decreases your chances of rebuilding the file to a usable condition, since DOS may write over some of the sectors you need. Run Disk Rx and select the File Builder option. From the second menu, select item 2, File Trace.
    Provide the damaged file's name (the D: prefix is not necessary). Disk Rx will look up your file in the disk directory and determine at which sector it begins. When this is done you will be presented with a screen detailing all of the information there is on the target file. Press a key when you are ready, and the actual trace will begin.
    As the file is traced, pertinent data about the file is displayed at the top of each sector display. This data is: TGT#-target file number, the number that we use as a reference; CUR#-current file number, the actual file number as derived from byte 125 of the sector just read and displayed (we want this to match our reference); NSEC#-the forward sector reference, which tells us where we are going; and BYTES-number of bytes in this sector which belong to the file we are tracing (this should equal 125 unless we are done, in which case it can be less).
    While we're on the subject, a word about sectors and bytes. There are physically 720 sectors, and 128 bytes in these sectors. The reason we're interested mainly in 125 of these is that we are reading and working with data sectors which reserve the remaining three bytes for controlling where the load is going. A boot sector uses all 128 bytes since it loads consecutively and does not need control. Disk Rx is not concerned with boot sectors. This program is a file fixer and works with files and data sectors.

More Options
When a file's trace is completed or stopped, the forward sector reference should be 0. The number of bytes claimed by our file should be less than or equal to 125. The trace routine will not continue if either of these parameters contains incorrect values, or if file number references do not match. The latter usually prevents a complete recovery of the file.
    In any case, you will have the option of saving the sector data collected during this trace or aborting the effort (in which case you go back to the main menu and all strings and buffers are cleared). When you save the new file, be sure to use the D: prefix. Using a different filename is suggested, so that you don't modify the sectors you just used as your source.
    The other option offered in the File Builder mode is the consecutive sector approach. This routine is used when the exact location of a file is known. This information can be learned by consulting the sector directory and tracing the file's sector linkage on the disk. The only information provided here is the sector being read and the file number to which the sector is supposed to belong.
    There is no checking for file integrity. This routine will cycle until it completes the sector range previously selected by the user. At this point, you are again presented with the choice to save or abort. This routine is also good for simply taking a tour of the disk. By selecting a range of 1 to 720, you can view as much of the disk as you like. Do this by answering N to the prompt regarding data collection.
    The routines and aids available in the File Builder section of Disk Rx are helpful and, in most cases, can bring a dead program back to life. However, not every damaged file can be recalled.

Special DOS: Uses And Limitations
The Special DOS functions differ from their conventional counterparts. When implemented, no checking is done on the directory bitmap or the file itself. The requested changes are made to the sector directory only. If you have a botched file and don't care about it, DOS usually won't allow you to delete it. Disk Rx will perform the deletion but will not free the sectors the target file used for other purposes. For a file which occupies many sectors, see the suggestions below. However, most small files can simply be deleted by Disk Rx and forgotten about (except for sector count discrepancies).
    This checking procedure also applies to the other Special DOS functions, Rename and Delete. The filename entry will be renamed even if its sectors are written over by another file. The Rename function is useful mainly for solving the problem of having duplicate filenames on the same disk. (If it hasn't happened to you yet, you're not trying.) When a Rename command is called, it acts on the first instance of the target name in the directory. Because of this, subsequent duplications remain unchanged.
    The most often needed routine in this program is probably the Undelete procedure. This function is also the simplest, but its success can only be guaranteed if the disk on which the file resides hasn't been written to since the deletion. Otherwise, recovery must be attempted through use of the File Builder option. This is another nonverify process, which means we are only changing the status of the sector directory entry so DOS will now acknowledge its presence and load it (assuming it is still intact). The final procedure recommended for this function is different from that for the Delete function. This time, load and save the newly accessible file by standard procedures to insure its success.
    These Special DOS functions can only be lifesavers if any necessary follow-up procedures are performed. Once again, the only true indication of a successful operation is the loading and execution of the recovered file. It is also strongly recommended that you resave any file which has been through any of Disk Rx's routines to insure complete recovery.

Botched File Deletion
One way to delete a damaged file and clear its related sectors for other uses is to use the File Trace function of File Builder to build a deletable file. This new file must be saved under the same name as the old file. This will insure that the same sectors are used in the new SAVE procedure. The new file can then be deleted completely by more conventional means, thereby freeing the associated sectors. This action is usually worth the trouble for very large files.

Console Button Controls
When sectors are displayed by Disk Rx, they can be toggled or aborted at any time by using the console buttons. During the display output, simply press the START button. This will freeze output to the screen. Pressing the SELECT button will then return control to where it left off. If you wish to terminate the function in progress, press the OPTION key instead and you will be returned to the main menu.
    Here are brief explanations of the subroutines included in Disk Rx. Some can be used in other applications, and to that end, have been written with portability in mind.

    150-200 Initialization: String dimensions, buffer setup (clearing), machine language subroutine loading, and subroutine variable setup.
    300-400 Consecutive sector loop: Note the IF-THEN statements in this routine as well as others which provide for usage by other, more central routines.
    400-500 File I/O setup: Gets filename and directs program flow to file I/O routine if there is data in the buffer to be saved.
    500-600 Sector I/O routine: Probably the most used routine in the program, it is capable of reading or writing a sector as determined by the SWRITE flag (POKE 770).
    600-700 Sector printout loop: Prints the contents of the sector buffer to the screen while not allowing control characters to perform their normal function. This is done by printing an escape character (CHR$(27);) before the intended character.
    1000-2000 Main menu: Displays options and gets choice.
    2000-3000 Console button control: Checks for START, SELECT, or OPTION pushed.
    3000-4000 Special DOS routine: Prints a menu and performs Undelete, Delete, or Rename.
    4000-5000 Directory search routine: This is not really suitable for portability since it jumps around so much. However, it is useful to study the method for examining and manipulating the filename string (FN$) and the directory entry string (ITEM$).
    5000-6000 File trace routine: Extracts information from disk sectors for rebuilding files.
    6000-7000 Sector directory printout routine: Displays sector information on the screen in the proper format.
    28000-29000 File I/O routine: This is extremely portable for any application in which it is necessary to save any portion of memory to a disk file (or to any device, for that matter). It is derived from a routine provided in De Re Atari.
    31000-32000 Proceed routine: Most routines use this to terminate their function. It clears the keyboard of previous entries and asks for another. When received, execution goes to the main menu (where the program is rerun to clear all buffers).
    32000-32110 Standard disk directory routine: This is entirely portable and a very useful feature to have in any program.

Disk Rx
Please refer to "COMPUTE!'s Guide To Typing In Programs" before entering this listing.

MM 150 ? "(CLEAR)":? "Okay...":DIM
        FN$(25),TANKS(130),DISS(10
       ),ITEMS(25),ENTS(25).EXTS(5
       ),FLAGS(25).IDS(3).CBIN$(32
       )
NB 155 DIM CIOS(7),CURNMS(16).NWNM
       $(16)
JE 156 POKE 16,64:POKE 53774,64:SE
       TCOLOR 2,13.0
IO 157 RAM=INT(FRE(0)*0.75):DIM BU
       F$(RAM)
FA 160 CBIN=ADR(CBIN$):CIO=ADR(CIO
       $):START=ADR(TANKS)
GP 165 BUF$="{,}":BUFS(RAM)=BUFS:B
       UF$(2)=BUF$:TANKS="{,}":TAN
       K$(130)=TANK$:TANK$(2)=TANK
       $
CJ 170 NAME=4008:MENU=1000:HALT=20
       00:SREAD=500:10=28000:CYCLE
       =220:PRNT=600:CONVERT=5160:
       DIREAD=4000
AK 175 IF PEEK(1572)=83 THEN 1010
AL 180 RESTORE :FOR A=1570 TO 1574
       :READ D:POKE A.D:NEXT A
NI 181 FOR A=1 TO 32:READ D:CBINS(
       A,A)=CHRS(D):NEXT A
JP 182 FOR A=1 TO 7:READ D:CIOS(A,
       A)=CHRS(D):NEXT A:GOTO 1010
NI 185 DATA 104,32,83,228,96
LG 186 DATA 104,104,104,141,144,6.
       141,145.6.78.144,6,78,144,6
       ,162,5,14,145.6.202.16,250.
       162,5,78.145,6.202.16.250,9
       6
JA 187 DATA 104,104,104,170,76,86,
       228
HG 200 REM
OA 205 TRAP 1150:? "{CLEAR}(2 DOWN)
       ENTER FIRST SECTOR ";:INPUT
        FSEC:CONS=1
OB 210 ? "{DOWN}ENTER LAST SECTOR
       ";:INPUT LSEC
IK 215 POKE 764,255:TRAP 220:? "
       {DOWN}DISPLAY SECTORS ";:IN
       PUT DISS:IF DISS(1,1)="Y" T
       HEN DISPLAY=1
PF 217 TRAP 220:? "{DOWN}LOAD SECT
       OR DATA INTO BUFFER";:INPUT
        DIS$:IF DIS$(1,1)="Y" THEN
        FILL=1:TRAP 40000
IE 220 POKE 764,255:TRAP 225:? "
       {2 DOWN)INSERT SOURCE DISK
       AND PRESS RETURN";:INPUT A
DN 225 TRAP 40000:?
HH 300 REM
NG 305 FOR SECT=FSEC TO LSEC
OO 310 IF PEEK(53279)=6 THEN GOSUB
        HALT
AP 315 IF CONS=1 THEN ? "{RVS} READING
       SECTOR {OFF}";SECT
NE 320 GOSUB SREAD:IF DISPLAY=1 TH
       EN GOSUB PRNT
LE 322 IF DIR<>1 THEN GOSUB CONVER
       T:? "{RVS} FILE NO. {OFF}";FILNO:?
NH 325 IF FILL=1 THEN SUFS(BCNT.BC
       NT+TYPE)=TANKS(1,TYPE):BCNT
       =BCNT+TYPE
CJ 330 NEXT SECT:IF DIR=1 THEN RET
       URN
HI 400 REM
BN 405 ? :? "HIT START TO SAVE":?
       "HIT OPTION TO RESTART"
OB 410 IF PEEK(53279)=6 THEN 425
LG 415 IF PEEK(53279)=3 THEN GOTO
       MENU
GE 420 GOTO 410
AB 425 IF BCNT<2 THEN ? :? CHRS(25
       3);"NO DATA TO SAVE":GOTO 3
       1000
CA 427 POKE 764,255:? "{CLEAR}
       {2 DOWN}ENTER OUTPUT FILESP
       EC ";:INPUT FN$
ME 430 IF FN%(1,2)<>"D:" THEN 425
EN 435 ? "{2 DOWN}PARAMETERS FOR F
       ILE ";FNS
PP 440 BYTES=BCNT:? "{DOWN}BYTES R
       EAD=";BYTES
OC 445 ? "{DOWN}WHICH EQUALS ";INT
       (BYTES/125);" SECTORS"
OD 450 STARR=ADR(BUFS):CMD=11:GOSU
       B IO:GOTO 31000
HJ 500 REM
IN 505 REM *** SECTOR READ ROUTINE
       ***
NB 510 POKE 769,1:POKE 770,82:POKE
        779,0
AN 515 IF SWRITE=1 THEN POKE 770,8
       7
NP 520 SUFLO=START-256*INT(START/2
       56):BUFHI=INT(START/256)
LD 525 POKE 772,BUFLO:POKE 773,BUF
       HI
PD 530 POKE 778,SECT-256*INT(SECT/
       256)
NG 535 POKE 779,INT(SECT/256)
GA 540 X=USR(1570):RETURN
IC 545 REM
HK 600 REM
HP 605 REM
IC 610    FOR X=l TO 128
PG 615 IF PEEK(53279)=6 THEN GOSUB
        HALT
GE 620 ? CHR$(27);TANK$(X.X);:NEXT
         X:? :? :RETURN
IN 996 REM
MD 997 REM *** {RVS}MAIN MENU {OFF} ***
LG 1000 RUN
DL 1010 SWRITE=0:DIR=0:UNDEL=0:NAM
        ER=0:CMD=7:DISPLAY=0:SECDI
        R=0:BCNT=1
PI 1020 POKE 764,255:TRAP MENU:? "
        {CLEAR}{(2 DOWN}{8 {RVS}SPACES{OFF}}{RVS}=
        =>{OFF}{4 {RVS}SPACES{OFF}}{RVS}DISK RX{OFF}
        {4 {RVS}SPACES{OFF}}{9 {RVS}SPACES{OFF}}"
NJ 1035 FOR S=1 TO 55:POKE 53279,0
        :NEXT S
MH 1040 ? "{3 DOWN}{7 SPACES}***OP
        TIONS***"
DI 1060 ? "{DOWN} [1] BROKEN FILE
        BUILDER"
BN 1070 ? " [2] SPECIAL DOS
        {8 SPACES}"
KI 1080 ? " [3] ACTIVE DIRECTORY
        {5 SPACES}"
LO 1090 ? " [4] SECTOR DIRECTORY
        {5 SPACES}"
NF 1095 ? " [5] QUIT PROGRAM
        {4 SPACES}";
HD 1099 INPUT CHOICE:TRAP 40000
FN 1100 IF CHOICE=2 THEN 3000
HF 1110 IF CHOICE=5 THEN END
JC 1120 IF CHOICE=3 THEN 32000
GF 1130 IF CHOICE=4 THEN 6000
EI 1140 IF CHOICE<>l THEN GOTO MEN
        U
MA 1150 TRAP 1150:? "{CLEAR}
        {2 DOWN}  {5 {RVS}SPACES{OFF}}{RVS}FILE B
        UILDER{OFF}{5 {RVS}SPACES{OFF}}"
MK 1160 ? "{3 DOWN}{6 SPACES}***OP
        TIONS***"
LN 1170 ? "{DOWN} [l] CONSECUTIVE
        SECTORS"
BI 1180 ? " [2] DISK SEARCH
        {8 SPACES}"
NG 1190 ? " [3] MAIN MENU
        {10 SPACES}";:INPUT OPTION:
        TRAP 40000
OE 1200 IF OPTION=l THEN TYPE=125:
        GOTO 200
DJ 1210 IF OPTION=3 THEN GOTO MENU
MP 1220 IF OPTION<>2 THEN 1150
KI 1230 GOTO DIREAD
KG 2000 REM
OA 2020 IF PEEK(53279)=3 THEN GOTO
         MENU
FF 2030 IF PEEK(53279)=5 THEN RETU
        RN
CI 2040 GOTO HALT
KH 3000 REM
IL 3010 REM *** SPECIAL DOS ***
KJ 3020 REM
JL 3030 TRAP 3000:? "{CLEAR}
        {2 DOWN} {5 {RVS}SPACES{OFF}}{RVS}SPECIA
        L DOS{OFF}{6 {RVS}SPACES{OFF}}"
MJ 3040 ? "{3 DOWN}{6 SPACES}***OP
        TIONS***"
NH 3050 ? "{DOWN} [l] UNDELETE FIL
        E"
AO 3060 ? " [2] RENAME FILE
        {8 SPACES}"
AL 3070 ? " [3] DELETE FILE
        {6 SPACES}"
NH 3080 ? " [4] MAIN MENU
        {10 SPACES}";:INPUT OPTION:
        TRAP 40000
IE 3090 ON OPTION GOTO 3110,3210,3
        110,MENU
MA 3100 GOTO 3000
KD 3110 REM *** UNDELETE ROUTINE
NN 3120 TRAP 40000:UNDEL=1:GOSUB D
        IREAD:ITEM$(1,1)="B":SECT=
        361:SWRITE=1:IF OPTION=3 T
        HEN ITEM$(1,1)="{  }"
NN 3130 BUFS(1+REC*16,16+REC*16)=I
        TEM$(l,16):START=ADR(BUF$)
NE 3140 ? :? "HIT {RVS} START {OFF} TO WRITE
         NEW DIRECTORY"
AP 3142 ? "HIT {RVS} OPTION {OFF} TO ABORT P
       ROCEDURE"
OL 3147 IF PEEK(53279)=3 THEN GOTO
         MENU
EE 3150 IF PEEK(53279)=6 THEN 3160
NG 3155 GOTO 3147
LJ 3160 GOSUB SREAD
KK 3170 FOR XX=1 TO 7
BN 3180 SECT=SECT+1:START=START+12
        8
AE 3190 GOSUB SREAD:NEXT XX:UNDEL=
        0
NH 3200 SWRITE=0:GOTO 31000
AG 3210 REM xxx RENAME ROUTINE
PB 3220 NAMER=1:? "{2 DOWN}ENTER C
        URRENT FILENAME";:INPUT FN
        $:GOSUB NAME:CURNM$=FN$
BC 3230 NAMER=1:? "ENTER NEW FILEN
        AME{4 SPACES}";:INPUT FNS:
        GOSUB NAME:NWNM$=FN$:FNS=C
        URNM$
NL 3240 TRAP 40000:UNDEL=I:GOSUB 4
        010:ITEMS(6,16)=NWNMS:SECT
        =361:SWRITE=1:GOTO 3130
NC 3999 REM
AP 4000 REM *** DIRECTORY SEARCH *
        **
PA 4005 TRAP 4005:? "{DOWN}ENTER T
        ARGET FILESPEC ";:INPUT FN
        $
KH 4008 D=LEN(FN$):IF D=0 THEN 400
        5
LH 4010 FOR 1=1 TO D:IF FN$(1,1)="
        ." THEN GOTO 4200
EP 4012 NEXT I
JL 4015 TRAP 4020:IF FN$(1,2)="D:"
         THEN FN$=FN$(3,LEN(FN$))
HK 4020 TRAP 40000:IF LEN(FN$)<11
        THEN FN$(LEN(FN$)+1)="
        {11 SPACES}":IF LEN(FN$)>11
         THEN FNS=FN$(1,11)
GE 4025 IF NAMER=1 THEN NAMER=0:RE
        TURN
BH 4030 FSEC=361:LSEC=368:DISPLAY=
        0:DIR=1:TYPE=128:REC=0
BN 4035 CONS=0:FILL=1:GOSUB CYCLE:
        IF REN=1 THEN REN=0:RETURN
MC 4040 ITEMS=BUF$(1+REC*16,16+REC
        *16):IF ITEMS(6,16)=FN$ TH
        EN 4055
HP 4045 IF REC>65 THEN ? CHR$(253)
        ;FNS;" NOT FOUND":GOTO 310
        00
FB 4050 REC=REC+1:GOTO 4040
FC 4055 IF UNDEL=1 THEN RETURN
BG 4060 ? "{CLEAR}{DOWN}**********
        **************************
        *{DOWN}"
BB 4065 ? :? ITEMS(6,16);" IS FILE
        NO.";REC:? :THIS=REC
FE 4070 FLAG=ASC(ITEM$(1,1)):SCNTL
        =ASC(ITEM$(2,2)):SCNTH=ASC
        (ITEM$(3,3)):SSNL=ASC(ITEM
        $(4,4)):SSNH=ASC(ITEM$(5,5
BE 4075 SCNT=SCNTH*256+SCNTL:SSN=S
        SNH*256+SSNL:IF SECDIR=1 T
        HEN RETURN
EB 4080 ? :? "*** PARAMETERS FOR F
        ILE"
BJ 4085 ? :? "DISK STARTING SECTOR
        =";SSN:?
FG 4090 ? "TOTAL SECTOR COUNT
        {3 SPACES}=";SCNT:?
FC 4095 ID$=ITEM$(1,1):IF ID$<>"b"
         AND ID$<>"B" AND ID$<(>"
        {{RVS},{OFF}}" THEN FLAG$="UNDEFINED
        "
AJ 4100 IF ITEM$(1,1)="b" THEN FLA
        G$="LOCKED"
JB 4105 IF ITEM$(1,1)="B" THEN FLA
        G$="UNLOCKED"
GN 4110    IF ITEMS(1,1)="{{RVS},{OFF}}" THEN F
        LAG$="DELETED"
JB 4115 IF SECDIR=1 THEN RETURN
JN 4120 ? :? "CURRENT FILE STATE I
        S ";FLAG$
NH 4125 ? :? "HIT ANY KEY TO BEGIN
         TRACE":POKE 764,255
HI 4130 IF PEEK(764)<>255 THEN 500
        0
NO 4135 GOTO 4130
HC 4200 EXT$=FN$(1+1,D):FN$=FN$(1,
        I-1)
PH 4205 D=LEN(FN$):IF D<8 THEN FN$
        (D+1)="{8 SPACES}":IF LEN(
        FN$)>8 THEN FN$=FN$(1,8)
AI 4210 ? CHR$(253):FN$(LEN(FN$)+1
        )=EXT$:GOTO 4015
KJ 5000 REM
GN 5020 ? "{CLEAR}{2 DOWN}>>>>>>FI
        LE TRACE<<<<<<"
OM 5022 DISPLAY=0:FILL=0:POKE 764,
        255
LN 5025 TRAP 5027:? :? "{2 DOWN}DI
        SPLAY SECTORS";:INPUT DIS$
        :IF DIS$(1,1)="Y" THEN DIS
        PLAY= 1
FN 5027 TRAP 5030:? "{DOWN}LOAD SE
        CTOR DATA INTO BUFFER";:IN
        PUT DIS$:IF DIS$(1,1)="Y"
        THEN FILL=1:TRAP 40000
PJ 5030 BCNT=1:SWRITE=0:UNDEL=0:DI
        R=0:TYPE=125:SEARCH=1:SECT
        =SSN:GOSUB SREAD
GK 5040 GOSUB CONVERT
EL 5050 ? :? "{RVS}TGT#{OFF}="1;THIS;" {RVS}CUR#{OFF}="
        :FILNO;" {RVS}NSEC{OFF}=";NSEC;" {RVS}BYT
        ES{OFF}=";BYTES:?
EN 5060 IF FILL=1 THEN BUF$(BCNT,B
        CNT+TYPE)=TANK$(1,TYPE):BC
        NT=BCNT+BYTES
NC 5070 IF DISPLAY=1 THEN GOSUB PR
        NT
ON 5075 IF THIS<>FILNO THEN ? :? "
        {RVS} FILE NUMBER MISMATCH {OFF}";CH
        R$(253):? :? "{RVS} OPTION {OFF}-ABO
        RT/{RVS} SELECT {OFF}-CONTINUE":GOTO
         HALT
KD 5080 IF TANK$(127,127)="(,)" TH
        EN 400
IN 5090 SECT=NSEC:GOSUB SREAD
CA 5100 IF PEEK(53279)=6 THEN GOSU
        B HALT
NJ 5110 GOTO 5040
KN 5120 REM
PO 5130 REM *** BYTE CONVERT ***
KO 5140 REM
AG 5160 A=USR(CBIN,ASC(TANK$(126,1
        26)))
MP 5170 FILNO=PEEK(1680):NSECHI=PE
        EK(1681):NSECLO=ASC(TANK$(
        127,127)):BYTES=ASC(TANK$(
        128,128))
KE 5180 NSEC=NSECHI*256+NSECLO
KP 5190 RETURN
KK 6000 REM
LG 6020 REM *** SECTOR DIR PRINTO
        UT *
KK 6030 REM
PF 6040 FSEC=361:LSEC=368:DISPLAY=
        0:DIR=1:TYPE=128:REC=1:SEC
        DIR=1:R=0:START=ADR(TANK$)
IK 6050 FILL=1:GOSUB CYCLE
GE 6055 TRAP 6060:? :? "WANT PRINT
        OUT";:INPUT ITEM$:IF ITEM$
        (1,1)="Y" THEN P=1:GOSUB 6
        200
MO 6060 ? "{CLEAR}{DOWN}
        {7 {RVS}SPACES{OFF}}{RVS}SECTOR DIRECTORY{OFF{
        {11 {RVS}SPACES{OFF}}"
LL 6070 ? "{RVS} {OFF}REC{RVS}  {OFF}FILENAME{RVS}  {OFF}SSN{RVS} {OFF}SCN
        T{RVS}  {OFF}STATUS{RVS}  {OFF}"
KA 6080 ITEMS=BUF$(1+REC)K16,16+REC
        *16)
KG 6090 GOSUB 4070:GOSUB 4095
MK 6100 IF ITEM$(1,5)="{5 ,}" THEN
         SECDIR=0:GOTO 31000
IC 6105    IF P=l THEN LPRINT REC,ITE
        M$(6,16),SSN,SCNT,FLAG$
KK 6110 POSITION 3,R+4:? REC:POSIT
        ION 6,R+4:? ITEM$(6,16):PO
        SITION 18,R+4:? SSN
NE 6120 POSITION 23,R+4:? SCNT:POS
        ITION 28,R+4:? FLAG$:R=R+l
        :REC=REC+1:IF R<>15 THEN 6
        080
BB 6130 POKE 764,255:? :? "[X]=END
        ....[C]=CONTINUE"
KP 6140 IF PEEK(764)=22 THEN GOTO
        MENU
EF 6150 IF PEEK(764)=18 THEN R=0:G
        OTO 6060
NB 6160 GOTO 6140
LC 6170 REM
LD 6200 TRAP 6220:LPRINT " ":LPRIN
        T " ":LPRINT "{7 {RVS}SPACES{OFF}}{RVS}SE
        CTOR DIRECTORY{OFF}{11 {RVS}SPACES{OFF}}"
KF 6210 LPR1NT "REC#{6 SPACES}FILE
        NAME{12 SPACES}SSN
        {7 SPACES}SCNT{6 SPACES}ST
        ATUS":LPRINT "  ":RETURN
DH 6220 ? :? "{RVS} TURN ON PRINTER {OFF}":G
        OTO 31000
PI 27999 REM
DB 28000 REM ** SHORT FORM FILE I/
         O **
NP 28001 REM
GH 28025 CB=1:BX=16*CB:CM=834+BX:S
         TA=835+BX:AL=836+BX:AH=83
         7+BX:LL=840+BX:LH=841+BX:
         A1=4:IF CMD=11 THEN A1=8
FA 28040 CLOSE #1:OPEN #CB,A1,0,FN
         $:TEMP=STADR:GOSUB 28060:
         POKE AL,LOW:POKE AH,HI:TE
         MP=BYTES:GOSUB 28060
EN 28050 POKE LL,LOW:POKE LH,HI:PO
         KE CM,CMD:ERROR=USR(ADR(C
         IO$),BX):ERROR=PEEK(STA):
         CLOSE #1:RETURN
IG 28060 H1=INT(TEMP/256):LOW=INT(
         TEMP-HI*256):RETURN
PJ 31000 POKE 764,255:? :? :? "HIT
          ANY KEY TO CONTINUE"
EO 31010 IF PEEK(764)<>255 THEN GO
         TO MENU
CE 31020 GOTO 31010
BJ 32000 REM {RVS} DISK DIRECTORY {OFF}
NO 32010 OPEN #5,6,0,"D:*.*":POKE
         82,1
PF 32020 ? "{CLEAR}":TRAP 32110:?
         :? "{11 {RVS}SPACES{OFF}}{RVS}DISK DIREC
         TORY{OFF}{11 {RVS}SPACES{OFF}}"   
FG 32040 INPUT #5,ENT$:? ENT$;"  "
AJ 32050 INPUT #5,ENT$:? ENT$:GOTO
          32040
NO 32110 CLOSE #5:? :? "
         {70 SPACES}";:POKE 82,2:GO
         TO 31000