Metropoli BBS
VIEWER: resize.asm MODE: TEXT (ASCII)
;****************************************************************************
; Filename: RESIZE.ASM
;   Author: Peter Andersson
;  Version: 0.0
;  Created: 1995.01.26
;  Updated: -
;****************************************************************************
; Copyright Peter Andersson, 1994-1995.
; All rights reserved.
;****************************************************************************
; Function: PVOID @resize(PVOID blockptr,ULONG blocksize);
;    Input: Eax, blockptr - pointer to the block to be resized
;           Edx, blocksize - new size of the block
;   Output: pointer to resized block or NULL if it failed
;  Comment: @resize tries to resize a previously allocated block. If it
;           fails you must allocate a new block and copy the block to the
;           new block. OBSERVE: The new block size can't be zero, use
;           @free to release a block!
;****************************************************************************

        Include STDDEF.INC
        Include "MEMORY.INC"

        Codeseg

Proc    resize ,2
                TestZ   Eax                                                     ; Do not allow any NULL pointers...
                Jz      @@Exit01
                TestZ   Edx                                                     ; ...and do not allow any zero length requests
                Jz      @@Exit01
                Push    Ebx
                Lea     Ebx,[Eax-Size AllocBlock]
                Cmp     [Ebx+AllocBlock.Ident],ALLOCID                          ; Check the allocation block identifier
                Jne     @@Exit02
                Adjust  Edx,MEMALIGN                                            ; Align the request length
                Add     Edx,Size AllocBlock                                     ; Add the block header size to the AllocBlock
                Mov     Ecx,[Ebx+AllocBlock.BlockSize]                          ; Get the current block size
                Sub     Edx,Ecx                                                 ; and check if it is big enough
                Ja      @@Next01                                                ; Jump if too small
                Neg     Edx
                Cmp     Edx,Size FreeBlock+MINBLOCK                             ; Check if it can be split?
                Jb      @@Next02                                                ; Jump if can't be split
                Add     Ecx,Ebx                                                 ; Get the next block
                Cmp     [Ecx+AllocBlock.Ident],ALLOCID                          ; Check if the next block is allocated
                Je      @@Next03                                                ; Jump if it is allocated
                Mov     Eax,[Ecx+FreeBlock.NextFree]                            ; Remove the block from the free list
                Mov     Ebx,[Ecx+FreeBlock.PrevFree]
                Mov     [Eax+FreeBlock.PrevFree],Ebx
                Mov     [Ebx+FreeBlock.NextFree],Eax
                Mov     Ebx,[Ecx+FreeBlock.PrevBlock]
                Mov     Eax,[Ebx+AllocBlock.BlockSize]
                Mov     Ecx,[Ecx+FreeBlock.BlockSize]
                Sub     Eax,Edx
                Add     Ecx,Edx
                Jmp     @@Next04
        Align   4
@@Next03:       Mov     Eax,[Ebx+FreeBlock.BlockSize]
                Sub     Eax,Edx
                Mov     Ecx,Edx
@@Next04:       Mov     [Ebx+AllocBlock.BlockSize],Eax
                Add     Eax,Ebx
                Mov     [Eax+FreeBlock.PrevBlock],Ebx
                Mov     [Eax+Ecx+AllocBlock.PrevBlock],Eax
                Mov     [Eax+FreeBlock.BlockSize],Ecx                           ; Fix header
                GetSize Edx,Ecx
                Mov     Ecx,[Edx+FreeBlock.NextFree]                            ; Add it to the free list
                Mov     [Edx+FreeBlock.NextFree],Eax
                Mov     [Eax+FreeBlock.PrevFree],Edx
                Mov     [Eax+FreeBlock.NextFree],Ecx
                Mov     [Ecx+FreeBlock.PrevFree],Eax
@@Next02:       Lea     Eax,[Ebx+Size AllocBlock]
                Pop     Ebx
                Ret
        Align   4
@@Next01:       Add     Ecx,Ebx
                Cmp     [Ecx+AllocBlock.Ident],ALLOCID                          ; Check the next block's identifier
                Je      @@Exit02                                                ; Jump if it is allocated
                Cmp     Edx,[Ecx+AllocBlock.BlockSize]                          ; Check the free block's size
                Jb      @@Exit02                                                ; Jump if the block wasn't big enough
                Mov     Ebx,[Ecx+FreeBlock.NextFree]                            ; Remove the block from the free list
                Mov     Eax,[Ecx+FreeBlock.PrevFree]
                Mov     [Ebx+FreeBlock.PrevFree],Eax
                Mov     [Eax+FreeBlock.NextFree],Ebx
                Mov     Ebx,[Ecx+FreeBlock.PrevBlock]
                Mov     Ecx,[Ecx+FreeBlock.BlockSize]
                Mov     Eax,[Ebx+AllocBlock.BlockSize]
                Add     Eax,Edx
                Sub     Ecx,Edx
                Jmp     @@Next04
        Align   4
@@Exit02:       Clear   Eax
                Pop     Ebx
@@Exit01:       Ret
Endp

        End


[ RETURN TO DIRECTORY ]