95 lines
3.1 KiB
C++
95 lines
3.1 KiB
C++
#include "icsneo/disk/neomemorydiskdriver.h"
|
|
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
|
#include "icsneo/communication/message/flashmemorymessage.h"
|
|
#include <cstring>
|
|
#include <iostream>
|
|
|
|
using namespace icsneo;
|
|
using namespace icsneo::Disk;
|
|
|
|
std::optional<uint64_t> 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<MessageFilter>((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<NeoReadMemorySDMessage>(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<FlashMemoryMessage>(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<uint64_t> NeoMemoryDiskDriver::writeLogicalDiskAligned(Communication& com, device_eventhandler_t,
|
|
uint64_t pos, const uint8_t* from, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) {
|
|
|
|
static std::shared_ptr<MessageFilter> NeoMemoryDone = std::make_shared<MessageFilter>(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<uint8_t> 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;
|
|
} |