Specifications
4
one-byte pixel color values into this space. The table used in this mapping is called a palette, as it is analogous to a
painter’s palette, which in theory holds an infinite range of colors, but can only hold a few at any one time. Palettes
are often used to reduce the amount of memory necessary to describe an image, and are thus useful on embedded
devices even today. For your final projects, some of you may want to play with graphic techniques such as palette
color selection to best represent a more detailed image and dithering to map a more detailed image into a given palette.
The mapping between screen pixels and video memory in mode X is a little contorted, but is not as bad as some of the
older modes. The screen is first separated into blocks four pixels wide and one pixel high. Each block corresponds to
a single memory address from the processor’s point of view. You may at this point wonder how four bytes of data get
crammed into a single memory address (one byte in a byte-addressable memory). The answer, of course, is that they
don’t. For performance reasons, the VGA memory was 32-bit, and the interface between the processor and the VGA
is used to determine how the processor’s 8-bit reads and writes are mapped into the VGA’s 32-bit words. For example,
when the processor writes to a memory address, four bits of a specific VGA register are used to enable (1 bits) or
disable (0 bits) writes to 8-bit groups of the corresponding word in VGA memory. When drawing rectangles of one
color, this mask reduces the work for the processor by a factor of four. When drawing images, however, it poses a
problem in that adjacent pixels must be written using different mask register settings. As changing a VGA register
value is relatively slow, the right way to use mode X is to split the image data into four groups of interleaved pixels, set
the mask for each group, and write each group as a whole using the x86 string instructions (you won’t need to write
any of these, although you may want to look at how it is done in the existing code or in the x86 manual).
0xA12D4
address
3210
(0xA1234 + 80)
0xA1284
address
0xA1236
address
0xA1235
address
address
0xA1237
(0xA1234 + 160)
. . .
. . .
. . .
(all at 0xA1236)
plane 0
plane 1
plane 2
plane 3
0xA1234
32103210
0
address
3210
3210
321
Mode X video memory is memory-mapped and runs from (physical) memory address 0xA0000 to 0xAFFFF, for a
total of 2
16
addresses and 256 kB of addressable memory (counting all four planes). The addresses used in your
program are virtual rather than physical addresses, a concept to be discussed later in the course; don’t be surprised if
they are not the same as the physical addresses, though. A full screen occupies 320 × 200/4 = 16, 000 addresses, so
four fit into the full memory, with a little extra room. The VGA can be directed to start the display from any address in
its memory; addresses wrap around if necessary. In the figure shown above, for example, the screen starts at address
0xA1234.
Due to the timing behavior of emulated interactions with video memory, the code provided to you does not use a
traditional double-buffering model in which the off-screen image is drawn directly within video memory. As with
double-buffering, we do maintain two regions within the video memory for screen images. However, we use regular
memory to maintain an image of the screen and to update that image in place. When a new image is ready for display,
we copy it into one of two regions of the video memory (the one not being displayed) and then change the VGA
registers to display the new image. Copying an entire screen into video memory using one x86 string instruction
seems to take about as long as writing a small number of bytes to video memory under QEMU, thus our image display
is actually faster than trying to draw a vertical line in video memory, which requires one MOV instruction per vertical
pixel.
Only the modex.c file relies on mode X. The rest of the code should use a graphics format more convenient to C. In
particular, an image that is X pixels wide and Y pixels high should be placed in an array of dimensions [Y ][X]. The
type of the array depends on the color depth of the image, and in our case is an unsigned char to store the 8-bit
color index for a pixel. When you write code to generate graphic images from text, as described in a later section, you
should use the same format.
Graphical Mapping in the Game
The game shows a two-dimensional photo for each virtual room in the simulated world, and the screen at any time
shows a region of the current photo. The photo is fully resident in memory, but could in theory be constructed