This commit is contained in:
Stephen White 2018-07-22 15:21:26 +10:00
commit 86131addf0
13 changed files with 206 additions and 87 deletions

4
.gitignore vendored
View File

@ -3,4 +3,6 @@
*.elf
*.img
*.lst
*.map
*.map
*.swp

View File

@ -53,6 +53,11 @@ GraphIEC = 1
// If you would like to specify what file will be loaded by LOAD"*" in browse mode then specify it here
//StarFileName = somefile
// Alt-N creates a new diskimage.
// Names are formed automatically as autoname001.d64, autoname002.d64 etc...
// change the base of the filename here
//AutoBaseName = autoname
// If you are using a LCD screen then specify it here
//LCDName = ssd1306_128x64
// If you are using a LCD screen and you would like PageUp and PageDown keys to work with it then specify this option
@ -60,6 +65,8 @@ GraphIEC = 1
// change startup logo on oled - 1541ii or 1541classic
//LcdLogoName = 1541ii
//LcdLogoName = 1541classic
//LcdLogoName = customfile.raw
// If you are using I2C LCD you can optionally change what pins it is connected to.
// (defaults to 0 for non-split lines (Option A) or 1 for split lines (Option B))
@ -68,6 +75,7 @@ GraphIEC = 1
//i2cLcdAddress = 60 // I2C display address in decimal and shifted. 60 == 0x78, 61 == 0x7A
//i2cLcdFlip = 1 // Rotate i2c LCD screen 180 degrees
//i2cLcdOnContrast = 127 // Allows you to adjust the contrast on your i2c LCD screen
//i2cScan = 1 // scan i2c bus and display addresses on screen
//QuickBoot = 0 // faster startup
//ShowOptions = 0 // display some options on startup screen

View File

@ -32,12 +32,19 @@ extern "C"
#include "rpi-gpio.h"
}
#include "iec_commands.h"
extern IEC_Commands m_IEC_Commands;
extern Options options;
#define PNG_WIDTH 320
#define PNG_HEIGHT 200
extern void GlobalSetDeviceID(u8 id);
unsigned char FileBrowser::LSTBuffer[FileBrowser::LSTBuffer_size];
const unsigned FileBrowser::SwapKeys[30] =
const unsigned FileBrowser::SwapKeys[33] =
{
KEY_F1, KEY_KP1, KEY_1,
KEY_F2, KEY_KP2, KEY_2,
@ -48,7 +55,8 @@ const unsigned FileBrowser::SwapKeys[30] =
KEY_F7, KEY_KP7, KEY_7,
KEY_F8, KEY_KP8, KEY_8,
KEY_F9, KEY_KP9, KEY_9,
KEY_F10, KEY_KP0, KEY_0
KEY_F10, KEY_KP0, KEY_0,
KEY_F11, KEY_KPMINUS, KEY_MINUS
};
static const u32 palette[] =
@ -370,7 +378,7 @@ FileBrowser::BrowsableList::Entry* FileBrowser::BrowsableList::FindEntry(const c
return 0;
}
FileBrowser::FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD, float scrollHighlightRate)
FileBrowser::FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, u8* deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD, float scrollHighlightRate)
: state(State_Folders)
, diskCaddy(diskCaddy)
, selectionsMade(false)
@ -892,21 +900,36 @@ void FileBrowser::UpdateInputFolders()
dirty = AddToCaddy(current);
}
}
else if (inputMappings->BrowseNewD64())
{
char newFileName[64];
strncpy (newFileName, options.GetAutoBaseName(), 63);
int num = folder.FindNextAutoName( newFileName );
m_IEC_Commands.CreateD64(newFileName, "42", true);
FolderChanged();
}
else
{
unsigned keySetIndex;
for (keySetIndex = 0; keySetIndex < ROMs::MAX_ROMS; ++keySetIndex)
for (keySetIndex = 0; keySetIndex < 11; ++keySetIndex)
{
unsigned keySetIndexBase = keySetIndex * 3;
if (keyboard->KeyPressed(FileBrowser::SwapKeys[keySetIndexBase]) || keyboard->KeyPressed(FileBrowser::SwapKeys[keySetIndexBase + 1]) || keyboard->KeyPressed(FileBrowser::SwapKeys[keySetIndexBase + 2]))
if (keyboard->KeyPressed(FileBrowser::SwapKeys[keySetIndexBase])
|| keyboard->KeyPressed(FileBrowser::SwapKeys[keySetIndexBase + 1])
|| keyboard->KeyPressed(FileBrowser::SwapKeys[keySetIndexBase + 2]))
{
if (roms->ROMValid[keySetIndex])
if ( (keySetIndex < ROMs::MAX_ROMS) && (roms->ROMValid[keySetIndex]) )
{
roms->currentROMIndex = keySetIndex;
roms->lastManualSelectedROMIndex = keySetIndex;
DEBUG_LOG("Swap ROM %d %s\r\n", keySetIndex, roms->ROMNames[keySetIndex]);
ShowDeviceAndROM();
}
else if ( (keySetIndex >= 7) && (keySetIndex <= 10 ) )
{
GlobalSetDeviceID( keySetIndex+1 );
ShowDeviceAndROM();
}
}
}
@ -1028,7 +1051,7 @@ void FileBrowser::ShowDeviceAndROM()
u32 x = 0; // 43 * 8
u32 y = screenMain->ScaleY(STATUS_BAR_POSITION_Y) - 20;
snprintf(buffer, 256, "Device %d %s\r\n", deviceID, roms->ROMNames[roms->currentROMIndex]);
snprintf(buffer, 256, "Device %2d %s\r\n", *deviceID, roms->ROMNames[roms->currentROMIndex]);
screenMain->PrintText(false, x, y, buffer, textColour, bgColour);
}
@ -1241,3 +1264,33 @@ void FileBrowser::AutoSelectImage(const char* image)
selectionsMade = FillCaddyWithSelections();
}
}
int FileBrowser::BrowsableList::FindNextAutoName(char* filename)
{
int index;
int len = (int)entries.size();
int inputlen = strlen(filename);
int lastNumber = 0;
char scanfname[64];
strncpy (scanfname, filename, 54);
strncat (scanfname, "%d",2);
int foundnumber;
for (index = 0; index < len; ++index)
{
Entry* entry = &entries[index];
if ( !(entry->filImage.fattrib & AM_DIR)
&& strncasecmp(filename, entry->filImage.fname, inputlen) == 0
&& sscanf(entry->filImage.fname, scanfname, &foundnumber) == 1
)
{
if (foundnumber > lastNumber)
lastNumber = foundnumber;
}
}
snprintf(filename + inputlen, 54, "%03d.d64", lastNumber+1);
return lastNumber+1;
}

