%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