MS-DOS 2.0

                    System Calls Reference












+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
| Certain structures,  constants  and  system  calls  below |
| are   private   to   the   DOS    and    are    extremely |
| version-dependent.  They  may  change  at any time at the |
| implementors' whim.   As  a  result,  they  must  not  be |
| documented to  the  general  public.   If an extreme case |
| arises, they must be documented with this warning.        |
|                                                           |
| Those structures and constants that are  subject  to  the |
| above will be marked and bracketed with the flag:         |
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+


















                          Section 1

            Extensions to existing call structure


    Name:   *   Alloc - allocate memory

    Assembler usage:
            MOV     BX,size
            MOV     AH,Alloc
            INT     21h
        ; AX:0 is pointer to allocated memory
        ; if alloc fails, BX is the largest block available

    Description:
            Alloc returns a pointer to a free block of  memory
        that has the requested size in paragraphs.

    Error return:
        AX = error_not_enough_memory
                The  largest  available  free block is smaller
                than that requested or there is no free block.
           = error_arena_trashed
                The internal consistency of the  memory  arena
                has  been  destroyed.   This  is due to a user
                program changing memory that does  not  belong
                to it.


    Name:   *   CharOper - change  incompatible  configuration
                parameters

    Assembler usage:
            MOV     AH, CharOper
            MOV     AL, func
            MOV     DL, data
            INT     21h
        ; on read functions, data is returned in DL

    Description:
            CharOper   allows   a  program  to  change  system
        parameters to allow for switch indicators and  whether
        devices are  available at every level of the directory
        tree.

            A function code is passed in AL:

        AL  Function
        --  --------
         0  DL,  on  return,  will  contain  the  DOS   switch
            character.   On  most systems this will default to
            '-'.
         1  Set the switch character to the character in DL.
         2  Read the device availability  byte  into  DL.   If
            this  byte  is 0, then devices must be accessed in
            file I/O calls by /dev/device.  If  this  byte  is
            non-zero, then  the devices are available at every
            node of  the  directory  tree  (i.e.  CON  is  the
            console  device  not  the file CON).  This byte is
            generally 0.
         3  Set  the  device availability byte to the value in
            DL.

    Error returns:
        AL = FF
                The function code specified in AL  is  not  in
                the range 0:3


    Name:   *   CurrentDir - return text of current  directory

    Assembler usage:
                MOV     AH,CurrentDir
                LDS     SI,area
                MOV     DL,drive
                INT     21h
            ; DS:SI is a pointer to 64 byte area that contains
            ; drive current directory.

    Description:
            CurrentDir returns the  current  directory  for  a
        particular drive.   The directory is root-relative and
        does not contain the drive specifier.  The drive  code
        passed in DL is 0=default, 1=A, 2=B, etc.

    Error returns:
        AX = error_invalid_drive
                The drive specified in DL was invalid.


    Name:   *   Dealloc - free allocated memory

    Assembler usage:
            MOV     ES,block
            MOV     AH,dealloc
            INT     21h

    Description:
            Dealloc  returns  a  piece of memory to the system
        pool that was allocated by alloc.

    Error return:
        AX = error_invalid_block
                The block passed in ES is  not  one  allocated
                via Alloc.
           = error_arena_trashed
                The internal consistency of the  memory  arena
                has  been  destroyed.   This  is due to a user
                program changing memory that does  not  belong
                to it.


    Name:   *   FileTimes  -  get/set  the  write  times  of a
                handle

    Assembler usage:
            MOV AH, FileTimes
            MOV AL, func
            MOV BX, handle
        ; if AL = 1 then then next two are mandatory
            MOV CX, time
            MOV DX, date
            INT 21h
        ; if AL = 0 then CX/DX has the last write time/date
        ; for the handle.

    Description:
            FileTimes returns or sets the last-write time  for
        a handle.  These times are not recorded until the file
        is closed.

            A function code is passed in AL:

        AL  Function
        --  --------
         0  Return the time/date of the handle in CX/DX
         1  Set the time/date of the handle to CX/DX

    Error returns:
        AX = error_invalid_function
                The function passed in AL was not in the range
                0:1.
           = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.


    Name:   *   FindFirst - find matching file

    Assembler usage:
            MOV AH, FindFirst
            LDS DX, pathname
            MOV CX, attr
            INT 21h
        ; DMA address has datablock

    Description:
            FindFirst takes a pathname with wildcards  in  the
        last component  (passed in DS:DX), a set of attributes
        (passed in CX) and attempts to  find  all  files  that
        match  the  pathname and have a subset of the required
        attributes.  A datablock at the current DMA is written
        that contains information in the following form:

            find_buf    STRUC
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
            find_buf_sattr      DB  ?  ; attribute of search
            find_buf_drive      DB  ?  ; drive of search
            find_buf_name       DB  11 DUP (?); search name
            find_buf_LastEnt    DW  ?  ; LastEnt
            find_buf_ThisDPB    DD  ?  ; This DPB
            find_buf_DirStart   DW  ?  ; DirStart
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

            find_buf_attr       DB  ?  ; attribute found
            find_buf_time       DW  ?  ; time
            find_buf_date       DW  ?  ; date
            find_buf_size_l     DW  ?  ; low(size)
            find_buf_size_h     DW  ?  ; high(size)
            find_buf_pname      DB  13 DUP (?) ; packed name
            find_buf    ENDS

            To obtain  the subsequent matches of the pathname,
        see the description of FindNext

    Error Returns:
        AX = error_file_not_found
                The path specified in  DS:DX  was  an  invalid
                path.
           = error_no_more_files
                There    were    no    files   matching   this
                specification.


    Name:   *   FindNext  -  step through a directory matching
                files

    Assembler usage:
        ; DMA points at area returned by find_first
            MOV AH, findnext
            INT 21h
        ; next entry is at dma

    Description:
            FindNext  finds  the  next  matching  entry  in  a
        directory.  The current DMA address must  point  at  a
        block returned by FindFirst (see FindFirst).

    Error Returns:
        AX = error_no_more_files
                There are no more files matching this pattern.


    Name:   *   GetDMA - get current DMA transfer address

    Assembler usage:
            MOV     AH,GetDMA
            INT     21h
        ; ES:BX has current DMA transfer address

    Description:
            Return DMA transfer address.

    Error returns:
            None.

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |

    Name:   *   GetDSKPT(DL) - get pointer to drive  parameter
                block

    Assembler usage:
            MOV     AH,GetDSKPT
            INT     21h
        ; DS:BX has address of drive parameter block

    Description:
            Return pointer to default drive parameter block.

    Error returns:
            None.

    Assembler usage:
            MOV     DL,DrvNUM
            MOV     AH,GetDSKPTDL
            INT     21h
        ; DS:BX has address of drive parameter block

    Description:
            Return pointer  to drive parameter block for drive
        designated in DL (0=Default, A=1, B=2 ...)

    Error returns:
        AL = FF
                The drive given in DL is invalid.
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+


    Name:   *   GetFreespace - get Disk free space

    Assembler usage:
            MOV     AH,GetFreespace
            MOV     DL,Drive            ;0 = default, A = 1
            INT     21h
        ; BX = Number of free allocation units on drive
        ; DX = Total number of allocation units on drive
        ; CX = Bytes per sector
        ; AX = Sectors per allocation unit

    Description:
            Return  Free  space  on disk along with additional
        information about the disk.

    Error returns:
        AX = FFFF
                The drive number given in DL was invalid.

    NOTE:  This  call returns the same information in the same
        registers (except for the FAT pointer) as the get  FAT
        pointer calls did in previous versions of the DOS.


    Name:   *   GetInDOSF - get DOS critical-section flag

    Assembler usage:
            MOV     AH,GetInDOSF
            INT     21h
        ; ES:BX has location of the flag
            MOV     CritSEG, ES
            MOV     CritOFF, BX
            ...
        IntVec:
            MOV     AX, DWORD PTR Crit
            CMP     AX,0
            JZ      DoFunc
            IRET
        DoFunc: ...

    Description:
            Return location of indos flag.  On return ES:BX is
        the address of a byte memory cell inside the DOS.   If
        used  in  an  interrupt  service routine, it indicates
        whether or not the DOS was interrupted in  a  critical
        section.   If  the cell was zero, then the DOS was not
        in a critical section and thus can be  called  by  the
        interrupt routine.   If the cell was non-zero, the DOS
        should be considered to be in an uninterruptable state
        and for reliability, no DOS calls should be given.

    Error returns:
            None.


    Name:   *   GetVector -  get interrupt vector

    Assembler usage:
            MOV     AH,GetVector
            MOV     AL,interrupt
            INT     21h
        ; ES:BX now has long pointer to interrupt routine

    Description:
            Return  interrupt  vector   associated   with   an
        interrupt.

    Error returns:
            None.


    Name:   *   GetVerifyFlag -  return current setting of the
                verify after write flag.

    Assembler usage:
            MOV     AH,GetVerifyFlag
            INT     21h
        ; AL is the current verify flag value

    Description:
            The current value of the verify flag  is  returned
        in AL.

    Error returns:
            None.


    Name:   *   GetVersion - get DOS version number

    Assembler usage:
            MOV     AH,GetVersion
            INT     21h
        ; AL is the major version number
        ; AH is the minor version number
        ; BH is the OEM number
        ; BL:CX is the (24 bit) user number

    Description:
            Return MS-DOS version  number.   On  return  AL.AH
        will  be  the  two  part version designation, ie.  for
        MS-DOS 1.28 AL would be 1 and AH would be 28.  For pre
        1.28 DOS AL = 0.  Note that version 1.1 is the same as
        1.10, not the same as 1.01.

    Error returns:
            None.


    Name:   *   International  -  return   country   dependent
                information

    Assembler usage:
            LDS     DX, blk
            MOV     AH, International
            MOV     AL, func
            INT     21h

    Description:
            This call returns in the block of  memory  pointed
        to  by  DS:DX,  the following information pertinent to
        international applications:

                +---------------------------+
                | WORD Date/time format     |
                +---------------------------+
                | BYTE ASCIZ string         |
                | currency symbol           |
                +---------------------------+
                | BYTE ASCIZ string         |
                | thousands separator       |
                +---------------------------+
                | BYTE ASCIZ string decimal |
                | separator                 |
                +---------------------------+

            The date/time  format has the following values and
        meanings:

        0 - USA standard    h:m:s m/d/y
        1 - Europe standard h:m:s d/m/y
        2 - Japan standard  y/m/d h:m:s

            The value passed in AL is either  0  (for  current
        country)  or  a  country  code  (to  be defined later.
        Currently the country code must be zero).

    Error returns:
        AX = error_invalid_function
                The   function   passed   in   AL  was  not  0
                (currently).


    Name:   *   KeepProcess -  terminate  process  and  remain
                resident

    Assembler usage:
            MOV     AL, exitcode
            MOV     DX, parasize
            MOV     AH, KeepProcess
            INT     21h

    Description:
            This  call  terminates  the  current  process  and
        attempts  to  set  the  initial  allocation block to a
        specific size in paragraphs.  It will not free up  any
        other  allocation  blocks  belonging  to that process.
        The exit code passed  in  AX  is  retrievable  by  the
        parent via Wait.

    Error Returns:
            None.


    Name:   *   Rename - move a directory entry

    Assembler usage:
            LDS     DX, source
            LES     DI, dest
            MOV     AH, Rename
            INT     21h

    Description:
            Rename will attempt to rename a file into  another
        path.  The paths must be on the same device.

    Error returns:
        AX = error_file_not_found
                The file name specifed by DS:DX was not found.
           = error_not_same_device
                The  source  and  destination are on different
                drives.
           = error_access_denied
                The path specified in DS:DX was a directory or
                the  file  specified  by  ES:DI  exists or the
                destination  directory  entry  could  not   be
                created.


    Name:   *   SetBlock - modify allocated blocks

    Assembler usage:
            MOV     ES,block
            MOV     BX,newsize
            MOV     AH,setblock
            INT     21h
        ; if setblock  fails  for  growing, BX will have the
        ; maximum size possible

    Description:
            Setblock will attempt to grow/shrink an  allocated
        block of memory.

    Error return:
        AX = error_invalid_block
                The block passed in ES is  not  one  allocated
                via Alloc.
           = error_arena_trashed
                The internal consistency of the  memory  arena
                has  been  destroyed.   This  is due to a user
                program changing memory that does  not  belong
                to it.
           = error_not_enough_memory
                There was not enough  free  memory  after  the
                specified block to satisfy the grow request.


    Name:   *   SetCtrlCTrapping  -  turn  on/off   broad   ^C
                checking

    Assembler usage:
            MOV     DL,val
            MOV     AH,SetCtrlCTrapping
            MOV     AL,func
            INT     21h
        ; If AL was 0, then DL has the current value of the
        ; ^C check

    Description:
            MSDOS  ordinarily  checks  for   a   ^C   on   the
        controlling  device  only  when  doing a function 1-12
        operation to that device.  SetCtrlCTrapping allows the
        user  to  expand  this  checking to include any system
        call.  For example, with the ^C trapping off, all disk
        I/O  will  proceed  without interruption while with ^C
        trapping on, the ^C interrupt is given at  the  system
        call that initiates the disk operation.

    Error return:
        AL = FF
                The function passed in AL was not in the range
                0:1.

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |

    Name:   *   Set_OEM_Handler - set handler for OEM
                        specific INT 21H calls.

    Assembler usage:
            LDS     DX,handler_address
            MOV     AH,Set_OEM_Handler
            INT     21H

    Description:
            Set handler address for 0F9H-0FFH INT 21H system
            calls to DS:DX. To return the 0F9H-0FFH calls to
            the uninitialized state, give DS=DX=-1.

    Error returns:
            None.

    Handler entry:
            All registers as user  set  them  when  INT  21H
            issued  (including  SS:SP).  INT 21 return is on
            stack, so the correct method for the OEM handler
            to  return  to the user is to give an IRET.  The
            OEM handler is free to make any INT  21H  system
            call  (including the 0F9H- 0FFH group if the OEM
            handler is re-entrant).


    The  AH  INT  21H  function  codes 0F8H through 0FFH are
    reserved for OEM  extensions  to  the  INT  21H  calling
    convention.   These  calls  have two states, initialized
    and uninitialized.  There will be one handler for all  7
    (0F9-0FFH)   functions.    When   the   DOS   is   first
    initialized, these calls are uninitialized.  The AH=0F8H
    call  is the call which will set the handler address for
    the  0F9-0FFH  calls.   If  the   0F9-0FFH   calls   are
    uninitialized,  an  attempt  to call them results in the
    normal invalid system call number return.
    OEMs should NOT document the 0F8 call.
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+


















                          Section 2

                XENIX-compatible system calls



        Previous  to  version  2.0,  MSDOS had a simple single
    directory structure that sufficed for small (160k to 320K)
    diskettes.   As  the need for hard disk support grows, and
    as MSDOS 2.0 will support a wide variety  of  hard  disks,
    the need  for better disk organization also grows.  Merely
    expanding the directory  is  not  an  effective  solution;
    doing  a  'DIR'  on  a  directory with 1000 files is not a
    user-friendly characteristic.

        People,  by  nature,  think  in  hierarchical   terms:
    organization  charts  and  family  trees, for example.  It
    would be nice to allow users to organize  their  files  on
    disk in a similar manner.  Consider the following:

        In  a  particular  business, both sales and accounting
    share a computer with a  large  disk  and  the  individual
    employees   use   it   for   preparation  of  reports  and
    maintaining accounting information.  One  would  naturally
    view  the  organization  of  files  on  the  disk  in this
    fashion:

                          +-disk-+
                         /        \
                        /          \
                       /            \
                    sales         accounting
                   /    |            |      \
                  /     |            |       \
                 /      |            |        \
            John       Mary         Steve      Sue
           /  | (A)       |         |   |         \
          /   |           |         |   |          \
         /    |           |         |   |           \
      report accts.     report   accts. report      report
             receiv.             receiv

        In MSDOS  2.0 the user can arrange his files in such a
    manner that files that are not part of his current task do
    not  interfere  with that task.  Pre-2.0 versions of MSDOS
    has a single directory that contains files.  MSDOS extends
    this  concept  to  allow a directory to contain both files
    and  directories  and  to  introduce  the  notion  of  the
    'current' directory.

        To  specify  a filename, the user could use one of two
    methods, either specify a path from the root node  to  the
    file, or specify a path from the current node to the file.
    A path is a series of directory names separated by '/' and
    ending  with  a  filename.  A path that starts at the root
    begins with a '/'.

        There is a special directory entry in each  directory,
    denoted by '..'  that is the parent of the directory.  The
    root directory's parent is itself (who created God?).

        Using a directory structure like the hierarchy  above,
    and  assuming  that the current directory is at point (D),
    to reference the report under John, the following are  all
    equivalent:

        report
        /sales/John/report
        ../John/report

        To  refer  to the report under Mary, the following are
    all equivalent:

        ../Mary/report
        /sales/Mary/report

        To  refer  to  the report under Sue, the following are
    all equivalent.

        ../../accounting/Sue/report
        /accounting/Sue/report

        There is no restriction in MSDOS 2.0 on the depth of a
    tree (the length of the longest path from  root  to  leaf)
    except  in  the number of allocation units available.  The
    root directory will have a fixed number of entries, 64 for
    the  single  sided diskettes to XXX for a large hard disk.
    For non-root directories, there is no limit to the  number
    of   files  per  directory  excepting  in  the  number  of
    allocation units available.

        Old (pre-2.0) disks will appear to MSDOS 2.0 as having
    only   a   root   directory   with  files  in  it  and  no
    subdirectories whatever.

        Implementation of the tree-structure is  simple.   The
    root  directory  is the pre-2.0 directory.  Subdirectories
    of the root have a special attribute set  indicating  that
    they  are  directories.  The subdirectories themselves are
    files, linked through the FAT as  usual.   Their  contents
    are  identical  in  character  to the contents of the root
    directory.

        Pre-2.0 programs that use system calls  not  described
    below  will  not  be  able  to  make use of files in other
    directories.  They will only be able to  access  files  in
    the   current   directory.   This  is  no  great  loss  of
    functionality as users will  aggregate  their  files  into
    sub-directories on  basis of functionality; the files that
    are being used will be found  in  the  current  directory.
    Those that  are not necessary for the current task will be
    placed in other directories.  Out of sight, out of mind.

        There are also new attributes in 2.0.  These  and  the
    old attributes apply to the tree structured directories in
    the following manner:

    Attribute   Meaning/Function        Meaning/Function
                    for files            for directories

    volume_id   Present at the root.    Meaningless.
                Only one file may have
                this set.

    directory   Meaningless.            Indicates that the
                                        directory entry is a
                                        directory.  Cannot be
                                        changed with ChMod.

    read_only   Old fcb-create, new     Meaningless.
                Creat, new open (for
                write or read/write)
                will fail.

    archive     Set when file is        Meaningless.
                written. Set/reset via
                ChMod.

    hidden/     Prevents file from      Prevents directory
    system      being found in search   entry from being
                first/search next.      found.  ChDir to
                New open will fail.     directory will still
                                        work.


    Name:   *   ChDir - Change the current directory

    Assembler usage:
            LDS     DX, name
            MOV     AH, ChDir
            INT     21h

    Description:
            ChDir is given the ASCIZ  name  of  the  directory
        which  is  to  become  the  current directory.  If any
        member of the specified pathname does not exist,  then
        the  current  directory  is unchanged.  Otherwise, the
        current directory is set to the string.

    Error returns:
        AX = error_path_not_found
                The path specified in DS:DX either indicated a
                file or the path was invalid.


    Name:   *   ChMod - change write protection

    Assembler usage:
            LDS     DX, name
            MOV     CX, attribute
            MOV     AL, func
            MOV     AH, ChMod
            INT     21h

    Description:
            Given  an  ASCIZ  name,  ChMod  will  set/get  the
        attributes of the file to those given in CX.

            A function code is passed in AL:

        AL  Function
        --  --------
         0  Return the attributes of the file in CX
         1  Set the attributes of the file to those in CX

    Error returns:
        AX = error_path_not_found
                The path specified was invalid.
           = error_access_denied
                The  attributes  specified in CX contained one
                that could not be changed  (directory,  volume
                ID).
           = error_invalid_function
                The function passed in AL was not in the range
                0:1.


    Name:   *   Close - close a file handle

    Assembler usage:
            MOV     BX, handle
            MOV     AH, Close
            INT     21h

    Description:
            In BX is passed a file handle (like that  returned
        by Open,  Creat or Dup); the Close call will close the
        associated file.  Internal buffers are flushed.

    Error return:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.


    Name:   *   Creat - create a file

    Assembler usage:
            LDS     DX, name
            MOV     AH, Creat
            MOV     CX, attribute
            INT     21h
        ; AX now has the handle

    Description:
            Creat creates a new file or truncates an old  file
        to  zero  length  in  preparation for writing.  If the
        file did not exist, then the file is  created  in  the
        appropriate  directory  and  the  file  is  given  the
        read/write protection code of access.

            CX contains the default attributes to be  set  for
        the file.  Currently, the read-only bit must be off.

    Error returns:
        AX = error_access_denied
                The attributes specified in CX  contained  one
                that  could  not be created (directory, volume
                ID),  a  file  already  existed  with  a  more
                inclusive  set  of  attributes, or a directory
                existed with the same name.
           = error_path_not_found
                The path specified was invalid.
           = error_too_many_open_files
                The  file  was  created  with  the   specified
                attributes,  but  there  were  no free handles
                available for the process or that the internal
                system tables were full.


    Name:   *   Dup - duplicate a file handle

    Assembler usage:
            MOV     BX, fh
            MOV     AH, Dup
            INT     21h
        ; AX has the returned handle

    Description:
            Dup  takes  an  already  opened  file  handle  and
        returns  a  new handle that refers to the same file at
        the same position.

    Error returns:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.
           = error_too_many_open_files
                There were no free handles  available  in  the
                current process  or the internal system tables
                were full.


    Name:   *   Dup2 - force a duplicate of a handle

    Assembler usage:
            MOV     BX, fh
            MOV     CX, newfh
            MOV     AH, Dup2
            INT     21h

    Description:
            Dup2 will cause newfh to refer to the same  stream
        as fh.  If there was an open file on newfh, then it is
        closed first.

    Error returns:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.


    Name:   *   Exec - load / execute a program

    Assembler usage:
            LDS     DX, name
            LES     BX, blk
            MOV     AH, Exec
            MOV     AL, func
            INT     21h

    Description:
            This call allows a program to load another program
        into  memory  and  (default)  begin  execution  of it.
        DS:DX points to the ASCIZ  name  of  the  file  to  be
        loaded.   ES:BX  points  to  a parameter block for the
        load.

            A function code is passed in AL:

        AL  Function
        --  --------
         0  Load and execute the program.  A program header is
            established for  the program and the terminate and
            ^C addresses are set to the instruction after  the
            EXEC system call.

            NOTE:   When  control  is  returned,  via  a ^C or
                terminate, from the program being  EXECed  ALL
                registers  are  altered  including  the stack.
                This is because control is returned  from  the
                EXECed  program,  not  the  system.  To regain
                your stack, store an SS:SP  value  in  a  data
                location reachable from your CS.

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
         1  Load,  create  the program header but do not begin
            execution.  The CS:IP/SS:SP  of  the  program  are
            returned in the area provided by the user.
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

         3  Load, do not create the program header, and do not
            begin  execution.   This  is  useful  in   loading
            program overlays.

            For each  value of AL, the block has the following
        format:

            AL = 0 -> load/execute program

                +---------------------------+
                | WORD segment address of   |
                | environment.              |
                +---------------------------+
                | DWORD pointer to command  |
                | line at 80h               |
                +---------------------------+
                | DWORD pointer to default  |
                | FCB to be passed at 5Ch   |
                +---------------------------+
                | DWORD pointer to default  |
                | FCB to be passed at 6Ch   |
                +---------------------------+

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
            AL = 1 -> load program

                +---------------------------+
                | WORD segment address of   |
                | environment.              |
                +---------------------------+
                | DWORD pointer to command  |
                | line at 80h               |
                +---------------------------+
                | DWORD pointer to default  |
                | FCB to be passed at 5Ch   |
                +---------------------------+
                | DWORD pointer to default  |
                | FCB to be passed at 6Ch   |
                +---------------------------+
                | DWORD returned value of   |
                | SS:SP                     |
                +---------------------------+
                | DWORD returned value of   |
                | CS:IP                     |
                +---------------------------+
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

            AL = 3 -> load overlay

                +---------------------------+
                | WORD segment address where|
                | file will be loaded.      |
                +---------------------------+
                | WORD relocation factor to |
                | be applied to the image.  |
                +---------------------------+

            Note  that  all  open  files  of  a  process   are
        duplicated  in  the child process after an Exec.  This
        is extremely powerful; the parent process has  control
        over the meanings of stdin, stdout, stderr, stdaux and
        stdprn.  The parent could, for example, write a series
        of records to a file, open the file as standard input,
        open a listing file as standard output and then Exec a
        sort  program  that  takes  its  input  from stdin and
        writes to stdout.

            Also inherited (or passed from the parent)  is  an
        'environment'.  This  is a block of text strings (less
        than   32K   bytes   total)   that   convey    various
        configurations   parameters.    The   format   of  the
        environment is as follows:

                     (paragraph boundary)
                +---------------------------+
                | BYTE asciz string 1       |
                +---------------------------+
                | BYTE asciz string 2       |
                +---------------------------+
                | ...                       |
                +---------------------------+
                | BYTE asciz string n       |
                +---------------------------+
                | BYTE of zero              |
                +---------------------------+

            Typically the environment strings have the form:

            parameter=value

        for  example,  COMMAND.COM always passes its execution
        search path as:

            PATH=A:/BIN;B:/BASIC/LIB

        A zero value of the environment address will cause the
        child  process  to  inherit  the  parent's environment
        unchanged.

            Note that on a successful return  from  EXEC,  all
        registers, except for CS:IP, are changed.

    Error return:
        AX = error_invalid_function
                The function passed in AL was not 0, 1 or 3.
           = error_bad_environment
                The environment was larger than 32Kb.
           = error_bad_format
                The file pointed to by DS:DX was an EXE format
                file   and   contained  information  that  was
                internally inconsistent.
           = error_not_enough_memory
                There was not enough memory for the process to
                be created.
           = error_file_not_found
                The path specified was invalid or not found.


    Name:   *   Exit - terminate a process

    Assembler usage:
            MOV     AL, code
            MOV     AH, Exit
            INT     21h

    Description:
            Exit   will   terminate   the   current   process,
        transferring  control  to  the  invoking  process.  In
        addition, a return code may be sent.  All  files  open
        at the time are closed.

    Error returns:
            None.


    Name:   *   Ioctl - I/O control for devices

    Assembler usage:
            MOV     BX, Handle

        (or MOV     BL, drive   for calls AL=4,5
                                0=default,A=1...)

            MOV     DX, Data

        (or LDS     DX, buf     and
            MOV     CX, count   for calls AL=2,3,4,5)

            MOV     AH, Ioctl
            MOV     AL, func
            INT     21h
    ; For calls AL=2,3,4,5 AX is the number of bytes
    ; transferred (same as READ and WRITE).
    ; For calls AL=6,7 AL is status returned, AL=0 if
    ; status is not ready, AL=0FFH otherwise.

    Description:
            Set or Get device information associated with open
        Handle,  or  send/receive  control  string  to  device
        Handle or device.

            The following values are allowed for func:

        Request Function
        ------  --------
           0    Get device information (returned in DX)
           1    Set device information (as determined by DX)
           2    Read CX number of bytes into DS:DX from device
                control channel.
           3    Write CX  number of bytes from DS:DX to device
                control channel.
           4    Same   as   2   only   drive   number   in  BL
                0=default,A=1,B=2,...
           5    Same   as   3   only   drive   number   in  BL
                0=default,A=1,B=2,...
           6    Get input status
           7    Get output status

            Ioctl can be used to get information about  device
        channels.   It  is  ok  to make Ioctl calls on regular
        files but only calls 0,6 and 7  are  defined  in  that
        case   (AL=0,6,7),   all   other   calls   return   an
        error_invalid_function error.

    CALLS AL=0 and AL=1

            The bits of DX are defined as  follows  for  calls
        AL=0 and  AL=1.  Note that the upper byte MUST be zero
        on a set call.

                                 |
            15 14 13 12 11 10 9 8|7 6 5 4 3 2 1 0
           +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+
           | R| C|               |I|E|R|S|I|I|I|I|
           | e| T|               |S|O|A|P|S|S|S|S|
           | s| R|    Reserved   |D|F|W|E|C|N|C|C|
           |  | L|               |E| | |C|L|U|O|I|
           |  |  |               |V| | |L|K|L|T|N|
           +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+
                                 |

        ISDEV = 1 if this channel is a device
              = 0 if this channel is a disk file (Bits 8-15  =
                  0 in this case)

        If ISDEV = 1

            EOF = 0 if End Of File on input
            RAW = 1 if this device is in Raw mode
                = 0 if this device is cooked
            ISCLK = 1 if this device is the clock device
            ISNUL = 1 if this device is the null device
            ISCOT = 1 if this device is the console output
            ISCIN = 1 if this device is the console input
            SPECL = 1 if this device is special

            CTRL = 0 if this device can NOT do control strings
                via calls AL=2 and AL=3.
            CTRL =  1  if  this  device  can  process  control
                strings via calls AL=2 and AL=3.
            NOTE that this bit cannot be set.

        If ISDEV = 0
            EOF = 0 if channel has been written
            Bits  0-5  are  the  block  device  number for the
                channel (0 = A, 1 = B, ...)

        Bits 15,8-13,4 are reserved and should not be altered.

    Calls 2..5:
        These four calls allow arbitrary control strings to be
        sent or received from a device.  The  Call  syntax  is
        the same as the READ and WRITE calls, except for 4 and
        5 which take a drive number in BL instead of a  handle
        in BX.

        An  error_invalid_function  error  is  returned if the
        CTRL bit (see above) is 0.

        An error_access_denied is returned by calls AL=4,5  if
        the drive number is invalid.

    Calls 6,7:
        These two calls allow the user  to  check  if  a  file
        handle  is  ready  for  input  or  output.   Status of
        handles open to a device is the intended use of  these
        calls,  but  status of a handle open to a disk file is
        OK and is defined as follows:

            Input:
                Always  ready  (AL=FF) until EOF reached, then
                always  not  ready   (AL=0)   unless   current
                position changed via LSEEK.
            Output:
                Always ready (even if disk full).

        IMPORTANT NOTE:
           The status is defined at the  time  the  system  is
           CALLED.  On future versions, by the time control is
           returned to the user from the  system,  the  status
           returned may NOT correctly reflect the true current
           state of the device or file.

    Error returns:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.
           = error_invalid_function
                The function passed in AL was not in the range
                0:7.
           = error_invalid_data
           = error_access_denied (calls AL=4..7)


    Name:   *   LSeek - move file read/write pointer

    Assembler usage:
            MOV     DX, offsetlow
            MOV     CX, offsethigh
            MOV     AL, method
            MOV     BX, handle
            MOV     AH, LSeek
            INT     21h
        ; DX:AX has the new location of the pointer

    Description:
            LSeek  moves  the  read/write pointer according to
        method:

        Method Function
        ------ --------
           0   The pointer is moved to offset bytes  from  the
               beginning of the file.
           1   The pointer is moved to  the  current  location
               plus offset.
           2   The pointer is moved to the end  of  file  plus
               offset.

            Offset should be regarded as a 32-bit integer with
        CX occupying the most significant 16 bits.

    Error returns:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.
           = error_invalid_function
                The function passed in AL was not in the range
                0:2.


    Name:   *   MkDir - Create a directory entry

    Assembler usage:
            LDS     DX, name
            MOV     AH, MkDir
            INT     21h

    Description:
            Given  a  pointer  to  an ASCIZ name, create a new
        directory entry at the end.

    Error returns:
        AX = error_path_not_found
                The path specified was invalid or not found.
           = error_access_denied
                The directory could not be created (no room in
                parent directory),  the directory/file already
                existed or a device name was specified.


    Name:   *   Open - access a file

    Assembler usage:
            LDS     DX, name
            MOV     AH, Open
            MOV     AL, access
            INT     21h
        ; AX has error or file handle
        ; If successful open

    Description:
            Open associates a 16-bit file handle with a  file.

            The following values are allowed for access:

        ACCESS Function
        ------ --------
           0   file is opened for reading
           1   file is opened for writing
           2   file is opened for both reading and writing.

            DS:DX point to an ASCIZ name of  the  file  to  be
        opened.

            The read/write pointer is set at the first byte of
        the file and the record size of the file  is  1  byte.
        The  returned  file handle must be used for subsequent
        I/O to the file.

            The DOS, on initialization, will  have  a  maximum
        number of  files.  See the configuration file document
        for information on changing this default.

    Error returns:
        AX = error_invalid_access
                The access specified in  AL  was  not  in  the
                range 0:2.
           = error_file_not_found
                The path specified was invalid or not found.
           = error_access_denied
                The  user  attempted  to  open  a directory or
                volume-id,  or  open  a  read-only  file   for
                writing.
           = error_too_many_open_files
                There were no free handles  available  in  the
                current process  or the internal system tables
                were full.


    Name:   *   Read - Do file/device I/O

    Assembler usage:
            LDS     DX, buf
            MOV     CX, count
            MOV     BX, handle
            MOV     AH, Read
            INT     21h
        ; AX has number of bytes read

    Description:
            Read transfers count bytes  from  a  file  into  a
        buffer location.   It is not guaranteed that all count
        bytes will be read;  for  example,  reading  from  the
        keyboard  will  read at most one line of text.  If the
        returned value is zero, then the program has tried  to
        read from the end of file.

            All  I/O  is  done  using  normalized pointers; no
        segment wraparound will occur.

    Error returns:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.
           = error_access_denied
                The handle passed in BX was opened in  a  mode
                that did not allow reading.


    Name:   *   RmDir - Remove a directory entry

    Assembler usage:
            LDS     DX, name
            MOV     AH, RmDir
            INT     21h

    Description:
            RmDir is given an asciz name of a directory.  That
        directory is removed from its parent

    Error returns:
        AX = error_path_not_found
                The path specified was invalid or not found.
           = error_access_denied
                The  path  specified  was  not  empty,  not  a
                directory, the  root  directory  or  contained
                invalid information.
           = error_current_directory
                The  path  specified was the current directory
                on a drive.


    Name:   *   Unlink - delete a directory entry

    Assembler usage:
            LDS     DX, name
            MOV     AH, Unlink
            INT     21h

    Description:
            Unlink removes a directory entry associated with a
        filename.   If  the  file is currently open on another
        handle, then no removal will take place.

    Error returns:
        AX = error_file_not_found
                The path specified was invalid or not found.
           = error_access_denied
                The   path   specified   was  a  directory  or
                read-only.


    Name:   *   Wait - retrieve the return code of a child

    Assembler usage:
            MOV     AH, Wait
            INT 21h
        ; AX has the exit code

    Description:
            Wait  will  return  the  Exit  code specified by a
        child process.  It will return  this  Exit  code  only
        once.   The  low byte of this code is that sent by the
        Exit routine.  The high byte is one of the  following:

            0 - terminate/abort
            1 - ^C
            2 - Hard error
            3 - Terminate and stay resident

    Error returns:
            None.


    Name:   *   Write - write to a file

    Assembler usage:
            LDS     DX, buf
            MOV     CX, count
            MOV     BX, handle
            MOV     AH, Write
            INT     21h
        ; AX has number of bytes written

    Description:
            Write transfers  count  bytes  from  a buffer into
        a file.  It should be regarded  as  an  error  if  the
        number of  bytes written is not the same as the number
        requested.

            It is  important  to  note  that  the write system
        call with a count of  zero  (CX  =  0)  will  truncate
        the file at the current position.

            All I/O  is  done  using  normalized  pointers; no
        segment wraparound will occur.

    Error Returns:
        AX = error_invalid_handle
                The handle passed  in  BX  was  not  currently
                open.
           = error_access_denied
                The handle  was  not  opened  in  a  mode that
                allowed writing.


