rdos/kernel/malloc.asm
2019-08-31 12:00:33 +00:00

173 lines
2.6 KiB
NASM

; All these functions assume DS=0 and ES=0
malloc_reserve:
push bx
call malloc_mark_allocated
pop bx
add bx, 0x10
loop malloc_reserve
ret
malloc_reset:
xor ax, ax
mov es, ax
call malloc_get_table
mov cx, 0x100 ; 256 words
rep stosw
; reserve IVT and BDA, the extra data area and this table itself
xor bx, bx
mov cx, 0x80
call malloc_reserve
; reserve location for chainloaded boot sector
mov bx, 0x7C00
mov cx, 0x20
call malloc_reserve
ret
; Input:
; 0:BX - ptr to mem paragraph
; Output:
; AL - bitmask for byte in table
; BX - offset in table
malloc_calc_offsets:
; ch is bit offset
; cl is operand for bit shifts
push cx
; strip last 4 bits (offset within paragraph)
mov cl, 4
shr bx, cl
; backup the next 3 bits of bx (wll be bit offset)
mov ch, bl
and ch, 0x07
; calculate byte offset by shifting off 3 bits
mov cl, 3
shr bx, cl
; setup bit mask in al, shifted by bit offset
mov al, 0x01
mov cl, ch
shl al, cl
pop cx
; fallthrough to setup DI
malloc_get_table:
mov di, 0x0600
ret
; IN: 0:BX ptr to paragraph to be marked as allocated
malloc_mark_allocated:
call malloc_calc_offsets
or byte [bx+di], al
ret
malloc_dump:
call malloc_get_table
mov si, di
mov cx, 0x200
xor dx, dx
.loop:
lodsb
call print8
xor ah, ah
call popcnt
add dx, ax
loop .loop
mov cl, 6
shr dx, cl
push dx
call printf
db " data %UkB", 0x0A, 0x0D, 0x00
pop dx
ret
; Allocate a paragraph
; out BX ptr
malloc:
; search for a byte that is not 0xFF
call malloc_get_table
mov cx, 0x0200
mov al, 0xFF
repe scasb
je fatal_oom
dec di
mov al, [es:di]
sub di, 0x0600
mov cl, 3
shl di, cl
jmp .ishere
; advance one bit each time
.nextbit:
inc di
shr al, 1
.ishere:
test al, 1
jnz .nextbit
mov cl, 4
shl di, cl
mov bx, di
call malloc_mark_allocated
mov bx, di
ret
; Free a paragraph
; IN: 0:BX ptr to paragraph to be marked as free
free:
call malloc_calc_offsets
not al
and byte [bx+di], al
ret
; Allocate a sector, 512 bytes or 32 paragraphs
; OUT BX ptr to sector
malloc_sector:
call malloc_get_table
mov cx, 0x0200
xor ax, ax
.continue:
repne scasw
jne fatal_oom
; we need a second word to be 0, otherwise continue search
scasw
jne .continue
sub di, 4
not ax
stosw
stosw
sub di, 0x604
mov cl, 7
shl di, cl
xchg bx, di
ret
; Free a sector
; IN BX ptr to sector
free_sector:
call malloc_calc_offsets
xor ax, ax
add di, bx
stosw
stosw
ret
fatal_oom:
call printf
db "PANIC OOM", 0x0A, 0x0D, 0x00
clip
.loop:
hlt
jmp .loop