diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/App.axaml.cs b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/App.axaml.cs
index 8564e767c..544eb30fb 100644
--- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/App.axaml.cs
+++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/App.axaml.cs
@@ -66,10 +66,10 @@ public partial class App : Application
public bool IsHostAppReady => _hostApp != null;
///
- /// Optional async runner invoked from
- /// when an automated startup has been requested (e.g. via URL query parameters in the Browser host).
- /// Running automation from there guarantees the Avalonia view tree has been loaded and rendered
- /// at least once, so subsequent InvalidateVisual calls actually trigger paint.
+ /// Optional async runner invoked from
+ /// when an automated startup has been requested (e.g. via URL query parameters in the Browser host).
+ /// Running automation from there guarantees the Avalonia view tree has been loaded and rendered
+ /// at least once, so subsequent InvalidateVisual calls actually trigger paint.
///
public Func? AutomatedStartupRunner => _automatedStartupRunner;
@@ -119,7 +119,7 @@ public partial class App : Application
/// Optional callback to remove a script by file name (browser: from localStorage).
/// Optional callback to seed bundled example scripts into the host's script storage.
///
- /// Optional automated-startup delegate invoked from
+ /// Optional automated-startup delegate invoked from
/// after the view tree has been loaded. When non-null, the UI's default system selection is
/// suppressed and the runner is invoked instead — used by the Browser host for URL-driven
/// automation, by Desktop for CLI-driven automation, and as a no-op (_ => Task.CompletedTask)
@@ -456,11 +456,25 @@ private void InitializeHostApp()
_scriptingConfig);
// Wire Lua scripting engine (NoScriptingEngine used when null, e.g. in WASM)
- _hostApp.SetScriptingEngine(_scriptingEngine ?? new NoScriptingEngine());
-
- // Signal waiters (e.g. automated startup on a background thread) that HostApp is ready.
- // TrySetResult guarantees all writes above are visible to awaiters before they resume.
- s_hostAppReady.TrySetResult(_hostApp);
+ _hostApp.SetScriptingEngine(_scriptingEngine ?? new NoScriptingEngine());
+
+ // Normal startup should have a selected system before the first view layout. Otherwise
+ // bindings that size the emulator display evaluate with no selected system and briefly
+ // fall back to 320x200 before MainView.Loaded selects the default system. Automated
+ // startup still runs after the view is loaded because it may need a rendered tree.
+ if (_automatedStartupRunner == null)
+ {
+ _logger.LogInformation(
+ "Selecting default system '{DefaultEmulator}' before Avalonia view creation",
+ _emulatorConfig.DefaultEmulator);
+#pragma warning disable VSTHRD002
+ _hostApp.SelectSystem(_emulatorConfig.DefaultEmulator).GetAwaiter().GetResult();
+#pragma warning restore VSTHRD002
+ }
+
+ // Signal waiters (e.g. automated startup on a background thread) that HostApp is ready.
+ // TrySetResult guarantees all writes above are visible to awaiters before they resume.
+ s_hostAppReady.TrySetResult(_hostApp);
}
catch (Exception ex)
{
diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/MainViewModel.cs b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/MainViewModel.cs
index 91270e51a..76310f7f2 100644
--- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/MainViewModel.cs
+++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/MainViewModel.cs
@@ -872,11 +872,9 @@ public MainViewModel(
.Select(config => GetAudioToolTip(config))
.ToProperty(this, x => x.AudioTooltip);
- // A host-config update can rebuild the selected system's temporary instance and thereby
- // change its screen dimensions (e.g. ROMs downloaded during automated startup make the C64
- // buildable, so CurrentSystemScreenInfo goes from the default fallback to the real size).
- // The system/variant identity does not change in that case, so refresh the emulator display
- // size here too — otherwise the display container keeps the default 320x200 size.
+ // A host-config update can rebuild the selected system's temporary instance or change the
+ // config-derived pre-build screen dimensions. The system/variant identity does not change in
+ // that case, so refresh the emulator display size here too.
_hostApp
.WhenAnyValue(x => x.CurrentHostSystemConfig)
.Subscribe(_ =>
@@ -1245,8 +1243,11 @@ private async Task SetDefaultSystemSelectionAsync()
return;
}
- _logger.LogInformation($"Setting default system '{_emulatorConfig.DefaultEmulator}' during MainViewModel initialization");
- await HostApp.SelectSystem(_emulatorConfig.DefaultEmulator);
+ if (HostApp.SelectedSystemName != _emulatorConfig.DefaultEmulator)
+ {
+ _logger.LogInformation($"Setting default system '{_emulatorConfig.DefaultEmulator}' during MainViewModel initialization");
+ await HostApp.SelectSystem(_emulatorConfig.DefaultEmulator);
+ }
}
///
diff --git a/src/libraries/Highbyte.DotNet6502.Systems.Commodore64/C64SystemConfigurerCore.cs b/src/libraries/Highbyte.DotNet6502.Systems.Commodore64/C64SystemConfigurerCore.cs
index ef487ea84..435d0b159 100644
--- a/src/libraries/Highbyte.DotNet6502.Systems.Commodore64/C64SystemConfigurerCore.cs
+++ b/src/libraries/Highbyte.DotNet6502.Systems.Commodore64/C64SystemConfigurerCore.cs
@@ -3,6 +3,7 @@
using Highbyte.DotNet6502.Systems.Commodore64.Cartridge.SwiftLink;
using Highbyte.DotNet6502.Systems.Commodore64.Transport;
using Highbyte.DotNet6502.Systems.Commodore64.Models;
+using Highbyte.DotNet6502.Systems.Commodore64.Video;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
@@ -65,6 +66,14 @@ public virtual IEnumerable GetUserContentDirectories()
public Task> GetConfigurationVariants(ISystemConfig systemConfig)
=> Task.FromResult(C64ModelInventory.C64Models.Keys.ToList());
+ public IScreen? GetScreenInfo(string configurationVariant, ISystemConfig systemConfig)
+ {
+ if (!C64ModelInventory.C64Models.TryGetValue(configurationVariant, out var c64Model))
+ return null;
+
+ return new Vic2Screen(c64Model.Vic2Models.First(), c64Model.CPUFrequencyHz);
+ }
+
///
/// Creates a fresh host config via the supplied factory and binds it from the matching
/// section. Hosts that store config elsewhere (e.g. browser
diff --git a/src/libraries/Highbyte.DotNet6502.Systems.Generic/GenericComputerSystemConfigurerCore.cs b/src/libraries/Highbyte.DotNet6502.Systems.Generic/GenericComputerSystemConfigurerCore.cs
index e59a07ad1..af16dd197 100644
--- a/src/libraries/Highbyte.DotNet6502.Systems.Generic/GenericComputerSystemConfigurerCore.cs
+++ b/src/libraries/Highbyte.DotNet6502.Systems.Generic/GenericComputerSystemConfigurerCore.cs
@@ -55,6 +55,22 @@ protected GenericComputerSystemConfigurerCore(
public virtual Task> GetConfigurationVariants(ISystemConfig systemConfig)
=> Task.FromResult(((GenericComputerSystemConfig)systemConfig).ExamplePrograms.Keys.ToList());
+ public IScreen? GetScreenInfo(string configurationVariant, ISystemConfig systemConfig)
+ {
+ var genericSystemConfig = (GenericComputerSystemConfig)systemConfig;
+ var genericComputerConfig = GenericComputerExampleConfigs.GetExampleConfig(configurationVariant, genericSystemConfig);
+ var screen = genericComputerConfig.Memory.Screen;
+ const int characterWidth = 8;
+ const int characterHeight = 8;
+
+ return new ScreenInfo(
+ screen.Cols * characterWidth,
+ screen.Rows * characterHeight,
+ (screen.Cols + (2 * screen.BorderCols)) * characterWidth,
+ (screen.Rows + (2 * screen.BorderRows)) * characterHeight,
+ genericComputerConfig.ScreenRefreshFrequencyHz);
+ }
+
///
/// Creates a fresh host config via the supplied factory and binds it from the matching
/// section. Hosts that store config elsewhere (e.g. browser
diff --git a/src/libraries/Highbyte.DotNet6502.Systems.Vic20/Vic20SystemConfigurerCore.cs b/src/libraries/Highbyte.DotNet6502.Systems.Vic20/Vic20SystemConfigurerCore.cs
index 8e1228e80..e5fe200d1 100644
--- a/src/libraries/Highbyte.DotNet6502.Systems.Vic20/Vic20SystemConfigurerCore.cs
+++ b/src/libraries/Highbyte.DotNet6502.Systems.Vic20/Vic20SystemConfigurerCore.cs
@@ -45,6 +45,17 @@ public virtual IEnumerable GetUserContentDirectories()
public virtual Task> GetConfigurationVariants(ISystemConfig systemConfig)
=> Task.FromResult(new List { VariantNtsc, VariantPal });
+ public IScreen? GetScreenInfo(string configurationVariant, ISystemConfig systemConfig)
+ {
+ var vic20Config = BuildVic20ConfigForVariant(configurationVariant);
+ return new ScreenInfo(
+ Vic20Config.DrawableAreaWidth,
+ Vic20Config.DrawableAreaHeight,
+ vic20Config.MaxVisibleWidth,
+ vic20Config.MaxVisibleHeight,
+ vic20Config.ScreenRefreshFrequencyHz);
+ }
+
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Host config binding is limited to known application config models that are rooted by the host application.")]
public virtual Task GetNewHostSystemConfig()
{
diff --git a/src/libraries/Highbyte.DotNet6502.Systems/HostApp.cs b/src/libraries/Highbyte.DotNet6502.Systems/HostApp.cs
index df7d20989..5393e6af1 100644
--- a/src/libraries/Highbyte.DotNet6502.Systems/HostApp.cs
+++ b/src/libraries/Highbyte.DotNet6502.Systems/HostApp.cs
@@ -73,15 +73,19 @@ public List AllSelectedSystemConfigurationVariants
}
set
{
- _allSelectedSystemConfigurationVariants = value;
- OnAfterAllSystemConfigurationVariantsChanged();
+ SetAllSelectedSystemConfigurationVariants(value);
}
}
private SystemRunner? _systemRunner = null;
public SystemRunner? CurrentSystemRunner => _systemRunner;
public ISystem? CurrentRunningSystem => _systemRunner?.System;
- public IScreen? CurrentSystemScreenInfo => _systemRunner != null ? _systemRunner?.System.Screen : _selectedSystemTemporary?.Screen;
+ public IScreen? CurrentSystemScreenInfo => _systemRunner != null
+ ? _systemRunner.System.Screen
+ : _selectedSystemTemporary?.Screen
+ ?? (_currentHostSystemConfig != null
+ ? _systemList.GetScreenInfo(_selectedSystemName, _selectedSystemConfigurationVariant, _currentHostSystemConfig)
+ : null);
public EmulatorState EmulatorState
{
get
@@ -437,19 +441,16 @@ public async Task SelectSystem(string systemName)
_selectedSystemName = systemName;
CurrentHostSystemConfig = await _systemList.GetHostSystemConfig(_selectedSystemName);
- OnAfterSelectedSystemChanged();
-
- SelectedSystemChanged?.Invoke(this, EventArgs.Empty);
- _scriptingEngine.InvokeEvent("on_system_selected", SelectedSystemName);
-
// If system changed, make sure any state regarding the system variant is also in sync
if (systemChanged)
{
- AllSelectedSystemConfigurationVariants = await _systemList.GetSystemConfigurationVariants(systemName, CurrentHostSystemConfig);
+ SetAllSelectedSystemConfigurationVariants(
+ await _systemList.GetSystemConfigurationVariants(systemName, CurrentHostSystemConfig),
+ notify: false);
if (_allSelectedSystemConfigurationVariants.Count > 0)
{
- var selectedSystemConfigurationVariant = _allSelectedSystemConfigurationVariants.First();
- await SelectSystemConfigurationVariant(selectedSystemConfigurationVariant);
+ _selectedSystemConfigurationVariant = _allSelectedSystemConfigurationVariants.First();
+ await UpdateSelectedSystemTemporary();
}
else
{
@@ -466,10 +467,26 @@ public async Task SelectSystem(string systemName)
_selectedSystemTemporary = null;
}
}
+
+ OnAfterAllSystemConfigurationVariantsChanged();
+ OnAfterSelectedSystemVariantChanged();
+ OnAfterSelectedSystemChanged();
+
+ SelectedSystemVariantChanged?.Invoke(this, EventArgs.Empty);
+ SelectedSystemChanged?.Invoke(this, EventArgs.Empty);
+ _scriptingEngine.InvokeEvent("on_variant_selected", SelectedSystemConfigurationVariant);
+ _scriptingEngine.InvokeEvent("on_system_selected", SelectedSystemName);
}
public virtual void OnAfterAllSystemConfigurationVariantsChanged() { }
+ private void SetAllSelectedSystemConfigurationVariants(List variants, bool notify = true)
+ {
+ _allSelectedSystemConfigurationVariants = variants;
+ if (notify)
+ OnAfterAllSystemConfigurationVariantsChanged();
+ }
+
public async Task SelectSystemConfigurationVariant(string configurationVariant)
{
if (EmulatorState != EmulatorState.Uninitialized)
@@ -479,7 +496,16 @@ public async Task SelectSystemConfigurationVariant(string configurationVariant)
throw new DotNet6502Exception($"System configuration variant not found: {configurationVariant}");
_selectedSystemConfigurationVariant = configurationVariant;
+ await UpdateSelectedSystemTemporary();
+
+ OnAfterSelectedSystemVariantChanged();
+ SelectedSystemVariantChanged?.Invoke(this, EventArgs.Empty);
+ _scriptingEngine.InvokeEvent("on_variant_selected", SelectedSystemConfigurationVariant);
+ }
+
+ private async Task UpdateSelectedSystemTemporary()
+ {
// Pre-create a temporary variable to contain the system if it is valid.
// This is useful if the system has not been started yet, but client requests the system object.
if (CurrentHostSystemConfig.IsValid(out _))
@@ -490,11 +516,6 @@ public async Task SelectSystemConfigurationVariant(string configurationVariant)
{
_selectedSystemTemporary = null;
}
-
- OnAfterSelectedSystemVariantChanged();
-
- SelectedSystemVariantChanged?.Invoke(this, EventArgs.Empty);
- _scriptingEngine.InvokeEvent("on_variant_selected", SelectedSystemConfigurationVariant);
}
public virtual void OnAfterSelectedSystemChanged() { }
diff --git a/src/libraries/Highbyte.DotNet6502.Systems/ISystemConfigurer.cs b/src/libraries/Highbyte.DotNet6502.Systems/ISystemConfigurer.cs
index a11c8a7a0..4a37b3d2d 100644
--- a/src/libraries/Highbyte.DotNet6502.Systems/ISystemConfigurer.cs
+++ b/src/libraries/Highbyte.DotNet6502.Systems/ISystemConfigurer.cs
@@ -4,6 +4,7 @@ public interface ISystemConfigurer
{
public string SystemName { get; }
public Task> GetConfigurationVariants(ISystemConfig systemConfig);
+ public IScreen? GetScreenInfo(string configurationVariant, ISystemConfig systemConfig) => null;
public Task BuildSystem(string configurationVariant, ISystemConfig systemConfig);
public Task GetNewHostSystemConfig();
public Task PersistHostSystemConfig(IHostSystemConfig hostSystemConfig);
diff --git a/src/libraries/Highbyte.DotNet6502.Systems/ScreenInfo.cs b/src/libraries/Highbyte.DotNet6502.Systems/ScreenInfo.cs
new file mode 100644
index 000000000..4a4c5fed4
--- /dev/null
+++ b/src/libraries/Highbyte.DotNet6502.Systems/ScreenInfo.cs
@@ -0,0 +1,35 @@
+namespace Highbyte.DotNet6502.Systems;
+
+///
+/// Immutable screen geometry for cases where a host knows the selected system/variant but does
+/// not yet have a built emulator instance. This lets UI code size the emulator display from
+/// configuration-derived dimensions without forcing CPU, memory, ROM, or render setup.
+///
+public sealed class ScreenInfo : IScreen
+{
+ ///
+ /// Creates a screen descriptor using drawable and visible pixel dimensions.
+ ///
+ public ScreenInfo(
+ int drawableAreaWidth,
+ int drawableAreaHeight,
+ int visibleWidth,
+ int visibleHeight,
+ float refreshFrequencyHz)
+ {
+ DrawableAreaWidth = drawableAreaWidth;
+ DrawableAreaHeight = drawableAreaHeight;
+ VisibleWidth = visibleWidth;
+ VisibleHeight = visibleHeight;
+ RefreshFrequencyHz = refreshFrequencyHz;
+ }
+
+ public int DrawableAreaWidth { get; }
+ public int DrawableAreaHeight { get; }
+ public int VisibleWidth { get; }
+ public int VisibleHeight { get; }
+ public bool HasBorder => VisibleWidth > DrawableAreaWidth || VisibleHeight > DrawableAreaHeight;
+ public int VisibleLeftRightBorderWidth => (VisibleWidth - DrawableAreaWidth) / 2;
+ public int VisibleTopBottomBorderHeight => (VisibleHeight - DrawableAreaHeight) / 2;
+ public float RefreshFrequencyHz { get; }
+}
diff --git a/src/libraries/Highbyte.DotNet6502.Systems/SystemList.cs b/src/libraries/Highbyte.DotNet6502.Systems/SystemList.cs
index 55a7de65e..527e05697 100644
--- a/src/libraries/Highbyte.DotNet6502.Systems/SystemList.cs
+++ b/src/libraries/Highbyte.DotNet6502.Systems/SystemList.cs
@@ -89,6 +89,14 @@ public async Task BuildSystem(string systemName, string configurationVa
return system;
}
+ public IScreen? GetScreenInfo(string systemName, string configurationVariant, IHostSystemConfig hostSystemConfig)
+ {
+ if (!Systems.Contains(systemName))
+ throw new DotNet6502Exception($"System does not exist: {systemName}");
+
+ return _systemConfigurers[systemName].GetScreenInfo(configurationVariant, hostSystemConfig.SystemConfig);
+ }
+
public async Task BuildSystemRunner(
string systemName,
string configurationVariant)
diff --git a/tests/Highbyte.DotNet6502.Systems.Tests/HostAppTests.cs b/tests/Highbyte.DotNet6502.Systems.Tests/HostAppTests.cs
index 87a4efae2..7d123ac29 100644
--- a/tests/Highbyte.DotNet6502.Systems.Tests/HostAppTests.cs
+++ b/tests/Highbyte.DotNet6502.Systems.Tests/HostAppTests.cs
@@ -137,6 +137,43 @@ public async Task UpdateHostSystemConfig_WhenConfigBecomesValid_RebuildsTemporar
Assert.NotNull(systemAfterFixup);
}
+ [Fact]
+ public async Task CurrentSystemScreenInfo_WhenSelectedSystemCannotBeBuilt_UsesConfigurerScreenInfo()
+ {
+ // Arrange: select a system, then make config invalid so no temporary system can be built.
+ var testApp = BuildTestHostApp();
+ await testApp.SelectSystem(TestSystem.SystemName);
+ testApp.UpdateHostSystemConfig(new TestHostSystemConfig { TestIsValid = false });
+
+ // Act
+ var screenInfo = testApp.CurrentSystemScreenInfo;
+
+ // Assert
+ Assert.NotNull(screenInfo);
+ Assert.Equal(123, screenInfo.VisibleWidth);
+ Assert.Equal(67, screenInfo.VisibleHeight);
+ }
+
+ [Fact]
+ public async Task SelectSystem_WhenPreviousSystemIsInvalid_UpdatesVariantBeforeSystemChangedNotification()
+ {
+ // Arrange: the first system is selected but cannot be built, so screen info must come from
+ // the selected system/variant rather than from a temporary system instance.
+ var testApp = BuildTestHostApp();
+ await testApp.SelectSystem(TestSystem.SystemName);
+ testApp.UpdateHostSystemConfig(new TestHostSystemConfig { TestIsValid = false });
+ testApp.ReadScreenInfoOnSelectedSystemChanged = true;
+
+ // Act: switch to a system whose GetScreenInfo rejects stale variants.
+ await testApp.SelectSystem(TestSystem2.SystemName);
+
+ // Assert: reading screen info during the selected-system notification saw the new variant.
+ Assert.Equal(TestSystem2Configurer.Variant, testApp.SelectedSystemConfigurationVariant);
+ Assert.NotNull(testApp.ScreenInfoReadDuringSelectedSystemChanged);
+ Assert.Equal(246, testApp.ScreenInfoReadDuringSelectedSystemChanged.VisibleWidth);
+ Assert.Equal(134, testApp.ScreenInfoReadDuringSelectedSystemChanged.VisibleHeight);
+ }
+
public class TestHostApp : HostApp
{
public TestHostApp(
@@ -144,6 +181,17 @@ SystemList systemList
) : base("TestHost", systemList, new NullLoggerFactory())
{
}
+
+ public bool ReadScreenInfoOnSelectedSystemChanged { get; set; }
+ public IScreen? ScreenInfoReadDuringSelectedSystemChanged { get; private set; }
+
+ public override void OnAfterSelectedSystemChanged()
+ {
+ if (ReadScreenInfoOnSelectedSystemChanged)
+ ScreenInfoReadDuringSelectedSystemChanged = CurrentSystemScreenInfo;
+
+ base.OnAfterSelectedSystemChanged();
+ }
}
private TestHostApp BuildTestHostApp(bool setContexts = true, bool initContexts = true)
diff --git a/tests/Highbyte.DotNet6502.Systems.Tests/SystemConfigurerTests.cs b/tests/Highbyte.DotNet6502.Systems.Tests/SystemConfigurerTests.cs
index b06a8b664..12cecb978 100644
--- a/tests/Highbyte.DotNet6502.Systems.Tests/SystemConfigurerTests.cs
+++ b/tests/Highbyte.DotNet6502.Systems.Tests/SystemConfigurerTests.cs
@@ -23,6 +23,9 @@ public class TestSystemConfigurer : ISystemConfigurer
public string SystemName => TestSystem.SystemName;
public Task> GetConfigurationVariants(ISystemConfig systemConfig) => Task.FromResult(new List { "DEFAULT" });
+ public IScreen? GetScreenInfo(string configurationVariant, ISystemConfig systemConfig)
+ => new ScreenInfo(100, 50, 123, 67, 60);
+
public Task GetNewHostSystemConfig()
{
return Task.FromResult(new TestHostSystemConfig());
@@ -51,7 +54,13 @@ IHostSystemConfig hostSystemConfig
public class TestSystem2Configurer : ISystemConfigurer
{
public string SystemName => TestSystem2.SystemName;
- public Task> GetConfigurationVariants(ISystemConfig systemConfig) => Task.FromResult(new List { "DEFAULT" });
+ public const string Variant = "TEST2";
+ public Task> GetConfigurationVariants(ISystemConfig systemConfig) => Task.FromResult(new List { Variant });
+
+ public IScreen? GetScreenInfo(string configurationVariant, ISystemConfig systemConfig)
+ => configurationVariant == Variant
+ ? new ScreenInfo(200, 100, 246, 134, 60)
+ : throw new ArgumentException($"Unexpected variant '{configurationVariant}'.", nameof(configurationVariant));
public Task GetNewHostSystemConfig()
{
diff --git a/tests/Highbyte.DotNet6502.Systems.Tests/SystemRunnerTests.cs b/tests/Highbyte.DotNet6502.Systems.Tests/SystemRunnerTests.cs
index 4d8891af3..8f9a732b7 100644
--- a/tests/Highbyte.DotNet6502.Systems.Tests/SystemRunnerTests.cs
+++ b/tests/Highbyte.DotNet6502.Systems.Tests/SystemRunnerTests.cs
@@ -77,7 +77,7 @@ public class TestSystem : ISystem
public Memory Mem => throw new NotImplementedException();
- public IScreen Screen => throw new NotImplementedException();
+ public IScreen Screen => new ScreenInfo(100, 50, 123, 67, 60);
public bool InstrumentationEnabled { get; set; } = false;
@@ -112,7 +112,7 @@ public class TestSystem2 : ISystem
public Memory Mem => throw new NotImplementedException();
- public IScreen Screen => throw new NotImplementedException();
+ public IScreen Screen => new ScreenInfo(200, 100, 246, 134, 60);
public bool InstrumentationEnabled { get; set; } = false;