MSX-DOS 2.20 functions [3/5] ASCII, 01-09-94 3.40 SET/RESET VERIFY FLAG (2EH) Parameters: C = 2EH (_VERIFY) E = 0 to disable verify <> 0 to enable verify Results: None This function simply enables or disables automatic verification of all writes. It defaults to off when MSX-DOS is started up. Enabling verify improves system reliability but also slows down write operations. Note that this function depends on the disk driver and the verification will not be done if the driver does not support it. 3.41 ABSOLUTE SECTOR READ (2FH) Parameters: C = 2FH (_RDABS) DE = Sector number L = Drive number (0=A: etc.) H = Number of sectors to read Results: A = Error code (0=> no error) This function reads sectors directly from the disk without interpreting them as files. The disk must be a valid DOS disk in order for the sector number to be translated into a physical position on the disk. The sectors will be read to the current disk transfer address. Any disk error will be reported by the system in the usual way. 3.42 ABSOLUTE SECTOR WRITE (30H) Parameters: C = 30H (_WRABS) DE = Sector number L = Drive number (0=A: etc.) H = Number of sectors to write Results: A = Error code This function writes sectors directly to the disk without interpreting them as files. The disk must be a valid DOS disk in order for the sector number to be translated into a physical position on the disk. The sectors will be written from the current disk transfer address. Any disk errors are reported by the system in the usual way. 3.43 GET DISK PARAMETERS (31H) Parameters: C = 31H (_DPARM) DE = Pointer to 32 byte buffer L = Drive number (0=default, 1=A: etc.) Results: A = Error code DE = Preserved This functions returns a series of parameters relating to the format of the disk in the specified drive, to the buffer allocated within the user's program. It is useful for programs which are going to do absolute sector reads and writes, in order for them to be able to interpret the absolute sector numbers. The parameters returned contain some redundant information in order to provide parameters which are most useful to transient programs. The format of the returned parameter block is: DE+0 - Physical drive number (1=A: etc) DE+1,2 - Sector size (always 512 currently) DE+3 - Sectors per cluster (non-zero power of 2) DE+4,5 - Number of reserved sectors (usually 1) DE+6 - Number of copies of the FAT (usually 2) DE+7,8 - Number of root directory entries DE+9,10 - Total number of logical sectors DE+11 - Media descriptor byte DE+12 - Number of sectors per FAT DE+13..14 - First root directory sector number DE+15..16 - First data sector number DE+17..18 - Maximum cluster number DE+19 - Dirty disk flag DE+20..23 - Volume id. (-1 => no volume id.) DE+24..31 - Reserved (currently always zero) The dirty disk flag indicates whether in the disk there is a file which can be recovered by UNDEL command. It is reset when the file allocation is done. 3.44 FIND FIRST ENTRY (40H) Parameters: C = 40H (_FFIRST) DE = Drive/path/file ASCIIZ string or fileinfo block pointer HL = filename ASCIIZ string (only if DE = fileinfo pointer) B = Search attributes IX = Pointer to new fileinfo block Results: A = Error (IX) = Filled in with matching entry The "drive/path" portion of the string, or the fileinfo block, specifies a directory which is to be searched. A ".IATTR" error will be returned if a fileinfo block which specifies a file is passed. The "file" portion of the string, or the filename ASCIIZ string in HL, determines what filenames will be matched. If no match is found then a ".NOFIL" error is returned, otherwise the fileinfo block pointed to by IX is filled in with the details of the matching entry. The filename may contain ambiguous filename characters ("?" or "*") in which case the first matching entry will be returned. If the filename is null (either the ASCIIZ string pointed to by DE is null or ends in a "\" or the filename string pointed to by HL is null), then this function will behave exactly as if the filename was "*.*" so any name will match. The attributes byte in register B specifies what type of entry will be matched. If it is zero then only non-hidden, non-system files will be found. If the directory, hidden or system bits in register B are set then entries with these attributes will be matched as well as ordinary files. The read only and archive bits of register B are ignored. If the volume name bit of register B is set then the search is exclusive, only the volume label entry will be found. In this case also the fileinfo block and filename or the drive/path/file string are ignored apart from specifying the drive. This means that the volume name will always be found in the root directory if it exists whether or not it matches the filename given. If DE points to a fileinfo block, then if desired, IX can point to the same fileinfo block. In this case when a match is found the new fileinfo block will overwrite the old one. 3.45 FIND NEXT ENTRY (41H) Parameters: C = 41H (_FNEXT) IX = Pointer to fileinfo block from previous find first function. Results: A = Error (IX) = Filled in with next matching entry This function should only be used after a "find first entry" function call. It searches the directory for the next match to the (presumably ambiguous) filename which was given to the "find first entry" function call. If there are no more matching entries then a ".NOFIL" error is returned, otherwise the fileinfo block is filled in with the information about the new matching entry. 3.46 FIND NEW ENTRY (42H) Parameters: C = 42H (_FNEW) DE = Drive/path/file ASCIIZ string or fileinfo block pointer HL = filename ASCIIZ string (only if DE = fileinfo pointer) B = b0..b6 = Required attributes b7 = Create new flag IX = Pointer to new fileinfo block containing template filename Results: A = Error (IX) = Filled in with new entry This function is very similar to the "find first entry" function described above. The parameters in HL and DE are used in exactly the same way to specify a directory entry. However instead of searching the selected directory for an entry which matches the specified name, a new entry will be created with this name. The fileinfo block pointed to by IX will be filled in with information about the new entry just as if it had been found with a "find first entry" call. If there are any ambiguous characters ("?" or "*") in the filename, then they will be replaced by the appropriate character from a "template filename" in the filename position of the new fileinfo block pointed to by IX. If the result is still ambiguous, or otherwise illegal, then a ".IFNM" error is returned. This is useful for copy operations which do an automatic rename. Like "find first entry", if the filename is null, then it will be treated exactly as if it was "*.*". For this function that means that the template filename will be used as the new filename to create. A ".DRFUL" error will be returned if there is no room in the root directory, and a ".DKFUL" if a sub-directory must be extended and the disk is already full. The attribute byte passed in register B is the attribute which the new entry will be given. If the volume name bit is set then a volume name will be created in the root directory. If the directory bit is set then the entry created will be for a sub-directory, otherwise it will be for a file. The system, hidden and read only bits may be set for a file, and the hidden bit for a sub-directory. A file will always be created with the archive attribute bit set. A file will be created as zero length with the current date and time. A sub-directory will have a single cluster allocated to it and the "." and ".." entries will be initialized appropriately. If there is already an entry with the specified name in the directory then the action depends on the "create new" flag (bit-7 of register B) and also on the type of the entry. If the "create new" flag is set then a ".FILEX" error will always be returned. Setting this flag thereforeensures that an existing file will not be deleted. If an entry already exists and the "create new" flag is not set then the type of the existing entry is examined to see whether it can be deleted to make room for the new file. An error will be returned if the entry is a read only file (".FILRO" error), a system file (".SYSX" error) or a sub-directory (".DIRX" error) or there is a file handle already open to this file (".FOPEN" error). If we are trying to create a sub-directory then even an ordinary file will not be deleted (".FILEX" error). For all of these error codes (".FILEX", ".FILRO", ".SYSX", ".DIRX", ".FOPEN"), the fileinfo block will be filed in with the details of the already existing entry and this fileinfo block may be used exactly as if it had been returned from a "find first" function. 3.47 OPEN FILE HANDLE (43H) Parameters: C = 43H (_OPEN) DE = Drive/path/file ASCIIZ string or fileinfo block pointer A = Open mode. b0 set => no write b1 set => no read b2 set => inheritable b3..b7 - must be clear Results: A = Error B = New file handle The drive/path/file string or the fileinfo block should normally refer to a file rather than a sub-directory or volume name. If it is a volume name then a ".IATTR" error will be returned. If it is a sub-directory then ".DIRX" error will be returned. Assuming that a file is specified then it will be opened ready for reading and/or writing (depending on the open mode in A) and a new file handle for it will be returned in register B. The lowest available file handle number will be used and an error will result if there are no spare file handles (".NHAND" error), or insufficient memory (".NORAM" error). If the "no read" bit of register A is set then reads from the file handle will be rejected and if the "no write" bit is set then writes will be rejected, in both cases with an ".ACCV" error. Writes will also be rejected if the file is read only (".FILRO" error). If the "inheritable" bit of register A is set then the file handle will be inherited by a new process created by the "fork" function call (see function 60h). If a device file handle is opened by giving a filename which matches one of the built in devices (for example "CON" or "NUL"), then it will always be opened initially in ASCII mode. The IOCTL function (function 4Bh) can be used to change this to binary mode but great care must be taken in reading from devices in binary mode because there is no end of file condition. 3.48 CREATE FILE HANDLE (44H) Parameters: C = 44H (_CREATE) DE = Drive/path/file ASCIIZ string A = Open mode. b0 set => no write b1 set => no read b2 set => inheritable b3..b7 - must be clear B = b0..b6 = Required attributes b7 = Create new flag Results: A = Error B = New file handle A file or sub-directory, as specified by the attributes in register B, will be created with the name and in the directory specified by the drive/path/file string. A ".IATTR" error is returned if register B specifies a volume name. An error will be returned if the file or sub-directory cannot be created. The error conditions in this case are the same as for the "find new entry" function (function 42h) with the main error codes being ".FILEX", ".DIRX", ".SYSX", ".FILRO", ".FOPEN", ".DRFUL" and ".DKFUL". Like the "find new" function, if the "create new" flag (bit-7 of register B) is set then an existing file will not be deleted and will always return a ".FILEX" error. If the attributes byte specifies a sub-directory then the hidden bit may also be set to create a hidden sub-directory. For a file, the hidden, system or read only bits may be set to create a file with the appropriate attributes. An invalid attributes bits will simply be ignored. A file will always be created with the archive attribute bit set. A file will automatically be opened just as for the "open" function described above, and a file handle returned in register B. The "open mode" parameter is interpreted in the same way as for the "open" function. A sub-directory will not be opened (because this is meaningless) so register B will be returned as 0FFh which can never be a valid file handle. 3.49 CLOSE FILE HANDLE (45H) Parameters: C = 45H (_CLOSE) B = File handle Results: A = Error This function releases the specified file handle for re-use. If the associated file has been written to then its directory entry will be updated with a new date and time, the archive attributes bit will be set, and any buffered data will be flushed to disk. Any subsequent attempt to use this file handle will return an error. If there are any other copies of this file handle, created by "duplicate file handle" or "fork", then these other copies may still be used. 3.50 ENSURE FILE HANDLE (46H) Parameters: C = 46H (_ENSURE) B = File handle Results: A = Error If the file associated with the file handle has been written to then its directory entry will be updated with a new date and time, the archive attributes bit will be set, and any buffered data will be flushed to disk. The file handle is not released and so it can still be used for accessing the file, and the current file pointer setting will not be altered. 3.51 DUPLICATE FILE HANDLE (47H) Parameters: C = 47H (_DUP) B = File handle Results: A = Error B = New file handle This function creates a copy of the specified file handle. The lowest available file handle number will always be used and a ".NHAND" error returned if there are none available. The new file handle will refer to the same file as the original and either one may be used. If the file pointer of one handle is moved, the other one will also be moved. If either handle is closed the other one may still be used. Note that because duplicate file handles created by this function are not "separately opened", they do not count as separate file handles for the purposes of generating ".FOPEN" errors. So for example a "DUP"ed file handle may be renamed (function 53h) or have its attributes changed (function 55h) and the effect will apply to both file handles. Note in particular that if one copy of a "DUP"ed file handle is deleted (function 54h) then the file really will be deleted and the other file handle, although still open, can no longer be used safely. If it is used (other than being closed, ensured or deleted) then an ".FDEL" error will be returned. 3.52 READ FROM FILE HANDLE (48H) Parameters: C = 48H (_READ) B = File handle DE = Buffer address HL = Number of bytes to read Results: A = Error HL = Number of bytes actually read The specified number of bytes are read from the file at the current file pointer position and copied to the buffer address specified in register DE. The file pointer is then updated to the next sequential byte. A ".ACCV" error will be returned if the file handle was opened with the "no read" access bit set. The number of bytes read may be less than the number requested for various reasons, and the number read will be returned in register HL if there is no error. In general if less is read than requested then this should not be treated as an error condition but another read should be done to read the next portion, until a ".EOF" error is returned. An ".EOF" error will never be returned for a partial read, only for a read which reads zero bytes. Reading files in this way ensures that device file handles will work correctly (see below). For disk files the number of bytes read will only be less than the number requested if the end of the file is reached and in this case the next read operation will read zero bytes and will return an ".EOF" error. When reading from a device file handle (for example the standard file handles 0 to 4), the behaviour depends on the particular device, and on whether it is being read in ASCII or binary mode (see function 4Bh below). The "CON" device will be described as an example because it is the most commonly used device, but other devices behave similarly. When reading from the "CON" device in binary mode, characters will be read from the keyboard, without any interpretation and without being echoed to the screen or printer. The exact number of characters requested will always be read and there is no end of file condition. Because of the lack of any end of file indication, great care must be taken when reading from devices in binary mode. A read function call to the "CON" device in ASCII mode (the default mode and that which normally applies to the standard input channel), will only read one line of input. The input line will be read from the keyboard with the normal line editing facilities available to the user, and the character typed will be echoed to the screen and to the printer if Ctrl-P is enabled. Special control characters "Ctrl-P", "Ctrl-N", "Ctrl-S" and "Ctrl-C" will be tested for and will be treated exactly as for the console status function 0Bh. When the user types a carriage return the line will be copied to the read buffer, terminated with a CR-LF sequence and the read function will return with an appropriate byte count. The next read will start another buffered line input operation. If the number of bytes requested in the read was less than the length of the line input then as many character as requested will be returned, and the next read function call will return immediately with the next portion of the line until it has all been read. If the user types a line which starts with a "Ctrl-Z" character then this will be interpreted as indicating end of file. The line will be discarded and the read function call will read zero bytes and return an ".EOF" error. A subsequent read after this will be back to normal and will start another line input. The end of file condition is thus not permanent. 3.53 WRITE TO FILE HANDLE (49H) Parameters: C = 49H (_WRITE) B = File handle DE = Buffer address HL = Number of bytes to write Results: A = Error HL = Number of bytes actually written This function is very similar to the "read" function above (function 48h). The number of bytes specified will be written to the current file pointer position in the file, and the file pointer will be adjusted to point to just after the last byte written. If the file was opened with the "no write" access bit set then a ".ACCV" error will be returned, and if the file is read only then a ".FILRO" error will be returned. If the write goes beyond the current end of file then the file will be extended as necessary. If the file pointer is already beyond the end of the file then disk space will be allocated to fill the gap and will not be initialized. If there is insufficient disk space then a ".DKFUL" error will be returned and no data will be written, even if there was room for some of the data. The number of bytes written can usually be ignored since it will either be zero if an error is returned or it will be equal to the number requested if the write was successful. It is very much more efficient to write files in a few large blocks rather than many small ones, so programs should always try to write in as large blocks as possible. This function sets a "modified" bit for the file handle which ensures that when the file handle is closed or ensured, either explicitly or implicitly, the directory entry will be updated with the new date, time and allocation information. Also the archive bit will be set to indicate that this file has been modified since it was last archived. Writing to device file handles is not a complicated as reading from them because there are no end of file conditions or line input to worry about. There are some differences between ASCII and binary mode when writing to the "CON" device, in that a console status check is done in ASCII mode only. Also printer echo if enabled will only be done in ASCII mode. 3.54 MOVE FILE HANDLE POINTER (4AH) Parameters: C = 4AH (_SEEK) B = File handle A = Method code DE:HL = Signed offset Results: A = Error DE:HL = New file pointer The file pointer associated with the specified file handle will be altered according to the method code and offset, and the new pointer value returned in DE:HL. The method code specifies where the signed offset is relative to as follows: A=0 Relative to the beginning of the file A=1 Relative to the current position A=2 Relative to the end of the file. Note that an offset of zero with an method code of 1 will simply return the current pointer value, and with a method code of 2 will return the size of the file. No end of file check is done so it is quite possible (and sometimes useful) to set the file pointer beyond the end of the file. If there are any copies of this file handle created by the "duplicate file handle" function (function 47h) or the "fork" function (function 60h) then their file pointer will also be changed. The file pointer only has any real meaning on disk files since random access is possible. On device files the file pointer is updated appropriately when any read or write is done, and can be examined or altered by this function. However changing will have no effect and examining it is very unlikely to be useful. 3.55 I/O CONTROL FOR DEVICES (4BH) Parameters: C = 4BH (_IOCTL) B = File handle A = Sub-function code 00H => get file handle status 01H => set ASCII/binary mode 02H => test input ready 03H => test output ready 04H => find screen size DE = Other parameters Results: A = Error DE = Other results This function allows various aspects of file handles to be examined and altered. In particular it can be used to determine whether a file handle refers to a disk file or a device. This is useful for programs which want to behave differently for disk files and device I/O. This function is passed the file handle in register B and a sub-function code in register A which specifies one of various different operations. Any other parameters required by the particular sub-function are passed in register DE and results are returned in register DE. If the sub-function code is invalid then a ".ISBFN" error will be returned. If A=0 then the operation is "get file handle status". This returns a word of flags which give various information about the file handle. The format of this word is different for device file handles and disk file handles, and bit-7 specifies which it is. The format of the word is as follows: For devices: DE - b0 set => console input device b1 set => console output device b2..b4 reserved b5 set => ASCII mode clear=> binary mode b6 set => end of file b7 always set (=> device) b8..b15 reserved For disk files: DE - b0..b5 drive number (0=A: etc) b6 set => end of file b7 always clear (=> disk file) b8..b15 reserved Note that the end of file flag is the same for devices as for disk files. For devices it will be set if the previous attempt to read from the device produced a ".EOF" error and will be cleared by the next read. For disk files it is worked out by comparing the file pointer with the file size. If A=1 then the operation is a "set ASCII/binary mode". This operation is only allowed for device file handles. An ASCII/binary flag must be passed in bit-5 of register E (exactly where it is returned by "get file handle status"). This is set for ASCII mode and clear for binary mode. All other bits of register DE are ignored. If A=2 or 3 then the operation is "test input ready" or "test output ready" respectively. In both cases a flag is returned in register E which is FFh if the file handle is ready for a character and 00h if not. The exact meaning of "ready for a character" depends on the device. Disk file handles are always ready for output, and are always ready for input unless the file pointer is at the end of file. The "CON" device checks the keyboard status to determine whether it is ready for input or not. If A=4 the the operation is "get screen size". This returns the logical screen size for the file handle with the number of rows in register D and the number of columns in register E. For devices with no screen size (such as disk files) both D and E will be zero. Zero for either result should therefore be interpreted as "unlimited". For example this function is used by the "DIR /W" command to decide how many files to print per line, and a value of zero for register E is defaulted to 80. 3.56 TEST FILE HANDLE (4CH) Parameters: C = 4CH (_HTEST) B = File handle DE = Drive/path/file ASCIIZ string or fileinfo block pointer Results: A = Error B = 00H => not the same file FFH => same file This rather specialist function is passed a file handle and either a drive/path/file string or a fileinfo block which identifies a file. It determines if the two files are actually the same file and returns a flag indicating the result. Note that if the file handle is for a device rather than a disk file then it will always return "B=00h" to indicate "not the same file". This function allows the "COPY" command to detect certain error conditions such as copying file onto themselves and give the user informative error messages. It may also be useful for other programs which need to do similar tests. 3.57 DELETE FILE OR SUBDIRECTORY (4DH) Parameters: C = 4DH (_DELETE) DE = Drive/path/file ASCIIZ string or fileinfo block pointer Results: A = Error This function deletes the object (file or sub-directory) specified by the drive/path/file string or the fileinfo block. Global filename characters are not allowed so only one file or sub-directory can be deleted with this function. A sub-directory can only be deleted if it is empty or an error (".DIRNE") occurs if not). The "." and ".." entries in a sub-directory cannot be deleted (".DOT" error) and neither can the root directory. A file cannot be deleted if there is a file handle open to it (.FOPEN error) or if it is read only (.FILRO error). If it is a file then any disk space which was allocated to it will be freed. If the disk is an MSX-DOS 2 disk then enough information is retained on the disk to allow the "UNDEL" utility program do undelete the file. This information is only retain ed until the next disk space allocation (usually a write to a file) is done on this disk. After making this function call, if a fileinfo block was passed then it must not be used again (other than passing it to a "find next entry" function) since the file to which it refers no longer exists. If a device name such as "CON" is specified then no error will be returned but the device will not actually be deleted. 3.58 RENAME FILE OR SUBDIRECTORY (4EH) Parameters: C = 4EH (_RENAME) DE = Drive/path/file ASCIIZ string or fileinfo block pointer HL = New filename ASCIIZ string Results: A = Error This function renames the object (file or sub-directory) specified by the drive/path/file string or the fileinfo block, with the new name in the string pointed to by HL. The new filename string must not contain a drive letter or directory path (".IFNM" error if it does). If a device name such as "CON" is specified then no error will be returned but the device will not actually be renamed. Global filename characters are not allowed in the drive/path/file string, so only one object can be renamed by this function. However global filename characters are allowed in the new filename passed in HL and where they occur the existing filename character will be left unaltered. Checks are done to avoid creating an illegal filename, for example a file called "XYZ" cannot be renamed with a new filename string of "????A" because the new filename would be "XYZ A" which is illegal. In this case a ".IFNM" error will be returned. If there is already an entry with the new filename then an error (".DUPF") is returned to avoid creating duplicate filenames. The "." and ".." entries in a sub-directory cannot be renamed (".IDOT" error) and neither can the root directory (it has noname). A file cannot be renamed if there is a file handle open to it (".FOPEN" error) although a read only file can be renamed. Note that if DE pointed to a fileinfo block, this is not updated with the new name of the file. Therefore care must be taken in using the fileinfo block after making this function call. 3.59 MOVE FILE OR SUBDIRECTORY (4FH) Parameters: C = 4FH (_MOVE) DE = Drive/path/file ASCIIZ string or fileinfo block pointer HL = New path ASCIIZ string Results: A = Error This function moves the object (file or sub-directory) specified by the drive/path/file string or the fileinfo block, to the directory specified by the new path string pointed to by HL. There must not be a drive name in the new path string. If a device name such as "CON" is specified then no error will be returned but the device will not actually be moved. Global filename characters are not allowed in any of the strings so only one object (file or sub-directory) can be moved by this function, although if a sub-directory is moved, all its descendants will be moved with it. If there is already an entry of the required name in the target directory then a ".DUPF" error is returned to prevent creating duplicate filenames. The "." and ".." entries in a sub-directory cannot be moved (".DOT" error) and also a directory cannot be moved into one of its own descendants (".DIRE" error) since this would create an isolated loop in the filing system. A file cannot be moved if there is a file handle open to it (".FOPEN" error). Note that if a fileinfo block is passed to this function, the internal information in the fileinfo block is not updated to reflect the new location of the file. This is necessary because otherwise the fileinfo block could not be used for a subsequent "find next" function call. However it does mean that the fileinfo block no longer refers to the moved file and so must not be used for any operations on it such as "rename" or "open". |