VDP

The VDP in a Model 1 Mega Drive.The VRAM is visible near the bottom left, and the cartridge slot near the top.

The VDP, also known as Video Display Processor, handles all video output on the Mega Drive. The VDP is often known as the YM7101, which is derived from the Sega Master System VDP for backwards compatibility. The Master System VDP is in turn derived from the Texas Instruments TMS9918A. In all Model 1 Mega Drives, the VDP is a dedicated large chip on the main motherboard, as shown on the right, whereas on later models it is integrated into one big chip with the I/O controllers.

It has 64 KB of VRAM, which can be used to store patterns (also known as art or tiles) plane and sprite name tables, as well as horizontal scroll data. The benefit of storing name tables and H-Scroll in VRAM is that it allows the programmer to decide where this data is stored, but leaves less room for art. The VDP has 64 9-bit entries of CRAM, totalling 64 words, to store palettes. This special area of the VDP is known as CRAM, or Colour RAM.

The VDP has the capability of displaying up to 80 sprites on-screen, as well as the A and B planes, and the Window plane. The window plane can be used as a replacement for the A plane in some circumstances. It can also support 64 on-screen colours at any time, as well as scrolling the entire screen or specific parts of it horizontally and vertically. There is also multiple registers that control how the VDP is configured, which are written to the control word as 16-bit words. The TMSS in late model 1 and all model 2 and 3 consoles disables the VDP if the ASCII "SEGA" isn't written to a specific area of I/O memory.[1] See this howto article for details.

Using the VDP

VDP I/O Layout

The VDP is mapped to an area of the 68k's memory — it may wrap around after the end of defined addresses, but the behaviour of this wrapping is undefined and unemulated. Below is a map of the VDP's IO memory, starting at $C00000:

Most of the time, it is not required to use any memory addresses besides the control and data ports. Note that the data and control ports are really only a word wide, but they are mirrored. Due to the way how the 16 bit 68000 does longword accesses (write high word, increment address, write low word,) this allows for more efficient longword writes, than two word writes to the same address. The H/V counter is usually not used for any significant purposes outside of randomisation and light guns. To use the H/V counter, it must be enabled in Register 0. Followed after the H/V counter is the PSG register, which can only be accessed as a byte on the odd addresses. It can also be accessed by the Z80, so accesses between the PSG register must be coordinated if both the Z80 and 68000 are going to be accessing it. Lastly, there is a 'debug register' which was presumably used during VDP development to test various features and verify functionality. Not much is known about it, besides what is noted below.

Due to the way the Mega Drive was designed, the 64 KB of VRAM were not mapped to M68k address space, which opens up lots of more space for I/O peripherals and other devices but can create an inconvenience in programming the VDP.

VDP Registers

The VDP has 25 registers, of which 24 are programmable through commands sent to the VDP. Some registers do not seem to do anything and are not documented anywhere, most likely meaning that they are left-overs from the original Master System VDP. The last register isn't a register that is written, but is instead a read-only register that can be read back by reading the VDP control port, which exposes various information about the current state of the VDP to the program reading it.

All register values are written to the control port as a word - the first byte being the register number with its most significant bit set, and the second byte being the value.

In the tables below, any bits shown as 0 will always be 0, and any values shown as 1 will always be 1. Bits shown as 'x' don't have a defined value, and should be set to 0. Bits that may be changed to produce some result have a letter assigned to them that is explained below the table.

When a bit is set to a fixed value, such as 0 or 1, they don't appear to serve any important or noticeable purpose, or their function is unknown due to lack of documentation.

$00 - Mode Register 1

Register 00 - Mode Register 01

7

6

5

4

3

2

1

0

0

0

L

IE1

0

1

M3

DE

When L is set, the leftmost 8 pixels are blanked.

The state of the bit IE1 decides whether the VDP will generate a horizontal interrupt for every nth scanline, or not. This is a level 4 interrupt for the M68k. A 1 means it is enabled, while 0 means it is disabled.

The state of M3 allows the H/V counter to be 'latched' on to its current value. If it is set to 1, the VDP will stop modifying the counter, while when set to 0, the VDP will actively update the counter.

DE tells the VDP if the display is enabled or not. Mode Register 02 also has this flag and this one is usually 0. When set to 1, it can be used to overlay an input from the CSync pin onto the video.

$01 - Mode Register 2

When V30 is used on NTSC hardware, the picture is unstable and will roll upwards.

DE decides if the display is enabled (1) or disabled (0). This is useful to perform quick art loading.

IE0 enables the vertical blank interrupt, or VBI. This is a Level 6 interrupt to the M68k.

M1 allows DMA to be performed when set, while it disables any sort of DMA when it is not set. This bit also masks CD5 in the VDP control word if cleared.

M2 sets the vertical display mode/resolution. When set to 1, 30 cell (240 pixel) mode is enabled, which is exclusive to PAL. When set to 0, 28 cell (224 pixel) mode is enabled, which is always the case on NTSC. Enabling 30 cell mode on an NTSC Mega Drive will cause the image to roll upwards and be unstable, as well as causing vertical interrupts to happen at 30 Hz, and no vertical sync pulse to be output on the video connector.

M5 selects between Master System (Mode 4) and Mega Drive (Mode 5) video modes. Should always be set to 1 when programming Mega Drive software.

$02 - Plane A Name Table Location

Register 02 - Plane A Name Table Location

7

