#include "icsneo/disk/neomemorydiskdriver.h" #include "icsneo/communication/message/neoreadmemorysdmessage.h" #include "icsneo/communication/message/flashmemorymessage.h" #include #include using namespace icsneo; using namespace icsneo::Disk; std::optional NeoMemoryDiskDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report, uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) { const auto filter = std::make_shared((memType == MemoryType::SD ? Network::NetID::NeoMemorySDRead : Network::NetID::RED_INT_MEMORYREAD)); filter->includeInternalInAny = true; if(pos % SectorSize != 0) return std::nullopt; if(amount != SectorSize) return std::nullopt; const uint64_t currentSector = pos / SectorSize; const uint8_t memLocation = (uint8_t)memType; uint64_t numWords = amount / 2; auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, &numWords] { return com.sendCommand(Command::NeoReadMemory, { memLocation, uint8_t(currentSector & 0xFF), uint8_t((currentSector >> 8) & 0xFF), uint8_t((currentSector >> 16) & 0xFF), uint8_t((currentSector >> 24) & 0xFF), uint8_t(numWords & 0xFF), uint8_t((numWords >> 8) & 0xFF), uint8_t((numWords >> 16) & 0xFF), uint8_t((numWords >> 24) & 0xFF) }); }, filter, timeout); if(!msg) return 0; if(memType == MemoryType::SD) { const auto mem = std::dynamic_pointer_cast(msg); if(!mem || mem->data.size() != SectorSize) { report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return std::nullopt; } memcpy(into, mem->data.data(), SectorSize); } else { // flash const auto mem = std::dynamic_pointer_cast(msg); if(!mem || mem->data.size() != SectorSize) { report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return std::nullopt; } memcpy(into, mem->data.data(), SectorSize); } return SectorSize; } std::optional NeoMemoryDiskDriver::writeLogicalDiskAligned(Communication& com, device_eventhandler_t report, uint64_t pos, const uint8_t* from, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) { static std::shared_ptr NeoMemoryDone = std::make_shared(Network::NetID::NeoMemoryWriteDone); if(pos % SectorSize != 0) return std::nullopt; if(amount != SectorSize) return std::nullopt; const uint64_t currentSector = pos / SectorSize; const uint8_t memLocation = (uint8_t)memType; uint64_t numWords = amount / 2; auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, from, amount, &numWords] { std::vector command = { memLocation, uint8_t(currentSector & 0xFF), uint8_t((currentSector >> 8) & 0xFF), uint8_t((currentSector >> 16) & 0xFF), uint8_t((currentSector >> 24) & 0xFF), uint8_t(numWords & 0xFF), uint8_t((numWords >> 8) & 0xFF), }; command.insert(command.end(), from, from + amount); return com.sendCommand(Command::NeoWriteMemory, command); }, NeoMemoryDone, timeout); if(!msg) return std::nullopt; return SectorSize; }