Make carts with S29GLXXXN rom compatible
Random aliexpress cart that I've seen quite a few variation of, they seem to all use the same family of rom chips.
Hey, thanks for updating the firmware on the cart reader/write. Any additions are always appreciated. Sorry if this is a pain, but none of the repos here have the ability to provide feedback at all. I've noticed a few issues with the firmware that'd be nice to get fixed, if possible. 1/ in GB.c Line 793 OledShowString(0,0,"start RAM testing...",8); should read: OledShowString(0,0,"Start RAM testing...",8);
2/ Any chance of taking a look at why certain GBC flash chips fail? The one used in the Perfect Dark repro cart (M29W640 will happily erase and test OK, however as soon as you write to it, the cart reader/writer instantly errors out with: Flashing failed Time out! Press OK button
This leaves the cart essentially blank. Testing with smaller games results in the same failure.
3/ Macronix MX29GL128E based GBA repro carts will not write correctly and fails instantly with a "Verify" error, and as above will result in a blank cart. NDS homebrew Burn2Slot works correctly allowing the use of an NDS to flash GBA repro carts. The write functions are slightly different, which is where the problem may lie.
Again, apologies, as I appreciate this isn't the correct place to open issues, however none of the repos allow issues to the open and investigated.
On this firmware, I did have one or two minor problems with the screen blanking and some text cut off (using GBC repro carts), however I have been unable to reproduce those errors after multiple attempts.
I'll do some GBC carts when I have some spare time as I do have some that don't work on the burnmaster (don't know yet what's in them, I haven't opened them yet). Sadly, I can only do it for carts I actually own, otherwise I will just be changing code blindly, and that's never good. Don't know about GBC, but I know that for GBA, some of the "write" functions don't check all the flags available and don't rewrite when the chip signals a buffer write failure.
Thank you. All I can do is ask. Looking through the code difference between burn2slot and this cart reader/writer, I can see that generally things correspond ok in the reset and erase, but when it comes to writing data, I think you're right. There appears to be (as you call it) a flag written incorrectly.
Burn2slots code (arm9->source->app.cpp) references:
u8 data_sec[] = { 0xAA, 0x55, 0xA0}; u32* addr_sec = getAddressSeq22XX(); //(referenced earlier as u32 seq_1[] = { 0xAAA, 0x555, 0xAAA, 0xAAA, 0x555, 0xAAA};)
for(u8 i = 0; i < 3; ++i) { write_word()(addr_sec[i], data_sec[i]);
Which, using my rudimentary knowledge of coding should be similar to the code:
writeWord_GAB(0xAAA, 0xAA); writeWord_GAB(0x555, 0x55); writeWord_GAB(currSector, 0x25);
However, there's that last line which instead of writing to 0xAAA with 0xA0, the value of 0x25 is written to some(?) sector. I'd change it and test the code, but I've never managed to successfully compile the firmware using Segger studio. Even the unmodified source wouldn't generate a working copy.
Those are command words, basically the write works as follows (at least in the burnmaster code) :
- Send "write to buffer" command sequence (0xAA to 0xAAA, 0x55 to 0x555, 0x25 to sector address)
- Send the size of what will be written (word count - 1, max buffer size for the chip will be in the datasheet), for spansion 15 (0xF) to the sector address
- Write however many words (Byte addressing so we jump by 2 for the address to write each word) for spansion, 16 words write buffer, so we concatenate 2 bytes from the file and write 16 times
- Send the "Write to buffer confirm" (0x29 to sector address)
- Read the status flags by reading the last address written repeatedly until you see the correct flags (also in the datasheet, it will tell you which data pins should be 0 or 1 when you read it, and what they mean)
- If write was successful, continue with next set of words, else send program abort command and restart the step
AA 55 A0 looks like the simple "program" sequence, which might be more robust to write (not sure, but for sure it's easier to do) which is way way way slower than using the write buffer
You can easily find out what the commands are by downloading the datasheet of the chip and looking up the command definition table,
The writeWord_GAB in that codebase for some reason flips some bits, there is a way to disable that behaviour by defining TEST_MY_CART I think (or something like that) before building the firmware (you might be able to test that yourself and see if it solves the issue). As to compiling it, you can always do what I did, fork, enable actions in gitlab and let the automated pipeline do the rest.
If you decide to fork and try to fix yourself, I would suggest looking at the write function for Spansion (most of these chips have same behaviour/command sequences but different timings or sizes for buffer) to add the "Retry buffer write in case of failures" when it reads the status. Also adding some delays here and there doesn't hurt (you can always dig into the datasheet if you want to be optimal about delay timings, otherwise just plonk delays where it makes sense). The "desperate" solution would be to write word by word like burn2cart does, but it will make flashing the cart way slower than it needs to be. (Each word write will have the "program command sequence" overhead instead of 16 words having the buffer write overhead)
Also, when doing the loops, you need to pay attention to the datasheet (set correct sector sizes, buffer size etc ...)
Hey, thanks for the information, and the idea of reading the datasheet for the chip. I've grabbed it, and between that and the code, it makes a lot of sense. Is it going to help massively? Probably not, I'm not a software engineer. Amusingly, the datasheet indicates the chip has 64KW/128KB uniform sector architecture, which, if my maths is correct and when this baby hits 88 Mph, we're going to see some series writes... Wait...
The very first line in the write section for the MX29 chip reads:
for (unsigned long currSector = 0; currSector < fileSize; currSector += 0x20000)
Whoops, that sector should be 0x10000. Did I try to change that ? Yes, and I did get one version to compile and work, and it went further than previously, however further changes to the code (to adjust the timing), resulted in a failed firmware with a blank screen (see below)
I tried the "TEST_MY_CART" build... It didn't work. Infact, I'm wondering if something at my end (either the hardware or the software/firmware). The "TEST_MY_CART" build worked in as much as general functionality did what it was supposed to. However, reverting the changes back caused the updated firmware to load to a blank screen.
So, I deleted the source and copied it from the archive, rebuilt it (debug firmware for some odd reason) and it worked fine. I found a bug:
Line 2683 in GBA.c : if(manufacturerid = 0x1) {
Should read: if(manufacturerid == 0x1) {
Fix that, recompile, update the firmware and blank screen again. Delete the source code, copy it from the archive, rebuild, update the device and it works fine. Change that one line, rebuild, update and ... Blank screen again.
Given that I'm mostly just tooling around, without knowing fully what I'm doing, forking the repo and making change after change in the random hope it works, seems somewhat silly, and almost a waste of resources. However, it if will compile properly, who knows... It might be worth the effort. How quickly does the compile happen ? And how often can I change the code and have it compile?
Thanks again for your help. It has been a frustrating few hours.
Edit: Forked the code, made some changes, and I can now get to: Writing... //rom name.gba
Then the LED goes red immediately and the device hangs. Further than it was before. :-/
I haven't done anything this low level for maybe 10 years, so yeah, mostly I've been modifying things and trying to output debug info to the screen to understand what was going on. My bad for the manufacturerid thing, that's one I missed For the pipeline build, don't know what limitations there are in github, but I'm guessing you will have to be tinkering pretty hard to hit any kind of hard limit. Pipelines usually complete in about 1min30 for me.
That has also been my experience tinkering with it. Try to get the device id properly (checking against the datasheet that what I was getting was the actual device id and not random data from the rom), then trying to erase the chip, then trying to write something adding some debug info to the device screen to check what was going on, and after a lot of tries I managed to get the full "identify device => erase => write => verify" flow working.
The good news is... After some 6-7 hours of tinkering, I actually got it to write a rom !! I managed to get it to write earlier, but the verify failed (using a modified writeTEST_GBA() routine) . Then I spent a lot of time undoing a myriad of changes, made a big change, and thank you, it was a modification of your code that did it. So, yeah, I'm pretty pleased that it actually works.
I'll need to clean up what I've done and then try a pull request. I wonder if I should have done this from your repo ? I've only changed the MX29GL128E section, so it shouldn't conflict, I hope.
The LED blinks red/blue, and I'm not sure if that's right... However, the erasing, writing and verifying finishes.
Well bugger. I tried a Pokemon rom (the one the repro came with), and whilst it showed erasing, writing, verifying, I only get a white screen. A smaller rom worked fine a few minutes ago.
More tests will have to wait until tomorrow, it's heading towards midnight here.
Edit: I tried a different Pokemon rom and it worked fine. I can only guess the filename/path was too long before? Or damaged rom. So excited.
Any updates on this?
Would also love to see the working state code. Even not cleaned up code would be great to assist in cleanup maybe? @Slade1972 do you still have the changes in place?
It's been a while since I've looked at this, but I forked the code here: https://github.com/Slade1972/Burnmaster-Firmware Any changes I made would be there. Sadly, the firmware file is no longer available from the auto build. I never did manage to get a working build from Segger Embeded Studio. You're welcome to try though.
Here is a copy of the local source code I have. I do not recall if this works or has any changes. It may be out of date compared to the GitHub link above.
I gave up when the original firmware author and Funny Playing stopped caring. Unfortunately the device now gathers dust.
@BennyFischer I recompiled the firmware from the changes I last made to the repository. It's attached here for you to test.
Sorry about the late reply. Time often gets away from me.
@Slade1972 wow, thanks for your efforts! I appreciate that. :) I will take a look at it. In the meantime, before you made your posts, I did a fork as well and merged the latest official firmware and the changes made in this branch. So that latest official FW is patched with combability for S29GLXXXN chips. Also, I restored the GitHub action to be used to build the firmware without local setup.
So far writing to the S29GLXXXN cards works. But just for the ROM part. Saves can't be read or written. Tried to dig into a bit. But time is also not infinite for me. And as you already mentioned FunnyPlaying seems to have lost their will to provide updates and support for this (from my point of view nice made) hardware. Wrote them mails regarding this topic but got no response for over 3 weeks now.
So far writing to the S29GLXXXN cards works. But just for the ROM part. Saves can't be read or written. Tried to dig into a bit. But time is also not infinite for me. And as you already mentioned FunnyPlaying seems to have lost their will to provide updates and support for this (from my point of view nice made) hardware. Wrote them mails regarding this topic but got no response for over 3 weeks now.
The adjustments I made worked on the MX29GLXXX chips. I picked up a repro cart from AliExpress and somehow I ordered one in the wrong language, so my motivation was the flash it back with the English rom. I don't believe I looked at reading / writing the saves either. The other issue with saves usually lies in that the saves are appended to the end of the rom, as these carts don't have sram or fram.
You're right, the hardware is decent and compact. The firmware on the other hand... If you "test" a cart, it'll erase the contents without warning, which happened to me as well. Not very amusing. As for email support, I recall emailing them and it took a week or so for them to respond, and they simply pointed me to this repo for firmware updates.
I can only imagine the cart reader wasn't a huge seller for Funnyplaying, so they had little interest in supporting it.
I look forward to seeing if you can merge in all the changes we both made.
@Slade1972 Did a merge and landed here https://github.com/BennyFischer/Burnmaster-Firmware/releases/tag/1.12.C.1 As I do only own a S29GLXXXN card I can't test your changes regarding the MX29GLXXX chips. But feel free to do so. Hope I broke nothing with the merge.
Regarding firmware: Fully agree, great example why good hardware is nothing without good software! Testing card also wiped some data for me. Did not expect that as well...
I have the feeling my card owns a dedicated F/SRAM. At least they advertise with additional 1Mbit Flash for saves. It can be found searching for "gba flash card solar" on AliExpress (solar maybe to support that weird Kojima game that wants you to sit in the sun with your GBA :)) and has a picture of something looking like Mario from the distance.
Need to debug with some printouts on the screen what happens in the code when I try to read/write saves. Also googling for the various chips on the board of my card might give clearer view.
Just for curiosity can you please give me a hint how to find the cart with the MX29GLXXX chips you bought? Would like to see the differences/what card you are talking about.
@BennyFischer I think I found the card you're talking about on AliExpress. If I'm correct, it has the name "Rewritable GBA Flash Cart - 32MB Storage, 1Mb Flash, Solar + RTC Functionality, Compatible with GBA/DS Series" (Which is a clone of this one it seems). That one definitely has some sort of SRAM to store saves. What's pretty snazzy about that one is the FPGA on board as well.
I have 3 repro carts, two are Zelda games, and both of those use two different Spansion chips (64mbit and 128mbit), but should be functionally identical aside from size. The other game is Pokemon Emerald (although as I previously may have mentioned, I ordered the German version and needed to flash it with the English rom). The Pokemon game came with the MX29GL chip. Given those are the only games I have, I'm not sure there is a particular way of checking which games use which chips. I did have a good look at the Pokemon PCB (It's very similar to this one), and it does have a Samsung SRAM chip on board (K6F2008T2E-YF70), although no battery to keep the SRAM alive, and having a decent look over the PCB, I can see that Pin 24 (VSS/GND) isn't connected, and VCC and CS2 are connected together via a trace on the PCB. I'm not sure running power to the chip would be beneficial and it may cause more problems. There are also no obvious solder pads, unlike the picture provided.
The Zelda games both have pads for soldering a CR2032 / CR 2025 battery on board, with a clearly labelled 1mbit SRAM chip. I should try those to see if they work and will store the save correctly, without needing to patch the game.
Good news, your firmware works. I took the Pokemon Emerald cart, backed it up and flashed Zelda Minish Cap to the cart. That worked fine, and then I flashed back the Pokemon Emerald rom and that was good too. The Spansion carts work as well, based on a similar test (erase / write different rom, erase / write original rom).
Short update from my side. I have not been able to dive deeper into the read/write save topic. But in the meantime, I exchanged some messages with the FunnyPlaying support. They have been asking for some information about my cartridge and where to buy etc. They can't promise anything, but it is now handed to some engineers, and they also noticed what we did so far on GitHub. Let's cross fingers that support is not dropped to 0 :)
That's actually kind of fantastic news, I thought they forgot about this haha. Thanks for your hard work.