
;   FILENAME: IDOS.MAC
;
;   Copyright (c) 1988, 1990 by Borland International, Inc.
;
;   DESCRIPTION: This include file contains various macros that may
;   be used to communicate with DOS. This include file uses Ideal mode
;   syntax. For documentation on each of the macros in this file see the
;   file DOSMAC.DOC.
;
;   NOTE: In order to use this macro file you must also include the files:
;   IMACROS.MAC, KBD.INC, and DOS.INC in your module.
;

macro   Terminate10Program
    DosCall <DOS_PROGRAM_TERMINATE>
endm

macro   ReadKBDEcho
    DosCall <DOS_READ_KBD_ECHO>
endm

macro   CharacterOutput Character
    ifb <Character>
        display "Caller must provide Character parameter to CharacterOutput."
        err
    else
        mov     dl, Character
        DosCall <DOS_WRITE_CHARACTER>
    endif
endm

macro   AuxiliaryInput
    DosCall <DOS_AUXILIARY_INPUT>
endm

macro   AuxiliaryOutput Character
    ifb <Character>
        display "Caller must provide Character parameter to AuxiliaryOutput."
        err
    else
        mov     dl, <Character>
        DosCall <DOS_AUXILIARY_OUTPUT>
    endif
endm

macro   PrinterOutput   Character
    ifb <Character>
        display "Caller must provide Character parameter to PrinterOutput."
        err
    else
        mov     dl, <Character>
        DosCall <DOS_PRINTER_OUTPUT>
    endif
endm

macro   ConsoleIO   Value
    ifb <Value>
        display "Caller must provide the Value parameter to ConsoleIO."
        err
    else
        mov     dl, Value
        DosCall <DOS_CONSOLE_IO>
    endif
endm

macro   UnfilteredCharInput
    DosCall <DOS_UNFILTERED_INPUT>
endm

macro   CharInputNoEcho
    DosCall <DOS_CHARACTER_INPUT>
endm

macro   WriteString StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide the string address parameters to WriteString."
        err
    endm

    ifb <StringSeg>
        ErrMsg
    else
        ifb <StringOfs>
            ErrMsg
        else
            ifidni  <StringSeg>, <ds>
                ; Do nothing
            else
                LoadSegment <ds>, <StringSeg>
            endif
            mov     dx, StringOfs
            DosCall DOS_WRITE_STRING
        endif
    endif
endm

macro   BufferedInput   StringSeg, StringOfs
    macro   ErrMsg
        display "Caller must provide the address parameters to BufferedInput."
        err
    endm

    ifb <StringSeg>
        ErrMsg
    else
        ifb <StringOfs>
            ErrMsg
        else
            ifidni  <ds>, <StringSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <StringSeg>
            endif
            mov     dx, StringOfs
            DosCall <DOS_BUFFERED_INPUT>
        endif
    endif
endm

macro   GetInputStatus
    DosCall <DOS_GET_INPUT_STATUS>
endm

macro   ResetInputBuffer    Function, StringSeg, StringOfs
    ifb <Function>
        display "Caller must provide the Function parameter to ResetInputBuffer."
        err
    else
        ifb <StringSeg>
            mov     al, Function
        else
            ifb <StringOfs>
                display "Caller must provide the StringOfs parameter to ResetInputBuffer."
                err
            else
                ifidni  <ds>, <StringSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <StringSeg>
                endif
                mov     dx, StringOfs
            endif
        endif
        DosCall <DOS_RESET_INPUT>
    endif
endm

macro   ResetDisk
    DosCall <DOS_DISK_RESET>
endm

macro   ChangeDrive Drive
    ifb <Drive>
        display "You must provide the Drive parameter to ChangeDrive."
        err
    else
        mov     dl, Drive
        DosCall DOS_CHANGE_DISK_DRIVE
    endif
endm

macro   OpenFCBFile FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to OpenFCBFile."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_OPEN_FCB_FILE>
        endif
    endif
endm

macro   CloseFCBFile    FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to CloseFCBFile."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_CLOSE_FCB_FILE>
        endif
    endif
endm

