mirror of
				https://github.com/cbmeeks/TMS9918.git
				synced 2025-10-31 11:36:44 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			710 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			710 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
 | 
						|
			Texas Instruments TMS9918A VDP
 | 
						|
	     Almost complete description including undocumented features
 | 
						|
 | 
						|
			By Sean Young (sean@msxnet.org)
 | 
						|
			    Version 0.4.2 September 2002
 | 
						|
 | 
						|
 | 
						|
In this document I'll try to give a complete description of the TMS9918A in
 | 
						|
software behaviour and display output. I only know the VDP in the MSX system,
 | 
						|
in other systems it may have features not described here.
 | 
						|
 | 
						|
You can always find the latest version of this document at:
 | 
						|
 | 
						|
	http://www.msxnet.org/tech/
 | 
						|
 | 
						|
1) Overview
 | 
						|
 1.1) Colours
 | 
						|
 1.2) Registers
 | 
						|
 1.3) External Video
 | 
						|
 | 
						|
2) I/O with the VDP
 | 
						|
 2.1) Memory access
 | 
						|
 2.2) Register access
 | 
						|
 2.3) I/O Ports quirks
 | 
						|
 2.4) Interrupts
 | 
						|
 | 
						|
3) Display modes
 | 
						|
 3.1) Mode 0 
 | 
						|
 3.2) Mode 1
 | 
						|
 3.3) Mode 2
 | 
						|
 3.4) Mode 3
 | 
						|
 3.5) Undocumented Mode 1 + 2
 | 
						|
 3.6) Undocumented Mode 2 + 3
 | 
						|
 3.7) Other (Mode 1+3 and Mode 1+2+3)
 | 
						|
 | 
						|
4) Sprite system
 | 
						|
 4.1) Sprite attribute
 | 
						|
 4.2) Sprite pattern sizes
 | 
						|
 4.3) Illegal sprites and collisions
 | 
						|
 | 
						|
5) Hardware
 | 
						|
 5.1) Pin outs
 | 
						|
 | 
						|
6) To-do
 | 
						|
 | 
						|
7) References
 | 
						|
 | 
						|
 | 
						|
1) Overview
 | 
						|
-----------
 | 
						|
 | 
						|
The TMS9918a is quite a simple VDP with 16kB or 4kB of video memory. The 
 | 
						|
display always  has a resolution of 256 pixels horizontal and 192 pixels 
 | 
						|
vertical. Around this area, there is the border colour (back drop) which can 
 | 
						|
be set in the registers. There also is a sprite subsystem, with maximum of 
 | 
						|
4 sprites on a horizontal line.
 | 
						|
 | 
						|
There is a PAL version of the chip, and a NTSC version. The interrupt speed
 | 
						|
is different: 50Hz for PAL and 60Hz for NTSC. Also the colours are different.
 | 
						|
 | 
						|
The TMS9918A was used in quite a few systems: MSX1, Coleco, TI99/4A and 
 | 
						|
probably more. I only know it in the MSX1 system.
 | 
						|
 | 
						|
 | 
						|
1.1) Colours
 | 
						|
 | 
						|
Taken from mess/vidhrdrw/tms9928a.c in MESS, by Raphael Nabet.
 | 
						|
 | 
						|
The first 3 columns are taken from the TI datasheet (in volts). The next 3 
 | 
						|
columns are based on this formula:
 | 
						|
 | 
						|
	Y = .299*R + .587*G + .114*B (NTSC)
 | 
						|
 | 
						|
The coefficients are likely to be slightly different with PAL. I assumed the 
 | 
						|
"zero" for R-Y and B-Y was 0.47V. The last 3 coeffs are the 8-bit values.
 | 
						|
 | 
						|
Colour           Y     R-Y   B-Y   R     G     B     R    G    B
 | 
						|
0 Transparent
 | 
						|
1 Black         0.00  0.47  0.47  0.00  0.00  0.00    0    0    0
 | 
						|
2 Medium green  0.53  0.07  0.20  0.13	0.79  0.26   33  200   66
 | 
						|
3 Light green   0.67  0.17  0.27  0.37  0.86  0.47   94  220  120
 | 
						|
4 Dark blue     0.40  0.40  1.00  0.33  0.33  0.93   84   85  237
 | 
						|
5 Light blue    0.53  0.43  0.93  0.49  0.46  0.99  125  118  252
 | 
						|
6 Dark red      0.47  0.83  0.30  0.83	0.32  0.30  212   82   77
 | 
						|
7 Cyan          0.73  0.00  0.70  0.26	0.92  0.96   66  235  245
 | 
						|
8 Medium red    0.53  0.93  0.27  0.99	0.33  0.33  252   85   84
 | 
						|
9 Light red     0.67  0.93  0.27  1.13! 0.47  0.47  255  121  120
 | 
						|
A Dark yellow   0.73  0.57  0.07  0.83	0.76  0.33  212  193   84
 | 
						|
B Light yellow  0.80  0.57  0.17  0.90	0.81  0.50  230  206  128
 | 
						|
C Dark green    0.47  0.13  0.23  0.13	0.69  0.23   33  176   59
 | 
						|
