Академический Документы
Профессиональный Документы
Культура Документы
txt
Marcel,
The VDP (Video Display Processor) chip used in the Colecovision and in
the early (MSX-1?) systems was the Texas Instruments TMS9918A, which was
also used in the TI99/4A Home Computer. This machine came onto the
market in 1980, in the midst of the video game/home computer boom.
During that time, I worked for TI as a student, and in 1982 I
co-authored (along with Jim Dramis) a game for the 99/4A called PARSEC,
among other things. All of us game programmers always lamented the fact
that the VDP memory was 'indirectly' mapped instead of direct, which of
course limited the amount of raw bit pushing we could do. Anyway, I
think the following will (hopefully) clear up your confusion regarding
accessing VDP memory. Note that later versions of the MSX systems
(MSX-2?) used a superset of the TI9918A, the YM9938, which was made by
Yamaha. The following discussion applies only to the TI9918A VDP chip.
You are correct when you stated that there is only ONE memory address
register in the VDP, and this is used for both reading and writing data.
Thus, there must be a way to indicate to the VDP whether the address
which has been written is to be used for reading or writing data. This
is done by using one of the upper address bits in the 16 bit address.
Since the 9918A can only address 16k bytes of memory, the upper two bits
in the address (A14-A15) will always be zero. While bit 15 (the most
significant) is always set to zero, bit 14 is used to distinguish
between a read and a write address. The following shows how this bit
affects subsequent VRAM data accesses.
If you are simply calculating the address for writing data, then using
that address as the write address without setting bit 14=1, this might
cause some unexpected behavior. If bit 14=0, this will cause the VDP to
initiate a read cycle and then increment the address counter, thus
giving the impression that the "write address" has been set to
(address+1). As I stated before, there really is only one address
register, so when you perform data reads/writes you are affecting the
same register.
I'm sure that the VDP designers (at TI, anyway) didn't expect people to
interleave data reads and writes without resetting the address, so any
undocumented operation may or may not be supported on all revisions of
the chip. As will any 'undocumented bugs/features', I'd be concerned
about the implementation of these 'features' in 9918A clones, such as
the Yamaha 9938.
According to the 9918A (VDP) Data Manual, there are two timing
constraints to be followed when access VRAM.
1. After the second address byte (MSByte) has been written to the VDP,
there must be a 2 microsecond wait before any data read/write accesses
can occur. This constraint ALWAYS applies, no matter which display mode
is in effect or which part of the screen (active video, vertical
sync/blanking) is being displayed. In the table below, this is referred
to as 'VDP Delay'.
WHY DOES THE VDP NEED SO MUCH BANDWIDTH TO REFRESH THE SCREEN,
AND OTHER STUFF YOU REALLY DON'T NEED TO KNOW ABOUT THE 9918A?
--------------------------------------------------------------
First, consider the overriding considerations for the guys who did the
9918A chip design. Of course, the part must function, but more
importantly, the die size must be as small as possible to keep the cost
down. After all, this chip was targeted toward a consumer market.
Now, a little background on VDP memory and pixel timing. The master
clock for the VDP is the color burst frequency X 3. All subsequent
calculations are for the NTSC version of the part, although the PAL
numbers will be similar. The color burst frequency is 3.579545 MHz.
While I don't know pi to this many digits, the color burst frequency is
very handy to know when working with NTSC video. So, the master clock
frequency is given by
Fmaster = Fcolorburst * 3
= 3.579545 MHz * 3
= 10.7386 MHz
Tmaster = 1/Fmaster
= 1/10.7386 MHz
= 93.12 ns (nanoseconds)
Each memory access takes four master clock times, so the memory access
time is given by
Tmem = Tmaster * 4
= 93.12 ns * 4
= 372.5 ns = 0.3725 us
The horizontal line time, or the amount of time from the start of one
horizontal display line to the next horizontal display line is specified
in the data sheet as Thorz = 63.695 us. So, the total number of times
which VDP memory can be accessed in a single horizontal scan line is
given by
We now know how many memory accesses are available to be allocated for
display refresh and CPU accesses combined.
Next, let's find out how many memory accesses are requied to build up a
single horizontal scan line in Graphics modes I or II. Any unused
accesses can theoretically be allocated to the CPU.
Any one active scan line is composed of up to six layers of graphic data
(listed in back to front hierarchy):
Let's see how many memory accesses are required to get the data for the
three different 'planes' described above.
Next, is the character data. There are 32 characters per scan line, and
each character in the scan line requires the following memory accesses
to retrieve the data required to generate the pixel data for that
character.
As you can see, it takes three memory accesses for each character, and
so the total number of memory accesses required per scan line to build
up the character display plane is given by
To determine which sprite will be visible on any given scan line, the
Y-position of all 32 sprites must be read from the Sprite Attribute
Table (SAT) in VRAM and compared against the current scan line number.
When doing the compare, the Mag bit from VDP register 1 must be taken
into account, since the magnification is in both the x and y directions.
In the worst case, the first 28 sprites, 0-27, are not displayed on a
given scan line, but sprites 28-31 will be displayed. In this case, the
Now, let's summarize the maximum total number of accesses required for
displaying four sprites on a scan line as
Msprite = total number of memory accesses per scan line for sprite
display
= test which sprites are on this line + sprite display data
access
= Msprite_test + Msprite_data
= 32 + 24
= 56 memory cycles
For those of you who I have not totally confused, the end is now in
sight. We are ready to compute the number of memory cycles available to
the CPU.
Mcpu = Mem accesses in one horizontal scan line - display mem accesses
= Mhorz - Mdisplay
= 171 - 152
= 19 memory accesses available for the CPU
If the CPU can access the memory every 5.95 us, then the total number of
CPU accesses allowed in a horizontal line time is given by
If one rounds 10.7 up to 11, that would seem to indicate that there are
8 memory cycles (19-11=8) which are unused.
Perhaps those extra 8 cycles could have been used to allow a fifth
sprite on a line, since each sprite costs a total of seven memory cycles
(1 for y-test, then 6 more if displayed). However, that would only leave
one memory cycle to spare. Also, there are scheduling and sycronization
issues involved regarding the sprites, and it would have probably
required too much chip area to squeeze in that one extra sprite.
Or, maybe those 19 cycles could have been all allocated to CPU accesses.
However, remember the earlier statement that every 16th memory accesses
is allocated for the CPU. It is relatively simple (cheap) to decode this
CPU access slot from the horizontal counter inside of the VDP which is
used for overall horizontal timing. If, instead, we take the 19 cycles
and divide them into the horizontal line time, we get
If memory cyclces take 372.5 ns, then the CPU could have every ninth
memory cycle (3.35/0.3725). Since this is not an integral power of two,
a separate CPU access counter would be required and would take more chip
area (cost) than a simple decode of the lower four bits of the
horizontal counter.
To summarize, the sprites take up slightly more than 1/3 of the display
bandwidth. Unfortunately, the chip designers did not incude a way to
turn off the sprites and thus allow 1 of four memory accesses to be
allocated to the CPU.
Paul Urbanus
urb@urbonix.com
*** ***
* Paul Urbanus urb@urbonix.com *
* *
* Never wrestle with a hog - you get dirty and the hog likes it. *
*** ***