flexfms - FLEX File Management System (FMS)


DESCRIPTION

The File Management System (FMS) forms the communication link between the DOS and the actual Disk Hardware. The FMS performs all file allocation and removal on the disk. All file space is allocated dynamically, and the space used by files is immediately reusable upon that file's deletion. The user of the FMS need not be concerned with the actual location of a file on the disk, or how many sectors it requires.

Communication with the FMS is done through File Control Blocks (FCB). These blocks contain the information about a file, such as its name and what drive it exists on. All disk I/O performed through FMS is "one character at a time" I/O. This means that programs need only send or request a single character at a time while doing file data transfers. In effect, the disk looks on different than a computer terminal. Files may be opened for either reading or writing. Any number of files may be opened at any one time, as long as each one is assigned its own File Control Block.

The FMS is a command language whose commands are represented by various numbers called Function Codes . Each Function Code tells FMS to perform a specific function such as open a file for read, or delete a file. In general, making use of the various functions which the FMS offers, is quite simple. The index register is made to point to the File Control Block which is to be used, the Function Code is stored in the first byte of the File Control Block , and FMS is called as a subroutine by JSR. At no time does the user ever have to be concerned with where the file is being located on the disk, how long it is, or where its directory entry is located. The FMS does all of this automatically.

Since the file structure of FLEX is a linked structure, and the disk space is allocated dynamically, it is possible for a file to exist on the disk in a set of non-contiguous sectors. Normally, if a disk has just been formatted, a file will use consecutive sectors on the disk. As files are created and deleted, however, the disk may become "fragmented". Fragmentation results in the sectors on the disk becoming out of order physically, even though logically they are still all sequential. This is a characteristic of "linked list" structures and dynamic file allocation methods. The user need not be concerned with this fragmentation, but should be aware of the fact that files may exist whose sectors seem to be spattered all over the disk. The only result of fragmentation is the slowing down of file read times, because of the increased number of head seeks necessary while reading the file.

FMS ENTRY POINTS

$D400 - FMS Initialization (FMSINI)
This entry point is used by the DOS portion of FLEX to initialize the File Management System after a cold start. There should be no need for a user-written program to use this entry point. Executing an FMS Initialization at the wrong time may result in the destruction of data files, necessitating a re-initialization of the diskette.
$D403 - FMS Close (FMSCLS)
This entry point is used by the DOS portion of FLEX at the end of each command line to close any files left open by the command processor. User-written programs may also use this entry point to close all open files; however, if an error is detected in trying to close a file, any remaining files will not be closed. Thus the programmer is cautioned against using this routine as a substitute for the good programming practice of closing files individually. There are no arguments to this routine. It is entered by a JSR instruction as though it were a subroutine. On exit, the CPU Z-Condition code is set if no error was detected (i. e. a "zero" condition exists). If an error was detected, the CPU Z-Condition code bit is cleared and the X-register contains the address of the FCB causing the error.
$D406 FMS Call (FMS)
This entry point is used for all calls to the File Management System. A function code is stored in the Function Code byte of the FCB, the address of the FCB is put in the X-register, and this entry point is called by a JSR instruction. On exit from this entry point, the CPU Z-Condition code bit is set if no error was detected in processing the function. This bit may be tested with a BEQ or BNE instruction. If an error was detected, the CPU Z-Condition code bit is cleared and the Error Status byte in the FCB contains the error number. Under all circumstances, the address of the FCB is still in the X-register on exit from this entry point. Some of the functions require additional parameters in the A and/or B-registers. The B, X, Y and U registers are always preserved with a call to FMS.

FMS FUNCTION CODES

The FLEX File Management System is utilized by the user through function codes. The proper function code number is placed, by the user, in the Function Code byte of the File Control Block (FCB) before calling FMS (Byte 0). FMS should be called by a JSR to the "FMS call" entry. On entry to FMS, the X-register should contain the address of the FCB. On exit from FMS, the CPU Z-condition code bit will be clear if an error was detected while processing the function. This bit may be tested by the BNE and BEQ instructions. Note: In the following examples, the line "JSR FMS" is referencing the FMS Call entry at $D406.
Function 0: Read/Write Next Byte/Character
If the file is open for reading, the next byte is fetched from the file and returned to the calling program in the A-register. If the file is open for writing, the content of the A-register on entry is placed in the buffer as the next byte to be written to the file. The Compression Mode Flag must contain the proper value for automatic space compression to take place, if desired (see FLEX File Control Block for details). On exit, this function code remains unchanged in the Function Code byte of the FCB; thus, consecutive read/writes may be performed without having to repeatedly store the function code. When reading, and End-of-File error is returned when all data in the file has been read. When the current sector being read is empty, the next sector in the file is prepared for processing automatically, without any action being required of the user. Similarly, when writing, full sectors are automatically written to the disk without user intervention.

Example:

