IOS: Implement MIOS functionality

This implements MIOS's PPC bootstrapping functionality, which enables
users to start a GameCube game from the Wii System Menu.

Because we aren't doing Starlet LLE (and don't have a boot1), we can
just jump to MIOS when the emulated software does an ES_LAUNCH or uses
ioctlv 0x25 to launch BC.

Note that the process is more complex on a real Wii and goes through
several more steps before getting to MIOS:

* The System Menu detects a GameCube disc and launches BC (1-100)
  instead of the game. [Dolphin does this too.]

* BC, which is reportedly very similar to boot1, lowers the Hollywood
  clock speed to the Flipper's and then launches boot2.

* boot2 sees the lowered clock speed and launches MIOS (1-101) instead
  of the System Menu.

MIOS runs instead of IOS in GC mode and has an embedded GC IPL (which
is the code actually responsible for loading the disc game) and a PPC
bootstrap code. To get things working properly, we simply need to load
both to memory, then jump to the bootstrap code at 0x3400.

Obviously, because of the way this works, a real MIOS is required.
This commit is contained in:
Léo Lam committed 2017-02-08 15:07:34 +01:00
1 parent 4662e25cbb
commit fdfe57a49b
25 files changed
+362 -67

No files matched your search

+1 -1
View File
@@ -35,6 +35,7 @@ public:
// Returns true if a map file exists, false if none could be found.
static bool FindMapFile(std::string* existing_map_file, std::string* writable_map_file,
std::string* title_id = nullptr);
static bool LoadMapFromFilename();
private:
static bool DVDRead(u64 dvd_offset, u32 output_address, u32 length, bool decrypt);
@@ -42,7 +43,6 @@ private:
static void UpdateDebugger_MapLoaded();
static bool LoadMapFromFilename();
static bool Boot_ELF(const std::string& filename);
static bool Boot_WiiWAD(const std::string& filename);
+4 -1
View File
@@ -102,7 +102,7 @@ const char* ElfReader::GetSectionName(int section) const
}
// This is just a simple elf loader, good enough to load elfs generated by devkitPPC
bool ElfReader::LoadIntoMemory()
bool ElfReader::LoadIntoMemory(bool only_in_mem1)
{
INFO_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx);
@@ -132,6 +132,9 @@ bool ElfReader::LoadIntoMemory()
u32 srcSize = p->p_filesz;
u32 dstSize = p->p_memsz;
if (only_in_mem1 && p->p_vaddr >= Memory::REALRAM_SIZE)
continue;
Memory::CopyToEmu(writeAddr, src, srcSize);
if (srcSize < dstSize)
Memory::Memset(writeAddr + srcSize, 0, dstSize - srcSize); // zero out bss
+1 -1
View File
@@ -39,7 +39,7 @@ public:
ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
u32 GetEntryPoint() const { return entryPoint; }
u32 GetFlags() const { return (u32)(header->e_flags); }
bool LoadIntoMemory();
bool LoadIntoMemory(bool only_in_mem1 = false);
bool LoadSymbols();
int GetNumSegments() const { return (int)(header->e_phnum); }