OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 2:06 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: VESA Tutorial
PostPosted: Wed Mar 09, 2016 11:03 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
VESA Tutorial
Hello. Today, I'm posting specifically to teach people who want graphics all about VESA. That means that in less than 30 minutes, you'll be able to have a high-color graphics world in your OS!
So anyway, VESA is the Video Electronics Standard Association. They are the people who made the VBE, or the VESA BIOS Extensions Standard. Like the name implies, it is an optional BIOS extension. But I think it's safe to say that 99% of PCs built since the late 1990's have VESA support. Note that UEFI GOP has succeeded VESA BIOS Extensions, but UEFI implementations also have a legacy VESA-compaitble BIOS for backwards-compatibility.

Anyway let's have a little history lesson...
In 1991, VESA released VBE version 1.2, which was mostly compatible with the previous 1.0 and 1.1 but had more popularity. Here, VESA defined some "video mode numbers" which are mostly the same idea as VGA mode numbers (e.g 0x03 is text 80x25, 0x13 is graphics 320x200x8bpp, ...) and they also defined "bank switching." The idea worked like this: you call the VESA BIOS and it sets a video mode for you. Then, because 1991 was still considered "DOS days," you write to 0xA000:0x0000 (linear 0xA0000) to draw to the screen. But that buffer only had a maximum of 64 KB because it is a 16-bit segment... So they invented bank switching; in which the BIOS divided the video memory into smaller chunks called banks, and you'll switch banks as you need to while drawing. For example, in a 640x480x8bpp VESA mode, we need 300 KB of video memory. But unfortunately, we can only access the video memory as 64 KB segments... So if we want to draw to the entire screen, first we switch to bank 0, which is the first 64 KB of the screen, then we draw; then we switch to bank 1, which is the second 64 KB of the screen, then we draw to the same address; then we switch to bank 2, and so on...
This had a severe performance penalty, and bank switching is deprecated today, and has been succeeded by linear framebuffers, which are discussed later in this tutorial.

Here are some modes the VESA defined with VBE 1.x:
Code:
MODE    RESOLUTION  BITS PER PIXEL  MAXIMUM COLORS
0x0100  640x480     4               16
0x0101  640x480     8               256
0x0102  800x600     4               16
0x0103  800x600     8               256
0x010D  320x200     15              32k
0x010E  320x200     16              64k
0x010F  320x200     24/32*          16m
0x0110  640x480     15              32k
0x0111  640x480     16              64k
0x0112  640x480     24/32*          16m
0x0113  800x600     15              32k
0x0114  800x600     16              64k
0x0115  800x600     24/32*          16m
0x0116  1024x768    15              32k
0x0117  1024x768    16              64k
0x0118  1024x768    24/32*          16m


Notes:
* Some BIOSes support 24-bit color, in which each color is an RGB value, in which each color component is 8 bits; giving a total of 16 million available colors. Other BIOSes support 32-bit color, in which color is also an RGB value and each color component is still 8 bits, but there is an empty 8 bits at the top, which are known as the alpha channel; so 32-bit color is often called RGBA color while 24-bit color is often called RGB color. This is done for two reasons: as a stub for software implementing alpha blending, as to speed up memory operations by 32-bit alignment. Note that the values are in little endian.

Then in 1994, VESA defined VBE 2.0 and this was a major improvement, although "most" VBE 2.0+ BIOSes are compatible with VBE 1.x. Anyway, in VBE 2.0, VESA defined the "linear framebuffer" which was a place in high memory (3 to 4 GB) that had a totally contiguous framebuffer; bank switching was deprecated although is still supported in the BIOS for backwards-compatibility. VESA also stated that all the modes that they defined in VBE 1.x are also deprecated, and that hardware manufacturers didn't need to support them, and that anyone can make up any modes they feel like. Most hardware vendors still support the standard VBE 1.x modes for backward-compatibility, but you should NEVER depend on that, because one day you'll find a PC on which your code just won't work.
But wait a minute... How can we set VESA modes without knowing the mode numbers? Well, VESA gave us two things: a function that returns an array of all available mode numbers, and another function that gets the details of a specified mode number (width, height, bpp, linear framebuffer address, etc...) The basic idea is that we query the BIOS for the information of every available mode, and when we find a mode that fits our needs, we can use it. Since mode numbers are not standard, you should NEVER assume mode numbers, width of a mode, height of a mode, or bpp of the mode. For example, my laptop has VESA mode 0x0118 as 1024x768x32 while older software assumed it to be a 24-bit mode. Newer software may assume it to be a 32-bit mode; while Bochs and QEMU emulate it as a 24-bit mode. Anyway, you should NEVER assume VESA modes and should always query the BIOS for what it supports.

