using System.Reflection; using System.Reflection.PortableExecutable; using Core; using System.Threading.Tasks; using System.Drawing.Imaging; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Desktop { public partial class Form1 : Form { private SmsMachine _machine = null!; private DebuggerForm _debugger; private Bitmap _screenBitmap = new Bitmap(256, 192, PixelFormat.Format32bppArgb); public bool IsRunning { get; private set; } = false; public ushort? Breakpoint { get => _machine?.Breakpoint; set { if (_machine != null) _machine.Breakpoint = value; } } public Form1() { InitializeComponent(); _machine = new SmsMachine(); } private void DrawScreen() { // Rapidly copy our VDP FrameBuffer into the Windows Bitmap var data = _screenBitmap.LockBits(new Rectangle(0, 0, 256, 192), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(_machine.VideoProcessor.FrameBuffer, 0, data.Scan0, _machine.VideoProcessor.FrameBuffer.Length); _screenBitmap.UnlockBits(data); // Update the PictureBox pbScreen.Image = _screenBitmap; } public void StartEmulator() { if (IsRunning) return; IsRunning = true; // Fire off a background task so we don't freeze the Windows UI! Task.Run(() => { while (IsRunning) { _machine.RunFrame(); Invoke((System.Windows.Forms.MethodInvoker)delegate { DrawScreen(); }); // Safety catch: If we hit a breakpoint while running, stop the loop! if (_machine.Breakpoint.HasValue && _machine.Cpu.PC == _machine.Breakpoint.Value) { IsRunning = false; // Optional: Force the debugger UI to update immediately so you see it! Invoke((System.Windows.Forms.MethodInvoker)delegate { _debugger?.uiUpdateTimer_Tick(null, EventArgs.Empty); }); } else { // Only throttle the speed if we are actively running Thread.Sleep(16); } } }); } public void StopEmulator() { IsRunning = false; } public void StepEmulator() { _machine.StepMachine(); } private void button1_Click(object sender, EventArgs e) { // 1. Load a commercial Master System ROM! byte[] rom = File.ReadAllBytes(@"C:\Parsons\Local Code Projects\ParsonsMasterSystem2026\Desktop\ROMS\Golden Axe Warrior.sms"); // 2. Jam it into the Sega Mapper _machine.LoadCartridge(rom); // 3. Open the Debugger to look around if (_debugger == null || _debugger.IsDisposed) { _debugger = new DebuggerForm(_machine.Cpu, _machine.MemoryBus, this); _debugger.Show(); } } } }