User:Ddribin/PPU Sandbox: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(Rename registers)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
== PPU Register Overview ==
== 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"
{| class="wikitable" border="1" cellspacing="0" cellpadding="3"
|+ PPU Registers
|-
|-
! Address !! Register Name !! (Alt. Name?) !! Function
! Address !! Name !! (Alt. Names?) !! Function
|-
|-
| $2000 || [[#PPUCTRL|PPUCTRL]] || PPUCR ||  PPU Control Register
| $2000 || [[#PPUCR1|PPUCR1]] || PPUCTRL PCR ||  PPU Control Register 1
|-
|-
| $2001 || [[#PPUMASK|PPUMASK]] || PPUMR  || PPU Mask Register
| $2001 || [[#PPUCR1|PPUCR2]] || PPUMASK PPUMR  PMR || PPU Control Register 2
|-
|-
| $2002 || [[#PPUSTATUS|PPUSTATUS]] || PPUSR || PPU Status Register
| $2002 || [[#PPUSR|PPUSR]] || PPUSTATUS PSR || PPU Status Register
|-
|-
| $2003 || OAMADDR || OAMAR || OAM Address Register
| $2003 || OAMAR || OAMADDR OAR || OAM Address Register
|-
|-
| $2004 || OAMDATA || OAMDR  || OAM Data Register
| $2004 || OAMDR || OAMDATA ODR || OAM Data Register
|-
|-
| $2005 || PPUSCROLL || PPUSCR || PPU Scroll Register
| $2005 || PPUSCR || PPUSCROLL PSCR || PPU Scroll Register
|-  
|-  
| $2006 || PPUADDR || PPUAR || PPU Address Register
| $2006 || PPUAR || PPUADDR PAR || PPU Address Register
|-
|-
| $2007 || PPUDATA || PPUDR || PPU Data Register
| $2007 || PPUDR || PPUDATA PDR || PPU Data Register
|-
|-
| $4014 || OAMDMA || OAMDMA || OAM DMA
| $4014 || OAMDMA || ODMA || OAM DMA
|}
|}


== <span id="PPUCTRL">PPUCTRL</span>: PPU Control Register ==
== <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 40: Line 44:


=== Bit 7 - NMIE<nowiki>:</nowiki> NMI Enable ===
=== Bit 7 - NMIE<nowiki>:</nowiki> NMI Enable ===
Setting NMI to one causes an NMI to be generated at the start of the  vertical blanking interval
Setting NMIE to one causes an NMI to be generated at the start of the  vertical blanking interval.


=== Bit 6 - MSE<nowiki>:</nowiki> Master/Slave Enable ===
=== Bit 6 - MSE<nowiki>:</nowiki> Master/Slave Enable ===
Line 71: Line 75:
|}
|}


== PPUMASK ==
== <span id="PPUCR2">PPUCR2</span>: PPU Control Register 2 ==


{| 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 78: Line 82:
|-
|-
! $2001
! $2001
| INB || ING || INR || SRE || BRE || SCD || BCD || GRYE
| INB || ING || INR || SRE || BRE || SCD || BCD || GSE
|-
|-
! Read/Write
! Read/Write
Line 87: Line 91:
|}
|}


; Bit 7 - INB<nowiki>:</nowiki> Intensify Blues
=== Bit 7 - INB<nowiki>:</nowiki> Intensify Blues ===


; Bit 6 - ING<nowiki>:</nowiki> Intensify Greens
Intensify blues and darken other colors.


; Bit 5 - INR<nowiki>:</nowiki> Intensify Reds
=== Bit 6 - ING<nowiki>:</nowiki> Intensify Greens ===


; Bit 4 - SRE<nowiki>:</nowiki> Sprite Render Enable
Intensify greens and darken other colors.


; Bit 3 - BRE<nowiki>:</nowiki> Background Render Enable
=== Bit 5 - INR<nowiki>:</nowiki> Intensify Reds ===


; Bit 2 - SCD<nowiki>:</nowiki> Sprite Clip Disable
Intensify reds and darken other colors.


; Bit 1 - BCD<nowiki>:</nowiki> Background Clip Disable
=== Bit 4 - SRE<nowiki>:</nowiki> Sprite Render Enable ===


; Bit 0 - GRYE<nowiki>:</nowiki> Grayscale Enable
Enable sprite rendering.


=== Bit 3 - BRE<nowiki>:</nowiki> Background Render Enable ===


== PPUSTATUS ==
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"
{| class="wikitable" style="text-align:center;" border="1" cellspacing="0" cellpadding="3"
Line 120: Line 139:
|}
|}


; Bit 7 - VBL<nowiki>:</nowiki> Vertical Blank  
=== Bit 7 - VBL: Vertical Blank ===


; Bit 6 - S0H<nowiki>:</nowiki> Sprite 0 Hit
=== Bit 6 - S0H: Sprite 0 Hit ===


; Bit 5 - SOV<nowiki>:</nowiki> Sprite Overflow
=== Bit 5 - SOV: Sprite Overflow ===


; Bits 4..0 - Res<nowiki>:</nowiki> Reserved
=== Bits 4..0 - Res: Reserved ===


== CA65 Definitions ==
== CA65 Definitions ==
Line 135: Line 154:


         ;; PPU Registers
         ;; PPU Registers
         ppuctrl := $2000
         ppucr1 := $2000
         ppumask := $2001
         nmie = bit2mask(7)
         ppustatus := $2002
        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
         oamaddr := $2003
         oamdata := $2004
         oamdata := $2004
Line 144: Line 190:
         ppuaddr := $2007
         ppuaddr := $2007
         oamdma := $4014
         oamdma := $4014
        ppuctrl_nmie = bit2mask(7)
        ppuctrl_mse = bit2mask(6)
        ppuctrl_ssz = bit2mask(5)
        ppuctrl_bpt = bit2mask(4)
        ppuctrl_spt = bit2mask(3)
        ppuctrl_vdn = bit2mask(2)
        ppuctrl_nta1 = bit2mask(1)
        ppuctrl_nta0 = bit2mask(0)
        ppuctrl_nta_2000 = bits2mask(%00, ppuctrl_nta0)
        ppuctrl_nta_2400 = bits2mask(%01, ppuctrl_nta0)
        ppuctrl_nta_2800 = bits2mask(%10, ppuctrl_nta0)
        ppuctrl_nta_2c00 = bits2mask(%11, ppuctrl_nta0)
       
        ppumask_inb = bit2mask(7)
        ppumask_ing = bit2mask(6)
        ppumask_inr = bit2mask(5)
        ppumask_sre = bit2mask(4)
        ppumask_bre = bit2mask(3)
        ppumask_scd = bit2mask(2)
        ppumask_bcd = bit2mask(1)
        ppumask_gry = bit2mask(0)
        ppustatus_vbl = bit2mask(7)
        ppustatus_s0h = bit2mask(6)
        ppustatus_sov = bit2mask(5)
</pre>
</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