diff --git a/Contralto/AltoSystem.cs b/Contralto/AltoSystem.cs index dad4d3e..4904311 100644 --- a/Contralto/AltoSystem.cs +++ b/Contralto/AltoSystem.cs @@ -82,6 +82,15 @@ namespace Contralto _displayController.DetachDisplay(); } + public void Shutdown() + { + // Kill any host interface threads that are running. + if (_ethernetController.HostInterface != null) + { + _ethernetController.HostInterface.Shutdown(); + } + } + public void SingleStep() { // Run every device that needs attention for a single clock cycle. @@ -140,6 +149,29 @@ namespace Contralto _diskController.Drives[drive].UnloadPack(); } + // + // Disk handling + // + public void CommitDiskPack(int driveId) + { + DiabloDrive drive = _diskController.Drives[driveId]; + if (drive.IsLoaded) + { + using (FileStream fs = new FileStream(drive.Pack.PackName, FileMode.Create, FileAccess.Write)) + { + try + { + drive.Pack.Save(fs); + } + catch (Exception e) + { + // TODO: this does not really belong here. + System.Windows.Forms.MessageBox.Show(String.Format("Unable to save disk {0}'s contents. Error {0}. Any changes have been lost.", e.Message), "Disk save error"); + } + } + } + } + public void PressBootKeys(AlternateBootType bootType) { switch(bootType) diff --git a/Contralto/CPU/Shifter.cs b/Contralto/CPU/Shifter.cs index 4887b02..2160a41 100644 --- a/Contralto/CPU/Shifter.cs +++ b/Contralto/CPU/Shifter.cs @@ -15,10 +15,9 @@ namespace Contralto.CPU // NOTE: FOR NOVA (NOVEL) SHIFTS (from aug '76 manual): // The emulator has two additional bits of state, the SKIP and CARRY flip flops.CARRY is identical // to the Nova carry bit, and is set or cleared as appropriate when the DNS+- (do Nova shifts) - // function is executed.DNS also addresses R from(1R[3 - 4] XOR 3), and sets the SKIP flip flop if + // function is executed. DNS also addresses R from (R[3 - 4] XOR 3), and sets the SKIP flip flop if // appropriate.The PC is incremented by 1 at the beginning of the next emulated instruction if - // SKIP is set, using ALUF DB.IR4- clears SKIP. - + // SKIP is set, using ALUF DB. IR<- clears SKIP. public static class Shifter { static Shifter() diff --git a/Contralto/CPU/Tasks/EmulatorTask.cs b/Contralto/CPU/Tasks/EmulatorTask.cs index 3444e1a..7bd636e 100644 --- a/Contralto/CPU/Tasks/EmulatorTask.cs +++ b/Contralto/CPU/Tasks/EmulatorTask.cs @@ -21,7 +21,9 @@ namespace Contralto.CPU public override void Reset() { base.Reset(); - _wakeup = true; + _wakeup = true; + + _systemType = Configuration.SystemType; } public override void BlockTask() @@ -153,7 +155,7 @@ namespace Contralto.CPU case EmulatorF1.LoadESRB: _rb = (ushort)((_busData & 0xe) >> 1); - if (_rb != 0 && Configuration.SystemType != SystemType.ThreeKRam) + if (_rb != 0 && _systemType != SystemType.ThreeKRam) { // Force bank 0 for machines with only 1K RAM. _rb = 0; @@ -455,6 +457,8 @@ namespace Contralto.CPU // // NB: _skip is in the encapsulating AltoCPU class to make it easier to reference since the ALU needs to know about it. private int _carry; + + private SystemType _systemType; } } } diff --git a/Contralto/CPU/UCodeDisassembler.cs b/Contralto/CPU/UCodeDisassembler.cs index 037cb82..1a77fa9 100644 --- a/Contralto/CPU/UCodeDisassembler.cs +++ b/Contralto/CPU/UCodeDisassembler.cs @@ -2,8 +2,7 @@ using System.Text; namespace Contralto.CPU -{ - // BUG: register assignments should come from L (not 0) +{ public static class UCodeDisassembler { @@ -150,9 +149,8 @@ namespace Contralto.CPU f1 = "TASK "; break; - case SpecialFunction1.Block: - // "...this function is reserved by convention only; it is *not* done by the microprocessor" - f1 = "BLOCK "; // throw new InvalidOperationException("BLOCK should never be invoked by microcode."); + case SpecialFunction1.Block: + f1 = "BLOCK "; break; case SpecialFunction1.LLSH1: diff --git a/Contralto/CPU/UCodeMemory.cs b/Contralto/CPU/UCodeMemory.cs index edc9be4..9b6c0ae 100644 --- a/Contralto/CPU/UCodeMemory.cs +++ b/Contralto/CPU/UCodeMemory.cs @@ -65,6 +65,9 @@ namespace Contralto.CPU _ramBank = 0; _ramSelect = true; _lowHalfsel = true; + + // Cache the system type from the configuration + _systemType = Configuration.SystemType; } public static void LoadBanksFromRMR(ushort rmr) @@ -97,25 +100,19 @@ namespace Contralto.CPU } public static void LoadControlRAMAddress(ushort address) - { - _ramBank = (address & 0x3000) >> 12; + { _ramSelect = (address & 0x0800) == 0; _lowHalfsel = (address & 0x0400) == 0; _ramAddr = (address & 0x3ff); // Clip RAM bank into range, it's always 0 unless we have a 3K uCode RAM system - switch (Configuration.SystemType) + if (_systemType != SystemType.ThreeKRam) { - case SystemType.OneKRom: - case SystemType.TwoKRom: - _ramBank = 0; - break; - case SystemType.ThreeKRam: - if (_ramBank > 2) - { - _ramBank = 2; - } - break; + _ramBank = 0; + } + else + { + _ramBank = (address & 0x3000) >> 12; } } @@ -129,7 +126,7 @@ namespace Contralto.CPU { // Log.Write(Logging.LogComponent.Microcode, "SWMODE: Current Bank {0}", _microcodeBank[(int)task]); - switch (Configuration.SystemType) + switch (_systemType) { case SystemType.OneKRom: _microcodeBank[(int)task] = _microcodeBank[(int)task] == MicrocodeBank.ROM0 ? MicrocodeBank.RAM0 : MicrocodeBank.ROM0; @@ -377,5 +374,7 @@ namespace Contralto.CPU private static bool _lowHalfsel; private static int _ramAddr; + private static SystemType _systemType; + } } diff --git a/Contralto/Contralto.csproj b/Contralto/Contralto.csproj index 825ec0c..6618755 100644 --- a/Contralto/Contralto.csproj +++ b/Contralto/Contralto.csproj @@ -163,7 +163,6 @@ Debugger.cs - @@ -393,6 +392,8 @@ + + diff --git a/Contralto/Disk/allgames.dsk b/Contralto/Disk/allgames.dsk index d25af00..ee49ceb 100644 Binary files a/Contralto/Disk/allgames.dsk and b/Contralto/Disk/allgames.dsk differ diff --git a/Contralto/Display/FakeDisplayController.cs b/Contralto/Display/FakeDisplayController.cs deleted file mode 100644 index 258defb..0000000 --- a/Contralto/Display/FakeDisplayController.cs +++ /dev/null @@ -1,155 +0,0 @@ -namespace Contralto.Display -{ - /// - /// FakeDisplayController draws the display without the aid of the - /// display microcode tasks (i.e. it cheats). It reads the displaylist - /// starting at DASTART and renders the display from there. - /// - public class FakeDisplayController : IClockable - { - public FakeDisplayController(AltoSystem system) - { - _system = system; - Reset(); - } - - public void AttachDisplay(IAltoDisplay display) - { - _display = display; - } - - public void Reset() - { - - } - - public void Clock() - { - _clocks++; - - if (_clocks > _frameClocks) - { - _clocks -= _frameClocks; - - RenderDisplay(); - _display.Render(); - } - } - - private void RenderDisplay() - { - // pick up DASTART; if zero we render a blank screen. - ushort daStart = _system.MemoryBus.DebugReadWord(0x110); - - if (daStart == 0) - { - for (int scanline = 0; scanline < 808; scanline++) - { - for (int word = 0; word < 38; word++) - { - _display.DrawDisplayWord(scanline, word, 0xffff, false); - } - } - - _display.Render(); - return; - } - - DCB dcb = GetNextDCB(daStart); - int dcbScanline = 0; - - for (int scanline = 0; scanline < 808; scanline++) - { - int wordOffset = 0; - - // fill in HTAB - for(int htab = 0;htab> 8; - dcb.nWrds = (mode & 0xff); - - dcb.startAddress = _system.MemoryBus.DebugReadWord((ushort)(address + 2)); - dcb.scanlineCount = _system.MemoryBus.DebugReadWord((ushort)(address + 3)) * 2; - - return dcb; - } - - - private struct DCB - { - public ushort daNext; - public bool lowRes; - public bool whiteOnBlack; - public int hTab; - public int nWrds; - public ushort startAddress; - public int scanlineCount; - } - - private double _clocks; - - private AltoSystem _system; - private IAltoDisplay _display; - - // Timing constants - // 38uS per scanline; 4uS for hblank. - // ~35 scanlines for vblank (1330uS) - private const double _scanlineClocks = 38.0 / 0.017; - private const double _frameClocks = _scanlineClocks * 850; // approx. - } -} diff --git a/Contralto/IO/DiskController.cs b/Contralto/IO/DiskController.cs index 96aea6f..8337fb5 100644 --- a/Contralto/IO/DiskController.cs +++ b/Contralto/IO/DiskController.cs @@ -351,8 +351,7 @@ namespace Contralto.IO if (_seclateEnable) { _seclate = true; - _kStat |= SECLATE; - Console.WriteLine("SECLATE for sector {0}.", _sector); + _kStat |= SECLATE; Log.Write(LogComponent.DiskSectorTask, "SECLATE for sector {0}.", _sector); } } @@ -500,8 +499,7 @@ namespace Contralto.IO // Debugging: on a read/check, if we are overwriting a word that was never read by the // microcode via KDATA, log it. if (_debugRead) - { - Console.WriteLine("--- missed sector word {0}({1}) ---", _sectorWordIndex, _kDataRead); + { Log.Write(LogType.Warning, LogComponent.DiskController, "--- missed sector word {0}({1}) ---", _sectorWordIndex, _kDataRead); } diff --git a/Contralto/IO/EthernetController.cs b/Contralto/IO/EthernetController.cs index 34e7618..db620fa 100644 --- a/Contralto/IO/EthernetController.cs +++ b/Contralto/IO/EthernetController.cs @@ -111,6 +111,11 @@ namespace Contralto.IO set { _countdownWakeup = value; } } + public IPacketEncapsulation HostInterface + { + get { return _hostInterface; } + } + public void ResetInterface() { // Latch status before resetting diff --git a/Contralto/IO/HostEthernetEncapsulation.cs b/Contralto/IO/HostEthernetEncapsulation.cs index a9785a1..1c9acb8 100644 --- a/Contralto/IO/HostEthernetEncapsulation.cs +++ b/Contralto/IO/HostEthernetEncapsulation.cs @@ -84,12 +84,24 @@ namespace Contralto.IO BeginReceive(); } + public void Shutdown() + { + if (_communicator != null) + { + _communicator.Break(); + } + + if (_receiveThread != null) + { + _receiveThread.Abort(); + } + } /// /// Sends an array of bytes over the ethernet as a 3mbit packet encapsulated in a 10mbit packet. /// /// - /// + /// public void Send(ushort[] packet, int length) { // Sanity check. @@ -222,7 +234,8 @@ namespace Contralto.IO // (probably need to make this more elegant so we can tear down the thread // properly.) Log.Write(LogComponent.HostNetworkInterface, "Receiver thread started."); - _communicator.ReceivePackets(-1, ReceiveCallback); + + _communicator.ReceivePackets(-1, ReceiveCallback); } private MacAddress Get10mbitDestinationMacFrom3mbit(byte destinationHost) diff --git a/Contralto/IO/IPacketEncapsulation.cs b/Contralto/IO/IPacketEncapsulation.cs index 8e862c6..b702b2e 100644 --- a/Contralto/IO/IPacketEncapsulation.cs +++ b/Contralto/IO/IPacketEncapsulation.cs @@ -19,5 +19,10 @@ namespace Contralto.IO /// /// void Send(ushort[] packet, int length); + + /// + /// Shuts down the encapsulation provider + /// + void Shutdown(); } } diff --git a/Contralto/IO/Mouse.cs b/Contralto/IO/Mouse.cs index e4fe479..6adc200 100644 --- a/Contralto/IO/Mouse.cs +++ b/Contralto/IO/Mouse.cs @@ -53,8 +53,7 @@ namespace Contralto.IO _ySteps = Math.Abs(dy); _yDir = Math.Sign(dy); - - //Console.WriteLine("Mouse move from ({0},{1}) to ({2},{3}).", _mouseX, _mouseY, _destX, _destY); + _lock.ExitWriteLock(); } @@ -122,9 +121,7 @@ namespace Contralto.IO else if (_yDir == 1 && _xDir == 1) { bits = 8; - } - - //Console.WriteLine("Mouse poll: xdir {0}, ydir {1}, bits {2}", _xDir, _yDir, Conversion.ToOctal(bits)); + } // Move the mouse closer to its destination if (_xSteps > 0) diff --git a/Contralto/IO/UDPEncapsulation.cs b/Contralto/IO/UDPEncapsulation.cs index 9cd6956..087e37a 100644 --- a/Contralto/IO/UDPEncapsulation.cs +++ b/Contralto/IO/UDPEncapsulation.cs @@ -91,6 +91,21 @@ namespace Contralto.IO BeginReceive(); } + public void Shutdown() + { + // Shut down the reciever thread. + + if (_receiveThread != null) + { + _receiveThread.Abort(); + } + + if (_udpClient != null) + { + _udpClient.Close(); + } + } + /// /// Sends an array of bytes over the ethernet as a 3mbit packet encapsulated in a 10mbit packet. diff --git a/Contralto/Memory/MemoryBus.cs b/Contralto/Memory/MemoryBus.cs index f1d4c5a..e9bf057 100644 --- a/Contralto/Memory/MemoryBus.cs +++ b/Contralto/Memory/MemoryBus.cs @@ -337,8 +337,7 @@ namespace Contralto.Memory } else { - //throw new NotImplementedException(String.Format("Read from unimplemented memory-mapped I/O device at {0}.", OctalHelpers.ToOctal(address))); - //Console.WriteLine("Read from unimplemented memory-mapped I/O device at {0}.", Conversion.ToOctal(address)); + //throw new NotImplementedException(String.Format("Read from unimplemented memory-mapped I/O device at {0}.", OctalHelpers.ToOctal(address))); return 0; } } @@ -369,8 +368,7 @@ namespace Contralto.Memory } else { - // throw new NotImplementedException(String.Format("Write to unimplemented memory-mapped I/O device at {0}.", OctalHelpers.ToOctal(address))); - //Console.WriteLine("Write to unimplemented memory-mapped I/O device at {0}.", Conversion.ToOctal(address)); + // throw new NotImplementedException(String.Format("Write to unimplemented memory-mapped I/O device at {0}.", OctalHelpers.ToOctal(address))); } } } diff --git a/Contralto/Program.cs b/Contralto/Program.cs index 224e2f7..598d670 100644 --- a/Contralto/Program.cs +++ b/Contralto/Program.cs @@ -3,6 +3,9 @@ using Contralto.IO; using System; using System.Net; using System.Collections.Generic; +using System.IO; +using System.Windows.Forms; +using System.Threading; namespace Contralto { @@ -17,18 +20,18 @@ namespace Contralto // See if WinPCap is installed and working TestPCap(); - AltoSystem system = new AltoSystem(); + _system = new AltoSystem(); if (!String.IsNullOrEmpty(Configuration.Drive0Image)) { try { - system.LoadDrive(0, Configuration.Drive0Image); + _system.LoadDrive(0, Configuration.Drive0Image); } catch(Exception e) { Console.WriteLine("Could not load image '{0}' for drive 0. Error '{1}'.", Configuration.Drive0Image, e.Message); - system.UnloadDrive(0); + _system.UnloadDrive(0); } } @@ -36,27 +39,51 @@ namespace Contralto { try { - system.LoadDrive(1, Configuration.Drive0Image); + _system.LoadDrive(1, Configuration.Drive1Image); } catch (Exception e) { Console.WriteLine("Could not load image '{0}' for drive 1. Error '{1}'.", Configuration.Drive1Image, e.Message); - system.UnloadDrive(1); + _system.UnloadDrive(1); } } - AltoWindow mainWindow = new AltoWindow(); + // + // Attach handlers so that we can properly flush state if we're terminated. + // + AppDomain.CurrentDomain.ProcessExit += OnProcessExit; - mainWindow.AttachSystem(system); - - mainWindow.ShowDialog(); + // + // Invoke the main UI window; this will run until the user closes it, at which + // point we are done. + // + using (AltoWindow mainWindow = new AltoWindow()) + { + mainWindow.AttachSystem(_system); + Application.Run(mainWindow); + } + } + private static void OnProcessExit(object sender, EventArgs e) + { + Console.WriteLine("Exiting..."); + + // + // Save disk contents + // + _system.CommitDiskPack(0); + _system.CommitDiskPack(1); + + // + // Commit current configuration to disk + // + Configuration.WriteConfiguration(); } private static void PrintHerald() { - Console.WriteLine("ContrAlto v0.1 (c) 2015, 2016 Living Computer Museum."); + Console.WriteLine("ContrAlto v1.0 (c) 2015, 2016 Living Computer Museum."); Console.WriteLine("Bug reports to joshd@livingcomputermuseum.org"); Console.WriteLine(); } @@ -72,12 +99,11 @@ namespace Contralto } catch { - Console.WriteLine("WARNING: WinPCAP does not appear to be properly installed."); - Console.WriteLine(" Raw Ethernet functionality will be disabled."); - Console.WriteLine(" Please install WinPCAP from: http://www.winpcap.org/"); - Configuration.HostRawEthernetInterfacesAvailable = false; } - } + } + + private static AltoSystem _system; + private static ManualResetEvent _closeEvent; } } diff --git a/Contralto/Properties/Resources.Designer.cs b/Contralto/Properties/Resources.Designer.cs index 0235d95..cd06c33 100644 --- a/Contralto/Properties/Resources.Designer.cs +++ b/Contralto/Properties/Resources.Designer.cs @@ -59,5 +59,15 @@ namespace Contralto.Properties { resourceCulture = value; } } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dragon { + get { + object obj = ResourceManager.GetObject("dragon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/Contralto/Properties/Resources.resx b/Contralto/Properties/Resources.resx index 1af7de1..2c3c270 100644 --- a/Contralto/Properties/Resources.resx +++ b/Contralto/Properties/Resources.resx @@ -117,4 +117,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\dragon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Contralto/Resources/dragon.png b/Contralto/Resources/dragon.png new file mode 100644 index 0000000..0a3c52c Binary files /dev/null and b/Contralto/Resources/dragon.png differ diff --git a/Contralto/UI/AboutBox.Designer.cs b/Contralto/UI/AboutBox.Designer.cs index 8a7b313..a01c55a 100644 --- a/Contralto/UI/AboutBox.Designer.cs +++ b/Contralto/UI/AboutBox.Designer.cs @@ -35,21 +35,23 @@ this.OkButton = new System.Windows.Forms.Button(); this.label4 = new System.Windows.Forms.Label(); this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(88, 19); + this.label1.Location = new System.Drawing.Point(88, 18); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(74, 13); this.label1.TabIndex = 0; - this.label1.Text = "ContrAlto v0.2"; + this.label1.Text = "ContrAlto v1.0"; // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(45, 45); + this.label2.Location = new System.Drawing.Point(41, 63); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(168, 13); this.label2.TabIndex = 1; @@ -59,7 +61,7 @@ // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(68, 32); + this.label3.Location = new System.Drawing.Point(69, 41); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(109, 13); this.label3.TabIndex = 2; @@ -67,7 +69,7 @@ // // OkButton // - this.OkButton.Location = new System.Drawing.Point(87, 161); + this.OkButton.Location = new System.Drawing.Point(87, 363); this.OkButton.Name = "OkButton"; this.OkButton.Size = new System.Drawing.Size(75, 23); this.OkButton.TabIndex = 3; @@ -77,16 +79,16 @@ // // label4 // - this.label4.Location = new System.Drawing.Point(23, 94); + this.label4.Location = new System.Drawing.Point(12, 320); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(231, 18); + this.label4.Size = new System.Drawing.Size(224, 18); this.label4.TabIndex = 4; this.label4.Text = "Bug reports, comments and miscellanea to"; // // linkLabel1 // this.linkLabel1.AutoSize = true; - this.linkLabel1.Location = new System.Drawing.Point(45, 112); + this.linkLabel1.Location = new System.Drawing.Point(41, 338); this.linkLabel1.Name = "linkLabel1"; this.linkLabel1.Size = new System.Drawing.Size(168, 13); this.linkLabel1.TabIndex = 5; @@ -94,24 +96,39 @@ this.linkLabel1.Text = "joshd@livingcomputermuseum.org"; this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); // + // pictureBox1 + // + this.pictureBox1.Image = global::Contralto.Properties.Resources.dragon; + this.pictureBox1.Location = new System.Drawing.Point(48, 79); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(153, 238); + this.pictureBox1.TabIndex = 6; + this.pictureBox1.TabStop = false; + // // AboutBox // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(256, 196); + this.ClientSize = new System.Drawing.Size(248, 393); + this.ControlBox = false; + this.Controls.Add(this.pictureBox1); this.Controls.Add(this.linkLabel1); this.Controls.Add(this.label4); this.Controls.Add(this.OkButton); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "AboutBox"; + this.ShowIcon = false; + this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "About ContrAlto"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -125,5 +142,6 @@ private System.Windows.Forms.Button OkButton; private System.Windows.Forms.Label label4; private System.Windows.Forms.LinkLabel linkLabel1; + private System.Windows.Forms.PictureBox pictureBox1; } } \ No newline at end of file diff --git a/Contralto/UI/AltoWindow.Designer.cs b/Contralto/UI/AltoWindow.Designer.cs index c27cdf9..b173f45 100644 --- a/Contralto/UI/AltoWindow.Designer.cs +++ b/Contralto/UI/AltoWindow.Designer.cs @@ -54,6 +54,7 @@ this.CaptureStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); this.SystemStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); this.DiskStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.saveScreenshotToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.DisplayBox)).BeginInit(); this.menuStrip1.SuspendLayout(); this.StatusLine.SuspendLayout(); @@ -86,6 +87,7 @@ // fileToolStripMenuItem // this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.saveScreenshotToolStripMenuItem, this.exitToolStripMenuItem}); this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); @@ -94,7 +96,7 @@ // exitToolStripMenuItem // this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(92, 22); + this.exitToolStripMenuItem.Size = new System.Drawing.Size(232, 22); this.exitToolStripMenuItem.Text = "Exit"; this.exitToolStripMenuItem.Click += new System.EventHandler(this.OnFileExitClick); // @@ -272,6 +274,15 @@ this.DiskStatusLabel.Size = new System.Drawing.Size(89, 17); this.DiskStatusLabel.Text = "DiskStatusLabel"; // + // saveScreenshotToolStripMenuItem + // + this.saveScreenshotToolStripMenuItem.Name = "saveScreenshotToolStripMenuItem"; + this.saveScreenshotToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt) + | System.Windows.Forms.Keys.P))); + this.saveScreenshotToolStripMenuItem.Size = new System.Drawing.Size(232, 22); + this.saveScreenshotToolStripMenuItem.Text = "Save Screenshot..."; + this.saveScreenshotToolStripMenuItem.Click += new System.EventHandler(this.OnFileSaveScreenshotClick); + // // AltoWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -330,5 +341,6 @@ private System.Windows.Forms.ToolStripStatusLabel DiskStatusLabel; private System.Windows.Forms.ToolStripMenuItem SystemEthernetBootMenu; private System.Windows.Forms.ToolStripMenuItem AlternateBootToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveScreenshotToolStripMenuItem; } } \ No newline at end of file diff --git a/Contralto/UI/AltoWindow.cs b/Contralto/UI/AltoWindow.cs index f371052..16b9a3e 100644 --- a/Contralto/UI/AltoWindow.cs +++ b/Contralto/UI/AltoWindow.cs @@ -91,7 +91,7 @@ namespace Contralto try { // Commit loaded pack back to disk - CommitDiskPack(0); + _system.CommitDiskPack(0); _system.LoadDrive(0, path); Drive0ImageName.Text = System.IO.Path.GetFileName(path); Configuration.Drive0Image = path; @@ -106,7 +106,7 @@ namespace Contralto private void OnSystemDrive0UnloadClick(object sender, EventArgs e) { - CommitDiskPack(0); + _system.CommitDiskPack(0); _system.UnloadDrive(0); Drive0ImageName.Text = _noImageLoadedText; Configuration.Drive0Image = String.Empty; @@ -124,7 +124,7 @@ namespace Contralto try { // Commit loaded pack back to disk - CommitDiskPack(1); + _system.CommitDiskPack(1); _system.LoadDrive(1, path); Drive1ImageName.Text = System.IO.Path.GetFileName(path); Configuration.Drive1Image = path; @@ -139,7 +139,7 @@ namespace Contralto private void OnSystemDrive1UnloadClick(object sender, EventArgs e) { - CommitDiskPack(1); + _system.CommitDiskPack(1); _system.UnloadDrive(1); Drive1ImageName.Text = _noImageLoadedText; Configuration.Drive1Image = String.Empty; @@ -193,6 +193,44 @@ namespace Contralto _debugger = null; } + private void OnFileSaveScreenshotClick(object sender, EventArgs e) + { + // Pause execution while the user selects the destination for the screenshot + bool wasRunning = _controller.IsRunning; + + _controller.StopExecution(); + + SaveFileDialog fileDialog = new SaveFileDialog(); + fileDialog.DefaultExt = "png"; + + fileDialog.Filter = "PNG Images (*.png)|*.png|All Files (*.*)|*.*"; + fileDialog.Title = String.Format("Select destination for screenshot."); + fileDialog.CheckPathExists = true; + fileDialog.FileName = "Screenshot.png"; + + DialogResult res = fileDialog.ShowDialog(); + + if (res == DialogResult.OK) + { + EncoderParameters p = new EncoderParameters(1); + p.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L); + + try + { + _displayBuffer.Save(fileDialog.FileName, GetEncoderForFormat(ImageFormat.Png), p); + } + catch + { + MessageBox.Show("Could not save screenshot. Check the specified filename and path and try again."); + } + } + + if (wasRunning) + { + _controller.StartExecution(AlternateBootType.None); + } + } + private void OnFileExitClick(object sender, EventArgs e) { _controller.StopExecution(); @@ -201,19 +239,17 @@ namespace Contralto private void OnAltoWindowClosed(object sender, FormClosedEventArgs e) { - // Halt the system and detach our display + // Halt the system and detach our display _controller.StopExecution(); _system.DetachDisplay(); + _system.Shutdown(); - // Commit loaded packs back to disk - CommitDiskPack(0); - CommitDiskPack(1); - + // // Commit current configuration to disk + // Configuration.WriteConfiguration(); - this.Dispose(); - Application.Exit(); + DialogResult = DialogResult.OK; } private string ShowImageLoadDialog(int drive) @@ -223,6 +259,8 @@ namespace Contralto fileDialog.DefaultExt = "dsk"; fileDialog.Filter = "Alto Disk Images (*.dsk, *.dsk44)|*.dsk;*.dsk44|Diablo 31 Disk Images (*.dsk)|*.dsk|Diablo 44 Disk Images (*.dsk44)|*.dsk44|All Files (*.*)|*.*"; fileDialog.Multiselect = false; + fileDialog.CheckFileExists = true; + fileDialog.CheckPathExists = true; fileDialog.Title = String.Format("Select image to load into drive {0}", drive); DialogResult res = fileDialog.ShowDialog(); @@ -250,29 +288,7 @@ namespace Contralto Console.WriteLine("Execution error: {0} - {1}", e.Message, e.StackTrace); System.Diagnostics.Debugger.Break(); - } - - // - // Disk handling - // - private void CommitDiskPack(int driveId) - { - DiabloDrive drive = _system.DiskController.Drives[driveId]; - if (drive.IsLoaded) - { - using (FileStream fs = new FileStream(drive.Pack.PackName, FileMode.Create, FileAccess.Write)) - { - try - { - drive.Pack.Save(fs); - } - catch (Exception e) - { - MessageBox.Show(String.Format("Unable to save disk {0}'s contents. Error {0}. Any changes have been lost.", e.Message), "Disk save error"); - } - } - } - } + } private void StartSystem(AlternateBootType bootType) { @@ -315,6 +331,10 @@ namespace Contralto _lastBuffer = _displayData0; } } + else + { + _lastBuffer = _currentBuffer; + } // Asynchronously render this frame. BeginInvoke(new DisplayDelegate(RefreshDisplayBox)); @@ -762,8 +782,22 @@ namespace Contralto _keyMap.Add(Keys.OemCloseBrackets, AltoKey.RBracket); _keyMap.Add(Keys.Down, AltoKey.LF); } - - + + private ImageCodecInfo GetEncoderForFormat(ImageFormat format) + { + ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); + + foreach (ImageCodecInfo codec in codecs) + { + if (codec.FormatID == format.Guid) + { + return codec; + } + } + return null; + } + + // Display related data. // Note: display is actually 606 pixels wide, but that's not an even multiple of 8, so we round up. // Two backbuffers and references to the current / last buffer for rendering diff --git a/Contralto/UI/Debugger.Designer.cs b/Contralto/UI/Debugger.Designer.cs index 10c0996..163540b 100644 --- a/Contralto/UI/Debugger.Designer.cs +++ b/Contralto/UI/Debugger.Designer.cs @@ -35,9 +35,6 @@ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle11 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle15 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle12 = new System.Windows.Forms.DataGridViewCellStyle(); @@ -53,8 +50,9 @@ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle23 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle24 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle25 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle26 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle27 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Debugger)); this.Microcode = new System.Windows.Forms.GroupBox(); this.SourceTabs = new System.Windows.Forms.TabControl(); @@ -66,10 +64,6 @@ this.Source = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Rom1Page = new System.Windows.Forms.TabPage(); this._rom1SourceViewer = new System.Windows.Forms.DataGridView(); - this.dataGridViewCheckBoxColumn1 = new System.Windows.Forms.DataGridViewCheckBoxColumn(); - this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Rom2Page = new System.Windows.Forms.TabPage(); this._ram0SourceViewer = new System.Windows.Forms.DataGridView(); this.dataGridViewCheckBoxColumn2 = new System.Windows.Forms.DataGridViewCheckBoxColumn(); @@ -106,10 +100,6 @@ this.Disassembly = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.label1 = new System.Windows.Forms.Label(); this.ExecutionStateLabel = new System.Windows.Forms.Label(); - this.groupBox5 = new System.Windows.Forms.GroupBox(); - this._diskData = new System.Windows.Forms.DataGridView(); - this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.ResetButton = new System.Windows.Forms.Button(); this.RunToNextTaskButton = new System.Windows.Forms.Button(); this.NovaStep = new System.Windows.Forms.Button(); @@ -118,7 +108,10 @@ this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.HackButton = new System.Windows.Forms.Button(); + this.dataGridViewCheckBoxColumn1 = new System.Windows.Forms.DataGridViewCheckBoxColumn(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.Microcode.SuspendLayout(); this.SourceTabs.SuspendLayout(); this.Rom0Page.SuspendLayout(); @@ -135,8 +128,6 @@ ((System.ComponentModel.ISupportInitialize)(this._otherRegs)).BeginInit(); this.groupBox4.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this._memoryData)).BeginInit(); - this.groupBox5.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this._diskData)).BeginInit(); this.groupBox6.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this._reservedMemory)).BeginInit(); this.SuspendLayout(); @@ -148,7 +139,7 @@ this.Microcode.Controls.Add(this.JumpToAddress); this.Microcode.Location = new System.Drawing.Point(3, 3); this.Microcode.Name = "Microcode"; - this.Microcode.Size = new System.Drawing.Size(603, 625); + this.Microcode.Size = new System.Drawing.Size(603, 622); this.Microcode.TabIndex = 0; this.Microcode.TabStop = false; this.Microcode.Text = "Microcode Source"; @@ -311,60 +302,11 @@ this._rom1SourceViewer.ShowCellErrors = false; this._rom1SourceViewer.ShowEditingIcon = false; this._rom1SourceViewer.ShowRowErrors = false; - this._rom1SourceViewer.Size = new System.Drawing.Size(582, 545); + this._rom1SourceViewer.Size = new System.Drawing.Size(582, 554); this._rom1SourceViewer.TabIndex = 2; this._rom1SourceViewer.TabStop = false; this._rom1SourceViewer.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.Rom1SourceViewCellClick); // - // dataGridViewCheckBoxColumn1 - // - this.dataGridViewCheckBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; - this.dataGridViewCheckBoxColumn1.FalseValue = "false"; - this.dataGridViewCheckBoxColumn1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.dataGridViewCheckBoxColumn1.HeaderText = "B"; - this.dataGridViewCheckBoxColumn1.IndeterminateValue = "null"; - this.dataGridViewCheckBoxColumn1.Name = "dataGridViewCheckBoxColumn1"; - this.dataGridViewCheckBoxColumn1.ReadOnly = true; - this.dataGridViewCheckBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewCheckBoxColumn1.TrueValue = "true"; - this.dataGridViewCheckBoxColumn1.Width = 20; - // - // dataGridViewTextBoxColumn4 - // - this.dataGridViewTextBoxColumn4.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; - dataGridViewCellStyle7.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.dataGridViewTextBoxColumn4.DefaultCellStyle = dataGridViewCellStyle7; - this.dataGridViewTextBoxColumn4.HeaderText = "Addr"; - this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; - this.dataGridViewTextBoxColumn4.ReadOnly = true; - this.dataGridViewTextBoxColumn4.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewTextBoxColumn4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn4.Width = 5; - // - // dataGridViewTextBoxColumn3 - // - this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; - dataGridViewCellStyle8.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewTextBoxColumn3.DefaultCellStyle = dataGridViewCellStyle8; - this.dataGridViewTextBoxColumn3.HeaderText = "Word"; - this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; - this.dataGridViewTextBoxColumn3.ReadOnly = true; - this.dataGridViewTextBoxColumn3.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewTextBoxColumn3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn3.Width = 5; - // - // dataGridViewTextBoxColumn5 - // - this.dataGridViewTextBoxColumn5.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - dataGridViewCellStyle9.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.dataGridViewTextBoxColumn5.DefaultCellStyle = dataGridViewCellStyle9; - this.dataGridViewTextBoxColumn5.HeaderText = "Source Code"; - this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; - this.dataGridViewTextBoxColumn5.ReadOnly = true; - this.dataGridViewTextBoxColumn5.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewTextBoxColumn5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - // // Rom2Page // this.Rom2Page.Controls.Add(this._ram0SourceViewer); @@ -486,9 +428,9 @@ // groupBox1 // this.groupBox1.Controls.Add(this._registerData); - this.groupBox1.Location = new System.Drawing.Point(614, 3); + this.groupBox1.Location = new System.Drawing.Point(909, 3); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(137, 625); + this.groupBox1.Size = new System.Drawing.Size(137, 667); this.groupBox1.TabIndex = 2; this.groupBox1.TabStop = false; this.groupBox1.Text = "General Registers"; @@ -528,7 +470,7 @@ this._registerData.ShowCellToolTips = false; this._registerData.ShowEditingIcon = false; this._registerData.ShowRowErrors = false; - this._registerData.Size = new System.Drawing.Size(123, 600); + this._registerData.Size = new System.Drawing.Size(123, 642); this._registerData.TabIndex = 0; this._registerData.TabStop = false; // @@ -563,7 +505,7 @@ // // StepButton // - this.StepButton.Location = new System.Drawing.Point(0, 954); + this.StepButton.Location = new System.Drawing.Point(9, 647); this.StepButton.Name = "StepButton"; this.StepButton.Size = new System.Drawing.Size(44, 23); this.StepButton.TabIndex = 3; @@ -574,7 +516,7 @@ // // AutoStep // - this.AutoStep.Location = new System.Drawing.Point(50, 954); + this.AutoStep.Location = new System.Drawing.Point(59, 647); this.AutoStep.Name = "AutoStep"; this.AutoStep.Size = new System.Drawing.Size(47, 23); this.AutoStep.TabIndex = 4; @@ -585,7 +527,7 @@ // // RunButton // - this.RunButton.Location = new System.Drawing.Point(103, 954); + this.RunButton.Location = new System.Drawing.Point(112, 647); this.RunButton.Name = "RunButton"; this.RunButton.Size = new System.Drawing.Size(41, 23); this.RunButton.TabIndex = 5; @@ -596,7 +538,7 @@ // // StopButton // - this.StopButton.Location = new System.Drawing.Point(351, 955); + this.StopButton.Location = new System.Drawing.Point(489, 648); this.StopButton.Name = "StopButton"; this.StopButton.Size = new System.Drawing.Size(43, 23); this.StopButton.TabIndex = 6; @@ -608,7 +550,7 @@ // groupBox2 // this.groupBox2.Controls.Add(this._taskData); - this.groupBox2.Location = new System.Drawing.Point(469, 634); + this.groupBox2.Location = new System.Drawing.Point(612, 326); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(137, 344); this.groupBox2.TabIndex = 7; @@ -679,9 +621,9 @@ // groupBox3 // this.groupBox3.Controls.Add(this._otherRegs); - this.groupBox3.Location = new System.Drawing.Point(612, 634); + this.groupBox3.Location = new System.Drawing.Point(755, 326); this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(137, 344); + this.groupBox3.Size = new System.Drawing.Size(148, 344); this.groupBox3.TabIndex = 8; this.groupBox3.TabStop = false; this.groupBox3.Text = "CPU Registers"; @@ -717,7 +659,7 @@ this._otherRegs.ShowCellToolTips = false; this._otherRegs.ShowEditingIcon = false; this._otherRegs.ShowRowErrors = false; - this._otherRegs.Size = new System.Drawing.Size(123, 319); + this._otherRegs.Size = new System.Drawing.Size(135, 319); this._otherRegs.TabIndex = 0; // // Reg @@ -746,16 +688,16 @@ this.groupBox4.Controls.Add(this.MemoryJumpToAddress); this.groupBox4.Controls.Add(this.label3); this.groupBox4.Controls.Add(this._memoryData); - this.groupBox4.Location = new System.Drawing.Point(172, 634); + this.groupBox4.Location = new System.Drawing.Point(612, 3); this.groupBox4.Name = "groupBox4"; - this.groupBox4.Size = new System.Drawing.Size(291, 298); + this.groupBox4.Size = new System.Drawing.Size(291, 317); this.groupBox4.TabIndex = 8; this.groupBox4.TabStop = false; - this.groupBox4.Text = "Memory"; + this.groupBox4.Text = "System Memory"; // // MemoryJumpToAddress // - this.MemoryJumpToAddress.Location = new System.Drawing.Point(53, 276); + this.MemoryJumpToAddress.Location = new System.Drawing.Point(53, 294); this.MemoryJumpToAddress.Name = "MemoryJumpToAddress"; this.MemoryJumpToAddress.Size = new System.Drawing.Size(48, 20); this.MemoryJumpToAddress.TabIndex = 15; @@ -765,7 +707,7 @@ // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(6, 279); + this.label3.Location = new System.Drawing.Point(4, 297); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(47, 13); this.label3.TabIndex = 14; @@ -807,7 +749,7 @@ this._memoryData.ShowCellToolTips = false; this._memoryData.ShowEditingIcon = false; this._memoryData.ShowRowErrors = false; - this._memoryData.Size = new System.Drawing.Size(279, 257); + this._memoryData.Size = new System.Drawing.Size(279, 272); this._memoryData.TabIndex = 0; this._memoryData.TabStop = false; this._memoryData.VirtualMode = true; @@ -860,7 +802,7 @@ // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(0, 935); + this.label1.Location = new System.Drawing.Point(9, 628); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(85, 13); this.label1.TabIndex = 9; @@ -869,77 +811,15 @@ // ExecutionStateLabel // this.ExecutionStateLabel.AutoSize = true; - this.ExecutionStateLabel.Location = new System.Drawing.Point(92, 935); + this.ExecutionStateLabel.Location = new System.Drawing.Point(101, 628); this.ExecutionStateLabel.Name = "ExecutionStateLabel"; this.ExecutionStateLabel.Size = new System.Drawing.Size(33, 13); this.ExecutionStateLabel.TabIndex = 10; this.ExecutionStateLabel.Text = "unset"; // - // groupBox5 - // - this.groupBox5.Controls.Add(this._diskData); - this.groupBox5.Location = new System.Drawing.Point(3, 634); - this.groupBox5.Name = "groupBox5"; - this.groupBox5.Size = new System.Drawing.Size(163, 298); - this.groupBox5.TabIndex = 11; - this.groupBox5.TabStop = false; - this.groupBox5.Text = "Disk"; - // - // _diskData - // - this._diskData.AllowUserToAddRows = false; - this._diskData.AllowUserToDeleteRows = false; - dataGridViewCellStyle24.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); - this._diskData.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle24; - this._diskData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this._diskData.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewTextBoxColumn1, - this.dataGridViewTextBoxColumn2}); - dataGridViewCellStyle25.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle25.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle25.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle25.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle25.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle25.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle25.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this._diskData.DefaultCellStyle = dataGridViewCellStyle25; - this._diskData.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; - this._diskData.Location = new System.Drawing.Point(6, 19); - this._diskData.MultiSelect = false; - this._diskData.Name = "_diskData"; - this._diskData.ReadOnly = true; - this._diskData.RowHeadersVisible = false; - this._diskData.RowTemplate.DefaultCellStyle.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this._diskData.RowTemplate.Height = 18; - this._diskData.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; - this._diskData.ShowCellErrors = false; - this._diskData.ShowCellToolTips = false; - this._diskData.ShowEditingIcon = false; - this._diskData.ShowRowErrors = false; - this._diskData.Size = new System.Drawing.Size(147, 273); - this._diskData.TabIndex = 1; - this._diskData.TabStop = false; - // - // dataGridViewTextBoxColumn1 - // - this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; - this.dataGridViewTextBoxColumn1.HeaderText = "Data"; - this.dataGridViewTextBoxColumn1.MinimumWidth = 16; - this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; - this.dataGridViewTextBoxColumn1.ReadOnly = true; - this.dataGridViewTextBoxColumn1.Width = 55; - // - // dataGridViewTextBoxColumn2 - // - this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; - this.dataGridViewTextBoxColumn2.HeaderText = "Value"; - this.dataGridViewTextBoxColumn2.MinimumWidth = 16; - this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; - this.dataGridViewTextBoxColumn2.ReadOnly = true; - // // ResetButton // - this.ResetButton.Location = new System.Drawing.Point(400, 955); + this.ResetButton.Location = new System.Drawing.Point(538, 648); this.ResetButton.Name = "ResetButton"; this.ResetButton.Size = new System.Drawing.Size(57, 23); this.ResetButton.TabIndex = 12; @@ -950,7 +830,7 @@ // // RunToNextTaskButton // - this.RunToNextTaskButton.Location = new System.Drawing.Point(150, 954); + this.RunToNextTaskButton.Location = new System.Drawing.Point(159, 647); this.RunToNextTaskButton.Name = "RunToNextTaskButton"; this.RunToNextTaskButton.Size = new System.Drawing.Size(51, 23); this.RunToNextTaskButton.TabIndex = 13; @@ -961,7 +841,7 @@ // // NovaStep // - this.NovaStep.Location = new System.Drawing.Point(207, 954); + this.NovaStep.Location = new System.Drawing.Point(216, 647); this.NovaStep.Name = "NovaStep"; this.NovaStep.Size = new System.Drawing.Size(66, 23); this.NovaStep.TabIndex = 14; @@ -973,9 +853,9 @@ // groupBox6 // this.groupBox6.Controls.Add(this._reservedMemory); - this.groupBox6.Location = new System.Drawing.Point(757, 3); + this.groupBox6.Location = new System.Drawing.Point(1052, 3); this.groupBox6.Name = "groupBox6"; - this.groupBox6.Size = new System.Drawing.Size(180, 975); + this.groupBox6.Size = new System.Drawing.Size(180, 667); this.groupBox6.TabIndex = 3; this.groupBox6.TabStop = false; this.groupBox6.Text = "Reserved Memory"; @@ -986,21 +866,21 @@ this._reservedMemory.AllowUserToDeleteRows = false; this._reservedMemory.AllowUserToResizeColumns = false; this._reservedMemory.AllowUserToResizeRows = false; - dataGridViewCellStyle26.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); - this._reservedMemory.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle26; + dataGridViewCellStyle24.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this._reservedMemory.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle24; this._reservedMemory.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this._reservedMemory.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.dataGridViewTextBoxColumn9, this.dataGridViewTextBoxColumn10, this.dataGridViewTextBoxColumn11}); - dataGridViewCellStyle27.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle27.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle27.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle27.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle27.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle27.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle27.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this._reservedMemory.DefaultCellStyle = dataGridViewCellStyle27; + dataGridViewCellStyle25.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle25.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle25.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle25.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle25.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle25.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle25.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this._reservedMemory.DefaultCellStyle = dataGridViewCellStyle25; this._reservedMemory.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically; this._reservedMemory.Location = new System.Drawing.Point(7, 19); this._reservedMemory.MultiSelect = false; @@ -1015,7 +895,7 @@ this._reservedMemory.ShowCellToolTips = false; this._reservedMemory.ShowEditingIcon = false; this._reservedMemory.ShowRowErrors = false; - this._reservedMemory.Size = new System.Drawing.Size(167, 950); + this._reservedMemory.Size = new System.Drawing.Size(167, 642); this._reservedMemory.TabIndex = 0; this._reservedMemory.TabStop = false; // @@ -1047,27 +927,64 @@ this.dataGridViewTextBoxColumn11.Resizable = System.Windows.Forms.DataGridViewTriState.False; this.dataGridViewTextBoxColumn11.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; // - // HackButton + // dataGridViewCheckBoxColumn1 // - this.HackButton.Location = new System.Drawing.Point(295, 955); - this.HackButton.Name = "HackButton"; - this.HackButton.Size = new System.Drawing.Size(36, 23); - this.HackButton.TabIndex = 15; - this.HackButton.Text = "hack"; - this.HackButton.UseVisualStyleBackColor = true; - this.HackButton.Click += new System.EventHandler(this.HackButton_Click); + this.dataGridViewCheckBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; + this.dataGridViewCheckBoxColumn1.FalseValue = "false"; + this.dataGridViewCheckBoxColumn1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.dataGridViewCheckBoxColumn1.HeaderText = "B"; + this.dataGridViewCheckBoxColumn1.IndeterminateValue = "null"; + this.dataGridViewCheckBoxColumn1.Name = "dataGridViewCheckBoxColumn1"; + this.dataGridViewCheckBoxColumn1.ReadOnly = true; + this.dataGridViewCheckBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewCheckBoxColumn1.TrueValue = "true"; + this.dataGridViewCheckBoxColumn1.Width = 20; + // + // dataGridViewTextBoxColumn4 + // + this.dataGridViewTextBoxColumn4.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; + dataGridViewCellStyle7.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.dataGridViewTextBoxColumn4.DefaultCellStyle = dataGridViewCellStyle7; + this.dataGridViewTextBoxColumn4.HeaderText = "T"; + this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; + this.dataGridViewTextBoxColumn4.ReadOnly = true; + this.dataGridViewTextBoxColumn4.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewTextBoxColumn4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; + this.dataGridViewTextBoxColumn4.Width = 5; + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader; + dataGridViewCellStyle8.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewTextBoxColumn3.DefaultCellStyle = dataGridViewCellStyle8; + this.dataGridViewTextBoxColumn3.HeaderText = "Addr"; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + this.dataGridViewTextBoxColumn3.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewTextBoxColumn3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; + this.dataGridViewTextBoxColumn3.Width = 5; + // + // dataGridViewTextBoxColumn5 + // + this.dataGridViewTextBoxColumn5.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; + dataGridViewCellStyle9.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.dataGridViewTextBoxColumn5.DefaultCellStyle = dataGridViewCellStyle9; + this.dataGridViewTextBoxColumn5.HeaderText = "Source Code"; + this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; + this.dataGridViewTextBoxColumn5.ReadOnly = true; + this.dataGridViewTextBoxColumn5.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewTextBoxColumn5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; // // Debugger // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(949, 997); - this.Controls.Add(this.HackButton); + this.ClientSize = new System.Drawing.Size(1235, 673); this.Controls.Add(this.groupBox6); this.Controls.Add(this.NovaStep); this.Controls.Add(this.RunToNextTaskButton); this.Controls.Add(this.ResetButton); - this.Controls.Add(this.groupBox5); this.Controls.Add(this.ExecutionStateLabel); this.Controls.Add(this.label1); this.Controls.Add(this.groupBox4); @@ -1106,8 +1023,6 @@ this.groupBox4.ResumeLayout(false); this.groupBox4.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this._memoryData)).EndInit(); - this.groupBox5.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this._diskData)).EndInit(); this.groupBox6.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this._reservedMemory)).EndInit(); this.ResumeLayout(false); @@ -1147,10 +1062,6 @@ private System.Windows.Forms.Label ExecutionStateLabel; private System.Windows.Forms.TextBox JumpToAddress; private System.Windows.Forms.Label label2; - private System.Windows.Forms.GroupBox groupBox5; - private System.Windows.Forms.DataGridView _diskData; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; private System.Windows.Forms.Button ResetButton; private System.Windows.Forms.Button RunToNextTaskButton; private System.Windows.Forms.Button NovaStep; @@ -1168,10 +1079,6 @@ private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7; private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn8; - private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewCheckBoxColumn1; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; private System.Windows.Forms.GroupBox groupBox6; private System.Windows.Forms.DataGridView _reservedMemory; private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn9; @@ -1179,6 +1086,9 @@ private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn11; private System.Windows.Forms.TextBox MemoryJumpToAddress; private System.Windows.Forms.Label label3; - private System.Windows.Forms.Button HackButton; + private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewCheckBoxColumn1; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; + private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; } } \ No newline at end of file diff --git a/Contralto/UI/Debugger.cs b/Contralto/UI/Debugger.cs index fe0a096..ab3216d 100644 --- a/Contralto/UI/Debugger.cs +++ b/Contralto/UI/Debugger.cs @@ -50,29 +50,30 @@ namespace Contralto DataGridView view = bank == MicrocodeBank.ROM0 ? _rom0SourceViewer : _rom1SourceViewer; - StreamReader sr = new StreamReader(path); - - while (!sr.EndOfStream) + using (StreamReader sr = new StreamReader(path)) { - string line = sr.ReadLine(); - - SourceLine src = new SourceLine(line); - - int i = view.Rows.Add( - false, // breakpoint - GetTextForTask(src.Task), - src.Address, - src.Text); - - // Give the row a color based on the task - view.Rows[i].DefaultCellStyle.BackColor = GetColorForTask(src.Task); - - // Tag the row based on the PROM address (if any) to make it easy to find. - if (!String.IsNullOrEmpty(src.Address)) + while (!sr.EndOfStream) { - view.Rows[i].Tag = Convert.ToUInt16(src.Address, 8); + string line = sr.ReadLine(); + + SourceLine src = new SourceLine(line); + + int i = view.Rows.Add( + false, // breakpoint + GetTextForTask(src.Task), + src.Address, + src.Text); + + // Give the row a color based on the task + view.Rows[i].DefaultCellStyle.BackColor = GetColorForTask(src.Task); + + // Tag the row based on the PROM address (if any) to make it easy to find. + if (!String.IsNullOrEmpty(src.Address)) + { + view.Rows[i].Tag = Convert.ToUInt16(src.Address, 8); + } } - } + } // Ensure the UI view gets refreshed to display the current MPC source Refresh(); @@ -121,19 +122,7 @@ namespace Contralto //_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.Skip, 1); _otherRegs.Rows[5].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MAR, 6); _otherRegs.Rows[6].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.MD, 6); - _otherRegs.Rows[7].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.Cycle & 0x3f, 2); - - // Disk info - _diskData.Rows[0].Cells[1].Value = _system.DiskController.ClocksUntilNextSector.ToString("0.00"); - _diskData.Rows[1].Cells[1].Value = _system.DiskController.Cylinder.ToString(); - _diskData.Rows[2].Cells[1].Value = _system.DiskController.SeekCylinder.ToString(); - _diskData.Rows[3].Cells[1].Value = _system.DiskController.Head.ToString(); - _diskData.Rows[4].Cells[1].Value = _system.DiskController.Sector.ToString(); - _diskData.Rows[5].Cells[1].Value = Conversion.ToOctal(_system.DiskController.KDATA, 6); - _diskData.Rows[6].Cells[1].Value = Conversion.ToOctal(_system.DiskController.KADR, 6); - _diskData.Rows[7].Cells[1].Value = Conversion.ToOctal(_system.DiskController.KCOM, 6); - _diskData.Rows[8].Cells[1].Value = Conversion.ToOctal(_system.DiskController.KSTAT, 6); - _diskData.Rows[9].Cells[1].Value = _system.DiskController.RECNO.ToString(); + _otherRegs.Rows[7].Cells[1].Value = Conversion.ToOctal(_system.MemoryBus.Cycle & 0x3f, 2); // Reserved memory locations for (int i = 0; i < _reservedMemoryEntries.Length; i++) @@ -245,18 +234,7 @@ namespace Contralto //_otherRegs.Rows.Add("SKIP", "0"); _otherRegs.Rows.Add("MAR", "0"); _otherRegs.Rows.Add("MD", "0"); - _otherRegs.Rows.Add("MCycle", "0"); - - _diskData.Rows.Add("Cycles", "0"); - _diskData.Rows.Add("Cylinder", "0"); - _diskData.Rows.Add("D.Cylinder", "0"); - _diskData.Rows.Add("Head", "0"); - _diskData.Rows.Add("Sector", "0"); - _diskData.Rows.Add("KDATA", "0"); - _diskData.Rows.Add("KADR", "0"); - _diskData.Rows.Add("KCOM", "0"); - _diskData.Rows.Add("KSTAT", "0"); - _diskData.Rows.Add("RECNO", "0"); + _otherRegs.Rows.Add("MCycle", "0"); for(int i=0;i< _reservedMemoryEntries.Length;i++) { @@ -797,7 +775,7 @@ namespace Contralto this.BeginInvoke(new StepDelegate(RefreshUI)); this.BeginInvoke(new StepDelegate(Invalidate)); System.Threading.Thread.Sleep(10); - return true; /* break always */ + return false; /* break always */ } case ExecutionType.Step: diff --git a/Contralto/UI/Debugger.resx b/Contralto/UI/Debugger.resx index 2f44b9e..29bc6e5 100644 --- a/Contralto/UI/Debugger.resx +++ b/Contralto/UI/Debugger.resx @@ -189,12 +189,6 @@ True - - True - - - True - True diff --git a/Contralto/UI/SystemOptions.cs b/Contralto/UI/SystemOptions.cs index dc4eacd..4e6b08f 100644 --- a/Contralto/UI/SystemOptions.cs +++ b/Contralto/UI/SystemOptions.cs @@ -215,7 +215,7 @@ namespace Contralto.UI Configuration.HostPacketInterfaceType != _selectedInterfaceType || Configuration.SystemType != _selectedSystemType) { - MessageBox.Show("Changes to CPU or Ethernet configuration will not take effect until ContrAlto is restarted."); + MessageBox.Show("Changes to CPU or host Ethernet configuration will not take effect until ContrAlto is restarted."); } // System diff --git a/Contralto/dragon.png b/Contralto/dragon.png new file mode 100644 index 0000000..0a3c52c Binary files /dev/null and b/Contralto/dragon.png differ