Added USB drive support.

This commit is contained in:
Stephen White 2018-11-04 17:14:28 +11:00
parent 2a8dad9f16
commit a26a4275b2
7 changed files with 245 additions and 137 deletions

View file

@ -42,6 +42,9 @@ extern Options options;
extern void GlobalSetDeviceID(u8 id);
extern void CheckAutoMountImage(EXIT_TYPE reset_reason , FileBrowser* fileBrowser);
extern void SwitchDrive(const char* drive);
extern int numberOfUSBMassStorageDevices;
unsigned char FileBrowser::LSTBuffer[FileBrowser::LSTBuffer_size];
static const u32 palette[] =
@ -498,6 +501,7 @@ FileBrowser::FileBrowser(InputMappings* inputMappings, DiskCaddy* diskCaddy, ROM
, screenMain(screenMain)
, screenLCD(screenLCD)
, scrollHighlightRate(scrollHighlightRate)
, displayingDevices(false)
{
u32 columns = screenMain->ScaleX(80);
u32 rows = (int)(38.0f * screenMain->GetScaleY());
@ -557,6 +561,39 @@ void FileBrowser::RefreshFolderEntries()
char* ext;
folder.Clear();
if (displayingDevices)
{
char label[1024];
DWORD vsn;
f_getlabel("SD:", label, &vsn);
if (strlen(label) > 0)
sprintf(entry.filImage.fname, "SD: %s", label);
else
sprintf(entry.filImage.fname, "SD:");
entry.filImage.fattrib |= AM_DIR;
entry.filIcon.fname[0] = 0;
folder.entries.push_back(entry);
for (int USBDriveIndex = 0; USBDriveIndex < numberOfUSBMassStorageDevices; ++USBDriveIndex)
{
char USBDriveId[16];
sprintf(USBDriveId, "USB%02d:", USBDriveIndex + 1);
f_getlabel(USBDriveId, label, &vsn);
if (strlen(label) > 0)
sprintf(entry.filImage.fname, "%s %s", USBDriveId, label);
else
strcpy(entry.filImage.fname, USBDriveId);
entry.filImage.fattrib |= AM_DIR;
entry.filIcon.fname[0] = 0;
folder.entries.push_back(entry);
}
}
else
{
res = f_opendir(&dir, ".");
if (res == FR_OK)
{
@ -566,8 +603,7 @@ void FileBrowser::RefreshFolderEntries()
ext = strrchr(entry.filImage.fname, '.');
if (res == FR_OK && entry.filImage.fname[0] != 0 && !(ext && strcasecmp(ext, ".png") == 0))
folder.entries.push_back(entry);
}
while (res == FR_OK && entry.filImage.fname[0] != 0);
} while (res == FR_OK && entry.filImage.fname[0] != 0);
f_closedir(&dir);
// Now check for icons
@ -591,8 +627,7 @@ void FileBrowser::RefreshFolderEntries()
}
}
}
}
while (res == FR_OK && entry.filIcon.fname[0] != 0);
} while (res == FR_OK && entry.filIcon.fname[0] != 0);
}
f_closedir(&dir);
@ -610,6 +645,7 @@ void FileBrowser::RefreshFolderEntries()
{
//DEBUG_LOG("Cannot open dir");
}
}
// incase they deleted something selected in the caddy
caddySelections.Clear();
@ -807,10 +843,38 @@ void FileBrowser::DisplayPNG()
}
}
int FileBrowser::IsAtRootOfDevice()
{
char buffer[1024];
if (f_getcwd(buffer, 1024) == FR_OK)
{
if (strcmp("SD:/", buffer) == 0)
return 0;
for (int USBDriveIndex = 0; USBDriveIndex < numberOfUSBMassStorageDevices; ++USBDriveIndex)
{
char USBDriveId[16];
sprintf(USBDriveId, "USB%02d:/", USBDriveIndex + 1);
if (strcmp(USBDriveId, buffer) == 0)
return USBDriveIndex + 1;
}
}
return -1;
}
void FileBrowser::PopFolder()
{
char buffer[1024];
if (f_getcwd(buffer, 1024) == FR_OK)
{
int deviceRoot = IsAtRootOfDevice();
if (deviceRoot >= 0)
{
displayingDevices = true;
RefreshFolderEntries();
folder.currentIndex = deviceRoot;
folder.SetCurrent();
}
else
{
// find the last '/' of the current dir
char *last_ptr = 0;
@ -820,10 +884,8 @@ void FileBrowser::PopFolder()
last_ptr = ptr;
ptr = strtok(NULL, "/");
}
f_chdir("..");
RefreshFolderEntries();
caddySelections.Clear();
unsigned found = 0;
if (last_ptr)
@ -844,6 +906,7 @@ void FileBrowser::PopFolder()
folder.currentIndex = found;
folder.SetCurrent();
}
}
RefeshDisplay();
}
}
@ -989,7 +1052,32 @@ void FileBrowser::UpdateInputFolders()
FileBrowser::BrowsableList::Entry* current = folder.current;
if (current)
{
if (current->filImage.fattrib & AM_DIR)
if (displayingDevices)
{
if (strncmp(current->filImage.fname, "SD", 2) == 0)
{
SwitchDrive("SD:");
displayingDevices = false;
RefreshFolderEntries();
}
else
{
for (int USBDriveIndex = 0; USBDriveIndex < numberOfUSBMassStorageDevices; ++USBDriveIndex)
{
char USBDriveId[16];
sprintf(USBDriveId, "USB%02d:", USBDriveIndex + 1);
if (strncmp(current->filImage.fname, USBDriveId, 5) == 0)
{
SwitchDrive(USBDriveId);
displayingDevices = false;
RefreshFolderEntries();
}
}
}
dirty = true;
}
else if (current->filImage.fattrib & AM_DIR)
{
if (strcmp(current->filImage.fname, "..") == 0)
{

View file

@ -224,6 +224,9 @@ private:
bool SelectROMOrDevice(u32 index);
// returns the volume index if at the root of a volume else -1
int IsAtRootOfDevice();
InputMappings* inputMappings;
enum State
@ -248,6 +251,8 @@ private:
float scrollHighlightRate;
bool displayingDevices;
char PNG[FILEBROWSER_MAX_PNG_SIZE];
};
#endif

View file

@ -8,12 +8,20 @@
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
#include "debug.h"
extern "C"
{
#include <uspi.h>
#include <uspi/usbmassdevice.h>
}
/* Definitions of physical drive number for each drive */
#define DEV_MMC 0 /* Example: Map MMC/SD card to physical drive 0 */
#define DEV_USB 1
//static struct emmc_block_dev *emmc_dev;
static CEMMCDevice* pEMMC;
static int USBDeviceIndex = -1;
#define SD_BLOCK_SIZE 512
@ -22,6 +30,11 @@ void disk_setEMM(CEMMCDevice* pEMMCDevice)
pEMMC = pEMMCDevice;
}
void disk_setUSB(unsigned deviceIndex)
{
USBDeviceIndex = (int)deviceIndex;
}
int sd_card_init(struct block_device **dev)
{
return 0;
@ -30,7 +43,6 @@ int sd_card_init(struct block_device **dev)
size_t sd_read(uint8_t *buf, size_t buf_size, uint32_t block_no)
{
// g_pLogger->Write("", LogNotice, "sd_read %d", block_no);
return pEMMC->DoRead(buf, buf_size, block_no);
}
@ -130,28 +142,9 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
//DRESULT res;
//int result;
// g_pLogger->Write("", LogNotice, "disk_read pdrv = %d", pdrv);
switch (pdrv) {
//case DEV_RAM :
// // translate the arguments here
// result = RAM_disk_read(buff, sector, count);
// // translate the reslut code here
// return res;
case DEV_MMC :
// translate the arguments here
//result = MMC_disk_read(buff, sector, count);
// g_pLogger->Write("", LogNotice, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!disk_read %d %d buf_size = 0x%x", sector, count, buf_size);
//DEBUG_LOG("r pdrv = %d\r\n", pdrv);
if (pdrv == 0)
{
for (UINT s = 0; s < count; ++s)
{
if (sd_read(buff, SD_BLOCK_SIZE, sector + s) < SD_BLOCK_SIZE)
@ -161,15 +154,15 @@ DRESULT disk_read (
buff += SD_BLOCK_SIZE;
}
return RES_OK;
}
else
{
unsigned bytes = (unsigned)USPiMassStorageDeviceRead(sector << UMSD_BLOCK_SHIFT, buff, count << UMSD_BLOCK_SHIFT, pdrv - 1);
//case DEV_USB :
// // translate the arguments here
if (bytes != (count << UMSD_BLOCK_SHIFT))
return RES_ERROR;
// result = USB_disk_read(buff, sector, count);
// // translate the reslut code here
// return res;
return RES_OK;
}
return RES_PARERR;
@ -188,29 +181,9 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
//DRESULT res;
//int result;
switch (pdrv) {
//case DEV_RAM :
// // translate the arguments here
// result = RAM_disk_write(buff, sector, count);
// // translate the reslut code here
// return res;
case DEV_MMC :
// translate the arguments here
//result = MMC_disk_write(buff, sector, count);
//size_t buf_size = count * SD_BLOCK_SIZE;
//if (sd_write((uint8_t *)buff, buf_size, sector) < buf_size)
//{
// return RES_ERROR;
//}
//DEBUG_LOG("w pdrv = %d\r\n", pdrv);
if (pdrv == 0)
{
for (UINT s = 0; s < count; ++s)
{
if (sd_write((uint8_t *)buff, SD_BLOCK_SIZE, sector+s) < SD_BLOCK_SIZE)
@ -219,17 +192,17 @@ DRESULT disk_write (
}
buff += SD_BLOCK_SIZE;
}
return RES_OK;
}
else
{
unsigned bytes = (unsigned)USPiMassStorageDeviceWrite(sector << UMSD_BLOCK_SHIFT, buff, count << UMSD_BLOCK_SHIFT, pdrv - 1);
//DEBUG_LOG("USB disk_write %d %d\r\n", (int)sector, (int)count);
if (bytes != (count << UMSD_BLOCK_SHIFT))
return RES_ERROR;
return RES_OK;
//case DEV_USB :
// // translate the arguments here
// result = USB_disk_write(buff, sector, count);
// // translate the reslut code here
// return res;
}
return RES_PARERR;

View file

@ -31,6 +31,7 @@ typedef enum {
void disk_setEMM(CEMMCDevice* pEMMCDevice);
void disk_setUSB(unsigned deviceIndex);
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);

View file

@ -519,7 +519,7 @@ typedef struct {
/ at start-up. If not, either the linker or start-up routine being used is
/ not compliance with C standard. */
#if _VOLUMES < 1 || _VOLUMES > 9
#if _VOLUMES < 1 || _VOLUMES > 17
#error Wrong _VOLUMES setting
#endif
static FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */
@ -3863,7 +3863,9 @@ FRESULT f_getcwd (
TCHAR *tp;
FILINFO fno;
DEF_NAMBUF
#if _STR_VOLUME_ID /* Find string drive id */
static const char* const str[] = { _VOLUME_STRS };
#endif
*buff = 0;
/* Get logical drive */
@ -3902,7 +3904,16 @@ FRESULT f_getcwd (
tp = buff;
if (res == FR_OK) {
#if _VOLUMES >= 2
#if _STR_VOLUME_ID /* Find string drive id */
const char* strptr = str[CurrVol];
while (*strptr != 0)
{
*tp++ = *strptr++;
}
#else
*tp++ = '0' + CurrVol; /* Put drive number */
#endif
*tp++ = ':';
#endif
if (i == len) { /* Root-directory */

View file

@ -56,7 +56,7 @@
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 0
#define _USE_LABEL 1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
@ -147,12 +147,13 @@
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define _VOLUMES 1
#define _VOLUMES 17
/* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
#define _STR_VOLUME_ID 1
//#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
#define _VOLUME_STRS "SD","USB01","USB02","USB03","USB04","USB05","USB06","USB07","USB08","USB09","USB10","USB11","USB12","USB13","USB14","USB15","USB16"
/* _STR_VOLUME_ID switches string support of volume ID.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each

View file

@ -47,7 +47,7 @@ extern "C"
#include "ssd_logo.h"
unsigned versionMajor = 1;
unsigned versionMinor = 15;
unsigned versionMinor = 16;
// When the emulated CPU starts we execute the first million odd cycles in non-real-time (ie as fast as possible so the emulated 1541 becomes responsive to CBM-Browser asap)
// During these cycles the CPU is executing the ROM self test routines (these do not need to be cycle accurate)
@ -97,6 +97,7 @@ u8 LcdLogoFile[LCD_LOGO_MAX_SIZE];
u8 s_u8Memory[0xc000];
int numberOfUSBMassStorageDevices = 0;
DiskCaddy diskCaddy;
Pi1541 pi1541;
Pi1581 pi1581;
@ -109,6 +110,7 @@ u8 deviceID = 8;
IEC_Commands m_IEC_Commands;
InputMappings* inputMappings;
Keyboard* keyboard;
bool USBKeyboardDetected = false;
//bool resetWhileEmulating = false;
bool selectedViaIECCommands = false;
u16 pc;
@ -1456,15 +1458,26 @@ void Reboot_Pi()
reboot_now();
}
void SwitchDrive(const char* drive)
{
FRESULT res;
res = f_chdrive(drive);
DEBUG_LOG("chdrive %s res %d\r\n", drive, res);
}
extern "C"
{
void kernel_main(unsigned int r0, unsigned int r1, unsigned int atags)
{
FATFS fileSystem;
FRESULT res;
FATFS fileSystemSD;
FATFS fileSystemUSB[16];
m_EMMC.Initialize();
disk_setEMM(&m_EMMC);
m_EMMC.Initialize();
f_mount(&fileSystem, "", 1);
f_mount(&fileSystemSD, "SD:", 1);
RPI_AuxMiniUartInit(115200, 8);
@ -1502,7 +1515,13 @@ extern "C"
USPiInitialize();
if (!USPiKeyboardAvailable())
DEBUG_LOG("\r\n");
numberOfUSBMassStorageDevices = USPiMassStorageDeviceAvailable();
DEBUG_LOG("%d USB Mass Storage Devices found\r\n", numberOfUSBMassStorageDevices);
USBKeyboardDetected = USPiKeyboardAvailable();
if (!USBKeyboardDetected)
DEBUG_LOG("Keyboard not found\r\n");
else
DEBUG_LOG("Keyboard found\r\n");
@ -1535,6 +1554,16 @@ extern "C"
//PlaySoundDMA();
}
for (int USBDriveIndex = 0; USBDriveIndex < numberOfUSBMassStorageDevices; ++USBDriveIndex)
{
char USBDriveId[16];
disk_setUSB(USBDriveIndex);
sprintf(USBDriveId, "USB%02d:", USBDriveIndex + 1);
res = f_mount(&fileSystemUSB[USBDriveIndex], USBDriveId, 1);
}
if (numberOfUSBMassStorageDevices > 0)
SwitchDrive("USB01:");
f_chdir("/1541");
m_IEC_Commands.SetStarFileName(options.GetStarFileName());