It would seem to be a pretty straightforward program. I did a little Google searching, which took me right back to this site! There's a post from Michael (SeaGtGruff) from back in 2013 that, in part, contains this info...
So to summarize, so far it looks like the .USR files are organized as follows:
- file identifier (16 bytes)
- sizes and format versions for the song, registration, and style sections (32 bytes)
- style names (200 bytes, or 5 * 40 bytes)
- unknown (4 bytes)
- song section (variable length, can be 0 bytes)
- registration section (1800 bytes, or 32 * 56 bytes bookended by a 4-byte header and 4-byte trailer)
- style section (variable length, can be 0 bytes)
This is just a small part of a much more detailed post in this thread...
https://www.psrtutorial.com/forum/index.php?topic=23188.0And of course, it is over four years old, so Michael may have discovered more complete/accurate information since then.
But, if the general format stated above holds true, it looks like all a program would have to do is load the file into memory, search for the first occurrence of the header "PSR." (where the "." is actually an unprintable character -- this is all described in more detail in the actual thread), then access the desired registration data by adding a calculated multiple of 56 to the file position of the header "PSR.", as other data in the above thread mentions speculation that each registration takes 56 bytes of data. This would be done with both USR files being worked on, and it should just be a simple matter of copying the 56-byte block of data, byte by byte, from the calculated position of the "source" file to the calculated position of the "destination" file, and then saving the modified "destination" file back on to the hard drive or flash drive, perhaps with a new filename to preserve the original USR file.
EDIT: I guess there would be the chance of the ASCII codes for the characters "P", "S", "R", and the unprintable character coming up coincidentally in the song data or elsewhere, so it might be advisable to take a precaution. Perhaps, upon finding the "PSR.", go up 1796 bytes from the "P" and see if you find the other "PSR.", and if so, then that essentially confirms you found the registration data. I would think the chances of "PSR." being randomly in those positions elsewhere to be exceptionally small.
Of course, the start points of the registration data would have to be calculated individually for both USR files, because it appears that the existence (or nonexistence) of song data would vary where the first "PSR." header is placed and therefore where registration data starts in each file.
And, I would think there might be a checksum in the USR file that adds the values of all the bytes of the file together for the purpose of error checking. If so, then this checksum would also have to be adjusted to reflect the new registration data.
Perhaps there are other considerations, but if not, it would seem quite possible. I could almost write such a program in BASIC, except that I don't know if BASIC's file handling capabilities would allow loading and manipulating such a file. I remember learning to "open" a file, then read it into string variables line by line until the end of the file is reached, then "close" the file. But those were simple text files, and I think each line was delineated by a carriage-return. On something like a USR file, with no carriage-return, it could try to cram the whole thing into one string variable, and the limitations of the programming language might not allow for such a large string variable. Or, the presence of the number 13 in any byte (which is the ASCII code for a carriage-return, if I remember correctly) could cause the program to treat different sections of the USR file as different lines of data.
Also, this is strictly for the PSR-E433, but I bet the E443 and E453 work similarly, but with a different number of bytes for custom styles and registration data to reflect the increased capabilities of these keyboards.