debugging!

This commit is contained in:
Luigi Thirty 2017-07-24 03:29:12 -04:00
parent 028574d142
commit a0d28938b7
7 changed files with 366 additions and 246 deletions

View File

@ -12,7 +12,7 @@
2AD458D01F205EB700F05121 /* DebuggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458CF1F205EB700F05121 /* DebuggerViewController.swift */; };
2AD458D21F205EB700F05121 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AD458D11F205EB700F05121 /* Assets.xcassets */; };
2AD458D51F205EB700F05121 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2AD458D31F205EB700F05121 /* Main.storyboard */; };
2AD458DF1F205F4500F05121 /* CPUState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458DE1F205F4500F05121 /* CPUState.swift */; };
2AD458DF1F205F4500F05121 /* CPU.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD458DE1F205F4500F05121 /* CPU.swift */; };
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 */; };
@ -29,7 +29,7 @@
2AD458D41F205EB700F05121 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
2AD458D61F205EB700F05121 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2AD458D71F205EB700F05121 /* FruitMachine.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FruitMachine.entitlements; sourceTree = "<group>"; };
2AD458DE1F205F4500F05121 /* CPUState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUState.swift; sourceTree = "<group>"; };
2AD458DE1F205F4500F05121 /* CPU.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPU.swift; sourceTree = "<group>"; };
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>"; };
@ -81,7 +81,7 @@
2AD458DD1F205F0D00F05121 /* M6502 */ = {
isa = PBXGroup;
children = (
2AD458DE1F205F4500F05121 /* CPUState.swift */,
2AD458DE1F205F4500F05121 /* CPU.swift */,
2AD458E21F20661300F05121 /* CPUInstructions.swift */,
2AE5BA031F23DE4400FAA343 /* Disassembly.swift */,
2AD458E41F2070DF00F05121 /* Opcodes.swift */,
@ -170,7 +170,7 @@
2AD458E51F2070DF00F05121 /* Opcodes.swift in Sources */,
2AE5BA061F2469EB00FAA343 /* AddressConversions.swift in Sources */,
2AD458E11F2064CB00F05121 /* MemoryInterface.swift in Sources */,
2AD458DF1F205F4500F05121 /* CPUState.swift in Sources */,
2AD458DF1F205F4500F05121 /* CPU.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -679,7 +679,7 @@
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
<point key="canvasLocation" x="75" y="-76"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
@ -688,7 +688,7 @@
<window key="window" title="Debugger" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="600" height="400"/>
<rect key="contentRect" x="196" y="240" width="800" height="400"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
@ -700,14 +700,14 @@
</windowController>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="250"/>
<point key="canvasLocation" x="74" y="209"/>
</scene>
<!--Debugger View Controller-->
<scene sceneID="hIz-AP-VOD">
<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="600" height="400"/>
<rect key="frame" x="0.0" y="0.0" width="450" height="400"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9cE-VZ-R2W">
@ -800,125 +800,6 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HdY-Jc-lNK">
<rect key="frame" x="36" y="13" 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"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btn_CPUStep:" target="XfG-lQ-9wD" id="sht-OT-bFK"/>
</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="434" 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="432" height="361"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="Ep4-FK-mkU" viewBased="YES" id="MuT-J3-VZ6">
<rect key="frame" x="0.0" y="0.0" width="432" height="338"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="AddressCellID" width="116" minWidth="40" maxWidth="1000" id="hX8-rd-9WQ">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Address">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Paw-o4-m30">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="CfD-bj-I9h">
<rect key="frame" x="1" y="1" width="116" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gF6-Xd-zbg">
<rect key="frame" x="0.0" y="0.0" width="116" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="rhk-Nf-Hah">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="gF6-Xd-zbg" id="lep-1z-ZAt"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="DataCellID" width="310" minWidth="40" maxWidth="1000" id="Ma5-Fz-J7v">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Disassembly">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="pvJ-AI-di6">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="ZF1-Mn-oL5">
<rect key="frame" x="120" y="1" width="310" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gen-Zj-0O4">
<rect key="frame" x="0.0" y="0.0" width="310" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="lxl-6b-xYm">
<font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="gen-Zj-0O4" id="t04-GH-nId"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
</tableView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="jEY-yd-b3r">
<rect key="frame" x="1" y="119" width="223" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="xl3-SC-c8c">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="Ep4-FK-mkU">
<rect key="frame" x="0.0" y="0.0" width="432" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="94S-pW-GeW">
<rect key="frame" x="36" y="46" 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"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btn_Break:" target="XfG-lQ-9wD" id="wvE-WV-51x"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6li-po-zVA">
<rect key="frame" x="18" y="215" width="18" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
@ -937,6 +818,169 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HdY-Jc-lNK">
<rect key="frame" x="36" y="46" 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"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btn_CPUStep:" target="XfG-lQ-9wD" id="sht-OT-bFK"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oRf-MK-DEX">
<rect key="frame" x="36" y="13" 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"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btn_CPURun:" target="XfG-lQ-9wD" id="2Qa-FX-i3o"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="94S-pW-GeW">
<rect key="frame" x="36" y="79" 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"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="btn_Break:" target="XfG-lQ-9wD" id="wvE-WV-51x"/>
</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"/>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="Ep4-FK-mkU" viewBased="YES" id="MuT-J3-VZ6">
<rect key="frame" x="0.0" y="0.0" width="282" height="338"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="AddressCellID" width="63" minWidth="40" maxWidth="1000" id="hX8-rd-9WQ">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Address">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Paw-o4-m30">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="CfD-bj-I9h">
<rect key="frame" x="1" y="1" width="63" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gF6-Xd-zbg">
<rect key="frame" x="0.0" y="0.0" width="63" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="rhk-Nf-Hah">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="gF6-Xd-zbg" id="lep-1z-ZAt"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="DataCellID" width="90" minWidth="40" maxWidth="1000" id="Ma5-Fz-J7v">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Disassembly">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="pvJ-AI-di6">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="ZF1-Mn-oL5">
<rect key="frame" x="67" y="1" width="90" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gen-Zj-0O4">
<rect key="frame" x="0.0" y="0.0" width="90" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="lxl-6b-xYm">
<font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="gen-Zj-0O4" id="t04-GH-nId"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="BytesCellID" width="120" minWidth="10" maxWidth="3.4028234663852886e+38" id="75d-2O-Elg">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Data">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="RRV-a9-iz9">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="Z5P-fi-p7r">
<rect key="frame" x="160" y="1" width="120" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="W5w-RR-wsz">
<rect key="frame" x="0.0" y="0.0" width="120" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="PUG-n5-Mez">
<font key="font" metaFont="fixedUser" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<connections>
<outlet property="textField" destination="W5w-RR-wsz" id="GuG-dM-2hx"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
</tableView>
</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"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="xl3-SC-c8c">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="Ep4-FK-mkU">
<rect key="frame" x="0.0" y="0.0" width="282" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
</subviews>
</view>
<connections>
@ -952,7 +996,7 @@
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<userDefaultsController representsSharedInstance="YES" id="C79-Oc-seX"/>
</objects>
<point key="canvasLocation" x="75" y="655"/>
<point key="canvasLocation" x="74" y="764"/>
</scene>
</scenes>
</document>

View File

@ -18,13 +18,17 @@ class DebuggerViewController: NSViewController {
@IBOutlet weak var debuggerTableView: NSTableView!
let CPU = CPUState.sharedInstance
var cpuInstance = CPU.sharedInstance
var isRunning = false
var disassembly: [Disassembly] = [Disassembly]()
func highlightCurrentInstruction() -> Bool {
for (index, instruction) in disassembly.enumerated() {
if(instruction.address == CPU.program_counter) {
if(instruction.address == cpuInstance.program_counter) {
debuggerTableView.selectRowIndexes(NSIndexSet(index: index) as IndexSet, byExtendingSelection: false)
debuggerTableView.scrollRowToVisible(index+10)
debuggerTableView.scrollRowToVisible(index-5)
return true //instruction found
}
}
@ -32,15 +36,15 @@ class DebuggerViewController: NSViewController {
}
func updateCPUStatusFields() {
text_CPU_A.stringValue = String(format:"%02X", CPU.accumulator)
text_CPU_X.stringValue = String(format:"%02X", CPU.index_x)
text_CPU_Y.stringValue = String(format:"%02X", CPU.index_y)
text_CPU_IP.stringValue = String(format:"%04X", CPU.program_counter)
text_CPU_SR.stringValue = String(format:"%02X", CPU.stack_pointer)
text_CPU_Flags.stringValue = String(CPU.status_register.asString())
text_CPU_A.stringValue = String(format:"%02X", cpuInstance.accumulator)
text_CPU_X.stringValue = String(format:"%02X", cpuInstance.index_x)
text_CPU_Y.stringValue = String(format:"%02X", cpuInstance.index_y)
text_CPU_IP.stringValue = String(format:"%04X", cpuInstance.program_counter)
text_CPU_SR.stringValue = String(format:"%02X", cpuInstance.stack_pointer)
text_CPU_Flags.stringValue = String(cpuInstance.status_register.asString())
if(!highlightCurrentInstruction()) {
disassembly = CPU.disassemble(fromAddress: CPU.program_counter, length: 256)
disassembly = cpuInstance.disassemble(fromAddress: cpuInstance.program_counter, length: 256)
highlightCurrentInstruction()
}
}
@ -51,11 +55,11 @@ class DebuggerViewController: NSViewController {
debuggerTableView.delegate = self
debuggerTableView.dataSource = self
CPU.memoryInterface.loadBinary(path: "/Users/luigi/6502/test.bin")
CPU.performReset()
CPU.program_counter = 0x400 //entry point for the test program
cpuInstance.memoryInterface.loadBinary(path: "/Users/luigi/6502/test.bin")
cpuInstance.performReset()
cpuInstance.program_counter = 0x400 //entry point for the test program
updateCPUStatusFields()
disassembly = CPU.disassemble(fromAddress: CPU.program_counter, length: 10000)
disassembly = cpuInstance.disassemble(fromAddress: cpuInstance.program_counter, length: 10000)
debuggerTableView.reloadData()
// Do any additional setup after loading the view.
@ -69,8 +73,7 @@ class DebuggerViewController: NSViewController {
func cpuStep() {
do {
try CPU.executeNextInstruction()
updateCPUStatusFields()
try cpuInstance.executeNextInstruction()
} catch CPUExceptions.invalidInstruction {
print("*** 6502 Exception: Invalid instruction 0xXX at 0xXXXX")
} catch {
@ -78,13 +81,39 @@ 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()
}
})
}
}
}
@IBAction func btn_CPUStep(_ sender: Any) {
cpuStep()
updateCPUStatusFields()
}
@IBAction func btn_Break(_ sender: Any) {
isRunning = false
_ = 0
}
@IBAction func btn_CPURun(_ sender: Any) {
cpuRun()
}
}
extension DebuggerViewController: NSTableViewDelegate {
@ -92,6 +121,7 @@ extension DebuggerViewController: NSTableViewDelegate {
fileprivate enum CellIdentifiers {
static let AddressCell = "AddressCellID"
static let DataCell = "DataCellID"
static let BytesCell = "BytesCellID"
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
@ -112,34 +142,49 @@ extension DebuggerViewController: NSTableViewDelegate {
case .accumulator:
cellText = String(format: "%@ A", operation.instruction!.mnemonic)
case .immediate:
cellText = String(format: "%@ #$%02X", operation.instruction!.mnemonic, operation.data[0])
cellText = String(format: "%@ #$%02X", operation.instruction!.mnemonic, operation.data[1])
case .implied:
cellText = String(format: "%@", operation.instruction!.mnemonic)
case .relative:
cellText = String(format: "%@ #$%04X", operation.instruction!.mnemonic, UInt16(operation.data[0]) + operation.address)
var destination: UInt16 = operation.address
if((operation.data[1] & 0x80) == 0x80) {
destination = destination + 1 - UInt16(~operation.data[1])
} else {
destination = destination + UInt16(operation.data[1])
}
cellText = String(format: "%@ #$%04X", operation.instruction!.mnemonic, destination)
case .absolute:
cellText = String(format: "%@ $%02X%02X", operation.instruction!.mnemonic, operation.data[1], operation.data[0])
cellText = String(format: "%@ $%02X%02X", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
case .zeropage:
cellText = String(format: "%@ $%02X", operation.instruction!.mnemonic, operation.data[0])
cellText = String(format: "%@ $%02X", operation.instruction!.mnemonic, operation.data[1])
case .indirect:
cellText = String(format: "%@ ($%02X%02X)", operation.instruction!.mnemonic, operation.data[1], operation.data[0])
cellText = String(format: "%@ ($%02X%02X)", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
case .absolute_indexed_x:
cellText = String(format: "%@ $%02X%02X,X", operation.instruction!.mnemonic, operation.data[1], operation.data[0])
cellText = String(format: "%@ $%02X%02X,X", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
case .absolute_indexed_y:
cellText = String(format: "%@ $%02X%02X,Y", operation.instruction!.mnemonic, operation.data[1], operation.data[0])
cellText = String(format: "%@ $%02X%02X,Y", operation.instruction!.mnemonic, operation.data[2], operation.data[1])
case .zeropage_indexed_x:
cellText = String(format: "%@ $%02X,X", operation.instruction!.mnemonic, operation.data[0])
cellText = String(format: "%@ $%02X,X", operation.instruction!.mnemonic, operation.data[1])
case .zeropage_indexed_y:
cellText = String(format: "%@ $%02X,Y", operation.instruction!.mnemonic, operation.data[0])
cellText = String(format: "%@ $%02X,Y", operation.instruction!.mnemonic, operation.data[1])
case .indexed_indirect:
cellText = String(format: "%@ ($%02X,X)", operation.instruction!.mnemonic, operation.data[0])
cellText = String(format: "%@ ($%02X,X)", operation.instruction!.mnemonic, operation.data[1])
case .indirect_indexed:
cellText = String(format: "%@ ($%02X),Y", operation.instruction!.mnemonic, operation.data[0])
cellText = String(format: "%@ ($%02X),Y", operation.instruction!.mnemonic, operation.data[1])
}
}
cellIdentifier = CellIdentifiers.DataCell
}
if(tableColumn == tableView.tableColumns[2]) {
cellText = ""
for byte in operation.data {
cellText += String(format: "%02X ", byte)
}
cellIdentifier = CellIdentifiers.BytesCell
}
if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: nil) as? NSTableCellView {
cell.textField?.stringValue = cellText
return cell

View File

@ -105,12 +105,12 @@ struct StatusRegister {
}
}
class CPUState: NSObject {
class CPU: NSObject {
let NMI_VECTOR: UInt16 = 0xFFFA
let RESET_VECTOR: UInt16 = 0xFFFC
let IRQ_VECTOR: UInt16 = 0xFFFE
static var sharedInstance = CPUState()
static var sharedInstance = CPU()
var cycles: Int
@ -124,11 +124,10 @@ class CPUState: NSObject {
var status_register: StatusRegister
var page_boundary_crossed: Bool
var branch_was_taken: Bool
var memoryInterface: MemoryInterface
var branch_was_taken: Bool
override init() {
cycles = 0
@ -149,32 +148,6 @@ class CPUState: NSObject {
}
func disassemble(fromAddress: UInt16, length: UInt16) -> [Disassembly] {
var disassembly: [Disassembly] = [Disassembly]()
var currentAddress: UInt16 = fromAddress
let endAddress: UInt16 = fromAddress + length
while(currentAddress < endAddress) {
let instruction = memoryInterface.readByte(offset: currentAddress)
let operation = InstructionTable[instruction]
var data = [UInt8]()
if(operation != nil) {
for index in 1...operation!.bytes {
data.append(memoryInterface.readByte(offset:currentAddress + UInt16(index)))
}
disassembly.append(Disassembly(instruction: operation, address: currentAddress, data: data))
currentAddress = currentAddress + UInt16(operation!.bytes)
} else {
currentAddress = currentAddress + 1
}
}
return disassembly
}
func getOperandByte() -> UInt8 {
//Returns the operand byte after the current instruction byte.
return memoryInterface.readByte(offset: program_counter + 1)
@ -215,7 +188,7 @@ class CPUState: NSObject {
throw CPUExceptions.invalidInstruction
}
operation!.action(CPUState.sharedInstance, operation!.addressingMode)
operation!.action(CPU.sharedInstance, operation!.addressingMode)
self.cycles += operation!.cycles
if(self.page_boundary_crossed) {

View File

@ -30,9 +30,9 @@ class CPUInstruction: NSObject {
let bytes: Int //How many bytes long is this instruction?
let addressingMode: AddressingMode //The addressing mode of this instruction.
let action: (CPUState, AddressingMode) -> Void //A closure that describes this function's action.
let action: (CPU, AddressingMode) -> Void //A closure that describes this function's action.
init(mnemonic: String, cycles: Int, bytes: Int, addressingMode: AddressingMode, action: @escaping (CPUState, AddressingMode) -> Void) {
init(mnemonic: String, cycles: Int, bytes: Int, addressingMode: AddressingMode, action: @escaping (CPU, AddressingMode) -> Void) {
self.mnemonic = mnemonic
self.cycles = cycles
self.bytes = bytes
@ -222,6 +222,7 @@ let InstructionTable: [UInt8:CPUInstruction] = [
0xF0: CPUInstruction(mnemonic: "BEQ", cycles: 2, bytes: 2, addressingMode: .relative, action: Opcodes.BEQ),
0x20: CPUInstruction(mnemonic: "JSR", cycles: 6, bytes: 3, addressingMode: .absolute, action: Opcodes.JSR),
0x40: CPUInstruction(mnemonic: "RTI", cycles: 6, bytes: 1, addressingMode: .implied, action: Opcodes.RTI),
0x60: CPUInstruction(mnemonic: "RTS", cycles: 6, bytes: 1, addressingMode: .implied, action: Opcodes.RTS),
0x00: CPUInstruction(mnemonic: "BRK", cycles: 7, bytes: 1, addressingMode: .implied, action: Opcodes.BRK),

View File

@ -19,3 +19,31 @@ class Disassembly: NSObject {
self.data = data
}
}
extension CPU {
func disassemble(fromAddress: UInt16, length: UInt16) -> [Disassembly] {
var disassembly: [Disassembly] = [Disassembly]()
var currentAddress: UInt16 = fromAddress
let endAddress: UInt16 = fromAddress + length
while(currentAddress < endAddress) {
let instruction = memoryInterface.readByte(offset: currentAddress)
let operation = InstructionTable[instruction]
var data = [UInt8]()
if(operation != nil) {
for index in 1...operation!.bytes {
data.append(memoryInterface.readByte(offset:currentAddress + UInt16(index-1)))
}
disassembly.append(Disassembly(instruction: operation, address: currentAddress, data: data))
currentAddress = currentAddress + UInt16(operation!.bytes)
} else {
currentAddress = currentAddress + 1
}
}
return disassembly
}
}

View File

@ -8,7 +8,7 @@
import Cocoa
extension CPUState {
extension CPU {
func popByte() -> UInt8 {
stack_pointer = stack_pointer &+ 1
@ -57,7 +57,7 @@ extension CPUState {
}
}
func getOperandByteForAddressingMode(state: CPUState, mode: AddressingMode) -> UInt8 {
func getOperandByteForAddressingMode(state: CPU, mode: AddressingMode) -> UInt8 {
switch (mode) {
case .immediate:
@ -93,7 +93,7 @@ func getOperandByteForAddressingMode(state: CPUState, mode: AddressingMode) -> U
}
}
func getOperandWordForAddressingMode(state: CPUState, mode: AddressingMode) -> UInt16 {
func getOperandWordForAddressingMode(state: CPU, mode: AddressingMode) -> UInt16 {
//Function that will provide a 16-bit operand to instructions.
//All instructions have 2 data bytes, little-endian.
@ -132,9 +132,7 @@ func hex2bcd(hex: UInt8) -> UInt8 {
class Opcodes: NSObject {
static func ADC(state: CPUState, addressingMode: AddressingMode) -> Void {
let operand = UInt8(getOperandByteForAddressingMode(state: state, mode: addressingMode))
static func _Add(state: CPU, operand: UInt8) {
var t16: UInt16 = UInt16(state.accumulator &+ operand) + UInt16((state.status_register.carry ? UInt8(1) : UInt8(0)))
let t8: UInt8 = UInt8(t16 & 0xFF)
@ -151,28 +149,54 @@ class Opcodes: NSObject {
state.accumulator = (UInt8(t16 & 0xFF))
}
static func LDA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func ADC(state: CPU, addressingMode: AddressingMode) -> Void {
_Add(state: state, operand: UInt8(getOperandByteForAddressingMode(state: state, mode: addressingMode)))
/*
let operand = UInt8(getOperandByteForAddressingMode(state: state, mode: addressingMode))
var t16: UInt16 = UInt16(state.accumulator &+ operand) + UInt16((state.status_register.carry ? UInt8(1) : UInt8(0)))
let t8: UInt8 = UInt8(t16 & 0xFF)
state.status_register.overflow = (~(state.accumulator ^ operand) & (state.accumulator ^ t8) & 0x80) == 0x80
state.status_register.zero = (t8 == 0)
state.status_register.negative = (t8 & 0x80) == 0x80
if(state.status_register.decimal) {
t16 = UInt16(hex2bcd(hex: state.accumulator) + hex2bcd(hex: operand) + (state.status_register.carry ? UInt8(1) : UInt8(0)))
} else {
state.status_register.carry = (t16 > 255)
}
state.accumulator = (UInt8(t16 & 0xFF))
*/
}
static func SBC(state: CPU, addressingMode: AddressingMode) -> Void {
_Add(state: state, operand: ~(UInt8(getOperandByteForAddressingMode(state: state, mode: addressingMode))))
}
static func LDA(state: CPU, addressingMode: AddressingMode) -> Void {
state.accumulator = getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
state.updateNegativeFlag(value: state.accumulator)
}
static func LDX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func LDX(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_x = getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.index_x)
state.updateNegativeFlag(value: state.index_x)
}
static func LDY(state: CPUState, addressingMode: AddressingMode) -> Void {
static func LDY(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_y = getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.index_y)
state.updateNegativeFlag(value: state.index_y)
}
static func STA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func STA(state: CPU, addressingMode: AddressingMode) -> Void {
let address: UInt16
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) {
@ -190,7 +214,7 @@ class Opcodes: NSObject {
}
}
static func STX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func STX(state: CPU, addressingMode: AddressingMode) -> Void {
let address: UInt16
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_y) {
@ -208,7 +232,7 @@ class Opcodes: NSObject {
}
}
static func STY(state: CPUState, addressingMode: AddressingMode) -> Void {
static func STY(state: CPU, addressingMode: AddressingMode) -> Void {
let address: UInt16
if(addressingMode == .zeropage || addressingMode == .zeropage_indexed_x) {
@ -227,63 +251,63 @@ class Opcodes: NSObject {
}
//Register instructions
static func TAX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func TAX(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_x = state.accumulator
state.updateZeroFlag(value: state.index_x);
state.updateNegativeFlag(value: state.index_x);
}
static func TXA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func TXA(state: CPU, addressingMode: AddressingMode) -> Void {
state.accumulator = state.index_x
state.updateZeroFlag(value: state.accumulator);
state.updateNegativeFlag(value: state.accumulator);
}
static func DEX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func DEX(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_x = state.index_x &- 1
state.updateZeroFlag(value: state.index_x);
state.updateNegativeFlag(value: state.index_x);
}
static func INX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func INX(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_x = state.index_x &+ 1
state.updateZeroFlag(value: state.index_x);
state.updateNegativeFlag(value: state.index_x);
}
static func TAY(state: CPUState, addressingMode: AddressingMode) -> Void {
static func TAY(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_y = state.accumulator
state.updateZeroFlag(value: state.index_y);
state.updateNegativeFlag(value: state.index_y);
}
static func TYA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func TYA(state: CPU, addressingMode: AddressingMode) -> Void {
state.accumulator = state.index_y
state.updateZeroFlag(value: state.accumulator);
state.updateNegativeFlag(value: state.accumulator);
}
static func DEY(state: CPUState, addressingMode: AddressingMode) -> Void {
static func DEY(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_y = state.index_x &- 1
state.updateZeroFlag(value: state.index_y);
state.updateNegativeFlag(value: state.index_y);
}
static func INY(state: CPUState, addressingMode: AddressingMode) -> Void {
static func INY(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_y = state.index_x &+ 1
state.updateZeroFlag(value: state.index_y);
state.updateNegativeFlag(value: state.index_y);
}
static func INC(state: CPUState, addressingMode: AddressingMode) -> Void {
static func INC(state: CPU, addressingMode: AddressingMode) -> Void {
let address: UInt16
var val: UInt8
@ -308,7 +332,7 @@ class Opcodes: NSObject {
state.updateNegativeFlag(value: val);
}
static func DEC(state: CPUState, addressingMode: AddressingMode) -> Void {
static func DEC(state: CPU, addressingMode: AddressingMode) -> Void {
let address: UInt16
var val: UInt8
@ -334,7 +358,7 @@ class Opcodes: NSObject {
}
//CMP
static func CMP(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CMP(state: CPU, addressingMode: AddressingMode) -> Void {
let data = state.accumulator - state.getOperandByte() //CMP is a subtract that doesn't affect memory
state.updateZeroFlag(value: data)
@ -342,7 +366,7 @@ class Opcodes: NSObject {
state.status_register.carry = (data >= 0)
}
static func CPX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CPX(state: CPU, addressingMode: AddressingMode) -> Void {
let data = state.index_x - state.getOperandByte() //CMP is a subtract that doesn't affect memory
state.updateZeroFlag(value: data)
@ -350,7 +374,7 @@ class Opcodes: NSObject {
state.status_register.carry = (data >= 0)
}
static func CPY(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CPY(state: CPU, addressingMode: AddressingMode) -> Void {
let data = state.index_y - state.getOperandByte() //CMP is a subtract that doesn't affect memory
state.updateZeroFlag(value: data)
@ -359,21 +383,21 @@ class Opcodes: NSObject {
}
//Boolean operators
static func EOR(state: CPUState, addressingMode: AddressingMode) -> Void {
static func EOR(state: CPU, addressingMode: AddressingMode) -> Void {
state.accumulator = state.accumulator ^ getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
state.updateNegativeFlag(value: state.accumulator)
}
static func AND(state: CPUState, addressingMode: AddressingMode) -> Void {
static func AND(state: CPU, addressingMode: AddressingMode) -> Void {
state.accumulator = state.accumulator & getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
state.updateNegativeFlag(value: state.accumulator)
}
static func ORA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func ORA(state: CPU, addressingMode: AddressingMode) -> Void {
state.accumulator = state.accumulator | getOperandByteForAddressingMode(state: state, mode: addressingMode)
state.updateZeroFlag(value: state.accumulator)
@ -381,7 +405,7 @@ class Opcodes: NSObject {
}
//Bitwise operators
static func BIT(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BIT(state: CPU, addressingMode: AddressingMode) -> Void {
let operand = getOperandByteForAddressingMode(state: state, mode: addressingMode)
let data = state.accumulator & operand
@ -390,7 +414,7 @@ class Opcodes: NSObject {
state.status_register.overflow = (state.accumulator & UInt8(0x40)) == 0x40
}
static func ASL(state: CPUState, addressingMode: AddressingMode) -> Void {
static func ASL(state: CPU, addressingMode: AddressingMode) -> Void {
let operand: UInt8
if(addressingMode == .implied) {
@ -410,7 +434,7 @@ class Opcodes: NSObject {
}
}
static func LSR(state: CPUState, addressingMode: AddressingMode) -> Void {
static func LSR(state: CPU, addressingMode: AddressingMode) -> Void {
let operand: UInt8
if(addressingMode == .implied) {
@ -430,7 +454,7 @@ class Opcodes: NSObject {
}
}
static func ROL(state: CPUState, addressingMode: AddressingMode) -> Void {
static func ROL(state: CPU, addressingMode: AddressingMode) -> Void {
let operand: UInt8
if(addressingMode == .implied) {
@ -456,7 +480,7 @@ class Opcodes: NSObject {
}
}
static func ROR(state: CPUState, addressingMode: AddressingMode) -> Void {
static func ROR(state: CPU, addressingMode: AddressingMode) -> Void {
let operand: UInt8
if(addressingMode == .implied) {
@ -481,52 +505,52 @@ class Opcodes: NSObject {
}
//Processor flag instructions
static func CLC(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CLC(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.carry = false
}
static func SEC(state: CPUState, addressingMode: AddressingMode) -> Void {
static func SEC(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.carry = true
}
static func CLI(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CLI(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.irq_disable = false
}
static func SEI(state: CPUState, addressingMode: AddressingMode) -> Void {
static func SEI(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.irq_disable = true
}
static func CLV(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CLV(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.overflow = false
}
static func CLD(state: CPUState, addressingMode: AddressingMode) -> Void {
static func CLD(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.decimal = false
}
static func SED(state: CPUState, addressingMode: AddressingMode) -> Void {
static func SED(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.carry = true
}
//Stack instructions
static func TXS(state: CPUState, addressingMode: AddressingMode) -> Void {
static func TXS(state: CPU, addressingMode: AddressingMode) -> Void {
state.stack_pointer = state.index_x
}
static func TSX(state: CPUState, addressingMode: AddressingMode) -> Void {
static func TSX(state: CPU, addressingMode: AddressingMode) -> Void {
state.index_x = state.stack_pointer
state.updateZeroFlag(value: state.index_x);
state.updateNegativeFlag(value: state.index_x);
}
static func PHA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func PHA(state: CPU, addressingMode: AddressingMode) -> Void {
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: state.accumulator)
state.stack_pointer = state.stack_pointer &- 1
}
static func PLA(state: CPUState, addressingMode: AddressingMode) -> Void {
static func PLA(state: CPU, addressingMode: AddressingMode) -> Void {
state.stack_pointer = state.stack_pointer &+ 1
state.accumulator = state.memoryInterface.readByte(offset: state.stackPointerAsUInt16())
@ -534,84 +558,89 @@ class Opcodes: NSObject {
state.updateNegativeFlag(value: state.accumulator);
}
static func PHP(state: CPUState, addressingMode: AddressingMode) -> Void {
static func PHP(state: CPU, addressingMode: AddressingMode) -> Void {
state.memoryInterface.writeByte(offset: state.stackPointerAsUInt16(), value: state.status_register.asByte())
state.stack_pointer = state.stack_pointer &- 1
}
static func PLP(state: CPUState, addressingMode: AddressingMode) -> Void {
static func PLP(state: CPU, addressingMode: AddressingMode) -> Void {
state.stack_pointer = state.stack_pointer &+ 1
state.status_register.fromByte(state: state.memoryInterface.readByte(offset: state.stackPointerAsUInt16()))
}
static func BPL(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BPL(state: CPU, addressingMode: AddressingMode) -> Void {
if(!state.status_register.negative) {
state.doBranch()
}
}
static func BMI(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BMI(state: CPU, addressingMode: AddressingMode) -> Void {
if(state.status_register.negative) {
state.doBranch()
}
}
static func BVC(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BVC(state: CPU, addressingMode: AddressingMode) -> Void {
if(!state.status_register.overflow) {
state.doBranch()
}
}
static func BVS(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BVS(state: CPU, addressingMode: AddressingMode) -> Void {
if(state.status_register.overflow) {
state.doBranch()
}
}
static func BCC(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BCC(state: CPU, addressingMode: AddressingMode) -> Void {
if(!state.status_register.carry) {
state.doBranch()
}
}
static func BCS(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BCS(state: CPU, addressingMode: AddressingMode) -> Void {
if(state.status_register.carry) {
state.doBranch()
}
}
static func BNE(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BNE(state: CPU, addressingMode: AddressingMode) -> Void {
if(!state.status_register.zero) {
state.doBranch()
}
}
static func BEQ(state: CPUState, addressingMode: AddressingMode) -> Void {
static func BEQ(state: CPU, addressingMode: AddressingMode) -> Void {
if(state.status_register.zero) {
state.doBranch()
}
}
//Misc
static func JMP(state: CPUState, addressingMode: AddressingMode) -> Void {
static func JMP(state: CPU, addressingMode: AddressingMode) -> Void {
state.program_counter = getOperandWordForAddressingMode(state: state, mode: addressingMode)
}
static func JSR(state: CPUState, addressingMode: AddressingMode) -> Void {
static func JSR(state: CPU, addressingMode: AddressingMode) -> Void {
state.pushWord(data: state.program_counter - 1)
state.program_counter = state.getOperandWord()
}
static func RTS(state: CPUState, addressingMode: AddressingMode) -> Void {
static func RTS(state: CPU, addressingMode: AddressingMode) -> Void {
state.program_counter = state.popWord() + 1
}
static func BRK(state: CPUState, addressingMode: AddressingMode) -> Void {
static func RTI(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.fromByte(state: state.popByte())
state.program_counter = state.popWord()
}
static func BRK(state: CPU, addressingMode: AddressingMode) -> Void {
state.status_register.brk = true
state.pushWord(data: state.program_counter)
state.pushByte(data: state.status_register.asByte())
state.program_counter = state.memoryInterface.readWord(offset: 0xFFFE)
}
static func NOP(state: CPUState, addressingMode: AddressingMode) -> Void {}
static func NOP(state: CPU, addressingMode: AddressingMode) -> Void {}
}