1
0
mirror of https://github.com/fadden/6502bench.git synced 2026-04-26 12:18:26 +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
+68 -31
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));
}
}
}
}
}