Implement block-based heap

This commit is contained in:
Nero 2019-03-24 14:45:53 +00:00
parent 6f7815bbe2
commit 0414af640a

View File

@ -1,12 +1,14 @@
heap_size:
dw 0x0100
; 1 step here means 1 byte heap alloc table + 16 byte heap data
; 0x0400 = 1kB table, 16kb data
dw 0x0400
heap_init:
push ax ; byte value (0)
push cx ; loop counter
push di ; target ptr
push es
mov ax, ds
mov ax, cs
mov es, ax
xor ax, ax
mov cx, [heap_size]
@ -21,12 +23,62 @@ heap_init:
; in ax number of bytes to alloc
; out ds:di
malloc:
push dx ; length of block index
or ax,0x0F
inc ax
mov dx, 0x100
mov bp, heap
push cx ; number of blocks to allocate
push bp ; base offset for block table
push es
int 0x2E
pop dx
; transfer 12 MSB from ax to cx
add ax, 0x000F
mov cl, 0x04
shr ax, cl
mov cx, ax
mov bp, heap
mov di, 0x0000
mov ax, ds
mov es, ax
xor ah, ah ; we use ax for reading from al once
jmp .firstblock
.testlength:
push cx
push di
add di, bp ; scasb doesn't add bp on its own
repe scasb
pop di
pop cx
je .found
; find next free item
mov al, 0x01
.nextblock:
add di, ax
.firstblock:
mov al, [bp+di]
cmp al, 0x00
jne .nextblock
cmp cx, 0x0001 ; fast case: 1 block allocation, skip test if length fits
jne .testlength
.found:
mov [bp+di], cl
mov cl, 0x04
shl di, cl
add di, bp
add di, [heap_size]
pop es
pop bp
pop cx
ret
; in ds:di begin of data block to free (di trashed)
free:
push cx
push bp
mov bp, heap
sub di, [heap_size]
sub di, bp
mov cl, 0x04
shr di, cl
mov byte [bp+di], 0x00
pop bp
pop cx
ret