$NOLIST

        NAME  MsCalls

; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
; WARNING! All of the routines in this module
; that call MsDosFileSystem depend on the
; fact that pError, the pointer to the error code
; is located at WORD PTR [BP+4].  If any new
; routines are added that call MsDosFileSystem,
; then make sure that pError is at this same place
; on the stack (The last parm).  See comment there.
;
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


;  This Module provides procedure calls interfaces
;  for MsDos Calls used by InteGRiD.

OS_CGROUP GROUP OS_CODE
OS_DGROUP GROUP OS_DATA


OS_DATA SEGMENT PUBLIC 'DATA'

EXTRN   pDosDiskCall: DWORD
EXTRN   pSetScreenMode: DWORD

OS_DATA ENDS



PUBLIC  MsXnxOpen, MsXnxCreate, MsXnxClose
PUBLIC  MsXnxSeek, MsXnxRead, MsXnxWrite
PUBLIC  MsXnxRename, MsXnxDelete
PUBLIC  MsXnxCreateDir, MsXnxDeleteDir
PUBLIC  MsXnxMatchFirst, MsXnxMatchNext, FcbGetVolumeName
PUBLIC  MsXnxGetFileAttr, MsXnxFileTime
PUBLIC  MsGetDiskFreeSpace, MsRandomNum

PUBLIC  GetServerEntrypoint

PUBLIC  MsGetCurrentDrive, MsSetCurrentDrive
PUBLIC  MsGetCurrentDir, MsSetCurrentDir
PUBLIC  MsCreateProcess

;                    EQUATES

; file system

oldFile    EQU 0                 ; really 1
updateFile EQU 1                 ; really 2
newFile    EQU 2                 ; really 3

seekBegPlus EQU 0
seekCurPlus EQU 1
seekEndPlus EQU 2

; general

FALSE             EQU 0
TRUE              EQU 1
fnCallInt         EQU 21H
videoInt          EQU 10H

; GRiD error codes

eOk               EQU 0
eDevNotReady      EQU 107
$EJECT

OS_CODE SEGMENT PUBLIC 'CODE'
  ASSUME CS:OS_CGROUP


;  MsXnxOpen: PROCEDURE (pPathName, access, pError) WORD CLEAN;
;    DCL access     BYTE;
;    DCL pPathname  PTR;
;    DCL pError     PTR;

pError     EQU DWORD PTR [BP+4]  ; parm 3
access     EQU BYTE  PTR [BP+8]  ; parm 2
pPathname  EQU DWORD PTR [BP+10] ; parm 1

MsXnxOpen PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DX, pPathname           ; ES:DX => pathname
    MOV  AL, access
    MOV  AH, 3DH
    CALL MsDosFileSystem         ; open

    POP  BP                      ; AX = conn
    RET  10
MsXnxOpen ENDP

PURGE pError, access, pPathname
$EJECT

;  MsXnxCreate: PROCEDURE (pPathName, attribute, pError) WORD CLEAN;
;    DCL attribute  WORD;
;    DCL pPathname  PTR;
;    DCL pError     PTR;

pError     EQU DWORD PTR [BP+4]  ; parm 3
attribute  EQU WORD  PTR [BP+8]  ; parm 2
pPathname  EQU DWORD PTR [BP+10] ; parm 1

MsXnxCreate PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DX, pPathname           ; ES:DX => pathname
    MOV  CX, attribute
    MOV  AH, 3CH
    CALL MsDosFileSystem         ; create

    POP  BP                      ; AX = conn
    RET  10
MsXnxCreate ENDP

PURGE pError, attribute, pPathname
$EJECT

;  MsXnxRead: PROCEDURE (conn, pBuffer, count, pError) WORD CLEAN;
;    DCL conn       WORD;
;    DCL count      WORD;
;    DCL pBuffer    PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]   ; parm 4
count     EQU WORD  PTR [BP+8]   ; parm 3
pBuffer   EQU DWORD PTR [BP+10]  ; parm 2
conn      EQU WORD  PTR [BP+14]  ; parm 1

