Merge pull request #10821 from Pokechu22/dimar-masking

DVDInterface: Mask upper bits of DIMAR in GC mode
This commit is contained in:
Tilka 2022-08-04 12:50:49 +01:00 committed by GitHub
commit 8105d0034d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 5 deletions

View File

@ -606,7 +606,7 @@ bool UpdateRunningGameMetadata(std::optional<u64> title_id)
return DVDThread::UpdateRunningGameMetadata(IOS::HLE::DIDevice::GetCurrentPartition(), title_id);
}
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
void RegisterMMIO(MMIO::Mapping* mmio, u32 base, bool is_wii)
{
mmio->Register(base | DI_STATUS_REGISTER, MMIO::DirectRead<u32>(&s_DISR.Hex),
MMIO::ComplexWrite<u32>([](u32, u32 val) {
@ -657,8 +657,18 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
// DMA related registers. Mostly direct accesses (+ masking for writes to
// handle things like address alignment) and complex write on the DMA
// control register that will trigger the DMA.
// The DMA address register masks away the top and bottom bits on GameCube, but only the top bits
// on Wii (which can be observed by reading back the register; this difference probably exists due
// to the existence of MEM2). The behavior of GameCube mode on a Wii (via MIOS/booting form the
// system menu) has not been tested yet. Note that RegisterMMIO does not get re-called when
// switching to GameCube mode; we handle this difference by applying the masking when using the
// GameCube's DI MMIO address (0x0C006000) but not applying it when using the Wii's DI MMIO
// address (0x0D006000), although we allow writes to both of these addresses if Dolphin was
// started in Wii mode. (Also, normally in Wii mode the DI MMIOs are only written by the
// IOS /dev/di module, but we *do* emulate /dev/di writing the DI MMIOs.)
mmio->Register(base | DI_DMA_ADDRESS_REGISTER, MMIO::DirectRead<u32>(&s_DIMAR),
MMIO::DirectWrite<u32>(&s_DIMAR, ~0x1F));
MMIO::DirectWrite<u32>(&s_DIMAR, is_wii ? ~0x1F : ~0xFC00001F));
mmio->Register(base | DI_DMA_LENGTH_REGISTER, MMIO::DirectRead<u32>(&s_DILENGTH),
MMIO::DirectWrite<u32>(&s_DILENGTH, ~0x1F));
mmio->Register(base | DI_DMA_CONTROL_REGISTER, MMIO::DirectRead<u32>(&s_DICR.Hex),

View File

@ -113,7 +113,7 @@ void ResetDrive(bool spinup);
void Shutdown();
void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base, bool is_wii);
void SetDisc(std::unique_ptr<DiscIO::VolumeDisc> disc,
std::optional<std::vector<std::string>> auto_disc_change_paths);

View File

@ -141,14 +141,14 @@ static void InitMMIO(bool is_wii)
ProcessorInterface::RegisterMMIO(mmio_mapping.get(), 0x0C003000);
MemoryInterface::RegisterMMIO(mmio_mapping.get(), 0x0C004000);
DSP::RegisterMMIO(mmio_mapping.get(), 0x0C005000);
DVDInterface::RegisterMMIO(mmio_mapping.get(), 0x0C006000);
DVDInterface::RegisterMMIO(mmio_mapping.get(), 0x0C006000, false);
SerialInterface::RegisterMMIO(mmio_mapping.get(), 0x0C006400);
ExpansionInterface::RegisterMMIO(mmio_mapping.get(), 0x0C006800);
AudioInterface::RegisterMMIO(mmio_mapping.get(), 0x0C006C00);
if (is_wii)
{
IOS::RegisterMMIO(mmio_mapping.get(), 0x0D000000);
DVDInterface::RegisterMMIO(mmio_mapping.get(), 0x0D006000);
DVDInterface::RegisterMMIO(mmio_mapping.get(), 0x0D006000, true);
SerialInterface::RegisterMMIO(mmio_mapping.get(), 0x0D006400);
ExpansionInterface::RegisterMMIO(mmio_mapping.get(), 0x0D006800);
AudioInterface::RegisterMMIO(mmio_mapping.get(), 0x0D006C00);