1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-11-29 10:50:28 +00:00

Progress toward new assembler configuration

Rather than have each assembler get its own app config string for
the cross-assembler executable, we now have a collection of per-
assembler config items, of which the executable path name is one
member.  The Asm Config tab has an auto-generated pop-up to select
the assembler.

The per-assembler settings block is serialized with the rather
unpleasant JSON-in-JSON approach, but nobody should have to look
at it.

This also adds assembler-specific column widths to the settings
dialog, though they aren't actually used yet.
This commit is contained in:
Andy McFadden 2018-10-17 17:12:37 -07:00
parent f81c534d25
commit 4f9af30455
10 changed files with 486 additions and 229 deletions

View File

@ -71,20 +71,23 @@ namespace SourceGen.AppForms {
this.showCol5 = new System.Windows.Forms.Button();
this.showCol4 = new System.Windows.Forms.Button();
this.asmConfigTabPage = new System.Windows.Forms.TabPage();
this.configureAsmGroupBox = new System.Windows.Forms.GroupBox();
this.asmColWidthIdLabel = new System.Windows.Forms.Label();
this.asmConfigAssemblerLabel = new System.Windows.Forms.Label();
this.asmCommentColWidthTextBox = new System.Windows.Forms.TextBox();
this.asmOperandColWidthTextBox = new System.Windows.Forms.TextBox();
this.asmOpcodeColWidthTextBox = new System.Windows.Forms.TextBox();
this.asmLabelColWidthTextBox = new System.Windows.Forms.TextBox();
this.asmColWidthLabel = new System.Windows.Forms.Label();
this.asmExeLabel = new System.Windows.Forms.Label();
this.asmConfigComboBox = new System.Windows.Forms.ComboBox();
this.asmExePathTextBox = new System.Windows.Forms.TextBox();
this.asmExeBrowseButton = new System.Windows.Forms.Button();
this.showCycleCountsCheckBox = new System.Windows.Forms.CheckBox();
this.configAsmGenLabel = new System.Windows.Forms.Label();
this.longLabelNewLineCheckBox = new System.Windows.Forms.CheckBox();
this.showAsmIdentCheckBox = new System.Windows.Forms.CheckBox();
this.disableLabelLocalizationCheckBox = new System.Windows.Forms.CheckBox();
this.clearMerlin32Button = new System.Windows.Forms.Button();
this.clearCc65Button = new System.Windows.Forms.Button();
this.browseMerlin32Button = new System.Windows.Forms.Button();
this.browseCc65Button = new System.Windows.Forms.Button();
this.cc65PathTextBox = new System.Windows.Forms.TextBox();
this.merlin32PathTextBox = new System.Windows.Forms.TextBox();
this.asmMerln32Label = new System.Windows.Forms.Label();
this.asmCc65Label = new System.Windows.Forms.Label();
this.asmExplanationLabel = new System.Windows.Forms.Label();
this.displayFormatTabPage = new System.Windows.Forms.TabPage();
this.fmtExplanationLabel = new System.Windows.Forms.Label();
this.quickDisplayFormatGroup = new System.Windows.Forms.GroupBox();
@ -160,6 +163,7 @@ namespace SourceGen.AppForms {
this.codeViewFontGroupBox.SuspendLayout();
this.columnVisGroup.SuspendLayout();
this.asmConfigTabPage.SuspendLayout();
this.configureAsmGroupBox.SuspendLayout();
this.displayFormatTabPage.SuspendLayout();
this.quickDisplayFormatGroup.SuspendLayout();
this.operandWidthGroupBox.SuspendLayout();
@ -519,20 +523,12 @@ namespace SourceGen.AppForms {
//
// asmConfigTabPage
//
this.asmConfigTabPage.Controls.Add(this.configureAsmGroupBox);
this.asmConfigTabPage.Controls.Add(this.showCycleCountsCheckBox);
this.asmConfigTabPage.Controls.Add(this.configAsmGenLabel);
this.asmConfigTabPage.Controls.Add(this.longLabelNewLineCheckBox);
this.asmConfigTabPage.Controls.Add(this.showAsmIdentCheckBox);
this.asmConfigTabPage.Controls.Add(this.disableLabelLocalizationCheckBox);
this.asmConfigTabPage.Controls.Add(this.clearMerlin32Button);
this.asmConfigTabPage.Controls.Add(this.clearCc65Button);
this.asmConfigTabPage.Controls.Add(this.browseMerlin32Button);
this.asmConfigTabPage.Controls.Add(this.browseCc65Button);
this.asmConfigTabPage.Controls.Add(this.cc65PathTextBox);
this.asmConfigTabPage.Controls.Add(this.merlin32PathTextBox);
this.asmConfigTabPage.Controls.Add(this.asmMerln32Label);
this.asmConfigTabPage.Controls.Add(this.asmCc65Label);
this.asmConfigTabPage.Controls.Add(this.asmExplanationLabel);
this.asmConfigTabPage.Location = new System.Drawing.Point(4, 22);
this.asmConfigTabPage.Name = "asmConfigTabPage";
this.asmConfigTabPage.Padding = new System.Windows.Forms.Padding(3);
@ -541,13 +537,138 @@ namespace SourceGen.AppForms {
this.asmConfigTabPage.Text = "Asm Config";
this.asmConfigTabPage.UseVisualStyleBackColor = true;
//
// configureAsmGroupBox
//
this.configureAsmGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.configureAsmGroupBox.Controls.Add(this.asmColWidthIdLabel);
this.configureAsmGroupBox.Controls.Add(this.asmConfigAssemblerLabel);
this.configureAsmGroupBox.Controls.Add(this.asmCommentColWidthTextBox);
this.configureAsmGroupBox.Controls.Add(this.asmOperandColWidthTextBox);
this.configureAsmGroupBox.Controls.Add(this.asmOpcodeColWidthTextBox);
this.configureAsmGroupBox.Controls.Add(this.asmLabelColWidthTextBox);
this.configureAsmGroupBox.Controls.Add(this.asmColWidthLabel);
this.configureAsmGroupBox.Controls.Add(this.asmExeLabel);
this.configureAsmGroupBox.Controls.Add(this.asmConfigComboBox);
this.configureAsmGroupBox.Controls.Add(this.asmExePathTextBox);
this.configureAsmGroupBox.Controls.Add(this.asmExeBrowseButton);
this.configureAsmGroupBox.Location = new System.Drawing.Point(6, 6);
this.configureAsmGroupBox.Name = "configureAsmGroupBox";
this.configureAsmGroupBox.Size = new System.Drawing.Size(602, 121);
this.configureAsmGroupBox.TabIndex = 0;
this.configureAsmGroupBox.TabStop = false;
this.configureAsmGroupBox.Text = "Assembler Configuration";
//
// asmColWidthIdLabel
//
this.asmColWidthIdLabel.AutoSize = true;
this.asmColWidthIdLabel.Location = new System.Drawing.Point(371, 88);
this.asmColWidthIdLabel.Name = "asmColWidthIdLabel";
this.asmColWidthIdLabel.Size = new System.Drawing.Size(171, 13);
this.asmColWidthIdLabel.TabIndex = 10;
this.asmColWidthIdLabel.Text = "(label, opcode, operand, comment)";
//
// asmConfigAssemblerLabel
//
this.asmConfigAssemblerLabel.AutoSize = true;
this.asmConfigAssemblerLabel.Location = new System.Drawing.Point(27, 22);
this.asmConfigAssemblerLabel.Name = "asmConfigAssemblerLabel";
this.asmConfigAssemblerLabel.Size = new System.Drawing.Size(58, 13);
this.asmConfigAssemblerLabel.TabIndex = 0;
this.asmConfigAssemblerLabel.Text = "Assembler:";
//
// asmCommentColWidthTextBox
//
this.asmCommentColWidthTextBox.Location = new System.Drawing.Point(301, 85);
this.asmCommentColWidthTextBox.Name = "asmCommentColWidthTextBox";
this.asmCommentColWidthTextBox.Size = new System.Drawing.Size(64, 20);
this.asmCommentColWidthTextBox.TabIndex = 9;
this.asmCommentColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged);
//
// asmOperandColWidthTextBox
//
this.asmOperandColWidthTextBox.Location = new System.Drawing.Point(231, 85);
this.asmOperandColWidthTextBox.Name = "asmOperandColWidthTextBox";
this.asmOperandColWidthTextBox.Size = new System.Drawing.Size(64, 20);
this.asmOperandColWidthTextBox.TabIndex = 8;
this.asmOperandColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged);
//
// asmOpcodeColWidthTextBox
//
this.asmOpcodeColWidthTextBox.Location = new System.Drawing.Point(161, 85);
this.asmOpcodeColWidthTextBox.Name = "asmOpcodeColWidthTextBox";
this.asmOpcodeColWidthTextBox.Size = new System.Drawing.Size(64, 20);
this.asmOpcodeColWidthTextBox.TabIndex = 7;
this.asmOpcodeColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged);
//
// asmLabelColWidthTextBox
//
this.asmLabelColWidthTextBox.Location = new System.Drawing.Point(91, 85);
this.asmLabelColWidthTextBox.Name = "asmLabelColWidthTextBox";
this.asmLabelColWidthTextBox.Size = new System.Drawing.Size(64, 20);
this.asmLabelColWidthTextBox.TabIndex = 6;
this.asmLabelColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged);
//
// asmColWidthLabel
//
this.asmColWidthLabel.AutoSize = true;
this.asmColWidthLabel.Location = new System.Drawing.Point(7, 88);
this.asmColWidthLabel.Name = "asmColWidthLabel";
this.asmColWidthLabel.Size = new System.Drawing.Size(78, 13);
this.asmColWidthLabel.TabIndex = 5;
this.asmColWidthLabel.Text = "Column widths:";
//
// asmExeLabel
//
this.asmExeLabel.AutoSize = true;
this.asmExeLabel.Location = new System.Drawing.Point(22, 61);
this.asmExeLabel.Name = "asmExeLabel";
this.asmExeLabel.Size = new System.Drawing.Size(63, 13);
this.asmExeLabel.TabIndex = 2;
this.asmExeLabel.Text = "Executable:";
//
// asmConfigComboBox
//
this.asmConfigComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.asmConfigComboBox.FormattingEnabled = true;
this.asmConfigComboBox.Items.AddRange(new object[] {
"cc65",
"Merlin32"});
this.asmConfigComboBox.Location = new System.Drawing.Point(91, 19);
this.asmConfigComboBox.Name = "asmConfigComboBox";
this.asmConfigComboBox.Size = new System.Drawing.Size(154, 21);
this.asmConfigComboBox.TabIndex = 1;
this.asmConfigComboBox.SelectedIndexChanged += new System.EventHandler(this.asmConfigComboBox_SelectedIndexChanged);
//
// asmExePathTextBox
//
this.asmExePathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.asmExePathTextBox.Location = new System.Drawing.Point(91, 58);
this.asmExePathTextBox.Name = "asmExePathTextBox";
this.asmExePathTextBox.Size = new System.Drawing.Size(424, 20);
this.asmExePathTextBox.TabIndex = 3;
this.asmExePathTextBox.Text = "C:\\something";
this.asmExePathTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged);
//
// asmExeBrowseButton
//
this.asmExeBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.asmExeBrowseButton.Location = new System.Drawing.Point(521, 56);
this.asmExeBrowseButton.Name = "asmExeBrowseButton";
this.asmExeBrowseButton.Size = new System.Drawing.Size(75, 23);
this.asmExeBrowseButton.TabIndex = 4;
this.asmExeBrowseButton.Text = "Browse...";
this.asmExeBrowseButton.UseVisualStyleBackColor = true;
this.asmExeBrowseButton.Click += new System.EventHandler(this.asmExeBrowseButton_Click);
//
// showCycleCountsCheckBox
//
this.showCycleCountsCheckBox.AutoSize = true;
this.showCycleCountsCheckBox.Location = new System.Drawing.Point(10, 217);
this.showCycleCountsCheckBox.Location = new System.Drawing.Point(6, 162);
this.showCycleCountsCheckBox.Name = "showCycleCountsCheckBox";
this.showCycleCountsCheckBox.Size = new System.Drawing.Size(116, 17);
this.showCycleCountsCheckBox.TabIndex = 53;
this.showCycleCountsCheckBox.TabIndex = 2;
this.showCycleCountsCheckBox.Text = "Show cycle counts";
this.showCycleCountsCheckBox.UseVisualStyleBackColor = true;
this.showCycleCountsCheckBox.CheckedChanged += new System.EventHandler(this.showCycleCountsCheckBox_CheckedChanged);
@ -555,29 +676,29 @@ namespace SourceGen.AppForms {
// configAsmGenLabel
//
this.configAsmGenLabel.AutoSize = true;
this.configAsmGenLabel.Location = new System.Drawing.Point(7, 128);
this.configAsmGenLabel.Location = new System.Drawing.Point(3, 143);
this.configAsmGenLabel.Name = "configAsmGenLabel";
this.configAsmGenLabel.Size = new System.Drawing.Size(154, 13);
this.configAsmGenLabel.TabIndex = 52;
this.configAsmGenLabel.Text = "Configure assembly generation:";
this.configAsmGenLabel.Size = new System.Drawing.Size(127, 13);
this.configAsmGenLabel.TabIndex = 1;
this.configAsmGenLabel.Text = "General code generation:";
//
// longLabelNewLineCheckBox
//
this.longLabelNewLineCheckBox.AutoSize = true;
this.longLabelNewLineCheckBox.Location = new System.Drawing.Point(10, 193);
this.longLabelNewLineCheckBox.Location = new System.Drawing.Point(6, 185);
this.longLabelNewLineCheckBox.Name = "longLabelNewLineCheckBox";
this.longLabelNewLineCheckBox.Size = new System.Drawing.Size(173, 17);
this.longLabelNewLineCheckBox.TabIndex = 51;
this.longLabelNewLineCheckBox.TabIndex = 3;
this.longLabelNewLineCheckBox.Text = "Put long labels on separate line";
this.longLabelNewLineCheckBox.UseVisualStyleBackColor = true;
//
// showAsmIdentCheckBox
//
this.showAsmIdentCheckBox.AutoSize = true;
this.showAsmIdentCheckBox.Location = new System.Drawing.Point(10, 147);
this.showAsmIdentCheckBox.Location = new System.Drawing.Point(6, 208);
this.showAsmIdentCheckBox.Name = "showAsmIdentCheckBox";
this.showAsmIdentCheckBox.Size = new System.Drawing.Size(154, 17);
this.showAsmIdentCheckBox.TabIndex = 10;
this.showAsmIdentCheckBox.TabIndex = 4;
this.showAsmIdentCheckBox.Text = "Identify assembler in output";
this.showAsmIdentCheckBox.UseVisualStyleBackColor = true;
this.showAsmIdentCheckBox.CheckedChanged += new System.EventHandler(this.showAsmIdentCheckBox_CheckedChanged);
@ -585,99 +706,14 @@ namespace SourceGen.AppForms {
// disableLabelLocalizationCheckBox
//
this.disableLabelLocalizationCheckBox.AutoSize = true;
this.disableLabelLocalizationCheckBox.Location = new System.Drawing.Point(10, 170);
this.disableLabelLocalizationCheckBox.Location = new System.Drawing.Point(6, 231);
this.disableLabelLocalizationCheckBox.Name = "disableLabelLocalizationCheckBox";
this.disableLabelLocalizationCheckBox.Size = new System.Drawing.Size(141, 17);
this.disableLabelLocalizationCheckBox.TabIndex = 9;
this.disableLabelLocalizationCheckBox.TabIndex = 5;
this.disableLabelLocalizationCheckBox.Text = "Disable label localization";
this.disableLabelLocalizationCheckBox.UseVisualStyleBackColor = true;
this.disableLabelLocalizationCheckBox.CheckedChanged += new System.EventHandler(this.disableLabelLocalizationCheckBox_CheckedChanged);
//
// clearMerlin32Button
//
this.clearMerlin32Button.Location = new System.Drawing.Point(531, 76);
this.clearMerlin32Button.Name = "clearMerlin32Button";
this.clearMerlin32Button.Size = new System.Drawing.Size(75, 23);
this.clearMerlin32Button.TabIndex = 8;
this.clearMerlin32Button.Text = "Clear";
this.clearMerlin32Button.UseVisualStyleBackColor = true;
this.clearMerlin32Button.Click += new System.EventHandler(this.clearMerlin32Button_Click);
//
// clearCc65Button
//
this.clearCc65Button.Location = new System.Drawing.Point(531, 35);
this.clearCc65Button.Name = "clearCc65Button";
this.clearCc65Button.Size = new System.Drawing.Size(75, 23);
this.clearCc65Button.TabIndex = 4;
this.clearCc65Button.Text = "Clear";
this.clearCc65Button.UseVisualStyleBackColor = true;
this.clearCc65Button.Click += new System.EventHandler(this.clearCc65Button_Click);
//
// browseMerlin32Button
//
this.browseMerlin32Button.Location = new System.Drawing.Point(450, 76);
this.browseMerlin32Button.Name = "browseMerlin32Button";
this.browseMerlin32Button.Size = new System.Drawing.Size(75, 23);
this.browseMerlin32Button.TabIndex = 7;
this.browseMerlin32Button.Text = "Browse...";
this.browseMerlin32Button.UseVisualStyleBackColor = true;
this.browseMerlin32Button.Click += new System.EventHandler(this.browseMerlin32Button_Click);
//
// browseCc65Button
//
this.browseCc65Button.Location = new System.Drawing.Point(450, 35);
this.browseCc65Button.Name = "browseCc65Button";
this.browseCc65Button.Size = new System.Drawing.Size(75, 23);
this.browseCc65Button.TabIndex = 3;
this.browseCc65Button.Text = "Browse...";
this.browseCc65Button.UseVisualStyleBackColor = true;
this.browseCc65Button.Click += new System.EventHandler(this.browseCc65Button_Click);
//
// cc65PathTextBox
//
this.cc65PathTextBox.Location = new System.Drawing.Point(65, 37);
this.cc65PathTextBox.Name = "cc65PathTextBox";
this.cc65PathTextBox.Size = new System.Drawing.Size(379, 20);
this.cc65PathTextBox.TabIndex = 2;
this.cc65PathTextBox.Text = "C:\\something";
this.cc65PathTextBox.TextChanged += new System.EventHandler(this.cc65PathTextBox_TextChanged);
//
// merlin32PathTextBox
//
this.merlin32PathTextBox.Location = new System.Drawing.Point(65, 78);
this.merlin32PathTextBox.Name = "merlin32PathTextBox";
this.merlin32PathTextBox.Size = new System.Drawing.Size(379, 20);
this.merlin32PathTextBox.TabIndex = 6;
this.merlin32PathTextBox.Text = "C:\\something";
this.merlin32PathTextBox.TextChanged += new System.EventHandler(this.merlin32PathTextBox_TextChanged);
//
// asmMerln32Label
//
this.asmMerln32Label.AutoSize = true;
this.asmMerln32Label.Location = new System.Drawing.Point(6, 81);
this.asmMerln32Label.Name = "asmMerln32Label";
this.asmMerln32Label.Size = new System.Drawing.Size(53, 13);
this.asmMerln32Label.TabIndex = 5;
this.asmMerln32Label.Text = "Merlin 32:";
//
// asmCc65Label
//
this.asmCc65Label.AutoSize = true;
this.asmCc65Label.Location = new System.Drawing.Point(25, 40);
this.asmCc65Label.Name = "asmCc65Label";
this.asmCc65Label.Size = new System.Drawing.Size(34, 13);
this.asmCc65Label.TabIndex = 1;
this.asmCc65Label.Text = "cc65:";
//
// asmExplanationLabel
//
this.asmExplanationLabel.AutoSize = true;
this.asmExplanationLabel.Location = new System.Drawing.Point(7, 7);
this.asmExplanationLabel.Name = "asmExplanationLabel";
this.asmExplanationLabel.Size = new System.Drawing.Size(179, 13);
this.asmExplanationLabel.TabIndex = 0;
this.asmExplanationLabel.Text = "Configure installed cross-assemblers:";
//
// displayFormatTabPage
//
this.displayFormatTabPage.Controls.Add(this.fmtExplanationLabel);
@ -1450,6 +1486,8 @@ namespace SourceGen.AppForms {
this.columnVisGroup.ResumeLayout(false);
this.asmConfigTabPage.ResumeLayout(false);
this.asmConfigTabPage.PerformLayout();
this.configureAsmGroupBox.ResumeLayout(false);
this.configureAsmGroupBox.PerformLayout();
this.displayFormatTabPage.ResumeLayout(false);
this.displayFormatTabPage.PerformLayout();
this.quickDisplayFormatGroup.ResumeLayout(false);
@ -1526,13 +1564,8 @@ namespace SourceGen.AppForms {
private System.Windows.Forms.Label strReverseHiLabel;
private System.Windows.Forms.TextBox strReverseTextBox;
private System.Windows.Forms.Label strReverseLabel;
private System.Windows.Forms.Label asmExplanationLabel;
private System.Windows.Forms.TextBox cc65PathTextBox;
private System.Windows.Forms.TextBox merlin32PathTextBox;
private System.Windows.Forms.Label asmMerln32Label;
private System.Windows.Forms.Label asmCc65Label;
private System.Windows.Forms.Button browseMerlin32Button;
private System.Windows.Forms.Button browseCc65Button;
private System.Windows.Forms.TextBox asmExePathTextBox;
private System.Windows.Forms.Button asmExeBrowseButton;
private System.Windows.Forms.GroupBox codeViewFontGroupBox;
private System.Windows.Forms.Label currentFontLabel;
private System.Windows.Forms.Button selectFontButton;
@ -1550,8 +1583,6 @@ namespace SourceGen.AppForms {
private System.Windows.Forms.CheckBox upperSCheckBox;
private System.Windows.Forms.CheckBox upperACheckBox;
private System.Windows.Forms.CheckBox upperPseudoOpCheckBox;
private System.Windows.Forms.Button clearMerlin32Button;
private System.Windows.Forms.Button clearCc65Button;
private System.Windows.Forms.CheckBox disableLabelLocalizationCheckBox;
private System.Windows.Forms.CheckBox enableDebugCheckBox;
private System.Windows.Forms.CheckBox showAsmIdentCheckBox;
@ -1579,5 +1610,15 @@ namespace SourceGen.AppForms {
private System.Windows.Forms.GroupBox clipboardGroupBox;
private System.Windows.Forms.ComboBox clipboardFormatComboBox;
private System.Windows.Forms.Label clipboardFormatLabel;
private System.Windows.Forms.ComboBox asmConfigComboBox;
private System.Windows.Forms.GroupBox configureAsmGroupBox;
private System.Windows.Forms.Label asmExeLabel;
private System.Windows.Forms.Label asmColWidthLabel;
private System.Windows.Forms.TextBox asmCommentColWidthTextBox;
private System.Windows.Forms.TextBox asmOperandColWidthTextBox;
private System.Windows.Forms.TextBox asmOpcodeColWidthTextBox;
private System.Windows.Forms.TextBox asmLabelColWidthTextBox;
private System.Windows.Forms.Label asmConfigAssemblerLabel;
private System.Windows.Forms.Label asmColWidthIdLabel;
}
}

View File

@ -21,6 +21,9 @@ using System.Reflection;
using System.Text;
using System.Windows.Forms;
using AssemblerInfo = SourceGen.AsmGen.AssemblerInfo;
using AssemblerConfig = SourceGen.AsmGen.AssemblerConfig;
namespace SourceGen.AppForms {
public partial class EditAppSettings : Form {
/// <summary>
@ -28,9 +31,9 @@ namespace SourceGen.AppForms {
/// </summary>
public enum Tab {
Unknown = -1,
CodeList = 0,
Assembler = 1,
AsmFormat = 2,
CodeView = 0,
AsmConfig = 1,
DisplayFOrmat = 2,
PseudoOp = 3
}
@ -57,12 +60,19 @@ namespace SourceGen.AppForms {
/// </summary>
private Tab mInitialTab;
/// <summary>
/// Assembler to initially select in combo boxes.
/// </summary>
private AssemblerInfo.Id mInitialAsmId;
// Map buttons to column show/hide buttons.
private const int NUM_COLUMNS = ProjectView.CodeListColumnWidths.NUM_COLUMNS;
private string[] mColumnFormats = new string[NUM_COLUMNS];
private Button[] mColButtons;
// Map pseudo-op text entry fields to PseudoOpName properties.
/// <summary>
/// Map pseudo-op text entry fields to PseudoOpName properties.
/// </summary>
private struct TextBoxPropertyMap {
public TextBox TextBox { get; private set; }
public PropertyInfo PropInfo { get; private set; }
@ -74,24 +84,42 @@ namespace SourceGen.AppForms {
}
private TextBoxPropertyMap[] mPseudoNameMap;
/// <summary>
/// Holds an item for the assembler-selection combox box.
/// </summary>
private class AsmComboItem {
// Enumerated ID.
public AssemblerInfo.Id AssemblerId { get; private set; }
public EditAppSettings(ProjectView projectView, Tab initialTab) {
// Human-readable name.
public string Name { get; private set; }
public AsmComboItem(AssemblerInfo info) {
AssemblerId = info.AssemblerId;
Name = info.Name;
}
}
public EditAppSettings(ProjectView projectView, Tab initialTab,
AssemblerInfo.Id initialAsmId) {
InitializeComponent();
mProjectView = projectView;
mInitialTab = initialTab;
mInitialAsmId = initialAsmId;
// Make a work copy, so we can discard changes if the user cancels out of the dialog.
projectView.SerializeCodeListColumnWidths();
mSettings = AppSettings.Global.GetCopy();
// Put buttons in an array.
// Put column-width buttons in an array.
mColButtons = new Button[] {
showCol0, showCol1, showCol2, showCol3, showCol4,
showCol5, showCol6, showCol7, showCol8 };
Debug.Assert(NUM_COLUMNS == 9);
// Extract formats from button labels.
// Extract formats from column-width button labels.
for (int i = 0; i < NUM_COLUMNS; i++) {
mColButtons[i].Click += ColumnVisibilityButtonClick;
mColumnFormats[i] = mColButtons[i].Text;
@ -122,6 +150,31 @@ namespace SourceGen.AppForms {
new TextBoxPropertyMap(strDciTextBox, "StrDci"),
new TextBoxPropertyMap(strDciHiTextBox, "StrDciHi"),
};
ConfigureComboBox(asmConfigComboBox);
}
private void ConfigureComboBox(ComboBox cb) {
// Show the Name field.
cb.DisplayMember = "Name";
cb.Items.Clear();
IEnumerator<AssemblerInfo> iter = AssemblerInfo.GetInfoEnumerator();
bool foundMatch = false;
while (iter.MoveNext()) {
AssemblerInfo info = iter.Current;
AsmComboItem item = new AsmComboItem(info);
cb.Items.Add(item);
if (item.AssemblerId == mInitialAsmId) {
cb.SelectedItem = item;
foundMatch = true;
}
}
if (!foundMatch) {
// Need to do this or box will show empty.
cb.SelectedIndex = 0;
}
}
private void EditAppSettings_Load(object sender, EventArgs e) {
@ -158,10 +211,7 @@ namespace SourceGen.AppForms {
enableDebugCheckBox.Checked = mSettings.GetBool(AppSettings.DEBUG_MENU_ENABLED, false);
// Assemblers.
cc65PathTextBox.Text =
mSettings.GetString(AppSettings.ASM_CC65_EXECUTABLE, string.Empty);
merlin32PathTextBox.Text =
mSettings.GetString(AppSettings.ASM_MERLIN32_EXECUTABLE, string.Empty);
PopulateAsmConfigItems();
showAsmIdentCheckBox.Checked =
mSettings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false);
disableLabelLocalizationCheckBox.Checked =
@ -202,9 +252,6 @@ namespace SourceGen.AppForms {
/// </summary>
private void UpdateControls() {
applyButton.Enabled = mDirty;
clearMerlin32Button.Enabled = !string.IsNullOrEmpty(merlin32PathTextBox.Text);
clearCc65Button.Enabled = !string.IsNullOrEmpty(cc65PathTextBox.Text);
}
/// <summary>
@ -358,41 +405,77 @@ namespace SourceGen.AppForms {
#region Asm Config
private void browseCc65Button_Click(object sender, EventArgs e) {
string pathName = BrowseForExecutable("cc65 CL", "cl65.exe");
/// <summary>
/// Populates the UI elements from the asm config item in the settings. If that doesn't
/// exist, use the default config.
/// </summary>
private void PopulateAsmConfigItems() {
AsmComboItem item = (AsmComboItem) asmConfigComboBox.SelectedItem;
AssemblerInfo.Id asmId = item.AssemblerId;
AssemblerConfig config = AssemblerConfig.GetConfig(mSettings, asmId);
if (config == null) {
AsmGen.IAssembler asm = AssemblerInfo.GetAssembler(asmId);
config = asm.GetDefaultConfig();
}
asmExePathTextBox.Text = config.ExecutablePath;
asmLabelColWidthTextBox.Text = config.ColumnWidths[0].ToString();
asmOpcodeColWidthTextBox.Text = config.ColumnWidths[1].ToString();
asmOperandColWidthTextBox.Text = config.ColumnWidths[2].ToString();
asmCommentColWidthTextBox.Text = config.ColumnWidths[3].ToString();
}
private AssemblerConfig GetAsmConfigFromUi() {
int[] widths = new int[4];
for (int i = 0; i < widths.Length; i++) {
widths[i] = 1; // minimum width for all fields is 1
}
int result;
if (int.TryParse(asmLabelColWidthTextBox.Text, out result) && result > 0) {
widths[0] = result;
}
if (int.TryParse(asmOpcodeColWidthTextBox.Text, out result) && result > 0) {
widths[1] = result;
}
if (int.TryParse(asmOperandColWidthTextBox.Text, out result) && result > 0) {
widths[2] = result;
}
if (int.TryParse(asmCommentColWidthTextBox.Text, out result) && result > 0) {
widths[3] = result;
}
return new AssemblerConfig(asmExePathTextBox.Text, widths);
}
private void asmConfigComboBox_SelectedIndexChanged(object sender, EventArgs e) {
PopulateAsmConfigItems();
}
private void asmExeBrowseButton_Click(object sender, EventArgs e) {
AsmComboItem item = (AsmComboItem)asmConfigComboBox.SelectedItem;
AssemblerInfo.Id asmId = item.AssemblerId;
// Figure out what we're looking for. For example, cc65 needs "cl65".
AsmGen.IAssembler asm = AssemblerInfo.GetAssembler(asmId);
asm.GetExeIdentifiers(out string humanName, out string exeName);
// Ask the user to find it.
string pathName = BrowseForExecutable(humanName, exeName);
if (pathName != null) {
cc65PathTextBox.Text = pathName;
mSettings.SetString(AppSettings.ASM_CC65_EXECUTABLE, pathName);
}
}
private void cc65PathTextBox_TextChanged(object sender, EventArgs e) {
mSettings.SetString(AppSettings.ASM_CC65_EXECUTABLE, cc65PathTextBox.Text);
asmExePathTextBox.Text = pathName;
AssemblerConfig.SetConfig(mSettings, asmId, GetAsmConfigFromUi());
SetDirty(true);
}
private void clearCc65Button_Click(object sender, EventArgs e) {
cc65PathTextBox.Text = string.Empty;
mSettings.SetString(AppSettings.ASM_CC65_EXECUTABLE, null);
SetDirty(true);
}
private void browseMerlin32Button_Click(object sender, EventArgs e) {
string pathName = BrowseForExecutable("Merlin Assembler", "Merlin32.exe");
if (pathName != null) {
merlin32PathTextBox.Text = pathName;
mSettings.SetString(AppSettings.ASM_MERLIN32_EXECUTABLE, pathName);
}
}
private void clearMerlin32Button_Click(object sender, EventArgs e) {
merlin32PathTextBox.Text = string.Empty;
mSettings.SetString(AppSettings.ASM_MERLIN32_EXECUTABLE, null);
SetDirty(true);
}
private void merlin32PathTextBox_TextChanged(object sender, EventArgs e) {
mSettings.SetString(AppSettings.ASM_MERLIN32_EXECUTABLE, merlin32PathTextBox.Text);
/// <summary>
/// Handles a text-changed event in the executable and column width text boxes.
/// </summary>
private void AsmConfig_TextChanged(object sender, EventArgs e) {
AsmComboItem item = (AsmComboItem)asmConfigComboBox.SelectedItem;
AssemblerConfig.SetConfig(mSettings, item.AssemblerId, GetAsmConfigFromUi());
SetDirty(true);
}
@ -405,19 +488,34 @@ namespace SourceGen.AppForms {
private string BrowseForExecutable(string prefix, string name) {
string pathName = null;
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
name += ".exe";
}
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = name;
dlg.Filter = prefix + "|" + name;
dlg.RestoreDirectory = true;
if (dlg.ShowDialog() != DialogResult.Cancel) {
pathName = dlg.FileName;
SetDirty(true);
}
dlg.Dispose();
return pathName;
}
private void showCycleCountsCheckBox_CheckedChanged(object sender, EventArgs e) {
mSettings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS,
showCycleCountsCheckBox.Checked);
SetDirty(true);
}
private void longLabelNewLineCheckBox_CheckedChanged(object sender, EventArgs e) {
mSettings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE,
longLabelNewLineCheckBox.Checked);
SetDirty(true);
}
private void showAsmIdentCheckBox_CheckedChanged(object sender, EventArgs e) {
mSettings.SetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, showAsmIdentCheckBox.Checked);
SetDirty(true);
@ -429,18 +527,6 @@ namespace SourceGen.AppForms {
SetDirty(true);
}
private void longLabelNewLineCheckBox_CheckedChanged(object sender, EventArgs e) {
mSettings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE,
longLabelNewLineCheckBox.Checked);
SetDirty(true);
}
private void showCycleCountsCheckBox_CheckedChanged(object sender, EventArgs e) {
mSettings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS,
showCycleCountsCheckBox.Checked);
SetDirty(true);
}
#endregion Asm Config

View File

@ -1936,15 +1936,16 @@ namespace SourceGen.AppForms {
// Edit > Settings...
private void settingsToolStripMenuItem_Click(object sender, EventArgs e) {
ShowAppSettings(EditAppSettings.Tab.Unknown);
ShowAppSettings(EditAppSettings.Tab.Unknown, AsmGen.AssemblerInfo.Id.Unknown);
}
/// <summary>
/// Opens the app settings dialog.
/// </summary>
/// <param name="initialTab">Tab to present to the user.</param>
public void ShowAppSettings(EditAppSettings.Tab initialTab) {
EditAppSettings dlg = new EditAppSettings(this, initialTab);
public void ShowAppSettings(EditAppSettings.Tab initialTab,
AsmGen.AssemblerInfo.Id initialAsmId) {
EditAppSettings dlg = new EditAppSettings(this, initialTab, initialAsmId);
dlg.ShowDialog();
dlg.Dispose();
}

View File

@ -108,11 +108,8 @@ namespace SourceGen {
// Main project view settings.
public const string PRVW_RECENT_PROJECT_LIST = "prvw-recent-project-list";
// cc65 assembler settings
public const string ASM_CC65_EXECUTABLE = "asm-cc65-executable";
// Merlin 32 assembler settings.
public const string ASM_MERLIN32_EXECUTABLE = "asm-merlin32-executable";
// Assembler settings prefix
public const string ASM_CONFIG_PREFIX = "asm-config-";
// Internal debugging features.
public const string DEBUG_MENU_ENABLED = "debug-menu-enabled";

View File

@ -661,16 +661,27 @@ namespace SourceGen.AsmGen {
private string WorkDirectory { get; set; }
// IAssembler
public void GetExeIdentifiers(out string humanName, out string exeName) {
humanName = "cc65 CL";
exeName = "cl65";
}
// IAssembler
public AssemblerConfig GetDefaultConfig() {
return new AssemblerConfig(string.Empty, new int[] { 9, 8, 11, 72 });
}
// IAssembler
public AssemblerVersion QueryVersion() {
string exe = AppSettings.Global.GetString(AppSettings.ASM_CC65_EXECUTABLE, null);
if (string.IsNullOrEmpty(exe)) {
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Cc65);
if (config == null || string.IsNullOrEmpty(config.ExecutablePath)) {
return null;
}
ShellCommand cmd = new ShellCommand(exe, "--version",
System.IO.Directory.GetCurrentDirectory(), null);
ShellCommand cmd = new ShellCommand(config.ExecutablePath, "--version",
Directory.GetCurrentDirectory(), null);
cmd.Execute();
if (string.IsNullOrEmpty(cmd.Stdout)) {
return null;
@ -721,25 +732,16 @@ namespace SourceGen.AsmGen {
Debug.WriteLine("NOTE: source file is not in work directory");
}
//string home = AppSettings.Global.GetString(AppSettings.ASM_CC65_HOME, null);
//string cl65 = AppSettings.Global.GetString(AppSettings.ASM_CC65_EXECUTABLE, null);
//Debug.Assert(!string.IsNullOrEmpty(cl65));
//Debug.Assert(!string.IsNullOrEmpty(home));
//Dictionary<string, string> envVars = new Dictionary<string, string>(1);
//envVars.Add("CC65_HOME", home);
//string exePath = Path.Combine(home, cl65);
string cl65 = AppSettings.Global.GetString(AppSettings.ASM_CC65_EXECUTABLE, null);
if (string.IsNullOrEmpty(cl65)) {
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Cc65);
if (string.IsNullOrEmpty(config.ExecutablePath)) {
Debug.WriteLine("Assembler not configured");
return null;
}
// Wrap pathname in quotes in case it has spaces.
// (Do we need to shell-escape quotes in the pathName?)
ShellCommand cmd = new ShellCommand(cl65,
ShellCommand cmd = new ShellCommand(config.ExecutablePath,
"--target none \"" + pathName + "\"", WorkDirectory, null);
cmd.Execute();

View File

@ -609,15 +609,27 @@ namespace SourceGen.AsmGen {
private string WorkDirectory { get; set; }
// IAssembler
public void GetExeIdentifiers(out string humanName, out string exeName) {
humanName = "Merlin Assembler";
exeName = "Merlin32";
}
// IAssembler
public AssemblerConfig GetDefaultConfig() {
return new AssemblerConfig(string.Empty, new int[] { 9, 6, 11, 74 });
}
// IAssembler
public AssemblerVersion QueryVersion() {
string exe = AppSettings.Global.GetString(AppSettings.ASM_MERLIN32_EXECUTABLE, null);
if (string.IsNullOrEmpty(exe)) {
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Merlin32);
if (config == null || string.IsNullOrEmpty(config.ExecutablePath)) {
return null;
}
ShellCommand cmd = new ShellCommand(exe, string.Empty,
System.IO.Directory.GetCurrentDirectory(), null);
ShellCommand cmd = new ShellCommand(config.ExecutablePath, string.Empty,
Directory.GetCurrentDirectory(), null);
cmd.Execute();
if (string.IsNullOrEmpty(cmd.Stdout)) {
return null;
@ -667,15 +679,16 @@ namespace SourceGen.AsmGen {
Debug.WriteLine("NOTE: source file is not in work directory");
}
string exe = AppSettings.Global.GetString(AppSettings.ASM_MERLIN32_EXECUTABLE, null);
if (string.IsNullOrEmpty(exe)) {
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Merlin32);
if (string.IsNullOrEmpty(config.ExecutablePath)) {
Debug.WriteLine("Assembler not configured");
return null;
}
// Wrap pathname in quotes in case it has spaces.
// (Do we need to shell-escape quotes in the pathName?)
ShellCommand cmd = new ShellCommand(exe, ". \"" + pathName + "\"",
ShellCommand cmd = new ShellCommand(config.ExecutablePath, ". \"" + pathName + "\"",
WorkDirectory, null);
cmd.Execute();

View File

@ -0,0 +1,111 @@
/*
* Copyright 2018 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Web.Script.Serialization;
namespace SourceGen.AsmGen {
/// <summary>
/// Assembler configuration holder. Serializes and deserializes information held in
/// application settings.
/// </summary>
public class AssemblerConfig {
// Fields are deserialized from JSON. Changing the names will break compatibility.
/// <summary>
/// Path to cross-assembler executable. Will be null or empty if this assembler
/// is not configured.
/// </summary>
public string ExecutablePath { get; set; }
/// <summary>
/// Column display widths.
/// </summary>
public int[] ColumnWidths { get; set; }
public const int NUM_COLUMNS = 4; // label, opcode, operand, comment
/// <summary>
/// Nullary constructor, for serialization.
/// </summary>
public AssemblerConfig() { }
/// <summary>
/// Constructor.
/// </summary>
/// <param name="exePath">Path to executable. May be empty.</param>
/// <param name="widths">Column widths.</param>
public AssemblerConfig(string exePath, int[] widths) {
if (exePath == null) {
throw new Exception("Bad exe path");
}
if (widths.Length != NUM_COLUMNS) {
throw new Exception("Bad widths.Length " + widths.Length);
}
ExecutablePath = exePath;
ColumnWidths = widths;
}
private static string GetSettingName(AssemblerInfo.Id id) {
return AppSettings.ASM_CONFIG_PREFIX + id.ToString();
}
/// <summary>
/// Creates a populated AssemblerConfig from the app settings for the specified ID.
/// </summary>
/// <param name="settings">Settings object to pull the values from.</param>
/// <param name="id">Assembler ID.</param>
/// <returns>The AssemblerConfig, or null if not configured.</returns>
public static AssemblerConfig GetConfig(AppSettings settings, AssemblerInfo.Id id) {
string cereal = settings.GetString(GetSettingName(id), null);
if (string.IsNullOrEmpty(cereal)) {
return null;
}
JavaScriptSerializer ser = new JavaScriptSerializer();
try {
AssemblerConfig config = ser.Deserialize<AssemblerConfig>(cereal);
if (config.ColumnWidths == null || config.ColumnWidths.Length != NUM_COLUMNS) {
throw new Exception("Bad column widths");
}
if (config.ExecutablePath == null) {
throw new Exception("Missing exe path");
}
return config;
} catch (Exception ex) {
Debug.WriteLine("AssemblerConfig deserialization failed: " + ex.Message);
return null;
}
}
/// <summary>
/// Updates the assembler settings for the specified ID.
/// </summary>
/// <param name="settings">Settings object to update.</param>
/// <param name="id">Assembler ID.</param>
/// <param name="config">Asm configuration.</param>
public static void SetConfig(AppSettings settings, AssemblerInfo.Id id,
AssemblerConfig config) {
JavaScriptSerializer ser = new JavaScriptSerializer();
string cereal = ser.Serialize(config);
settings.SetString(GetSettingName(id), cereal);
}
}
}

View File

@ -221,22 +221,12 @@ namespace SourceGen.AsmGen {
}
/// <summary>
/// Returns true if the selected assembler has been configured.
/// Returns true if the selected cross-assembler executable has been configured.
/// </summary>
private bool IsAssemblerConfigured() {
string settingStr;
switch (mSelectedAssemblerId) {
case AssemblerInfo.Id.Cc65:
settingStr = AppSettings.ASM_CC65_EXECUTABLE;
break;
case AssemblerInfo.Id.Merlin32:
settingStr = AppSettings.ASM_MERLIN32_EXECUTABLE;
break;
default:
Debug.Assert(false);
return false;
}
return !string.IsNullOrEmpty(AppSettings.Global.GetString(settingStr, null));
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, mSelectedAssemblerId);
return !string.IsNullOrEmpty(config.ExecutablePath);
}
private void assemblerSettingsButton_Click(object sender, EventArgs e) {
@ -254,7 +244,8 @@ namespace SourceGen.AsmGen {
/// </summary>
private void DoSettings() {
// Pop open the app settings dialog, with the appropriate tab selected.
mProjView.ShowAppSettings(AppForms.EditAppSettings.Tab.Assembler);
mProjView.ShowAppSettings(AppForms.EditAppSettings.Tab.AsmConfig,
mSelectedAssemblerId);
// Update the controls based on whether or not the assembler is now available.
UpdateAssemblerControls();

View File

@ -22,6 +22,20 @@ namespace SourceGen.AsmGen {
/// Common interface for executing assemblers.
/// </summary>
public interface IAssembler {
/// <summary>
/// Gets identification strings for the executable. These are used when browsing for
/// the assembler binary.
/// </summary>
/// <param name="humanName">Human-readable name to show in the "open" dialog.</param>
/// <param name="exeName">Name of executable to find, without ".exe".</param>
void GetExeIdentifiers(out string humanName, out string exeName);
/// <summary>
/// Queries the assembler for its default configuration.
/// </summary>
/// <returns>Config object with default values.</returns>
AssemblerConfig GetDefaultConfig();
/// <summary>
/// Queries the assembler for its version.
/// </summary>

View File

@ -98,6 +98,7 @@
<Compile Include="AppSettings.cs" />
<Compile Include="AsmGen\AsmCc65.cs" />
<Compile Include="AsmGen\AsmMerlin32.cs" />
<Compile Include="AsmGen\AssemblerConfig.cs" />
<Compile Include="AsmGen\AssemblerVersion.cs" />
<Compile Include="AsmGen\GenAndAsm.cs">
<SubType>Form</SubType>