Пример #1
0
func NewPPU() *PPU {
	p := new(PPU)

	p.Memory = cpu.NewMemory()

	for i := 0; i < 4; i++ {
		p.Nametables[i] = NewNametable()
		nametable := p.Nametables[i]

		lower := cpu.Address(i * 0x400)
		upper := cpu.Address((i+1)*0x400 - 1)

		p.Memory.Mount(nametable, 0x2000+lower, 0x2000+upper)
		p.Memory.Mount(nametable, 0x3000+lower, 0x3000+upper)
	}

	p.Memory.Mount(NewVRAM(), 0x3f00, 0x3fff)

	// 256 pixels per scanline, and 240 scanlines, each pixel with three RGB
	// components
	p.Display = make([]byte, 256*3*240)

	p.Frame = 0
	p.Scanline = PRERENDER_SCANLINE

	return p
}
Пример #2
0
func TestNormalizeMirrorsPaletteIndexes(t *testing.T) {
	ram := new(VRAM)

	assert.Equal(t, ram.normalize(0x0020), cpu.Address(0x0000))
	assert.Equal(t, ram.normalize(0x0040), cpu.Address(0x0000))
	assert.Equal(t, ram.normalize(0x0060), cpu.Address(0x0000))
	assert.Equal(t, ram.normalize(0x00ff), cpu.Address(0x001f))
}
Пример #3
0
func (p *PPU) WriteVRAMAddr(val byte) {
	if p.AddressLatch {
		p.VRAMAddr = cpu.Address(val)<<8 | (0x00ff & p.VRAMAddr)
	} else {
		p.VRAMAddr = cpu.Address(val) | (0xff00 & p.VRAMAddr)
	}

	p.AddressLatch = !p.AddressLatch
}
Пример #4
0
func run(filename string) {
	var file *os.File
	var err error
	if file, err = os.Open(filename); err != nil {
		log.Fatal(err)
		return
	}

	var rom *nes.ROM
	rom, err = nes.ReadROM(file)
	if err != nil {
		log.Fatal(err)
		return
	}

	var machine = nes.NewMachine()
	machine.Insert(rom)

	machine.CPU.Debug = false
	machine.CPU.Reset()

	// First step until the tests start.
	for machine.CPU.Memory.Read(0x6000) != 0x80 {
		machine.CPU.Step()
	}

	machine.CPU.Cycle = func() {
		for i := 0; i < 3; i++ {
			machine.PPU.Step()
		}
	}

	parts := strings.Split(filename, string(filepath.Separator))
	fmt.Printf("Running %s tests...\n", parts[len(parts)-1])

	// Next step until the tests are finished.
	for machine.CPU.Memory.Read(0x6000) > 0x7f {
		machine.CPU.Step()

		if machine.CPU.Memory.Read(0x6000) == 0x81 {
			panic("Need to press reset, but isn't implemented")
		}
	}

	var output = ""
	for i := 0; machine.CPU.Memory.Read(cpu.Address(0x6004+i)) != 0x00; i++ {
		char := machine.CPU.Memory.Read(cpu.Address(0x6004 + i))
		output += fmt.Sprintf("%c", char)
	}

	if strings.Contains(output, "Passed") {
		fmt.Printf("Results: OK\n")
	} else {
		fmt.Printf("Results: FAIL\n")
		fmt.Printf("====\n%s====\n", output)
	}
}
Пример #5
0
func TestPPUDATAReadIncrementsVRAMAddrCorrectly(t *testing.T) {
	p := NewPPU()
	p.Memory.Mount(NewPatterntable(make([]byte, 0x1000)), 0x0000, 0x0fff)

	p.VRAMAddr = cpu.Address(0x0000)
	p.Ctrl.VRAMAddressInc = VRAM_INC_ACROSS
	p.Read(PPUDATA)

	assert.Equal(t, p.VRAMAddr, cpu.Address(0x0001))

	p.VRAMAddr = cpu.Address(0x0000)
	p.Ctrl.VRAMAddressInc = VRAM_INC_DOWN
	p.Read(PPUDATA)

	assert.Equal(t, p.VRAMAddr, cpu.Address(0x0020))
}
Пример #6
0
func TestPPUReadAt2007ReadsData(t *testing.T) {
	p := NewPPU()
	p.Memory.Mount(NewPatterntable(make([]byte, 0x1000)), 0x0000, 0x0fff)

	p.VRAMAddr = cpu.Address(0x0000)
	p.Memory.Write(0xbe, p.VRAMAddr)

	assert.Equal(t, p.Read(PPUDATA), byte(0xbe))
}
Пример #7
0
func TestPPUWritePPUAddr(t *testing.T) {
	p := NewPPU()

	p.AddressLatch = true
	p.Write(0xbe, PPUADDR)
	p.Write(0xef, PPUADDR)

	assert.Equal(t, p.VRAMAddr, cpu.Address(0xbeef))
}
Пример #8
0
func TestWriteVRAMAddr(t *testing.T) {
	p := NewPPU()

	p.AddressLatch = true
	p.WriteVRAMAddr(0xbe)
	p.WriteVRAMAddr(0xef)

	assert.Equal(t, p.VRAMAddr, cpu.Address(0xbeef))
}
Пример #9
0
func TestPPUWritePPUData(t *testing.T) {
	p := NewPPU()
	p.VRAMAddr = 0x0000
	p.Memory.Mount(NewPatterntable(make([]byte, 0x1000)), 0x0000, 0x0fff)

	p.Write(0xbe, PPUDATA)

	assert.Equal(t, p.Memory.Read(0x0000), byte(0xbe))
	assert.Equal(t, p.VRAMAddr, cpu.Address(0x0001))
}
Пример #10
0
func (n *Nametable) Attribute(x int, y int) uint8 {
	offset := cpu.Address(y/4*8 + x/4 + 0x3c0)

	attribs := n.Read(offset)

	xt := (x / 2) % 2
	yt := (y / 2) % 2

	bit_index := (yt * 2) + xt
	return (attribs >> uint(bit_index*2)) & 0x3
}
Пример #11
0
func (m *Machine) Insert(rom *ROM) {
	first := rom.Mapper.Patterntable(0)
	var err = m.PPU.Memory.Mount(first, 0x0000, 0x0fff)
	if err != nil {
		panic(err)
	}
	m.PPU.Patterntables[0] = first

	second := rom.Mapper.Patterntable(1)
	err = m.PPU.Memory.Mount(second, 0x1000, 0x1fff)
	if err != nil {
		panic(err)
	}
	m.PPU.Patterntables[1] = second

	err = m.CPU.Memory.Mount(rom.Mapper.Program(), 0x8000, 0xffff)
	if err != nil {
		panic(err)
	}

	m.CPU.PC = cpu.Address(m.CPU.Memory.Read(0xFFFC)) |
		(cpu.Address(m.CPU.Memory.Read(0xFFFD)) << 8)
}
Пример #12
0
func TestNormalizeMirrorsPPURegisters(t *testing.T) {
	p := NewPPU()

	assert.Equal(t, p.normalize(0x0008), cpu.Address(0x0000))
	assert.Equal(t, p.normalize(0x1456), cpu.Address(0x0006))
}
Пример #13
0
func (n *Nametable) TileIndex(x int, y int) uint8 {
	offset := cpu.Address(x + y*32)
	return n.Read(offset)
}