6

5

4

3

2

1

0

x

SA16

SA15

SA14

SA13

x

x

x

SA15-SA13 defines the upper three bits of the VRAM location of Plane A's nametable. This value is effectively the address divided by $400; however, the low three bits are ignored, so the Plane A nametable has to be located at a VRAM address that's a multiple of $2000. For example, if the Plane A nametable was to be located at $C000 in VRAM, it would be divided by $400, which results in $30, the proper value for this register.

SA16 is only valid if 128 KB mode is enabled, and allows for rebasing the Plane A nametable to the second 64 KB of VRAM.

$03 - Window Name Table Location

Register 03 - Window Name Table Location

7

6

5

4

3

2

1

0

x

WD16

WD15

WD14

WD13

WD12

WD11

x

WD15-WD11 defines the upper five bits of the VRAM location of the Window's nametable. This value is effectively the address divided by $400; however, the low bit is ignored, so the Window nametable has to be located at a VRAM address that's a multiple of $800. For example, if the Window nametable was to be located at $F000 in VRAM, it would be divided by $400, which results in $3C, the proper value for this register.

WD11 is ignored if the display resolution is 320px wide (H40), which limits the Window nametable address to multiples of $1000.

WD16 is only valid if 128 KB mode is enabled, and allows for rebasing the Plane A nametable to the second 64 KB of VRAM.

$04 - Plane B Name Table Location

Register 04 - Plane B Name Table Location

7

6

5

4

3

2

1

0

x

x

x

x

SB16

SB15

SB14

SB13

SB15-SB13 defines the upper three bits of the VRAM location of Plane B's nametable. This value is effectively the address divided by $2000, meaning that the Plane B nametable has to be located at a VRAM address that's a multiple of $2000. For example, if the Plane A nametable was to be located at $E000 in VRAM, it would be divided by $2000, which results in $07, the proper value for this register.

SB16 is only valid if 128 KB mode is enabled, and allows for rebasing the Plane B nametable to the second 64 KB of VRAM.

$05 - Sprite Table Location

Register 05 - Sprite Attribute Table Location

7

6

5

4

3

2

1

0

AT16

AT15

AT14

AT13

AT12

AT11

AT10

AT9

AT15-AT9 defines the upper seven bits of the VRAM location of the Sprite Attribute Table. This value is effectively the address divided by $200, meaning that the Sprite Attribute Table has to be located at a VRAM address that's a multiple of $200. For example, if the Sprite Attribute Table was to be located at $D800 in VRAM, it would be divided by $200, which results in $6C, the proper value for this register.

AT16 is only valid if 128 KB mode is enabled, and allows for rebasing the Sprite Attribute Table to the second 64 KB of VRAM.

Note: Due to the larger amount of possibilities for locating the sprite attribute table, it's possible to put the sprite attribute in the space between nametables.

$06 - Sprite Pattern Generator Base Address

Register 06 - Sprite Pattern Generator Base Address

7

6

5

4

3

2

1

0

x

x

AP16

x

x

x

x

x

This register is related to the 128K VRAM mode — it requires hardware modifications and compatibility with some systems is unknown.

AP16 allows for rebasing of the Sprite Pattern Generator (sprite tiles) by serving as A16 of the address for the sprite pattern data. When set, the sprite pattern address as indicated in the Sprite Attribute Table must be added to $10000 to get the proper VRAM address.[3]

$07 - Background Colour

Register 07 - Background Colour

7

6

5

4

3

2

1

0

x

x

CPT1

CPT0

COL3

COL2

COL1

COL0

CPT is the palette line from where the background color is to be retrieved from, while COL is the entry in that palette to use. Do note that the color(s) declared as the transparent color can be displayed, which allows for greater utilization of the 60 displayable colors without the need for raster effects to reload the palette mid-screen.

$08 - Unused

Register 08 - Unused in Mode 5

7

6

5

4

3

2

1

0

x

x

x

x

x

x

x

x

This register was used as the Horizontal Scroll register for the background layer on the Sega Master System (Mode 4). On the Mega Drive (Mode 5), this has been replaced by the Horizontal Scroll table, and this register is left unused. This register should not be written to.

$09 - Unused

Register 09 - Unused in Mode 5

7

6

5

4

3

2

1

0

x

x

x

x

x

x

x

x

This register was used as the Vertical Scroll register for the background layer on the Sega Master System (Mode 4). On the Mega Drive (Mode 5), this has been replaced by the VSRAM, and this register is left unused. This register should not be written to.

$0A - Horizontal Interrupt Counter

Register 10 - Horizontal Interrupt

7

6

5

4

3

2

1

0

H

H

H

H

H

H

H

H

HHHHHHHH is the value for the horizontal interrupt counter. For this to take any effect, horizontal interrupts must be enabled in register 0's IE1, and that the interrupt mask on the M68k side isn't blocking level 4 interrupts.

Note that this counter is reloaded at the top of the screen, or when a horizontal interrupt is fired, but at no other times.

$0B - Mode Register 3

Register 11 - Mode Register 3

7

6

5

4

3

2

1

0

0

0

0

0

IE2

VS

HS1

HS2

IE2 controls external interrupts that are raised by the TH pin on one of the three IO ports. This is how almost all light guns function. When the trigger is depressed, they pull TH high which causes the game's external interrupt routine to run. This is a Level 2 interrupt on the M68k side.