macro   FindFirstFCB    FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to FindFirstFCB."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_FIND_FIRST_FCB>
        endif
    endif
endm

macro   FindNextFCB    FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to FindNextFCB."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_FIND_NEXT_FCB>
        endif
    endif
endm

macro   DeleteFCBFile    FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to DeleteFCBFile."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_DELETE_FCB_FILE>
        endif
    endif
endm

macro   SequentialFCBRead   FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to SequentialFCBRead."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_SEQUENTIAL_READ>
        endif
    endif
endm

macro   SequentialFCBWrite  FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to SequentialFCBWrite."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_SEQUENTIAL_WRITE>
        endif
    endif
endm

macro   CreateFCBFile   FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to CreateFCBFile."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_CREATE_FCB_FILE>
        endif
    endif
endm

macro   RenameFCBFile   FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to RenameFCBFile."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_RENAME_FCB_FILE>
        endif
    endif
endm

macro   GetDrive
    DosCall <DOS_GET_DISK_DRIVE>
endm

macro   SetDTA  DTASeg, DTAOfs
    macro   ErrMsg
        display "You must provide the DTASeg:DTAOfs parameters to SetDTA."
        err
    endm

    ifb <DTASeg>
        ErrMsg
    else
        ifb <DTAOfs>
            ErrMsg
        else

            ; First check if the parameter is a register. If it is then
            ; push it and pop the value into ds. If not check if it's a
            ; constant or variable and act accordingly.

            ifidni  <ds>, <DTASeg>
                ; Do nothing
            else
                LoadSegment <ds>, <DTASeg>
            endif
            mov     dx, DTAOfs              ; Get offset of DTA
            DosCall DOS_SET_DTA             ; Set new DTA address
        endif
    endif
endm

macro   DefaultDiskAllocation
    DosCall <DOS_DEFAULT_DRIVE_INFO>
endm

macro   DiskAllocation  Drive
    ifb <Drive>
        display "Caller must provide Drive parameter to DiskAllocation."
        err
    else
        mov     dl, Drive
        DosCall <DOS_DRIVE_INFO>
    endif
endm

macro   RandomFCBRead   FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to RandomFCBRead."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_RANDOM_READ>
        endif
    endif
endm

macro   RandomFCBWrite  FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to RandomFCBWrite."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_RANDOM_WRITE>
        endif
    endif
endm

macro   GetFCBFileSize  FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to GetFCBFileSize."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_GET_FILE_SIZE>
        endif
    endif
endm

macro   SetFCBFileRecord    FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide FCB address to SetFCBFileRecord."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifidni  <ds>, <FCBSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <FCBSeg>
            endif
            mov     dx, FCBOfs
            DosCall <DOS_SET_RECORD_NUMBER>
        endif
    endif
endm

macro   SetVector   Vector, VectorSeg, VectorOfs
    macro   ErrMsg
        display "You must provide the Vector, VectorSeg and VectorOfs parameters to SetVector."
        err
    endm

    ifb <Vector>
        ErrMsg
    else
        ifb <VectorSeg>
            ErrMsg
        else
            ifb <VectorOfs>
                ErrMsg
            else
                ifidni  <ds>, <VectorSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <VectorSeg>
                endif
                mov     dx, VectorOfs
                mov     al,Vector        ; Load the number of the vector
                DosCall DOS_SET_VECTOR
            endif
        endif
    endif
endm

macro   CreatePSP   PSPSeg
    ifb <PSPSeg>
        display "Caller must provide PSPSeg parameter to CreatePSP."
        err
    else
        mov     dx, <PSPSeg>
        DosCall <DOS_CREATE_PSP>
    endif
endm

macro   RandomFCBBlockRead  FCBSeg, FCBOfs, Count
    macro   ErrMsg
        display "Caller must provide FCB address to RandomFCBBlockRead."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifb <Count>
                ErrMsg
            else
                ifidni  <ds>, <FCBSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <FCBSeg>
                endif
                mov     dx, FCBOfs
                mov     cx, Count
                DosCall <DOS_RANDOM_BLOCK_READ>
            endif
        endif
    endif
