;       SCCSID = @(#)dospmsem.asm 6.3 91/09/13
PAGE    ,132
TITLE   SEM - Ring 3 Library interface to 16 BIT PM Semaphores
NAME    SEM
.286p

;***    DOSPMSEM.ASM
;
;       Title:
;
;               CP/DOS Ring 3 Library interface to 16 PM Semaphores
;               Copyright IBM Corporation, 1994
;               2/15/94
;
;       Description:
;
;               This is the ring 3 dynamic interface for the 16 Bit
;               RAM Semaphore support code.  This supports DOSPMSEMWAIT and
;               DOSPMMUXWAIT. The DOSPMSEMWAIT code mirrors the DOSEMWAIT
;               code in DOSSEM.ASM in the DOSCALL1 Subdirectory so any
;               changes made to that module should also be made here. If
;               the semaphore is clear, control is returned back to the caller.
;               otherwise control is passed on to the kernel version of the
;               to block on the semaphore.
;
;       Modification History:
;
;       2/15/94         RAC     Initial Version vx.x
;       6/9/94          RAC     xxxxx Save ax over call to reset semaphore call
;
.xlist
include error.inc
include infoseg.inc
include basemaca.inc
include dc1segs.inc                                             ; DCR 704
include dc1mmpha.inc
.list

;ModName DOSSEM

include sem.inc
include semxport.inc

EXTRN   DOSISEMWAIT:FAR
EXTRN   DOSMUXSEMWAIT:FAR


; Declared for 16->32 thunks here
.386p
CODE32_TUNE1 SEGMENT DWORD USE32 PUBLIC 'CODE'                  ; DCR 704
EXTRN   DOS32PM16SEMCHK:NEAR
EXTRN   DOS32PM16SEMRST:NEAR
CODE32_TUNE1  ENDS


.286p

CODE16C_TUNE1  SEGMENT
CODE16C_TUNE1  ENDS


CODE16C_TUNE1  SEGMENT                                          ; DCR 704


BREAK   <callPMSEMWAIT - wait until semaphore is cleared>

;***    callPMSEMWAIT - wait until semaphore is cleared
;
;       Wait for a semaphore to be cleared, does not establish
;       ownership of the semaphore.
;
;       DOSPMSEMWAIT (PMSemHandle, SemHandle, Timeout);
;
;       ENTRY:  DWORD   pm semaphore handle.
;               DWORD   semaphore handle.
;               DWORD   time out value.
;
;       EXIT:   AX = error code.
;
;       USES:   AX, Flags
;
;       This routine will call the 32 Bit PM semaphore support code
;       to set up the processing of for a multi waited and mixed
;       16 and 32 PM semaphores. Then,
;       this routine checks the high word of the semaphore
;       handle for the system semaphore ID. If this handle
;       is a system semaphore then the kernel version of
;       SemWait is called which performs the operation on
;       the system semaphore. If this handle is a RAM semaphore
;       handle, then the handle is the address of the RAM
;       semaphore. The semaphore is check if it is clear and
;       returns if so. If the semaphore was previously set, then
;       the kernel version of SemWait is called to block on the
;       semaphore. Before control is returned to the caller,
;       we call the PMSemaphore processing code to see what has
;       been posted.
;
;       WARNINGS: There is no address checking done by this routine
;                 on the RAM semaphore address before it is used, but
;                 this should not matter because if it is a bad address
;                 it will cause a fault and the process terminated.
;
        ASSUME  CS:CODE16C_TUNE1, DS:NOTHING, ES:NOTHING, SS:NOTHING

Procedure callPMSEMCHK,NEAR

ArgVar  PMSemHandle,DWORD

        EnterProc

        .386p
        ;align   4  54686                ; DWORD align jump target
        push    PMSemHandle
                                        ; routine.
CODE32_TUNE1  SEGMENT
        assume CS:FLAT
        ;align   4  54686                ; DWORD align jump target
T_DOS32PM16SEMCHK label near
CODE32_TUNE1  ENDS

        jmp     far ptr FLAT:T_DOS32PM16SEMCHK
        ;align   4  54686                ; DWORD align jump target
R_DOS32PM16SEMCHK:

CODE32_TUNE1  SEGMENT
        call DOS32PM16SEMCHK
        jmp far ptr R_DOS32PM16SEMCHK
CODE32_TUNE1  ENDS
        .286p

        LeaveProc

        ret

EndProc    callPMSEMCHK



Procedure callPMSEMRST,NEAR

ArgVar  PMSemHandle,DWORD

        EnterProc

        .386p
        ;align   4  54686                ; DWORD align jump target
        push    PMSemHandle
                                        ; routine.
CODE32_TUNE1  SEGMENT
        assume CS:FLAT
        ;align   4  54686                ; DWORD align jump target
T_DOS32PM16SEMRST label near
CODE32_TUNE1  ENDS

        jmp     far ptr FLAT:T_DOS32PM16SEMRST
        ;align   4  54686                ; DWORD align jump target
R_DOS32PM16SEMRST:

CODE32_TUNE1  SEGMENT
        call DOS32PM16SEMRST
        jmp far ptr R_DOS32PM16SEMRST
CODE32_TUNE1  ENDS
        .286p

        LeaveProc

        ret

EndProc    callPMSEMRST

BREAK   <DOSPMSEMWAIT - wait until semaphore is cleared>

;***    DOSPMSEMWAIT - wait until semaphore is cleared
;
;       Wait for a semaphore to be cleared, does not establish
;       ownership of the semaphore.
;
;       DOSPMSEMWAIT (PMSemHandle, SemHandle, Timeout);
;
;       ENTRY:  DWORD   pm semaphore handle.
;               DWORD   semaphore handle.
;               DWORD   time out value.
;
;       EXIT:   AX = error code.
;
;       USES:   AX, Flags
;
;       This routine will call the 32 Bit PM semaphore support code
;       to set up the processing of for a multi waited and mixed
;       16 and 32 PM semaphores. Then,
;       this routine checks the high word of the semaphore
;       handle for the system semaphore ID. If this handle
;       is a system semaphore then the kernel version of
;       SemWait is called which performs the operation on
;       the system semaphore. If this handle is a RAM semaphore
;       handle, then the handle is the address of the RAM
;       semaphore. The semaphore is check if it is clear and
;       returns if so. If the semaphore was previously set, then
;       the kernel version of SemWait is called to block on the
;       semaphore. Before control is returned to the caller,
;       we call the PMSemaphore processing code to see what has
;       been posted.
;
;       WARNINGS: There is no address checking done by this routine
;                 on the RAM semaphore address before it is used, but
;                 this should not matter because if it is a bad address
;                 it will cause a fault and the process terminated.
;
        ASSUME  CS:CODE16C_TUNE1, DS:NOTHING, ES:NOTHING, SS:NOTHING

Procedure DOSPMSEMWAIT,FAR

ArgVar  TimeOut,DWORD
ArgVar  SemHandle,DWORD
ArgVar  PMSemHandle,DWORD

        EnterProc

        MMPHPreDOSSemWait               ; Performance Hook (1809h)

        mov     ax,SemHandleH
        cmp     ax,USERHANDLE_HIGHWORD  ; check for system semaphore
        je      dsw1

        SaveReg <ds,bx>
        mov     ds,ax                   ; (DS) = selector of ram semaphore
        mov     bx,SemHandleL           ; (BX) = offset of ram semaphore
        xor     ax,ax                   ; (AX) = return code if no error
        .errnz  SEM_CLEAR
        cmp     [bx].RamSemBusyFlag,0   ; check if semaphore is clear
        RestoreReg <bx,ds>
        je      dsw2                    ; jump if semaphore is clear
        cmp     TimeOutH,0              ; if time out == 0 then just return
        jne     dsw1                    ;  with error
        cmp     TimeOutL,0
        jne     dsw1
        mov     ax,ERROR_SEM_TIMEOUT
        jmp     short dsw2

dsw1:   ; First call the PM Semphore handling code.

        push    PMSemHandleH
        push    PMSemHandleL
        call    callPMSEMCHK
        pop     PMSemHandleL
        pop     PMSemHandleH

        cmp     ax,0
        jnz     short dsw2

        push    SemHandleH
        push    SemHandleL
        push    TimeOutH
        push    TimeOutL

        call    DOSISEMWAIT             ; otherwise wait until it is clear

        push    ax                      ; xxxxx Save return code from DOSISEMWAIT
        push    PMSemHandleH
        push    PMSemHandleL
        call    callPMSEMRST
;        pop     PMSemHandleL           ; Pop into ax instead of stack. 3 clocks
;        pop     PMSemHandleH           ; versus 6 clocks
        pop     ax
        pop     ax
        pop     ax                      ; restore return code

dsw2:

;       MMIOPH Performance Hook Removed
;       Maj/Min = 1889H, Data = none.

        MMPHPostDOSSemWait               ; Performance Hook (1889h)

        LeaveProc
        ret     ?aframe
EndProc    DOSPMSEMWAIT


BREAK   <DOSPMMUXSEMWAIT - wait until one of N Semaphore is cleared>

;***    DOSPMMUXSEMWAIT - wait until one of N semaphore is cleared
;
;       DOSPMSEMWAIT (PMSemHandle, SemHandle, Timeout);
;
;       ENTRY:  DWORD   pm semaphore handle.
;               DWORD   IndexNr           ; Index Number Returned ( 2 Words )
;               DWORD   Other ListAddr    ; semaphore list.       ( 2 Words )
;               DWORD   time out value.   ; timeout vakue         ( 2 Words )
;
;       EXIT:   AX = error code.
;
;       USES:   AX, Flags
;
;       This routine will call the 32 Bit PM semaphore support code
;       to set up the processing of for a multi waited and mixed
;       16 and 32 PM semaphores. Then, it will pass control onto the
;       kernel API which handles the MuxSemWait processing.  When control
;       is received back from the kernel, we will again call the PM semaphore
;       routines to see if we are returning because a PM semaphore was
;       posted.
;
;       WARNINGS: There is no address checking done by this routine
;                 on the RAM semaphore address before it is used, but
;                 this should not matter because if it is a bad address
;                 it will cause a fault and the process terminated.
;
        ASSUME  CS:CODE16C_TUNE1, DS:NOTHING, ES:NOTHING, SS:NOTHING

Procedure DOSPMMUXSEMWAIT,FAR

ArgVar  TimeOut,DWORD
ArgVar  ListAddr,DWORD
ArgVar  IndexNbr,DWORD
ArgVar  PMSemHandle,DWORD

        EnterProc

        ; First call the PM Semphore handling code.
        push    PMSemHandleH
        push    PMSemHandleL
        call    callPMSEMCHK
        pop     PMSemHandleL
        pop     PMSemHandleH

        cmp     ax,0                      ; Check for error returned.
        jnz     short dsw12

        push    IndexNbrH
        push    IndexNbrL
        push    ListAddrH
        push    ListAddrL
        push    TimeOutH
        push    TimeOutL
        call    DOSMUXSEMWAIT           ; Wait until it is clear posted

        push    ax                       ; Save return code
        push    PMSemHandleH
        push    PMSemHandleL
        call    callPMSEMRST
;        pop     PMSemHandleL
;        pop     PMSemHandleH
        pop     ax                       ; Pop to ax for faster code
        pop     ax
        pop     ax                       ; restore return code

dsw12:

;       MMIOPH Performance Hook Removed
;       Maj/Min = 1889H, Data = none.

        MMPHPostDOSSemWait               ; Performance Hook (1889h)

        LeaveProc
        ret     ?aframe
EndProc    DOSPMMUXSEMWAIT

CODE16C_TUNE1    ENDS

        END
