Advertisement
Guest User

Untitled

a guest
Jul 17th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 2.27 KB | None | 0 0
  1. // GamePak, A Class That Emulates An NES Game Pak
  2. // Copyright (C) 2018 Sam Breadman
  3.  
  4. import Foundation
  5.  
  6. public class GamePak {
  7.  
  8.     var prgData: [UInt8]
  9.     var prgBankCount: Int
  10.     var lowPrgBankIndex: Int
  11.     var highPrgBankIndex: Int
  12.    
  13.     var sramData: [UInt8]
  14.     let hasBattery: Bool
  15.    
  16.     var chrData: [UInt8]
  17.     let mirrorType: UInt8
  18.  
  19.     public init(_ fileName: String) {
  20.  
  21.         let fileUrl = Bundle.main.url(forResource: fileName, withExtension: "nes")
  22.         let fileData = try! Data(contentsOf: fileUrl!)
  23.  
  24.         let prgDataSize = Int(fileData[0x4]) * 0x4000
  25.         self.prgData = Array(repeating: 0x0, count: prgDataSize)
  26.         for i in 0x0..<prgDataSize {
  27.             prgData[i] = fileData[0x10 + i]
  28.         }
  29.         self.prgBankCount = prgData.count / 0x4000
  30.         self.lowPrgBankIndex = 0x0
  31.         self.highPrgBankIndex = self.prgBankCount - 0x1
  32.  
  33.         self.sramData = Array(repeating: 0x0, count: 0x1FFF)
  34.  
  35.         self.hasBattery = (fileData[0x6] >> 0x1) & 0x1 == 0x1
  36.  
  37.         let chrDataSize = Int(fileData[0x5]) * 0x2000
  38.         self.chrData = Array(repeating: 0x0, count: chrDataSize)
  39.         for i in 0x0..<chrDataSize {
  40.             chrData[i] = fileData[0x10 + prgDataSize + i]
  41.         }
  42.  
  43.         let lowMirrorTypeNibble: UInt8 = fileData[0x6] & 0x1
  44.         let highMirrorTypeNibble: UInt8 = (fileData[0x6] >> 0x3) & 0x1
  45.         self.mirrorType = lowMirrorTypeNibble | (highMirrorTypeNibble << 0x1)
  46.        
  47.     }
  48.  
  49.     public func read(fromAddress address: UInt16) -> (UInt8) {
  50.  
  51.         if address < 0x2000 {
  52.             return self.chrData[Int(address)]
  53.         } else if address >= 0xC000 {
  54.             let index = self.highPrgBankIndex * 0x4000 + Int(address - 0xC000)
  55.             return self.prgData[index]
  56.         } else if address >= 0x8000 {
  57.             let index = self.lowPrgBankIndex * 0x4000 + Int(address - 0x8000)
  58.             return self.prgData[index]
  59.         } else if address >= 0x6000 {
  60.             let index = Int(address) - 0x6000
  61.             return sramData[index]
  62.         } else {
  63.             fatalError("Attempt to read outside mapper bounds")
  64.         }
  65.  
  66.     }
  67.  
  68.     public func write(_ value: UInt8, toAddress address: UInt16) {
  69.  
  70.         if address < 0x2000 {
  71.             self.chrData[Int(address)] = value
  72.         } else if address >= 0x8000 {
  73.             self.lowPrgBankIndex = Int(value) % self.prgBankCount
  74.         } else if address >= 0x6000 {
  75.             let index = Int(address) - 0x6000
  76.             sramData[index] = value
  77.         } else {
  78.             fatalError("Attempt to write outside mapper bounds")
  79.         }
  80.    
  81.     }
  82.    
  83. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement