aboutsummaryrefslogtreecommitdiff
path: root/ppu/memory.go
diff options
context:
space:
mode:
authorcrecher <crecher@crecher.net>2026-10-12 16:30:32 +0200
committercrecher <crecher@crecher.net>2026-10-12 16:30:32 +0200
commit0be10a289132f7ed9b42d5949db844227075e7ce (patch)
tree305a468b3c8e1fecb86c22bbe920c8140c46c3a0 /ppu/memory.go
parentf5969959b81bce1841974cedcac0289d44f7c69e (diff)
downloadgones-0be10a289132f7ed9b42d5949db844227075e7ce.tar.gz
gones-0be10a289132f7ed9b42d5949db844227075e7ce.zip
ITS ALIVE (not rly no image yet)
Diffstat (limited to 'ppu/memory.go')
-rw-r--r--ppu/memory.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/ppu/memory.go b/ppu/memory.go
new file mode 100644
index 0000000..3379242
--- /dev/null
+++ b/ppu/memory.go
@@ -0,0 +1,46 @@
+package ppu
+
+import "crecher.net/gones/v2/cart"
+
+// maps a $2000-$3EFF address onto an offset into the 2KB of nametable RAM,
+// according to the cartridge's mirroring mode. four-screen carts will be
+// expected to use their own extra 2KB of RAM via the mapper, but since no
+// implemented mapper does that yet, four-screen just falls back to the vertical
+// mirroring as a placeholder
+
+func (p *PPU) nametableOffset(addr uint16) int {
+ addr &= 0x0FFF
+ table := addr / 0x400
+ offset := int(addr % 0x400)
+
+ var page uint16
+ switch p.mirroring {
+ case cart.Horizontal:
+ page = table / 2
+ case cart.SingleScreenLower:
+ page = 0
+ case cart.SingleScreenUpper:
+ page = 1
+ default: // TODO: add correct four-screen behavior once four-screen carts are added
+ page = table % 2
+ }
+ return int(page)*0x400 + offset
+}
+
+// paletteIndex applies the $3F10/$3F14/$3F18/$3F1C -> $3F00/$3F04/$3F08/$3F0C
+// mirroring
+func paletteIndex(addr uint16) uint16 {
+ idx := addr & 0x1F
+ if idx >= 0x10 && idx%4 == 0 {
+ idx -= 0x10
+ }
+ return idx
+}
+
+func (p *PPU) readPalette(addr uint16) uint8 {
+ return p.palette[paletteIndex(addr)]
+}
+
+func (p *PPU) writePalette(addr uint16, v uint8) {
+ p.palette[paletteIndex(addr)] = v
+}