VS controls vertical scrolling. When set to 0, the entire screen is scrolled by one longword in VSRAM. When set to 1, every word in VSRAM vertically scrolls two cells, or tiles of art.

HS1 and HS2 both control horizontal scrolling. When set to 00, the entire screen is scrolled at once by one longword in the horizontal scroll table. Setting 01 is prohibited, and may cause undefined behaviour. When set to 10, every long scrolls 8 pixels, and when set to 11, every longword scrolls one scanline.

$0C - Mode Register 4

Sonic the Hedgehog 2's multiplayer mode uses Interlace Mode 2.

Register 12 - Mode Register 4

7

6

5

4

3

2

1

0

RS0

VSY

HSY

SPR

SHI

LSM1

LSM0

RS1

RS0 and RS1 should be set to the same value, seeing as they control the same thing. When set to 0, the VDP is using horizontal 32 tile mode. When set to 1, the VDP will use a 40 tile wide display.

SHI enables shadow/highlight mode, a special mode to allow for more colours on-screen when set.

LSM1 and LSM0 control interlace settings: 00 sets no interlace, 01 enables interlace, 10 is prohibited, and 11 interlaces at double resolution. Sonic 2 and some other games use the latter interlace mode for their dual-player split screen.

HSY appears to do something relating to the horizontal sync, which seems to freeze it.

VSY replaces the VSync signal with a pixel clock signal when set.

$0D - Horizontal Scroll Data Location

Register 13 - HScroll Data Location

7

6

5

4

3

2

1

0

x

HS16

HS15

HS14

HS13

HS12

HS11

HS10

HS15-HS10 defines the upper six bits of the VRAM location of the Horizontal Scroll Table. This value is effectively the address divided by $400, meaning that the Horizontal Scroll Table has to be located at a VRAM address that's a multiple of $400. For example, if the Horizontal Scroll Table was to be located at $DC00 in VRAM, it would be divided by $400, which results in $37, the proper value for this register.

HS16 is only valid if 128 KB mode is enabled, and allows for rebasing the Horziontal Scroll Table to the second 64 KB of VRAM.

$0E - Nametable Pattern Generator Base Address

Register 14 - Unused/Unknown

7

6

5

4

3

2

1

0

x

x

x

PB16

x

x

x

PA16

This register is related to the 128K VRAM mode — it requires hardware modifications and compatibility with some systems is unknown.

PA16: When this bit is set, pattern data of layer A is rebased to the upper memory area. This also includes the Window layer.

PB16: When this bit as well as PA16 are both set, pattern data of layer B is rebased to the upper memory area.[4]

$0F - Auto-Increment Value

Register 15 - Auto-Increment Value

7

6

5

4

3

2

1

0

INC7

INC6

INC5

INC4

INC3

INC2

INC1

INC0

INC7-INC0 sets the 8-bit value to add after a VRAM data access. This value is most often set to 2.

$10 - Plane Size

Register 16 - Plane Size

7

6

5

4

3

2

1

0

x

x

VSZ1

VSZ0

x

x

HSZ1

HSZ0

VSZ sets the vertical size of both the A and B planes.

HSZ sets the horizontal size of both the A and B planes.

Both VSZ and HSZ can be set to one of the following values:

00: 32 tiles

01: 64 tiles

10: Prohibited - this setting may cause undefined behavior.

11: 128 tiles

Note: A nametable can never exceed 8192 bytes. While a 64x64 or 128x32 name table is valid, a 128x128 or 64x128 name table is not valid. This is most likely due to a limitation of the nametable address generator in the VDP, but this size restriction can be circumvented by using tile reloading.

$11 - Window Plane Horizontal Position

Register 17 - Window Plane Horizontal Position

7

6

5

4

3

2

1

0

RGHT

x

x

WHP5

WHP4

WHP3

WHP2

WHP1

RGHT sets the direction in which to move the window plane horizontally. 0 means to the left, while 1 means to the right.

WHP5-WHP1 sets how many cells to move the window plane horizontally in the direction specified by RGHT. This is in units of two cells, so it's effectively cells/2.

Note: There is a bug that causes incorrect tiles to be fetched if RGHT=0 and the horizontal scroll offset is not a multiple of 16.

$12 - Window Plane Vertical Position

Register 18 - Window Plane Vertical Position

7

6

5

4

3

2

1

0

DOWN

x

x

WVP5

WVP4

WVP3

WVP2

WVP1

DOWN sets the direction in which to move the window plane horizontally. 0 means up, while 1 means down.

WVP5-WVP1 sets how many cells to move the window plane vertically in the direction specified by DOWN. This is in units of two cells, so it's effectively cells/2.

Note: The Window plane can not be displayed in any places that plane A is displayed, meaning that the window plane essentially takes its place in areas that they overlap in. This effect can best be seen if the window plane map has several transparent pixels. This quality makes it desirable for some games to use as a HUD.

$13 and $14 - DMA Length

Registers 19 and 20 - DMA Length

Reg.19

7

6

5

4

3

2

1

0

Reg.20

7

6

5

4

3

2

1

0

L7

L6

L5

L4

L3

L2

L1

L0

H7

H6

H5

H4

H3

H2

H1

H0

L7-L0 is the low byte of the DMA length.

H7-H0 is the high byte of the DMA length.

The VDP decrements the length before checking if it's equal to 0, which results in an integer underflow if the length is 0. In other words, if you set the DMA length to 0, it will act like you set it to $10000. This is almost always an error on the programmer's part.

