#pragma once #include "common/bitfield.h" #include "controller.h" #include #include #include #include class System; class MemoryCard final { public: enum : u32 { DATA_SIZE = 128 * 1024, // 1mbit SECTOR_SIZE = 128, NUM_SECTORS = DATA_SIZE / SECTOR_SIZE }; MemoryCard(System* system); ~MemoryCard(); static std::shared_ptr Create(System* system); static std::shared_ptr Open(System* system, std::string_view filename); void Reset(); bool DoState(StateWrapper& sw); void ResetTransferState(); bool Transfer(const u8 data_in, u8* data_out); void Format(); private: union FLAG { u8 bits; BitField no_write_yet; BitField write_error; }; FLAG m_FLAG = {}; enum class State : u8 { Idle, Command, ReadCardID1, ReadCardID2, ReadAddressMSB, ReadAddressLSB, ReadACK1, ReadACK2, ReadConfirmAddressMSB, ReadConfirmAddressLSB, ReadData, ReadChecksum, ReadEnd, WriteCardID1, WriteCardID2, WriteAddressMSB, WriteAddressLSB, WriteData, WriteChecksum, WriteACK1, WriteACK2, WriteEnd, }; static u8 ChecksumFrame(const u8* fptr); u8* GetSectorPtr(u32 sector); bool LoadFromFile(); bool SaveToFile(); System* m_system; State m_state = State::Idle; u16 m_address = 0; u8 m_sector_offset = 0; u8 m_checksum = 0; u8 m_last_byte = 0; bool m_changed = false; std::array m_data{}; std::string m_filename; };