For the more inquisitive, I will say that for a long time I had the intention of introducing a few modifications to the selector software (i.e. the part of the code responsible for operating the menu and the entire user interface) in KrzysioCarta
* The main reason was to add a save persistence in the case of games that support saving and have a battery in cartridge releases, e.g. Kirby, Final Fantasy),
* I also wanted to make some smaller changes according to the suggestions (e.g. automatic cursor movement when we hold the arrow or in the case when there are a lot of files in the folder - speed up the transition to the next screens),
* and also correct some minor bugs (e.g. in some rare cases, after entering a directory, and then going back to a higher level, from some point on, items may be displayed incorrectly)
Simply adding a battery to the cartridge would not solve the issue of preserving the record:

* First, because the selector also uses this memory for its own purposes and the data saved by the game would be erased.
* And even if you eliminated the use of this memory, after selecting a new game, the save from the previous game would be erased with the new one.
So a different approach was needed.
Of course, I had to start all the work by reviewing and analyzing the code that I hadn't looked at for 1-2 years. Unfortunately, with assembler it is so, that sometimes and after 2 days, looking at a fragment, I wonder not what it is responsible for, but whether I wrote it at all

)
The first step was to streamline the testing process. Believe it or not, the work cycle so far has been as follows:
wprowadzenie poprawki do kodu -> kompilacja kodu -> wsadzenie KrzysioCarta do Kazzo -> przeprogramowanie kartridża nowym kodem -> wsadzenie KrzysioCarta do konsoli -> uruchomienie -> jeśli nie działa zgodnie z oczekiwaniem - wróć na początek
Testing in the emulator was not possible, because the cartridge uses a memory card and also programs an internal flash-rom. However, I said enough and added my mapper definition to the emulator, which emulates both flash-rom (sending programming / deleting commands) and the memory card (sending all necessary SPI commands). Any hard disk image file can be selected as the "content" of the card.

