]> git.lizzy.rs Git - nyax.git/blobdiff - stage2/vesa.asm
Page calculation
[nyax.git] / stage2 / vesa.asm
diff --git a/stage2/vesa.asm b/stage2/vesa.asm
new file mode 100644 (file)
index 0000000..5335896
--- /dev/null
@@ -0,0 +1,188 @@
+vesa:
+       ; print message
+       mov ebx, .msg
+       call print_str
+
+       ; get vesa bios info
+       mov eax, dword[.vbe2]
+       mov dword[VESAINFO], eax ; move "VBE2" to start of vesainfo struct
+       mov ax, 0x4F00           ; get VESA BIOS information
+       mov di, VESAINFO         ; struct buffer
+       int 0x10
+
+       cmp ax, 0x004F           ; check ax for correct magic number
+       jne .fail_getinfo
+
+       mov eax, dword[.vesa]
+       cmp dword[VESAINFO], eax ; check if "VESA" is at start of stuct
+       jne .fail_getinfo
+
+       ; print select message
+       mov ebx, .select_msg
+       call print_str
+
+       ; get segment:offset pointer to video modes into gs:ebx
+       movzx ebx, word[VESAINFO+14]
+       mov    ax, word[VESAINFO+16]
+       mov gs, ax
+
+       ; convert modes to own structure
+
+       xor esi, esi        ; number of avail modes
+
+.mode_loop:
+       ; get mode info
+       mov cx, [gs:ebx]    ; video mode into cx
+       cmp cx, 0xFFFF      ; 0xFFFF is terminator, no suitable mode has been found
+       je .mode_done
+       mov ax, 0x4F01      ; get VESA mode information
+       mov di, VESAMODE    ; vesa mode info struct buffer
+       int 0x10
+
+       cmp ax, 0x004F      ; check ax for correct magic number
+       jne .fail_modeinfo
+
+       mov al, byte[VESAMODE] ; get attributes
+       and al, 0b10000000     ; extract bit 7, indicates linear framebuffer support
+       jz .mode_next
+
+       mov al, byte[VESAMODE+25] ; get bpp (bits per pixel)
+       cmp al, 32
+       jne .mode_next
+
+       push ebx ; print_dec and print_str modify ebx
+
+       mov eax, esi
+       mov ebx, 12
+       mul ebx
+       mov edi, eax
+       add edi, OWNMODE
+
+       mov [edi+10], cx ; copy mode
+
+       ; print selector
+       mov al, '['
+       call print_chr
+
+       mov eax, esi
+       add eax, 'a'
+       call print_chr
+
+       mov al, ']'
+       call print_chr
+
+       mov al, ' '
+       call print_chr
+
+       mov ax, [VESAMODE+16] ; copy pitch
+       mov [edi+0], ax
+
+       movzx eax, word[VESAMODE+18] ; copy width
+       mov [edi+2], ax
+       call print_dec
+
+       mov al, 'x'
+       call print_chr
+
+       movzx eax, word[VESAMODE+20] ; copy height
+       mov [edi+4], ax
+       call print_dec
+       call newline
+
+       mov eax, [VESAMODE+40] ; copy framebuffer
+       mov [edi+6], eax
+
+       pop ebx
+
+       inc esi
+       cmp esi, 'z'-'a'   ; only print up to z
+       jg .mode_done
+
+.mode_next:
+       add ebx, 2         ; increase mode pointer
+       jmp .mode_loop     ; loop
+
+.mode_done:
+       cmp esi, 0
+       je .fail_nomode
+
+.input:
+       mov ebx, .select_prompt
+       call print_str
+
+       mov ah, 0x00   ; get keypress, blocking
+       int 0x16
+
+       call print_chr ; echo user input
+
+       movzx edi, al  ; backup al
+       call newline
+
+       sub edi, 'a'
+       cmp edi, esi
+       jb .valid      ; check validity
+
+       mov ebx, .invalid
+       call print_str
+
+       jmp .input
+
+.valid:
+       ; convert selected number to address
+       mov eax, edi
+       mov ebx, 12
+       mul ebx
+       add eax, OWNMODE
+
+       ; copy to final gfx info location
+       mov ebx, [eax+0]
+       mov [GFXINFO+0], ebx
+
+       mov ebx, [eax+4]
+       mov [GFXINFO+4], ebx
+
+       mov bx, [eax+8]
+       mov [GFXINFO+8], bx
+
+       ;mov edi, eax
+       ;mov eax, [edi+6]
+       ;call print_hex
+       ;call newline
+       ;mov eax, edi
+       ;jmp $
+
+       ; set mode
+       mov bx, [eax+10]           ; video mode in bx (first 13 bits)
+       or  bx, 1 << 14            ; set bit 14: enable linear frame buffer
+       and bx, 0b0111111111111111 ; clear deprecated bit 15
+       mov ax, 0x4F02             ; set VBE mode
+       int 0x10
+
+       ret
+
+.msg: db "setting up vesa", 10, 13, 0
+.vbe2: db "VBE2"
+.vesa: db "VESA"
+.select_msg: db "avaliable video modes:", 10, 13, 0
+.select_prompt: db "select video mode: ", 0
+.invalid: db "invalid input", 10, 13, 0
+
+.fail_getinfo:
+       mov ebx, .fail_getinfo_msg
+       jmp .fail
+
+.fail_modeinfo:
+       mov ebx, .fail_modeinfo_msg
+       jmp .fail
+
+.fail_nomode:
+       mov ebx, .fail_nomode_msg
+       jmp .fail
+
+.fail_getinfo_msg: db "failed getting vesa bios info", 10, 13, 0
+.fail_modeinfo_msg: db "failed getting video mode info", 10, 13, 0
+.fail_nomode_msg: db "no suitable video modes available", 10, 13, 0
+
+.fail:
+       call print_str
+       jmp $