MsXnxRead PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  BX, conn
    MOV  CX, count
    LES  DX, pBuffer
    MOV  AH, 3FH
    CALL MsDosFileSystem

    POP  BP                      ; AX = # bytes read
    RET  12
MsXnxRead ENDP

PURGE pError, count, pBuffer, conn
$EJECT

;  MsXnxWrite: PROCEDURE (conn, pBuffer, count, pError) WORD CLEAN;
;    DCL conn       WORD;
;    DCL count      WORD;
;    DCL pBuffer    PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]   ; parm 4
count     EQU WORD  PTR [BP+8]   ; parm 3
pBuffer   EQU DWORD PTR [BP+10]  ; parm 2
conn      EQU WORD  PTR [BP+14]  ; parm 1

MsXnxWrite PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  BX, conn
    MOV  CX, count
    LES  DX, pBuffer
    MOV  AH, 40H
    CALL MsDosFileSystem

    POP  BP                      ; Returns AX = # bytes written
    RET  12
MsXnxWrite ENDP

PURGE pError, count, pBuffer, conn
$EJECT

;  MsXnxSeek: PROCEDURE (conn, mode, count, pError) DWORD CLEAN;
;    DCL mode       BYTE;
;    DCL conn       WORD;
;    DCL count      DWORD;
;    DCL pError     PTR;

pError      EQU DWORD PTR [BP+4]  ; parm 4
count       EQU DWORD PTR [BP+8]  ; parm 3
mode        EQU BYTE  PTR [BP+12] ; parm 2
conn        EQU WORD  PTR [BP+14] ; parm 1

MsXnxSeek PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DX, count
    MOV  CX, ES                  ; CX:DX => count
    MOV  BX, conn                ; BX = conn
    MOV  AL, mode                ; AL = mode
    MOV  AH, 42H
    CALL MsDosFileSystem

    POP  BP                      ; DX:AX => new file position
    RET  12
MsXnxSeek ENDP

PURGE pError, count, mode, conn
$EJECT

;  MsXnxRename: PROCEDURE (pOldName, pNewName, pError) CLEAN;
;    DCL pOldName   PTR;
;    DCL pNewName   PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]   ; parm 3
pNewName  EQU DWORD PTR [BP+8]   ; parm 2
pOldName  EQU DWORD PTR [BP+12]  ; parm 1

MsXnxRename PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DI, pNewName
    MOV  SI, ES                  ; SI:DI => new name
    LES  DX, pOldName            ; ES:DX => old name
    MOV  AH, 56H
    CALL MsDosFileSystem

    POP  BP
    RET  12
MsXnxRename ENDP

PURGE pError, pNewName, pOldName
$EJECT

;  MsXnxDelete: PROCEDURE (pPathname, pError) CLEAN;
;    DCL pPathname  PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]   ; parm 2
pPathName EQU DWORD PTR [BP+8]   ; parm 1

MsXnxDelete PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DX, pPathname
    MOV  AH, 41H
    CALL MsDosFileSystem

    POP  BP
    RET  8
MsXnxDelete ENDP

PURGE pError, pPathname
$EJECT

;  MsXnxClose: PROCEDURE (conn, pError) CLEAN;
;    DCL conn       WORD;
;    DCL pError     PTR;

pError EQU DWORD PTR [BP+4]      ; parm 2
conn   EQU WORD  PTR [BP+8]      ; parm 1

MsXnxClose PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  BX, conn
    MOV  AH, 3EH
    CALL MsDosFileSystem

    POP  BP
    RET  6
MsXnxClose ENDP

PURGE pError, conn
$EJECT

;  MsXnxCreateDir: PROCEDURE (pDirName, pError) CLEAN;
;    DCL pDirName   PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]      ; parm 2
pDirName  EQU DWORD PTR [BP+8]      ; parm 1

