bits 16 org 0x7c3e kernel_sectors equ 64 kernel_segment equ 0x3000 support_flags equ 0x4000 pci_hw_char equ 0x4001 pci_ver equ 0x4002 last_pci_bus equ 0x4004 bios_mmap_len equ 0x4006 vbe_mode equ 0x4008 vbe_block equ 0x4200 vbe_mode_info equ 0x4400 pci_support equ 0x80 pae_support equ 0x40 in al, 0x92 or al, 0x02 out 0x92, al xor ax, ax mov ss, ax mov sp, 0x8000 mov ax, kernel_segment mov es, ax mov ax, 0x0200 + kernel_sectors xor bx, bx mov cx, 0x0002 xor dh, dh int 0x13 mov ax, 0xb101 int 0x1a cmp edx, 0x20494350 jne no_pci test ah, ah jnz no_pci mov byte [support_flags], pci_support mov byte [pci_hw_char], al mov word [pci_ver], bx mov byte [last_pci_bus], cl no_pci: mov eax, 1 cpuid test dl, 0x40 jz no_pae or byte [support_flags], pae_support no_pae: mov ax, 0x1000 mov es, ax xor di, di mov edx, 0x534d4150 xor ebx, ebx mmap_loop: mov eax, 0xe820 mov ecx, 24 int 0x15 jc mmap_end add di, 24 test ebx, ebx jnz mmap_loop mmap_end: mov word [bios_mmap_len], di xor ax, ax mov es, ax mov di, vbe_block mov ah, 0x4f mov dword [di], 0x32454256;'VBE2' int 0x10 cmp dword [di], 0x41534556;'VESA' jne no_vbe mov bx, word [di + 0x0e] mov ax, word [di + 0x10] mov fs, ax xor esi, esi mov bp, 0xffff mov di, 0x5000 vbe_loop: max_height equ 800 ;fs:bx is mode pointer ;esi is highest resolution yet (width * height) ;bp is that mode's number ;uses 0x5000 - 0x50ff as mode info buffer ;skips those without byte-aligned pixels mov cx, word [fs:bx] cmp cx, 0xffff je got_highest_vbe add bx, 4 mov ax, 0x4f01 int 0x10 mov al, byte [di] not al test al, 0x9a jnz vbe_loop mov dx, word [di + 0x14];height cmp dx, max_height jg vbe_loop mov ax, word [di + 0x12];width mul dx shl edx, 16 mov dx, ax xor eax, eax mov al, byte [di + 0x19];bpp test al, 0x07 jnz vbe_loop mul edx cmp eax, esi jle vbe_loop mov esi, eax mov bp, cx jmp vbe_loop got_highest_vbe: cmp bp, 0xffff je no_vbe mov cx, bp mov ax, 0x4f01 mov di, vbe_mode_info int 0x10 or ch, 0x40 mov word [vbe_mode], cx mov ax, 0x4f02 mov bx, cx int 0x10 cli lgdt [gdt] mov eax, cr0 or al, 0x01 mov cr0, eax jmp 0x10:pmode no_vbe: xor ax, ax mov es, ax mov ax, 0x1300 mov bx, 0x004f mov cx, no_vbe_str.len xor dx, dx mov bp, no_vbe_str int 0x10 real_halt: hlt jmp real_halt no_vbe_str: db "NO VBE2!" .len equ $ - no_vbe_str bits 32 pmode: mov ax, 0x18 mov ds, ax mov es, ax mov ss, ax mov esp, 0x00040000 xor ebp, ebp call kernel_segment * 16 halt: hlt jmp halt times $$ + 510 - 0x3e - $ - (gdt.e - gdt) db 0 gdt: dw .e - .t dd .t .t: dq 0x0000_0000_0000_0000;0x00: null dq 0x0040_8900_4f98_0068;0x08: tss, 0x4f98 dq 0x00cf_9a00_0000_ffff;0x10: kernel code dq 0x00cf_9200_0000_ffff;0x18: kernel data dq 0x00cf_fa00_0000_ffff;0x20: user code dq 0x00cf_f200_0000_ffff;0x28: user data .e: dw 0xaa55