That's enough theory for today, I guess. Let's take a look on how to actually use the VESA BIOS Extensions!
VESA put its VBE functions at function 0x4F of BIOS interrupt 0x10. You put the function number 0x4F in AH register, the subfunction number in AL register, parameters in other registers, and call INT 0x10.
All VESA calls return 0x004F in AX on success. Any other return code should be taken as an error.

Here are some useful functions that can be used with VBE 2.0+:

FUNCTION: Get VESA BIOS information
Function code: 0x4F00
Description: Returns the VESA BIOS information, including manufacturer, supported modes, available video memory, etc...
Input: AX = 0x4F00
ES:DI = Segment:Offset pointer to where to store VESA BIOS information structure.
Output: AX = 0x004F on success, other values indicate that VESA BIOS is not supported.

Anyway, the above function returns the following structure and stores it in ES:DI as they were on entry. On entry, ES:DI should contain a pointer to the following structure:
Code:
vbe_info_structure:
   .signature      db "VBE2"   ; indicate support for VBE 2.0+
   .table_data:      resb 512-4   ; reserve space for the table below

After the BIOS call, if it succeeded (AX is 0x004F), then the same structure above now contains the following:
Code:
struct vbe_info_structure {
   char[4] signature = "VESA";   // must be "VESA" to indicate valid VBE support
   uint16 version;         // VBE version; high byte is major version, low byte is minor version
   uint32 oem;         // segment:offset pointer to OEM
   uint32 capabilities;      // bitfield that describes card capabilities
   uint32 video_modes;      // segment:offset pointer to list of supported video modes
   uint16 video_memory;      // amount of video memory in 64KB blocks
   uint16 software_rev;      // software revision
   uint32 vendor;         // segment:offset to card vendor string
   uint32 product_name;      // segment:offset to card model name
   uint32 product_rev;      // segment:offset pointer to product revision
   char reserved[222];      // reserved for future expansion
   char oem_data[256];      // OEM BIOSes store their strings in this area
} __attribute__ ((packed));

Notice that all segment:offset fields are in little-endian, which means the low word is the offset, and the high word is the segment.
Things that might be of interest to you from the above structure: "signature" will be changed from "VBE2" to "VESA". It must be "VBE2" on entry to indicate software support for VBE 2.0. If it contains "VBE2", the BIOS will return the 512 bytes of data for VBE 2.0+. If it contains "VESA", the BIOS will return 256 bytes of data for VBE 1.x. If it is not "VESA" after the call, you should assume that VESA BIOS Extensions are not available. "version" tells you the version of VBE; 0x100 is 1.0, 0x101 is 1.1, 0x102 is 1.2, 0x200 is 2.0, and 0x300 is 3.0 (the latest version). VBE 1.x returns 256 bytes of data in the above structure, VBE 2.0 and 3.0 return 512 bytes of data if the "signature" field contained "VBE2" on entry. "video_modes" is a segment:offset pointer to the list of supported video modes. Each entry in the array is a 16-bit word, and is terminated by a 0xFFFF. If while searching for your mode, you find a 0xFFFF, then the mode is not supported. "video_memory" contains how much VGA RAM the PC has in 64 KB chunks. So, to have it in KB, multiply the value in "video_memory" by 64.
Anyway, about the supported modes array, if the PC supports modes 0x0103, 0x0115, and 0x0118, the array would look like this in a hexdump:
Code:
03 01 15 01 18 01 FF FF

Notice how it is terminated by a 0xFFFF and all values are in little-endian.

