;/*****************************************************************************
;*
;* SOURCE FILE NAME = DEVHLP.ASM
;*
;* DESCRIPTIVE NAME = Device helper interface routines
;*
;* COPYRIGHT    COPYRIGHT IBM CORPORATION, 1991, 1992
;*              LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
;*              REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
;*              RESTRICTED MATERIALS OF IBM
;*              IBM CONFIDENTIAL
;*
;* VERSION      V2.0
;*
;* DATE         09/23/91
;*
;* DESCRIPTION
;*
;* FUNCTIONS    DHVERIFYACCESS, DHGETDOSVAR,     DHBLOCK,
;*              DHRUN,          DHATTACHDD,      DHREGISTERPDD,
;*              DHSEMREQUEST,   DHDEVDONE,       DHDEREGISTER,
;*              DHREGISTER,     DHMONITORCREATE, DHMONITORDESTROY,
;*              DHMONWRITE,     DHMONFLUSH,      DHSEMCLEAR,
;*              DHBEEP,         DHVMFREE,        DHVMALLOC,
;*              DHVIRTTOLIN,    DHINTERNALERROR.
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*****************************************************************************/

        .386p

extrn   _DevHlp_Entry:dword


        .MODEL  LARGE,PASCAL


_DATA           SEGMENT USE16
_DATA           ENDS

FIXED_TEXT      SEGMENT USE16 PARA PUBLIC 'CODE'

        ASSUME  CS:FIXED_TEXT


.xlist

include devhlp.inc

.list


sdword  struc
dlo     dd      ?
dhi     dd      ?
sdword  ends

sword   struc
        wlo     dw      ?
        whi     dw      ?
sword   ends

sseg    struc
        xoff    dw      ?
        xseg    dw      ?
sseg    ends

sbyte   struc
        blo     db      ?
        bhi     db      ?
sbyte   ends


HiEAXtoDX       macro
        shld edx,eax,16                 ; mov hi word eax to dx
        endm

SaveRegs        macro
        push    cx
        push    bx
        push    si
        push    di
        push    es
        push    ds
        endm

RestoreRegs     macro
        pop     ds
        pop     es
        pop     di
        pop     si
        pop     bx
        pop     cx
        endm


;/***************************************************************************
;*
;* FUNCTION NAME = DHVERIFYACCESS
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHVerifyAccess( VOID FAR * pMem, USHORT Len, UCHAR VType)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = Return true if access check failed
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHVERIFYACCESS  PROC FAR pMem:FAR PTR, Len:WORD, VType:WORD

        SaveRegs

        mov     di, [pMem].xoff
        mov     ax, [pMem].xseg
        mov     cx, Len
        mov     dh, [VType].blo
        mov     dl, DevHlp_VerifyAccess
        call    _DevHlp_Entry
        mov     ax, 0                   ; no error, access ok
        jnc     short fin

        inc     ax                      ; error, access failed
fin:

        RestoreRegs
        ret

DHVERIFYACCESS  ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHGETDOSVAR
;*
;* DESCRIPTION   =
;*   VOID FAR * DHENTRY DHGetDOSVar( UCHAR Ord)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = Returns NULL if error
;*
;**************************************************************************/

DHGETDOSVAR     PROC FAR Ord:WORD

        SaveRegs

        mov     al, [Ord].blo
        mov     dl, DevHlp_GetDOSVar
        call    _DevHlp_Entry
        jnc     short fin               ; jif no error

        xor     ax, ax                  ; error, return NULL
        mov     bx, ax
fin:
        mov     dx, ax
        mov     ax, bx

        RestoreRegs
        ret

DHGETDOSVAR     ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHBLOCK
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHBlock( VOID FAR * EventId, ULONG Time, UCHAR fInt)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHBLOCK         PROC FAR EventId:FAR PTR, Time:DWORD, fInt:WORD

        SaveRegs

        mov     bx, [EventId].xoff
        mov     ax, [EventId].xseg
        mov     cx, [Time].wlo
        mov     di, [Time].whi
        mov     dh, [fInt].blo
        mov     dl, DevHlp_ProcBlock
        call    _DevHlp_Entry
        jnc     short fin1              ; jif no error

        jnz     short fin               ; jif interrupted

        mov     ax, -1                  ; timeout

        jmp     short fin

fin1:
        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHBLOCK         ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHRUN
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHRun( VOID FAR * EventId)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHRUN   PROC FAR EventId:FAR PTR

        SaveRegs

        mov     bx, [EventId].xoff
        mov     ax, [EventId].xseg
        mov     dl, DevHlp_ProcRun
        call    _DevHlp_Entry

        ;*
        ;* ax = number of threads awakened
        ;*

        RestoreRegs
        ret

DHRUN           ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHATTACHDD
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHAttachDD( PSZ Name, PIDC pIdc)
;*   Name & pIdc must be in same segment
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHATTACHDD      PROC FAR DDName:FAR PTR, pIdc:FAR PTR

