1
             Calling Macros in DOS.INC and BIOS.INC

You are responsible for saving and restoring registers used in
macros. The "Registers used" field identifies registers to save.

Macros that accept address parameters use internal macros that
allow you to specify addresses in several ways. The macro
automatically identifies the type of the argument and handles it
appropriately. For example, assume the following declarations:

  String    DB   "test$"
  pString   DW   Str
  fpString  DD   Str

Given these values, the macro @DispStr (which displays the string
at DS:DX) has the following effects:

  Kind of argument          Example               Value loaded

  Label of byte variable    @DispStr String       DS:OFFSET String
  Near pointer variable     @DispStr pString      DS:pString
  Far pointer variable      @DispStr fpString     fpString[2]:fpString[0]
  Constant                  @DispStr 0            DS:0
  Pointer in register       @DispStr si           DS:SI
  Near Pointer with segment @DispStr pString,es   ES:pString
  Constant with segment     @DispStr 0,es         ES:
  Register with segment     @DispStr di,es        ES:DI

Note that if a far pointer or a segment is given, DS must be
saved before the macro call and restored afterward. Segments may
be given as registers, constants, or word variables.

In syntax, parameters enclosed in brackets are optional.
Paramaters sometimes have a leading symbol to indicate that the
argument must have a certain type, as shown below:

  Leading Symbol   Example      Limitation

        #          #return      Must be constant
        &          &vector      Must be offset address as described above
        $          $terminator  May be constant or register, but not memory

Parameters with no leading symbol may be constants, registers, or
variables. Parameters are 16-bit except where noted in the description.

Symbols must be previously defined before they can be passed as
arguments to most of the DOS macros. Generally this means that
data must be declared before code in the source file.

                  DOS Macro Syntax and Description

KEYBOARD INPUT

@GetKey (01h, 07h, 08h, 0Ch)

Gets a keystroke from the keyboard

