protected override void LoadContent() { m_sprite_batch = new SpriteBatch(GraphicsDevice); m_white_texture = Content.Load <Texture2D>("White"); m_crt_effect_border = Content.Load <Effect>("crt"); m_crt_effect_border.Parameters["Viewport"].SetValue(new Vector2(GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height)); m_crt_effect_border.Parameters["TextureHeight"].SetValue(GraphicsDevice.Viewport.Height / CPC_PIXEL_HEIGHT); m_crt_effect_border.Parameters["ScreenHeight"].SetValue(GraphicsDevice.Viewport.Height); m_crt_effect_screen = m_crt_effect_border.Clone(); m_crt_effect_screen.Parameters["Viewport"].SetValue(new Vector2(GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height)); m_crt_effect_screen.Parameters["TextureHeight"].SetValue(TextureDisplay.MAX_SCREEN_HEIGHT); m_crt_effect_screen.Parameters["ScreenHeight"].SetValue(m_screen_rect.Height); m_texture_display = new TextureDisplay(GraphicsDevice); m_audio = new Audio(); m_emulator = new CPC.Emulator(m_audio, m_texture_display); for (PlayerIndex index = PlayerIndex.One; index <= PlayerIndex.Four; index++) { // For now all gamepads respond as joystick 0 m_emulator.Keyboard.AssignJoystick(new CPC.Joystick(0, index)); } // Use CPC464 ROM only for now BinaryFile rom_file = LoadBinaryFile("rom\\CPC464"); m_emulator.Memory.LoadROM(CPC.ROM.LOWER_ROM_INDEX, rom_file.m_data, 0); m_emulator.Memory.LoadROM(CPC.ROM.BASIC_ROM_INDEX, rom_file.m_data, CPC.ROM.ROM_SIZE); // List snapshots that can be played GetSnapshotFileList(); List <string> pause_menu_options = new List <string>(); pause_menu_options.Add("Unpause"); //Resume pause_menu_options.Add("Load Snapshot"); //LoadSnapshot pause_menu_options.Add("Reset CPC"); //Reset pause_menu_options.Add("Toggle CRT Shader"); //ToggleCRTShader pause_menu_options.Add("Throttle Speed"); //ThrottleSpeed pause_menu_options.Add("Quit"); //Quit m_pause_menu.SetupMenu("XNACPC - Gavin Pugh 2011", pause_menu_options, PauseCallback); m_pause_menu.SetupMenuToggle((int)EPauseMenuOptions.ThrottleSpeed, m_throttle_speed); m_pause_menu.SetupMenuToggle((int)EPauseMenuOptions.ToggleCRTShader, m_use_crt_shader); m_snapshot_menu.SetupMenu("Choose a snapshot", m_snapshot_files, SnapshotCallback); if (m_startup_load_sna != null) { // Check the sna list. Do a case-insensitive compare to check it's a valid .sna foreach (string snaFile in m_snapshot_files) { if (String.Compare(snaFile, m_startup_load_sna, StringComparison.OrdinalIgnoreCase) == 0) { // Got it! Now just load it in. LoadSnapshotFile(m_startup_load_sna); break; } } } GC.Collect(); m_timer.Reset(); m_timer.Start(); base.LoadContent(); }
public void LoadSnapshot(Emulator emulator) { // Check header for (int i = 0; i < ID_STRING.Length; i++) { Debug.Assert(ID_STRING[i] == GetByte(Indices.IDString + i)); } if (GetByte(Indices.Version) < 3) { // Use the hack for v1/2 snapshots that don't have CRTC/GA timing info emulator.PreSnapshotHack(); } // Z80 processor state emulator.Processor.F(GetByte(Indices.RegisterF)); emulator.Processor.A(GetByte(Indices.RegisterA)); emulator.Processor.C(GetByte(Indices.RegisterC)); emulator.Processor.B(GetByte(Indices.RegisterB)); emulator.Processor.E(GetByte(Indices.RegisterE)); emulator.Processor.D(GetByte(Indices.RegisterD)); emulator.Processor.L(GetByte(Indices.RegisterL)); emulator.Processor.H(GetByte(Indices.RegisterH)); emulator.Processor.R(GetByte(Indices.RegisterR)); emulator.Processor.I(GetByte(Indices.RegisterI)); emulator.Processor.IFF1(GetByte(Indices.RegisterIFF0) != 0); emulator.Processor.IFF2(GetByte(Indices.RegisterIFF1) != 0); emulator.Processor.IX(GetWord(Indices.RegisterIXHigh, Indices.RegisterIXLow)); emulator.Processor.IY(GetWord(Indices.RegisterIYHigh, Indices.RegisterIYLow)); emulator.Processor.SP(GetWord(Indices.RegisterSPHigh, Indices.RegisterSPLow)); emulator.Processor.PC(GetWord(Indices.RegisterPCHigh, Indices.RegisterPCLow)); emulator.Processor.IM(GetByte(Indices.InterruptMode)); emulator.Processor.SetAltAF(GetWord(Indices.RegisterAltA, Indices.RegisterAltF)); emulator.Processor.SetAltBC(GetWord(Indices.RegisterAltB, Indices.RegisterAltC)); emulator.Processor.SetAltDE(GetWord(Indices.RegisterAltD, Indices.RegisterAltE)); emulator.Processor.SetAltHL(GetWord(Indices.RegisterAltH, Indices.RegisterAltL)); // Gate Array emulator.GateArray.SetCurrentPen(GetByte(Indices.GASelectedPen)); for (int i = 0; i < GateArray.NUM_PEN_SETTINGS; i++) { emulator.GateArray.SetPenColour(i, GetByte(Indices.GAPenColours + i)); } emulator.GateArray.ScreenModeAndROMSelect(GetByte(Indices.GAMultiConfig)); emulator.Memory.RAMBankSelect(GetByte(Indices.GARAMSelect)); // CRTC emulator.CRTC.SelectRegister((CRTC.Register)GetByte(Indices.CRTCSelReg)); for (int i = 0; i < CRTC.NUM_REGISTERS; i++) { emulator.CRTC.SetRegister((CRTC.Register)i, GetByte(Indices.CRTCRegData + i)); } // ROM Select emulator.Memory.SelectUpperROM(GetByte(Indices.ROMSelect)); // PPI emulator.PPI.WritePortC(GetByte(Indices.PPIControl)); emulator.PPI.SetPortA(GetByte(Indices.PPIPortA)); emulator.PPI.SetPortB(GetByte(Indices.PPIPortB)); emulator.PPI.SetPortC(GetByte(Indices.PPIPortC)); // PSG emulator.PSG.SelectRegister((PSG.Register)GetByte(Indices.PSGSelRegister)); for (int i = 0; i < PSG.NUM_REGISTERS; i++) { emulator.PSG.WriteRegister((PSG.Register)i, GetByte(Indices.PSGRegData + i)); } // Extra stuff for v3 snapshots if (GetByte(Indices.Version) >= 3) { emulator.CRTC.SetTiming( GetByte(Indices.CRTCHorizChar), GetByte(Indices.CRTCVertChar), GetByte(Indices.CRTCScanline), GetByte(Indices.CRTCHSyncCount), GetByte(Indices.CRTCVSyncCount), (GetByte(Indices.CRTCStateFlags) & (1 << 1)) != 0, //< HSync Active (GetByte(Indices.CRTCStateFlags) & (1 << 0)) != 0 //< VSync Active ); emulator.GateArray.SetCounters( GetByte(Indices.GAScanlineCount), GetByte(Indices.GAVSyncDelay) ); emulator.Processor.SetInterruptRequest(GetByte(Indices.CPUIRQFlag) != 0); } // Memory Dump int mem_size = GetWord(Indices.MemDumpSizeHigh, Indices.MemDumpSizeLow); Debug.Assert((mem_size == 64) || (mem_size == 128)); //< NOTE: 128k not currently supported emulator.Memory.SetRAM(m_data, (int)Indices.MemDump, mem_size); }