ifdef DEBUG
;*
;*      if( SELECTOROF(Name) != SELECTOROF(pIdc))
;*              panic( __FILE__, __LINE__, "DHAttachDD: segments not same");
;*
endif


        SaveRegs

        mov     ax, ds                  ; Save DGROUP for ...
        mov     es, ax                  ; ... dev hlp call

        lds     bx, DDName              ; offset & segment
        mov     di, [pIdc].xoff         ; offset only
        mov     dl, DevHlp_AttachDD
        call    es:_DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHATTACHDD      ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHREGISTERPDD
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHRegisterPDD( PSZ name, USHORT (FAR PASCAL * func)())
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHREGISTERPDD   PROC FAR DDName:FAR PTR, func:FAR PTR

        SaveRegs

        mov     ax, ds                  ; Save DGROUP for ...
        mov     fs, ax                  ; ... dev hlp call

        lds     si, DDName
        les     di, func
        mov     dl, DevHlp_RegisterPDD

        call    fs:_DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHREGISTERPDD   ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHSEMREQUEST
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHSemRequest( VOID FAR * psem, ULONG time)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHSEMREQUEST    PROC FAR psem:FAR PTR, time:DWORD

        SaveRegs

        mov     bx, [psem].xoff
        mov     ax, [psem].xseg
        mov     cx, [time].wlo
        mov     di, [time].whi
        mov     dl, DevHlp_SemRequest
        call    _DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHSEMREQUEST    ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHDEVDONE
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHDevDone( PREQBLK pReqBlk)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHDEVDONE       PROC FAR pReqBlk:FAR PTR

        SaveRegs

        les     bx, pReqBlk
        mov     dl, DevHlp_DevDone
        call    _DevHlp_Entry

        xor     ax, ax                  ; no error

        RestoreRegs
        ret

DHDEVDONE       ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHDEREGISTER
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHDeRegister( USHORT pid, USHORT handle, PUSHORT pnum)
;*   pnum may be NULL if output not required
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHDEREGISTER    PROC FAR pid:WORD, handle:WORD, pnum:FAR PTR WORD

        SaveRegs

        mov     bx, pid
        mov     ax, handle
        mov     dl, DevHlp_DeRegister
        call    _DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        les     bx, pnum
        mov     cx, es
        or      cx, bx
        jz      short fin1              ; jif o/p ptr null, do not update

        mov     word ptr es:[bx], ax    ; save return value
fin1:
        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHDEREGISTER    ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHREGISTER
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHRegister( BYTE FAR * pIBuf, BYTE FAR * pOBuf,
;*                              USHORT pid, USHORT handle, UCHAR fPlace)
;*   obuff & ibuff must be in the same segment
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHREGISTER      PROC FAR pIBuf:FAR PTR, pOBuf:FAR PTR, pid:WORD, handle:WORD, fPlace:WORD

        SaveRegs

ifdef DEBUG
;*
;*      if( SELECTOROF(pIBuf) != SELECTOROF(pOBuf))
;*              panic( __FILE__, __LINE__, "DHRegister: segments not same");
;*
endif

        les     si, pIBuf               ; offset & segment
        mov     di, [pOBuf].xoff        ; offset only
        mov     cx, pid
        mov     ax, handle
        mov     dh, [fPlace].blo
        mov     dl, DevHlp_Register
        call    _DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHREGISTER      ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHMONITORCREATE
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHMonitorCreate( PMONBUF pBuf, PFVOID pfnNotify,
;*                                   PUSHORT pHandle)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHMONITORCREATE PROC FAR pBuf:FAR PTR, pfnNotify:FAR PTR, pHandle:FAR PTR WORD

        SaveRegs

        mov     ax, ds                  ; Save DGROUP for ...
        mov     fs, ax                  ; ... dev hlp call

        les     si, pBuf
        lds     di, pfnNotify
        mov     ax, 0                   ; create
        mov     dl, DevHlp_MonitorCreate

        call    fs:_DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        les     bx, pHandle             ; ptr should not be null as value needed
        mov     word ptr es:[bx], ax

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHMONITORCREATE ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHMONITORDESTROY
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHMonitorDestroy( USHORT Handle)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHMONITORDESTROY        PROC FAR Handle:WORD

        SaveRegs

        mov     ax, Handle
        mov     dl, DevHlp_MonitorCreate; create with handle != 0
        call    _DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        ;*
        ;* ax == 0 if destroy successful
        ;*
fin:
        RestoreRegs
        ret

