diff options
Diffstat (limited to 'boot/bios.inc')
-rw-r--r-- | boot/bios.inc | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/boot/bios.inc b/boot/bios.inc new file mode 100644 index 0000000..ccc94e3 --- /dev/null +++ b/boot/bios.inc @@ -0,0 +1,128 @@ +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 + 4 + 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 +} |