testing
This commit is contained in:
parent
88618bde1c
commit
da0417bb46
100
src/core/bus.cpp
100
src/core/bus.cpp
|
@ -189,6 +189,8 @@ bool DoState(StateWrapper& sw)
|
||||||
void SetExpansionROM(std::vector<u8> data)
|
void SetExpansionROM(std::vector<u8> data)
|
||||||
{
|
{
|
||||||
m_exp1_rom = std::move(data);
|
m_exp1_rom = std::move(data);
|
||||||
|
if (m_exp1_rom.size() < 256 * 1024)
|
||||||
|
m_exp1_rom.resize(256 * 1024, 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBIOS(const std::vector<u8>& image)
|
void SetBIOS(const std::vector<u8>& image)
|
||||||
|
@ -813,24 +815,38 @@ ALWAYS_INLINE static TickCount DoBIOSAccess(u32 offset, u32& value)
|
||||||
return m_bios_access_time[static_cast<u32>(size)];
|
return m_bios_access_time[static_cast<u32>(size)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool flash_unlocked = false;
|
||||||
|
static bool chip_id_mode = false;
|
||||||
|
static u8 chip_id[] = {0x1F, 0xA4};
|
||||||
|
static u8 flash_command_key[] = {0xAA, 0x55};
|
||||||
|
static u8 flash_command_sequence = 0;
|
||||||
|
|
||||||
template<MemoryAccessType type, MemoryAccessSize size>
|
template<MemoryAccessType type, MemoryAccessSize size>
|
||||||
static TickCount DoEXP1Access(u32 offset, u32& value)
|
static TickCount DoEXP1Access(u32 offset, u32& value)
|
||||||
{
|
{
|
||||||
|
constexpr u32 transfer_size = u32(1) << static_cast<u32>(size);
|
||||||
|
|
||||||
if constexpr (type == MemoryAccessType::Read)
|
if constexpr (type == MemoryAccessType::Read)
|
||||||
{
|
{
|
||||||
if (m_exp1_rom.empty())
|
if (chip_id_mode)
|
||||||
|
{
|
||||||
|
if ((offset + transfer_size) > sizeof(chip_id))
|
||||||
|
value = 0;
|
||||||
|
else
|
||||||
|
std::memcpy(&value, &chip_id[offset], sizeof(value));
|
||||||
|
}
|
||||||
|
else if (m_exp1_rom.empty())
|
||||||
{
|
{
|
||||||
// EXP1 not present.
|
// EXP1 not present.
|
||||||
value = UINT32_C(0xFFFFFFFF);
|
value = UINT32_C(0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
else if (offset == 0x20018)
|
else if (offset == 0x60000)
|
||||||
{
|
{
|
||||||
// Bit 0 - Action Replay On/Off
|
// Bit 0 - Action Replay On/Off
|
||||||
value = UINT32_C(1);
|
value = UINT32_C(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const u32 transfer_size = u32(1) << static_cast<u32>(size);
|
|
||||||
if ((offset + transfer_size) > m_exp1_rom.size())
|
if ((offset + transfer_size) > m_exp1_rom.size())
|
||||||
{
|
{
|
||||||
value = UINT32_C(0);
|
value = UINT32_C(0);
|
||||||
|
@ -861,6 +877,69 @@ static TickCount DoEXP1Access(u32 offset, u32& value)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log_WarningPrintf("EXP1 write: 0x%08X <- 0x%08X", EXP1_BASE | offset, value);
|
Log_WarningPrintf("EXP1 write: 0x%08X <- 0x%08X", EXP1_BASE | offset, value);
|
||||||
|
|
||||||
|
if (offset == 0x5555 && value == 0xAA && flash_command_sequence == 0)
|
||||||
|
{
|
||||||
|
flash_command_sequence = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (offset == 0x2AAA && value == 0x55 && flash_command_sequence == 1)
|
||||||
|
{
|
||||||
|
flash_command_sequence = 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (offset == 0x5555 && flash_command_sequence == 2)
|
||||||
|
{
|
||||||
|
flash_command_sequence = 0;
|
||||||
|
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0xA0:
|
||||||
|
{
|
||||||
|
Log_DevPrintf("Flash unlocked");
|
||||||
|
flash_unlocked = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x90:
|
||||||
|
{
|
||||||
|
Log_DevPrintf("Enter ID mode");
|
||||||
|
chip_id_mode = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xF0:
|
||||||
|
{
|
||||||
|
Log_DevPrintf("Exit ID mode");
|
||||||
|
chip_id_mode = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x80:
|
||||||
|
{
|
||||||
|
Log_WarningPrintf("Erase chip 1");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x10:
|
||||||
|
{
|
||||||
|
Log_WarningPrintf("Erase chip 2");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Unknown flash command 0x%02X", value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((offset + transfer_size) <= m_exp1_rom.size())
|
||||||
|
std::memcpy(&m_exp1_rom[offset], &value, sizeof(value));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1294,12 +1373,25 @@ ALWAYS_INLINE_RELEASE bool DoInstructionRead(PhysicalMemoryAddress address, void
|
||||||
}
|
}
|
||||||
else if (address >= BIOS_BASE && address < (BIOS_BASE + BIOS_SIZE))
|
else if (address >= BIOS_BASE && address < (BIOS_BASE + BIOS_SIZE))
|
||||||
{
|
{
|
||||||
std::memcpy(data, &g_bios[(address - BIOS_BASE) & BIOS_MASK], sizeof(u32) * word_count);
|
std::memcpy(data, &g_bios[address - BIOS_BASE], sizeof(u32) * word_count);
|
||||||
if constexpr (add_ticks)
|
if constexpr (add_ticks)
|
||||||
g_state.pending_ticks += m_bios_access_time[static_cast<u32>(MemoryAccessSize::Word)] * word_count;
|
g_state.pending_ticks += m_bios_access_time[static_cast<u32>(MemoryAccessSize::Word)] * word_count;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (address >= EXP1_BASE && address < (EXP1_BASE + EXP1_SIZE))
|
||||||
|
{
|
||||||
|
const u32 offset = (address - EXP1_BASE);
|
||||||
|
if ((offset + (word_count * sizeof(u32))) <= m_exp1_rom.size())
|
||||||
|
std::memcpy(data, m_exp1_rom.data() + offset, sizeof(u32) * word_count);
|
||||||
|
else
|
||||||
|
std::memset(data, 0, sizeof(u32) * word_count);
|
||||||
|
|
||||||
|
if constexpr (add_ticks)
|
||||||
|
g_state.pending_ticks += m_exp1_access_time[static_cast<u32>(MemoryAccessSize::Word)] * word_count;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (raise_exceptions)
|
if (raise_exceptions)
|
||||||
|
|
|
@ -399,6 +399,19 @@ bool HostInterface::HasAnyBIOSImages()
|
||||||
return (FindBIOSImageInDirectory(ConsoleRegion::Auto, dir.c_str()).has_value());
|
return (FindBIOSImageInDirectory(ConsoleRegion::Auto, dir.c_str()).has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::vector<u8>> HostInterface::GetExpansionROMImage()
|
||||||
|
{
|
||||||
|
std::string filename = GetStringSettingValue("BIOS", "ExpansionROMPath", "");
|
||||||
|
if (filename.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(filename.c_str()));
|
||||||
|
if (!ret)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool HostInterface::LoadState(const char* filename)
|
bool HostInterface::LoadState(const char* filename)
|
||||||
{
|
{
|
||||||
std::unique_ptr<ByteStream> stream = FileSystem::OpenFile(filename, BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
|
std::unique_ptr<ByteStream> stream = FileSystem::OpenFile(filename, BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
|
||||||
|
|
|
@ -142,6 +142,9 @@ public:
|
||||||
/// Returns true if any BIOS images are found in the configured BIOS directory.
|
/// Returns true if any BIOS images are found in the configured BIOS directory.
|
||||||
bool HasAnyBIOSImages();
|
bool HasAnyBIOSImages();
|
||||||
|
|
||||||
|
/// Loads the configured expansion ROM image, if any.
|
||||||
|
std::optional<std::vector<u8>> GetExpansionROMImage();
|
||||||
|
|
||||||
/// Opens a file in the DuckStation "package".
|
/// Opens a file in the DuckStation "package".
|
||||||
/// This is the APK for Android builds, or the program directory for standalone builds.
|
/// This is the APK for Android builds, or the program directory for standalone builds.
|
||||||
virtual std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) = 0;
|
virtual std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) = 0;
|
||||||
|
|
|
@ -64,7 +64,6 @@ static bool SaveMemoryState(MemorySaveState* mss);
|
||||||
static bool LoadMemoryState(const MemorySaveState& mss);
|
static bool LoadMemoryState(const MemorySaveState& mss);
|
||||||
|
|
||||||
static bool LoadEXE(const char* filename);
|
static bool LoadEXE(const char* filename);
|
||||||
static bool SetExpansionROM(const char* filename);
|
|
||||||
|
|
||||||
/// Opens CD image, preloading if needed.
|
/// Opens CD image, preloading if needed.
|
||||||
static std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload);
|
static std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload);
|
||||||
|
@ -804,6 +803,15 @@ bool Boot(const SystemBootParameters& params)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load expansion ROM image.
|
||||||
|
std::optional<std::vector<u8>> expansion_rom = g_host_interface->GetExpansionROMImage();
|
||||||
|
if (!expansion_rom)
|
||||||
|
{
|
||||||
|
g_host_interface->ReportError(g_host_interface->TranslateString("System", "Failed to expansion ROM image."));
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Notify change of disc.
|
// Notify change of disc.
|
||||||
UpdateRunningGame(media ? media->GetFileName().c_str() : params.filename.c_str(), media.get());
|
UpdateRunningGame(media ? media->GetFileName().c_str() : params.filename.c_str(), media.get());
|
||||||
|
|
||||||
|
@ -831,6 +839,9 @@ bool Boot(const SystemBootParameters& params)
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus::SetBIOS(*bios_image);
|
Bus::SetBIOS(*bios_image);
|
||||||
|
if (expansion_rom && !expansion_rom->empty())
|
||||||
|
Bus::SetExpansionROM(std::move(*expansion_rom));
|
||||||
|
|
||||||
UpdateControllers();
|
UpdateControllers();
|
||||||
UpdateMemoryCards();
|
UpdateMemoryCards();
|
||||||
UpdateMultitaps();
|
UpdateMultitaps();
|
||||||
|
@ -1683,34 +1694,6 @@ bool InjectEXEFromBuffer(const void* buffer, u32 buffer_size, bool patch_bios)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetExpansionROM(const char* filename)
|
|
||||||
{
|
|
||||||
std::FILE* fp = FileSystem::OpenCFile(filename, "rb");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
Log_ErrorPrintf("Failed to open '%s'", filename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::fseek(fp, 0, SEEK_END);
|
|
||||||
const u32 size = static_cast<u32>(std::ftell(fp));
|
|
||||||
std::fseek(fp, 0, SEEK_SET);
|
|
||||||
|
|
||||||
std::vector<u8> data(size);
|
|
||||||
if (std::fread(data.data(), size, 1, fp) != 1)
|
|
||||||
{
|
|
||||||
Log_ErrorPrintf("Failed to read ROM data from '%s'", filename);
|
|
||||||
std::fclose(fp);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::fclose(fp);
|
|
||||||
|
|
||||||
Log_InfoPrintf("Loaded expansion ROM from '%s': %u bytes", filename, size);
|
|
||||||
Bus::SetExpansionROM(std::move(data));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StallCPU(TickCount ticks)
|
void StallCPU(TickCount ticks)
|
||||||
{
|
{
|
||||||
CPU::AddPendingTicks(ticks);
|
CPU::AddPendingTicks(ticks);
|
||||||
|
|
Loading…
Reference in New Issue