;****************************************************************************
; Filename: MALLOC.ASM
; Author: Peter Andersson
; Version: 0.0
; Created: 1994.12.25
; Updated: -
;****************************************************************************
; Copyright Peter Andersson, 1994-1995.
; All rights reserved.
;****************************************************************************
; Function: PVOID @malloc(ULONG blocksize);
; Input: Eax, blocksize - size of block to allocate
; Output: pointer to the allocated memory or NULL
; Comment: PALallocate allocates a memory block from the global heap memory.
; It returns a pointer to the allocated memory block or NULL if not
; enough memory is available.
;****************************************************************************
Include STDDEF.INC
Include "MEMORY.INC"
Codeseg
Proc malloc ,1
TestZ Eax ; If zero size is requested then exit
Jz @@Exit01
Push Ebx
Add Eax,Size AllocBlock ; Add the header size
Adjust Eax,MEMALIGN ; Align the requested block size
GetSize Edx,Eax
@@Next01: Mov Ebx,[Edx+FreeBlock.NextFree] ; Get the bit block pointer
Mov Ecx,[Ebx+FreeBlock.BlockSize] ; Get the block size
Jecxz @@Next03 ; If the block size is zero then abort the loop
Sub Ecx,Eax ; Check the block size and
Jae @@Next06 ; jump if it's big enough
@@Next02: Mov Ebx,[Ebx+FreeBlock.NextFree] ; Get the next free pointer
Mov Ecx,[Ebx+FreeBlock.BlockSize] ; Get the block size
Jecxz @@Next03 ; If the block size is zero then abort loop
Sub Ecx,Eax ; Check the block size and
Jae @@Next06 ; jump if it's big enough
Mov Ebx,[Ebx+FreeBlock.NextFree] ; Get the next free pointer
Mov Ecx,[Ebx+FreeBlock.BlockSize] ; Get the block size
Jecxz @@Next03 ; If the block size is zero then abort loop
Sub Ecx,Eax ; Check the size and
Jb @@Next02 ; don't jump if it's big enough
Jmp @@Next06
Align 4
@@Next03: Add Edx,Size FreeBlock ; Get next pointer from the free pointer list
Cmp Edx,Offset BlockTableEnd ; Reached the end?
Jne @@Next01 ; No, jump and do another lap
Pop Ebx
Clear Eax ; Return a NULL pointer
Ret
Align 4
@@Next06: Cmp Ecx,Size FreeBlock+MEMALIGN ; Jump if it can can't split the block
Jb @@Next08
Mov [Ebx+AllocBlock.BlockSize],Eax ; Store the new block size
Add Eax,Ebx ; Calculate a new pointer to the free block
Mov Edx,[Ebx+FreeBlock.NextFree] ; Save the old NextFree pointer
Mov [Eax+FreeBlock.BlockSize],Ecx ; Fix the free header
Mov [Eax+FreeBlock.PrevBlock],Ebx ; Make the free header
Add Ecx,Eax ; Get pointer to the next block
Mov [Ecx+AllocBlock.PrevBlock],Eax
Mov Ecx,[Ebx+FreeBlock.PrevFree]
Mov [Edx+FreeBlock.PrevFree],Ecx
Mov [Ecx+FreeBlock.NextFree],Edx
Mov Ecx,[Eax+FreeBlock.BlockSize]
GetSize Edx,Ecx
Mov Ecx,[Edx+FreeBlock.NextFree] ; Get the old pointer and insert it into
Mov [Eax+FreeBlock.PrevFree],Edx ; the new free block list
Mov [Ecx+FreeBlock.PrevFree],Eax
Mov [Ebx+AllocBlock.Ident],ALLOCID ; Mark the block as allocated
Mov [Edx+FreeBlock.NextFree],Eax
Mov [Eax+FreeBlock.NextFree],Ecx
Lea Eax,[Ebx+Size AllocBlock] ; Return pointer to to the allocated block
Pop Ebx
Ret
Align 4
@@Next08: Mov Ecx,[Ebx+FreeBlock.NextFree] ; Remove block from the free pointer list
Mov Edx,[Ebx+FreeBlock.PrevFree]
Mov [Ebx+AllocBlock.Ident],ALLOCID ; Mark the block as allocated
Mov [Edx+FreeBlock.PrevFree],Ecx
Mov [Ecx+FreeBlock.NextFree],Edx
Lea Eax,[Ebx+Size AllocBlock] ; Return pointer to the allocated block
Pop Ebx
@@Exit01: Ret
Endp
End