Diskette operations

Structure of the Volume Label

Track 0 side 0 sector 7 on each IBM formatted diskette contains the Volume Label. Before each access this label must be read by issuing a Sense command. It contains information about the layout of the diskette. All text strings and numerical values are storen as EBCDIC strings so that the diskette is interchangeable with other IBM systems.
 
Offset  Name                        Description/contents
------------------------------------------------------------------------------ 
00-03   Volume Label ID and Number  Identifies this sector as Volume 
                                    Label; contains the text 'VOL1' 
04-09   Volume Identifier           Name of the disk; standard 'VOLID ' 
0A      Accessibility               If non-blank access to the diskette is
                                    restricted
0B-0F   (reserved) 
10-17   (reserved) 
18-24   System Identification       Identity of the system that initialized 
                                    the diskette, e.g. 'IBM5100' on an
                                    IBM 5110/5120. 
25-32   Owner Identification        optional name of the owner; 
                                    standard 'OWNERID       ' 
33-3F   (reserved) 
40      Extended Label Area         Contains the additional number of tracks
                                    for the directory on a Diskette 2D
				    (Blank or 0 to 9)
41-46   (reserved) 
47      Volume Surface Indicator    Blank=Diskette 1, '2'=Diskette 2, 
                                    'M'=Diskette 2D 
48      Extended Arrangement Ind.   unused, must be blank 
49      Special Requirements Ind.   unused, must be blank 
4A      (reserved) 
4B      Physical Sector Length      Blank=128, '1'=256, '2'=512, '3'=1024 
4C-4D   Phys. Record Sequence Code  Specifies an optional interleave factor; 
                                    Blank or '01'=Interleave 1:1 
4E      (reserved) 
4F      Label Standard Version      must be 'W' 
50-7F   (unused) 

Structure of a directory entry

The directory starts at track 0 side 0 sector 8, each entry has a size of 128 bytes. On a diskette 2D the additional sectors contain two entries because of a sector size of 256 bytes. Each position in an entry is in EBCDIC.
 
Offset  Name                        Description/contents
------------------------------------------------------------------------------ 
00-03   Header Label ID and Number  Contains 'HDR1' with used entries; unused
                                    ones have a 'D' in the first position
04      (reserved) 
05-15   Data Set Identifier         File name; must be unique on a disk 
16-1A   Block Length                Size of a logica file block; e.g. 
                                    '  128', '00256' etc. 
1B      Record Attribute            must be blank
1C-20   Beginning of Extent (BOE)1  First sector of a file given as CCHSS 
                                    CC=cylinder, H=head, SS=sector
21      Physical Record Length      Sector size, must be equal to the entry in the 
                                    Volume Label 
22-26   End of Extent (EOE)1        Last sector that has been marked for
                                    the file
27      Record Block Format         Indicates FM or MFM data recording 
28      Bypass Indicator            unused, must be blank
29      Data Set Security           must be blank
2A      Write Protect Indicator     Blank=Writing allowed; 
                                    'P'=File is write protected
2B      Exchange Type Indicator     Depends on the disk format; 
                                    usually blank, 'E' or 'H' 
2C      Multivolume Data Set Ind.   unused 
2D-2E   Volume Sequence Indicator   unused
2F-34   Creation Date               unused; format 'YYMMDD' 
35-38   Record Length               Size of a record within the file;
                                    depends from the file type 
39-3D   Offset to Next Record Space unused; must contain blanks
3E-41   (reserviert) 
42-47   Expiration Date             unused; must contain blanks
48      Verify/Copy Indicator       unused
49      Data Set Organization       usually blank 
4A-4E   End of Data (EOD)1          Address of the first sector following 
                                    data
4F-5E   (reserviert) 
5F-6B   System Code                 Identity string of the system that created
                                    the file, e.g. 'IBM5100      ' 
6C-6D   File Application Type       File type, always two numbers
6E-7F   (unbenutzt) 
1 Relationship of BOE, EOE and EOD in graphical form:
 
     /--------- marked space on diskette ------------\ 
    /                                                 \ 
 
...-----------------------------------------------------... 
   |                                   |               | 
   |     used space by file            |   (free)      | 
