diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index b81298264b..10d5eb3aab 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -266,6 +266,7 @@ + diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs index 4bdc9aca30..0096c9af86 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/Datacorder/DatacorderDevice.cs @@ -18,7 +18,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum private SpectrumBase _machine { get; set; } private Z80A _cpu { get; set; } - private Buzzer _buzzer { get; set; } + private IBeeperDevice _buzzer { get; set; } /// /// Default constructor @@ -369,8 +369,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public bool GetEarBit(long cpuCycle) { - - // decide how many cycles worth of data we are capturing long cycles = cpuCycle - _lastCycle; diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/Buzzer.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/Buzzer.cs index 04e5b53222..0e98c67c29 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/Buzzer.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/Buzzer.cs @@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// For the purposes of emulation this devices is locked to a frame /// a list of Pulses is built up over the course of the frame and outputted at the end of the frame /// - public class Buzzer : ISoundProvider + public class Buzzer : ISoundProvider, IBeeperDevice { /// /// Supplied values are right for 48K spectrum @@ -99,6 +99,30 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /* + // set the tstatesperframe + _tStatesPerFrame = tStatesPerFrame; + + // calculate actual refresh rate + double refresh = (double)_machine.ULADevice.ClockSpeed / (double)_tStatesPerFrame; + + // how many samples per frame are expected by ISoundProvider (at 44.1KHz) + _samplesPerFrame = 880;// (int)((double)sampleRate / (double)refresh); + + // set the sample rate + _sampleRate = sampleRate; + + // calculate samples per frame (what ISoundProvider will be expecting at 44100) + //_samplesPerFrame = (int)((double)_tStatesPerFrame / (double)refresh); + + // calculate tstates per sameple + _tStatesPerSample = 79;// _tStatesPerFrame / _samplesPerFrame; + + /* + + + + + // get divisors var divs = from a in Enumerable.Range(2, _tStatesPerFrame / 2) where _tStatesPerFrame % a == 0 @@ -109,8 +133,8 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum // get _samplesPerFrame _samplesPerFrame = _tStatesPerFrame / _tStatesPerSample; - */ - + + */ Pulses = new List(1000); } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/IBeeperDevice.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/IBeeperDevice.cs new file mode 100644 index 0000000000..7367e3948f --- /dev/null +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Hardware/SoundOuput/IBeeperDevice.cs @@ -0,0 +1,24 @@ +using BizHawk.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum +{ + public interface IBeeperDevice + { + void Init(int sampleRate, int tStatesPerFrame); + + void ProcessPulseValue(bool fromTape, bool earPulse); + + void StartFrame(); + + void EndFrame(); + + void SetTapeMode(bool tapeMode); + + void SyncState(Serializer ser); + } +} diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs index a508f9fa8e..d52ac067a2 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.Port.cs @@ -30,6 +30,15 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// /// public abstract void WritePort(ushort port, byte value); + + /// + /// Increments the CPU totalCycles counter by the tStates value specified + /// + /// + public virtual void PortContention(int tStates) + { + CPU.TotalExecutedCycles += tStates; + } } } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs index 444a22a46c..67f26496c0 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/SpectrumBase.cs @@ -55,7 +55,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// /// The spectrum buzzer/beeper /// - public Buzzer BuzzerDevice { get; set; } + public IBeeperDevice BuzzerDevice { get; set; } /// /// Device representing the AY-3-8912 chip found in the 128k and up spectrums diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULABase.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULABase.cs index e10bdd16c0..d4e5144b35 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULABase.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ULABase.cs @@ -445,7 +445,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } //the additional 1 tstate is required to get correct number of bytes to output in ircontention.sna - elapsedTStates = (_tstates + 1 - lastTState); + elapsedTStates = (_tstates + 1 - lastTState) - 1; //It takes 4 tstates to write 1 byte. Or, 2 pixels per t-state. diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Memory.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Memory.cs index f1a63b0b24..bb3f42ac31 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Memory.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.Memory.cs @@ -170,7 +170,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } // update ULA screen buffer if necessary - if ((addr & 49152) == 16384) + if ((addr & 49152) == 16384 && _render) ULADevice.UpdateScreenBuffer(CurrentFrameCycle); } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.cs index 1eb5b96a14..eb1b25aa19 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128K/ZX128.cs @@ -40,7 +40,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum KeyboardDevice = new StandardKeyboard(this); InitJoysticks(joysticks); - //KempstonDevice = new KempstonJoystick(this); TapeDevice = new DatacorderDevice(); TapeDevice.Init(this); diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs index d236edc82e..a7044ca032 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.Memory.cs @@ -310,7 +310,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum } // update ULA screen buffer if necessary - if ((addr & 49152) == 16384) + if ((addr & 49152) == 16384 && _render) ULADevice.UpdateScreenBuffer(CurrentFrameCycle); } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs index 1bc487dd78..9fb6b4db95 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum128KPlus3/ZX128Plus3.cs @@ -40,7 +40,6 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum KeyboardDevice = new StandardKeyboard(this); InitJoysticks(joysticks); - //KempstonDevice = new KempstonJoystick(this); TapeDevice = new DatacorderDevice(); TapeDevice.Init(this); diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs index 0a1efe104e..5812c898c4 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Memory.cs @@ -65,7 +65,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum bank[index] = value; // update ULA screen buffer if necessary - if ((addr & 49152) == 16384) + if ((addr & 49152) == 16384 && _render) ULADevice.UpdateScreenBuffer(CurrentFrameCycle); } diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs index 873fa6a926..2c7db07cbd 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.Port.cs @@ -17,6 +17,11 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { InputRead = true; + // It takes four T states for the Z80 to read a value from an I/O port, or write a value to a port + // (not including added ULA contention) + // The Bizhawk Z80A implementation appears to not consume any T-States for this operation + PortContention(4); + int result = 0xFF; // Check whether the low bit is reset @@ -171,6 +176,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum /// public override void WritePort(ushort port, byte value) { + // It takes four T states for the Z80 to read a value from an I/O port, or write a value to a port + // (not including added ULA contention) + // The Bizhawk Z80A implementation appears to not consume any T-States for this operation + PortContention(4); + + // Check whether the low bit is reset // Technically the ULA should respond to every even I/O address bool lowBitReset = (port & 0x01) == 0; diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.cs index 3affcf59b1..aaf4ffdebd 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/Machine/ZXSpectrum48K/ZX48.cs @@ -32,14 +32,10 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum InitJoysticks(joysticks); - //KempstonDevice = new KempstonJoystick(this); - TapeDevice = new DatacorderDevice(); TapeDevice.Init(this); InitializeMedia(files); - - //TapeDevice.LoadTape(file); } #endregion diff --git a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs index 4656ba6fa2..2af8fbe390 100644 --- a/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs +++ b/BizHawk.Emulation.Cores/Computers/SinclairSpectrum/ZXSpectrum.cs @@ -94,12 +94,12 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum ser.Register(_cpu); ser.Register(_machine.ULADevice); - SoundMixer = new SoundProviderMixer(_machine.BuzzerDevice); + SoundMixer = new SoundProviderMixer((ISoundProvider)_machine.BuzzerDevice); if (_machine.AYDevice != null) SoundMixer.AddSource(_machine.AYDevice); - dcf = new DCFilter(SoundMixer, 256); - ser.Register(dcf); + //dcf = new DCFilter(SoundMixer, 256); + ser.Register(SoundMixer);