From f0b3dcd95b6c807e8d5e0e011b1d29482ca9d8e5 Mon Sep 17 00:00:00 2001 From: Candygoblen123 Date: Fri, 10 May 2024 23:06:45 -0400 Subject: [PATCH] add LDA, STA, TAX, INX, BRK --- .gitignore | 8 ++ Package.swift | 15 ++++ Sources/CPU.swift | 182 ++++++++++++++++++++++++++++++++++++++++++ Sources/main.swift | 7 ++ Sources/opcodes.swift | 38 +++++++++ Tests/CPU.swift | 72 +++++++++++++++++ 6 files changed, 322 insertions(+) create mode 100644 .gitignore create mode 100644 Package.swift create mode 100644 Sources/CPU.swift create mode 100644 Sources/main.swift create mode 100644 Sources/opcodes.swift create mode 100644 Tests/CPU.swift diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0023a53 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..2921c5d --- /dev/null +++ b/Package.swift @@ -0,0 +1,15 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SwiftNES", + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "SwiftNES"), + .testTarget(name: "SwiftNESTests", dependencies: ["SwiftNES"]) + ] +) diff --git a/Sources/CPU.swift b/Sources/CPU.swift new file mode 100644 index 0000000..97fed05 --- /dev/null +++ b/Sources/CPU.swift @@ -0,0 +1,182 @@ + + +enum AddressingMode { + case Immediate + case ZeroPage + case ZeroPage_X + case ZeroPage_Y + case Absolute + case Absolute_X + case Absolute_Y + case Indirect_X + case Indirect_Y + case NoneAddressing +} + +class CPU { + var register_a: UInt8 = 0 + var register_x: UInt8 = 0 + var register_y: UInt8 = 0 + + var status: UInt8 = 0 + var programCounter: UInt16 = 0 + private var memory = [UInt8](repeating: 0, count: 0xFFFF) + + + func getOpperandAddress(_ mode: AddressingMode) -> UInt16 { + switch mode { + case .Immediate: + return programCounter + case .ZeroPage: + return UInt16(memRead(programCounter)) + case .Absolute: + return memReadU16(programCounter) + case .ZeroPage_X: + let pos = memRead(programCounter) + let addr = pos &+ register_x + return UInt16(addr) + case .ZeroPage_Y: + let pos = memRead(programCounter) + let addr = pos &+ register_y + return UInt16(addr) + case .Absolute_X: + let base = memReadU16(programCounter) + return base &+ UInt16(register_x) + case .Absolute_Y: + let base = memReadU16(programCounter) + return base &+ UInt16(register_y) + case .Indirect_X: + let base = memRead(programCounter) + + let ptr = UInt8(base) &+ register_x + let lo = memRead(UInt16(ptr)) + let hi = memRead(UInt16(ptr &+ 1)) + return UInt16(hi) << 8 | UInt16(lo) + case .Indirect_Y: + let base = memRead(programCounter) + + let lo = memRead(UInt16(base)) + let hi = memRead(UInt16(base &+ 1)) + let deref_base = UInt16(hi) << 8 | UInt16(lo) + let deref = deref_base &+ UInt16(register_y) + return deref + case .NoneAddressing: + fatalError("mode \(mode) is not implemented") + } + } + + func memRead(_ addr: UInt16) -> UInt8 { + memory[Int(addr)] + } + + func memReadU16(_ addr: UInt16) -> UInt16 { + let lo = UInt16(memRead(addr)) + let hi = UInt16(memRead(addr + 1)) + return (hi << 8) | lo + } + + func memWriteU16(addr: UInt16, data: UInt16) { + let hi = UInt8(data >> 8) + let lo = UInt8(data & 0xff) + self.memWrite(addr: addr, data: lo) + self.memWrite(addr: addr + 1, data: hi) + } + + func memWrite(addr: UInt16, data: UInt8) { + memory[Int(addr)] = data + } + + func reset() { + register_a = 0 + register_x = 0 + register_y = 0 + status = 0 + + programCounter = self.memReadU16(0xFFFC) + } + + func loadAndRun(_ program: [UInt8]) { + load(program) + reset() + run() + } + + func load(_ program: [UInt8]) { + memory[0x8000 ..< (0x8000 + program.count)] = program[0..