endm

macro   RandomFCBBlockWrite FCBSeg, FCBOfs, Count
    macro   ErrMsg
        display "Caller must provide FCB address to RandomFCBBlockWrite."
        err
    endm

    ifb <FCBSeg>
        ErrMsg
    else
        ifb <FCBOfs>
            ErrMsg
        else
            ifb <Count>
                ErrMsg
            else
                ifidni  <ds>, <FCBSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <FCBSeg>
                endif
                mov     dx, FCBOfs
                mov     cx, Count
                DosCall <DOS_RANDOM_BLOCK_WRITE>
            endif
        endif
    endif
endm

macro   ParseFCBFilename    Flags, FilenameSeg, FilenameOfs, FCBSeg, FCBOfs
    macro   ErrMsg
        display "Caller must provide the Flags and address parameters to ParseFCBFilename."
        err
    endm

    ifb <Flags>
        ErrMsg
    else
        ifb <FilenameSeg>
            ErrMsg
        else
            ifb <FilenameOfs>
                ErrMsg
            else
                ifb <FCBSeg>
                    ErrMsg
                else
                    ifb <FCBOfs>
                        ErrMsg
                    else
                        LoadSegment <es>, <FCBSeg>
                        mov     di, FCBOfs
                        LoadSegment <ds>, <FilenameSeg>
                        mov     si, FilenameOfs
                        mov     al, Flags
                        DosCall <DOS_PARSE_FILENAME>
                    endif
                endif
            endif
        endif
    endif
endm

macro   GetDate
    DosCall <DOS_GET_DATE>
endm

macro   SetDate Year, Month, Day
    macro   ErrMsg
        display "Caller must provide Year, Month and Day parameters to SetDate."
        err
    endm

    ifb <Year>
        ErrMsg
    else
        ifb <Month>
            ErrMsg
        else
            ifb <Day>
                ErrMsg
            else
                mov     cx, Year
                mov     dh, Month
                mov     dl, Day
                DosCall <DOS_SET_DATE>
            endif
        endif
    endif
endm

macro   GetTime
    DosCall <DOS_GET_TIME>
endm

macro   SetTime Hour, Minute, Second, Hundredth
    macro   ErrMsg
        display "Caller must provide Hour, Minute, Second and Hundredth parameters to SetTime."
        err
    endm

    ifb <Hour>
        ErrMsg
    else
        ifb <Minute>
            ErrMsg
        else
            ifb <Second>
                ErrMsg
            else
                ifb <Hundredth>
                    ErrMsg
                else
                    mov     ch, Hour
                    mov     cl, Minute
                    mov     dh, Second
                    mov     dl, Hundredth
                    DosCall <DOS_SET_TIME>
                endif
            endif
        endif
    endif
endm

macro   SetVerifyFlag   Flag
    ifb <Flag>
        display "Caller must provide Flag parameter to SetVerifyFlag."
        err
    else
        xor     dl, dl
        mov     al, Flag
        DosCall <DOS_SET_VERIFY_FLAG>
    endif
endm

macro   GetDTA
    DosCall DOS_GET_DTA
endm

macro   GetDOSVersion
    DosCall DOS_GET_DOS_VERSION
endm

macro   TSR Result, Paragraphs
    macro   ErrMsg
        display "Caller must provide Result and Paragraphs parameters to TSR."
        err
    endm

    ifb <Result>
        ErrMsg
    else
        ifb <Paragraphs>
            ErrMsg
        else
            mov     al, Result
            mov     dx, Paragraphs
            DosCall <DOS_KEEP>
        endif
    endif
endm

macro   GetSetBREAK Mode, Value
    ifb <Mode>
        display "Caller must provide Mode and optionally Value parameters to GetSetBREAK."
        err
    else
        ifnb    <Value>
            mov     dl, Value
        endif
        mov     al, Mode
        DosCall <DOS_GET_SET_CTRL_BREAK>
    endif
endm

macro   GetVector   Interrupt
    ifb <Interrupt>
        display "Caller must provide Interrupt parameter to GetVector."
        err
    else
        mov     al, Interrupt
        DosCall <DOS_GET_VECTOR>
    endif
