Page 1 of 1
Bochs VBE with LFB, wrong pixel coordinates.
Posted: Thu Mar 03, 2016 6:59 pm
by David94
Hi guys,
I'm trying to plot some pixels in my OS, but I'm caught in a problem.
Using BGA I can change the video mode and draw some erratic pixels on the screen. Everywhere I looked, I saw that I need 'bytes per pixel' field to calculate the coordinates.
The question is: there is any way to get this information, or even the 'ModeInfoBlock' structure without using any bios interrupt?
I really at this point I didn't wanna go back to the real mode to get this information and I thought if there was any way to Bochs also provide me this value, by reading/writing in BGA registers.
Thanks in advance.
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Thu Mar 03, 2016 7:31 pm
by SpyderTL
The
bga page has details about the bits per pixel register, and the memory layout.
Is this what you are looking for?
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Thu Mar 03, 2016 8:08 pm
by David94
SpyderTL wrote:The
bga page has details about the bits per pixel register, and the memory layout.
Is this what you are looking for?
Thanks for quickly reply,
This link is broken, did you mean
BGA? if so, I've read this page, but I stuck on:
"A formula to calculate the video memory offset from a pixel coordinate is: offset = (Y * X-resolution + X) * <some-factor>. The factor varies using the different bit depths."
I suppose that this factor is the 'pitch' field of ModeInfoBlock structure obtained by INT 0x10, AX = 0x4F01 (described here
VESA Video Modes). The point is that I am in protected mode and I have considerable work to return to the real mode, I wonder if there is any way to get this value through BGA instead of the bios interrupts.
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Thu Mar 03, 2016 10:38 pm
by SpyderTL
The "pitch" when using Bochs will always be the screen width * bits per pixel / 8.
There is no hidden memory between one row of pixels and the next. (Unless you have enabled virtual screen space.)
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Thu Mar 03, 2016 10:44 pm
by beyondsociety
If your using your own bootloader, im not sure if there is a way to get that info besides switching to real mode, using Vesa functions and switching back to protected mode. Hopefully someone may know better. If your using grub to load your os, then you can use the graphics fields of multiboot to clear the screen and plot pixels like with bga and as an added bonus multiboot will give you that info.
The main difference between the two is that once you are in graphics mode with grub, writing to the screen doesn't work like before. So if you were using grub, you would have to rewrite your print function for graphics which uses pixels instead. I started working on the exact same thing as you and started to rewrite my print function using grub and life got in the way, I plan to eventually come back to this and finish it.
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Fri Mar 04, 2016 12:03 am
by David94
Thanks for the answers,
SpyderTL wrote:The "pitch" when using Bochs will always be the screen width * bits per pixel / 8.
There is no hidden memory between one row of pixels and the next. (Unless you have enabled virtual screen space.)
I'm using 1024x768, 24bpp, so the pitch was 3072? I'm using this code to draw and yet still wrong position:
Code: Select all
void draw_pixel(unsigned x, unsigned y, unsigned color)
{
unsigned *vga = (unsigned*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;
unsigned pitch = (SCREEN_WIDTH * 24 / 8);
unsigned offset = (y * SCREEN_WIDTH + x) * pitch;
vga[offset] = color;
}
//and I call
draw_pixel(0,0,0x00ff00);
draw_pixel(1,0,0x00ff00);
as result I have:
http://i.imgur.com/jHohIU2.png, It may be something trivial that I'm forgetting.
beyondsociety wrote:If your using your own bootloader, im not sure if there is a way to get that info besides switching to real mode, using Vesa functions and switching back to protected mode. Hopefully someone may know better. If your using grub to load your os, then you can use the graphics fields of multiboot to clear the screen and plot pixels like with bga and as an added bonus multiboot will give you that info.
The main difference between the two is that once you are in graphics mode with grub, writing to the screen doesn't work like before. So if you were using grub, you would have to rewrite your print function for graphics which uses pixels instead. I started working on the exact same thing as you and started to rewrite my print function using grub and life got in the way, I plan to eventually come back to this and finish it.
Yep, I'm using Grub as bootloader. I tried to list all the modes using 'vbe_mode_info' informed by multiboot_info but got a very strange output, might be the version of grub (I am using 2.0) but I can test with the legacy if necessary.
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Fri Mar 04, 2016 12:21 am
by SpyderTL
It should be offset = (y * pitch) + (x * stride)
Where stride = bits per pixel / 8
Edit: You shouldn't be using "unsigned" ints (which are 4 bytes each), if you are using 24 bit pixels (which are 3 bytes each).
You either need to use an array of structs with 3 one byte fields, or you need to change your video mode to 32-bits per pixel.
You also need to change your offset to match your pixel size, so divide by 3 for 24-bit or divide by 4 for 32 bit, since you are using an array.
Re: Bochs VBE with LFB, wrong pixel coordinates.
Posted: Fri Mar 04, 2016 1:07 am
by David94
SpyderTL wrote:It should be offset = (y * pitch) + (x * stride)
Where stride = bits per pixel / 8
Edit: You shouldn't be using "unsigned" ints (which are 4 bytes each), if you are using 24 bit pixels (which are 3 bytes each).
You either need to use an array of structs with 3 one byte fields, or you need to change your video mode to 32-bits per pixel.
You also need to change your offset to match your pixel size, so divide by 3 for 24-bit or divide by 4 for 32 bit, since you are using an array.
WoW, I've never been so happy to draw some pixels.
For simplicity, I changed the depth to 32bpp, and applied the stride to offset calculation, worked perfectly.
The final code looks like this:
Code: Select all
void draw_pixel(unsigned x, unsigned y, unsigned color)
{
unsigned *vga = (unsigned*)VBE_DISPI_LFB_PHYSICAL_ADDRESS;
unsigned pitch = (SCREEN_WIDTH * VBE_DISPI_BPP_32 / 8);
unsigned stride = (VBE_DISPI_BPP_32 / 8);
unsigned offset = (y * pitch) + (x * stride);
vga[offset/4] = color;
}
Thank you so much, SpyderTL and beyondsociety, with this little 'setting' initial, I believe I can go on.