Function 1: Open for Read
The file specified in the FCB is opened for read-only access. If the file cannot be found, an error is returned. The only parts of the FCB which must be preset by the programmer before issuing this function are the file specification parts (drive number, file name and file extension) and the function code. The remaining parts of the FCB will be initialized by the Open process. The Open process sets the File Compression Mode Flag to zero, indicating a text file. If the file is binary, the programmer should set the File Compression Mode Flag to $FF, after opening the file, to disable the space compression feature. On exit from FMS, after opening a file, the function code in the FCB is automatically set to zero (Read/Write Next Byte Function) in anticipation of I/O on the file.

Example:

Function 2: Open for Write
This is the same as Function 1, Open For Read, except that the file must not already exist in the diskette directory, and it is opened for write-only access. A file opened for write may not be read unless it is first closed and then re-opened for read-only. The space compression flag should be treated the same as described in "Open for Read". A file is normally opened as a sequential file but may be created as a random file by setting the FCB location File Sector Map byte non-zero immediately following an open for write operation. Refer to the section on Random Files for more details. The file will be created on the drive specified unless the drive spec is $FF in which case the file will be created on the first drive found to be ready.

Example:

Function 3: Open for Update
This function opens the file for both read and write. The file must not be open and must exist on the specified drive. If the drive spec is $FF, all drives will be searched. Once the file has been opened for update, four operations may be performed on it:

Note that it is not possible to do sequential writes to a file open for update. This implies that it is not possible to increase the size of a file which is open for update.

Function 4: Close File
If the file was opened for reading, a close merely removes the FCB from the chain of open files. If the file was opened for writing, any data remaining in the buffer is first written to the disk, padding with zeros if necessary, to fill out the sector. If a file was opened for writing but never written upon, the name of the file is removed from the diskette directory since the file contains no data.

Example:

Function 5: Rewind File
Only files which have been opened for read may be rewound. On exit from FMS, the function code in the FCB is set to zero, anticipating a read operation on the file. If the programmer wishes to rewind a file which is open for writing so that it may now be read, the file must first be closed, then re-opened for reading.

Example:

Function 6: Open Directory
This function opens the directory on the diskette for access by a program. The FCB used for this function must not already be open for use by a file. On entry, the only information which must be preset in the FCB is the drive number; no file name is required. The directory entries are read by using the Get Information Record function. The Put Information Record function is used to write a directory entry. The normal Read/Write Next Byte function will not function correctly on an FCB which is opened for directory access. It is not necessary to close an FCB which has been opened for directory access after the directory manipulation is finished. The user should normally not need to access the directory.
Function 7: Get Information Record
This function should only be issued on an FCB which has been opened with the Open Directory function. Each time the Get Information Record function is issued, the next directory entry will be loaded into the Directory Information area of the FCB. All directory entries, including deleted and unused entries are read when using this function. After an entry has been read, the FCB is said to "point" to the directory entry just read; the Current Directory Address bytes in the FCB refer to the entry just read. An End-of-File error is returned when the end of the directory is reached.

Example:

Function 8: Put Information Record
This function should only be issued on an FCB which has been opened whith the Open Directory function. The directory information is copied from the Directory Information portion of the FCB into the directory entry to which the FCB currently points. The directory sector just updated is then re-written automatically on the diskette to ensure that the directory is up-to-date. A user program should normally never have to write into a directory. Careless use of this function can lead to the destruction of data files, necessitating a re-initialization of the diskette.
Function 9: Read Single Sector
This function is a low-level interface directly to the disk driver which permits the reading of a single sector, to which the Current Position byte of the FCB point, into the Sector Buffer area of the FCB. This function is normally used internally within FLEX and a user program should never need to use it. The Read/Write Next Byte function should be used instead, whenever possible. Extreme care should be taken when using this function since it does not conform to the usual conventions to which most of other FLEX functions adhere.

Example:

Function 10: Write Single Sector
This function, like the Read Single Sector function, is a low-level interface directly to the disk driver which permits the writing of a single sector. As such, it requires extreme care in its use. This function is normally used internally by FLEX, and a user program should never need to use it. The Read/Write Next Byte function should be used whenever possible. Careless use of the Write Single Sector function may result in the destruction of data, necessitating a re-initialization of the diskette. The disk address being written is taken from the Current Position byte of the FCB; the data is taken from the Current Position bytes of the FCB; the data is taken from the FCB Sector Buffer. This function honors the Verify Flag (see FLEX Memory Map ), and will check the sector after writing it if directed to do so by the Verify Flag.
Function 11: Reserved for future system use
Function 12: Delete File
This function deletes the file whose specification is in the FCB (drive number, file name and extension). The sectors used by the file are released to the system for re-use. The file should not be open when this function is issued. The file specification in the FCB is altered during the delete process.

Example:

Function 13: Rename File
On entry, the file must not be open, the old name must be in the File Specification area of the FCB, and the new name and extension must be in the Scratch Bytes area of the FCB. The file whose specification is in the FCB is renamed to the name and extension stored in the FCB Scratch Bytes area. Both the new name and the new extension must be specified; neither the name nor the extension can be defaulted.

Example:

