User:Ddribin/PPU Sandbox: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
No edit summary
(Rename registers)
 
(25 intermediate revisions by the same user not shown)
Line 1: Line 1:
== PPUCTRL - The PPU Control Register ==
== PPU Register Overview ==
 
The PPU exposes only eight memory-mapped registers to the CPU. These nominally sit at $2000 through $2007 in the CPU's address space, but because they're incompletely decoded, they're mirrored in every 8 bytes from $2008 through $3FFF, so a write to $3456 is the same as a write to $2006.
 
{| class="wikitable" border="1" cellspacing="0" cellpadding="3"
|+ PPU Registers
|-
! Address !! Name !! (Alt. Names?) !! Function
|-
| $2000 || [[#PPUCR1|PPUCR1]] || PPUCTRL PCR ||  PPU Control Register 1
|-
| $2001 || [[#PPUCR1|PPUCR2]] || PPUMASK PPUMR  PMR || PPU Control Register 2
|-
| $2002 || [[#PPUSR|PPUSR]] || PPUSTATUS PSR || PPU Status Register
|-
| $2003 || OAMAR || OAMADDR OAR || OAM Address Register
|-
| $2004 || OAMDR || OAMDATA ODR || OAM Data Register
|-
| $2005 || PPUSCR || PPUSCROLL PSCR || PPU Scroll Register
|-
| $2006 || PPUAR || PPUADDR PAR || PPU Address Register
|-
| $2007 || PPUDR || PPUDATA PDR || PPU Data Register
|-
| $4014 || OAMDMA || ODMA || OAM DMA
|}
 
== <span id="PPUCR1">PPUCR1</span>: PPU Control Register 1 ==


{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
Line 6: Line 34:
|-
|-
! $2000
! $2000
| NMI || MSS || SSZ || BPT || SPT || VDN || NTA1 || NTA0
| NMIE || MSE || SSZ || BPT || SPT || VDN || NTA1 || NTA0
|-
|-
! Read/Write
! Read/Write
Line 12: Line 40:
|-
|-
! Initial Value
! Initial Value
| X || X || X || X || X || X || X || X
| 0 || X || 0 || 0 || 0 || 0 || 0 || 0
|}
|}


; Bit 7 - NMI<nowiki>:</nowiki> NMI Enable
=== Bit 7 - NMIE<nowiki>:</nowiki> NMI Enable ===
:Generate an NMI at the start of th vertical blanking interval (0: off; 1: on)
Setting NMIE to one causes an NMI to be generated at the start of the vertical blanking interval.


; Bit 6 - MSS<nowiki>:</nowiki> Master/Slave Enable
=== Bit 6 - MSE<nowiki>:</nowiki> Master/Slave Enable ===
: Has no effect on the NES.
Has no effect on the NES.


; Bit 5 - SSZ<nowiki>:</nowiki> Sprite Size
=== Bit 5 - SSZ<nowiki>:</nowiki> Sprite Size ===
: Sprite size (0: 8x8; 1: 8x16)
0: 8x8; 1: 8x16


; Bit 4 - BPT<nowiki>:</nowiki> Background Pattern Table
=== Bit 4 - BPT<nowiki>:</nowiki> Background Pattern Table ===
: Background pattern table address (0: $0000; 1: $1000)
Background pattern table address (0: $0000; 1: $1000)


; Bit 3 - SPT<nowiki>:</nowiki> Sprite Pattern Table
=== Bit 3 - SPT<nowiki>:</nowiki> Sprite Pattern Table ===
: Sprite pattern table address for 8x8 sprites (0: $0000; 1: $1000)
Sprite pattern table address for 8x8 sprites (0: $0000; 1: $1000)


; Bit 2 - VDN<nowiki>:</nowiki> VRAM Increment Down
=== Bit 2 - VDN<nowiki>:</nowiki> VRAM Increment Down ===
: VRAM address increment per CPU read/write of PPUDATA (0: increment by 1, going across; 1: increment by 32, going down)
VRAM address increment per CPU read/write of PPUDATA (0: increment by 1, going across; 1: increment by 32, going down)


; Bits 1, 0 - NTA1 and NTA0<nowiki>:</nowiki> Base Nametable Address
=== Bits 1, 0 - NTA1 and NTA0<nowiki>:</nowiki> Base Nametable Address 1 and 0 ===
: Base nametable address (00 = $2000; 01 = $2400; 10 = $2800; 11 = $2C00)
{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
|-
|-
Line 47: Line 74:
| 1 || 1 || $2C00 (Nametable 3)
| 1 || 1 || $2C00 (Nametable 3)
|}
|}
== <span id="PPUCR2">PPUCR2</span>: PPU Control Register 2 ==
{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
|-
! Bit !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0
|-
! $2001
| INB || ING || INR || SRE || BRE || SCD || BCD || GSE
|-
! Read/Write
| W || W || W || W || W || W || W || W
|-
! Initial Value
| 0 || 0 || 0|| 0 || 0 || X || X || 0
|}
=== Bit 7 - INB<nowiki>:</nowiki> Intensify Blues ===
Intensify blues and darken other colors.
=== Bit 6 - ING<nowiki>:</nowiki> Intensify Greens ===
Intensify greens and darken other colors.
=== Bit 5 - INR<nowiki>:</nowiki> Intensify Reds ===
Intensify reds and darken other colors.
=== Bit 4 - SRE<nowiki>:</nowiki> Sprite Render Enable ===
Enable sprite rendering.
=== Bit 3 - BRE<nowiki>:</nowiki> Background Render Enable ===
Enable background rendering.
=== Bit 2 - SCD<nowiki>:</nowiki> Sprite Clip Disable ===
Control sprite clipping in leftmost 8 pixels of screen (0: clip; 1: display).
=== Bit 1 - BCD<nowiki>:</nowiki> Background Clip Disable ===
Control background clipping in leftmost 8 pixels of screen (0: clip; 1: display).
=== Bit 0 - GSE<nowiki>:</nowiki> Grayscale Enable ===
0: normal color; 1: AND all palette entries with 0x30, effectively producing a monochrome display; note that colour emphasis STILL works when this is on!
== <span id="PPUSR">PPUSR</span>: PPU Status Register ==
{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
|-
! Bit !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0
|-
! $2002
| VBL || S0H || SOV || --- || --- || --- || --- || ---
|-
! Read/Write
| R || R || R || R || R || R || R || R
|-
! Initial Value
| X || 0 || X || X  || X || X || X || X
|}
=== Bit 7 - VBL: Vertical Blank ===
=== Bit 6 - S0H: Sprite 0 Hit ===
=== Bit 5 - SOV: Sprite Overflow ===
=== Bits 4..0 - Res: Reserved ===
== CA65 Definitions ==
<pre>
.define bit2mask(bitnum) (1 << bitnum)
.define bits2mask(bits, bitnum) (bits << bitnum)
        ;; PPU Registers
        ppucr1 := $2000
        nmie = bit2mask(7)
        mse  = bit2mask(6)
        ssz  = bit2mask(5)
        bpt  = bit2mask(4)
        spt  = bit2mask(3)
        vdn  = bit2mask(2)
        nta1 = bit2mask(1)
        nta0 = bit2mask(0)
        nta_2000 = bits2mask(%00, nta0)
        nta_2400 = bits2mask(%01, nta0)
        nta_2800 = bits2mask(%10, nta0)
        nta_2c00 = bits2mask(%11, nta0)
        ppucr2 := $2001
        inb = bit2mask(7)
        ing = bit2mask(6)
        inr = bit2mask(5)
        sre = bit2mask(4)
        bre = bit2mask(3)
        scd = bit2mask(2)
        bcd = bit2mask(1)
        gse= bit2mask(0)
        ppusr := $2002
        vbl = bit2mask(7)
        s0h = bit2mask(6)
        sov = bit2mask(5)
        oamaddr := $2003
        oamdata := $2004
        ppuscroll := $2005
        ppuaddr := $2006
        ppuaddr := $2007
        oamdma := $4014
</pre>

Latest revision as of 22:09, 5 December 2010

PPU Register Overview

The PPU exposes only eight memory-mapped registers to the CPU. These nominally sit at $2000 through $2007 in the CPU's address space, but because they're incompletely decoded, they're mirrored in every 8 bytes from $2008 through $3FFF, so a write to $3456 is the same as a write to $2006.

PPU Registers
Address Name (Alt. Names?) Function
$2000 PPUCR1 PPUCTRL PCR PPU Control Register 1
$2001 PPUCR2 PPUMASK PPUMR PMR PPU Control Register 2
$2002 PPUSR PPUSTATUS PSR PPU Status Register
$2003 OAMAR OAMADDR OAR OAM Address Register
$2004 OAMDR OAMDATA ODR OAM Data Register
$2005 PPUSCR PPUSCROLL PSCR PPU Scroll Register
$2006 PPUAR PPUADDR PAR PPU Address Register
$2007 PPUDR PPUDATA PDR PPU Data Register
$4014 OAMDMA ODMA OAM DMA

PPUCR1: PPU Control Register 1

Bit 7 6 5 4 3 2 1 0
$2000 NMIE MSE SSZ BPT SPT VDN NTA1 NTA0
Read/Write W W W W W W W W
Initial Value 0 X 0 0 0 0 0 0

Bit 7 - NMIE: NMI Enable

Setting NMIE to one causes an NMI to be generated at the start of the vertical blanking interval.

Bit 6 - MSE: Master/Slave Enable

Has no effect on the NES.

Bit 5 - SSZ: Sprite Size

0: 8x8; 1: 8x16

Bit 4 - BPT: Background Pattern Table

Background pattern table address (0: $0000; 1: $1000)

Bit 3 - SPT: Sprite Pattern Table

Sprite pattern table address for 8x8 sprites (0: $0000; 1: $1000)

Bit 2 - VDN: VRAM Increment Down

VRAM address increment per CPU read/write of PPUDATA (0: increment by 1, going across; 1: increment by 32, going down)

Bits 1, 0 - NTA1 and NTA0: Base Nametable Address 1 and 0

NTA1 NTA0 Base VRAM Address
0 0 $2000 (Nametable 0)
0 1 $2400 (Nametable 1)
1 0 $2800 (Nametable 2)
1 1 $2C00 (Nametable 3)

PPUCR2: PPU Control Register 2

Bit 7 6 5 4 3 2 1 0
$2001 INB ING INR SRE BRE SCD BCD GSE
Read/Write W W W W W W W W
Initial Value 0 0 0 0 0 X X 0

Bit 7 - INB: Intensify Blues

Intensify blues and darken other colors.

Bit 6 - ING: Intensify Greens

Intensify greens and darken other colors.

Bit 5 - INR: Intensify Reds

Intensify reds and darken other colors.

Bit 4 - SRE: Sprite Render Enable

Enable sprite rendering.

Bit 3 - BRE: Background Render Enable

Enable background rendering.

Bit 2 - SCD: Sprite Clip Disable

Control sprite clipping in leftmost 8 pixels of screen (0: clip; 1: display).

Bit 1 - BCD: Background Clip Disable

Control background clipping in leftmost 8 pixels of screen (0: clip; 1: display).

Bit 0 - GSE: Grayscale Enable

0: normal color; 1: AND all palette entries with 0x30, effectively producing a monochrome display; note that colour emphasis STILL works when this is on!

PPUSR: PPU Status Register

Bit 7 6 5 4 3 2 1 0
$2002 VBL S0H SOV --- --- --- --- ---
Read/Write R R R R R R R R
Initial Value X 0 X X X X X X

Bit 7 - VBL: Vertical Blank

Bit 6 - S0H: Sprite 0 Hit

Bit 5 - SOV: Sprite Overflow

Bits 4..0 - Res: Reserved

CA65 Definitions

.define bit2mask(bitnum) (1 << bitnum)
.define bits2mask(bits, bitnum) (bits << bitnum)

        ;; PPU Registers
        ppucr1 := $2000
        nmie = bit2mask(7)
        mse  = bit2mask(6)
        ssz  = bit2mask(5)
        bpt  = bit2mask(4)
        spt  = bit2mask(3)
        vdn  = bit2mask(2)
        nta1 = bit2mask(1)
        nta0 = bit2mask(0)

        nta_2000 = bits2mask(%00, nta0)
        nta_2400 = bits2mask(%01, nta0)
        nta_2800 = bits2mask(%10, nta0)
        nta_2c00 = bits2mask(%11, nta0)

        ppucr2 := $2001
        inb = bit2mask(7)
        ing = bit2mask(6)
        inr = bit2mask(5)
        sre = bit2mask(4)
        bre = bit2mask(3)
        scd = bit2mask(2)
        bcd = bit2mask(1)
        gse= bit2mask(0)

        ppusr := $2002
        vbl = bit2mask(7)
        s0h = bit2mask(6)
        sov = bit2mask(5)

        oamaddr := $2003
        oamdata := $2004
        ppuscroll := $2005
        ppuaddr := $2006
        ppuaddr := $2007
        oamdma := $4014