aboutsummaryrefslogtreecommitdiff
path: root/ppu/ppu.go
diff options
context:
space:
mode:
authorcrecher <crecher@crecher.net>2026-10-12 22:08:09 +0200
committercrecher <crecher@crecher.net>2026-10-12 22:08:09 +0200
commit96ff6d8eda2ba434682909f4ff4ce350d78b2273 (patch)
treefc1982c54420254ef82c588b742d7ecacfbe7d48 /ppu/ppu.go
parent84801d18b9885c6d70914c67a76d8ac8e3b2b20d (diff)
downloadgones-96ff6d8eda2ba434682909f4ff4ce350d78b2273.tar.gz
gones-96ff6d8eda2ba434682909f4ff4ce350d78b2273.zip
ppu: add background rendering
cmd/gones: add sdl2 frontend
Diffstat (limited to 'ppu/ppu.go')
-rw-r--r--ppu/ppu.go24
1 files changed, 20 insertions, 4 deletions
diff --git a/ppu/ppu.go b/ppu/ppu.go
index cfc3620..322cf3d 100644
--- a/ppu/ppu.go
+++ b/ppu/ppu.go
@@ -5,10 +5,13 @@ import "crecher.net/gones/v2/cart"
const (
ctrlNametableMask = 0x03
ctrlIncrement32 = 0x04
+ ctrlBGPatternHigh = 0x10
ctrlNMIEnable = 0x80
- maskShowBackground = 0x08
- maskShowSprites = 0x10
+ maskGreyscale = 0x01
+ maskShowBackgroundLeft = 0x02
+ maskShowBackground = 0x08
+ maskShowSprites = 0x10
statusOverflow = 0x20
statusSprite0 = 0x40
@@ -43,6 +46,19 @@ type PPU struct {
Dot int
Frame uint64
+ // finished pixels as ARGB8888
+ framebuffer [ScreenWidth * ScreenHeight]uint32
+
+ // background pipeline, see https://www.nesdev.org/wiki/PPU_rendering
+ // next* hold the bytes fetched for the tile after the one being drawn
+ nextTileID uint8
+ nextAttr uint8
+ nextPatternLo uint8
+ nextPatternHi uint8
+ // shifters, the top bit (minus fine x) is the pixel being drawn
+ patternLo, patternHi uint16
+ attrLo, attrHi uint16
+
nmiOutput bool // PPUCTRL bit 7
nmiLine bool // vblank && nmiOutput, latched each tick for edge detection
nmiPending bool // set on nmiLine's rising edge, consumed by PollNMI
@@ -75,10 +91,10 @@ func (p *PPU) updateNMILine() {
p.nmiLine = current
}
-// advances PPU by one dot, right now only tracks the dot/scanline position and the vblank flag/NMI line,
-// which is enough to just validate the timings.
+// advances PPU by one dot
func (p *PPU) Tick() {
p.advanceDot()
+ p.renderTick()
switch {
case p.Scanline == 241 && p.Dot == 1: