;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/

;/*************************************************************************
;*                                                                         
;* SOURCE FILE NAME = MEM.ASM                                                                           
;*                                                                                                                
;* DESCRIPTIVE NAME = Worker routines used for dynamic memory                        
;*                    allocation.                                                                                 
;*
;*                                                                         
;* VERSION      V2.0                                                       
;*                                                                         
;* DATE         07/08/91
;*                                                                         
;* DESCRIPTION                                
;*                                                                         
;* FUNCTIONS    AllocCB        - Allocate a control block
;*              FreeCB         - Free a CB
;*              AllocMem       - Allocate memory
;*              FindCB         - Get a pointer to a specific CB
;*              FindCBPtr      - Find a CB pointer structur
;*             
;*
;* NOTES        This file contains the worker routines used for     
;*              dynamic memory allocation of our per session control
;*              blocks. It also has some routines used for finding  
;*              a CB for a particular session.                      
;*             
;* STRUCTURES   NONE                                                       
;*                                                                         
;* EXTERNAL REFERENCES                                                     
;*                                                                         
;*              NONE                                                       
;*                                                                         
;* EXTERNAL FUNCTIONS                                                      
;*                                                                         
;*              NONE                                                       
;*                                                                         
;* CHANGE ACTIVITY =                                                       
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION                       
;*   --------  ----------  -----  --------------------------------------   
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx                                  
;**************************************************************************

.386p

.xlist
        include mouse.inc
        include filemode.inc
        include basemaca.inc
.list

;*
;*   External Mouse Module Data References
;*

       extrn  Num_Grps             : byte
       extrn  FullScrCBs           : byte

       extrn  Device_Help          : dword

CSEG2    SEGMENT   WORD  PUBLIC  USE16 'SWAPCODE'
         ASSUME    CS:CSEG2, SS:nothing, ES:nothing, DS:nothing

;*
;*    Module Procs made Public for other Mouse Modules
;*

       public  AllocMem
       public  AllocCB
       public  FreeCB
       public  FindCBPtr
       public  FindCB


;/***************************************************************************
;*                                                                           
;* FUNCTION NAME =  AllocCB                       
;*                                                
;* DESCRIPTION   =  Allocate a control block.     
;*                                                
;*                  This routine allocates a control block and puts     
;*                  it in the next free slot in the CB pointer chain.   
;*                     
;*                     
;* INPUT         =   DS - DD data segment                        
;*                   BX - session number                         
;*                   CX - number of bytes to allocate for CB     
;*                                                               
;* OUTPUT        =   CY set if error detected, DS:SI = CB address if n  
;*                   error detected.                                  
;*
;*                   stack is clean
;*                     
;* RETURN-NORMAL =   none
;*                     
;*                     
;* RETURN-ERROR  =   none
;*                     
;*                     
;**************************************************************************/ 
;* PSEUDOCODE :
;*
;* BeginSub  AllocCB
;*
;*  call FindCBPtr to see if CB already allocated
;*  IF <not found (not allocated yet)>
;*     IF <requested session is not fullscreen>
;*        call FindCBPtr to locate a free slot
;*        IF <no free slot found>
;*           call AllocMem to allocate another pointer block structure
;*           IF <memory allocated OK>
;*              link new pointer block structure to last block structure
;*              initialize new block structure to all free
;*           ELSE
;*              set error code and exit
;*           ENDIF
;*        ENDIF
;*     ENDIF
;*     call AllocMem to allocate memory for control block
;*     IF <control block allocated OK>
;*        save pointer to control block
;*        mark control block pointer structure with session information
;*     ENDIF
;*
;*     IF <no errors detected>
;*        load DS:SI with sel:off of new control block
;*     ENDIF
;*
;*EndSub  AllocCB
;*
;************************************************************************

AllocCB  proc  near

;*
;*   First see if the control block is already allocated.  If so then
;*   just exit with carry clear.  If carry was set then we need to allocate
;*   the CB.
;*
       push es
       push ds
       pop  es
       call FindCBPtr
       .if <c>
          call AllocMem
          .if <nc>
             mov  [si].SGSelOff, ecx
             mov  [si].SGLinear, eax
          .endif
       .endif

       lds  si, [si].SGSelOff                 ; leave DS:SI with the ptr
       pop  es

       ret

AllocCB  EndP


;/***************************************************************************
;*                                                                           
;* FUNCTION NAME = FreeCB
;*                                                                                                                  
;* DESCRIPTION   = Free a CB.
;*                                                                                                                        
;*                 This routine will free the memory associated with                                                          
;*                 a control block.  The memory is returned using                                                             
;*                 VNFree on the linear address returned by a                                                                 
;*                 previous VMAlloc call.                                                                                     
;*                                                                           
;* INPUT         = BX -> requested session #.                                                           
;*                 DS -> DD Data Seg                                                                    
;*                                                                           
;* OUTPUT        = NONE.
;*                                                                           
;*                                                                           
;* RETURN-NORMAL = NONE.
;*                                                                           
;*                                                                           
;* RETURN-ERROR  = NONE.
;*                                                                           
;*                                                                           
;**************************************************************************/ 
;* PSEUDOCODE :
;*
;*  BeginSub  FreeCB
;*
;*  call FindCBPtr to get the requested session CB pointer structure
;*  IF <found>
;*     get linear address of CB
;*     call Device_Help(VMFree) to free the memory
;*     mark CB Pointer structure as free
;*  ENDIF
;*
;* EndSub  FreeCB
;*
;***********************************************************************/

FreeCB  proc  near

       push bx
       push es
       push ds
       push ds
       pop  es
       call FindCBPtr
       .if <nc>
          mov  eax, [si].SGLinear
          mov  dl, DevHlp_VMFree
          call es:Device_Help
          .if <nc>
             mov  word ptr [si].SGSelOff+2, 0
          .endif
       .endif
       pop  ds
       pop  es
       pop  bx
       ret

