I made some macros (which will inline the code since it's so small) to handle allocation in pooled memory and I thought I'd share it.
Code: Select all
; Lib project
; Copyright (C) 2009, Cryzbl
;
; File pool.inc
; Easily create pooled memory
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef _POOL_INC
#define _POOL_INC
#include "lib/macros.inc"
;; ==== POOL_INIT ====
;; Initializes the pool, number of elements known at runtime
;; pre:
;; bc = number of elements to store, has to be larger then 2
;; post:
;; Pool is initialized
INLINE POOL_INIT(base, elem)
INLINE_PRE ld hl, base+2
INLINE_PRE ld (base), hl ; Initialize firstfree pointer
INLINE_PRE MOV_DE_HL
INLINE_PRE dec bc ; We manually initialize the last element
INLINE_PRE LOOPBC_INIT
INLINE_PRE _loop:
INLINE_PRE ld a, elem
INLINE_PRE ADD_DE_A
INLINE_PRE MOV_IHL_DE ; Write ptr to current element
INLINE_PRE MOV_HL_DE ; Advance to next element
INLINE_PRE LOOPBC(_loop)
INLINE_PRE MOV_IHL_BC ; Zero the last element to signal end of pool
INLINE_END
;; ==== POOL_INIT ====
;; Initializes the pool, number of elements known at assemble time
;; post:
;; Pool is initialized
INLINE POOL_INIT(base, elem, total)
INLINE_PRE ld hl, base+2
INLINE_PRE ld (base), hl ; Initialize firstfree pointer
INLINE_PRE MOV_DE_HL
INLINE_PRE LOOPBC_INIT(total-1)
INLINE_PRE _loop:
INLINE_PRE ld a, elem
INLINE_PRE ADD_DE_A
INLINE_PRE MOV_IHL_DE ; Write ptr to current element
INLINE_PRE MOV_HL_DE ; Advance to next element
INLINE_PRE LOOPBC(_loop)
INLINE_PRE ld (base+2+((total-1)*elem)), bc
INLINE_END
;; ==== POOL_ALLOC_SAFE ====
;; Allocates a resource in the pool, checks if there's enough memory
;; post:
;; carry = set means fail, reset means successful
;; hl = if successful this points to the allocated data
;; Destroys af, bc
INLINE POOL_ALLOC_SAFE(base)
INLINE_PRE ld hl, (base) ; Ptr to firstfree
INLINE_PRE OR_HL ; Zero indicates end of pool
INLINE_PRE scf
INLINE_PRE jr z, _done
INLINE_PRE MOV_DE_IHL
INLINE_PRE dec hl
INLINE_PRE ld (base), de ; Store next element from the free list in firstfree
INLINE_PRE ccf
INLINE_PRE _done:
INLINE_END
;; ==== POOL_ALLOC ====
;; Allocates a resource in the pool, does not check if there is enough memory
;; post:
;; hl = if successful this points to the allocated data
;; Destroys bc
INLINE POOL_ALLOC(base)
INLINE_PRE ld hl, (base) ; Ptr to firstfree
INLINE_PRE MOV_DE_IHL
INLINE_PRE dec hl
INLINE_PRE ld (base), de ; Store next element from the free list in firstfree
INLINE_END
;; ==== POOL_FREE ====
;; Frees allocated data from a pool
;; pre:
;; hl = pointer to allocated data
;; post:
;; Data deallocated
;; Destroys de
INLINE POOL_FREE(base)
INLINE_PRE ld de, (base) ; Ptr to firstfree
INLINE_PRE MOV_IHL_DE ; Make the current element point to the firstfree element
INLINE_PRE dec hl
INLINE_PRE ld (base), hl ; Make current element the firstfree
INLINE_END
#endif
; -----------------------------
; End of file
; -----------------------------
http://paste.krus.dk/index.php?id=825252018
Example usage would be
Code: Select all
POOL_INIT(mypool, 4, 50) ; NEVER MAKE A POOL WITH ELEMENT SIZE 1.
; We created a pool for 50 elements of each 4 bytes in size. Total size required is 2+4*50 = 202
; Now we can allocate stuff in it
POOL_ALLOC(mypool)
; hl now points to a 4 byte resource, do whatever you want
push hl
; Let's alloc some more
POOL_ALLOC(mypool)
POOL_ALLOC(mypool)
; It's a bad idea to delete the handles but this is just an example, so let's just ignore them
pop hl
; Now we free the first resource we allocated.
POOL_FREE(mypool)
ret
mypool:
.fill 202, 0; 202 bytes filled with zeros