View File

@ -151,6 +151,7 @@ public:
};
Entry* FindEntry(const char* name);
int FindNextAutoName(char* basename);
void RefreshViews();
void RefreshViewsHighlightScroll();
@ -165,7 +166,7 @@ public:
std::vector<BrowsableListView> views;
};
FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, unsigned deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD, float scrollHighlightRate);
FileBrowser(DiskCaddy* diskCaddy, ROMs* roms, u8* deviceID, bool displayPNGIcons, ScreenBase* screenMain, ScreenBase* screenLCD, float scrollHighlightRate);
void AutoSelectImage(const char* image);
void DisplayRoot();
@ -187,8 +188,6 @@ public:
void ClearScreen();
void SetDeviceID(u8 id) { deviceID = id; }
static const long int LSTBuffer_size = 1024 * 8;
static unsigned char LSTBuffer[];
@ -229,7 +228,7 @@ private:
bool selectionsMade;
const char* lastSelectionName;
ROMs* roms;
unsigned deviceID;
u8* deviceID;
bool displayPNGIcons;
BrowsableList caddySelections;

View File

@ -170,10 +170,12 @@ bool InputMappings::CheckKeyboardBrowseMode()
// SetKeyboardFlag(PAGEUP_LCD_FLAG);
//else if (keyboard->KeyHeld(KEY_END))
// SetKeyboardFlag(PAGEDOWN_LCD_FLAG);
else if (keyboard->KeyHeld(KEY_N) && keyboard->KeyEitherAlt() )
SetKeyboardFlag(NEWD64_FLAG);
else
{
unsigned index;
for (index = 0; index < 10; ++index)
for (index = 0; index < 11; ++index)
{
unsigned keySetIndexBase = index * 3;
if (keyboard->KeyHeld(FileBrowser::SwapKeys[keySetIndexBase]) || keyboard->KeyHeld(FileBrowser::SwapKeys[keySetIndexBase + 1]) || keyboard->KeyHeld(FileBrowser::SwapKeys[keySetIndexBase + 2]))

View File

@ -28,14 +28,17 @@
#define UP_FLAG (1 << 4)
#define PAGEUP_FLAG (1 << 5)
#define DOWN_FLAG (1 << 6)
#define PAGEDOWN_FLAG (1 << 7)
#define PAGEDOWN_FLAG (1 << 7)
#define SPACE_FLAG (1 << 8)
#define BACK_FLAG (1 << 9)
#define INSERT_FLAG (1 << 10)
#define NUMBER_FLAG (1 << 11)
#define PAGEDOWN_LCD_FLAG (1 << 12)
#define PAGEUP_LCD_FLAG (1 << 13)
#define PAGEDOWN_LCD_FLAG (1 << 12)
#define PAGEUP_LCD_FLAG (1 << 13)
#define NEWD64_FLAG (1 << 14)
// dont exceed 32!!
class InputMappings : public Singleton<InputMappings>
{
@ -137,6 +140,11 @@ public:
return KeyboardFlag(INSERT_FLAG)/* | UartFlag(INSERT_FLAG)*/ | ButtonFlag(INSERT_FLAG);
}
inline bool BrowseNewD64()
{
return KeyboardFlag(NEWD64_FLAG);
}
// Used by the 2 cores so need to be volatile
//volatile static unsigned directDiskSwapRequest;
static unsigned directDiskSwapRequest;

View File

@ -344,5 +344,9 @@ public:
{
return (keyStatus[0] | keyStatus[1]);
}
inline bool KeyEitherAlt()
{
return (modifier & (KEY_MOD_LALT | KEY_MOD_RALT) );
}
};
#endif

View File

@ -34,7 +34,7 @@ public:
void ResetCurrentROMIndex();
static const int ROM_SIZE = 16384;
static const int MAX_ROMS = 8;
static const int MAX_ROMS = 7;
unsigned char ROMImages[MAX_ROMS][ROM_SIZE];
char ROMNames[MAX_ROMS][256];

View File

@ -1099,71 +1099,16 @@ void IEC_Commands::New(void)
if (ParseFilenames((char*)channel.buffer, filenameNew, ID))
{
FILINFO filInfo;
FRESULT res;
char* ptr;
int i;
//bool g64 = false;
//if (strstr(filenameNew, ".g64") || strstr(filenameNew, ".G64"))
// g64 = true;
//else
if(!(strstr(filenameNew, ".d64") || strstr(filenameNew, ".D64")))
strcat(filenameNew, ".d64");
res = f_stat(filenameNew, &filInfo);
if (res == FR_NO_FILE)
{
FIL fpOut;
res = f_open(&fpOut, filenameNew, FA_CREATE_ALWAYS | FA_WRITE);
if (res == FR_OK)
{
char buffer[256];
u32 bytes;
u32 blocks;
int ret = CreateD64(filenameNew, ID, true);
memset(buffer, 0, sizeof(buffer));
// TODO: Should check for disk full.
for (blocks = 0; blocks < 357; ++blocks)
{
if (f_write(&fpOut, buffer, 256, &bytes) != FR_OK)
break;
}
ptr = (char*)&blankD64DIRBAM[DISKNAME_OFFSET_IN_DIR_BLOCK];
int len = strlen(filenameNew);
for (i = 0; i < len; ++i)
{
*ptr++ = ascii2petscii(filenameNew[i]);
}
for (; i < 18; ++i)
{
*ptr++ = 0xa0;
}
for (i = 0; i < 2; ++i)
{
*ptr++ = ascii2petscii(ID[i]);
}
f_write(&fpOut, blankD64DIRBAM, 256, &bytes);
buffer[1] = 0xff;
f_write(&fpOut, buffer, 256, &bytes);
buffer[1] = 0;
for (blocks = 0; blocks < 324; ++blocks)
{
if (f_write(&fpOut, buffer, 256, &bytes) != FR_OK)
break;
}
f_close(&fpOut);
// Mount the new disk? Shoud we do this or let them do it manually?
if (f_stat(filenameNew, &filInfo) == FR_OK)
{
DIR dir;
Enter(dir, filInfo);
}
}
}
if (ret==0)
updateAction = REFRESH;
else
{
Error(ERROR_63_FILE_EXISTS);
}
Error(ret);
}
}
@ -1233,6 +1178,7 @@ void IEC_Commands::Scratch(void)
f_unlink(filInfo.fname);
}
res = f_findnext(&dir, &filInfo);
updateAction = REFRESH;
}
text = ParseNextName(text, filename, true);
}
@ -1926,3 +1872,74 @@ void IEC_Commands::CloseFile(u8 secondary)
channel.Close();
}
int IEC_Commands::CreateD64(char* filenameNew, char* ID, bool automount)
{
FILINFO filInfo;
FRESULT res;
char* ptr;
int i;
//bool g64 = false;
//if (strstr(filenameNew, ".g64") || strstr(filenameNew, ".G64"))
// g64 = true;
//else
if(!(strstr(filenameNew, ".d64") || strstr(filenameNew, ".D64")))
strcat(filenameNew, ".d64");
res = f_stat(filenameNew, &filInfo);
if (res == FR_NO_FILE)
{
FIL fpOut;
res = f_open(&fpOut, filenameNew, FA_CREATE_ALWAYS | FA_WRITE);
if (res == FR_OK)
{
char buffer[256];
u32 bytes;
u32 blocks;
memset(buffer, 0, sizeof(buffer));
// TODO: Should check for disk full.
for (blocks = 0; blocks < 357; ++blocks)
{
if (f_write(&fpOut, buffer, 256, &bytes) != FR_OK)
break;
}
ptr = (char*)&blankD64DIRBAM[DISKNAME_OFFSET_IN_DIR_BLOCK];
int len = strlen(filenameNew);
for (i = 0; i < len; ++i)
{
*ptr++ = ascii2petscii(filenameNew[i]);
}
for (; i < 18; ++i)
{
*ptr++ = 0xa0;
}
for (i = 0; i < 2; ++i)
{
*ptr++ = ascii2petscii(ID[i]);
}
f_write(&fpOut, blankD64DIRBAM, 256, &bytes);
buffer[1] = 0xff;
f_write(&fpOut, buffer, 256, &bytes);
buffer[1] = 0;
for (blocks = 0; blocks < 324; ++blocks)
{
if (f_write(&fpOut, buffer, 256, &bytes) != FR_OK)
break;
}
f_close(&fpOut);
}
// Mount the new disk? Shoud we do this or let them do it manually?
if (automount && f_stat(filenameNew, &filInfo) == FR_OK)
{
DIR dir;
Enter(dir, filInfo);
}
return(ERROR_00_OK);
}
else
{
return(ERROR_63_FILE_EXISTS);
}
}