MsXnxCreateDir PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DX, pDirName
    MOV  AH, 39H
    CALL MsDosFileSystem

    POP  BP
    RET  8
MsXnxCreateDir ENDP

PURGE pError, pDirName
$EJECT

;  MsXnxDeleteDir: PROCEDURE (pDirName, pError) CLEAN;
;    DCL pDirName   PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]      ; parm 2
pDirName  EQU DWORD PTR [BP+8]      ; parm 1

MsXnxDeleteDir PROC NEAR
    PUSH BP
    MOV  BP, SP

    LES  DX, pDirName
    MOV  AH, 3AH
    CALL MsDosFileSystem

    POP  BP
    RET  8
MsXnxDeleteDir ENDP

PURGE pError, pDirName
$EJECT

;  MsXnxMatchFirst: PROCEDURE (attr, pPathname, pMatchBlk, pError) WORD CLEAN;
;    DCL attr       WORD;
;    DCL pPathName  PTR;
;    DCL pMatchBlk  PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]      ; parm 4
pMatchBlk EQU DWORD PTR [BP+8]      ; parm 3
pPathName EQU DWORD PTR [BP+12]     ; parm 2
attr      EQU WORD  PTR [BP+16]     ; parm 1

MsXnxMatchFirst PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  BX, 1                   ; Number found = 1

    MOV  CX, attr
    LES  DX, pPathName
    MOV  AH, 4EH
    CALL GetDTAParms             ; SI:DI set to pMatchBlk
    CALL MsDosFileSystem
    JNC  MsXnxMatchFirstExit

    DEC  BX                      ; Number found = 0

MsXnxMatchFirstExit:
    XCHG AX, BX                  ; RETURN (numRead)
    POP  BP
    RET  14
MsXnxMatchFirst ENDP

PURGE pError, pMatchBlk, pPathname, attr
$EJECT

;  MsXnxMatchNext: PROCEDURE (pMatchBlk, pError) WORD CLEAN;
;    DCL pError     PTR;
;    DCL pMatchBlk  PTR;

pError    EQU DWORD PTR [BP+4]      ; parm 2
pMatchBlk EQU DWORD PTR [BP+8]      ; parm 1

MsXnxMatchNext PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  BX, 1                   ; Number found = 1

    MOV  AH, 4FH
    CALL GetDTAParms             ; SI:DI set to pMatchBlk
    CALL MsDosFileSystem
    JNC  MsXnxMatchNextExit

    DEC  BX                      ; Number found = 0

MsXnxMatchNextExit:
    XCHG AX, BX                  ; RETURN (numRead)
    POP  BP
    RET  8
MsXnxMatchNext ENDP

PURGE pError, pMatchBlk
$EJECT

;  FcbGetVolumeName: PROCEDURE (pSearchBuf, pError) WORD CLEAN;
;    DCL pSearchBuf PTR;
;    DCL pError     PTR;

pError     EQU DWORD PTR [BP+4]  ; parm 2
pSearchBuf EQU DWORD PTR [BP+8]  ; parm 1

FcbGetVolumeName PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  AH, 0DH
    INT  fnCallInt               ; Send reset to devices

    MOV  BX, 1                   ; Number found = 1

    MOV  AH, 11H
    LES  DX, pSearchBuf          ; ES:DX set to pSearchBuf for Fcb buffer
    CALL GetDTAParms             ; SI:DI set to pSearchBuf for DTA results
    CALL MsDosFileSystem         ; Fcb search first
    JC   FcbGetVolNameNone       ; return if error (w/number found = 0)

    OR   AL, AL                  ; If return value is zero
    JZ   FcbGetVolNameExit       ; then exit (w/number found = 1)

FcbGetVolNameNone:
    DEC  BX                      ; Number found = 0

