diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2022-10-06 16:45:17 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2022-10-06 16:45:17 +0200 |
commit | f8397815545adb7d0da36614e0065aa68453a2e4 (patch) | |
tree | a771f526970c6724b2511577dceece8783450a49 /stage2/vesa.asm | |
download | cuddles-f8397815545adb7d0da36614e0065aa68453a2e4.tar.xz |
Initial commit
Diffstat (limited to 'stage2/vesa.asm')
-rw-r--r-- | stage2/vesa.asm | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/stage2/vesa.asm b/stage2/vesa.asm new file mode 100644 index 0000000..da7eb81 --- /dev/null +++ b/stage2/vesa.asm @@ -0,0 +1,190 @@ +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 $ + + ;ret + + ; 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 $ |