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?
VESA in P-Mode
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????
JAL
DexOS as two types of driver for floppy and hdd you can use the BIOS or the pmode driver, the BIOS goes to realmode and back.
It works fine in DexOS, but than it's a 32bit pmode single-tasking OS.
The reasan for two drivers is that there are case where the BIOS ( int 13h ) is ver usefull, eg: you can read/write to a USB key fob, from PMode if your BIOS will boot from such a device or load from a externel usb floppy drive etc.
Heres a demo i wrote for VESA mode switching www.dex4u.com/demos/VesaDemo.zip
OR you can try DexOS to see how it works, as it defaults to BIOS, you type
pmode <enter>
To use the pmode drivers.
It works fine in DexOS, but than it's a 32bit pmode single-tasking OS.
The reasan for two drivers is that there are case where the BIOS ( int 13h ) is ver usefull, eg: you can read/write to a USB key fob, from PMode if your BIOS will boot from such a device or load from a externel usb floppy drive etc.
Heres a demo i wrote for VESA mode switching www.dex4u.com/demos/VesaDemo.zip
OR you can try DexOS to see how it works, as it defaults to BIOS, you type
pmode <enter>
To use the pmode drivers.
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. But modeswitching for reading disk sectors will cause decreased responsiveness.
I also have some code that does that, switches from pmode to real mode and back again. My code, you place the mode you want to switch to in ax and call this procedure from p-mode. On my system its located at 0xfe00, but oyu can adjust yours as needed. I also saved the IDT at 0x9000 on bootup for real mode so youd need to do the same.
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.
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
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
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.
Combuster's right. On my laptop's real hardware, switching mode takes about 2 seconds. Just because it's instant in an emulator doesn't make it so in real life. Secondly, to the OP, my operating system switches VESA modes in pmode by using vm86 mode. I have posted my source code in another topic and if you like, you're welcome to study it. The source files you'd be interested in are dolphin/src/i386/vm86.c, dolphin/src/i386/thread.c, dolphin/src/i386/switch.S, and dolphin/src/servers/console/i386/console.c.
vm86.c contains the vm86 monitor which handles opcodes that the processor cannot handle in vm86 mode. thread.c contains the main loop for the vm86 server thread. Applications can message this thread in order to call a vm86 interrupt. switch.S contains the function that will jump to vm86 mode and finally, console.c is the file that contains the code that actually calls vm86 interrupts to set up the VESA mode.
If you have any questions, just ask.
vm86.c contains the vm86 monitor which handles opcodes that the processor cannot handle in vm86 mode. thread.c contains the main loop for the vm86 server thread. Applications can message this thread in order to call a vm86 interrupt. switch.S contains the function that will jump to vm86 mode and finally, console.c is the file that contains the code that actually calls vm86 interrupts to set up the VESA mode.
If you have any questions, just ask.
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.