endm

macro   GetDiskSpace    Disk
    ifb <Disk>
        display "Caller must provide Disk parameter to GetDiskSpace."
        err
    else
        mov     dl, Disk
        DosCall <DOS_GET_DISK_SPACE>
    endif
endm

macro   GetSetCountryInfo   BufferSeg, BufferOfs, ShortCode, LongCode
    macro   ErrMsg
        display "Caller must provide the buffer address and country code parameters"
        display "to GetSetCountryInfo."
        err
    endm

    ifb <BufferSeg>
        ErrMsg
    else
        ifb <BufferOfs>
            ErrMsg
        else
            ifb <ShortCode>
                ErrMsg
            else
                ifnb    <LongCode>
                    mov     bx, LongCode
                endif
                mov     al, ShortCode
                LoadSegment <ds>, <BufferSeg>
                mov     dx, BufferOfs
                DosCall <DOS_GET_SET_COUNTRY>
            endif
        endif
    endif
endm

macro   CreateDir   StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide address parameters to CreateDir."
        err
    endm

    ifb <StringSeg>
        ErrMsg
    else
        ifb <StringOfs>
            ErrMsg
        else
            ifidni  <ds>, <StringSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <StringSeg>
            endif
            mov     dx, StringOfs
            DosCall DOS_MAKE_DIRECTORY
        endif
    endif
endm

macro   RemoveDir   StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide address parameters to RemoveDir."
        err
    endm

    ifb <StringSeg>
        ErrMsg
    else
        ifb <StringOfs>
            ErrMsg
        else
            ifidni  <ds>, <StringSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <StringSeg>
            endif
            mov     dx, StringOfs
            DosCall DOS_DELETE_DIRECTORY
        endif
    endif
endm

macro   ChangeDirectory StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide the segment and offset of the new path to ChangeDirectory."
        err
    endm

    ifb <StringSeg>
        ErrMsg
    else
        ifb <StringOfs>
            ErrMsg
        else
            ifidni  <ds>, <StringSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <StringSeg>
            endif
            mov     dx, StringOfs           ; Store the offset of the
            DosCall DOS_SET_CURRENT_DIR     ; new path
        endif
    endif
endm


macro   CreateFile  Attributes, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide Attributes and address parameters to CreateFile."
        err
    endm

    ifb <Attributes>
        ErrMsg
    else
        ifb <StringSeg>
            ErrMsg
        else
            ifb <StringOfs>
                ErrMsg
            else
                ifidni  <ds>, <StringSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <StringSeg>
                endif
                mov     dx, StringOfs
                mov     cx, Attributes
                DosCall DOS_CREATE_FILE
            endif
        endif
    endif
endm

macro   OpenFile  AccessMode, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide AccessMode and address parameters to OpenFile."
        err
    endm

    ifb <AccessMode>
        ErrMsg
    else
        ifb <StringSeg>
            ErrMsg
        else
            ifb <StringOfs>
                ErrMsg
            else
                ifidni  <ds>, <StringSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <StringSeg>
                endif
                mov     dx, StringOfs
                mov     al, AccessMode
                DosCall DOS_OPEN_FILE
            endif
        endif
    endif
endm

macro   CloseFile   Handle
    ifb <Handle>
        display "You must provide a file handle to CloseFile."
        err
    else
        mov     bx, Handle
        DosCall DOS_CLOSE_FILE
    endif
endm

macro   ReadFile    Handle, Count, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide Handle, Count and address parameters to ReadFile."
        err
    endm

    ifb <Handle>
        ErrMsg
    else
        ifb <Count>
            ErrMsg
        else
            ifb <StringSeg>
                ErrMsg
            else
                ifb <StringOfs>
                    ErrMsg
                else
                    ifidni  <ds>, <StringSeg>
                        ; Do nothing
                    else
                        LoadSegment <ds>, <StringSeg>
                    endif
                    mov     dx, StringOfs
                    mov     cx, Count
                    mov     bx, Handle
                    DosCall DOS_READ_FROM_HANDLE
                endif
            endif
        endif
    endif