FUNCTION: Get VESA mode information
Function code: 0x4F01
Description: This function returns the mode information structure for a specified mode. The mode number should be gotten from the supported modes array.
Input: AX = 0x4F01
CX = VESA mode number from the video modes array
ES:DI = Segment:Offset pointer of where to store the VESA Mode Information Structure shown below.
Output: AX = 0x004F on success, other values indicate a BIOS error or a mode-not-supported error.

Here's the structure returned by this function in ES:DI:
Code:
struct vbe_mode_info_structure {
   uint16 attributes;      // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
   uint8 window_a;         // deprecated
   uint8 window_b;         // deprecated
   uint16 granularity;      // deprecated; used while calculating bank numbers
   uint16 window_size;
   uint16 segment_a;
   uint16 segment_b;
   uint32 win_func_ptr;      // deprecated; used to switch banks from protected mode without returning to real mode
   uint16 pitch;         // number of bytes per horizontal line
   uint16 width;         // width in pixels
   uint16 height;         // height in pixels
   uint8 w_char;         // unused...
   uint8 y_char;         // ...
   uint8 planes;
   uint8 bpp;         // bits per pixel in this mode
   uint8 banks;         // deprecated; total number of banks in this mode
   uint8 memory_model;
   uint8 bank_size;      // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
   uint8 image_pages;
   uint8 reserved0;

   uint8 red_mask;
   uint8 red_position;
   uint8 green_mask;
   uint8 green_position;
   uint8 blue_mask;
   uint8 blue_position;
   uint8 reserved_mask;
   uint8 reserved_position;
   uint8 direct_color_attributes;

   uint32 framebuffer;      // physical address of the linear frame buffer; write here to draw to the screen
   uint32 off_screen_mem_off;
   uint16 off_screen_mem_size;   // size of memory in the framebuffer but not being displayed on the screen
   uint8 reserved1[206];
} __attribute__ ((packed));


Lots of useless sh*t, I know. The only things that interest us: "attributes" bit 7 (value 0x80) indicates the mode supports a linear frame buffer. "width", "height" are "bpp" are used while searching for the mode we want to use. "framebuffer" is the 32-bit physical pointer to the linear framebuffer. The linear framebuffer must be enabled while setting the VBE mode, which is discussed in the next function. If you are using paging, be sure to map the framebuffer somewhere known in the virtual address space!

FUNCTION: Set VBE mode
Function code: 0x4F02
Description: This function sets a VBE mode.
Input: AX = 0x4F02
BX = Bits 0-13 mode number; bit 14 is the LFB bit: when set, it enables the linear framebuffer, when clear, software must use bank switching. Bit 15 is the DM bit: when set, the BIOS doesn't clear the screen. Bit 15 is usually ignored and should always be cleared.
Output: AX = 0x004F on success, other values indicate errors; such as BIOS error, too little video memory, unsupported VBE mode, mode doesn't support linear frame buffer, or any other error.

So that means, if VBE mode 0x0118 is 1024x768x32bpp, and we wanted to set this mode and ask the BIOS to clear the screen for us, we can do this:
Code:
mov ax, 0x4F02   ; set VBE mode
mov bx, 0x4118   ; VBE mode number; notice that bits 0-13 contain the mode number and bit 14 (LFB) is set and bit 15 (DM) is clear.
int 0x10         ; call VBE BIOS
cmp ax, 0x004F   ; test for error
jne error

after:
   ; ...

Anyway, like I mentioned at least a hundred times, you should first get the mode number from the video modes array. Those mode numbers only have the plain mode numbers (0x0118, 0x0103, etc...) and you should set bit 14 when you set the VBE mode.

FUNCTION: Get current VBE mode
Function code: 0x4F03
Description: This function returns the current VBE mode.
Input: AX = 0x4F03
Output: AX = 0x004F on success, other values indicate errors; maybe the system is not in a VBE mode?
BX = Bits 0-13 mode number; bit 14 is the LFB bit: when set, the system is using the linear framebuffer, when clear, the system is using bank switching. Bit 15 is the DM bit: when clear, video memory was cleared when the VBE mode was set.

