Difference between revisions of "Sega Mega Drive/VDP general usage"

From Sega Retro

(Created page with "The '''VDP''' (Video Display Processor) is the main graphics processor in the Sega Mega Drive. It is capable of displaying two graphics planes - a foreground (plane A) and...")
 
Line 44: Line 44:
  
 
===Writing===
 
===Writing===
Writing to the control port will modify one of 24 write-only [[Sega Mega Drive/VDP registers|registers]], which are used to change various settings, or to set an address for doing read/write operations on the VRAM/CRAM/VSRAM.
+
====Registers====
 +
Writing to the control port can modify one of 24 write-only [[Sega Mega Drive/VDP registers|registers]], which are used to change various settings, or to set up a DMA transfer.
  
 
{{bitfield|1|0|0|RS4-RS0;5}}{{bitfield|D7-D0;8}}
 
{{bitfield|1|0|0|RS4-RS0;5}}{{bitfield|D7-D0;8}}
Line 52: Line 53:
 
To modify a register, write a word (1 byte for the register number, 1 byte for the modification) to the control port:
 
To modify a register, write a word (1 byte for the register number, 1 byte for the modification) to the control port:
  
<tt>move.w #$8004,($c00004).l ; set register 0 to $04</tt>
+
: <tt>move.w #$8004,($c00004).l ; set register 0 to $04</tt>
  
 
Because the control port is mirrored at $c00006, it is possible to send two words at the same time:
 
Because the control port is mirrored at $c00006, it is possible to send two words at the same time:
  
<tt>move.l #$80048134,($C00004).l ; set register 0 to $04 and register 1 to $34</tt>
+
: <tt>move.l #$80048134,($C00004).l ; set register 0 to $04 and register 1 to $34</tt>
 +
 
 +
====Addresses====
 +
The control port can also be used to point to an address in VRAM, CRAM or VSRAM, so that the 68k can send data to that address via the data port. This is done by writing a longword in the following format:
 +
 
 +
{{bitfield|CD1|CD0|A13-A8;6}}{{bitfield|A7-A0;8}}{{bitfield|0|0|0|0|0|0|0|0}}{{bitfield|CD5|CD4|CD3|CD2|0|0|A15|A14}}
 +
* '''A15-A0:''' VRAM/CRAM/VSRAM address.
 +
* '''CD0:''' 1 = write; 0 = read.
 +
* '''CD3-CD1:''' 000 = VRAM; 100 = CRAM (read); 001 = CRAM (write); 010 = VSRAM; 110 = VRAM (byte read)
 +
* '''CD4:''' 1 = VRAM to VRAM copy.
 +
* '''CD5:''' 1 = DMA.
 +
 
 +
{|
 +
! Memory space || Type || CD3-CD0 || Code
 +
|-
 +
|rowspan="2"| VRAM
 +
| read
 +
| 0000
 +
| <tt>move.l #$00000000+(($xxxx&$3FFF)<<16)+(($xxxx&$C000)>>14),($C00004).l</tt>
 +
|-
 +
| write
 +
| 0001
 +
| <tt>move.l #$40000000+(($xxxx&$3FFF)<<16)+(($xxxx&$C000)>>14),($C00004).l</tt>
 +
|-
 +
|rowspan="2"| CRAM
 +
| read
 +
| 1000
 +
| <tt>move.l #$00000020+($xx<<16),($C00004).l</tt>
 +
|-
 +
| write
 +
| 0011
 +
| <tt>move.l #$C0000000+($xx<<16),($C00004).l</tt>
 +
|-
 +
|rowspan="2"| VSRAM
 +
| read
 +
| 0100
 +
| <tt>move.l #$00000010+($xx<<16),($C00004).l</tt>
 +
|-
 +
| write
 +
| 0101
 +
| <tt>move.l #$40000010+($xx<<16),($C00004).l</tt>
 +
|-
 +
|}
  
 
==Data port==
 
==Data port==

Revision as of 14:21, 8 June 2018

The VDP (Video Display Processor) is the main graphics processor in the Sega Mega Drive. It is capable of displaying two graphics planes - a foreground (plane A) and background (plane B) - which can be moved independently, as well as a static window plane, and up to 80 sprites (no more than 20 per scanline) on screen.

It contains 64kB of VRAM, used to store graphics data, nametable data for the three planes, horizontal scroll data for the foreground and background planes, and the sprite table. It also has 128 bytes of CRAM, used to store 64 colours (4 palettes of 16 colours). In practice, this equates to 61 usable colours since the first colour in each palette is transparent, and one of those is used as the "background" colour. Finally, VSRAM stores the vertical scroll data.

Ports

Features of the VDP such as VRAM are not directly accessible by the 68k. Instead, all instructions and data must be sent through the control and data ports.

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 H/V counter (read-only)
$C0000A B/W H/V counter (read-only, mirror)
$C0000C B/W H/V counter (read-only, mirror)
$C0000E B/W H/V 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 Debug register
$C0001E W Debug register (mirror)

Control port

Reading

Reading the control port always returns the status register, which contains information about what the VDP is currently doing.

move.w ($c00004).l,d0

Writing

Registers

Writing to the control port can modify one of 24 write-only registers, which are used to change various settings, or to set up a DMA transfer.

7
6
5
4
3
2
1
0

1
0
0
RS4-RS0
7
6
5
4
3
2
1
0

D7-D0
  • RS4-RS0: Register number.
  • D7-D0: Data to write to register.

To modify a register, write a word (1 byte for the register number, 1 byte for the modification) to the control port:

move.w #$8004,($c00004).l ; set register 0 to $04

Because the control port is mirrored at $c00006, it is possible to send two words at the same time:

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

Addresses

The control port can also be used to point to an address in VRAM, CRAM or VSRAM, so that the 68k can send data to that address via the data port. This is done by writing a longword in the following format:

7
6
5
4
3
2
1
0

CD1
CD0
A13-A8
7
6
5
4
3
2
1
0

A7-A0
7
6
5
4
3
2
1
0

0
0
0
0
0
0
0
0
7
6
5
4
3
2
1
0

CD5
CD4
CD3
CD2
0
0
A15
A14
  • A15-A0: VRAM/CRAM/VSRAM address.
  • CD0: 1 = write; 0 = read.
  • CD3-CD1: 000 = VRAM; 100 = CRAM (read); 001 = CRAM (write); 010 = VSRAM; 110 = VRAM (byte read)
  • CD4: 1 = VRAM to VRAM copy.
  • CD5: 1 = DMA.
Memory space Type CD3-CD0 Code
VRAM read 0000 move.l #$00000000+(($xxxx&$3FFF)<<16)+(($xxxx&$C000)>>14),($C00004).l
write 0001 move.l #$40000000+(($xxxx&$3FFF)<<16)+(($xxxx&$C000)>>14),($C00004).l
CRAM read 1000 move.l #$00000020+($xx<<16),($C00004).l
write 0011 move.l #$C0000000+($xx<<16),($C00004).l
VSRAM read 0100 move.l #$00000010+($xx<<16),($C00004).l
write 0101 move.l #$40000010+($xx<<16),($C00004).l

Data port