Beeper implemented but has noise on the port - to fix
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
using System.Diagnostics;
|
using Core.Interfaces;
|
||||||
using Core.Interfaces;
|
using System.Diagnostics;
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
|
||||||
namespace Core.Io
|
namespace Core.Io
|
||||||
{
|
{
|
||||||
public class IO_Bus
|
public class IO_Bus
|
||||||
{
|
{
|
||||||
public byte BorderColorIndex { get; private set; } = 7; // 7 is White
|
public byte BorderColorIndex { get; private set; } = 7;
|
||||||
|
public bool BeeperState { get; private set; } = false;
|
||||||
// 8 rows representing the Spectrum keyboard matrix. Default to 0xFF (unpressed).
|
|
||||||
public byte[] KeyboardRows = new byte[8] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
public byte[] KeyboardRows = new byte[8] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
public byte ReadPort(ushort portAddress)
|
public byte ReadPort(ushort portAddress)
|
||||||
@@ -42,11 +42,13 @@ namespace Core.Io
|
|||||||
// The ULA intercepts any write to an even port address
|
// The ULA intercepts any write to an even port address
|
||||||
if ((portAddress & 0x01) == 0)
|
if ((portAddress & 0x01) == 0)
|
||||||
{
|
{
|
||||||
// The bottom 3 bits (0-2) define the border color!
|
// The bottom 3 bits (0-2) define the border color
|
||||||
BorderColorIndex = (byte)(portValue & 0x07);
|
BorderColorIndex = (byte)(portValue & 0x07);
|
||||||
|
|
||||||
// (Bits 3 and 4 handle the cassette MIC output and the internal speaker,
|
// Bit 4 controls the speaker
|
||||||
// which we will need when we start playing audio!)
|
BeeperState = (portValue & 0x10) != 0;
|
||||||
|
|
||||||
|
// Bit 3 handles the cassette MIC output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
41
Desktop/BeeperDevice.cs
Normal file
41
Desktop/BeeperDevice.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using NAudio.Wave;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Desktop
|
||||||
|
{
|
||||||
|
public class BeeperDevice
|
||||||
|
{
|
||||||
|
private WaveOutEvent _waveOut;
|
||||||
|
private BufferedWaveProvider _buffer;
|
||||||
|
|
||||||
|
public BeeperDevice()
|
||||||
|
{
|
||||||
|
_waveOut = new WaveOutEvent();
|
||||||
|
_waveOut.DesiredLatency = 50; // 100ms latency to prevent buffer stutter
|
||||||
|
|
||||||
|
// 44.1kHz, 1 channel (Mono), Float format
|
||||||
|
_buffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 1));
|
||||||
|
_buffer.BufferDuration = TimeSpan.FromSeconds(1);
|
||||||
|
_buffer.DiscardOnBufferOverflow = true;
|
||||||
|
|
||||||
|
_waveOut.Init(_buffer);
|
||||||
|
_waveOut.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSample(bool isHigh)
|
||||||
|
{
|
||||||
|
//Buffer overrun check and dump
|
||||||
|
if (_buffer.BufferedDuration.TotalMilliseconds > 100)
|
||||||
|
{
|
||||||
|
_buffer.ClearBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the boolean into a physical sound wave (-0.2 or +0.2)
|
||||||
|
float sampleValue = isHigh ? 0.2f : -0.2f;
|
||||||
|
|
||||||
|
// Convert the float to bytes and drop it in the pipe
|
||||||
|
byte[] bytes = BitConverter.GetBytes(sampleValue);
|
||||||
|
_buffer.AddSamples(bytes, 0, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="NAudio" Version="2.3.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Core\Core.csproj" />
|
<ProjectReference Include="..\Core\Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Desktop
|
|||||||
private ULA _ula = null!;
|
private ULA _ula = null!;
|
||||||
private TapManager _tapManager = null!;
|
private TapManager _tapManager = null!;
|
||||||
private DebuggerForm? _debugger = null;
|
private DebuggerForm? _debugger = null;
|
||||||
|
private BeeperDevice _beeper = null!;
|
||||||
private string _baseTitle = "";
|
private string _baseTitle = "";
|
||||||
private bool _isRunning = false;
|
private bool _isRunning = false;
|
||||||
private bool _isPaused = false;
|
private bool _isPaused = false;
|
||||||
@@ -41,6 +42,7 @@ namespace Desktop
|
|||||||
_memoryBus = new MemoryBus();
|
_memoryBus = new MemoryBus();
|
||||||
_simpleIoBus = new IO_Bus();
|
_simpleIoBus = new IO_Bus();
|
||||||
_ula = new ULA(_memoryBus, _simpleIoBus);
|
_ula = new ULA(_memoryBus, _simpleIoBus);
|
||||||
|
_beeper = new BeeperDevice();
|
||||||
_tapManager = new TapManager();
|
_tapManager = new TapManager();
|
||||||
_memoryBus.CrapRAMData();
|
_memoryBus.CrapRAMData();
|
||||||
byte[] romData = RomLoader.Load("48.rom");
|
byte[] romData = RomLoader.Load("48.rom");
|
||||||
@@ -70,6 +72,7 @@ namespace Desktop
|
|||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
var fpsStopwatch = Stopwatch.StartNew();
|
var fpsStopwatch = Stopwatch.StartNew();
|
||||||
long scanlineCount = 0;
|
long scanlineCount = 0;
|
||||||
|
long audioSampleCount = 0;
|
||||||
|
|
||||||
while (_isRunning)
|
while (_isRunning)
|
||||||
{
|
{
|
||||||
@@ -90,6 +93,13 @@ namespace Desktop
|
|||||||
// --- Execute Instruction ---
|
// --- Execute Instruction ---
|
||||||
_cpu.Step();
|
_cpu.Step();
|
||||||
|
|
||||||
|
//Process audio at the correct time
|
||||||
|
while (_cpu.TotalTStates >= (long)(audioSampleCount * 79.365))
|
||||||
|
{
|
||||||
|
_beeper.AddSample(_simpleIoBus.BeeperState);
|
||||||
|
audioSampleCount++;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Check for End of Frame ---
|
// --- Check for End of Frame ---
|
||||||
if (_cpu.TotalTStates >= nextScanlineTarget)
|
if (_cpu.TotalTStates >= nextScanlineTarget)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user