D Magenta       0.53  0.73  0.67  0.79	0.36  0.73  201   91  186
 | 
						|
E Gray          0.80  0.47  0.47  0.80	0.80  0.80  204  204  204
 | 
						|
F White         1.00  0.47  0.47  1.00	1.00  1.00  255  255  255
 | 
						|
 | 
						|
 | 
						|
1.2) Registers
 | 
						|
 | 
						|
The VDP has 8 control registers (0-7) and one status register. 
 | 
						|
 | 
						|
Control Registers:
 | 
						|
 | 
						|
Reg/Bit	7	6	5	4	3	2	1	0
 | 
						|
0	-	-	-	-	-	-	M2	EXTVID
 | 
						|
1	4/16K	BL	GINT	M1	M3	-	SI	MAG
 | 
						|
2	-	-	-	-	PN13	PN12	PN11	PN10
 | 
						|
3	CT13	CT12	CT11	CT10	CT9	CT8	CT7	CT6
 | 
						|
4	-	-	-	-	-	PG13	PG12	PG11
 | 
						|
5	-	SA13	SA12	SA11	SA10	SA9	SA8	SA7
 | 
						|
6	-	-	-	-	-	SG13	SG12	SG11
 | 
						|
7	TC3	TC2	TC1	TC0	BD3	BD2	BD1	BD0
 | 
						|
 | 
						|
Status Register:
 | 
						|
 | 
						|
	7	6	5	4	3	2	1	0
 | 
						|
	INT	5S	C	FS4	FS3	FS2	FS1	FS0
 | 
						|
 | 
						|
The function of the bits is as follows:
 | 
						|
 | 
						|
M1,M2,M3	Select screen mode
 | 
						|
EXTVID		Enables external video input.
 | 
						|
4/16K		Selects 16kB RAM if set. No effect in MSX1 system.
 | 
						|
BL		Blank screen if reset; just backdrop. Sprite system inactive
 | 
						|
SI		16x16 sprites if set; 8x8 if reset
 | 
						|
MAG		Sprites enlarged if set (sprite pixels are 2x2)
 | 
						|
GINT		Generate interrupts if set
 | 
						|
PN*		Address for pattern name table
 | 
						|
CT*		Address for colour table (special meaning in M2)
 | 
						|
PG*		Address for pattern generator table (special meaning in M2)
 | 
						|
SA*		Address for sprite attribute table
 | 
						|
SG*		Address for sprite generator table
 | 
						|
TC*		Text colour (foreground)
 | 
						|
BD*		Back drop (background). Sets the colour of the border around
 | 
						|
		the drawable area. If it is 0, it is black (like colour 1).
 | 
						|
