;*DDK*************************************************************************/
;
; 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.;
;*****************************************************************************/
        PAGE     55,132
        TITLE    Memory Management Functions
        SUBTITLE Header
;/*****************************************************************************
;*
;* SOURCE FILE NAME = MEMMAN.ASM
;*
;* DESCRIPTIVE NAME = Memory Management
;*
;*
;* VERSION      V2.0
;*
;* DATE         10/14/91
;*
;* DESCRIPTION  This module contains all the routines which interface to the OS/2 
;*              and Presentation Manager memory management functions.
;*
;* FUNCTIONS    alloc_bm     
;*              alloc_ddc    
;*              AllocMem     
;*              free_bm      
;*              free_ddc     
;*              FreeMem      
;*              global_alloc 
;*              global_free  
;*              private_alloc
;*              private_free 
;*              
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   10/14/91                     Written by micrografx
;*
;*****************************************************************************/

;/*
;** Model and processor selection                                              
;*/

        .386P
        .MODEL FLAT,SYSCALL

        .xlist

;/*
;** Included files
;*/

INCL_DOSERRORS          equ 1
INCL_DOSMEMMGR          equ 1

OS2_NOBASEAPI           equ 1

INCL_GPIPRIMITIVES      equ 1
INCL_DOSPROCESS         equ 1

        INCLUDE PMGRE.INC

DINCL_VIO               equ        1
DINCL_BITMAP            equ        1
DINCL_ENABLE            equ        1

        INCLUDE        DRIVER.INC
        INCLUDE        EXTERN.INC
        include protos.inc
        
        .list

;/*
;** Equates
;*/

;/*
;** Return status codes
;*/

BLOCKFREED    EQU 1             ; Block successfully freed
BLOCKNOTFREED EQU 0             ; Could not free block
HEAPALLOCED   EQU 1             ; Heap allocated

        .CODE

;/*
;** Public functions
;*/
   
        SUBTITLE AllocMem Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = AllocMem 
;*
;* DESCRIPTION   = 
;*  This function allocates a block of memory of the given size plus eight  
;*  bytes from the driver heap.  This block will have the following format: 
;*                                                                          
;*    +-------------------+-------+-------------------------------+         
;*    |       Byte        | Type  | Description                   |         
;*    +-------------------+-------+-------------------------------+         
;*    |         0         | DWORD | Heap block signature          |         
;*    +-------------------+-------+-------------------------------+         
;*    |         4         | DWORD | Size of block                 |         
;*    +-------------------+-------+-------------------------------+         
;*    |         8         | BYTE  | First byte of allocated block |         
;*    +-------------------+-------+-------------------------------+         
;*                                .                                         
;*                                .                                         
;*                                .                                         
;*    +-------------------+-------+-------------------------------+         
;*    | 7 + Size of block | BYTE  | Last byte of allocated block  |         
;*    +-------------------+-------+-------------------------------+         
;*                                                                          
;*  The return value will be either a pointer to the beginning of the       
;*  allocated block (byte following the block size) or 0 to indicate that   
;*  memory could not be allocated.                                          
;*
;* INPUT         = EAX = Size of requested block in bytes 
;* OUTPUT        = EAX = Pointer to the allocated block of memory 
;*
;* RETURN-NORMAL = EAX = Pointer to the allocated block of memory 
;* RETURN-ERROR  = ECX = 0 
;*                 EAX = 0 
;**************************************************************************/

ALIGN 4

AllocMem PROC SYSCALL PUBLIC uses EBX

        LOCAL   pbBlockOffset:PBYTE

        LEA     EBX,pbBlockOffset

        INVOKE  SSAllocMem,
                EBX,
                EAX,
                0

        CMP     EAX,NO_ERROR            ; Allocated?
        JNE     NotAllocated            ;  N - Error
        MOV     EAX,pbBlockOffset       ;  Y - Store heap block signature
        MOV     ECX,1
        JMP     AllocMemRet
ALIGN 4

NotAllocated:

        rip     text,<AllocMem Failed>
        XOR     EAX,EAX                 ; Indicate error
        XOR     ECX,ECX

AllocMemRet:

        RET

AllocMem ENDP
   
        SUBTITLE free_mem Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = FreeMem 
;*
;* DESCRIPTION   = This function releases the memory block in the driver heap 
;*                 beginning at offset pbBlockOffset.  Each such block must 
;*                 first have been allocated by the AllocMem function.  Refer to 
;*                 the documentation for that function for a description of the 
;*                 format of that block.                              
;*
;* INPUT         =  EAX = Pointer to memory block
;* OUTPUT        =  NONE
;*
;* RETURN-NORMAL =  EAX <> 0 
;* RETURN-ERROR  =  EAX = 0 
;*
;**************************************************************************/

ALIGN 4

FreeMem PROC    SYSCALL PUBLIC uses EBX


        INVOKE  SSFreeMem,
                EAX

        CMP     EAX,NO_ERROR                    ; OK?
        MOV     EAX,BLOCKFREED
        JE      FreeMemExit                     ;  Y - Done

