diff --git a/.gitignore b/.gitignore index 3734ad6..d2da255 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ *.elf *.img *.lst -*.map \ No newline at end of file +*.map +*.swp + diff --git a/options.txt b/options.txt index c2d900c..8ecff4d 100644 --- a/options.txt +++ b/options.txt @@ -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 diff --git a/src/FileBrowser.cpp b/src/FileBrowser.cpp index 59647ea..739c8da 100644 --- a/src/FileBrowser.cpp +++ b/src/FileBrowser.cpp @@ -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; +} diff --git a/src/FileBrowser.h b/src/FileBrowser.h index 45611de..7893b22 100644 --- a/src/FileBrowser.h +++ b/src/FileBrowser.h @@ -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 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; diff --git a/src/InputMappings.cpp b/src/InputMappings.cpp index 6ca7164..5c2b83b 100644 --- a/src/InputMappings.cpp +++ b/src/InputMappings.cpp @@ -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])) diff --git a/src/InputMappings.h b/src/InputMappings.h index 6e5f99f..19a5d64 100644 --- a/src/InputMappings.h +++ b/src/InputMappings.h @@ -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 { @@ -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; diff --git a/src/Keyboard.h b/src/Keyboard.h index 4d2ba74..ad0e631 100644 --- a/src/Keyboard.h +++ b/src/Keyboard.h @@ -344,5 +344,9 @@ public: { return (keyStatus[0] | keyStatus[1]); } + inline bool KeyEitherAlt() + { + return (modifier & (KEY_MOD_LALT | KEY_MOD_RALT) ); + } }; #endif diff --git a/src/ROMs.h b/src/ROMs.h index 7f438bc..38cf962 100644 --- a/src/ROMs.h +++ b/src/ROMs.h @@ -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]; diff --git a/src/iec_commands.cpp b/src/iec_commands.cpp index 1bc71d3..0d70a2c 100644 --- a/src/iec_commands.cpp +++ b/src/iec_commands.cpp @@ -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); + } +} diff --git a/src/iec_commands.h b/src/iec_commands.h index 5f35dd0..f9f0012 100644 --- a/src/iec_commands.h +++ b/src/iec_commands.h @@ -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 \ No newline at end of file +#endif + diff --git a/src/main.cpp b/src/main.cpp index 529aee5..9a3b4b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 } } + diff --git a/src/options.cpp b/src/options.cpp index fb4569c..5fa487e 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -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); diff --git a/src/options.h b/src/options.h index b5eb17b..22a8931 100644 --- a/src/options.h +++ b/src/options.h @@ -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];