.MB +5
.MT -3
.LL 65
.PN 29
.HE MP/M User's Guide
.FT   (All Information Herein is Proprietary to Digital Research.)
.sp
.pp
2.2  Basic Disk Operating System Functions
.pp
In general, the Basic Disk Operating System (BDOS) facilities are
identical to that of CP/M 2.0.  Each function is covered in this
section by describing the
entry parameters, returned values, and any differences between
CP/M and MP/M.
.sp 2
.cp 13
.li
***************************************
*                                     *
*  FUNCTION 0:  SYSTEM RESET          *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  00H             *
***************************************
.pp
The SYSTEM RESET function terminates the calling program,
releasing the memory segment, console, and mutual exclusion
messages owned by the calling program.
When the console is released it is usually given back to the
terminal message process (TMP) for that console.
.pp
Effectively the operation of the SYSTEM RESET function is the
same for MP/M     as it is for CP/M 2.0 because the program
is terminated and the operator receives the prompt to
enter another command.
However, MP/M does not re-initialize the disk subsystem
by selecting and logging-in disk drive A.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 1:  CONSOLE INPUT         *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  01H             *
*                                     *
*  Returned   Value:                  *
*      Register   A:  ASCII Character *
***************************************
.pp
The CONSOLE INPUT function reads the next console character
to register A.  Graphic characters, along with carriage return,
line feed, and backspace (ctl-H) are echoed to the console.
Tab characters (ctl-I) are expanded in columns of eight
characters.  A check is made for start/stop scroll (ctl-S)
and start/stop printer echo (ctl-P).
The BDOS does not return to the calling program until a character
has been typed, thus suspending execution if a character is
not ready.
.sp 2
.cp 15
.li
***************************************
*                                     *
*  FUNCTION 2:  CONSOLE OUTPUT        *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  02H             *
*      Register   E:  ASCII Character *
*                                     *
***************************************
.pp
The ASCII character from register E is sent to the console
device.  Similar to function 1, tabs are expanded and
checks are made for start/stop scroll and printer echo.
.sp 2
.cp 14
.li
***************************************
*                                     *
*  FUNCTION 3:  RAW CONSOLE INPUT     *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  03H             *
*                                     *
*  Returned   Value:                  *
*      Register   A:  ASCII Character *
***************************************
.pp
The RAW CONSOLE INPUT function reads the next console
character to Register A.  There is no testing of the input
character, that is, the system will directly pass through all
characters including the control characters without any
interpretation.   This function does not require that the console
be attached, nor does it attach the console.
.pp
The READER INPUT function is not supported under MP/M.  All
character I/O devices such as the reader/punch are treated as consoles.
MP/M supports up to 16 consoles or character I/O devices.
.sp 2
.cp 14
.li
***************************************
*                                     *
*  FUNCTION 4:  RAW CONSOLE OUTPUT    *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  04H             *
*      Register   E:  ASCII Character *
*                                     *
***************************************
.pp
The  RAW  CONSOLE OUTPUT function sends the  ASCII  character
from register E to the console device.  There is no testing of the
output character, that is, tabs are not expanded and no checks are
made  for start/stop scroll and printer echo.  This function  does
not  require that the console be attached, nor does it attach  the
console.  Thus, unsolicited messages may be sent to other consoles
by  simply changing the console byte of the process descriptor  and
then using this function.
.pp
The PUNCH OUTPUT function is not supported under MP/M.
.sp 2
.cp 15
.li
***************************************
*                                     *
*  FUNCTION 5:  LIST OUTPUT           *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  05H             *
*      Register   E:  ASCII Character *
*                                     *
***************************************
.pp
The LIST OUTPUT function sends the ASCII character in register
E to the logical listing device.
.pp
Caution  must be observed in the use of the  printer  since
there is no implicit list device ownership.  That is, the
list  device is not "opened" or "closed".  MP/M affords  a
secondary   explicit   means  to  resolve  printer   mutual
exclusion.  A queue named 'MXList' is created by the system
to handle mutual exclusion.  To properly obtain use  of the
printer  a program should open the 'MXList' queue and  read
the message.  When the message is obtained the printer may
be used.  When printing is completed the message should  be
written back to the 'MXList' queue.  This technique is used
by the MP/M PIP, SPOOLer, and TMP ctl-P operations.
.sp 2
.cp 20
.li
***************************************
*                                     *
*  FUNCTION 6:  DIRECT CONSOLE I/O    *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  06H             *
*      Register   E:  0FFH (input) or *
*                     0FEH (status)or *
*                     char (output)   *
*                                     *
*  Returned   Value:                  *
*      Register   A:  char or status  *
*                     (no value)      *
***************************************
.pp
Direct console I/O is supported under MP/M for those specialized
applications where unadorned console input and output is
required.  Use of this function should, in general, be avoided
since it bypasses all of MP/M's normal control character functions
(e.g., control-S and control-P).
Programs which perform direct I/O through the BIOS
under previous releases of CP/M, however,
should be changed to use direct I/O under BDOS so that they
can be fully supported under MP/M and CP/M.
.pp
Upon entry to function 6, register E either contains hexadecimal
FF, denoting a console input request, a hexadecimal FE, denoting
a console input status request, or register E contains
an ASCII character.  If the input value is FF, then function 6
returns the next console input character.
.pp
If the input value is FE, then function 6 returns a value of FF
if a character is ready, or a 00 if no character has been received.
.pp
If the input value in E is not FF or FE, then function 6 assumes that
E contains a valid ASCII character which is sent to the
console.
.pp
Note that BDOS functions 3 and 4 (raw console input/output) can be
used for totally transparent console I/O.  When using functions 3 and 4,
the console status operation can be performed by using function 6 with
a parameter of FE.
.sp 2
.cp 14
.li
***************************************
*                                     *
*  FUNCTION 7:  GET I/O BYTE          *
*                                     *
***************************************
*                                     *
*    Not supported under MP/M         *
*                                     *
***************************************
.pp
The GET I/O BYTE function is not supported under MP/M.
.sp 2
.cp 14
.li
***************************************
*                                     *
*  FUNCTION 8:  SET I/O BYTE          *
*                                     *
***************************************
*                                     *
*    Not supported under MP/M         *
*                                     *
***************************************
.pp
The SET I/O BYTE function is not supported under MP/M.
.sp 2
.cp 15
.li
***************************************
*                                     *
*  FUNCTION 9:  PRINT STRING          *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  09H             *
*      Registers DE:  String Address  *
*                                     *
***************************************
.pp
The PRINT STRING function sends the character string stored in
memory at the location given by DE to the console device, until
a "$" is encountered in the string.  Tabs are expanded as in
function 2, and checks are made for start/stop scroll and printer
echo.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 10: READ CONSOLE BUFFER   *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  0AH             *
*      Registers DE:  Buffer Address  *
*                                     *
*  Returned   Value:                  *
*      Console Characters in Buffer   *
***************************************
.pp
The READ BUFFER function reads a line of edited console input
into a buffer addressed by registers DE.  Console input is
terminated when either the input buffer overflows.
The READ BUFFER takes the
form:
.sp
.cp 5
.li
    DE: +0 +1 +2 +3 +4 +5 +6 +7 +8    . . .    +n
       -------------------------------------------
       |mx|nc|c1|c2|c3|c4|c5|c6|c7|   . . .   |??|
       -------------------------------------------