$15 to $17 - DMA Source

Registers 21, 22 and 23 - DMA Source

Reg.21

7

6

5

4

3

2

1

0

Reg.22

7

6

5

4

3

2

1

0

Reg.23

7

6

5

4

3

2

1

0

L7

L6

L5

L4

L3

L2

L1

L0

M7

M6

M5

M4

M3

M2

M1

M0

DMD1

DMD0

H5

H4

H3

H2

H1

H0

L7-L0 is the low byte of the DMA source address.

M7-M0 is the middle byte of the DMA source address.

H5-H0 is the high byte of the DMA source address. If DMD1=0, DMD0 acts as H6.

DMD1-DMD0 tell the VDP what type of DMA shall be coming up:

0x: VDP will copy data at the specified M68K source address to the destination target specified in the command word. Only DMD1 is significant here; DMD0 becomes the high bit of the source address. (Note that in this mode, the source address is divided by two; DMA source of $7F0000 corresponds to M68K address $FE0000.)

10: DMA FILL. VDP will fill the specified destination address with the next word written to the data port.

11: DMA COPY. VDP will copy a block of VRAM from the source address to the destination address.

More about these DMA modes can be found here.
Note that the DMA source is the M68K address shifted to the right one bit, as there is no A0 line.

Status Register

To retrieve some information about the VDP's internal state, the control port, $C00004 or $C00006 can be read as a word to get the status register.

VDP Status Register

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

0

0

1

1

0

1

EMPTY

FULL

VIP

SOVR

SCOL

ODD

VB

HB

DMA

PAL

EMPTY and FULL indicate the status of the FIFO.

When EMPTY is set, the FIFO is empty.

When FULL is set, the FIFO is full.

If the FIFO has items but is not full, both EMPTY and FULL will be clear.

The FIFO can hold 4 16-bit words for the VDP to process. If the M68K attempts to write another word once the FIFO has become full, it will be frozen until the first word can be delivered.

VIP indicates that a vertical interrupt has occurred, approximately at line $E0. It seems to be cleared at the end of the frame.

SOVR is set when there are too many sprites on the current scanline. The 17th sprite in 32 cell mode and the 21st sprite on one scanline in 40 cell mode will cause this.

SCOL is set when any sprites have non-transparent pixels overlapping. This is cleared when the Control Port is read.

ODD is set if the VDP is currently showing an odd-numbered frame while Interlaced Mode is enabled.

VB returns the real-time status of the V-Blank signal. It is presumably set on line $E0 and unset at $FF.

HB returns the real-time status of the H-Blank signal.

DMA is set for the duration of a DMA operation. This is only useful for fills and copies, since the M68K is frozen during M68K to VRAM transfers.

PAL seems to be set when the system's display is PAL, and possibly reflects the state of having 240 line display enabled. The same information can be obtained from the version register.

Note: The SCOL flag is a holdover from the TMS9918, which could only show 4 sprites on a scanline. Since the Mega Drive can show up to 20 sprites per scanline (16 in 32-cell mode), and there's no indication as to which sprites overlapped, this bit is useless and should be ignored.

To access the VRAM, the VRAM address needs to somehow be communicated to the VDP, but VRAM is not mapped directly into address space, so therefore a command must be written to the VDP's control port ($C00004) to tell it which of its memories will be accessed.

Any bits set to 0 in the table above should always be set to 0 in any produced command words. The A's refer to the actual memory address — For example, to write to VRAM address $AC80, the address would first be converted into binary, like so:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

1

0

1

0

1

1

0

0

1

0

0

0

0

0

0

0

The CD bits in the command register are used to set up the code register. They indicate if data will be read or written as well as which section of memory will be accessed. Possible values of CD include: (MSB on left)

The 8-bit VRAM read function reads a single byte from VRAM. The returned value consists of the VRAM byte as the low byte, plus a byte from the FIFO as the high byte. It's recommended to use the standard VRAM read function instead.

If the proper address and mode bits are set in the VDP command, a command word like this would be produced:

When converted back to hexadecimal, this produces the value $6C800002, which would be written to the VDP's control port.

VDP Features

Palettes

The VDP has an internal memory called CRAM, or colour RAM, which is 64 words of 9 bits each. This is divided up into 4 palette lines, while one palette line is divided into 16 different palette entries, with the first entry always being transparent (but is able to be displayed as the display background colour,) and the remaining 15 entries being able to be used regularly. Tiles reference into a palette with each nybble, and mappings tell them which one of the 4 palette lines it shall use. The format of a CRAM entry is as follows:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

x

x

x

x

B

B

B

x

G

G

G

x

R

R

R

x

The CRAM can be accessed at any time during the display period, with one access 'slot' every 32 pixels during active display, and any time during inactive display. If the CRAM is attempted to be read or written during active display, the value that was being read or written to the CRAM at that location will appear on-screen due to a bug on the hardware. This bug is often refered to as "CRAM dots." Therefore, it is common practice to update the CRAM during blanking through the use of DMA.

VRAM

The VDP comes with 64 KB of VRAM that is used to most data that's displayed, save for vertical scrolling info and colours. The VDP could theoretically be modified to use 128 KB of VRAM by replacing the DRAM chips, as there is enough address bits to accommodate 512 rows in the DRAM instead of 256. Access to the VRAM is severely limited during active display and is done through a 4 level FIFO that stores the address and data to write to it. The status register indicates the status of it, and should it become full, the 68k is halted until the FIFO clears. Therefore, it's recommended practice to turn the display off or transfer data using DMA during blanking to access the VRAM.

