Message board for the users of flat assembler.
> OS Construction > How to set a single pixel without interrupt?
ivan_tux 30 Jun 2012, 11:42
|30 Jun 2012, 11:42||
me239 30 Jun 2012, 22:14
well if you can get to mode 13h, then you can write to the video memory at 0xA000.
mov ax, 0013h int 10h push 0xa000 pop es xor di, di mov al, 04 stosb int 20h
this should place a red pixel in the right corner.
|30 Jun 2012, 22:14||
Stephen 01 Jul 2012, 05:44
That depends mostly on two things 1) are you in 16, 32 or 64 bit mode, 2) what video mode are you in, text, a vga type mode or a vesa mode. If you are in vesa mode are you using a lfb.
The basic answer is simple. the screen is a memory location and you simply write to that location. If it's vga and not text or mode 13h you likely also need to play with io ports and use paged memory. If it's vesa you need to find out where the lfb is in memory and write to that area. It also gets a bit complicated and depending on the video card, each pixel might be as few bits as 1 and as many as 32. Mode 13 is nice, in that it's 8 bits and the vesa modes you are likely to use are likely 32, but your card might only support 24 bit pixels.
I don't think there is a video card that doesn't support mode 3 text and mode 13h graphics. The address would be 0xA0000, 0xA000 or 0xB8000, 0xB800 for text. Unless you've been playing with your segment registers
|01 Jul 2012, 05:44||
ivan_tux 09 Jul 2012, 01:50
How about VESA?
When i try to run code from some tutorials, it doesnt display anything...
I'm using Bochs
|09 Jul 2012, 01:50||
freecrac 10 Jul 2012, 09:59
How about VESA?
I never used Bochs, but maybe you forget to enable VESA by setting the vga option to vbe?
Or the tutorial use a unsupported resolution (current limitation)?
Running under pure DOS there is no limitation, so we can use all resolution that come within our vesa-bios, if our monitor provide those resolutions too, checking the capacity by getting the EDID via DDC.
With my Nvidia GTX 295 card i can use the native widescreen resolution of my 28" LCD in 1920x1200x32.
Using this VBE-mode i can set a single pixel by writing a dword to the linear framebuffer.
|10 Jul 2012, 09:59||
ivan_tux 11 Jul 2012, 00:44
@freecrac. hey, you're right...
the mode that i chose is not supported by Bochs.. thanks friend
And my last question is :
how to set a pixel in 24bpp mode?
a. store 3 bytes color to lfb
b. store 4 bytes color(1st byte unused).
i have tried A. it work work on bochs, but B not works perfectly..
i know A works perfectly on bochs, but i"m still doubt...
[sorry, bad English]
|11 Jul 2012, 00:44||
freecrac 11 Jul 2012, 06:50
@freecrac. hey, you're right...
No problem, i try to use some simple english words.
With 24bpp we have to write three single bytes, or at minimum one word and one byte for to set one pixel.
With regarding of the FieldPosition and the MaskSize of the colors we have to check the pixel format, so if we become a RGB-pixel format, or a BGR-pixel format.
If we found a RGB-pixel format, then we become red, green, blue, red, green, blue, .....and so on,
else if we found a BGR-pixel format, then we become blue, green, red, blue, green, red, ....with 24bpp.
Personaly i can not understand why those videomodes with 24bpp continue to be exist on modern video cards with a lot of videoram.
So i prefer modes with 32bpp, so we can write only one dword to set a single pixel.
red, green, blue, x, red, green, blue, x, ....
x, blue, green, red, x, blue, green, red, .... with 32bpp.
Some words about how to calculate an address of a pixel.
The horizontal X-resolution and the vertical Y-resolution, the bits per pixel and the length of the logical scanline can be found inside of the Mode-Info-Block.
The length of the logical scanline can be longer as the X-resolution and then one part of the scanline is outside of the visible screensize.
Example: If we want to use a resolution of 640x480x8 and the length of the logical scanline is 1024,
then the second line begin at the address 1024 and not at the address 640.
The addressrange of the first line is then from 0 - 1023 and the content of the addresses between 640 - 1023 are not visible in this mode.
The same occur with all other lines of this mode, only 640 pixel per line are visible, but we have to calculate the addresses of the lines with the length of the logical scanline of the Mode-Info-Block.
The addresses of the beginning of every line can be calculated and be stored in a address-table before we begin to calculate an address of a pixel.
Using this table (with our pixel set routine) we can use the quadruple of the Y-position as a pointer inside of our table to get the address of the line.
Now we can simple add the X-position to become the address of the pixel.
Result: Our pixel set routine will be shorter and lost one calculation.
But the ram-access to our address-table cost some times, if the table is not fully cached inside of the first level cache of the CPU.
If you have some more questions, then please ask again.
|11 Jul 2012, 06:50||
ivan_tux 11 Jul 2012, 10:56
wow, you are the best
By the way, where i can get vesa tutorial?
|11 Jul 2012, 10:56||
freecrac 11 Jul 2012, 13:00
wow, you are the best
I never found a tutorial about all functions of VBE 3.
But in the public document vbe3.pdf we can find some information.
I download the public and cost free documents directly from vesa.org.
But the download from vesa.org need to register and/or login, because the internet adress of the download page change every time we open/enter this download page.
Beginning with VBE2 we have to use the vesa modenumbers of our vesa bios.
These numbers(Words) are stored in a modetable and the end of this table is signed with FFFF.
With function 0 we can get the vesa information in a buffer of 256(vbe3 512) bytes, if no error occur.
Inside of the buffer we can find "VbeVersion dw ?" and "VideoModePtr dd ?". Here we can find the offset, segment address to the modenumbertable.
With function 1 we can get the Mode information of each modenumber in a new buffer of 256 bytes.
If we can find a number with a resolution that we want to use, then we can switch to this mode with funnction 2.
In a situation that we poll the Input Status #1 Register at port 3DAh on an unbufferd screen
and we move larger objects by writing those object directly to the visible screen and make a restauration on the last position,
then the flickering and tearing will be very ugly (most shown on the top of the screen).
Address calculation using VESA hardware triple buffering
(Note: The vesa hardware triple buffering are only aviable with a VBE 3 bios and it is more usefull in combination with higher refreshrates than the default 60hz.)
The goal of using a buffering is to move very large objects across the hole screen without to become a tearing or a flickering on the screen.
(I test this function with my older geforce 4 card from MSI(AGP; 64MB) and a 19" CRT monitor from Samsung with 96khz/160hz in 1024x768x32@100hz.)
Each buffer has a size that can be calculate with (the length of the logical scanline) * (the vertical Y-resolution) * (the count of the bits per pixel).
Starting with the first buffer at the address of the LFB
An example of a pure DOS(without emm386 or other ems-manager) Application can be download from my homepage:
Need to boot pure DOS without memorymanager like emm386.exe.
Need a VBE3-Bios and an analog CRT-monitor with 96khz or higher.
Last edited by freecrac on 12 Jul 2012, 04:50; edited 1 time in total
|11 Jul 2012, 13:00||
ivan_tux 12 Jul 2012, 00:08
OK, i think just that...
Thank a lot, you're helpful...
|12 Jul 2012, 00:08||
< Last Thread | Next Thread >
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.