mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-31 21:30:59 +00:00
Wire up the Info panel
This commit is contained in:
parent
fa386a0d03
commit
814ab97c4d
@ -24,6 +24,7 @@ using Asm65;
|
||||
using CommonUtil;
|
||||
using SourceGenWPF.ProjWin;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace SourceGenWPF {
|
||||
/// <summary>
|
||||
@ -1013,6 +1014,12 @@ namespace SourceGenWPF {
|
||||
return mProject != null;
|
||||
}
|
||||
|
||||
public void SelectionChanged(out SelectionState newState) {
|
||||
newState = UpdateSelectionState();
|
||||
|
||||
UpdateInfoPanel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gathered facts about the current selection. Recalculated whenever the selection
|
||||
/// changes.
|
||||
@ -1282,5 +1289,228 @@ namespace SourceGenWPF {
|
||||
}
|
||||
|
||||
#endregion Main window UI event handlers
|
||||
|
||||
#region Info panel
|
||||
|
||||
private void UpdateInfoPanel() {
|
||||
if (mMainWin.GetSelectionCount() != 1) {
|
||||
// Nothing selected, or multiple lines selected.
|
||||
mMainWin.InfoBoxContents = string.Empty;
|
||||
return;
|
||||
}
|
||||
int lineIndex = mMainWin.GetFirstSelectedIndex();
|
||||
LineListGen.Line line = CodeListGen[lineIndex];
|
||||
StringBuilder sb = new StringBuilder(250);
|
||||
|
||||
// TODO(someday): this should be made easier to localize
|
||||
string lineTypeStr;
|
||||
string extraStr = string.Empty;
|
||||
switch (line.LineType) {
|
||||
case LineListGen.Line.Type.Code:
|
||||
lineTypeStr = "code";
|
||||
break;
|
||||
case LineListGen.Line.Type.Data:
|
||||
if (mProject.GetAnattrib(line.FileOffset).IsInlineData) {
|
||||
lineTypeStr = "inline data";
|
||||
} else {
|
||||
lineTypeStr = "data";
|
||||
}
|
||||
break;
|
||||
case LineListGen.Line.Type.LongComment:
|
||||
lineTypeStr = "comment";
|
||||
break;
|
||||
case LineListGen.Line.Type.Note:
|
||||
lineTypeStr = "note";
|
||||
break;
|
||||
case LineListGen.Line.Type.Blank:
|
||||
lineTypeStr = "blank line";
|
||||
//lineTypeStr = "blank line (+" +
|
||||
// mOutputFormatter.FormatOffset24(line.FileOffset) + ")";
|
||||
break;
|
||||
case LineListGen.Line.Type.OrgDirective:
|
||||
lineTypeStr = "address directive";
|
||||
break;
|
||||
case LineListGen.Line.Type.RegWidthDirective:
|
||||
lineTypeStr = "register width directive";
|
||||
break;
|
||||
case LineListGen.Line.Type.EquDirective: {
|
||||
lineTypeStr = "equate";
|
||||
int symIndex = LineListGen.DefSymIndexFromOffset(line.FileOffset);
|
||||
DefSymbol defSym = mProject.ActiveDefSymbolList[symIndex];
|
||||
string sourceStr;
|
||||
if (defSym.SymbolSource == Symbol.Source.Project) {
|
||||
sourceStr = "project symbol definition";
|
||||
} else if (defSym.SymbolSource == Symbol.Source.Platform) {
|
||||
sourceStr = "platform symbol file";
|
||||
} else {
|
||||
sourceStr = "???";
|
||||
}
|
||||
extraStr = "Source: " + sourceStr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lineTypeStr = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
// For anything that isn't code or data, show something simple and bail.
|
||||
if (line.OffsetSpan == 0) {
|
||||
sb.AppendFormat(Res.Strings.INFO_LINE_SUM_NON_FMT,
|
||||
lineIndex, lineTypeStr);
|
||||
#if DEBUG
|
||||
sb.Append(" [offset=+" + line.FileOffset.ToString("x6") + "]");
|
||||
#endif
|
||||
if (!string.IsNullOrEmpty(extraStr)) {
|
||||
sb.Append("\r\n\r\n");
|
||||
sb.Append(extraStr);
|
||||
}
|
||||
mMainWin.InfoBoxContents = sb.ToString();
|
||||
return;
|
||||
}
|
||||
Debug.Assert(line.IsCodeOrData);
|
||||
|
||||
Anattrib attr = mProject.GetAnattrib(line.FileOffset);
|
||||
|
||||
// Show number of bytes of code/data.
|
||||
if (line.OffsetSpan == 1) {
|
||||
sb.AppendFormat(Res.Strings.INFO_LINE_SUM_SINGULAR_FMT,
|
||||
lineIndex, line.OffsetSpan, lineTypeStr);
|
||||
} else {
|
||||
sb.AppendFormat(Res.Strings.INFO_LINE_SUM_PLURAL_FMT,
|
||||
lineIndex, line.OffsetSpan, lineTypeStr);
|
||||
}
|
||||
sb.Append("\r\n");
|
||||
|
||||
if (!mProject.OperandFormats.TryGetValue(line.FileOffset, out FormatDescriptor dfd)) {
|
||||
// No user-specified format, but there may be a generated format.
|
||||
sb.AppendFormat(Res.Strings.INFO_FD_SUM_FMT, Res.Strings.DEFAULT_VALUE);
|
||||
if (attr.DataDescriptor != null) {
|
||||
sb.Append(" [");
|
||||
sb.Append(attr.DataDescriptor.ToUiString());
|
||||
sb.Append("]");
|
||||
}
|
||||
} else {
|
||||
// User-specified operand format.
|
||||
// If the descriptor has a weak reference to an unknown symbol, should we
|
||||
// call that out here?
|
||||
sb.AppendFormat(Res.Strings.INFO_FD_SUM_FMT, dfd.ToUiString());
|
||||
}
|
||||
sb.Append("\r\n");
|
||||
|
||||
// Debug only
|
||||
//sb.Append("DEBUG: opAddr=" + attr.OperandAddress.ToString("x4") +
|
||||
// " opOff=" + attr.OperandOffset.ToString("x4") + "\r\n");
|
||||
|
||||
sb.Append("\u2022Attributes:");
|
||||
if (attr.IsHinted) {
|
||||
sb.Append(" Hinted(");
|
||||
for (int i = 0; i < line.OffsetSpan; i++) {
|
||||
switch (mProject.TypeHints[line.FileOffset + i]) {
|
||||
case CodeAnalysis.TypeHint.Code:
|
||||
sb.Append("C");
|
||||
break;
|
||||
case CodeAnalysis.TypeHint.Data:
|
||||
sb.Append("D");
|
||||
break;
|
||||
case CodeAnalysis.TypeHint.InlineData:
|
||||
sb.Append("I");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (i > 8) {
|
||||
sb.Append("...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sb.Append(')');
|
||||
}
|
||||
if (attr.IsEntryPoint) {
|
||||
sb.Append(" EntryPoint");
|
||||
}
|
||||
if (attr.IsBranchTarget) {
|
||||
sb.Append(" BranchTarget");
|
||||
}
|
||||
if (attr.DoesNotContinue) {
|
||||
sb.Append(" NoContinue");
|
||||
}
|
||||
if (attr.DoesNotBranch) {
|
||||
sb.Append(" NoBranch");
|
||||
}
|
||||
if (mProject.StatusFlagOverrides[line.FileOffset].AsInt != 0) {
|
||||
sb.Append(" StatusFlags");
|
||||
}
|
||||
sb.Append("\r\n\r\n");
|
||||
|
||||
if (attr.IsInstruction) {
|
||||
Asm65.OpDef op = mProject.CpuDef.GetOpDef(mProject.FileData[line.FileOffset]);
|
||||
|
||||
string shortDesc = mOpDesc.GetShortDescription(op.Mnemonic);
|
||||
if (!string.IsNullOrEmpty(shortDesc)) {
|
||||
if (op.IsUndocumented) {
|
||||
sb.Append("\u25b6[*] ");
|
||||
} else {
|
||||
sb.Append("\u25b6 ");
|
||||
}
|
||||
sb.Append(shortDesc);
|
||||
string addrStr = mOpDesc.GetAddressModeDescription(op.AddrMode);
|
||||
if (!string.IsNullOrEmpty(addrStr)) {
|
||||
sb.Append(", ");
|
||||
sb.Append(addrStr);
|
||||
}
|
||||
sb.Append("\r\n");
|
||||
}
|
||||
|
||||
sb.Append("\u2022Cycles: ");
|
||||
int cycles = op.Cycles;
|
||||
Asm65.OpDef.CycleMod cycMods = op.CycleMods;
|
||||
sb.Append(cycles.ToString());
|
||||
if (cycMods != 0) {
|
||||
sb.Append(" (");
|
||||
int workBits = (int)cycMods;
|
||||
while (workBits != 0) {
|
||||
// Isolate rightmost bit.
|
||||
int firstBit = (~workBits + 1) & workBits;
|
||||
sb.Append(mOpDesc.GetCycleModDescription((OpDef.CycleMod)firstBit));
|
||||
// Remove from set.
|
||||
workBits &= ~firstBit;
|
||||
if (workBits != 0) {
|
||||
// more to come
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
sb.Append(")");
|
||||
}
|
||||
sb.Append("\r\n");
|
||||
|
||||
const string FLAGS = "NVMXDIZC";
|
||||
sb.Append("\u2022Flags affected: ");
|
||||
Asm65.StatusFlags affectedFlags = op.FlagsAffected;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (affectedFlags.GetBit((StatusFlags.FlagBits)(7 - i)) >= 0) {
|
||||
sb.Append(' ');
|
||||
sb.Append(FLAGS[i]);
|
||||
} else {
|
||||
sb.Append(" -");
|
||||
}
|
||||
}
|
||||
sb.Append("\r\n");
|
||||
|
||||
string longDesc = mOpDesc.GetLongDescription(op.Mnemonic);
|
||||
if (!string.IsNullOrEmpty(longDesc)) {
|
||||
sb.Append("\r\n");
|
||||
sb.Append(longDesc);
|
||||
sb.Append("\r\n");
|
||||
}
|
||||
} else {
|
||||
// do we want descriptions of the pseudo-ops?
|
||||
}
|
||||
|
||||
|
||||
// Publish
|
||||
mMainWin.InfoBoxContents = sb.ToString();
|
||||
}
|
||||
|
||||
#endregion Info panel
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +314,9 @@ limitations under the License.
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Row="2" Header="Info">
|
||||
<TextBox/>
|
||||
<TextBox Text="{Binding InfoBoxContents}"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"
|
||||
TextWrapping="Wrap"/>
|
||||
</GroupBox>
|
||||
|
||||
<GridSplitter Height="4" Grid.Row="1"
|
||||
|
@ -43,6 +43,11 @@ namespace SourceGenWPF.ProjWin {
|
||||
/// </summary>
|
||||
public DisplayList CodeDisplayList { get; private set; }
|
||||
|
||||
/// Version string, for display.
|
||||
/// </summary>
|
||||
public string ProgramVersionString {
|
||||
get { return App.ProgramVersion.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reference to controller object.
|
||||
@ -203,11 +208,20 @@ namespace SourceGenWPF.ProjWin {
|
||||
get { return mShowCodeListView ? Visibility.Visible : Visibility.Hidden; }
|
||||
}
|
||||
|
||||
/// Version string, for display.
|
||||
/// <summary>
|
||||
/// Text to display in the Info panel. This is a simple TextBox.
|
||||
/// </summary>
|
||||
public string ProgramVersionString {
|
||||
get { return App.ProgramVersion.ToString(); }
|
||||
public string InfoBoxContents {
|
||||
get {
|
||||
return mInfoBoxContents;
|
||||
}
|
||||
set {
|
||||
mInfoBoxContents = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
private string mInfoBoxContents;
|
||||
|
||||
|
||||
private void CodeListView_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||
//DateTime startWhen = DateTime.Now;
|
||||
@ -215,8 +229,9 @@ namespace SourceGenWPF.ProjWin {
|
||||
// Update the selected-item bitmap.
|
||||
CodeDisplayList.SelectedIndices.SelectionChanged(e);
|
||||
|
||||
// Update the selection summary, which is used for can-execute methods.
|
||||
mSelectionState = mMainCtrl.UpdateSelectionState();
|
||||
// Notify MainController that the selection has changed. This hands back an updated
|
||||
// selection summary, which is used for "can execute" methods.
|
||||
mMainCtrl.SelectionChanged(out mSelectionState);
|
||||
|
||||
Debug.Assert(CodeDisplayList.SelectedIndices.DebugValidateSelectionCount(
|
||||
codeListView.SelectedItems.Count));
|
||||
|
@ -3,6 +3,7 @@
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:local="clr-namespace:SourceGenWPF.Res">
|
||||
|
||||
<system:String x:Key="str_DefaultValue">Default</system:String>
|
||||
<system:String x:Key="str_ErrBadFd">Bad format descriptor at +{0:x6}.</system:String>
|
||||
<system:String x:Key="str_ErrBadFdFormat">Bad format descriptor type</system:String>
|
||||
<system:String x:Key="str_ErrBadFileLength">Bad file length</system:String>
|
||||
@ -27,6 +28,10 @@
|
||||
<system:String x:Key="str_FileFilterDis65">SourceGen projects(*.dis65)|*.dis65</system:String>
|
||||
<system:String x:Key="str_FileFilterSym65">SourceGen symbols (*.sym65)|*.sym65</system:String>
|
||||
<system:String x:Key="str_GeneratedForVersion">Target assembler: {0} v{1} [{2}]</system:String>
|
||||
<system:String x:Key="str_InfoFdSumFmt">•Operand format is {0}</system:String>
|
||||
<system:String x:Key="str_InfoLineSumNonFmt">Line {0}: {1}</system:String>
|
||||
<system:String x:Key="str_InfoLineSumPluralFmt">Line {0}: {1} bytes of {2}</system:String>
|
||||
<system:String x:Key="str_InfoLineSumSingularFmt">Line {0}: {1} byte of {2}</system:String>
|
||||
<system:String x:Key="str_InitialExtensionScripts">Extension scripts:</system:String>
|
||||
<system:String x:Key="str_InitialParameters">Default settings:</system:String>
|
||||
<system:String x:Key="str_InitialSymbolFiles">Symbol files:</system:String>
|
||||
|
@ -18,6 +18,8 @@ using System.Windows;
|
||||
|
||||
namespace SourceGenWPF.Res {
|
||||
public static class Strings {
|
||||
public static string DEFAULT_VALUE =
|
||||
(string)Application.Current.FindResource("str_DefaultValue");
|
||||
public static string ERR_BAD_FD =
|
||||
(string)Application.Current.FindResource("str_ErrBadFd");
|
||||
public static string ERR_BAD_FD_FORMAT =
|
||||
@ -66,6 +68,14 @@ namespace SourceGenWPF.Res {
|
||||
(string)Application.Current.FindResource("str_FileFilterSym65");
|
||||
public static string GENERATED_FOR_VERSION_FMT =
|
||||
(string)Application.Current.FindResource("str_GeneratedForVersion");
|
||||
public static string INFO_FD_SUM_FMT =
|
||||
(string)Application.Current.FindResource("str_InfoFdSumFmt");
|
||||
public static string INFO_LINE_SUM_NON_FMT =
|
||||
(string)Application.Current.FindResource("str_InfoLineSumNonFmt");
|
||||
public static string INFO_LINE_SUM_PLURAL_FMT =
|
||||
(string)Application.Current.FindResource("str_InfoLineSumPluralFmt");
|
||||
public static string INFO_LINE_SUM_SINGULAR_FMT =
|
||||
(string)Application.Current.FindResource("str_InfoLineSumSingularFmt");
|
||||
public static string INITIAL_EXTENSION_SCRIPTS =
|
||||
(string)Application.Current.FindResource("str_InitialExtensionScripts");
|
||||
public static string INITIAL_PARAMETERS =
|
||||
|
Loading…
Reference in New Issue
Block a user