1
0
mirror of https://github.com/fadden/6502bench.git synced 2025-07-22 10:24:07 +00:00

Add Data Bank Register management, part 1

On the 65816, 16-bit data access instructions (e.g. LDA abs) are
expanded to 24 bits by merging in the Data Bank Register (B).  The
value of the register is difficult to determine via static analysis,
so we need a way to annotate the disassembly with the correct value.
Without this, the mapping of address to file offset will sometimes
be incorrect.

This change adds the basic data structures and "fixup" function, a
functional but incomplete editor, and source for a new test case.
This commit is contained in:
Andy McFadden
2020-07-08 17:56:27 -07:00
parent 44522dc2f2
commit 18e6951f17
15 changed files with 590 additions and 22 deletions

View File

@@ -74,6 +74,11 @@ namespace SourceGen {
/// </summary>
public string[] Comments { get; private set; }
/// <summary>
/// Data Bank Register overrides.
/// </summary>
public Dictionary<int, CodeAnalysis.DbrValue> DbrValues { get; private set; }
/// <summary>
/// Full line, possibly multi-line comments.
/// </summary>
@@ -274,6 +279,7 @@ namespace SourceGen {
Comments[i] = string.Empty;
}
DbrValues = new Dictionary<int, CodeAnalysis.DbrValue>();
LongComments = new Dictionary<int, MultiLineComment>();
Notes = new SortedList<int, MultiLineComment>();
@@ -807,6 +813,13 @@ namespace SourceGen {
ca.Analyze();
reanalysisTimer.EndTask("CodeAnalysis.Analyze");
if (!CpuDef.HasAddr16) {
// 24-bit address space, so DBR matters
reanalysisTimer.StartTask("CodeAnalysis.ApplyDataBankRegister");
ca.ApplyDataBankRegister(DbrValues);
reanalysisTimer.EndTask("CodeAnalysis.ApplyDataBankRegister");
}
// Save a copy of the current state.
mCodeOnlyAnattribs = new Anattrib[mAnattribs.Length];
Array.Copy(mAnattribs, mCodeOnlyAnattribs, mAnattribs.Length);
@@ -831,6 +844,8 @@ namespace SourceGen {
DataAnalysis da = new DataAnalysis(this, mAnattribs);
da.DebugLog = debugLog;
// Convert references to addresses into references to labels, generating labels
// as needed.
reanalysisTimer.StartTask("DataAnalysis.AnalyzeDataTargets");
da.AnalyzeDataTargets();
reanalysisTimer.EndTask("DataAnalysis.AnalyzeDataTargets");
@@ -2103,6 +2118,27 @@ namespace SourceGen {
UndoableChange.ReanalysisScope.CodeAndData);
}
break;
case UndoableChange.ChangeType.SetDataBank: {
// If there's no entry, treat it as an entry with value = Unknown.
if (!DbrValues.TryGetValue(offset, out CodeAnalysis.DbrValue current)) {
current = CodeAnalysis.DbrValue.Unknown;
}
if (current != (CodeAnalysis.DbrValue)oldValue) {
Debug.WriteLine("GLITCH: old DBR value mismatch (" +
current + " vs " + oldValue + ")");
Debug.Assert(false);
}
if ((CodeAnalysis.DbrValue)newValue == CodeAnalysis.DbrValue.Unknown) {
DbrValues.Remove(offset);
} else {
DbrValues[offset] = (CodeAnalysis.DbrValue)newValue;
}
// ignore affectedOffsets
Debug.Assert(uc.ReanalysisRequired ==
UndoableChange.ReanalysisScope.CodeAndData);
}
break;
case UndoableChange.ChangeType.SetTypeHint: {
// Always requires full code+data re-analysis.
ApplyTypeHints((TypedRangeSet)oldValue, (TypedRangeSet)newValue);