Hi,
Shikhin wrote:A
short summary of my problem: I just don't know what I need to know for this. I ended up scanning the compilation of Book Recommendations by L4B, and downloading 'Black Book of Graphics Programming'. However, that exactly didn't seem like what I wanted. I did a lot of googling, but on the overall, I'm very confused on where to begin, with what.

The general approach depends on the level of complexity and capabilities you want from it. However, it can be easier to start simple and then build on that (rather than starting from "complex" and being confused

).
The simplest possible way would be to use the old "VGA" BIOS functions to set a mode like 640 * 480 * 16 colours, and just use that. No EDID, no VBE and no list/s of video modes. This should allow you to write code that generates graphics data for all 16 colour modes (e.g. just use variables for "address of display memory", horizontal resolution, vertical resolution and "bytes between lines" so that it's easy to support all other 16 colour modes later).
If you're planning to support other colour depths later, then I'd recommend that you generate the graphics data in a specific format (e.g. 32-bit per pixel format) in a buffer in RAM, and then (after everything is drawn in the buffer) convert from that format into what the video mode needs. This means that eventually (e.g. when you support 4-bpp, 8-bpp, 15-bpp, 16-bpp, 24-bpp and 32-bpp) you only need to write more conversion routines and don't need new versions of all the different functions that do the drawing.
The next step might be to add support for other "16 colour" VGA modes (640 * 350, 640 * 200 and 320 * 200). For this you could just use conditional compilation - e.g. "#if USE_320_240_4BPP_MODE ....". This should be very easy to do, and it lets you make sure that the code to generate the graphics data does handle other resolutions properly.
Next, add support for 320 * 240 * 256 colour mode (and modify your "drawing" code to support all 256 colour modes).
After that you could generate a list containing the details for all of the VGA modes that you support (mode number, resolution, colour depth, address of display memory, etc); and write code to choose a video mode from your list. How your code decides which mode to choose depends on your OS. It could be a complex thing that takes into account various ratings (e.g. user's preference, OS's preference, monitor's preference, etc), or it could be something simple like "always choose the highest resolution video mode", or it could be some sort of menu that the user uses to choose one. It should also be easy to make it simple to begin with, and then replace it with something more complex later on. Once you've chosen a mode, you should use the mode number from the list to set that video mode - e.g. write your own "set_video_mode(mode_number);" function that calls the BIOS function and then does things like setup the palette if/when necessary).
The next step would be the beginning of VBE support. Get the list of video modes from VBE then have a loop to check each mode. To begin with, for each video mode:
- Check if the OS supports it (e.g. make sure it doesn't require bank switching, and that it's either a 4-bpp/16 colour mode or a 8-bpp/256 colour mode).
- Add the details for the video mode to your list of modes.
You'd also modify your "set_video_mode(mode_number);" function to accept and handle VBE modes.
Now you should be able to support and 4-bpp/16 colour mode and any 8-bpp/256 colour mode (e.g. including 1920 * 1600 * 256 colour, etc). After that, you'd add support for more colour depths (15-bpp, 16-bpp, 24-bpp, 32-bpp); so that your code is able to handle (almost) every possible video mode.
Then comes EDID. Start by just getting the raw EDID data and putting it into a buffer in RAM.
Then you'd want to write code to parse the EDID data. Unfortunately EDID is messy (it uses a bunch of different ways to represent video modes). The end result of parsing should be that some generic variables are set (e.g. physical size of screen in millimetres, etc) and a sane list of supported video mode timings (including some sort of "monitor preference" rating for each of them). After parsing you'd just display the details to make sure it works like it should.
The next step would be to loop through the video modes you got from the video card. For each video mode, use the data you got from EDID to determine the probability that the monitor supports it and also set a "monitor preference" for that video mode. Now modify the routine that chooses a video mode from a list to take into account the probability that the monitor supports the mode and the "monitor preference".
The final step would be to add support for the "CRTC info" structure that VBE 3.0 introduced, to force the video card to generate timings that the monitor wants. This means creating new versions of VBE video modes, so that (in your list of video modes) you'd end up with the original VBE mode (without CRTC info) and none or more new versions of the same video mode (with CRTC info). This allows you to make sure the monitor supports the timing (rather than guessing at the chance of the monitor supporting the mode); and also allows you to support different refresh rates (e.g. "800 * 600 @ 60 Hz", "800 * 600 @ 75 Hz", etc). There's also a "double scanned" flag in the CRTC info which allows you to halve the vertical resolution and create even more video modes (e.g. create "800 * 300" modes from an "800 * 600" mode).
For example, if the video card supports 4 different "800 * 600" video modes (at different colour depths, e.g. 4-bpp, 8-bpp, 16-bpp and 32-bpp), then you'd have 4 "base modes". If you can use CRTC info to set timing then you might expand that list of 4 modes to 3 different refresh rates (e.g. 60 Hz, 75 Hz, 80 Hz) and end up with the 4 original modes plus 12 new modes (e.g. "800 * 600 * 4-bpp @ 60 Hz", "800 * 600 * 4-bpp @ 75 Hz", etc); and then use the "double scanned" flag to get 12 more variations (e.g. "800 * 300 * 4-bpp @ 60 Hz", "800 * 600 * 4-bpp @ 75 Hz", etc). The end result may be a total of 28 different modes (including the original 4 modes). I've done this before - from around 22 modes reported by VBE, I ended up with a list of around 150 different video modes.
That's about as complex as things can get, so after all that you're done (but you may be done sooner if you don't want all of that)!
Cheers,
Brendan