endm

macro   WriteFile    Handle, Count, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide Handle, Count and address parameters to WriteFile."
        err
    endm

    ifb <Handle>
        ErrMsg
    else
        ifb <Count>
            ErrMsg
        else
            ifb <StringSeg>
                ErrMsg
            else
                ifb <StringOfs>
                    ErrMsg
                else
                    ifidni  <ds>, <StringSeg>
                        ; Do nothing
                    else
                        LoadSegment <ds>, <StringSeg>
                    endif
                    mov     dx, StringOfs
                    mov     cx, Count
                    mov     bx, Handle
                    DosCall DOS_WRITE_TO_HANDLE
                endif
            endif
        endif
    endif
endm

macro   DeleteFile  StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide address parameters to OpenFile."
        err
    endm

    ifb <StringSeg>
        ErrMsg
    else
        ifb <StringOfs>
            ErrMsg
        else
            ifidni  <ds>, <StringSeg>
                ; Do nothing
            else
                LoadSegment <ds>, <StringSeg>
            endif
            mov     dx, StringOfs
            DosCall DOS_DELETE_FILE
        endif
    endif
endm

macro   MoveFilePtr Mode, Handle, OffsetHigh, OffsetLow
    macro   ErrMsg
        display "You must provide Mode, Handle and offset parameters to MoveFilePtr."
        err
    endm

    ifb <Mode>
        ErrMsg
    else
        ifb <Handle>
            ErrMsg
        else
            ifb <OffsetHigh>
                ErrMsg
            else
                ifb <OffsetLow>
                    ErrMsg
                else
                    mov     al, Mode
                    mov     bx, Handle
                    mov     cx, OffsetHigh
                    mov     dx, OffsetLow
                    DosCall DOS_MOVE_FILE_POINTER
                endif
            endif
        endif
    endif
endm

macro   GetSetAttributes    Mode, Attributes, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide Mode, Attribute and address parameters to GetSetAttributes."
        err
    endm

    ifb <Mode>
        ErrMsg
    else
        ifb <Attributes>
            ErrMsg
        else
            ifb <StringSeg>
                ErrMsg
            else
                ifb <StringOfs>
                    ErrMsg
                else
                    ifidni  <ds>, <StringSeg>
                        ; Do nothing
                    else
                        LoadSegment <ds>, <StringSeg>
                    endif
                    mov     dx, StringOfs
                    mov     al, Mode
                    cmp     al, 1
                    mov     cx, Attributes
                    DosCall DOS_GET_SET_ATTRIBUTES
                endif
            endif
        endif
    endif
endm

macro   IOCTL   Function, HandleDrive, Count, BufSegDevInfo, BufferOfs
    macro   ErrMsg
        display "Caller must provide Function, HandleDrive, Count, BufferSeg,"
        display "BufferOfs and DeviceInfo parameters to IOCTL."
        err
    endm

    ifb <Function>
        ErrMsg
    else
        ifb <HandlDrive>
            ErrMsg
        else
            ifb <Count>
                ErrMsg
            else
                ifnb    <BufferOfs>                   ; Assume that the buffer
                    LoadSegment <ds>, <BufSegDevInfo> ; address parameters are
                    mov     dx, BufferOfs             ; are defined
                else                                  ; Assume that the Device
                    mov     dx, BufSegDevinfo         ; information parameter
                endif                                 ; is defined
                mov     al, Function
                mov     bx, HandleDrive
                mov     cx, Count
                DosCall <DOS_IOCTL>
            endif
        endif
    endif
endm

macro   DuplicateHandle Handle
    ifb <Handle>
        display "Caller must provide Handle parameter to DuplicateHandle."
        err
    else
        mov     bx, Handle
        DosCall <DOS_DUPLICATE_HANDLE>
    endif
endm

macro   ForceDupHandle  OriginalHandle, HandleCopy
    macro   ErrMsg
        display "Caller must provide handle parameters to ForceDupHandle."
        err
    endm

    ifb <Original>
        ErrMsg
    else
        ifb <Copy>
            ErrMsg
        else
            mov     bx, OriginalHandle
            mov     cx, HandleCopy
            DosCall <DOS_FORCE_DUP_HANDLE>
        endif
    endif
