Work on launcher

Also tryed to get x86 windows working without dynarec enabled
This commit is contained in:
meepingsnesroms
2019-05-17 21:18:31 -07:00
parent 48ba518086
commit b6093dc8ca
13 changed files with 376 additions and 96 deletions

View File

@@ -2,6 +2,7 @@
#include <QPixmap>
#include <QImage>
#include <QFile>
#include <QFileInfo>
#include <QByteArray>
#include <QDateTime>
#include <QDate>
@@ -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;

View File

@@ -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;}

View File

@@ -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));
}
}
}

View File

@@ -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;

View File

@@ -240,23 +240,6 @@
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="debugger">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/debugger.svg</normaloff>:/buttons/images/debugger.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="addressBook">
<property name="enabled">
@@ -274,23 +257,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="debugInstall">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/install.svg</normaloff>:/buttons/images/install.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="5">
<widget class="QPushButton" name="todo">
<property name="enabled">
@@ -354,6 +320,56 @@
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="debugger">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/debugger.svg</normaloff>:/buttons/images/debugger.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="debugInstall">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="mainwindow.qrc">
<normaloff>:/buttons/images/install.svg</normaloff>:/buttons/images/install.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="bootApp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Boot</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -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;

View File

@@ -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

View File

@@ -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 <stdbool.h>
#include <string.h>
#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;

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}