public static void SetupExecutionState(BootMode bootMode) { if (bootMode == BootMode.IPL_ROM) { throw new InvalidOperationException("Low-level IPL booting not supported yet"); //Machine.Current.RCP.State.PC = 0x1FC00000; /* TODO: * Schedule CPU and RCP threads to execute MIPS Interpreter * Have CPU sit idle, and RCP execute the PIF Rom * */ } else if (bootMode == BootMode.HLE_IPL) { if (Machine.Current.DeviceRCP.DevicePI.InsertedCartridge != null) { /* Code taken from mupen64plus-core on github */ ExecutionState state = Machine.Current.DeviceCPU.State; state.PC = 0xA4000040; /* PI Setup */ PIRegisters piRegs = Machine.Current.DeviceRCP.MMIO_PI; PiBusSpeedConfig config = Cartridge.Current.RomImage.BusConfig; piRegs.Domain1Latency = (UInt32)config.DeviceLatency; piRegs.Domain1PageSize = (UInt32)config.PageSize; piRegs.Domain1PulseWidth = (UInt32)config.PulseWidth; piRegs.Domain1Release = (UInt32)config.ReleaseTime; piRegs.Status = 0; /* sp_register.sp_status_reg = 1; rsp_register.rsp_pc = 0; ai_register.ai_dram_addr = 0; ai_register.ai_len = 0; vi_register.vi_v_intr = 1023; vi_register.vi_current = 0; vi_register.vi_h_start = 0; MI_register.mi_intr_reg &= ~(0x10 | 0x8 | 0x4 | 0x1) */ logger.Debug("PIF HLE: Copying cartridge bootrom into DMEM + 0x40"); Machine.Current.N64MemorySafe.Position = N64MemRegions.SPDMem.ToRegionAddress() + 0x40; Machine.Current.DeviceRCP.DevicePI.InsertedCartridge.RomImage.BootRomInformation.CopyCode(Machine.Current.N64MemorySafe); state.GPRRegs[19] = 0; /* 0: Cart, 1: DiskDrive */ state.GPRRegs[20] = (UInt64)((Int32)Cartridge.Current.RomImage.Region) - 1; state.GPRRegs[21] = 0; /* 0: ColdReset, 1: NMI */ state.GPRRegs[22] = (UInt64)Cartridge.Current.RomImage.BootRomInformation.CIC.Seed(); state.GPRRegs[23] = 0; /* S7: Unknown */ /* Required by CIC X105 */ BinaryWriter bw = new BinaryWriter(Machine.Current.N64MemorySafe); bw.BaseStream.Position = 0x04001000; bw.Write(0x3c0dbfc0U); bw.Write(0x8da807fcU); bw.Write(0x25ad07c0U); bw.Write(0x31080080U); bw.Write(0x5500fffcU); bw.Write(0x3c0dbfc0U); bw.Write(0x8da80024U); bw.Write(0x3c0bb000U); /* Required by CIC X105 */ state.GPRRegs[11] = 0xffffffffa4000040UL; /* T3 */ state.GPRRegs[29] = 0xffffffffa4001ff0UL; /* SP */ state.GPRRegs[31] = 0xffffffffa4001550UL; /* RA */ } else { logger.Warn("No cartridge inserted, skipping IPL boot"); Machine.Current.DeviceCPU.State.PC = 0xBFC00000; } logger.Debug("ROM Entry Point: " + Machine.Current.DeviceCPU.State.PC.ToString("X8")); } else if (bootMode == BootMode.HLE_IPL_OLD) { if (Machine.Current.DeviceRCP.DevicePI.InsertedCartridge != null) { /* This is the older method of booting the emulator */ Machine.Current.DeviceCPU.State.PC = 0xA4000040; /* This simulates the effects of the PIF Bootloader */ /* 1. Copy the game cartrdige boot rom into SP Memory * 2. Load a snapshot of the CPU / Memory state generated by the real PIF boot sequence */ logger.Debug("PIF HLE: Copying cartridge bootrom into DMEM + 0x40"); Machine.Current.N64MemorySafe.Position = N64MemRegions.SPDMem.ToRegionAddress() + 0x40; Machine.Current.DeviceRCP.DevicePI.InsertedCartridge.RomImage.BootRomInformation.CopyCode(Machine.Current.N64MemorySafe); using (Stream stream = typeof(SoftBootManager).Assembly.GetManifestResourceStream("Soft64.BootStateSnapshots.xml")) { CartridgeInfo info = Cartridge.Current.GetCartridgeInfo(); CICKeyType cic = Cartridge.Current.RomImage.BootRomInformation.CIC; BootSnapReader bootsnap = new BootSnapReader(stream); bootsnap.LoadBootSnap(cic, info.RegionCode); } } else { logger.Warn("No cartridge inserted, skipping IPL boot"); Machine.Current.DeviceCPU.State.PC = 0xBFC00000; } logger.Debug("ROM Entry Point: " + Machine.Current.DeviceCPU.State.PC.ToString("X8")); } else { throw new ArgumentException("Unknown bootmode"); } }
public static void SetupExecutionState(BootMode bootMode) { if (bootMode == BootMode.IPL_ROM) { throw new InvalidOperationException("Low-level IPL booting not supported yet"); //Machine.Current.RCP.State.PC = 0x1FC00000; /* TODO: * Schedule CPU and RCP threads to execute MIPS Interpreter * Have CPU sit idle, and RCP execute the PIF Rom * */ } else if (bootMode == BootMode.HLE_IPL) { if (Machine.Current.DeviceRCP.Interface_Parallel.InsertedCartridge != null) { /* Code taken from mupen64plus-core on github */ ExecutionState state = Machine.Current.DeviceCPU.State; state.PC = 0xA4000040; /* PI Setup */ var pi = Machine.Current.Memory.PI; PiBusSpeedConfig config = Cartridge.Current.RomImage.BusConfig; pi.Domain1Latency = config.DeviceLatency; pi.Domain1PageSize = config.PageSize; pi.Domain1PulseWidth = config.PulseWidth; pi.Domain1Release = config.ReleaseTime; pi.Status.DataShared = 0; /* TODO: sp_register.sp_status_reg = 1; * rsp_register.rsp_pc = 0; * * ai_register.ai_dram_addr = 0; * ai_register.ai_len = 0; * * vi_register.vi_v_intr = 1023; * vi_register.vi_current = 0; * vi_register.vi_h_start = 0; * * /* MI Setup */ var mi = Machine.Current.Memory.MI; mi.VersionReg.DataToMaster = 0x02020102; mi.VersionReg.DataToSlave &= ~(0x10U | 0x8U | 0x4U | 0x1U); PifHleCopyBootRom(); state.GPRRegs[19] = 0; /* 0: Cart, 1: DiskDrive */ state.GPRRegs[20] = (UInt64)((Int32)Cartridge.Current.RomImage.Region) - 1; state.GPRRegs[21] = 0; /* 0: ColdReset, 1: NMI */ state.GPRRegs[22] = (UInt64)Cartridge.Current.RomImage.BootRomInformation.CIC.Seed(); state.GPRRegs[23] = 0; /* S7: Unknown */ /* Required by CIC X105 */ BinaryWriter bw = new BinaryWriter(Machine.Current.Memory); bw.BaseStream.Position = 0x04001000; bw.Write(0x3c0dbfc0U); bw.Write(0x8da807fcU); bw.Write(0x25ad07c0U); bw.Write(0x31080080U); bw.Write(0x5500fffcU); bw.Write(0x3c0dbfc0U); bw.Write(0x8da80024U); bw.Write(0x3c0bb000U); /* Required by CIC X105 */ state.GPRRegs[11] = 0xffffffffa4000040UL; /* T3 */ state.GPRRegs[29] = 0xffffffffa4001ff0UL; /* SP */ state.GPRRegs[31] = 0xffffffffa4001550UL; /* RA */ } else { logger.Warn("No cartridge inserted, skipping IPL boot"); Machine.Current.DeviceCPU.State.PC = 0xBFC00000; } logger.Debug("ROM Entry Point: " + Machine.Current.DeviceCPU.State.PC.ToString("X8")); } else if (bootMode == BootMode.HLE_IPL_OLD) { if (Machine.Current.DeviceRCP.Interface_Parallel.InsertedCartridge != null) { /* This is the older method of booting the emulator */ Machine.Current.DeviceCPU.State.PC = 0xA4000040; /* This simulates the effects of the PIF Bootloader */ /* 1. Copy the game cartrdige boot rom into SP Memory * 2. Load a snapshot of the CPU / Memory state generated by the real PIF boot sequence */ PifHleCopyBootRom(); using (Stream stream = typeof(SoftBootManager).Assembly.GetManifestResourceStream("Soft64.BootStateSnapshots.xml")) { CartridgeInfo info = Cartridge.Current.GetCartridgeInfo(); CICKeyType cic = Cartridge.Current.RomImage.BootRomInformation.CIC; BootSnapReader bootsnap = new BootSnapReader(stream); bootsnap.LoadBootSnap(cic, info.RegionCode); } } else { logger.Warn("No cartridge inserted, skipping IPL boot"); Machine.Current.DeviceCPU.State.PC = 0xBFC00000; } logger.Debug("ROM Entry Point: " + Machine.Current.DeviceCPU.State.PC.ToString("X8")); } else { throw new ArgumentException("Unknown bootmode"); } }