<
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>