FS*		Fifth sprite (first sprite that's not displayed). Only valid
 | 
						|
		if 5S is set.
 | 
						|
C		Sprite collision detected
 | 
						|
5S		Fifth sprite (not displayed) detected. Value in FS* is valid.
 | 
						|
INT		Set at each screen update, used for interrupts.
 | 
						|
 | 
						|
The exact meaning of all these bits should become clear in the remainder of 
 | 
						|
this document.
 | 
						|
 | 
						|
The bits marked with `-' are "don't care": set or reset, doesn't make any
 | 
						|
difference. However, to maintain upwards compatibility, you should 
 | 
						|
reset these bits.
 | 
						|
 | 
						|
 | 
						|
1.3) External Video
 | 
						|
 | 
						|
Tursi <tursi@yiffco.com> writes:
 | 
						|
 | 
						|
The 9918A processor is capable of genlocking with an external video signal 
 | 
						|
and providing video overlay - this is the purpose of the Transparent color. 
 | 
						|
(I don't know about the 9918 -- perhaps in that chip it *is* B&W, as I've 
 | 
						|
heard of 99/4s (no A) outputting only B&W video, but I haven't seen it so 
 | 
						|
I can not confirm or deny it.)
 | 
						|
 | 
						|
Anyway, so far as the 9918A goes, the EXTVDP and _RESET/SYNC pins (using 
 | 
						|
the names in your doc) are used to input external video and video sync. 
 | 
						|
When Register 0 bit 0 is reset, the chip performs normally. When it is set, 
 | 
						|
video sync is taken in through the sync pin, and the VDP's video is mixed 
 | 
						|
on top of any video being fed into the EXTVDP pin.
 | 
						|
 | 
						|
I have experimentally confirmed that this does in fact work. Although the 
 | 
						|
TI-99 is not designed to use this feature, I hacked together a quick circuit 
 | 
						|
many years ago to attempt it. I was not successful in getting the sync to 
 | 
						|
work to my liking (mostly due to inexperience), but I did confirm the 
 | 
						|
operation of this bit as switching the external video on and off.
 | 
						|
 | 
						|
 | 
						|
2) I/O with the VDP
 | 
						|
-------------------
 | 
						|
 | 
						|
The VDP has two I/O ports (#0 and #1) which can be read or written. In the MSX
 | 
						|
system, they are mapped to port 98h and 99h. The VDP also has an INT output,
 | 
						|
which can be used by the CPU to detect screen updates (or vertical blank).
 | 
						|
 | 
						|
 | 
						|
2.1) Memory access
 | 
						|
 | 
						|
The video memory can't be accessed directly; only through the I/O ports. To 
 | 
						|
the contrary to what many (official!) docs say, there is only one read/write 
 | 
						|
address where the VDP reads or writes in the memory. There also is a 
 | 
						|
read-ahead buffer, which stores one byte. Memory is "read ahead", so when a
 | 
						|
read is requested, it can give the value immediately.
 | 
						|
 | 
						|
This memory address (the r/w address) can be set by writing two bytes to port 
 | 
						|
#1. Despite the fact there is only one address, a distinction is made between 
 | 
						|
setting it for reading or writing (this because of the read-ahead buffer).
 | 
						|
 | 
						|
The two bytes are formatted as follows:
 | 
						|
 | 
						|
		7	6	5	4	3	2	1	0
 | 
						|
Byte #0		A7	A6	A5	A4	A3	A2	A1	A0
 | 
						|
Byte #1		0	R/W	A13	A12	A11	A10	A9	A8
 | 
						|
 | 
						|
A13-A0 make up the address. R/W specifies whether you want to read or write
 | 
						|
from that address. It should be 0 for reading, 1 for writing.
 | 
						|
 | 
						|
What happens internally in the VDP is interesting. This depends on what you
 | 
						|
set the R/W bit to:
 | 
						|
 | 
						|
Write (1):	Simply set the r/w address to the A* value specified.
 | 
						|
Read (0):	Read the contents of the A* address from the VRAM and put it
 | 
						|
		in the read-ahead buffer. Set the r/w address to A* + 1.
 | 
						|
 | 
						|
Now that the r/w address is set, we can start reading from or writing to it. 
 | 
						|
After each access it is increased. By reading port #0 we can read from the 
 | 
						|
address, by writing to it we write to the address. What happens internally is:
 | 
						|
 | 
						|
Read:	Return value in read-ahead buffer. Read next value from the r/w 
 | 
						|
	address, put it in the read-ahead buffer. Increase the r/w address.
 | 
						|
Write:	Write back the value to the r/w address, then increase the r/w address.
 | 
						|
	Interestingly, the value written is also stored in the read-ahead 
 | 
						|
	buffer.
 | 
						|
 | 
						|
After 3fffh (16kB limit) the r/w address wraps to zero.
 | 
						|
 | 
						|
In 4Kb mode addressing works differently. Charles MacDonald explains:
 | 
						|
 | 
						|
I wanted to contribute some information to your TMS9918 document. The 4K/16K 
 | 
						|
bit of register #1 tells the TMS9918 how to form addresses when accessing 
 | 
						|
VRAM. However, memory is not really limited to 4K, the full 16K range is 
 | 
						|
addressable. This does have consequences if you write to VRAM in one 
 | 
						|
setting, then change the bit and try to read data back.
 | 
						|
 | 
						|
The modified addresses look like this:
 | 
						|
 | 
						|
VDP address      VRAM address
 | 
						|
   (Column)         4K mode     8/16K mode
 | 
						|
   AD0              VA0         VA0
 | 
						|
   AD1              VA1         VA1
 | 
						|
   AD2              VA2         VA2
 | 
						|
   AD3              VA3         VA3
 | 
						|
   AD4              VA4         VA4
 | 
						|
   AD5              VA5         VA5
 | 
						|
   AD6              VA12        VA6
 | 
						|
   AD7              Not used    Not used
 | 
						|
   (Row)
 | 
						|
   AD0              VA6         VA7
 | 
						|
   AD1              VA7         VA8
 | 
						|
   AD2              VA8         VA9
 | 
						|
   AD3              VA9         VA10
 | 
						|
   AD4              VA10        VA11
 | 
						|
   AD5              VA11        VA12
 | 
						|
   AD6              VA13        VA13
 | 
						|
   AD7              Not used    Not used
 | 
						|
 | 
						|
ADx - TMS9928 8-bit VRAM address/data bus
 | 
						|
VAx - 14-bit VRAM address that the VDP wants to access
 | 
						|
 | 
						|
In 4K mode the most significant bit of the DRAM row and column contains the 
 | 
						|
high-order address bits (VA12/VA13). Normally you'd think these bits would 
 | 
						|
be forced to zero, thereby limiting VRAM to 4K and making it appear mirrored 
 | 
						|
throughout the rest of the 16K space.
 | 
						|
 | 
						|
This has to do with how the cells in a DRAM chip are arranged, they are in a 
 | 
						|
64x64 array for 4Kx1, and 128x64 or 128x128 for 8Kx1 or 16Kx1. The 4K/16K 
 | 
						|
select bit determines the 'width', meaning how many bits are allocated for 
 | 
						|
the row and column addresses. (mainly 64 versus 128)
 | 
						|
 | 
						|
I had tested and determined these results from a TMS9929A in an old Sega 
 | 
						|
personal computer, which used eight 16Kx1 chips for 16K of VRAM. I'm fairly 
 | 
						|
sure it also applies to the TMS9918 and TMS9928 as well.
 | 
						|
 | 
						|
 | 
						|
2.2) Register access
 | 
						|
 | 
						|
The status register can only be read; the control registers can't be read so 
 | 
						|
they can only can be written.
 | 
						|
 | 
						|
By reading port #1, you get the value of the status register. After reading
 | 
						|
it, bit 7 (INT bit) and bit 5 (C bit) are reset.
 | 
						|
 | 
						|
By writing to port #1, a control register is set. Two bytes must be written
 | 
						|
to port #1:
 | 
						|
 | 
						|
		7	6	5	4	3	2	1	0
 | 
						|
Byte #0		V7	V6	V5	V4	V3	V2	V1	V0
 | 
						|
Byte #1		1	?	?	?	?	R2	R1	R0
 | 
						|
 | 
						|
The V* bits make up the value written to the register, which is specified
 | 
						|
with the R* bits. Bits 6-3 of the second byte are "don't care": it doesn't
 | 
						|
matter what value you set them. Officially, they must be 0. It is best to
 | 
						|
set them to 0. The upwards TMS9918A compatible V9938 and V9958 have more 
 | 
						|
registers and so these bits do have meaning. So, for compatibility, set them 
 | 
						|
to 0. Bit 7 must be set, to indicate you want to write to a register; otherwise
 | 
						|
you're changing the r/w address.
 | 
						|
 | 
						|
 | 
						|
2.3) I/O Ports quirks
 | 
						|
 | 
						|
As you've probably noticed, writes to port #1 must always go in pairs of two
 | 
						|
bytes. Suppose you would write one byte to port #1, and let normal programming
 | 
						|
continue .. you'd assume that the byte order of any port #1 write is wrong and 
 | 
						|
strange things happen. But that isn't true.
 | 
						|
 | 
						|
What happens internally is this. After writing the first byte to port #1, a 
 | 
						|
flag is set to indicate that the next byte written to port #1 is the second of 
 | 
						|
the pair and completes the register write or r/w address set. This flag is 
 | 
						|
reset after that.
 | 
						|
 | 
						|
But this flag is also reset whenever you read port #1, or read or write port
 | 
						|
#0. This probably done to prevent an accidental single write to port #1 mess up
 | 
						|
the whole programming (which without this setup, would require a hard reset or 
 | 
						|
another write to port #1 to return to normal operation).
 | 
						|
 | 
						|
So, in between writing two bytes to port #1, never access any other port of the
 | 
						|
VDP. This is why interrupts must be disabled during writing to port #1: the 
 | 
						|
interrupt service routine most likely accesses the VDP (status register read 
 | 
						|
for example) and that will mess it up.
 | 
						|
 | 
						|
 | 
						|
2.4) Interrupts
 | 
						|
 | 
						|
The VDP can generate interrupts for the CPU. It works as follows: at the end
 | 
						|
of the last line of the screen (after vertical line 192, last of the drawable 
 | 
						|
screen; at the beginning of the bottom part of the backdrop) bit 7 of status 
 | 
						|
register is set. 
 | 
						|
 | 
						|
If bit 7 of the status register is set (INT), and bit 5 of control register #1
 | 
						|
is set (GINT), the INT output line is low (requesting an interrupt), otherwise
 | 
						|
it is high (not requesting an interrupt).
 | 
						|
 | 
						|
So if bit 5 of control register #1 is reset, interrupts are never requested.
 | 
						|
 | 
						|
After the status register is read, bit 7 is reset. The INT line goes high
 | 
						|
again, so it isn't requesting an interrupt anymore. That's why this register
 | 
						|
must always be read in an interrupt routine: otherwise the INT is remains low
 | 
						|
and the interrupt service routine is called again and again.
 | 
						|
 | 
						|
Another interesting fact is this: if bit 5 of control register #1 is reset,
 | 
						|
and you set it while bit 7 of the status register is set, the INT line goes
 | 
						|
low immediately and an interrupt is requested. This is important for emulators
 | 
						|
too: if this isn't emulated properly, the MSX game Track & Field 1 and 2 slows
 | 
						|
down considerably.
 | 
						|
 | 
						|
 | 
						|
3) Screen modes
 | 
						|
---------------
 | 
						|
 | 
						|
There are 4 official screen modes but 3 mode bits (8 possibilities). The
 | 
						|
modes define how the screen is built up. In some modes, the sprite subsystem
 | 
						|
is active which is described in section 4).
 | 
						|
 | 
						|
All screen modes are character based.
 | 
						|
 | 
						|
Screen mode x simply means the respective Mx bits are set. Mode 0 indicates
 | 
						|
none of the M* bits are set.
 | 
						|
 | 
						|
 | 
						|
3.1) Mode 0 
 | 
						|
 | 
						|
This screen mode is known as SCREEN 1 in MSX BASIC, and GRAPHIC 1 in the
 | 
						|
V9938 Technical Data Book.
 | 
						|
 | 
						|
Like most screen modes, it has width 32 characters and 24 characters vertical.
 | 
						|
The sprite subsystem is active.
 | 
						|
 | 
						|
Since the size is 32 x 24, the Pattern Name Table (PN) has 32 x 24 = 768 
 | 
						|
elements, which are bytes referring to the Pattern Generator Table (PG) and 
 | 
						|
Colour Table (CT). 
 | 
						|
 | 
						|
The first character is the top-left one, the second the one to the right of
 | 
						|
it. Character no. 32 the first character of the second row.
 | 
						|
 | 
						|
Each character is 8 x 8. The character number refers to an character pattern in
 | 
						|
the PG, which has 256 characters patterns. Each pattern is 8 bytes, so the
 | 
						|
entire PG is 256 x 8 = 2048 bytes. Each byte is a pixel line of the character 
 | 
						|
(top first). If a bit is set, the foreground colour in the CT is shown, 
 | 
						|
otherwise the background colour in the CT.
 | 
						|
 | 
						|
The CT sets the colour of the character. Each byte in the CT sets the colour 
 | 
						|
of 8 complete characters, so the CT is 32 bytes. The high four bits set the
 | 
						|
foreground colour, the low the background colour. If either of these is 0,
 | 
						|
it is transparent and the colour of the backdrop (BD) is used. To calculate
 | 
						|
the element in the CT, divide the character number in PN by 8.
 | 
						|
 | 
						|
The TC in control register #7 is not used in this mode.
 | 
						|
 | 
						|
 | 
						|
3.2) Mode 1
 | 
						|
 | 
						|
This mode is known as SCREEN 0 in MSX BASIC, and as TEXT 1 in the V9938 
 | 
						|
Technical Data Book.
 | 
						|
 | 
						|
In this mode, the screen has width 40 characters and 24 characters vertical. 
 | 
						|
Only two colours are used, TC and BD from control register #7. Since the 
 | 
						|
characters are 6 pixels wide, the width is 40 x 6 = 240. There is a 8 pixels
 | 
						|
border at the left and right side of the screen (with the colour of the back 
 | 
						|
drop). The sprite subsystem is inactive.
 | 
						|
 | 
						|
Since the size is 40 x 24, the Pattern Name Table (PN) has 40 x 24 = 960 
 | 
						|
elements, which are bytes refering to the Pattern Generator Table (PG). The
 | 
						|
Colour Table (CT) is not used.
 | 
						|
 | 
						|
The first character is the top-left one, the second the one to the right of
 | 
						|
it. Character no. 40 the first character of the second row.
 | 
						|
 | 
						|
Each character is 6 x 8 pixels. The character number refers to a character 
 | 
						|
pattern in the PG, which has 256 characters patterns. Each pattern is 8 bytes, 
 | 
						|
so the entire PG is 256 x 8 = 2048 bytes. Each byte is a pixel line of the 
 | 
						|
character (top first). If a bit is set, the TC in control register #7 is shown,
 | 
						|
otherwise BD in the same register. The two highest bits of each byte in the PG
 | 
						|
are ignored.
 | 
						|
 | 
						|
 | 
						|
3.3) Mode 2
 | 
						|
 | 
						|
This mode is known as SCREEN 2 in MSX BASIC, and as GRAPHIC 2 in the V9938 
 | 
						|
Data Book. It is the most complex and has the most possibilities of all the 
 | 
						|
modes of the TMS9918A.
 | 
						|
 | 
						|
Like most screen modes, it has width 32 characters and 24 characters vertical.
 | 
						|
The sprite subsystem is active.
 | 
						|
 | 
						|
Since the size is 32 x 24, the Pattern Name Table (PN) has 32 x 24 = 768 
 | 
						|
elements, which are bytes refering to the Pattern Generator Table (PG) and 
 | 
						|
Colour Table (CT). 
 | 
						|
 | 
						|
The first character is the top-left one, the second the one to the right of
 | 
						|
it. Character no. 32 the first character of the second row. There are three
 | 
						|
colour and three pattern tables. The character number is as follows:
 | 
						|
 | 
						|
The first 8 rows: byte from PN + 000h
 | 
						|
The middle 8 rows: byte from PN + 100h
 | 
						|
The bottom 8 rows: byte from PN + 200h
 | 
						|
 | 
						|
Each character is 8 x 8. The character number refers to an character pattern 
 | 
						|
in the PG, which has 768 characters patterns (three distinct tables). For the 
 | 
						|
first 8 rows of the screen, the first 256 entries are used. For the second 8 
 | 
						|
rows, the second 256 patterns, and for the last 8 rows the third 256 patterns 
 | 
						|
(depending on the value of control register #4, see below). So the entire PG is
 | 
						|
3 x 256 x 8 = 6144 bytes. Each byte is a pixel line of the character (top 
 | 
						|
first). If a bit is set, the foreground colour in the CT is used, otherwise 
 | 
						|
the background colour in the CT.
 | 
						|
 | 
						|
Control register #4 which sets the PG address of the PG has a different 
 | 
						|
function in mode 2. Only bit 2, PG13, sets the address of the PG (so it's either
 | 
						|
address 0 or 2000h). Bits 0 and 1 are an AND mask over the character number. 
 | 
						|
The character number is 0 - 767 (2FFh) and these two bits are ANDed over the 
 | 
						|
two highest bits of this value (2FFh is 10 bits, so over bit 8 and 9). So in 
 | 
						|
effect, if bit 0 of control register #4 is set, the second array of 256 
 | 
						|
patterns in the PG is used for the middle 8 rows of characters, otherwise the 
 | 
						|
first 256 patterns. If bit 1 is set, the third array of patterns is used in 
 | 
						|
the PG, otherwise the first.
 | 
						|
 | 
						|
The relation PN -> CT is the same as PN -> GT. Each byte in the CT sets the
 | 
						|
colour of one pixel line of a character.  The high four bits set the foreground 
 | 
						|
colour, the low the background colour. If either of these is 0, it is 
 | 
						|
transparent and the colour of the backdrop (BD) is used. 
 | 
						|
 | 
						|
Also control register #3 has a different meaning. Only bit 7 (CT13) sets the CT
 | 
						|
address. Somewhat like control register #4 for the PG, bits 6 - 0 are an AND
 | 
						|
mask over the top 7 bits of the character number.
 | 
						|
 | 
						|
The TC in control register #7 is not used in this mode.
 | 
						|
 | 
						|
 | 
						|
3.4) Mode 3
 | 
						|
 | 
						|
This mode is known as SCREEN 3 in MSX-BASIC, and as MULTICOLOR in the V9938
 | 
						|
Technical Data Book. In this mode, each `unit' on the screen is 4 x 4 pixels. 
 | 
						|
In these units all the pixels have the same colour. Unlike all the other modes
 | 
						|
there is no colour spill (each pixel can have any colour). The sprite subsystem 
 | 
						|
is active.
 | 
						|
 | 
						|
The characters are 8 x 8 pixels. There are 32 x 24 characters on the screen,
 | 
						|
so the pattern name table (PN) has 768 elements (bytes) which refer to a 
 | 
						|
pattern in the pattern generator table (PG). Only two bytes of the 8 bytes in
 | 
						|
the pattern are used. Which two bytes depends on the vertical row (0 - 23).
 | 
						|
The address in the PG can be calculated as follows:
 | 
						|
 | 
						|
	PG + (byte in PN) x 8 + (row AND 3) x 2
 | 
						|
 | 
						|
Each character is 4 units. Each byte sets the color of two blocks of 4 x 4 
 | 
						|
pixels. The lower four bits set the colour of the left block, the highest four 
 | 
						|
bits set the colour of the right block. If either is 0, the block is transparent
 | 
						|
and the backdrop (BD) is visible. 
 | 
						|
 | 
						|
The TC in control register #7 is not used in this mode, neither is the colour
 | 
						|
table (CT).
 | 
						|
 | 
						|
 | 
						|
3.5) Undocumented Mode 1 + 2
 | 
						|
 | 
						|
