=====================================================================
ISSUES/QUESTIONS/UNKNOWNS
=====================================================================
- chain4 16-color mode 416x312, with the color planes 16224 bytes apart?
  possible? don't have to use outportb() to select the plane/color
- nominal sync pulse widths? 5 uS for HS? what for VS?
        for automatic setting of sync pulse width in vgaTimingToReg()
- VGA text-mode fonts 16 bits wide? 32 bits? probably not possible
- figure out what byte/word/doubleword modes do
- higher 16-color or 2-color resolution than 640x480?

- VLinesPerChar==2 truly the same as doublescan?
  can I use VLinesPerChar==3? ==4?
- interlace? VGA doesn't support it?
- NTSC output (to TV)? My monitor says NTSC.C produces the proper sync
  frequencies but it won't display anything...
- use of various write modes (incl. set/reset)?
- flesh out 27-entry mode table
- 3 registers select text/alpha: what happens when you mix & match?
- 3 registers select even/odd: mix and match?
- (un)chained mode w/ 64K bank select?
- is calculation of HBlankEnd, VBlankStart, VBlankEnd correct?
- set/reset mode? write mode? use ALU and/or rotate?
- control of plane read from/written to?

====================================
DETECTING/IDENTIFYING VIDEO HARDWARE
====================================
PCI boards: use the PCI BIOS or equivalent code. (Reliable and safe
detection of hardware is a major win of PCI.) My video board shows
up in a PCI scan as
        Vendor 0x5333 (S3)
        Device 0x8811 (Trio 64V+; 86c765)

ISA PnP boards: unknown

Non-PnP ISA boards: Asssume VGA, then apply chipset-specific
detection routines. This involves poking registers to see if
they're present, trying to change registers that contain read-
only values such as the chipset revision, etc.

