/**
 * Write to VGA CRTC Index Register (0x3b4 or 0x3d4)
 *
 * The VGA CRTC Registers control how the video is output to the display.
 *
 * The CRTC registers are accessed in an indexed fashion. By writing a byte
 * to the CRTC Index Register (0x3d4) equal to the index of the particular
 * sub-register you wish to access, one can address the data pointed to by that
 * index by reading and writing the CRTC Data Register (0x3d5).
 *
 * CRTC registers:
 *   - Horizontal Total Register (index 0x00)
 *   - End Horizontal Display Register (index 0x01)
 *   - Start Horizontal Blanking Register (index 0x02)
 *   - End Horizontal Blanking Register (index 0x03)
 *   - Start Horizontal Retrace Register (index 0x04)
 *   - End Horizontal Retrace Register (index 0x05)
 *   - Vertical Total Register (index 0x06)
 *   - Overflow Register (index 0x07)
 *   - Preset Row Scan Register (index 0x08)
 *   - Maximum Scan Line Register (index 0x09)
 *   - Cursor Start Register (index 0x0a)
 *   - Cursor End Register (index 0x0b)
 *   - Start Address High Register (index 0x0c)
 *   - Start Address Low Register (index 0x0d)
 *   - Cursor Location High Register (index 0x0e)
 *   - Cursor Location Low Register (index 0x0f)
 *   - Vertical Retrace Start Register (index 0x10)
 *   - Vertical Retrace End Register (index 0x11)
 *   - Vertical Display End Register (index 0x12)
 *   - Offset Register (index 0x13)
 *   - Underline Location Register (index 0x14)
 *   - Start Vertical Blanking Register (index 0x15)
 *   - End Vertical Blanking (index 0x16)
 *   - CRTC Mode Control Register (index 0x17)
 *   - Line Compare Register (index 0x18)
 *   .
 *
 * \code
 * Horizontal Total register (index 0x00)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Horizontal Total:
 * This field is used to specify the number of character clocks per scan line.
 * This field, along with the dot rate selected, controls the horizontal
 * refresh rate of the VGA by specifying the amount of time one scan line
 * takes.  This field is not programmed with the actual number of character
 * clocks, however. Due to timing factors of the VGA hardware (which, for
 * compatibility purposes has been emulated by VGA compatible chipsets), the
 * actual horizontal total is 5 character clocks more than the value stored in
 * this field, thus one needs to subtract 5 from the actual horizontal total
 * value desired before programming it into this register.
 *
 * End Horizontal Display register (index 0x01)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: End Horizontal Display:
 * This field is used to control the point that the sequencer stops outputting
 * pixel values from display memory, and sequences the pixel value specified by
 * the Overscan Palette Index field for the remainder of the scan line. The
 * overscan begins the character clock after the the value programmed into this
 * field. This register should be programmed with the number of character
 * clocks in the active display - 1. Note that the active display may be
 * affected by the Display Enable Skew field.
 *
 * Start Horizontal Blanking register (index 0x02)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Start Horizontal Blanking:
 * This field is used to specify the character clock at which the horizontal
 * blanking period begins.  During the horizontal blanking period, the VGA
 * hardware forces the DAC into a blanking state, where all of the intensities
 * output are at minimum value, no matter what color information the attribute
 * controller is sending to the DAC.  This field works in conjunction with the
 * End Horizontal Blanking field to specify the horizontal blanking period.
 * Note that the horizontal blanking can be programmed to appear anywhere within
 * the scan line, as well as being programmed to a value greater than the
 * Horizontal Total field preventing the horizontal blanking from occurring at
 * all.
 *
 * End Horizontal Blanking register (index 0x03)
 * +-+---+---------+
 * |7|6 5|4 3 2 1 0|
 * +-+---+---------+
 *  ^  ^      ^
 *  |  |      +-- 0..4: End Horizontal Blanking:
 *  |  |                Contains bits 4-0 of the End Horizontal Blanking field
 *  |  |                which specifies the end of the horizontal blanking
 *  |  |                period.  Bit 5 is located in bit 7 of the End Horizontal
 *  |  |                Retrace register (index 0x05). After the period has
 *  |  |                begun as specified by the Start Horizontal Blanking
 *  |  |                field, the 6-bit value of this field is compared against
 *  |  |                the lower 6 bits of the character clock. When a match
 *  |  |                occurs, the horizontal blanking signal is disabled. This
 *  |  |                provides from 1 to 64 character clocks although some
 *  |  |                implementations may match in the character clock
 *  |  |                specified by the Start Horizontal Blanking field, in which
 *  |  |                case the range is 0 to 63.  Note that if blanking extends
 *  |  |                past the end of the scan line, it will end on the first
 *  |  |                match of this field on the next scan line.
 *  |  +--------- 5..6: Display Enable Skew:
 *  |                   This field affects the timings of the display enable
 *  |                   circuitry in the VGA. The value of this field is the number
 *  |                   of character clocks that the display enable "signal" is
 *  |                   delayed. In all known VGA cards, this field is always
 *  |                   programmed to 0. Programming it to non-zero values results
 *  |                   in the overscan being displayed over the number of
 *  |                   characters programmed into this field at the beginning of
 *  |                   the scan line, as well as the end of the active display
 *  |                   being shifted the number of characters programmed into this
 *  |                   field. The characters that extend past the normal end of the
 *  |                   active display can be garbled in certain circumstances that
 *  |                   is dependent on the particular VGA implementation. According
 *  |                   to documentation from IBM, "This skew control is needed to
 *  |                   provide sufficient time for the CRT controller to read a
 *  |                   character and attribute code from the video buffer, to gain
 *  |                   access to the character generator, and go through the
 *  |                   Horizontal PEL Panning register in the attribute controller.
 *  |                   Each access requires the 'display enable' signal to be
 *  |                   skewed one character clock so that the video output is
 *  |                   synchronized with the horizontal and vertical retrace
 *  |                   signals." as well as "Note: Character skew is not adjustable
 *  |                   on the Type 2 video and the bits are ignored; however,
 *  |                   programs should set these bits for the appropriate skew to
 *  |                   maintain compatibility."  This may be required for some early
 *  |                   IBM VGA implementations or may be simply an unused "feature"
 *  |                   carried over along with its register description from the IBM
 *  |                   EGA implementations that require the use of this field.
 *  +--------------- 7: Enable Vertical Retrace Access:
 *                      This field was used in the IBM EGA to provide access to the
 *                      light pen input values as the light pen registers were mapped
 *                      over CRTC indexes 10h-11h. The VGA lacks capability for light
 *                      pen input, thus this field is normally forced to 1 (although
 *                      always writing it as 1 might be a good idea for compatibility),
 *                      which in the EGA would enable access to the vertical retrace
 *                      fields instead of the light pen fields.
 *
 * Start Horizontal Retrace register (index 0x04)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Start Horizontal Retrace:
 * This field specifies the character clock at which the VGA begins sending the
 * horizontal synchronization pulse to the display which signals the monitor to retrace
 * back to the left side of the screen. The end of this pulse is controlled by the End
 * Horizontal Retrace field. This pulse may appear anywhere in the scan line, as well
 * as set to a position beyond the Horizontal Total field which effectively disables
 * the horizontal synchronization pulse.
 *
 * End Horizontal Retrace register (index 0x05)
 * +-+---+---------+
 * |7|6 5|4 3 2 1 0|
 * +-+---+---------+
 *  ^  ^      ^
 *  |  |      +-- 0..4: End Horizontal Retrace:
 *  |  |                This field specifies the end of the horizontal retrace period,
 *  |  |                which begins at the character clock specified in the Start
 *  |  |                Horizontal Retrace field.  The horizontal retrace signal is
 *  |  |                enabled until the lower 5 bits of the character counter match
 *  |  |                the 5 bits of this field.  This provides for a horizontal
 *  |  |                retrace period from 1 to 32 character clocks.  Note that some
 *  |  |                implementations may match immediately instead of 32 clocks
 *  |  |                away, making the effective range 0 to 31 character clocks.
 *  |  +--------- 5..6: Horizontal Retrace Skew:
 *  |                   This field delays the start of the horizontal retrace period
 *  |                   by the number of character clocks equal to the value of this
 *  |                   field.  From observation, this field is programmed to 0, with
 *  |                   the exception of the 40 column text modes where this field is
 *  |                   set to 1.  The VGA hardware simply acts as if this value is
 *  |                   added to the Start Horizontal Retrace field. According to IBM
 *  |                   documentation, "For certain modes, the 'horizontal retrace'
 *  |                   signal takes up the entire blanking interval. Some internal
 *  |                   timings are generated by the falling edge of the 'horizontal
 *  |                   retrace' signal. To ensure that the signals are latched
 *  |                   properly, the 'retrace' signal is started before the end of
 *  |                   the 'display enable' signal and then skewed several character
 *  |                   clock times to provide the proper screen centering." This does
 *  |                   not appear to be the case, leading me to believe this is yet
 *  |                   another holdout from the IBM EGA implementations that do
 *  |                   require the use of this field.
 *  +--------------- 7: End Horizontal Blanking (bit 5):
 *                      This contains bit 5 of the End Horizontal Blanking field in the
 *                      End Horizontal Blanking register (index 0x03).
 *
 * Vertical Total register (index 0x06)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Vertical Total
 * This contains the lower 8 bits of the Vertical Total field. Bits 9-8 of this field are
 * located in the Overflow Register (index 0x07). This field determines the number of
 * scanlines in the active display and thus the length of each vertical retrace. This
 * field contains the value of the scanline counter at the beginning of the last
 * scanline in the vertical period.
 *
 * Overflow register (index 0x07)
 * +-+-+-+-+-+-+-+-+
 * |7|6|5|4|3|2|1|0|
 * +-+-+-+-+-+-+-+-+
 *  ^ ^ ^ ^ ^ ^ ^ ^
 *  | | +-|-|-|-|-+- 0,5: Bit 8,9 of Vertical Total (index 0x06)
 *  | +---|-|-|-+--- 1,6: Bit 8,9 of Vertical Display End (index 0x12)
 *  +-----|-|-+----- 2,7: Bit 8,9 of Vertical Retrace Start (index 0x10)
 *        | +--------- 3: Bit 8 of Start Vertical Blanking (index 0x15)
 *        +----------- 4: Bit 8 of Line Compare (index 0x18)
 *
 * Preset Row Scan register (index 0x08)
 * +-+---+---------+
 * | |6 5|4 3 2 1 0|
 * +-+---+---------+
 *     ^      ^
 *     |      +-- 0..4: Preset Row Scan:
 *     |                This field is used when using text mode or any mode with a non-zero
 *     |                Maximum Scan Line field (index 0x09) to provide for more precise
 *     |                vertical scrolling than the Start Address Register provides. The
 *     |                value of this field specifies how many scan lines to scroll the
 *     |                display upwards. Valid values range from 0 to the value of the
 *     |                Maximum Scan Line field. Invalid values may cause undesired effects
 *     |                and seem to be dependent upon the particular VGA implementation.
 *     +--------- 5..6: Byte Panning:
 *                      The value of this field is added to the Start Address Register when
 *                      calculating the display memory address for the upper left hand pixel
 *                      or character of the screen. This allows for a maximum shift of 15,
 *                      31, or 35 pixels without having to reprogram the Start Address
 *                      Register.
 *
 * Maximum Scan Line register (index 0x09)
 * +-+-+-+---------+
 * |7|6|5|4 3 2 1 0|
 * +-+-+-+---------+
 *  ^ ^ ^     ^
 *  | | |     +-- 0..4: Maximum Scan Line:
 *  | | |               In text modes, this field is programmed with the character height - 1
 *  | | |               (scan line numbers are zero based.) In graphics modes, a non-zero
 *  | | |               value in this field will cause each scan line to be repeated by the
 *  | | |               value of this field + 1.
 *  | | +----------- 5: Bit 9 of Start Vertical Blanking (index 0x15)
 *  | +------------- 6: Bit 9 of Line Compare (index 0x18)
 *  +--------------- 7: Scan Doubling:
 *                      When this bit is set to 1, 200-scan-line video data is converted to
 *                      400-scan-line output. To do this, the clock in the row scan counter is
 *                      divided by 2, which allows the 200-line modes to be displayed as 400
 *                      lines on the display (this is called double scanning; each line is
 *                      displayed twice). When this bit is set to 0, the clock to the row scan
 *                      counter is equal to the horizontal scan rate.
 *
 * Cursor Start Register (index 0x0a)
 * +---+-+---------+
 * |   |5|4 3 2 1 0|
 * +---+-+---------+
 *      ^     ^
 *      |     +-- 0..4: Cursor Scan Line Start:
 *      |               This field controls the appearance of the text-mode cursor by
 *      |               specifying the scan line location within a character cell at which
 *      |               the cursor should begin, with the top-most scan line in a character
 *      |               cell being 0 and the bottom being with the value of the Maximum Scan
 *      |               Line field.
 *      +------------5: Cursor Disable:
 *                      This field controls whether or not the text-mode cursor is displayed:
 *                        0: Cursor Enabled.
 *                        1: Cursor Disabled.
 *
 * Cursor End Register (index 0x0b)
 * +-+---+---------+
 * | |6 5|4 3 2 1 0|
 * +-+---+---------+
 *     ^      ^
 *     |      +-- 0..4: Cursor Scan Line End:
 *     |                This field controls the appearance of the text-mode cursor by
 *     |                specifying the scan line location within a character cell at which
 *     |                the cursor should end, with the top-most scan line in a character
 *     |                cell being 0 and the bottom being with the value of the Maximum Scan
 *     |                Line field. If this field is less than the Cursor Scan Line Start
 *     |                field, the cursor is not drawn. Some graphics adapters, such as the
 *     |                IBM EGA display a split-block cursor instead.
 *     +------------ 5: Cursor Skew:
 *                      This field was necessary in the EGA to synchronize the cursor with
 *                      internal timing. In the VGA it basically is added to the cursor
 *                      location. In some cases when this value is non-zero and the cursor is
 *                      near the left or right edge of the screen, the cursor will not appear
 *                      at all, or a second cursor above and to the left of the actual one may
 *                      appear. This behavior may not be the same on all VGA compatible adapter
 *                      cards.
 *
 * Start Address High register (index 0x0c)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 8..15 of the Start Address.
 * Bits 0..7 are in the Start Address Low register (index 0x0d). The Start Address field
 * specifies the display memory address of the upper left pixel or character of the screen.
 * Because the standard VGA has a maximum of 256K of memory, and memory is accessed 32 bits at
 * a time, this 16-bit field is sufficient to allow the screen to start at any memory address.
 * Normally this field is programmed to 0h, except when using virtual resolutions, paging,
 * and/or split-screen operation. Note that the VGA display will wrap around in display memory
 * if the starting address is too high. (This may or may not be desirable, depending on your
 * intentions.)
 *
 * Start Address Low register (index 0x0d)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 0..7 of the Start Address. See Start Address High register (index 0x0c)
 *
 * Cursor Location High register (index 0x0e)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 8..15 of the Cursor Location.
 * Bits 0..7 are in the Cursor Location Low register (index 0x0d). When the VGA hardware is
 * displaying text mode and the text-mode cursor is enabled, the hardware compares the address of
 * the character currently being displayed with sum of value of this field and the sum of the
 * Cursor Skew field. If the values equal then the scan lines in that character specified by the
 * Cursor Scan Line Start field and the Cursor Scan Line End field are replaced with the
 * foreground color.
 *
 * Cursor Location Low register (index 0x0f)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 0..7 of the Cursor Location. See Cursor Location High register (index 0x0f)
 *
 * Vertical Retrace Start register (index 0x10)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 0..7 of Vertical Retrace Start
 * Bits 8 and 9 are in the Overflow Register (index 0x07). This field controls the start of the
 * vertical retrace pulse which signals the display to move up to the beginning of the active
 * display. This field contains the value of the vertical scanline counter at the beginning of the
 * first scanline where the vertical retrace signal is asserted.
 *
 * Vertical Retrace End register (index 0x11)
 * +-+-+---+-------+
 * |7|6|5|4|3 2 1 0|
 * +-+-+---+-------+
 *  ^ ^ ^ ^   ^
 *  | | | |   +-- 0..3: Vertical Retrace End:
 *  | | | |             This field determines the end of the vertical retrace pulse, and thus its
 *  | | | |             length. This field contains the lower four bits of the vertical scanline
 *  | | | |             counter at the beginning of the scanline immediately after the last
 *  | | | |             scanline where the vertical retrace signal is asserted.
 *  | | | +--------- 4: End Vertical Interrupt
 *  | | +----------- 5: Enable Vertical Interrupt
 *  | +------------- 6: Memory Refresh Bandwidth:
 *  |                   Nearly all video chipsets include a few registers that control memory, bus,
 *  |                   or other timings not directly related to the output of the video card. Most
 *  |                   VGA/SVGA implementations ignore the value of this field; however, in the
 *  |                   least, IBM VGA adapters do utilize it and thus for compatibility with these
 *  |                   chipsets this field should be programmed. This register is used in the IBM
 *  |                   VGA hardware to control the number of DRAM refresh cycles per scan line.
 *  |                   The three refresh cycles per scanline is appropriate for the IBM VGA
 *  |                   horizontal frequency of approximately 31.5 kHz. For horizontal frequencies
 *  |                   greater than this, this setting will work as the DRAM will be refreshed more
 *  |                   often. However, refreshing not often enough for the DRAM can cause memory
 *  |                   loss. Thus at some point slower than 31.5 kHz the five refresh cycle setting
 *  |                   should be used. At which particular point this should occur, would require
 *  |                   better knowledge of the IBM VGA's schematics than I have available.
 *  |                   According to IBM documentation, "Selecting five refresh cycles allows use of
 *  |                   the VGA chip with 15.75 kHz displays." which isn't really enough to go by
 *  |                   unless the mode you are defining has a 15.75 kHz horizontal frequency.
 *  +--------------- 7: CRTC Registers Protect Enable:
 *                      This field is used to protect the video timing registers from being changed
 *                      by programs written for earlier graphics chipsets that attempt to program
 *                      these registers with values unsuitable for VGA timings. When this field is
 *                      set to 1, the CRTC register indexes 00h-07h ignore write access, with the
 *                      exception of bit 4 of the Overflow Register, which holds bit 8 of the Line
 *                      Compare field.
 *
 * Vertical Display End register (index 0x12)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 0..7 of Vertical Display End
 * Bits 8 and 9 are in the Overflow Register (index 0x07). This field contains the value of the
 * vertical scanline counter at the beggining of the scanline immediately after the last scanline of
 * active display.
 *
 * Offset register (index 0x13)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Offset:
 * This field specifies the address difference between consecutive scan lines or two lines of
 * characters. Beginning with the second scan line, the starting scan line is increased by twice the
 * value of this register multiplied by the current memory address size (byte = 1, word = 2,
 * double-word = 4) each line. For text modes the following equation is used:
 *       Offset = Width / ( MemoryAddressSize * 2 )
 * and in graphics mode, the following equation is used:
 *       Offset = Width / ( PixelsPerAddress * MemoryAddressSize * 2 )
 * where Width is the width in pixels of the screen. This register can be modified to provide for a
 * virtual resolution, in which case Width is the width is the width in pixels of the virtual screen.
 * PixelsPerAddress is the number of pixels stored in one display memory address, and
 * MemoryAddressSize is the current memory addressing size.
 *
 * Underline Location register (index 0x14)
 * +-+-+-+---------+
 * | |6|5|4 3 2 1 0|
 * +-+-+-+---------+
 *    ^ ^     ^
 *    | |     +-- 0..4: Underline Location
 *    | |               These bits specify the horizontal scan line of a character row on which an
 *    | |               underline occurs. The value programmed is the scan line desired minus 1.
 *    | +----------- 5: Divide Memory Address Clock by 4:
 *    |                   1: The memory-address counter is clocked with the character clock divided
 *    |                      by 4, which is used when doubleword addresses are used.
 *    +------------- 6: Double-Word Addressing:
 *                        1: Memory addresses are doubleword addresses. See the description of the
 *                           word/byte mode bit (bit 6) in the CRT Mode Control Register (index 0x17)
 *
 * Start Vertical Blanking register (index 0x15)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 0..7 of Start Vertical Blanking
 * Bit 8 is in the Overflow Register (index 0x07), and bit 9 is in the Maximum Scan Line register
 * (index 0x09). This field determines when the vertical blanking period begins, and contains the
 * value of the vertical scanline counter at the beginning of the first vertical scanline of
 * blanking.
 *
 * End Vertical Blanking register (index 0x16)
 * +-+-------------+
 * | |6 5 4 3 2 1 0|
 * +-+-------------+
 *          ^
 *          +---- 0..6: End Vertical Blanking:
 *                      This field determines when the vertical blanking period ends, and contains the
 *                      value of the vertical scanline counter at the beginning of the vertical
 *                      scanline immediately after the last scanline of blanking.
 *
 * CRTC Mode Control Register (index 0x17)
 * +-+-+-+-+-+-+-+-+
 * |7|6|5| |3|2|1|0|
 * +-+-+-+-+-+-+-+-+
 *  ^ ^ ^   ^ ^ ^ ^
 *  | | |   | | | +- 0: Map Display Address 13:
 *  | | |   | | |       This bit selects the source of bit 13 of the output multiplexer:
 *  | | |   | | |         0: Bit 0 of the row scan counter is the source.
 *  | | |   | | |         1: Bit 13 of the address counter is the source.
 *  | | |   | | |       The CRT controller used on the IBM Color/Graphics Adapter was capable of
 *  | | |   | | |       using 128 horizontal scan-line addresses. For the VGA to obtain 640-by-200
 *  | | |   | | |       graphics resolution, the CRT controller is programmed for 100 horizontal
 *  | | |   | | |       scan lines with two scan-line addresses per character row. Row scan address
 *  | | |   | | |       bit 0 becomes the most-significant address bit to the display buffer.
 *  | | |   | | |       Successive scan lines of the display image are displaced in 8KB of memory.
 *  | | |   | | |       This bit allows compatibility with the graphics modes of earlier adapters.
 *  | | |   | | +--- 1: Map Display Address 14:
 *  | | |   | |         This bit selects the source of bit 14 of the output multiplexer:
 *  | | |   | |           0: Bit 1 of the row scan counter is the source.
 *  | | |   | |           1: Bit 14 of the address counter is the source.
 *  | | |   | +----- 2: Divide Scan Line clock by 2:
 *  | | |   |           This bit selects the clock that controls the vertical timing counter:
 *  | | |   |             0: The horizontal retrace clock.
 *  | | |   |             1: The horizontal retrace clock divided by 2.
 *  | | |   |           Dividing the clock effectively doubles the vertical resolution of the CRT
 *  | | |   |           controller. The vertical counter has a maximum resolution of 1024 scan lines
 *  | | |   |           because the vertical total value is 10-bits wide. If the vertical counter is
 *  | | |   |           clocked with the horizontal retrace divided by 2, the vertical resolution is
 *  | | |   |           doubled to 2048 scan lines."
 *  | | |   +------- 3: Divide Memory Address clock by 2:
 *  | | |               This bit selects the clock that controlls the address counter:
 *  | | |                 0: The character clock.
 *  | | |                 1: The character clock divided by 2.
 *  | | |               This bit is used to create either a byte or word refresh address for the
 *  | | |               display buffer.
 *  | | +----------- 5: Address Wrap Select:
 *  | |                 This bit selects the memory-address bit, bit MA 13 or MA 15, that appears on
 *  | |                 the output pin MA 0, in the word address mode. If the VGA is not in the word
 *  | |                 address mode, bit 0 from the address counter appears on the output pin, MA 0.
 *  | |                   0: Selects MA 13. Used in applications where only 64KB of video memory is
 *  | |                      present.
 *  | |                   1: Selects MA 15. In odd/even mode, this bit should be set to 1 because
 *  | |                      256KB of video memory is installed on the system board.
 *  | |                 This function maintains compatibility with the IBM Color/Graphics Monitor
 *  | |                 Adapter.
 *  | +------------- 6: Word/Byte Mode Select:
 *  |                     0: Selects the word address mode. The word mode shifts the memory-address
 *  |                        counter bits to the left by one bit; the most-significant bit of the
 *  |                        counter appears on the least-significant bit of the memory address
 *  |                        outputs.
 *  |                     1: Selects the byte address mode.
 *  |                   The doubleword bit in the Underline Location register (index 0x14) also
 *  |                   controls the addressing. When the doubleword bit is 0, the word/byte bit
 *  |                   selects the mode. When the doubleword bit is set to 1, the addressing is
 *  |                   shifted by two bits.
 *  +--------------- 7: Sync Enable:
 *                        0: Disables the horizontal and vertical retrace signals and forces them to
 *                           an inactive level.
 *                        1: Enables the horizontal and vertical retrace signals.
 *                      This bit does not reset any other registers or signal outputs.
 *
 * Line Compare register (index 0x18)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 * 0..7: Bits 0..7 of Line Compare
 * Bit 8 is in the Overflow Register (index 0x07), and bit 9 is in the Maximum Scan Line register
 * (index 0x09). The Line Compare field specifies the scan line at which a horizontal division can
 * occur, providing for split-screen operation. If no horizontal division is required, this field
 * should be set to 3FFh. When the scan line counter reaches the value in the Line Compare field, the
 * current scan line address is reset to 0 and the Preset Row Scan is presumed to be 0. If the Pixel
 * Panning Mode field is set to 1 then the Pixel Shift Count and Byte Panning fields are reset to 0
 * for the remainder of the display cycle.
 * \endcode
 **/


 /**
 * Write to VGA CRTC Data Register (0x3b5 or 0x3d5)
 *
 * For a description of CRTC Registers, see CCirrus::write_b_3d4.
 **/

 void CS3Trio64::write_b_3d5(u8 value)
{
#if DEBUG_VGA_NOISY
	printf("VGA: 3d5 WRITE CRTC register=0x%02x BINARY VALUE=" PRINTF_BINARY_PATTERN_INT8 " HEX VALUE=0x%02x\n", vga.crtc.index, PRINTF_BYTE_TO_BINARY_INT8(value), value);
#endif

	// ---- S3 unlock gating (match 86Box) ----
	if (vga.crtc.index >= 0x20 && vga.crtc.index < 0x40 &&
		vga.crtc.index != 0x36 && vga.crtc.index != 0x38 && vga.crtc.index != 0x39 &&
		((s3.reg_lock1 & 0xCC) != 0x48)) {
		return;
	}
	if (vga.crtc.index >= 0x40 && ((s3.reg_lock2 & 0xE0) != 0xA0)) {
		return;
	}
	if (vga.crtc.index == 0x36 && (s3.reg_lock2 != 0xA5)) {
		return;
	}
	if (vga.crtc.index == 0x68 && s3.reg_lock2 != 0xA5) { // per datasheet...
		return;
	}


	if (vga.crtc.index <= 0x18 || vga.crtc.index == 0x24) {
		m_crtc_map.write_byte(vga.crtc.index, value);
		return;
	}

	//if (value != vga.crtc.data[vga.crtc.index])
	switch (vga.crtc.index)
	{
	case 0x2d:
	case 0x2e:
	case 0x2f:
	case 0x30: // read only...
	case 0x31:  // Memory Configuration
	case 0x32: // Backward Compatibility 1 (BKWD_1)
	case 0x33: // Backward Compatibility 2 (BKWD_2)        
	case 0x34: // Backward Compatibility 3 (CR34)
	case 0x35:  // CPU bank + timing locks
	case 0x36: // Configuration 1 Register (CONFG_REG1) (CR36)
	case 0x37: // Configuration 2 Register (CONFG_REG2) (CR37)
	case 0x38: // CR38 Register Lock 1
	case 0x39: // CR39 Register Lock 2
	case 0x3A: // Miscellaneous 1 Register (MISC_1) (CR3A) 
	case 0x3B: // Start Display FIFO Register (DT_EX-POS) (CR3B) - real effect is enabled by CR34 bit4,
	case 0x3C: // Interlace Retrace Start Register (IL_RTSTART) (CR3C)
		m_crtc_map.write_byte(vga.crtc.index, value);
		break;

	case 0x40: // CR40 system config
		m_crtc_map.write_byte(vga.crtc.index, value);
#if S3_ACCEL_TRACE
		printf("S3 CR40 = %02X (GE %s)\n", value, state.accel.enabled ? "ENABLED" : "DISABLED");
#endif
		// When (re)disabled, present bus float on status reads.
		break;

	case 0x41: // BIOS Flag Register (BIOS_FLAG) (CR41)
	case 0x42:  // Mode Control Register (MODE_CTl) (CR42) Return 0x0d for non-interlaced. 
	case 0x43: // Extended Mode Register (EXT_MODE)
	case 0x45: // Hardware Graphics Cursor Mode Register (HGC_MODE) (CR45) 
	case 0x46: // Hardware Graphics Cursor Origin-X Registers (HWGC_ORGX(H)(L)) (CR46, CR47) 
	case 0x47: // Hardware Graphics Cursor Origin-X Registers (HWGC_ORGX(H)(L)) (CR46, CR47) 
	case 0x48: // Hardware Graphics Cursor Origin-Y Registers (HWGC_ORGY(H)(L)) (CR48, CR49) 
	case 0x49: // Hardware Graphics Cursor Origin-Y Registers (HWGC_ORGY(H)(L)) (CR48, CR49) 
	case 0x4A: // Hardware Graphics Cursor Foreground Color Stack Register (HWGC_FGSTK) (CR4A) 
	case 0x4B: // Hardware Graphics Cursor Background Color Stack Register (HWGC_BGSTK) (CR4B) 
	case 0x4C: // Hardware Graphics Cursor Storage Start Address Registers (HWGC_STA(H)(L) (CR4C, CR4D) 
	case 0x4D: // Hardware Graphics Cursor Storage Start Address Registers (HWGC_STA(H)(L) (CR4C, CR4D) 
	case 0x4E: // Hardware Graphics Cursor Pattern Display Start X-PXL-Position Register (HWGC_DX) (CR4E) 
	case 0x4F: // Hardware Graphics Cursor Pattern Disp Start V-PXL-Position Register (HGC_DV) (CR4F) 
	case 0x50: // Extended System Control 1
	case 0x51: // Extended System Control 2
	case 0x52: // Extended BIOS flag 1 register (EXT_BBFLG1) (CR52)
	case 0x53: // Extended Memory Control 1 Register - dosbox calls VGA_SETUPHANDLERS(); inside if register != value
	case 0x54: // Extended Memory Control 2 Register (EX_MCTL_2) (CR54) 
	case 0x55: // Extended RAMDAC Control Register (EX_DAC_CT) (CR55) 
	case 0x56: // External Sync Control 1 Register (EX_SYNC_1) (CR56)
	case 0x57: // External Sync Control 2 Register (EX_SYNC_2) (CR57)
	case 0x58: // Linear Address Window Control Register (LAW_CTL) (CR58) - dosbox calls VGA_StartUpdateLFB() after storing the value
	case 0x59: // Linear Address Window Position High
	case 0x5A: // Linear Address Window Position Low
	case 0x5b: // undocumented on trio64?
	case 0x5c:  // General output port register - we don't use this (CR5C)
	case 0x5d: // Extended Horizontal Overflow
	case 0x5E: // Extended Vertical Overflow Register (EXL_V_OVF) (CR5E)
	case 0x5F: // undocumented on trio64?
	case 0x60: // Extended Memory Control 3 Register (EXT-MCTL-3) (CR60) 
	case 0x61: // Extended Memory Control 4 Register (EXT-MCTL-4) (CR61)
	case 0x62: // undocumented?
	case 0x63: // External Sync Control 3 Register (EX-SYNC-3) (CR63) 
	case 0x64: // undocumented?
	case 0x65: // Extended Miscellaneous Control Register (EXT-MISC-CTL) (CR6S) 
	case 0x66: // Extended Miscellaneous Control 1 Register (EXT-MISC-1) (CR66) - S3 BIOS writes 0 here - normal operation & PCI bus disconnect disabled
	case 0x67: // Extended Miscellaneous Control 2 Register (EXT-MISC-2) (CR67) - Dosbox-X wants VGA_DetermineMode() here
	case 0x68: // Configuration 3 Register (CNFG-REG-3) (CR68)
	case 0x69: // Extended System Control 3 Register (EXT-SCTL-3)(CR69) - overrides CR31/CR51 when non-zero
	case 0x6A: // Extended System Control 4 Register (EXT-SCTL-4)(CR6A) per TRIO64V+ documentation - bank select shortcut
	case 0x6b: // Extended BIOS Flag 3 Register (EBIOS-FLG3) (CR6B) - Bios scratchpad
	case 0x6c: // Extended BIOS Flag 4 Register (EBIOS-FLG3) (CR6C) - Bios scratchpad
	case 0x6d: // undocumented
		m_crtc_map.write_byte(vga.crtc.index, value);
		break;

	default:
		printf("VGA 3d5 write: unimplemented CRTC register 0x%02x\n", (unsigned)vga.crtc.index);
		m_crtc_map.write_byte(vga.crtc.index, value);

	}
}

