Posted: Wed May 28, 2008 2:20 pm
And it doesn't work on all computers toosvdmeer wrote:Microsoft Windows '95 does use int 13h @ vm86 (16-bit disk access) doesn't it?
And it doesn't work on all computers toosvdmeer wrote:Microsoft Windows '95 does use int 13h @ vm86 (16-bit disk access) doesn't it?
I'm pretty sure it doesn't.svdmeer wrote:Microsoft Windows '95 does use int 13h @ vm86 (16-bit disk access) doesn't it?
I'm not sure what you mean exactly, as your English is a bit poor, but int 10h points to the video ROM, except on the original XT/PC, as the CGA does not have a ROM.edfed wrote:by evidence, there is a STANDARD layer somewhere between BIOS and VESA that permits to change all video modes with the simple int 10h ( in fact, a function inside the bios that wil call some functions into the VGA bios????
Code: Select all
;; Video driver code - switches the CPU back into real mode
;; Then executes an int 0x10 instruction
; dont be fooled by how simple this looks, it took lots of
; hours of frustration to get this to work right
[bits 32]
[org 0xfe00]
jmp vid_start
save_idt: dd 0
dw 0
save_esp: dd 0
vid_mode: dw 0
vid_start:
cli
mov word [vid_mode],ax
mov [save_esp],esp
sidt [save_idt]
lidt [0x9000] ;; saved on bootup see loader.asm
jmp 0x18:pmode
pmode:
mov eax,0x20
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr0
dec eax
mov cr0,eax
jmp 0:realmode1
[bits 16]
realmode1:
xor ax,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov sp,0xf000
sti
;; first zero out the 256 byte memory for the return function from getmodeinfo
cld
;; ax is already zero! I just saved myself a few bytes!!
mov cx,128
mov di,0x5000
rep stosw
mov ax,[vid_mode]
xor ax,0x13
jnz svga_mode
;; Ok, just a regular mode13
mov ax,0x13
int 0x10
;; we didnt actually get a Vidmode structure in 0x5000, so we
;; fake it with the stuff the kernel actually uses
mov word [0x5000],0xDD ; mode attribs, and my favorite cup size
mov word [0x5012],320 ; width
mov word [0x5014],200 ; height
mov byte [0x5019],8 ; bpp
mov byte [0x501B],1 ; memory model type = CGA
mov dword [0x5028],0xa0000 ; screen memory
jmp done
svga_mode:
mov ax,0x4f01 ; Get mode info function
mov cx,[vid_mode]
or cx,0x4000 ; always try to use linear buffer
mov di,0x5000
int 0x10
mov ax,0x4f02 ; Now actually set the mode
mov bx,[vid_mode]
or bx,0x4000
int 0x10
done:
cli
mov eax,cr0
inc eax
mov cr0,eax
jmp 0x8:pm1
[bits 32]
pm1:
mov eax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov dword esp,[save_esp]
lidt [save_idt]
ret
Changing modes? don't count on it. I once traced through my ATI Rage's bios, and I discovered that it perfomed three VSyncs, a delay while selecting the clock, and a lot of time spent blanking the screen. The Vsyncs alone account for at least 100ms, then there's the other stuff that needs to be done. That is a lot longer than the average disk access time.Switching to realmode for bios functions is only possible when the OS is singletasking OR the BIOS function executes very fast. That's the case with VESA-functions. The machine is in realmode for a very short time, so you multitasking will run fine.
Is segment 0x18 defined with 16 bit code size?crbenesch wrote:Code: Select all
mov word [0x5000],0xDD ; mode attribs, and my favorite cup size
Its a little simplistic and doesnt handle errors, but it works. Also you need to set up two descriptors for code and data that conform to real mode at 0x18 and 0x20 index of your GDT table. That being just like your pmode descriptors but without the high limit.