Interrupts

The VDP is responsible for providing interrupts for the 68k. These interrupts are either of levels 2, 4 or 6.

Vertical Interrupt

The Vertical Interrupt, or VBlank, is fired when the electron beam in the television has finished drawing the last scanline and will start moving back to the top to draw the next frame again. It's commonly used to fire off DMA queues, palette buffers, read controllers and so on. The VBlank interrupt level is 6, meaning it has the lowest priority.

Horizontal Interrupt

The horizontal interrupt is fired once the VDP has completed outputting the scanline specified by the Register 10. The VDP's internal scanline counter is loaded with the value from this register at the top of the screen, and once it hits 0, the interrupt will be fired and the register re-loaded with the value. For example, if the register were to be set to $10, the interrupt would be fired every 16 scanlines. Horizontal interrupts have an interrupt level of 4, meaning it can interrupt a VBlank.

Due to how the VDP is designed, there is a delay before the new value set in Register 10 becomes effective. The counter for the horizontal interrupt must first expire with the previous value before the new one takes effect. For example, when it it is set to $10, and after the first interrupt on line $10 it is set to $08, the next interrupt will still happen after $10 scanlines, at which point the new value will take effect. This is caused because the VDP's internal scanline counter for horizontal interrupts is only reloaded with the value of Register 10 once it reaches 0, not when the register is written to.

External Interrupt

Controller ports can be configured so that when the /TH port is changed, the VDP will latch the HV counter's value, and generate a level 2 interrupt on the Motorola 68000. This facility is used by light guns to interrupt the game when the trigger is pressed, at which point the game will use various techniques to determine if the gun was aimed at the object at the position specified by the HV counter. Note that programatically changing /TH does not cause an interrupt.

DMA

The VDP has a feature called DMA, or Direct Memory Access, something it has in common with almost all computers and other devices. DMA allows these devices to move data faster without requiring the CPU to do it. As explained in the registers section above, the VDP has the capability of doing 3 different DMA types - M68k to VRAM,VRAM Fill and VRAM copy. Something important to note is that during M68k to VRAM transfers, as the VDP will have the bus, the M68k will be frozen by the VDP for the duration of the DMA transfer. However, the speed advantage of DMA over manually writing art in a tight loop on the 68k is worth the lost execution time, as long as the DMA is done during VBlank or when the display is enabled. During HBlank, the speed of DMA is about the same as the speed of a art loading loop running on the M68k. Do note that the Z80 will keep running during DMA, unless it attempts to access the bus, at which point it will also be frozen for the duration of the DMA transfer.

To set up a DMA, the DMA registers (19-23) must be set. Additionally, for DMA to work, DMA needs to be enabled in register 1, as well as set the auto-increment register (15) to a meaningful value — usually this is 2, to transfer art, but other values can be used to optimise VRAM accesses, and even creating a bitmapped display. The VDP will then halt the 68k, transfer the data specified at the fastest speed possible to its memory, and then resume the M68k. It's for this reason that ROMs used to hold Mega Drive programs need to be at least a specific access speed if DMA is used.

A VRAM Fill will 'fill' will fill another VRAM address with data from an even VRAM address. This applies to only VRAM, not CRAM or VSRAM. The last DMA mode is VRAM Copy - it will copy from the source address to the destination address, for as many bytes as the length register indicates. These two modes don't freeze the M68k, but it is important that only the VDP status register and H/V counter are read, and the PSG registers are written. Doing otherwise may corrupt VRAM and VDP registers.

Often times, games will create a DMA queue that will hold a specific number of entries to DMA on the next vertical blank interrupt, where it will be processed. See the howto article on this to learn about making one.

DMA Bandwidth

All numbers in the tables indicating transfer capacity are in bytes, not words. Active display indicates the total number of bytes transferrable during the time of active display, including HBlank intervals. Disabled display indicates the amount of bytes of data transferrable during the VBlank.

When calculating for DMA to CRAM or VSRAM, numbers below should be doubled. VRAM access slots are per byte, whereas VSRAM and CRAM are by words.

68k to VRAM

The table below indicates the available bandwidth when doing a DMA from the 68k address space to the VDP.

Resolution

Disabled Display

Active Display

Total

60 Hz

256 x 224

6118

3584

9702

320 x 224

7524

4032

11556

50 Hz

256 x 224

14329

3584

17913

320 x 224

17622

4032

21654

256 x 240

11753

3840

15593

320 x 240

14454

4320

18774

VRAM Fill

The table below indicates the available bandwidth when doing a VRAM fill DMA.

Resolution

Disabled Display

Active Display

Total

60 Hz

256 x 224

6308

3360

9668

320 x 224

7752

3808

11560

50 Hz

256 x 224

14774

3360

18134

320 x 224

18156

3360

18134

256 x 240

12118

3600

15718

320 x 240

14892

4080

18972

VRAM Copy

The table below indicates the available bandwidth when doing a VRAM copy from one area in VRAM to another.

Resolution

Disabled Display

Active Display

Total

60 Hz

256 x 224

3154

1792

4946

320 x 224

3876

2016

5892

50 Hz

256 x 224

7387

