mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-02-26 08:14:13 +00:00
ini option to upload custom rom files
This commit is contained in:
7
fat.c
7
fat.c
@@ -305,8 +305,7 @@ unsigned char FindDrive(void) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
unsigned char FileOpen(fileTYPE *file, const char *name) {
|
||||
unsigned long iDirectory = 0; // only root directory is supported
|
||||
unsigned char FileOpenDir(fileTYPE *file, const char *name, unsigned long iDirectory) {
|
||||
DIRENTRY *pEntry = NULL; // pointer to current entry in sector buffer
|
||||
unsigned long iDirectorySector; // current sector of directory entries table
|
||||
unsigned long iDirectoryCluster; // start cluster of subdirectory or FAT32 root directory
|
||||
@@ -377,6 +376,10 @@ unsigned char FileOpen(fileTYPE *file, const char *name) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
unsigned char FileOpen(fileTYPE *file, const char *name) {
|
||||
return FileOpenDir(file, name, 0);
|
||||
}
|
||||
|
||||
unsigned char lfn_checksum(unsigned char *pName)
|
||||
{
|
||||
unsigned char i = 11;
|
||||
|
||||
1
fat.h
1
fat.h
@@ -128,6 +128,7 @@ unsigned long GetFATLink(unsigned long cluster);
|
||||
unsigned char FileNextSector(fileTYPE *file) RAMFUNC;
|
||||
unsigned char FileNextSectorExpand(fileTYPE *file);
|
||||
unsigned char FileOpen(fileTYPE *file, const char *name);
|
||||
unsigned char FileOpenDir(fileTYPE *file, const char *name, unsigned long dirCluster);
|
||||
unsigned char FileSeek(fileTYPE *file, unsigned long offset, unsigned long origin);
|
||||
unsigned char FileRead(fileTYPE *file, unsigned char *pBuffer) RAMFUNC;
|
||||
unsigned char FileReadEx(fileTYPE *file, unsigned char *pBuffer, unsigned long nSize);
|
||||
|
||||
30
ini_parser.c
30
ini_parser.c
@@ -13,7 +13,7 @@
|
||||
#include "ini_parser.h"
|
||||
#ifndef INI_PARSER_TEST
|
||||
#include "debug.h"
|
||||
#include "rafile.h"
|
||||
#include "fat.h"
|
||||
#endif
|
||||
#include "user_io.h"
|
||||
|
||||
@@ -56,11 +56,22 @@ FILE* ini_fp = NULL;
|
||||
char sector_buffer[INI_BUF_SIZE] = {0};
|
||||
int ini_size=0;
|
||||
#else
|
||||
RAFile ini_file;
|
||||
fileTYPE ini_file;
|
||||
#endif
|
||||
|
||||
int ini_pt = 0;
|
||||
|
||||
// call user_io_rom_upload but reload sector_buffer afterwards since the io
|
||||
// operations in user_io_rom_upload may have overwritten the buffer
|
||||
// mode = 0: prepare for rom upload, mode = 1: rom upload, mode = 2, end rom upload
|
||||
void ini_rom_upload(char *s) {
|
||||
#ifndef INI_PARSER_TEST
|
||||
user_io_rom_upload(s, 1);
|
||||
|
||||
FileRead(&ini_file, sector_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
//// ini_getch() ////
|
||||
char ini_getch()
|
||||
{
|
||||
@@ -69,14 +80,15 @@ char ini_getch()
|
||||
#ifdef INI_PARSER_TEST
|
||||
fread(sector_buffer, sizeof(char), INI_BUF_SIZE, ini_fp);
|
||||
#else
|
||||
RARead(&ini_file, sector_buffer, INI_BUF_SIZE);
|
||||
FileNextSector(&ini_file);
|
||||
FileRead(&ini_file, sector_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INI_PARSER_TEST
|
||||
if (ini_pt >= ini_size) return 0;
|
||||
#else
|
||||
if (ini_pt >= ini_file.file.size) return 0;
|
||||
if (ini_pt >= ini_file.size) return 0;
|
||||
#endif
|
||||
else return sector_buffer[(ini_pt++)&0x1ff];
|
||||
}
|
||||
@@ -303,12 +315,14 @@ void ini_parse(const ini_cfg_t* cfg)
|
||||
|
||||
ini_parser_debugf("Start INI parser for core \"%s\".", get_core_name());
|
||||
|
||||
user_io_rom_upload(NULL, 0); // prepare upload
|
||||
|
||||
// open ini file
|
||||
#ifdef INI_PARSER_TEST
|
||||
if ((ini_fp = fopen(cfg->filename, "rb")) == NULL) {
|
||||
#else
|
||||
memset(&ini_file, 0, sizeof(ini_file));
|
||||
if (!RAOpen(&ini_file, cfg->filename)) {
|
||||
if (!FileOpen(&ini_file, cfg->filename)) {
|
||||
#endif
|
||||
ini_parser_debugf("Can't open file %s !", cfg->filename);
|
||||
return;
|
||||
@@ -324,7 +338,7 @@ void ini_parse(const ini_cfg_t* cfg)
|
||||
#ifdef INI_PARSER_TEST
|
||||
ini_parser_debugf("Opened file %s with size %d bytes.", cfg->filename, ini_size);
|
||||
#else
|
||||
ini_parser_debugf("Opened file %s with size %d bytes.", cfg->filename, ini_file.file.size);
|
||||
ini_parser_debugf("Opened file %s with size %d bytes.", cfg->filename, ini_file.size);
|
||||
#endif
|
||||
|
||||
ini_pt = 0;
|
||||
@@ -333,7 +347,7 @@ void ini_parse(const ini_cfg_t* cfg)
|
||||
#ifdef INI_PARSER_TEST
|
||||
fread(sector_buffer, sizeof(char), INI_BUF_SIZE, ini_fp);
|
||||
#else
|
||||
RARead(&ini_file, sector_buffer, INI_BUF_SIZE);
|
||||
FileRead(&ini_file, sector_buffer);
|
||||
#endif
|
||||
|
||||
// parse ini
|
||||
@@ -359,6 +373,8 @@ void ini_parse(const ini_cfg_t* cfg)
|
||||
// close file
|
||||
fclose(ini_fp);
|
||||
#endif
|
||||
|
||||
user_io_rom_upload(NULL, 2); // upload done
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ typedef struct {
|
||||
//// functions ////
|
||||
void ini_parse(const ini_cfg_t* cfg);
|
||||
void ini_save(const ini_cfg_t* cfg);
|
||||
void ini_rom_upload(char *s);
|
||||
|
||||
#endif // __INI_PARSER_H__
|
||||
|
||||
|
||||
@@ -57,12 +57,12 @@ const ini_var_t mist_ini_vars[] = {
|
||||
{"JOYSTICK_DISABLE_SHORTCUTS", (void*)(&(mist_cfg.joystick_disable_shortcuts)), UINT8, 0, 1, 1},
|
||||
{"JOYSTICK_IGNORE_OSD", (void*)(&(mist_cfg.joystick_ignore_osd)), UINT8, 0, 1, 1},
|
||||
{"JOYSTICK0_PREFER_DB9", (void*)(&(mist_cfg.joystick0_prefer_db9)), UINT8, 0, 1, 1},
|
||||
{"KEY_MENU_AS_RGUI", (void*)(&(mist_cfg.key_menu_as_rgui)), UINT8, 0, 1, 1},
|
||||
{"KEY_MENU_AS_RGUI", (void*)(&(mist_cfg.key_menu_as_rgui)), UINT8, 0, 1, 1},
|
||||
{"KEY_REMAP", (void*)user_io_key_remap, CUSTOM_HANDLER, 0, 0, 1},
|
||||
{"HID_BUTTON_REMAP", (void*)hid_joystick_button_remap, CUSTOM_HANDLER, 0, 0, 1},
|
||||
{"JOYSTICK_REMAP", (void*)virtual_joystick_remap, CUSTOM_HANDLER, 0, 0, 1},
|
||||
{"JOY_KEY_MAP", (void*)joystick_key_map, CUSTOM_HANDLER, 0, 0, 1}
|
||||
|
||||
{"JOY_KEY_MAP", (void*)joystick_key_map, CUSTOM_HANDLER, 0, 0, 1},
|
||||
{"ROM", (void*)ini_rom_upload, CUSTOM_HANDLER, 0, 0, 1}
|
||||
};
|
||||
|
||||
// mist ini config
|
||||
|
||||
122
user_io.c
122
user_io.c
@@ -20,6 +20,7 @@
|
||||
#include "mmc.h"
|
||||
#include "tos.h"
|
||||
#include "errors.h"
|
||||
#include "ini_parser.h"
|
||||
|
||||
// up to 16 key can be remapped
|
||||
#define MAX_REMAP 16
|
||||
@@ -627,12 +628,8 @@ void user_io_file_mount(fileTYPE *file, unsigned char index) {
|
||||
spi_uio_cmd8(UIO_SET_SDSTAT, index);
|
||||
}
|
||||
|
||||
void user_io_file_tx(fileTYPE *file, unsigned char index) {
|
||||
unsigned long bytes2send = file->size;
|
||||
|
||||
/* transmit the entire file using one transfer */
|
||||
|
||||
iprintf("Selected file %.11s with %lu bytes to send for index %d\n", file->name, bytes2send, index);
|
||||
static void user_io_file_tx_prepare(unsigned char index) {
|
||||
iprintf("Preparing transmission for index %d\n", index);
|
||||
|
||||
// set index byte (0=bios rom, 1-n=OSD entry index)
|
||||
user_io_set_index(index);
|
||||
@@ -643,13 +640,18 @@ void user_io_file_tx(fileTYPE *file, unsigned char index) {
|
||||
spi_write((void*)(DirEntry+sort_table[iSelectedEntry]), sizeof(DIRENTRY));
|
||||
DisableFpga();
|
||||
|
||||
// hexdump(DirEntry+sort_table[iSelectedEntry], sizeof(DIRENTRY), 0);
|
||||
|
||||
// prepare transmission of new file
|
||||
EnableFpga();
|
||||
SPI(UIO_FILE_TX);
|
||||
SPI(0xff);
|
||||
DisableFpga();
|
||||
}
|
||||
|
||||
static void user_io_file_tx_send(fileTYPE *file) {
|
||||
unsigned long bytes2send = file->size;
|
||||
|
||||
/* transmit the entire file using one transfer */
|
||||
iprintf("Selected file %.11s with %lu bytes to send\n", file->name, file->size);
|
||||
|
||||
while(bytes2send) {
|
||||
iprintf(".");
|
||||
@@ -673,7 +675,9 @@ void user_io_file_tx(fileTYPE *file, unsigned char index) {
|
||||
if(bytes2send)
|
||||
FileNextSector(file);
|
||||
}
|
||||
}
|
||||
|
||||
static void user_io_file_tx_done(void) {
|
||||
// signal end of transmission
|
||||
EnableFpga();
|
||||
SPI(UIO_FILE_TX);
|
||||
@@ -683,6 +687,12 @@ void user_io_file_tx(fileTYPE *file, unsigned char index) {
|
||||
iprintf("\n");
|
||||
}
|
||||
|
||||
void user_io_file_tx(fileTYPE *file, unsigned char index) {
|
||||
user_io_file_tx_prepare(index);
|
||||
user_io_file_tx_send(file);
|
||||
user_io_file_tx_done();
|
||||
}
|
||||
|
||||
// 8 bit cores have a config string telling the firmware how
|
||||
// to treat it
|
||||
char *user_io_8bit_get_string(char index) {
|
||||
@@ -2039,3 +2049,99 @@ unsigned char user_io_ext_idx(fileTYPE *file, char* ext) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern unsigned char nDirEntries;
|
||||
extern unsigned long iCurrentDirectory; // cluster number of current directory, 0 for root
|
||||
|
||||
// this should be moved into fat.c and be re-used for the menu functions as well
|
||||
void change_into_core_dir(void) {
|
||||
char s[13]; // 8+3+'\0'
|
||||
user_io_create_config_name(s);
|
||||
|
||||
// try to change into subdir named after the core
|
||||
strcpy(s+8, " ");
|
||||
iprintf("Trying to open work dir \"%s\"\n", s);
|
||||
|
||||
ScanDirectory(SCAN_INIT, "", SCAN_DIR | FIND_DIR);
|
||||
|
||||
// no return flag :(, so scan 10 times blindly...
|
||||
for(;;) {
|
||||
int i;
|
||||
char res = 0;
|
||||
unsigned short last_StartCluster = DirEntry[0].StartCluster;
|
||||
|
||||
for(i=0;i<nDirEntries;i++) {
|
||||
//iprintf("cmp %11s %11s\n", DirEntry[i].Name, s);
|
||||
if(strncasecmp(DirEntry[i].Name, s, 11) == 0) {
|
||||
ChangeDirectory(DirEntry[i].StartCluster + (fat32 ? (DirEntry[i].HighCluster & 0x0FFF) << 16 : 0));
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// found directory: stop searching
|
||||
if(res) { iprintf("ok\n"); break; }
|
||||
|
||||
// last search returned less than 8 entries: Stop searching since
|
||||
// there sure aren't more
|
||||
if(nDirEntries != 8)
|
||||
break;
|
||||
|
||||
// get next 8 directory entries
|
||||
iSelectedEntry = MAXDIRENTRIES -1;
|
||||
ScanDirectory(SCAN_NEXT_PAGE, "", SCAN_DIR | FIND_DIR);
|
||||
|
||||
// if 8 entries are returned check if the start cluster of the first entry
|
||||
// is the same as the first one in the previous list. If it is, then this
|
||||
// is the same list and we are done
|
||||
if((nDirEntries == 8) && (DirEntry[0].StartCluster == last_StartCluster))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void user_io_rom_upload(char *rname, char mode) {
|
||||
fileTYPE f;
|
||||
static char first = 1;
|
||||
char s[13]; // 8+3+'\0'
|
||||
|
||||
// new ini parsing starts, prepare uploads
|
||||
if(mode == 0) {
|
||||
first = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// ini parsing done
|
||||
if(mode == 2) {
|
||||
// has something been uploaded?
|
||||
// -> then end transfer
|
||||
if(!first) {
|
||||
iprintf("upload ends\n");
|
||||
|
||||
user_io_file_tx_done();
|
||||
user_io_8bit_set_status(0, UIO_STATUS_RESET);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// try to change into core dir. Stay in root if that doesn't exist
|
||||
change_into_core_dir();
|
||||
|
||||
strcpy(s, " ROM");
|
||||
strncpy(s, rname, strlen(rname));
|
||||
iprintf("rom upload '%s' %d\n", s, sizeof(f));
|
||||
|
||||
if (FileOpenDir(&f, s, iCurrentDirectory)) {
|
||||
iprintf("file found!\n");
|
||||
|
||||
if(first) {
|
||||
// set reset
|
||||
user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET);
|
||||
user_io_file_tx_prepare(0);
|
||||
first = 0;
|
||||
}
|
||||
|
||||
// user_io_file_tx(&f, 0);
|
||||
user_io_file_tx_send(&f);
|
||||
} else
|
||||
iprintf("file not found!\n");
|
||||
}
|
||||
|
||||
@@ -196,6 +196,10 @@ void add_modifiers(uint8_t mod, uint16_t* keys_ps2);
|
||||
void user_io_set_index(unsigned char index);
|
||||
unsigned char user_io_ext_idx(fileTYPE *, char*);
|
||||
|
||||
// called when a rom entry is found in the mist.ini
|
||||
void user_io_rom_upload(char *s, char mode);
|
||||
|
||||
#define USB_LOAD_VAR *(int*)(0x0020FF04)
|
||||
#define USB_LOAD_VAR *(int*)(0x0020FF04)
|
||||
#define USB_LOAD_VALUE 12345678
|
||||
|
||||
|
||||
Reference in New Issue
Block a user