FcbGetVolNameExit:
    XCHG AX, BX                  ; RETURN (numRead)
    POP  BP
    RET  8
FcbGetVolumeName ENDP

PURGE pError, pSearchBuf



; GetDiskTransferAddressParms

;  This routine gets the disk transfer address (DTA) into ES:DI (passed SI:DI)
;  In the call DosDiskCallGRiDError it is used to set the disk
;  transfer address for XnxMatchFirst, XnxMatchNext & FcbGetVolumeName.

;  NOTE: This routine depends on the fact that the disk transfer address
;  is passed on the stack in the same place from these calls (BP+8).

;  Returns SI:DI pointing to DTA

pDTA EQU DWORD PTR [BP+8]

GetDTAParms PROC NEAR
    PUSH ES
    LES  DI, pDTA
    MOV  SI, ES
    POP  ES
    RET
GetDTAParms ENDP

PURGE pDTA
$EJECT

;  MsXnxGetFileAttr: PROCEDURE (pPathname, pError) WORD CLEAN;
;    DCL pPathname  PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]      ; parm 2
pPathname EQU DWORD PTR [BP+8]      ; parm 1

MsXnxGetFileAttr PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  AL, 0                   ; Return the attribute
    LES  DX, pPathname

    MOV  AH, 43H
    CALL MsDosFileSystem

    MOV  AX, CX                  ; attributes
    POP  BP
    RET  8
MsXnxGetFileAttr ENDP

PURGE pError, pPathname
$EJECT

;  MsXnxFileTime: PROCEDURE (conn, mode, pTimeDate, pError) CLEAN;
;    DCL conn       WORD;
;    DCL mode       BYTE;
;    DCL pTimeDate  PTR;
;    DCL pError     PTR;

pError    EQU DWORD PTR [BP+4]      ; parm 3
pTimeDate EQU DWORD PTR [BP+8]      ; parm 2
mode      EQU BYTE  PTR [BP+12]     ; parm 1
conn      EQU WORD  PTR [BP+14]

MsXnxFileTime PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  AL, mode
    MOV  BX, conn

    CMP  AL, 0                   ; if mode is get date/time
    JE   MsXnxFileTimeCallHere   ; then don't pass in any values

    LES  DI, pTimeDate
    MOV  CX, ES:[DI+0]           ; get time to be set
    MOV  DX, ES:[DI+2]           ; get date to be set

MsXnxFileTimeCallHere:
    MOV  AH, 57H
    CALL MsDosFileSystem
    JC   MsXnxFileTimeExit

    CMP  mode, 1                 ; if mode was set time then
    JE   MsXnxFileTimeExit       ; all done

    LES  DI, pTimeDate
    MOV  ES:[DI+0], CX           ; return time
    MOV  ES:[DI+2], DX           ; return date

MsXnxFileTimeExit:
    POP  BP
    RET  12
MsXnxFileTime ENDP

PURGE pError, pTimeDate, conn, mode
$EJECT

;  MsGetDiskFreeSpace: PROCEDURE (drive, pInfo, pError) CLEAN;
;    DCL drive      BYTE;
;    DCL pInfo      PTR;
;    DCL pError     PTR;

pError  EQU DWORD PTR [BP+4]     ; parm 3
pInfo   EQU DWORD PTR [BP+8]     ; parm 2
drive   EQU BYTE  PTR [BP+12]    ; parm 1

MsGetDiskFreeSpace PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  DL, drive
    MOV  AH, 36H
    INT  fnCallInt

    PUSH DS

    LDS  DI, pError
    MOV  WORD PTR DS:[DI], eDevNotReady
    CMP  AX, 0FFFFH
    JE   MsGetDiskFreeSpaceRet

    MOV  WORD PTR DS:[DI], eOK
    LDS  DI, pInfo
    MOV  [DI+0], BX
    MOV  [DI+2], DX
    MOV  [DI+4], CX
    MOV  [DI+6], AX

