macro bios_a20_enable { mov ax, 0x2401 int 0x15 } macro bios_vga_write_mode_3 { mov ax, 0x03 int 0x10 } ; assumes dl = drive number macro bios_disk_read dst*, cyl*, head*, sector*, count*, err_label* { local read_disk assert 0 <= cyl & cyl <= 1023 assert 0 <= head & head <= 15 assert 1 <= sector & sector <= 17 assert 1 <= count & count <= 128 ; try to read disk up to 3 times mov di, 3 read_disk: ; ah = 0x02, al = number of sectors to read mov ax, (0x0200 or count) ; es:bx = pointer to destination buffer if dst = 0 xor bx, bx else mov bx, dst end if ; ch = track/cylinder number, cl = sector number mov cx, ((cyl and 0xff) shl 8) or ((cyl and 0x300) shl 6) or sector ; dh = head number if head = 0 xor dh, dh else mov dh, head end if int 0x13 jc .error cmp ax, count jne .error jmp .exit .error: dec di jz err_label ; reset disk on error xor ah, ah stc int 0x13 jc err_label jmp read_disk .exit: } macro bios_e820_mmap mmap*, err_label* { local e820, e820_entry e820: virtual at di label e820_entry .base dq ? .length dq ? .type dd ? .ext_attr dd ? .sizeof = $ - e820_entry end virtual mov di, mmap + 8 xor ebx, ebx xor bp, bp mov edx, 0x0534d4150 mov eax, 0xe820 mov byte [.ext_attr], 0x01 mov ecx, .sizeof int 0x15 jc err_label mov edx, 0x0534d4150 cmp eax, edx jne err_label test ebx, ebx jz err_label jmp @f .e820_loop: mov ax, 0xe820 mov byte [.ext_attr], 0x01 mov ecx, .sizeof int 0x15 jc err_label mov edx, 0x0534d4150 @@: jcxz .skip_entry ; ACPI < 3.0 cmp cl, (.sizeof-4) jbe .not_ext ; ignore data flag test byte [.ext_attr], 0x01 jz .skip_entry .not_ext: mov ecx, dword [.length] or ecx, dword [.length + 4] jz .skip_entry inc bp add di, .sizeof .skip_entry: test ebx, ebx jnz .e820_loop ; store e820 mmap entry count at beginning mov [mmap], bp }