endm

macro   GetCurrentDir   Drive, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide Drive and address parameters to GetCurrentDir."
        err
    endm

    ifb <Drive>
        ErrMsg
    else
        ifb <StringSeg>
            ErrMsg
        else
            ifb <StringOfs>
                ErrMsg
            else
                ifidni  <ds>, <StringSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <StringSeg>
                endif
                mov     si, StringOfs
                mov     dl, Drive
                DosCall DOS_GET_DIRECTORY
            endif
        endif
    endif
endm

macro   AllocateMemory  Paragraphs
    ifb <Paragraphs>
        display "You must provide the number of paragraphs to AllocateMemory."
        err
    else
        mov     bx, Paragraphs
        DosCall DOS_ALLOCATE_MEMORY
    endif
endm

macro   FreeMemory  BlockAddress
    ifb <BlockAddress>
        display "You must provide the BlockAddress parameter to FreeMemory."
        err
    else
        LoadSegment <es>, <BlockAddress>
        DosCall DOS_FREE_MEMORY
    endif
endm

macro   ModifyMemory    Size, MemoryBlock
    macro   ErrMsg
        display "You must provide the Size and MemoryBlock parameters to ModifyMemory."
        err
    endm

    ifb <Size>
        ErrMsg
    else
        ifb <MemoryBlock>
            ErrMsg
        else
            ifidni  <es>, <MemoryBlock>
                ; Do nothing
            else
                LoadSegment <es>, <MemoryBlock>
            endif
            mov     bx, Size
            DosCall DOS_MODIFY_MEMORY
        endif
    endif
endm

macro   Exec    Type, ParmSeg, ParmOfs, ProgramSeg, ProgramOfs
    macro   ErrMsg
        display "Caller must provide Type and address parameters to Exec."
        err
    endm

    ifb <Type>
        ErrMsg
    else
        ifb <ParmSeg>
            ErrMsg
        else
            ifb <ParmOfs>
                ErrMsg
            else
                ifb <ProgramSeg>
                    ErrMsg
                else
                    ifb <ProgramOfs>
                        ErrMsg
                    else
                        mov     al, Type
                        LoadSegment <es>, <ParmSeg>
                        mov     bx, ParmOfs
                        LoadSegment <ds>, <ProgramSeg>
                        mov     dx, ProgramOfs
                        DosCall <DOS_EXEC>
                    endif
                endif
            endif
        endif
    endif
endm

macro   TerminateProgram    ErrorLevel
    ifnb    <ErrorLevel>
        mov al, ErrorLevel      ; Return optional errorlevel to DOS
    endif
    DosCall DOS_TERMINATE_EXE
endm

macro   GetReturnCode
    DosCall <DOS_GET_RETURN_CODE>
endm

macro   FindFirst   Attributes, StringSeg, StringOfs
    macro   ErrMsg
        display "You must provide Attributes and address parameters to FindFirst."
        err
    endm

    ifb <Attributes>
        ErrMsg
    else
        ifb <StringSeg>
            ErrMsg
        else
            ifb <StringOfs>
                ErrMsg
            else
                ifidni  <ds>, <StringSeg>
                    ; Do nothing
                else
                    LoadSegment <ds>, <StringSeg>
                endif
                mov     dx, StringOfs
                mov     cx, Attributes
                DosCall DOS_FIND_FIRST
            endif
        endif
    endif
endm

macro   FindNext
    DosCall DOS_FIND_NEXT
endm

macro   GetVerifyFlag
    DosCall <DOS_GET_VERIFY_FLAG>
endm

macro   RenameFile  OrigSeg, OrigOfs, NewSeg, NewOfs
    macro   ErrMsg
        display "Caller must provide address parameters to RenameFile."
        err
    endm

    ifb <OrigSeg>
        ErrMsg
    else
        ifb <OrigOfs>
            ErrMsg
        else
            ifb <NewSeg>
                ErrMsg
            else
                ifb <NewOfs>
                    ErrMsg
                else
                    LoadSegment <es>, <NewSeg>
                    LoadSegment <ds>, <OrigSeg>
                    mov     dx, OrigOfs
                    mov     di, NewOfs
                    DosCall <DOS_RENAME_FILE>
                endif
            endif
        endif
    endif
