VDP Documentation/General/Ports

From Sonic Retro

SCHG: VDP Documentation
Main Article
General Information
Control port
Getting VDP status
Writing to registers
Setting VDP access
Data port
H/V counter
Direct Memory Access
Vertical interrupt
Horizontal interrupt
External interrupt
Memory Divisions
Video RAM
Horizontal scroll table
Sprite attribute table
Plane name tables
Color RAM
Vertical Scroll RAM
Data Formats
Display Control
Scroll planes
Window plane
Shadow and highlight
VDP Bugs

This article is a work in progress.
Its content and location may change completely and frequently until this notice is removed.

The main Mega Drive processor (the Motorola 68000) cannot directly access VDP memory areas. Instead, it communicates with the VDP through ports.

Memory map

The addresses for the VDP ports are shown exhaustively below, though only $C00000 and $C00004 are used generally.

68k Address Length Description
$C00000 B/W/L Data port
$C00002 B/W Data port (mirror)
$C00004 B/W/L Control port
$C00006 B/W Control port (mirror)
$C00008 B/W HV counter (read-only)
$C0000A B/W HV counter (read-only, mirror)
$C0000C B/W HV counter (read-only, mirror)
$C0000E B/W HV counter (read-only, mirror)
$C00011 B SN76489 PSG (write-only)
$C00013 B SN76489 PSG (write-only, mirror)
$C00015 B SN76489 PSG (write-only, mirror)
$C00017 B SN76489 PSG (write-only, mirror)
$C0001C W Unused mystery port

Control port

The control port, as the name suggests, allows the 68000 to control VDP memory access. Additionally, it also allows the reading of VDP status and the setting of registers. The control port is accessed at address $C00004 from the 68000.

Getting VDP status

Reading the control port returns a VDP status word, which has the following format, counting from the least significant bit:

Bit Description
0 This is 0 if the VDP is in NTSC mode, and 1 if it's in PAL mode.
1 This is set for the duration of a DMA operation. It is only useful for fills and copies, as the 68000 is frozen for transfers from 68000 memory to VDP.
2 Set during horizontal blanking.
3 Set during vertical blanking.
4 Set when the odd frame is being displayed in interlaced mode, clear otherwise.
5 Set when any two sprites have non-transparent pixels overlapping each other. Its usefulness is quite limited however since it cannot be determined which two sprites collided and where.
6 Set when there are too many sprites on a scan line i.e. over 17 in 32-cell mode or over 21 in 40-cell mode.
7 Set when a vertical interrupt occurs, presumably cleared at the end of a frame.
8 FIFO full flag. The VDP has a FIFO which can hold up to 4 words while the VDP's busy and unable to immediately process the write command. This flag is set when the 4th word is written and the FIFO cannot hold any more data. If the 68000 attempts to write again it will be frozen until at least one of the stored words has been delivered to its destination.
9 FIFO empty flag. This flag is only set when the FIFO is completely empty. If the FIFO is only partially filled both this flag and the FIFO full flag are 0.
10 Unused (always set).
11 Unused (always cleared).
12 Unused (always set).
13 Unused (always set).
14 Unused (always cleared).
15 Unused (always cleared).

Writing to registers

The VDP has 24 write-only registers, each taking bytes, the purpose of which is explained here. A register can be set by writing a word to the control port, which has the following format:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 0 0 RS4 RS3 RS2 RS1 RS0 D7 D6 D5 D4 D3 D2 D1 D0

Bits 15 and 14 are always 1 and 0 respectively to differentiate register writes from access control writes. RS4-RS0 is the register number, from $00 to $17 (writing to registers $18-$1F has no effect), and D7-D0 is the data to write. Since the VDP treats longword access as equivalent to two word accesses, two registers can be programmed at the same time by writing a longword:

	move.l	#$80048134,($C00004).l	; set register 0 to $04 and register 1 to $34

Setting VDP access

The 68000 can set VDP access by writing a longword to the control port, which has the following format:

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
CD1 CD0 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 CD5 CD4 CD3 CD2 0 0 A15 A14

A15-A0 is the destination RAM address. CD5 is the DMA flag, and CD4 is set for a VRAM copy DMA operation. Bits CD3-CD0 govern the type of access:

Access type CD3 CD2 CD1 CD0
VRAM read 0 0 0 0
VRAM write 0 0 0 1
CRAM read 1 0 0 0
CRAM write 0 0 1 1
VSRAM read 0 1 0 0
VSRAM write 0 1 0 1

Data port

After VDP access has been set, data can be read or written through the data port, which is accessed at address $C00000 from the 68000. After each read or write, the address is increased by the value of the auto increment register (register $0F). Attempting to read data after setting up a write operation or vice-versa will cause the read or write to be ignored.

As an example, the following code swaps first four colours of the first palette line (CRAM addresses 0 to 7) with the first four colours of the last palette line (CRAM addresses $60 to $67):

	lea	($C00004).l,a5	; VDP control port
	lea	($C00000).l,a6	; VDP data port
	move.w	#$8F02,(a5)	; set auto-increment to 2 (see registers page for explanation)
	move.l	#$00000020,(a5)	; CRAM read at address $0
	move.l	(a6),d0		; get first two colours of first palette line
	move.l	(a6),d1		; get next two colours of first palette line
	move.l	#$00600020,(a5)	; CRAM read at address $60
	move.l	(a6),d2		; get first two colours of last palette line
	move.l	(a6),d3		; get next two colours of last palette line
	move.l	#$C0000000,(a5)	; CRAM write at address $0
	move.l	d2,(a6)		; set first two colours of first palette line
	move.l	d3,(a6)		; set next two colours of first palette line
	move.l	#$C0600000,(a5)	; CRAM write at address $60
	move.l	d0,(a6)		; set first two colours of last palette line
	move.l	d1,(a6)		; set next two colours of last palette line

H/V counter

The H/V counter is a read-only port which can be accessed at address $C00008 from the 68000. It keeps track of the position of the TV beam and its value is only meaningful in active scan (i.e. not during vertical blank).

Reading the port will lead to a 2 byte value: the low byte is the horizontal position of the beam and the high byte is the vertical position. Under H40 or interlaced modes, values may be bigger than 255 and hence don't fit. Because of this, the LSB of the vertical counter is replaced by the MSB in interlaced mode, and the LSB of the horizontal counter is always dropped (so it'll have half the real value).

Sonic Community Hacking Guide
Sonic Music Hacking Guide | SonED2 Manual
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic Eraser | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Nick Arcade prototype) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (8-bit) | Sonic 2 & Knuckles | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Sonic 3 | Sonic & Knuckles | Sonic the Hedgehog 3 & Knuckles | Sonic & Knuckles Collection | Sonic Crackers | Sonic 3D: Flickies' Island | Chaotix | Sonic R PC | Sonic Jam 6 | Sonic Advance | Sonic Advance 2 | Sonic Advance 3 | Sonic Battle | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Shadow the Hedgehog | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Lost World | Sonic Forces
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | Subroutine Equivalency List | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | VDP Documentation | Official Sega 32X Documentation | Official Mega-CD Documentation | Official Sega Mega Drive Documentation