func NewRP2A03(apuFrequency int) *RP2A03 { mem := NewMappedMemory(m65go2.NewBasicMemory(m65go2.DefaultMemorySize)) mirrors := make(map[uint32]uint32) // Mirrored 2KB internal RAM for i := uint32(0x0800); i <= 0x1fff; i++ { mirrors[i] = i % 0x0800 } // Mirrored PPU registers for i := uint32(0x2008); i <= 0x3fff; i++ { mirrors[i] = 0x2000 + (i & 0x0007) } mem.AddMirrors(mirrors) cpu := m65go2.NewM6502(mem) cpu.DisableDecimalMode() apu := NewAPU(mem, uint64(1789773/apuFrequency), cpu.InterruptLine(m65go2.Irq)) // APU memory maps mem.AddMappings(apu, CPU) dma := NewDMA(mem) // DMA memory maps mem.AddMappings(dma, CPU) return &RP2A03{ Memory: mem, M6502: cpu, APU: apu, DMA: dma, } }
func NewOAM() *OAM { cycleFuncs := []CycleFunc{ ClearBuffer: clearBuffer, CopyYPosition: copyYPosition, CopyIndex: copyIndex, CopyAttributes: copyAttributes, CopyXPosition: copyXPosition, EvaluateYPosition: evaluateYPosition, EvaluateIndex: evaluateIndex, EvaluateAttributes: evaluateAttributes, EvaluateXPosition: evaluateXPosition, FailCopyYPosition: failCopyYPosition, } return &OAM{ BasicMemory: m65go2.NewBasicMemory(256), Buffer: m65go2.NewBasicMemory(32), SpriteZeroInBuffer: false, cycleFuncs: cycleFuncs, WriteCycle: FailCopyYPosition, } }
func NewRP2C02(interrupt func(bool), region string) *RP2C02 { mem := rp2ago3.NewMappedMemory(m65go2.NewBasicMemory(m65go2.DefaultMemorySize)) mirrors := make(map[uint32]uint32) // Mirrored nametables for i := uint32(0x3000); i <= 0x3eff; i++ { mirrors[i] = i - 0x1000 } // Mirrored palette for _, i := range []uint32{0x3f10, 0x3f14, 0x3f18, 0x3f1c} { mirrors[i] = i - 0x0010 } for i := uint32(0x3f20); i <= 0x3fff; i++ { mirrors[i] = 0x3f00 + (i & 0x001f) } nametable := NewNametable() mem.AddMappings(nametable, rp2ago3.PPU) mem.AddMirrors(mirrors) ppu := &RP2C02{ colors: make([]uint8, 0xf000), Memory: mem, Nametable: nametable, Interrupt: interrupt, OAM: NewOAM(), ShowBackground: true, ShowSprites: true, PAL: region == "PAL", } if !ppu.PAL { ppu.NumScanlines = NumScanlinesNTSC ppu.PreRenderScanline = PreRenderScanlineNTSC } else { ppu.NumScanlines = NumScanlinesPAL ppu.PreRenderScanline = PreRenderScanlinePAL } ppu.initCycleJumpTable() mem.AddMappings(ppu, rp2ago3.PPU) return ppu }