Sega Mega Drive/VDP registers

From Sega Retro

Reg. Name Bits Code
00 Mode Register 1
7
6
5
4
3
2
1
0

0
0
L
IE1
0
M4
M3
DE
move.w #$80xx,($c00004).l
01 Mode Register 2
7
6
5
4
3
2
1
0

VR
DE
IE0
M1
M2
M5
0
0
  • VR: 1 = use 128kB of VRAM. Will not work correctly on standard consoles with 64kB VRAM.
  • DE: 1 = enable display; 0 = fill display with background colour.
  • IE0: 1 = enable vertical interrupts.
  • M1: 1 = enable DMA operations; 0 = ignore DMA operations.
  • M2: 1 = 240 pixel (30 cell) PAL mode; 0 = 224 pixel (28 cell) NTSC mode.
  • M5: 1 = Mega Drive (mode 5) display; 0 = Master System (mode 4) display.
move.w #$81xx,($c00004).l
02 Plane A Name Table Location
7
6
5
4
3
2
1
0

0
PA6
PA5-PA3
0
0
0
  • PA5-PA3: Bits 15-13 of foreground (plane A) nametable address in VRAM. Effectively the address (which must be a multiple of $2000) divided by $400.
  • PA6: Used for 128kB VRAM.
move.w #$8200+($xxxx>>10),($c00004).l
03 Window Name Table Location
7
6
5
4
3
2
1
0

0
W6
W5-W1
0
  • W5-W1: Bits 15-11 of window nametable address in VRAM. Effectively the address (which must be a multiple of $800) divided by $400.
  • W1: Ignored in 320 pixel wide mode, limiting the address to a multiple of $1000.
  • W6: Used for 128kB VRAM.
move.w #$8300+($xxxx>>10),($c00004).l
04 Plane B Name Table Location
7
6
5
4
3
2
1
0

0
0
0
0
PB3
PB2-PB0
  • PB2-PB0: Bits 15-13 of foreground (plane B) nametable address in VRAM. Effectively the address (which must be a multiple of $2000) divided by $2000.
  • PB3: Used for 128kB VRAM.
move.w #$8400+($xxxx>>13),($c00004).l
05 Sprite Table Location
7
6
5
4
3
2
1
0

ST7
ST6-ST0
  • ST6-ST0: Bits 15-9 of sprite table address in VRAM. Effectively the address (which must be a multiple of $200) divided by $200.
  • ST0: Ignored in 320 pixel wide mode, limiting the address to a multiple of $400.
  • ST7: Used for 128kB VRAM.
move.w #$8500+($xxxx>>9),($c00004).l
06
7
6
5
4
3
2
1
0

0
0
SP5
0
0
0
0
0
move.w #$8600+($xxxxxx>>11),($c00004).l
07 Background Colour
7
6
5
4
3
2
1
0

0
0
PL1-PL0
C3-C0
  • PL1-PL0: Palette line.
  • C3-C0: Colour.
move.w #$8500+(xx<<4)+yy,($c00004).l
08 Unused Master System horizontal scroll register
09 Unused Master System vertical scroll register
0A Horizontal Interrupt Counter
7
6
5
4
3
2
1
0

H
move.w #$8Axx,($c00004).l
0B Mode Register 3
7
6
5
4
3
2
1
0

0
0
0
0
IE2
VS
HS1-HS2
move.w #$8Bxx,($c00004).l
0C Mode Register 4
7
6
5
4
3
2
1
0

RS1
VS
HS
EP
SH
LS1-LS0
RS0
  • RS1/RS0: 1 = 320 pixel (40 cell) wide mode; 0 = 256 pixel (32 cell) wide mode. Both bits must be the same.
  • VS:
  • HS:
  • EP: 1 = enable external pixel bus.
  • SH: 1 = enable shadow/highlight mode.
  • LS1-LS0: Interlace mode: 00 = no interlace; 01 = interlace normal resolution; 10 = no interlace; 11 = interlace double resolution.
move.w #$8Cxx,($c00004).l
0D Horizontal Scroll Data Location
7
6
5
4
3
2
1
0

0
HS6
HS5-HS0
  • HS5-HS0: Bits 15-10 of horizontal scroll data address in VRAM. Effectively the address (which must be a multiple of $400) divided by $400.
  • HS6: Used for 128kB VRAM.
