29#include <EASTL/functional.h>
165 : m_device(device), m_port(port), m_sector(
sector), m_buffer(
buffer) {}
167 template <
typename U>
181 Error m_result = Error::OK;
186 : m_device(device), m_port(port), m_sector(
sector), m_buffer(
buffer) {}
188 template <
typename U>
201 const void *m_buffer;
202 Error m_result = Error::OK;
218 static constexpr bool c_useIrq =
true;
225 static bool isTransient(
Error error);
228 enum class Action : uint8_t { None, Read, Write };
229 enum class StepResult { Continue, Done };
231 void installIrqHandler();
233 void startTransfer(Action action,
Port port, uint16_t
sector,
void *readBuf,
const void *writeBuf);
235 StepResult readStep();
236 StepResult writeStep();
237 uint8_t exchangeByte(uint8_t
out);
238 Error irqTransferBlocking(Action action,
Port port, uint16_t
sector,
void *readBuf,
const void *writeBuf);
244 void startAsyncAttempt(Action action,
Port port, uint16_t
sector,
void *readBuf,
const void *writeBuf);
246 static uint16_t portMask(
Port port);
251 void selectPort(
Port port);
253 void flushRxBuffer();
254 uint8_t transceive(uint8_t dataOut);
260 void recoverBeforeSelect();
262 static void busyLoop(
unsigned delay) {
264 while (++cycles < delay)
asm(
"");
268 volatile Action m_action = Action::None;
270 Port m_port = Port::Port0;
271 uint16_t m_sector = 0;
272 uint8_t *m_readBuffer =
nullptr;
273 const uint8_t *m_writeBuffer =
nullptr;
274 uint8_t m_runningChecksum = 0;
275 uint8_t m_cardChecksum = 0;
276 volatile bool m_done =
false;
277 volatile Error m_result = Error::OK;
278 bool m_blocking =
false;
283 eastl::function<
void(
Error)> m_userCallback;
284 Action m_retryAction = Action::None;
285 unsigned m_attempt = 0;
293 static constexpr uint32_t c_ackTimeoutShort = 0x4000;
297 static constexpr uint32_t c_ackTimeoutLong = 0x40000;
298 static constexpr uint32_t c_ackHighTimeout = 0x4000;
300 static constexpr unsigned c_selectDelay = 100;
308 static constexpr unsigned c_interTransactionDelay = 70000;
310 static constexpr unsigned c_maxAttempts = 3;
313 static constexpr uint32_t c_irqWatchdog = 0x800000;
A low level driver for the PlayStation memory cards.
Definition memory-card.hh:67
Error
The error codes returned by every memory card operation.
Definition memory-card.hh:75
static constexpr uint32_t c_sectorSize
Definition memory-card.hh:101
static constexpr uint32_t sectorCount()
Definition memory-card.hh:108
static constexpr uint32_t c_sectorsPerBlock
Definition memory-card.hh:105
Port
The memory card port to talk to.
Definition memory-card.hh:98
Error writeSectorBlocking(Port port, uint16_t sector, const void *buffer)
Writes a single 128-byte sector synchronously.
Definition memory-card.cpp:704
static constexpr uint32_t sectorSize()
Definition memory-card.hh:107
static constexpr uint32_t blockCount()
Definition memory-card.hh:110
TaskQueue::Task scheduleReadSector(Port port, uint16_t sector, void *buffer, Error *resultOut)
Definition memory-card.cpp:782
WriteSectorAwaiter writeSector(Port port, uint16_t sector, const void *buffer)
Definition memory-card.hh:206
static const char * errorMessage(Error error)
Returns a human readable string for an error code.
Definition memory-card.cpp:62
void writeSector(Port port, uint16_t sector, const void *buffer, eastl::function< void(Error)> &&callback)
Definition memory-card.cpp:742
Error readSectorBlocking(Port port, uint16_t sector, void *buffer)
Reads a single 128-byte sector synchronously.
Definition memory-card.cpp:700
ReadSectorAwaiter readSector(Port port, uint16_t sector, void *buffer)
Definition memory-card.hh:205
void readSector(Port port, uint16_t sector, void *buffer, eastl::function< void(Error)> &&callback)
Definition memory-card.cpp:718
TaskQueue::Task scheduleWriteSector(Port port, uint16_t sector, const void *buffer, Error *resultOut)
Definition memory-card.cpp:792
static constexpr uint32_t c_blockSize
Definition memory-card.hh:103
static constexpr uint32_t c_sectorCount
Definition memory-card.hh:102
Error probeBlocking(Port port)
Probes the card for presence.
Definition memory-card.cpp:708
static constexpr uint32_t blockSize()
Definition memory-card.hh:109
void prepare()
Prepares the SIO0 bus for memory card access.
Definition memory-card.cpp:102
static constexpr uint32_t c_blockCount
Definition memory-card.hh:104
The Task class.
Definition task.hh:140
uint32_t out
Definition cpu.c:62
unsigned timeout
Definition dma.c:115
char in[50]
Definition memcpy.c:74
void * result
Definition memcpy.c:47
Definition memory-card.hh:163
Error await_resume()
Definition memory-card.hh:174
bool await_ready() const
Definition memory-card.hh:166
ReadSectorAwaiter(MemoryCard &device, Port port, uint16_t sector, void *buffer)
Definition memory-card.hh:164
void await_suspend(std::coroutine_handle< U > handle)
Definition memory-card.hh:168
Definition memory-card.hh:184
WriteSectorAwaiter(MemoryCard &device, Port port, uint16_t sector, const void *buffer)
Definition memory-card.hh:185
bool await_ready() const
Definition memory-card.hh:187
void await_suspend(std::coroutine_handle< U > handle)
Definition memory-card.hh:189
Error await_resume()
Definition memory-card.hh:195
static void * buffer
Definition syscalls.h:231
static int sector
Definition syscalls.h:468
void uint32_t(classId, spec)