mirror of
https://github.com/fadden/6502bench.git
synced 2024-06-24 08:29:29 +00:00
Show variable tables in line list
Multi-line item, with one .eq line per variable definition. Add one header line if "clear previous" is set. Also, limit variable values to 0-255 in the editor. This is somewhat arbitrary, but I think a focus on DP is useful.
This commit is contained in:
parent
0eeb36f59a
commit
c4c67757c0
|
@ -224,6 +224,10 @@ namespace SourceGen {
|
|||
|
||||
private List<Tag> mSelectionTags = new List<Tag>();
|
||||
|
||||
/// <summary>
|
||||
/// Holds data that helps us position the scroll view at the correct position
|
||||
/// after changes have been applied.
|
||||
/// </summary>
|
||||
private class Top {
|
||||
// File offset of line.
|
||||
public int FileOffset { get; private set; }
|
||||
|
@ -496,6 +500,9 @@ namespace SourceGen {
|
|||
case Line.Type.Data:
|
||||
parts = GenerateDataLine(line.FileOffset, line.SubLineIndex);
|
||||
break;
|
||||
case Line.Type.LocalVariableTable:
|
||||
parts = GenerateLvTableLine(line.FileOffset, line.SubLineIndex);
|
||||
break;
|
||||
case Line.Type.Blank:
|
||||
// Nothing to do.
|
||||
parts = FormattedParts.CreateBlankLine();
|
||||
|
@ -937,6 +944,23 @@ namespace SourceGen {
|
|||
longComment.BackgroundColor, lines);
|
||||
}
|
||||
|
||||
// Local variable tables come next. Defer rendering.
|
||||
if (mProject.LvTables.TryGetValue(offset, out LocalVariableTable lvt)) {
|
||||
int count = lvt.Variables.Count;
|
||||
// If "clear previous" is set, we output an additional line.
|
||||
if (lvt.ClearPrevious) {
|
||||
count++;
|
||||
}
|
||||
if (count == 0) {
|
||||
// Need to show something so the user will know an empty table is here.
|
||||
count = 1;
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
Line line = new Line(offset, 0, Line.Type.LocalVariableTable, i);
|
||||
lines.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (attr.IsInstructionStart) {
|
||||
// Generate reg width directive, if necessary.
|
||||
if (mProject.CpuDef.HasEmuFlag) {
|
||||
|
@ -1270,6 +1294,48 @@ namespace SourceGen {
|
|||
return parts;
|
||||
}
|
||||
|
||||
private FormattedParts GenerateLvTableLine(int offset, int subLineIndex) {
|
||||
if (!mProject.LvTables.TryGetValue(offset, out LocalVariableTable lvt)) {
|
||||
Debug.Assert(false);
|
||||
return FormattedParts.CreateLongComment("BAD OFFSET +" + offset.ToString("x6") +
|
||||
" sub=" + subLineIndex);
|
||||
}
|
||||
|
||||
if (lvt.ClearPrevious) {
|
||||
if (subLineIndex == 0) {
|
||||
return FormattedParts.CreateLongComment(
|
||||
Res.Strings.LOCAL_VARIABLE_TABLE_CLEAR);
|
||||
} else {
|
||||
// adjust for previously output "clear" line
|
||||
subLineIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
if (lvt.Variables.Count == 0) {
|
||||
// If ClearPrevious is set, we returned the "clear" line for index zero.
|
||||
// So this is an empty table without a clear. We want to show something so
|
||||
// the user knows there's dead weight here.
|
||||
Debug.Assert(subLineIndex == 0 && !lvt.ClearPrevious);
|
||||
return FormattedParts.CreateLongComment(
|
||||
Res.Strings.LOCAL_VARIABLE_TABLE_EMPTY);
|
||||
}
|
||||
|
||||
if (subLineIndex >= lvt.Variables.Values.Count) {
|
||||
return FormattedParts.CreateLongComment("BAD INDEX +" + offset.ToString("x6") +
|
||||
" sub=" + subLineIndex);
|
||||
} else {
|
||||
DefSymbol defSym = lvt.Variables.Values[subLineIndex];
|
||||
// Use an operand length of 1 so things are shown as concisely as possible.
|
||||
string addrStr = PseudoOp.FormatNumericOperand(mFormatter, mProject.SymbolTable,
|
||||
null, defSym.DataDescriptor, defSym.Value, 1,
|
||||
PseudoOp.FormatNumericOpFlags.None);
|
||||
string comment = mFormatter.FormatEolComment(defSym.Comment);
|
||||
return FormattedParts.CreateEquDirective(defSym.Label,
|
||||
mFormatter.FormatPseudoOp(mPseudoOpNames.EquDirective),
|
||||
addrStr, comment);
|
||||
}
|
||||
}
|
||||
|
||||
private FormattedParts[] GenerateStringLines(int offset, string popcode,
|
||||
List<string> operands) {
|
||||
FormattedParts[] partsArray = new FormattedParts[operands.Count];
|
||||
|
|
|
@ -25,6 +25,10 @@ namespace SourceGen {
|
|||
/// The class is mutable, but may only be modified by the LvTable editor (which makes
|
||||
/// changes to a work object that moves through the undo/redo buffer) or the
|
||||
/// deserializer.
|
||||
///
|
||||
/// (Referring to these as "local" variables is a bit of a misnomer, since they have
|
||||
/// global scope from the point where they're defined. The name reflects their intended
|
||||
/// usage, rather than how the assembler will treat them.)
|
||||
/// </summary>
|
||||
public class LocalVariableTable {
|
||||
/// <summary>
|
||||
|
@ -38,10 +42,15 @@ namespace SourceGen {
|
|||
/// table is encountered.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Might be useful to allow addresses (DP ops) and constants (StackRel ops) to be
|
||||
/// This does not correspond to any output in generated assembly code. We simply stop
|
||||
/// trying to associate the symbols with instructions. The code will either use a
|
||||
/// less tightly-scoped value (e.g. project symbol) or output as hex. There is no need
|
||||
/// to tell the assembler to forget the symbol.
|
||||
///
|
||||
/// It might be useful to allow addresses (DP ops) and constants (StackRel ops) to be
|
||||
/// cleared independently, but I suspect the typical compiled-language scenario will
|
||||
/// involve StackRel for args and a sliding DP for locals, so generally it makes
|
||||
/// sense to just clear both.
|
||||
/// sense to just clear everything.
|
||||
/// </remarks>
|
||||
public bool ClearPrevious { get; set; }
|
||||
|
||||
|
|
|
@ -1455,6 +1455,11 @@ namespace SourceGen {
|
|||
EditNote();
|
||||
}
|
||||
break;
|
||||
case LineListGen.Line.Type.LocalVariableTable:
|
||||
if (CanEditLocalVariableTable()) {
|
||||
EditLocalVariableTable();
|
||||
}
|
||||
break;
|
||||
|
||||
case LineListGen.Line.Type.Code:
|
||||
case LineListGen.Line.Type.Data:
|
||||
|
@ -3179,6 +3184,14 @@ namespace SourceGen {
|
|||
extraStr = "Source: " + sourceStr;
|
||||
}
|
||||
break;
|
||||
case LineListGen.Line.Type.LocalVariableTable:
|
||||
lineTypeStr = "variable table";
|
||||
if (mProject.LvTables.TryGetValue(line.FileOffset,
|
||||
out LocalVariableTable lvt)) {
|
||||
extraStr = string.Format("{0} entries, clear-previous={1}",
|
||||
lvt.Variables.Count, lvt.ClearPrevious);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lineTypeStr = "???";
|
||||
break;
|
||||
|
|
|
@ -84,6 +84,8 @@ limitations under the License.
|
|||
<system:String x:Key="str_InvalidFormatWordSelCaption">Invalid Selection</system:String>
|
||||
<system:String x:Key="str_InvalidFormatWordSelNon1" xml:space="preserve">Unable to format as word: selection must be an even number of bytes that have not previously been formatted as multi-byte values.

Use Toggle Data Scan (Ctrl+D) to turn off auto-detection of strings and memory fill.</system:String>
|
||||
<system:String x:Key="str_InvalidFormatWordSelUnevenFmt">Unable to format as word: each selected region must have an even number of bytes ({0} region(s) are selected).</system:String>
|
||||
<system:String x:Key="str_LocalVariableTableClear">• Clear variables</system:String>
|
||||
<system:String x:Key="str_LocalVariableTableEmpty">• Empty variable table</system:String>
|
||||
<system:String x:Key="str_NoFilesAvailable">no files available</system:String>
|
||||
<system:String x:Key="str_OpenDataDoesntExist">The file doesn't exist.</system:String>
|
||||
<system:String x:Key="str_OpenDataEmpty">File is empty</system:String>
|
||||
|
|
|
@ -149,6 +149,10 @@ namespace SourceGen.Res {
|
|||
(string)Application.Current.FindResource("str_InvalidFormatWordSelNon1");
|
||||
public static string INVALID_FORMAT_WORD_SEL_UNEVEN_FMT =
|
||||
(string)Application.Current.FindResource("str_InvalidFormatWordSelUnevenFmt");
|
||||
public static string LOCAL_VARIABLE_TABLE_CLEAR =
|
||||
(string)Application.Current.FindResource("str_LocalVariableTableClear");
|
||||
public static string LOCAL_VARIABLE_TABLE_EMPTY =
|
||||
(string)Application.Current.FindResource("str_LocalVariableTableEmpty");
|
||||
public static string NO_FILES_AVAILABLE =
|
||||
(string)Application.Current.FindResource("str_NoFilesAvailable");
|
||||
public static string OPEN_DATA_DOESNT_EXIST =
|
||||
|
|
|
@ -52,6 +52,7 @@ limitations under the License.
|
|||
<StackPanel Grid.Column="1" Grid.Row="1">
|
||||
<TextBox Margin="0,1,0,0" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBlock Name="valueRangeLabel" Text="• Value between 0-255" Margin="0,4,0,0"/>
|
||||
<TextBlock Name="valueNotesLabel" Text="• Decimal, hex ($), or binary (%)" Margin="0,4,0,16"/>
|
||||
</StackPanel>
|
||||
|
||||
|
@ -59,7 +60,7 @@ limitations under the License.
|
|||
<StackPanel Name="widthEntry2" Grid.Column="1" Grid.Row="2">
|
||||
<TextBox Margin="0,1,0,0" Text="{Binding VarWidth, UpdateSourceTrigger=PropertyChanged}"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBlock Name="widthNotesLabel" Text="• Decimal, 1-4" Margin="0,4,0,16"/>
|
||||
<TextBlock Name="widthNotesLabel" Text="• Decimal value, 1-4" Margin="0,4,0,16"/>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="3" Text="Comment:" Margin="0,0,8,0"/>
|
||||
|
|
|
@ -127,6 +127,7 @@ namespace SourceGen.WpfGui {
|
|||
widthEntry1.Visibility = widthEntry2.Visibility = labelUniqueLabel.Visibility =
|
||||
Visibility.Collapsed;
|
||||
labelUniqueLabel.Visibility = Visibility.Collapsed;
|
||||
valueRangeLabel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,10 +179,14 @@ namespace SourceGen.WpfGui {
|
|||
// Value must be blank, meaning "erase any earlier definition", or valid value.
|
||||
// (Hmm... don't currently have a way to specify "no symbol" in DefSymbol.)
|
||||
//if (!string.IsNullOrEmpty(valueTextBox.Text)) {
|
||||
bool valueValid = ParseValue(out int unused1, out int unused2);
|
||||
bool valueValid = ParseValue(out int value, out int unused2);
|
||||
//} else {
|
||||
// valueValid = true;
|
||||
//}
|
||||
bool valueRangeValid = true;
|
||||
if (mIsVariable && valueValid && (value < 0 || value > 255)) {
|
||||
valueRangeValid = false;
|
||||
}
|
||||
|
||||
bool widthValid = true;
|
||||
if (widthEntry1.Visibility == Visibility.Visible) {
|
||||
|
@ -191,14 +196,14 @@ namespace SourceGen.WpfGui {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(maybe): do this the XAML way, with properties and Styles
|
||||
labelNotesLabel.Foreground = labelValid ? mDefaultLabelColor : Brushes.Red;
|
||||
labelUniqueLabel.Foreground = projectLabelUniqueLabel.Foreground =
|
||||
labelUnique ? mDefaultLabelColor : Brushes.Red;
|
||||
valueNotesLabel.Foreground = valueValid ? mDefaultLabelColor : Brushes.Red;
|
||||
valueRangeLabel.Foreground = valueRangeValid ? mDefaultLabelColor : Brushes.Red;
|
||||
widthNotesLabel.Foreground = widthValid ? mDefaultLabelColor : Brushes.Red;
|
||||
|
||||
IsValid = labelValid && labelUnique && valueValid && widthValid;
|
||||
IsValid = labelValid && labelUnique && valueValid && valueRangeValid && widthValid;
|
||||
}
|
||||
|
||||
private bool ParseValue(out int value, out int numBase) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user