FUNCTION: Display Window Control (deprecated)
Function code: 0x4F05
Description: Sets/Gets the current bank (deprecated)
Input: AX = 0x4F05
BH = 0x00 to set bank, 0x01 to get bank
BL = 0x00 for window A, 0x01 for window B
DX = Bank number in window granularity units
Output: AX = 0x004F on success, other values indicate errors; such as BIOS errors, unusable bank, unpresent bank, not using banked mode...

Because bank switching is deprecated, I will not go into how to calculate bank numbers.

FUNCTION: Return protected mode interface
Function: 0x4F0A
Description: Returns the VBE 2.0 protected mode interface
Input: AX = 0x4F0A
BL = 0x00
Output: AX = 0x004F on success, other values indicate errors; such as BIOS errors, protected mode interface not supported, or VBE version is less than 2.0
ES:DI = Segment:Offset pointer to protected mode table
CX = Length of table including code in bytes for copying purposes

This function allows software to switch banks (function 0x4F05), set display start (function 0x4F07) and set primary pallette data (function 0x4F09) from protected mode, without needing to return to real mode. This increases performance somewhat, but is overall deprecated and may not be supported in some BIOSes.
Anyway, the table returned by ES:DI looks like this:

Code:
struct vbe2_pmi_table {
   uint16 set_window;      // offset in table for protected mode code for function 0x4F05
   uint16 set_display_start;   // offset in table for protected mode code for function 0x4F07
   uint16 set_pallette;      // offset in table for protected mode code for function 0x4F09
} __attribute__ ((packed));

That means, to set the bank from protected mode, one should first find the linear address of the set_window function, by doing ES * 0x10 + DI + [ES:DI] and then doing a near CALL, because all protected mode functions end with a near RET. Useless, I know, but perhaps some people want to use bank switching as a fallback when VBE 2.0 is not available, or when the specific mode doesn't support a linear frame buffer.

By now, your understanding of VESA should be quite clear and your implementation of VESA shouldn't be that difficult. Note, that if you use v8086 to call VESA BIOS, many video cards have memory-mapped register in high memory (3-4 GB) and the BIOS will have to switch to protected mode transparently to you during VBE execution, which goes beyond limits of v8086. For this problem, it is recommended to configure VESA in plain 16-bit real mode, before 32-bit/64-bit mode.

Need code?
Here's a function to set a VESA mode directly from a specified width/height/bpp, copied and pasted from my OS code. Notice that it runs in 16-bit real mode with DS = ES = FS = GS = 0.
Code:
; vbe_set_mode:
; Sets a VESA mode
; In\   AX = Width
; In\   BX = Height
; In\   CL = Bits per pixel
; Out\   FLAGS = Carry clear on success
; Out\   Width, height, bpp, physical buffer, all set in vbe_screen structure

vbe_set_mode:
   mov [.width], ax
   mov [.height], bx
   mov [.bpp], cl

   sti

   push es               ; some VESA BIOSes destroy ES, or so I read
   mov ax, 0x4F00            ; get VBE BIOS info
   mov di, vbe_info_block
   int 0x10
   pop es

   cmp ax, 0x4F            ; BIOS doesn't support VBE?
   jne .error

   mov ax, word[vbe_info_block.video_modes]
   mov [.offset], ax
   mov ax, word[vbe_info_block.video_modes+2]
   mov [.segment], ax

   mov ax, [.segment]
   mov fs, ax
   mov si, [.offset]