This mode is very much like Mode 1; the difference is that there can be three
 | 
						|
different pattern tables, and control register #4 has a different meaning.
 | 
						|
 | 
						|
The pattern table now has 3 x 256 patterns; the screen is divided in three
 | 
						|
parts (the top 8 character rows, the middle 8, the bottom 8). Each part can
 | 
						|
use a different part of the pattern generator table (the first 256, the second 
 | 
						|
256, the last 256). The top part always uses the first 256 patterns in the PG.
 | 
						|
 | 
						|
Control register #4:
 | 
						|
 bit 7 - 3 : ignored
 | 
						|
 bit 2     : PG13; if set, PG = 2000h otherwise 0
 | 
						|
 bit 1 	   : if set, the last 8 rows use the 3rd pattern table otherwise 1st.
 | 
						|
 bit 0     : if set, the middle 8 rows use the 2nd pattern table otherwise 1st.
 | 
						|
 | 
						|
This undocumented mode is not available in the V9938 as far as I know.
 | 
						|
 | 
						|
 | 
						|
3.6) Undocumented Mode 2 + 3
 | 
						|
 | 
						|
This mode is very much like Mode 3; it differs in the same way that 
 | 
						|
undocumented mode 1 + 2 differs from mode 1. See section above for details.
 | 
						|
 | 
						|
 | 
						|
