Plot pixel at Linear Frame Buffer
Plot pixel at Linear Frame Buffer
Hello all,
This is my first post in this forum. I'm creating an operating system and I'm pretty successful until now. I'm using VESA and want to plot a pixel. I can find examples for doing it in C, but the problem is I'm still using assembly. How to plot a pixel in assembly? I'm using mode 117h (1024 x 768 16bit color). I already found the address of the linear frame buffer. I hope somebody can help.
Thanks in advance.
This is my first post in this forum. I'm creating an operating system and I'm pretty successful until now. I'm using VESA and want to plot a pixel. I can find examples for doing it in C, but the problem is I'm still using assembly. How to plot a pixel in assembly? I'm using mode 117h (1024 x 768 16bit color). I already found the address of the linear frame buffer. I hope somebody can help.
Thanks in advance.
Re: Plot pixel at Linear Frame Buffer
Hi,
Then multiply the X co-ord by the bytes per pixel (2) to find the offset of the pixel on the line; then add it to your "offset for the start of the line". For example (assuming EBX contains the X co-ord):
Then add the address of the LFB. Hopefully you're using paging to map it at a fixed address, so the above instruction can be "lea edx,[ebx*2+eax+LFB_address]". Otherwise you need a whole new instruction for it:
Once you've got the right address calculated, store the colour at the address. For example (assuming CX contains the colour):
Of course hopefully you're using paging and can combine this with the "lea edx,[ebx*2+eax+LFB_address]", and do "mov [ebx*2+eax+LFB_address],cx" instead.
Basically, if your LFB isn't at a fixed address you might get something like this:
And if your LFB is at a fixed address you might get something like this:
Now; in both cases the code is relatively small, so the call/ret will add significant overhead. For this reason it'd be better to implement it as a macro.
Cheers,
Brendan
Find the offset in the LFB for the start of the line, using "Y * bytes_per_line". For example (assuming EAX contains the Y co-ord):Elja98 wrote:This is my first post in this forum. I'm creating an operating system and I'm pretty successful until now. I'm using VESA and want to plot a pixel. I can find examples for doing it in C, but the problem is I'm still using assembly. How to plot a pixel in assembly? I'm using mode 117h (1024 x 768 16bit color). I already found the address of the linear frame buffer. I hope somebody can help.
Code: Select all
mul dword [bytes_per_line] ;edx:eax = y * bytes_per_line
Code: Select all
lea edx,[ebx*2+eax] ;edx = y * bytes_per_line + x * bytes_per_pixel
Code: Select all
add edx,[LFB_address] ;edx = LFB_address + y * bytes_per_line + x * bytes_per_pixel
Code: Select all
mov [edx],cx
Basically, if your LFB isn't at a fixed address you might get something like this:
Code: Select all
;Input:
; eax = Y co-ord
; ebx = X co-ord
; cx = colour
;
;Output
; none
;
;Trashed
; edx, eax
plotPixel:
mul dword [bytes_per_line] ;edx:eax = y * bytes_per_line
lea edx,[ebx*2+eax] ;edx = y * bytes_per_line + x * bytes_per_pixel
add edx,[LFB_address] ;edx = LFB_address + y * bytes_per_line + x * bytes_per_pixel
mov [edx],cx ;Set the pixel's colour
ret
Code: Select all
;Input:
; eax = Y co-ord
; ebx = X co-ord
; cx = colour
;
;Output
; none
;
;Trashed
; edx, eax
plotPixel:
mul dword [bytes_per_line] ;edx:eax = y * bytes_per_line
mov [ebx*2+eax+LFB_address],cx ;Set the pixel's colour
ret
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Plot pixel at Linear Frame Buffer
Thanks for your quick reply Brendan! Such an easy answer for something I worked days on Thanks for your help
Re: Plot pixel at Linear Frame Buffer
I tested your code but unfortunately it doesn't work. Is there something that I have to do with the GDT? Or anything I have to setup to make your code work. Here's my code for now:
My 16 bits code:
After that I enter 32 bits mode and use this:
Again, Thanks in advance
My 16 bits code:
Code: Select all
mov ax, 4F02h ;Set video mode
mov bx, 117h ;1024 x 768 16 bpp
or bx, 4000h ;Use Linear Frame Buffer
int 10h
mov ax, 4F01h ;Get mode information
mov cx, 117h ;Of mode 117h
mov di, buffer
int 10h
mov ax, WORD [buffer+2Ah] ;Get location of Linear Frame Buffer
mov WORD [loc_lfb], ax ;Save it
mov ax, WORD [buffer+32h] ;Get Bytes Per Scanline
mov WORD [BPS], ax ;Save it
Code: Select all
mov eax, 1 ;X = 1, Y = 1
mov ebx, 1
mov cx, 0000011111100000b ;Color = green
PlotPixel:
mul WORD [BPS] ;eax = Y * BytesPerScanline
lea edx, [ebx*2+eax] ;edx = X * 2 + Y * BytesPerScanline
add edx, [loc_lfb] ;edx = (X * 2 + Y * BytesPerScanline) + LFB (0xE000 bochs)
mov [edx], cx ;Plot it
Re: Plot pixel at Linear Frame Buffer
Isn't the LFB at offset 0x28 within the structure? And 4 bytes long?
Regards,
John.
Regards,
John.
Re: Plot pixel at Linear Frame Buffer
Yes, but first I did some tests with Bochs to print the dword at 28h. I got 0x0000E000 so I just decided to ignore the first byte and just use 0xE000.
- 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:
Re: Plot pixel at Linear Frame Buffer
Your print function is wrong. The correct answer is 0xE0000000 (stored as 00 00 00 E0), not 0x0000E000 (which would be 00 E0 00 00 in memory)
Also ignoring one byte is not the same as ignoring two bytes. This business is very, very sensitive to details and I would recommend that you grow some appreciation for that. Tiny mistakes like these will tend to haunt you through your entire OS if left unchecked.
Also ignoring one byte is not the same as ignoring two bytes. This business is very, very sensitive to details and I would recommend that you grow some appreciation for that. Tiny mistakes like these will tend to haunt you through your entire OS if left unchecked.
Re: Plot pixel at Linear Frame Buffer
I'm feeling like a complete idiot right now. I always forget to swap bytes and words when I read hex. I work days on it and after that I find out I have to swap them. But thanks sir!
I changed my code and it works perfect:
Thanks to everybody that helped me
I changed my code and it works perfect:
Code: Select all
16 bits:
mov ax, WORD [buffer+28h]
mov WORD [loc_lfb], ax
mov ax, WORD [buffer+2Ah]
mov WORD [loc_lfb+2], ax
32 bits:
PlotPixel:
mul WORD [BPS]
lea edx, [ebx*2+eax]
add edx, [loc_lfb]
mov [edx], cx
loc_lfb dd 0
Re: Plot pixel at Linear Frame Buffer
normally you'd rather plot on a backbuffer in memory and then copying the backbuffer on the vesa framebuffer memory, it avoid flickering or out of sync display, the method is the same than explained above but done to a memory buffer, and with vesa you can also have the backbuffer in video memory if you change the access window with a vesa interupt, you can store your pixel in some part of the video memory that is not displayed, and then swap the start address of display memory to display it and then draw the new pixels in the area that is not displayed, i don't remember all the details of doing that, but it's not very good to draw directly to the display framebuffer, with the vesa memory window change, you can have a backbuffer without the need to copy a backbuffer to video memory