;       SCCSID = @(#)mdsuba.asm	6.2 91/07/23


        page 66, 132
        title  Monitor Dispatcher DvHlp Functions - Assembler subroutines
        subttl IBM Confidential
; ***************************************************************************
; *
; *                       IBM Confidential
; *
; *                 Copyright (c) IBM Corporation  1987, 1990
; *                           All Rights Reserved
; *
; ***************************************************************************

;/********************** START OF SPECIFICATIONS **************************
;/*
;/*  Source File Name: MDSUBA.ASM
;/*
;/*  Descriptive Name: Monitor Dispatcher DevHlp routines - Part 3
;/*
;/*  Function:  Character Device Monitors provide a mechanism for
;/*     applications or subsystems to monitor all characters passing
;/*     through a device driver.  This mechanism allows any reg-
;/*     istered process to remove, insert or modify the information
;/*     passing through the device.
;/*
;/*     The Monitor Dispatcher DevHlp routines provide the services
;/*     for device drivers to support character stream monitoring.
;/*
;/*  Notes: These modules make up the Monitor Dispatcher DevHlps:
;/*
;/*     MDINIT.ASM  - Initialization routine
;/*     MDINTRF.ASM - Stub entries for devhlps in low mem
;/*     MDSUBA.ASM  - Common subroutines that must be assembler
;/*     MDLOCK.C    - dhw_Write and subroutines (interrupt-time routines)
;/*     MDSWAP1.C   - MD32IMONREAD, MD32IMONWRITE, and subroutines
;/*     MDSWAP2.C   - dhw_Create, dhw_Register, dhw_Deregister, and subroutines
;/*
;/*  Procedures Defined in this module:
;/*     _Notify32MonNotify - Set up registers to call DD's notification routine
;/*     NotifyMonNotify  - 16bit stub for so that we can call monnotify
;/*     _access_ubuffers - Get access to user's buffer's
;/*
;/*  External References (other kernel components):
;/*
;/*************************************************************************


EXTRN16   FuWordNF
EXTRN     _SELVirtToLin:near
EXTRN     _TKProbeBuff:near


         include mddvhlp.inc
         include infoseg.inc

CpuMode  386

FARCODE LOW
CODE    SEGMENT

                 ASSUME ds:nothing, es:nothing
;-----------------------------------------------------------------------------
; Should be in 16 bit fixed segment
;/****************** START OF SPECIFICATIONS *******************
;/
;/ SUBROUTINE NAME:  NotifyMonNotify
;/
;/ DESCRIPTIVE NAME: call Mon Notify routine
;/
;/ FUNCTION: Call Device Driver's Mon Notify routine
;/
;/ ENTRY POINT: NotifyMonNotify
;/    LINKAGE:  FAR CALL
;/
;/ INPUT:  EBX = MonChainPtr
;/         FS  = Flat
;/
;/ EXIT-NORMAL:  returns nothing
;/
;/ EXIT-ERROR:   returns nothing
;/
;/
;/ EFFECTS:
;/
;/ INTERNAL REFERENCES:
;/    Changes registers (saved and restored by _Notify32MonNotify)
;/
;/ EXTERNAL REFERENCES:
;/
;/****************** END OF SPECIFICATIONS *********************

Procedure NotifyMonNotify,far16

 ;call MonChainPtr->dev_notify routine (It's 16:16)
   Call DWORD ptr FS:[EBX].dev_notify

   RETFD             ;return far-double (CS:EIP is on stack)
EndProc  NotifyMonNotify

CODE ENDS


;/***************************************************************************
;/***************************************************************************
;/***************************************************************************
;-----------------------------------------------------------------------------
; The following procedures should be in 32 bit swapable segment
;-----------------------------------------------------------------------------

        FARCODE HIGH32
MON32SWAP_TEXT    segment

;/******************* START OF SPECIFICATIONS *******************
;/*
;/* SUBROUTINE NAME:  _access_ubuffers
;/*
;/* DESCRIPTIVE NAME: Gain access to a USER's monitor buffers
;/*                   from the kernel.
;/*
;/* FUNCTION:  Verifies selectors for monitor buffers in user
;/*            space and allows us to access them from the
;/*            kernel.
;/*
;/* NOTES:  Called by all mon_Register, mon_deRegister,
;/*         mon_thread_code, move_circular_to_circular, and
;/*         move_circular_to_flat.
;/*
;/* ENTRY POINT:  access_ubuffers
;/*    LINKAGE:  NEAR CALL
;/*
;/* INPUT:  (from local variables)
;/*
;/*    BufferI = 16:16 selector:offset of monitor's input buffer
;/*    BufferO = 16:16 selecotr:offset of monitor's output buffer
;/*
;/* EXIT-NORMAL:  EAX = 0
;/*
;/* EXIT-ERROR:   EAX = -1
;/*
;/* EFFECTS:  USES EAX
;/*
;/* INTERNAL REFERENCES:  None
;/*
;/* EXTERNAL REFERENCES:
;/*                 _SELVirtToLin
;/*                 _TKProbeBuff
;/*                 FuWord
;/******************* END OF SPECIFICATIONS *********************

Procedure _access_ubuffers, NEAR
        ArgVar  BufferIn, DWORD
        ArgVar  BufferOut, DWORD
        EnterProc

 ; We first need to access the length word in the buffer header for each of the
 ; monitor's buffers and then to verify the entire buffer
        mon_savemost_regs

        MOV     BX, [BufferIn].Segmt   ; get the length word from the buffer
        MOV     SI, [BufferIn].Offst   ; header from the monitor's INPUT buffer
        SaveReg <DS,ES>
        CALL16 FuWordNF
        RestoreReg <ES,DS>
        JC      aub_error              ; error on accessing buffer

        MOVZX   ECX, AX
        MOVZX   EBX, [BufferIn].Segmt  ; verify the entire monitor INPUT buffer
        MOVZX   ESI, [BufferIn].Offst
        MOV     EDX,TK_UM_WRITE        ; need R/W access to this selector

        PushP   edx                    ; Flags for _TKProbeBuff
        PushP   ecx                    ; Size for _TKProbeBuff
        CCallNest                      ; Push parameters for _SELVirtToLin:
        PushP   ebx                    ; Selector for _SELVirtToLin
        PushP   esi                    ; Offset for _SELVirtToLin
        CCall   _SELVirtToLin,,PushP   ; (EAX) = linear address (or -1)
        PushP   eax                    ; Linear address for _TKProbeBuff
        CCall   _TKProbeBuff,,PushP    ; Probe the buffer
        or      eax,eax

        JNZ     aub_error              ; error on probing buffer

        MOV     BX, [BufferOut].Segmt  ; get the length word from the buffer
        MOV     SI, [BufferOut].Offst  ; header for the monitor's OUTPUT buffer
        SaveReg <DS,ES>
        CALL16  FuWordNF
        RestoreReg <ES,DS>
        JC      aub_error              ; error on probing buffer

        MOVZX   ECX, AX
        MOVZX   EBX, [BufferOut].Segmt ;verify the entire monitor OUTPUT buffer
        MOVZX   ESI, [BufferOut].Offst
        MOV     EDX, TK_UM_WRITE       ; need R/W access to this selector

        PushP   edx                    ; Flags for _TKProbeBuff
        PushP   ecx                    ; Size for _TKProbeBuff
        CCallNest                      ; Push parameters for _SELVirtToLin:
        PushP   ebx                    ; Selector for _SELVirtToLin
        PushP   esi                    ; Offset for _SELVirtToLin
        CCall   _SELVirtToLin,,PushP   ; (EAX) = linear address (or -1)
        PushP   eax                    ; Linear address for _TKProbeBuff
        CCall   _TKProbeBuff,,PushP    ; Probe the buffer
        or      eax,eax

        JZ      aub_done
aub_error:
        mov     eax,-1
aub_done:
        mon_restoremost_regs
        LeaveProc
aub_ret: RET

EndProc _access_ubuffers

MON32SWAP_TEXT    ENDS



;/***************************************************************************
;/***************************************************************************
;/***************************************************************************
;-----------------------------------------------------------------------------
; Everything below should be in 32 bit lockable segment
;-----------------------------------------------------------------------------

        FARCODE HIGH32
MON32LOCK_TEXT    segment

;/****************** START OF SPECIFICATIONS *******************
;/
;/ SUBROUTINE NAME:  _Notify32MonNotify
;/
;/ DESCRIPTIVE NAME: Set up registers and call Mon Notify routine
;/
;/ FUNCTION: Set up registers and call Mon Notify routine
;/
;/ ENTRY POINT: _Notify32MonNotify
;/    LINKAGE:  FAR CALL
;/
;/ INPUT:  None
;/
;/ EXIT-NORMAL:  returns nothing
;/
;/ EXIT-ERROR:   returns nothing
;/
;/
;/ EFFECTS:
;/
;/ INTERNAL REFERENCES:
;/
;/ EXTERNAL REFERENCES:
;/
;/****************** END OF SPECIFICATIONS *********************

Procedure _Notify32MonNotify, NEAR
  ;must be Assembler
  ArgVar MonChainPtr, DWORD
  EnterProc

   pushad
   push   ds
   push   es
   push   fs

   FlatContext FS
   mov    EBX, MonChainPtr

 ;set DS:SI to MonChainPtr->dev_buff
   mov   ES, FS:[EBX].dev_buff.Segmt
   mov   DS, FS:[EBX].dev_buff.Segmt
   mov   SI, FS:[EBX].dev_buff.Offst
   mov   DI, FS:[EBX].dev_buff.Offst    ; not documented but counted on by
                                        ; a 4216 printer device driver
   CALL16 NotifyMonNotify           ; Far jump into 16-bit code
                                    ; so we can call DD's monnotify.
   pop    fs
   pop    es
   pop    ds
   popad

  LeaveProc
  ret
EndProc _Notify32MonNotify

MON32LOCK_TEXT    ENDS

        END
