From 04f65c9b1b8244b21e17e677b3a8c92c3f0aefb8 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 14 Feb 2021 10:32:00 -1000 Subject: [PATCH] Support for searching references of memory address in code --- ActiveGS_iOS/ActiveGS/ActiveGS.entitlements | 11 + .../activegs.xcodeproj/project.pbxproj | 14 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../Debug6502Interpreter.swift | 3 + .../Debugger/CheatFinderManager.swift | 58 +++++ Common.iphone/Debugger/EmuMemoryModel.swift | 37 +++- .../DebugMemoryActionViewController.swift | 199 +++++++++++++++--- .../DebugMemoryViewController.swift | 28 ++- 8 files changed, 322 insertions(+), 36 deletions(-) create mode 100644 ActiveGS_iOS/ActiveGS/ActiveGS.entitlements create mode 100644 ActiveGS_iOS/activegs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Common.iphone/Debugger/CheatFinderManager.swift diff --git a/ActiveGS_iOS/ActiveGS/ActiveGS.entitlements b/ActiveGS_iOS/ActiveGS/ActiveGS.entitlements new file mode 100644 index 0000000..8b1b443 --- /dev/null +++ b/ActiveGS_iOS/ActiveGS/ActiveGS.entitlements @@ -0,0 +1,11 @@ + + + + + com.apple.developer.user-fonts + + app-usage + system-installation + + + diff --git a/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj b/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj index cc35ee8..ba7619e 100644 --- a/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj +++ b/ActiveGS_iOS/activegs.xcodeproj/project.pbxproj @@ -632,6 +632,7 @@ 92A9D67425CC5B7D008F5031 /* DebugMemoryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMemoryButton.swift; sourceTree = ""; }; 92A9D67825CC5BB6008F5031 /* DebugMemoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMemoryCell.swift; sourceTree = ""; }; 92A9D67E25CC5C66008F5031 /* DebugMemoryActionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMemoryActionViewController.swift; sourceTree = ""; }; + 92AF5B1325D1B7A00025578D /* ActiveGS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = ActiveGS.entitlements; path = ActiveGS/ActiveGS.entitlements; sourceTree = ""; }; 92B9EADD24D3369600E6CFB2 /* ActiveGS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ActiveGS-Bridging-Header.h"; sourceTree = ""; }; 92B9EADE24D3369700E6CFB2 /* EmulatorKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmulatorKeyboard.swift; sourceTree = ""; }; 92E2063125AADF6E00AE3F28 /* PreviewUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewUI.swift; sourceTree = ""; }; @@ -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 = ""; diff --git a/ActiveGS_iOS/activegs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ActiveGS_iOS/activegs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ActiveGS_iOS/activegs.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Common.iphone/Debugger/65C02Interpreter/Debug6502Interpreter.swift b/Common.iphone/Debugger/65C02Interpreter/Debug6502Interpreter.swift index ae375c6..ecd0815 100644 --- a/Common.iphone/Debugger/65C02Interpreter/Debug6502Interpreter.swift +++ b/Common.iphone/Debugger/65C02Interpreter/Debug6502Interpreter.swift @@ -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)] } diff --git a/Common.iphone/Debugger/CheatFinderManager.swift b/Common.iphone/Debugger/CheatFinderManager.swift new file mode 100644 index 0000000..c5762d3 --- /dev/null +++ b/Common.iphone/Debugger/CheatFinderManager.swift @@ -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) { + 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 +} diff --git a/Common.iphone/Debugger/EmuMemoryModel.swift b/Common.iphone/Debugger/EmuMemoryModel.swift index 1f8dfca..2c379cf 100644 --- a/Common.iphone/Debugger/EmuMemoryModel.swift +++ b/Common.iphone/Debugger/EmuMemoryModel.swift @@ -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() } } diff --git a/Common.iphone/Debugger/ViewControllers/DebugMemoryActionViewController.swift b/Common.iphone/Debugger/ViewControllers/DebugMemoryActionViewController.swift index 8c269be..3be117d 100644 --- a/Common.iphone/Debugger/ViewControllers/DebugMemoryActionViewController.swift +++ b/Common.iphone/Debugger/ViewControllers/DebugMemoryActionViewController.swift @@ -13,6 +13,7 @@ protocol DebugMemoryActionViewControllerDelegate: class { func updateMemory(at address: Int, with memory:UInt8) var memory: UnsafeMutablePointer? { 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) + } } } diff --git a/Common.iphone/Debugger/ViewControllers/DebugMemoryViewController.swift b/Common.iphone/Debugger/ViewControllers/DebugMemoryViewController.swift index 82057f7..cae32ae 100644 --- a/Common.iphone/Debugger/ViewControllers/DebugMemoryViewController.swift +++ b/Common.iphone/Debugger/ViewControllers/DebugMemoryViewController.swift @@ -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 + } }