3.7) Other (Mode 1+3 and Mode 1+2+3)
 | 
						|
 | 
						|
There are two undocumented modes left: 1+3 and 1+2+3. Something weird happens
 | 
						|
in both modes: no longer do the tables have any influence on how the screen 
 | 
						|
looks like. The screen simply shows 40 vertical lines of text colour (TC). By 
 | 
						|
the looks of it, it's 4 pixels TC, 2 pixels BD. Like in mode 1, there is a 8 
 | 
						|
pixel border with colour backdrop (BD) at the left and right of the screen.
 | 
						|
It seems possible that memory refresh isn't done any more, but Tursi 
 | 
						|
<tursi@yiffco.com> tested this, and memory was still intact after a couple
 | 
						|
of frames.
 | 
						|
 | 
						|
The sprite subsystem is inactive.
 | 
						|
 | 
						|
 | 
						|
4) Sprite system
 | 
						|
----------------
 | 
						|
 | 
						|
In all modes except when M1 is set or BL is reset, the sprite subsystem is 
 | 
						|
active. Sprites can be either 8 x 8 pixels, or 16 x 16; also these pixels can 
 | 
						|
be enlarged (twice the size; "zoomed").
 | 
						|
 | 
						|
 | 
						|
4.1) Sprite attribute table
 | 
						|
 | 
						|
