mirror of
https://github.com/fadden/6502bench.git
synced 2025-04-07 00:37:06 +00:00
Finish split-address table formatter
A lot of things react to other things in this dialog. I think I got everything behaving correctly.
This commit is contained in:
parent
c6b63afb3e
commit
e49ee6f20b
@ -343,12 +343,17 @@ jmptabh .dd1 >func1
|
||||
<p>Sometimes the tables contain <code>address - 1</code>, because the
|
||||
values are to be pushed onto the stack for an RTS call.</p>
|
||||
|
||||
<p>The split-address table formatter helps you associate symbols with the
|
||||
<p>While the .dd2 case is easy to format with the data operand editor,
|
||||
formatting addresses whose components are split into multiple tables can
|
||||
be tedious.</p>
|
||||
|
||||
<p>The Split-Address Table Formatter helps you associate symbols with the
|
||||
addresses in the table. To use it, start by selecting the entire table.
|
||||
In the example above, you would select all 6 bytes. The number of bytes
|
||||
in each part must be equal: here, it's 3 low bytes, followed by 3 high
|
||||
bytes. If the number of bytes selected can't be evenly divided by the
|
||||
number of parts, the formatter will report an error.</p>
|
||||
number of parts -- two parts for 16-bit data, three parts for 24-bit data --
|
||||
the formatter will report an error.</p>
|
||||
<p>With the data selected, open the format dialog with
|
||||
Actions > Format Split-Address Table. The rather complicated dialog
|
||||
is split into sections.</p>
|
||||
@ -358,17 +363,17 @@ is split into sections.</p>
|
||||
don't have the CPU set to 65816.) If the address parts are being pushed
|
||||
on the stack for an RTS/RTL, check the "Adjusted for RTS/RTL" box to
|
||||
adjust them by 1.</li>
|
||||
<li>Low Bytes: indicate which part of the table holds the low bytes. In
|
||||
<li>Low Byte Source: indicate which part of the table holds the low bytes. In
|
||||
the example above, the low bytes came first, followed by the high bytes,
|
||||
so you would select "first part of selection". If they were stored the
|
||||
other way around, you would click "second part" instead.</li>
|
||||
<li>High Bytes: indicate which part of the table holds the high bytes. For
|
||||
<li>High Byte Source: indicate which part of the table holds the high bytes. For
|
||||
a 16-bit address this will be the part you didn't pick for the low bytes.
|
||||
Sometimes, if all addresses land on the same 256-byte page, the high byte
|
||||
will be a constant in the code, and only the low bytes will be stored in
|
||||
a table. If that's the case, select "Constant", and enter the high byte
|
||||
in the text box. (Decimal, hex, and binary are accepted.)</li>
|
||||
<li>Bank Bytes: for 24-bit addresses, you can select "Nth part of
|
||||
<li>Bank Byte Source: for 24-bit addresses, you can select "Nth part of
|
||||
selection", which will just use whichever part you didn't specify for
|
||||
the low and high bytes. If the table holds 16-bit addresses, you can
|
||||
use the "Constant" field to specify the data bank.</li>
|
||||
@ -394,7 +399,7 @@ It also tells you how many groups there are, but unlike the data operand
|
||||
formatter, the split-address table formatter doesn't care about group
|
||||
boundaries. For this reason, tables do not have to be contiguous in
|
||||
memory. The low bytes and high bytes could be on separate 256-byte
|
||||
pages.</p>
|
||||
pages. You just need to have all of the data selected.</p>
|
||||
|
||||
<p>It should be mentioned that SourceGen does not record the fact that the
|
||||
data in question is part of a table. The formatting, labels, and code hints
|
||||
|
@ -1853,9 +1853,9 @@ namespace SourceGenWPF {
|
||||
|
||||
public bool CanFormatSplitAddress() {
|
||||
EntityCounts counts = SelectionAnalysis.mEntityCounts;
|
||||
// Must be at least one byte of data, and no code.
|
||||
// Must be at least one line of data, and no code. Note this is lines, not bytes,
|
||||
// so we can't screen out single-byte lines without additional work.
|
||||
return (counts.mDataLines > 0 && counts.mCodeLines == 0);
|
||||
|
||||
}
|
||||
|
||||
public void FormatSplitAddress() {
|
||||
|
@ -74,6 +74,7 @@ limitations under the License.
|
||||
<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>
|
||||
<system:String x:Key="str_InvalidAddress">(unknown address)</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>
|
||||
|
@ -129,6 +129,8 @@ namespace SourceGenWPF.Res {
|
||||
(string)Application.Current.FindResource("str_InitialParameters");
|
||||
public static string INITIAL_SYMBOL_FILES =
|
||||
(string)Application.Current.FindResource("str_InitialSymbolFiles");
|
||||
public static string INVALID_ADDRESS =
|
||||
(string)Application.Current.FindResource("str_InvalidAddress");
|
||||
public static string NO_FILES_AVAILABLE =
|
||||
(string)Application.Current.FindResource("str_NoFilesAvailable");
|
||||
public static string OPEN_DATA_DOESNT_EXIST =
|
||||
|
@ -28,9 +28,11 @@ limitations under the License.
|
||||
Loaded="Window_Loaded">
|
||||
|
||||
<Window.Resources>
|
||||
<system:String x:Key="str_SingleByte">One byte is selected</system:String>
|
||||
<system:String x:Key="str_SingleGroup">There are {0} bytes selected</system:String>
|
||||
<system:String x:Key="str_MultiGroup">There are {0} bytes selected, across {1} groups</system:String>
|
||||
<system:String x:Key="str_SingleByte">Only one byte is selected!</system:String>
|
||||
<system:String x:Key="str_SingleGroup">There are {0} bytes selected.</system:String>
|
||||
<system:String x:Key="str_MultiGroup">There are {0} bytes selected, across {1} groups.</system:String>
|
||||
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid Margin="8">
|
||||
@ -43,97 +45,123 @@ limitations under the License.
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
|
||||
<TextBlock Name="selectionInfoLabel" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
|
||||
Text="{StaticResource str_MultiGroup}"/>
|
||||
|
||||
<StackPanel Grid.Column="0" Grid.Row="1" Margin="0,8,8,0">
|
||||
<GroupBox Header="Address Characteristics">
|
||||
<StackPanel>
|
||||
<RadioButton Name="width16Radio" GroupName="Addr" Margin="0,4,0,0"
|
||||
Content="16-bit"/>
|
||||
Content="16-bit" Checked="WidthRadio_CheckedChanged"/>
|
||||
<RadioButton Name="width24Radio" GroupName="Addr" Margin="0,4,0,0"
|
||||
Content="24-bit"/>
|
||||
<CheckBox Margin="0,4,0,0" Content="Adjusted for RTS/RTL (target - 1)"/>
|
||||
Content="24-bit" Checked="WidthRadio_CheckedChanged"/>
|
||||
<CheckBox Margin="0,4,0,0" Content="Adjusted for RTS/RTL (target - 1)"
|
||||
IsChecked="{Binding AdjustedForReturn}"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Low Bytes">
|
||||
<GroupBox Header="Low Byte Source">
|
||||
<StackPanel>
|
||||
<RadioButton Name="lowFirstPartRadio" GroupName="Low" Margin="0,4,0,0"
|
||||
Content="First part of selection"/>
|
||||
Content="First part of selection"
|
||||
Checked="LowByte_CheckedChanged"/>
|
||||
<RadioButton Name="lowSecondPartRadio" GroupName="Low" Margin="0,4,0,0"
|
||||
Content="Second part of selection"/>
|
||||
Content="Second part of selection"
|
||||
Checked="LowByte_CheckedChanged"/>
|
||||
<RadioButton Name="lowThirdPartRadio" GroupName="Low" Margin="0,4,0,0"
|
||||
Content="Third part of selection"/>
|
||||
Content="Third part of selection"
|
||||
IsEnabled="{Binding ElementName=width24Radio, Path=IsChecked}"
|
||||
Checked="LowByte_CheckedChanged"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="High Bytes">
|
||||
<GroupBox Header="High Byte Source">
|
||||
<StackPanel>
|
||||
<RadioButton Name="highFirstPartRadio" GroupName="High" Margin="0,4,0,0"
|
||||
Content="First part of selection"/>
|
||||
Content="First part of selection"
|
||||
Checked="HighByte_CheckedChanged"/>
|
||||
<RadioButton Name="highSecondPartRadio" GroupName="High" Margin="0,4,0,0"
|
||||
Content="Second part of selection"/>
|
||||
Content="Second part of selection"
|
||||
Checked="HighByte_CheckedChanged"/>
|
||||
<RadioButton Name="highThirdPartRadio" GroupName="High" Margin="0,4,0,0"
|
||||
Content="Third part of selection"/>
|
||||
Content="Third part of selection"
|
||||
IsEnabled="{Binding ElementName=width24Radio, Path=IsChecked}"
|
||||
Checked="HighByte_CheckedChanged"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<RadioButton Name="highConstantRadio" GroupName="High" Margin="0,4,0,0"
|
||||
Content="Constant:"/>
|
||||
<TextBox Name="highConstantTextBox" Width="100" Margin="8,1,0,0"/>
|
||||
Content="Constant:" Checked="HighByte_CheckedChanged"/>
|
||||
<TextBox Name="highConstantTextBox" Width="100" Margin="8,2,0,0"
|
||||
TextChanged="HighConstantTextBox_TextChanged"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Bank Bytes">
|
||||
<StackPanel>
|
||||
<GroupBox Header="Bank Byte Source">
|
||||
<StackPanel IsEnabled="{Binding ElementName=width24Radio, Path=IsChecked}">
|
||||
<RadioButton Name="bankNthPartRadio" GroupName="Bank" Margin="0,4,0,0"
|
||||
Content="Nth part of selection"/>
|
||||
Content="Nth part of selection"
|
||||
Checked="BankByte_CheckedChanged"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<RadioButton Name="bankConstantRadio" GroupName="Bank" Margin="0,4,0,0"
|
||||
Content="Constant:"/>
|
||||
<TextBox Name="bankConstantTextBox" Width="100" Margin="8,1,0,0"/>
|
||||
Content="Constant:"
|
||||
Checked="BankByte_CheckedChanged"/>
|
||||
<TextBox Name="bankConstantTextBox" Width="100" Margin="8,2,0,0"
|
||||
TextChanged="BankConstantTextBox_TextChanged"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Options">
|
||||
<StackPanel>
|
||||
<CheckBox Content="Add code entry hint if needed" Margin="0,4,0,0"/>
|
||||
<CheckBox Content="Add code entry hint if needed" Margin="0,4,0,0"
|
||||
IsChecked="{Binding WantCodeHints}"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
|
||||
<DockPanel Grid.Column="1" Grid.Row="1" Margin="0,8,0,0">
|
||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,8,0,0">
|
||||
<Button Name="okButton" Content="OK" IsDefault="True" Width="70"
|
||||
IsEnabled="{Binding IsValid}" Click="OkButton_Click"/>
|
||||
<Button Name="cancelButton" Content="Cancel" IsCancel="True"
|
||||
Width="70" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
<Grid Grid.Column="1" Grid.Row="1" Margin="0,8,0,0">
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,8,0,0">
|
||||
<Button Name="okButton" Content="OK" IsDefault="True" Width="70"
|
||||
IsEnabled="{Binding IsValid}" Click="OkButton_Click"/>
|
||||
<Button Name="cancelButton" Content="Cancel" IsCancel="True"
|
||||
Width="70" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<GroupBox DockPanel.Dock="Top" Header="Generated Addresses">
|
||||
<!-- We're currently auto-sizing everything outside this, so the width of
|
||||
the columns determines the width of the window. Resizing the columns resizes
|
||||
the window, even though the window isn't resizeable. "It's a feature." -->
|
||||
<DataGrid Name="outputPreviewList"
|
||||
Margin="0,2,0,0"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{Binding OutputPreviewList}"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"
|
||||
SnapsToDevicePixels="True"
|
||||
GridLinesVisibility="Vertical"
|
||||
VerticalGridLinesBrush="#FF7F7F7F"
|
||||
AutoGenerateColumns="False"
|
||||
HeadersVisibility="Column"
|
||||
CanUserReorderColumns="False"
|
||||
SelectionMode="Single">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Addr" Width="60" Binding="{Binding Addr}"/>
|
||||
<DataGridTextColumn Header="Offset" Width="60" Binding="{Binding Offset}"/>
|
||||
<DataGridTextColumn Header="Symbol" Width="180" Binding="{Binding Type}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
<GroupBox DockPanel.Dock="Top" Header="Generated Addresses">
|
||||
<!-- We're currently auto-sizing everything outside this, so the width of
|
||||
the columns determines the width of the window. Resizing the columns resizes
|
||||
the window, even though the window isn't resizeable. "It's a feature." -->
|
||||
<DataGrid Name="outputPreviewList"
|
||||
Margin="0,2,0,0"
|
||||
Height="318"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{Binding OutputPreviewList}"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"
|
||||
SnapsToDevicePixels="True"
|
||||
GridLinesVisibility="Vertical"
|
||||
VerticalGridLinesBrush="#FF7F7F7F"
|
||||
AutoGenerateColumns="False"
|
||||
HeadersVisibility="Column"
|
||||
CanUserReorderColumns="False"
|
||||
SelectionMode="Single">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Addr" Width="60" Binding="{Binding Addr}"/>
|
||||
<DataGridTextColumn Header="Offset" Width="60" Binding="{Binding Offset}"/>
|
||||
<DataGridTextColumn Header="Symbol" Width="180" Binding="{Binding Symbol}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
|
||||
<TextBlock Name="incompatibleSelectionLabel"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,-20,0,0"
|
||||
Text="Options incompatible with selection" FontSize="16" Foreground="Red"
|
||||
Visibility="{Binding IncompatibleSelectionVisibility, Converter={StaticResource BoolToVis}}"/>
|
||||
<TextBlock Name="invalidConstantLabel"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,20,0,0"
|
||||
Text="Invalid constant" FontSize="16" Foreground="Red"
|
||||
Visibility="{Binding InvalidConstantVisibility, Converter={StaticResource BoolToVis}}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -43,19 +44,59 @@ namespace SourceGenWPF.WpfGui {
|
||||
/// </summary>
|
||||
public List<int> AllTargetOffsets { get; private set; }
|
||||
|
||||
public bool WantCodeHints = true; // TODO
|
||||
#if false
|
||||
{
|
||||
get {
|
||||
return addCodeHintCheckBox.Checked;
|
||||
/// <summary>
|
||||
/// If set, targets are offset by one for RTS/RTL.
|
||||
/// </summary>
|
||||
public bool AdjustedForReturn {
|
||||
get { return mAdjustedForReturn; }
|
||||
set {
|
||||
mAdjustedForReturn = value;
|
||||
OnPropertyChanged();
|
||||
UpdateControls();
|
||||
}
|
||||
}
|
||||
private bool mAdjustedForReturn;
|
||||
|
||||
/// <summary>
|
||||
/// If set, caller will add code entry hints to targets.
|
||||
/// </summary>
|
||||
public bool WantCodeHints {
|
||||
get { return mWantCodeHints; }
|
||||
set {
|
||||
mWantCodeHints = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
private bool mWantCodeHints;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to make the "incompatible with selection" message visible.
|
||||
/// </summary>
|
||||
public bool IncompatibleSelectionVisibility {
|
||||
get { return mIncompatibleSelectionVisibility; }
|
||||
set {
|
||||
mIncompatibleSelectionVisibility = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
private bool mIncompatibleSelectionVisibility;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to make the "invalid constant" message visible.
|
||||
/// </summary>
|
||||
public bool InvalidConstantVisibility {
|
||||
get { return mInvalidConstantVisibility; }
|
||||
set {
|
||||
mInvalidConstantVisibility = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
private bool mInvalidConstantVisibility;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true when valid output is available.
|
||||
/// </summary>
|
||||
private bool mOutputReady;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Set to true when input is valid. Controls whether the OK button is enabled.
|
||||
@ -69,6 +110,19 @@ namespace SourceGenWPF.WpfGui {
|
||||
}
|
||||
private bool mIsValid;
|
||||
|
||||
public class OutputPreviewItem {
|
||||
public string Addr { get; private set; }
|
||||
public string Offset { get; private set; }
|
||||
public string Symbol { get; private set; }
|
||||
|
||||
public OutputPreviewItem(string addr, string offset, string symbol) {
|
||||
Addr = addr;
|
||||
Offset = offset;
|
||||
Symbol = symbol;
|
||||
}
|
||||
}
|
||||
public ObservableCollection<OutputPreviewItem> OutputPreviewList { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Selected offsets. An otherwise contiguous range of offsets can be broken up
|
||||
/// by user-specified labels and address discontinuities, so this needs to be
|
||||
@ -86,6 +140,11 @@ namespace SourceGenWPF.WpfGui {
|
||||
/// </summary>
|
||||
private Formatter mFormatter;
|
||||
|
||||
/// <summary>
|
||||
/// Reentrancy block for UpdateControls().
|
||||
/// </summary>
|
||||
private bool mUpdating;
|
||||
|
||||
// INotifyPropertyChanged implementation
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||
@ -103,145 +162,147 @@ namespace SourceGenWPF.WpfGui {
|
||||
mFormatter = formatter;
|
||||
mSelection = selection;
|
||||
IsValid = false;
|
||||
|
||||
OutputPreviewList = new ObservableCollection<OutputPreviewItem>();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
// TDOO
|
||||
mUpdating = true;
|
||||
|
||||
string fmt, infoStr;
|
||||
if (mSelection.RangeCount == 1 && mSelection.Count == 1) {
|
||||
infoStr = (string)FindResource("str_SingleByte");
|
||||
} else if (mSelection.RangeCount == 1) {
|
||||
fmt = (string)FindResource("str_SingleGroup");
|
||||
infoStr = string.Format(fmt, mSelection.Count);
|
||||
} else {
|
||||
fmt = (string)FindResource("str_MultiGroup");
|
||||
infoStr = string.Format(fmt, mSelection.Count, mSelection.RangeCount);
|
||||
}
|
||||
selectionInfoLabel.Text = infoStr;
|
||||
|
||||
width16Radio.IsChecked = true;
|
||||
lowFirstPartRadio.IsChecked = true;
|
||||
highSecondPartRadio.IsChecked = true;
|
||||
bankNthPartRadio.IsChecked = true;
|
||||
|
||||
IncompatibleSelectionVisibility = InvalidConstantVisibility = false;
|
||||
|
||||
if (mProject.CpuDef.HasAddr16) {
|
||||
// Disable the 24-bit option. Having 16-bit selected will disable the rest.
|
||||
width24Radio.IsEnabled = false;
|
||||
}
|
||||
|
||||
mUpdating = false;
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||
DialogResult = true;
|
||||
}
|
||||
|
||||
#if false
|
||||
private void FormatSplitAddress_Load(object sender, EventArgs e) {
|
||||
mInitializing = true;
|
||||
|
||||
string fmt = selectionInfoLabel.Text;
|
||||
selectionInfoLabel.Text = string.Format(fmt, mSelection.Count, mSelection.RangeCount);
|
||||
|
||||
width16Radio.Checked = true;
|
||||
lowFirstPartRadio.Checked = true;
|
||||
highSecondPartRadio.Checked = true;
|
||||
bankNthPartRadio.Checked = true;
|
||||
|
||||
incompatibleSelectionLabel.Visible = invalidConstantLabel.Visible = false;
|
||||
|
||||
if (mProject.CpuDef.HasAddr16) {
|
||||
// Disable the 24-bit option. Having 16-bit selected will disable the rest.
|
||||
width24Radio.Enabled = false;
|
||||
}
|
||||
|
||||
outputPreviewListView.SetDoubleBuffered(true);
|
||||
|
||||
mInitializing = false;
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void UpdateControls() {
|
||||
if (mInitializing) {
|
||||
if (mUpdating) {
|
||||
return;
|
||||
}
|
||||
mInitializing = true; // no re-entry
|
||||
mUpdating = true; // no re-entry
|
||||
|
||||
lowThirdPartRadio.Enabled = width24Radio.Checked;
|
||||
highThirdPartRadio.Enabled = width24Radio.Checked;
|
||||
bankByteGroupBox.Enabled = width24Radio.Checked;
|
||||
// handled with XAML bindings
|
||||
//lowThirdPartRadio.Enabled = width24Radio.Checked;
|
||||
//highThirdPartRadio.Enabled = width24Radio.Checked;
|
||||
//bankByteGroupBox.Enabled = width24Radio.Checked;
|
||||
|
||||
lowSecondPartRadio.Enabled = true;
|
||||
lowSecondPartRadio.IsEnabled = true;
|
||||
|
||||
// If the user selects "constant" for high byte or bank byte, then there is no
|
||||
// 3rd part available for low/high, so we need to turn those back off.
|
||||
if (width24Radio.Checked) {
|
||||
bool haveThree = !(highConstantRadio.Checked || bankConstantRadio.Checked);
|
||||
lowThirdPartRadio.Enabled = haveThree;
|
||||
highThirdPartRadio.Enabled = haveThree;
|
||||
if (width24Radio.IsChecked == true) {
|
||||
bool haveThree = !(highConstantRadio.IsChecked == true ||
|
||||
bankConstantRadio.IsChecked == true);
|
||||
lowThirdPartRadio.IsEnabled = haveThree;
|
||||
highThirdPartRadio.IsEnabled = haveThree;
|
||||
|
||||
// If "constant" is selected for high byte *and* bank byte, then there's no
|
||||
// 2nd part available for low.
|
||||
if (highConstantRadio.Checked && bankConstantRadio.Checked) {
|
||||
lowSecondPartRadio.Enabled = false;
|
||||
if (highConstantRadio.IsChecked == true && bankConstantRadio.IsChecked == true) {
|
||||
lowSecondPartRadio.IsEnabled = false;
|
||||
}
|
||||
} else {
|
||||
// For 16-bit address, if high byte is constant, then there's no second
|
||||
// part for the low byte.
|
||||
if (highConstantRadio.Checked) {
|
||||
lowSecondPartRadio.Enabled = false;
|
||||
if (highConstantRadio.IsChecked == true) {
|
||||
lowSecondPartRadio.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Was a now-invalidated radio button selected before?
|
||||
if (!lowThirdPartRadio.Enabled && lowThirdPartRadio.Checked) {
|
||||
if (!lowThirdPartRadio.IsEnabled && lowThirdPartRadio.IsChecked == true) {
|
||||
// low now invalid, switch to whatever high isn't using
|
||||
if (highFirstPartRadio.Checked) {
|
||||
lowSecondPartRadio.Checked = true;
|
||||
if (highFirstPartRadio.IsChecked == true) {
|
||||
lowSecondPartRadio.IsChecked = true;
|
||||
} else {
|
||||
lowFirstPartRadio.Checked = true;
|
||||
lowFirstPartRadio.IsChecked = true;
|
||||
}
|
||||
}
|
||||
if (!highThirdPartRadio.Enabled && highThirdPartRadio.Checked) {
|
||||
if (width16Radio.IsChecked == true && highThirdPartRadio.IsChecked == true) {
|
||||
// high now invalid, switch to whatever low isn't using
|
||||
if (lowFirstPartRadio.Checked) {
|
||||
highSecondPartRadio.Checked = true;
|
||||
if (lowFirstPartRadio.IsChecked == true) {
|
||||
highSecondPartRadio.IsChecked = true;
|
||||
} else {
|
||||
highFirstPartRadio.Checked = true;
|
||||
highFirstPartRadio.IsChecked = true;
|
||||
}
|
||||
}
|
||||
if (!lowSecondPartRadio.Enabled && lowSecondPartRadio.Checked) {
|
||||
if (!lowSecondPartRadio.IsEnabled && lowSecondPartRadio.IsChecked == true) {
|
||||
// Should only happen when high part is constant.
|
||||
Debug.Assert(highFirstPartRadio.Checked == false);
|
||||
lowFirstPartRadio.Checked = true;
|
||||
Debug.Assert(highFirstPartRadio.IsChecked == false);
|
||||
lowFirstPartRadio.IsChecked = true;
|
||||
}
|
||||
|
||||
mInitializing = false;
|
||||
mUpdating = false;
|
||||
UpdatePreview();
|
||||
|
||||
okButton.Enabled = mOutputReady;
|
||||
IsValid = mOutputReady;
|
||||
}
|
||||
|
||||
private void widthRadio_CheckedChanged(object sender, EventArgs e) {
|
||||
private void WidthRadio_CheckedChanged(object sender, RoutedEventArgs e) {
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void pushRtsCheckBox_CheckedChanged(object sender, EventArgs e) {
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void lowByte_CheckedChanged(object sender, EventArgs e) {
|
||||
private void LowByte_CheckedChanged(object sender, RoutedEventArgs e) {
|
||||
// If we conflict with the high byte, change the high byte.
|
||||
if (lowFirstPartRadio.Checked && highFirstPartRadio.Checked) {
|
||||
highSecondPartRadio.Checked = true;
|
||||
} else if (lowSecondPartRadio.Checked && highSecondPartRadio.Checked) {
|
||||
highFirstPartRadio.Checked = true;
|
||||
} else if (lowThirdPartRadio.Checked && highThirdPartRadio.Checked) {
|
||||
highFirstPartRadio.Checked = true;
|
||||
if (lowFirstPartRadio.IsChecked == true && highFirstPartRadio.IsChecked == true) {
|
||||
highSecondPartRadio.IsChecked = true;
|
||||
} else if (lowSecondPartRadio.IsChecked == true && highSecondPartRadio.IsChecked == true) {
|
||||
highFirstPartRadio.IsChecked = true;
|
||||
} else if (lowThirdPartRadio.IsChecked == true && highThirdPartRadio.IsChecked == true) {
|
||||
highFirstPartRadio.IsChecked = true;
|
||||
}
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void highByte_CheckedChanged(object sender, EventArgs e) {
|
||||
private void HighByte_CheckedChanged(object sender, RoutedEventArgs e) {
|
||||
// If we conflict with the low byte, change the low byte.
|
||||
if (lowFirstPartRadio.Checked && highFirstPartRadio.Checked) {
|
||||
lowSecondPartRadio.Checked = true;
|
||||
} else if (lowSecondPartRadio.Checked && highSecondPartRadio.Checked) {
|
||||
lowFirstPartRadio.Checked = true;
|
||||
} else if (lowThirdPartRadio.Checked && highThirdPartRadio.Checked) {
|
||||
lowFirstPartRadio.Checked = true;
|
||||
if (lowFirstPartRadio.IsChecked == true && highFirstPartRadio.IsChecked == true) {
|
||||
lowSecondPartRadio.IsChecked = true;
|
||||
} else if (lowSecondPartRadio.IsChecked == true && highSecondPartRadio.IsChecked == true) {
|
||||
lowFirstPartRadio.IsChecked = true;
|
||||
} else if (lowThirdPartRadio.IsChecked == true && highThirdPartRadio.IsChecked == true) {
|
||||
lowFirstPartRadio.IsChecked = true;
|
||||
}
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void bankByte_CheckedChanged(object sender, EventArgs e) {
|
||||
private void BankByte_CheckedChanged(object sender, EventArgs e) {
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void highConstantTextBox_TextChanged(object sender, EventArgs e) {
|
||||
highConstantRadio.Checked = true;
|
||||
private void HighConstantTextBox_TextChanged(object sender, TextChangedEventArgs e) {
|
||||
highConstantRadio.IsChecked = true;
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
private void bankConstantTextBox_TextChanged(object sender, EventArgs e) {
|
||||
bankConstantRadio.Checked = true;
|
||||
private void BankConstantTextBox_TextChanged(object sender, TextChangedEventArgs e) {
|
||||
bankConstantRadio.IsChecked = true;
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
@ -250,21 +311,21 @@ namespace SourceGenWPF.WpfGui {
|
||||
|
||||
int minDiv;
|
||||
|
||||
if (width16Radio.Checked) {
|
||||
if (highConstantRadio.Checked) {
|
||||
if (width16Radio.IsChecked == true) {
|
||||
if (highConstantRadio.IsChecked == true) {
|
||||
minDiv = 1;
|
||||
} else {
|
||||
minDiv = 2;
|
||||
}
|
||||
} else {
|
||||
if (highConstantRadio.Checked) {
|
||||
if (bankConstantRadio.Checked) {
|
||||
if (highConstantRadio.IsChecked == true) {
|
||||
if (bankConstantRadio.IsChecked == true) {
|
||||
minDiv = 1;
|
||||
} else {
|
||||
minDiv = 2;
|
||||
}
|
||||
} else {
|
||||
if (bankConstantRadio.Checked) {
|
||||
if (bankConstantRadio.IsChecked == true) {
|
||||
minDiv = 2;
|
||||
} else {
|
||||
minDiv = 3;
|
||||
@ -272,42 +333,37 @@ namespace SourceGenWPF.WpfGui {
|
||||
}
|
||||
}
|
||||
|
||||
incompatibleSelectionLabel.Visible = invalidConstantLabel.Visible = false;
|
||||
IncompatibleSelectionVisibility = InvalidConstantVisibility = false;
|
||||
|
||||
try {
|
||||
// Start by clearing the previous contents of the list. If something goes
|
||||
// wrong, we want to show the error messages on an empty list.
|
||||
outputPreviewListView.BeginUpdate();
|
||||
outputPreviewListView.Items.Clear();
|
||||
// Start by clearing the previous contents of the list. If something goes
|
||||
// wrong, we want to show the error messages on an empty list.
|
||||
OutputPreviewList.Clear();
|
||||
|
||||
if ((mSelection.Count % minDiv) != 0) {
|
||||
incompatibleSelectionLabel.Visible = true;
|
||||
if ((mSelection.Count % minDiv) != 0) {
|
||||
IncompatibleSelectionVisibility = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int highConstant = -1;
|
||||
if (highConstantRadio.IsChecked == true) {
|
||||
if (!Number.TryParseInt(highConstantTextBox.Text, out highConstant,
|
||||
out int unused) || (highConstant != (byte) highConstant)) {
|
||||
InvalidConstantVisibility = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int highConstant = -1;
|
||||
if (highConstantRadio.Checked) {
|
||||
if (!Number.TryParseInt(highConstantTextBox.Text, out highConstant,
|
||||
out int unused) || (highConstant != (byte) highConstant)) {
|
||||
invalidConstantLabel.Visible = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int bankConstant = -1;
|
||||
if (bankConstantRadio.Enabled && bankConstantRadio.Checked) {
|
||||
if (!Number.TryParseInt(bankConstantTextBox.Text, out bankConstant,
|
||||
out int unused) || (bankConstant != (byte) bankConstant)) {
|
||||
invalidConstantLabel.Visible = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Looks valid, generate format list.
|
||||
GenerateFormats(minDiv, highConstant, bankConstant);
|
||||
} finally {
|
||||
outputPreviewListView.EndUpdate();
|
||||
}
|
||||
|
||||
int bankConstant = -1;
|
||||
if (bankConstantRadio.IsEnabled && bankConstantRadio.IsChecked == true) {
|
||||
if (!Number.TryParseInt(bankConstantTextBox.Text, out bankConstant,
|
||||
out int unused) || (bankConstant != (byte) bankConstant)) {
|
||||
InvalidConstantVisibility = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Looks valid, generate format list.
|
||||
GenerateFormats(minDiv, highConstant, bankConstant);
|
||||
}
|
||||
|
||||
private void GenerateFormats(int div, int highConst, int bankConst) {
|
||||
@ -319,27 +375,27 @@ namespace SourceGenWPF.WpfGui {
|
||||
int span = mSelection.Count / div;
|
||||
int lowOff, highOff, bankOff;
|
||||
|
||||
if (lowFirstPartRadio.Checked) {
|
||||
if (lowFirstPartRadio.IsChecked == true) {
|
||||
lowOff = 0;
|
||||
} else if (lowSecondPartRadio.Checked) {
|
||||
} else if (lowSecondPartRadio.IsChecked == true) {
|
||||
lowOff = span;
|
||||
} else if (lowThirdPartRadio.Checked) {
|
||||
} else if (lowThirdPartRadio.IsChecked == true) {
|
||||
lowOff = span * 2;
|
||||
} else {
|
||||
Debug.Assert(false);
|
||||
lowOff = -1;
|
||||
}
|
||||
if (highFirstPartRadio.Checked) {
|
||||
if (highFirstPartRadio.IsChecked == true) {
|
||||
highOff = 0;
|
||||
} else if (highSecondPartRadio.Checked) {
|
||||
} else if (highSecondPartRadio.IsChecked == true) {
|
||||
highOff = span;
|
||||
} else if (highThirdPartRadio.Checked) {
|
||||
} else if (highThirdPartRadio.IsChecked == true) {
|
||||
highOff = span * 2;
|
||||
} else {
|
||||
highOff = -1; // use constant
|
||||
}
|
||||
if (width24Radio.Checked) {
|
||||
if (bankNthPartRadio.Checked) {
|
||||
if (width24Radio.IsChecked == true) {
|
||||
if (bankNthPartRadio.IsChecked == true) {
|
||||
// Use whichever part isn't being used by the other two.
|
||||
if (lowOff != 0 && highOff != 0) {
|
||||
bankOff = 0;
|
||||
@ -369,7 +425,7 @@ namespace SourceGenWPF.WpfGui {
|
||||
}
|
||||
|
||||
int adj = 0;
|
||||
if (pushRtsCheckBox.Checked) {
|
||||
if (AdjustedForReturn) {
|
||||
adj = 1;
|
||||
}
|
||||
|
||||
@ -396,7 +452,7 @@ namespace SourceGenWPF.WpfGui {
|
||||
if (targetOffset < 0) {
|
||||
// Address not within file bounds.
|
||||
// TODO(maybe): look for matching platform/project symbols
|
||||
AddPreviewItem(addr, -1, Properties.Resources.INVALID_ADDRESS);
|
||||
AddPreviewItem(addr, -1, Res.Strings.INVALID_ADDRESS);
|
||||
} else {
|
||||
// Note the same target offset may appear more than once.
|
||||
targetOffsets.Add(targetOffset);
|
||||
@ -447,17 +503,11 @@ namespace SourceGenWPF.WpfGui {
|
||||
}
|
||||
|
||||
private void AddPreviewItem(int addr, int offset, string label) {
|
||||
ListViewItem lvi = new ListViewItem(mFormatter.FormatAddress(addr,
|
||||
!mProject.CpuDef.HasAddr16));
|
||||
if (offset >= 0) {
|
||||
lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi,
|
||||
mFormatter.FormatOffset24(offset)));
|
||||
} else {
|
||||
lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, "---"));
|
||||
}
|
||||
lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, label));
|
||||
outputPreviewListView.Items.Add(lvi);
|
||||
OutputPreviewItem newItem = new OutputPreviewItem(
|
||||
mFormatter.FormatAddress(addr, !mProject.CpuDef.HasAddr16),
|
||||
(offset >= 0 ? mFormatter.FormatOffset24(offset) : "---"),
|
||||
label);
|
||||
OutputPreviewList.Add(newItem);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user