Monochrome or color emulation for VGA: According to Dark Fiber
(http://homepages.ihug.com.au/~entropy), you need to look at a
value stored in the BIOS data segment:

        Foo=_farpeekb(_dos_ds, 0x410) & 0x30;
        if(Foo == 0x00 || Foo == 0x20)
        {       /* color  emulation
                        CRTC index register at 0x3D4
                        CRTC data  register at 0x3D5
                        input stat register at 0x3DA */ }
        else if(Foo == 0x30)
        {       /* monochrome emulation
                        CRTC index register at 0x3B4
                        CRTC data  register at 0x3B5
                        input stat register at 0x3BA */ }
        else /* ??? */ ;

=====================================
VGA ARCHITECTURAL UNITS AND REGISTERS
=====================================
Get Finn Thoegersen's VGADOC4B.ZIP, and look at file VGAREGS.TXT.
Briefly:

    CRT controller (CRTC)
        index register at 0x3D4 (color) or 0x3B4 (mono)
        data  register at 0x3D5 (color) or 0x3B5 (mono)
        25 data registers.

    Attribute controller (AC)
        index register at 0x3C0
        read data from 0x3C1
        write data to 0x3C0
        21 data registers.

        Writes to 0x3C0 alternate between index and data. Read
        from the input status register (0x3DA color, 0x3BA mono)
        to reset 0x3C0 to index.

    Graphics controller (GC)
        index register at 0x3CE
        data  register at 0x3CF
        9 data registers.

    Sequencer (SEQ)
        index register at 0x3C4
        data  register at 0x3C5
        5 data registers.

    Miscellaneous (MISC) register.
        read data from 0x3CC
        write data to  0x3C2

    DAC
        read index at 0x3C7
        write index at 0x3C8
        data register at 0x3C9
        256 3-byte palette entries.

        To write all or part of the 256-color palette:
        - write first color index to I/O address 0x3C8
	- while more_colors_to_read:
                - read 6-bit red value from I/O address 0x3C9
                - read 6-bit green value from I/O address 0x3C9
                - read 6-bit blue value from I/O address 0x3C9
        The color index at 3C8h will be automatically incremented
        after the third write (the blue value) to 0x3C9.

        To read all or part of the 256-color palette:
        - write first color index to I/O address 0x3C7
	- while more_colors_to_read:
                - read 6-bit red value from I/O address 0x3C9
                - read 6-bit green value from I/O address 0x3C9
                - read 6-bit blue value from I/O address 0x3C9
        The color index at 3C7h will be automatically incremented
        after the third read (the blue value) from 0x3C9.

=====================================================================
THE OVERUSED WORD 'MODE'
=====================================================================
Graphics modes:
--> 3 registers select text/alpha, one selects 256-color or not
text:		Character generator and serializer enabled.
                Planes (P1, P2, P4, and P8) select between text,
                attribute, and/or font.
16-color:	Character generator disabled, serializer enabled.
		Planes set drawing color.
256-color:	Character generator and serializer disabled.
		Planes used to extend display address space.

Addressing modes (CPU access to video memory):
--> 3 registers select even/odd, one selects chain 4
flat:		Consecutive addresses select consecutive memory
		bytes in a single plane. Used by 16-color graphics
                modes and Mode X. Plane controls the color written
                to the screen (16-color modes) or selects 64K bank
                (Mode X).
even/odd:	Lowest address bit selects between planes P4/P1
		(even addresses) or planes P8/P2 (odd addresses).
		Used by text modes. Plane chooses between character/
		attribute display (P1 and P2) or font (P4).
chain4:		Lowest TWO address bits select plane. Used by
		256-color BIOS mode 13h. All planes must be
		enabled.

Clocking modes:
--> 2 registers select byte mode, word mode, doubleword mode.
doubleword:	?
word:		?
byte:		?

=====================================================================
MASTER MODE TABLE
=====================================================================
3^3 = 27 combinations

                graphics        addressing      clocking
description     mode            mode            mode     
===========	========	=========	========
		text		flat		byte
(This puts character bytes at consecutive addresses, and the
attribute bytes in a separate plane.)
		text		flat		word
		text		flat		doubleword
		text		even/odd	byte
BIOS text	text		even/odd	word
		text		even/odd	doubleword
		text		chain4		byte
		text		chain4		word
		text		chain4		doubleword
BIOS 12h        16-color        flat            byte
		16-color	flat		word
		16-color	flat		doubleword
		16-color	even/odd	byte
		16-color	even/odd	word
		16-color	even/odd	doubleword
		16-color	chain4		byte
		16-color	chain4		word
		16-color	chain4		doubleword
Mode X		256-color	flat		byte
		256-color	flat		word
		256-color	flat		doubleword
		256-color	even/odd	byte
		256-color	even/odd	word
		256-color	even/odd	doubleword
		256-color	chain4		byte
		256-color	chain4		word
BIOS 13h	256-color	chain4		doubleword

====================================================================
COMMON ERRORS
====================================================================
- undo the write-protect bits in CRTC registers 03h and 11h
- can't access 16-color palette unless b5 of attribute index reg is clear
- remember to set b5 of attribute index reg after changing palette,
  else display will go blank
- only lowest 6 bits of R, G, and B palette entries are significant
- BIOS text output routines don't work as expected if you've been
  fiddling directly with the VGA registers
- it's the same memory, whether it's at B800:0000 or A000:0000
  i.e. scribbling at offset 0 in graphics mode will clobber whatever
  was on text page 0

====================================================================
VGA TIMING IN A NUTSHELL
====================================================================
Different registers in the VGA chose the dot clock, character clock
divisor (8 or 9), Htot, Vtot, etc. For more info, see VGAREGS.TXT
or any of the Open Source VGA libraries (e.g. Linux SVGAlib).

Dot clock (or pixel clock or master clock); one of the following:
    28.35 MHz       14.175 MHz      25.2 MHz       12.6 MHz

    SVGA cards have a broader range of dot clocks to chose from.
    Some cards have a PLL synthesizer that can produce almost
    any desired dot clock frequency.

Character clock
    1/8 or 1/9 the dot clock frequency. Used in graphics modes
    as well as text.

Horizontal retrace (sync) frequency
    = character clock / Htot
        31.5 KHz                (very old VGA-only monitors)
        31.5, 35.1, 35.5 KHz    (fixed-frequency SVGA monitors)
        31.5-56.0+ KHz          (newer frequency-agile monitors)

Vertical sync frequency
    = horizontal sync / Vtot
        60 or 70 Hz             (VGA-only monitors)
        43.5 interlaced or 56   (SVGA/8514)
        43.5-75+ Hz             (frequency-agile)

    It is unlikely that a modern monitor could be destroyed by
    driving it with improper sync frequencies, but you should
    be careful anyway.

Sync pulse widths
    5 microseconds horizontal? 200 usec vertical?
    Not sure about these, they could be monitor-dependent.

Blanking
    Hdisp=Htot * 80%            (typical)
    Vdisp=Vtot * 95%            (typical)

====================================================================
OTHER VGA SUBJECTS
====================================================================

How many text pages/virtual consoles?
    If you leave the text "window" at B800:0000, you get only 32K
    of memory. 80x25 resolution is 2000 characters and 4000 bytes.
    32K / 4000 = 8.129 pages/consoles.

    You can move the "window" to A000:0000 (used only for graphics
    modes by the VGA BIOS) so you get 64K instead; enough display
    memory for 16 80x25 pages/consoles.

Sync pulse polarities
    Old fixed-frequency monitors look at the sync pulse polarities
    to determine the vertical resolution (350, 400, or 480 lines).
    Newer monitors ignore sync pulse polarity.

Changing the text-mode font
    Look at Bill Currie's DJGPP kernel: http://www.taniwha.org
    Basically:
        - turn off even/odd clocking and planes P1 and P2
        - turn on flat clocking and plane P4
        - read/write font from offset:
            font    offset          font    offset
            0        0              4        8K
            1       16K             5       24K
            2       32K             6       40K
            3       48K             7       56K
        - turn off plane P4
        - turn on even/odd clocking and planes P2 and P1

Changing cursor shape
    CRTC registers 0x0A and 0x0B (first and last scanline of
    cursor within character cell).

Setting the color in 16-color mode
    outportb(0x3C4, 2);
    outportb(0x3C5, Color & 15);

    This is a quick-and-dirty way to set the color of writes.
    Later writes that overlap earlier ones will cause color
    mixing i.e. writing a red line on top of a green one will
    result in yellow.

Hardware/smooth scrolling
    - CRTC registers 0x0C and 0x0D (display start address)
    - attribute register 0x13 (smooth horizontal scrolling)
    - CRTC register 0x08 (smooth vertical scrolling for text
        and byte-panning register for Mode X)

Virtual display
    CRTC register 0x13 (offset) sets the virtual width. This is
    in bytes, words, or dwords depending on the clocking mode.
    (Width, virtual or not, must be divisible by 2, 4, or 8
    depending on clocking mode.) You must have enough off-screen
    video memory for the virtual resolution you select (e.g.
    640x400x256 Mode X uses 256000 of the 262144 bytes of VGA
    memory (588x441 for 4:3 aspect ratio)).

Highest resolution
    text:       90x60 displayed,    ? virtual
    16-color:   ? displayed,        800x600 virtual
    256-color:  360x480 displayed,  640x400 virtual (using Mode X)

Mode X
    Advantages of Mode X (from "Zen of Graphics Programming",
    by Mike Abrash):
    - Can program the VGA to move data from one video memory
      location to another four bytes at a time (fast!).
    - Mode X is a byte-per-pixel mode, and has simpler/faster
      software than 16-color mode (though not as simple as
      regular packed-pixel 256-color mode).
    - Can have 320x240 resolution with 4:3 aspect ratio (square
      pixels).
    - Can do fast animation with page-flipping.
    - Large amount of offscreen memory, relative to mode 0x13.

    If you give some of these advantages, you can get Mode X up
    to 360x480 resolution.

Getting to mode X
        /* set BIOS mode 0x13, then:
        turn off Chain4 */
                outportb(0x3C4, 0x04);
                Temp=inportb(0x3C5);
                outportb(0x3C5, Temp & ~0x08);
        /* turn off doubleword clocking */
                outportb(0x3D4, 0x14);
                Temp=inportb(0x3D5);
                outportb(0x3D5, Temp & ~0x40);
        /* turn off word clocking */
                outportb(0x3D4, 0x17);
                Temp=inportb(0x3D5);
                outportb(0x3D5, Temp | 0x40);

Character attribute bytes

   MSB     b6      b5      b4      b3      b2      b1      LSB
 -------+-------+-------+-------+-------+-------+-------+-------
| blink |  bg4  |  bg2  |  bg1  |  fg8  |  fg4  |  fg2  |  fg1  |
 -------+-------+-------+-------+-------+-------+-------+-------
	blink                   1 for blinking or intense character
	bg4, bg2, bg1           Background color (0 through 7)
	fg8, fg4, fg2, fg1      Foreground color (0 through 15)

	Colors:
	0000     black                  1000    gray
	0001     blue                   1001    bright blue
	0010     green                  1010    bright green
	0011     cyan                   1011    bright cyan
	0100     red                    1100    bright red
	0101     magenta                1101    pink
	0110     orange                 1110    yellow
	0111     white                  1111    bright white

    Either the 256-color or 16-color palette can be reprogrammed
    to sacrifice the fg8 bit, giving only eight foreground
    colors. fg8 can then be programmed to select one of two
    text-mode fonts. This lets you have up to 512 distinct
    characters on the text-mode screen.

====================================================================
VGA BLOCK DIAGRAM
====================================================================
Not yet done :(

master clock
        |
(/1 or /2)      SEQ 01 b3
        |
(/8 or /9)      SEQ 01 b0
        |
        +----------char clock---------------------+
        |                                         |
(/Htot)         CRTC 00 (plus 5)                (/offset)       CRTC 13h
        |                                         |
        +----------hsync                        (/1 or /2)      CRTC 09 b7
        |                                         |
(/1 or /2)      CRTC 17h b2                     (/Fht)          CRTC 09 b0-b4
        |                                         |
(/Vtot)         CRTC 6, CRTC 7 b0 and b5        line clock
        |
        +----------vsync