Function 14: Reserved for future system use
Function 15: Next Sequential Sector
On entry the file should be open for either reading or writing (not update). If the file is open for reading, this function code will cause all of the remaining (yet unread) data bytes in the current sector to be skipped, and the data pointer will be positioned at the first data byte of the next sequential sector of the file. If the file is opened for write, this operation will cause the remainder of the current sector to be zero filled and written out to the first available data location in the next sequential sector. It should be noted that all calls to this function code will be ignored unless at least one byte of data has either been written or read from the current sector.
Function 16: Open System Information Record
On entry, only the drive number need be specified in the FCB; there is no file name associated with this function. The FCB must not be open for use by a file. This function accesses the System Information Record for the diskette whose drive number is in the FCB. There are no separate functions for reading or changing this sector. All references to the data contained in the System Information Record must be made by manipulating the Sector Buffer directly. This function is used internally within FLEX; there should be no need for a user-written program to change the System Information Record. Doing so may result in the destruction of data, necessitating the re-initialization of the diskette. There is no need to close the FCB when finished.
Function 17: Get Random Byte From Sector
On entry, the file should be open for reading or update. Also, the desired byte's number should be stored in the Random Index byte of the FCB. This byte number is relative to the beginning of the sector buffer. On exit, the byte whose number is stored in the Random Index is returned to the calling program in the A-register. The Random Index should not be less than 4 since there is no user data in the first four bytes of the sector.

Example:

Function 18: Put Random Byte in Sector
The file must be open for update. This function is similar to Get Random Byte except the character in the A accumulator is written into the sector at the data location specified by Random Index of the FCB. The Random Index should not be less than 4 since only system data resides in the first 4 bytes of the sector.

Example:

Function 19: Reserved for future system use
Function 20: Find Next Drive
This function is used to find the next online drive which is in the "ready" state. Due to hardware limitations, the mini floppy version of FLEX performs this command differently than the full size floppy version. The functioning of the full size floppy version is as follows. If the drive number in the FCB is hex FF, the search for drives will start with drive 0. If the drive number is 0, 1 or 2, the search will start with drive 1, 2 or 3 respectively. If a ready drive is found, its drive number will be returned in the drive number byte of the FCB and the carry bit will be cleared. If no ready drive is found, the carry bit will be set and error #16 (Drives Not Ready) is set.

The minifloppy version functions as follows. If called with a Drive Number in the FCB of hex FF, the function will return with 0 as the drive number in the FCB. If called with a 0, it will return with the drive number set to 1. In both cases the carry is cleared on return. If called with a drive number of 1 or higher, the drive number is left unchanged, the carry bit is set on return and error #16 (Drives Not Ready) is set.

Function 21: Position to Record N
This is one of the 2 function codes provided for random file accessing by sector. The desired record number to be accessed should be stored in the FCB location Current Record Number (a 16-bit binary value). The file must be open for read or update before record number one. Positioning to record 0 will read in the first sector of the File Sector Map. After a successful Position operation, the first character read with a sequential read will be the first data byte of the specified record. An attempt to position to a nonexistent record will cause an error. For more information on random files see RANDOM FILES for details.

Example:

Function 22: Backup One Record
This is also used for random file accessing. This function takes the Current Record Number in the FCB and decrements it by one. A Position to the new record is performed. This has the effect of back spacing one full record. For example, if the Current Record Number is 16 and the Backup One Record function is performed, the file would be positioned to read the first byte of record #15. The file must be open for read or update before this function may be used. See section RANDOM FILES for details.

RANDOM FILES

FLEX version 9.0 supports random files. The random access technique allows access by record number of a file and can reach any specified sector in a file, no matter how large it is, in a maximum of two disk reads. With a small calculation using the number of data bytes in a sector (252), the user may also easily reach the Nth character of a file using the same mechanism.

Not all files may be accessed in a random manner. It is necessary to create the file as a random file. The default creation mode is sequential and is what all of the standard FLEX Utilities work with. The only random file in a standard FLEX system is the ERRORS.SYS file. FLEX uses a random access technique when reporting error messages. A file which has been created as a random access file may read either randomly or sequentially. A sequential file may only be read sequentially.

To create a random file, the normal procedure for opening a file for write should be used. Immediately following a successful open, set the File Sector Map location of the FCB to any non-zero value and proceed with the file's creation. It only makes sense to create text type files in the random mode. As the file is built, the system creates a File Sector Map. This File Sector Map (FSM) is a map or directory which tells the system where each record (sector) of the file is located on the disk. The FSM is always two sectors in length and is assigned record number 0 in the file. This implies that a data file requiring 5 sectors for the data will actually be 7 sectors in length. The user has no need for the FSM sectors and they are automatically skipped when opening a file for read. The FMS uses them for the Position and Backup function code operations.

The directory information of a file states whether or not a file is a random file. If the File Sector Map byte is non-zero, the file is random, otherwise it is sequential only. It should be noted that random files can be copied from a disk to another without losing its random properties, but it can not be appended to another file.

Within flexemu if using a directory as a FLEX drive the user execution bit will be used to distinguish between random and sequential files. Random files have this bit set.

SEE ALSO

Documents on the behalf of the FLEX User Group

Related Links