FreeCB  EndP

;/***************************************************************************
;*                                                                           
;* FUNCTION NAME = AllocMem                                                                                                
;*                                                                                                                         
;* DESCRIPTION   = Allocate memory.                                                                                        
;*                                                                                                                         
;*                 This routine will allcoate the specified number                                                            
;*                 of bytes of memory.  It uses the allocation flags                                                          
;*                 to determine how the memory is to be allocated.                                                            
;*                 currently this is not implemented (for future).                                                            
;*                                                                           
;* INPUT         = cx - number of bytes to allocate                                                                           
;*                 es - DD data segment                                                                                       
;*                                                                                                                            
;* OUTPUT        = CY set if error detected, regs setup from call to                                                          
;*                 VMAlloc.                                                                                                   
;*                                                                           
;* RETURN-NORMAL = NONE.
;*                                                                           
;*                                                                           
;* RETURN-ERROR  = NONE
;*                                                                           
;*                                                                           
;************************************************************************/ 
;* PSEUDOCODE :
;*
;* BeginSub  AllocMem
;*
;* call DeviceHelp(VirtToLin) to get linear address of where to
;*    put linear address of allocated memory
;* IF <VirtToLin worked>
;*    call DeviceHelp(VMAlloc) to allocate requested memory
;* ENDIF
;* return last error code from DevHelp call
;*
;*EndSub  AllocMem
;*
;***********************************************************************


AllocMem  proc  near

       enter 4,0
       push si
       mov  ax, ss
       mov  si, bp
       sub  si, 4
       and  esi, 0000ffffh
       mov  dl, DevHlp_VirtToLin
       call es:Device_Help
       .if <nc>
          mov  edi, eax
          mov  eax, 10000010b           ; flags for allocation
          and  ecx, 0000ffffh           ; clear high word
          mov  dl, DevHlp_VMAlloc
          call es:Device_Help
       .endif
       pop  si
       leave
       ret

AllocMem  endp

;/***************************************************************************
;*                                                                           
;* FUNCTION NAME =  FindCB                                                                                                  
;*                                                                                                                          
;* DESCRIPTION   =  Get a pointer to a specific CB.                                                                         
;*                                                                                                                          
;*                  This routine will return the pointer to a control                                                          
;*                  block.                                                                                                     
;*                                                                           
;* INPUT         =  DS    -> DD Data Seg                                                                                      
;*                  BX    -> requested session #.                                                                             
;* OUTPUT        =                                                                                                            
;*                  IF carry set CB was not found, clear if found and                                                         
;*                  DS:SI -> fullscreen CB                                                                                    
;* RETURN-NORMAL =                                                           
;*                  NONE.
;*                                                                           
;* RETURN-ERROR  =  NONE.
;*                                                                           
;**************************************************************************/ 
;* PSEUDOCODE :
;*
;* BeginSub  FindCB
;*
;* call FindCBPtr to get the CB pointer structure
;* IF <found>
;*    load DS:SI with the selctor:offset of the CB
;* ENDIF
;* return
;*
;*EndSub  FindCB
;*
;************************************************************************/

FindCB  proc  near

       push bx
       push es                       ; save es
       push ds                       ; put ds in es
       pop  es
       call FindCBPtr                ; go find the CB ptr structure
       .if <nc>                      ; if found
          lds  si, [si].SGSelOff     ; load DS:SI with the CB pointer
       .endif
       pop  es                       ; restore es
       pop  bx
       ret                           ; return to caller

FindCB  endp
;/***************************************************************************
;*                                                                           
;* FUNCTION NAME = FindCBPtr                                                                                                  
;*                                                                                                                            
;* DESCRIPTION   = Find a CB pointer structure.                                                                               
;*                                                                                                                            
;*                 This routine will return the pointer to a control                                                          
;*                 block structure for the requested session #.                                                               
;*                 Carry will be clr if the session # was found and                                                           
;*                 its CB was allocated, set otherwise.                                                                       
;*                                                                           
;* INPUT         = DS    -> DD Data Seg                                                                                       
;*                 BX    -> requested session #.                                                                              
;*                                                                                                                            
;* OUTPUT        = DS:SI -> slot for fullscreen CB                                                                            
;*                 carry is set if CB not allocated, clear otherwise                                                          
;*                                                                           
;* RETURN-NORMAL =  NONE.
;*                                                                           
;*                                                                           
;* RETURN-ERROR  =  NONE.
;*                                                                           
;*                                                                           
;**************************************************************************/ 
;* PSEUDOCODE :
;*
;* BeginSub  FindCBPtr
;*
;*    Multiply screen group number by the size of CBPtrStruc
;*    IF <fullscreen CB is allocated>
;*       set allocated status
;*    ELSE
;*       set not-allocated status
;*    ENDIF
;*
;* EndSub  FindCBPtr
;*
;***********************************************************************/

FindCBPtr  proc  near

       push ax                                ; AX used in IMUL operation
       mov  ax, bx                            ; SG # is the multiplier
       mov  dx, SIZE CBPtrStruc               ; Get entry size
       imul dx                                ; (Entry size) * (SG #) = offset
       mov  si, offset FullScrCBs             ; to the CB entry for this SG #
       add  si, ax                            ; Add offset to start of table
       .if <<word ptr [si].SGSelOff+2> ne 0>  ; If the selector is nonzero we
          clc                                 ; know that a CB has been alloc
       .else                                  ; If ZERO then no CB yet.
          stc                                 ; Return status to caller.
       .endif
       pop  ax                                ; Restore callers AX value
       ret

FindCBPtr  endp

CSEG2  ENDS
       END