32 different sprites can be display at the same time on the same screen, with
 | 
						|
the exception that no more than 4 four sprites can be displayed on one 
 | 
						|
horizontal pixel line. The location and colour of the sprites is specified in 
 | 
						|
the sprite attribute table (SA). For each of the 32 sprites, there are four 
 | 
						|
bytes.
 | 
						|
 | 
						|
SA ->	0	Y sprite 0
 | 
						|
	1	X sprite 0
 | 
						|
	2	sprite pattern 0
 | 
						|
	3	colour sprite 0 + EC
 | 
						|
	4	Y sprite 1
 | 
						|
	5	X sprite 1
 | 
						|
	6	sprite pattern 1
 | 
						|
	7	colour sprite 1 + EC
 | 
						|
	.
 | 
						|
	.
 | 
						|
 | 
						|
The values have special meanings. If the Y coordinate is 0, it's displayed on
 | 
						|
the second pixel line from the top. With value 255 it's exactly on the the top
 | 
						|
line, and with coordinate 254 the top line isn't visible any more, with 253 to
 | 
						|
two top lines aren't visible any more, etc.
 | 
						|
 | 
						|
If Y is 208, that sprite and all following sprites in the table are not 
 | 
						|
displayed.
 | 
						|
 | 
						|
The X coordinate is simply, as you would expect, the X coordinate from 0 to 
 | 
						|
