diff --git a/Core/Io/ULA.cs b/Core/Io/ULA.cs
index 96afc34..451bbb3 100644
--- a/Core/Io/ULA.cs
+++ b/Core/Io/ULA.cs
@@ -12,6 +12,7 @@ namespace Core.Io
public const int ScreenWidth = 320;
public const int ScreenHeight = 256; // Perfectly cropped size
public int[] FrameBuffer { get; private set; }
+ public int[] FrontBuffer { get; private set; } = new int[ScreenWidth * ScreenHeight];
private int _ulaFrameCount = 0;
@@ -124,5 +125,10 @@ namespace Core.Io
FrameBuffer[rowStartIndex + b] = currentBorderColor;
}
}
+
+ public void CommitFrame()
+ {
+ Array.Copy(FrameBuffer, FrontBuffer, FrameBuffer.Length);
+ }
}
}
\ No newline at end of file
diff --git a/Desktop/48.rom.bak b/Desktop/48.rom.bak
deleted file mode 100644
index ced65a8..0000000
Binary files a/Desktop/48.rom.bak and /dev/null differ
diff --git a/Desktop/DebuggerForm.Designer.cs b/Desktop/DebuggerForm.Designer.cs
index b1fc976..cbcb374 100644
--- a/Desktop/DebuggerForm.Designer.cs
+++ b/Desktop/DebuggerForm.Designer.cs
@@ -38,13 +38,10 @@
lblFlags = new Label();
lblTStates = new Label();
txtMemoryStart = new TextBox();
- btnStep = new Button();
btnRefreshMemory = new Button();
txtMemoryView = new RichTextBox();
lstDisassembly = new ListBox();
lstStack = new ListBox();
- btnExit = new Button();
- saveFileDialog1 = new SaveFileDialog();
label1 = new Label();
txtBreakpoint = new TextBox();
label2 = new Label();
@@ -151,17 +148,6 @@
txtMemoryStart.TextAlign = HorizontalAlignment.Center;
txtMemoryStart.TextChanged += btnRefreshMemory_Click;
//
- // btnStep
- //
- btnStep.Location = new Point(6, 418);
- btnStep.Margin = new Padding(2);
- btnStep.Name = "btnStep";
- btnStep.Size = new Size(90, 27);
- btnStep.TabIndex = 12;
- btnStep.Text = "Step";
- btnStep.UseVisualStyleBackColor = true;
- btnStep.Click += btnStep_Click;
- //
// btnRefreshMemory
//
btnRefreshMemory.Location = new Point(425, 21);
@@ -200,16 +186,6 @@
lstStack.Size = new Size(130, 264);
lstStack.TabIndex = 17;
//
- // btnExit
- //
- btnExit.Location = new Point(815, 416);
- btnExit.Margin = new Padding(2);
- btnExit.Name = "btnExit";
- btnExit.Size = new Size(90, 27);
- btnExit.TabIndex = 18;
- btnExit.Text = "Exit";
- btnExit.UseVisualStyleBackColor = true;
- //
// label1
//
label1.AutoSize = true;
@@ -276,7 +252,7 @@
// lblIE
//
lblIE.AutoSize = true;
- lblIE.Location = new Point(200, 345);
+ lblIE.Location = new Point(88, 397);
lblIE.Name = "lblIE";
lblIE.Size = new Size(109, 20);
lblIE.TabIndex = 26;
@@ -346,12 +322,10 @@
Controls.Add(label2);
Controls.Add(txtBreakpoint);
Controls.Add(label1);
- Controls.Add(btnExit);
Controls.Add(lstStack);
Controls.Add(lstDisassembly);
Controls.Add(txtMemoryView);
Controls.Add(btnRefreshMemory);
- Controls.Add(btnStep);
Controls.Add(txtMemoryStart);
Controls.Add(lblTStates);
Controls.Add(lblFlags);
@@ -379,13 +353,10 @@
private Label lblFlags;
private Label lblTStates;
private TextBox txtMemoryStart;
- private Button btnStep;
private Button btnRefreshMemory;
private RichTextBox txtMemoryView;
private ListBox lstStack;
- private Button btnExit;
public ListBox lstDisassembly;
- private SaveFileDialog saveFileDialog1;
private Label label1;
private TextBox txtBreakpoint;
private Label label2;
diff --git a/Desktop/DebuggerForm.resx b/Desktop/DebuggerForm.resx
index 7d0a62d..e7a282e 100644
--- a/Desktop/DebuggerForm.resx
+++ b/Desktop/DebuggerForm.resx
@@ -117,9 +117,6 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 17, 17
-
182, 17
diff --git a/Desktop/Desktop.csproj b/Desktop/Desktop.csproj
index 132ab54..e936603 100644
--- a/Desktop/Desktop.csproj
+++ b/Desktop/Desktop.csproj
@@ -8,6 +8,44 @@
enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
@@ -16,10 +54,4 @@
-
-
- PreserveNewest
-
-
-
\ No newline at end of file
diff --git a/Desktop/Form1.Designer.cs b/Desktop/Form1.Designer.cs
index 4e3bfdd..e0690c8 100644
--- a/Desktop/Form1.Designer.cs
+++ b/Desktop/Form1.Designer.cs
@@ -43,6 +43,9 @@
resetToolStripMenuItem1 = new ToolStripMenuItem();
optionsToolStripMenuItem = new ToolStripMenuItem();
HighSpeedToolStripMenuItem = new ToolStripMenuItem();
+ includedToolStripMenuItem = new ToolStripMenuItem();
+ tAPToolStripMenuItem1 = new ToolStripMenuItem();
+ sNAToolStripMenuItem1 = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
@@ -66,7 +69,7 @@
//
// openToolStripMenuItem
//
- openToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { tAPToolStripMenuItem, sNAToolStripMenuItem });
+ openToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { includedToolStripMenuItem, tAPToolStripMenuItem, sNAToolStripMenuItem });
openToolStripMenuItem.Name = "openToolStripMenuItem";
openToolStripMenuItem.Size = new Size(128, 26);
openToolStripMenuItem.Text = "Open";
@@ -74,14 +77,14 @@
// tAPToolStripMenuItem
//
tAPToolStripMenuItem.Name = "tAPToolStripMenuItem";
- tAPToolStripMenuItem.Size = new Size(121, 26);
+ tAPToolStripMenuItem.Size = new Size(149, 26);
tAPToolStripMenuItem.Text = "TAP";
tAPToolStripMenuItem.Click += loadTAPToolStripMenuItem_Click;
//
// sNAToolStripMenuItem
//
sNAToolStripMenuItem.Name = "sNAToolStripMenuItem";
- sNAToolStripMenuItem.Size = new Size(121, 26);
+ sNAToolStripMenuItem.Size = new Size(149, 26);
sNAToolStripMenuItem.Text = "SNA";
sNAToolStripMenuItem.Click += openSNAToolStripMenuItem_Click;
//
@@ -116,28 +119,28 @@
// runToolStripMenuItem
//
runToolStripMenuItem.Name = "runToolStripMenuItem";
- runToolStripMenuItem.Size = new Size(129, 26);
+ runToolStripMenuItem.Size = new Size(224, 26);
runToolStripMenuItem.Text = "Run";
runToolStripMenuItem.Click += btnRun_Click;
//
// resetToolStripMenuItem
//
resetToolStripMenuItem.Name = "resetToolStripMenuItem";
- resetToolStripMenuItem.Size = new Size(129, 26);
+ resetToolStripMenuItem.Size = new Size(224, 26);
resetToolStripMenuItem.Text = "Pause";
resetToolStripMenuItem.Click += btnPause_Click;
//
// stepToolStripMenuItem
//
stepToolStripMenuItem.Name = "stepToolStripMenuItem";
- stepToolStripMenuItem.Size = new Size(129, 26);
+ stepToolStripMenuItem.Size = new Size(224, 26);
stepToolStripMenuItem.Text = "Step";
stepToolStripMenuItem.Click += btnStep_Click;
//
// resetToolStripMenuItem1
//
resetToolStripMenuItem1.Name = "resetToolStripMenuItem1";
- resetToolStripMenuItem1.Size = new Size(129, 26);
+ resetToolStripMenuItem1.Size = new Size(224, 26);
resetToolStripMenuItem1.Text = "Reset";
resetToolStripMenuItem1.Click += btnReset_Click;
//
@@ -151,10 +154,29 @@
// HighSpeedToolStripMenuItem
//
HighSpeedToolStripMenuItem.Name = "HighSpeedToolStripMenuItem";
- HighSpeedToolStripMenuItem.Size = new Size(170, 26);
+ HighSpeedToolStripMenuItem.Size = new Size(224, 26);
HighSpeedToolStripMenuItem.Text = "High Speed";
HighSpeedToolStripMenuItem.Click += btnHighSpeedToggle_Click;
//
+ // includedToolStripMenuItem
+ //
+ includedToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { tAPToolStripMenuItem1, sNAToolStripMenuItem1 });
+ includedToolStripMenuItem.Name = "includedToolStripMenuItem";
+ includedToolStripMenuItem.Size = new Size(149, 26);
+ includedToolStripMenuItem.Text = "Included";
+ //
+ // tAPToolStripMenuItem1
+ //
+ tAPToolStripMenuItem1.Name = "tAPToolStripMenuItem1";
+ tAPToolStripMenuItem1.Size = new Size(224, 26);
+ tAPToolStripMenuItem1.Text = "TAP";
+ //
+ // sNAToolStripMenuItem1
+ //
+ sNAToolStripMenuItem1.Name = "sNAToolStripMenuItem1";
+ sNAToolStripMenuItem1.Size = new Size(224, 26);
+ sNAToolStripMenuItem1.Text = "SNA";
+ //
// Form1
//
AutoScaleDimensions = new SizeF(8F, 20F);
@@ -187,5 +209,8 @@
private ToolStripMenuItem resetToolStripMenuItem1;
private ToolStripMenuItem optionsToolStripMenuItem;
private ToolStripMenuItem HighSpeedToolStripMenuItem;
+ private ToolStripMenuItem includedToolStripMenuItem;
+ private ToolStripMenuItem tAPToolStripMenuItem1;
+ private ToolStripMenuItem sNAToolStripMenuItem1;
}
}
diff --git a/Desktop/Form1.cs b/Desktop/Form1.cs
index ca5a847..ab93bda 100644
--- a/Desktop/Form1.cs
+++ b/Desktop/Form1.cs
@@ -1,11 +1,12 @@
-using System.Drawing.Imaging;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
-using System.Threading;
-using System.IO;
using Core.Cpu;
using Core.Io;
using Core.Memory;
+using System.Diagnostics;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
namespace Desktop
{
@@ -35,6 +36,7 @@ namespace Desktop
public Form1()
{
InitializeComponent();
+ PopulateIncludedTapsMenu();
this.DoubleBuffered = true;
this.ResizeRedraw = true;
InitializeEmulator();
@@ -94,7 +96,7 @@ namespace Desktop
audioSampleCount = 0;
nextScanlineTarget = TStatesPerFrame;
stopwatch.Restart();
-
+ tapeLoaded = false;
_pendingReset = false;
}
@@ -174,26 +176,26 @@ namespace Desktop
{
if (TotalFrameCount % 10 == 0)
{
- this.BeginInvoke((MethodInvoker)delegate
+ this.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate
{
UpdateScreenBitmap(); // Your existing method that writes the ULA data to _screenBitmap
this.Invalidate(); // Tells Windows: "The bitmap changed, please run OnPaint()!"
- this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1}";
+ this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
});
}
}
else
{
- this.BeginInvoke((MethodInvoker)delegate
+ this.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate
{
UpdateScreenBitmap(); // Your existing method that writes the ULA data to _screenBitmap
this.Invalidate(); // Tells Windows: "The bitmap changed, please run OnPaint()!"
- this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1}";
+ this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
});
}
@@ -225,7 +227,7 @@ namespace Desktop
catch (Exception ex)
{
_isPaused = true;
- this.Invoke((MethodInvoker)delegate
+ this.Invoke((System.Windows.Forms.MethodInvoker)delegate
{
MessageBox.Show(ex.Message, "CPU Crash", MessageBoxButtons.OK, MessageBoxIcon.Error);
@@ -234,6 +236,77 @@ namespace Desktop
});
}
+ private void PopulateIncludedTapsMenu()
+ {
+ // 1. Get the current assembly (your .exe)
+ Assembly assembly = Assembly.GetExecutingAssembly();
+
+ // 2. Find all embedded resources
+ string[] resourceNames = assembly.GetManifestResourceNames();
+
+ foreach (string resourceName in resourceNames)
+ {
+ // Check if it is a TAP file in our TestRoms folder
+ // (Embedded resources use dot-notation, e.g., "Desktop.TestRoms.ZEXALL.TAP")
+ if (resourceName.Contains("Desktop.ROMS.TAP.") && resourceName.EndsWith(".TAP", StringComparison.OrdinalIgnoreCase))
+ {
+ // Clean up the name for the menu (e.g., "Desktop.TestRoms.ZEXALL.TAP" -> "ZEXALL")
+ string[] parts = resourceName.Split('.');
+ string displayName = parts[parts.Length - 2];
+
+ // Create the new menu item
+ ToolStripMenuItem item = new ToolStripMenuItem(displayName);
+
+ // Store the full internal path in the Tag so we know what to load when clicked
+ item.Tag = resourceName;
+
+ // Wire up the click event
+ item.Click += IncludedTapMenuItem_Click;
+
+ // Add it to the "Open Included..." dropdown
+ tAPToolStripMenuItem1.DropDownItems.Add(item);
+ }
+ }
+ }
+
+ private void IncludedTapMenuItem_Click(object? sender, EventArgs e)
+ {
+ if (sender is ToolStripMenuItem item && item.Tag is string resourceName)
+ {
+ _isPaused = true;
+
+ try
+ {
+ Assembly assembly = Assembly.GetExecutingAssembly();
+
+ // Open a stream directly into the binary file
+ using (Stream? stream = assembly.GetManifestResourceStream(resourceName))
+ {
+ if (stream == null) throw new Exception("Could not find embedded resource.");
+
+ // Copy the binary stream into a byte array
+ using (MemoryStream ms = new MemoryStream())
+ {
+ stream.CopyTo(ms);
+ byte[] tapBytes = ms.ToArray();
+
+ // Feed it directly to your existing TapManager!
+ _tapManager.LoadTapData(tapBytes);
+ tapeLoaded = true;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Failed to load built-in TAP:\n{ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ finally
+ {
+ _isPaused = false;
+ }
+ }
+ }
+
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
@@ -326,7 +399,7 @@ namespace Desktop
bmp.PixelFormat);
// Pull the raw pixel data
- Marshal.Copy(_ula.FrameBuffer, 0, bmpData.Scan0, _ula.FrameBuffer.Length);
+ Marshal.Copy(_ula.FrontBuffer, 0, bmpData.Scan0, _ula.FrontBuffer.Length);
bmp.UnlockBits(bmpData);
// Dispose of the old frame to prevent massive RAM leaks!
@@ -388,10 +461,6 @@ namespace Desktop
private void btnReset_Click(object sender, EventArgs e)
{
_pendingReset = true;
- _isPaused = true;
- _cpu.Reset();
- _memoryBus.CleanRAMData();
- _isPaused = false;
}
private void btnExit_Click(object sender, EventArgs e)
diff --git a/Desktop/ROMS/Snapshot/ChuckieEgg.sna b/Desktop/ROMS/Snapshot/ChuckieEgg.sna
new file mode 100644
index 0000000..20162ad
Binary files /dev/null and b/Desktop/ROMS/Snapshot/ChuckieEgg.sna differ
diff --git a/Desktop/ROMS/Snapshot/GHILL48K.sna b/Desktop/ROMS/Snapshot/GHILL48K.sna
new file mode 100644
index 0000000..65609a0
Binary files /dev/null and b/Desktop/ROMS/Snapshot/GHILL48K.sna differ
diff --git a/Desktop/ROMS/Snapshot/manic.sna b/Desktop/ROMS/Snapshot/manic.sna
new file mode 100644
index 0000000..d8fcfa1
Binary files /dev/null and b/Desktop/ROMS/Snapshot/manic.sna differ
diff --git a/Desktop/ROMS/TAP/Chuckie Egg.tap b/Desktop/ROMS/TAP/Chuckie Egg.tap
new file mode 100644
index 0000000..0d18626
Binary files /dev/null and b/Desktop/ROMS/TAP/Chuckie Egg.tap differ
diff --git a/Desktop/ROMS/TAP/GHILL48K.TAP b/Desktop/ROMS/TAP/GHILL48K.TAP
new file mode 100644
index 0000000..dad2868
Binary files /dev/null and b/Desktop/ROMS/TAP/GHILL48K.TAP differ
diff --git a/Desktop/ROMS/TAP/MANIC.TAP b/Desktop/ROMS/TAP/MANIC.TAP
new file mode 100644
index 0000000..bc34199
Binary files /dev/null and b/Desktop/ROMS/TAP/MANIC.TAP differ
diff --git a/Desktop/ROMS/TAP/zexall.tap b/Desktop/ROMS/TAP/zexall.tap
new file mode 100644
index 0000000..1066688
Binary files /dev/null and b/Desktop/ROMS/TAP/zexall.tap differ