summaryrefslogtreecommitdiff
path: root/bincode.asm
diff options
context:
space:
mode:
Diffstat (limited to 'bincode.asm')
-rw-r--r--bincode.asm131
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