1792

9179

320 x 224

9078

2016

11094

256 x 240

6059

1920

7979

320 x 240

7446

2160

9606

DMA Limitations

Because the VDP acquires bus mastership during a DMA transfer, it is not possible for any other hardware to access the MD bus. This can pose a problem for the Z80, as most of the time it is used as part of the sound driver, which often needs to read from ROM. The Z80 may continue running during a DMA transfer, but if it attempts to access 68k access space, it will be halted for the remainder of the DMA transfer. It's common for games to stop the Z80 during the length of a DMA transfer, but the reason for this is currently unknown. It is possible that this may be done to circumvent a bug in the I/O controller or VDP itself on certain hardware.

Due to limitations in the VDP, all data transferred through DMA must not cross a 128KB boundary. If data crosses this 128 KB boundary, random data from elsewhere in the 68k address space will be read. For example, if art that was 64 kilobytes in size was located in a ROM at $1E0000, it would be able to be transferred without problems, as it does not exceed $1FFFFF, the next boundary. If however, this same piece of art was located at $1F2000, and a DMA was attempted, parts of the art after $1FFFFF would not be transferred correctly. This issue is caused due to the implementation of the DMA unit in the VDP: Every DMA cycle, only the low and middle bytes of the DMA source registers are incremented. As there is no 0th bit, this leads to $1FFFF bytes before the counters wrap over.

A similar issue occurs if the second word of the DMA address is written to the mirror of the VDP port (at $C00006) which may cause the first word of the DMA transfer to not be transferred. This can be circumvented easily by writing the second word of the transfer address to the first control port, not the mirror of it. A similar problem can occur when performing a DMA transfer from the Mega CD Word RAM, due to a timing problem with the DRAM that prevents the address from getting latched into the memory, although all following words that will be transferred correctly. To circumvent this problem, set the DMA source and destination as one word less than needed, and length one more than is needed. This may corrupt the word in VRAM before, but ensure all data will be transferred correctly.

DMA copies do not work well when copying data to and from the sprite table. While all data is properly copied, the sprite cache is not completely updated, causing various visual issues including disappearing sprites.

There is significantly less DMA bandwidth available on NTSC-60 hardware than there is on PAL-50 hardware, due to the fact that NTSC hardware has a higher output framerate.

Patterns

Patterns are 8x8 pieces of art that can be displayed in any of the 4 available palettes. Each pattern is $20 bytes in length, and is stored anywhere in VRAM. They are mapped to the display through the use of the nametables, which can also set the palette line for them to use, rotating the tile horizontally and vertically, as well as the high priority flag. Many games store their patterns compressed in their ROMs for a number of reasons, mainly the fact to save ROM space. Some games will decompress them to RAM and DMA from there, while others will simply just write to the VDP.

Nametables

Nametables will tell the VDP what to draw, and where to draw it. Essentially, they map patterns to the different planes that can be had on-screen at any given time. As mentioned before, these name tables can never exceed 8KBytes in size. Some games will compress these, but in some cases, for example, if scrolling credits are needed and so is tile reloading, compression can often be a hassle unless it is able to decompress only a specific range of bytes. RLE compression often works very well for compressing name tables. If supplying the horizontal or vertical scroll memories with values past the end of the nametable, the nametable will wrap again — a feature that can be (ab)used to create parallax backgrounds.

An entry in a name table is 16 bits, and works as follows:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Priority

Palette

Vertical Flip

Horizontal Flip

Tile Index

When the priority bit is set, the tile will be displayed above low priority tiles on the same plane, or planes 'below' it in the priority ordering. Horizontal and Vertical flip will flip the tile either horizontally or vertically. The palette bits allow displaying the tile with one of the four palette lines. It is worth noting that when Interlace mode 2 is selected, the LSB of the tile index will be ignored, as tiles are now 8x16 in size.

Priority

The VDP has a complex system of priorities that can be used to achieve several complex effects. The priority order goes like follows, with the least priority being the first item in the list:

Backdrop Colour

Plane B with priority bit clear

Plane A with priority bit clear

Sprites with priority bit clear

Window Plane with priority bit clear

Plane B with priority bit set

Plane A with priority bit set

Sprites with priority bit set

Window Plane with priority bit set

Sprites

An example of a 2x2 cell sprite from Sonic the Hedgehog, with the palette below it.

Sprites are objects with a size of up to 4x4 (cells) that can be arbitrarily positioned on-screen.

Sprites can only appear in the active display area, unless some programming trick is employed. The sprites with the highest priority will be the ones that will get drawn if there are more than the maximum sprites on a single scanline. When a sprite's X position is set to 0, it can be used to mask all other sprites on that same scanline, so long as they have low priority. The range X values is 0 through 551, but the displayable X values begins at 128, up to 383 or 447, depending on horizontal mode. The sprite's Y position values are from 0 through 551, but the displayable values start at 128 and go up to 351 or 367 depending on vertical mode. When interlace mode 2 is enabled (to double vertical resolution) the sprite's Y position range doubles, with the displayable area starting at 256 to 703 or 735 depending on vertical mode.

Note: The VDP has an internal 'cache' memory for the sprite attribute table that is loaded every vertical blanking interval, which effectively prevents the re-use of sprites by changing their position during active display that was common with other computers of the era. Tile data for sprites is also fetched during the blanking interval of the line before. This can be circumvented by changing the sprite table address register, but may result in dropped sprites.

