diff options
Diffstat (limited to 'bincode.asm')
-rw-r--r-- | bincode.asm | 131 |
1 files changed, 125 insertions, 6 deletions
diff --git a/bincode.asm b/bincode.asm index ca96944..81201da 100644 --- a/bincode.asm +++ b/bincode.asm @@ -309,13 +309,17 @@ gfx_pal_tmp dd 0 ; (lin) pals dw 0 ; the current gfx mode +; note: for vbe modes, bit 14 (framebuffer mode) is always 0 +; fb_active is used to indicate whether to use fb drawing functions gfx_mode dw 3 ; != 0 if we're using a vbe mode (hi byte of gfx_mode) vbe_active equ gfx_mode + 1 -pixel_bits db 0 ; pixel size (8 or 16) -color_bits db 0 ; color bits (8, 15 or 16) +pixel_bits db 0 ; pixel size (8, 16, or 32) +color_bits db 0 ; color bits (8, 15, 16, or 24) pixel_bytes dd 0 ; pixel size in bytes +; framebuffer start +framebuffer dd 0 ; (lin) ; segment address of writeable window window_seg_w dw 0 ; segment address of readable window (= gfx_window_seg_w if 0) @@ -324,6 +328,8 @@ window_seg_r dw 0 window_inc db 0 ; currently mapped window mapped_window db 0 +; do we use the framebuffer for drawing? +fb_active db 0 ; cursor position gfx_cur equ $ ; both x & y @@ -3394,6 +3400,10 @@ set_mode_20: pop word [screen_width] push word [es:edi+14h] pop word [screen_height] + mov eax,[es:edi+28h] + mov [framebuffer],eax + or eax,eax + setnz byte [fb_active] movzx eax,byte [es:edi+1dh] inc eax @@ -3413,6 +3423,14 @@ set_mode_25: mov dh,[es:edi+1fh] ; red add dh,[es:edi+21h] ; green add dh,[es:edi+23h] ; blue + mov dl,dh + add dl,[es:edi+25h] ; reserved + + ; workaround for broken VBE info + ; assume pixel size (ah) to be at least r+g+b+reserved bits (dl) + cmp dl,ah + jbe set_mode_40 + mov ah,dl jmp set_mode_40 set_mode_30: cmp al,4 ; PL 8 @@ -3434,6 +3452,11 @@ set_mode_45: mov [pixel_bytes],ah mov [color_bits],dh + ; VBE linear framebuffer doesn't use win A / win B segments + ; skip the test and proceed + cmp byte [fb_active],0 + jnz set_mode_60 + ; we check if win A is readable _and_ writable; if not, we want ; at least a writable win A and a readable win B ; other, even more silly variations are not supported @@ -3479,8 +3502,13 @@ set_mode_50: jz set_mode_80 mov [window_inc],al mov byte [mapped_window],0ffh - mov ax,4f02h +set_mode_60: mov bx,[gfx_mode] + cmp byte [fb_active],0 + jz set_mode_70 + or bh,40h +set_mode_70: + mov ax,4f02h int 10h cmp ax,4fh jnz set_mode_80 @@ -3501,6 +3529,17 @@ set_mode_90: mode_init: ; graphics window selectors + cmp byte [fb_active],0 + jz mode_init_20 + + mov eax,[framebuffer] + mov si,pm_seg.screen_w16 + call set_gdt_base_pm + mov si,pm_seg.screen_r16 + call set_gdt_base_pm + jmp mode_init_40 + +mode_init_20: movzx eax,word [window_seg_w] shl eax,4 mov si,pm_seg.screen_w16 @@ -3508,12 +3547,13 @@ mode_init: movzx ecx,word [window_seg_r] shl ecx,4 - jz mode_init_05 + jz mode_init_30 mov eax,ecx -mode_init_05: +mode_init_30: mov si,pm_seg.screen_r16 call set_gdt_base_pm +mode_init_40: ; pixel get/set functions mov dword [setpixel],setpixel_8 @@ -5430,7 +5470,15 @@ prim_aend_10: jnz prim_aend_10 dec ecx - lea eax,[ecx+4*ecx+2] + + ; we need 5 * array_size + 2 bytes (for head) for our array + ; BUT... + ; +8: allocate a bit more memory than strictly necessary + ; else memory allocation gets corrupted on hyper-v (bnc #876640) + ; (part of the next block gets overwritten) + ; it's unclear, why + ; even with identical memory layout it doesn't break in other vms + lea eax,[ecx+4*ecx+2 + 8] push ecx call calloc @@ -7397,6 +7445,29 @@ prim_settype_90: ret +;; screen.framebuffer - ptr to framebuffer +; +; group: draw +; +; ( -- ptr1 ) +; +; ptr1: ptr to framebuffer or undef if no fb mode is active +; +; example +; screen.framebuffer +; + + bits 32 + +prim_screenframebuffer: + xor eax,eax + cmp byte [fb_active],0 + jz prim_screenframebuffer_90 + mov eax,[framebuffer] +prim_screenframebuffer_90: + jmp pr_getptr_or_none + + ;; screen.size - screen size in pixel ; ; group: gfx.screen @@ -9599,11 +9670,16 @@ prim_setmode: mov ecx,eax jmp prim_setmode_80 prim_setmode_30: + ; clear fb mode bit + and ah,~40h xchg [gfx_mode],ax + push eax call set_mode pop eax jnc prim_setmode_60 + + ; restore last mode xchg [gfx_mode],ax call set_mode stc @@ -12392,6 +12468,32 @@ set_win: jz set_win_90 cmp [mapped_window],al jz set_win_90 + cmp byte [fb_active],0 + jz set_win_40 + pusha + mov [mapped_window],al + mov ah,0 + shl eax,10h + add eax,[framebuffer] + mov si,pm_seg.screen_w16 + call set_gdt_base_pm + mov si,pm_seg.screen_r16 + call set_gdt_base_pm + + mov ax,fs + cmp ax,pm_seg.screen_r16 + jnz set_win_10 + mov fs,ax +set_win_10: + mov ax,gs + cmp ax,pm_seg.screen_w16 + jnz set_win_20 + mov gs,ax +set_win_20: + + popa + jmp set_win_90 +set_win_40: pusha mov [mapped_window],al mov ah,[window_inc] @@ -12813,6 +12915,23 @@ cfont_init: movzx eax,word [rm_seg.es] shl eax,4 add eax,ebp + + push eax + mov eax,100h*16 + call calloc + xchg eax,edi + pop eax + + or edi,edi + jz cfont_init_90 + + ; copy font for faster access + mov esi,eax + mov eax,edi + mov ecx,100h*16 + es rep movsb + +cfont_init_90: mov [cfont.lin],eax mov dword [cfont_height],16 |