Page 1 of 1

VGA Memory Map

Posted: Sun Jan 16, 2011 8:18 pm
by myrk
Hello,
What would be the best way to create a two-dimensional pointer that points to the 0xA000 that goes like this:

Code: Select all

pointer[x][y] = color;
(for a 640x480x8 mode)
Thanks. :D

Re: VGA Memory Map

Posted: Sun Jan 16, 2011 8:49 pm
by pcmattman
Determine the width of a row in the framebuffer, use that as the 'x' dimension. Determine the number of rows, use that as the 'y' dimension.

Also, you should be addressing as:

Code: Select all

buffer[y][x] = color;
Do the pointer maths on paper to find out why.

Also, the framebuffer is not always purely linear - sometimes there may be padding on the end of each row, and sometimes there may be banks for the video mode. Make sure you're aware of the intricacies of the mode you're using and what your BIOS calls do.

Re: VGA Memory Map

Posted: Mon Jan 17, 2011 10:39 am
by myrk
Ok, thanks. But how would I declare it? Would it be:

Code: Select all

char * buffer[y] = 0xA000
Thanks

Re: VGA Memory Map

Posted: Mon Jan 17, 2011 11:04 am
by Brendan
Hi,
myrk wrote:What would be the best way to create a two-dimensional pointer that points to the 0xA000 that goes like this:

Code: Select all

pointer[x][y] = color;
(for a 640x480x8 mode)
If "640x480x8" is a 256-colour mode, then that isn't a standard VGA mode. It requires (at least) 300 KiB of display memory (so you'd have to use bank switching or a linear frame buffer to access it because 300 KiB is more than 64 KiB), and the number of bytes per line may be more than 640 bytes (with padding, etc after the "real" data). For both of these reasons you wouldn't be able to treat it as a simple 2 dimensional array.

Note: The compiler must know how many "bytes per line" at compile time to be able to calculate the address of the next line.

Basically, to do it properly (assuming you're using a linear frame buffer and not bank switching) you need to use "unsigned char *pointer;" or "unsigned char pointer[];" and treat it as a single-dimensional array, where you do "pixel = pointer[y*bytes_per_line + x];" so that the address is calculated at run-time and not at compile time. Assuming you're using a linear frame buffer, the address of display memory will not be 0x000A0000 (it will probably be somewhere in the "PCI hole" between 0xC0000000 and 0xFFF00000, and you must use VBE to find out where).

To do it properly with bank switching, it gets messy because you can only access the selected 64 KiB bank, and you need to tell the video card (using VBE functions) which 64 KiB bank you want to use.


Cheers,

Brendan

Re: VGA Memory Map

Posted: Mon Jan 17, 2011 12:28 pm
by myrk
Ok, I'll try that.
But if 640x480x8 isn't the standard VGA mode, then what is it?
Thanks.

Re: VGA Memory Map

Posted: Mon Jan 17, 2011 1:49 pm
by Tosi
There is no "standard" VGA mode. You tell the BIOS what mode to set or you manipulate the VGA registers directly.

Re: VGA Memory Map

Posted: Mon Jan 17, 2011 1:51 pm
by NickJohnson
Even though there isn't exactly a standard VGA mode, 320x200x8 is the typical setup and is easiest to work with, although 320x240x8 is the maximum possible with 8 bit depth.

Re: VGA Memory Map

Posted: Tue Jan 18, 2011 3:14 am
by Combuster
NickJohnson wrote:320x240x8 is the maximum possible with 8 bit depth.
Nope. 320x240x8 is the safe maximum for square pixels, 320x480x8 is the real "safe" maximum. 400x300 (actually 416x312x8) is the maximum square pixel size with page flipping, which still works fairly well but not everywhere since it is a bit demanding on your monitor's timing circuitry (which is capable of destroying old fixed-sync CRTs, as well as some cheap LCDs that shouldn't have been made). And, for the record, you have the theoretic maximum of 588x441x8 which comes with a big fat epilepsy warning besides the standard monitor destruction disclaimer and the fact that I haven't actually seen it work.

In any case, anything beyond 320x200x8 requires banked or planar memory access, and so do all regular 4-bit modes - which is exactly why this mode was popular: it is the easiest graphics mode (by an order of magnitude) to develop for.

Re: VGA Memory Map

Posted: Tue Jan 18, 2011 5:40 am
by Brendan
Hi,
myrk wrote:But if 640x480x8 isn't the standard VGA mode, then what is it?
There's 3 parts to this.

The first part is the video card's low-level interface (IO ports, etc). After VGA there were a lot of extensions on top of VGA (more display memory, higher resolutions, higher colour depths) that were all typically referred to as "SVGA" (or Super VGA); but "SVGA" was never a standard. Different video card manufacturers all added their own extensions in their own incompatible way.

The second part is the interface programmers use. For SVGA, initially someone writing (for e.g.) a game for DOS would detect what sort of card is present and write their own driver for each video card to control things like bank switching (while using non-standard extensions for the old "int 0x10, ah = 0x00" BIOS function to set higher resolution video modes). This was a nightmare for programmers. Fortunately VESA released the VBE standard not long after so that software had a sane interface they could use instead. For some video cards (e.g. video cards that didn't support VBE in ROM) VBE was implemented as a TSR for DOS, but it didn't take long before all video cards supported VBE in ROM.

The third part is the signals to the monitor, which includes the timing of lots of different signals (see Video Signals And Timing for a full description). For the (red/green/blue) colour signals, a DAC converts the digital colour data into analogue signals. Because these signals are analogue it doesn't matter how many bits of colour data the DAC uses to create the analogue signals - from the monitor's perspective it's "640 * 480 with analogue colour data @ 60 Hz". Therefore, for a 640 * 480 * 8-bpp video mode the video card can use video signal timings originally defined by VGA without the monitor knowing/caring. The VGA's "640 * 480 @ 60 Hz" video signal timing became the basis of VESA's "safe mode timing" standard (which is a formal specification, and not a de-facto standard that we ended up with due to other manufacturers cloning IBM's video cards). VESA also defined a bunch of other video mode timings for higher resolutions and higher refresh rates; but (unlike the "safe mode timing" which monitors are sort of required to support) these other standardised video mode timings all optional.


Cheers,

Brendan