MemoryCard: Split into image helper functions

This commit is contained in:
Connor McLaughlin
2020-09-19 00:26:19 +10:00
parent 70768c02af
commit 92da9917a8
7 changed files with 534 additions and 114 deletions

View File

@ -107,7 +107,7 @@ bool MemoryCard::Transfer(const u8 data_in, u8* data_out)
case State::ReadData:
{
const u8 bits = m_data[ZeroExtend32(m_address) * SECTOR_SIZE + m_sector_offset];
const u8 bits = m_data[ZeroExtend32(m_address) * MemoryCardImage::FRAME_SIZE + m_sector_offset];
if (m_sector_offset == 0)
{
Log_DevPrintf("Reading memory card sector %u", ZeroExtend32(m_address));
@ -122,7 +122,7 @@ bool MemoryCard::Transfer(const u8 data_in, u8* data_out)
ack = true;
m_sector_offset++;
if (m_sector_offset == SECTOR_SIZE)
if (m_sector_offset == MemoryCardImage::FRAME_SIZE)
{
m_state = State::ReadChecksum;
m_sector_offset = 0;
@ -153,7 +153,7 @@ bool MemoryCard::Transfer(const u8 data_in, u8* data_out)
m_checksum ^= data_in;
}
const u32 offset = ZeroExtend32(m_address) * SECTOR_SIZE + m_sector_offset;
const u32 offset = ZeroExtend32(m_address) * MemoryCardImage::FRAME_SIZE + m_sector_offset;
m_changed |= (m_data[offset] != data_in);
m_data[offset] = data_in;
@ -161,7 +161,7 @@ bool MemoryCard::Transfer(const u8 data_in, u8* data_out)
ack = true;
m_sector_offset++;
if (m_sector_offset == SECTOR_SIZE)
if (m_sector_offset == MemoryCardImage::FRAME_SIZE)
{
m_state = State::WriteChecksum;
m_sector_offset = 0;
@ -262,96 +262,15 @@ std::unique_ptr<MemoryCard> MemoryCard::Open(std::string_view filename)
return mc;
}
u8 MemoryCard::ChecksumFrame(const u8* fptr)
{
u8 value = 0;
for (u32 i = 0; i < SECTOR_SIZE - 1; i++)
value ^= fptr[i];
return value;
}
void MemoryCard::Format()
{
// fill everything with FF
m_data.fill(u8(0xFF));
// header
{
u8* fptr = GetSectorPtr(0);
std::fill_n(fptr, SECTOR_SIZE, u8(0));
fptr[0] = 'M';
fptr[1] = 'C';
fptr[0x7F] = ChecksumFrame(fptr);
}
// directory
for (u32 frame = 1; frame < 16; frame++)
{
u8* fptr = GetSectorPtr(frame);
std::fill_n(fptr, SECTOR_SIZE, u8(0));
fptr[0] = 0xA0; // free
fptr[8] = 0xFF; // pointer to next file
fptr[9] = 0xFF; // pointer to next file
fptr[0x7F] = ChecksumFrame(fptr); // checksum
}
// broken sector list
for (u32 frame = 16; frame < 36; frame++)
{
u8* fptr = GetSectorPtr(frame);
std::fill_n(fptr, SECTOR_SIZE, u8(0));
fptr[0] = 0xFF;
fptr[1] = 0xFF;
fptr[2] = 0xFF;
fptr[3] = 0xFF;
fptr[8] = 0xFF; // pointer to next file
fptr[9] = 0xFF; // pointer to next file
fptr[0x7F] = ChecksumFrame(fptr); // checksum
}
// broken sector replacement data
for (u32 frame = 36; frame < 56; frame++)
{
u8* fptr = GetSectorPtr(frame);
std::fill_n(fptr, SECTOR_SIZE, u8(0x00));
}
// unused frames
for (u32 frame = 56; frame < 63; frame++)
{
u8* fptr = GetSectorPtr(frame);
std::fill_n(fptr, SECTOR_SIZE, u8(0x00));
}
// write test frame
std::memcpy(GetSectorPtr(63), GetSectorPtr(0), SECTOR_SIZE);
MemoryCardImage::Format(&m_data);
m_changed = true;
}
u8* MemoryCard::GetSectorPtr(u32 sector)
{
Assert(sector < NUM_SECTORS);
return &m_data[sector * SECTOR_SIZE];
}
bool MemoryCard::LoadFromFile()
{
std::unique_ptr<ByteStream> stream =
FileSystem::OpenFile(m_filename.c_str(), BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
if (!stream)
return false;
const size_t num_read = stream->Read(m_data.data(), SECTOR_SIZE * NUM_SECTORS);
if (num_read != (SECTOR_SIZE * NUM_SECTORS))
{
Log_ErrorPrintf("Only read %zu of %u sectors from '%s'", num_read / SECTOR_SIZE, NUM_SECTORS, m_filename.c_str());
return false;
}
Log_InfoPrintf("Loaded memory card from %s", m_filename.c_str());
return true;
return MemoryCardImage::LoadFromFile(&m_data, m_filename.c_str());
}
bool MemoryCard::SaveIfChanged(bool display_osd_message)
@ -366,27 +285,19 @@ bool MemoryCard::SaveIfChanged(bool display_osd_message)
if (m_filename.empty())
return false;
std::unique_ptr<ByteStream> stream =
FileSystem::OpenFile(m_filename.c_str(), BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_TRUNCATE | BYTESTREAM_OPEN_WRITE |
BYTESTREAM_OPEN_ATOMIC_UPDATE | BYTESTREAM_OPEN_STREAMED);
if (!stream)
if (!MemoryCardImage::SaveToFile(m_data, m_filename.c_str()))
{
Log_ErrorPrintf("Failed to open '%s' for writing.", m_filename.c_str());
if (display_osd_message)
{
g_host_interface->AddOSDMessage(
StringUtil::StdStringFromFormat("Failed to save memory card to '%s'", m_filename.c_str()), 20.0f);
}
return false;
}
if (!stream->Write2(m_data.data(), SECTOR_SIZE * NUM_SECTORS) || !stream->Commit())
{
Log_ErrorPrintf("Failed to write sectors to '%s'", m_filename.c_str());
stream->Discard();
return false;
}
Log_InfoPrintf("Saved memory card to '%s'", m_filename.c_str());
if (display_osd_message)
{
g_host_interface->AddOSDMessage(StringUtil::StdStringFromFormat("Saved memory card to '%s'", m_filename.c_str()));
}
return true;
}