.sp
where "mx" is the maximum number of characters which the
buffer will hold (1 to 255), "nc" is the number of characters
read (set by BDOS upon return), followed by the characters
read from the console.  if nc < mx, then uninitialized
positions follow the last character, denoted by "??" in
the above figure.
A number of control functions are recognized during line
editing:
.sp
.li
         rub/del removes and echoes the last character
          ctl-C  reboots when at the beginning of line
          ctl-E  causes physical end of line
          ctl-H  backspaces one character position
          ctl-J  (line feed) terminates input line
          ctl-M  (return) terminates input line
          ctl-R  retypes the current line after new line
          ctl-U  removes current line after new line
          ctl-X  backspaces to beginning of current line
.sp
Note also that certain functions which return the carriage to
the leftmost position (e.g., ctl-X) do so only to the column
position where the prompt ended (in earlier releases, the carriage
returned to the extreme left margin).  This convention
makes operator data input and line correction more legible.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 11: GET CONSOLE STATUS    *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  0BH             *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Console Status  *
***************************************
.pp
The CONSOLE STATUS function checks to see if a character
has been typed at the console.  If a character is ready,
the value 0FFH is returned in register A.  Otherwise a
00H value is returned.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 12: RETURN VERSION NUMBER *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  0CH             *
*                                     *
*  Returned   Value:                  *
*      Registers HL:  Version Number  *
***************************************
.pp
Function 12 provides information which
allows version independent programming.
A two-byte value is returned, with H = 00 designating the CP/M
release (H = 01 for MP/M), and L = 00 for all releases
previous to 2.0.  CP/M 2.0 returns a hexadecimal 20 in register
L, with subsequent version 2 releases in the hexadecimal
range 21, 22, through 2F.  Using function 12, for example,
you can write application programs which provide both
sequential and random access functions, with random access
disabled when operating under early releases of CP/M.
.sp 2
.cp 14
.li
***************************************
*                                     *
*  FUNCTION 13: RESET DISK SYSTEM     *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  0DH             *
*                                     *
*  Returned Value:                    *
*      Register   A:  Return Code     *
***************************************
.pp
The RESET DISK function is used to programmatically restore
the file system to a reset state where all disks are set to
read/write (see functions 28 and 29),
and the default DMA address is reset to the memory segment base +0080H.
This function can be used, for example, by an application
program which requires a disk change without a system reboot.
.pp
The  RESET DISK SYSTEM function is qualified in  MP/M.  If
there  are  any open files on any  drive, the  reset  disk
system  is  denied  and  the reason  is  displayed  on  the
console.
The returned value indicates whether or not the reset  disk
was  successful.  If any process is currently accessing  a
drive, an error code of 0FFH is returned in the A register.
A return code of 0 indicates success.
.sp 2
.cp 15
.li
***************************************
*                                     *
*  FUNCTION 14: SELECT DISK           *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  0EH             *
*      Register   E:  Selected Disk   *
*                                     *
***************************************
.pp
The SELECT DISK function designates the disk drive named in
register E as the default disk for subsequent file operations,
with E = 0 for drive A, 1 for drive B, and so-forth through
15 corresponding to drive P in a full sixteen drive system.
The drive is placed in an "on-line" status which, in particular,
activates its directory until the next cold start, warm start,
or disk system reset operation.  If the disk media is changed
while it is on-line, the drive automatically goes to a read/only
status in a standard MP/M environment (see function 28).
FCB's which specify drive code zero (dr = 00H) automatically
reference the currently selected default drive.  Drive code
values between 1 and 16, however, ignore the selected default
drive and directly reference drives A through P.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 15: OPEN FILE             *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  0FH             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The OPEN FILE operation is used to activate a file which
currently exists in the disk directory for either the currently
active user code or user code 0.  The BDOS scans the referenced disk
directory for a match in positions 1 through 14 of the
FCB referenced by DE (byte s1 is automatically zeroed),
where an ASCII question mark (3FH) matches any directory
character in any of these positions.  Normally, no
question marks are included and, further, bytes "ex" and
"s2" of the FCB are zero.
.pp
If a directory element is matched, the relevant directory
information is copied into bytes d0 through dn of the FCB,
thus allowing access to the files through subsequent read
and write operations.  Note that an existing file must not
be accessed until a sucessful open operation is completed.
Upon return, the open function returns a "directory code"
with the value 0 through 3 if the open was successful, or
0FFH (255 decimal) if the file cannot be found.  If
question marks occur in the FCB then the first matching
FCB is activated.
Note that the current record ("cr") must be zeroed by
the program if the file is to be accessed sequentially
from the first record.
.pp
The open file operation will succeed for files with either the
current user code or user code 0.  This presents a problem when
files with the same name exist under both the current user code
and under user code 0.  When such a situation exists the first one
found in the directory will be opened.  Even though this should
not present a problem because user code 0 is intended only for
system and commonly used files, a potential problem can be
detected by using the search file function.  The search file
function enables examination of the directory FCB and thus the
actual file user code can be determined.
.pp
Opening a file sets the appropriate bit in the drive active vector
of the calling processes process descriptor.  This bit is cleared
only by terminating the process or making a free drive (function 39)
call.  Setting of the bit in the drive active vector will prevent
any other process from resetting the drive on which the file was
opened.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 16: CLOSE FILE            *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  10H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The CLOSE FILE function performs the inverse of the open file
function.  Given that the FCB addressed by DE has been previously
activated through an open or make function (see functions 15 and 22),
the close function permanently records the new FCB in the referenced
disk directory.  The FCB matching process for the close is identical
to the open function.  The directory code returned for a successful
close operation is 0, 1, 2, or 3, while a 0FFH (255 decimal) is
returned if the file name cannot be found in the directory.
A file need not be closed if only read operations have taken
place.  If write operations have occurred, however, the close operation
is necessary to permanently record the new directory information.
.pp
Note that the close file function does not affect the drive active
vector of the calling processes process descriptor.  The free drive
function (function 39) must be used to reset the bit of the drive
active vector.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 17: SEARCH FOR FIRST      *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  11H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
SEARCH FIRST scans the directory for a match with the file
given by the FCB addressed by DE.
Files with either the currently active user code or user code 0
will match.
The value 255 (hexadecimal
FF) is returned if the file is not found, otherwise
0, 1, 2, or 3 is returned indicating the file is present.
In the case that the file is found, the current DMA address
is filled with the record containing the directory entry,
and the relative starting position is A * 32 (i.e., rotate
the A register left 5 bits, or ADD A five times).  Although
not normally required for application programs, the directory
information can be extracted from the buffer at this position.
.pp
An ASCII question mark (63 decimal, 3F hexadecimal) in any
position from "f1" through "ex" matches
the corresponding field of
any directory entry on
the default or auto-selected disk drive.
If the "dr" field contains an ASCII question mark, then the
auto disk select function is disabled, the default disk
is searched, with the search function returning any
matched entry, allocated or free, belonging to any user
number.  This latter function is not normally used by
application programs, but does allow complete flexibility
to scan all current directory values.
If the "dr" field is not a question mark, the "s2" byte is
automatically zeroed.
.pp
To determine the user code of a successful search (it may be the
currently active user code or user code 0), the returned directory
code can be used as described above to index into the DMA buffer
and the user code of the directory FCB can be obtained.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 18: SEARCH FOR NEXT       *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  12H             *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The SEARCH NEXT function is similar to the Search First function,
except that the directory scan continues from the last matched
entry.  Similar to function 17, function 18 returns the decimal
value 255 in A when no more directory items match.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 19: DELETE FILE           *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  13H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The DELETE FILE function removes files which match the FCB
addressed by DE.  The filename and type may contain ambiguous
references (i.e., question marks in various positions), but
the drive select code cannot be ambiguous, as in the Search
and Search Next functions.
.pp
Function 19 returns a decimal 255 if the referenced file or
files cannot be found, otherwise a value in the range
0 to 3 is returned.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 20: READ SEQUENTIAL       *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  14H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
Given that the FCB addressed by DE has been activated
through an open or make function (numbers 15 and 22), the
READ SEQUENTIAL function reads the next 128 byte record
from the file into memory at the current DMA address.
the record is read from position "cr" of the extent, and
the "cr" field is automatically incremented to the next
record position.  If the "cr" field overflows
then the next logical extent is automatically opened and the
"cr" field is reset to zero in preparation for the next
read operation.
The value 00H is returned in the A register if the read
operation was successful, while a non-zero value is returned
if no data exists at the next record position (e.g., end of
file occurs).
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 21: WRITE SEQUENTIAL      *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  15H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
Given that the FCB addressed by DE has been activated
through an open or make function (numbers 15 and 22), the
WRITE SEQUENTIAL function writes the 128 byte data record
at the current DMA address to the file named by the FCB.
the record is placed at position "cr" of the file, and
the "cr" field is automatically incremented to the next
record position.  If the "cr" field overflows
then the next logical extent is automatically opened and the
"cr" field is reset to zero in preparation for the next
write operation.  Write operations can take place into an
existing file, in which case newly written records overlay
those which already exist in the file.
Register A = 00H upon return from a successful write operation,
while a non-zero value indicates
a full disk.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 22: MAKE FILE             *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  16H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The MAKE FILE operation is similar to the open file operation
except that the FCB must name a file which does not exist
in the currently referenced disk directory (i.e., the one
named explicitly by a non-zero "dr" code, or the default
disk if "dr" is zero).  The FDOS creates the file and initializes
both the directory and main memory value to an empty file.
The programmer must ensure that no duplicate file names
occur, and a preceding delete operation is sufficient if
there is any possibility of duplication.
Upon return, register A = 0, 1, 2, or 3 if the operation
was successful and 0FFH (255 decimal) if no more directory
space is available.  The make function has the side-effect
of activating the FCB and thus a subsequent open is not
necessary.
.pp
Making a file sets the appropriate bit in the drive active vector
of the calling processes process descriptor.  This bit is cleared
only by terminating the process or making a free drive (function 39)
call.  Setting of the bit in the drive active vector will prevent
any other process from resetting the drive on which the file was
opened.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 23: RENAME FILE           *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  17H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The RENAME FILE function uses the FCB addressed by DE to change
all occurrences of the file named in the first 16 bytes
to the file named in the second 16 bytes.  The drive code
"dr" at position 0 is used to select the drive, while the
drive code for the new file name at position 16 of the
FCB is assumed to be zero.  Upon return, register A is
set to a value between 0 and 3 if the rename was successful,
and 0FFH (255 decimal) if the first file name could not
be found in the directory scan.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 24: RETURN LOGIN VECTOR   *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  18H             *
*                                     *
*  Returned   Value:                  *
*      Registers HL:  Login Vector    *
***************************************
.pp
The login vector value returned by MP/M is a 16-bit
value in HL, where the least significant bit of L corresponds
to the first drive A, and the high order bit of H corresponds
to the sixteenth drive, labelled P.
A "0" bit indicates that the drive is not on-line, while
a "1" bit marks an drive that is actively on-line due
to an explicit disk drive selection, or an implicit drive
select caused by a file operation which specified a
non-zero "dr" field.
Note that compatibility
is maintained with earlier releases, since registers A and
L contain the same values upon return.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 25: RETURN CURRENT DISK   *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  19H             *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Current Disk    *
***************************************
.pp
Function 25 returns the currently selected default disk
number in register A.  The disk numbers range from 0 through
15 corresponding to drives A through P.
.sp 2
.cp 15
.li
***************************************
*                                     *
*  FUNCTION 26: SET DMA ADDRESS       *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  1AH             *
*      Registers DE:  DMA Address     *
*                                     *
***************************************
.pp
"DMA" is an acronym for Direct Memory Address, which is often
used in connection with disk controllers which directly
access the memory of the mainframe computer to transfer
data to and from the disk subsystem.  Although many
computer systems use non-DMA access (i.e., the data is
transfered through programmed I/O operations), the DMA
address has, in MP/M, come to mean the address at which
the 128 byte data record resides before a disk write
and after a disk read.  Upon cold start, warm start, or
disk system reset, the DMA address is automatically
set to BOOT+0080H.  The Set DMA function, however, can
be used to change this default value to address another
area of memory where the data records reside.
Thus, the DMA address becomes the value specified by
DE until it is changed by a subsequent Set DMA function,
cold start, warm start, or disk system reset.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 27: GET ADDR(ALLOC)       *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  1BH             *
*                                     *
*  Returned   Value:                  *
*      Registers HL:  ALLOC Address   *
***************************************
.pp
An "allocation vector" is maintained in main memory for each
on-line disk drive.  Various system programs use the
information provided by the allocation vector to determine
the amount of remaining storage (see the STAT program).
Function 27 returns the base address of the allocation
vector for the currently selected disk drive.
The allocation information may, however, be invalid if
the selected disk has been marked read/only.
Although this function is not normally used by application
programs, additional details of the allocation vector
are found in the "CP/M 2.0 Alteration Guide."
.sp 2
.cp 14
.li
***************************************
*                                     *
*  FUNCTION 28: WRITE PROTECT DISK    *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  1CH             *
*                                     *
***************************************
.pp
The disk write protect function provides temporary write
protection for the currently selected disk.  Any attempt
to write to the disk, before the next cold or warm start
operation produces the message
.sp
.ce
Bdos Err on d: R/O
.pp
Use of this function is not recommended while operating under
MP/M because it will deny read/write access to files on the
disk by another user.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 29: GET READ/ONLY VECTOR  *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  1DH             *
*                                     *
*  Returned   Value:                  *
*      Registers HL:  R/O Vector Value*
***************************************
.pp
Function 29 returns a bit vector in register pair HL which
indicates drives which have the temporary read/only bit set.
Similar to function 24, the least significant bit corresponds
to drive A, while the most significant bit corresponds to
drive P.
The R/O
bit is set either by an explicit call to function 28, or
by the automatic software mechanisms within MP/M which
detect changed disks.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 30: SET FILE ATTRIBUTES   *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  1EH             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Directory Code  *
***************************************
.pp
The SET FILE ATTRIBUTES function allows programmatic manipulation
of permanent indicators attached to files.  In particular, the
R/O, System, and Update attributes (t1', t2', and t3') can be set or
reset.  The DE pair addresses an unambiguous file
name with the appropriate attributes set or reset.  Function
30 searches for a match, and changes the matched directory
entry to contain the selected indicators.  Indicators f1'
through f4' are not presently used, but may be useful for
applications programs, since they are not involved in the
matching process during file open and close operations.
Indicators f5' through f8' are reserved for
future system expansion.
.sp 2
.cp 16
.li
***************************************
*                                     *
*  FUNCTION 31: GET ADDR(DISK PARMS)  *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  1FH             *
*                                     *
*  Returned   Value:                  *
*      Registers HL:  DPB Address     *
***************************************
.pp
The address of the BIOS resident disk parameter block is
returned in HL as a result of this function call.  This
address can be used for either of two purposes.  First,
the disk parameter values can be extracted for
display and space computation purposes,
or transient programs can dynamically change the values
of current disk parameters when the disk environment
changes, if required.  Normally, application programs
will not require this facility.
.sp 2
.cp 19
.li
***************************************
*                                     *
*  FUNCTION 32: SET/GET USER CODE     *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  20H             *
*      Register   E:  0FFH (get) or   *
*                     User Code (set) *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Current Code or *
*                     (no value)      *
***************************************
.pp
An application program can change or interrogate
the currently active user
number by calling function 32.  If register E = 0FFH, then
the value of the current user number is returned in register A,
where the value is in the range 0 to 15.  If register E is not
0FFH, then the current user number is changed to the value of
E (modulo 16).
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 33: READ RANDOM           *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  21H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Return Code     *
***************************************
.pp
The READ RANDOM function is similar to the sequential file
read operation of previous releases, except that the read
operation takes place at a particular record number, selected
by the 24-bit value constructed from the three byte field
following the FCB (byte positions r0 at 33, r1 at 34, and
r2 at 35).  Note that the sequence of 24 bits is stored
with least significant byte first (r0), middle byte
next (r1), and high byte last (r2).  MP/M
does not reference byte r2, except in computing the size
of a file (function 35).  Byte r2 must be zero, however,
since a non-zero value indicates overflow past the end
of file.
.pp
Thus, the r0,r1 byte pair is treated
as a double-byte, or "word" value, which contains the
record to read.  This value ranges from 0 to 65535, providing
access to any particular record of the 8 megabyte file.
In order to process a file using random access, the base
extent (extent 0) must first be opened.  Although the base
extent may or may not contain any allocated data, this
ensures that the file is properly recorded in the directory,
and is visible in DIR requests.  The selected record number
is then stored into the random record field (r0,r1), and
the BDOS is called to read the record.  Upon return from
the call, register A either contains an error code, as
listed below, or the value 00 indicating the operation
was successful.  In the latter case, the current DMA
address contains the randomly accessed record.  Note that
contrary to the sequential read operation, the record
number is not advanced.  Thus, subsequent random read
operations continue to read the same record.
.pp
Upon each random read operation, the logical extent and current
record values are automatically set.
Thus, the file can be sequentially read or written, starting from
the current randomly accessed position.  Note, however,
that in this case, the last randomly read record will
be re-read as you switch from random mode to sequential
read, and the last record will be re-written as you
switch to a sequential write operation.
You can, of course, simply advance the random
record position following each random read or write to obtain
the effect of a sequential I/O operation.
.pp
Error codes returned in register A following a random
read are listed below.
.sp
.cp 7
.li
                01  reading unwritten data
                02  (not returned in random mode)
                03  cannot close current extent
                04  seek to unwritten extent
                05  (not returned in read mode)
                06  seek past physical end of disk
.sp
Error code 01 and 04 occur when a random read operation
accesses a data block which has not been previously
written, or an extent which has not been created, which
are equivalent conditions.  Error 3 does not normally
occur under proper system operation, but can be cleared
by simply re-reading, or re-opening extent zero
as long as the disk is not physically write protected.
Error code 06 occurs whenever byte r2 is non-zero under
the current 2.0 release.
Normally, non-zero return codes can be treated as missing
data, with zero return codes indicating operation complete.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 34: WRITE RANDOM          *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  22H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Return Code     *
***************************************
.pp
The WRITE RANDOM operation is initiated similar
to the READ RANDOM call, except that data is written to
the disk from the current DMA address.  Further, if the
disk extent or data block which is the target of the
write has not yet been allocated, the allocation is performed
before the write operation continues.  As in the Read
Random operation, the random record number is not changed
as a result of the write.  The logical extent number
and current record positions of the file control block
are set to correspond to the random record which is
being written.
Again, sequential read or write operations can commence
following a random write, with the notation that the
currently addressed record is either read or rewritten
again as the sequential operation begins.
You can also simply advance the random record position
following each write to get the effect of a sequential
write operation.  Note that in particular, reading or
writing the last record of an extent in random mode
does not cause an automatic extent switch as it does
in sequential mode.
.pp
The error codes returned by a random write are identical
to the random read operation with the addition of error
code 05, which indicates that a new extent cannot be
created due to directory overflow.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 35: COMPUTE FILE SIZE     *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  23H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Random Record Field Set        *
***************************************
.pp
When computing the size of a file, the DE register pair addresses an FCB in random mode
format (bytes r0, r1, and r2 are present).  The FCB contains
an unambiguous file name which is used in the directory
scan.  Upon return, the random record bytes contain the
"virtual" file size which is, in effect, the record
address of the record following the end of the file.
if, following a call to function 35, the high record
byte r2 is 01, then the file contains the maximum record
count 65536.  Otherwise, bytes r0 and r1
constitute a 16-bit value (r0 is the least significant byte,
as before) which is the file size.
.pp
Data can be appended to the end of an existing
file by simply calling function 35 to set the random
record position to the end of file, then performing a
sequence of random writes starting at the preset record
address.
.pp
The virtual size of a file corresponds to the physical
size when the file is written sequentially.  If, instead,
the file was created in random mode and "holes" exist
in the allocation, then the file may in fact contain
fewer records than the size indicates.  If, for example,
only the last record of an eight megabyte file is written
in random mode (i.e., record number 65535), then the
virtual size is 65536 records, although only one
block of data is actually allocated.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 36: SET RANDOM RECORD     *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  24H             *
*      Registers DE:  FCB Address     *
*                                     *
*  Returned   Value:                  *
*      Random Record Field Set        *
***************************************
.pp
The SET RANDOM RECORD function causes
the BDOS to automatically produce the random
record position from a file which has been read or
written sequentially to a particular point.  The function
can be useful in two ways.
.pp
First, it is often necessary to initially read and
scan a sequential file to extract the positions of
various "key" fields.  As each key is encountered, function
36 is called to compute the random record position
for the data corresponding to this key.  If the data
unit size is 128 bytes, the resulting record position
is placed into a table with the key for later retrieval.
After scanning the entire file and tabularizing the
keys and their record numbers, you can move instantly
to a particular keyed record by performing a random
read using the corresponding random record number
which was saved earlier.  The scheme is easily generalized
when variable record lengths are involved since the
program need only store the buffer-relative byte
position along with the key and record number in order
to find the exact starting position of the keyed data
at a later time.
.pp
A second use of function 36 occurs when switching from
a sequential read or write over to random read or
write.  A file is sequentially accessed to a particular
point in the file, function 36 is called which sets
the record number, and subsequent random read and
write operations continue from the selected point in
the file.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 37:  RESET DRIVE          *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  25H             *
*      Register  DE:  Drive Vector    *
*                                     *
*  Returned   Value:                  *
*      Register   A:  Return Code     *
***************************************
.pp
The  RESET  DRIVE  function  allows  resetting  of  specified
drive(s).  The passed parameter is a 16 bit vector of drives to be
reset,  the  least significant bit is drive A:.  If there are  any
open files on a specified drive,  the reset drive is denied and the
reason is displayed on the console.
.pp
The  returned value indicates whether or not the reset  drive
was successful.  If any process is currently accessing a drive  to
be reset,  an error code of 0FFH is returned in the A register.  A
return code of 0 indicates success.                 
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 38:  ACCESS DRIVE         *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  26H             *
*      Register  DE:  Drive Vector    *
*                                     *
***************************************
.pp
The  ACCESS  DRIVE function allows setting the  drive  access
bit(s)  in  the calling processes process descriptor.  The  passed
parameter is a 16 bit vector of drive(s) to be accessed,  the least
significant bit is drive A:.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 39:  FREE DRIVE           *
*                                     *
***************************************
*  Entry Parameters:                  *
*      Register   C:  27H             *
*      Register  DE:  Drive Vector    *
*                                     *
***************************************
.pp
The  FREE  DRIVE  function allows freeing  the  drive  access
bit(s)  in the calling processes process  descriptor.  The  passed
parameter  is  a 16 bit vector of drive(s) to be freed,  the  least
significant bit is drive A:.
.sp 2
.cp 17
.li
***************************************
*                                     *
*  FUNCTION 40:  WRITE RANDOM WITH    *
*                   ZERO FILL         *
***************************************
*  Entry Parameters:                  *
*      Register   C:  28H             *
*      Register  DE:  FCB Address     *
*                                     *
*  Returned Value:                    *
*      Register   A:  Return Code     *
***************************************
.pp
The  WRITE  RANDOM  WITH ZERO FILL operation  is  similar  to
FUNCTION  34: WRITE RANDOM with the exception that a previously unallocated
record is filled with zeroes before the data is written.
