The Device Control Block (DCB) is used to communicate with the disk handler. Figure 8-10 illustrates the structure of the DCB. The calling sequence for the disk handler is:
;caller has already set up DCB
JSR DSKINV ;system routine Vector to the resident Disk Handler
BPL OKAY ;Branch if success, Y Reg. = 1
;Else y reg. = error status (DCBSTA also has error)
The disk handler is a subroutine that is used to support the physical transfers of data between the 6502 inside the ATARI Home Computer System, and another processor located inside the ATARI 810 Disk Drive. This data transfer occurs over the serial input/output bus. The OS resident disk handier supports four functions:
FORMAT READ SECTOR WRITE/VERIFY SECTOR STATUS |
Issue a Format command to the disk controller Read a specified sector Write sector; check sector to see if written Ask the disk controller for its status |
The FORMAT command clears all the tracks on the diskette and writes sector addresses onto the tracks. No file structure is put on the diskette by this command. The data portion of each sector is set to all zeros, and the initial Volume Table of Contents and the File Directory are established. For more information on the physical layout of data on a diskette, refer to the OPERATING SYSTEM Manual and the subsection on FMS Disk Utilization.
You should note that all I/O from the disk handier is sector-oriented. The sector I/O commands can be used to read and write any sector on the diskette. You can use them to implement your own file structure. Section 10 of the OPERATING SYSTEM Manual has an example of using the disk handler to write a boot tile.
The STATUS function is used to determine the status of the disk drive. This command causes the disk drive to transmit four bytes that define its current status. These bytes are loaded into DVSTAT [$02EA,4]. The first byte is a command status byte and contains the following status bits:
The second byte is a hardware status byte and contains a copy of the
status register of the INS1771-1 Floppy Disk Controller chip used in the
disk controller. The third byte is a timeout byte that contains a
controller- provided maximum timeout value (in seconds) to be used by
the handler. The fourth byte is unused. You can use the STATUS
command for several purposes. Since the device timeout value for a
STATUS command is less than that for the other commands, you can
use it to see if a specific disk drive is connected. If the disk handler
returns a device timeout error, you know the disk drive is not connected.
File Management System
The File Management System (FMS) is a nonresident device handler
that uses the normal device handler-CIO interface. FMS is not present
in the OS ROM. It is booted in at power-up if a diskette containing DOS
is present.
FMS, like the other device handlers, gets I/O control data from CIO. FMS then uses its own disk handler to input and output to the diskette. The additional disk handler code was provided primarily to overcome an operating system bug. This bug is the result of an incorrect 16-bit compare of buffer pointers that may occur during SIO transfers. Specifically, it occurs when a buffer ends on a page boundary. However, since the result of this patch is to place a disk handler in RAM, it is possible to customize DOS somewhat. The hardware in the disk drive itself is capable of another function not supported by the resident disk handler. This function is a WRITE SECTOR WITHOUT VERIFY command. Even though some reliability is sacrificed, disk writes occur faster. To perform this customization from BASIC, you need to type:
POKE 1913,80
for fast Write (Write without Read Verify). If you want to restore the Write with Read verify, type:
POKE 1913,87
FMS is called by setting up an IOCB and calling CIO. FMS supports some special CIO functions not available to other handlers:
FORMAT | FMS calls the disk handler to format the diskette. After a successful format, FMS writes some file structure data on the diskette. |
NOTE | FMS returns the current value of the file pointer. |
POINT | FMS sets the file pointer to a specified value. |
The subsection on Random Access contains instructions on using NOTE and POINT.
Disk I/O
You can access all the standard file I/O calls through CIO. In BASIC this means using the I/O commands, such as OPEN, CLOSE, GET, PUT and XIO. In assembly language you have to set up the IOCB yourself and call CIO.
To do any disk I/O, you must first OPEN a file. The BASIC syntax for the OPEN command is:
OPEN #IOCB,ICAX1,0,"D:MYPROG.BAS"
The # IOCB selects one of the eight IOCBs available (see the CIO subsection In section 8, the Operating System, for IOCB setup). You should avoid IOCBs #0, 6, and 7 since they are used by the OS and BASIC at various times. ICAX1 is the OPEN type code. The bits for the type code are:
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
x | x | x | x | W | R | D | A |
Where: | A is Append D is Directory R is Read W is Write x is unused |
Figure 9-1 Auxiliary Byte Layout for the OPEN Command
The various values for ICAX1 are discussed in Section 5 of the OPERATING SYSTEM Manual. Some of the key things to note about the various OPEN modes are:
ICAX1=6 | This is used to OPEN the diskette directory. Records READ are the diskette directory entries. |
ICAX1=4 | READ mode. |
ICAX1=8 | WRITE mode. Any existing file opened in this mode is first deleted. The first bytes written will be at the start of the file. |
ICAX1=9 | WRITE APPEND mode. The file is left intact. Bytes written to this file are put at the end of the file. |
ICAX1=12 | UPDATE mode. This mode allows both READ and WRITE to the file. Bytes read and written start at the first byte in the file. |
ICAX1=13 | Not supported. |
There are two types of I/O you can use to transfer data between your program and the disk, record or character.
Character I/O means that the data In a file is a sequential string of bytes. DOS interprets this list of bytes as data, with none of the values being interpreted as control characters. An example of character data (all values are in Hex):
00 23 4F 55 FF 34 21.
Record I/O means that data in a file is made up of a set of records. A record is a group of bytes followed by an End of Line (EOL) character with the value $9B. An example of two records is:
00 23 4F 55 FF 34 9B 21 34 44 9B
| record 1 | record 2 |
Record and character I/O to files can be done in any arbitrary order. Indeed, data created as records can be read as characters, and file data created as characters can be read as records. The only difference between character and record I/O is that records must end with a $9B value. $9B is treated as ordinary data when using character I/O.
BASIC supports record I/O quite well. The commands PRINT and INPUT can be used to write and read records from files. BASIC does not completely support character I/O. The commands GET and PUT allow you to read and write a single byte at a time. However, the OS has the ability to read and write blocks of characters. This ability is not used by BASIC. In using this feature in the OS, you must specify the length and address of the data block to be transferred. To use the character block mode of the OS from BASIC, you can write an assembly language module to be called from BASIC by the USR function. Figure 8-16 has an example of a subroutine to do character block I/O.
The XIO command in BASIC is a general Input/Output statement that
allows for direct communication with CIO from BASIC., It is described
in more detail in the following subsection.
Disk Utility Package
The Disk Utility Package (DUP) is a set of utilities for diskette
management, familiarly seen as the DOS menu. DUP executes
commands by calling FMS through CIO. The commands are:
A. B. C. D. E. F. G. H. I. J. K. L. M. N. O. |
DIRECTORY RUN CARTRIDGE COPY FILES DELETE FILES RENAME FILES LOCK FILES UNLOCK FILES WRITE DOS FILES FORMAT DISK DUPLICATE DISK SAVE BINARY FILE LOAD BINARY FILE RUN AT ADDRESS WRITE MEM.SAV FILE DUPLICATE FILE |
The following subsections describe each of these functions. However, for complete information on these functions, refer to the DISK OPERATING SYSTEM II Manual.
Wild Cards
Many of the DUP commands require a filename specification. DOS recognizes two "wild cards" that you can substitute for characters in a filename. Wild cards are represented by the special characters, question mark (?) and asterisk (*).
These characters are used in filename descriptors where, for whatever reason, there exists some uncertainty as to the exact filename. An example of this would be when a filename extension is not known, for instance. Another example would be when you want to copy only files with a specific extension such as OBJ.
The question mark (?) may be substituted for a single character. The asterisk (*) can stand for any valid combination of characters or number of characters. The following examples illustrate the use of these characters in a Directory command.
*.BAS | will list all files on a diskette in Drive 1 that end in BAS. |
D2:*.* | will list all the program files on the Drive 2 diskette. |
PRO*.BAS | will list all the program files on diskette in Drive 1 that begin with PRO and have BAS as the extender. |
TEST?? | will list all the program files on diskette in Drive 1 that begin with TEST and have any combination of letters or numbers for the last two characters. |
Disk Directory (A)
The Disk Directory contains a list of all the files on a diskette. This command will list the filenames, the extender, and the number of sectors that the file occupies on the diskette. A partial list can be generated by entering specific filename parameters. Wild cards can be used in the parameters.
RUN CARTRIDGE (B)
The 'B' command, Run Cartridge, is typed, DOS gives control of the system to whichever cartridge is inserted. The response from that point on is dependent upon specific cartridges. BASIC, for instance, will respond by printing READY on the screen.
If the diskette in drive 1 has not been changed since the DUP was loaded, and if a MEM.SAV file is present on the diskette, then the contents of this file is copied back into RAM before control is released to the cartridge. This file normally is used to store the contents of the portion of RAM that DUP occupies when it is loaded. However, this file must already exist on the diskette when a call is issued to load DUP. Before DUP is loaded, the RAM contents are written out to the diskette for later retrieval. You can think of MEM.SAV and DUP as swapping places between the diskette and RAM.
Copy File (C)
The Copy File command ('C'), is used to copy a file from a diskette in one disk drive to another diskette in a second disk drive. You will be prompted to give file specifications for the file to COPY-FROM, TO. The first file specification may contain wild cards, and can be used to indicate a series of files to be copied. The second parameter is also generally a file specification, but may also be a destination device such as E: (screen) or P: (printer). The second parameter may be followed with a '/A? option, which indicates that the first named file should be appended to the second file. This option should not be used with tokenized Basic files.
Delete File (D)
This option allows you to delete one or more files from a diskette. Wildcards can be used in file specification names. You can avoid having to respond to the delete verification promt by appending a '/N' option to the file specification.
Rename File (E)
This option allows you to change the name of an existing file on a diskette. You must provide two parameters, OLD NAME and NEW. The first parameter must be a complete file specification, but the second is just the new file name. Wild cards are permitted for both names. If no device specification is included, D1: is assumed. An error will be generated if the first file name doesn't exist on the diskette, if the file is locked, or if the diskette is write protected.
Lock File (F)
This command is used to prevent a file from being inadvertently erased or modified. A locked file is indicated by an asterisk (*) preceding its name in the directory. Note however, that the Format command pays no attention to the Lock status of any file on a diskette.
Unlock File (G)
This option is used to Unlock a file that has been previously Locked. Both this and the Lock commands may use wild cards.
Write DOS File (H)
This option must be used to create a copy of DOS on a formatted diskette, since they can't be copied with a Copy command.
Format Diskette (I)
This option is used to create the sector and track information on a blank diskette so that it may be used by DOS. If a bad sector is encountered during the formatting process, DOS will not continue. A diskette with a bad sector cannot be formatted, and is useless. WARNING! Be very careful with this command, for it will wipe out any existing file on the diskette.
Duplicate Disk (J)
This menu option is used to create an exact duplicate of any diskette that has been created and maintained by DOS. This option can be used with either single or multiple drive systems. Duplicating on a single drive system does require repeated manual swapping of the source and the destination diskettes.
The duplication process occurs on a sector-by-sector basis. However, only those sectors that are marked as in use by the Volume Table of Contents are copied.
Care should be taken in using this command, for it destroyes any files that may have resided on the destination diskette. A good policy would be to place a write protect tab on the source diskette to preclude a catastrophic mistake by typing the source and destination values in reverse order.
Binary Save (K)
This command is use to save the contents of memory locations in an object file (binary) format. This format is also used by the ATARI Editor Assembler Cartridge. This format consists of two header bytes of $FF, two bytes for the starting load address, and two bytes for the ending load address. The remainder of the file is actual load data. You will be prompted to enter a filename and the starting and ending addresses for the load. There is also two additional address values that may optionally be entered. These are values that upon load will be placed In locations known as INIT [$02EO,2] and RUN [$02E2,2]. If these locations are updated during a load, then the code pointed to by the values in these locations will be executed.
Binary Load (L)
This command is used to load a binary load file from the diskette into RAM memory. If values for INIT and RUN values have been appended to this file, then it will function as a load-and-go routine.
Run At Address (M)
This command is used to transfer control to a machine language routine located in memory. This is normally used to start a program that has been loaded, but did not have INIT or RUN values appended to the file.
Create MEM.SAV (N)
This menu option is used to create a file called MEM.SAV. This file is used to save the contents of memory that will be overlaid when the DUP is loaded in. Effectively then, MEM.SAV and DUP swap places from RAM to disk. Note that MEM.SAV must be on the diskette in drive 1 to work. It also takes about 20 seconds to swap memory out and load DUP in if MEM.SAV is used.
Duplicate File (0)
This option is provided to copy a file from one diskette to another in a single drive system. Functionally, it is very similar to the single drive Copy command. The primary difference is that Duplicate file can be used to copy a file created under DOS 1, whereas the Copy command cannot.
Substituting the XIO Command for DUP Menu Options
The XIO command in BASIC is a general I/O statement that issues a direct call to the Centralized Input/Output Subsystem. The format of the XIO command is:
XIO command number, #iocb, auxialiary 1, auxialiary 2, file specification
The XIO command can be used to perform functions that would normally require DUP to be present. The command number for various DUP functions are shown below.
COMMAND NUMBER | FUNCTION |
---|---|
5 7 9 11 12 13 32 33 35 36 |
OPEN GET Record GET Characters PUT Record PUT Characters CLOSE STATUS Request RENAME DELETE LOCK File UNLOCK File |
DOS keeps a file pointer for each file currently OPEN which tells the DOS the location of the next byte to be accessed in the file. NOTE and POINT are used to find out the current value of this pointer, or to set it to a specific value. The file pointer has two parameters, a sector number and a byte number. The sector number is a value from 1-719 that tells DOS what sector on the diskette the file pointer is pointing to. The byte number indicates the specific byte in the sector that will be the next accessed. Figure 9-2 shows the value of the file pointer at different bytes within the file. All values are hex. The file pointer values for the bytes in this file are given below the bytes in the file.
File | A 41 |
B 42 |
C 43 |
EOL 9B |
D 44 |
E 45 |
F 46 |
EOL 9B |
G 47 |
H 48 |
I 49 |
J 4A |
K 4B |
EOL 9B |
... |
A 41 |
B 42 |
File pointer | |||||||||||||||||
Sector Number |
50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | 50 | ... | 50 | 51 |
Byte Count | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | ... | 7C | 0 |
Figure 9-2 NOTE and POINT Values
The above file was created in BASIC by the following program:
10 OPEN #1,8,0,"D:FILE"
20 ?#l;"ABC"
30 ?#1;"DEF"
40 ?#1;"GHIJK"
:
: :REM Fill the rest of the sector
:
100 ?#1;"AB" :REM This writes a record that crosses end of sector
150 CLOSE #1
The sector number of 50 was arbitrarily chosen for this example. The sector number changed to 51 because the file is longer than a single sector. FMS linked the file to the next available sector, 51. The record "AB" crosses the end of the first sector.
The byte count of the file pointer starts at 0 and is incremented until the end of the sector, $7D (125 Decimal). DOS reserves the last 3 bytes of every sector for overhead data for the file. The maximum byte number is 124 (0-124 = 125 total bytes). When the file reaches the end of a sector, the byte number recycles to 0.
When the POINT command is used to set the file pointer, DOS checks that the sector pointed to belongs to the file that is OPENed. If a file number mismatch is found, the POINT operation is not allowed.
Figure 9-3 is a subroutine that may be used to save records, keep track of where they are, and retrieve them in random access fashion.
1000 REM THIS ROUTINE CREATES AND ACCESSES RANDOM ACCESS FILES FOR FIXED
1001 REM LENGTH RECORDS
1002 REM
1003 REM ... COMMANDS ARE
1004 REM CMD=1 WRITE NTH RECORD
1005 REM CMD=2 READ NTH RECORD
1006 REM CMD=3 UPDATE NTH RECORD
1007 REM
1008 REM RECORD$ IS THE INPUT/OUTPUT RECORD
1009 REM N IS THE RECORD NUMBER
1010 REM INDEX IS A TWO DIMENSIONAL ARRAY DIM'ED INDEX(1,RECNUM)
1015 REM INDEX HOLDS THE NOTE VALUES FOR ALL RECORDS
1020 REM THIS ROUTINE ASSUMES LOGICAL FILE #1 HAS BEEN OPENED FOR I/O
1100 REM
1120 REM ROUTINE BEGINS AT 1200
1130 REM
1200 ON CMD GOTO 2000,3000,4000
2000 REM ............................
2100 REM WRITE NTH RECORD
2200 NOTE #1,X,Y
2300 INDEX(SEC,N)=X:INDEX(BYTE,N)=Y
2400 ? #1;RECORD$:RETURN
3000 REM ............................
3010 REM READ NTH RECORD
3020 REM
3030 X=INDEX(SEC,N):Y=INDEX(BYTE,N)
3040 POINT #1,X,Y
3050 INPUT #1;RECORD$
3060 RETURN
4000 REM ............................
4010 REM UPDATE NTH RECORD
4020 REM
4040 X=INDEX(SEC,N):Y=INDEX(BYTE,N)
4050 POINT #1,X,Y
4060 ? #1;RECORD$
4070 RETURN
Figure 9-3 NOTE and POINT Example
+--------------+
| BOOT record | Sector 1
+--------------+
| FMS BOOT | Sector 2
= file =
| 'DOS.SYS' | Sector 40 ($28)
+--------------+
| Disk | Sector 41 ($29)
= Utilities =
| Package | Sector 83 ($53)
+--------------+
| User | Sector 84 ($54)
= file =
| Area | Sector 359 ($167)
+--------------+
| VOLUME TABLE | Sector 360 ($168)
| of CONTENTS |
+--------------+
| File | Sector 361 ($169)
= Directory =
| | Sector 368 ($170)
+--------------+
| User | Sector 369 ($171)
= file =
| Area | Sector 719 ($2CF)
+--------------+
| Unused | Sector 720 ($2D0)
+--------------+
FMS Boot Record
The first sector on a diskette is reserved for FMS boot usage. This record contains information concerning the FMS system configuration, as well as an indication of whether the DOS.SYS is present on the diskette or not.
If the DOS files are present they usually begin at sector 2 and extend for 81 sectors.
Volume Table of Contents
Sector 360 is reserved for the FMS Volume Table of Contents (VTOC). This table contains a bit map that shows which sectors on the diskette are allocated and which are free. Since VTOC is referred to before every disk write, sector 360 was chosen to hold VTOC. This sector is in the middle of the diskette and has the minimum average access time of any diskette sector. The bit map begins in byte 10 of VTOC and extends to byte 99. Each byte in this area contains allocation information for eight sectors. A 0 in a bit position indicates the corresponding sector is in use, and a 1 Indicates it is available. The volume bit map is organized as shown below:
7 0
+-+-+-+-+-+-+-+-+
| 1 2 3 4 5 6 7| Byte 10 of VTOC
+-+-+-+-+-+-+-+-+
|8 9 . . . . . .| 11
= =
| | 99
+-+-+-+-+-+-+-+-+
File Directory Format
Eight sectors (361-368) are reserved for a diskette file directory, with each sector able to store information for up to eight files. Thus, the maximum number of files that can be placed on a single diskette is 64.
Each file directory entry consists of 16 bytes. The format of each entry is shown on the next page.
+---------------+
| flag byte | Byte 0
+---------------+
| sector (lo) | 1
+ +
| count (hi) | 2
+---------------+
| starting (lo) | 3
+ sector +
| number (hi) | 4
+---------------+
| (1) | 5
+ +
| (2) | 6
+ +
| (3) | 7
+ +
| file (4) | 8
+ +
| name (5) | 9
+ +
| primary (6) | 10
+ +
| (7) | 11
+ +
| (8) | 12
+---------------+
| file (1) | 13
+ +
| name (2) | 14
+ +
| extension (3) | 15
+---------------+
The flag byte has the following bit assignments:
Bit-7 = 1 if the file has been deleted.
Bit-6 = 1 if the file is in use.
Bit-5 = 1 if the file is locked.
Bit-0 = 1 if OPEN for output.
FMS File Sector Format
The format of a sector in a diskette file is shown below:
7 0
+-+-+-+-+-+-+-+-+
| | Byte 0
= D A T A =
| | 124
+-+-+-+-+-+-+-+-+
| file |hi | 125
+-+-+-+-+-+-+-+-+
|forward pointer| 126
+-+-+-+-+-+-+-+-+
|S| byte count | 127
+-+-+-+-+-+-+-+-+
The file # is information that FMS uses to ensure file integrity is maintained. This field contains the value of the directory position for that file. If there is ever a mismatch between the file's position in the directory and the file number field in a sector, the FMS will generate an error, and abort whichever operation was being performed.
The forward pointer is a 10-bit pointer that indicates the next sector in a file. This is described as a forward linked list, with the forward pointer of the last sector equal to 0.
If the S bit is set (i.e., equal to 1), then the sector is a "short sector" and contains less than 125 data bytes.
The byte count field contains the number of bytes in the sector.
THE AUTORUN.SYS FILE
DOS contains a feature that allows a special file to be loaded into
memory each time the system is powered-up. This can be data to
customize features of the system such as setting up different margin
values, or changing the default colors. If desired this can be a machine
language program to be executed before the normal DOS boot process
occurs.
This file must be 6 binary load file with the name AUTORUN.SYS. To make this an executable file, an address value must be loaded into the INIT [$02E0,2] or the RUN [$02E2,2] locations. The difference between these two parameters is that the code pointed to by INIT will be executed as soon as that location is loaded, whereas code pointed to by RUN will only be executed after the load process is complete. To return control to DOS after executing an AUTORUN.SYS file, terminate your code with an RTS.
The AUTORUN.SYS file can be extremely useful in setting up "load- and-go" assembly language routines. It also provides a method of reconfiguring the OS by "stealing" certain of the system vectors before DOS has a chance to be initialized. Among other things, this feature can be used to provide a certain measure of diskette protection. Refer to Figure 8-3 for an example of setting up an AUTORUN.SYS file to reset the MEMLO pointer.