[metal] Fix bug in video mode switch, & document data structure

This commit is contained in:
tkchia 2022-09-27 21:31:43 +00:00
parent 43b2973a04
commit 596f7d1ed4

View file

@ -35,6 +35,16 @@
(VGA_PREFER_TTY_WIDTH * VGA_ASSUME_CHAR_WIDTH_PX) (VGA_PREFER_TTY_WIDTH * VGA_ASSUME_CHAR_WIDTH_PX)
#define MAX_VESA_MODES_TO_TRACK 64 #define MAX_VESA_MODES_TO_TRACK 64
// Mode information data structure, used internally.
.set "mi::type",0
.set "mi::bpp",1
.set "mi::width",2
.set "mi::height",4
.set "mi::mode_num",6
.set "mi::stride",8
.set "mi::fb",10
.set "mi::sizeof",14
// Routine to activate additional VESA functionality if the user holds // Routine to activate additional VESA functionality if the user holds
// down a magic key, when booting from bare metal. Currently this just // down a magic key, when booting from bare metal. Currently this just
// dumps a list of all usable VESA VBE video modes on the console. // dumps a list of all usable VESA VBE video modes on the console.
@ -84,7 +94,7 @@ _rlinit_vesa:
push %esi push %esi
push %bp push %bp
push %es push %es
sub $2+MAX_VESA_MODES_TO_TRACK*14,%sp sub $2+MAX_VESA_MODES_TO_TRACK*"mi::sizeof",%sp
mov %sp,%bp mov %sp,%bp
call .gather_vesa_modes # gather list of VESA modes call .gather_vesa_modes # gather list of VESA modes
jc 8f jc 8f
@ -96,27 +106,27 @@ _rlinit_vesa:
or $-1,%esi # %esi = best fit screen size or $-1,%esi # %esi = best fit screen size
xor %bx,%bx # %bx = pointer to best info. struct. xor %bx,%bx # %bx = pointer to best info. struct.
# (start with NULL) # (start with NULL)
1: cmpb $PC_VIDEO_BGR565,(%bp) 1: cmpb $PC_VIDEO_BGR565,"mi::type"(%bp)
jnz 2f jnz 2f
movzwl 2(%bp),%eax movzwl "mi::width"(%bp),%eax
cmp $VGA_PREFER_GRAPH_WIDTH,%ax cmp $VGA_PREFER_GRAPH_WIDTH,%ax
jb 2f jb 2f
movzwl 4(%bp),%edx movzwl "mi::height"(%bp),%edx
cmp $VGA_PREFER_GRAPH_HEIGHT,%dx cmp $VGA_PREFER_GRAPH_HEIGHT,%dx
jb 2f jb 2f
imul %edx,%eax imul %edx,%eax
cmp %esi,%edx cmp %esi,%eax
jnb 2f jnb 2f
mov %edx,%esi mov %eax,%esi
mov %bp,%bx mov %bp,%bx
2: add $14,%bp 2: add $"mi::sizeof",%bp
loop 1b loop 1b
3: test %bx,%bx # if no good video mode found, 3: test %bx,%bx # if no good video mode found,
jz 6f # bail out jz 6f # bail out
movw %bx,%bp # otherwise... movw %bx,%bp # otherwise...
mov $REAL(str.use_mode),%si mov $REAL(str.use_mode),%si
call .puts call .puts
mov 6(%bp),%ax mov "mi::mode_num"(%bp),%ax
mov %ax,%bx mov %ax,%bx
call .putx call .putx
call .putnl call .putnl
@ -125,17 +135,16 @@ _rlinit_vesa:
int $0x10 int $0x10
cmp $0x004f,%ax cmp $0x004f,%ax
jnz 9f jnz 9f
mov (%bp),%al mov "mi::type"(%bp),%al
.set mm,0x0500 .set mm,0x0500
mov %al,mm+"struct mman::pc_video_type" mov %al,mm+"struct mman::pc_video_type"
mov 2(%bp),%ax mov "mi::width"(%bp),%ax
mov %ax,mm+"struct mman::pc_video_width" mov %ax,mm+"struct mman::pc_video_width"
mov 4(%bp),%ax movzwl "mi::height"(%bp),%edx
movzwl %ax,%edx mov %dx,mm+"struct mman::pc_video_height"
mov %ax,mm+"struct mman::pc_video_height" mov "mi::fb"(%bp),%eax
mov 10(%bp),%eax
mov %eax,mm+"struct mman::pc_video_framebuffer" mov %eax,mm+"struct mman::pc_video_framebuffer"
movzwl 8(%bp),%eax movzwl "mi::stride"(%bp),%eax
mov %ax,mm+"struct mman::pc_video_stride" mov %ax,mm+"struct mman::pc_video_stride"
imul %edx,%eax imul %edx,%eax
mov %eax,mm+"struct mman::pc_video_framebuffer_size" mov %eax,mm+"struct mman::pc_video_framebuffer_size"
@ -144,7 +153,7 @@ _rlinit_vesa:
mov %eax,mm+"struct mman::pc_video_framebuffer_size"+4 mov %eax,mm+"struct mman::pc_video_framebuffer_size"+4
clc clc
5: lahf 5: lahf
add $2+MAX_VESA_MODES_TO_TRACK*14,%sp add $2+MAX_VESA_MODES_TO_TRACK*"mi::sizeof",%sp
sahf sahf
pop %es pop %es
pop %bp pop %bp
@ -277,9 +286,9 @@ _rlinit_vesa:
jnb .fail3 jnb .fail3
inc %bx # otherwise start noting down mode inc %bx # otherwise start noting down mode
mov %bx,(%bp) # information... mov %bx,(%bp) # information...
imul $14,%bx imul $"mi::sizeof",%bx
lea 2-14(%ebp,%ebx),%bx lea 2-"mi::sizeof"(%ebp,%ebx),%bx
mov %al,%ss:(%bx) # ...starting from frame buffer type mov %al,%ss:("mi::type")(%bx) # ...starting from frame buffer type
call .putsp # echo and remember mode information call .putsp # echo and remember mode information
call .putsp call .putsp
test $0b00010000,%cl # first, echo mode attributes test $0b00010000,%cl # first, echo mode attributes
@ -289,21 +298,21 @@ _rlinit_vesa:
call .putc call .putc
call .putsp call .putsp
xchg %ax,%si # then process xchg %ax,%si # then process
mov %ax,%ss:6(%bx) # - mode number mov %ax,%ss:("mi::mode_num")(%bx) # - mode number
call .putx call .putx
mov %es:0x12(%di),%ax # - mode width mov %es:0x12(%di),%ax # - mode width
mov %ax,%ss:2(%bx) mov %ax,%ss:("mi::width")(%bx)
call .putd call .putd
mov %es:0x14(%di),%ax # - mode height mov %es:0x14(%di),%ax # - mode height
mov %ax,%ss:4(%bx) mov %ax,%ss:("mi::height")(%bx)
call .putd call .putd
mov %es:0x19(%di),%al # - bits per pixel mov %es:0x19(%di),%al # - bits per pixel
mov %al,%ss:1(%bx) mov %al,%ss:("mi::bpp")(%bx)
call .putdb call .putdb
mov %es:0x10(%di),%ax # - mode stride mov %es:0x10(%di),%ax # - mode stride
mov %ax,%ss:8(%bx) mov %ax,%ss:("mi::stride")(%bx)
mov %es:0x28(%di),%eax # - frame buffer address mov %es:0x28(%di),%eax # - frame buffer address
mov %eax,%ss:10(%bx) mov %eax,%ss:("mi::fb")(%bx)
clc clc
.done3: lea 0x100(%esp),%sp .done3: lea 0x100(%esp),%sp
pop %di pop %di