Support for searching references of memory address in code

This commit is contained in:
Yoshi Sugawara 2021-02-14 10:32:00 -10:00
parent 31c4370046
commit 04f65c9b1b
8 changed files with 322 additions and 36 deletions

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.user-fonts</key>
<array>
<string>app-usage</string>
<string>system-installation</string>
</array>
</dict>
</plist>

View File

@ -632,6 +632,7 @@
92A9D67425CC5B7D008F5031 /* DebugMemoryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMemoryButton.swift; sourceTree = "<group>"; };
92A9D67825CC5BB6008F5031 /* DebugMemoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMemoryCell.swift; sourceTree = "<group>"; };
92A9D67E25CC5C66008F5031 /* DebugMemoryActionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMemoryActionViewController.swift; sourceTree = "<group>"; };
92AF5B1325D1B7A00025578D /* ActiveGS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = ActiveGS.entitlements; path = ActiveGS/ActiveGS.entitlements; sourceTree = "<group>"; };
92B9EADD24D3369600E6CFB2 /* ActiveGS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ActiveGS-Bridging-Header.h"; sourceTree = "<group>"; };
92B9EADE24D3369700E6CFB2 /* EmulatorKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmulatorKeyboard.swift; sourceTree = "<group>"; };
92E2063125AADF6E00AE3F28 /* PreviewUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewUI.swift; sourceTree = "<group>"; };
@ -1072,6 +1073,7 @@
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
92AF5B1325D1B7A00025578D /* ActiveGS.entitlements */,
096604C819127DB700A22C51 /* activegs.plist */,
09052B4219053C9F00853FAE /* Libraries */,
09520D8516AEF8250065E84A /* Drivers */,
@ -1600,7 +1602,7 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_ENTITLEMENTS = ActiveGS/ActiveGS.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
@ -1625,7 +1627,7 @@
"$(inherited)",
"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/GraphicsServices.framework\"",
);
PRODUCT_BUNDLE_IDENTIFIER = com.activeGS.test;
PRODUCT_BUNDLE_IDENTIFIER = com.yoshisuga.activeGS;
PRODUCT_NAME = ActiveGS;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1645,7 +1647,7 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_ENTITLEMENTS = ActiveGS/ActiveGS.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
@ -1672,7 +1674,7 @@
"$(inherited)",
"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/GraphicsServices.framework\"",
);
PRODUCT_BUNDLE_IDENTIFIER = com.activeGS.test;
PRODUCT_BUNDLE_IDENTIFIER = com.yoshisuga.activeGS;
PRODUCT_NAME = ActiveGS;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1692,7 +1694,7 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_ENTITLEMENTS = ActiveGS/ActiveGS.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
@ -1716,7 +1718,7 @@
"$(inherited)",
"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/GraphicsServices.framework\"",
);
PRODUCT_BUNDLE_IDENTIFIER = com.activeGS.test;
PRODUCT_BUNDLE_IDENTIFIER = com.yoshisuga.activeGS;
PRODUCT_NAME = ActiveGS;
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -22,6 +22,9 @@ enum InterpreterError: Error {
public class Debug6502Interpreter: Bus {
public func read(from address: UInt16) throws -> UInt8 {
if address >= memory.count {
return 0
}
return memory[Int(address)]
}

View File

@ -0,0 +1,58 @@
//
// CheatFinderManager.swift
// ActiveGS
//
// Created by Yoshi Sugawara on 1/29/21.
//
import Foundation
class CheatFinderManager {
private(set) var matchedMemoryAddresses = [Int: UInt8]()
var comparisonMemory = [UInt8]()
enum UIState {
case initial, startedNewSearch, isSearching, didSearch
}
enum SearchMode {
case less, greater, same
case equalTo(Int)
}
var uiState = UIState.initial
func update(with memory: UnsafeMutablePointer<UInt8>) {
for address in 0..<0x95ff {
matchedMemoryAddresses[address] = memory[address]
}
}
func findNewMatches(searchMode: SearchMode) {
var newMatches = [Int: UInt8]()
for (address, oldValue) in matchedMemoryAddresses {
let newValue = comparisonMemory[address]
var matched = false
switch searchMode {
case .less:
matched = newValue < oldValue
case .greater:
matched = newValue > oldValue
case .same:
matched = newValue == oldValue
case .equalTo(let searchValue):
matched = newValue == searchValue
}
if matched {
newMatches[address] = newValue
}
}
matchedMemoryAddresses = newMatches
}
// start new search:
// put all memory into matched
//
// set less than
// run findNewMatches
}

View File

@ -12,6 +12,7 @@ class EmuMemoryModel {
let maxMemorySize = 128 * 1024
private(set) var memory = EmuWrapper.memory()
private(set) var referencedAddresses = [UInt16: [AddressedInstruction]]()
var selectedAddress: Int?
@ -71,6 +72,7 @@ class EmuMemoryModel {
}
print("Setting memory address %04X to %02X",address,value)
memory[address] = value
refresh()
}
func getMemory(at address:Int) -> UInt8 {
@ -96,11 +98,40 @@ class EmuMemoryModel {
}
lazy var interpretedInstructions: [AddressedInstruction] = {
let interpreter = Debug6502Interpreter(memory: memoryAsArray)
return interpreter.interpret()
return interpreted()
}()
private func interpreted() -> [AddressedInstruction] {
let interpreter = Debug6502Interpreter(memory: memoryAsArray)
let instructions = interpreter.interpret()
referencedAddresses = [UInt16: [AddressedInstruction]]()
let updateBlock: ((UInt16, AddressedInstruction) -> Void) = { address, instruction in
var instructions: [AddressedInstruction] = {
if let existingInstructions = self.referencedAddresses[address] {
return existingInstructions
}
return [AddressedInstruction]()
}()
instructions.append(instruction)
self.referencedAddresses[address] = instructions
}
for instruction in instructions {
switch instruction.instruction.addressingMode {
case .absolute(let address):
updateBlock(address, instruction)
case .zeroPage(let zeroPageAddress):
updateBlock(UInt16(zeroPageAddress), instruction)
case .indirect(let fromAddress):
updateBlock(fromAddress, instruction)
default:
break
}
}
return instructions
}
func refresh() {
memory = EmuWrapper.memory()
interpretedInstructions = interpreted()
}
}

View File

@ -13,6 +13,7 @@ protocol DebugMemoryActionViewControllerDelegate: class {
func updateMemory(at address: Int, with memory:UInt8)
var memory: UnsafeMutablePointer<UInt8>? { get }
var selectedAddress: Int? { get }
var referencedMemoryAddresses: [UInt16: [AddressedInstruction]] { get }
}
class DebugMemoryActionViewController: UIViewController {
@ -24,6 +25,8 @@ class DebugMemoryActionViewController: UIViewController {
var mode: Mode = .jumpToAddress
var cheatFinder = CheatFinderManager()
var matchedInstructions = [AddressedInstruction]()
weak var delegate:DebugMemoryActionViewControllerDelegate?
let segmentedControl: UISegmentedControl = {
@ -193,6 +196,16 @@ class DebugMemoryActionViewController: UIViewController {
button.widthAnchor.constraint(equalToConstant: 30).isActive = true
return button
}()
let findCodeButton: DebugMemoryButton = {
let button = DebugMemoryButton()
button.titleLabel?.font = UIFont(name: "Print Char 21", size: 9)
button.setTitle("Find in Code >", for: .normal)
button.setTitle("Cancel", for: .selected)
button.setTitleColor(.red, for: .selected)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
// lazy var cheatFinderSearchStackView: UIStackView = {
// let stackView = UIStackView(arrangedSubviews: [cheatFinderSearchLessButton, cheatFinderSearchGreaterButton])
@ -260,7 +273,7 @@ class DebugMemoryActionViewController: UIViewController {
cheatFinderPromptLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -48).isActive = true
cheatFinderMatchesTableView.topAnchor.constraint(equalTo: cheatFinderPromptLabel.bottomAnchor, constant: 4).isActive = true
cheatFinderMatchesTableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24).isActive = true
cheatFinderMatchesTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 24).isActive = true
cheatFinderMatchesTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24).isActive = true
cheatFinderMatchesTableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 8).isActive = true
[cheatFinderInitialActionsStackView, cheatFinderPromptLabel, cheatFinderMatchesTableView].forEach{ $0.isHidden = true }
}
@ -329,15 +342,14 @@ class DebugMemoryActionViewController: UIViewController {
// view.addSubview(memoryField)
view.addSubview(keyboardView)
titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16).isActive = true
titleLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 16).isActive = true
titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
segmentedControl.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8).isActive = true
segmentedControl.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor).isActive = true
editFieldsStackView.topAnchor.constraint(equalTo: segmentedControl.bottomAnchor, constant: 8).isActive = true
// memoryField.widthAnchor.constraint(equalToConstant: 80).isActive = true
// memoryField.heightAnchor.constraint(equalToConstant: 40).isActive = true
editFieldsStackView.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor).isActive = true
keyboardView.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor).isActive = true
editFieldsStackView.centerXAnchor.constraint(equalTo: keyboardView.centerXAnchor).isActive = true
keyboardView.topAnchor.constraint(equalTo: editFieldsStackView.bottomAnchor, constant: 8).isActive = true
// keyboardView.widthAnchor.constraint(equalToConstant: 200).isActive = true
keyboardView.heightAnchor.constraint(equalToConstant: 200).isActive = true
@ -349,16 +361,127 @@ class DebugMemoryActionViewController: UIViewController {
emulatorScreenView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16).isActive = true
emulatorScreenView.isHidden = true
view.backgroundColor = .black
view.backgroundColor = UIColor.init(red: 0.14, green: 0.13, blue: 0.14, alpha: 1)
}
// Jump tab: normal constraints
private var keyboardViewCenterXConstraint: NSLayoutConstraint!
private var findCodeButtonLeadingConstraint: NSLayoutConstraint!
private var findCodeButtonCenterYConstraint: NSLayoutConstraint!
private var findInCodeTableViewLeadingConstraintOutOfView: NSLayoutConstraint!
private var findInCodeTableViewBottomConstraintOutOfView: NSLayoutConstraint!
var jumpTabNormalModeConstraints: [NSLayoutConstraint] {
[
keyboardViewCenterXConstraint,
findCodeButtonLeadingConstraint,
findCodeButtonCenterYConstraint,
findInCodeTableViewLeadingConstraintOutOfView,
findInCodeTableViewBottomConstraintOutOfView
]
}
// Jump tab: find in code constraints
private var keyboardViewLeadingConstraint: NSLayoutConstraint!
private var findCodeButtonBottomConstraint: NSLayoutConstraint!
private var findCodeButtonCenterXConstraint: NSLayoutConstraint!
private var findInCodeTableViewLeadingConstraint: NSLayoutConstraint!
private var findInCodeTableViewTrailingConstraint: NSLayoutConstraint!
private var findInCodeTableViewBottomConstraint: NSLayoutConstraint!
var jumpTabFindInCodeConstraints: [NSLayoutConstraint] {
[
keyboardViewLeadingConstraint,
findCodeButtonBottomConstraint,
findInCodeTableViewLeadingConstraint,
findInCodeTableViewTrailingConstraint,
findCodeButtonCenterXConstraint,
findInCodeTableViewBottomConstraint
]
}
// Jump tab: find in code table
lazy var findInCodeResultsTableView: UITableView = {
let view = UITableView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .clear
view.dataSource = self
view.delegate = self
view.register(UITableViewCell.self, forCellReuseIdentifier: "FindInCodeResultsCell")
return view
}()
func findInCodeSetupView() {
view.addSubview(findCodeButton)
view.addSubview(findInCodeResultsTableView)
// Find Code Button Normal config
keyboardViewCenterXConstraint = keyboardView.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor)
findCodeButtonLeadingConstraint = findCodeButton.leadingAnchor.constraint(equalTo: keyboardView.trailingAnchor, constant: 8)
findCodeButtonCenterYConstraint = findCodeButton.centerYAnchor.constraint(equalTo: keyboardView.centerYAnchor)
findInCodeTableViewLeadingConstraintOutOfView = findInCodeResultsTableView.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 50)
findInCodeTableViewBottomConstraintOutOfView = findInCodeResultsTableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -8)
// Find Code Button Searching Config
keyboardViewLeadingConstraint = keyboardView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 8)
findCodeButtonBottomConstraint = findCodeButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 4)
findCodeButtonCenterXConstraint = findCodeButton.centerXAnchor.constraint(equalTo: findInCodeResultsTableView.centerXAnchor)
findInCodeTableViewBottomConstraint = findInCodeResultsTableView.bottomAnchor.constraint(equalTo: findCodeButton.topAnchor, constant: -4)
findInCodeResultsTableView.topAnchor.constraint(equalTo: segmentedControl.bottomAnchor, constant: 8).isActive = true
findInCodeTableViewLeadingConstraint = findInCodeResultsTableView.leadingAnchor.constraint(equalTo: keyboardView.trailingAnchor, constant: 8)
findInCodeTableViewTrailingConstraint = findInCodeResultsTableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8)
NSLayoutConstraint.deactivate(jumpTabFindInCodeConstraints)
NSLayoutConstraint.activate(jumpTabNormalModeConstraints)
findCodeButton.onTapped = { isSelected in
self.updateKeyboardPosition(isFindingCode: isSelected)
self.updateMatchedInstructions()
}
}
private func updateMatchedInstructions() {
if let delegate = delegate,
let text = memoryField.text,
let address = getAddressFromText(text) {
matchedInstructions = delegate.referencedMemoryAddresses[UInt16(address)] ?? [AddressedInstruction]()
findInCodeResultsTableView.reloadData()
}
}
private func updateKeyboardPosition(isFindingCode: Bool = false) {
let animator = UIViewPropertyAnimator(duration: 0.2, curve: .linear) {
if isFindingCode {
NSLayoutConstraint.deactivate(self.jumpTabNormalModeConstraints)
NSLayoutConstraint.activate(self.jumpTabFindInCodeConstraints)
} else {
NSLayoutConstraint.deactivate(self.jumpTabFindInCodeConstraints)
NSLayoutConstraint.activate(self.jumpTabNormalModeConstraints)
}
self.view.layoutIfNeeded()
}
animator.startAnimation()
}
override func viewDidLoad() {
super.viewDidLoad()
setupView()
cheatFinderSetupView()
findInCodeSetupView()
update()
}
func getAddressFromText(_ text: String?) -> UInt64? {
guard let text = text else {
return nil
}
let scanner = Scanner(string: text)
var address: UInt64 = 0
if scanner.scanHexInt64(&address) && address < 0x95ff {
return address
}
return nil
}
func updateTextField(with keyCode: Int) {
guard var text = memoryField.text else {
print("no text in address field!")
@ -378,11 +501,10 @@ class DebugMemoryActionViewController: UIViewController {
if text.count > charLimit {
text.removeFirst()
}
if mode == .jumpToAddress {
let scanner = Scanner(string: text)
var address: UInt64 = 0
if scanner.scanHexInt64(&address) && address < 0x95ff {
delegate?.jump(to: Int(address))
if mode == .jumpToAddress, let address = getAddressFromText(text) {
delegate?.jump(to: Int(address))
if findCodeButton.isSelected {
updateMatchedInstructions()
}
}
memoryField.text = text
@ -407,6 +529,8 @@ class DebugMemoryActionViewController: UIViewController {
func update() {
cheatFinderHide()
emulatorScreenView.isHidden = true
findCodeButton.isHidden = true
findInCodeResultsTableView.isHidden = true
switch mode {
case .jumpToAddress:
memoryField.isHidden = false
@ -416,9 +540,12 @@ class DebugMemoryActionViewController: UIViewController {
updateMemoryButton.isHidden = true
resetMemoryButton.isHidden = true
keyboardView.isHidden = false
findCodeButton.isHidden = false
findInCodeResultsTableView.isHidden = false
if let selectedAddress = delegate?.selectedAddress {
memoryField.text = String(format: "%04X", selectedAddress)
}
updateKeyboardPosition(isFindingCode: findCodeButton.isSelected)
case .changeMemory:
memoryField.isHidden = false
memoryField.layer.borderColor = UIColor.orange.cgColor
@ -430,6 +557,7 @@ class DebugMemoryActionViewController: UIViewController {
if let selectedAddress = delegate?.selectedAddress {
memoryField.text = delegate?.memoryHex(at: selectedAddress)
}
updateKeyboardPosition()
case .cheat:
memoryField.isHidden = true
editFieldsStackView.isHidden = true
@ -473,6 +601,7 @@ extension DebugMemoryActionViewController: EmulatorKeyboardKeyPressedDelegate {
extension DebugMemoryActionViewController: DebugMemoryViewControllerDelegate {
func refreshActionController() {
update()
updateMatchedInstructions()
}
func updateEmulatorScreen() {
let emulatorView = EmuWrapper.getEmulatorView()
@ -485,29 +614,49 @@ extension DebugMemoryActionViewController: DebugMemoryViewControllerDelegate {
extension DebugMemoryActionViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cheatFinder.matchedMemoryAddresses.keys.count
if tableView == findInCodeResultsTableView {
return matchedInstructions.count
} else {
return cheatFinder.matchedMemoryAddresses.keys.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CheatFinderMatchCell", for: indexPath)
let addresses = cheatFinder.matchedMemoryAddresses.keys
let index = addresses.index(addresses.startIndex, offsetBy: indexPath.row)
let address = addresses[index]
cell.textLabel?.text = String(format: "%04X",address)
cell.textLabel?.font = UIFont(name: "Print Char 21", size: 14)
cell.textLabel?.textColor = .red
cell.textLabel?.textAlignment = .center
return cell
if tableView == findInCodeResultsTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "FindInCodeResultsCell", for: indexPath)
let instruction = matchedInstructions[indexPath.row]
cell.textLabel?.text = instruction.description
cell.textLabel?.font = UIFont(name: "Print Char 21", size: 11)
cell.textLabel?.textColor = .yellow
cell.textLabel?.textAlignment = .center
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "CheatFinderMatchCell", for: indexPath)
let addresses = cheatFinder.matchedMemoryAddresses.keys
let index = addresses.index(addresses.startIndex, offsetBy: indexPath.row)
let address = addresses[index]
cell.textLabel?.text = String(format: "%04X: %02X",address,cheatFinder.matchedMemoryAddresses[address]!)
cell.textLabel?.font = UIFont(name: "Print Char 21", size: 14)
cell.textLabel?.textColor = .red
cell.textLabel?.textAlignment = .center
return cell
}
}
}
extension DebugMemoryActionViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let addresses = cheatFinder.matchedMemoryAddresses.keys
let index = addresses.index(addresses.startIndex, offsetBy: indexPath.row)
let address = addresses[index]
delegate?.jump(to: address)
tableView.deselectRow(at: indexPath, animated: true)
if tableView == findInCodeResultsTableView {
let instruction = matchedInstructions[indexPath.row]
let address = instruction.address
delegate?.jump(to: Int(address))
} else {
let addresses = cheatFinder.matchedMemoryAddresses.keys
let index = addresses.index(addresses.startIndex, offsetBy: indexPath.row)
let address = addresses[index]
delegate?.jump(to: address)
tableView.deselectRow(at: indexPath, animated: true)
}
}
}

View File

@ -219,10 +219,10 @@ protocol DebugMemoryViewControllerDelegate: class {
actionController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(actionController.view)
actionController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
actionControllerBottomConstraint = actionController.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 250)
actionControllerBottomConstraint = actionController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 250)
actionControllerBottomConstraint?.isActive = true
actionControllerHeightConstraint = actionController.view.heightAnchor.constraint(equalToConstant: 320)
actionControllerHeightConstraint = actionController.view.heightAnchor.constraint(equalToConstant: 380)
actionControllerLeadingToViewLeadingConstraint = actionController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor)
actionControllerTopToTableViewBottomConstraint = actionController.view.topAnchor.constraint(equalTo: dataTableView.bottomAnchor)
tableViewTrailingToViewTrailingConstraint = dataTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8)
@ -303,6 +303,17 @@ protocol DebugMemoryViewControllerDelegate: class {
framesSinceUpdateScreen += 1
}
func registerAppleIIFont() {
let fontUrl = Bundle.main.url(forResource: "PrintChar21", withExtension: "ttf")
CTFontManagerRegisterFontURLs([fontUrl] as CFArray, .persistent, true) { errors, done -> Bool in
if(done) {
print("Done installing custom font!")
}
print(errors as Array)
return true
}
}
override func viewDidLoad() {
super.viewDidLoad()
setupView()
@ -310,6 +321,7 @@ protocol DebugMemoryViewControllerDelegate: class {
setupTableView()
setupPauseResumeButton()
memoryViewModeControlChanged(memoryViewModeControl)
// registerAppleIIFont()
}
override func viewWillAppear(_ animated: Bool) {
@ -379,6 +391,9 @@ extension DebugMemoryViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == codeTableView {
let cell = tableView.dequeueReusableCell(withIdentifier: DebugMemoryCell.identifier, for: indexPath) as! DebugMemoryCell
if indexPath.row >= memoryModel.interpretedInstructions.count {
return cell
}
let instruction = memoryModel.interpretedInstructions[indexPath.row]
let values = [
instruction.instruction.mnemonic.description,
@ -461,6 +476,12 @@ extension DebugMemoryViewController: DebugMemoryActionViewControllerDelegate {
print("jumping to address: \(String(format: "%04X",address)) decimal: \(address)")
let indexPath = memoryModel.indexPath(for: address)
dataTableView.scrollToRow(at: indexPath, at: .middle, animated: true)
if let codeIndex = memoryModel.interpretedInstructions.firstIndex(where: { $0.address == address }) {
let indexPath = IndexPath(row: codeIndex, section: 0)
codeTableView.scrollToRow(at: indexPath, at: .middle, animated: true)
}
updateSelection(to: address)
}
func memoryHex(at address: Int) -> String {
@ -472,4 +493,7 @@ extension DebugMemoryViewController: DebugMemoryActionViewControllerDelegate {
var selectedAddress: Int? {
return memoryModel.selectedAddress
}
var referencedMemoryAddresses: [UInt16: [AddressedInstruction]] {
return memoryModel.referencedAddresses
}
}