rdos/lib/earlymcb.asm

66 lines
1.7 KiB
NASM

%define mcb_first 0x5F
; This alloc uses an MCB-like list always starting at a fixed offset.
; Boot components may use it to allocate space during early boot.
; The list ends with the most recently allocated arena at its end,
; contrary to how the MCBs work on DOS.
; Memory Layout:
; 0000 Interrupt table
; 0400 BIOS data area
; 05F0 16 bytes Arena header 1
; 0600 BX paragraphs Arena 1
; .... 16 bytes Arena header 2
; .... BX paragraphs Arena 2
; ...
; .... 16 bytes Arena header n
; .... BX paragraphs Arena n
; Unmanaged memory
; Take note that this mechanism works differently than under DOS -
; but this one is optimized for fast and small alloc.
; Typical usecases:
; - Diskette Parameter Table (See interrupt 1Eh)
; - Partition table
; - Boot sector relocations
; - Boot sector data (FAT table, rootdir)
; Allocate paragraphs in unmanaged memory
; IN BX requested memory in paragraphs
; OUT AX output segment
early_alloc:
push ds
push bx
push si
; si is used as zero register
; this allows the opcodes to use a byte as disp instead of word
xor si, si
mov ax, mcb_first
.next:
mov ds, ax
inc ax
; DS is seg of arena header
; AX is seg of arena
cmp BYTE [si], 0x4D
jne .here
add ax, WORD [si+3]
jmp .next
.here:
; mark as item
mov BYTE [si], 0x4D
; write segment length in paragraphs
mov WORD [si+3], bx
; if allocation is higher than CS, then we are in managed memory
; set ourself as owner then, otherwise use dummy value 8
mov bx, cs
cmp ax, bx ; CF = CS in unmanaged memory
jnc .setup_owner
mov bx, 8
.setup_owner:
mov WORD [si+1], bx
pop si
pop bx
pop ds
ret