.find_mode:
   mov dx, [fs:si]
   add si, 2
   mov [.offset], si
   mov [.mode], dx
   mov ax, 0
   mov fs, ax

   cmp [.mode], 0xFFFF         ; end of list?
   je .error

   push es
   mov ax, 0x4F01            ; get VBE mode info
   mov cx, [.mode]
   mov di, mode_info_block
   int 0x10
   pop es

   cmp ax, 0x4F
   jne .error

   mov ax, [.width]
   cmp ax, [mode_info_block.width]
   jne .next_mode

   mov ax, [.height]
   cmp ax, [mode_info_block.height]
   jne .next_mode

   mov al, [.bpp]
   cmp al, [mode_info_block.bpp]
   jne .next_mode

   ; If we make it here, we've found the correct mode!
   mov ax, [.width]
   mov word[vbe_screen.width], ax
   mov ax, [.height]
   mov word[vbe_screen.height], ax
   mov eax, [mode_info_block.framebuffer]
   mov dword[vbe_screen.physical_buffer], eax
   mov ax, [mode_info_block.pitch]
   mov word[vbe_screen.bytes_per_line], ax
   mov eax, 0
   mov al, [.bpp]
   mov byte[vbe_screen.bpp], al
   shr eax, 3
   mov dword[vbe_screen.bytes_per_pixel], eax

   mov ax, [.width]
   shr ax, 3
   dec ax
   mov word[vbe_screen.x_cur_max], ax

   mov ax, [.height]
   shr ax, 4
   dec ax
   mov word[vbe_screen.y_cur_max], ax

   ; Set the mode
   push es
   mov ax, 0x4F02
   mov bx, [.mode]
   or bx, 0x4000         ; enable LFB
   mov di, 0         ; not sure if some BIOSes need this... anyway it doesn't hurt
   int 0x10
   pop es

   cmp ax, 0x4F
   jne .error

   clc
   ret

.next_mode:
   mov ax, [.segment]
   mov fs, ax
   mov si, [.offset]
   jmp .find_mode

.error:
   stc
   ret

.width            dw 0
.height            dw 0
.bpp            db 0
.segment         dw 0
.offset            dw 0
.mode            dw 0


What's next?
Well, that's entirely up to you! Just kidding, here's some tips on implementing a graphics library.
Calculating pixel offset:
Code:
uint32 pixel_offset = y * pitch + (x * (bpp/8)) + framebuffer;

Where "pitch", "bpp" and "framebuffer" are gotten from the structure returned by function 0x4F01. Then, you can plot a pixel by writing a value there.
For 32-bit modes, each pixel value is 0x00RRGGBB in little endian, so to plot a red pixel, we would write 0x00FF0000. In 24-bit mode, each pixel is 0xRRGGBB in little endian. Due to the bad memory alignment, performance is relatively low with 24-bit modes. In 16-bit modes, we have a total of 64K colors, and the color has 5 bits of red, 6 bits of green, and 5 bits of blue. There is more green because according to Wikipedia, the human eye is more sensitive to green than red and blue...
In 15-bit modes, we have a total of 32K colors, 5 bits of red, 5 bits of green and 5 bits of blue. The highest bit (bit 15, value 0x8000) is unused.
Because my OS supports 32-bit/24-bit modes and 16-bit as a fallback, I will focus on these. Anyway if you want something less than 16-bit your limiting yourself to the obsolete technology...
Just by getting the pixel's offset and writing there, you've implemented a put_pixel() routine!
Now, we want some more things: lines, squares, alpha blending, and some hot graphics! It may seem easy to implement a fill_rect() routine: just put_pixel() everything. That's going to work, but it's not going to work fast. For a 32*32 rectangle, you'll be calculating the pixel offset 1024 times! Instead, a better approach is to calculate the pixel offset one time, and then (REP STOSD/REP STOSW) for one line. Then you can do (offset = offset + pitch) just to skip one line down. This way, you can fill a 512x512 rectangle yet calculate the pixel offset only one time. By calling put_pixel() for every pixel, you'd be calculating the pixel offset 262144 times! Using the method I just said, you can make performance 262144 times better.
For drawing lines, you'll probably implement an existing algorithm. Wikipedia has a good article on drawing lines.
As for alpha blending, Wikipedia also has good information on that.
Now that you have a linear framebuffer, a basic put_pixel() routine and a fill_rect() routine, you can implement a basic graphics library. Programming graphics now is just the same as non-OS graphics programming. Enjoy!

Keep reading!
VBE 2.0 Specification (PDF)
Drawing Text -- You'll need to print text from graphics mode.
Double Buffering -- A way of majorly improving graphics performance.
Alpha Compositing -- Who doesn't want shiny transparent graphics in their OS?

