Atari 7800 Video System by Daniel Boris 12/30/98 Disclaimer: The material in this document was derived from the official Atari Maria programmers guide, as well as my experience while working on the Atari 7800 driver for MESS. I have made every attempt to be as accurate as possible, but there are very likely errors in this document. Use this information at your own risk. Introduction The 7800 uses a very unique system for generating the display. Each scanline on the display has an associated display list that describes how to create that scanline. (Note: Don't confuse this with the Atari 8-bit display list since they work in very different ways). Each entry in a display list describes a single object on that scanline. The objects are drawn into a temporary scanline buffer one after another so that later object can be drawn over earlier ones. The 7800 has 2 scanline buffers, while one is being drawn to the screen the other is being loaded from the display list. At the end of each scanline the buffers are swapped. The only limitation on the number of objects on each line is the amount of time it takes to build the line. The Display List List (no that's not a typo, that's what it's called) The top level structure for the video display is the Display List List (DLL). Each entry in the DLL defines a block of scanlines and points to the DL that should be used for that block. The system steps through each of the DLL entries until every scanline on the screen has been filled, at which point it starts over. The start of the DLL is pointed to by Maria registers $2C (High byte) and $30 (Low byte). Each DLL entry has this format: Byte 0 : Bit 7 - DLI Bit 6 - Holey DMA 16 Bit 5 - Holey DMA 8 Bit 4 - Unused Bit 0..3 - Offset Byte 1: Bit 0..7 - DL address high Byte 2: Bit 0..7 - DL address low DLI (Display list interrupt): When set to 1 an NMI interrupt to the processor will occur at the start of the current region. Holey DMA 8 - 1 = DMA interprets odd 2K blocks (A11 = 1) as zeros. Holey DMA 16 - 1 = DMA interprets odd 4K blocks (A12 = 1) as zeros. Offset: This determines how many scanlines will be drawn using the specified display list. After each scanline is drawn offset is decremented until it reached -1 at which point the next DLL entry is read DL address: This is the pointer to the DL that is used to draw these scanlines Display List (DL) A Display List is used to describe how a scanline should be drawn. It consists of a series of entries, one for each object on the line. Each entry is read and data is moved from memory to the appropriate location on the scanline. As the scanline is drawn earlier objects may be over drawn by later ones thus giving certain object priority over others. There are two formats for the display list entry: Normal: byte 0: Address Low byte 1: bits 5..7 Palette bits 0..4 Width byte 2: Address High byte 3: Horizontal Position Extended: byte 0: Address Low byte 1: bit 7 Write mode bit 6 1 bit 5 Indirect mode bit 0..4 0 byte 2: Address High byte 3: bits 5..7 Palette bits 0..4 Width byte 4: Horizontal Position Address high/low: This is the address where the data that is to me copied to the scanline is stored. Horizontal Position: This is the horizontal position on the scanline where the data should start being copied to. Width: This indicates how many bytes of data will be transferred to the scanline. This is a 2's complement value in the range from 1 - 31. Palette: This determines which of the 8 palettes will be used for drawing the current object. Write mode: This is used along with the read mode in the maria control register to determine how data is drawn to the screen. Indirect mode: 1 = Enable indirect mode. Indirect mode is used for character type graphics and adds a layer of indirection to the data transfer. In direct mode the address of the data is calculated like this: graph_addr - graphics data address from the DL entry x - counts from 0 to width offset - current offset from the DLL de-incremented each scanline chbase - character base from MARIA register data_address = graph_addr + x + (offset << 8) for indirect mode: c = data at (graph_addr+x) /* This is the character number */ data_address = (chbase << 8) + c + (offset << 8) Graphics modes The graphics modes are as follows: Mode WM RM1 RM0 160A (160x2) 0 0 0 160B (160x4) 1 0 0 320A (320x1) 0 1 1 320B (320x2) 1 1 0 320C (320x2) 1 1 1 320D (320x1) 0 1 0 160A (160x2) Mode This mode has 2 bits per pixel and a maximum width of 160 pixels. The color of each pixel (left to right) is determined as follows: pixel 0 - bits 7..6 pixel 1 - bits 5..4 pixel 2 - bits 3..2 pixel 3 - bits 1..0 160B (160x4) Mode This mode has 4 bits per pixel and a maximum width of 160 pixels. The color of each pixel (left to right) is determined as follows: pixel 0 - bits 3,2,7,6 pixel 1 - bits 1,0,5,4 320A (320x1) Mode This mode has one bit per pixel and a maximum width of 320 pixels. The color of each pixel (left to right) is determined as follows: pixel 0 - bit 7 pixel 1 - bit 6 pixel 2 - bit 5 pixel 3 - bit 4 pixel 4 - bit 3 pixel 5 - bit 2 pixel 6 - bit 1 pixel 7 - bit 0 320B (320x2) Mode This mode has two bits per pixel and a maximum width of 320 pixels. The color of each pixel (left to right) is determined as follows: pixel 0 - bits 7,3 pixel 1 - bits 6,2 pixel 2 - bits 5,1 pixel 3 - bits 4,0 320C (320x2) Mode This mode is a little different then the others. Each byte can specify 4 pixels. The remaining bits are used to determine which palette the color for the pixel will come from. If a pixel is on it is color 2, if it off it is either transparent or the background color. The pixels are specified by bits 7..4: pixel 0 = bit 7 pixel 1 = bit 6 pixel 2 = bit 5 pixel 3 = bit 4 The palette for pixels 0 and 1 is specified by bits 3..2 and bit 2 of the palette select from the DL. So the palette number is like this: [P2][bit3][bit2] thus selecting one of the 8 palettes. The palette for pixels 2 and 3 is specified by bits 1..0 and bit 2 of the palette select from the DL. So the palette number is like this: [P2][bit1][bit0] thus selecting one of the 8 palettes. 320D (320x1) Mode This is probably the most unusual mode. Each byte specifies 8 pixels and each pixel can be 1 of four colors. If 'P' are the palette bits from the DL and 'D' are the data bits from the graphics data, the data is formatted as follows: palette P2 P2 P2 P2 P2 P2 P2 P2 color DP DP DP DP DP DP DP DP 71 60 51 40 31 20 11 00 pixel 0 1 2 3 4 5 6 7 So for example, the color for pixel 0 (the left most pixel) is determined by combining bit 7 of the graphics data, and but 1 from the palette select.