<
meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
The MSX Red Book Revised - P.P.I.
code {color: #0000C0}
pre {color: #FF0000}
<
br><
a name="VDP"><
/a><
h2 align="Center">
4. VIDEO DISPLAY PROCESSOR<
/h2><
br><
br>
<
p align="Justify"> The
9929 VDP contains all the circuitry necessary to
generate the video display. It appears to the Z80 as two I/O
ports called the Data Port and the Command Port. Although the
VDP has its own 16 KB of VRAM (Video RAM), the contents of which
define the screen image, this cannot be directly accessed by
the Z80. Instead it must use the two I/O ports to modify the
VRAM and to set the various VDP operating conditions.<
/p>
<
p align="Justify"> The original
version of
"The MSX Red Book"
documented the VDP ports associated to I/O addresses 98H and 99H,
which are prevalent on most machines, but it is completely deprecated
by MSX standard that foresees VDP expansions, which must use different
I/O mapping to avoid conflicts with internal VDP. The MSX-BIOS contains
two addresses that <
b>must be<
/b> read to determine where the VDP read and write
ports are mapped. These addresses are 0006H (read ports) and 0007H (write ports).
On MSX, VDP has only two ports mapped. On MSX2, MSX2+ and turbo R, VDP has six ports mapped.<
/p>
<
table cellspacing="0" cellpadding="4" border="1">
<
tr align="center"><
td>#
0<
/td><
td>read<
/td><
td>
(0006H
)<
/td><
td>
1
2
2+ tR<
/td><
td>VRAM datum read<
/td><
/tr>
<
tr align="center"><
td>#
0<
/td><
td>write<
/td><
td>
(0007H
)<
/td><
td>
1
2
2+ tR<
/td><
td>VRAM datum write<
/td><
/tr>
<
tr align="center"><
td>#
1<
/td><
td>read<
/td><
td>
(0006H
)+
1<
/td><
td>
2
2+ tR<
/td><
td>Status registers<
/td><
/tr>
<
tr align="center"><
td>#
1<
/td><
td>write<
/td><
td>
(0007H
)+
1<
/td><
td>
2
2+ tR<
/td><
td>VDP Command<
/td><
/tr>
<
tr align="center"><
td>#
2<
/td><
td>write<
/td><
td>
(0007H
)+
2<
/td><
td>
2
2+ tR<
/td><
td>Palette registers access<
/td><
/tr>
<
tr align="center"><
td>#
3<
/td><
td>write<
/td><
td>
(0007H
)+
3<
/td><
td>
2
2+ tR<
/td><
td>Sequential registers access<
/td><
/tr>
<
p align="Justify"> Usage example:<
/p>
<
table cellspacing="0" cellpadding="0" border="0">
<
tbody><
tr valign="Top"><
td><
code>ld c,
(0006H
)<
/code><
/td><
td rowspan="8"> <
/td><
td>; Load standard VDP read port
(0006H
) in register C.<
/td><
/tr>
<
tr valign="Top"><
td><
hr style="border-style:dashed"><
/td><
td><
/td><
/tr>
<
tr valign="Top"><
td><
code>ld c,
(0007H
)<
/code><
/td><
td>; Load standard VDP write port
(0007H
) in register C.<
/td><
/tr>
<
tr valign="Top"><
td><
code>out
(c
),l<
br>out
(c
),h<
/code><
/td><
td>; Write datum in HL to sequential register port.<
/td><
/tr>
<
br><
a name="VDP-Data"><
/a><
h3 align="Left">
Data Port<
/h3><
br>
<
p align="Justify"> The
Data Port, which
value is
stored in <
a href="http://www.angelfire.com/art2/unicorndreams/msx/RR-BIOS.html">BIOS<
/a> address 00006H, is used to read or write single bytes to the
VRAM. The VDP possesses an internal address register pointing
to a location in the VRAM. Reading the Data Port will input the
byte from this VRAM location, while writing to the Data Port
will store a byte there. After a read or write the address
register is automatically incremented to point to the next VRAM
location. Sequential bytes can be accessed simply by continuous
reads or writes to the
Data Port.<
/p>
<
br><
a name="VDP-Command"><
/a><
h3 align="Left">Command Port<
/h3><
br>
<
p align="Justify"> The Command Port is used
for three purposes:<
/p>
<
li><
a href="#VDP-Address">To set up the
Data Port address register.<
/a><
/li>
<
li><
a href="#ModeReg">To write to one of the VDP Mode Registers.<
/a><
/li>
<
li><
a href="#VDP-StatusReg">To read the VDP Status Registers.<
/a><
/li>
<
br><
a name="VDP-Address"><
/a><
h3 align="Left">Address Register<
/h3><
br>
<
p align="Justify"> The
Data Port address register
(VRAM pointer
) must be set up in different
ways depending on whether the subsequent access is to be a read
or a write. The address register can be set to any value from
0000H to 3FFFH by first writing the LSB (Least Significant
Byte) and then the MSB (Most Significant Byte) to the Command
Port. Bits 6 and 7 of the MSB are used by the VDP to determine
whether the address register is being set up for subsequent
reads or writes as follows:<
/p>
<
table cellspacing="16" cellpadding="0" border="0">
<
p>Figure
1: VDP Address Setup.<
/p>
<
p align="Justify"> It is important that no other accesses are made to the VDP
in between writing the LSB and the MSB as this will upset its
synchronization. The MSX ROM interrupt handler is continuously
reading the VDP Status Register as a background task so
interrupts should be disabled as necessary. It is also important
to prepare VDP for reading or writing every time the program
needs to change from one operation to the other, that is, a
program <
b>cannot<
/b> read a byte from VRAM and, without setting
VDP for writing, write a byte to the next address, or write
a byte to VRAM and, after that, read a byte them the next
address without preparing VDP
for reading.<
/p>
<
table cellspacing="0" cellpadding="0" border="0">
<
tbody><
tr valign="Top"><
td><
code>di<
/code><
/td><
td rowspan="15"> <
/td><
td>; Disable all maskable interruptions.<
/td><
/tr>
<
tr valign="Top"><
td><
code>ld c,
(0007H
)<
br>inc c<
/code><
/td><
td>; Load standard VDP command port
(0007H
)+
1 in register C.<
/td><
/tr>
<
tr valign="Top"><
td><
code>out
(c
),l<
/code><
/td><
td>; Write LSB of VRAM address in HL to VDP.<
/td><
/tr>
<
tr valign="Top"><
td><
code>out
(c
),a<
/code><
/td><
td>; Write MSB of VRAM address, preparing it to be read.<
/td><
/tr>
<
tr valign="Top"><
td><
hr style="border-style:dashed"><
/td><
td><
/td><
/tr>
<
tr valign="Top"><
td><
code>ld c,
(0007H
)<
br>inc c<
/code><
/td><
td>; Load standard VDP command port
(0007H
)+
1 in register C.<
/td><
/tr>
<
tr valign="Top"><
td><
code>out
(c
),l<
/code><
/td><
td>; Write LSB of VRAM address in HL to VDP.<
/td><
/tr>
<
tr valign="Top"><
td><
code>out
(c
),a<
/code><
/td><
td>; Write MSB of VRAM address, preparing it
for writing.<
/td><
/tr>
<
br><
a name="ModeReg"><
/a><
h3 align="Left">VDP Mode Registers<
/h3><
br>
<
p align="Justify"> The VDP has
forty-seven write-only registers, numbered 0 to 46,
which control its general operation. A particular register is
set by first writing a data byte then a register selection byte
to the Command Port. The register selection byte contains the
register number in the six lower bits: 10RRRRRR. As the Mode
Registers are write-only, and cannot be read, the MSX ROM
maintains an exact copy of the part of the registers in the Workspace
Area of RAM (Chapter 6). Using the MSX ROM standard routines
for VDP functions ensures that those registers images are correctly
<
table cellspacing="16" cellpadding="0" border="0">
<
tr align="Center"><
td>Set up register:<
/td><
td>xxxxxxxx<
/td><
td>10xxxxxx<
/td><
/tr>
<
p>Figure
2: VDP Address Setup.<
/p>
<
br><
a name="ModeReg0"><
/a><
h4 align="Left">Mode Register
0<
/h4><
br>
<
table style="border-collapse: collapse" width="75%" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
td style="border: 1px solid">
0<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-DG'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">DG<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-IE2'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'" bgcolor="#FFFFFF">IE2<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-IE1'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'" bgcolor="#FFFFFF">IE1<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-M5'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">M5<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-M4'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">M4<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-M3'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">M3<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg0-EV'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">EV<
/td>
<
a name="ModeReg0-EV"><
/a><
p align="Justify"> The <
b>External VDP<
/b>
(EV
) bit determines whether external VDP input is to be enabled or
disabled:
0=Disabled,
1=Enabled.<
/p>
<
a name="ModeReg0-M3"><
/a><
a href="#ModeReg0-M4"><
/a><
a href="#ModeReg0-M5"><
/a>
<
p align="Justify"> The <
b>M3<
/b>, <
b>M4<
/b> and <
b>M5<
/b>
bits are three of the five <
a href="#VDP-ScreenMode">VDP mode Selection<
/a> bits
that define the VDP display mode.<
/p>
<
a name="ModeReg0-IE1"><
/a><
p align="Justify"> The <
b>Interruption Enable
1<
/b>
(IE1
) bit,
when set to "1", enables the line interruption, of which line number is defined by
<
a href="#ModeReg19">Mode Register
19<
/a>. When the display raster reaches the defined line,
an interruption is sent to the CPU. The <
a href="#VDP-StatusReg0-F">Status Register
0 Frame Flag<
/a> should be
read to check if the interruption was not an end-of-
frame interruption.<
/p>
<
a name="ModeReg0-IE2"><
/a><
p align="Justify"> The <
b>Interruption Enable
2<
/b>
(IE2
) bit,
when set to "1", enables light-pen interruption. When the display raster reaches the light-pen sensor position on
screen, an interruption is sent to the system. The <
a href="#VDP-StatusReg0-F">Status Register
0 Frame Flag<
/a> should be
read to check if the interruption was not an end-of-
frame interruption.<
/p>
<
a name="ModeReg0-DG"><
/a><
p align="Justify"> The <
b>Digitizer<
/b>
(DG
) bit,
when set to
"1", enables the colour bus input mode, capturing
data into the VRAM.<
/p>
<
br><
a name="ModeReg1"><
/a><
h4 align="Left">Mode Register
1<
/h4><
br>
<
table style="border-collapse: collapse" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-4-16K'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">
4/16K<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-Blank'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Blank<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-IE'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">IE<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-M1'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">M1<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-M2'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">M2<
/td>
<
td style="border: 1px solid">
0<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-Size'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Size<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg1-Mag'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Mag<
/td><
/tr>
<
p>Figure
4: VDP Mode Register
1.<
/p>
<
a name="ModeReg1-Mag"><
/a><
p align="Justify"> The <
b>Magnification<
/b>
(Mag) bit determines whether sprites will be
normal or doubled in
size:
0=Normal,
1=Doubled.<
/p>
<
a name="ModeReg1-Size"><
/a><
p align="Justify"> The
<
b>Size<
/b> bit determines whether each sprite pattern will be
8x8 bits or 16x16 bits:
0=8x8,
1=16x16.<
/p>
<
a name="ModeReg1-M1"><
/a><
a name="ModeReg1-M2"><
/a>
<
p align="Justify"> The <
b>M1<
/b>
and <
b>M2<
/b> bits determine the <
a href="#VDP-ScreenMode">VDP
operating mode<
/a> in conjunction with the M3, M4 and M5 bits
from <
a href="#ModeReg0">Mode Register
0<
/a>.<
/p>
<
a name="ModeReg1-IE"><
/a><
p align="Justify"> The
<
b>Interrupt Enable<
/b> bit enables or disables the interrupt
output signal from the VDP:
0=Disable,
1=Enable.<
/p>
<
a name="ModeReg1-Blank"><
/a><
p align="Justify"> The
<
b>Blank<
/b> bit is used to enable or disable the entire video
display: 0=Disable, 1=Enable. When the display is blanked it
will be the same colour as the
border.<
/p>
<
a name="ModeReg1-4-16K"><
/a><
p align="Justify"> The <
b>
4/16K<
/b> bit
alters the VDP VRAM addressing characteristics to suit either 4 KB or 16 KB chips:
<
br><
a name="ModeReg2"><
/a><
h4 align="Left">Mode Register
2<
/h4><
br>
<
table style="border-collapse: collapse" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
tr align="Center"><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td colspan="4" style="border: 1px solid">Name Table Base<
/td><
/tr>
<
p align="Justify"> Mode Register
2 defines the starting address of the
Name
Table in the VDP VRAM. The four available bits only specify
positions 00BB BB00 0000 0000 of the full address so register
contents of 0FH would result in a base address of 3C00H.<
/p>
<
br><
a name="ModeReg3"><
/a><
h4 align="Left">Mode Register
3<
/h4><
br>
<
table style="border-collapse: collapse" width="75%" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
tr align="Center"><
td colspan="8" style="border: 1px solid">Colour Table Base<
/td><
/tr>
<
p align="Justify"> Mode Register
3 defines the starting address of the Colour
Table in the VDP VRAM. The eight available bits only specify
positions 00BB BBBB BB00 0000 of the full address so register
contents of FFH would result in a base address of 3FC0H. In
Graphics Mode only bit 7 is effective thus offering a base of
0000H or 2000H. Bits
0 to
6 must be
1.<
/p>
<
br><
a name="ModeReg4"><
/a><
h4 align="Left">Mode Register
4<
/h4><
br>
<
table style="border-collapse: collapse" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
tr align="Center"><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td colspan="3" style="border: 1px solid">Character Pattern<
/td><
/tr>
<
p align="Justify"> Mode Register
4 defines the starting address of the
Character Pattern Table in the VDP VRAM. The three available
bits only specify positions 00BB B000 0000 0000 of the full
address so register contents of 07H would result in a base
address of 3800H. In Graphics Mode only bit 2 is effective thus
offering a base of 0000H or 2000H. Bits
0 and
1 must be
1.<
/p>
<
br><
a name="ModeReg5"><
/a><
h4 align="Left">Mode Register
5<
/h4><
br>
<
table style="border-collapse: collapse" width="75%" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
tr align="Center"><
td style="border: 1px solid">
0<
/td><
td colspan="7" style="border: 1px solid">Sprite Attribute base<
/td><
/tr>
<
p align="Justify"> Mode Register
5 defines the starting address of the Sprite
Attribute Table in the VDP VRAM. The seven available bits only
specify positions 00BB BBBB B000 0000 of the full address so
register contents of 7FH would result in a base address of
<
br><
a name="ModeReg6"><
/a><
h4 align="Left">Mode Register
6<
/h4><
br>
<
table style="border-collapse: collapse" width="75%" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
tr align="Center"><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td colspan="3" style="border: 1px solid">Sprite Pattern<
/td><
/tr>
<
p align="Justify"> Mode Register
6 defines the starting address of the Sprite
Pattern Table in the VDP VRAM. The three available bits only
specify positions 00BB B000 0000 0000 of the full address so
register contents of 07H would result in a base address of
<
br><
a name="ModeReg7"><
/a><
h4 align="Left">Mode Register
7<
/h4><
br>
<
table style="border-collapse: collapse" width="75%" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
td colspan="4" style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg7-TC'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'" bgcolor="#FFFFFF">
Text Colour
1<
/td>
<
td colspan="4" style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#ModeReg7-BC'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">
Border Colour<
/td><
/tr>
<
a name="ModeReg7-BC"><
/a><
p align="Justify"> The
<
b>
Border Colour<
/b> bits determine the colour of the region
surrounding the active video area in all four VDP modes. They
also determine the colour of all 0 pixels on the screen in
40x24 Text Mode. Note that the border region actually extends
across the entire screen but will only become visible in the
active area if the overlying pixel is transparent.<
/p>
<
a name="ModeReg7-TC"><
/a><
p align="Justify"> The
<
b>
Text Colour<
/b>
1 bits determine the colour of all
1 pixels
in 40x24 Text Mode. They have no effect in the other three
modes where greater flexibility is provided through the use of
the Colour Table. The VDP colour codes are:<
/p>
<
table cellspacing="8" cellpadding="0" border="0">
<
tr align="Center"><
td align="Right">
0<
/td><
td rowspan="16"> <
/td><
td bgcolor="#FFFFFF"> <
/td><
td rowspan="16"> <
/td><
td>Transparent<
/td><
/tr>
<
tr align="Center"><
td align="Right">
1<
/td><
td bgcolor="#000000"> <
/td><
td>Black<
/td><
/tr>
<
tr align="Center"><
td align="Right">
2<
/td><
td bgcolor="#20C840"> <
/td><
td>Green<
/td><
/tr>
<
tr align="Center"><
td align="Right">
3<
/td><
td bgcolor="#58D878"> <
/td><
td>Light Green<
/td><
/tr>
<
tr align="Center"><
td align="Right">
4<
/td><
td bgcolor="#5050E8"> <
/td><
td>Dark Blue<
/td><
/tr>
<
tr align="Center"><
td align="Right">
5<
/td><
td bgcolor="#7870F7"> <
/td><
td>Light Blue<
/td><
/tr>
<
tr align="Center"><
td align="Right">
6<
/td><
td bgcolor="#D05048"> <
/td><
td>Dark Red<
/td><
/tr>
<
tr align="Center"><
td align="Right">
7<
/td><
td bgcolor="#40E8F0"> <
/td><
td>Cyan<
/td><
/tr>
<
tr align="Center"><
td align="Right">
8<
/td><
td bgcolor="#F75050"> <
/td><
td>Red<
/td><
/tr>
<
tr align="Center"><
td align="Right">
9<
/td><
td bgcolor="#F77878"> <
/td><
td>Bright Red<
/td><
/tr>
<
tr align="Center"><
td align="Right">
10<
/td><
td bgcolor="#D0C050"> <
/td><
td>Yellow<
/td><
/tr>
<
tr align="Center"><
td align="Right">
11<
/td><
td bgcolor="#E0C880"> <
/td><
td>Light Yellow<
/td><
/tr>
<
tr align="Center"><
td align="Right">
12<
/td><
td bgcolor="#20B038"> <
/td><
td>Dark Green<
/td><
/tr>
<
tr align="Center"><
td align="Right">
13<
/td><
td bgcolor="#C858B8"> <
/td><
td>Purple<
/td><
/tr>
<
tr align="Center"><
td align="Right">
14<
/td><
td bgcolor="#C8C8C8"> <
/td><
td>Gray<
/td><
/tr>
<
tr align="Center"><
td align="Right">
15<
/td><
td bgcolor="#F7F7F7"> <
/td><
td>White<
/td><
/tr>
<
p>Figure
11: MSX default colours.<
/p>
<
table cellspacing="8" cellpadding="0" border="0">
<
tr align="Center"><
td align="Right">
0<
/td><
td rowspan="16"> <
/td><
td bgcolor="#FFFFFF"> <
/td><
td rowspan="16"> <
/td><
td>Transparent<
/td><
/tr>
<
tr align="Center"><
td align="Right">
1<
/td><
td bgcolor="#060653"> <
/td><
td>Dark Blue<
/td><
/tr>
<
tr align="Center"><
td align="Right">
2<
/td><
td bgcolor="#6A0606"> <
/td><
td>Dark Red<
/td><
/tr>
<
tr align="Center"><
td align="Right">
3<
/td><
td bgcolor="#6A0653"> <
/td><
td>Dark Purple<
/td><
/tr>
<
tr align="Center"><
td align="Right">
4<
/td><
td bgcolor="#066A06"> <
/td><
td>Dark Green<
/td><
/tr>
<
tr align="Center"><
td align="Right">
5<
/td><
td bgcolor="#066A53"> <
/td><
td>Dark Cyan<
/td><
/tr>
<
tr align="Center"><
td align="Right">
6<
/td><
td bgcolor="#6A6A06"> <
/td><
td>Dark Yellow<
/td><
/tr>
<
tr align="Center"><
td align="Right">
7<
/td><
td bgcolor="#6A6A53"> <
/td><
td>Gray<
/td><
/tr>
<
tr align="Center"><
td align="Right">
8<
/td><
td bgcolor="#F99053"> <
/td><
td>Orange<
/td><
/tr>
<
tr align="Center"><
td align="Right">
9<
/td><
td bgcolor="#0606F9"> <
/td><
td>Blue<
/td><
/tr>
<
tr align="Center"><
td align="Right">
10<
/td><
td bgcolor="#F90606"> <
/td><
td>Red<
/td><
/tr>
<
tr align="Center"><
td align="Right">
11<
/td><
td bgcolor="#F906F9"> <
/td><
td>Magenta<
/td><
/tr>
<
tr align="Center"><
td align="Right">
12<
/td><
td bgcolor="#06F906"> <
/td><
td>Green<
/td><
/tr>
<
tr align="Center"><
td align="Right">
13<
/td><
td bgcolor="#06F9F9"> <
/td><
td>Cyan<
/td><
/tr>
<
tr align="Center"><
td align="Right">
14<
/td><
td bgcolor="#F9F906"> <
/td><
td>Yellow<
/td><
/tr>
<
tr align="Center"><
td align="Right">
15<
/td><
td bgcolor="#F9F9F9"> <
/td><
td>White<
/td><
/tr>
<
p>Figure 11b:
(screen
8) sprite colours.<
/p>
<
br><
a name="VDP-StatusReg"><
/a><
h3 align="Left">VDP Status Registers<
/h3><
br>
<
p align="Justify"> Reading the Command Port will input the contents of the VDP
Status Registers. On MSX, there is only one status register. On MSX2, MSX2+ and turbo R, there
are ten status registers (from S0 till S9), which are selected by
<
a href="#ModeReg15">Mode Register
15<
/a>.<
/p>
<
br><
a name="VDP-StatusReg0"><
/a><
h4 align="Left">VDP Status Register
0<
/h4><
br>
<
p align="Justify"> On MSX, this is the only status register available:<
/p>
<
table style="border-collapse: collapse" width="75%" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="12.5%">
7<
/td><
td width="12.5%">
6<
/td><
td width="12.5%">
5<
/td><
td width="12.5%">
4<
/td><
td width="12.5%">
3<
/td><
td width="12.5%">
2<
/td><
td width="12.5%">
1<
/td><
td width="12.5%">
0<
/td><
/tr>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#VDP-StatusReg0-F'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">F<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#VDP-StatusReg0-5S'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">5S<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#VDP-StatusReg0-C'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">C<
/td>
<
td style="border: 1px solid; cursor:pointer; cursor:hand" colspan="5" onclick="window.location='#VDP-StatusReg0-5SFlag'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Fifth Sprite Number<
/td>
<
p>Figure
12: VDP Status Register.<
/p>
<
a name="VDP-StatusReg0-5SNum"><
/a><
p align="Justify"> The <
b>Fifth Sprite Number<
/b> bits contain the number
(0 to
31) of the sprite triggering the <
a href="#VDP-StatusReg0-5SFlag">Fifth Sprite Flag<
/a>.<
/p>
<
a name="VDP-StatusReg0-C"><
/a><
p align="Justify"> The <
b>Coincidence Flag<
/b>
(C
)
is normally "0" but is set to "1" if any
sprites have one or more overlapping pixels. Reading the Status
Register will reset this flag to a 0. Note that coincidence is
only checked as each pixel is generated during a video frame,
every 1/60 s (on a UK machine this is every 20 ms). If fast
moving sprites pass over each other between checks then no
coincidence will be flagged.<
/p>
<
a name="VDP-StatusReg0-5SFlag"><
/a><
p align="Justify"> The <
b>Fifth Sprite Flag<
/b>
(5S
)
is normally 0 but is set to 1 when
there are more than four sprites on any pixel line. On MSX2, MSX2+ and turbo R,
this flag indicates when there are more than eight sprites in line. Reading the
Status Register will reset this flag to
"0".<
/p>
<
a name="VDP-StatusReg0-F"><
/a><
p align="Justify"> The <
b>
Frame Flag<
/b>
(F
)
is normally 0 but is set to 1 at the end of
the last active line of the video frame. This will occur every
1/60 s (for UK machines with a 50 Hz frame rate this will occur
every 20 ms). Reading the Status register will reset this flag
to a 0. There is an associated output signal from the VDP which
generates Z80 interrupts at the same rate, this drives the MSX
ROM interrupt handler.<
/p>
<
br><
a name="VDP-ScreenMode"><
/a><
h3 align="Left">Screen Modes<
/h3><
br>
<
table cellspacing="0" cellpadding="4" border="0">
<
tr align="Center"><
td colspan="11"><
hr><
/td><
/tr>
<
p align="Justify"> The VDP has thirteen operating modes, each one offering a
slightly different set of capabilities. Generally speaking, as
the resolution goes up the price to be paid in VRAM size and
updating complexity also increases. In a dedicated application
these associated hardware and software costs are important
considerations. For an MSX machine they are irrelevant, it
therefore seems a pity that a greater attempt was not made to
standardize on one particular mode. The Graphics Mode is
capable of adequately performing all the functions of the other
modes with only minor reservations.<
/p>
<
p align="Justify"> An added difficulty in using the VDP arises because
insufficient allowance was made in its design for the
overscanning used by most televisions. The resulting loss of
characters at the screen edges has forced all the video-related
MSX software into being based on peculiar screen sizes. UK
machines normally use only the central thirty-seven characters
available in 40x24 Text Mode. Japanese machines, with NTSC
(National Television Standards Committee) video outputs, use the
central thirty-nine characters.<
/p>
<
p align="Justify"> The central element in the VDP, from the programmer
's point
of view, is the Name Table. This is a simple list of single-
byte character codes held in VRAM. It is 960 bytes long in
40x24 Text Mode, 768 bytes long in 32x24 Text Mode, Graphics
Mode and Multicolour Mode. Each position in the Name Table
corresponds to a particular location on the screen.</p>
<p align="Justify"> During a video frame the VDP will sequentially read every
character code from the Name Table, starting at the base. As
each character code is read the corresponding 8x8 pattern of
pixels is looked up in the Character Pattern Table and
displayed on the screen. The appearance of the screen can thus
be modified by either changing the character codes in the Name
Table or the pixel patterns in the Character Pattern Table.</p>
<p align="Justify"> Note that the VDP has no hardware cursor facility, if one is
required it must be software generated.</p>
<br><a name="VDP-ScreenMode0"></a><h4 align="Left">40x24 Text Mode</h4><br>
<p align="Justify"> The Name Table occupies 960 bytes of VRAM from 0000H to
03BFH:</p>
<a name="Figure25"></a>
<ul><table cellspacing="0" cellpadding="0" border="0">
<tbody><tr><td></td><td rowspan="27"> </td><td><tt>0 1 2 3</tt></td><td rowspan="27"> </td><td></td></tr>
<tr><td></td><td><tt>0123456789012345678901234567890123456789</tt></td><td></td></tr>
<tr><td align="Right">0000H</td><td style="border-left: 1px solid; border-right: 1px solid; border-top: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">0</td></tr>
<tr><td align="Right">0028H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">1</td></tr>
<tr><td align="Right">0050H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">2</td></tr>
<tr><td align="Right">0078H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">3</td></tr>
<tr><td align="Right">00A0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">4</td></tr>
<tr><td align="Right">00C8H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">5</td></tr>
<tr><td align="Right">00F0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">6</td></tr>
<tr><td align="Right">0118H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">7</td></tr>
<tr><td align="Right">0140H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">8</td></tr>
<tr><td align="Right">0168H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">9</td></tr>
<tr><td align="Right">0190H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">10</td></tr>
<tr><td align="Right">01B8H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">11</td></tr>
<tr><td align="Right">01E0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">12</td></tr>
<tr><td align="Right">0208H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">13</td></tr>
<tr><td align="Right">0230H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">14</td></tr>
<tr><td align="Right">0258H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">15</td></tr>
<tr><td align="Right">0280H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">16</td></tr>
<tr><td align="Right">02A8H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">17</td></tr>
<tr><td align="Right">02D0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">18</td></tr>
<tr><td align="Right">02F8H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">19</td></tr>
<tr><td align="Right">0320H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">20</td></tr>
<tr><td align="Right">0348H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">21</td></tr>
<tr><td align="Right">0370H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">22</td></tr>
<tr><td align="Right">0398H</td><td style="border-left: 1px solid; border-right: 1px solid; border-bottom: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">23</td></tr>
<tr><td></td><td><tt>0123456789012345678901234567890123456789</tt></td><td></td></tr>
<tr><td></td><td rowspan="27"> </td><td><tt>0 1 2 3</tt></td><td rowspan="27"> </td><td></td></tr></tbody></table>
<p>Figure 25: 40x24 Name Table.</p>
</ul>
<p align="Justify"> Pattern Table occupies 2 KB of VRAM from 0800H
to 0FFFH. Each eight byte block contains the pixel pattern for
a character code:</p>
<a name="Figure26"></a>
<ul><table cellspacing="0" cellpadding="0" border="0">
<tbody><tr><td bgcolor="#C0C0FF"><tt>0 0 1 0 0 0 0 0</tt></td><td rowspan="8"> </td><td align="Right">Byte 0</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>0 1 0 1 0 0 0 0</tt></td><td align="Right">Byte 1</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>1 0 0 0 1 0 0 0</tt></td><td align="Right">Byte 2</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>1 0 0 0 1 0 0 0</tt></td><td align="Right">Byte 3</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>1 1 1 1 1 0 0 0</tt></td><td align="Right">Byte 4</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>1 0 0 0 1 0 0 0</tt></td><td align="Right">Byte 5</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>1 0 0 0 1 0 0 0</tt></td><td align="Right">Byte 6</td></tr>
<tr><td bgcolor="#C0C0FF"><tt>0 0 0 0 0 0 0 0</tt></td><td align="Right">Byte 7</td></tr></tbody></table>
<p>Figure 26: Character Pattern Block (No. 65 shown = 'A').</p>
</ul>
<p align="Justify"> The first block contains the pattern for character code 0, the
second the pattern for character code 1 and so on to character
code 255. Note that only the leftmost six pixels are actually
displayed in this mode. The colours of the 0 and 1 pixels in
this mode are defined by <a href="#ModeReg7">VDP Mode Register 7</a>,
initially they are blue and white (on Japanese and European machines)
or black and white (on Brazilian machines).</p>
<br><a name="VDP-ScreenMode1"></a><h4 align="Left">32x24 Text Mode</h4><br>
<p align="Justify"> The Name Table occupies 768 bytes of VRAM from 1800H to
1AFFH. As in 40x24 Text Mode normal operation involves placing
character codes in the required position in the table. The
"VPOKE" statement may be used to attain familiarity with the
screen layout:</p>
<a name="Figure27"></a>
<ul><table cellspacing="0" cellpadding="0" border="0">
<tbody><tr><td></td><td rowspan="27"> </td><td><tt>0 1 2 3</tt></td><td rowspan="27"> </td><td></td></tr>
<tr><td></td><td><tt>01234567890123456789012345678901</tt></td><td></td></tr>
<tr><td align="Right">1800H</td><td style="border-left: 1px solid; border-right: 1px solid; border-top: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">0</td></tr>
<tr><td align="Right">1820H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">1</td></tr>
<tr><td align="Right">1840H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">2</td></tr>
<tr><td align="Right">1860H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">3</td></tr>
<tr><td align="Right">1880H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">4</td></tr>
<tr><td align="Right">18A0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">5</td></tr>
<tr><td align="Right">18C0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">6</td></tr>
<tr><td align="Right">18E0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">7</td></tr>
<tr><td align="Right">1900H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">8</td></tr>
<tr><td align="Right">1920H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">9</td></tr>
<tr><td align="Right">1940H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">10</td></tr>
<tr><td align="Right">1960H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">12</td></tr>
<tr><td align="Right">19A0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">13</td></tr>
<tr><td align="Right">19C0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">14</td></tr>
<tr><td align="Right">19E0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">15</td></tr>
<tr><td align="Right">1A00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">16</td></tr>
<tr><td align="Right">1A20H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">17</td></tr>
<tr><td align="Right">1A40H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">18</td></tr>
<tr><td align="Right">1A60H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">19</td></tr>
<tr><td align="Right">1A80H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">20</td></tr>
<tr><td align="Right">1AA0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">21</td></tr>
<tr><td align="Right">1AC0H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">22</td></tr>
<tr><td align="Right">1AE0H</td><td style="border-left: 1px solid; border-right: 1px solid; border-bottom: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">23</td></tr>
<tr><td></td><td><tt>01234567890123456789012345678901</tt></td><td></td></tr>
<tr><td></td><td><tt>0 1 2 3</tt></td><td></td></tr></tbody></table>
<p>Figure 27: 32x24 Name Table.</p>
</ul>
<p align="Justify"> The Character Pattern Table occupies 2 KB of VRAM from 0000H
to 07FFH. Its structure is the same as in 40x24 Text Mode, all
eight pixels of an 8x8 pattern are now displayed.</p>
<p align="Justify"> The border colour is defined by VDP Mode Register 7 and is
initially blue. An additional table, the Colour Table,
determines the colour of the 0 and 1 pixels. This occupies
thirty-two bytes of VRAM from 2000H to 201FH. Each entry in the
Colour Table defines the 0 and 1 pixel colours for a group of
eight character codes, the lower four bits defining the 0 pixel
colour, the upper four bits the 1 pixel colour. The first entry
in the table defines the colours for character codes 0 to 7,
the second for character codes 8 to 15 and so on for thirty-two
entries. The MSX ROM initializes all entries to the same value,
blue and white, and provides no facilities for changing
individual ones.</p>
<br><a name="VDP-ScreenMode2"></a><h4 align="Left">Graphics Mode</h4><br>
<p align="Justify"> The Name Table occupies 768 bytes of VRAM from 1800H to
1AFFH, the same as in 32x24 Text Mode. The table is initialized
with the character code sequence 0 to 255 repeated three times
and is then left untouched, in this mode it is the Character
Pattern Table which is modified during normal operation.</p>
<p align="Justify"> The Character Pattern Table occupies 6 KB of VRAM from 0000H
to 17FFH. While its structure is the same as in the text modes
it does not contain a character set but is initialized to all 0
pixels. The first 2 KB of the Character Pattern Table is
addressed by the character codes from the first third of the
Name Table, the second 2 KB by the central third of the Name
Table and the last 2 KB by the final third of the Name Table.
Because of the sequential pattern in the Name Table the entire
Character Pattern Table is read out linearly during a video
frame. Setting a point on the screen involves working out where
the corresponding bit is in the Character Pattern Table and
turning it on. For a BASIC program to convert (X,Y) coordinates
to an address see the <a href="http://www.angelfire.com/art2/unicorndreams/msx/RR-BIOS.html#MAPXYC">MAPXYC</a> standard routine in Chapter 4.</p>
<a name="Figure28"></a>
<ul><table cellspacing="0" cellpadding="0" border="0">
<tbody><tr><td></td><td rowspan="27"> </td><td><tt>0 1 2 3</tt></td><td rowspan="27"> </td><td></td></tr>
<tr><td></td><td><tt>01234567890123456789012345678901</tt></td><td></td></tr>
<tr><td align="Right">0000H</td><td style="border-left: 1px solid; border-right: 1px solid; border-top: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">0</td></tr>
<tr><td align="Right">0100H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">1</td></tr>
<tr><td align="Right">0200H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">2</td></tr>
<tr><td align="Right">0300H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">3</td></tr>
<tr><td align="Right">0400H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">4</td></tr>
<tr><td align="Right">0500H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">5</td></tr>
<tr><td align="Right">0600H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">6</td></tr>
<tr><td align="Right">0700H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">7</td></tr>
<tr><td align="Right">0800H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">8</td></tr>
<tr><td align="Right">0900H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">9</td></tr>
<tr><td align="Right">0A00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">10</td></tr>
<tr><td align="Right">0B00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">11</td></tr>
<tr><td align="Right">0C00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">12</td></tr>
<tr><td align="Right">0D00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">13</td></tr>
<tr><td align="Right">0E00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">14</td></tr>
<tr><td align="Right">0F00H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">15</td></tr>
<tr><td align="Right">1000H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">16</td></tr>
<tr><td align="Right">1100H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">17</td></tr>
<tr><td align="Right">1200H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">18</td></tr>
<tr><td align="Right">1300H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">19</td></tr>
<tr><td align="Right">1400H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">20</td></tr>
<tr><td align="Right">1500H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">21</td></tr>
<tr><td align="Right">1600H</td><td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">22</td></tr>
<tr><td align="Right">1700H</td><td style="border-left: 1px solid; border-right: 1px solid; border-bottom: 1px solid" bgcolor="#C0E0FF"><tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO</tt></td><td align="Right">23</td></tr>
<tr><td></td><td><tt>01234567890123456789012345678901</tt></td><td></td></tr>
<tr><td></td><td rowspan="27"> </td><td><tt>0 1 2 3</tt></td><td rowspan="27"> </td><td></td></tr></tbody></table>
<p>Figure 28: Graphics Character Pattern Table.</p>
</ul>
<p align="Justify"> The border colour
is defined by <a href="#ModeReg7">VDP Mode Register 7</a> and
is initially blue. The Colour Table occupies 6 KB of VRAM from
2000H to 37FFH. There is an exact byte-to-byte mapping from the
Character Pattern Table to the Colour Table but, because it
takes a whole byte to define the 0 pixel and 1 pixel colours,
there is a lower resolution for colours than for pixels. The
lower four bits of a Colour Table entry define the colour of
all the 0 pixels on the corresponding eight pixel line. The
upper four bits define the colour of the 1 pixels. The Colour
Table is initialized so that the 0 pixel colour and the 1 pixel
colour are blue for the entire table. Because both colours are
the same it will be necessary to alter one colour when a bit is
set in the Character Pattern Table.</p>
<br><a name="VDP-ScreenMode3"></a><h4 align="Left">Multicolour Mode</h4><br>
<p align="Justify"> The Name Table occupies 768 bytes of VRAM from 0800H to
0AFFH, the screen mapping is the same as in 32x24 Text Mode.
The table is initialized with the following character code
pattern:</p>
<ul><table cellspacing="8" cellpadding="0" border="0">
<tbody><tr><td align="Center">00H to 1FH</td><td>(repeated four times, from 0800H till 087FH)</td></tr>
<tr><td align="Center">20H to 3FH</td><td>(repeated four times, from 0880H till 08FFH)</td></tr>
<tr><td align="Center">40H to 5FH</td><td>(repeated four times, from 0900H till 097FH)</td></tr>
<tr><td align="Center">60H to 7FH</td><td>(repeated four times, from 0980H till 09FFH)</td></tr>
<tr><td align="Center">80H to 9FH</td><td>(repeated four times, from 0A00H till 0A7FH)</td></tr>
<tr><td align="Center">A0H to BFH</td><td>(repeated four times, from 0A80H till 0AFFH)</td></tr>
</tbody></table></ul>
<p align="Justify"> As with Graphics Mode this is just a character code "driver"
pattern, it is the Character Pattern Table which is modified
during normal operation.</p>
<p align="Justify"> The Character Pattern
table occupies 1536 bytes of VRAM from 0000H to 05FFH.
As in the other modes each character code maps
onto an eight byte block in the Character Pattern Table.
Because of the lower resolution in this mode, only two bytes of
the pattern block are actually needed to define an 8x8 pattern:</p>
<a name="Figure29"></a>
<ul><table cellspacing="32" cellpadding="0" border="0">
<tbody><tr align="Center"><td>VRAM</td><td>Byte</td><td>Screen</td></tr>
<tr valign="Top">
<td><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td style="border-top: 1px solid; border-left: 1px solid; border-right: 1px solid; padding: 8px">
<tt><font color="#FF0000">A A A A</font> <font color="#DD0000">B B B B</font><br>
<font color="#BB0000">C C C C</font> <font color="#990000">D D D D</font><br>
<font color="#00FF00">E E E E</font> <font color="#00DD00">F F F F</font><br>
<font color="#00BB00">G G G G</font> <font color="#009900">H H H H</font></tt>
<hr style="border-style:dashed">
<tt><font color="#0000FF">W W W W</font> <font color="#0000DD">X X X X</font><br>
<font color="#0000BB">Y Y Y Y</font> <font color="#000099">Z Z Z Z</font></tt></td></tr>
<tr><td style="border-left: 1px solid; border-right: 1px solid;" align="Center">.<br>.</td></tr>
<tr><td style="border-left: 1px dashed; border-right: 1px dashed;" align="Center">.<br><br></td></tr></tbody></table></td>
<td><table cellspacing="0" cellpadding="0" border="0">
<tbody><tr><td style="padding: 8px">
<tt>Byte 0<br>Byte 1<br>Byte 2<br>Byte 3</tt>
<hr style="border-style:dashed">
<tt>Byte 8<br>Byte 9</tt></td></tr>
<tr><td align="Center">.<br>.</td></tr>
<tr><td align="Center">.<br><br></td></tr></tbody></table></td>
<td><table style="border-collapse: collapse" cellspacing="0" cellpadding="2" border="0">
<tbody><tr>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#FF0000">A</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#DD0000">B</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#0000FF">W</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#0000DD">X</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px solid; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px solid; border-left: 1px dashed" width="30%"> </td>
<td style="border-top: 1px solid; border-left: 1px dashed; border-right: 1px solid" width="10%"> </td></tr>
<tr>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#BB0000">C</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#990000">D</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#0000BB">Y</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#000099">Z</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="30%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed; border-right: 1px solid" width="10%"> </td></tr>
<tr>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#00FF00">E</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#00DD00">F</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px solid; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="30%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed; border-right: 1px solid" width="10%"> </td></tr>
<tr>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#00BB00">G</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"><tt><font color="#009900">H</font></tt></td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td width="30%"> </td>
<td style="border-right: 1px solid" width="10%"> </td></tr>
<tr>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px solid; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed" width="10%"> </td>
<td width="30%"> </td>
<td style="border-right: 1px solid" width="10%"> </td></tr>
<tr>
<td style="border-top: 1px dashed; border-left: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed" width="10%"> </td>
<td width="10%"> </td>
<td style="border-right: 1px dashed" width="30%"> </td>
<td style="border-right: 1px solid" width="10%"> </td></tr>
<tr>
<td style="border-top: 1px dashed; border-left: 1px solid; border-bottom: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed; border-bottom: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed; border-bottom: 1px solid" width="10%"> </td>
<td style="border-bottom: 1px solid" width="10%"> </td>
<td style="border-bottom: 1px solid" width="10%"> </td>
<td style="border-bottom: 1px solid" width="10%"> </td>
<td style="border-top: 1px dashed; border-bottom: 1px solid" width="30%"> </td>
<td style="border-top: 1px dashed; border-left: 1px dashed; border-bottom: 1px solid; border-right: 1px solid" width="10%"> </td></tr>
</tbody></table></td>
</tr></tbody></table>
<p>Figure 29: Multicolour Pattern Block.</p>
</ul>
<p align="Justify"> As can be seen from
<a href="#Figure29">Figure 29</a>, each four bit section of the two
byte block contains a colour code and thus defines the COLOUR
of a quadrant of the 8x8 pixel pattern. So that the entire
eight bytes of the pattern block can be utilized, a given
character code will use a different two byte section depending
upon the character code's screen location (i.e., its position in
<
ul><
table cellspacing="8" cellpadding="0" border="0">
<
tr><
td>Video row
1,
5,
9,
13,
17,
21<
/td><
td>⇒<
/td><
td>Uses bytes
2 and
3<
/td><
/tr>
<
tr><
td>Video row
2,
6,
10,
14,
18,
22<
/td><
td>⇒<
/td><
td>Uses bytes
4 and
5<
/td><
/tr>
<
tr><
td>Video row
3,
7,
11,
15,
19,
23<
/td><
td>⇒<
/td><
td>Uses bytes
6 and
7<
/td><
/tr>
<
p align="Justify"> When the
Name Table is filled with the special driver sequence
of character codes shown above the Character Pattern Table will
be read out linearly during a video
frame:<
/p>
<
ul><
table cellspacing="0" cellpadding="0" border="0">
<
tbody><
tr><
td><
/td><
td rowspan="27"> <
/td><
td><
tt>
0
1
2
3<
/tt><
/td><
td rowspan="27"> <
/td><
td><
/td><
/tr>
<
tr><
td align="Right">0000H<
/td><
td style="border-left: 1px solid; border-right: 1px solid; border-top: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
0<
/td><
/tr>
<
tr><
td align="Right">0002H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
1<
/td><
/tr>
<
tr><
td align="Right">0004H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
2<
/td><
/tr>
<
tr><
td align="Right">0006H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
3<
/td><
/tr>
<
tr><
td align="Right">0100H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
4<
/td><
/tr>
<
tr><
td align="Right">0102H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
5<
/td><
/tr>
<
tr><
td align="Right">0104H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
6<
/td><
/tr>
<
tr><
td align="Right">0106H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
7<
/td><
/tr>
<
tr><
td align="Right">0200H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
8<
/td><
/tr>
<
tr><
td align="Right">0202H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
9<
/td><
/tr>
<
tr><
td align="Right">0204H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
10<
/td><
/tr>
<
tr><
td align="Right">0206H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
11<
/td><
/tr>
<
tr><
td align="Right">0300H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
12<
/td><
/tr>
<
tr><
td align="Right">0302H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
13<
/td><
/tr>
<
tr><
td align="Right">0304H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
14<
/td><
/tr>
<
tr><
td align="Right">0306H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
15<
/td><
/tr>
<
tr><
td align="Right">0400H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
16<
/td><
/tr>
<
tr><
td align="Right">0402H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
17<
/td><
/tr>
<
tr><
td align="Right">0404H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
18<
/td><
/tr>
<
tr><
td align="Right">0406H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
19<
/td><
/tr>
<
tr><
td align="Right">0500H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
20<
/td><
/tr>
<
tr><
td align="Right">0502H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
21<
/td><
/tr>
<
tr><
td align="Right">0504H<
/td><
td style="border-left: 1px solid; border-right: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
22<
/td><
/tr>
<
tr><
td align="Right">0506H<
/td><
td style="border-left: 1px solid; border-right: 1px solid; border-bottom: 1px solid" bgcolor="#C0E0FF"><
tt>OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO<
/tt><
/td><
td align="Right">
23<
/td><
/tr>
<
tr><
td><
/td><
td rowspan="27"> <
/td><
td><
tt>
0
1
2
3<
/tt><
/td><
td rowspan="27"> <
/td><
td><
/td><
/tr><
/tbody><
/table>
<
p>Figure
30: Multicolour Character Pattern Table.<
/p>
<
p align="Justify"> The
border colour is defined by VDP Mode Register
7 and is
initially blue. There is no separate Colour Table as the
colours are defined directly by the contents of the Character
Pattern Table, this is initially filled with blue.<
/p>
<
br><
a name="VDP-Sprites"><
/a><
h3 align="Left">Sprites<
/h3><
br>
<
p align="Justify"> The VDP can control thirty-two sprites in all modes except
40X24 Text Mode. Their treatment is identical in all modes and
independent of any character-orientated activity.<
/p>
<
p align="Justify"> The Sprite Attribute Table occupies
128 bytes of VRAM from
1B00H to 1B7FH. The table contains thirty-two four byte blocks,
one for each sprite. The first block controls sprite 0 (the
"top" sprite), the second controls sprite 1 and so on to sprite
31. The format of each block is as below:<
/p>
<
table style="border-collapse: collapse" cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="10%">
7<
/td><
td width="10%">
6<
/td><
td width="10%">
5<
/td><
td width="10%">
4<
/td><
td width="10%">
3<
/td><
td width="10%">
2<
/td><
td width="10%">
1<
/td><
td width="10%">
0<
/td><
td rowspan="5" width="5%"> <
/td><
td width="15%"><
/td><
/tr>
<
tr align="Center"><
td colspan="8" style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#Sprite-Vertical'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Vertical Position<
/td><
td>Byte
0<
/td><
/tr>
<
tr align="Center"><
td colspan="8" style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#Sprite-Horizontal'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Horizontal Position<
/td><
td>Byte
1<
/td><
/tr>
<
tr align="Center"><
td colspan="8" style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#Sprite-PatNum'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Pattern Number<
/td><
td>Byte
2<
/td><
/tr>
<
tr align="Center"><
td style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#Sprite-EC'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">EC<
/td>
<
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td><
td style="border: 1px solid">
0<
/td>
<
td colspan="4" style="border: 1px solid; cursor:pointer; cursor:hand" onclick="window.location='#Sprite-ColCod'" onmouseover="bgColor='#A0D0FF'" onmouseout="bgColor='#FFFFFF'">Colour Code<
/td><
td>Byte
3<
/td><
/tr>
<
p>Figure
31: Sprite Attribute Block.<
/p>
<
a name="Sprite-Vertical"><
/a><
p align="Justify"> Byte
0
specifies the <
b>vertical coordinate<
/b>
(Y
) of the top-left
pixel of the sprite. The coordinate system runs from -1 (FFH)
for the top pixel line on the screen down to 190 (BEH) for the
bottom line, that is, there is an one-line delay, so sprites
are shown one line below their defined vertical position.
Values less than -1 can be used to slide the sprite in
from the top of the screen. The exact values needed will
obviously depend upon the size of the sprite. Curiously
there has been no attempt in MSX BASIC to reconcile this
coordinate system with the normal graphics range of Y=0 to 191.
As a consequence a sprite will always be one pixel lower on the
screen than the equivalent graphic point. Note that the special
vertical coordinate value of 208 (D0H) placed in a sprite
attribute block will cause the VDP to ignore all subsequent
blocks in the Sprite Attribute Table. Effectively this means
that any lower sprites will disappear from the screen.<
/p>
<
ul><
table cellspacing="8" cellpadding="0" border="0">
<
tbody><
tr><
td><
table style="empty-cells: show" width="256px" height="192px" cellspacing="0" cellpadding="0" border="0">
<
tbody><
tr><
td style="border-left: 1px solid; border-top: 1px solid" width="32px" height="32px"><
/td><
td colspan="4" style="border-top: 1px solid"><
/td><
td style="border-top: 1px solid; border-right: 1px solid"><
/td><
/tr>
<
tr><
td style="border-left: 1px solid" height="4px"><
/td><
td width="32px" bgcolor="#00FF00"><
/td><
td width="32px" bgcolor="#FF0000"><
/td><
td bgcolor="#FF0000"><
/td><
td width="32px" bgcolor="#FF0000"><
/td><
td style="border-right: 1px solid"><
/td><
/tr>
<
tr><
td rowspan="2" style="border-left: 1px solid"><
/td><
td height="24px" bgcolor="#00FF00"><
/td><
td><
/td><
td width="32px" bgcolor="#0000FF"><
/td><
td><
/td><
td rowspan="2" style="border-right: 1px solid">
1 pixel delay<
/td><
/tr>
<
tr><
td style="border-left: 1px solid; border-bottom: 1px solid" height="124px"><
/td><
td colspan="4" style="border-bottom: 1px solid"><
/td><
td style="border-bottom: 1px solid; border-right: 1px solid"><
/td><
/tr>
<
td><
table cellspacing="0" cellpadding="0" border="0">
20 SPRITE$
(0)=STRING$
(32,
255)<
br>
30 LINE
(32,<
b>
32<
/b>
)-STEP
(15,
15),
2,BF<
br>
40 PUT SPRITE
0,
(64,<
b>
32<
/b>
),
4,
0<
br>
50 LINE
(48,<
b>
32<
/b>
)-
(160,<
b>
32<
/b>
),
8<
br>
60 GOTO 60
<
p>Figure
32: sprite
1 line delay example
(PUT SPRITE sets sprite
at vertical position 32, but it is actually shown after line
<
a name="Sprite-Horizontal"><
/a><
p align="Justify"> Byte
1
specifies the <
b>horizontal coordinate<
/b>
(X
) of the top-
left pixel of the sprite. The coordinate system runs from 0 for
the leftmost pixel to 255 (FFH) for the rightmost. As this
coordinate system provides no mechanism for sliding a sprite in
from the left a special bit in byte 3 is used for this purpose,
<
a name="Sprite-PatNum"><
/a><
p align="Justify"> Byte
2
selects one of the two hundred and fifty-six 8x8 bit
<
b>patterns<
/b> available in the Sprite Pattern Table. If the
Size bit
is set in VDP Mode Register 1, resulting in 16x16 bit patterns
occupying thirty-two bytes each, the two least significant bits
of the pattern number are ignored. Thus pattern numbers 0, 1, 2
and
3 would all select pattern number
0.<
/p>
<
a name="Sprite-ColCod"><
/a><
p align="Justify"> In Byte
3,
the four <
b>Colour Code<
/b> bits define the colour of the
1 pixels in the sprite patterns, 0 pixels are always
<
a name="Sprite-EC"><
/a><
p align="Justify"> In Byte
3,
the <
b>Early Clock<
/b> bit is normally
0 but will shift
the sprite thirty-two pixels to the left when set to 1. This is
so that sprites can slide in from the left of the screen, there
being no spare coordinates in the horizontal direction.<
/p>
<
table cellspacing="0" cellpadding="4" border="0">
<
tbody><
tr align="Center"><
td width="10%"> <
/td><
td width="10%"> <
/td><
td colspan="2" style="border-left: 2px dashed; border-top: 2px dashed; border-right: 2px dashed" width="20%" bgcolor="#FFFF00">
(X, -Y
)<
/td><
td colspan="5" width="10%"> <
/td><
td rowspan="8" width="10%"> <
/td><
/tr>
<
tr align="Center"><
td rowspan="7"> <
/td><
td style="border-left: 1px solid; border-top: 1px solid"> <
/td><
td colspan="2" style="border-top: 1px solid; border-left: 2px solid; border-bottom: 2px solid; border-right: 2px solid" bgcolor="#FFFF00"> <
/td><
td colspan="4" style="border-top: 1px solid"> <
/td><
td style="border-top: 1px solid; border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td colspan="5" rowspan="2" style="border-left: 1px solid"> <
/td><
td colspan="2" rowspan="2" style="border: 2px solid" bgcolor="#FFC0C0">
(X, Y
)<
/td><
td style="border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td style="border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td colspan="8" style="border-left: 1px solid; border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td colspan="2" style="border-left: 1px solid"> <
/td><
td colspan="2" rowspan="2" style="border: 2px solid" bgcolor="#C0FFFF">
(X-
32, Y
)<
/td><
td rowspan="2">⇐<
/td><
td rowspan="2">EC
=1<
/td><
td colspan="2" rowspan="2" style="border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td colspan="2" style="border-left: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td colspan="8" style="border-left: 1px solid; border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td rowspan="2" style="border-left: 2px dashed; border-top: 2px dashed; border-bottom: 2px dashed" bgcolor="#C0C0FF"> <
/td><
td rowspan="2" style="border-left: 1px solid; border-top: 2px solid; border-right: 2px solid; border-bottom: 2px solid" bgcolor="#C0C0FF"> <
/td><
td colspan="2">←
(X-
32, Y
)<
/td><
td colspan="2" rowspan="2"> <
/td><
td colspan="2" rowspan="2">
(X, Y
) →<
/td><
td rowspan="2" style="border-left: 2px solid; border-top: 2px solid; border-bottom: 2px solid; border-right: 1px solid" bgcolor="#C0FFC0"> <
/td><
td rowspan="2" style="border-top: 2px dashed; border-right: 2px dashed; border-bottom: 2px dashed" bgcolor="#C0FFC0"> <
/td><
/tr>
<
tr align="Center"><
td rowspan="3"> <
/td><
td colspan="8" style="border-left: 1px solid; border-right: 1px solid"> <
/td><
/tr>
<
tr align="Center"><
td colspan="4" style="border-left: 1px solid; border-bottom: 1px solid"> <
/td><
td colspan="2" style="border-left: 2px solid; border-top: 2px solid; border-right: 2px solid; border-bottom: 1px solid" bgcolor="#FFC0FF">
(X, Y
)<
/td><
td colspan="2" style="border-bottom: 1px solid; border-right: 1px solid"> <
/td><
td> <
/td><
/tr>
<
tr align="Center"><
td width="10%"> <
/td><
td width="10%"> <
/td><
td width="10%"> <
/td><
td width="10%"> <
/td><
td colspan="2" style="border-left: 2px dashed; border-bottom: 2px dashed; border-right: 2px dashed" width="20%" bgcolor="#FFC0FF"> <
/td><
td width="10%"> <
/td><
td width="10%"> <
/td><
td width="10%"> <
/td><
/tr>
<
p>Figure
33: sprite control to slide it through the screen
<
p align="Justify"> The
Sprite Pattern Table occupies 2 KB of VRAM from 3800H to
3FFFH. It contains two hundred and fifty-six 8x8 pixel
patterns, numbered from 0 to 255. If the Size bit in VDP Mode
Register 1 is 0, resulting in 8x8 sprites, then each eight byte
sprite pattern block is structured in the same way as the
character pattern block shown in <
a href="#Figure26">Figure
26<
/a>. If the
Size bit is
1, resulting in 16x16 sprites, then four eight byte blocks are
needed to define the pattern as below:<
/p>
<
table cellspacing="0" cellpadding="8" border="0">
<
/tr><
tr><
td bgcolor="#FFFFA0">
8 Bytes<
br>Block B<
/td><
/tr><
tr>
<
/tr><
tr><
td bgcolor="#A0FFA0">
8 Bytes<
br>Block C<
/td><
/tr><
tr>
<
/tr><
tr><
td bgcolor="#A0A0FF">
8 Bytes<
br>Block D<
/td><
/tr><
tr>
<
td><
table cellspacing="0" cellpadding="8" border="1">
<
p>Figure
34: 16x16 Sprite Pattern Block.<
/p>
<
p align="Center"><
a href="http://www.angelfire.com/art2/unicorndreams/msx/RR-PSG.html">Go to next chapter: P.S.G.<
/a><
/p>