endm

macro   GetSetFileDateTime  GetSet, Handle, Time, Date
    macro   ErrMsg
        display "Caller must provide GetSet and Handle parameters to GetSetFileDateTime."
        err
    endm

    ifb <GetSet>
        ErrMsg
    else
        ifb <Handle>
            ErrMsg
        else
            ifnb    <Time>
                mov     cx, Time
                ifb <Date>
                    display "You must provide the Date parameter to GetSetFileDateTime."
                    err
                else
                    mov     dx, Date
                endif
                mov     bx, Handle
                mov     al, GetSet
                DosCall <DOS_GET_SET_DATE_TIME>
            endif
        endif
    endif
endm

macro   GetSetAllocationStrategy
    DosCall <DOS_GET_SET_ALLOCATION>
endm
macro   GetExtendedErrors
    xor     bx, bx
    DosCall <DOS_GET_EXTENDED_ERRORS>
endm

macro   CreateTemporaryFile Attribute, FilenameSeg, FilenameOfs
    macro   ErrMsg
        display "Caller must provide Attribute and address parameters to CreateTemporaryFile."
        err
    endm

    ifb <Attribute>
        ErrMsg
    else
        ifb <FilenameSeg>
            ErrMsg
        else
            ifb <FilenameOfs>
                ErrMsg
            else
                LoadSegment <ds>, <FilenameSeg>
                mov     dx, FilenameOfs
                mov     cx, Attribute
                DosCall <DOS_CREATE_TEMP_FILE>
            endif
        endif
    endif
endm

macro   CreateNewFile   Attribute, FilenameSeg, FilenameOfs
    macro   ErrMsg
        display "Caller must provide Attribute and address parameters to CreateNewFile."
        err
    endm

    ifb <Attribute>
        ErrMsg
    else
        ifb <FilenameSeg>
            ErrMsg
        else
            ifb <FilenameOfs>
                ErrMsg
            else
                LoadSegment <ds>, <FilenameSeg>
                mov     dx, FilenameOfs
                mov     cx, Attribute
                DosCall <DOS_CREATE_NEW_FILE>
            endif
        endif
    endif
endm

macro   ControlFileAccess   LockUnlock, Handle, OffsetHigh, OffsetLow, LengthHigh, LengthLow
    macro   ErrMsg
        display "Caller must provide the function, file handle, record position and size"
        display "parameters to ControlFileAccess."
        err
    endm

    ifb <LockUnlock>
        ErrMsg
    else
        ifb <Handle>
            ErrMsg
        else
            ifb <OffsetHigh>
                ErrMsg
            else
                ifb <OffsetLow>
                    ErrMsg
                else
                    ifb <LengthHigh>
                        ErrMsg
                    else
                        ifb <LengthLow>
                            ErrMsg
                        else
                            mov     al, LockUnlock
                            mov     bx, Handle
                            mov     cx, OffsetHigh
                            mov     dx, OffsetLow
                            mov     si, LengthHigh
                            mov     di, LengthLow
                            DosCall <DOS_CONTROL_ACCESS>
                        endif
                    endif
                endif
            endif
        endif
    endif
endm

macro   GetMachineName  BufferSeg, BufferOfs
    macro   ErrMsg
        display "Caller must provide buffer address parameters to GetMachineName."
        err
    endm

    ifb <BufferSeg>
        ErrMsg
    else
        ifb <BufferOfs>
            ErrMsg
        else
            LoadSegment <ds>, <BufferSeg>
            mov     dx, BufferOfs
            xor     al, al
            DosCall <NET_GET_MACHINE_NAME>
        endif
    endif
endm

