TMS9918


The TMS9918 is a video display controller manufactured by Texas Instruments and introduced in 1979. In TI's manuals it's called a "Video Display Processor". The TMS9918 and its variants are used in the Casio PV-2000, Coleco Adam, ColecoVision, CreatiVision, Hanimex Pencil II, MSX, Memotech MTX, NABU Personal Computer, PECOS, SG-1000, SC-3000, SV-318, SV-328, Sord M5, TI-99/4, Tatung Einstein, and Tomy Tutor.
The TMS9918 was an advanced design for the era. It had four graphics modes based on an underlying 256 wide by 192 high pixel layout, which could be used as a 40 by 24 character display, a 256 by 192 pixel display, or a 64 by 48 pixel display which used less memory. It had a fixed color palette with 15 colors plus transparent. It also supported 32 single-color 8x8 or 16x16 pixel sprites, numbered 0 to 31, with lower-numbered sprites appearing on top of higher-numbered ones. This allowed for layering and perspective effects. It also featured a video input and sync pin, which allowed video from another source to appear under the graphics being created by the chip. This could be used to layer the output from multiple 9918's, or to use the 9918 as a system for titling and overlays on other video sources.
To support this advanced feature set, the 9918 required fast access to memory. To allow this, it was given a dedicated 16 KB pool of RAM that was separate from the main memory of the computer that it was part of. TI referred to this as VRAM. This meant that the CPU could only update the video display over a separate 8-bit data bus with the VDP moving data on the bus to and from its dedicated RAM. This limited the speed at which the CPU and 9918 could communicate. It also meant that the common solution of using the video chip to refresh memory could not be used and had to be implemented in separate hardware. While these represented minor complications compared to systems that shared memory in a single pool, the result was a display that was much more colorful and offered some parity with arcade game-level displays.
The Yamaha V9938 is an enhanced version of the TMS9918.

Description

General information

The TMS9918 was packaged in a 40-pin dual in-line package. Power was provided as +5V on pin 33, V, and ground on pin 12, V. A quartz crystal running at 10.7386 MHz, three times the NTSC colorburst frequency, was connected across pins 40, XT1, and 39, XT2. Video output was on pin 36, COMVID, and input, if used, on pin 35, EXTV, with their connector's shield connection connected to ground.
In order to achieve the memory performance needed to support full-color operation, the system used a dedicated area of DRAM they referred to as VRAM. To operate this memory, the system included a separate set of pins forming an 8-bit address bus on pins 3 through 10 and an 8-bit data bus on pins 25 through 32, supported by a read/write control on pin 11, and RAS and CAS on pins 1 and 2.
Communications with the host computer were through a separate 8-bit data bus on pins 17 through 24, D7 to D0. Pin 13, MODE, controls whether the data on that bus is an address or data. To write to the TMS9918, the CPU first sets the mode and writes data to an internal address register, then writes the data to the bus and changes the mode to cause the data to be deposited into that address. After the data byte is read, the TMS9918 increments the pointer in the address register, allowing a series of bytes to be written in succession.
The TMS9918 logically arranges graphics in a number of layers, 32 sprite layers on top, a graphics or text layer, a "backdrop" with a single solid color filling the screen, and finally an external video layer. The backdrop plane is slightly larger than the others, so it completely fills the screen. The system uses a 15-color palette, along with color 0 which is transparent. At any pixel location on the screen, the system sees if a particular object is in that location, and whether or not it is set to transparent. If it is transparent it looks at the next object, and so on, until it reaches the external video layer. The following descriptions are ordered in this same fashion.

Sprites

