mirror of
https://github.com/libretro/Mu.git
synced 2026-09-23 07:05:37 +00:00
Update SD card stuff, SD card still doesnt work though
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "../emulator.h"
|
||||
#include "../ads7846.h"
|
||||
#include "../hardwareRegisters.h"
|
||||
#include "../portability.h"
|
||||
#include "../specs/emuFeatureRegistersSpec.h"
|
||||
#include "sandbox.h"
|
||||
#include "trapNames.h"
|
||||
@@ -505,6 +506,7 @@ uint32_t sandboxCommand(uint32_t test, void* data){
|
||||
palmRom[0x83653] = 0x71;
|
||||
palmRom[0x83654] = 0x4E;
|
||||
palmRom[0x83655] = 0x71;
|
||||
swap16BufferIfLittle(&palmRom[0x83652], 4 / sizeof(uint16_t));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -110,10 +110,10 @@ uint32_t emulatorInit(buffer_t palmRomDump, buffer_t palmBootDump, uint32_t spec
|
||||
sed1376Reset();
|
||||
ads7846Reset();
|
||||
pdiUsbD12Reset();
|
||||
sdCardReset();
|
||||
sandboxInit();
|
||||
|
||||
memset(&palmInput, 0x00, sizeof(palmInput));
|
||||
memset(&palmSdCard, 0x00, sizeof(palmSdCard));
|
||||
memset(&palmMisc, 0x00, sizeof(palmMisc));
|
||||
palmMisc.batteryLevel = 100;
|
||||
|
||||
@@ -155,6 +155,7 @@ void emulatorHardReset(void){
|
||||
sed1376Reset();
|
||||
ads7846Reset();
|
||||
pdiUsbD12Reset();
|
||||
sdCardReset();
|
||||
setRtc(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -164,6 +165,7 @@ void emulatorSoftReset(void){
|
||||
sed1376Reset();
|
||||
ads7846Reset();
|
||||
pdiUsbD12Reset();
|
||||
sdCardReset();
|
||||
}
|
||||
|
||||
void emulatorSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds){
|
||||
@@ -202,7 +204,7 @@ uint64_t emulatorGetStateSize(void){
|
||||
size += sizeof(uint8_t) * 2;//pwm1(Read/Write)
|
||||
size += sizeof(uint8_t) * 7;//palmMisc
|
||||
size += sizeof(uint32_t);//palmSdCard.command
|
||||
size += sizeof(uint8_t) * 2;//palmSdCard.commandBitsRemaining / palmSdCard.currentAction
|
||||
size += sizeof(uint8_t) * 2;//palmSdCard.commandBitsRemaining / palmSdCard.currentExchange
|
||||
size += sizeof(uint64_t);//palmSdCard.index
|
||||
size += palmSdCard.flashChip.size;//palmSdCard.flashChip.data
|
||||
|
||||
@@ -350,7 +352,7 @@ bool emulatorSaveState(buffer_t buffer){
|
||||
offset += sizeof(uint8_t);
|
||||
writeStateValue64(buffer.data + offset, palmSdCard.index);
|
||||
offset += sizeof(uint64_t);
|
||||
writeStateValue8(buffer.data + offset, palmSdCard.currentAction);
|
||||
writeStateValue8(buffer.data + offset, palmSdCard.currentExchange);
|
||||
offset += sizeof(uint8_t);
|
||||
memcpy(buffer.data + offset, palmSdCard.flashChip.data, palmSdCard.flashChip.size);
|
||||
offset += palmSdCard.flashChip.size;
|
||||
@@ -503,7 +505,7 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
offset += sizeof(uint8_t);
|
||||
palmSdCard.index = readStateValue64(buffer.data + offset);
|
||||
offset += sizeof(uint64_t);
|
||||
palmSdCard.currentAction = readStateValue8(buffer.data + offset);
|
||||
palmSdCard.currentExchange = readStateValue8(buffer.data + offset);
|
||||
offset += sizeof(uint8_t);
|
||||
if(palmSdCard.flashChip.data)
|
||||
free(palmSdCard.flashChip.data);
|
||||
@@ -562,6 +564,7 @@ uint32_t emulatorInsertSdCard(buffer_t image){
|
||||
memset(palmSdCard.flashChip.data, 0x00, image.size);
|
||||
|
||||
palmSdCard.flashChip.size = image.size;
|
||||
sdCardReset();
|
||||
|
||||
return EMU_ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ typedef struct{
|
||||
typedef struct{
|
||||
uint64_t command;
|
||||
uint8_t commandBitsRemaining;
|
||||
uint64_t index;
|
||||
uint8_t currentAction;
|
||||
uint64_t index;//this is in bits not bytes
|
||||
uint8_t currentExchange;
|
||||
buffer_t flashChip;
|
||||
}sd_card_t;
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ static void checkInterrupts(void){
|
||||
intLevel = 4;
|
||||
}
|
||||
|
||||
//even masked interrupts turn off PCTLR, Chapter 4.5.4 MC68VZ328UM.pdf
|
||||
//even masked interrupts turn off PCTLR, 4.5.4 Power Control Register MC68VZ328UM.pdf
|
||||
if(intLevel > 0 && registerArrayRead8(PCTLR) & 0x80){
|
||||
registerArrayWrite8(PCTLR, registerArrayRead8(PCTLR) & 0x1F);
|
||||
pctlrCpuClockDivider = 1.0;
|
||||
|
||||
@@ -336,30 +336,28 @@ static void setSpiCont1(uint16_t value){
|
||||
|
||||
//do a transfer if enabled(this register write and last) and exchange set
|
||||
if(value & oldSpiCont1 & 0x0200 && value & 0x0100){
|
||||
uint16_t currentTxFifoEntry = spi1TxFifoRead();
|
||||
uint16_t newRxFifoEntry = 0;
|
||||
uint8_t bitCount = (value & 0x000F) + 1;
|
||||
uint16_t startBit = 1 << (bitCount - 1);
|
||||
uint8_t bits;
|
||||
|
||||
debugLog("SPI1 transfer, PC:0x%08X\n", flx68000GetPc());
|
||||
|
||||
while(spi1TxFifoEntrys() > 0){
|
||||
uint16_t currentTxFifoEntry = spi1TxFifoRead();
|
||||
uint16_t newRxFifoEntry = 0;
|
||||
uint8_t bits;
|
||||
|
||||
//I dont actually know if bits are shifted out the top or bottom of the newest TX FIFO entry, using top right now because thats what SPI2 does
|
||||
for(bits = 0; bits < bitCount; bits++){
|
||||
newRxFifoEntry |= sdCardExchangeBit(!!(currentTxFifoEntry & startBit));
|
||||
newRxFifoEntry <<= 1;
|
||||
currentTxFifoEntry <<= 1;
|
||||
}
|
||||
|
||||
spi1RxFifoWrite(newRxFifoEntry);
|
||||
|
||||
//overflow occured, remove 1 FIFO entry
|
||||
//I do not currently know if the FIFO entry is removed from the back or front of the FIFO, going with the back for now
|
||||
//if(spi1RxFifoEntrys() == 0)
|
||||
// spi1RxFifoRead();
|
||||
//The most significant bit is output when the CPU loads the transmitted data, 13.2.3 SPI 1 Phase and Polarity Configurations MC68VZ328UM.pdf
|
||||
for(bits = 0; bits < bitCount; bits++){
|
||||
newRxFifoEntry |= sdCardExchangeBit(!!(currentTxFifoEntry & startBit));
|
||||
newRxFifoEntry <<= 1;
|
||||
currentTxFifoEntry <<= 1;
|
||||
}
|
||||
|
||||
//since exact timing isnt implemented reads have to be done at the same time as writes
|
||||
spi1RxFifoWrite(newRxFifoEntry);
|
||||
|
||||
//overflow occured, remove 1 FIFO entry
|
||||
//I do not currently know if the FIFO entry is removed from the back or front of the FIFO, going with the back for now
|
||||
//if(spi1RxFifoEntrys() == 0)
|
||||
// spi1RxFifoRead();
|
||||
}
|
||||
|
||||
registerArrayWrite16(SPICONT1, value);
|
||||
@@ -550,7 +548,7 @@ static uint8_t getPortDInputPinValues(void){
|
||||
}
|
||||
|
||||
static uint8_t getPortAValue(void){
|
||||
//not attached, used as data lines
|
||||
//not attached, used as CPU data lines
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
|
||||
137
src/sdCard.c
137
src/sdCard.c
@@ -9,73 +9,124 @@
|
||||
|
||||
|
||||
enum{
|
||||
SD_CARD_ACTION_NOTHING = 0,
|
||||
SD_CARD_ACTION_READ_DATA_BLOCK,
|
||||
SD_CARD_ACTION_READ_DATA_STREAM,
|
||||
SD_CARD_ACTION_WRITE_DATA_BLOCK,
|
||||
SD_CARD_ACTION_WRITE_DATA_STREAM,
|
||||
SD_CARD_ACTION_GET_ID
|
||||
//see http://elm-chan.org/docs/mmc/mmc_e.html for more command information
|
||||
SD_CARD_CMD_GO_IDLE_STATE = 0,//software reset
|
||||
SD_CARD_CMD_SEND_OP_COND = 1,//initiate initialization process
|
||||
SD_CARD_CMD_SEND_CSD = 9,//read CSD register
|
||||
SD_CARD_CMD_SEND_CID = 10,//read CID register
|
||||
SD_CARD_CMD_STOP_TRANSMISSION = 12,//stop to read data
|
||||
SD_CARD_CMD_SET_BLOCKLEN = 16,//change R/W block size
|
||||
SD_CARD_CMD_READ_SINGLE_BLOCK = 17,//read a block
|
||||
SD_CARD_CMD_READ_MULTIPLE_BLOCK = 18,//read multiple blocks
|
||||
SD_CARD_CMD_WRITE_SINGLE_BLOCK = 24,//write a block
|
||||
SD_CARD_CMD_WRITE_MULTIPLE_BLOCK = 25,//write multiple blocks
|
||||
SD_CARD_CMD_READ_OCR = 58,//read OCR(operation condtion register)
|
||||
SD_CARD_CMD_NOTHING = 0xFF//no command is currently being processed
|
||||
};
|
||||
|
||||
enum{
|
||||
SD_CARD_EXCHANGE_NOTHING = 0,
|
||||
SD_CARD_EXCHANGE_WAIT_RETURN_0,
|
||||
SD_CARD_EXCHANGE_WAIT_RETURN_1,
|
||||
SD_CARD_EXCHANGE_R1_RESPONCE,
|
||||
SD_CARD_EXCHANGE_R3_RESPONCE,
|
||||
SD_CARD_EXCHANGE_DATA_PACKET,
|
||||
SD_CARD_EXCHANGE_READ_DATA_AT_INDEX,
|
||||
SD_CARD_EXCHANGE_WRITE_DATA_AT_INDEX
|
||||
};
|
||||
|
||||
|
||||
static void sdCardInvalidFormat(void){
|
||||
static const uint64_t sdCardCsd[2] = {0x0000000000000000, 0x0000000000000000};
|
||||
static const uint64_t sdCardCid[2] = {0x0000000000000000, 0x0000000000000000};
|
||||
static const uint32_t sdCardOcr = 0x00000000;
|
||||
|
||||
|
||||
static void sdCardCmdInvalidFormat(void){
|
||||
debugLog("SD command invalid:0x%012X, bits remaining:%d\n", palmSdCard.command, palmSdCard.commandBitsRemaining);
|
||||
palmSdCard.command = 0x0000000000000000;
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
}
|
||||
|
||||
static bool sdCardCmdIsCrcValid(uint64_t command){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
uint64_t data = palmSdCard.command >> 8 & 0x3FFFFFFFFF;
|
||||
uint8_t crc = palmSdCard.command >> 1 & 0x7F;
|
||||
|
||||
//add real check
|
||||
|
||||
return true;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sdCardReset(void){
|
||||
palmSdCard.command = 0x0000000000000000;
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
palmSdCard.index = 0;
|
||||
palmSdCard.currentAction = SD_CARD_ACTION_NOTHING;
|
||||
palmSdCard.currentExchange = SD_CARD_CMD_NOTHING;
|
||||
}
|
||||
|
||||
bool sdCardExchangeBit(bool bit){
|
||||
bool sdCardOutputValue = true;//default output value is true, if an action is ongoing it will be set to the data provide by that action
|
||||
|
||||
//check validity of incoming bit
|
||||
switch(palmSdCard.commandBitsRemaining - 1){
|
||||
case 47:
|
||||
if(bit)
|
||||
sdCardInvalidFormat();
|
||||
return true;
|
||||
//make sure SD is actually plugged in
|
||||
if(palmSdCard.flashChip.data){
|
||||
#if !defined(EMU_NO_SAFETY)
|
||||
//check validity of incoming bit
|
||||
switch(palmSdCard.commandBitsRemaining - 1){
|
||||
case 47:
|
||||
if(bit)
|
||||
sdCardCmdInvalidFormat();
|
||||
return true;
|
||||
|
||||
case 46:
|
||||
case 0:
|
||||
if(!bit)
|
||||
sdCardInvalidFormat();
|
||||
return true;
|
||||
}
|
||||
case 46:
|
||||
case 0:
|
||||
if(!bit)
|
||||
sdCardCmdInvalidFormat();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//add the bit
|
||||
palmSdCard.command <<= 1;
|
||||
palmSdCard.command |= bit;
|
||||
palmSdCard.commandBitsRemaining--;
|
||||
//add the bit
|
||||
palmSdCard.command <<= 1;
|
||||
palmSdCard.command |= bit;
|
||||
palmSdCard.commandBitsRemaining--;
|
||||
|
||||
//process command if all bits are present
|
||||
if(palmSdCard.commandBitsRemaining == 0){
|
||||
uint8_t command = palmSdCard.command >> 40 & 0x3F;
|
||||
uint32_t argument = palmSdCard.command >> 8 & 0xFFFFFFFF;
|
||||
uint8_t crc = palmSdCard.command >> 1 & 0x7F;
|
||||
//process command if all bits are present
|
||||
if(palmSdCard.commandBitsRemaining == 0){
|
||||
//check command validity
|
||||
if(sdCardCmdIsCrcValid(palmSdCard.command)){
|
||||
uint8_t command = palmSdCard.command >> 40 & 0x3F;
|
||||
uint32_t argument = palmSdCard.command >> 8 & 0xFFFFFFFF;
|
||||
uint8_t crc = palmSdCard.command >> 1 & 0x7F;
|
||||
|
||||
switch(command){
|
||||
switch(command){
|
||||
case SD_CARD_CMD_GO_IDLE_STATE:
|
||||
sdCardReset();
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("SD command:cmd:0x%02X, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
|
||||
break;
|
||||
default:
|
||||
debugLog("SD command:cmd:0x%02X, arg:0x%08X, CRC:0x%02X\n", command, argument, crc);
|
||||
break;
|
||||
}
|
||||
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
}
|
||||
else{
|
||||
sdCardCmdInvalidFormat();
|
||||
}
|
||||
}
|
||||
|
||||
palmSdCard.commandBitsRemaining = 48;
|
||||
}
|
||||
//process current exchange
|
||||
switch(palmSdCard.currentExchange){
|
||||
case SD_CARD_EXCHANGE_NOTHING:
|
||||
break;
|
||||
|
||||
//do action associated with newest command
|
||||
switch(palmSdCard.currentAction){
|
||||
case SD_CARD_ACTION_NOTHING:
|
||||
break;
|
||||
|
||||
default:
|
||||
debugLog("SD action:%d\n", palmSdCard.currentAction);
|
||||
break;
|
||||
default:
|
||||
debugLog("SD exchange:%d\n", palmSdCard.currentExchange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sdCardOutputValue;
|
||||
|
||||
Reference in New Issue
Block a user