Actions

SCHG

Difference between revisions of "VDP Documentation/General/Ports"

From Sonic Retro

(Writing to registers: 24 bytes? lolwut?)
m (Data port)
(5 intermediate revisions by 2 users not shown)
Line 78: Line 78:
  
 
=== Writing to registers ===
 
=== Writing to registers ===
The VDP has 24 bit-long write-only registers, the purpose of which is explained [[SCHG:VDP Documentation/General/Registers|here]]. A register can be set by writing a word to the control port, which has the following format:
+
The VDP has 24 write-only registers, each taking bytes, the purpose of which is explained [[SCHG:VDP Documentation/General/Registers|here]]. A register can be set by writing a word to the control port, which has the following format:
  
 
{| class="prettytable" style="margin-left: auto; margin-right: auto; text-align: center"
 
{| class="prettytable" style="margin-left: auto; margin-right: auto; text-align: center"
Line 176: Line 176:
 
 
 
move.l #$00000020,(a5) ; CRAM read at address $0
 
move.l #$00000020,(a5) ; CRAM read at address $0
movem.l (a6),d0/d1 ; get first four colours of first palette line
+
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 #$00600020,(a5) ; CRAM read at address $60
movem.l (a6),d2/d3 ; get first four colours of last palette line
+
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 #$C0000000,(a5) ; CRAM write at address $0
movem.l d2/d3,(a6) ; set first four colours of first palette line
+
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 #$C0600000,(a5) ; CRAM write at address $60
movem.l d0/d1,(a6) ; set first four colours of last palette line</asm>
+
move.l d0,(a6) ; set first two colours of last palette line
 +
move.l d1,(a6) ; set next two colours of last palette line</asm>
  
 
== H/V counter ==
 
== H/V counter ==

Revision as of 13:25, 27 July 2014

Template:SCHG VDP 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:

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

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

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

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
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam | Sonic Jam 6 | 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 | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | Sonic Lost World
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 | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information