AppleII - make clock registers deterministic if needed
also don't state monochrome (non-sync setting? todo: verify)
This commit is contained in:
parent
b730af7b73
commit
13456e51bf
|
@ -21,6 +21,8 @@ namespace Jellyfish.Virtu
|
|||
private RingRegister _clockRegister;
|
||||
private RingRegister _comparisonRegister;
|
||||
|
||||
public Func<DateTime> FrontendTimeCallback;
|
||||
|
||||
public NoSlotClock(Video video)
|
||||
{
|
||||
_video = video;
|
||||
|
@ -117,7 +119,7 @@ namespace Jellyfish.Virtu
|
|||
private void PopulateClockRegister()
|
||||
{
|
||||
// all values are in packed BCD format (4 bits per decimal digit)
|
||||
var now = DateTime.Now;
|
||||
var now = FrontendTimeCallback();
|
||||
|
||||
int centisecond = now.Millisecond / 10; // 00-99
|
||||
_clockRegister.WriteNibble(centisecond % 10);
|
||||
|
|
|
@ -121,7 +121,8 @@ namespace Jellyfish.Virtu
|
|||
ser.Sync(nameof(_vLineLeaveVBlank), ref _vLineLeaveVBlank);
|
||||
ser.Sync(nameof(_charSet), ref _charSet, false);
|
||||
ser.Sync(nameof(_isCellDirty), ref _isCellDirty, false);
|
||||
ser.Sync(nameof(_isMonochrome), ref _isMonochrome);
|
||||
//ser.Sync(nameof(_isMonochrome), ref _isMonochrome);
|
||||
//TODO: does this affect sync?
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
|
|
Binary file not shown.
|
@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
|
||||
public string SystemId => VSystemID.Raw.AppleII;
|
||||
|
||||
public bool DeterministicEmulation => true;
|
||||
public bool DeterministicEmulation { get; }
|
||||
|
||||
public bool FrameAdvance(IController controller, bool render, bool renderSound)
|
||||
{
|
||||
|
|
|
@ -1,24 +1,58 @@
|
|||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.AppleII
|
||||
{
|
||||
public partial class AppleII : ISettable<AppleII.Settings, object>
|
||||
public partial class AppleII : ISettable<AppleII.Settings, AppleII.SyncSettings>
|
||||
{
|
||||
private Settings _settings;
|
||||
private SyncSettings _syncSettings;
|
||||
|
||||
public class Settings
|
||||
{
|
||||
[DisplayName("Monochrome")]
|
||||
[DefaultValue(false)]
|
||||
[Description("Choose a monochrome monitor.")]
|
||||
public bool Monochrome { get; set; }
|
||||
|
||||
public Settings Clone() => (Settings)MemberwiseClone();
|
||||
public Settings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
|
||||
public Settings Clone()
|
||||
=> (Settings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public Settings GetSettings() => _settings.Clone();
|
||||
public class SyncSettings
|
||||
{
|
||||
[DisplayName("Initial Time")]
|
||||
[Description("Initial time of emulation.")]
|
||||
[DefaultValue(typeof(DateTime), "2010-01-01")]
|
||||
[TypeConverter(typeof(BizDateTimeConverter))]
|
||||
public DateTime InitialTime { get; set; }
|
||||
|
||||
public object GetSyncSettings() => null;
|
||||
[DisplayName("Use Real Time")]
|
||||
[Description("If true, RTC clock will be based off of real time instead of emulated time. Ignored (set to false) when recording a movie.")]
|
||||
[DefaultValue(false)]
|
||||
public bool UseRealTime { get; set; }
|
||||
|
||||
public SyncSettings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
|
||||
public SyncSettings Clone()
|
||||
=> (SyncSettings)MemberwiseClone();
|
||||
|
||||
public static bool NeedsReboot(SyncSettings x, SyncSettings y)
|
||||
=> !DeepEquality.DeepEquals(x, y);
|
||||
}
|
||||
|
||||
public Settings GetSettings()
|
||||
=> _settings.Clone();
|
||||
|
||||
public SyncSettings GetSyncSettings()
|
||||
=> _syncSettings.Clone();
|
||||
|
||||
public PutSettingsDirtyBits PutSettings(Settings o)
|
||||
{
|
||||
|
@ -30,6 +64,11 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
return PutSettingsDirtyBits.None;
|
||||
}
|
||||
|
||||
public PutSettingsDirtyBits PutSyncSettings(object o) => PutSettingsDirtyBits.None;
|
||||
public PutSettingsDirtyBits PutSyncSettings(SyncSettings o)
|
||||
{
|
||||
var ret = SyncSettings.NeedsReboot(_syncSettings, o);
|
||||
_syncSettings = o;
|
||||
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
ser.Sync("CurrentDisk", ref _currentDisk);
|
||||
ser.Sync("WhiteAppleDown", ref Keyboard.WhiteAppleDown);
|
||||
ser.Sync("BlackAppleDown", ref Keyboard.BlackAppleDown);
|
||||
ser.Sync("ClockTime", ref _clockTime);
|
||||
ser.Sync("ClockRemainder", ref _clockRemainder);
|
||||
|
||||
ser.BeginSection("Events");
|
||||
_machine.Events.Sync(ser);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common.CollectionExtensions;
|
||||
|
@ -20,7 +21,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
}
|
||||
|
||||
[CoreConstructor(VSystemID.Raw.AppleII)]
|
||||
public AppleII(CoreLoadParameters<Settings, object> lp)
|
||||
public AppleII(CoreLoadParameters<Settings, SyncSettings> lp)
|
||||
{
|
||||
_romSet = lp.Roms.Select(r => r.RomData).ToList();
|
||||
var ser = new BasicServiceProvider(this);
|
||||
|
@ -35,7 +36,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
_diskIIRom = lp.Comm.CoreFileProvider.GetFirmwareOrThrow(new(SystemId, "DiskII"), "The DiskII firmware is required");
|
||||
|
||||
_machine = new Components(_appleIIRom, _diskIIRom);
|
||||
|
||||
|
||||
// make a writable memory stream cloned from the rom.
|
||||
// for junk.dsk the .dsk is important because it determines the format from that
|
||||
InitDisk();
|
||||
|
@ -46,6 +47,10 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
|
||||
SetupMemoryDomains();
|
||||
PutSettings(lp.Settings ?? new Settings());
|
||||
|
||||
_syncSettings = lp.SyncSettings ?? new SyncSettings();
|
||||
DeterministicEmulation = lp.DeterministicEmulationRequested || !_syncSettings.UseRealTime;
|
||||
InitializeRtc(DeterministicEmulation);
|
||||
}
|
||||
|
||||
private static readonly ControllerDefinition AppleIIController;
|
||||
|
@ -155,6 +160,8 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
_prevPressed = false;
|
||||
}
|
||||
|
||||
AdvanceRtc();
|
||||
|
||||
MachineAdvance(RealButtons.Where(controller.IsPressed));
|
||||
if (IsLagFrame)
|
||||
{
|
||||
|
@ -211,5 +218,38 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
};
|
||||
_machine.Memory.InputCallback = InputCallbacks.Call;
|
||||
}
|
||||
|
||||
private bool _useRealTime;
|
||||
private long _clockTime;
|
||||
private int _clockRemainder;
|
||||
private const int TicksInSecond = 10000000; // DateTime.Ticks uses 100-nanosecond intervals
|
||||
|
||||
private DateTime GetFrontendTime()
|
||||
{
|
||||
if (_useRealTime && DeterministicEmulation)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
return _useRealTime
|
||||
? DateTime.Now
|
||||
: new DateTime(_clockTime * TicksInSecond + (_clockRemainder * TicksInSecond / VsyncNumerator));
|
||||
}
|
||||
|
||||
private void InitializeRtc(bool useRealTime)
|
||||
{
|
||||
_useRealTime = useRealTime;
|
||||
_clockTime = _syncSettings.InitialTime.Ticks / TicksInSecond;
|
||||
_clockRemainder = (int)(_syncSettings.InitialTime.Ticks % TicksInSecond) * VsyncNumerator / TicksInSecond;
|
||||
_machine.NoSlotClock.FrontendTimeCallback = GetFrontendTime;
|
||||
}
|
||||
|
||||
private void AdvanceRtc()
|
||||
{
|
||||
_clockRemainder += VsyncDenominator;
|
||||
if (_clockRemainder >= VsyncNumerator)
|
||||
{
|
||||
_clockRemainder -= VsyncNumerator;
|
||||
_clockTime++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue