Page 2 of 3

Re: VESA problem, help

Posted: Tue Jul 22, 2008 7:18 am
by jal
Mattx wrote:So proper order is like this ? : (in my case of course)
1. Set stack
2. Say hello :)
3. Check VESA and obtain framwork buffer address
4. Switch to proper video mode with framebuffer enable
5. Switch to protected mode
6. and what now ???
Okey so let say that I switch to pmode by setting cr register and so on and what next ? There is a lot tutorials on net about pmode so maybe i will gunderstand something but what should i do when i in pmode and have LFB adress (i get it when i was in real mode) ...
Well, in pmode you must set up stuff like GDT and IDT. If you do not want to get into that yet, try unreal mode first. It'll give you the advantages of real mode, but also allow you to address data above the 1MB barrier.

A question for you: do you understand how the video card translates the contents of its memory to output on your screen? That is, do you know how it interprets the bit/byte values? If not, read up on that. If so, the LFB pointer gives you full access to the video memory, so you can just put values in there and see the pixels appear on your screen, just like you would do when accessing video memory at b8000 or a0000.


JAL

Re: VESA problem, help

Posted: Tue Jul 22, 2008 10:51 am
by Dex
Here's how it works, simple pmode vesa demo
Vesa.asm

Code: Select all

;************************************
; Smallest pmode vesa demo
; By Craig Bamford (Dex)
;
; Assemble with fasm 
; c:\fasm Vesa.asm Vesa.bin
;
; Use rawrite to put it on fdd
;
;************************************
org 0x7C00 

use16
;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00 
;****************************
; Vesa start code.
;****************************
        mov  bx,4112h
        mov  ax,4f01h
        mov  di,Mode_Info	
        mov  cx,bx
        int  10h 
        
        mov  ax,4f02h
        int  10h
;*****************************
; Setting up, to enter pmode.
;*****************************
        cli 
        lgdt  [gdtr]
        
        mov   eax, cr0
        or    al,0x1 
        mov   cr0,eax
 
        jmp   0x10: protected
;*****************************
; Pmode. ;-)
;*****************************
use32
protected:
        mov   ax,0x8 
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   esp,0x7C00
;*****************************
; Turn floppy off (if space).
;*****************************
        mov   dx,3F2h
        mov   al,0
        out   dx,al
;*****************************
; Do we have 32 BitsPerPixel.
;*****************************
        cmp   byte[ModeInfo_BitsPerPixel],32
        jne   ErrorStop 
;*****************************
; fade background screen.
;*****************************
fill_screen:
        mov   edi,[ModeInfo_PhysBasePtr]
        xor   eax,eax
        mov   ecx,640*480
        rep   stosd
;*****************************
; Plot_pixel.
;*****************************
Plot_pixel:
        mov   edi,[ModeInfo_PhysBasePtr]
        mov   eax,0x00ffffff
        mov   ecx,10
        rep   stosd
;*****************************
; ErrorStop.
;*****************************
ErrorStop:
        hlt
        jmp   $
;*************************************
; GDT. 
;*************************************
gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF
gdt_end:

gdtr:	    dw gdt_end - gdt - 1	                                  
	    dd gdt 

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-start)  db 0  
dw 0xaa55
;*************************************
; Put uninitialized data here.
;*************************************
include 'vesa.inc'
vesa.inc

Code: Select all

;=========================================================;
; Vesa Information Block                         11/12/03 ;
;---------------------------------------------------------;
; DOS EXTREME OS V0.01                                    ;
; by Craig Bamford(Dex).                                  ;
;                                                         ;
;=========================================================;