DHMONITORDESTROY        ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHMONWRITE
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHMonWrite( PMONREC pRec, USHORT Count,
;*                              USHORT Handle, UCHAR WaitFlag)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHMONWRITE      PROC FAR pRec:FAR PTR, Count:WORD, Handle:WORD, WaitFlag:WORD

        SaveRegs

        mov     ax, ds                  ; Save DGROUP for
        mov     es, ax                  ; for dev hlp call

        lds     si, pRec
        mov     cx, Count
        mov     ax, Handle
        mov     dh, [WaitFlag].blo
        mov     dl, DevHlp_MonWrite
        call    es:_DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHMONWRITE      ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHMONFLUSH
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHMonFlush( USHORT Handle)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHMONFLUSH      PROC FAR Handle:WORD

        ;*
        ;* DS must point to device drivers data segment
        ;*

        SaveRegs

        mov     ax, Handle
        mov     dl, DevHlp_MonFlush
        call    _DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        ;*
        ;* ax == 0 if successful
        ;*
fin:
        RestoreRegs
        ret

DHMONFLUSH      ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHSEMCLEAR
;*
;* DESCRIPTION   =
;*   USHORT DHENTRY DHSemClear( VOID FAR * psem)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHSEMCLEAR      PROC FAR psem:FAR PTR

        SaveRegs

        mov     bx, [psem].xoff
        mov     ax, [psem].xseg
        mov     dl, DevHlp_SemClear
        call    _DevHlp_Entry
        jc      short fin               ; jif error, ax=error code

        xor     ax, ax                  ; no error
fin:
        RestoreRegs
        ret

DHSEMCLEAR      ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHBEEP
;*
;* DESCRIPTION   =
;*   VOID DHENTRY DHBeep( USHORT func, USHORT freq, USHORT durat)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHBEEP          PROC FAR func:WORD, freq:WORD, durat:WORD

        SaveRegs

        mov     ax, func
        mov     bx, freq
        mov     cx, durat
        mov     dl, DevHlp_Beep
        call    _DevHlp_Entry

        RestoreRegs
        ret

DHBEEP          ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHVMFREE
;*
;* DESCRIPTION   =
;*   ULONG DHENTRY DHVMFree( LIN32 linAddr)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHVMFREE        PROC FAR linAddr:DWORD

        SaveRegs                        ; d

        mov     eax, linAddr

        mov     dl, DevHlp_VMFree
        call    _DevHlp_Entry
        jc      short fin               ; jif error, EAX=error code

        xor     eax, eax                ; no error
fin:
        HiEAXtoDX                       ; convert return value

        RestoreRegs                     ; d
        ret

DHVMFREE        ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHVMALLOC
;*
;* DESCRIPTION   =
;*   ULONG DHENTRY DHVMAlloc( ULONG Flags, ULONG MemSize,
;*                            LIN32 pPhysAddr, PMEM pMem)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHVMALLOC       PROC FAR Flags:DWORD, MemSize:DWORD, pPhysAddr:DWORD, pMem:FAR PTR

        SaveRegs                        ; d

        mov     eax, Flags
        mov     ecx, MemSize
        mov     edi, pPhysAddr

        mov     dl, DevHlp_VMAlloc
        call    _DevHlp_Entry
        jc      short fin               ; jif error, EAX=error code


        les     bx, pMem
        mov     es:[bx].dlo, eax        ; Lin
        mov     es:[bx].dhi, ecx        ; Virt

        xor     eax, eax                ; no error
fin:
        HiEAXtoDX                       ; convert return value

        RestoreRegs                     ; d
        ret

DHVMALLOC       ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHVIRTTOLIN
;*
;* DESCRIPTION   =
;*   ULONG DHENTRY DHVirtToLin( VOID FAR * sel_off, PLIN32 pLin)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHVIRTTOLIN     PROC FAR sel_off:FAR PTR, pLin:FAR PTR

        SaveRegs                        ; d

        mov     ax, [sel_off].xoff
        mov     si, [sel_off].xseg

        and     esi, 0000ffffh

        mov     dl, DevHlp_VirtToLin
        call    _DevHlp_Entry
        jc      short fin               ; jif error, EAX=error code

        les     bx, pLin                ; ptr must not be null as value needed
        mov     es:[bx], eax

        xor     eax, eax                ; no error
fin:
        HiEAXtoDX                       ; convert return value

        RestoreRegs                     ; d
        ret

DHVIRTTOLIN     ENDP


;/***************************************************************************
;*
;* FUNCTION NAME = DHINTERNALERROR
;*
;* DESCRIPTION   =
;*   VOID DHENTRY DHInternalError( PSZ msg_txt, USHORT msg_len)
;*
;*
;* INPUT         = NONE
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL =
;*
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

DHINTERNALERROR PROC FAR msg_txt:FAR PTR, msg_len:WORD

        SaveRegs

        mov     ax, ds                  ; Save DGROUP for
        mov     es, ax                  ; for dev hlp call

        lds     si, msg_txt
        mov     di, msg_len
        mov     dl, DevHlp_InternalError
        call    es:_DevHlp_Entry

        RestoreRegs
        ret

DHINTERNALERROR ENDP


FIXED_TEXT      ENDS

        END

;*
;* end
;*