Syntax:         @GetKey [#echo] [,[#break] [,#clearbuf]]

Arguments:      echo        = nonzero to echo keystroke - default yes
                break       = nonzero to accept Control-C - default yes
                clearbuf    = nonzero to clear keyboard buffer - default no
                (Arguments may be omitted to get defaults)
Return:         ASCII code of key in AL
Registers used: AX used for all, DL used if echo on and ctrl-c off


@GetStr (0Ah)

Gets a string from the keyboard

Syntax:         @GetStr &buffer [,[$terminator] [,[#limit] [,segment]]]

Arguments:      buffer      = Offset of buffer where string will be stored
                    Byte 1  = Maximum length of string (before call)
                    Byte 2  = Actual length of string (after call)
                    Byte 3+ = Bytes of string
                terminator  = Terminating byte - usually null (0) or $ (24h)
                limit       = Maximum length of string (if not given as
                              argument, must be in buffer before macro call)
                segment     = Segment of buffer (DS if not given)
Return:         Pointer to string in SI, length of string in BX
Registers used: AX, DX, BX, SI

OUTPUT

@DispCh (02h)

Displays one or more characters to screen

Syntax:         @DispCh char [,char]...

Arguments:      char        = 8-bit ASCII code
Return:         Code in AL
Registers used: AX and DL


@PrtCh (05h)

Prints one or more characters to LPT1

Syntax:         @PrtCh char [,char]...

Arguments:      char        = 8-bit ASCII code
Return:         Code in AL
Registers used: AX and DL


@DispStr (09h)

Displays a $-terminated string

Syntax:         @DispStr &address [,segment]

Arguments:      address     = Address of string terminated by "$" (24h)
                segment     = Segment of address string (DS if not given)
Return:         None
Registers used: AX and DS

DEVICE I/O

@Read (3Fh)

Reads data from a file or device

Syntax:         @Read &buffer, length [,[handle] [,segment]]

Arguments:      buffer      = Offset of buffer where data will be stored
                length      = Length of data in bytes
                handle      = File or device handle; if none given,
                              keyboard (handle 0) is assumed
                segment     = Segment of address string (DS if not given)
Return:         If carry clear, bytes read in AX
Registers used: Always AX, DX, BX, and CX; DS if segment changed


@Write (40h)

Writes data to a file or device

Syntax:         @Write &buffer, length, [,[handle] [,segment]]

Arguments:      buffer      = Offset of buffer where data is stored
                length      = Length of data in bytes
                handle      = File or device handle; if none given, screen
                              (handle 1) is assumed
                segment     = Segment of address string (DS if not given)
Return:         If carry clear, bytes written in AX
Registers used: Always AX, DX, BX, and CX; DS if segment changed

FILE CONTROL

@MakeFil (3Ch, 5Ah, 5Bh)

Creates a file

Syntax:         @MakeFil &path [,[attrib] [,[segment] [,#kind]]]

Arguments:      path        = ASCIIZ string of file
                attrib      = File atrribute (0 is default if none given)
                segment     = Segment of address string (DS if not given)
                kind        = If none given, a file is always created even if
                              one already exists. Under DOS 3+ "tmp" can be
                              given to create a unique file or "new" to create
                              file only if one doesn't already exist.
Return:         If carrry clear, file handle in AX
Registers used: Always AX, DX, and CX; DS if segment changed


@OpenFil (3Dh)

Opens a file for input or output

Syntax:         @OpenFil &path, #access [,segment]

Arguments:      path        = ASCIIZ string of file
                access      = File access code
                segment     = Segment of address string (DS if not given)
Return:         If carrry set, error code in AX
Registers used: Always AX and DX; DS if segment changed


@ClosFil (3Eh)

Closes an open file handle

Syntax:         @ClosFil handle

Arguments:      handle      = Previously opened file handle
Return:         If carrry set, error code in AX
Registers used: AX and BX


@DelFil (41h)

Deletes a specified file

Syntax:         @DelFil &path [,segment]

Arguments:      path        = Offset of ASCIIZ filespec
                segment     = Segment of path (DS if none given)
Return:         If carrry set, error code in AX
Registers used: AX and DX; DS if segment changed

@MoveFil (56h)

Moves or renames a file by changing its path specification.

Syntax:         @MoveFil &old, &new [,[segold] [,segnew]]

Arguments:      old         = Offset of file spec to be renamed
                new         = Offset of new file spec
                segold      = Segment of old name (DS if none given)
                segnew      = Segment of new name (ES if none given)
Return:         If carry set, error code in AX
Registers used: AX, DX, and DI; DS and ES if corresponding segments changed


@GetFirst (4Eh) and @GetNext (4Fh)

Parses file specifications (optionally including wild cards) into
file names

Syntax:         @GetFirst &path [,[attribute] [,segment]]
                @GetNext

Arguments:      path        = Offset of ASCIIZ filespec (can have wild cards)
                attribute   = File attribute to search for (0 for normal if
                              none given)
                segment     = Segment of path (DS if none given)
Return:         If carrry set, error code in AX
Registers used: @GetFirst   = AX, CX, and DX; DS if segment changed
                @GetNext    = AX only


@GetDTA (1Ah) and @SetDTA (2Fh)

Gets or sets the Disk Transfer Address (DTA)

Syntax:         @GetDTA
                @SetDTA &buffer [,segment]

Arguments:      buffer      = Offset of new DTA buffer
                segment     = Segment of new DTA buffer (DS if none given)
Return:         @GetDTA     = ES:BX points to DTA
                @SetDTA     = None
Registers used: AX for both; DS and DX for @SetDTA; ES and BX for @GetDTA

@GetFilSz (42h)

Gets the file size by moving the file pointer to end of the file.
Note that the file pointer is reset to zero. Thus this macro should
not be called during operations that move the pointer.

Syntax:         @GetFilSz handle

Arguments:      handle      = Previously opened file handle
Return:         If carrry clear, file length in DX:AX
Registers used: AX, BX, CX, and DX


@MovePrtAbs and @MovePtrRel (42h)

Moves the file pointer in an open file. The pointer can be moved to
an absolute position, or relative to its current position.

Syntax:         @MovePrtAbs handle [,distance]
                @MovePrtRel handle [,distance]

Arguments:      handle      = Previously opened file handle
                distance    = Distance to move pointer - must be a 16-bit
                              constant or a 16- or 32-bit variable; or
                              leave blank and set distance in CX:DX before
                              macro call
Return:         If carrry clear, file pointer position in DX:AX
Registers used: AX, BX, CX, and DX

DIRECTORY CONTROL

@MkDir, (39h), @RmDir (3Ah), and @ChDir (3Bh)

Creates, deletes, or changes to the specified directory

Syntax:         @MkDir &path [,segment]
                @RmDir &path [,segment]
                @ChDir &path [,segment]

Arguments:      path        = Offset of ASCIIZ string to
                segment     = Segment of path (DS if none given)
Return:         If carrry set, error code in AX
Registers used: AX and DX; DS if segment changed


@GetDir (47h)

Returns the current directory of the specified drive

Syntax:         @GetDir &path [,[drive] [,segment]]

Arguments:      buffer      = Offset of buffer to receive ASCIIZ directory
                drive       = 8-bit drive number - 0=current, 1=A, 2=B, etc.
                              (0 if none given)
                segment     = Segment of path (DS if none given)
Return:         If carrry set, error code in AX
Registers used: AX, SI, and DL; DS if segment changes


DRIVE CONTROL

@GetDrv (0Eh) and @SetDrv (19h)

Gets or sets the current drive

Syntax:         @GetDrv
                @SetDrv drive

Argument:       drive       = 8-bit drive number (0=A, 1=B, etc.)
Return:         @GetDrv     = Drive number in AL (0=A, 1=B, etc.)
                @SetDrv     = Number of drives in AL
Registers used: AX for both; DL for @SetDrv


@ChkDrv (36h)

Gets various data about a disk

Syntax:         @ChkDrv [drive]

Argument:       drive       = 8-bit drive number (0=current,A=1, B=2, etc.);
                              if none given, current assumed
Return:         AX          = Sectors per cluster (-1 if drive invalid)
                BX          = Available clusters
                CX          = Bytes per sector
                DX          = Clusters per drive
Registers used: AX, BX, CX, and DX

PROCESS CONTROL

@Exit (4Ch)

Exits to DOS with return code

Syntax:         @Exit [#return]

Argument:       return      = 8-bit code to return to DOS; if none given,
                              AL is used
Return:         None
Registers used: AX


@Exec (4Bh)

Executes a child process or an overlay

Syntax:         @Exec path, params [,[segpath] [,[segparams] [,overlay]]]

Arguments:      path        = Offset of ASCIIZ filespec to be executed
                params      = Offset of process parameter block
                segpath     = Segment of filespec (DS if none given)
                segparams   = Segment of parameter block (ES if none given)
                overlay     = If not defined, normal process executed;
                              if defined, overlay executed
Return:         If carry set, error code
Registers used: AX, SI, and DI; DS and ES if corresponding segments given


@GetRet (4Dh)

Gets the return code of a child process

Syntax:         @GetRet

Argument:       None
Return:         Return code in AX
Register used:  AX


@TSR (31h)

Terminates a program, but leaves it resident in memory

Syntax:         @TSR paragraphs [,#return]

Arguments:      return      = Code to return to DOS; if none, AL used
                paragraphs  = Memory in paragraphs (16 bytes) to
                              allocate for resident program
Return:         None
Registers used: AX and DX

MEMORY CONTROL

@FreeBlok (49h)

Frees a block of memory

Syntax:         @FreeBlok [segment]

Argument:       segment     = Starting address of memory to be freed;
                              if none, ES address assumed
Return:         If carry set, error code in AX
Register used:  AX; ES if segment given


@GetBlok (48h)

Allocates a block of memory

Syntax:         @GetBlok paragraphs

Argument:       paragraphs  = Paragraphs (16 bytes) of memory wanted
Return:         AX and ES   = Segment address of allocated memory
                BX          = Paragraphs actually allocated (may be
                              less than requested if memory is short)
Register used:  AX and BX


@ModBlok (48h)

Modifies an allocated block of memory

Syntax:         @ModBlok paragraphs [,segment]

Argument:       paragraphs  = Paragraphs (16 bytes) of memory wanted
                segment     = Starting address of memory to be freed;
                              if none, ES address assumed
Return:         If carry set, error code in AX, else:
                        ES  = Segment address of allocated memory
                        BX  = If carry is clear, paragraphs allocated
Register used:  AX and BX; ES if segment given

MISCELLANEOUS

@GetDate (2Ah) and @SetDate (2Bh)

Gets or sets the system date

Syntax:         @GetDate
                @SetDate month, day, year

Arguments:      year        = 16-bit year (1980-2099)
                month       = 8-bit month (1-12)
                day         = 8-bit day (1-31)
Return:         For @GetDate:
                        AL  = Day of week (0 = Sunday, 1 = Monday, etc.)
                        CX  = Year (1980-2099)
                        DL  = Month (1-12)
                        DH  = Day (1-31)
                For @SetDate:
                        AL  = If date was valid 0, else -1
Registers used: AX, CX, and DX


@GetTime (2Ch) and @SetTime (2Dh)

Gets or sets the system time

Syntax:         @GetTime
                @SetTime hour,minute,second,hundredth

Arguments:      hour        = 8-bit hour (0-23)
                minute      = 8-bit hour (0-59)
                second      = 8-bit hour (0-59)
                hundredth   = 8-bit hour (0-99)
Return:         For @GetTime:
                        CL  = Hour (0-23)
                        CH  = Minute (0-59)
                        DL  = Second (0-59)
                        DH  = Hundredth (0-99)
                For @SetTime:
                        AL  = If time was valid 0, else -1
Registers used: AX, CX, and DX


@GetVer (30h)

Gets the DOS version

Syntax:         @GetVer

Argument:       None
Return:         AL          = Major version (0 for versions prior to 2.0)
                AH          = Minor version
                BH          = OEM serial number
                BL:CX       = 24-bit user number
Register used:  AX, BX, and CX

@GetInt (35h) and @SetInt (25h)

Gets or sets the vector for a specified interrupt routine

Syntax:         @GetInt #interrupt
                @SetInt #interrupt, &vector [,segment]

Arguments:      interrupt   = 8-bit interrupt number
                vector      = Offset of interrupt routine
                segment     = Segment of routine - if none given, DS assumed
                              for data; segment ignored for code labels
Return:         @GetInt     = None
                @SetInt     = ES:BX points to interrupt routine
Registers used: AX for both; ES and BX for @GetInt; DS and DS for @SetInt

                 BIOS Macro Syntax and Description


MODE, PAGE, AND COLOR CONTROL

@GetMode (I 10h F 0Fh)

Gets the current video mode and page

Syntax:         @GetMode

Arguments:      None
Return:         AL          = Mode
                AH          = Width in characters
                BH          = Page
Registers used: AX and BH


@SetMode (I 10h F 00h)

Gets the current video mode and page

Syntax:         @SetMode mode

Arguments:      mode        = 8-bit video mode
Return:         none
Registers used: AX


@SetColor (I 10h F 0Bh)

Sets the background color

Syntax:         @SetColor color

Arguments:      color       = 8-bit background color (0-15);
                              border color in text modes
Return:         none
Registers used: AX and BX


@SetPalet (I 10h F 0Bh)

Sets the color palette

Syntax:         @SetPalet color

Arguments:      color       = 8-bit color palette (0-1 for modes 5 and 6)
Return:         none
Registers used: AX and BX

@SetPage (I 10h F 05h)

Sets the video page

Syntax:         @SetPage page

Arguments:      page        = 8-bit page number; 0-3 for modes 2 and 3
Return:         none
Registers used: AX


CHARACTER AND CURSOR CONTROL

@GetCur (I 10h F 04h)

Gets the cursor position and size

Syntax:         @GetCur [page]

Arguments:      page        = 8-bit page with cursor (if none, 0 assumed)
Return:         DL          = Column
                DH          = Row
                CL          = Starting scan line
                CH          = Ending scan line
Registers used: AX, DX, CX, and BH


@SetCurPos (I 10h F 02h)

Sets the cursor position

Syntax:         @SetCurSz [column] [,[row] [,page]]

Arguments:      column      = 8-bit column; if none, DL used
                row         = 8-bit row; if none, DH used
                page        = 8-bit page with cursor (if none, 0 assumed)
Return:         none
Registers used: AX, DX, and BH


@SetCurSz (I 10h F 01h)

Sets the cursor size and shape by specifying active scan lines. The
CGA adapter the lines are 0-7. The monochrome adapter has lines 0-13.

Syntax:         @SetCurSz startline, endline

Arguments:      startline   = 8-bit starting scan line (default CGA=6; MA=12)
                endline     = 8-bit ending scan line (default CGA=7; MA=13)
Return:         none
Registers used: AX and CX

@GetChAtr (I 10h F 08h)

Gets the character and attribute at the cursor location

Syntax:         @GetChAtr [page]

Arguments:      page        = 8-bit page to check (if none, 0 assumed)
Return:         AH          = Attribute
                AL          = ASCII character
Registers used: AX and BH


@PutChAtr (I 10h F 09h) and @PutCh (I 10h F 0Ah)

Puts one or more characters and attributes at the current cursor
position. For @PutCh, the current attribute is used in text modes
and any specified attribute is ignored.

Syntax:         @PutChAtr [character] [,[attrib] [,[page] [,count]]]

Arguments:      character   = 8-bit ASCII character to put; if none, AL used
                attrib      = 8-bit attribute to put; if none, BL used
                page        = 8-bit page to put on (if none, 0 assumed)
                count       = Number to put (if none, 1 assumed)
Return:         AH          = Attribute
                AL          = ASCII character
Registers used: AX, BX, CX


@Scroll (I 10h F 06h and 07h)

Scrolls a specified window up or down

Syntax:         @Scroll dist [,[attr] [,[uprow [,[upcol [,[dnrow] [,dncol]]]]]

Arguments:      dist        = 8-bit number of lines to scroll; positive
                              scrolls down; negative scrolls up; 0 clears
                attr        = 8-bit attribute for blank lines (if none, 07h)
                uprow       = Upper left row (if none, CH used)
                upcol       = Upper left column (if none, CL used)
                dnrow       = Lower right row (if none, DH used)
                dncol       = Lower right column (if none, DL used)
Return:         none
Registers used: AX, CX, DX, and BH


@Cls (I 10h F 06, 08h, and 02h)

Clears the screen of the current page

Syntax:         @Cls

Arguments:      None
Return:         None
Registers used: AX, BX, CX, and DX
 1:1