The following  XENIX  convention  is  followed for the new 2.0
system calls:

    o   If no error occurred, then  the  carry  flag  will  be
        reset and  register  AX  will  contain the appropriate
        information.

    o   If an error occurred, then  the  carry  flag  will  be
        set and  register  AX  will  contain  the  error code.

The following  code  sample illustrates the recommended method
of detecting these errors:

        ...
        MOV     errno,0
        INT     21h
        JNC     continue
        MOV     errno,AX
continue:
        ...

The word variable errno will now have the correct  error  code
for that system call.

The current equates for the error codes are:

no_error_occurred               EQU 0

error_invalid_function          EQU 1
error_file_not_found            EQU 2
error_path_not_found            EQU 3
error_too_many_open_files       EQU 4
error_access_denied             EQU 5
error_invalid_handle            EQU 6
error_arena_trashed             EQU 7
error_not_enough_memory         EQU 8
error_invalid_block             EQU 9
error_bad_environment           EQU 10
error_bad_format                EQU 11
error_invalid_access            EQU 12
error_invalid_data              EQU 13
error_invalid_drive             EQU 15
error_current_directory         EQU 16
error_not_same_device           EQU 17
error_no_more_files             EQU 18


System call assignments:

ABORT                           EQU 0   ;  0      0
STD_CON_INPUT                   EQU 1   ;  1      1
STD_CON_OUTPUT                  EQU 2   ;  2      2
STD_AUX_INPUT                   EQU 3   ;  3      3
STD_AUX_OUTPUT                  EQU 4   ;  4      4
STD_PRINTER_OUTPUT              EQU 5   ;  5      5
RAW_CON_IO                      EQU 6   ;  6      6
RAW_CON_INPUT                   EQU 7   ;  7      7
STD_CON_INPUT_NO_ECHO           EQU 8   ;  8      8
STD_CON_STRING_OUTPUT           EQU 9   ;  9      9
STD_CON_STRING_INPUT            EQU 10  ; 10      A
STD_CON_INPUT_STATUS            EQU 11  ; 11      B
STD_CON_INPUT_FLUSH             EQU 12  ; 12      C
DISK_RESET                      EQU 13  ; 13      D
SET_DEFAULT_DRIVE               EQU 14  ; 14      E
FCB_OPEN                        EQU 15  ; 15      F
FCB_CLOSE                       EQU 16  ; 16     10
DIR_SEARCH_FIRST                EQU 17  ; 17     11
DIR_SEARCH_NEXT                 EQU 18  ; 18     12
FCB_DELETE                      EQU 19  ; 19     13
FCB_SEQ_READ                    EQU 20  ; 20     14
FCB_SEQ_WRITE                   EQU 21  ; 21     15
FCB_CREATE                      EQU 22  ; 22     16
FCB_RENAME                      EQU 23  ; 23     17
GET_DEFAULT_DRIVE               EQU 25  ; 25     19
SET_DMA                         EQU 26  ; 26     1A
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
GET_DEFAULT_DPB                 EQU 31  ; 31     1F
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
FCB_RANDOM_READ                 EQU 33  ; 33     21
FCB_RANDOM_WRITE                EQU 34  ; 34     22
GET_FCB_FILE_LENGTH             EQU 35  ; 35     23
GET_FCB_POSITION                EQU 36  ; 36     24
SET_INTERRUPT_VECTOR            EQU 37  ; 37     25
CREATE_PROCESS_DATA_BLOCK       EQU 38  ; 38     26
FCB_RANDOM_READ_BLOCK           EQU 39  ; 39     27
FCB_RANDOM_WRITE_BLOCK          EQU 40  ; 40     28
PARSE_FILE_DESCRIPTOR           EQU 41  ; 41     29
GET_DATE                        EQU 42  ; 42     2A
SET_DATE                        EQU 43  ; 43     2B
GET_TIME                        EQU 44  ; 44     2C
SET_TIME                        EQU 45  ; 45     2D
SET_VERIFY_ON_WRITE             EQU 46  ; 46     2E
; Extended functionality group
GET_DMA                         EQU 47  ; 47     2F
GET_VERSION                     EQU 48  ; 48     30
KEEP_PROCESS                    EQU 49  ; 49     31
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
GET_DPB                         EQU 50  ; 50     32
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
SET_CTRL_C_TRAPPING             EQU 51  ; 51     33
GET_INDOS_FLAG                  EQU 52  ; 52     34
GET_INTERRUPT_VECTOR            EQU 53  ; 53     35
GET_DRIVE_FREESPACE             EQU 54  ; 54     36
CHAR_OPER                       EQU 55  ; 55     37
INTERNATIONAL                   EQU 56  ; 56     38
; XENIX CALLS
;   Directory Group
MKDIR                           EQU 57  ; 57     39
RMDIR                           EQU 58  ; 58     3A
CHDIR                           EQU 59  ; 59     3B
;   File Group
CREAT                           EQU 60  ; 60     3C
OPEN                            EQU 61  ; 61     3D
CLOSE                           EQU 62  ; 62     3E
READ                            EQU 63  ; 63     3F
WRITE                           EQU 64  ; 64     40
UNLINK                          EQU 65  ; 65     41
LSEEK                           EQU 66  ; 66     42
CHMOD                           EQU 67  ; 67     43
IOCTL                           EQU 68  ; 68     44
XDUP                            EQU 69  ; 69     45
XDUP2                           EQU 70  ; 70     46
CURRENT_DIR                     EQU 71  ; 71     47
;    Memory Group
ALLOC                           EQU 72  ; 72     48
DEALLOC                         EQU 73  ; 73     49
SETBLOCK                        EQU 74  ; 74     4A
;    Process Group
EXEC                            EQU 75  ; 75     4B
EXIT                            EQU 76  ; 76     4C
WAIT                            EQU 77  ; 77     4D
FIND_FIRST                      EQU 78  ; 78     4E
;   Special Group
FIND_NEXT                       EQU 79  ; 79     4F
; SPECIAL SYSTEM GROUP
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
SET_CURRENT_PDB                 EQU 80  ; 80     50
GET_CURRENT_PDB                 EQU 81  ; 81     51
GET_IN_VARS                     EQU 82  ; 82     52
SETDPB                          EQU 83  ; 83     53
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
GET_VERIFY_ON_WRITE             EQU 84  ; 84     54
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
|                                                           |
DUP_PDB                         EQU 85  ; 85     55
|                                                           |
|     C  A  V  E  A  T     P  R  O  G  R  A  M  M  E  R     |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
RENAME                          EQU 86  ; 86     56
FILE_TIMES                      EQU 87  ; 87     57
����������������������������������������