A key feature of the 9918 series was its powerful sprite support. It used a series of 8 bytes in VRAM to store patterns for 8 by 8 pixel sprites, one byte for each line of 8 pixels. It also had a second mode with 16 by 16 pixel sprites, 2 bytes per row and 16 rows. Additionally, either size of sprite could be magnified two times to make the spites larger on the screen. The pattern data for the sprites, in 8 or 32 byte long entries, was held in a block of memory known as the sprite generator table.
In addition to the 8 or 32 byte long entries holding the patterns, there was a separate sprite attribute table that defined how the data was interpreted and displayed. This included 8-bit values for the horizontal and vertical position of the sprite, a pointer to the start of the data for that sprite in the SGT, and a color code in the lower four bits, for a total of 4 bytes per sprite for a total of 128 bytes in the SAT.
To determine what color to display at any given pixel on the screen, the system looked to see which sprites were visible at that location, and then searched down the patterns until it found the first one that held a 1 in that location, then drew the color found in the SAT at that pixel. This caused the sprites to be displayed in order, such that lower numbered sprites appeared on top of higher numbered ones. That meant, for instance, that sprite 0 always appeared on top. If there was no sprite on the screen at that location with a 1, that pixel was transparent, and the background graphics would be displayed instead.
As the sprites were drawn in order, it is sometimes necessary to change that order to produce the desired layering effects. This is the purpose of the "name" field entries in the SAT. For instance, if one wants to change the display so sprite 10 appears in front of 5, the values in the name field entries of the two can be swapped, avoiding the need to move the pattern data. Through careful arrangement of the sprite ordering, the system can easily produce pseudo-3D and parallax scrolling effects.
Due to performance issues, only four sprites can be displayed on any one scan line. If more are specified on a given line, they will simply not be displayed. The VDP has a status register that reports the number of the first sprite that had to be dropped. It is up to the programmer to design their system to ensure this limit is not reached. One trick to emulate more sprites on a line can be achieved by changing the priorities by swapping the name values every other frame so that one set of eight is displayed on one frame and then another on the next. This allows up to eight sprites, but results in noticeable flickering.
The sprite collision flag is set when non-zero pattern bits of two sprites coincide, even if either sprite has transparent colour. The VDP does not indicate which sprites have collided, simply that at least two have done so. This is normally used to trigger more advanced collision detection routines inside the software, which can then determine the exact location of the collision and act upon it.

Graphics modes

The graphics of the 9918 were based on an underlying 256 wide by 192 high pixel layout. These numbers are typical for systems of the era which used analog video signals for output in a progressive scan display. This is close to the maximum resolution achieved on television sets of the era, which was around 320 by 240, due to the complexity of the NTSC radio-frequency signals.
There were four ways the graphics layer could be used:
Mode 0, or Text Mode, broke the screen into a 40 by 24 layout of "blocks", each 6 pixels wide and 8 high. Each block could hold a value from 0 to 255, normally representing an expanded ASCII character set. The patterns for each of the 256 characters was stored in VRAM and could be changed by loading the VRAM values using the CPU. Each line of the characters was defined as a series of "on" or "off" pixels stored in one byte per line, and 8 bytes per character. Because the blocks were 6 by 8 on the screen, it was up to the designer to lay out the characters in a 5 by 7 grid to leave space between them. The color for the "on" and "off" bits in the patterns could be any of the 15 colors available, and stored in VRAM.
Mode 1, or Graphics I, was essentially a modification of Text Mode that broke the screen into a 32 by 24 layout, so that each block was 8 by 8 pixels instead of 6 by 8. The pattern for any given pixel on the screen was looked up from the same 256-entry table of bit patterns as the one holding characters in Text Mode. As there were 768 possible locations and only 256 possible patterns, this mode was limited in the sorts of displays it could produce. Graphics I also added a separate section of VRAM that held the color values for the on and off pixels for any given block, with 768 entries. This meant every block of 8 by 8 pixels could have its own two colors, but the pixels within any block all had to be the same. This is not an uncommon solution for the era, and leads to a well-known problem known as attribute clash when it is not possible to choose colors that to not result in the edges of the cells being visible.
Mode 2, or Graphics II, was a further modification of Graphics I, allowing separate patterns for all 768 blocks, as well as separate color settings for each line within the blocks. This meant any block could use all 15 colors, although only two per line. This display allows any image to be drawn and more colors to be displayed, producing a display that is pixel-addressable and suitable for high-resolution drawing of arbitrary images. The cost is that it requires 32 color entries for each of the 192 lines, as well as an extended pattern map with 768 separate entries, increasing the VRAM needed to hold all of the data to about 12 KB.
Mode 3, or Multicolor Mode, broke the screen into 64 by 48 blocks, for a total of 3072 blocks. There were no patterns in this mode, the entire cell was either on or off. There was a color table entry for each block, so every block could select its own color. This produced a low-resolution but high-color display using less than 3 KB of VRAM.
One limitation of the system is that it did not include hardware fine scrolling support, and could only scroll along cell boundaries, normally 8 lines high. Scrolling was accomplished by moving the pattern already stored in VRAM and then adding data for the new line or column, which took some time to perform. Additionally, as all of the graphics modes were essentially character modes with custom characters in each cell, patterns that spanned cells, like lines or circles, had to calculate the pixels for each line of any given cell and upload those values into the character sets.