;============================== VESA MODE INFORMATION ===========================================
Mode_Info:		
ModeInfo_ModeAttributes		rw	1
ModeInfo_WinAAttributes		rb	1
ModeInfo_WinBAttributes		rb	1
ModeInfo_WinGranularity		rw	1
ModeInfo_WinSize		rw	1
ModeInfo_WinASegment		rw	1
ModeInfo_WinBSegment		rw	1
ModeInfo_WinFuncPtr		rd	1
ModeInfo_BytesPerScanLine	rw	1
ModeInfo_XResolution		rw	1
ModeInfo_YResolution		rw	1
ModeInfo_XCharSize		rb	1
ModeInfo_YCharSize		rb	1
ModeInfo_NumberOfPlanes		rb	1
ModeInfo_BitsPerPixel		rb	1
ModeInfo_NumberOfBanks		rb	1
ModeInfo_MemoryModel		rb	1
ModeInfo_BankSize		rb	1
ModeInfo_NumberOfImagePages	rb	1
ModeInfo_Reserved_page		rb	1
ModeInfo_RedMaskSize		rb	1
ModeInfo_RedMaskPos		rb	1
ModeInfo_GreenMaskSize		rb	1
ModeInfo_GreenMaskPos		rb	1
ModeInfo_BlueMaskSize		rb	1
ModeInfo_BlueMaskPos		rb	1
ModeInfo_ReservedMaskSize	rb	1
ModeInfo_ReservedMaskPos	rb	1
ModeInfo_DirectColorModeInfo	rb	1
; VBE 2.0 extensions
ModeInfo_PhysBasePtr		rd	1
ModeInfo_OffScreenMemOffset	rd	1
ModeInfo_OffScreenMemSize	rw	1
Now to plot a pixel in vesa of that mode in pmode, you first get the lfb address from the vesa info block and mov it into the 32-bit destination reg, eg: EDI
Like so

Code: Select all

        mov   edi,[ModeInfo_PhysBasePtr]
Than you move the color of the pixel into EAX, in this case white (eg: 0x00ffffff)

Code: Select all

        mov   eax,0x00ffffff
Then move the number of pixels into ECX, (eg: 10)

Code: Select all

        mov   ecx,10

Then we use the "rep" pre fix, which repeats the STOSD the number the number of times thats in ecx (in this case 10).
The STOSD is the same as move whats in eax, into the address that ES:EDI points to, then add 4 to EDI (note: as ES in this case is zero, as we have set it to zero a base).

Code: Select all

        rep   stosd
So what this does is plot a row of 10 white pixels at the top left hand corner of the screen.
If you wanted to put them 1 row down you would ADD the size of a row to the LFB eg:

Code: Select all

        mov   edi,[ModeInfo_PhysBasePtr]
        add    edi,640*4
        mov   eax,0x00ffffff
        mov   ecx,10
        rep   stosd
Note: each pixel in this case is 4bytes long 32-bits, so we times the X by 4.

Please do not point out about things like 24-bit color or 'BytesPerScanLine' as i have try to keep it simple.

Re: VESA problem, help

Posted: Wed Jul 23, 2008 12:23 am
by Mattx
With support like you people it is hard to not understand :) First of all sorry for (maybe) stupid questions, but it is really very hard to find someting about this topic, there is a lot of pmode, mem manager, filessystems in two words internal things. Now about graphics it is quite clear for me ( i will check it out soon :)). I wanted to thank you again. And by the way dont you thing it is crazy all about this VESA and graphics drivers ? I mean there should be open specification, some abstraction layer not only windows drivers , DirectX and on the end is VESA that very body forget about... Maybe I wrong in this topic it all should be in diffrent direction, evry OS ( like windows , linux, our own ) should be capable with some general graphics driver. Espacially when ther are only two graphics card manufacturers ( nvidia , ati ) that are on market now. I read somewhere when VESA was created aleardy windwos exists and every body just doing drivers for it I think It was very lazy point of view... What you think about it ? Are there any importeant fact i dont know ( probably yes :) ) And thanks for tell me about it within big and bold words - it's very important for person that just starts in this topic :)

Re: VESA problem, help