MsGetDiskFreeSpaceRet:
    POP  DS

    POP  BP
    RET  10
MsGetDiskFreeSpace ENDP

PURGE pError, pInfo, drive
$EJECT

;  MsRandomNum: PROCEDURE BYTE CLEAN;

MsRandomNum PROC NEAR
    MOV  AH, 2CH                 ; Get current time
    INT  fnCallInt

    MOV  AL, DH                  ; Use total of number of
    ADD  AL, DL                  ; seconds + hundredths
                                 ; for the random number
    RET
MsRandomNum ENDP
$EJECT

;  GetServerEntrypoint: PROCEDURE (pSignature, pError) PTR CLEAN;
;    DCL pSignature   PTR;
;    DCL pError       PTR;

pError     EQU DWORD PTR [BP+4]  ; parm 2
pSignature EQU DWORD PTR [BP+8]  ; parm 1

GetServerEntrypoint PROC NEAR
    PUSH BP
    MOV  BP, SP

    PUSH DS

    LES  BX, pSignature
    LDS  DI, pError
    PUSH DS
    PUSH DI                      ; save @error

    MOV  CX, BX                  ; pSignature is
    MOV  BX, ES                  ; passed in BX:CX
    XOR  AX, AX
    MOV  DX, AX                  ; Registers
    MOV  DI, AX                  ; DX, DI, SI, BP
    MOV  SI, AX                  ; must be zero
    MOV  BP, AX
    DEC  AX
    MOV  DS, AX                  ; DS & ES must be
    MOV  ES, AX                  ; NULLWORD

    MOV  AX, 0C98H               ; Use flush kbd
    INT  fnCallInt               ; fnc w/ 98H

    INC  AX                      ; Upon return
    JNZ  GetEntryErrorExit       ; AX = NULLWORD

    MOV  AX, DS                  ; And DS must
    OR   AX, AX                  ; be zero
    JNZ  GetEntryErrorExit

    INC  DX
    INC  DI
    INC  SI
    INC  BP

    MOV  AX, ES                  ; And ES must
    OR   AX, DX                  ; be zero; plus
    OR   AX, DI                  ; registers DX,
    OR   AX, SI                  ; DI, SI and BP
    OR   AX, BP                  ; must be NULLWORD
    JNZ  GetEntryErrorExit       ; for valid return

    MOV  ES, BX                  ; @ entrypoint is
    MOV  BX, CX                  ; in BX:CX
    JMP  SHORT GetEntrypointExit

GetEntryErrorExit:
    MOV  AX, 0FFFFH
    MOV  ES, AX
    MOV  BX, 0FH                 ; RETURN (NULLPTR)

GetEntrypointExit:
    POP  DI
    POP  DS                      ; @error
    MOV  DS:[DI], AX

    POP  DS

    POP  BP
    RET  8
GetServerEntrypoint ENDP

PURGE pError, pSignature
$EJECT

;  MsGetCurrentDrive: PROCEDURE BYTE CLEAN;

MsGetCurrentDrive PROC NEAR
    MOV  AH, 19H
    INT  fnCallInt  ; Get current disk into AL
    RET
MsGetCurrentDrive ENDP


;  MsSetCurrentDrive: PROCEDURE (drive) CLEAN;

drive    EQU  BYTE PTR [BP+4]    ; parm 1

MsSetCurrentDrive PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  DL, drive
    MOV  AH, 0EH
    INT  fnCallInt               ; Set current drive

    POP  BP
    RET  2
MsSetCurrentDrive ENDP

PURGE drive
$EJECT

;  MsGetCurrentDir: PROCEDURE (pDir) CLEAN;
;    DCL pDir   PTR

pDir    EQU DWORD PTR [BP+4]     ; parm 1