move.w #$8D00+($xxxx>>10),($c00004).l
0E
7
6
5
4
3
2
1
0

0
0
0
PB4
0
0
0
PA0
  • PB4: Bit 16 of background (plane B) nametable address in 128kB VRAM.
  • PA0: Bit 16 of foreground (plane A) nametable address in 128kB VRAM.
move.w #$8E00+(($xxxxxx&$10000)>>12)+($yyyyyy>>16),($c00004).l
0F Auto-Increment Value
7
6
5
4
3
2
1
0

INC7-INC0
  • INC7-INC0: Value to be added to the VDP address register after each read/write to the data port. 2 is most common.
move.w #$8Fxx,($c00004).l
10 Plane Size
7
6
5
4
3
2
1
0

0
0
H1-H0
0
0
W1-W0
  • H1-H0: Height setting for background and foreground (planes A & B). 00 = 256 pixels (32 cells); 01 = 512 pixels (64 cells); 10 = invalid; 11 = 1024 pixels (128 cells).
  • W1-W0: Width setting for background and foreground (planes A & B). Same as above.
  • Height/width settings of 64x128 or 128x128 cells are invalid, due to a maximum plane size of $2000 bytes.
move.w #$90xx,($c00004).l
11 Window Plane Horizontal Position
7
6
5
4
3
2
1
0

R
0
0
HP4-HP0
  • R: 1 = draw window from HP to right edge of screen; 0 = draw window from HP to left edge of screen.
  • HP4-HP0: Horizontal position on screen to start drawing the window plane (in units of 8 pixels).
move.w #$91xx,($c00004).l
12 Window Plane Vertical Position
7
6
5
4
3
2
1
0

D
0
0
VP4-VP0
  • D: 1 = draw window from VP to bottom edge of screen; 0 = draw window from VP to top edge of screen.
  • VP4-VP0: Vertical position on screen to start drawing the window plane (in units of 8 pixels).
move.w #$92xx,($c00004).l
13-14 DMA Length
7
6
5
4
3
2
1
0

L7-L0
7
6
5
4
3
2
1
0

H7-H0
  • L7-L0: Low byte of DMA length in bytes, divided by 2.
  • H7-H0: High byte of DMA length in bytes, divided by 2.
move.w #$9300+(($xxxx>>1)&$FF),($c00004).l
move.w #$9400+((($xxxx>>1)&$FF00)>>8),($c00004).l
15-17 DMA Source
7
6
5
4
3
2
1
0

L7-L0
7
6
5
4
3
2
1
0

M7-M0
7
6
5
4
3
2
1
0

T1
T0
H5-H0
  • L7-L0: Low byte of DMA source address, divided by 2.
  • M7-M0: Middle byte of DMA source address, divided by 2.
  • H5-H0: High byte of DMA source address, divided by 2.
  • T1/T0: DMA type. 0x = 68k to VRAM copy (T0 is used as the highest bit in source address); 10 = VRAM fill (source can be left blank); 11 = VRAM to VRAM copy.
move.w #$9500+(($xxxxxx>>1)&$FF),($c00004).l
move.w #$9600+((($xxxxxx>>1)&$FF00)>>8),($c00004).l
move.w #$9700+((($xxxxxx>>1)&$7F0000)>>16),($c00004).l
Status Register
7
6
5
4
3
2
1
0

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

VI
SO
SC
OD
VB
HB
DMA
PAL
  • E: 1 = FIFO is empty.
  • F: 1 = FIFO is full.
  • VI: 1 = vertical interrupt occurred.
  • SO: 1 = sprite limit has been hit on current scanline. i.e. 17+ in 256 pixel wide mode or 21+ in 320 pixel wide mode.
  • SC: 1 = any two sprites have non-transparent pixels overlapping. Used for pixel-accurate collision detection.
  • OD: 1 = odd frame displayed in interlaced mode; 0 = even frame displayed in interlaced mode.
  • VB: 1 = vertical blank in progress.
  • HB: 1 = horizontal blank in progress.
  • DMA: 1 = DMA in progress.
  • PAL: 1 = PAL system; 0 = NTSC system.
move.w ($c00004).l,d0