66 lines
1.7 KiB
NASM
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
|