/**
 * Write to the VGA sequencer index register (0x3c4)
 *
 * The Sequencer registers control how video data is sent to the DAC.
 *
 * The Sequencer registers are accessed in an indexed fashion. By writing a byte
 * to the Sequencer Index Register (0x3c4) equal to the index of the particular
 * sub-register you wish to access, one can address the data pointed to by that
 * index by reading and writing the Sequencer Data Register (0x3c5).
 *
 * Sequencer registers:
 *   - Reset register (index 0x00)
 *   - Clocking Mode register (index 0x01)
 *   - Map Mask register (index 0x02)
 *   - Character Map Select register (index 0x03)
 *   - Memory Mode register (index 0x04)
 *   .
 *
 * \code
 * Reset register (index 0x00)
 * +-----------+-+-+
 * |           |1|0|
 * +-----------+-+-+
 *              ^ ^
 *              | +- 0: Asynchronous Reset:
 *              |         0: Commands the sequencer to asynchronously clear and
 *              |            halt. Resetting the sequencer with this bit can
 *              |            cause loss of video data.
 *              |         1: Allows the sequencer to function normally.
 *              +--- 1: Sychnronous Reset:
 *                        0: Commands the sequencer to synchronously clear and
 *                           halt.
 *                        1: Allows the sequencer to function normally.
 * Bits 1 and 0 must be 1 to allow the sequencer to operate.
 * To prevent the loss of data, bit 1 must be set to 0 during the active display
 * interval before changing the clock selection. The clock is changed through the
 * Clocking Mode register or the Miscellaneous Output register.
 *
 * Clocking Mode register (index 0x01)
 * +---+-+-+-+-+-+-+
 * |   |5|4|3|2| |0|
 * +---+-+-+-+-+-+-+
 *      ^ ^ ^ ^   ^
 *      | | | |   +- 0: 9/8 Dot Mode: Selects whether a character is 8 or 9 dots
 *      | | | |         wide. This can be used to select between 720 and 640
 *      | | | |         pixel modes (or 360 and 320) and also is used to provide
 *      | | | |         9 bit wide character fonts in text mode:
 *      | | | |           0: Selects 9 dots per character.
 *      | | | |           1: Selects 8 dots per character.
 *      | | | +----- 2: Shift/Load Rate:
 *      | | |             0: Video serializers are loaded every character clock.
 *      | | |             1: Video serializers are loaded every other character
 *      | | |                clock, which is useful when 16 bits are fetched per
 *      | | |                cycle and chained together in the shift registers.
 *      | | +------- 3: Dot Clock Rate:
 *      | |               0: Selects the normal dot clocks derived from the
 *      | |                  sequencer master clock input.
 *      | |               1: The master clock will be divided by 2 to generate
 *      | |                  the dot clock. All other timings are affected
 *      | |                  because they are derived from the dot clock. The dot
 *      | |                  clock divided by 2 is used for 320 and 360 horizontal
 *      | |                  PEL modes.
 *      | +--------- 4: Shift Four Enable:
 *      |                 0: Video serializers are loaded every character clock.
 *      |                 1: Video serializers are loaded every fourth character
 *      |                    clock, which is useful when 32 bits are fetched per
 *      |                    cycle and chained together in the shift registers.
 *      +----------- 5: Screen Disable:
 *                        0: Display enabled.
 *                        1: Display blanked. Maximum memory bandwidth assigned to
 *                           the system.
 *
 * Map Mask register (index 0x02)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Memory Plane Write Enable: If a bit is set, then write
 *                      operations will modify the respective plane of display
 *                      memory. If a bit is not set then write operations will not
 *                      affect the respective plane of display memory.
 *
 * Character Map Select register (index 0x03)
 * +---+-+-+---+---+
 * |   |5|4|3 2|1 0|
 * +---+-+-+---+---+
 *      ^ ^  ^   ^
 *      | +--|---+- 0..1,4: Character Set B Select: This field is used to select the
 *      |    |              font that is used in text mode when bit 3 of the attribute
 *      |    |              byte for a character is set to 0. (*)
 *      +----+----- 2..3,5: Character Set A Select: This field is used to select the
 *                          font that is used in text mode when bit 3 of the attribute
 *                          byte for a character is set to 1. (*)
 *
 * (*) Note that this field is not contiguous in order to provide EGA compatibility.
 *     The font selected resides in plane 2 of display memory at the address specified
 *     by this field, as follows:
 * +------+---------------+
 * |  val | font at       |
 * +------+---------------+
 * | 000b | 0000h - 1FFFh |
 * | 001b | 4000h - 5FFFh |
 * | 010b | 8000h - 9FFFh |
 * | 011b | C000h - DFFFh |
 * | 100b | 2000h - 3FFFh |
 * | 101b | 6000h - 7FFFh |
 * | 110b | A000h - BFFFh |
 * | 111b | E000h - FFFFh |
 * +------+---------------+
 *
 * Memory Mode register (index 0x04)
 * +-------+-+-+-+-+
 * |       |3|2|1| |
 * +-------+-+-+-+-+
 *          ^ ^ ^
 *          | | +--- 1: Extended Memory:
 *          | |           0: 64 KB of video memory enabled
 *          | |           1: 256 KB of video memory enabled. This bit must be set to 1 to
 *          | |              enable the character map selection described for the
 *          | |              previous register.
 *          | +----- 2: Odd/Even Host Memory Write Adressing Disable:
 *          |             0: Even system addresses access maps 0 and 2, while odd system
 *          |                addresses access maps 1 and 3.
 *          |             1: System addresses sequentially access data within a bit map,
 *          |                and the maps are accessed according to the value in the Map
 *          |                Mask register (index 0x02).
 *          +------- 3: Chain 4 Enable: This bit controls the map selected during system
 *                      read operations.
 *                        0: Enables system addresses to sequentially access data within
 *                           a bit map by using the Map Mask register.
 *                        1: Causes the two low-order bits to select the map accessed as
 *                           shown below:
 *                           +----+----+--------------+
 *                           | A0 | A1 | Map Selected |
 *                           +----+----+--------------+
 *                           |  0 |  0 | 0            |
 *                           |  0 |  1 | 1            |
 *                           |  1 |  0 | 2            |
 *                           |  1 |  1 | 3            |
 *                           +----+----+--------------+
 * \endcode
 **/

 /**
 * Write to VGA Graphics Controller Index Register (0x3ce)
 *
 * The Graphics Controller registers control how the system accesses video RAM.
 *
 * The Graphics registers are accessed in an indexed fashion. By writing a byte
 * to the Graphics Index Register (0x3ce) equal to the index of the particular
 * sub-register you wish to access, one can address the data pointed to by that
 * index by reading and writing the Graphics Data Register (0x3cf).
 *
 * Graphics registers:
 *   - Set/Reset register (index 0x00)
 *   - Enable Set/Reset register (index 0x01)
 *   - Color Compare register (index 0x02)
 *   - Data Rotate register (index 0x03)
 *   - Read Map Select register (index 0x04)
 *   - Graphics Mode register (index 0x05)
 *   - Miscellaneous Graphics register (index 0x06)
 *   - Color Don't Care register (index 0x07)
 *   - Bit Mask register (index 0x08)
 *   .
 *
 * \code
 * Set/Reset register (index 0x00)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Set/Reset: Bits 3-0 of this field represent planes 3-0 of
 *                      the VGA display memory. This field is used by Write Mode
 *                      0 and Write Mode 3 (See the Write Mode field.) In Write
 *                      Mode 0, if the corresponding bit in the Enable Set/Reset
 *                      field is set, and in Write Mode 3 regardless of the Enable
 *                      Set/Reset field, the value of the bit in this field is
 *                      expanded to 8 bits and substituted for the data of the
 *                      respective plane and passed to the next stage in the
 *                      graphics pipeline, which for Write Mode 0 is the Logical
 *                      Operation unit and for Write Mode 3 is the Bit Mask unit.
 *
 * Enable Set/Reset Register (index 0x01)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Enable Set/Reset: Bits 3-0 of this field represent planes
 *                      3-0 of the VGA display memory. This field is used in Write
 *                      Mode 0 (See the Write Mode field) to select whether data
 *                      for each plane is derived from host data or from expansion
 *                      of the respective bit in the Set/Reset field.
 *
 * Color Compare Register (index 0x02)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Color Compare: Bits 3-0 of this field represent planes 3-0
 *                      of the VGA display memory. This field holds a reference
 *                      color that is used by Read Mode 1 (See the Read Mode field.)
 *                      Read Mode 1 returns the result of the comparison between
 *                      this value and a location of display memory, modified by
 *                      the Color Don't Care field.
 *
 * Data Rotate Register (index 0x03)
 * +-----+---+-----+
 * |     |4 3|2 1 0|
 * +-----+---+-----+
 *         ^    ^
 *         |    +- 0..2: Rotate Count:
 *         |             This field is used in Write Mode 0 and Write Mode 3 (See
 *         |             the Write Mode field.) In these modes, the host data is
 *         |             rotated to the right by the value specified by the value of
 *         |             this field. A rotation operation consists of moving bits
 *         |             7-1 right one position to bits 6-0, simultaneously
 *         |             wrapping bit 0 around to bit 7, and is repeated the number
 *         |             of times specified by this field.
 *         +------ 3..4: Logical Operation:
 *                       This field is used in Write Mode 0 and Write Mode 2 (See
 *                       the Write Mode field.) The logical operation stage of the
 *                       graphics pipeline is 32 bits wide (1 byte * 4 planes) and
 *                       performs the operations on its inputs from the previous
 *                       stage in the graphics pipeline and the latch register. The
 *                       latch register remains unchanged and the result is passed
 *                       on to the next stage in the pipeline. The results based on
 *                       the value of this field are:
 *                         00: Result is input from previous stage unmodified.
 *                         01: Result is input from previous stage logical ANDed
 *                             with latch register.
 *                         10: Result is input from previous stage logical ORed with
 *                             latch register.
 *                         11: Result is input from previous stage logical XORed
 *                             with latch register.
 *
 * Read Map Select register (index 0x04)
 * +-----------+---+
 * |           |1 0|
 * +-----------+---+
 *               ^
 *               +- 0..1: Read Map Select: The value of this field is used in Read
 *                        Mode 0 (see the Read Mode field) to specify the display
 *                        memory plane to transfer data from. Due to the arrangement
 *                        of video memory, this field must be modified four times to
 *                        read one or more pixels values in the planar video modes.
 *
 * Graphics Mode Register (index 0x05)
 * +-+-+-+-+-+-+---+
 * | |6|5|4|3| |1 0|
 * +-+-+-+-+-+-+---+
 *    ^ ^ ^ ^    ^
 *    | | | |    +- 0..1: Write Mode
 *    | | | |             This field selects between four write modes, simply known
 *    | | | |             as Write Modes 0-3, based upon the value of this field:
 *    | | | |               00: Write Mode 0: In this mode, the host data is first
 *    | | | |                   rotated as per the Rotate Count field, then the
 *    | | | |                   Enable Set/Reset mechanism selects data from this or
 *    | | | |                   the Set/Reset field. Then the selected Logical
 *    | | | |                   Operation is performed on the resulting data and the
 *    | | | |                   data in the latch register. Then the Bit Mask field
 *    | | | |                   is used to select which bits come from the resulting
 *    | | | |                   data and which come from the latch register. Finally,
 *    | | | |                   only the bit planes enabled by the Memory Plane Write
 *    | | | |                   Enable field are written to memory.
 *    | | | |               01: Write Mode 1: In this mode, data is transferred directly
 *    | | | |                   from the 32 bit latch register to display memory,
 *    | | | |                   affected only by the Memory Plane Write Enable field.
 *    | | | |                   The host data is not used in this mode.
 *    | | | |               10: Write Mode 2: In this mode, the bits 3-0 of the host
 *    | | | |                   data are replicated across all 8 bits of their
 *    | | | |                   respective planes. Then the selected Logical Operation
 *    | | | |                   is performed on the resulting data and the data in the
 *    | | | |                   latch register. Then the Bit Mask field is used to
 *    | | | |                   select which bits come from the resulting data and which
 *    | | | |                   come from the latch register. Finally, only the bit
 *    | | | |                   planes enabled by the Memory Plane Write Enable field
 *    | | | |                   are written to memory.
 *    | | | |               11: Write Mode 3: In this mode, the data in the Set/Reset
 *    | | | |                   field is used as if the Enable Set/Reset field were set
 *    | | | |                   to 1111b. Then the host data is first rotated as per the
 *    | | | |                   Rotate Count field, then logical ANDed with the value of
 *    | | | |                   the Bit Mask field. The resulting value is used on the
 *    | | | |                   data obtained from the Set/Reset field in the same way
 *    | | | |                   that the Bit Mask field would ordinarily be used. to
 *    | | | |                   select which bits come from the expansion of the
 *    | | | |                   Set/Reset field and which come from the latch register.
 *    | | | |                   Finally, only the bit planes enabled by the Memory Plane
 *    | | | |                   Write Enable field are written to memory.
 *    | | | +--------- 3: Read Mode:
 *    | | |               This field selects between two read modes, simply known as Read
 *    | | |               Mode 0, and Read Mode 1, based upon the value of this field:
 *    | | |                 0: Read Mode 0: In this mode, a byte from one of the four
 *    | | |                    planes is returned on read operations. The plane from
 *    | | |                    which the data is returned is determined by the value of
 *    | | |                    the Read Map Select field.
 *    | | |                 1: Read Mode 1: In this mode, a comparison is made between
 *    | | |                    display memory and a reference color defined by the Color
 *    | | |                    Compare field. Bit planes not set in the Color Don't Care
 *    | | |                    field then the corresponding color plane is not considered
 *    | | |                    in the comparison. Each bit in the returned result
 *    | | |                    represents one comparison between the reference color, with
 *    | | |                    the bit being set if the comparison is true.
 *    | | +----------- 4: Host Odd/Even Memory Read Addressing Enable:
 *    | |                   0: Selects the standard addressing mode.
 *    | |                   1: Selects the odd/even addressing mode used by the IBM CGA
 *    | |                      Adapter.
 *    | |                 Normally, the value here follows the value of Memory Mode
 *    | |                 register bit 2 in the sequencer."
 *    | +------------- 5: Shift Register Interleave Mode:
 *    |                     1: Directs the shift registers in the graphics controller to
 *    |                        format the serial data stream with even-numbered bits from
 *    |                        both maps on even-numbered maps, and odd-numbered bits from
 *    |                        both maps on the odd-numbered maps. This bit is used for
 *    |                        modes 4 and 5.
 *    +--------------- 6: 256-Color Shift Mode:
 *                          0: Allows bit 5 to control the loading of the shift registers.
 *                          1: Causes the shift registers to be loaded in a manner that
 *                             supports the 256-color mode.
 *
 * Miscellaneous Graphics register (index 0x06)
 * +-------+---+-+-+
 * |       |3 2|1|0|
 * +-------+---+-+-+
 *           ^  ^ ^
 *           |  | +- 0: Alphanumeric Mode Disable:
 *           |  |       This bit controls alphanumeric mode addressing.
 *           |  |         0: Text mode.
 *           |  |         1: Graphics modes, disables character generator latches.
 *           |  +--- 1: Chain Odd/Even Enable
 *           |            1: Directs the system address bit, A0, to be replaced by a
 *           |               higher-order bit. The odd map is then selected when A0 is 1,
 *           |               and the even map when A0 is 0.
 *           +--- 2..3: Memory Map Select
 *                      This field specifies the range of host memory addresses that is
 *                      decoded by the VGA hardware and mapped into display memory
 *                      accesses. The values of this field and their corresponding host
 *                      memory ranges are:
 *                        00: A0000h-BFFFFh (128K region)
 *                        01: A0000h-AFFFFh (64K region)
 *                        10: B0000h-B7FFFh (32K region)
 *                        11: B8000h-BFFFFh (32K region)
 *
 * Color Don't Care register (index 0x07)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Color Don't Care: Bits 3-0 of this field represent planes
 *                      3-0 of the VGA display memory. This field selects the
 *                      planes that are used in the comparisons made by Read Mode
 *                      1 (See the Read Mode field.) Read Mode 1 returns the
 *                      result of the comparison between the value of the Color
 *                      Compare field and a location of display memory. If a bit
 *                      in this field is set, then the corresponding display
 *                      plane is considered in the comparison. If it is not set,
 *                      then that plane is ignored for the results of the
 *                      comparison.
 *
 * Bit Mask register (index 0x08)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 *         +----- 0..7: Bit Mask: This field is used in Write Modes 0, 2, and 3
 *                      (See the Write Mode field.) It it is applied to one byte
 *                      of data in all four display planes. If a bit is set,
 *                      then the value of corresponding bit from the previous
 *                      stage in the graphics pipeline is selected; otherwise
 *                      the value of the corresponding bit in the latch register
 *                      is used instead. In Write Mode 3, the incoming data byte,
 *                      after being rotated is logical ANDed with this byte and
 *                      the resulting value is used in the same way this field
 *                      would normally be used by itself.
 * \endcode
 **/

 