View File

@ -78,6 +78,9 @@ public:
const char* GetNameOfImageSelected() const { return selectedImageName; }
const FILINFO* GetImageSelected() const { return &filInfoSelectedImage; }
void SetStarFileName(const char* fileName) { starFileName = fileName; }
int CreateD64(char* filenameNew, char* ID, bool automount);
protected:
enum ATNSequence
{
@ -128,6 +131,7 @@ protected:
void CloseAllChannels();
void SendError();
bool Enter(DIR& dir, FILINFO& filInfo);
bool FindFirst(DIR& dir, const char* matchstr, FILINFO& filInfo);
@ -168,4 +172,5 @@ protected:
const char* starFileName;
};
#endif
#endif

View File

@ -639,8 +639,15 @@ static void PlaySoundDMA()
static void SetVIAsDeviceID(u8 id)
{
if (id & 1) pi1541.VIA[0].GetPortB()->SetInput(VIAPORTPINS_DEVSEL0, true);
if (id & 2) pi1541.VIA[0].GetPortB()->SetInput(VIAPORTPINS_DEVSEL1, true);
pi1541.VIA[0].GetPortB()->SetInput(VIAPORTPINS_DEVSEL0, id & 1);
pi1541.VIA[0].GetPortB()->SetInput(VIAPORTPINS_DEVSEL1, id & 2);
}
void GlobalSetDeviceID(u8 id)
{
deviceID = id;
m_IEC_Commands.SetDeviceId(id);
SetVIAsDeviceID(id);
}
static void CheckAutoMountImage(EXIT_TYPE reset_reason , FileBrowser* fileBrowser)
@ -677,7 +684,7 @@ void emulator()
roms.lastManualSelectedROMIndex = 0;
diskCaddy.SetScreen(&screen, screenLCD);
fileBrowser = new FileBrowser(&diskCaddy, &roms, deviceID, options.DisplayPNGIcons(), &screen, screenLCD, options.ScrollHighlightRate());
fileBrowser = new FileBrowser(&diskCaddy, &roms, &deviceID, options.DisplayPNGIcons(), &screen, screenLCD, options.ScrollHighlightRate());
fileBrowser->DisplayRoot();
pi1541.Initialise();
@ -697,8 +704,10 @@ void emulator()
fileBrowser->ClearSelections();
// Go back to the root folder so you can load fb* again?
if ((resetWhileEmulating && options.GetOnResetChangeToStartingFolder()) || selectedViaIECCommands) fileBrowser->DisplayRoot(); // Go back to the root folder and display it.
else fileBrowser->RefeshDisplay(); // Just redisplay the current folder.
// if ((resetWhileEmulating && options.GetOnResetChangeToStartingFolder()) || selectedViaIECCommands)
// fileBrowser->DisplayRoot(); // Go back to the root folder and display it.
// else
fileBrowser->RefeshDisplay(); // Just redisplay the current folder.
resetWhileEmulating = false;
selectedViaIECCommands = false;
@ -788,10 +797,9 @@ void emulator()
fileBrowser->FolderChanged();
break;
case IEC_Commands::DEVICEID_CHANGED:
deviceID = m_IEC_Commands.GetDeviceId();
fileBrowser->SetDeviceID(deviceID);
GlobalSetDeviceID( m_IEC_Commands.GetDeviceId() );
fileBrowser->ShowDeviceAndROM();
SetVIAsDeviceID(deviceID); // Let the emilated VIA know
SetVIAsDeviceID(deviceID); // Let the emulated VIA know
break;
default:
break;
@ -979,12 +987,14 @@ void emulator()
IEC_Bus::WaitUntilReset();
//DEBUG_LOG("6502 resetting\r\n");
if (options.GetOnResetChangeToStartingFolder() || selectedViaIECCommands)
fileBrowser->DisplayRoot();//m_IEC_Commands.ChangeToRoot(); // TO CHECK
emulating = false;
resetWhileEmulating = true;
if (reset)
{
exitReason = EXIT_RESET;
if (options.GetOnResetChangeToStartingFolder() || selectedViaIECCommands)
fileBrowser->DisplayRoot(); // TO CHECK
}
if (exitEmulation)
exitReason = EXIT_KEYBOARD;
break;
@ -1125,6 +1135,8 @@ void DisplayOptions(int y_pos)
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
snprintf(tempBuffer, tempBufferSize, "LcdLogoName = %s\r\n", options.GetLcdLogoName());
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
snprintf(tempBuffer, tempBufferSize, "AutoBaseName = %s\r\n", options.GetAutoBaseName());
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
}
void DisplayI2CScan(int y_pos)
@ -1357,3 +1369,4 @@ extern "C"
#endif
}
}