255. If bit 7 of the ``colour sprite'' is set (Early Clock -- EC), the sprite
 | 
						|
is moved 32 pixels to the left; in this way it's possible to partially display
 | 
						|
the sprite at the left side.
 | 
						|
 | 
						|
The lower 4 bits of ``colour sprite'' define the colour. Bit 7 is the EC.
 | 
						|
Bits 6 - 4 should be zero officially, but they are ignored. If the colour is 
 | 
						|
0, the sprite is transparent (not visible).
 | 
						|
 | 
						|
 | 
						|
4.2) Sprite generator & sizes
 | 
						|
 | 
						|
These options are in the control register #1. If bit 0 (MAG) is set, the 
 | 
						|
sprites are enlarged. If bit 1 (SI) is set, the sprites are 16 x 16 in size,
 | 
						|
otherwise 8 x 8.
 | 
						|
 | 
						|
The sprite pattern defines which pattern to use. In the case of 8 x 8 sprites,
 | 
						|
there are 8 bytes for the sprite pattern, and there are 256 patterns in the
 | 
						|
sprite generator table (SG). So simply multiply the sprite pattern by 8 to 
 | 
						|
get the address in the SG. Each of these bytes set the colour of the pixels
 | 
						|
of the sprite. If a bit is set, the pixel has the colour of the ``colour
 | 
						|
sprite'' -- unless it is 0, in which case it is transparent.
 | 
						|
 | 
						|
In the case of 16 x 16, it is slightly more complex. The SG is still 256 x 8
 | 
						|
bytes, and each pattern is 32 bytes now. To calculate the address in the
 | 
						|
SG: ((pattern number) AND 252) x 8. The first 16 bytes set the colour of the
 | 
						|
left 8 pixels of the sprite, the next 16 bytes set the colour of the right
 | 
						|
16 pixels of the sprite. If it is 0, it is transparent.
 | 
						|
 | 
						|
If bit 0 of control register 1 (MAG) is set, the sprites are enlarged. The
 | 
						|
starting coordinates are the same, but every pixel of the sprite is 2 x 2 
 | 
						|
real pixels. 
 | 
						|
 | 
						|
 | 
						|
4.3) Illegal sprites & sprite collision
 | 
						|
 | 
						|
On each horizontal pixel line, only 4 sprites are allowed. Any more than that 
 | 
						|
are not displayed. These sprites that aren't displayed are known as ``illegal
 | 
						|
sprites''. The first sprite illegal sprite that is detected is put in the
 | 
						|
status register. Bit 6 (5S) is set, to show an illegal sprite is detected. The
 | 
						|
sprite number (SA element number) is stored in the FS* bits. Note that even 
 | 
						|
transparent (colour 0) sprites count for illegal sprites, and sprites that 
 | 
						|
aren't displayed because they're of the left or right side of the screen.
 | 
						|
 | 
						|
If no illegal sprite was found, 5S won't be set and FS* contains the highest
 | 
						|
sprite number in the SA, either the last (31) or the first with Y coordinate
 | 
						|
208 (if it exists). Note that isn't fully checked (but probably not really
 | 
						|
important).
 | 
						|
 | 
						|
Remember the screen is built line by line from top to bottom; the first illegal
 | 
						|
sprite is on the highest pixel line with an illegal sprite.
 | 
						|
 | 
						|