...-----------------------------------------------------... 
   ^                                    ^              ^ 
   |                                    |              | 
  BOE                                  EOD            EOE 
BOE contains the first sector of a marked file, EOE the last sector. Within this boundary a file can be of any size (a multiple of the sector size). The first sector of the free area (or the first sector after the data area) is stored in EOD. An empty file like one created with the MARK command has EOD equal to BOE. If the file space is completely used EOD points to the sector after EOE. You have to pay attention to this when doing file handling.

Structure of the Work Area

Offset  Size      Description/Contents
------------------------------------------------------------------------------
00      2         Track (Bits 0-7), Side (Bit 8), Sector (Bits 9-15)
02      2         Size of the used space in number of sectors (EOD-BOE)
04      2         Size of the maked file in number of sectors (EOE-BOE)
06      2         File number after Find operation
08      1         Physical record size (0=128 bytes, 1=256 bytes, ...)
09      1         [last I/O function number]

Opening or finding a file

There is no real "Open" command like in other systems. Instead you have to find the location of a file on disk before using the file. To do this the diskette must be known by the system by issuing a Sense command. Next the directory entry for the desired file must be found with the Find command. Two methods are possible for doing a find. The first is to give the file number that is equal to the number of the directory entry to the find command. The other one is to tell Find to look for a file with a given file name.

In either case the first operation must always be a Sense. It is done by calling the I/O supervisor as explained in IOCB. The IOCB for a Sense operation must have the following fields defined:

After this the desired file can be found with a Find command, either by name or by number:
File name as parameter
File number as parameter

Important: During all operations concerning the same file IOCB_WA has to point to the same buffer all the time. The I/O routines store information about the current file like file offsets etc.

If the file has been found IOCB_Ret will contain the value 0. Otherwise (and no other error has occured) $F4F1 = '41' is returned as error code.
On successful operation the directory entry can be found in the specified buffer. IOCB_CI2 contains a pointer to it. The values are the same as explained above with two exceptions:

 
Offset  Name                        Description/contents
------------------------------------------------------------------------------ 
25-26   End of Extent               This is now a 16 bit integer value for
                                    the size of the marked area in number of
				    sectors.
 
4D-4E   End of Data                 16 bit integer value for the size of 
                                    the used file area in number of sectors. 
This way you don't have to worry about the diskette layout to get the size of the file.

Reading or writing of a file block

Reading or writing can only be done in a multiple of the sector size, also called block size. The IOCB:

With an offset each location of a file can be reached, there is no explicit file seek operation.

Creating a new file

To create a new file one has to find an unused directory entry. The simplest way of doing this is to do a Find over all file numbers until either an error '41' or '36' is returned. A '41' indicates an unused directory entry that can be used to create a new file. When '36' is returned the end of the directory has been reached so there are no free entries left.
With a free entry just found the Mark command is called. The IOCB looks like this:

This command has the same effect as the MARK command in BASIC or )MARK in APL. To be able to use the new file a Find command has to be issued a second time, now with the file number of the new file. Then data can be written or read.
You must not forget to update the file size (EOD) in the directory entry, eventually you also want to change the file name from 'SYSxxxx' (xxxx=file number) which is the default name to something else. The directory entry is loaded into a buffer with the Find command and the desired fields are changed. The entry is updated with a Write Header command.

Freeing or deleting a file

Freeing a file means to make all the marked space available for new data. This is done by changing the EOD field of the directory entry to 0 (zero) with a Find / Write Header command.

Deleting a file is different in that it alters the directory entry to the unused state ('DDR1' instead of 'HDR1'). This is accomplished by a Mark command and a file size of 0 kB (in IOCB_CI1).

Reading or writing an absolute sector

Reading or writing an absolute sector bypasses the file structure to gain access to any sector on a diskette. After the obligatorical Sense command no Find command is needed. The IOCB for direct access to a sector looks like this:

Track changes are done automatically.
Bit 0 = MSB, bit 15 = LSB!

More commands

When the bit for absolute sector access is set only the following commands are allowed: Read, Write, Find ID and Initialize Head, all others will be rejected with error code 02.