;*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
        include tune.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
;*/

_TUNE SEGMENT DWORD FLAT PUBLIC 'CODE'
        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
_TUNE ENDS
        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
_TUNE SEGMENT DWORD FLAT PUBLIC 'CODE'
        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
_TUNE ENDS

        END