If anywhere on the screen two or more sprites overlap, the C bit of the status
 | 
						|
register is set. The colour of the sprite is not important (can even be 0), the 
 | 
						|
pattern is. If a sprite line is not displayed because it is illegal, it does 
 | 
						|
not count for sprite collision. The C bit of the status register is reset
 | 
						|
after the register is read.
 | 
						|
 | 
						|
 | 
						|
5) Hardware
 | 
						|
-----------
 | 
						|
 | 
						|
5.1) Pin-outs
 | 
						|
 | 
						|
		    TMS9918A
 | 
						|
 | 
						|
		+--------------+
 | 
						|
	   _RAS | 1	    40 | XLAT2 
 | 
						|
	   _CAS | 2	    39 | XLAT1
 | 
						|
	    AD7 | 3	    38 | CPUCLK
 | 
						|
	    AD6 | 4	    37 | GROMCLK
 | 
						|
	    AD5 | 5	    36 | COMVID
 | 
						|
	    AD4 | 6	    35 | EXTVDP
 | 
						|
	    AD3 | 7	    34 | _RESET / SYNC
 | 
						|
	    AD2	| 8	    33 | Vcc
 | 
						|
	    AD1 | 9	    32 | RD0
 | 
						|
	    AD0 | 10	    31 | RD1
 | 
						|
	   R/_W | 11	    30 | RD2
 | 
						|
	    Vss | 12	    29 | RD3
 | 
						|
	   MODE | 13	    28 | RD4
 | 
						|
	   _CSW | 14	    27 | RD5
 | 
						|
	   _CSR | 15	    26 | RD6
 | 
						|
	   _INT | 16	    25 | RD7
 | 
						|
	    CD7 | 17	    24 | CD0
 | 
						|
	    CD6 | 18	    23 | CD1
 | 
						|
	    CD5 | 19	    22 | CD2
 | 
						|
	    CD4	| 20	    21 | CD3
 | 
						|
		+--------------+
 | 
						|
 | 
						|
 | 
						|
		    TMS9928A
 | 
						|
 | 
						|
		+--------------+
 | 
						|
	   _RAS | 1	    40 | XLAT2 
 | 
						|
	   _CAS | 2	    39 | XLAT1
 | 
						|
	    AD7 | 3	    38 | R-Y
 | 
						|
	    AD6 | 4	    37 | GROMCLK
 | 
						|
	    AD5 | 5	    36 | Y
 | 
						|
	    AD4 | 6	    35 | B-Y
 | 
						|
	    AD3 | 7	    34 | _RESET / SYNC
 | 
						|
	    AD2	| 8	    33 | Vcc
 | 
						|
	    AD1 | 9	    32 | RD0
 | 
						|
	    AD0 | 10	    31 | RD1
 | 
						|
	   R/_W | 11	    30 | RD2
 | 
						|
	    Vss | 12	    29 | RD3
 | 
						|
	   MODE | 13	    28 | RD4
 | 
						|
	   _CSW | 14	    27 | RD5
 | 
						|
	   _CSR | 15	    26 | RD6
 | 
						|
	   _INT | 16	    25 | RD7
 | 
						|
	    CD7 | 17	    24 | CD0
 | 
						|
	    CD6 | 18	    23 | CD1
 | 
						|
	    CD5 | 19	    22 | CD2
 | 
						|
	    CD4	| 20	    21 | CD3
 | 
						|
		+--------------+
 | 
						|
 | 
						|
 | 
						|
6) To-do
 | 
						|
 | 
						|
There are some things still need finding out.
 | 
						|
 | 
						|
 o How to emulate by scanline: what are the exact timings, when are the
 | 
						|
   different tables read.
 | 
						|
 
 | 
						|
 o What are the colours in PAL mode.
 | 
						|
 | 
						|
 | 
						|
7) References
 | 
						|
-------------
 | 
						|
 | 
						|
MSX Handboek voor gevorderden
 | 
						|
	A Dutch MSX1 technical manual. It's full of mistakes but very complete.
 | 
						|
 | 
						|
V9938 MSX-Video Technical Data Book
 | 
						|
	The be-all, end-all guide to the MSX2 VDP; some things are true for the
 | 
						|
	TMS9918A VDP too.
 | 
						|
 | 
						|
http://www.msxnet.org/tech/tmsposting.txt
 | 
						|
	A posting by Paul Urbanus (urb@onramp.net) in comp.emulators.misc.
 | 
						|
	Very interesting stuff about timings and the one r/w address.
 | 
						|
 | 
						|
http://home.swipnet.se/~w-16418/tech_vdp.htm
 | 
						|
	This is an expanded version of my original tms9918a document. It's more 
 | 
						|
	complete than my old version, but this document should be better. :-)
 | 
						|
 | 
						|
http://www.mess.org/
 | 
						|
	The MESS emulator, includes a TMS9928A emulator nearly all 
 | 
						|
	undocumented features described here are emulated.
 | 
						|
 | 
						|
http://www.spies.com/~arcade/dataSheets/ti/TMS9918.pdf
 | 
						|
	TMS9918 Data Book
 |