diff --git a/Desktop/DebuggerForm.Designer.cs b/Desktop/DebuggerForm.Designer.cs
index ecf17d3..47266da 100644
--- a/Desktop/DebuggerForm.Designer.cs
+++ b/Desktop/DebuggerForm.Designer.cs
@@ -58,6 +58,12 @@
richTextBox1 = new RichTextBox();
button1 = new Button();
CpuRun = new Button();
+ groupBox1 = new GroupBox();
+ lblTone0 = new Label();
+ lblNoise = new Label();
+ lblTone2 = new Label();
+ lblTone1 = new Label();
+ groupBox1.SuspendLayout();
SuspendLayout();
//
// lblAF
@@ -164,10 +170,10 @@
//
// txtMemoryView
//
- txtMemoryView.Location = new Point(110, 100);
+ txtMemoryView.Location = new Point(110, 101);
txtMemoryView.Margin = new Padding(2);
txtMemoryView.Name = "txtMemoryView";
- txtMemoryView.Size = new Size(553, 1118);
+ txtMemoryView.Size = new Size(553, 543);
txtMemoryView.TabIndex = 15;
txtMemoryView.Text = "Memory View Window";
//
@@ -242,7 +248,7 @@
// lblIff1
//
lblIff1.AutoSize = true;
- lblIff1.Location = new Point(709, 514);
+ lblIff1.Location = new Point(11, 533);
lblIff1.Margin = new Padding(4, 0, 4, 0);
lblIff1.Name = "lblIff1";
lblIff1.Size = new Size(45, 25);
@@ -252,7 +258,7 @@
// lblIff2
//
lblIff2.AutoSize = true;
- lblIff2.Location = new Point(709, 572);
+ lblIff2.Location = new Point(11, 586);
lblIff2.Margin = new Padding(4, 0, 4, 0);
lblIff2.Name = "lblIff2";
lblIff2.Size = new Size(45, 25);
@@ -262,12 +268,12 @@
// lblIE
//
lblIE.AutoSize = true;
- lblIE.Location = new Point(710, 462);
+ lblIE.Location = new Point(11, 486);
lblIE.Margin = new Padding(4, 0, 4, 0);
lblIE.Name = "lblIE";
- lblIE.Size = new Size(133, 25);
+ lblIE.Size = new Size(33, 25);
lblIE.TabIndex = 26;
- lblIE.Text = "Interrupt Mode";
+ lblIE.Text = "IM";
//
// btnReset
//
@@ -289,7 +295,7 @@
// lblFrames
//
lblFrames.AutoSize = true;
- lblFrames.Location = new Point(709, 852);
+ lblFrames.Location = new Point(14, 660);
lblFrames.Margin = new Padding(2, 0, 2, 0);
lblFrames.Name = "lblFrames";
lblFrames.Size = new Size(149, 25);
@@ -299,7 +305,7 @@
// lblFPS
//
lblFPS.AutoSize = true;
- lblFPS.Location = new Point(824, 949);
+ lblFPS.Location = new Point(129, 757);
lblFPS.Margin = new Padding(2, 0, 2, 0);
lblFPS.Name = "lblFPS";
lblFPS.Size = new Size(41, 25);
@@ -309,7 +315,7 @@
// lblFrameTime
//
lblFrameTime.AutoSize = true;
- lblFrameTime.Location = new Point(755, 898);
+ lblFrameTime.Location = new Point(60, 706);
lblFrameTime.Margin = new Padding(2, 0, 2, 0);
lblFrameTime.Name = "lblFrameTime";
lblFrameTime.Size = new Size(104, 25);
@@ -319,7 +325,7 @@
// richTextBox1
//
richTextBox1.Enabled = false;
- richTextBox1.Location = new Point(709, 636);
+ richTextBox1.Location = new Point(682, 474);
richTextBox1.Margin = new Padding(4);
richTextBox1.Name = "richTextBox1";
richTextBox1.ReadOnly = true;
@@ -329,7 +335,7 @@
//
// button1
//
- button1.Location = new Point(694, 1030);
+ button1.Location = new Point(1075, 756);
button1.Margin = new Padding(4);
button1.Name = "button1";
button1.Size = new Size(118, 36);
@@ -340,7 +346,7 @@
//
// CpuRun
//
- CpuRun.Location = new Point(694, 1104);
+ CpuRun.Location = new Point(943, 757);
CpuRun.Margin = new Padding(4);
CpuRun.Name = "CpuRun";
CpuRun.Size = new Size(118, 36);
@@ -349,11 +355,61 @@
CpuRun.UseVisualStyleBackColor = true;
CpuRun.Click += CpuRun_Click;
//
+ // groupBox1
+ //
+ groupBox1.Controls.Add(lblTone1);
+ groupBox1.Controls.Add(lblTone2);
+ groupBox1.Controls.Add(lblNoise);
+ groupBox1.Controls.Add(lblTone0);
+ groupBox1.Location = new Point(266, 658);
+ groupBox1.Name = "groupBox1";
+ groupBox1.Size = new Size(397, 222);
+ groupBox1.TabIndex = 35;
+ groupBox1.TabStop = false;
+ groupBox1.Text = "Audio (SN76489)";
+ //
+ // lblTone0
+ //
+ lblTone0.AutoSize = true;
+ lblTone0.Location = new Point(25, 48);
+ lblTone0.Name = "lblTone0";
+ lblTone0.Size = new Size(59, 25);
+ lblTone0.TabIndex = 0;
+ lblTone0.Text = "Tone0";
+ //
+ // lblNoise
+ //
+ lblNoise.AutoSize = true;
+ lblNoise.Location = new Point(25, 160);
+ lblNoise.Name = "lblNoise";
+ lblNoise.Size = new Size(57, 25);
+ lblNoise.TabIndex = 1;
+ lblNoise.Text = "Noise";
+ //
+ // lblTone2
+ //
+ lblTone2.AutoSize = true;
+ lblTone2.Location = new Point(25, 122);
+ lblTone2.Name = "lblTone2";
+ lblTone2.Size = new Size(59, 25);
+ lblTone2.TabIndex = 2;
+ lblTone2.Text = "Tone2";
+ //
+ // lblTone1
+ //
+ lblTone1.AutoSize = true;
+ lblTone1.Location = new Point(25, 83);
+ lblTone1.Name = "lblTone1";
+ lblTone1.Size = new Size(59, 25);
+ lblTone1.TabIndex = 3;
+ lblTone1.Text = "Tone1";
+ //
// DebuggerForm
//
AutoScaleDimensions = new SizeF(10F, 25F);
AutoScaleMode = AutoScaleMode.Font;
- ClientSize = new Size(1206, 1238);
+ ClientSize = new Size(1206, 892);
+ Controls.Add(groupBox1);
Controls.Add(CpuRun);
Controls.Add(button1);
Controls.Add(richTextBox1);
@@ -385,6 +441,8 @@
Margin = new Padding(2);
Name = "DebuggerForm";
Text = "Debugger";
+ groupBox1.ResumeLayout(false);
+ groupBox1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
@@ -420,6 +478,11 @@
private Button button1;
private Button CpuRun;
public System.Windows.Forms.Timer uiUpdateTimer;
+ private GroupBox groupBox1;
+ private Label lblTone1;
+ private Label lblTone2;
+ private Label lblNoise;
+ private Label lblTone0;
//private TextBox textBox4;
}
}
\ No newline at end of file
diff --git a/Desktop/DebuggerForm.cs b/Desktop/DebuggerForm.cs
index e7b9123..2e934d7 100644
--- a/Desktop/DebuggerForm.cs
+++ b/Desktop/DebuggerForm.cs
@@ -1,6 +1,8 @@
using System;
+using System.Reflection.PortableExecutable;
using System.Text;
using System.Windows.Forms;
+using Core.Audio;
using Core.Cpu;
using Core.Memory;
@@ -100,7 +102,7 @@ namespace Desktop
lblIY.Text = $"IY: {_cpu.IY.Word:X4}";
lblIff1.Text = $"IFF1: {_cpu.IFF1}";
lblIff2.Text = $"IFF2: {_cpu.IFF2}";
- lblIE.Text = $"Interrupt Mode: {_cpu.InterruptMode}";
+ lblIE.Text = $"IM: {_cpu.InterruptMode}";
lblFlags.Text = $"Flags: {_cpu.GetFlagsString()}";
lblTStates.Text = $"T-States: {_cpu.TotalTStates}";
lblFrames.Text = $"Frames Rendered: {_mainForm.TotalFrameCount}";
@@ -109,11 +111,23 @@ namespace Desktop
UpdateMemoryView();
UpdateStackView();
UpdateDisassemblyView();
+ // --- AUDIO REGISTERS ---
+ // Use _mainForm to access the Machine, and then grab the AudioProcessor!
+ if (_mainForm._machine != null && _mainForm._machine.AudioProcessor != null)
+ {
+ ushort[] apuRegs = _mainForm._machine.AudioProcessor.Registers;
+
+ lblTone0.Text = $"Tone 0: 0x{apuRegs[0]:X4} (Vol: 0x{apuRegs[1]:X1})";
+ lblTone1.Text = $"Tone 1: 0x{apuRegs[2]:X4} (Vol: 0x{apuRegs[3]:X1})";
+ lblTone2.Text = $"Tone 2: 0x{apuRegs[4]:X4} (Vol: 0x{apuRegs[5]:X1})";
+
+ lblNoise.Text = $"Noise : 0x{apuRegs[6]:X1} (Vol: 0x{apuRegs[7]:X1})";
+ }
}
private void UpdateMemoryView()
{
- int count = 40;
+ int count = 20;
// Try to parse the hex string the user typed in
if (!ushort.TryParse(txtMemoryStart.Text, System.Globalization.NumberStyles.HexNumber, null, out ushort startAddress))
{
diff --git a/Desktop/DebuggerForm.resx b/Desktop/DebuggerForm.resx
index 7ac8c1e..cd73f8b 100644
--- a/Desktop/DebuggerForm.resx
+++ b/Desktop/DebuggerForm.resx
@@ -120,4 +120,7 @@
17, 17
+
+ 47
+
\ No newline at end of file
diff --git a/Desktop/Desktop.csproj b/Desktop/Desktop.csproj
index 999caf6..9b6c28d 100644
--- a/Desktop/Desktop.csproj
+++ b/Desktop/Desktop.csproj
@@ -343,6 +343,7 @@
+
diff --git a/Desktop/Form1.Designer.cs b/Desktop/Form1.Designer.cs
index 9e9b85d..fa9b97c 100644
--- a/Desktop/Form1.Designer.cs
+++ b/Desktop/Form1.Designer.cs
@@ -139,6 +139,7 @@
Margin = new Padding(4);
Name = "ParsonsForm1";
Text = "Form1";
+ FormClosing += ParsonsForm1_FormClosing;
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
diff --git a/Desktop/Form1.cs b/Desktop/Form1.cs
index 36b15ba..d6923f1 100644
--- a/Desktop/Form1.cs
+++ b/Desktop/Form1.cs
@@ -6,14 +6,16 @@ using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Core;
+using Desktop.Audio;
namespace Desktop
{
public partial class ParsonsForm1 : Form
{
- private SmsMachine _machine = null!;
+ public SmsMachine _machine = null!;
private DebuggerForm _debugger;
private Bitmap _screenBitmap = new Bitmap(256, 192, PixelFormat.Format32bppArgb);
+ private NAudioPlayer _audioPlayer;
private Task _emulatorTask;
private double TargetFrameTime = 16.667f;
public int TotalFrameCount = 0;
@@ -34,6 +36,8 @@ namespace Desktop
InitializeComponent();
this.Text = $"Parsons Master System 2026 - {_currentRomName}";
_machine = new SmsMachine();
+ _audioPlayer = new NAudioPlayer();
+ _machine.AudioProcessor.AudioDevice = _audioPlayer;
PopulateIncludedRomsMenu();
@@ -157,7 +161,8 @@ namespace Desktop
framesThisSecond = 0;
lastFpsUpdate = currentTime;
- BeginInvoke((System.Windows.Forms.MethodInvoker)delegate {
+ BeginInvoke((System.Windows.Forms.MethodInvoker)delegate
+ {
this.Text = $"Parsons Master System - {_currentRomName} [FPS/FT: {FramesPerSecond:F0}/{FrameTime:F1}]";
});
}
@@ -299,5 +304,11 @@ namespace Desktop
_machine.IoBus.Joypad1Keyboard |= bitMask; // Target Keyboard!
}
}
+
+ private void ParsonsForm1_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ IsRunning = false;
+ _audioPlayer?.Stop();
+ }
}
}
diff --git a/Desktop/NAudioPlayer.cs b/Desktop/NAudioPlayer.cs
new file mode 100644
index 0000000..aaf4c2e
--- /dev/null
+++ b/Desktop/NAudioPlayer.cs
@@ -0,0 +1,49 @@
+using System;
+using Core.Interfaces;
+using Microsoft.VisualBasic;
+using NAudio.Wave;
+
+namespace Desktop.Audio // Change this to match your project's namespace
+{
+ public class NAudioPlayer : IAudioDevice
+ {
+ private WaveOutEvent _waveOut;
+ private BufferedWaveProvider _buffer;
+
+ public NAudioPlayer()
+ {
+ // Set up the audio format: 44100 Hz, 32-bit IEEE float, 1 channel (Mono)
+ WaveFormat format = WaveFormat.CreateIeeeFloatWaveFormat(44100, 1);
+
+ _buffer = new BufferedWaveProvider(format);
+
+ // CRITICAL FOR EMULATORS:
+ // If the emulator runs slightly too fast, the audio buffer will fill up
+ // and the sound will lag behind the gameplay. Discarding overflow keeps it synced!
+ _buffer.DiscardOnBufferOverflow = true;
+
+ _waveOut = new WaveOutEvent();
+
+ // 100ms latency is a great sweet spot for WinForms emulators.
+ // Too low = crackling audio. Too high = delayed sound effects.
+ _waveOut.DesiredLatency = 100;
+ _waveOut.Init(_buffer);
+ _waveOut.Play();
+ }
+
+ public void AddSample(float sample)
+ {
+ // Convert the float (-1.0f to 1.0f) into 4 raw bytes
+ byte[] sampleBytes = BitConverter.GetBytes(sample);
+
+ // Push the 4 bytes to the sound card buffer!
+ _buffer.AddSamples(sampleBytes, 0, 4);
+ }
+
+ public void Stop()
+ {
+ _waveOut?.Stop();
+ _waveOut?.Dispose();
+ }
+ }
+}
\ No newline at end of file