123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- ; vim: ts=4:et:sw=4:
- ; Copyleft (K) by Jose M. Rodriguez de la Rosa
- ; (a.k.a. Boriel)
- ; http://www.boriel.com
- ;
- ; This ASM library is licensed under the BSD license
- ; you can use it for any purpose (even for commercial
- ; closed source programs).
- ;
- ; Please read the BSD license on the internet
- ; ----- IMPLEMENTATION NOTES ------
- ; The heap is implemented as a linked list of free blocks.
- ; Each free block contains this info:
- ;
- ; +----------------+ <-- HEAP START
- ; | Size (2 bytes) |
- ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | <free bytes...>| | <-- If Size > 4, then this contains (size - 4) bytes
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | <free bytes...>| |
- ; | (0 if Size = 4)| |
- ; +----------------+ |
- ; <Allocated> | <-- This zone is in use (Already allocated)
- ; +----------------+ <-+
- ; | Size (2 bytes) |
- ; +----------------+
- ; | Next (2 bytes) |---+
- ; +----------------+ |
- ; | <free bytes...>| |
- ; | (0 if Size = 4)| |
- ; +----------------+ <-+
- ; | Next (2 bytes) |--> NULL => END OF LIST
- ; | 0 = NULL |
- ; +----------------+
- ; | <free bytes...>|
- ; | (0 if Size = 4)|
- ; +----------------+
- ; When a block is FREED, the previous and next pointers are examined to see
- ; if we can defragment the heap. If the block to be breed is just next to the
- ; previous, or to the next (or both) they will be converted into a single
- ; block (so defragmented).
- ; MEMORY MANAGER
- ;
- ; This library must be initialized calling __MEM_INIT with
- ; HL = BLOCK Start & DE = Length.
- ; An init directive is useful for initialization routines.
- ; They will be added automatically if needed.
- #init "__MEM_INIT"
- ; ---------------------------------------------------------------------
- ; __MEM_INIT must be called to initalize this library with the
- ; standard parameters
- ; ---------------------------------------------------------------------
- __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and
- ;- ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start
- ;- ld de, ZXBASIC_HEAP_SIZE ; Change this with your size
- ; ---------------------------------------------------------------------
- ; __MEM_INIT2 initalizes this library
- ; Parameters:
- ; HL : Memory address of 1st byte of the memory heap
- ; DE : Length in bytes of the Memory Heap
- ; ---------------------------------------------------------------------
- __MEM_INIT2:
- ; HL as TOP
- ;- PROC
- ;- dec de
- ;- dec de
- ;- dec de
- ;- dec de ; DE = length - 4; HL = start
- ; This is done, because we require 4 bytes for the empty dummy-header block
- eor z80_a ;- xor a
- lda z80_a ;- ld (hl),a
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl
- bne *+4
- inc z80_h
- lda z80_a ;- ld (hl),a ; First "free" block is a header: size=0, Pointer=&(Block) + 4
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl
- bne *+4
- inc z80_h
- lda z80_h ;- ld b,h
- sta z80_b
- lda z80_l ;- ld c,l
- sta z80_c
- inc z80_c ;- inc bc
- bne *+4
- inc z80_b
- inc z80_c ;- inc bc ; BC = starts of next block
- bne *+4
- inc z80_b
- lda z80_c ;- ld (hl),c
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl
- bne *+4
- inc z80_h
- lda z80_b ;- ld (hl),b
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl ; Pointer to next block
- bne *+4
- inc z80_h
- lda z80_e ;- ld (hl),e
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl
- bne *+4
- inc z80_h
- lda z80_d ;- ld (hl),d
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl ; Block size (should be length - 4 at start); This block contains all the available memory
- bne *+4
- inc z80_h
- lda z80_a ;- ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block)
- ldy #$00
- sta (z80_hl),y
- inc z80_l ;- inc hl
- bne *+4
- inc z80_h
- lda z80_a ;- ld (hl),a
- ldy #$00
- sta (z80_hl),y
- ;- ld a,201
- ;- ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again
- rts ;- ret
- ;- ENDP
|