private static void MEMHardReset() { // memory WRAM = new byte[0x800]; WRAM[0x0008] = 0xF7; WRAM[0x0008] = 0xF7; WRAM[0x0009] = 0xEF; WRAM[0x000A] = 0xDF; WRAM[0x000F] = 0xBF; palettes_bank = new byte[] // Miscellaneous, real NES loads values similar to these during power up { 0x09, 0x01, 0x00, 0x01, 0x00, 0x02, 0x02, 0x0D, 0x08, 0x10, 0x08, 0x24, 0x00, 0x00, 0x04, 0x2C, // Bkg palette 0x09, 0x01, 0x34, 0x03, 0x00, 0x04, 0x00, 0x14, 0x08, 0x3A, 0x00, 0x02, 0x00, 0x20, 0x2C, 0x08 // Spr palette }; oam_ram = new byte[256]; oam_secondary = new byte[32]; BUS_ADDRESS = 0; BUS_RW = false; BUS_RW_P = false; // Read SRAM if found Trace.WriteLine("Reading SRAM"); if (File.Exists(SRAMFileName)) { Stream str = new FileStream(SRAMFileName, FileMode.Open, FileAccess.Read); byte[] inData = new byte[str.Length]; str.Read(inData, 0, inData.Length); str.Flush(); str.Close(); byte[] outData = new byte[0]; ZlipWrapper.DecompressData(inData, out outData); board.LoadSRAM(outData); Trace.WriteLine("SRAM read successfully."); } else { Trace.WriteLine("SRAM file not found; rom has no SRAM or file not exist."); } board.HardReset(); }
/// <summary> /// Load current game state from file /// </summary> /// <param name="fileName">The complete path to the state file</param> public void LoadStateAs(string fileName) { if (state_is_saving_state) { this.EmulationPaused = false; this.view.WriteNotification("Can't load state while it's saving state !", 120, Color.Red); return; } if (state_is_loading_state) { this.EmulationPaused = false; this.view.WriteNotification("Already loading a state !", 120, Color.Red); return; } state_is_loading_state = true; // Read the file Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); // Decompress byte[] inData = new byte[stream.Length]; byte[] outData = new byte[0]; stream.Read(inData, 0, inData.Length); stream.Close(); ZlipWrapper.DecompressData(inData, out outData); // Create the reader BinaryReader bin = new BinaryReader(new MemoryStream(outData)); // Read header byte[] header = new byte[3]; bin.Read(header, 0, header.Length); if (Encoding.ASCII.GetString(header) != "MNS") { this.EmulationPaused = false; this.view.WriteNotification("Unable load state at slot " + STATESlot + "; Not My Nes State File !", 120, Color.Red); state_is_loading_state = false; return; } // Read version if (bin.ReadByte() != state_version) { this.EmulationPaused = false; this.view.WriteNotification("Unable load state at slot " + STATESlot + "; Not compatible state file version !", 120, Color.Red); state_is_loading_state = false; return; } string sha1 = ""; for (int i = 0; i < this.memory.board.RomSHA1.Length; i += 2) { sha1 += (bin.ReadByte()).ToString("X2"); } if (sha1.ToLower() != this.memory.board.RomSHA1.ToLower()) { this.EmulationPaused = false; this.view.WriteNotification("Unable load state at slot " + STATESlot + "; This state file is not for this game; not same SHA1 !", 120, Color.Red); state_is_loading_state = false; return; } // Read data #region General this.emulator.palCyc = bin.ReadByte(); #endregion #region APU this.apu.LoadState(bin); #endregion #region CPU this.cpu.LoadState(bin); #endregion #region DMA this.dma.LoadState(bin); #endregion #region DMC this.apu.dmcChannel.LoadState(bin); #endregion #region Input this.input.LoadState(bin); #endregion #region Interrupts this.interrupts.LoadState(bin); #endregion #region Memory this.memory.LoadState(bin); #endregion #region Noise this.apu.noiseChannel.LoadState(bin); #endregion #region PPU this.ppu.LoadState(bin); #endregion #region Pulse this.apu.pulse1Channel.LoadState(bin); this.apu.pulse2Channel.LoadState(bin); #endregion #region Triangle this.apu.triangleChannel.LoadState(bin); #endregion // Finished ! bin.Close(); this.EmulationPaused = false; state_is_loading_state = false; this.view.WriteNotification("State loaded from slot " + STATESlot, 120, Color.Green); }
/// <summary> /// Load current game state from file /// </summary> /// <param name="fileName">The complete path to the state file</param> public static void LoadStateAs(string fileName) { if (state_is_saving_state) { EmulationPaused = false; videoOut.WriteNotification("Can't load state while it's saving state !", 120, Color.Red); return; } if (state_is_loading_state) { EmulationPaused = false; videoOut.WriteNotification("Already loading a state !", 120, Color.Red); return; } if (!File.Exists(fileName)) { videoOut.WriteNotification("No state found at slot " + STATESlot, 120, Color.Red); return; } state_is_loading_state = true; // Read the file Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); // Decompress byte[] inData = new byte[stream.Length]; byte[] outData = new byte[0]; stream.Read(inData, 0, inData.Length); stream.Close(); ZlipWrapper.DecompressData(inData, out outData); // Create the reader BinaryReader bin = new BinaryReader(new MemoryStream(outData)); // Read header byte[] header = new byte[3]; bin.Read(header, 0, header.Length); if (Encoding.ASCII.GetString(header) != "MNS") { EmulationPaused = false; videoOut.WriteNotification("Unable load state at slot " + STATESlot + "; Not My Nes State File !", 120, Color.Red); state_is_loading_state = false; return; } // Read version if (bin.ReadByte() != state_version) { EmulationPaused = false; videoOut.WriteNotification("Unable load state at slot " + STATESlot + "; Not compatible state file version !", 120, Color.Red); state_is_loading_state = false; return; } string sha1 = ""; for (int i = 0; i < board.RomSHA1.Length; i += 2) { sha1 += (bin.ReadByte()).ToString("X2"); } if (sha1.ToLower() != board.RomSHA1.ToLower()) { EmulationPaused = false; videoOut.WriteNotification("Unable load state at slot " + STATESlot + "; This state file is not for this game; not same SHA1 !", 120, Color.Red); state_is_loading_state = false; return; } // Read data #region General palCyc = bin.ReadByte(); #endregion #region APU Cycles = bin.ReadInt32(); SequencingMode = bin.ReadBoolean(); CurrentSeq = bin.ReadByte(); isClockingDuration = bin.ReadBoolean(); FrameIrqEnabled = bin.ReadBoolean(); FrameIrqFlag = bin.ReadBoolean(); oddCycle = bin.ReadBoolean(); #endregion #region CPU registers.a = bin.ReadByte(); registers.c = bin.ReadBoolean(); registers.d = bin.ReadBoolean(); registers.eah = bin.ReadByte(); registers.eal = bin.ReadByte(); registers.i = bin.ReadBoolean(); registers.n = bin.ReadBoolean(); registers.pch = bin.ReadByte(); registers.pcl = bin.ReadByte(); registers.sph = bin.ReadByte(); registers.spl = bin.ReadByte(); registers.v = bin.ReadBoolean(); registers.x = bin.ReadByte(); registers.y = bin.ReadByte(); registers.z = bin.ReadBoolean(); M = bin.ReadByte(); opcode = bin.ReadByte(); byte_temp = bin.ReadByte(); int_temp = bin.ReadInt32(); int_temp1 = bin.ReadInt32(); dummy = bin.ReadByte(); #endregion #region DMA dmaDMCDMAWaitCycles = bin.ReadInt32(); dmaOAMDMAWaitCycles = bin.ReadInt32(); isOamDma = bin.ReadBoolean(); oamdma_i = bin.ReadInt32(); dmaDMCOn = bin.ReadBoolean(); dmaOAMOn = bin.ReadBoolean(); dmaDMC_occurring = bin.ReadBoolean(); dmaOAM_occurring = bin.ReadBoolean(); dmaOAMFinishCounter = bin.ReadInt32(); dmaOamaddress = bin.ReadInt32(); OAMCYCLE = bin.ReadInt32(); latch = bin.ReadByte(); #endregion #region DMC DeltaIrqOccur = bin.ReadBoolean(); DMCIrqEnabled = bin.ReadBoolean(); dmc_dmaLooping = bin.ReadBoolean(); dmc_dmaEnabled = bin.ReadBoolean(); dmc_bufferFull = bin.ReadBoolean(); dmc_dmaAddrRefresh = bin.ReadInt32(); dmc_dmaSizeRefresh = bin.ReadInt32(); dmc_dmaSize = bin.ReadInt32(); dmc_dmaBits = bin.ReadInt32(); dmc_dmaByte = bin.ReadByte(); dmc_dmaAddr = bin.ReadInt32(); dmc_dmaBuffer = bin.ReadByte(); dmc_output = bin.ReadByte(); dmc_cycles = bin.ReadInt32(); dmc_freqTimer = bin.ReadInt32(); #endregion #region Input PORT0 = bin.ReadInt32(); PORT1 = bin.ReadInt32(); inputStrobe = bin.ReadInt32(); #endregion #region Interrupts NMI_Current = bin.ReadBoolean(); NMI_Old = bin.ReadBoolean(); NMI_Detected = bin.ReadBoolean(); IRQFlags = bin.ReadInt32(); IRQ_Detected = bin.ReadBoolean(); interrupt_vector = bin.ReadInt32(); interrupt_suspend_nmi = bin.ReadBoolean(); interrupt_suspend_irq = bin.ReadBoolean(); nmi_enabled = bin.ReadBoolean(); nmi_old = bin.ReadBoolean(); vbl_flag = bin.ReadBoolean(); vbl_flag_temp = bin.ReadBoolean(); #endregion #region Memory board.LoadState(bin); bin.Read(WRAM, 0, WRAM.Length); bin.Read(palettes_bank, 0, palettes_bank.Length); bin.Read(oam_ram, 0, oam_ram.Length); bin.Read(oam_secondary, 0, oam_secondary.Length); BUS_ADDRESS = bin.ReadInt32(); BUS_RW = bin.ReadBoolean(); BUS_RW_P = bin.ReadBoolean(); temp_4015 = bin.ReadByte(); temp_4016 = bin.ReadByte(); temp_4017 = bin.ReadByte(); #endregion #region Noise noz_envelope = bin.ReadInt32(); noz_env_startflag = bin.ReadBoolean(); noz_env_counter = bin.ReadInt32(); noz_env_devider = bin.ReadInt32(); noz_length_counter_halt_flag = bin.ReadBoolean(); noz_constant_volume_flag = bin.ReadBoolean(); noz_volume_decay_time = bin.ReadInt32(); noz_duration_haltRequset = bin.ReadBoolean(); noz_duration_counter = bin.ReadByte(); noz_duration_reloadEnabled = bin.ReadBoolean(); noz_duration_reload = bin.ReadByte(); noz_duration_reloadRequst = bin.ReadBoolean(); noz_mode = bin.ReadBoolean(); noz_shiftRegister = bin.ReadInt32(); noz_feedback = bin.ReadInt32(); noz_frequency = bin.ReadInt32(); noz_cycles = bin.ReadInt32(); #endregion #region PPU VClock = bin.ReadInt32(); HClock = bin.ReadInt32(); oddSwap = bin.ReadBoolean(); current_pixel = bin.ReadInt32(); temp = bin.ReadInt32(); temp_comparator = bin.ReadInt32(); bkg_pos = bin.ReadInt32(); spr_pos = bin.ReadInt32(); object0 = bin.ReadInt32(); infront = bin.ReadInt32(); bkgPixel = bin.ReadInt32(); sprPixel = bin.ReadInt32(); bkg_fetch_address = bin.ReadInt32(); bkg_fetch_nametable = bin.ReadByte(); bkg_fetch_attr = bin.ReadByte(); bkg_fetch_bit0 = bin.ReadByte(); bkg_fetch_bit1 = bin.ReadByte(); spr_fetch_address = bin.ReadInt32(); spr_fetch_bit0 = bin.ReadByte(); spr_fetch_bit1 = bin.ReadByte(); spr_fetch_attr = bin.ReadByte(); for (int i = 0; i < spr_zero_buffer.Length; i++) { spr_zero_buffer[i] = bin.ReadBoolean(); } vram_temp = bin.ReadInt32(); vram_address = bin.ReadInt32(); vram_address_temp_access = bin.ReadInt32(); vram_address_temp_access1 = bin.ReadInt32(); vram_increament = bin.ReadInt32(); vram_flipflop = bin.ReadBoolean(); vram_fine = bin.ReadByte(); reg2007buffer = bin.ReadByte(); bkg_enabled = bin.ReadBoolean(); bkg_clipped = bin.ReadBoolean(); bkg_patternAddress = bin.ReadInt32(); spr_enabled = bin.ReadBoolean(); spr_clipped = bin.ReadBoolean(); spr_patternAddress = bin.ReadInt32(); spr_size16 = bin.ReadInt32(); spr_0Hit = bin.ReadBoolean(); spr_overflow = bin.ReadBoolean(); grayscale = bin.ReadInt32(); emphasis = bin.ReadInt32(); ppu_2002_temp = bin.ReadByte(); ppu_2004_temp = bin.ReadByte(); ppu_2007_temp = bin.ReadByte(); oam_address = bin.ReadByte(); oam_fetch_data = bin.ReadByte(); oam_evaluate_slot = bin.ReadByte(); oam_evaluate_count = bin.ReadByte(); oam_fetch_mode = bin.ReadBoolean(); oam_phase_index = bin.ReadByte(); spr_render_i = bin.ReadInt32(); bkg_render_i = bin.ReadInt32(); spr_evaluation_i = bin.ReadInt32(); spr_render_temp_pixel = bin.ReadInt32(); #endregion #region Pulse 1 sq1_envelope = bin.ReadInt32(); sq1_env_startflag = bin.ReadBoolean(); sq1_env_counter = bin.ReadInt32(); sq1_env_devider = bin.ReadInt32(); sq1_length_counter_halt_flag = bin.ReadBoolean(); sq1_constant_volume_flag = bin.ReadBoolean(); sq1_volume_decay_time = bin.ReadInt32(); sq1_duration_haltRequset = bin.ReadBoolean(); sq1_duration_counter = bin.ReadByte(); sq1_duration_reloadEnabled = bin.ReadBoolean(); sq1_duration_reload = bin.ReadByte(); sq1_duration_reloadRequst = bin.ReadBoolean(); sq1_dutyForm = bin.ReadInt32(); sq1_dutyStep = bin.ReadInt32(); sq1_sweepDeviderPeriod = bin.ReadInt32(); sq1_sweepShiftCount = bin.ReadInt32(); sq1_sweepCounter = bin.ReadInt32(); sq1_sweepEnable = bin.ReadBoolean(); sq1_sweepReload = bin.ReadBoolean(); sq1_sweepNegateFlag = bin.ReadBoolean(); sq1_frequency = bin.ReadInt32(); sq1_sweep = bin.ReadInt32(); sq1_cycles = bin.ReadInt32(); #endregion #region Pulse 2 sq2_envelope = bin.ReadInt32(); sq2_env_startflag = bin.ReadBoolean(); sq2_env_counter = bin.ReadInt32(); sq2_env_devider = bin.ReadInt32(); sq2_length_counter_halt_flag = bin.ReadBoolean(); sq2_constant_volume_flag = bin.ReadBoolean(); sq2_volume_decay_time = bin.ReadInt32(); sq2_duration_haltRequset = bin.ReadBoolean(); sq2_duration_counter = bin.ReadByte(); sq2_duration_reloadEnabled = bin.ReadBoolean(); sq2_duration_reload = bin.ReadByte(); sq2_duration_reloadRequst = bin.ReadBoolean(); sq2_dutyForm = bin.ReadInt32(); sq2_dutyStep = bin.ReadInt32(); sq2_sweepDeviderPeriod = bin.ReadInt32(); sq2_sweepShiftCount = bin.ReadInt32(); sq2_sweepCounter = bin.ReadInt32(); sq2_sweepEnable = bin.ReadBoolean(); sq2_sweepReload = bin.ReadBoolean(); sq2_sweepNegateFlag = bin.ReadBoolean(); sq2_frequency = bin.ReadInt32(); sq2_sweep = bin.ReadInt32(); sq2_cycles = bin.ReadInt32(); #endregion #region Triangle trl_length_counter_halt_flag = bin.ReadBoolean(); trl_duration_haltRequset = bin.ReadBoolean(); trl_duration_counter = bin.ReadByte(); trl_duration_reloadEnabled = bin.ReadBoolean(); trl_duration_reload = bin.ReadByte(); trl_duration_reloadRequst = bin.ReadBoolean(); trl_linearCounter = bin.ReadByte(); trl_linearCounterReload = bin.ReadByte(); trl_step = bin.ReadByte(); trl_linearCounterHalt = bin.ReadBoolean(); trl_halt = bin.ReadBoolean(); trl_frequency = bin.ReadInt32(); trl_cycles = bin.ReadInt32(); #endregion // Finished ! bin.Close(); EmulationPaused = false; state_is_loading_state = false; videoOut.WriteNotification("State loaded from slot " + STATESlot, 120, Color.Green); }