SwiftNES/Sources/Data/Bus.swift

85 lines
2.7 KiB
Swift
Raw Normal View History

2024-07-19 21:52:46 -05:00
class Bus {
var cpuVram: [UInt8] = .init(repeating: 0, count: 2048)
2024-08-19 10:21:24 -05:00
var prgRom: [UInt8]
var ppu: NesPPU
2024-07-21 20:43:37 -05:00
2024-07-19 21:52:46 -05:00
fileprivate let RAM : UInt16 = 0x0000
fileprivate let RAM_MIRRORS_END: UInt16 = 0x1FFF
fileprivate let PPU_REGISTERS: UInt16 = 0x2000
fileprivate let PPU_REGISTERS_MIRRORS_END: UInt16 = 0x3FFF
2024-07-21 20:43:37 -05:00
fileprivate let ROM_ADDRESS_START: UInt16 = 0x8000
fileprivate let ROM_ADDRESS_END: UInt16 = 0xFFFF
init(_ rom: Rom) {
2024-08-19 10:21:24 -05:00
ppu = NesPPU(rom.character, rom.screenMirror)
self.prgRom = rom.program
2024-07-21 20:43:37 -05:00
}
2024-07-19 21:52:46 -05:00
}
extension Bus: Memory {
func memRead(_ addr: UInt16) -> UInt8 {
switch addr {
case RAM...RAM_MIRRORS_END:
let mirrorDownAddr = addr & 0b00000111_11111111
return self.cpuVram[Int(mirrorDownAddr)]
2024-08-19 10:21:24 -05:00
case 0x2000, 0x2001, 0x2003, 0x2005, 0x2006, 0x4014:
fatalError("Attempt to read from write-only PPU address \(addr)")
case 0x2002:
return ppu.readStatus()
case 0x2004:
return ppu.readOamData()
case 0x2007:
return ppu.readData()
case 0x2008...PPU_REGISTERS_MIRRORS_END:
2024-07-19 21:52:46 -05:00
let mirrorDownAddr = addr & 0b00100000_00000111;
2024-08-19 10:21:24 -05:00
return self.memRead(mirrorDownAddr)
2024-07-21 20:43:37 -05:00
case ROM_ADDRESS_START...ROM_ADDRESS_END:
return readProgramRom(addr)
2024-07-19 21:52:46 -05:00
default:
print("Ignoring mem access at \(addr)")
return 0
}
}
func memWrite(_ addr: UInt16, data: UInt8) {
switch addr {
case RAM...RAM_MIRRORS_END:
let mirrorDownAddr = addr & 0b11111111111
self.cpuVram[Int(mirrorDownAddr)] = data
2024-08-19 10:21:24 -05:00
case 0x2000:
ppu.writeToCtrl(data)
case 0x2001:
ppu.writeToMask(data)
case 0x2002:
fatalError("Attempt to write to PPU status register")
case 0x2003:
ppu.writeToOamAddr(data)
case 0x2004:
ppu.writeToOamData(data)
case 0x2005:
ppu.writeToScroll(data)
case 0x2006:
ppu.writeToPPUAddr(data)
case 0x2007:
ppu.writeToData(data)
case 0x2008...PPU_REGISTERS_MIRRORS_END:
2024-07-19 21:52:46 -05:00
let mirrorDownAddr = addr & 0b00100000_00000111
2024-08-19 10:21:24 -05:00
memWrite(mirrorDownAddr, data: data)
case ROM_ADDRESS_START...ROM_ADDRESS_END:
fatalError("Attempt to write to Cartridge ROM space: \(addr)")
2024-07-19 21:52:46 -05:00
default:
print("Ignorming mem-write at \(addr)")
}
}
2024-07-21 20:43:37 -05:00
func readProgramRom(_ addr: UInt16) -> UInt8 {
var addr = addr - 0x8000
2024-08-19 10:21:24 -05:00
if prgRom.count == 0x4000 && addr >= 0x4000 {
2024-07-21 20:43:37 -05:00
// rom mirroring
addr = addr % 0x4000
}
2024-08-19 10:21:24 -05:00
return prgRom[Int(addr)]
2024-07-21 20:43:37 -05:00
}
2024-07-19 21:52:46 -05:00
}