The advantage is not only the speed of testing, but most of all the possibility of debugging - checking which command was sent to the card, which command to the flash-rom. And when "something" is written on the card, but it does not work as expected, you can preview the difference in sectors before and after writing.
-
In order to implement the save game functionality, it was necessary to add a number of functionalities:
* adding the SPI (CMD24) command to write the sector to the memory card,
* adding a file / directory search function for a given name in a given directory to know if, for example, there is already a SAVE file for a game
* modification of the existing function of reading the cluster from the FAT partition, taking into account checking whether we are at the end of the cluster - useful when we want to create a new entry in the directory, and the current entries already fill the entire cluster
* added function to find the first free cluster in a FAT partition
* adding the function of extending the existing FAT chain in the partition with a newly found free one
* adding the function of creating a new entry (file / directory) in a given directory, taking into account the need to create entries with a long name (LFN - Long File Name).
I had quite a headache with the latter, because Windows, despite creating such entries, did not want to take into account the long name, and always displayed the short name (8 + 3). Additionally, testing with CHKDISK found errors. For the uninitiated, I would like to remind you that the content of each directory is stored in the cluster in the form of direntry entries. Each of these entries takes 32 bytes and contains, among others, the following information:
* name (8 + 11 characters), which is what DOS used to display
* starting cluster where file / directory starts
* file size in bytes
* date of creation / modification / last access
* attributes (archival, read-only, system, hidden).
To create something with a longer name, Windows adds dummy entries (called LFN - Long File Name). Each of such entries stores information about 13 characters from the name, so e.g. when creating a file "Ala ma cat.txt", the system will create 3 entries for such a file in this order
"xt*`````````` (LFN #2)
"Ala ma kota.t" (LFN #1)
ALAMAK~1.TXT 8+3 entry
So why were there so many problems with it? There are some tricks:
a) the need to correctly calculate the CRC checksum from the short name and place it in each LFN entry
b) The fields in the last LFN entry after the trailing 00 character (marked with an asterisk) must be FF (marked with `).
c) If the name is 26 characters, the system will create two LFN entries (there will be no third entry with only trailing zero and the rest of the FFs)

* need to generate short name from long name. Initially, I wanted these names to follow "good rules", ie the first six letters, a tilde and a number, eg MOJPLI ~ 1. This, however, would entail the necessity to re-search the directory to see if such a name exists, and if it does, then another search to see if there is MOJPLI ~ 2, etc. operations, e.g.
1998-01-09 17:44 65 552 THELEG~1.NES The Legend of Kage.nes
1997-07-13 03:53 131 088 THELEG~2.NES The Legends of Zelda 1.nes
1997-04-06 13:54 245 904 THELEG~3.NES The Legends of Zelda 2.nes
Looking for another idea, I accidentally checked that Windows does not stick to these "good rules" anyway - e.g. when the long name includes regional characters (e.g. "oż"), its DOS name is 0C707 ~ 1 despite the fact that the long name and so is shorter than 8 characters. Then I had the idea that the short name does not have to be related to the new one in any way. All you have to do is make sure that it is unique in a given folder - and it's great to take the hexadecimal cluster number as the name of the starting cluster number - it is just 8 characters long.
Of course, someone seeing something like this could be surprised or laugh a lot, but who uses DOS nowadays? Besides, what's the difference, if it works anyway

The very transfer of the content of WRAM memory to the memory card (and the other way round) is also not easy, because the functions of the memory card and FAT support also use this memory as a temporary one. Therefore, it was necessary to use one of the unused areas of the flash-rom as a temporary storage location:
* When transferring WRAM-> MemoryCard, the program must program the contents of the WRAM memory in the flash-rom, and then gradually save from the flash-rom to the memory card
* At KartaPmem-> WRAM, the program first programs the flash-rom with data read from the card, and then, just before starting the game, it rewrites them from the flash-rom to WRAM.
Finally, just testing whether the WRAM memory content is restored correctly was also troublesome on ready-made games, because it required, for example, passing the first level in Kirby, because only then the player's location was saved.
So I had to write my ROM for the test, which calculates the CRC from the data stored in the WRAM and if the user asks for it - it generates a new memory content:

Tips:
* In FAT16, the root directory is not stored in the cluster, but just after the allocation tables. As a result, the maximum number of entries is limited in advance and this must be taken into account (checked) when creating a new entry
* By the way, I found the cause of the previously described error related to going back to the main directory: the system puts two (invisible to the user, unless using DOS) entries in each folder:. and .., pointing to the current folder and a higher-level folder.
For some reason in FAT32, if .. points to the root folder, then its cluster number in this entry is 0, not 2. As a result, cardij, wanting to list the contents of the folder at a higher level, reads the cluster pointing to ".. "and reads the contents of cluster 0, which is garbage. (which is funny - in FAT16 it worked, because for the sake of simplicity I assumed that in fact the root directory cluster is number 0)
* Finding the first free cluster - in the case of FAT16 partitions, the maximum number of clusters is 2 ^ 16 - 2 i.e. 65534
Fixes (improvements) compared to the previous version:
* the cartridge has a battery that stores the contents of the internal RAM memory when you turn off the console. After restarting, the memory content is automatically transferred to the micro SD card (to the! SAVE directory), and when you select the same game again sometime, the save state is restored. Selecting another one when it DOES NOT CAUSE the loss of the previous write state. The files with the saved state can then be read on the computer and, for example, finish the game on the emulator or the other way round - the game started on the emulator can be finished on a real console.
* adding support for mapper 30 - now it is also possible to play games created with NesMaker - a program facilitating game development or other unofficial titles with a size of 512 kB using mapper No. 2 (e.g. Battle Kid 2),
* displaying subtitles was previously implemented as: 1) disable image generation, 2) display, 3) enable image generation, which caused flashing. Currently it is: 1) wait for vblank 2) view.
* Display the names of buttons "A", "B", "SELECT" as graphics instead of text on the main screen
* Holding down the down / up / right / left button scrolls continuously
* When going to the next page with the list of files, the information from the previous function call is used, thanks to which the screen appears faster
* Unicode characters> 127 (regional) will be displayed as a dash instead of something random.
* wide range of housing colors with a choice of your favorite color

And for die-hard NESmaniaków - soon a version adapted for the NES console: