diff --git a/qtBuildSystem/Mu/emuwrapper.cpp b/qtBuildSystem/Mu/emuwrapper.cpp index 922d5f2..38db3ce 100644 --- a/qtBuildSystem/Mu/emuwrapper.cpp +++ b/qtBuildSystem/Mu/emuwrapper.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include "emuwrapper.h" #include "../../src/emulator.h" +#include "../../src/fileLauncher/launcher.h" extern "C"{ #include "../../src/flx68000.h" @@ -254,6 +256,88 @@ void EmuWrapper::reset(bool hard){ } } +uint32_t EmuWrapper::bootFromFileList(const QStringList& paths){ + bool wasPaused = isPaused(); + uint32_t error = EMU_ERROR_NONE; + QByteArray* fileDataBuffers = new QByteArray[paths.length()]; + QByteArray infoBuffer; + file_t* files = new file_t[paths.length()]; + sd_card_info_t cardInfo; + int32_t newestBootableFile = -1; + + if(!wasPaused) + pause(); + + memset(files, 0x00, sizeof(file_t) * paths.length()); + + for(int32_t index = 0; index < paths.length(); index++){ + QFile appFile(paths[index]); + + if(appFile.open(QFile::ReadOnly)){ + QString suffix = QFileInfo(paths[index]).suffix().toLower(); + + *fileDataBuffers = appFile.readAll(); + appFile.close(); + + files[index].fileData = (uint8_t*)fileDataBuffers->data(); + files[index].fileSize = fileDataBuffers->size(); + + if(suffix == "prc"){ + files[index].type = LAUNCHER_FILE_TYPE_PRC; + newestBootableFile = index; + } + else if(suffix == "pdb"){ + files[index].type = LAUNCHER_FILE_TYPE_PDB; + } + else if(suffix == "pqa"){ + files[index].type = LAUNCHER_FILE_TYPE_PQA; + newestBootableFile = index; + } + else if(suffix == "zip"){ + files[index].type = LAUNCHER_FILE_TYPE_ZIP; + newestBootableFile = index; + } + else if(suffix == "img"){ + //check for an info file + //TODO parse info file if it exists + //memset(&cardInfo, 0x00, sizeof(cardInfo)); + //files[index].info = &cardInfo; + files[index].type = LAUNCHER_FILE_TYPE_IMG; + newestBootableFile = index; + } + else{ + error = EMU_ERROR_INVALID_PARAMETER; + goto errorOccurred; + } + } + else{ + error = EMU_ERROR_RESOURCE_LOCKED; + goto errorOccurred; + } + } + + if(newestBootableFile != -1){ + files[newestBootableFile].boot = true; + } + else{ + error = EMU_ERROR_INVALID_PARAMETER; + goto errorOccurred; + } + + //actually pass everything to the emu + //TODO actually hook up the save files + error = launcherLaunch(files, paths.length(), NULL, 0, NULL, 0); + + //need this goto because the emulator must be released before returning + errorOccurred: + + if(!wasPaused) + resume(); + + delete[] fileDataBuffers; + return error; +} + uint32_t EmuWrapper::saveState(const QString& path){ bool wasPaused = isPaused(); uint32_t error = EMU_ERROR_INVALID_PARAMETER; diff --git a/qtBuildSystem/Mu/emuwrapper.h b/qtBuildSystem/Mu/emuwrapper.h index 306a181..ab7a11d 100644 --- a/qtBuildSystem/Mu/emuwrapper.h +++ b/qtBuildSystem/Mu/emuwrapper.h @@ -48,6 +48,7 @@ public: void pause(); void resume(); void reset(bool hard); + uint32_t bootFromFileList(const QStringList& paths); uint32_t saveState(const QString& path); uint32_t loadState(const QString& path); bool isInited() const{return emuInited;} diff --git a/qtBuildSystem/Mu/mainwindow.cpp b/qtBuildSystem/Mu/mainwindow.cpp index 7bbf1d2..8eb5125 100644 --- a/qtBuildSystem/Mu/mainwindow.cpp +++ b/qtBuildSystem/Mu/mainwindow.cpp @@ -110,6 +110,7 @@ MainWindow::MainWindow(QWidget* parent) : ui->settings->installEventFilter(this); ui->debugInstall->installEventFilter(this); ui->debugger->installEventFilter(this); + ui->bootApp->installEventFilter(this); //hide onscreen keys if needed ui->up->setHidden(hideOnscreenKeys); @@ -337,6 +338,7 @@ void MainWindow::on_ctrlBtn_clicked(){ ui->stateManager->setEnabled(true); ui->debugger->setEnabled(true); ui->reset->setEnabled(true); + ui->bootApp->setEnabled(true); ui->ctrlBtn->setIcon(QIcon(":/buttons/images/pause.svg")); } @@ -358,7 +360,7 @@ void MainWindow::on_ctrlBtn_clicked(){ void MainWindow::on_debugInstall_clicked(){ if(emu.isInited()){ - QString app = QFileDialog::getOpenFileName(this, "Select Application", QDir::root().path(), "Palm OS App (*.prc *.pdb *.pqa)"); + QString app = QFileDialog::getOpenFileName(this, "Select File", QDir::root().path(), "Palm OS File (*.prc *.pdb *.pqa)"); if(app != ""){ uint32_t error = emu.debugInstallApplication(app); @@ -426,3 +428,16 @@ void MainWindow::on_settings_clicked(){ if(wasInited && !wasPaused) emu.resume(); } + +void MainWindow::on_bootApp_clicked(){ + if(emu.isInited()){ + QString app = QFileDialog::getOpenFileName(this, "Select Application", QDir::root().path(), "Palm OS Executable File (*.prc *.pqa *.zip)"); + + if(app != ""){ + uint32_t error = emu.bootFromFileList(QStringList(app)); + + if(error != EMU_ERROR_NONE) + popupErrorDialog("Could not run app, Error:" + QString::number(error)); + } + } +} diff --git a/qtBuildSystem/Mu/mainwindow.h b/qtBuildSystem/Mu/mainwindow.h index fb4c34e..1ca7e86 100644 --- a/qtBuildSystem/Mu/mainwindow.h +++ b/qtBuildSystem/Mu/mainwindow.h @@ -73,6 +73,7 @@ private slots: void on_stateManager_clicked(); void on_reset_clicked(); void on_settings_clicked(); + void on_bootApp_clicked(); private: SettingsManager* settingsManager; diff --git a/qtBuildSystem/Mu/mainwindow.ui b/qtBuildSystem/Mu/mainwindow.ui index 6d512e2..8ccfaf7 100644 --- a/qtBuildSystem/Mu/mainwindow.ui +++ b/qtBuildSystem/Mu/mainwindow.ui @@ -240,23 +240,6 @@ - - - - false - - - - 0 - 0 - - - - - :/buttons/images/debugger.svg:/buttons/images/debugger.svg - - - @@ -274,23 +257,6 @@ - - - - false - - - - 0 - 0 - - - - - :/buttons/images/install.svg:/buttons/images/install.svg - - - @@ -354,6 +320,56 @@ + + + + false + + + + 0 + 0 + + + + + :/buttons/images/debugger.svg:/buttons/images/debugger.svg + + + + + + + false + + + + 0 + 0 + + + + + :/buttons/images/install.svg:/buttons/images/install.svg + + + + + + + false + + + + 0 + 0 + + + + Boot + + + diff --git a/src/armv5te/os/os-win32.c b/src/armv5te/os/os-win32.c index 4b552eb..8c03763 100644 --- a/src/armv5te/os/os-win32.c +++ b/src/armv5te/os/os-win32.c @@ -26,6 +26,7 @@ void os_free(void *ptr, size_t size) VirtualFree(ptr, 0, MEM_RELEASE); } +#if OS_HAS_PAGEFAULT_HANDLER void *os_commit(void *addr, size_t size) { return VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE); @@ -41,12 +42,14 @@ void os_sparse_decommit(void *page, size_t size) VirtualFree(page, size, MEM_DECOMMIT); return; } +#endif void *os_alloc_executable(size_t size) { return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); } +#if OS_HAS_PAGEFAULT_HANDLER static int addr_cache_exception(PEXCEPTION_RECORD er, void *x, void *y, void *z) { (void) x; (void) y; (void) z; if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { @@ -55,6 +58,7 @@ static int addr_cache_exception(PEXCEPTION_RECORD er, void *x, void *y, void *z) } return 1; // Continue search } +#endif void addr_cache_init() { // Don't run more than once @@ -63,22 +67,28 @@ void addr_cache_init() { DWORD flags = MEM_RESERVE; -#ifndef NDEBUG +#if defined(AC_FLAGS) // Commit memory to not trigger segfaults which make debugging a PITA flags |= MEM_COMMIT; #endif addr_cache = VirtualAlloc(NULL, AC_NUM_ENTRIES * sizeof(ac_entry), flags, PAGE_READWRITE); + if(!addr_cache){ + printf("Cant allocate addr_cache!\n"); + exit(1); + } -#ifndef NDEBUG - // Without segfaults we have to invalidate everything here +#if !defined(AC_FLAGS) unsigned int i; - for(i = 0; i < AC_NUM_ENTRIES; ++i) + for(unsigned int i = 0; i < AC_NUM_ENTRIES; ++i) { AC_SET_ENTRY_INVALID(addr_cache[i], (i >> 1) << 10) } +#else + memset(addr_cache, 0xFF, AC_NUM_ENTRIES * sizeof(ac_entry)); #endif +#if defined(__i386__) && !defined(NO_TRANSLATION) // Relocate the assembly code that wants addr_cache at a fixed address extern DWORD *ac_reloc_start[] __asm__("ac_reloc_start"), *ac_reloc_end[] __asm__("ac_reloc_end"); DWORD **reloc; @@ -88,8 +98,10 @@ void addr_cache_init() { **reloc += (DWORD)addr_cache; VirtualProtect(*reloc, 4, prot, &prot); } +#endif } +#if OS_HAS_PAGEFAULT_HANDLER void os_faulthandler_arm(os_exception_frame_t *frame) { assert(frame->prev == NULL); @@ -106,16 +118,19 @@ void os_faulthandler_unarm(os_exception_frame_t *frame) asm ("movl %0, %%fs:(%1)" : : "r" (frame->prev), "r" (0)); frame->prev = NULL; } +#endif void addr_cache_deinit() { if(!addr_cache) return; +#if defined(__i386__) && !defined(NO_TRANSLATION) // Undo the relocations extern DWORD *ac_reloc_start[] __asm__("ac_reloc_start"), *ac_reloc_end[] __asm__("ac_reloc_end"); DWORD **reloc; for (reloc = ac_reloc_start; reloc != ac_reloc_end; reloc++) **reloc -= (DWORD)addr_cache; +#endif VirtualFree(addr_cache, 0, MEM_RELEASE); addr_cache = NULL; diff --git a/src/armv5te/os/os.h b/src/armv5te/os/os.h index 1d827e9..23f486b 100644 --- a/src/armv5te/os/os.h +++ b/src/armv5te/os/os.h @@ -13,7 +13,7 @@ extern "C" { int iOS_is_debugger_attached(); #endif -#if !defined(__x86_64__) && (defined(_WIN32) || defined(WIN32)) +#if !defined(__x86_64__) && !defined(NO_TRANSLATION) && (defined(_WIN32) || defined(WIN32)) #define OS_HAS_PAGEFAULT_HANDLER 1 #else #define OS_HAS_PAGEFAULT_HANDLER 0 diff --git a/src/fileLauncher/fatFs/diskio.c b/src/fileLauncher/fatFs/diskio.c index 51b1b6d..6b89cae 100644 --- a/src/fileLauncher/fatFs/diskio.c +++ b/src/fileLauncher/fatFs/diskio.c @@ -1,17 +1,16 @@ -/*-----------------------------------------------------------------------*/ -/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ -/*-----------------------------------------------------------------------*/ -/* If a working storage control module is available, it should be */ -/* attached to the FatFs via a glue function rather than modifying it. */ -/* This is an example of glue functions to attach various exsisting */ -/* storage control modules to the FatFs module with a defined API. */ -/*-----------------------------------------------------------------------*/ +#include "ff.h" +#include "diskio.h" + +#include +#include +#include "../../emulator.h" -#include "ff.h" /* Obtains integer types */ -#include "diskio.h" /* Declarations of disk functions */ -/* Definitions of physical drive number for each drive */ #define DEV_RAM 0 +#define PALM_SD_CARD_SECTOR_SIZE 512 + + +static bool cardInitalized = false; /*-----------------------------------------------------------------------*/ @@ -22,11 +21,10 @@ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { - if(pdrv == DEV_RAM){ + if(pdrv == DEV_RAM) + return cardInitalized ? 0x00 : STA_NOINIT; - } - - return STA_NOINIT; + return STA_NOINIT; } @@ -40,7 +38,9 @@ DSTATUS disk_initialize ( ) { if(pdrv == DEV_RAM){ - + memset(palmSdCard.flashChipData, 0x00, palmSdCard.flashChipSize); + cardInitalized = true; + return 0x00; } return STA_NOINIT; @@ -60,7 +60,11 @@ DRESULT disk_read ( ) { if(pdrv == DEV_RAM){ + if(!(sector * PALM_SD_CARD_SECTOR_SIZE + PALM_SD_CARD_SECTOR_SIZE < palmSdCard.flashChipSize)) + return RES_ERROR; + memcpy(buff, palmSdCard.flashChipData + sector * PALM_SD_CARD_SECTOR_SIZE, count * PALM_SD_CARD_SECTOR_SIZE); + return RES_OK; } return RES_PARERR; @@ -82,7 +86,11 @@ DRESULT disk_write ( ) { if(pdrv == DEV_RAM){ + if(!(sector * PALM_SD_CARD_SECTOR_SIZE + PALM_SD_CARD_SECTOR_SIZE < palmSdCard.flashChipSize)) + return RES_ERROR; + memcpy(palmSdCard.flashChipData + sector * PALM_SD_CARD_SECTOR_SIZE, buff, count * PALM_SD_CARD_SECTOR_SIZE); + return RES_OK; } return RES_PARERR; @@ -102,7 +110,8 @@ DRESULT disk_ioctl ( ) { if(pdrv == DEV_RAM){ - + //RAM has no ioctls + return RES_PARERR; } return RES_PARERR; diff --git a/src/fileLauncher/launcher.c b/src/fileLauncher/launcher.c index e640345..b890ccd 100644 --- a/src/fileLauncher/launcher.c +++ b/src/fileLauncher/launcher.c @@ -9,46 +9,173 @@ bool launcherSaveSdCardImage; -void launcherInstallPassMeM515(void){ +static void launcherInstallPassMeM515(void){ //works like PassMe on a DS, boots from a different slot } #if defined(EMU_SUPPORT_PALM_OS5) -void launcherInstallPassMeTungstenC(void){ +static void launcherInstallPassMeTungstenC(void){ //works like PassMe on a DS, boots from a different slot } #endif +static const char* launcherGetFileExtension(uint8_t fileType){ + switch(fileType){ + case LAUNCHER_FILE_TYPE_PRC: + return "PRC"; + + case LAUNCHER_FILE_TYPE_PDB: + return "PDB"; + + case LAUNCHER_FILE_TYPE_PQA: + return "PQA"; + + default: + return "000"; + } +} + +static uint32_t launcherMakeBootRecord(const char* appName){ + //writes BOOT.TXT to the PASSME of the SD card, the application in the PassMe image will run the application with the ID listed in this file after everything is copyed over + //type is always 'appl', creator is the 4 letter app name + FIL record; + FRESULT result; + uint32_t written; + + result = f_open(&record, "0/PASSME/BOOT.TXT", FA_WRITE | FA_CREATE_ALWAYS); + if(result != FR_OK) + return EMU_ERROR_UNKNOWN; + + result = f_write(&record, appName, 4, &written); + if(result != FR_OK || written != 4) + return EMU_ERROR_UNKNOWN; + + result = f_close(&record); + if(result != FR_OK) + return EMU_ERROR_UNKNOWN; + + return EMU_ERROR_NONE; +} + +static uint32_t launcherCopyPrcPdbPqaToSdCard(file_t* file, uint32_t* fileId){ + FIL application; + char name[FF_MAX_LFN]; + FRESULT result; + uint32_t written; + + sprintf(name, "0/PASSME/%d.%s", *fileId, launcherGetFileExtension(file->type)); + + result = f_open(&application, name, FA_WRITE | FA_CREATE_ALWAYS); + if(result != FR_OK) + return EMU_ERROR_UNKNOWN; + + result = f_write(&application, file->fileData, file->fileSize, &written); + if(result != FR_OK || written != file->fileSize) + return EMU_ERROR_UNKNOWN; + + result = f_close(&application); + if(result != FR_OK) + return EMU_ERROR_UNKNOWN; + + //set boot record if this is the boot application + if(file->boot){ + uint32_t error; + + //cant read the name, not a real app + if(file->fileSize < 0x40 + 4) + return EMU_ERROR_INVALID_PARAMETER; + + //the app name is at 0x40, dont know if this applys to pqa or not + error = launcherMakeBootRecord(file->fileData + 0x40); + if(error != EMU_ERROR_NONE) + return error; + } + + (*fileId)++; + return EMU_ERROR_NONE; +} + +static uint32_t launcherCopyZipContentsToSdCard(file_t* file, uint32_t* fileId){ + //TODO + return EMU_ERROR_NOT_IMPLEMENTED; +} + +static uint32_t launcherSetupSdCardImageFromApps(file_t* files, uint32_t fileCount){ + uint32_t fileId = 0;//first file is named 0.p**, next is 1.p**, and the name continues going up with the file count + FRESULT result; + uint32_t error; + uint32_t index; + + //setup filesystem + result = f_mkfs("0", FM_FAT, 4096, NULL, 0); + if(result != FR_OK) + return EMU_ERROR_UNKNOWN; + + //setup directory + result = f_mkdir("0/PASSME"); + if(result != FR_OK) + return EMU_ERROR_UNKNOWN; + + for(index = 0; index < fileCount; index++){ + switch(files[index].type){ + case LAUNCHER_FILE_TYPE_PRC: + case LAUNCHER_FILE_TYPE_PDB: + case LAUNCHER_FILE_TYPE_PQA: + error = launcherCopyPrcPdbPqaToSdCard(&files[index], &fileId); + break; + + case LAUNCHER_FILE_TYPE_ZIP: + error = launcherCopyZipContentsToSdCard(&files[index], &fileId); + break; + + case LAUNCHER_FILE_TYPE_NONE: + case LAUNCHER_FILE_TYPE_IMG: + case LAUNCHER_FILE_TYPE_INFO_IMG: + default: + error = EMU_ERROR_INVALID_PARAMETER; + break; + } + + if(error != EMU_ERROR_NONE) + return error; + } + + return EMU_ERROR_NONE; +} + uint32_t launcherLaunch(file_t* files, uint32_t fileCount, uint8_t* sramData, uint32_t sramSize, uint8_t* sdCardData, uint32_t sdCardSize){ bool applicationFileHasBeenLoaded = false; bool cardImageHasBeenLoaded = false; bool bootFileExists = false; uint32_t bootFileNum; - uint64_t totalSize = 0; - uint32_t count; + uint32_t totalSize = 0; bool success; + uint32_t index; - for(count = 0; count < fileCount; count++){ + for(index = 0; index < fileCount; index++){ //cant load anything else if a card image has been loaded if(cardImageHasBeenLoaded) return EMU_ERROR_INVALID_PARAMETER; //cant load a card image if an app has been loaded already - if(applicationFileHasBeenLoaded && (files[count].type == LAUNCHER_FILE_TYPE_IMG || files[count].type == LAUNCHER_FILE_TYPE_INFO_IMG)) + if(applicationFileHasBeenLoaded && (files[index].type == LAUNCHER_FILE_TYPE_IMG || files[index].type == LAUNCHER_FILE_TYPE_INFO_IMG)) return EMU_ERROR_INVALID_PARAMETER; - if(files[count].boot){ - bootFileExists = true; - bootFileNum = count; + //there must be exactly 1 boot file + if(files[index].boot){ + if(!bootFileExists) + bootFileExists = true; + else + return EMU_ERROR_INVALID_PARAMETER; } - totalSize += files[count].fileSize; + totalSize += files[index].fileSize; } if(!bootFileExists) return EMU_ERROR_INVALID_PARAMETER; - //incase the installed apps store anything on the SD card + //in case the installed apps store anything on the SD card launcherSaveSdCardImage = true; //make the card image or just copy it over @@ -61,13 +188,24 @@ uint32_t launcherLaunch(file_t* files, uint32_t fileCount, uint8_t* sramData, ui launcherSaveSdCardImage = false; } else{ + //in case the emulator is currently running with an SD card inserted + emulatorEjectSdCard(); + if(sdCardData){ //use existing SD card image emulatorInsertSdCard(sdCardData, sdCardSize, NULL); } else{ //load apps to new SD card image - //TODO + uint32_t error; + + error = emulatorInsertSdCard(NULL, totalSize, NULL); + if(error != EMU_ERROR_NONE) + return error; + + error = launcherSetupSdCardImageFromApps(files, fileCount); + if(error != EMU_ERROR_NONE) + return error; } } @@ -90,7 +228,7 @@ uint32_t launcherLaunch(file_t* files, uint32_t fileCount, uint8_t* sramData, ui //execute frames until launch is completed(or failed with a time out) success = false; palmEmuFeatures.value = 'RUN0'; - for(count = 0; count < EMU_FPS * 10; count++){ + for(index = 0; index < EMU_FPS * 10; index++){ emulatorRunFrame(); if(palmEmuFeatures.value == 'STOP'){ success = true; diff --git a/src/fileLauncher/readme.md b/src/fileLauncher/readme.md index b90017a..6a24889 100644 --- a/src/fileLauncher/readme.md +++ b/src/fileLauncher/readme.md @@ -1,10 +1,13 @@ # Automatic file launcher for Mu -This along with an internal program allows booting .prc, .pqa, .zip and .img files, .img files can be passed with an optional .info file with any .img file to specify any attributes not stored in the flash memory. +## This module is completely optional!!! +By default it is not compiled in with the emu, to build it in define EMU_HAVE_FILE_LAUNCHER. + +This along with an internal program allows booting .prc, .pqa, .zip and .img files, .img files can be passed with an optional .info file to specify any attributes not stored in the flash memory. There is also the option to load multiple files at the same time and specify the boot file. -In .zip files the file named "launch.prc" in the root of the zip is the boot file, if this file does not exist the zip is not booted, its contents are just passively installed. +In .zip files the file named "launch.prc" in the root of the zip is launched if the zip is the boot file. The supported file types are: * .prc(bootable) @@ -14,6 +17,7 @@ The supported file types are: * .img(bootable) * .info + .img(bootable) -All file types can be mixed, the last file loaded with the boot bit set will be the file that boots. +All file types can be mixed, except .img files. +.img files can not be loaded with any other file types or other .img files. -.img files can not be loaded with any other file types. +NOTE: Some Palm apps would name prc files with the ".pdb" extension or pdb files with the ".prc" extension, for this reason they are being treated the same in the boot code, attempting to boot an actual pdb will still not work. diff --git a/src/makefile.all b/src/makefile.all index 29aaed7..d75a9f2 100644 --- a/src/makefile.all +++ b/src/makefile.all @@ -20,6 +20,14 @@ EMU_SOURCES_C := $(EMU_PATH)/emulator.c \ EMU_SOURCES_CXX := EMU_SOURCES_ASM := +ifeq ($(EMU_HAVE_FILE_LAUNCHER), 1) + EMU_SOURCES_C += $(EMU_PATH)/fileLauncher/fatFs/diskio.c \ + $(EMU_PATH)/src/fileLauncher/fatFs/ff.c \ + $(EMU_PATH)/src/fileLauncher/fatFs/ffsystem.c \ + $(EMU_PATH)/src/fileLauncher/fatFs/ffunicode.c \ + $(EMU_PATH)/src/fileLauncher/launcher.c +endif + ifeq ($(EMU_SUPPORT_PALM_OS5), 1) # ARM emulator uses C++11 so it must be supported and enabled if Palm OS 5 support is enabled EMU_DEFINES += -DEMU_SUPPORT_PALM_OS5 diff --git a/src/sdCard.c b/src/sdCard.c index 7ae40b7..782d673 100644 --- a/src/sdCard.c +++ b/src/sdCard.c @@ -387,21 +387,10 @@ bool sdCardExchangeBit(bool bit){ sdCardDoResponseDataResponse(DR_CRC_ERROR); } - //this fixes broken write mode??? - //this may not be a hack, elm-chan says: + //write acknowledge is returned on the same bit as the event, unlike other flags which are on the bit/byte after + //elm-chan says: //The card responds a Data Response immediataly following the data packet from the host. //The Data Response trails a busy flag and host controller must suspend the next command or data transmission until the card goes ready. - //that could mean the response is returned starting on the final bit of the data packet instead of the bit after, violating byte boundrys - //the return data is 1 bit misaligned, but I dont know how it gets this way - //Currently: - //SPI1 transfer, bitCount:8, PC:0x100A7D98(printed 1 times) - //SPIRXD read, FIFO value:0x0082, SPIINTCS:0x0001(printed 1 times) - //SPI1 transfer, bitCount:8, PC:0x100A5B32(printed 1 times) - //SPIRXD read, FIFO value:0x0080, SPIINTCS:0x0001(printed 1 times) - //Should be: - //SPIRXD read, FIFO value:0x0005, SPIINTCS:0x0001(printed 1 times) - //SPI1 transfer, bitCount:8, PC:0x100A5B32(printed 1 times) - //SPIRXD read, FIFO value:0x0000, SPIINTCS:0x0001(printed 1 times) outputValue = sdCardResponseFifoReadBit(); if(palmSdCard.runningCommand == WRITE_SINGLE_BLOCK){ @@ -467,9 +456,9 @@ bool sdCardExchangeBit(bool bit){ static uint32_t sdCardExchangeXBitsUnoptimized(uint32_t bits, uint8_t size){ uint32_t returnBits = 0x00000000; uint32_t mask = 1 << size - 1; - uint8_t count; + uint8_t index; - for(count = 0; count < size; count++){ + for(index = 0; index < size; index++){ returnBits <<= 1; returnBits |= sdCardExchangeBit(!!(bits & mask)); bits <<= 1; @@ -519,9 +508,9 @@ uint32_t sdCardExchangeXBitsOptimized(uint32_t bits, uint8_t size){ default:{ //slow method - uint8_t count; + uint8_t index; - for(count = 0; count < size; count++){ + for(index = 0; index < size; index++){ returnBits <<= 1; returnBits |= sdCardResponseFifoReadBit(); } @@ -536,10 +525,10 @@ uint32_t sdCardExchangeXBitsOptimized(uint32_t bits, uint8_t size){ if(alignedProperly && currentByte > 0 && currentByte + size / 8 < SD_CARD_BLOCK_DATA_PACKET_SIZE - 1){ //byte aligned in the middle of a data packet, can just copy data over - uint8_t count; + uint8_t index; - for(count = 0; count < size / 8; count++){ - palmSdCard.runningCommandPacket[currentByte] = bits >> (size - 8) - (count * 8) & 0xFF; + for(index = 0; index < size / 8; index++){ + palmSdCard.runningCommandPacket[currentByte] = bits >> (size - 8) - (index * 8) & 0xFF; palmSdCard.runningCommandVars[2] += 8; currentByte++; returnBits <<= 8; diff --git a/src/sdCardAccessors.c.h b/src/sdCardAccessors.c.h index 529c83e..bd42594 100644 --- a/src/sdCardAccessors.c.h +++ b/src/sdCardAccessors.c.h @@ -28,9 +28,9 @@ static uint8_t sdCardResponseFifoReadByteOptimized(void){ case 1:{ //unsafe, use slow mode uint8_t byte = 0x00; - uint8_t count; + uint8_t index; - for(count = 0; count < 8; count++){ + for(index = 0; index < 8; index++){ byte <<= 1; byte |= sdCardResponseFifoReadBit(); }