memory_card.h (2304B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "controller.h" 7 #include "memory_card_image.h" 8 #include "timing_event.h" 9 10 #include "common/bitfield.h" 11 12 #include <array> 13 #include <memory> 14 #include <string> 15 #include <string_view> 16 17 class MemoryCard final 18 { 19 public: 20 MemoryCard(); 21 ~MemoryCard(); 22 23 static constexpr u32 STATE_SIZE = 1 + 1 + 2 + 1 + 1 + 1 + MemoryCardImage::DATA_SIZE + 1; 24 25 static std::unique_ptr<MemoryCard> Create(); 26 static std::unique_ptr<MemoryCard> Open(std::string_view filename); 27 28 const MemoryCardImage::DataArray& GetData() const { return m_data; } 29 MemoryCardImage::DataArray& GetData() { return m_data; } 30 const std::string& GetFilename() const { return m_filename; } 31 void SetFilename(std::string filename) { m_filename = std::move(filename); } 32 33 void Reset(); 34 bool DoState(StateWrapper& sw); 35 void CopyState(const MemoryCard* src); 36 37 void ResetTransferState(); 38 bool Transfer(const u8 data_in, u8* data_out); 39 40 bool IsOrWasRecentlyWriting() const; 41 42 void Format(); 43 44 private: 45 enum : u32 46 { 47 // save in three seconds, that should be long enough for everything to finish writing 48 SAVE_DELAY_IN_SECONDS = 5, 49 }; 50 51 union FLAG 52 { 53 u8 bits; 54 55 BitField<u8, bool, 3, 1> no_write_yet; 56 BitField<u8, bool, 2, 1> write_error; 57 }; 58 59 enum class State : u8 60 { 61 Idle, 62 Command, 63 64 ReadCardID1, 65 ReadCardID2, 66 ReadAddressMSB, 67 ReadAddressLSB, 68 ReadACK1, 69 ReadACK2, 70 ReadConfirmAddressMSB, 71 ReadConfirmAddressLSB, 72 ReadData, 73 ReadChecksum, 74 ReadEnd, 75 76 WriteCardID1, 77 WriteCardID2, 78 WriteAddressMSB, 79 WriteAddressLSB, 80 WriteData, 81 WriteChecksum, 82 WriteACK1, 83 WriteACK2, 84 WriteEnd, 85 86 GetIDCardID1, 87 GetIDCardID2, 88 GetIDACK1, 89 GetIDACK2, 90 GetID1, 91 GetID2, 92 GetID3, 93 GetID4, 94 }; 95 96 static TickCount GetSaveDelayInTicks(); 97 98 bool SaveIfChanged(bool display_osd_message); 99 void QueueFileSave(); 100 101 State m_state = State::Idle; 102 FLAG m_FLAG = {}; 103 u16 m_address = 0; 104 u8 m_sector_offset = 0; 105 u8 m_checksum = 0; 106 u8 m_last_byte = 0; 107 bool m_changed = false; 108 109 TimingEvent m_save_event; 110 std::string m_filename; 111 112 MemoryCardImage::DataArray m_data{}; 113 };