1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-25 05:29:31 +00:00

Make "smart" PLP handling optional

We try to be clever with PHP/PLP, but sometimes we get it wrong.  If
we get it wrong a lot, we want to turn it off.  Now we can.
This commit is contained in:
Andy McFadden 2019-09-02 15:57:59 -07:00
parent 54e7f68490
commit 431ad94d95
8 changed files with 64 additions and 23 deletions

View File

@ -146,6 +146,11 @@ namespace SourceGen {
/// </summary>
private StatusFlags mEntryFlags;
/// <summary>
/// User-configurable analysis parameters.
/// </summary>
private ProjectProperties.AnalysisParameters mAnalysisParameters;
/// <summary>
/// Debug trace log.
/// </summary>
@ -168,7 +173,8 @@ namespace SourceGen {
/// <param name="debugLog">Object that receives debug log messages.</param>
public CodeAnalysis(byte[] data, CpuDef cpuDef, Anattrib[] anattribs,
AddressMap addrMap, TypeHint[] hints, StatusFlags[] statusFlagOverrides,
StatusFlags entryFlags, ScriptManager scriptMan, DebugLog debugLog) {
StatusFlags entryFlags, ProjectProperties.AnalysisParameters parms,
ScriptManager scriptMan, DebugLog debugLog) {
mFileData = data;
mCpuDef = cpuDef;
mAnattribs = anattribs;
@ -177,6 +183,7 @@ namespace SourceGen {
mStatusFlagOverrides = statusFlagOverrides;
mEntryFlags = entryFlags;
mScriptManager = scriptMan;
mAnalysisParameters = parms;
mDebugLog = debugLog;
mScriptSupport = new ScriptSupport(this);
@ -789,16 +796,18 @@ namespace SourceGen {
backOffsetLimit = 0;
}
StatusFlags flags = StatusFlags.AllIndeterminate;
for (int offset = plpOffset - 1; offset >= backOffsetLimit; offset--) {
Anattrib attr = mAnattribs[offset];
if (!attr.IsInstructionStart || !attr.IsVisited) {
continue;
}
OpDef op = mCpuDef.GetOpDef(mFileData[offset]);
if (op == OpDef.OpPHP_StackPush) {
LogI(plpOffset, "Found visited PHP at +" + offset.ToString("x6"));
flags = mAnattribs[offset].StatusFlags;
break;
if (mAnalysisParameters.SmartPlpHandling) {
for (int offset = plpOffset - 1; offset >= backOffsetLimit; offset--) {
Anattrib attr = mAnattribs[offset];
if (!attr.IsInstructionStart || !attr.IsVisited) {
continue;
}
OpDef op = mCpuDef.GetOpDef(mFileData[offset]);
if (op == OpDef.OpPHP_StackPush) {
LogI(plpOffset, "Found visited PHP at +" + offset.ToString("x6"));
flags = mAnattribs[offset].StatusFlags;
break;
}
}
}

View File

@ -618,8 +618,8 @@ namespace SourceGen {
reanalysisTimer.StartTask("CodeAnalysis.Analyze");
CodeAnalysis ca = new CodeAnalysis(mFileData, CpuDef, mAnattribs, AddrMap,
TypeHints, StatusFlagOverrides, ProjectProps.EntryFlags, mScriptManager,
debugLog);
TypeHints, StatusFlagOverrides, ProjectProps.EntryFlags,
ProjectProps.AnalysisParams, mScriptManager, debugLog);
ca.Analyze();
reanalysisTimer.EndTask("CodeAnalysis.Analyze");

View File

@ -219,6 +219,7 @@ namespace SourceGen {
public string DefaultTextScanMode { get; set; }
public int MinCharsForString { get; set; }
public bool SeekNearbyTargets { get; set; }
public bool SmartPlpHandling { get; set; }
public SerAnalysisParameters() { }
public SerAnalysisParameters(ProjectProperties.AnalysisParameters src) {
@ -226,6 +227,7 @@ namespace SourceGen {
DefaultTextScanMode = src.DefaultTextScanMode.ToString();
MinCharsForString = src.MinCharsForString;
SeekNearbyTargets = src.SeekNearbyTargets;
SmartPlpHandling = src.SmartPlpHandling;
}
}
public class SerAddressMap {
@ -511,6 +513,13 @@ namespace SourceGen {
spf.ProjectProps.AnalysisParams.MinCharsForString;
proj.ProjectProps.AnalysisParams.SeekNearbyTargets =
spf.ProjectProps.AnalysisParams.SeekNearbyTargets;
if (spf._ContentVersion < 2) {
// This was made optional in v1.3. Default it to true for older projects.
proj.ProjectProps.AnalysisParams.SmartPlpHandling = true;
} else {
proj.ProjectProps.AnalysisParams.SmartPlpHandling =
spf.ProjectProps.AnalysisParams.SmartPlpHandling;
}
// Deserialize ProjectProperties: external file identifiers.
Debug.Assert(proj.ProjectProps.PlatformSymbolFileIdentifiers.Count == 0);

View File

@ -51,18 +51,22 @@ namespace SourceGen {
public TextScanMode DefaultTextScanMode { get; set; }
public int MinCharsForString { get; set; }
public bool SeekNearbyTargets { get; set; }
public bool SmartPlpHandling { get; set; }
public AnalysisParameters() {
// Set default values.
AnalyzeUncategorizedData = true;
DefaultTextScanMode = TextScanMode.LowHighAscii;
MinCharsForString = DataAnalysis.DEFAULT_MIN_STRING_LENGTH;
SeekNearbyTargets = true;
SmartPlpHandling = true;
}
public AnalysisParameters(AnalysisParameters src) {
AnalyzeUncategorizedData = src.AnalyzeUncategorizedData;
DefaultTextScanMode = src.DefaultTextScanMode;
MinCharsForString = src.MinCharsForString;
SeekNearbyTargets = src.SeekNearbyTargets;
SmartPlpHandling = src.SmartPlpHandling;
}
}

View File

@ -244,15 +244,18 @@ status flag override to get correct disassembly.</p>
<p>The instruction that is most likely to cause problems is <code>PLP</code>,
which pulls the processor status flags off of the stack. SourceGen
doesn't try to track stack contents, so it can't know what values may
be pulled. In many cases the PLP appears not long after a PHP, so
SourceGen will scan backward through the file to find the nearest PHP,
and use the status flags from that. If no PHP can be found, then all
be pulled. In many cases the <code>PLP</code> appears not long after a
<code>PHP</code>, so SourceGen will scan backward through the file to
find the nearest <code>PHP</code>, and use the status flags from that. If
no <code>PHP</code> can be found, then all
flags are set to "indeterminate". (The boot loader in the Apple II 5.25"
floppy disk controller is an example where SourceGen gets it wrong. The
code does <code>CLC</code>/<code>PHP</code>, followed a bit later by the
<code>PLP</code>, but it's actually using the stack to pass the carry
flag around. Flagging the carry bit as indeterminate with a status flag
override on the instruction following the PLP fixes things.)</p>
override on the instruction following the PLP fixes things.) The
"smart" behavior can be disabled in the project properties if it's coming
out wrong more often than right.</p>
<p>Some other things that the code analyzer can't recognize automatically:</p>
<ul>

View File

@ -227,11 +227,17 @@ entry point hint) will use this value. This is chiefly of value for
<p>If "analyze uncategorized data" is checked, SourceGen will attempt to
identify character strings and regions that are filled with a repeated
value. If it's
not checked, anything that isn't detected as code or explicitly formatted
will simply be shown as a byte value.</p>
value. If it's not checked, anything that isn't detected as code or
explicitly formatted as data will be shown as individual byte values.</p>
<p>If "seek nearby targets" is checked, the analyzer will try to use
nearby labels for data loads and stores.</p>
nearby labels for data loads and stores, adjusting them to fit
(e.g. <code>LDA LABEL+1</code>). If not enabled, labels are only used
when they match exactly.</p>
<p>If "smart PLP handling" is checked, the analyzer will try to use
the processor status flags from a nearby <code>PHP</code> when a
<code>PLP</code> is encountered. If not enabled, all flags are set to
"indeterminate" following a <code>PLP</code>.</p>
<p>The "default text encoding" setting has two effects. First, it
specifies which character encoding to use when searching for strings in
uncategorized data. Second, if an assembler has a notion of preferred

View File

@ -94,10 +94,12 @@ limitations under the License.
<GroupBox Header="Analysis Parameters" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2"
Margin="4,0,0,0" Padding="2,4">
<StackPanel>
<CheckBox Name="analyzeUncategorizedCheckBox" Content="Analyze uncategorized data"
<CheckBox Content="Analyze uncategorized data"
IsChecked="{Binding AnalyzeUncategorizedData}"/>
<CheckBox Name="seekAltTargetCheckBox" Margin="0,4,0,0" Content="Seek nearby targets"
<CheckBox Margin="0,4,0,0" Content="Seek nearby targets"
IsChecked="{Binding SeekNearbyTargets}"/>
<CheckBox Margin="0,4,0,0" Content="Smart PLP handling"
IsChecked="{Binding SmartPlpHandling}"/>
<StackPanel Orientation="Horizontal" Margin="0,4,0,0">
<TextBlock Margin="0,3,0,0" Text="Default text encoding:"/>

View File

@ -275,6 +275,14 @@ namespace SourceGen.WpfGui {
IsDirty = true;
}
}
public bool SmartPlpHandling {
get { return mWorkProps.AnalysisParams.SmartPlpHandling; }
set {
mWorkProps.AnalysisParams.SmartPlpHandling = value;
OnPropertyChanged();
IsDirty = true;
}
}
private void Loaded_General() {
for (int i = 0; i < CpuItems.Length; i++) {