mirror of
https://github.com/trudnai/Steve2.git
synced 2025-04-07 20:37:12 +00:00
Binary search for breakpoints
This commit is contained in:
parent
6ebb350ec3
commit
042cbb54d4
@ -750,6 +750,7 @@
|
||||
32D08987291A450400F2B486 /* 6502_bp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 6502_bp.h; sourceTree = "<group>"; };
|
||||
32D08992291AF23500F2B486 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = A2Mac/Base.lproj/Debug.storyboard; sourceTree = "<group>"; };
|
||||
32D089D7291E1BF800F2B486 /* DisassView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisassView.swift; sourceTree = "<group>"; };
|
||||
32D089EC291EE19200F2B486 /* UnfairLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnfairLock.swift; sourceTree = "<group>"; };
|
||||
32DBF7632334657900DD50E7 /* HiRes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiRes.swift; sourceTree = "<group>"; };
|
||||
32DBF76723373FB400DD50E7 /* disassembler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = disassembler.h; sourceTree = "<group>"; };
|
||||
32E21BE62491BF8B006C0C72 /* apple-rainbow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apple-rainbow.png"; sourceTree = "<group>"; };
|
||||
@ -1173,6 +1174,7 @@
|
||||
children = (
|
||||
32BFFB5E22EACC660003B53F /* Assets.xcassets */,
|
||||
32B18438233FAB3900DBB4AB /* verticies.swift */,
|
||||
32D089EC291EE19200F2B486 /* UnfairLock.swift */,
|
||||
32BFFB5A22EACC630003B53F /* AppDelegate.swift */,
|
||||
32B3778E291787CA0040845B /* NSLayoutConstraint.swift */,
|
||||
32100A8A2875387300D894EE /* CheatMenu.swift */,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -50,7 +50,7 @@ class DebuggerViewController: NSViewController {
|
||||
// // Update window title with the active TableView Title
|
||||
// self.parent?.view.window?.title = self.title!
|
||||
|
||||
Update()
|
||||
UpdateImmediately()
|
||||
|
||||
if let debugger = DebuggerWindowController.current {
|
||||
debugger.PauseButtonUpdate(needUpdateMainToolbar: false)
|
||||
@ -242,7 +242,7 @@ N V - B D I Z C
|
||||
|
||||
|
||||
func getLine(inView view: NSTextView, forY: CGFloat) -> Int {
|
||||
var scrollTo = view.visibleRect.origin
|
||||
// var scrollTo = view.visibleRect.origin
|
||||
let lineSpacing = CGFloat(1.5)
|
||||
let lineHeight = view.font!.pointSize * lineSpacing
|
||||
|
||||
@ -328,6 +328,7 @@ N V - B D I Z C
|
||||
}
|
||||
|
||||
|
||||
let textViewMouseYOffset = CGFloat(-4.0)
|
||||
func convertMouseCoordinates(scrollView : NSView, display : NSTextView, mouseLocation : NSPoint) -> NSPoint {
|
||||
var location = mouseLocation
|
||||
let parent_frame = scrollView.superview?.frame
|
||||
@ -338,7 +339,7 @@ N V - B D I Z C
|
||||
let maxY = minY + scrollView.frame.height
|
||||
|
||||
// location.x = maxX - location.x
|
||||
location.y = maxY - location.y + display.visibleRect.origin.y
|
||||
location.y = maxY - location.y + display.visibleRect.origin.y + textViewMouseYOffset
|
||||
|
||||
return location
|
||||
}
|
||||
@ -411,7 +412,6 @@ N V - B D I Z C
|
||||
|
||||
|
||||
func DisplayDisassembly( scrollY : CGFloat = -1 ) {
|
||||
let m6502_saved = m6502
|
||||
var disass = ""
|
||||
|
||||
line_number = 0
|
||||
@ -423,14 +423,15 @@ N V - B D I Z C
|
||||
|
||||
// TODO: Also check if memory area updated!
|
||||
|
||||
var need_disass = m6502.PC < disass_addr || m6502.PC > disass_addr + disass_addr_max
|
||||
line_number_at_PC = getLine(forAddr: m6502_saved.PC)
|
||||
var need_disass = m6502.PC <= disass_addr || m6502.PC > disass_addr + disass_addr_max
|
||||
line_number_at_PC = getLine(forAddr: m6502.PC)
|
||||
|
||||
// if m6502.PC > disass_addr && m6502.PC < disass_addr + disass_addr_max {
|
||||
if line_number_at_PC != 0 && !need_disass {
|
||||
m6502.PC = disass_addr
|
||||
}
|
||||
else {
|
||||
if line_number_at_PC == 0 || need_disass {
|
||||
ViewController.current?.UpdateSemaphore.wait()
|
||||
|
||||
let m6502_saved = m6502
|
||||
|
||||
need_disass = true
|
||||
addr_line.removeAll()
|
||||
|
||||
@ -467,6 +468,9 @@ N V - B D I Z C
|
||||
|
||||
disass += line + "\n"
|
||||
}
|
||||
|
||||
m6502 = m6502_saved
|
||||
ViewController.current?.UpdateSemaphore.signal()
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
@ -498,21 +502,24 @@ N V - B D I Z C
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
// your code here
|
||||
// }
|
||||
m6502 = m6502_saved
|
||||
}
|
||||
|
||||
|
||||
func UpdateImmediately() {
|
||||
DisplayRegisters()
|
||||
DisplayStack()
|
||||
DisplayMemory()
|
||||
DisplayDisassembly()
|
||||
}
|
||||
|
||||
|
||||
let UpdateSemaphore = DispatchSemaphore(value: 1)
|
||||
func Update() {
|
||||
DispatchQueue.global().async {
|
||||
self.UpdateSemaphore.wait()
|
||||
|
||||
self.DisplayRegisters()
|
||||
self.DisplayStack()
|
||||
self.DisplayMemory()
|
||||
self.DisplayDisassembly()
|
||||
|
||||
self.UpdateSemaphore.signal()
|
||||
if self.UpdateSemaphore.wait(timeout: .now()) == .success {
|
||||
self.UpdateImmediately()
|
||||
self.UpdateSemaphore.signal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
32
A2Mac/UnfairLock.swift
Normal file
32
A2Mac/UnfairLock.swift
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// UnfairLock.swift
|
||||
// A2Mac
|
||||
//
|
||||
// Created by Tamas Rudnai on 11/11/22.
|
||||
// Copyright © 2022 GameAlloy. All rights reserved.
|
||||
//
|
||||
|
||||
// Read http://www.russbishop.net/the-law for more information on why this is necessary
|
||||
final class UnfairLock {
|
||||
private var _lock: UnsafeMutablePointer<os_unfair_lock>
|
||||
|
||||
init() {
|
||||
_lock = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
|
||||
_lock.initialize(to: os_unfair_lock())
|
||||
}
|
||||
|
||||
deinit {
|
||||
_lock.deallocate()
|
||||
}
|
||||
|
||||
func locked<ReturnValue>(_ f: () throws -> ReturnValue) rethrows -> ReturnValue {
|
||||
os_unfair_lock_lock(_lock)
|
||||
defer { os_unfair_lock_unlock(_lock) }
|
||||
return try f()
|
||||
}
|
||||
}
|
||||
|
||||
//let lock = UnfairLock()
|
||||
//lock.locked {
|
||||
// // Critical region
|
||||
//}
|
@ -1279,7 +1279,6 @@ class ViewController: NSViewController {
|
||||
func Update() {
|
||||
if UpdateSemaphore.wait(timeout: .now() + 0.001) == .timedOut {
|
||||
// get back here next time...
|
||||
print("UpdateSemaphore.wait")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -29,19 +29,90 @@
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "6502_bp.h"
|
||||
|
||||
|
||||
uint16_t breakpoints[DEBUG_MAX_BREAKPOINTS];
|
||||
int bp_last_idx = 0;
|
||||
int bp_idx = 0;
|
||||
|
||||
|
||||
void m6502_dbg_bp_swap(uint16_t * a, uint16_t * b) {
|
||||
uint16_t temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
|
||||
void m6502_dbg_bp_sort( uint16_t arr[], int first, int last ) {
|
||||
int i, j;
|
||||
uint16_t pivot;
|
||||
|
||||
if ( first < last ) {
|
||||
pivot = first; // (first + last) / 2;
|
||||
i = first;
|
||||
j = last;
|
||||
|
||||
while ( i < j ) {
|
||||
while ( arr[i] <= arr[pivot] && i < last ) {
|
||||
i++;
|
||||
}
|
||||
while ( arr[j] > arr[pivot] && j > first ) {
|
||||
j--;
|
||||
}
|
||||
|
||||
if ( i < j ) {
|
||||
m6502_dbg_bp_swap(breakpoints + i, breakpoints + j);
|
||||
}
|
||||
}
|
||||
|
||||
m6502_dbg_bp_swap(breakpoints + pivot, breakpoints + j);
|
||||
|
||||
|
||||
if (j > first) {
|
||||
m6502_dbg_bp_sort( arr, first, j - 1 );
|
||||
}
|
||||
if (j < last) {
|
||||
m6502_dbg_bp_sort( arr, j + 1, last );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A recursive binary search function. It returns
|
||||
/// location of addr in given array arr[l..r] is present,
|
||||
/// otherwise -1
|
||||
int m6502_dbg_bp_search(uint16_t arr[], int l, int r, uint16_t addr) {
|
||||
if ( (r >= l) && (addr >= arr[l]) && (addr <= arr[r]) ) {
|
||||
int mid = (l + r) / 2;
|
||||
|
||||
// found it
|
||||
if (arr[mid] == addr) {
|
||||
return mid;
|
||||
}
|
||||
|
||||
// maybe in the left side?
|
||||
if (arr[mid] > addr) {
|
||||
return m6502_dbg_bp_search(arr, l, mid - 1, addr);
|
||||
}
|
||||
|
||||
// maybe in the right side?
|
||||
return m6502_dbg_bp_search(arr, mid + 1, r, addr);
|
||||
}
|
||||
|
||||
// addr not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// m6502_dbg_bp_get_empty
|
||||
/// Get an empty slot in the bp astorage
|
||||
/// @return Index of the empty breakpoint or -1 if error
|
||||
int m6502_dbg_bp_get_empty() {
|
||||
for (int i = 0; i < DEBUG_MAX_BREAKPOINTS; i++) {
|
||||
if ( breakpoints[i] == 0 ) {
|
||||
int m6502_dbg_bp_get_last(int i) {
|
||||
i++;
|
||||
while(--i) {
|
||||
if ( breakpoints[i] ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -54,7 +125,7 @@ int m6502_dbg_bp_get_empty() {
|
||||
/// Get first valid BP
|
||||
/// @return addr of BP or 0 if non
|
||||
uint16_t m6502_dbg_bp_get_next() {
|
||||
while ( bp_idx < DEBUG_MAX_BREAKPOINTS ) {
|
||||
while ( bp_idx < bp_last_idx ) {
|
||||
uint16_t addr = breakpoints[++bp_idx];
|
||||
if (addr) {
|
||||
return addr;
|
||||
@ -74,17 +145,54 @@ uint16_t m6502_dbg_bp_get_first() {
|
||||
}
|
||||
|
||||
|
||||
/// m6502_dbg_bp_get_empty
|
||||
/// Get an empty slot in the bp storage
|
||||
/// @return Index of the empty breakpoint or -1 if error
|
||||
int m6502_dbg_bp_get_empty() {
|
||||
for (int i = 0; i < DEBUG_MAX_BREAKPOINTS; i++) {
|
||||
if ( breakpoints[i] == 0 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// no empty slots
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// m6502_dbg_bp_get_not_empty
|
||||
/// Get first not empty slot in the bp storage
|
||||
/// @return Index of the empty breakpoint or -1 if error
|
||||
int m6502_dbg_bp_get_not_empty() {
|
||||
for (int i = 0; i < DEBUG_MAX_BREAKPOINTS; i++) {
|
||||
if ( breakpoints[i] ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// no empty slots
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/// m6502_dbg_bp_compact
|
||||
/// move array down to eliminate
|
||||
void m6502_dbg_bp_compact() {
|
||||
int i = m6502_dbg_bp_get_not_empty();
|
||||
memcpy(breakpoints, breakpoints + i, bp_last_idx);
|
||||
memset(breakpoints + bp_last_idx + 1, 0, DEBUG_MAX_BREAKPOINTS - bp_last_idx - 1);
|
||||
bp_last_idx = m6502_dbg_bp_get_last(bp_last_idx);
|
||||
}
|
||||
|
||||
|
||||
/// m6502_dbg_bp_get_first
|
||||
/// Get first valid BP
|
||||
/// @return addr of BP or 0 if non
|
||||
_Bool m6502_dbg_bp_is_exists(uint16_t addr) {
|
||||
for (uint16_t bp = m6502_dbg_bp_get_first(); bp; bp = m6502_dbg_bp_get_next()) {
|
||||
if ( bp == addr) {
|
||||
// found it!
|
||||
return 1;
|
||||
}
|
||||
if (addr) {
|
||||
int i = m6502_dbg_bp_search(breakpoints, 0, bp_last_idx, addr);
|
||||
return i >= 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -96,6 +204,10 @@ int m6502_dbg_bp_add(uint16_t addr) {
|
||||
int i = m6502_dbg_bp_get_empty();
|
||||
if ( i >= 0 ) {
|
||||
breakpoints[i] = addr;
|
||||
if (i > bp_last_idx) {
|
||||
bp_last_idx = i;
|
||||
}
|
||||
m6502_dbg_bp_sort(breakpoints, 0, bp_last_idx);
|
||||
return i;
|
||||
}
|
||||
// no empty slots
|
||||
@ -110,6 +222,9 @@ void m6502_dbg_bp_del(uint16_t addr) {
|
||||
for (uint16_t bp = m6502_dbg_bp_get_first(); bp; bp = m6502_dbg_bp_get_next()) {
|
||||
if ( bp == addr ) {
|
||||
breakpoints[bp_idx] = 0;
|
||||
m6502_dbg_bp_sort(breakpoints, 0, bp_last_idx);
|
||||
m6502_dbg_bp_compact();
|
||||
// bp_last_idx = m6502_dbg_bp_get_last(bp_last_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user