VGA, 1987
Mode 13h is where a generation learned graphics: 320x200, 256 colours, one byte per pixel, a framebuffer at A000. This era pokes that memory directly, cycles the palette, opens Mode X and builds the demoscene effects that came out of it.
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.
What you will do
- draw the reference scene in 256 colours
refIBM shipped VGA on the PS/2 Model 50 and 60 on 2 April 1987. Mode 13h puts 256 colours on screen at once, picked from a 262144-colour DAC.
- set mode 13h through the BIOS
mode 13hINT 10h with AH=00h and AL=13h asks the BIOS for mode 13h: one byte per pixel, 320 bytes per row, 64000 bytes starting at segment A000h.
- read what IBM actually put on the board
cardVGA was IBM's first analog display adapter: a 15-pin DE-15 connector and three 6-bit DACs, where EGA drove six TTL colour lines (RrGgBb) and could only ever reach 64 colours.
- map the framebuffer at A000h
mem320 x 200 is 64000 bytes, which fits inside one 64 KB real-mode segment. That single fact is why mode 13h needed no bank switching and why every beginner started there.
- write one byte of video RAM and light a pixel
poke 32160 14Offset is y * 320 + x, so 100 * 320 + 160 lands at A000:7DA0 and lights the centre pixel. EGA needed four port writes and a latch read for the same dot.
- read the byte back out of video RAM
peek 32160Reads come straight back. Mode 13h video memory is ordinary memory that the CRTC happens to scan out seventy times a second.
- see where a scanline lives in memory
row 100Scanlines are consecutive: row 100 owns bytes 32000 to 32319, and row 101 starts at 32320. CGA split even and odd rows into two 8000-byte banks; VGA dropped that entirely.
- draw all 256 default DAC entries
palThe palette the BIOS loads at mode set is 16 EGA-compatible colours, 16 greys and a 6x6x6 colour cube. Demos threw all of it away and wrote their own.
- write one DAC entry and watch a colour change
dac 14 63 0 0Each DAC channel is six bits, 0 to 63, so eighteen bits per entry and 262144 possible colours. Swatch 14 went yellow to red without a single pixel byte being rewritten.
- interpolate the lower half of a 224-step ramp
gradient 32 143 0 0 0 63 20 0A ramp is plain interpolation written through port 3C8h once and port 3C9h three times per entry. Indices 32 to 143 now run black to deep orange.
- finish the ramp from orange to pale white
gradient 144 255 63 20 0 63 63 48Indices 32 to 255 are now one continuous 224-step ramp. From here on every effect writes intensity, not colour, and the palette decides what intensity looks like.
- see the seeded generator demos used instead of a random source
lcgA compo entry had to render identically every time it ran on the party machine, so nobody sampled a timer for noise. A linear congruential generator seeded with a constant gave repeatable static.
- build the sine lookup table every effect will use
sineA 386SX had no FPU on most desks and a library sine cost thousands of cycles. Demos built one 1024-entry table at startup and never called a transcendental function again.
- run the fire effect
fireFire seeds the bottom rows from the generator, then makes every pixel the average of the three below it and the one two rows down, scaled slightly under a quarter so heat fades as it rises.
- run a 3D starfield
starsA starfield keeps x, y and z per star and projects with x/z and y/z. One divide per star per frame was affordable on a 386; one divide per pixel was not.
- rotate and zoom a texture with two steppers
rotozoomRotozoom computes du and dv once per frame from a cosine and a sine, then walks the texture by adding them. Masking the coordinates with 63 makes a 64x64 texture tile for free.
- run plasma, the effect the boss needs
plasmaPlasma sums four sines per pixel. Split into a per-column term and a per-row term it fills 520 table entries with two lookups each, 1040 a frame plus one add per pixel, instead of 256000 lookups.
- rotate the DAC ramp every frame
cycle onPalette cycling animates a picture without touching video memory: rotate 224 DAC entries and the same 64000 bytes read as a moving image. It cost 672 port writes a frame.
- read the retrace status bit and find the tear
vsyncPort 3DAh bit 3 is the vertical retrace status. Without polling it the CRTC scans out a frame that is part new and part old, and you see the seam move down the screen.
- lock drawing to the vertical retrace
vsync onThe classic wait is two spin loops: first until bit 3 clears so you are not mid-retrace, then until it sets again. At 320x200 the VGA refreshes 70 times a second, giving 14.3 ms a frame.
- cost out double buffering
flipDouble buffering builds the frame in system RAM and copies it to A000h at retrace. On a 25 MHz 386 over 16-bit ISA that copy ate roughly a third of the frame doing nothing but moving bytes.
- switch to 320x240 planar with square pixels
modex onMichael Abrash published Mode X in Dr. Dobb's Journal in July 1991: an undocumented tweak of mode 13h giving 320x240, square pixels, four planes and all 256 KB addressable.
- see how unchained memory is laid out
planesUnchained memory puts pixel x in plane x AND 3 at offset x/4. Setting the Map Mask register at 3C4h index 2 to 1111b writes four pixels with one byte, which is why Mode X cleared the screen four times faster.
- flip pages by moving the CRTC start address
page 1At 320x240 each page is 19200 bytes per plane, so 256 KB holds three of them. Writing the start address into CRTC registers 0Ch and 0Dh flips pages with no copying at all.
- return to mode 13h for the finale
modex offMost demos used both modes: Mode X for scrollers and page flipping, mode 13h for anything that wanted a flat framebuffer and no plane juggling.
- read where these effects came from
sceneFuture Crew released Second Reality at Assembly 1993 in Finland: a 386, a Sound Blaster, a rotozoomer, a dot tunnel and a bitmap scroller, all in real time, and it set the bar for the rest of the decade.
- Boss missionrun plasma with palette cycling, retrace locking and your own DAC ramp
demoThat is the whole 1987 stack in one frame: a linear 64000-byte buffer, a palette you wrote yourself, an effect that only ever writes intensity, and a retrace poll holding it steady at 70 Hz.
Certificate
This track is certifiable. Clear the boss mission in the terminal, then run EXAM VGA 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.