View File

@ -152,6 +152,7 @@ Options::Options(void)
autoMountImageName[0] = 0;
strcpy(ROMFontName, "chargen");
strcpy(LcdLogoName, "1541ii");
strcpy(autoBaseName, "autoname");
starFileName[0] = 0;
ROMName[0] = 0;
ROMNameSlot2[0] = 0;
@ -224,6 +225,10 @@ void Options::Process(char* buffer)
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimTime)
ELSE_CHECK_FLOAT_OPTION(scrollHighlightRate)
ELSE_CHECK_DECIMAL_OPTION(keyboardBrowseLCDScreen)
else if ((strcasecmp(pOption, "AutoBaseName") == 0))
{
strncpy(autoBaseName, pValue, 255);
}
else if ((strcasecmp(pOption, "StarFileName") == 0))
{
strncpy(starFileName, pValue, 255);

View File

@ -89,6 +89,8 @@ public:
const char* GetLCDName() const { return LCDName; }
const char* GetAutoBaseName() const { return autoBaseName; }
static unsigned GetDecimal(char* pString);
static float GetFloat(char* pString);
@ -128,6 +130,7 @@ private:
unsigned int keyboardBrowseLCDScreen;
char starFileName[256];
char autoBaseName[256];
char LCDName[256];
char LcdLogoName[256];