macro   SetupPrinter    BufferSeg, BufferOfs, ListIndex, StrLength
    macro   ErrMsg
        display "Caller must provide buffer address, Index and length parameters"
        display "to SetupPrinter."
        err
    endm

    ifb <BufferSeg>
        ErrMsg
    else
        ifb <BufferOfs>
            ErrMsg
        else
            ifb <ListIndex>
                ErrMsg
            else
                ifb <StrLength>
                    ErrMsg
                else
                    mov     al, 2
                    mov     bx, ListIndex
                    mov     cx, StrLength
                    LoadSegment <ds>, <BufferSeg>
                    mov     si, BufferOfs
                    DosCall <NET_SET_PRINTER_SETUP>
                endif
            endif
        endif
    endif
endm

macro   GetPrinterSetup BufferSeg, BufferOfs, ListIndex
    macro   ErrMsg
        display "Caller must provide buffer address and Index parameters GetPrinterSetup."
        err
    endm

    ifb <BufferSeg>
        ErrMsg
    else
        ifb <BufferOfs>
            ErrMsg
        else
            ifb <ListIndex>
                ErrMsg
            else
                mov     al, 3
                mov     bx, ListIndex
                LoadSegment <es>, <BufferSeg>
                mov     di, BufferOfs
                DosCall <NET_GET_PRINTER_SETUP>
            endif
        endif
    endif
endm

macro   GetListEntry    ListIndex, DeviceSeg, DeviceOfs, NetworkSeg, NetworkOfs
    macro   ErrMsg
        display "Caller must provide ListIndex and buffer address parameters to GetListEntry."
        err
    endm

    ifb <ListIndex>
        ErrMsg
    else
        ifb <DeviceSeg>
            ErrMsg
        else
            ifb <DeviceOfs>
                ErrMsg
            else
                ifb <NetworkSeg>
                    ErrMsg
                else
                    ifb <NetworkOfs>
                        ErrMsg
                    else
                        mov     al, 2
                        mov     bx, ListIndex
                        LoadSegment <ds>, <DeviceSeg>
                        LoadSegment <es>, <NetworkSeg>
                        mov     si, DeviceOfs
                        mov     di, NetworkOfs
                        DosCall <NET_GET_REDIRECTION_LIST>
                    endif
                endif
            endif
        endif
    endif
endm

macro   GetListEntry    Type, Save, DeviceSeg, DeviceOfs, NetworkSeg, NetworkOfs
    macro   ErrMsg
        display "Caller must provide ListIndex and buffer address parameters to GetListEntry."
        err
    endm

    ifb <Type>
        ErrMsg
    else
        ifb <Save>
            ErrMsg
            ifb <DeviceSeg>
                ErrMsg
            else
                ifb <DeviceOfs>
                    ErrMsg
                else
                    ifb <NetworkSeg>
                        ErrMsg
                    else
                        ifb <NetworkOfs>
                            ErrMsg
                        else
                            mov     al, 3
                            mov     bl, Type
                            mov     cx, Save
                            LoadSegment <ds>, <DeviceSeg>
                            LoadSegment <es>, <NetworkSeg>
                            mov     si, DeviceOfs
                            mov     di, NetworkOfs
                            DosCall <NET_REDIRECT_DEVICE>
                        endif
                    endif
                endif
            endif
        endif
    endif
endm

macro   GetListEntry    DeviceSeg, DeviceOfs
    macro   ErrMsg
        display "Caller must provide ListIndex and buffer address parameters to GetListEntry."
        err
    endm

    ifb <DeviceSeg>
        ErrMsg
    else
        ifb <DeviceOfs>
            ErrMsg
        else
            mov     al, 4
            mov     cx, Save
            LoadSegment <ds>, <DeviceSeg>
            mov     si, DeviceOfs
            DosCall <NET_CANCEL_REDIRECT>
        endif
    endif
endm

macro   GetPSPAddress
    DosCall <DOS_GET_PSP>
endm

macro   LeadByteTable   Function, Console
    ifb <Function>
        display "Caller must provide Function parameter to LeadByteTable."
        err
    else
        ifnb    <Console>
            mov     dl, Console
        else
            mov     al, Function
            DosCall <DOS_GET_LEAD_BYTE_TABLE>
        endif
    endif
endm

