diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index 7c5243a..c6e34fa 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -750,6 +750,7 @@ 32D08987291A450400F2B486 /* 6502_bp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 6502_bp.h; sourceTree = ""; }; 32D08992291AF23500F2B486 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = A2Mac/Base.lproj/Debug.storyboard; sourceTree = ""; }; 32D089D7291E1BF800F2B486 /* DisassView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisassView.swift; sourceTree = ""; }; + 32D089EC291EE19200F2B486 /* UnfairLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnfairLock.swift; sourceTree = ""; }; 32DBF7632334657900DD50E7 /* HiRes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiRes.swift; sourceTree = ""; }; 32DBF76723373FB400DD50E7 /* disassembler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = disassembler.h; sourceTree = ""; }; 32E21BE62491BF8B006C0C72 /* apple-rainbow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apple-rainbow.png"; sourceTree = ""; }; @@ -1173,6 +1174,7 @@ children = ( 32BFFB5E22EACC660003B53F /* Assets.xcassets */, 32B18438233FAB3900DBB4AB /* verticies.swift */, + 32D089EC291EE19200F2B486 /* UnfairLock.swift */, 32BFFB5A22EACC630003B53F /* AppDelegate.swift */, 32B3778E291787CA0040845B /* NSLayoutConstraint.swift */, 32100A8A2875387300D894EE /* CheatMenu.swift */, diff --git a/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist b/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist index ce10f13..4ee7691 100644 --- a/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist +++ b/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist @@ -3,81 +3,269 @@ version = "1.0"> + contextName = "woz_write:woz.c"> + value = "WOZwrite.data"> + value = "new"> + + + + + + + + + + + contextName = "HiRes.compute():HiRes.swift"> + value = "computePipelineState.maxTotalThreadsPerThreadgroup"> + value = "result[2]"> + + - - + contextName = "ViewController.newUpdateTimer(timeInterval:):ViewController.swift"> - - - - - - + value = "upd"> + contextName = "HiRes.initMetal():HiRes.swift"> + value = "mtlBufferB"> + + + + + + + + + contextName = "_INC:6502_instr_inc_dec.h"> + value = "WRLOMEM[addr]"> + value = "Apple2_64K_MEM[1]"> + value = "WRHIMEM[addr]"> + value = "Apple2_64K_RAM[1]"> + value = "Apple2_64K_AUX[1]"> + + + + + + + + + + + + + + + + + + + value = "ctx?.height"> + value = "ctx?.width"> + value = "ctx?.bytesPerRow"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -98,6 +286,852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -113,32 +1147,10 @@ - - + contextName = "is_wr_enabled:mmio.c"> - - - - - - - - - - - - - - + value = "MEMcfg.WR_RAM_cntr"> @@ -160,21 +1172,92 @@ + contextName = "MonitorView.init(coder:):MonitorView.swift"> + value = "frame.size"> + + + contextName = "DisplayView.mouseExited(with:):DisplayView.swift"> + value = "bounds"> + value = "frame"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -187,60 +1270,10 @@ + contextName = "PUSH:6502_instr_stack.h"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + value = "m6502.SP"> @@ -289,79 +1322,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + contextName = "init:6502.c"> @@ -372,95 +1333,21 @@ + contextName = "ViewController.extraBuf(_:):ViewController.swift"> - - - - + value = "soundGapLabel"> + contextName = "m6502_ColdReset:6502.c"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + value = "RAM_PG_RD_TBL"> @@ -479,166 +1366,31 @@ - - - - + contextName = "spkr_toggle:speaker.c"> + value = "default_MHz_6502 * 1000 * 1000 / spkr_sample_rate"> + value = "( (spkr_clk + m6502.clkfrm) / ( 1024000 / spkr_sample_rate ) ) * 2"> + value = "(int16_t)28000 + (int16_t)-32768"> - - - - - - + value = "spkr_samples[spkr_sample_last_idx]"> - - - - - - - - - - - - - - + value = "(int)spkr_sample_idx_diff"> + value = "m6502.clkfrm"> - - - - - - - - - - - - + value = "(spkr_clk + m6502.clkfrm)"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + value = "( (spkr_clk + m6502.clkfrm) / ( default_MHz_6502 * 1000 * 1000 / spkr_sample_rate)) * 2"> @@ -653,110 +1405,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -775,625 +1423,36 @@ + contextName = "ViewController.mouseMoved(with:):ViewController.swift"> + value = "oldLocation"> + + + + - - + contextName = "closure #1 in ViewController.Update():ViewController.swift"> + value = "txtArr"> + value = "self.shadowTxt"> + value = "txt"> + value = "MEMcfg.is_80STORE"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + value = "MEMcfg.txt_page_2"> diff --git a/A2Mac/DebuggerViewController.swift b/A2Mac/DebuggerViewController.swift index 3dda958..0d754a5 100644 --- a/A2Mac/DebuggerViewController.swift +++ b/A2Mac/DebuggerViewController.swift @@ -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() + } } } diff --git a/A2Mac/UnfairLock.swift b/A2Mac/UnfairLock.swift new file mode 100644 index 0000000..2474898 --- /dev/null +++ b/A2Mac/UnfairLock.swift @@ -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 + + init() { + _lock = UnsafeMutablePointer.allocate(capacity: 1) + _lock.initialize(to: os_unfair_lock()) + } + + deinit { + _lock.deallocate() + } + + func locked(_ 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 +//} diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift index d3c36d1..a082432 100644 --- a/A2Mac/ViewController.swift +++ b/A2Mac/ViewController.swift @@ -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 } diff --git a/src/cpu/6502_bp.c b/src/cpu/6502_bp.c index ac9f557..e4926f4 100644 --- a/src/cpu/6502_bp.c +++ b/src/cpu/6502_bp.c @@ -29,19 +29,90 @@ // #include +#include #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); } } }