Posted: Wed Jul 23, 2008 4:31 am
by jal
Mattx wrote:What you think about it ?
The main problem with VESA is that it was too little, too late. VESA v1 came out years after SVGA graphics cards were available, and VESA v2 (with some pmode interface) years after pmode OSes existed. When VESA v3 came out, nobody really bothered. As for the 'too little', VESA only specifies frame buffer stuff, but OSes need 2D acceleration to perform at all, like bitblt to move blocks of data (other acceleration stuff like mouse pointer and line drawing are less important on today's fast systems, but since video memory is still rather slow, having bitblt is a must, unless of course you go for 3D acceleration). Win3.11 supported VESA, and when running in 640x480x256 colours that was ok. But when running in, say, 1280x1024x32bpp mode, VESA is sloooow.


JAL

Re: VESA problem, help

Posted: Wed Jul 23, 2008 5:26 am
by Mattx
So what is best way with handling graphics in OS for people like as, people who creating own operating systems. You said VESA is too slow I thought it is fast when you work on frame buffer :( . To work with drivers you have to have some specification of grapfics cards right ? So is there better solution for this case, what techniques I should concentrate on when thinking of GUI ?

Regards
Mattx

Re: VESA problem, help

Posted: Wed Jul 23, 2008 7:03 am
by DerekDouglas
There is VBE/AF, which was supposed to be a standard way to access 2D acceleration functions by Sci-Tech; but IIRC you still needed drivers specific to the card for it.

http://www.vesa.org/public/VBE/VBE-AF07.pdf is the spec.

http://www.talula.demon.co.uk/freebe/ - FreeBE/AF is a free implementation with source.

Re: VESA problem, help

Posted: Wed Jul 23, 2008 7:11 am
by jal
Mattx wrote:So what is best way with handling graphics in OS for people like as, people who creating own operating systems. You said VESA is too slow I thought it is fast when you work on frame buffer :( . To work with drivers you have to have some specification of grapfics cards right ? So is there better solution for this case, what techniques I should concentrate on when thinking of GUI ?
For starters, do use the frame buffer. If you stay in 640x480 or 800x600, it should be fast enough. Later, you can develop drivers for specific cards. Remember, there are currently only a limited number of players in the field (as opposed to the early days when there were a myriad). Supporting AMD/ATI, nVidia and Intel will get you 90% of the market (at least). Of these, only nVidia doesn't provide full specifications, but as long as you stick to 2D, that needn't be a problem.


JAL

Re: VESA problem, help

Posted: Thu Aug 07, 2008 12:48 am
by Mattx
Okey becouse people here are very helpful I managed to write bootloader and kernel, bootloader loads kernel, unlock A20 , VESA switch , Pmode switch jump to 32 bit kernel. But I still have few problems -
1. Using bochs, when I want to obtain LFB addr using 4F01h INT 10 it gives me an error : LOCK PREFIX UNALLOWED ( op1=0x53,arrt=0x0,mod=0x0,nnn=0) and on the end is read_virtual_check() : read beylond limit....
using Virtual PC nothing happen like this...(becouse first I want have LFB sotred and then switch to proper mode) and i VPC he just switch to it.
2. How to pass LFB address to kernel ( I do it using stack ) is there a better way to do it ?
3.Dex gave me code like this :

Code: Select all

fill_screen:
        mov   edi,[ModeInfo_PhysBasePtr]
        xor   eax,eax
        mov   ecx,640*480
        rep   stosd
but after all this stuff VPC gives me an error,
without all VESA stuff bootloader + kernel works amazingly OK

Code: Select all


use16
org 0x7C00

start:
			mov ax,0
			mov es,ax
			mov bx,1000h
	
			mov ah,2
			mov al,10
			xor ch,ch
			mov cl,2
			mov dh,0
			int 13h
vesa_LFB:
			mov   ax,4F01h
			mov   cx,4112h
			int   0x10
			
			xor eax,eax
			mov eax,dword[es:di + 40]
			mov dword[LinearBaseAddr],eax
vesa_GFX:
			mov ax,4F02h
			mov bx,112h		;101h = 640x480x8 112h = 640x480x32 118h = 1024x768x32bit
			or bx, 4000h	;enable frame buffer bit 14
			int 10h
gate_A20:
			in al,0x92
			or al,2
			out 0x92,al
		
			cli

			xor ax,ax
			mov ds,ax
		
			lgdt [gdt_desc]
		
			mov eax, cr0
			or eax, 1
			mov cr0, eax

			jmp 08h:pmode
		
		
use32
pmode:
			mov ax, 10h
			mov ds, ax
			mov ss, ax
			mov es, ax
			mov gs, ax
			mov fs, ax
			mov esp,090000h
		
			mov eax,[LinearBaseAddr]
			push eax	
			
kernel32:		
		jmp 08h:1000h
			
		
gdt:

gdt_null:
			dd 0
			dd 0
gdt_code:
			dw 0FFFFh
			dw 0
			db 0
			db 10011010b
			db 11001111b
			db 0
gdt_data:
			dw 0FFFFh
			dw 0
			db 0
			db 10010010b
			db 11001111b
			db 0
gdt_end:
gdt_desc:
			dw gdt_end - gdt - 1
			dd gdt
		
LinearBaseAddr dd 0,0,0,0

times 510 - ($ - $$) db 0
db 0x55
db 0xAA
and kernel code

Re: VESA problem, help

Posted: Thu Aug 07, 2008 12:50 am
by Mattx

Code: Select all

use32
org 0000h


start:
		nop
		nop
		;mov byte[gs:0B8000h],'+'
		;mov byte[gs:0B8001h],1Bh
		
		pop eax
		mov [LinearBaseAddr],eax
main32:		

		mov   edi,[LinearBaseAddr]
        mov   eax,0x00ffffff
        mov   ecx,640*480
        rep   stosd

		jmp main32
		
		
LinearBaseAddr dd 0,0,0,0
Thanks for any response, please help

Re: VESA problem, help

Posted: Thu Aug 07, 2008 3:34 am
by jal
Mattx wrote:1. Using bochs, when I want to obtain LFB addr using 4F01h INT 10 it gives me an error : LOCK PREFIX UNALLOWED ( op1=0x53,arrt=0x0,mod=0x0,nnn=0) and on the end is read_virtual_check() : read beylond limit....

Code: Select all

			mov   ax,4F01h
			mov   cx,4112h
			int   0x10
			
			xor eax,eax
			mov eax,dword[es:di + 40]
			mov dword[LinearBaseAddr],eax
So... exactly where are you setting es and di?
2. How to pass LFB address to kernel ( I do it using stack ) is there a better way to do it ?
Since you are loading the kernel yourself, you can pass a value in any number of ways. Why, for example, not put it in a register instead of on the stack? Or use a dedicated buffer and pass the address in a register (like GRUB does).

Code: Select all

fill_screen:
        mov   edi,[ModeInfo_PhysBasePtr]
        xor   eax,eax
        mov   ecx,640*480
        rep   stosd
but after all this stuff VPC gives me an error
That's no doubt because you have an invalid ModeInfo_PhysBasePtr, given the fact that the int 10h call doesn't work. Did you try to find out what the value is?

General note: if one emulator gives an error on something this trivial, and another doesn't, don't assume it's going well in the other emulator, and then be suprised it crashes alter on.


JAL

Re: VESA problem, help

Posted: Wed Oct 01, 2008 8:07 am
by ivarivar
Hello!

Thanks for nice code jal, I have been scratching my head for a little while. :)

Anyhow, bochs actually returns 24 BPP for some reason..

I put the slightly modified code here: http://ivarref.at.ifi.uio.no/bochs/

Mattx: My problem (in my own OS) was not setting the higher nibble size to 0xF in the GDT
(but I think you are doing that correctly though).

Re: VESA problem, help

Posted: Wed Oct 01, 2008 2:28 pm
by rdos
I don't think VESA is slow. At up to 600x800x24 there is absolutely no difference between a well-coded VESA-based driver and Linux or Windows. What matters (initially at least) is that it will work on basically all cards. This is very different from how it was when VGA and SVGA were standards. Lots of palette and bit-plane modes that made things really hard.

Setting up a LFB-mode and buffer is also straight forward, at least if you do it before starting pmode.

What is really tricky is to be able to handle mode-switches and virtual displays in different modes. Then you often need to run the BIOS code in V86-mode, and provide virtualization of the BIOS area and some IO-ports. I've finally made this work, but only by writing an emulator that can emulate instructions for V86 mode.

Re: VESA problem, help

Posted: Wed Oct 01, 2008 11:17 pm
by inflater
I don't think VESA is slow. At up to 600x800x24 there is absolutely no difference between a well-coded VESA-based driver and Linux or Windows.
Try 3D my good friend. ;)
I've finally made this work, but only by writing an emulator that can emulate instructions for V86 mode.
No offence, but why people prefer writing a vm8086 emulator instead of momentarily switching to real mode? Its more easier...

Re: VESA problem, help

Posted: Thu Oct 02, 2008 12:08 am
by pcmattman
No offence, but why people prefer writing a vm8086 emulator instead of momentarily switching to real mode? Its more easier...
Because a vm8086 task can be threaded with pmode tasks. Switching back to realmode means switching display resolutions stops everything else on the system. That's not what you want in a modern OS.

Re: VESA problem, help

Posted: Thu Oct 02, 2008 2:25 am
by rdos
inflater wrote:Try 3D my good friend. ;)
As long as it works in the areas I need, I see no need to devote time for 3D-acceleration. I'm not writing computer-games for RDOS. RDOS is tailored at embedded systems.
No offence, but why people prefer writing a vm8086 emulator instead of momentarily switching to real mode? Its more easier...
Because it would destroy real-time performance. When you switch to real mode you will miss all interrupts and time-critical threads cannot run. When you run the mode switch code in V86, everything else continues to work as usual.