Someone please tell me if it is wrong to write simple tutorials like this, because I am willing to write a detailed ACPI tutorial just like this one, soon.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Last edited by BrightLight on Thu Mar 10, 2016 9:18 am, edited 6 times in total.

Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Wed Mar 09, 2016 12:07 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2010 4:53 pm
Posts: 1150
Location: Scotland
I haven't time to go through it carefully, but it looks as if it will help newcomers get into VESA modes early on. What you say about VBE3 is long out of date as it has been around for a long time and is likely in use on a hundred million machines. You also haven't mentioned that screen modes offered by the computer may not be compatible with the monitor - they should be on a laptop, but you need to make sure people are aware of EDID so that they don't think they've completed the job when they're only half way there. I read through your tutorial looking to see what you'd say about that because I haven't done any work with EDID myself yet.

Quote:
Note that UEFI GOP has preceeded VESA BIOS Extensions

I wasn't looking for mistakes and only saw this trivial one, but you should change "preceeded" into "succeeded".

_________________
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Wed Mar 09, 2016 12:18 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
Oops, fixed. :oops:
I didn't talk much about VBE 3.0 because I don't think there is much difference other than a protected mode interface. And I didn't talk about EDID because I'm still learning about EDID myself.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Wed Mar 09, 2016 1:02 pm 
Offline
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1225
A simple application in Assembly could be written to simply switch modes with the + an - keys, and use Esc to return to the original video mode, and finally Enter to change the video mode. This would be very similar to Windows or a graphical Linux console test.

I find that the very minimum for a windowed interface (window manager) is to be implemented in standard 80x25Text Mode. It's very easy to implement windows from there, then emulate the text characters and limit/dimensions in any other graphics mode, and then just change the characters that the window is made of as if it was a window skin or some sort of mask or texture.

And also, the minimum graphics element to learn about windowed interfaces is a text control. With this we can learn about thinking how to draw, reserve and find the writable area, then how to add a "multilayer" procedure to add the border and then maybe shadows (like having a minimum control to think about how to implement and extend for classes or other way to create that is reasonable and properly implemented).

Also, the text screen is just a big automatic TEXTAREA of 2000 characters for 80x25 mode and capable of colors (in that it's superior than an HTML TEXTAREA).

_________________
Live PC 1: Image Live PC 2: Image

YouTube:
http://youtube.com/@AltComp126/streams
http://youtube.com/@proyectos/streams

http://master.dl.sourceforge.net/projec ... 7z?viasf=1


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 12:31 am 
Offline

Joined: Fri Sep 25, 2015 5:30 am
Posts: 22
Nice, but could you explain REP STOSD and REP STOSW a bit more? I'm not so good witb assembly


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 12:58 am 
Offline
Member
Member

Joined: Fri Jan 30, 2015 4:57 pm
Posts: 215
Location: Germany
stosb/w/d/q stores the value in al/ax/eax/rex to a memory location given by segment es and offset (e)di.
The rep prefix repeats this instruction as many times as given in (e)cx. Wether edi or di, ecx or cx is used depends on the currently used operand size or the o32 prefix.


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 4:04 am 
Offline
Member
Member

Joined: Thu Jul 05, 2012 5:12 am
Posts: 923
Location: Finland
You explained this already but I think this might be worth noting more carefully.

Code:
; Before the "Function 00h - Return VBE Controller Information" call, es:di points to this structure:

vbe_info_structure:
    .signature:     db 'VBE2'           ; set beforehand (always be prepared to receive 512 bytes)

    times (512-4)   db 0                ; zeros are not strictly necessary but as a good practice
                                        ; I recommend having them instead of random values


Code:
; After the successful call, es:di points to this structure:

vbe_info_structure:
    .signature:     db 'VESA'           ; "VBE2" set beforehand is now "VESA"

    .version:       dw 0x????

    ; if (vbe_info_structure.version >= 0x0200) then
    ;     sizeof(vbe_info_structure) = 512
    ; else
    ;     sizeof(vbe_info_structure) = 256
    ; endif

    .oemStringPtr:  dd 0x????????
    ; ...
    ; ...


I predict that it is a common mistake to miss the idea of "input" and "output" structure.

_________________
Undefined behavior since 2012


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 9:26 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
Antti wrote:
I predict that it is a common mistake to miss the idea of "input" and "output" structure.

Fixed. ;)

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 11:13 am 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1110
Location: Tartu, Estonia
This looks like a good piece of work!

