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 }