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

Data Bank Register management, part 4

Implemented "smart" PLB handling.  If we see PHK/PLB, or 8-bit
LDA imm/PHA/PLB, we create a data bank change item.  The feature
can be disabled with a project property.
This commit is contained in:
Andy McFadden 2020-07-09 19:36:22 -07:00
parent ee58d9e803
commit 0929077fda
9 changed files with 111 additions and 45 deletions

View File

@ -1295,47 +1295,34 @@ namespace SourceGen {
/// Determines the value of the Data Bank Register (DBR, register 'B') for relevant
/// instructions, and updates the Anattrib OperandOffset value.
/// </summary>
/// <remarks>
/// This is of questionable value when we have reliable relocation data. OTOH it's
/// pretty quick even on very large files.
/// </remarks>
public void ApplyDataBankRegister(Dictionary<int, DbrValue> userValues,
Dictionary<int, DbrValue> dbrChanges) {
Debug.Assert(!mCpuDef.HasAddr16); // 65816 only
dbrChanges.Clear();
short[] bval = new short[mAnattribs.Length];
// Initialize all entries to "unknown".
Misc.Memset(bval, DbrValue.UNKNOWN);
// Set B=K every time we cross an address boundary and the program bank changes.
short prevBank = DbrValue.UNKNOWN;
foreach (AddressMap.AddressMapEntry ent in mAddrMap) {
short mapBank = (short)(ent.Addr >> 16);
if (mapBank != prevBank) {
bval[ent.Offset] = mapBank;
prevBank = mapBank;
dbrChanges.Add(ent.Offset, new DbrValue(false, (byte)mapBank,
DbrValue.Source.Auto));
}
if (mAnalysisParameters.SmartPlbHandling) {
GenerateSmartPlbChanges(dbrChanges);
}
// Apply the user-specified values, overwriting existing values.
// Apply the user-specified values, overwriting auto-generated values.
foreach (KeyValuePair<int, DbrValue> kvp in userValues) {
dbrChanges[kvp.Key] = kvp.Value;
}
// Create an array for fast access.
short[] bval = new short[mAnattribs.Length];
Misc.Memset(bval, DbrValue.UNKNOWN);
foreach (KeyValuePair<int, DbrValue> kvp in dbrChanges) {
bval[kvp.Key] = kvp.Value.AsShort;
}
// Run through the file, looking for PHK/PLB pairs. When we find one, set an
// entry for the PLB instruction unless an entry already exists there.
// add to dbrChanges with "Auto" or "smart"
// ? look for LDA #imm8 / PHA / PLB?
// ...
// Run through file, updating instructions as needed.
short curVal = 0;
short curVal = (byte)(mAddrMap.Get(0) >> 16); // start with B=K
for (int offset = 0; offset < mAnattribs.Length; offset++) {
if (bval[offset] != DbrValue.UNKNOWN) {
curVal = bval[offset];
@ -1358,15 +1345,65 @@ namespace SourceGen {
int newOffset = mAddrMap.AddressToOffset(offset, newAddr);
if (newAddr != mAnattribs[offset].OperandAddress ||
newOffset != mAnattribs[offset].OperandOffset) {
Debug.WriteLine("DBR rewrite at +" + offset.ToString("x6") + ": $" +
mAnattribs[offset].OperandAddress.ToString("x6") + "/+" +
mAnattribs[offset].OperandOffset.ToString("x6") + " --> $" +
newAddr.ToString("x6") + "/+" + newOffset.ToString("x6"));
//Debug.WriteLine("DBR rewrite at +" + offset.ToString("x6") + ": $" +
// mAnattribs[offset].OperandAddress.ToString("x6") + "/+" +
// mAnattribs[offset].OperandOffset.ToString("x6") + " --> $" +
// newAddr.ToString("x6") + "/+" + newOffset.ToString("x6"));
mAnattribs[offset].OperandAddress = newAddr;
mAnattribs[offset].OperandOffset = newOffset;
}
}
}
private void GenerateSmartPlbChanges(Dictionary<int, DbrValue> dbrChanges) {
#if false
// Set B=K every time we cross an address boundary and the program bank changes.
short prevBank = DbrValue.UNKNOWN;
foreach (AddressMap.AddressMapEntry ent in mAddrMap) {
short mapBank = (short)(ent.Addr >> 16);
if (mapBank != prevBank) {
prevBank = mapBank;
dbrChanges.Add(ent.Offset, new DbrValue(false, (byte)mapBank,
DbrValue.Source.Auto));
}
}
#endif
// Run through the file, looking for PLB. If the preceding code was something
// we can reliably pull a value out of, create an entry for it.
for (int offset = 0; offset < mAnattribs.Length; offset++) {
if (!mAnattribs[offset].IsInstructionStart) {
continue;
}
OpDef op = mCpuDef.GetOpDef(mFileData[offset]);
if (op != OpDef.OpPLB_StackPull) {
continue;
}
if (offset < 1) {
continue;
}
if (!mAnattribs[offset - 1].IsInstructionStart) {
continue;
}
op = mCpuDef.GetOpDef(mFileData[offset - 1]);
if (op == OpDef.OpPHK_StackPush) {
// output B=K
dbrChanges.Add(offset, new DbrValue(true, 0, DbrValue.Source.Auto));
} else if (op == OpDef.OpPHA_StackPush && offset >= 4) {
// check for LDA imm
if (!mAnattribs[offset - 3].IsInstructionStart) {
continue;
}
op = mCpuDef.GetOpDef(mFileData[offset - 3]);
if (!(op == OpDef.OpLDA_ImmLongA || op == OpDef.OpLDA_Imm)) {
continue;
}
byte bank = mFileData[offset - 2];
dbrChanges.Add(offset, new DbrValue(false, bank, DbrValue.Source.Auto));
}
}
}
}
}

View File

@ -1056,19 +1056,21 @@ namespace SourceGen {
// behavior is unwise.)
if (mProject.DbrChanges.TryGetValue(offset,
out CodeAnalysis.DbrValue dbrValue)) {
string operandStr;
string bankStr;
if (dbrValue.FollowPbr) {
operandStr = Res.Strings.DATA_BANK_USER_K;
bankStr = Res.Strings.DATA_BANK_K;
} else {
string fmt;
if (dbrValue.ValueSource == CodeAnalysis.DbrValue.Source.Auto) {
fmt = Res.Strings.DATA_BANK_AUTO_FMT;
} else {
fmt = Res.Strings.DATA_BANK_USER_FMT;
}
operandStr = string.Format(fmt,
mFormatter.FormatHexValue(dbrValue.Bank, 2));
bankStr = mFormatter.FormatHexValue(dbrValue.Bank, 2);
}
string fmt;
if (dbrValue.ValueSource == CodeAnalysis.DbrValue.Source.Auto) {
fmt = Res.Strings.DATA_BANK_AUTO_FMT;
} else {
fmt = Res.Strings.DATA_BANK_USER_FMT;
}
string operandStr = string.Format(fmt, bankStr);
Line dbrLine = new Line(offset, 0, Line.Type.DataBankDirective);
dbrLine.Parts = FormattedParts.CreateDirective(
mFormatter.FormatPseudoOp(mPseudoOpNames.DataBankDirective),

View File

@ -225,6 +225,7 @@ namespace SourceGen {
public bool SeekNearbyTargets { get; set; }
public bool UseRelocData { get; set; }
public bool SmartPlpHandling { get; set; }
public bool SmartPlbHandling { get; set; }
public SerAnalysisParameters() { }
public SerAnalysisParameters(ProjectProperties.AnalysisParameters src) {
@ -234,6 +235,7 @@ namespace SourceGen {
SeekNearbyTargets = src.SeekNearbyTargets;
UseRelocData = src.UseRelocData;
SmartPlpHandling = src.SmartPlpHandling;
SmartPlbHandling = src.SmartPlbHandling;
}
}
public class SerAddressMap {
@ -632,12 +634,19 @@ namespace SourceGen {
proj.ProjectProps.AnalysisParams.UseRelocData =
spf.ProjectProps.AnalysisParams.UseRelocData;
if (spf._ContentVersion < 2) {
// This was made optional in v1.3. Default it to true for older projects.
// This was made optional in v1.3 (#2). Default it to true for older projects.
proj.ProjectProps.AnalysisParams.SmartPlpHandling = true;
} else {
proj.ProjectProps.AnalysisParams.SmartPlpHandling =
spf.ProjectProps.AnalysisParams.SmartPlpHandling;
}
if (spf._ContentVersion < 4) {
// Introduced in v1.7 (#4). Default it to true for older projects.
proj.ProjectProps.AnalysisParams.SmartPlbHandling = true;
} else {
proj.ProjectProps.AnalysisParams.SmartPlbHandling =
spf.ProjectProps.AnalysisParams.SmartPlbHandling;
}
// Deserialize ProjectProperties: external file identifiers.
Debug.Assert(proj.ProjectProps.PlatformSymbolFileIdentifiers.Count == 0);

View File

@ -54,6 +54,7 @@ namespace SourceGen {
public bool SeekNearbyTargets { get; set; }
public bool UseRelocData { get; set; }
public bool SmartPlpHandling { get; set; }
public bool SmartPlbHandling { get; set; }
public AnalysisParameters() {
// Set default values.
@ -63,6 +64,7 @@ namespace SourceGen {
SeekNearbyTargets = true;
UseRelocData = false;
SmartPlpHandling = true;
SmartPlbHandling = true;
}
public AnalysisParameters(AnalysisParameters src) {
AnalyzeUncategorizedData = src.AnalyzeUncategorizedData;
@ -71,6 +73,7 @@ namespace SourceGen {
SeekNearbyTargets = src.SeekNearbyTargets;
UseRelocData = src.UseRelocData;
SmartPlpHandling = src.SmartPlpHandling;
SmartPlbHandling = src.SmartPlbHandling;
}
}

View File

@ -36,7 +36,7 @@ limitations under the License.
<system:String x:Key="str_ClipformatDisassembly">Disassembly</system:String>
<system:String x:Key="str_DataBankAutoFmt">{0} (auto)</system:String>
<system:String x:Key="str_DataBankUserFmt">{0}</system:String>
<system:String x:Key="str_DataBankUserK">K</system:String>
<system:String x:Key="str_DataBankK">K</system:String>
<system:String x:Key="str_DefaultHeaderCommentFmt">6502bench SourceGen v{0}</system:String>
<system:String x:Key="str_DefaultAsciiDelimPat">&#x2018;#&#x2019;</system:String>
<system:String x:Key="str_DefaultHighAsciiDelimPat">&#x201c;#&#x201d;</system:String>

View File

@ -47,8 +47,8 @@ namespace SourceGen.Res {
(string)Application.Current.FindResource("str_DataBankAutoFmt");
public static string DATA_BANK_USER_FMT =
(string)Application.Current.FindResource("str_DataBankUserFmt");
public static string DATA_BANK_USER_K =
(string)Application.Current.FindResource("str_DataBankUserK");
public static string DATA_BANK_K =
(string)Application.Current.FindResource("str_DataBankK");
public static string DEFAULT_HEADER_COMMENT_FMT =
(string)Application.Current.FindResource("str_DefaultHeaderCommentFmt");
public static string DEFAULT_ASCII_DELIM_PAT =

View File

@ -262,6 +262,11 @@ improve automatic operand formatting.</p>
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>If "smart PLB handling" is checked, the analyzer will watch for
code patterns like <code>PLB</code> preceded by <code>PHK</code>,
and generate appropriate Data Bank Register changes. If not enabled,
the DBR is set to the bank of the address of the start of the file,
and does not change unless explicitly set. Only useful for 65816 code.</p>
<p>The "default text encoding" setting has two effects. First, it
specifies which character encoding to use when searching for strings in

View File

@ -107,6 +107,8 @@ limitations under the License.
IsChecked="{Binding UseRelocData}" IsEnabled="{Binding IsRelocDataAvailable}"/>
<CheckBox Margin="0,4,0,0" Content="Smart PLP handling"
IsChecked="{Binding SmartPlpHandling}"/>
<CheckBox Margin="0,4,0,0" Content="Smart PLB handling"
IsChecked="{Binding SmartPlbHandling}"/>
<StackPanel Orientation="Horizontal" Margin="0,4,0,0">
<TextBlock Margin="0,3,0,0" Text="Default text encoding:"/>

View File

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