using Core.Cpu; using Core.Io; using Core.Memory; using System; using System.IO; using System.Collections.Generic; namespace Core { public class SmsMachine { public Z80 Cpu { get; private set; } public SmsMemoryBus MemoryBus { get; private set; } public SmsIoBus IoBus { get; private set; } public Core.Video.SmsVdp VideoProcessor { get; private set; } public ushort? Breakpoint { get; set; } = null; // NTSC SMS T-States per frame public const int TStatesPerFrame = 59736; public SmsMachine() { MemoryBus = new SmsMemoryBus(); VideoProcessor = new Core.Video.SmsVdp(); IoBus = new SmsIoBus { VideoProcessor = this.VideoProcessor }; Cpu = new Z80(MemoryBus, IoBus); } public void LoadCartridge(byte[] romData) { MemoryBus.LoadCartridge(romData); Reset(); } public void Reset() { MemoryBus.CleanRAMData(); Cpu.Reset(); } public int StepMachine() { // 1. Tick the CPU int tStates = Cpu.Step(); // 2. Tell the VDP how much time just passed VideoProcessor.Update(tStates); // 3. Trigger interrupts if the VDP hit scanline 192 if (VideoProcessor.InterruptPending) { tStates += Cpu.RequestInterrupt(); } return tStates; } public void RunFrame() { long currentFrameTStates = 0; while (currentFrameTStates < TStatesPerFrame) { currentFrameTStates += StepMachine(); string filePath = "captured_data.txt"; // Mock data to loop through //List sensorReadings = new List { Cpu.PC, Cpu.AF.Word, Cpu.BC.Word, Cpu.DE.Word, Cpu.HL.Word, Cpu.SP}; //List type = new List {"PC: 0x", "AF: 0x", "BC: 0x", "DE: 0x", "HL: 0x", "SP: 0x" }; //try //{ // // 2. Initialize StreamWriter within a 'using' block // // The 'true' parameter means "append" to the file. Use 'false' to overwrite. // using (StreamWriter writer = new StreamWriter(filePath, append: true)) // { // foreach (int reading in sensorReadings) // { // string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // // 3. Construct your string and write it // foreach (string _type in type) // { // string line = $"{timestamp} | {_type} {reading}"; // writer.WriteLine(line); // } // // Optional: Console feedback // //Console.WriteLine($"Logged: {line}"); // } // } // // File is automatically closed and saved here // //Console.WriteLine("Data capture complete."); //} //catch (IOException e) //{ // Console.WriteLine($"An error occurred: {e.Message}"); //} // THE TRIPWIRE: Check the breakpoint after EVERY single instruction! if (Breakpoint.HasValue && Cpu.PC == Breakpoint.Value) { break; // Abort the frame loop immediately! } } } } }