Sprite Attribute Table

All sprites are specified in the VRAM in the Sprite Attribute table, pointed to by Register $05. Each entry takes up 8 bytes, with the following format:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Unused

Vertical Position

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Unused

Horizontal Size

Vertical Size

Unused

Link Data

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Priority

Palette

Vertical Flip

Horizontal Flip

Pattern to use

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Unused

Horizontal Position

Note: If 128 KB mode is enabled, bit 5 from Register $06 is used as bit 11 of the pattern number.

Sprite Sizes

The numbers inside boxes represent their link entry, a yellow box represents a sprite with the priority bit set. The blue rectangle is the window plane, whereas the red and green are the BG and FG, respectively. No planes have the priority set on any tile.

Using two bits for vertical and horizontal sizes, 16 different sprite sizes are possible, up to 4x4 cells. Sizes are defined in cells (8x8 patterns, or 8x16 in Interlace 2) going down the row before the column.

Vert →Horiz↓

0

1

2

3

0

0

0

1

0

1

2

0

1

2

3

1

0

1

0

2

1

3

0

3

1

4

2

5

0

4

1

5

2

6

3

7

2

0

1

2

0

2

4

1

3

5

0

3

6

1

4

7

2

5

8

0

4

8

1

5

9

2

6

A

3

7

B

3

0

1

2

3

0

2

4

6

1

3

5

7

0

3

6

9

1

4

7

A

2

5

8

B

0

4

8

C

1

5

9

D

2

6

A

E

3

7

B

F

Linking and Priority

Each sprite entry has a link field, which indicates the next sprite entry to draw. This ID can be acquired by taking the VRAM absolute address of the sprite entry, subtracting the sprite table base address from it and dividing it by 8. The VDP will begin drawing the first sprite, and then draw the next one indicated by the link. Sprites that come later in the link list can be considered of having a higher priority - they will be drawn above any other sprites that may be drawn at their coordinates. However, the priority flag in the sprite table entry can be used to enhance this.

At the end of a sprite table, the last sprite must have its link field set to 0, otherwise the results are undefined.

Limitations

The VDP imposes some limitations as for how many sprites may be displayed on one line (If more sprites are to be displayed, they will simply not be drawn):

In 32 cell horizontal mode, the VDP will display up to 64 sprites per frame, and a maximum of 16 sprites on a single scanline.

In 40 cell horizontal mode, the VDP will display up to 80 sprites per frame, and a maximum of 20 sprites on a single scanline.

Usually one would expect to be able to change the data in the sprite table mid-frame to create effects - however, this is not possible by simply changing the values of the sprite table as the VDP contains an internal sprite table buffer in which the sprites are pre-calculated prior to displaying them. This cache is re-calculated every frame, or if the sprite table location register is changed. This register can be changed mid-frame, but the side effects of doing this are unknown and undefined.

Shadow/Highlight

An example of Shadow/Highlight on the Mega Drive. The highlighted states are done using sprites.

An example of the Shadow/Highlight effect with sprites being used for a sort of 'Lens Flare' effect in Vectorman.

Shadow/Highlight is a special VDP mode that allows for more colours to be displayed on-screen at once, about 3 times as much as the normal 512. To use this mode, special colours and the priority system are used. Even though there wasn't very many Mega Drive games that took advantage of this mode, a notable example of this mode is the game Vectorman, where it is used extensively.

An entry in a name table is by default shadowed with the priority bit cleared. When it is set, it will be displayed at regular intensity. If a tile in Plane B has the priority bit set, any other tiles on other planes that pass over that tile will also be highlighted. Sprites with special colours can be used to either add shadow or highlight a colour:

Sprites with colour 15 of palette 4 will highlight the underlying pixels - if the underlying pixel is shadowed, it will be displayed normally. If it's already normal, it will be highlighted.

Sprites with colour 16 of palette 4 will shadow the underlying pixels - if the underlying pixel is normal, it will be shadowed. If it is shadowed, nothing will occur. If it's highlighted, it will be displayed normally.

It is possible to mix these colours with other colours from the same palette line to create effects. Sprites are also displayed differently depending on their priority setting, identically how it works with name tables.

Note that colours 14 of any palette behave abnormally in Shadow/Highlight mode. This is most likely due to a bug in the VDP implementation. There may be other colours that don't function as expected.

Emulators calculate shadow colours by dividing regular colours by two, and highlight colours by multiplying by two. Hardware appears to follow this behaviour to some extent, although it can't be known for certain as it's very hard to get undistorted colour values from the hardware.

Horizontal Scrolling

An example illustrating how horizontal and vertical scrolling work. The numbers indicate the scroll value for the columns/rows adjacent/below them. The red illustrates where the patterns would loop.

The VDP can scroll the A and B plane horizontally in a number of ways - the entire plane, every row of tiles, or every scanline. This is controlled by Register 11 as well as Register 13. The HScroll data is located in VRAM, meaning it has to share the memory with nametables and tile data.

If whole plane scrolling is enabled, the VDP high word will scroll the FG plane, and the low plane will scroll the BG plane. Note that the plane will wrap once it reaches the edge of the plane's size.

When per-row horizontal scrolling is enabled, every longword in the HScroll table will tell the VDP how much to scroll every 8-pixel row on-screen. The format is still the same as before - first word scrolls the FG, and the second scrolls the BG.