MsGetCurrentDir PROC NEAR
    PUSH BP
    MOV  BP, SP

    PUSH DS
    LDS  SI, pDir
    MOV  WORD PTR DS:[SI], 5C00H ; Preset length to 0, First char to \
    INC  SI
    INC  SI
    MOV  DL, 0                   ; Default drive
    MOV  AH, 47H
    INT  fnCallInt               ; Return text of current directory
    POP  DS

    POP  BP
    RET  4
MsGetCurrentDir ENDP

PURGE pDir
$EJECT

;  MsSetCurrentDir: PROCEDURE (pDir) CLEAN;
;    DCL pDir   PTR

pDir    EQU DWORD PTR [BP+4]     ; parm 1

MsSetCurrentDir PROC NEAR
    PUSH BP
    MOV  BP, SP

    PUSH DS
    LDS  DX, pDir
    INC  DX                      ; Skip the length byte
    MOV  AH, 3BH
    INT  fnCallInt               ; Set current directory
    POP  DS

    POP  BP
    RET  4
MsSetCurrentDir ENDP

PURGE pDir
$EJECT

;  MsCreateProcess: PROCEDURE (exitPrompt, pPath, pParmBlock, pError) CLEAN;
;    DCL exitPrompt  BOOLEAN
;    DCL pPath       PTR
;    DCL pParmBlock  PTR
;    DCL pError      PTR

pError       EQU DWORD PTR [BP+4]      ; parm 4
pParmBlock   EQU DWORD PTR [BP+8]      ; parm 3
pPathname    EQU DWORD PTR [BP+12]     ; parm 2
exitPrompt   EQU BYTE  PTR [BP+16]     ; parm 1


MsCreateProcess PROC NEAR
    PUSH BP
    MOV  BP, SP

    MOV  AX, 2                   ; Set the display to 80 x 25 BW alpha mode
    INT  videoInt

    LES  BX, pParmBlock
    MOV  SI, ES                  ; SI:BX => parmblock
    LES  DX, pPathname           ; ES:DX => pathname
    MOV  AH, 4BH                 ; Only load & go is supported (AL=0)
    MOV  AL, exitPrompt          ; AL is used for 'Type EXIT to return' msg
    CALL MsDosFileSystem

    CALL DWORD PTR DS:pSetScreenMode

MsCreateProcessRet:
    POP  BP
    RET  12
MsCreateProcess ENDP

PURGE pError, pParmBlock, pPathname, exitPrompt
$EJECT

; MsDosFileSystem

; This routine should only be called for MsDos Xenix
; file system calls, the load & go call and fcb search 1st.
; Non-file system calls such as get current time
; can use INT fnCallInt directly.

; This routine calls DosDiskCallGRiDError, a routine
; that is in RAM (Versus ROM)that checks for
; interrupt24 error situations and other errors.
; Errorcode will be set to either eOK or the error.
; The carry flag will be set upon return if there
; was an error otherwise it will be cleared.
; Sometimes an error of eOK will be returned, but
; the carry flag should still indicate if there was
; an error.

; If an MsDos call expects something in DS, pass it to here in ES
; If an MsDos call expects something in ES, pass it to here in SI

; Entry
;  AH = Call number, other registers set dependant on call
;  DS must point to DGROUP (DATA)
;  ES is masquerading as DS
;  SI is masquerading as ES
;  SS:BP+4 => Word location to store error code

; Exit
;  Carry set => error
;  Carry Reset => no error
;  ES:DI => error code
;  AX is changed to error only if there was an error

pErrorCode EQU DWORD PTR [BP+4]  ; Callers pError

MsDosFileSystem PROC NEAR
    CALL DWORD PTR DS:pDosDiskCall

    LES  DI, pErrorCode
    MOV  WORD PTR ES:[DI], eOK
    JNC  MsDosFileSystemExit

    MOV  ES:[DI], AX

MsDosFileSystemExit:
    RET
MsDosFileSystem ENDP

PURGE pErrorCode


OS_CODE    ENDS

        END
