EGA Registers
Most register references you will find online are for the VGA exclusively, or else intermingle EGA and VGA to the point where it can be confusing if you are looking for a EGA specific reference.
Every bit listed in this section is specific to the original IBM EGA, unless where noted.
NOTE: The original IBM EGA and several clones have jumpers that can invert address line A09 during port decoding. This causes all the
3XXrange registers to be decoded at2XX. This is a fairly obscure feature and I am not aware of anything that uses it - even video BIOS routines will typically fail to control the card with this jumper set.
The EGA can switch between a port base of 3DX and 3BX for the CRTC and Input Status Register 1 registers - this is primarily for MDA compatibility. The EGA may configure itself this way on boot depending on the status of the EGA DIP Switches.
Indexed Registers
Register indexing is a common way to reduce the complexity of address decoding and conserve the IO address space. In its most common form, it consists of a pair of registers - an address port and a data port. First, a byte address or register index is written to the address port. This selects the desired register, assuming it represents a valid index. Then, with the desired register selected, the new value for the register is written to the data port. The address port and data port are typically consecutive IO addresses, with the address port at an even address. There is a good reason for this.
A consequence of the 8088’s transparent 8-bit bus is that an indexed register can be selected and written to via a single word-sized OUT. The data byte is typically packed into AH, with the address in AL. The 8088’s BIU will convert the word write into two 8-bit writes at the base IO address and then the base address + 1. On the AT and subsequent 16-bit architectures, this conversion had to be specifically emulated by hardware on the motherboard.
Indexed registers can also be implemented via an internal flip-flop, where only a single IO port is required. The first write will set the register index, the second write will set the corresponding register data. Under this scheme there must be a way to reset the flip-flop to a known state. This technique is used for the EGA’s single Attribute Controller IO port, which can be reset by reading Input Status Register 1 at either 3DAh or 3BAh, depending on the EGA’s current base address.
Register File Overview
| I/O Address | Read Function | Write Function |
|---|---|---|
| 3B4 / 3D4 | Not Readable | CRTC Address Register |
| 3B5 / 3D5 | Not Readable | CRTC Data Register |
| 3BA / 3DA | Input Status Register 1 | Feature Control Register |
| 3C0 | Not Readable | Attribute Controller |
| 3C2 | Input Status Register 0 | Miscellaneous Output Register |
| 3C4 | Not Readable | Sequencer Address Register |
| 3C5 | Not Readable | Sequencer Data Register |
| 3CE | Not Readable | Graphics Controller Address Register |
| 3CF | Not Readable | Graphics Controller Data Register |
Register Set Details Index
CRTC Registers
The EGA uses a custom LSI CRTC chip. It is very similar in operation to the Motorola 6845, but defines most vertical counters in units of scanlines. Using scanlines as the vertical unit is more convenient for a graphics-mode oriented video adapter. It also has the big advantage of not requiring any memory-addressing tricks that lead to inconvenient video memory layouts on the CGA and Hercules cards.
Most of the EGA CRTC registers are write-only, with the exception of the three register pairs that hold memory addresses - the Start Address, Cursor Location, and Light Pen address registers can be read out. The inability to read the EGA CRTC registers was an annoyance for graphics and games programmers everywhere. This was rectified on the VGA which made most of the register file readable, but much software written for 4bpp modes did not rely on this to maintain backwards compatibility.
| Index | Register Name | Access | Description |
|---|---|---|---|
| 00h | Horizontal Total | W | Total character clocks in a scanline, minus 2 |
| 01h | Horizontal Display End | W | Number of characters visible per line |
| 02h | Start Horizontal Blank | W | Character position where horizontal blanking begins |
| 03h | End Horizontal Blank | W | Character position where horizontal blanking ends |
| 04h | Start Horizontal Retrace | W | Character position where horizontal retrace begins |
| 05h | End Horizontal Retrace | W | Character position where horizontal retrace ends |
| 06h | Vertical Total | W | Total number of scanlines per frame |
| 07h | Overflow | W | High bits for V-Total, V-Display, V-Sync |
| 08h | Preset Row Scan | W | Starting scanline within a character cell |
| 09h | Max Scan Line | W | Height of character cell minus 1 |
| 0Ah | Cursor Start | W | Top scanline of cursor |
| 0Bh | Cursor End | W | Bottom scanline of cursor |
| 0Ch | Start Address High | RW | High byte of display memory start pointer |
| 0Dh | Start Address Low | RW | Low byte of display memory start pointer |
| 0Eh | Cursor Location High | RW | High byte of cursor memory address |
| 0Fh | Cursor Location Low | RW | Low byte of cursor memory address |
| 10h | Vertical Retrace Start | W | Scanline where Vertical Retrace begins |
| 10h | Light Pen Address High | R | High byte of Light Pen latched memory address |
| 11h | Vertical Retrace End | W | Scanline where Vertical Retrace ends (Bits 0-3) |
| 11h | Light Pen Address Low | R | Low byte of Light Pen latched memory address |
| 12h | Vertical Display End | W | Last visible scanline (low 8 bits) |
| 13h | Offset | W | Span width of logical scanline |
| 14h | Underline Location | W | Scanline within cell for underline |
| 15h | Start Vertical Blank | W | Scanline where blanking starts |
| 16h | End Vertical Blank | W | Scanline where blanking ends |
| 17h | Mode Control | W | Hardware compatibility/timing toggles |
| 18h | Line Compare | W | Scanline on which CRTC start address is reset |
Graphics Controller Registers
| Port | Register Name | Access |
|---|---|---|
| 3CC | Graphics 1 Position | W |
| 3CA | Graphics 2 Position | W |
| 3CE | Graphics Address | W |
| 3CF | Graphics Data | W |
On the original IBM EGA, there are two separate Graphics Controller chips. They can generally be treated as a single entity except for the two Graphics Position registers. These two registers are used to tell each of the graphics controllers which pair of graphics planes they will be managing.
The Graphics Controller chips lack an IOW pin, thus all their registers are write-only.
Graphics Controller Indexed Registers
| Index | Register Name |
|---|---|
| 00h | Set/Reset |
| 01h | Enable Set/Reset |
| 02h | Color Compare |
| 03h | Data Rotate |
| 04h | Read Map Select |
| 05h | Mode Register |
| 06h | Miscellaneous |
| 07h | Color Don’t Care |
| 08h | Bit Mask |
Sequencer Registers
| Port | Register Name | Access |
|---|---|---|
| 3C4 | Sequencer Address | W |
| 3C5 | Sequencer Data | W |
Sequencer Indexed Registers
| Index | Register Name |
|---|---|
| 00h | Reset |
| 01h | Clocking Mode |
| 02h | Map Mask |
| 03h | Character Map Select |
| 04h | Memory Mode |
Attribute Controller Registers
| Port | Register Name | Access |
|---|---|---|
| 3BA / 3CA | Reset Attribute Flip-Flop | R |
| 3C0 | Address / Data (Flip-flops on each write) | W |
Attribute Controller Indexed Registers
| Index | Register Name | Access |
|---|---|---|
| 00h-0Fh | Attribute Palette Entries [0-F] | W* |
| 10h | Mode Control | W |
| 11h | Overscan Color | W |
| 12h | Color Plane Enable | W |
| 13h | Horizontal Pel Panning | W |
The first sixteen registers in the Attribute Controller define a 4bpp palette.
External Register Details
| Bits | Name | Description |
|---|---|---|
| 0 | IO | I/O Address (0=3Bx mono, 1=3Dx color) |
| 1 | ERAM | Enable RAM (1=Enabled) |
| 2:3 | CLK | Clock Select (00=14MHz, 01=16MHz, 10=External, 11=Unused) |
| 4 | DISABLE | Disable Video Drivers (1=Disable) |
| 5 | PAGE | Page bit for Odd/Even mode |
| 6 | HSP | Horizontal Sync Polarity (0=Pos, 1=Neg) |
| 7 | VSP | Vertical Sync Polarity (0=Pos, 1=Neg) |
| Bits | Name | Description |
|---|---|---|
| 0 | FC0 | Feature Control Bit 0 |
| 1 | FC1 | Feature Control Bit 1 |
| 2:3 | Reserved | Reserved |
| 4:7 | – | Unused |
| Bits | Name | Description |
|---|---|---|
| 0:3 | – | Unused |
| 4 | SENSE | Switch Sense - State of selected configuration switch |
| 5 | FEAT0 | State of FEAT0 pin on Feature Connector |
| 6 | FEAT1 | State of FEAT1 pin on Feature Connector |
| 7 | INT | CRT Interrupt Pending (1=Yes) |
Attribute Controller Register Details
| Bits | Name | Description |
|---|---|---|
| 0 | B | Blue |
| 1 | G | Green |
| 2 | R | Red |
| 3 | SB/I | Secondary Blue / Mono Intensity |
| 4 | SG/I | Secondary Green / Intensity |
| 5 | SR | Secondary Red |
| 6:7 | Unused | Unused |
| Bits | Name | Description |
|---|---|---|
| 0 | G/A | Video Mode: 1: Graphics Mode 0: Alphanumeric Mode |
| 1 | DT | Text Attribute Type: 0: Color 1: MDA |
| 2 | LG | Enable Line Graphics Characters |
| 3 | B/I | Attribute Bit 7 interpreted as: 1: Blink Enabled 0: Background Intensity |
| 4:7 | Unused | Unused |
| Bits | Name | Description |
|---|---|---|
| 0 | B | Blue |
| 1 | G | Green |
| 2 | R | Red |
| 3 | SB/I | Secondary Blue |
| 4 | SG/I | Secondary Green / Intensity |
| 5 | SR | Secondary Red |
| 6:7 | Unused | Unused |
| Bits | Name | Description |
|---|---|---|
| 0:3 | ECP | Enable Color Planes Each bit set in this field enables the corresponding plane 0-3. |
| 4:5 | MUX | Video Status MUX |
| 6:7 | Unused | Unused |
| Bits | Name | Description |
|---|---|---|
| 0:3 | PAN | Horizontal Pel Panning Value EGA Mode: 0-7 Monochrome Mode: 8,0-7 |
| 4:7 | Unused | Unused |