/**
 * Write to the attribute controller I/O port (0x3c0)
 *
 * The attribute controller registers are used to select the 16 color
 * and 64 color palettes used for EGA/CGA compatibility.
 *
 * The attribute registers are accessed in an indexed fashion.
 * The address register is read and written via port 3C0h.
 * The data register is written to port 3C0h and read from port 3C1h.
 * The index and the data are written to the same port, one after
 * another. A flip-flop inside the card keeps track of whether the
 * next write will be handled is an index or data. Because there is
 * no standard method of determining the state of this flip-flop, the
 * ability to reset the flip-flop such that the next write will be
 * handled as an index is provided. This is accomplished by reading
 * the Input Status #1 Register (normally port 3DAh) (the data
 * received is not important.)
 *
 * Attribute registers:
 *   - Palette Index registers (index 0x00 - 0x0f)
 *   - Attribute Mode Control register (index 0x10)
 *   - Overscan Color register (index 0x11)
 *   - Color Plane Enable register (index 0x12)
 *   - Horizontal Pixel Panning register (index 0x13)
 *   - Color Select register (index 0x14)
 *   .
 *
 * \code
 * Attribute Address Register(3C0h)
 * +---+-+---------+
 * |   |5|4 3 2 1 0|
 * +---+-+---------+
 *      ^     ^
 *      |     +-- 0..4: Attribute Address: This field specifies the index
 *      |               value of the attribute register to be read or written
 *      +----------- 5: Palette Address Source: This bit is set to 0 to load
 *                      color values to the registers in the internal palette.
 *                      It is set to 1 for normal operation of the attribute
 *                      controller.
 *
 * Palette Index Registers (index 0x00 - 0x0f)
 * +---+-----------+
 * |   |5 4 3 2 1 0|
 * +---+-----------+
 *           ^
 *           +--- 0..5: Internal Palette Index: These 6-bit registers allow a
 *                      dynamic mapping between the text attribute or graphic
 *                      color input value and the display color on the CRT
 *                      screen. These internal palette values are sent off-chip
 *                      to the video DAC, where they serve as addresses into
 *                      the DAC registers.
 *
 * Attribute Mode Control Register (index 0x10)
 * +-+-+-+-+-+-+-+-+
 * |7|6|5| |3|2|1|0|
 * +-+-+-+-+-+-+-+-+
 *  ^ ^ ^   ^ ^ ^ ^
 *  | | |   | | | +- 0: ATGE - Attribute Controller Graphics Enable:
 *  | | |   | | |         0: Disables the graphics mode of operation.
 *  | | |   | | |         1: Selects the graphics mode of operation.
 *  | | |   | | +--- 1: MONO - Monochrome Emulation: This bit is present and
 *  | | |   | |         programmable in all of the hardware but it apparently
 *  | | |   | |         does nothing.
 *  | | |   | +----- 2: LGE - Line Graphics Enable: This field is used in 9
 *  | | |   |           bit wide character modes to provide continuity for the
 *  | | |   |           horizontal line characters in the range C0h-DFh:
 *  | | |   |             0: the 9th column is replicated from the 8th column.
 *  | | |   |             1: the 9th column is set to the background.
 *  | | |   +------- 3: BLINK - Blink Enable:
 *  | | |                 0: Bit 7 of the attribute selects the background
 *  | | |                    intensity (allows 16 colors for background).
 *  | | |                 1: Bit 7 of the attribute enables blinking.
 *  | | +----------- 5: PPM -- Pixel Panning Mode: Allows the upper half of
 *  | |                 the screen to pan independently of the lower screen.
 *  | |                   0: nothing special occurs during a successful line
 *  | |                      compare (see the Line Compare field.)
 *  | |                   1: upon a successful line compare, the bottom portion
 *  | |                      of the screen is displayed as if the Pixel Shift
 *  | |                      Count and Byte Panning fields are set to 0.
 *  | +------------- 6: 8BIT -- 8-bit Color Enable:
 *  |                     1: The video data is sampled so that eight bits are
 *  |                        available to select a color in the 256-color mode.
 *  |                     0: All other modes.
 *  +--------------- 7: P54S -- Palette Bits 5-4 Select: Selects the source for
 *                      the P5 and P4 video bits that act as inputs to the video
 *                      DAC.
 *                        0: P5 and P4 are the outputs of the Internal Palette
 *                           registers.
 *                        1: P5 and P4 are bits 1 and 0 of the Color Select
 *                           register.
 *
 * Overscan Color Register (index 0x11)
 * +---------------+
 * |7 6 5 4 3 2 1 0|
 * +---------------+
 *         ^
 *         +----- 0..7: Overscan Palette Index: Selects a color from one of the
 *                      DAC registers for the border.
 *
 * Color Plane Enable Register (index 0x12)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Color Plane Enable: Setting a bit to 1 enables the
 *                      corresponding display-memory color plane.
 *
 * Horizontal Pixel Panning Register (index 0x13)
 * +-------+-------+
 * |       |3 2 1 0|
 * +-------+-------+
 *             ^
 *             +- 0..3: Pixel Shift Count: These bits select the number of pels
 *                      that the video data is shifted to the left.
 *
 * Color Select Register (index 0x14)
 * +-------+---+---+
 * |       |3 2|1 0|
 * +-------+---+---+
 *           ^   ^
 *           |   +- 0..1: Color Select 5-4: These bits can be used in place of
 *           |            the P4 and P5 bits from the Internal Palette registers
 *           |            to form the  8-bit digital color value to the video DAC.
 *           |            Selecting these bits is done in the Attribute Mode
 *           |            Control register (index 0x10).
 *           +----- 2..3: Color Select 7-6: In modes other than mode 0x13
 *                        (256-color VGA), these are the two most-significant bits
 *                        of the 8-bit digital color value to the video DAC.
 * \endcode
 **/

 /**
 * Write to VGA DAC Pixel Mask register (0x3c6)
 *
 * The pixel inputs (R, G and B) are anded with this value. Set to FFh
 * for normal operation.
 **/

 /**
 * Write VGA DAC Address Read Mode register (0x3c7)
 *
 * The Color Registers in the standard VGA provide a mapping between the
 * palette of between 2 and 256 colors to a larger 18-bit color space.
 * This capability allows for efficient use of video memory while
 * providing greater flexibility in color choice. The standard VGA has
 * 256 palette entries containing six bits each of red, green, and blue
 * values. The palette RAM is accessed via a pair of address registers
 * and a data register.
 *
 * To write a palette entry, output the palette entry's index value to
 * the DAC Address Write Mode Register (0x3c8) then perform 3 writes to
 * the DAC Data Register (0x3c9), loading the red, green, then blue
 * values into the palette RAM. The internal write address automatically
 * advances allowing the next value's RGB values to be loaded without
 * having to reprogram the DAC Address Write Mode Register. This allows
 * the entire palette to be loaded in one write operation.
 *
 * To read a palette entry, output the palette entry's index to the DAC
 * Address Read Mode Register (0x3c7). Then perform 3 reads from the DAC
 * Data Register (0x3c9), loading the red, green, then blue values from
 * palette RAM. The internal read address automatically advances
 * allowing the next RGB values to be read without having to reprogram
 * the DAC Address Read Mode Register.
 *
 * The data values are 6-bits each.
 **/

 /**
 * Write VGA DAC Address Write Mode register (0x3c8)
 *
 * For a description of DAC registers see CCirrus::write_b_3c7
 **/

 /**
 * Write VGA DAC Data register (0x3c9)
 *
 * For a description of DAC registers see CCirrus::write_b_3c7
 **/

 /**
 * Read the VGA Miscellaneous Output Register (0x3cc)
 *
 * For a description of the Miscellaneous Output register, see CCirrus::write_b_3c2
 **/

 /**
 * Read from the VGA Input Status 1 register (0x3ba or 0x3da)
 *
 * \code
 * +-------+-+---+-+
 * |       |3|   |0|
 * +-------+-+---+-+
 *          ^     ^
 *          |     +- 0: Display Disabled:
 *          |             1: Indicates a horizontal or vertical retrace interval. This
 *          |                bit is the real-time status of the inverted 'display
 *          |                enable' signal. Programs have used this status bit to
 *          |                restrict screen updates to the inactive display intervals
 *          |                in order to reduce screen flicker. The video subsystem is
 *          |                designed to eliminate this software requirement; screen
 *          |                updates may be made at any time without screen degradation.
 *          +------- 1: Vertical Retrace:
 *                        1: Indicates that the display is in a vertical retrace interval.
 *                           This bit can be programmed, through the Vertical Retrace End
 *                           register, to generate an interrupt at the start of the
 *                           vertical retrace.
 * \endcode
 **/
 // above comment applies to the read, not this write function

 /**
 * Read from the VGA Feature Control register (index 0x3ca)
 *
 * \code
 * +-----------+-+-+
 * |           |1|0|
 * +-----------+-+-+
 *              ^ ^
 *              | +- 0: Feature Control 0 (reserved)
 *              +--- 1: Feature Control 1 (reserved)
 * \endcode
 **/

 /**
 * Write the VGA Enable register (0x3c3)
 *
 * (Not sure where this comes from; doesn't seem to be in the VGA specs.)
 **/
void CS3Trio64::write_b_3c3(u8 value)
{
#if DEBUG_VGA_NOISY
	printf("VGA: 3c3 WRITE VGA ENABLE 0x%02x\n", value);
#endif
	vga_enabled() = value;
}
