From 9be99a7cac741b83fb44cb78693a2c13f9ce926f Mon Sep 17 00:00:00 2001
From: Andy McFadden
Date: Sun, 7 Oct 2018 21:51:15 -0700
Subject: [PATCH] Make hint application less annoying
Two changes:
(1) Code and data hints are now only applied to the first byte on
each selected line. This allows you to slap a code hint on a
string without lighting up the whole string. Inline-data hints
and hint removal work as before.
(2) Added a menu item (with Ctrl+D as shortcut) to toggle the state
of the uncategorized data analyzer. This makes it easy to turn
off the feature that put the code into a string in the first
place.
---
SourceGen/AppForms/ProjectView.Designer.cs | 12 ++++++
SourceGen/AppForms/ProjectView.cs | 45 +++++++++++++++++++---
SourceGen/RuntimeData/Help/index.html | 3 +-
SourceGen/RuntimeData/Help/intro.html | 11 ++++--
SourceGen/RuntimeData/Help/mainwin.html | 40 +++++++++++++------
5 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/SourceGen/AppForms/ProjectView.Designer.cs b/SourceGen/AppForms/ProjectView.Designer.cs
index 750eb6d..2137b0d 100644
--- a/SourceGen/AppForms/ProjectView.Designer.cs
+++ b/SourceGen/AppForms/ProjectView.Designer.cs
@@ -175,6 +175,7 @@ namespace SourceGen.AppForms
this.symbolNameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.infoGroupBox = new System.Windows.Forms.GroupBox();
this.infoTextBox = new System.Windows.Forms.TextBox();
+ this.toggleDataScanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mainMenuStrip.SuspendLayout();
this.mainStatusStrip.SuspendLayout();
this.mainToolStrip.SuspendLayout();
@@ -342,11 +343,13 @@ namespace SourceGen.AppForms
this.toolStripMenuItem3,
this.editHeaderCommentToolStripMenuItem,
this.projectPropertiesToolStripMenuItem,
+ this.toggleDataScanToolStripMenuItem,
this.toolStripMenuItem7,
this.settingsToolStripMenuItem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
this.editToolStripMenuItem.Text = "Edit";
+ this.editToolStripMenuItem.DropDownOpening += new System.EventHandler(this.editToolStripMenuItem_DropDownOpening);
//
// undoToolStripMenuItem
//
@@ -1446,6 +1449,14 @@ namespace SourceGen.AppForms
this.infoTextBox.Size = new System.Drawing.Size(177, 120);
this.infoTextBox.TabIndex = 0;
//
+ // toggleDataScanToolStripMenuItem
+ //
+ this.toggleDataScanToolStripMenuItem.Name = "toggleDataScanToolStripMenuItem";
+ this.toggleDataScanToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D)));
+ this.toggleDataScanToolStripMenuItem.Size = new System.Drawing.Size(207, 22);
+ this.toggleDataScanToolStripMenuItem.Text = "Toggle Data Scan";
+ this.toggleDataScanToolStripMenuItem.Click += new System.EventHandler(this.toggleDataScanToolStripMenuItem_Click);
+ //
// ProjectView
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -1631,6 +1642,7 @@ namespace SourceGen.AppForms
private System.Windows.Forms.ToolStripMenuItem editProjectSymbolToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem deleteNoteCommentToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem formatSplitAddressTableToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem toggleDataScanToolStripMenuItem;
}
}
diff --git a/SourceGen/AppForms/ProjectView.cs b/SourceGen/AppForms/ProjectView.cs
index c4a4425..328d1b4 100644
--- a/SourceGen/AppForms/ProjectView.cs
+++ b/SourceGen/AppForms/ProjectView.cs
@@ -602,6 +602,7 @@ namespace SourceGen.AppForms {
gotoToolStripMenuItem.Enabled = true;
editHeaderCommentToolStripMenuItem.Enabled = true;
projectPropertiesToolStripMenuItem.Enabled = true;
+ toggleDataScanToolStripMenuItem.Enabled = true;
showUndoRedoHistoryToolStripMenuItem.Enabled = true;
showAnalysisTimersToolStripMenuItem.Enabled = true;
@@ -633,6 +634,7 @@ namespace SourceGen.AppForms {
gotoToolStripMenuItem.Enabled = false;
editHeaderCommentToolStripMenuItem.Enabled = false;
projectPropertiesToolStripMenuItem.Enabled = false;
+ toggleDataScanToolStripMenuItem.Enabled = false;
showUndoRedoHistoryToolStripMenuItem.Enabled = false;
showAnalysisTimersToolStripMenuItem.Enabled = false;
@@ -1896,6 +1898,16 @@ namespace SourceGen.AppForms {
}
}
+ // Edit > Toggle Data Scan
+ private void toggleDataScanToolStripMenuItem_Click(object sender, EventArgs e) {
+ ProjectProperties oldProps = mProject.ProjectProps;
+ ProjectProperties newProps = new ProjectProperties(oldProps);
+ newProps.AnalysisParams.AnalyzeUncategorizedData =
+ !newProps.AnalysisParams.AnalyzeUncategorizedData;
+ UndoableChange uc = UndoableChange.CreateProjectPropertiesChange(oldProps, newProps);
+ ApplyUndoableChanges(new ChangeSet(uc));
+ }
+
// Edit > Settings...
private void settingsToolStripMenuItem_Click(object sender, EventArgs e) {
ShowAppSettings(EditAppSettings.Tab.Unknown);
@@ -2473,6 +2485,13 @@ namespace SourceGen.AppForms {
return -1;
}
+
+ private void editToolStripMenuItem_DropDownOpening(object sender, EventArgs e) {
+ // Set the checkmark on Toggle Data Scan.
+ toggleDataScanToolStripMenuItem.Checked = (mProject != null) &&
+ mProject.ProjectProps.AnalysisParams.AnalyzeUncategorizedData;
+ }
+
///
/// Handles an "opening" event for the codeListView's ContextMenuStrip.
///
@@ -2951,19 +2970,33 @@ namespace SourceGen.AppForms {
}
private void MarkAsCode_Click(Object sender, EventArgs e) {
- MarkAsType(CodeAnalysis.TypeHint.Code);
+ MarkAsType(CodeAnalysis.TypeHint.Code, true);
}
private void MarkAsData_Click(Object sender, EventArgs e) {
- MarkAsType(CodeAnalysis.TypeHint.Data);
+ MarkAsType(CodeAnalysis.TypeHint.Data, true);
}
private void MarkAsInlineData_Click(Object sender, EventArgs e) {
- MarkAsType(CodeAnalysis.TypeHint.InlineData);
+ MarkAsType(CodeAnalysis.TypeHint.InlineData, false);
}
private void MarkAsNoHint_Click(Object sender, EventArgs e) {
- MarkAsType(CodeAnalysis.TypeHint.NoHint);
+ MarkAsType(CodeAnalysis.TypeHint.NoHint, false);
}
- private void MarkAsType(CodeAnalysis.TypeHint hint) {
- RangeSet sel = OffsetSetFromSelected();
+ private void MarkAsType(CodeAnalysis.TypeHint hint, bool firstByteOnly) {
+ RangeSet sel;
+
+ if (firstByteOnly) {
+ sel = new RangeSet();
+ foreach (int index in codeListView.SelectedIndices) {
+ int offset = mDisplayList[index].FileOffset;
+ if (offset >= 0) {
+ // Not interested in the header stuff for hinting.
+ sel.Add(offset);
+ }
+ }
+ } else {
+ sel = OffsetSetFromSelected();
+ }
+
TypedRangeSet newSet = new TypedRangeSet();
TypedRangeSet undoSet = new TypedRangeSet();
diff --git a/SourceGen/RuntimeData/Help/index.html b/SourceGen/RuntimeData/Help/index.html
index 52b65e1..66bf4f7 100644
--- a/SourceGen/RuntimeData/Help/index.html
+++ b/SourceGen/RuntimeData/Help/index.html
@@ -16,7 +16,7 @@ and 65816 code. The official web site is
https://6502bench.com/.
If you want to dive right in, try the
-Tutorial.
+Tutorials.
Contents
diff --git a/SourceGen/RuntimeData/Help/intro.html b/SourceGen/RuntimeData/Help/intro.html
index 3074e19..d229c30 100644
--- a/SourceGen/RuntimeData/Help/intro.html
+++ b/SourceGen/RuntimeData/Help/intro.html
@@ -241,7 +241,7 @@ L1009 CLC
Be careful that you only add hints to the instruction opcode. If
-you selected the full range of bytes from $1003 to $1008, you would
+you applied hints to the full range of bytes from $1003 to $1008, you would
end up with this:
.ORG $1000
@@ -257,7 +257,9 @@ L1009 CLC
The problem is that the bytes in the middle of the instruction have
been marked as entry points, and SourceGen is treating them as
embedded instructions. $EF and $12 aren't valid 6502 opcodes, so
-they're being ignored, but $10 is BPL and $30 is BMI.
+they're being ignored, but $10 is BPL and $30 is BMI. Because hinting
+multiple consecutive bytes is rarely useful, SourceGen only applies code
+hints to the first byte in a selected line.
Data hints tell the analyzer when it should stop. For example,
suppose address $ff00 is known to always be nonzero, and the code uses
@@ -276,6 +278,8 @@ the BNE that sets Z=0, so the code tracer will know it's a branch-always
and do the right thing.) It's only necessary to place a hint on the
very first (opcode) byte. Placing a data hint in the middle of what
SourceGen believes to be instruction will have no effect.
+As with code hints, only the first byte in each selected line will
+be hinted.
Inline data hints identify bytes as being part of the
instruction stream, but not instructions. A simple example of this
@@ -289,7 +293,8 @@ is the ProDOS 8 call interface on the Apple II, which looks like this:
The three bytes following the JSR $bf00
should be hinted
as inline data, so that the code analyzer skips them and continues the
-analysis at the BCS
.
+analysis at the BCS
. Because you need to hint *every* byte
+of inline data, all bytes in a selected line will receive hints.
If code branches into a region that is marked as inline data, the
branch will be ignored.
diff --git a/SourceGen/RuntimeData/Help/mainwin.html b/SourceGen/RuntimeData/Help/mainwin.html
index e41aa6e..124c0f0 100644
--- a/SourceGen/RuntimeData/Help/mainwin.html
+++ b/SourceGen/RuntimeData/Help/mainwin.html
@@ -281,20 +281,26 @@ Ctrl+- / Ctrl+Shift+-, as keyboard shortcuts.)
-To add code entry or data hints, select the offsets with the instruction
-opcodes, and then use the "Hint as Code Entry Point" or "Hint as Data"
-menu item. Remember to avoid hinting additional bytes, especially with
-code entry points, as that can lead to unwanted embedded instructions.
-For inline data, select all of the data that the code analyzer should
-skip, and use the "Hint as Inline Data" menu item.
+To add code entry or data hints, select the desired offsets and
+use Actions > Hint As Code Entry Point or Hint As Data. Because code
+hints mean "the code analyzer should start here", and data hints mean
+"the code analyzer should stop here", there is rarely any reason to hint
+multiple consecutive bytes. For this reason, only the first byte on each
+selected line will be hinted.
+For inline data, you need to hint every byte, so every byte in every
+selected line is hinted when you select Hint As Inline Data. Similarly,
+the Remove Hints menu item will remove hints from every byte.
If you're having a hard time selecting just the right bytes because
the instructions are caught up in a multi-byte data item, such as an
-auto-detected ASCII string, you can use the "Toggle Single-Byte Format"
-menu item to "flatten" the item. Apply the hint, then toggle the bytes
-back to default format. You can also disable uncategorized data analysis
-entirely from the
-project properties editor.
+auto-detected ASCII string, you can disable uncategorized data analysis
+(the thing that creates the .STR and .FILL ops for you). You can do this
+from the
+project properties editor,
+or simply by hitting Ctrl+D. Hit that, apply the hint, then hit it
+again to re-enable the string & fill analyzer.
+Another approach is to can use the "Toggle Single-Byte Format"
+menu item to "flatten" the item.
@@ -392,6 +398,18 @@ selecting "Default".
string, but you want to see it as bytes or set a label in the middle.
+
+
+This menu item is in the Edit menu, and acts as a shortcut to opening
+the Project Properties editor, and clicking on the "Analyze Uncategorized
+Data" checkbox. When enabled, SourceGen will look for ASCII strings and
+regions of identical bytes, and generate .STR and .FILL directives. When
+disabled, uncategorized data is presented as one byte per line, which can
+be handy if you're trying to get at a bit in the middle of a string.
+As with all other project properties changes, this is an undoable
+event.
+
+
When you use Edit > Copy, all lines selected in the code list are