Lastly is per-scanline horizontal scrolling. This mode allows scrolling of all 224 on-screen scanlines (240 in PAL mode) individually. This can be used to create visually appealing effects such as water wobbles, and so on. Each long in the HScroll table will tell the VDP how to scroll each scanline. As previously, the first word will be controlling controlling the FG, and the second controlling the BG. This mode also takes up the most space in VRAM, with 960 bytes.

It's best to have an in-RAM buffer for the last two modes as writing to the VDP isn't exactly fast. The buffer can then be transferred using DMA every VBlank.

Vertical Scrolling

Like Horizontal Scrolling, Vertical Scrolling allows scrolling of the content on the VDP's 2 planes, but vertically. The setup of VScroll is decided by Register 11. Both planes can be scrolled completely, or the VDP can scroll a 2 tile wide column of the name tables at once. Vertical Scrolling data is located in RAM on the VDP itself. It is also written like regular VRAM, but it is not exactly fast either, so a buffer should be applied here too.

The first mode of vertical scrolling is much like the first mode of horizontal scrolling - the entire screen is scrolled vertically by the first long in VSRAM. The first word scrolls the FG, and the second scrolls the BG.

To have more precise effects, the VDP can scroll individual columns that are 2 tiles (or 16 pixels) wide individually. Every column is scrolled by a long in VSRAM - the first word scrolls the FG, while the second word scrolls the BG. Combined with horizontal scrolling of various accuracies, it is possible to create very interesting effects, such as rotations, and more.

H/V Counter

The H/V counter contains the current location of the electron beam in the television, or the currently drawn pixel. By pulling the /TH line low on controllers, a game may latch the HV counter as well as cause a 68k interrupt. This technique is often used for light guns. It can be read from $C00008.

The format of the counter in regular non-interlace mode is as follows:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

V7-V0

H8-H1

However, due to the fact that interlace mode doubles the screen resolution, another bit is needed for resolution. To get around that, the LSB is dropped from the vertical component to allow adding of another bit.

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

V7

V6

V5

V4

V3

V2

V1

V8

H8-H1

The vertical counter will count to 224 pixels in 28 vertical cell mode, and count to 240 pixels in 30 vertical cell mode.

During HBlank in 32 horizontal cell mode, when the counter reaches 264, it will increment. It will then increment normally until 296 and then jump to a value of -46 indicating the beam is restarting on a new line.

During HBlank in 40 horizontal cell mode, when the counter reaches 328, it will increment. It will then increment normally until 360 and then jump to a value of -46 indicating the beam is restarting on a new line.

During VBlank in 28 vertical cell mode the counter will continue to increment normally from 224 to 234. It will reset to 229, indicating the beam will re-start on the top of the display. It will then increment until active display.

During VBlank in 30 vertical cell mode the counter will continue to increment normally from 240 to 10. It will reset to 210, indicating the beam will re-start on the top of the display. It will then increment until active display.

PSG

The PSG chip is integrated into the VDP die. See this article for more information.

Undocumented Features

Debug Register

The VDP contains a register at $C0001C in memory space that will disable various parts of the VDP and cause it to perform other 'test' modes. This register is not supported on any emulator, and it is mirrored at $C0001E.

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

?

SHDE2

SHDE1

SHDE0

CLICK

CLICK

PSGEN

BGHDE

SDBG

DISP

CORR1

?

KILL1

?

?

?

SHDE0 to SHDE2: These bits hide all sprites on screen, but some bits may do other functions when combined with others.

CORR1: When set, corrupt data is displayed, and it appears to corrupt the internal VDP state

KILL1: When set, causes streaks down screen as if there was a continuous 68k -> CRAM DMA

No games appear to use this register, nor is it documented anywhere. A ROM to test this behaviour (real hardware only) can be downloaded here.

Timings

Below are documented the timings of accessing the VDP during the active and blanking display.

H32 Mode

Each scanline has 16 access slots. Each block of two cells has one access slot, but every fourth group of cells inserts a refresh cycle in place of the access cycle. During blanking, four access slots are available between pattern data fetches.

H40 Mode

Each scanline has 18 access slots. Each block of two cells has one access slot, but every fourth group of two cells inserts a refresh cycle in place of the access cycle. During blanking, three access slots are available between sprite pattern data fetches.

Pinout

The VDP is a 128 pin QFP chip on the main board of the Mega Drive. On Model 2 and 3 Mega Drives, it is no longer a discrete chip because it is integrated with the other hardware in a single chip, to save space and manufacturing costs.

Unused External Buses

The VDP has multiple busses that are not connected to anything, but still broken out to pins. These buses are:

The VDP can use 128 KB of VRAM, which is supported by nearly everything but tile indices — however, registers have been found that allow rebasing of tile data.. The serial data access bus appears to be shared between both memories.

128K VRAM

The external "VRAM2" bus can be used to provide a total of 128KB of VRAM to the VDP, with several registers allowing for rebasing of tiles, which can allow the tiles to be located in the upper 64KB of RAM.

It is worth noting that the additional VRAM is interleaved with the regular 64KB. [5] Because of this interleaving, enabling 128K VRAM mode on a system that does not actually have the extra VRAM causes the graphics to become garbled.

Test Programme

The first page of the programme.

This programme gives examples of various effects the VDP is capable of displaying. To change pages, hold the Start button, and then press the left or right buttons. Pressing Start and up at the same time will open the table of contents.