diff --git a/D/Configuration.cs b/D/Configuration.cs index 701bdbc..a9e4e3e 100644 --- a/D/Configuration.cs +++ b/D/Configuration.cs @@ -89,7 +89,7 @@ namespace D // // Sanity-check settings that need sanity-checking. // - if (MemorySize > 1024 || + if (MemorySize > 768 || MemorySize == 0 || (MemorySize % 128) != 0) { diff --git a/D/Ethernet/EthernetController.cs b/D/Ethernet/EthernetController.cs index a3d6fdf..ebad542 100644 --- a/D/Ethernet/EthernetController.cs +++ b/D/Ethernet/EthernetController.cs @@ -57,24 +57,8 @@ namespace D.Ethernet _pendingPackets = new Queue(); _crc32 = new CRC32(); - - // Attach real Ethernet device if user has specified one, otherwise leave unattached; output data - // will go into a bit-bucket. - try - { - - if (Configuration.HostRawEthernetInterfacesAvailable && - !string.IsNullOrWhiteSpace(Configuration.HostPacketInterfaceName)) - { - _hostInterface = new HostEthernetEncapsulation(Configuration.HostPacketInterfaceName); - _hostInterface.RegisterReceiveCallback(OnHostPacketReceived); - } - } - catch (Exception e) - { - _hostInterface = null; - Log.Write(LogComponent.HostEthernet, "Unable to configure network interface. Error {0}", e.Message); - } + + AttachHostEthernet(); _readerLock = new ReaderWriterLockSlim(); @@ -84,6 +68,15 @@ namespace D.Ethernet Reset(); } + public void Shutdown() + { + if (_hostInterface != null) + { + _hostInterface.Shutdown(); + _hostInterface = null; + } + } + public void Reset() { _turnOff_ = false; @@ -116,6 +109,20 @@ namespace D.Ethernet _crc32.Reset(); } + public void HostInterfaceChanged() + { + // + // Shut down previous host interface (if any) and attach a new one: + // + if (_hostInterface != null) + { + _hostInterface.Shutdown(); + _hostInterface = null; + } + + AttachHostEthernet(); + } + public int EtherDisp() { // @@ -869,7 +876,28 @@ namespace D.Ethernet if (Log.Enabled) Log.Write(LogComponent.EthernetControl, "Sleeping Ethernet task."); _system.CP.SleepTask(TaskType.Ethernet); } - } + } + + private void AttachHostEthernet() + { + // Attach real Ethernet device if user has specified one, otherwise leave unattached; output data + // will go into a bit-bucket. + try + { + + if (Configuration.HostRawEthernetInterfacesAvailable && + !string.IsNullOrWhiteSpace(Configuration.HostPacketInterfaceName)) + { + _hostInterface = new HostEthernetEncapsulation(Configuration.HostPacketInterfaceName); + _hostInterface.RegisterReceiveCallback(OnHostPacketReceived); + } + } + catch (Exception e) + { + _hostInterface = null; + Log.Write(LogComponent.HostEthernet, "Unable to configure network interface. Error {0}", e.Message); + } + } private DSystem _system; diff --git a/D/IO/SA1000.cs b/D/IO/SA1000.cs index 9947730..86a4607 100644 --- a/D/IO/SA1000.cs +++ b/D/IO/SA1000.cs @@ -98,7 +98,14 @@ namespace D.IO public void Save(string path) { - using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) + // + // We commit to a temporary file first, then replace the original with the + // temporary file if successful. This ensures that if something goes wrong + // during the Save operation that at the very least the original image file + // is left unscathed. + string tempPath = Path.GetTempFileName(); + + using (FileStream fs = new FileStream(tempPath, FileMode.Create, FileAccess.Write)) { // // Format is: @@ -119,9 +126,11 @@ namespace D.IO } } } - - _diskImagePath = path; } + + // Complete: Move temporary file to final location. + File.Copy(tempPath, path, true /* overwrite */); + _diskImagePath = path; } public void Load(string path) diff --git a/D/Program.cs b/D/Program.cs index 0e230ea..1adfd0a 100644 --- a/D/Program.cs +++ b/D/Program.cs @@ -68,7 +68,7 @@ namespace D private static void PrintHerald() { Console.WriteLine("Darkstar v{0}", typeof(Program).Assembly.GetName().Version); - Console.WriteLine("(c) 2017, 2018 Living Computers: Museum+Labs"); + Console.WriteLine("(c) 2017-2019 Living Computers: Museum+Labs"); Console.WriteLine("Bug reports to joshd@livingcomputers.org"); Console.WriteLine(); } diff --git a/D/Properties/AssemblyInfo.cs b/D/Properties/AssemblyInfo.cs index 857048c..10ae20f 100644 --- a/D/Properties/AssemblyInfo.cs +++ b/D/Properties/AssemblyInfo.cs @@ -39,7 +39,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Living Computers: Museum+Labs")] [assembly: AssemblyProduct("Darkstar")] -[assembly: AssemblyCopyright("Copyright © 2017, 2018")] +[assembly: AssemblyCopyright("Copyright © 2017-2019")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -61,5 +61,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.0.0.1")] +[assembly: AssemblyFileVersion("1.0.0.1")] diff --git a/D/System.cs b/D/System.cs index 0e6486c..688cd3f 100644 --- a/D/System.cs +++ b/D/System.cs @@ -125,7 +125,9 @@ namespace D public void Shutdown(bool commitDisks) { + Console.WriteLine("Saving disk images and shutting down. Please wait..."); _hardDrive.Save(); + _ethernetController.Shutdown(); } public bool IsExecuting diff --git a/D/UI/AboutBox.Designer.cs b/D/UI/AboutBox.Designer.cs index adcdd55..2febcc1 100644 --- a/D/UI/AboutBox.Designer.cs +++ b/D/UI/AboutBox.Designer.cs @@ -89,9 +89,9 @@ namespace D.UI this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(56, 54); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(235, 13); + this.label3.Size = new System.Drawing.Size(232, 13); this.label3.TabIndex = 2; - this.label3.Text = "(c) 2017, 2018 Living Computers: Museum+Labs"; + this.label3.Text = "(c) 2017-2019 Living Computers: Museum+Labs"; this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // label4 diff --git a/D/UI/ConfigurationDialog.cs b/D/UI/ConfigurationDialog.cs index 9e1e968..756c2f3 100644 --- a/D/UI/ConfigurationDialog.cs +++ b/D/UI/ConfigurationDialog.cs @@ -60,7 +60,7 @@ namespace D.UI { // System Tab MemorySizeComboBox.Items.Clear(); - for (int i = 128; i <= 1024; i+= 128) + for (int i = 128; i <= 768; i+= 128) { MemorySizeComboBox.Items.Add(string.Format("{0}KW", i)); if (i == MemorySize) diff --git a/D/UI/DWindow.cs b/D/UI/DWindow.cs index 25f8eec..17615b9 100644 --- a/D/UI/DWindow.cs +++ b/D/UI/DWindow.cs @@ -315,7 +315,8 @@ namespace D.UI if (configDialog.HostPacketInterfaceName != Configuration.HostPacketInterfaceName) { - MessageBox.Show("Changes to ethernet interface will not take effect until the system is restarted."); + Configuration.HostPacketInterfaceName = configDialog.HostPacketInterfaceName; + _system.EthernetController.HostInterfaceChanged(); } if (configDialog.TODSetMode != Configuration.TODSetMode || @@ -334,8 +335,7 @@ namespace D.UI } } - Configuration.MemorySize = configDialog.MemorySize; - Configuration.HostPacketInterfaceName = configDialog.HostPacketInterfaceName; + Configuration.MemorySize = configDialog.MemorySize; Configuration.ThrottleSpeed = configDialog.ThrottleSpeed; Configuration.DisplayScale = configDialog.DisplayScale; Configuration.SlowPhosphor = configDialog.SlowPhosphor; diff --git a/D/readme.txt b/D/readme.txt index a356026..43d3449 100644 --- a/D/readme.txt +++ b/D/readme.txt @@ -15,7 +15,7 @@ used to refer to any of the above machines. Darkstar currently emulates the following Star hardware: - Standard 8010/1108 Central Processor (CP) with 4KW of microcode store - i8085-based IO Processor (IOP) - - Up to 1MW of main memory + - Up to 768KW of main memory - Bitmapped Display - Keyboard / Mouse - 10, 40, or 80mb hard drives (SA1000 interface) @@ -363,12 +363,8 @@ Each tab is explained in detail in the following subsections. The System Configuration tab provides configuration for three options: - Memory Size (KW): Configures the amount of memory installed in the system, - From 128KW to 1024KW in 128KW increments. This defaults to 768KW. - Changes made here will not take effect until the system is reset. Note - that memory sizes over 768KW (1.5MB) never officially existed on real Star - hardware and may cause issues with some software that isn't prepared for - it. In particular, Interlisp-D releases later than Harmony will crash - after startup. + From 128KW to 768KW in 128KW increments. This defaults to 768KW. + Changes made here will not take effect until the system is reset. - Host ID (MAC Address): Configures the Star's Ethernet MAC Address (also used as the system's Host ID for licensing.) If you have multiple instances of @@ -457,11 +453,10 @@ synopsis of the various commands at your disposal. 6.0 Known Issues ================ -- Interlisp-D releases after Harmony do not run properly. -- The Ethernet hardware has not been thoroughly tested. - Speed throttling is not implemented on Unix platforms. -- SDL is forced to software-rendering mode due to an odd bug that has yet to - be solved. Performance may suffer as a result. +- SDL is forced to software-rendering mode on Unix platformst + due to an odd bug that has yet to be solved. Performance may suffer as a + result. 7.0 Reporting Bugs @@ -553,6 +548,14 @@ https://github.com/flibitijibibo/SDL2-CS. 11.0 Change History =================== -V1.0 +v1.0.0.1 +-------- +- Fixed Ethernet receiver; Ethernet controller now works reliably. +- Cleaned up shutdown code, made hard disk image saving more robust in the face + of failure +- Removed 1MW memory option since it was never a shipping configuration and + causes issues with various Xerox software. + +v1.0 ---- Initial release.