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 | + | ====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.
- 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:
- 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 |