mirror of
https://github.com/libretro/Mu.git
synced 2026-07-09 02:08:10 +00:00
162 lines
5.5 KiB
C
162 lines
5.5 KiB
C
//FIFO accessors
|
|
static uint16_t sdCardResponseFifoByteEntrys(void){
|
|
//check for wraparound
|
|
if(palmSdCard.responseWritePosition < palmSdCard.responseReadPosition)
|
|
return palmSdCard.responseWritePosition + SD_CARD_RESPONSE_FIFO_SIZE - palmSdCard.responseReadPosition;
|
|
return palmSdCard.responseWritePosition - palmSdCard.responseReadPosition;
|
|
}
|
|
|
|
static bool sdCardResponseFifoReadBit(void){
|
|
if(sdCardResponseFifoByteEntrys() > 0){
|
|
bool bit = !!(palmSdCard.responseFifo[palmSdCard.responseReadPosition] & 1 << palmSdCard.responseReadPositionBit);
|
|
palmSdCard.responseReadPositionBit--;
|
|
if(palmSdCard.responseReadPositionBit < 0){
|
|
palmSdCard.responseReadPositionBit = 7;
|
|
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
|
}
|
|
return bit;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static uint8_t sdCardResponseFifoReadByteOptimized(void){
|
|
switch(sdCardResponseFifoByteEntrys()){
|
|
case 0:
|
|
//no bytes
|
|
return 0xFF;
|
|
|
|
case 1:{
|
|
//unsafe, use slow mode
|
|
uint8_t byte = 0x00;
|
|
uint8_t index;
|
|
|
|
for(index = 0; index < 8; index++){
|
|
byte <<= 1;
|
|
byte |= sdCardResponseFifoReadBit();
|
|
}
|
|
|
|
return byte;
|
|
}
|
|
|
|
default:{
|
|
uint8_t byte;
|
|
|
|
if(palmSdCard.responseReadPositionBit == 7){
|
|
//just read the whole byte at once
|
|
byte = palmSdCard.responseFifo[palmSdCard.responseReadPosition];
|
|
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
|
return byte;
|
|
}
|
|
else{
|
|
//have to merge 2 bytes
|
|
byte = palmSdCard.responseFifo[palmSdCard.responseReadPosition] << 7 - palmSdCard.responseReadPositionBit;
|
|
palmSdCard.responseReadPosition = (palmSdCard.responseReadPosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
|
byte |= palmSdCard.responseFifo[palmSdCard.responseReadPosition] >> palmSdCard.responseReadPositionBit + 1;
|
|
return byte;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void sdCardResponseFifoWriteByte(uint8_t value){
|
|
if(likely(sdCardResponseFifoByteEntrys() < SD_CARD_RESPONSE_FIFO_SIZE - 1)){
|
|
palmSdCard.responseFifo[palmSdCard.responseWritePosition] = value;
|
|
palmSdCard.responseWritePosition = (palmSdCard.responseWritePosition + 1) % SD_CARD_RESPONSE_FIFO_SIZE;
|
|
}
|
|
}
|
|
|
|
static void sdCardResponseFifoFlush(void){
|
|
palmSdCard.responseReadPosition = palmSdCard.responseWritePosition;
|
|
palmSdCard.responseReadPositionBit = 7;
|
|
}
|
|
|
|
//basic responses
|
|
static void sdCardDoResponseDelay(uint16_t bytes){
|
|
uint16_t index;
|
|
for(index = 0; index < bytes; index++)
|
|
sdCardResponseFifoWriteByte(0xFF);
|
|
}
|
|
|
|
static void sdCardDoResponseBusy(uint16_t bytes){
|
|
uint16_t index;
|
|
for(index = 0; index < bytes; index++)
|
|
sdCardResponseFifoWriteByte(0x00);
|
|
}
|
|
|
|
static void sdCardDoResponseR1(uint8_t r1){
|
|
sdCardDoResponseDelay(SD_CARD_NCR_BYTES);
|
|
sdCardResponseFifoWriteByte(r1);
|
|
}
|
|
|
|
static void sdCardDoResponseR2(uint8_t r1, uint8_t status){
|
|
sdCardDoResponseR1(r1);
|
|
sdCardResponseFifoWriteByte(status);
|
|
}
|
|
|
|
static void sdCardDoResponseR3R7(uint8_t r1, uint32_t value){
|
|
sdCardDoResponseR1(r1);
|
|
sdCardResponseFifoWriteByte(value >> 24);
|
|
sdCardResponseFifoWriteByte(value >> 16 & 0xFF);
|
|
sdCardResponseFifoWriteByte(value >> 8 & 0xFF);
|
|
sdCardResponseFifoWriteByte(value & 0xFF);
|
|
}
|
|
|
|
static void sdCardDoResponseDataPacket(uint8_t token, const uint8_t* data, uint16_t size){
|
|
uint16_t crc16;
|
|
uint16_t offset;
|
|
|
|
if(likely(palmSdCard.allowInvalidCrc))
|
|
crc16 = 0x0000;
|
|
else
|
|
crc16 = sdCardCrc16(data, size);
|
|
|
|
sdCardResponseFifoWriteByte(token);
|
|
for(offset = 0; offset < size; offset++)
|
|
sdCardResponseFifoWriteByte(data[offset]);
|
|
sdCardResponseFifoWriteByte(crc16 >> 8);
|
|
sdCardResponseFifoWriteByte(crc16 & 0xFF);
|
|
}
|
|
|
|
static void sdCardDoResponseDataResponse(uint8_t response){
|
|
sdCardResponseFifoWriteByte(response);
|
|
sdCardDoResponseBusy(1);
|
|
}
|
|
|
|
static void sdCardDoResponseErrorToken(uint8_t token){
|
|
sdCardResponseFifoWriteByte(token);
|
|
}
|
|
|
|
//register getters
|
|
static void sdCardGetCsd(uint8_t* csd){
|
|
uint16_t deviceSize;
|
|
|
|
memcpy(csd, palmSdCard.sdInfo.csd, 16);
|
|
|
|
//set device size field(in multiples of 256k right now, the multiplier size also scales based on chip size), needed to get size
|
|
deviceSize = palmSdCard.flashChipSize / SD_CARD_BLOCK_SIZE / 512;//to calculate the card capacity excluding security area ((device size + 1) * device size multiplier * max read data block length) bytes
|
|
csd[6] = csd[6] & 0xFC | deviceSize >> 10 & 0x03;
|
|
csd[7] = deviceSize >> 2 & 0xFF;
|
|
csd[8] = csd[8] & 0x3F | deviceSize << 6 & 0xC0;
|
|
|
|
if(unlikely(!palmSdCard.allowInvalidCrc))
|
|
csd[15] = sdCardCrc7(csd, 15);
|
|
|
|
//debugLog("CSD bytes: 0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", csd[0], csd[1], csd[2], csd[3], csd[4], csd[5], csd[6], csd[7], csd[8], csd[9], csd[10], csd[11], csd[12], csd[13], csd[14], csd[15]);
|
|
}
|
|
|
|
static void sdCardGetCid(uint8_t* cid){
|
|
memcpy(cid, palmSdCard.sdInfo.cid, 16);
|
|
|
|
if(unlikely(!palmSdCard.allowInvalidCrc))
|
|
cid[15] = sdCardCrc7(cid, 15);
|
|
}
|
|
|
|
static void sdCardGetScr(uint8_t* scr){
|
|
//dont know it this needs a CRC7 or not?
|
|
memcpy(scr, palmSdCard.sdInfo.scr, 8);
|
|
}
|
|
|
|
static uint32_t sdCardGetOcr(void){
|
|
return !palmSdCard.inIdleState << 31/*power up status*/ | 0 << 30/*card capacity status*/ | palmSdCard.sdInfo.ocr/*supported voltages, misc stuff*/;
|
|
}
|