NotFreed:

        rip     text,<FreeMem Failed>
        MOV     EAX,BLOCKNOTFREED               ; Indicate error occurred

FreeMemExit:

        RET

FreeMem ENDP
   
        SUBTITLE alloc_ddc
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = alloc_ddc
;*
;* DESCRIPTION   = This function allocates space from the driver's heap for a ddc      
;*                 structure.  No initialization is performed on the allocated 
;*                 memory.
;*                 The memory semaphore is acquired and released around the allocation.
;*                 allocation.
;*
;* INPUT         = NONE
;* OUTPUT        = EAX = Pointer to allocated memory block
;*                 ECX = Pointer to allocated memory block
;* RETURN-NORMAL = EAX <> 0
;* RETURN-ERROR  = EAX = 0
;*
;**************************************************************************/

ALIGN 4

alloc_ddc PROC  SYSCALL PUBLIC

        MOV     EAX,size DDC
        CALL    AllocMem
        MOV     ECX,EAX
        
        RET

alloc_ddc ENDP        

        SUBTITLE free_ddc
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = free_ddc
;*
;* DESCRIPTION   = Free the memory formerly used by a no-longer existing DDC.  The    
;*                 identifier for ddc in the freed memory block is set to the 
;*                 deleted object identifier.
;*                                                                                    
;*                 The memory semaphore is acquired and released around the release.  
;*
;*                 Registers Preserved:           
;*                        SI,DI,DS,BP             
;*                 Registers Destroyed:           
;*                        AX,BX,CX,DX,ES,FLAGS    
;*
;* INPUT         = ESI = Pointer to the ddc to be freed 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ALIGN 4
free_ddc PROC   SYSCALL PUBLIC

        ddc?    ESI,<SURFACE,LEVELS>                    ; Validate the ddc
        MOV     [ESI].DDC.ddc_usId,DELETED_IDENT        ; Indicate ddc no 
                                                        ; longer valid
        MOV     EAX,ESI
        CALL    FreeMem                                 ; Free its memory

IFDEF FIREWALLS

        OR      EAX,EAX
        JNZ     @F

        rip text,<Heap Manager returned an error while freeing a ddc (free_ddc)>

@@:

ENDIF

        RET

free_ddc ENDP
   
        SUBTITLE alloc_bm Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = alloc_bm
;*
;* DESCRIPTION   = This function allocates memory for a bitmap.  This memory is not   
;*                 initialized.                                                       
;*                                                                                    
;*                 The memory semaphore is aquired and released around the 
;*                 allocation
;*
;*                 Registers Preserved:         
;*                        SI,DI,DS,BP           
;*                 Registers Destroyed:         
;*                        AX,BX,CX,DX,ES,FLAGS  
;*
;* INPUT         = NONE
;* OUTPUT        = EAX = Pointer to memory block
;*                 ECX = Pointer to memory block
;* RETURN-NORMAL = EAX <> 0
;* RETURN-ERROR  = EAX = 0
;*                 ECX = 0
;**************************************************************************/

ALIGN 4

alloc_bm PROC   SYSCALL PUBLIC

        MOV     EAX,sizeof BITMAP
        INVOKE  AllocMem

        CMP     EAX,0
        JE      AllocBMErr              ;  N - Error

        MOV     ECX,EAX
        JMP     AllocBMExit

ALIGN 4

AllocBMErr:

        rip     text,<alloc_bm Failed>

AllocBMExit:

        RET

alloc_bm ENDP
   
        SUBTITLE free_bm Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = free_bm
;*
;* DESCRIPTION   = This function frees the memory used by a no-longer-needed bitmap.  
;*                 The identifier for the bitmap is set to the deleted object
;*                 identifier.
;*                 The memory semaphore is acquired and released around the 
;*                 allocation
;*
;*                 Registers Preserved:         
;*                        SI,DI,DS,BP           
;*                 Registers Destroyed:         
;*                        AX,BX,CX,DX,ES,FLAGS  
;*
;* INPUT         = ESI = Pointer to bitmap to free
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

ALIGN 4

free_bm PROC    SYSCALL PUBLIC

IFDEF FIREWALLS

        CMP     [ESI].BITMAP.bm_sd.sd_usId,SURFACE_IDENT       ; Is it a bitmap?
        JNE     FreeBMBigProblems                       ;  N - Oops!
        TEST    [ESI].BITMAP.bm_sd.sd_fb,SD_DEVICE             ;  M - Really?
        JZ      @F                                      ;  Y - Whew!

FreeBMBigProblems:

        rip     text,<free_bm - Surface is not a bitmap>
@@:

ENDIF

        MOV     [ESI].DDC.ddc_usId,DELETED_IDENT        ; Indicate not valid
        MOV     EAX,ESI
        INVOKE  FreeMem


IFDEF FIREWALLS

        CMP     EAX,0                                   ; Successful?
        JNZ     @F                                      ;  Y - Go on

        rip     text,<Heap Manager returned an error while freeing an object>
@@:

ENDIF

        RET

free_bm ENDP
   
        SUBTITLE global_alloc
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = global_alloc
;*
;* DESCRIPTION   = This function allocates a block of memory of the requested size 
;*                 from the shared memory that is managed by the selector server 
;*                 component of the graphics engine.
;*
;*                 Registers Preserved:     
;*                        BX,SI,DI,DS,ES,BP 
;*                 Registers Destroyed:     
;*                        AX,CX,DX,FLAGS    
;*
;* INPUT         = EAX = Number of bytes needed                                       
;*                 ECX = Allocation flags (only valid one is OBJ_TILE)                
;*                 EBX = Pointer to buffer into which pointer to allocated memory 
;*                       block will be placed
;*
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = ECX = 0 
;* RETURN-ERROR  = ECX = OS/2 error code 
;*
;**************************************************************************/

ALIGN 4

global_alloc PROC SYSCALL PUBLIC

        or      eax,EAX                 ; Don't allocate if they want 0 bytes
        JZ      GlobalAllocDone
        INVOKE  AllocMem

        MOV     DWORD PTR [EBX],EAX
        XOR     ECX,ECX                 ; ECX = completion status
        CMP     EAX,0
        JNE     GlobalAllocDone

GA_FAIL:

        rip     text,<global_alloc Failed>
        MOV     ECX,PMERR_INSUFFICIENT_MEMORY

GlobalAllocDone:

        RET

global_alloc ENDP
   
        SUBTITLE global_free
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = global_free
;*
;* DESCRIPTION   = This function frees a global memory block.                
;*
;*                 Registers Preserved:            
;*                        BX,CX,DX,SI,DI,DS,ES,BP  
;*                 Registers Destroyed:            
;*                        AX,FLAGS                 
;*
;* INPUT         = ECX = Pointer to block to free 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = OS/2 return code
;* RETURN-ERROR  = EAX = OS/2 return code
;*
;**************************************************************************/

ALIGN 4

global_free PROC SYSCALL PUBLIC

        MOV     EAX,ECX
        INVOKE  FreeMem
        
IFDEF FIREWALLS

        CMP     EAX,NO_ERROR
        JE        @F
        rip        text,<global_free Failed>

@@:

ENDIF

        RET

global_free ENDP
   
        SUBTITLE private_alloc Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = private_alloc
;*
;* DESCRIPTION   = This function allocates a block of private memory of the 
;*                 requested size. It differs from the AllocMem function in that 
;*                 it uses the DosAllocMem function.  One of the consequences of 
;*                 this is that memory is allocated in 4K chunks; therefore, 
;*                 excessive allocation of blocks of memory that are n * 4096 + m 
;*                 in size, where m << 4096, can be quite wasteful of memory.                                                                 
;*
;*                 Registers Preserved:      
;*                        BX,SI,DI,DS,ES,BP  
;*                 Registers Destroyed:      
;*                        AX,CX,DX,FLAGS     
;*
;* INPUT         = EAX = Requested size of block.  The size is rounded up to the 
;*                       next 4K.
;*                 EBX = Pointer to a PBYTE buffer into which the pointer to the     
;*                       allocated memory block will be placed upon return.          
;*
;* OUTPUT        = [EBX] = Pointer to allocated memory block.
;*                                          
;* RETURN-NORMAL = ECX   = NO_ERROR 
;* RETURN-ERROR  = ECX = OS/2 error code
;*
;**************************************************************************/

ALIGN 4

private_alloc PROC SYSCALL PUBLIC

        CALL    AllocMem
        cmp     eax,0
        jnz     pa_noerror
        mov     ecx,PMERR_INSUFFICIENT_MEMORY
        jmp     PrivateAllocDone

ALIGN 4

pa_noerror:

        mov     DWORD PTR [ebx],eax
        mov     ecx,0

PrivateAllocDone:

        RET

private_alloc ENDP
   
        SUBTITLE private_free Function
        PAGE +

;/***************************************************************************
;*
;* FUNCTION NAME = private_free
;*
;* DESCRIPTION   = This function frees the memory allocated with the private_alloc  
;*                 function.                                                        
;*
;*                 Registers Preserved:           
;*                        BX,CX,DX,SI,DI,DS,ES,BP 
;*                 Registers Destroyed:           
;*                        AX,FLAGS                
;*
;* INPUT         = ECX = Pointer to memory block to free 
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = EAX = OS/2 return status
;* RETURN-ERROR  = EAX = OS/2 error code 
;*
;**************************************************************************/

ALIGN 4

private_free PROC SYSCALL PUBLIC

        mov     eax,ecx
        CALL    FreeMem

IFDEF FIREWALLS

        OR      EAX,EAX
        JNZ     @F

        rip text,<Heap Manager returned an error while freeing memory (private_free)>

        mov     eax,PMERR_INSUFFICIENT_MEMORY
        jmp     pf_exit

ALIGN 4

@@:

ENDIF
        mov     eax,0

pf_exit:        

        RET

private_free ENDP
   

        END
