mirror of
https://github.com/Luigi30/FruitMachine-Swift.git
synced 2025-02-16 23:31:01 +00:00
debugging!
This commit is contained in:
parent
028574d142
commit
a0d28938b7
@ -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;
|
||||
};
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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) {
|
@ -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),
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 {}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user