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.
Bochs VBE with LFB, wrong pixel coordinates.
Re: Bochs VBE with LFB, wrong pixel coordinates.
The bga page has details about the bits per pixel register, and the memory layout.
Is this what you are looking for?
Is this what you are looking for?
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Re: Bochs VBE with LFB, wrong pixel coordinates.
Thanks for quickly reply,SpyderTL wrote:The bga page has details about the bits per pixel register, and the memory layout.
Is this what you are looking for?
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.
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.)
There is no hidden memory between one row of pixels and the next. (Unless you have enabled virtual screen space.)
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
- beyondsociety
- Member
- Posts: 39
- Joined: Tue Oct 17, 2006 10:35 pm
- Location: Eagle, ID (USA)
- Contact:
Re: Bochs VBE with LFB, wrong pixel coordinates.
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.
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.
"I think it may be time for some guru meditation"
"Barbarians don't do advanced wizardry"
"Barbarians don't do advanced wizardry"
Re: Bochs VBE with LFB, wrong pixel coordinates.
Thanks for the answers,
as result I have: http://i.imgur.com/jHohIU2.png, It may be something trivial that I'm forgetting.
I'm using 1024x768, 24bpp, so the pitch was 3072? I'm using this code to draw and yet still wrong position: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.)
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);
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.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.
Re: Bochs VBE with LFB, wrong pixel coordinates.
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.
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.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Re: Bochs VBE with LFB, wrong pixel coordinates.
WoW, I've never been so happy to draw some pixels.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.
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;
}