private void Reset(bool softReset) { lock (_runLock) { CoreWrapper.reset(string.Empty, softReset); Step(1); } }
void LoadRom(string filename) { byte[] rom = File.ReadAllBytes(filename); if ((rom[6] & 0x08) == 0x08) { CoreWrapper.setMirroringType(MirroringType.FourScreens); } else { CoreWrapper.setMirroringType((rom[6] & 0x01) == 0x01 ? MirroringType.Vertical : MirroringType.Horizontal); } int prgRamSize = rom[4] * 0x4000; int chrRamSize = rom[5] * 0x2000; byte[] prgRam = new byte[prgRamSize]; byte[] chrRam = new byte[chrRamSize]; Array.Copy(rom, 16, prgRam, 0, prgRamSize); Array.Copy(rom, 16 + prgRamSize, chrRam, 0, chrRamSize); if (prgRamSize == 0x4000) { Array.Resize(ref prgRam, 0x8000); Array.Copy(prgRam, 0, prgRam, 0x4000, 0x4000); } lock (_runLock) { Stop(); Reset(false); CoreWrapper.setMemoryState(MemoryType.ChrRam, chrRam); CoreWrapper.setMemoryState(MemoryType.PrgRam, prgRam); } }
private void HighlightNode(List <int> nodeNumbers) { using (Graphics g = Graphics.FromImage(_imgHighlight)) { g.Clear(Color.Transparent); _highlightedNodes = nodeNumbers; foreach (int nn in nodeNumbers) { if (nn < 0) { //Draw transistor using (Brush brush = new SolidBrush(Color.FromArgb(180, 255, 255, 255))) { List <int> bb = _chipDef.Transistors[-nn + 1].bb; DrawSegment(g, brush, new List <int> { bb[0], bb[2], bb[1], bb[2], bb[1], bb[3], bb[0], bb[3] }, false); } } else if (_chipDef.Nodes[nn].segs.Count > 0) { //Draw node Color color = CoreWrapper.isNodeHigh(nn) ? Color.FromArgb(180, 255, 0, 0) : Color.FromArgb(180, 255, 255, 255); using (Brush brush = new SolidBrush(color)) { foreach (List <int> segments in _chipDef.Nodes[nn].segs) { DrawSegment(g, brush, segments, false); } } } } } _viewPortChanged = true; }
private void UpdateRam() { lock (_runLock) { if (_chrRamChanged) { CoreWrapper.setMemoryState(MemoryType.ChrRam, ((StaticByteProvider)hexChrRam.ByteProvider).Bytes.ToArray()); } if (_nametableRamChanged) { CoreWrapper.setMemoryState(MemoryType.NametableRam, ((StaticByteProvider)hexNametableRam.ByteProvider).Bytes.ToArray()); } if (_paletteRamChanged) { CoreWrapper.setMemoryState(MemoryType.PaletteRam, ((StaticByteProvider)hexPaletteRam.ByteProvider).Bytes.ToArray()); } if (_spriteRamChanged) { CoreWrapper.setMemoryState(MemoryType.SpriteRam, ((StaticByteProvider)hexSpriteRam.ByteProvider).Bytes.ToArray()); } if (_cpuRamChanged) { CoreWrapper.setMemoryState(MemoryType.CpuRam, ((StaticByteProvider)hexCpuRam.ByteProvider).Bytes.ToArray()); } if (_prgRamChanged) { CoreWrapper.setMemoryState(MemoryType.PrgRam, ((StaticByteProvider)hexPrgRam.ByteProvider).Bytes.ToArray()); } } _chrRamChanged = false; _nametableRamChanged = false; _paletteRamChanged = false; _spriteRamChanged = false; _cpuRamChanged = false; _prgRamChanged = false; }
private void mnuSaveState_Click(object sender, EventArgs e) { SaveFile("Save states (*.ss)|*.ss", (file) => { lock (_runLock) { UpdateRam(); File.WriteAllBytes(file, CoreWrapper.getMemoryState(MemoryType.FullState)); } }); }
private void btnExportPrgRam_Click(object sender, EventArgs e) { SaveFile("PRG RAM (*.pr)|*.pr", (file) => { lock (_runLock) { UpdateRam(); File.WriteAllBytes(file, CoreWrapper.getMemoryState(MemoryType.PrgRam)); } }); }
void SetMirroring(MirroringType mirroringType) { mnuMirrorHorizontal.Checked = mirroringType == MirroringType.Horizontal; mnuMirrorVertical.Checked = mirroringType == MirroringType.Vertical; mnuMirrorScreenA.Checked = mirroringType == MirroringType.ScreenAOnly; mnuMirrorScreenB.Checked = mirroringType == MirroringType.ScreenBOnly; mnuMirrorFourScreens.Checked = mirroringType == MirroringType.FourScreens; CoreWrapper.setMirroringType(mirroringType); }
private void StartEmulationThread() { _emulationThread = Task.Run(() => { while (!_stopFlag) { while (!_stopFlag && _stepsToRun > 0) { UpdateRam(); int stepsToRun = Math.Min(_refreshSpeed, _stepsToRun); Interlocked.Add(ref _stepsToRun, -stepsToRun); Stopwatch sw = new Stopwatch(); lock (_runLock) { sw.Start(); CoreWrapper.step((UInt32)stepsToRun); CoreWrapper.getState(ref _previousState); _chrRamData = CoreWrapper.getMemoryState(MemoryType.ChrRam); _nametableRamData = CoreWrapper.getMemoryState(MemoryType.NametableRam); _paletteData = CoreWrapper.getMemoryState(MemoryType.PaletteRam); _spriteData = CoreWrapper.getMemoryState(MemoryType.SpriteRam); _cpuRamData = CoreWrapper.getMemoryState(MemoryType.CpuRam); _prgRamData = CoreWrapper.getMemoryState(MemoryType.PrgRam); if (mnuShowSimulationState.Checked) { ctrlChipDisplay.ShowState = true; ctrlChipDisplay.RefreshState(true); } sw.Stop(); } this.BeginInvoke((MethodInvoker)(() => { double emulatedHz = Stopwatch.Frequency / (double)sw.ElapsedTicks * stepsToRun / 2; int nesMasterClockSpeed = 21477272; double speedPercent = (emulatedHz / nesMasterClockSpeed) * 100; lblHz.Text = string.Format("{0:0} ({1:0.0000}% of NES speed - {2:0.0000} FPM)", emulatedHz, speedPercent, speedPercent / 100 * 60.1 * 60); UpdateUI(); })); } if (_autoRun) { Interlocked.Add(ref _stepsToRun, _refreshSpeed); } else { System.Threading.Thread.Sleep(50); } } }); }
protected override void OnClosed(EventArgs e) { Stop(); _stopFlag = true; if (_emulationThread != null) { _emulationThread.Wait(); } CoreWrapper.release(); base.OnClosed(e); }
private void SetMemoryState(MemoryType type, byte[] data) { lock (_runLock) { UpdateRam(); CoreWrapper.setMemoryState(type, data); _chrRamData = CoreWrapper.getMemoryState(MemoryType.ChrRam); _paletteData = CoreWrapper.getMemoryState(MemoryType.PaletteRam); _spriteData = CoreWrapper.getMemoryState(MemoryType.SpriteRam); _cpuRamData = CoreWrapper.getMemoryState(MemoryType.CpuRam); _prgRamData = CoreWrapper.getMemoryState(MemoryType.PrgRam); } UpdateMemoryViews(); }
private void mnuLoadState_Click(object sender, EventArgs e) { LoadFile("Save states (*.ss)|*.ss", (file) => { lock (_runLock) { CoreWrapper.setMemoryState(MemoryType.FullState, File.ReadAllBytes(file)); _chrRamChanged = false; _paletteRamChanged = false; _spriteRamChanged = false; _cpuRamChanged = false; _prgRamChanged = false; Step(1); } }); }
private void UpdatePicture() { using (Graphics graphics = Graphics.FromImage(picPpuOutput.Image)) { GCHandle handle = GCHandle.Alloc(CoreWrapper.getFrameBuffer(), GCHandleType.Pinned); Bitmap source = new Bitmap(256, 240, 4 * 256, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject()); try { graphics.DrawImage(source, 0, 0); } finally { handle.Free(); } picPpuOutput.Invalidate(); this.Text = "PPU Output" + (frmMain.CurrentRom.Length > 0 ? " - " + Path.GetFileNameWithoutExtension(frmMain.CurrentRom) : ""); } }
private void btnSelectColumns_Click(object sender, EventArgs e) { using (frmSelectColumns frm = new frmSelectColumns(_chipDef, _tracedColumns)) { if (frm.ShowDialog() == DialogResult.OK) { lock (_runLock) { _tracedColumns.Clear(); _tracedColumns.AddRange(frmSelectColumns.SelectedColumns); CoreWrapper.setTrace(string.Join("|", _tracedColumns)); _needColumnUpdate = true; Step(1); } } } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!DesignMode) { cboLogMaxLines.SelectedIndex = 0; SetMirroring(MirroringType.Horizontal); CoreWrapper.initEmulator(); CoreWrapper.setTrace(string.Join("|", _tracedColumns)); CoreWrapper.reset(string.Empty, false); Step(1); StartEmulationThread(); } }
void addNodeToGroup(int nn, HashSet <int> group) { if (nn == ngnd) { return; } if (nn == npwr) { return; } if (group.Add(nn)) { foreach (transistor t in _nodes[nn].c1c2s) { if (CoreWrapper.isTransistorOn(t.name)) { addNodeToGroup(t.c1 == nn ? t.c2 : t.c1, group); } } } }
public void RefreshState(bool async = false) { if (!_refreshingState && _showState) { Action updateState = () => { _refreshingState = true; lock (_imgHighNodes) { using (Graphics g = Graphics.FromImage(_imgHighNodes)) { g.Clear(Color.Transparent); using (Brush brush = new SolidBrush(Color.FromArgb(100, 255, 0, 64))) { foreach (node node in _chipDef.Nodes) { if (node != null) { if (node.num != 1 && CoreWrapper.isNodeHigh(node.num)) { foreach (List <int> segments in node.segs) { DrawSegment(g, brush, segments, false); } } } } } } } _needRefresh = true; _refreshingState = false; }; if (async) { Task.Run(updateState); } else { updateState(); } } }
private void btnStartLogging_Click(object sender, EventArgs e) { if (_logging) { btnStartLogging.Text = "Start Logging"; _logging = false; chkLogHex.Enabled = true; chkLogCsv.Enabled = true; lock (_runLock) { CoreWrapper.stopLogging(); } } else { using (SaveFileDialog sfd = new SaveFileDialog()) { sfd.Filter = "Log file (*.txt)|*.txt"; sfd.FileName = "tracelog.txt"; if (sfd.ShowDialog() == DialogResult.OK) { lock (_runLock) { if (CoreWrapper.startLogging(sfd.FileName, chkLogHex.Checked, chkLogCsv.Checked)) { btnStartLogging.Text = "Stop Logging"; _logging = true; chkLogHex.Enabled = false; chkLogCsv.Enabled = false; } else { MessageBox.Show("Couldn't open file"); } } } } } }
public void HighlightNode(List <int> nodeNumbers, bool focusOnSelection = false) { List <List <int> > segmentList = new List <List <int> >(); using (Graphics g = Graphics.FromImage(_imgHighlight)) { g.Clear(Color.Transparent); foreach (int nn in nodeNumbers) { if (nn < 0) { segmentList.Add(_chipDef.Transistors[-nn + 1].bb); //Draw transistor using (Brush brush = new SolidBrush(Color.FromArgb(180, 255, 255, 255))) { List <int> bb = _chipDef.Transistors[-nn + 1].bb; DrawSegment(g, brush, new List <int> { bb[0], bb[2], bb[1], bb[2], bb[1], bb[3], bb[0], bb[3] }, false); } } else if (_chipDef.Nodes[nn].segs.Count > 0) { segmentList.AddRange(_chipDef.Nodes[nn].segs); //Draw node Color color = CoreWrapper.isNodeHigh(nn) ? Color.FromArgb(180, 255, 255, 255) : Color.FromArgb(180, 255, 255, 255); using (Brush brush = new SolidBrush(color)) { foreach (List <int> segments in _chipDef.Nodes[nn].segs) { DrawSegment(g, brush, segments, false); } } } } } if (focusOnSelection && segmentList.Count > 0) { var xmin = segmentList[0][0]; var xmax = segmentList[0][0]; var ymin = segmentList[0][1]; var ymax = segmentList[0][1]; foreach (List <int> segments in segmentList) { for (var i = 0; i < segments.Count; i += 2) { if (segments[i] < xmin) { xmin = segments[i]; } if (segments[i] > xmax) { xmax = segments[i]; } if (segments[i + 1] < ymin) { ymin = segments[i + 1]; } if (segments[i + 1] > ymax) { ymax = segments[i + 1]; } } } ZoomToBox(xmin, xmax, ymin, ymax); } _viewPortChanged = true; }