20static constexpr byte DRT_ACCEPTED = 0x05;
21static constexpr byte DRT_WRITE_ERROR = 0x0D;
24static constexpr byte START_BLOCK_TOKEN = 0xFE;
25static constexpr byte START_BLOCK_TOKEN_MBW = 0xFC;
26static constexpr byte STOP_TRAN_TOKEN = 0xFD;
29static constexpr byte DATA_ERROR_TOKEN_ERROR = 0x01;
30static constexpr byte DATA_ERROR_TOKEN_OUT_OF_RANGE = 0x08;
33static constexpr byte R1_BUSY = 0x00;
34static constexpr byte R1_IDLE = 0x01;
35static constexpr byte R1_ILLEGAL_COMMAND = 0x04;
36static constexpr byte R1_PARAMETER_ERROR = 0x80;
39 : hd(config.getXML() ?
std::make_unique<
HD>(config) : nullptr)
46byte SdCard::readCurrentByteFromCurrentSector()
49 if (currentByteInSector == -1) {
51 hd->readSector(currentSector, sectorBuf);
52 return START_BLOCK_TOKEN;
53 }
catch (MSXException&) {
54 return DATA_ERROR_TOKEN_ERROR;
58 return sectorBuf.
raw[currentByteInSector];
61 currentByteInSector++;
62 if (currentByteInSector ==
sizeof(sectorBuf)) {
79 if (transferDelayCounter > 0) {
80 --transferDelayCounter;
82 if (responseQueue.
empty()) {
85 retval = readCurrentByteFromCurrentSector();
86 if (currentByteInSector ==
sizeof(sectorBuf)) {
95 if (currentSector >= hd->getNbSectors()) {
97 retval = DATA_ERROR_TOKEN_OUT_OF_RANGE;
99 retval = readCurrentByteFromCurrentSector();
100 if (currentByteInSector ==
sizeof(sectorBuf)) {
102 currentByteInSector = -1;
122 if (currentByteInSector == -1) {
123 if (value == START_BLOCK_TOKEN) {
124 currentByteInSector++;
128 if (currentByteInSector <
int(
sizeof(sectorBuf))) {
129 sectorBuf.
raw[currentByteInSector] = value;
131 currentByteInSector++;
132 if (currentByteInSector == (
sizeof(sectorBuf) + 2)) {
133 byte response = DRT_ACCEPTED;
136 hd->writeSector(currentSector, sectorBuf);
138 response = DRT_WRITE_ERROR;
141 transferDelayCounter = 1;
147 if (currentByteInSector == -1) {
148 if (value == STOP_TRAN_TOKEN) {
151 if (value == START_BLOCK_TOKEN_MBW) {
152 currentByteInSector++;
156 if (currentByteInSector <
int(
sizeof(sectorBuf))) {
157 sectorBuf.
raw[currentByteInSector] = value;
159 currentByteInSector++;
160 if (currentByteInSector == (
sizeof(sectorBuf) + 2)) {
162 byte response = DRT_ACCEPTED;
163 if (currentSector >= hd->getNbSectors()) {
164 response = DRT_WRITE_ERROR;
172 hd->writeSector(currentSector, sectorBuf);
173 currentByteInSector = -1;
176 response = DRT_WRITE_ERROR;
185 transferDelayCounter = 1;
191 if ((cmdIdx == 0 && (value >> 6) == 1)
193 cmdBuf[cmdIdx] = value;
206void SdCard::executeCommand()
210 transferDelayCounter = 2;
211 byte command = cmdBuf[0] & 0x3F;
214 responseQueue.
clear();
240 auto c_size = narrow<uint32_t>((hd->getNbSectors() *
sizeof(sectorBuf)) /
size_t(512 * 1024) - 1);
242 byte((c_size >> 16) & 0x3F),
243 byte((c_size >> 8) & 0xFF),
244 byte((c_size >> 0) & 0xFF),
286 if (currentSector >= hd->getNbSectors()) {
287 responseQueue.
push_back(R1_PARAMETER_ERROR);
291 case 17: mode =
READ;
break;
293 case 24: mode =
WRITE;
break;
297 currentByteInSector = -1;
318 responseQueue.
push_back(R1_ILLEGAL_COMMAND);
323static constexpr std::initializer_list<enum_string<SdCard::Mode>> modeInfo = {
332template<
typename Archive>
335 ar.serialize(
"mode", mode,
337 ar.serialize_blob(
"sectorBuf", sectorBuf.
raw);
338 if (hd) ar.serialize(
"hd", *hd);
339 ar.serialize(
"cmdIdx", cmdIdx,
340 "transferDelayCounter", transferDelayCounter,
341 "responseQueue", responseQueue,
342 "currentSector", currentSector,
343 "currentByteInSector", currentByteInSector);
SdCard(const DeviceConfig &config)
void serialize(Archive &ar, unsigned version)
byte transfer(byte value, bool cs)
uint32_t readB32(const void *p)
This file implemented 3 utility functions:
uint8_t byte
8 bit unsigned integer
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
std::array< uint8_t, 512 > raw