mirror of
https://github.com/Luigi30/FruitMachine-Swift.git
synced 2024-11-26 21:52:45 +00:00
adding a basic debug console and fixing issues with branch instructions
This commit is contained in:
parent
a0d28938b7
commit
3c04503525
@ -16,6 +16,7 @@
|
||||
2AD458E11F2064CB00F05121 /* MemoryInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E01F2064CB00F05121 /* MemoryInterface.swift */; };
|
||||
2AD458E31F20661300F05121 /* CPUInstructions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E21F20661300F05121 /* CPUInstructions.swift */; };
|
||||
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458E41F2070DF00F05121 /* Opcodes.swift */; };
|
||||
2AD6D5841F26E6BF008F3CF5 /* DebuggerCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */; };
|
||||
2AE5BA041F23DE4400FAA343 /* Disassembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE5BA031F23DE4400FAA343 /* Disassembly.swift */; };
|
||||
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE5BA051F2469EB00FAA343 /* AddressConversions.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
@ -33,6 +34,7 @@
|
||||
2AD458E01F2064CB00F05121 /* MemoryInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryInterface.swift; sourceTree = "<group>"; };
|
||||
2AD458E21F20661300F05121 /* CPUInstructions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUInstructions.swift; sourceTree = "<group>"; };
|
||||
2AD458E41F2070DF00F05121 /* Opcodes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Opcodes.swift; sourceTree = "<group>"; };
|
||||
2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggerCommands.swift; sourceTree = "<group>"; };
|
||||
2AE5BA031F23DE4400FAA343 /* Disassembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disassembly.swift; sourceTree = "<group>"; };
|
||||
2AE5BA051F2469EB00FAA343 /* AddressConversions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressConversions.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@ -70,6 +72,7 @@
|
||||
2AD458DD1F205F0D00F05121 /* M6502 */,
|
||||
2AD458CD1F205EB700F05121 /* AppDelegate.swift */,
|
||||
2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */,
|
||||
2AD6D5831F26E6BF008F3CF5 /* DebuggerCommands.swift */,
|
||||
2AD458D11F205EB700F05121 /* Assets.xcassets */,
|
||||
2AD458D31F205EB700F05121 /* Main.storyboard */,
|
||||
2AD458D61F205EB700F05121 /* Info.plist */,
|
||||
@ -166,6 +169,7 @@
|
||||
2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */,
|
||||
2AD458CE1F205EB700F05121 /* AppDelegate.swift in Sources */,
|
||||
2A22EBFB1F21A7A700A36A61 /* IntegerExtensions.swift in Sources */,
|
||||
2AD6D5841F26E6BF008F3CF5 /* DebuggerCommands.swift in Sources */,
|
||||
2AE5BA041F23DE4400FAA343 /* Disassembly.swift in Sources */,
|
||||
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */,
|
||||
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */,
|
||||
|
@ -707,11 +707,11 @@
|
||||
<objects>
|
||||
<viewController id="XfG-lQ-9wD" customClass="DebuggerViewController" customModule="FruitMachine" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="450" height="400"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="450" height="550"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9cE-VZ-R2W">
|
||||
<rect key="frame" x="18" y="363" width="18" height="17"/>
|
||||
<rect key="frame" x="18" y="513" width="18" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="A" id="teN-CC-Ijg">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -720,7 +720,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WjO-ue-iRg">
|
||||
<rect key="frame" x="42" y="360" width="96" height="22"/>
|
||||
<rect key="frame" x="42" y="510" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="tFR-bO-ncf">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
@ -729,7 +729,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="PyS-Mu-bnf">
|
||||
<rect key="frame" x="18" y="333" width="18" height="17"/>
|
||||
<rect key="frame" x="18" y="483" width="18" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="X" id="YEp-wn-anc">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -738,7 +738,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nOs-8C-MbH">
|
||||
<rect key="frame" x="42" y="330" width="96" height="22"/>
|
||||
<rect key="frame" x="42" y="480" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="rbk-9r-h0r">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
@ -747,7 +747,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DmJ-LS-i50">
|
||||
<rect key="frame" x="18" y="303" width="18" height="17"/>
|
||||
<rect key="frame" x="18" y="453" width="18" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Y" id="Or5-cX-RQb">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -756,7 +756,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eqA-qk-YQy">
|
||||
<rect key="frame" x="42" y="300" width="96" height="22"/>
|
||||
<rect key="frame" x="42" y="450" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="TpP-00-jRa">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
@ -765,7 +765,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X2P-rm-4XW">
|
||||
<rect key="frame" x="18" y="275" width="18" height="17"/>
|
||||
<rect key="frame" x="18" y="425" width="18" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="PC" id="okQ-uV-ovH">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -774,7 +774,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XbV-5m-dd0">
|
||||
<rect key="frame" x="42" y="270" width="96" height="22"/>
|
||||
<rect key="frame" x="42" y="420" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="tiL-Qj-d0G">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
@ -783,7 +783,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iZJ-VB-xRU">
|
||||
<rect key="frame" x="18" y="245" width="18" height="17"/>
|
||||
<rect key="frame" x="18" y="395" width="18" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="SR" id="2XF-Q8-qZg">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -792,7 +792,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5TT-BA-Iw1">
|
||||
<rect key="frame" x="42" y="240" width="96" height="22"/>
|
||||
<rect key="frame" x="42" y="390" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="wzs-zZ-PQs">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
@ -801,7 +801,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6li-po-zVA">
|
||||
<rect key="frame" x="18" y="215" width="18" height="17"/>
|
||||
<rect key="frame" x="18" y="365" width="18" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="F" id="qfi-b1-PI7">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -810,7 +810,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ecN-Ge-1hE">
|
||||
<rect key="frame" x="42" y="210" width="96" height="22"/>
|
||||
<rect key="frame" x="42" y="360" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="4dD-B8-JHv">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
@ -819,7 +819,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HdY-Jc-lNK">
|
||||
<rect key="frame" x="36" y="46" width="108" height="32"/>
|
||||
<rect key="frame" x="36" y="196" width="108" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Step" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="kSv-aI-p6H">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -830,7 +830,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oRf-MK-DEX">
|
||||
<rect key="frame" x="36" y="13" width="108" height="32"/>
|
||||
<rect key="frame" x="36" y="163" width="108" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Run" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="e8U-eN-C1K">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -841,7 +841,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="94S-pW-GeW">
|
||||
<rect key="frame" x="36" y="79" width="108" height="32"/>
|
||||
<rect key="frame" x="36" y="229" width="108" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Break" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Pg2-w8-mzE">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -852,7 +852,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="D58-pD-kHB">
|
||||
<rect key="frame" x="146" y="20" width="284" height="362"/>
|
||||
<rect key="frame" x="146" y="170" width="284" height="362"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="bpK-Jl-YbG">
|
||||
<rect key="frame" x="1" y="0.0" width="282" height="361"/>
|
||||
@ -969,7 +969,7 @@
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="jEY-yd-b3r">
|
||||
<rect key="frame" x="1" y="346" width="442" height="15"/>
|
||||
<rect key="frame" x="1" y="-15" width="0.0" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="xl3-SC-c8c">
|
||||
@ -981,9 +981,61 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gOM-wQ-387">
|
||||
<rect key="frame" x="42" y="20" width="388" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" state="on" borderStyle="bezel" title="debuggerInput" drawsBackground="YES" usesSingleLineMode="YES" id="Tgu-VW-lrU">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="debuggerInput_submit:" target="XfG-lQ-9wD" id="YfD-Ke-ibS"/>
|
||||
<outlet property="delegate" destination="XfG-lQ-9wD" id="j9U-3F-uJ0"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ki7-hi-cZ9">
|
||||
<rect key="frame" x="36" y="262" width="108" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Restart" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="z0u-6V-7iW">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="btn_CPU_Restart:" target="XfG-lQ-9wD" id="B2O-Nw-A6U"/>
|
||||
</connections>
|
||||
</button>
|
||||
<scrollView wantsLayer="YES" fixedFrame="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ytp-2q-EO1">
|
||||
<rect key="frame" x="42" y="50" width="388" height="112"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="8jz-1j-CtB">
|
||||
<rect key="frame" x="1" y="1" width="371" height="110"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView ambiguous="YES" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" usesRuler="YES" textCompletion="NO" id="3gF-hp-68k">
|
||||
<rect key="frame" x="0.0" y="-1" width="371" height="110"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<size key="minSize" width="371" height="110"/>
|
||||
<size key="maxSize" width="463" height="10000000"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="6LY-CO-tGe">
|
||||
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="bS2-z2-W2K">
|
||||
<rect key="frame" x="372" y="1" width="15" height="110"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="btn_CPU_restart" destination="ki7-hi-cZ9" id="PD7-dk-eNE"/>
|
||||
<outlet property="debuggerTableView" destination="MuT-J3-VZ6" id="TMx-Do-29u"/>
|
||||
<outlet property="text_CPU_A" destination="WjO-ue-iRg" id="kaI-Bh-Efs"/>
|
||||
<outlet property="text_CPU_Flags" destination="ecN-Ge-1hE" id="dDw-IG-xNd"/>
|
||||
@ -991,6 +1043,8 @@
|
||||
<outlet property="text_CPU_SR" destination="5TT-BA-Iw1" id="Bnh-oz-AnZ"/>
|
||||
<outlet property="text_CPU_X" destination="nOs-8C-MbH" id="71D-al-r5q"/>
|
||||
<outlet property="text_CPU_Y" destination="eqA-qk-YQy" id="c88-2h-DES"/>
|
||||
<outlet property="text_debugger_input" destination="gOM-wQ-387" id="2XS-fM-VQn"/>
|
||||
<outlet property="text_debugger_output" destination="3gF-hp-68k" id="esg-CB-lFg"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
|
25
FruitMachine/DebugConsole.swift
Normal file
25
FruitMachine/DebugConsole.swift
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// DebugConsole.swift
|
||||
// FruitMachine
|
||||
//
|
||||
// Created by Christopher Rohl on 7/24/17.
|
||||
// Copyright © 2017 Christopher Rohl. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class DebugConsole: NSObject {
|
||||
func interpretCommand(command: String) {
|
||||
let commandSplit = command.split(separator: " ")
|
||||
if(commandSplit[0] == "bplist") {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class DebugCommands: NSObject {
|
||||
static func bplist() -> String {
|
||||
|
||||
}
|
||||
}
|
86
FruitMachine/DebuggerCommands.swift
Normal file
86
FruitMachine/DebuggerCommands.swift
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// DebuggerCommands.swift
|
||||
// FruitMachine
|
||||
//
|
||||
// Created by Christopher Rohl on 7/24/17.
|
||||
// Copyright © 2017 Christopher Rohl. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
extension DebuggerViewController {
|
||||
func interpretCommand(command: String) {
|
||||
debugConsolePrint(str: "> \(command)", newline: true)
|
||||
|
||||
let commandSplit = command.components(separatedBy: " ")
|
||||
var parameters: [String] = commandSplit
|
||||
parameters.remove(at: 0)
|
||||
|
||||
if(commandSplit[0] == "bplist")
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.bplist(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
else if(commandSplit[0] == "bpdel")
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.bpdel(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
else if(commandSplit[0] == "bpadd")
|
||||
{
|
||||
debugConsolePrint(str: DebuggerCommands.bpadd(state: cpuInstance, parameters: parameters), newline: true)
|
||||
}
|
||||
else
|
||||
{
|
||||
debugConsolePrint(str: "Unrecognized command", newline: true)
|
||||
}
|
||||
text_debugger_output.scrollToEndOfDocument(self)
|
||||
}
|
||||
}
|
||||
|
||||
class DebuggerCommands: NSObject {
|
||||
static func bplist(state: CPU, parameters: [String]) -> String {
|
||||
var output = ""
|
||||
for (index, bp) in state.breakpoints.enumerated() {
|
||||
output += "Breakpoint \(index): $\(bp.asHexString())\r\n"
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
static func bpadd(state: CPU, parameters: [String]) -> String {
|
||||
var output = ""
|
||||
let val = UInt16(parameters[0])
|
||||
|
||||
if(val != nil) {
|
||||
state.breakpoints.append(val!)
|
||||
output += "Breakpoint added at $\(val!.asHexString())."
|
||||
}
|
||||
else {
|
||||
output += "Usage: bpadd <address>"
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
static func bpdel(state: CPU, parameters: [String]) -> String {
|
||||
var output = ""
|
||||
let val = Int(parameters[0])
|
||||
|
||||
if(val != nil)
|
||||
{
|
||||
if (val! >= 0 && val! < state.breakpoints.count) {
|
||||
state.breakpoints.remove(at: val!)
|
||||
output += "Breakpoint \(val!) deleted."
|
||||
}
|
||||
else
|
||||
{
|
||||
output += "Breakpoint \(val!) does not exist."
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output += "Usage: bpdel <breakpoint-number>. Use bplist to find breakpoint numbers."
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
}
|
@ -16,6 +16,9 @@ class DebuggerViewController: NSViewController {
|
||||
@IBOutlet weak var text_CPU_SR: NSTextField!
|
||||
@IBOutlet weak var text_CPU_Flags: NSTextField!
|
||||
|
||||
@IBOutlet weak var text_debugger_output: NSTextView!
|
||||
@IBOutlet weak var text_debugger_input: NSTextField!
|
||||
|
||||
@IBOutlet weak var debuggerTableView: NSTableView!
|
||||
|
||||
var cpuInstance = CPU.sharedInstance
|
||||
@ -43,10 +46,8 @@ class DebuggerViewController: NSViewController {
|
||||
text_CPU_SR.stringValue = String(format:"%02X", cpuInstance.stack_pointer)
|
||||
text_CPU_Flags.stringValue = String(cpuInstance.status_register.asString())
|
||||
|
||||
if(!highlightCurrentInstruction()) {
|
||||
disassembly = cpuInstance.disassemble(fromAddress: cpuInstance.program_counter, length: 256)
|
||||
highlightCurrentInstruction()
|
||||
}
|
||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 10000)
|
||||
highlightCurrentInstruction()
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
@ -59,9 +60,11 @@ class DebuggerViewController: NSViewController {
|
||||
cpuInstance.performReset()
|
||||
cpuInstance.program_counter = 0x400 //entry point for the test program
|
||||
updateCPUStatusFields()
|
||||
disassembly = cpuInstance.disassemble(fromAddress: cpuInstance.program_counter, length: 10000)
|
||||
disassembly = cpuInstance.disassemble(fromAddress: 0, length: 10000)
|
||||
debuggerTableView.reloadData()
|
||||
|
||||
cpuInstance.breakpoints.append(0x0528)
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
@ -75,7 +78,8 @@ class DebuggerViewController: NSViewController {
|
||||
do {
|
||||
try cpuInstance.executeNextInstruction()
|
||||
} catch CPUExceptions.invalidInstruction {
|
||||
print("*** 6502 Exception: Invalid instruction 0xXX at 0xXXXX")
|
||||
isRunning = false
|
||||
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
@ -83,20 +87,26 @@ class DebuggerViewController: NSViewController {
|
||||
|
||||
func cpuRun() {
|
||||
isRunning = true
|
||||
let queue = DispatchQueue(label: "com.luigithirty.m6502.instructions")
|
||||
let main = DispatchQueue.main
|
||||
|
||||
queue.async {
|
||||
while(self.isRunning == true)
|
||||
{
|
||||
queue.asyncAfter(deadline: .now() + .seconds(1), execute: {
|
||||
self.cpuStep()
|
||||
main.sync {
|
||||
self.updateCPUStatusFields()
|
||||
}
|
||||
})
|
||||
cpuInstance.cycles = 0
|
||||
cpuInstance.cyclesInBatch = 1000
|
||||
|
||||
while(!cpuInstance.checkOutOfCycles() && isRunning) {
|
||||
cpuStep()
|
||||
|
||||
if (cpuInstance.breakpoints.contains(cpuInstance.program_counter)) {
|
||||
isRunning = false
|
||||
updateCPUStatusFields()
|
||||
debugConsolePrint(str: "Breakpoint reached at $\(cpuInstance.program_counter.asHexString())", newline: true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func queueCPUStep(queue: DispatchQueue) {
|
||||
queue.async {
|
||||
self.cpuStep()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func btn_CPUStep(_ sender: Any) {
|
||||
@ -112,8 +122,26 @@ class DebuggerViewController: NSViewController {
|
||||
@IBAction func btn_CPURun(_ sender: Any) {
|
||||
cpuRun()
|
||||
}
|
||||
|
||||
@IBAction func btn_CPU_Restart(_ sender: Any) {
|
||||
cpuInstance.performReset()
|
||||
cpuInstance.program_counter = 0x400
|
||||
debugConsolePrint(str: "CPU restarted from $0400", newline: true)
|
||||
}
|
||||
|
||||
|
||||
@IBAction func debuggerInput_submit(_ sender: NSTextField) {
|
||||
interpretCommand(command: sender.stringValue)
|
||||
sender.stringValue = ""
|
||||
}
|
||||
|
||||
func debugConsolePrint(str: String, newline: Bool) {
|
||||
text_debugger_output.appendText(line: str)
|
||||
if(newline) {
|
||||
text_debugger_output.appendText(line:"\r\n")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension DebuggerViewController: NSTableViewDelegate {
|
||||
@ -150,7 +178,7 @@ extension DebuggerViewController: NSTableViewDelegate {
|
||||
if((operation.data[1] & 0x80) == 0x80) {
|
||||
destination = destination + 1 - UInt16(~operation.data[1])
|
||||
} else {
|
||||
destination = destination + UInt16(operation.data[1])
|
||||
destination = destination + 2 + UInt16(operation.data[1])
|
||||
}
|
||||
cellText = String(format: "%@ #$%04X", operation.instruction!.mnemonic, destination)
|
||||
case .absolute:
|
||||
@ -204,3 +232,21 @@ extension DebuggerViewController: NSTableViewDataSource {
|
||||
return disassembly[atIndex]
|
||||
}
|
||||
}
|
||||
|
||||
extension NSTextView {
|
||||
func appendText(line: String) {
|
||||
let attrDict = [NSAttributedStringKey.font: NSFont.userFixedPitchFont(ofSize: 11)]
|
||||
let astring = NSAttributedString(string: "\(line)", attributes: attrDict)
|
||||
self.textStorage?.append(astring)
|
||||
let loc = self.string.lengthOfBytes(using: String.Encoding.utf8)
|
||||
|
||||
let range = NSRange(location: loc, length: 0)
|
||||
self.scrollRangeToVisible(range)
|
||||
}
|
||||
}
|
||||
|
||||
func xlog(logView:NSTextView?, line:String) {
|
||||
if let view = logView {
|
||||
view.appendText(line: line)
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ class CPU: NSObject {
|
||||
static var sharedInstance = CPU()
|
||||
|
||||
var cycles: Int
|
||||
var cyclesInBatch: Int
|
||||
|
||||
var instruction_register: UInt8
|
||||
|
||||
@ -128,8 +129,11 @@ class CPU: NSObject {
|
||||
|
||||
var memoryInterface: MemoryInterface
|
||||
|
||||
var breakpoints: [UInt16]
|
||||
|
||||
override init() {
|
||||
cycles = 0
|
||||
cyclesInBatch = 0
|
||||
|
||||
instruction_register = 0
|
||||
|
||||
@ -146,6 +150,8 @@ class CPU: NSObject {
|
||||
//Branches incur a 1-cycle penalty if taken plus the page boundary penalty if necessary.
|
||||
branch_was_taken = false
|
||||
|
||||
breakpoints = [UInt16]()
|
||||
|
||||
}
|
||||
|
||||
func getOperandByte() -> UInt8 {
|
||||
@ -205,6 +211,14 @@ class CPU: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
func checkOutOfCycles() -> Bool {
|
||||
if(cycles > cyclesInBatch) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func performReset() {
|
||||
program_counter = memoryInterface.readWord(offset: RESET_VECTOR)
|
||||
stack_pointer = 0xFF
|
||||
|
@ -12,4 +12,8 @@ extension UInt16 {
|
||||
static func + (left: UInt16, right: UInt8) -> UInt16 {
|
||||
return left + UInt16(right)
|
||||
}
|
||||
|
||||
func asHexString() -> String {
|
||||
return String(format: "%04X", self)
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ extension CPU {
|
||||
|
||||
func pushWord(data: UInt16) -> Void {
|
||||
let low = UInt8(data & 0x00FF)
|
||||
let high = UInt8(data & 0xFF00)
|
||||
let high = UInt8((data & 0xFF00) >> 8)
|
||||
|
||||
pushByte(data: low)
|
||||
pushByte(data: high)
|
||||
@ -52,8 +52,18 @@ extension CPU {
|
||||
}
|
||||
}
|
||||
|
||||
program_counter = UInt16(Int(program_counter) + Int(distance))
|
||||
if(distance > 0) {
|
||||
program_counter = UInt16(Int(program_counter) + Int(distance))
|
||||
} else {
|
||||
program_counter = UInt16(Int(program_counter) + Int(distance))
|
||||
}
|
||||
|
||||
branch_was_taken = true
|
||||
|
||||
if(distance == -2) {
|
||||
print("Infinite loop at $\(program_counter.asHexString()). Halting execution.")
|
||||
cyclesInBatch = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,7 +126,7 @@ func getOperandWordForAddressingMode(state: CPU, mode: AddressingMode) -> UInt16
|
||||
let pointer: UInt16 = state.memoryInterface.readWord(offset: UInt16(zp)) + UInt16(state.index_y)
|
||||
return state.memoryInterface.readWord(offset: pointer)
|
||||
default:
|
||||
print("Called getOperand: UInt16 on an instruction that expects a UInt8")
|
||||
print("Called getOperand: UInt16 on an instruction that expects a UInt8. Address: \(state.program_counter.asHexString())")
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -231,7 +241,7 @@ class Opcodes: NSObject {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static func STY(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
let address: UInt16
|
||||
|
||||
@ -294,14 +304,14 @@ class Opcodes: NSObject {
|
||||
}
|
||||
|
||||
static func DEY(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.index_y = state.index_x &- 1
|
||||
state.index_y = state.index_y &- 1
|
||||
|
||||
state.updateZeroFlag(value: state.index_y);
|
||||
state.updateNegativeFlag(value: state.index_y);
|
||||
}
|
||||
|
||||
static func INY(state: CPU, addressingMode: AddressingMode) -> Void {
|
||||
state.index_y = state.index_x &+ 1
|
||||
state.index_y = state.index_y &+ 1
|
||||
|
||||
state.updateZeroFlag(value: state.index_y);
|
||||
state.updateNegativeFlag(value: state.index_y);
|
||||
|
Loading…
Reference in New Issue
Block a user