Wouldn't the wiki be a better place to keep this?

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 11:40 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
XenOS wrote:
This looks like a good piece of work!

Wouldn't the wiki be a better place to keep this?

Thanks! Unfortunately, I don't know how to edit the Wiki (using tags, etc). It tooks me a while just to add my OS to the Projects list.
Is there a manual/guide?

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 4:04 pm 
Offline
Member
Member

Joined: Thu Sep 20, 2012 5:11 am
Posts: 69
Location: germany hamburg
Hello.

I like show how to use a refreshrate controlled videomode together with VBE hardware triple buffering with a resolution of 1024x768x32@100hz written for MSDOS and a Geforce TI 4200 AGPx4 64MB VBE3 BIOS and a 19" CRT monitor with 96khz capacity. http://www.alice-dsl.net/freecracmaps/Tools/Neutrip.zip

If no error occur some colored balls are moving across the screen and if they reached a border, then they change their direction. Some of the balls are moving slowly and some them faster.

Puplic and costfree documents from http://www.vesa.org (register/login):
vbe3.pdf
EEDIDguideV1.pdf
EEDIDverifGuideRa.pdf

For calculating CRTC values:
VBEHz 2.23
http://home.arcor.de/g.s/dostools.htm

With my Radeon 9750 from Sapphire(PCIex16; VBE3) i can use the resolution of 1920x1200x32 for to fit the native resolution of my 28" LCD (widescreen 16:10 aspect ratio).

Dirk


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Thu Mar 10, 2016 4:37 pm 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1110
Location: Tartu, Estonia
omarrx024 wrote:
Thanks! Unfortunately, I don't know how to edit the Wiki (using tags, etc). It tooks me a while just to add my OS to the Projects list.
Is there a manual/guide?

This might be a good starting point: http://wiki.osdev.org/OSDevWiki:Editing

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Sat Mar 12, 2016 11:42 am 
Offline

Joined: Thu Mar 10, 2016 8:47 am
Posts: 4
Location: Tours, France
Great thing you've done ! very helpful.

What is this vbe_screen ? What are its fields and what do they do/represent ?
sorry if it's obvious.

PS: I'm french so my english can be a bit strange.

EDIT: more precisely, why redundancy in byte-per-pixel and bpp and what does x-cur-max and y-cur-max mean ?


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Sat Mar 12, 2016 1:56 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
This is a structure used internally by my kernel. I have mentioned that the above code is copied/pasted from my current OS (not open source yet.)
"vbe_screen" contains basic screen information which are gotten from the VBE Mode Information structure: width, height, bpp (bits per pixel), pitch (bytes per line), linear frame buffer address and so on.
"bytes_per_pixel" is simply bpp/8 because there are 8 bits in a byte. "x_cur_max" and "y_cur_max" are the maximum X/Y cursor coordinates, used for text mode cursor emulation. In my OS, each character is 8x16 pixels, and so you can guess what I did from there. ;)

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: VESA Tutorial
PostPosted: Sat Mar 12, 2016 2:16 pm 
Offline
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1225
XenOS wrote:
omarrx024 wrote:
Thanks! Unfortunately, I don't know how to edit the Wiki (using tags, etc). It tooks me a while just to add my OS to the Projects list.
Is there a manual/guide?

This might be a good starting point: http://wiki.osdev.org/OSDevWiki:Editing


By the way, your website at http://hwdb.mipt.cc/Main_Page is down. I can't see it, it just doesn't load.

_________________
Live PC 1: Image Live PC 2: Image

YouTube:
http://youtube.com/@AltComp126/streams
http://youtube.com/@proyectos/streams

http://master.dl.sourceforge.net/projec ... 7z?viasf=1


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 33 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group