
| Resolution | Colours | Memory Required |
| 640 x 400 | 256 | 250Kb |
| 640 x 480 | 256 | 300Kb |
| 800 x 600 | 256 | 469Kb |
| 1024 x 768 | 256 | 768Kb |
| 1280 x 1024 | 256 | 1.28Mb |
| 640 x 400 | 65536 | 500Kb |
| 640 x 480 | 65536 | 600Kb |
| 800 x 600 | 65536 | 930Kb |
| 1024 x 768 | 65536 | 1.5Mb |
| 1280 x 1024 | 65536 | 2.5Mb |
| 640 x 400 | 16.7 million | 750Kb |
| 640 x 480 | 16.7 million | 900Kb |
| 800 x 600 | 16.7 million | 1.4Mb |
| 1024 x 768 | 16.7 million | 2.25Mb |
| 1280 x 1024 | 16.7 million | 3.75Mb |


256 colour modes (8 - bit):
32768 colour modes (15 - bit):

65536 colour modes (16 - bit):

16.7 million colour modes (24 - bit):

Extended VGA BIOS Interrupt list
For clarity, I am going to split the program up on several different pages, listed below.
Try to write all the pixels in one bank before switching to the next. ie, write all those
pixels in bank 0, then switch to bank 1 and write all the pixels in that bank.
If this is not possible, then keep a record of the current bank and don't switch if you
don't need to.
The VESA specification says this:
The organization of most software algorithms which perform video operations consists of a pair of nested loops: and outer loop over rows or scan lines and an inner loop across the row or scan line. The latter is the proverbial inner loop, which is the bottle neck to high performance software.If a target rectangle is large enough, or poorly located, part of the required memory may be with within the video memory mapped into the CPU address space and part of it may not be addressable by the CPU without changing the mapping. It is desirable that the test for remapping the video memory is located outside of the inner loop.
If the granularity is equal to the length of the CPU address space, i.e. the least significant address bit of the hardware mapping function is more significant than the most significant bit of the CPU address, then the inner loop will have to contain the test for crossing the end or beginning of the CPU address space. This is because if the length of the CPU address space (which is the granularity in this case) is not evenly divisible by the length of a scan line, then the scan line at the end of the CPU address will be in two different video memory which cannot be mapped into the CPU address space simultaneously.

The format of this array would be as follows:
structure BankArray
integer BankNum ; The bank the first pixel on the scanline
; resides in
integer Boundary ; the last pixel in the scan line which
; resides in that bank. If there is no boundary
; then set this value to the Logical screen width
end structure
array BankArray(0 to NumScanLines-1)
um, I think an example would be in order:
The first 102 scanlines reside entirely inside bank 0.
BankArray.Banknum(i) = 0 BankArray.Boundary(i) = 0 ;0 meaning that no bank change happensThe 103rd scanline (number 102) crosses a bank boundary. Its 257th pixel (number 256) resides in bank 1:
BankArray.Banknum(102) = 0 BankArray.Boundary(102) = 255 ;last pixel on this line in bank 0Before the filling algorithm writes to a scanline, it should check to see if either of the two X coordinates are greater than BankArray.Boundary(i).
I think it's time for a little pseudocode to make things clearer. I can't guarantee that this
code works. I just wrote it off the top of my head. Please tell me if you spot a mistake.
Procedure FillRectangle (x, y, xsize, ysize, colour)
ScreenPointer = y * LogicalWidth + x
SwitchBank(BankArray.BankNum(y))
loop y from y to (y+ysize-1)
; is there a bank boundary on this line ?
if BankArray.BankBoundary(y) > 0 then
; does it happen before the rectangle ?
if BankArray.BankBoundary(y) <= x then
switch bank to BankArray.BankNum(y)
ScreenPointer = x - BankArray.BankBoundary(y)
; draw this line
write xsize bytes to the screen
end if
; does it happen in the rectangle ?
if (BankArray.BankBoundary(y) > x) and (BankArray.BankBoundary(y) < x+xsize-1) then
; draw the first part of this line
write (BankArray.BankBoundary(y)-x) bytes to the screen
switch bank to BankArray.BankNum(y)
ScreenPointer = 0 ; the begining of the new bank
; draw the rest of this line
write xsize-(BankArray.BankBoundary(y)-x) bytes to the screen
ScreenPointer = ScreenPointer + 640-xsize ; next line
end if
; does it happen after the rectangle ?
if BankArray.BankBoundary(y) > x+xsize-1 then
; draw this line
write xsize bytes to the screen
switch bank to BankArray.BankNum(y)
ScreenPointer = ScreenPointer + 640-xsize - 65536
end if
; No bank boundary on this line
else
; otherwise, just keep drawing
write xsize bytes to the screen ; write the colour
ScreenPointer = ScreenPointer + 640-xsize ; next line
end if
end loop
end FillRectangle