diff --git a/src/debug/sandbox.c b/src/debug/sandbox.c index afb24fd..e12773c 100644 --- a/src/debug/sandbox.c +++ b/src/debug/sandbox.c @@ -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; diff --git a/src/emulator.c b/src/emulator.c index edd3e53..4d78701 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -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; } diff --git a/src/emulator.h b/src/emulator.h index 8ce4166..670d6eb 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -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; diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 1468e0f..f1fe48c 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -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; diff --git a/src/hardwareRegistersAccessors.c.h b/src/hardwareRegistersAccessors.c.h index d650f85..f7c02b8 100644 --- a/src/hardwareRegistersAccessors.c.h +++ b/src/hardwareRegistersAccessors.c.h @@ -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; } diff --git a/src/sdCard.c b/src/sdCard.c index 82dedd8..99930cd 100644 --- a/src/sdCard.c +++ b/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;