EGA, 1984

The EGA added planes. Four of them, 16 colours out of 64, latch registers sitting between you and video memory, and a start address you can scroll. This era works each of those by hand until the plane model stops feeling strange.

Graphics track · 27 missions · boss mission, written exam and certificate · free, no signup. Everything below runs in the browser terminal on the SERVBG home page.

Open EGA in the terminal

What you will do

  1. render the reference scene through the EGA pipeline ref

    IBM announced the Enhanced Graphics Adapter in September 1984 alongside the PC/AT: 640x350 in 16 colours, against the CGA's four. The card listed at 524 dollars and the 5154 Enhanced Color Display at 849.

  2. enter 640x350 with 16 colours out of 64 mode 10h

    Sixteen colours at 640x350 need 112,000 bytes, so a 64KB EGA ran mode 10h from two planes in four colours; the full 16 needed the Graphics Memory Expansion Card. IBM shipped the 64KB version first and the picture everybody wanted required the upgrade.

  3. paint the 16 palette registers as colour bars bars

    A pixel on an EGA never stores a colour. It stores a number from 0 to 15, and the attribute controller decides what that number looks like.

  4. dump the 16 attribute-controller palette registers palette

    The 16 palette registers live at port 3C0h and hold 6 bits each. There is no DAC on an EGA: those six bits drive six TTL wires, two per channel, so 64 colours exist and any 16 of them can be on screen.

  5. decode one 6-bit rgbRGB colour code by hand bits 0x14

    The bit order is rgbRGB: the low three bits are the primary red, green and blue at value 170, the high three the secondary set at 85. Four levels per channel, 4x4x4 = 64.

  6. break the brown fix and watch bar 6 turn olive palette 6 0x06

    Without the fix, index 6 is red plus green at equal strength: AAAA00, a dark yellow nobody wanted. IBM had already faced this on the CGA and cured it in the 5153 monitor by halving the green.

  7. restore the brown fix palette 6 0x14

    On the EGA the fix is not hardware at all, just the default value 14h in one register, which swaps in the secondary green bit for AA5500. Any program was free to overwrite it and some did.

  8. list all 64 colours the EGA output can generate gamut

    Sixty-four available, sixteen loadable. Every EGA picture is two separate decisions: which 16 of the 64, and which of those 16 each pixel points at.

  9. retint index 1 from dark blue to bright cyan palette 1 0x3b

    Reprogramming one register repaints every pixel holding that index in a single I/O write, however much of the screen it covers. Palette animation on the EGA cost nothing per pixel.

  10. see the planar memory map and its arithmetic vram

    All four planes are mapped at A000:0000 at once. The address selects the pixel group; registers, not the address, select which plane a read or write actually touches.

  11. set one pixel and watch four separate plane bits move plot 320 175 12

    One pixel costs four memory writes, one per plane. That is why EGA code that mattered never plotted single pixels and always worked eight at a time.

  12. read one byte from all four planes at once peek 14040

    The offset arithmetic is y * 80 + (x >> 3): scan line 175 at byte column 40 is offset 14040, covering pixels 320 to 327. A real read returns one plane's byte, chosen by Read Map Select at 3CEh index 04h.

  13. paint eight pixels with a single byte store poke 14040 0xff

    With the map mask wide open, one 8-bit store sets the same bit pattern in all four planes, turning eight adjacent pixels white. Eight pixels per instruction is the whole reason the planar layout existed.

  14. write-enable plane 1 only mapmask 0x02

    The Sequencer Map Mask register sits at 3C4h index 02h. Its low four bits say which planes a CPU write is allowed to reach; the rest keep whatever they already held.

  15. repeat the same write with only one plane enabled poke 14120 0xff

    Identical instruction, identical data, different result: only bit 1 of each pixel is set, so the eight pixels come out green rather than white. The colour was decided by a register, not by the value you wrote.

  16. restore write access to all four planes mapmask 0x0f

    Leaving a narrow map mask set is one of the classic EGA bugs: every later drawing routine quietly paints in one bit-plane and the picture comes out in the wrong colours.

  17. load all four latches with one dummy read latch 14040

    The EGA holds four 8-bit latches, one per plane. Any CPU read of video memory fills all four, even though the CPU itself only receives one byte back.

  18. write the latches back somewhere else: a 4-plane block copy latchwrite 14200

    In write mode 1 the byte the CPU stores is discarded and the latches go out instead. One read plus one write moves 32 bits of picture across the card without the data ever crossing the ISA bus.

  19. blank plane 2 at display time and lose the red bit plane 2 off

    Color Plane Enable is attribute controller register 12h. It forces a plane's bit to 0 on the way to the output while video memory keeps every bit it had - the standard way to build a fade or a flash without touching the frame.

  20. let plane 2 reach the output again plane 2 on

    The picture comes back untouched, which proves the masking happened after memory and before the output pins rather than anywhere in between.

  21. build a 16x16 tile map across the whole frame tiles fill

    A tile engine stores a small map of tile numbers, not a screen-sized picture. Re-stamping 16x16 blocks was the only way an 8 MHz machine could keep a 112,000-byte frame moving.

  22. load a 16x16 four-colour glyph sprite load

    The EGA had no hardware sprites. Every moving object was software: save the background, draw the glyph, restore the background next frame, and do it before the beam catches you.

  23. move the sprite to a new position sprite move 300 160

    Index 0 in a sprite is not black, it is transparent - the blit skips those pixels entirely. Forget to restore the saved background and the sprite leaves a trail, the most common EGA game bug of the decade.

  24. shift the view one pixel with pel panning scroll 1

    CRTC registers 0Ch and 0Dh at port 3D4h hold the address the frame starts from, in bytes - so 8 pixels at a time. Attribute register 13h, horizontal pel panning, supplies the 1 to 7 pixels in between.

  25. move a full byte and watch pel panning wrap back to zero scroll 8

    Eight pixels of movement is exactly one increment of the start address, so the pel panning value returns to 0. No pixels were copied for any of this: the card simply began reading from a different address.

  26. poll 3DAh bit 3 for vertical retrace and lose the tear vsync on

    Input Status Register 1 at 3DAh sets bit 3 during vertical retrace, the gap after the last scan line while the beam returns to the top. Change the start address inside that window and the whole next frame is drawn from one consistent value.

  27. Boss missionrun the full scrolling pipeline — tiles, sprite, all four planes, retrace-synced scroll demo

    John Carmack had a 16-colour EGA scrolling smoothly in September 1990 with adaptive tile refresh: redraw only the tiles that actually changed and let the start address carry everything else. Commander Keen shipped on it that December. The received wisdom was that a PC could not scroll like a console. It could, on hardware that was six years old by then.

Certificate

This track is certifiable. Clear the boss mission in the terminal, then run EXAM EGA for the written paper: 20 server-graded questions drawn from our own bank, pass mark 14 of 20. The certificate is issued once both are done, and it carries a verification code.

Nearby eras

Previous
1981 · CGA
Program the 1981 IBM CGA: 320x200 in four colours, the B800 framebuffer, palette selection, dithering and composite artifact colour.
Next
1987 · VGA
Program VGA mode 13h: 256 colours, the 18-bit DAC, poking the A000 framebuffer, palette cycling, Mode X and demoscene effects.

All 25 eras in the Terminal Academy

Open EGA in the terminal