diff --git a/SourceGen/AppForms/FormatSplitAddress.Designer.cs b/SourceGen/AppForms/FormatSplitAddress.Designer.cs
index 277878d..07ea09f 100644
--- a/SourceGen/AppForms/FormatSplitAddress.Designer.cs
+++ b/SourceGen/AppForms/FormatSplitAddress.Designer.cs
@@ -23,15 +23,16 @@
/// the contents of this method with the code editor.
///
private void InitializeComponent() {
- System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem(new string[] {
- "123456",
+ System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem(new string[] {
+ "12/3456",
+ "+123456",
"(+) T_123456"}, -1);
this.cancelButton = new System.Windows.Forms.Button();
this.okButton = new System.Windows.Forms.Button();
this.selectionInfoLabel = new System.Windows.Forms.Label();
this.addressCharacteristicsGroup = new System.Windows.Forms.GroupBox();
- this.returnAddrCheckBox = new System.Windows.Forms.CheckBox();
- this.width24Button = new System.Windows.Forms.RadioButton();
+ this.pushRtsCheckBox = new System.Windows.Forms.CheckBox();
+ this.width24Radio = new System.Windows.Forms.RadioButton();
this.width16Radio = new System.Windows.Forms.RadioButton();
this.lowByteGroupBox = new System.Windows.Forms.GroupBox();
this.lowThirdPartRadio = new System.Windows.Forms.RadioButton();
@@ -51,8 +52,11 @@
this.addrColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.symbolColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.outputPreviewGroupBox = new System.Windows.Forms.GroupBox();
+ this.invalidConstantLabel = new System.Windows.Forms.Label();
+ this.incompatibleSelectionLabel = new System.Windows.Forms.Label();
this.addCodeHintCheckBox = new System.Windows.Forms.CheckBox();
this.optionsGroupBox = new System.Windows.Forms.GroupBox();
+ this.offsetColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.addressCharacteristicsGroup.SuspendLayout();
this.lowByteGroupBox.SuspendLayout();
this.highByteGroupBox.SuspendLayout();
@@ -65,10 +69,10 @@
//
this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.cancelButton.Location = new System.Drawing.Point(479, 465);
+ this.cancelButton.Location = new System.Drawing.Point(461, 461);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
- this.cancelButton.TabIndex = 0;
+ this.cancelButton.TabIndex = 8;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
//
@@ -76,10 +80,10 @@
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
- this.okButton.Location = new System.Drawing.Point(398, 465);
+ this.okButton.Location = new System.Drawing.Point(380, 461);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
- this.okButton.TabIndex = 1;
+ this.okButton.TabIndex = 7;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
@@ -89,42 +93,44 @@
this.selectionInfoLabel.AutoSize = true;
this.selectionInfoLabel.Location = new System.Drawing.Point(13, 13);
this.selectionInfoLabel.Name = "selectionInfoLabel";
- this.selectionInfoLabel.Size = new System.Drawing.Size(207, 13);
- this.selectionInfoLabel.TabIndex = 2;
- this.selectionInfoLabel.Text = "There are {0} bytes selected in {1} groups.";
+ this.selectionInfoLabel.Size = new System.Drawing.Size(213, 13);
+ this.selectionInfoLabel.TabIndex = 0;
+ this.selectionInfoLabel.Text = "There are {0} bytes selected, in {1} group(s)";
//
// addressCharacteristicsGroup
//
- this.addressCharacteristicsGroup.Controls.Add(this.returnAddrCheckBox);
- this.addressCharacteristicsGroup.Controls.Add(this.width24Button);
+ this.addressCharacteristicsGroup.Controls.Add(this.pushRtsCheckBox);
+ this.addressCharacteristicsGroup.Controls.Add(this.width24Radio);
this.addressCharacteristicsGroup.Controls.Add(this.width16Radio);
- this.addressCharacteristicsGroup.Location = new System.Drawing.Point(16, 44);
+ this.addressCharacteristicsGroup.Location = new System.Drawing.Point(16, 40);
this.addressCharacteristicsGroup.Name = "addressCharacteristicsGroup";
- this.addressCharacteristicsGroup.Size = new System.Drawing.Size(222, 90);
- this.addressCharacteristicsGroup.TabIndex = 3;
+ this.addressCharacteristicsGroup.Size = new System.Drawing.Size(204, 90);
+ this.addressCharacteristicsGroup.TabIndex = 1;
this.addressCharacteristicsGroup.TabStop = false;
this.addressCharacteristicsGroup.Text = "Address Characteristics";
//
- // returnAddrCheckBox
+ // pushRtsCheckBox
//
- this.returnAddrCheckBox.AutoSize = true;
- this.returnAddrCheckBox.Location = new System.Drawing.Point(7, 68);
- this.returnAddrCheckBox.Name = "returnAddrCheckBox";
- this.returnAddrCheckBox.Size = new System.Drawing.Size(170, 17);
- this.returnAddrCheckBox.TabIndex = 2;
- this.returnAddrCheckBox.Text = "Return addresses (address - 1)";
- this.returnAddrCheckBox.UseVisualStyleBackColor = true;
+ this.pushRtsCheckBox.AutoSize = true;
+ this.pushRtsCheckBox.Location = new System.Drawing.Point(7, 68);
+ this.pushRtsCheckBox.Name = "pushRtsCheckBox";
+ this.pushRtsCheckBox.Size = new System.Drawing.Size(167, 17);
+ this.pushRtsCheckBox.TabIndex = 2;
+ this.pushRtsCheckBox.Text = "Push for RTS/RTL (target - 1)";
+ this.pushRtsCheckBox.UseVisualStyleBackColor = true;
+ this.pushRtsCheckBox.CheckedChanged += new System.EventHandler(this.pushRtsCheckBox_CheckedChanged);
//
- // width24Button
+ // width24Radio
//
- this.width24Button.AutoSize = true;
- this.width24Button.Location = new System.Drawing.Point(7, 44);
- this.width24Button.Name = "width24Button";
- this.width24Button.Size = new System.Drawing.Size(51, 17);
- this.width24Button.TabIndex = 1;
- this.width24Button.TabStop = true;
- this.width24Button.Text = "24-bit";
- this.width24Button.UseVisualStyleBackColor = true;
+ this.width24Radio.AutoSize = true;
+ this.width24Radio.Location = new System.Drawing.Point(7, 44);
+ this.width24Radio.Name = "width24Radio";
+ this.width24Radio.Size = new System.Drawing.Size(51, 17);
+ this.width24Radio.TabIndex = 1;
+ this.width24Radio.TabStop = true;
+ this.width24Radio.Text = "24-bit";
+ this.width24Radio.UseVisualStyleBackColor = true;
+ this.width24Radio.CheckedChanged += new System.EventHandler(this.widthRadio_CheckedChanged);
//
// width16Radio
//
@@ -136,16 +142,17 @@
this.width16Radio.TabStop = true;
this.width16Radio.Text = "16-bit";
this.width16Radio.UseVisualStyleBackColor = true;
+ this.width16Radio.CheckedChanged += new System.EventHandler(this.widthRadio_CheckedChanged);
//
// lowByteGroupBox
//
this.lowByteGroupBox.Controls.Add(this.lowThirdPartRadio);
this.lowByteGroupBox.Controls.Add(this.lowSecondPartRadio);
this.lowByteGroupBox.Controls.Add(this.lowFirstPartRadio);
- this.lowByteGroupBox.Location = new System.Drawing.Point(13, 140);
+ this.lowByteGroupBox.Location = new System.Drawing.Point(13, 136);
this.lowByteGroupBox.Name = "lowByteGroupBox";
- this.lowByteGroupBox.Size = new System.Drawing.Size(225, 94);
- this.lowByteGroupBox.TabIndex = 4;
+ this.lowByteGroupBox.Size = new System.Drawing.Size(207, 94);
+ this.lowByteGroupBox.TabIndex = 2;
this.lowByteGroupBox.TabStop = false;
this.lowByteGroupBox.Text = "Low Byte";
//
@@ -159,6 +166,7 @@
this.lowThirdPartRadio.TabStop = true;
this.lowThirdPartRadio.Text = "Third part of selection";
this.lowThirdPartRadio.UseVisualStyleBackColor = true;
+ this.lowThirdPartRadio.CheckedChanged += new System.EventHandler(this.lowByte_CheckedChanged);
//
// lowSecondPartRadio
//
@@ -170,6 +178,7 @@
this.lowSecondPartRadio.TabStop = true;
this.lowSecondPartRadio.Text = "Second part of selection";
this.lowSecondPartRadio.UseVisualStyleBackColor = true;
+ this.lowSecondPartRadio.CheckedChanged += new System.EventHandler(this.lowByte_CheckedChanged);
//
// lowFirstPartRadio
//
@@ -181,6 +190,7 @@
this.lowFirstPartRadio.TabStop = true;
this.lowFirstPartRadio.Text = "First part of selection";
this.lowFirstPartRadio.UseVisualStyleBackColor = true;
+ this.lowFirstPartRadio.CheckedChanged += new System.EventHandler(this.lowByte_CheckedChanged);
//
// highByteGroupBox
//
@@ -189,10 +199,10 @@
this.highByteGroupBox.Controls.Add(this.highThirdPartRadio);
this.highByteGroupBox.Controls.Add(this.highSecondPartRadio);
this.highByteGroupBox.Controls.Add(this.highFirstPartRadio);
- this.highByteGroupBox.Location = new System.Drawing.Point(13, 240);
+ this.highByteGroupBox.Location = new System.Drawing.Point(13, 236);
this.highByteGroupBox.Name = "highByteGroupBox";
- this.highByteGroupBox.Size = new System.Drawing.Size(225, 120);
- this.highByteGroupBox.TabIndex = 5;
+ this.highByteGroupBox.Size = new System.Drawing.Size(207, 120);
+ this.highByteGroupBox.TabIndex = 3;
this.highByteGroupBox.TabStop = false;
this.highByteGroupBox.Text = "High Byte";
//
@@ -203,6 +213,7 @@
this.highConstantTextBox.Name = "highConstantTextBox";
this.highConstantTextBox.Size = new System.Drawing.Size(93, 20);
this.highConstantTextBox.TabIndex = 4;
+ this.highConstantTextBox.TextChanged += new System.EventHandler(this.highConstantTextBox_TextChanged);
//
// highConstantRadio
//
@@ -214,6 +225,7 @@
this.highConstantRadio.TabStop = true;
this.highConstantRadio.Text = "Constant:";
this.highConstantRadio.UseVisualStyleBackColor = true;
+ this.highConstantRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged);
//
// highThirdPartRadio
//
@@ -225,6 +237,7 @@
this.highThirdPartRadio.TabStop = true;
this.highThirdPartRadio.Text = "Third part of selection";
this.highThirdPartRadio.UseVisualStyleBackColor = true;
+ this.highThirdPartRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged);
//
// highSecondPartRadio
//
@@ -236,6 +249,7 @@
this.highSecondPartRadio.TabStop = true;
this.highSecondPartRadio.Text = "Second part of selection";
this.highSecondPartRadio.UseVisualStyleBackColor = true;
+ this.highSecondPartRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged);
//
// highFirstPartRadio
//
@@ -247,16 +261,17 @@
this.highFirstPartRadio.TabStop = true;
this.highFirstPartRadio.Text = "First part of selection";
this.highFirstPartRadio.UseVisualStyleBackColor = true;
+ this.highFirstPartRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged);
//
// bankByteGroupBox
//
this.bankByteGroupBox.Controls.Add(this.bankConstantTextBox);
this.bankByteGroupBox.Controls.Add(this.bankNthPartRadio);
this.bankByteGroupBox.Controls.Add(this.bankConstantRadio);
- this.bankByteGroupBox.Location = new System.Drawing.Point(13, 367);
+ this.bankByteGroupBox.Location = new System.Drawing.Point(13, 362);
this.bankByteGroupBox.Name = "bankByteGroupBox";
- this.bankByteGroupBox.Size = new System.Drawing.Size(225, 70);
- this.bankByteGroupBox.TabIndex = 6;
+ this.bankByteGroupBox.Size = new System.Drawing.Size(207, 70);
+ this.bankByteGroupBox.TabIndex = 4;
this.bankByteGroupBox.TabStop = false;
this.bankByteGroupBox.Text = "Bank Byte";
//
@@ -266,7 +281,8 @@
this.bankConstantTextBox.MaxLength = 10;
this.bankConstantTextBox.Name = "bankConstantTextBox";
this.bankConstantTextBox.Size = new System.Drawing.Size(93, 20);
- this.bankConstantTextBox.TabIndex = 5;
+ this.bankConstantTextBox.TabIndex = 2;
+ this.bankConstantTextBox.TextChanged += new System.EventHandler(this.bankConstantTextBox_TextChanged);
//
// bankNthPartRadio
//
@@ -274,10 +290,11 @@
this.bankNthPartRadio.Location = new System.Drawing.Point(10, 19);
this.bankNthPartRadio.Name = "bankNthPartRadio";
this.bankNthPartRadio.Size = new System.Drawing.Size(120, 17);
- this.bankNthPartRadio.TabIndex = 2;
+ this.bankNthPartRadio.TabIndex = 0;
this.bankNthPartRadio.TabStop = true;
this.bankNthPartRadio.Text = "Nth part of selection";
this.bankNthPartRadio.UseVisualStyleBackColor = true;
+ this.bankNthPartRadio.CheckedChanged += new System.EventHandler(this.bankByte_CheckedChanged);
//
// bankConstantRadio
//
@@ -289,6 +306,7 @@
this.bankConstantRadio.TabStop = true;
this.bankConstantRadio.Text = "Constant:";
this.bankConstantRadio.UseVisualStyleBackColor = true;
+ this.bankConstantRadio.CheckedChanged += new System.EventHandler(this.bankByte_CheckedChanged);
//
// outputPreviewListView
//
@@ -296,38 +314,67 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.outputPreviewListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.addrColumnHeader,
+ this.offsetColumnHeader,
this.symbolColumnHeader});
+ this.outputPreviewListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.outputPreviewListView.FullRowSelect = true;
this.outputPreviewListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.outputPreviewListView.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
- listViewItem2});
+ listViewItem5});
this.outputPreviewListView.Location = new System.Drawing.Point(6, 19);
this.outputPreviewListView.MultiSelect = false;
this.outputPreviewListView.Name = "outputPreviewListView";
this.outputPreviewListView.Size = new System.Drawing.Size(290, 369);
- this.outputPreviewListView.TabIndex = 7;
+ this.outputPreviewListView.TabIndex = 0;
this.outputPreviewListView.UseCompatibleStateImageBehavior = false;
this.outputPreviewListView.View = System.Windows.Forms.View.Details;
//
// addrColumnHeader
//
this.addrColumnHeader.Text = "Addr";
+ this.addrColumnHeader.Width = 52;
//
// symbolColumnHeader
//
this.symbolColumnHeader.Text = "Symbol";
- this.symbolColumnHeader.Width = 200;
+ this.symbolColumnHeader.Width = 174;
//
// outputPreviewGroupBox
//
this.outputPreviewGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.outputPreviewGroupBox.Controls.Add(this.invalidConstantLabel);
+ this.outputPreviewGroupBox.Controls.Add(this.incompatibleSelectionLabel);
this.outputPreviewGroupBox.Controls.Add(this.outputPreviewListView);
- this.outputPreviewGroupBox.Location = new System.Drawing.Point(252, 44);
+ this.outputPreviewGroupBox.Location = new System.Drawing.Point(234, 40);
this.outputPreviewGroupBox.Name = "outputPreviewGroupBox";
- this.outputPreviewGroupBox.Size = new System.Drawing.Size(302, 394);
- this.outputPreviewGroupBox.TabIndex = 8;
+ this.outputPreviewGroupBox.Size = new System.Drawing.Size(302, 393);
+ this.outputPreviewGroupBox.TabIndex = 6;
this.outputPreviewGroupBox.TabStop = false;
- this.outputPreviewGroupBox.Text = "Output Preview";
+ this.outputPreviewGroupBox.Text = "Generated Addresses";
+ //
+ // invalidConstantLabel
+ //
+ this.invalidConstantLabel.AutoSize = true;
+ this.invalidConstantLabel.BackColor = System.Drawing.SystemColors.Window;
+ this.invalidConstantLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.invalidConstantLabel.ForeColor = System.Drawing.Color.Red;
+ this.invalidConstantLabel.Location = new System.Drawing.Point(101, 200);
+ this.invalidConstantLabel.Name = "invalidConstantLabel";
+ this.invalidConstantLabel.Size = new System.Drawing.Size(100, 16);
+ this.invalidConstantLabel.TabIndex = 2;
+ this.invalidConstantLabel.Text = "Invalid constant";
+ //
+ // incompatibleSelectionLabel
+ //
+ this.incompatibleSelectionLabel.AutoSize = true;
+ this.incompatibleSelectionLabel.BackColor = System.Drawing.SystemColors.Window;
+ this.incompatibleSelectionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.incompatibleSelectionLabel.ForeColor = System.Drawing.Color.Red;
+ this.incompatibleSelectionLabel.Location = new System.Drawing.Point(43, 177);
+ this.incompatibleSelectionLabel.Name = "incompatibleSelectionLabel";
+ this.incompatibleSelectionLabel.Size = new System.Drawing.Size(216, 16);
+ this.incompatibleSelectionLabel.TabIndex = 1;
+ this.incompatibleSelectionLabel.Text = "Options incompatible with selection";
//
// addCodeHintCheckBox
//
@@ -336,26 +383,33 @@
this.addCodeHintCheckBox.AutoSize = true;
this.addCodeHintCheckBox.Location = new System.Drawing.Point(10, 19);
this.addCodeHintCheckBox.Name = "addCodeHintCheckBox";
- this.addCodeHintCheckBox.Size = new System.Drawing.Size(123, 17);
- this.addCodeHintCheckBox.TabIndex = 8;
- this.addCodeHintCheckBox.Text = "Add code entry hints";
+ this.addCodeHintCheckBox.Size = new System.Drawing.Size(165, 17);
+ this.addCodeHintCheckBox.TabIndex = 0;
+ this.addCodeHintCheckBox.Text = "Add code entry hint if needed";
this.addCodeHintCheckBox.UseVisualStyleBackColor = true;
//
// optionsGroupBox
//
this.optionsGroupBox.Controls.Add(this.addCodeHintCheckBox);
- this.optionsGroupBox.Location = new System.Drawing.Point(13, 444);
+ this.optionsGroupBox.Location = new System.Drawing.Point(13, 439);
this.optionsGroupBox.Name = "optionsGroupBox";
- this.optionsGroupBox.Size = new System.Drawing.Size(225, 43);
- this.optionsGroupBox.TabIndex = 9;
+ this.optionsGroupBox.Size = new System.Drawing.Size(207, 43);
+ this.optionsGroupBox.TabIndex = 5;
this.optionsGroupBox.TabStop = false;
this.optionsGroupBox.Text = "Options";
//
+ // offsetColumnHeader
+ //
+ this.offsetColumnHeader.Text = "Offset";
+ this.offsetColumnHeader.Width = 55;
+ //
// FormatSplitAddress
//
+ this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(566, 500);
+ this.CancelButton = this.cancelButton;
+ this.ClientSize = new System.Drawing.Size(548, 496);
this.Controls.Add(this.optionsGroupBox);
this.Controls.Add(this.outputPreviewGroupBox);
this.Controls.Add(this.bankByteGroupBox);
@@ -382,6 +436,7 @@
this.bankByteGroupBox.ResumeLayout(false);
this.bankByteGroupBox.PerformLayout();
this.outputPreviewGroupBox.ResumeLayout(false);
+ this.outputPreviewGroupBox.PerformLayout();
this.optionsGroupBox.ResumeLayout(false);
this.optionsGroupBox.PerformLayout();
this.ResumeLayout(false);
@@ -396,8 +451,8 @@
private System.Windows.Forms.Label selectionInfoLabel;
private System.Windows.Forms.GroupBox addressCharacteristicsGroup;
private System.Windows.Forms.RadioButton width16Radio;
- private System.Windows.Forms.RadioButton width24Button;
- private System.Windows.Forms.CheckBox returnAddrCheckBox;
+ private System.Windows.Forms.RadioButton width24Radio;
+ private System.Windows.Forms.CheckBox pushRtsCheckBox;
private System.Windows.Forms.GroupBox lowByteGroupBox;
private System.Windows.Forms.RadioButton lowFirstPartRadio;
private System.Windows.Forms.RadioButton lowSecondPartRadio;
@@ -418,5 +473,8 @@
private System.Windows.Forms.GroupBox outputPreviewGroupBox;
private System.Windows.Forms.CheckBox addCodeHintCheckBox;
private System.Windows.Forms.GroupBox optionsGroupBox;
+ private System.Windows.Forms.Label incompatibleSelectionLabel;
+ private System.Windows.Forms.Label invalidConstantLabel;
+ private System.Windows.Forms.ColumnHeader offsetColumnHeader;
}
}
\ No newline at end of file
diff --git a/SourceGen/AppForms/FormatSplitAddress.cs b/SourceGen/AppForms/FormatSplitAddress.cs
index 75edcd6..7c7f5db 100644
--- a/SourceGen/AppForms/FormatSplitAddress.cs
+++ b/SourceGen/AppForms/FormatSplitAddress.cs
@@ -20,54 +20,409 @@ using System.Windows.Forms;
using Asm65;
using CommonUtil;
+using CommonWinForms;
namespace SourceGen.AppForms {
public partial class FormatSplitAddress : Form {
///
- /// Result set that describes the formatting to perform. Not all regions will have
- /// the same format, e.g. the "mixed ASCII" mode will alternate strings and bytes
- /// (rather than a dedicated "mixed ASCII" format type).
+ /// Format descriptors to apply.
///
- public SortedList Results { get; private set; }
+ public SortedList NewFormatDescriptors { get; private set; }
+
+ ///
+ /// User labels to apply.
+ ///
+ public Dictionary NewUserLabels { get; private set; }
+
+ ///
+ /// All target offsets found. The list may contain redundant entries.
+ ///
+ public List AllTargetOffsets { get; private set; }
///
/// Selected offsets. An otherwise contiguous range of offsets can be broken up
/// by user-specified labels and address discontinuities, so this needs to be
/// processed by range.
///
- public TypedRangeSet Selection { private get; set; }
+ private TypedRangeSet mSelection;
///
- /// Raw file data.
+ /// Project reference.
///
- private byte[] mFileData;
-
- ///
- /// Symbol table to use when resolving symbolic values.
- ///
- private SymbolTable mSymbolTable;
+ private DisasmProject mProject;
///
/// Formatter to use when displaying addresses and hex values.
///
- private Asm65.Formatter mFormatter;
+ private Formatter mFormatter;
+
+ ///
+ /// Set to prevent controls from going nuts while initializing.
+ ///
+ private bool mInitializing;
+
+ ///
+ /// Set to true when valid output is available.
+ ///
+ private bool mOutputReady;
- public FormatSplitAddress(byte[] fileData, SymbolTable symbolTable,
+ public FormatSplitAddress(DisasmProject project, TypedRangeSet selection,
Formatter formatter) {
InitializeComponent();
- mFileData = fileData;
- mSymbolTable = symbolTable;
+ mProject = project;
mFormatter = formatter;
+ mSelection = selection;
+
+ mOutputReady = 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 okButton_Click(object sender, EventArgs e) {
- Results = new SortedList();
+ private void okButton_Click(object sender, EventArgs e) { }
+
+ private void UpdateControls() {
+ if (mInitializing) {
+ return;
+ }
+ mInitializing = true; // no re-entry
+
+ lowThirdPartRadio.Enabled = width24Radio.Checked;
+ highThirdPartRadio.Enabled = width24Radio.Checked;
+ bankByteGroupBox.Enabled = width24Radio.Checked;
+
+ lowSecondPartRadio.Enabled = 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 "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;
+ }
+ } 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;
+ }
+ }
+
+ // Was a now-invalidated radio button selected before?
+ if (!lowThirdPartRadio.Enabled && lowThirdPartRadio.Checked) {
+ // low now invalid, switch to whatever high isn't using
+ if (highFirstPartRadio.Checked) {
+ lowSecondPartRadio.Checked = true;
+ } else {
+ lowFirstPartRadio.Checked = true;
+ }
+ }
+ if (!highThirdPartRadio.Enabled && highThirdPartRadio.Checked) {
+ // high now invalid, switch to whatever low isn't using
+ if (lowFirstPartRadio.Checked) {
+ highSecondPartRadio.Checked = true;
+ } else {
+ highFirstPartRadio.Checked = true;
+ }
+ }
+ if (!lowSecondPartRadio.Enabled && lowSecondPartRadio.Checked) {
+ // Should only happen when high part is constant.
+ Debug.Assert(highFirstPartRadio.Checked == false);
+ lowFirstPartRadio.Checked = true;
+ }
+
+ mInitializing = false;
+ UpdatePreview();
+
+ okButton.Enabled = mOutputReady;
+ }
+
+ private void widthRadio_CheckedChanged(object sender, EventArgs e) {
+ UpdateControls();
+ }
+
+ private void pushRtsCheckBox_CheckedChanged(object sender, EventArgs e) {
+ UpdateControls();
+ }
+
+ private void lowByte_CheckedChanged(object sender, EventArgs 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;
+ }
+ UpdateControls();
+ }
+
+ private void highByte_CheckedChanged(object sender, EventArgs 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;
+ }
+ UpdateControls();
+ }
+
+ private void bankByte_CheckedChanged(object sender, EventArgs e) {
+ UpdateControls();
+ }
+
+ private void highConstantTextBox_TextChanged(object sender, EventArgs e) {
+ highConstantRadio.Checked = true;
+ UpdateControls();
+ }
+
+ private void bankConstantTextBox_TextChanged(object sender, EventArgs e) {
+ bankConstantRadio.Checked = true;
+ UpdateControls();
+ }
+
+ private void UpdatePreview() {
+ mOutputReady = false;
+
+ int minDiv;
+
+ if (width16Radio.Checked) {
+ if (highConstantRadio.Checked) {
+ minDiv = 1;
+ } else {
+ minDiv = 2;
+ }
+ } else {
+ if (highConstantRadio.Checked) {
+ if (bankConstantRadio.Checked) {
+ minDiv = 1;
+ } else {
+ minDiv = 2;
+ }
+ } else {
+ if (bankConstantRadio.Checked) {
+ minDiv = 2;
+ } else {
+ minDiv = 3;
+ }
+ }
+ }
+
+ incompatibleSelectionLabel.Visible = invalidConstantLabel.Visible = 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();
+
+ if ((mSelection.Count % minDiv) != 0) {
+ incompatibleSelectionLabel.Visible = 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();
+ }
+ }
+
+ private void GenerateFormats(int div, int highConst, int bankConst) {
+ SortedList newDfds = new SortedList();
+ Dictionary newLabels = new Dictionary();
+ List targetOffsets = new List();
+
+ // Identify the offset where each set of data starts.
+ int span = mSelection.Count / div;
+ int lowOff, highOff, bankOff;
+
+ if (lowFirstPartRadio.Checked) {
+ lowOff = 0;
+ } else if (lowSecondPartRadio.Checked) {
+ lowOff = span;
+ } else if (lowThirdPartRadio.Checked) {
+ lowOff = span * 2;
+ } else {
+ Debug.Assert(false);
+ lowOff = -1;
+ }
+ if (highFirstPartRadio.Checked) {
+ highOff = 0;
+ } else if (highSecondPartRadio.Checked) {
+ highOff = span;
+ } else if (highThirdPartRadio.Checked) {
+ highOff = span * 2;
+ } else {
+ highOff = -1; // use constant
+ }
+ if (width24Radio.Checked) {
+ if (bankNthPartRadio.Checked) {
+ // Use whichever part isn't being used by the other two.
+ if (lowOff != 0 && highOff != 0) {
+ bankOff = 0;
+ } else if (lowOff != span && highOff != span) {
+ bankOff = span;
+ } else {
+ Debug.Assert(lowOff != span * 2 && highOff != span * 2);
+ bankOff = span * 2;
+ }
+ } else {
+ bankOff = -1; // use constant
+ }
+ } else {
+ bankOff = -1; // use constant
+ bankConst = 0; // always bank 0
+ }
+
+ Debug.WriteLine("Extract from low=" + lowOff + " high=" + highOff +
+ " bank=" + bankOff);
+
+ // The TypedRangeSet doesn't have an index operation, so copy the values into
+ // an array.
+ int[] offsets = new int[mSelection.Count];
+ int index = 0;
+ foreach (TypedRangeSet.Tuple tup in mSelection) {
+ offsets[index++] = tup.Value;
+ }
+
+ int adj = 0;
+ if (pushRtsCheckBox.Checked) {
+ adj = 1;
+ }
+
+ // Walk through the file data, generating addresses as we go.
+ byte[] fileData = mProject.FileData;
+ for (int i = 0; i < span; i++) {
+ byte low, high, bank;
+
+ low = fileData[offsets[lowOff + i]];
+ if (highOff >= 0) {
+ high = fileData[offsets[highOff + i]];
+ } else {
+ high = (byte) highConst;
+ }
+ if (bankOff >= 0) {
+ bank = fileData[offsets[bankOff + i]];
+ } else {
+ bank = (byte) bankConst;
+ }
+
+ int addr = ((bank << 16) | (high << 8) | low) + adj;
+ Debug.WriteLine("GOT " + i + ": " + addr.ToString("x6"));
+
+ int targetOffset = mProject.AddrMap.AddressToOffset(offsets[0], addr);
+ if (targetOffset < 0) {
+ // Address not within file bounds.
+ // TODO(maybe): look for matching platform/project symbols
+ AddPreviewItem(addr, -1, Properties.Resources.INVALID_ADDRESS);
+ } else {
+ // Note the same target offset may appear more than once.
+ targetOffsets.Add(targetOffset);
+
+ // If there's a user-defined label there already, use it. Otherwise, we'll
+ // need to generate one.
+ string targetLabel;
+ if (mProject.UserLabels.TryGetValue(targetOffset, out Symbol sym)) {
+ AddPreviewItem(addr, targetOffset, sym.Label);
+ targetLabel = sym.Label;
+ } else {
+ AddPreviewItem(addr, targetOffset, "(+)");
+ // Generate a symbol that's unique vs. the symbol table. We don't need
+ // it to be unique vs. the labels we're generating here, because we
+ // won't generate identical labels for different addresses, and we do
+ // want to generate a single label if more than one table entry refers
+ // to the same target.
+ Symbol tmpSym = SymbolTable.GenerateUniqueForAddress(addr,
+ mProject.SymbolTable, "T");
+ // tmpSym was returned as an auto-label, make it a user label instead
+ tmpSym = new Symbol(tmpSym.Label, tmpSym.Value, Symbol.Source.User,
+ Symbol.Type.LocalOrGlobalAddr);
+ newLabels[targetOffset] = tmpSym; // overwrites previous
+ targetLabel = tmpSym.Label;
+ }
+
+ // Now we need to create format descriptors for the addresses where we
+ // extracted the low, high, and bank values.
+ newDfds.Add(offsets[lowOff + i], FormatDescriptor.Create(1,
+ new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.Low), false));
+ if (highOff >= 0) {
+ newDfds.Add(offsets[highOff + i], FormatDescriptor.Create(1,
+ new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.High), false));
+ }
+ if (bankOff >= 0) {
+ newDfds.Add(offsets[bankOff + i], FormatDescriptor.Create(1,
+ new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.Bank), false));
+ }
+ }
+ }
+
+ NewFormatDescriptors = newDfds;
+ NewUserLabels = newLabels;
+ AllTargetOffsets = targetOffsets;
+
+ mOutputReady = true;
+ }
+
+ 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);
}
}
}
diff --git a/SourceGen/AppForms/ProjectView.cs b/SourceGen/AppForms/ProjectView.cs
index f1b731d..02f9323 100644
--- a/SourceGen/AppForms/ProjectView.cs
+++ b/SourceGen/AppForms/ProjectView.cs
@@ -2225,7 +2225,7 @@ namespace SourceGen.AppForms {
}
formatSplitAddressTableToolStripMenuItem.Enabled =
- (entityCounts.mDataLines > 1 && entityCounts.mCodeLines == 0);
+ (entityCounts.mDataLines > 0 && entityCounts.mCodeLines == 0);
toggleSingleBytesToolStripMenuItem.Enabled =
(entityCounts.mDataLines > 0 && entityCounts.mCodeLines == 0);
@@ -2618,27 +2618,56 @@ namespace SourceGen.AppForms {
}
private void FormatSplitAddressTable_Click(object sender, EventArgs e) {
- FormatSplitAddress dlg = new FormatSplitAddress(mProject.FileData,
- mProject.SymbolTable, mOutputFormatter);
-
- TypedRangeSet trs = dlg.Selection = GroupedOffsetSetFromSelected();
+ TypedRangeSet trs = GroupedOffsetSetFromSelected();
if (trs.Count == 0) {
// shouldn't happen
Debug.Assert(false, "FormatSplitAddressTable found nothing to edit");
- dlg.Dispose();
return;
}
- // TODO: check to see if the selection is eligible for treatment as a
- // split-address table. If not, show a dialog explaining why.
+ FormatSplitAddress dlg = new FormatSplitAddress(mProject, trs, mOutputFormatter);
dlg.ShowDialog();
if (dlg.DialogResult == DialogResult.OK) {
- ChangeSet cs = mProject.GenerateFormatMergeSet(dlg.Results);
+ // Start with the format descriptors.
+ ChangeSet cs = mProject.GenerateFormatMergeSet(dlg.NewFormatDescriptors);
+
+ // Add in the user labels.
+ foreach (KeyValuePair kvp in dlg.NewUserLabels) {
+ Symbol oldUserValue = null;
+ if (mProject.UserLabels.ContainsKey(kvp.Key)) {
+ Debug.Assert(false, "should not be replacing label");
+ oldUserValue = mProject.UserLabels[kvp.Key];
+ }
+ UndoableChange uc = UndoableChange.CreateLabelChange(kvp.Key,
+ oldUserValue, kvp.Value);
+ cs.Add(uc);
+ }
+
+
+ // Apply code hints.
+ TypedRangeSet newSet = new TypedRangeSet();
+ TypedRangeSet undoSet = new TypedRangeSet();
+
+ foreach (int offset in dlg.AllTargetOffsets) {
+ if (!mProject.GetAnattrib(offset).IsInstruction) {
+ CodeAnalysis.TypeHint oldType = mProject.TypeHints[offset];
+ if (oldType == CodeAnalysis.TypeHint.Code) {
+ continue; // already set
+ }
+ undoSet.Add(offset, (int)oldType);
+ newSet.Add(offset, (int)CodeAnalysis.TypeHint.Code);
+ }
+ }
+ if (newSet.Count != 0) {
+ cs.Add(UndoableChange.CreateTypeHintChange(undoSet, newSet));
+ }
+
+ // Finally, apply the change.
if (cs.Count != 0) {
ApplyUndoableChanges(cs);
} else {
- Debug.WriteLine("No change to data formats");
+ Debug.WriteLine("No changes found");
}
}
diff --git a/SourceGen/DataAnalysis.cs b/SourceGen/DataAnalysis.cs
index 322e8e3..d924803 100644
--- a/SourceGen/DataAnalysis.cs
+++ b/SourceGen/DataAnalysis.cs
@@ -292,7 +292,7 @@ namespace SourceGen {
// up with a user or platform label that matches an auto label, so we
// need to do some renaming in that case. Shouldn't happen often.
Symbol sym = SymbolTable.GenerateUniqueForAddress(mAnattribs[targetOffset].Address,
- mProject.SymbolTable);
+ mProject.SymbolTable, "L");
mAnattribs[targetOffset].Symbol = sym;
// This will throw if the symbol already exists. That is the desired
// behavior, as that would be a bug.
diff --git a/SourceGen/Properties/Resources.Designer.cs b/SourceGen/Properties/Resources.Designer.cs
index 4ecec92..4a19e49 100644
--- a/SourceGen/Properties/Resources.Designer.cs
+++ b/SourceGen/Properties/Resources.Designer.cs
@@ -582,6 +582,15 @@ namespace SourceGen.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to (unknown address).
+ ///
+ internal static string INVALID_ADDRESS {
+ get {
+ return ResourceManager.GetString("INVALID_ADDRESS", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Legal Stuff.
///
diff --git a/SourceGen/Properties/Resources.resx b/SourceGen/Properties/Resources.resx
index f9f9f9c..c24a9a3 100644
--- a/SourceGen/Properties/Resources.resx
+++ b/SourceGen/Properties/Resources.resx
@@ -291,6 +291,9 @@
Symbol files:
+
+ (unknown address)
+
Legal Stuff
diff --git a/SourceGen/SymbolTable.cs b/SourceGen/SymbolTable.cs
index 31b7779..d847ed9 100644
--- a/SourceGen/SymbolTable.cs
+++ b/SourceGen/SymbolTable.cs
@@ -216,10 +216,13 @@ namespace SourceGen {
/// Generates a unique address symbol. Does not add the symbol to the list.
///
/// Address label will be applied to
+ /// Symbol table.
+ /// Prefix to use; must start with a letter.
/// Newly-created, unique symbol.
- public static Symbol GenerateUniqueForAddress(int addr, SymbolTable symbols) {
+ public static Symbol GenerateUniqueForAddress(int addr, SymbolTable symbols,
+ string prefix) {
// $1234 == L1234, $05/1234 == L51234.
- string label = "L" + addr.ToString("X4");
+ string label = prefix + addr.ToString("X4"); // always upper-case
if (symbols.TryGetValue(label, out Symbol unused)) {
const int MAX_RENAME = 999;
string baseLabel = label;