i've just been able to switch to some common resolution like 800*600*16 and 1024*768*32 through VBE, and fill the screen to be a color of comfortable green.
But i want to get the best suitable resolution through code(it very neccessarily for LCD,i think),
but the result is that i got some extreamly large resolution, like 2048*1536*24 in vmware, and sth no smaller in bochs.
Another problem is, when i switch to such extreamly large resolutions, the code of filling green doesn't work any more.
But in qemu, everything works, and the resolution is not too high, about 1280*1024 i think.
On my real machine, it works too, but my LCD inform me of sth like "Not best suitable resolution"(my SUMSUNG 943NW+ will zoom any resolution to fit the screen).
my code:
Code: Select all
change_vesa_mode:
mov ax,0x4f00
mov di,VbeInfoBlock
int 0x10
or ah,ah
jnz change_vesa_mode
mov eax,[VbeInfoBlock.VideoModePtr]
mov si,ax
shr eax,16
push ax
.choose:
pop bx
mov ds,bx
lodsw
mov bp,ax
push ds
xor bx,bx
mov ds,bx
cmp ax,0xffff ;last item, finish
je .do_switch
mov cx,ax
mov ax,0x4f01
mov di,VbeModeInfoBlock
int 0x10
or ah,ah
jnz .choose
mov ax,[VbeModeInfoBlock.ModeAttributes]
bt ax,0 ;supported?
jnc .choose
bt ax,7 ;LFB?
jnc .choose
;if the mode is better?
cmp byte [VbeModeInfoBlock.BitsPerPixel],16 ;color depth > 16
jb .choose
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,[VbeModeInfoBlock.XResolution]
mov bx,[VbeModeInfoBlock.YResolution]
mov cl,[VbeModeInfoBlock.BitsPerPixel]
mul ebx
mov ebx,ecx
mul ebx
cmp eax,[BestBits]
jna .choose ;not that better
mov [BestBits],eax
mov [BestMode],bp
jmp .choose
.do_switch:
;we need to get the ModeInfoBlock again for use
mov cx,[BestMode]
or cx,0x4000 ;LFB
mov ax,0x4f01
mov di,VbeModeInfoBlock
int 0x10
or ah,ah
jnz .do_switch
;really switch
mov bx,[BestMode]
mov ax,0x4f02
mov di,0
int 0x10
or ah,ah
jz .vbe_mode_done
;if failed
mov dword [BestMode],0x4114
mov dword [BestBits],800*600*16
jmp .do_switch
.vbe_mode_done:
Code: Select all
;fill the screen
mov ecx,[BestBits]
shr ecx,5
mov edi,[VbeModeInfoBlock.PhysBasePtr]
mov eax,0x04000400
cmp byte [VbeModeInfoBlock.BitsPerPixel],16
je .fill_16_32
mov eax,0x00008000
cmp byte [VbeModeInfoBlock.BitsPerPixel],32
je .fill_16_32
cmp byte [VbeModeInfoBlock.BitsPerPixel],24
je .fill_24
jmp $
.fill_16_32:
rep
stosd
jmp .fill_done
.fill_24:
stosd
dec edi
loop .fill_24
.fill_done:
and i think the reason why i can't fill the screen may be the LFB is at above 4G or sth wrong with it.
what i want to do now, is to get the best suitable resolution and ensure the screen filled green.
thanks,
lemonyii