Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
PCBs for the cartridge and the programmer were shipped by ITead 8 days ago. Hope it doesn't take too much time to arrive (last time I ordered a PCB from them, it took almost two months...).
Offline
I found this in my inbox:
I hope I can assemble the boards soon, I don't have too much spare time ATM.
@Tauwasser: I'll need the programmer sources (or the firmware image) soon (I hope). Could you please upload them?
Offline
Wow, they turned out pretty nicely. You even had them gold-plated? Cool
I'll upload the firmware soon. I got caught up in other stuff, planned to do it for weeks actually :-/
EDIT: I finally spent some time preparing stuff and now uploaded the C firmware source to Github. Hardware and Reader Software branches will follow shortly, but the firmware would probably be the most important part anyway.
cYa,
Tauwasser
Last edited by Tauwasser (2015-05-30 20:53:16)
Offline
Thanks a lot for uploading the firmware. Time to install avr-gcc to try building it!
Edit: Tried building this way:
avr-gcc -Os -Wall -mmcu=atmega8515 GB_Cart_Flasher_FW.c -o gbcartflasher.elf -Wl,-M=map.txt
And it was built nicely without error/warning messages. Unfortunately I'll not be able to test it until I assemble the boards. From the generated map file, .text section is 3436 bytes, .data is 0 bytes, and .bss is 150 bytes. So far, so good.
Last edited by doragasu (2015-05-31 13:27:22)
Offline
I have programmed the FT232 to output 12 MHz for the AVR clock, and it's working perfect. Time to search for my homemade parallel port download cable to burn this thing!
Offline
Before you do that, you should probably check out the v1.1 tag, edit it for 12 MHz -- remember the original uses 6 MHz -- and remember to take out the PE port baud rate select logic as it might change the baud rate while floating. Test with the original software and see how it goes. If that works, then you should probably gradually use the interrupt-driven UART I wrote and some other smaller changes (in master branch).
I'll see if I can manage to prepare the software repository in the mean time. Also, don't forget to remove the DIV8 fuse setting, or nothing will work
cYa,
Tauwasser
Offline
Found the cable, and also borrowed a Xilinx Platform Cable USB II!
I checked out v1.1, and will have to browse your code to make the suggested changes. Do you know if there is a way of setting the fuses in the code? I suppose there is, because when I have burned some AVR chips in the past, when I burned the .elf file, fuses were set automatically (they were not automatically set when I burned the .hex file though).
To program the carts, I'll try using Linux version of GB Cart Flasher 1.1 here. I'm trying to build it, but it fails because of the changes from Qt4 to Qt5...
Offline
Got the software to build.
I cannot see a configuration option to set baud rate... I'll have to browse the sources to see if I can find it. Or is there a way to force the baud rate on the FT232?
Offline
In case anyone is interested, here is the patch to fix build problems and add -ultraspeed (1500000 bps) to gbcartflasher.
Offline
@Tauwasser: I'm now browsing v1.1 tag of your firmware, and I think I don't need to edit anything to get 1500000 bps, because baud rate select code is ignored, this is after baud rate selection:
UBRRL = 0x00; // force 750000 baud anyway UCSRA = (1u << U2X);
As I'm clocking it at 12 MHz, baud rate should be 1500000 bps without touching a single line.
What I suppose I'll have to change are WAIT_LOOP values (I suppose I'll have to double them). Do you think I'll need to change anything else?
Edit: I don't understand the inline assembly on the WAIT_LOOP macro. Could this work for 12 MHz?:
#ifdef _CLK_12MHZ_ #define WAIT_LOOP(_X_, _VAR_) for (_VAR_ = 2*(_X_); _VAR_; --_VAR_) __asm__ __volatile__ ("" : "=r"(_VAR_) : "r"(_VAR_)) #else #define WAIT_LOOP(_X_, _VAR_) for (_VAR_ = _X_; _VAR_; --_VAR_) __asm__ __volatile__ ("" : "=r"(_VAR_) : "r"(_VAR_)) #endif
Also changed this because with the changed macro, variable overflowed (j is int8_t and i is uint8_t):
// actual cycles from original ASM: 660 // 110us #ifdef _CLK_12MHZ_ WAIT_LOOP(165, i); #else WAIT_LOOP(220, j); #endif
Edit: More changes, this time for timers:
#ifdef _CLK_12MHZ_ OCR1AH = 0x89u; OCR1AL = 0x54u; #else OCR1AH = 0x44u; OCR1AL = 0xAAu; #endif
I also wanted to double the count on TIMER0, but I cannot find a write to OCR0. Also thought about doubling TIMER0 prescaler, but now it's set to 8, and next step is 64 (unfortunately not 16). I suppose I could set prescaler to 64 and OCR0 to 64 to get the same timing, but it doesn't look TIMER0 delay time is critical, is it?
Last edited by doragasu (2015-06-04 16:02:22)
Offline
Tauwasser wrote:
Also, don't forget to remove the DIV8 fuse setting, or nothing will work
I'm having a look to the datasheet, and I cannot find a DIV8 fuse. Could you mean CKSEL0 maybe?
Offline
OK, burned the CPLD, the atmega and did my first test. Unfortunately it is not working
It looks like the PC and the atmega communicate properly, but the cart is not working. If I hit "Cart Info" button, I get this:
--Device information-- Device firmware version: 02.10 --Cartridge information-- FLASH memory manufacturer ID: 0xff FLASH memory manufacturer name: Unknown manufacturer FLASH memory chip ID: 0xff Game logo signature is incorrect. Cartridge is blank, damaged or not connected.
It's not being able to read the flash ID .
Then I tried writing "Gex enter the gecko". It looks like it's writing the game, but when I read it back, I only get 0xFFs.
It looks like the programmer is working. This is e.g. what it spits when I hit "Cart info" with my GB Everdrive inserted:
--Device information-- Device firmware version: 02.10 --Cartridge information-- FLASH memory manufacturer ID: 0xc3 FLASH memory manufacturer name: Unknown manufacturer FLASH memory chip ID: 0x80 --ROM/FLASH content information-- Game logo signature is correct. Game title: GBOS KRKZ Designed for Color GB: YES Designed for Super GB: YES Cartridge type: ROM ONLY ROM size: 32KB RAM size: 0KB Checksum: 0xffff
So I must have a problem with my cart ...
Last edited by doragasu (2015-06-04 16:54:11)
Offline
doragasu wrote:
Got the software to build. I cannot see a configuration option to set baud rate... I'll have to browse the sources to see if I can find it. Or is there a way to force the baud rate on the FT232?
There are command line switches. They're documented in the accompanying PDF file.
doragasu wrote:
@Tauwasser: I'm now browsing v1.1 tag of your firmware, and I think I don't need to edit anything to get 1500000 bps, because baud rate select code is ignored, this is after baud rate selection:
Code:
UBRRL = 0x00; // force 750000 baud anyway UCSRA = (1u << U2X);As I'm clocking it at 12 MHz, baud rate should be 1500000 bps without touching a single line.
That's in the master branch though, not the v1.1 tag... Something went wrong with git checkout, I assume?
doragasu wrote:
What I suppose I'll have to change are WAIT_LOOP values (I suppose I'll have to double them). Do you think I'll need to change anything else?
Generally, these are the original timing as I found them in the original hex file. They aren't very precise, I think. The idea is that MBCs are only rated for 1 MHz (2 MHz from MBC3 or MBC5 on, I forgot which), so you have to wait between assertions and deassertions of control signals.
doragasu wrote:
I also wanted to double the count on TIMER0, but I cannot find a write to OCR0. Also thought about doubling TIMER0 prescaler, but now it's set to 8, and next step is 64 (unfortunately not 16). I suppose I could set prescaler to 64 and OCR0 to 64 to get the same timing, but it doesn't look TIMER0 delay time is critical, is it?
OCR0 isn't used, because this isn't CTC mode, but Normal mode, so count from 0x00 to 0xFF and set overflow when 0xFF is reached. Timer0 is only used as a timeout during DATA_POLL flash mode. I think the default is mode DEFAULT, which waits 5s instead of polling bit7 or checking for toggle. Depends on the flash algorithm you select using the command line in the flash tool.
doragasu wrote:
I'm having a look to the datasheet, and I cannot find a DIV8 fuse.
Sorry, I misremembered. Newer AVRs have a fuse that divides the clock by 8. This is often a point that's forgotten, which is why I mentioned it. So you only need to worry about the CKSEL fuses for now. And program EESAVE so you don't wear out your EEPROM.
doragasu wrote:
OK, burned the CPLD, the atmega and did my first test. Unfortunately it is not working
That's unfortunate!
First, make sure you're really using the v1.1 tag. In master, I changed the AIN pin to default LOW, because the MBC5D development cartridges use it as write protect for the flash. So with current master HEAD, you would always write to FLASH, which shouldn't matter as long as you don't hit the magic unlock sequence.
Next, check if your CPLD code does the polarity stuff correctly. You might just have the translators pointing the wrong way.
Also, it might be the case that you have to change the programming algorithms slightly. There's a mismatch between firmware and your flash chip. Checking out the datasheet, it seems that the addresses A0-A10 always expect the same bit patterns regardless of 8x/16x mode, A-1 is ignored until data is actually supposed to be read. Thus, you might need to left-shift PRODUCT_ID_ENTRY, PRODUCT_ID_EXIT (and so on) addresses by one bit to the left and fill that bit with one, i.e. addr_new = (addr << 1) | 0x01;
Firmware should get a facelift anyhow for supporting more mappers. Might as well address the issue of 16x/8x chips and maybe support CFI for newer flash chips.
cYa,
Tauwasser
Offline
You are right, I have checked out v1.1 on another machine, and the 750000 bps force lines are not there. Somehow I must have screwed the git checkout command before.
Thanks for your suggestions, I hope I have some time this evening to check them. My main suspects are CPLD and level shifter polarities.
Offline
I'm having a thorough look to the sources, and to the flash chip datasheet (S29GL064), and I think I'll have to completely modify the algorithms. At least the command values and the autoselect sequences to get device and product IDs.
Also there's something I don't get... Why does the code try each write using both AIN and WR? I suppose I can remove the WR part without a problem, right?
I'll try to get the flasher to read device and product ID, and once I have it working, I'll try getting to work everything else.
Another thing... flashing algorithm is extremely unoptimal. Instead of using Unlock Bypass to program faster, it issues a Program command each time (along with two bank switches per byte). Now I understand why it takes so much time flashing anything!
Also it looks to me like cur_flash_algorithm is ignored (I suppose this is for ALG16 or ALG12)... for WR writes ALG12 is forced, and for for AIN writes alg selection is done using cur_wait_mode instead of cur_flash_algorithm. WEIRD!
Last edited by doragasu (2015-06-05 13:55:09)
Offline
Fuck yeah!
--Device information-- Device firmware version: 02.10 --Cartridge information-- FLASH memory manufacturer ID: 0x1 FLASH memory manufacturer name: AMD FLASH memory chip ID: 0x7e Game logo signature is incorrect. Cartridge is blank, damaged or not connected.
Edit: Unfortunately I have hit a wall...
I can erase the flash, program ROMs, read them back and diff says they are exactly the same. But they do not work. E.g. if I write Tetris (no mapper, 32 KiB), as I wrote, I can read it back and readed file is exactly the same, but when I hit "Cart Info" button, logo signature check fails . Also when I insert the cart in a Gameboy (I have tried the first big one, and a GBBoy clone) the game doesn't boot (logo is corrupted).
I suppose it must be some kind of timing problem, but that's strange because the problem occurs even when using ROM only games like Tetris.
Last edited by doragasu (2015-06-05 16:53:25)
Offline
Nicely done!
doragasu wrote:
I'm having a thorough look to the sources, and to the flash chip datasheet (S29GL064), and I think I'll have to completely modify the algorithms. At least the command values and the autoselect sequences to get device and product IDs.
You should only have had to shift the addresses...?
doragasu wrote:
Also there's something I don't get... Why does the code try each write using both AIN and WR? I suppose I can remove the WR part without a problem, right?
It tries to do the right thing for both kinds of flashcarts: ones that connect #WR to flash and the ones that connect #AIN to flash. The assumption is that the code won't do anything bad for the complementary case (use #WR when #AIN is connected, use #AIN when #WR is connected etc.)
doragasu wrote:
Another thing... flashing algorithm is extremely unoptimal. Instead of using Unlock Bypass to program faster, it issues a Program command each time (along with two bank switches per byte). Now I understand why it takes so much time flashing anything!
Yep, it is.
doragasu wrote:
Also it looks to me like cur_flash_algorithm is ignored (I suppose this is for ALG16 or ALG12)... for WR writes ALG12 is forced, and for for AIN writes alg selection is done using cur_wait_mode instead of cur_flash_algorithm. WEIRD!
Yes, it's like that in the original source, too. I was confused about that for a long time. I'm going over the disassembly now and see if I missed anything. But I definitely remember these two trading places a few times while I disassembled the hex file, because the variables were being reused throughout parts of the program. I probably screwed up somewhere with search&replace :-/
cYa,
Tauwasser
Offline
OK, yes, it was a search and replace issue. I switched "flash type" and "flash wait mode" around a few times and apparently screwed up during the final rename step :-|
Apart from that, I re-organized the git new (git push -f), sorry about that.
EDIT: Just saw your edit. It's unfortunate that there's trouble. Is it corrupted as in completely black logo or are parts recognizable? If it's completely black, make sure you don't accidentally read and write from another ROM bank. If it's partly recognizable, it could be your CPLD speed, the translators' speed or even the translators' sink/source capability.
cYa,
Tauwasser
Last edited by Tauwasser (2015-06-05 19:25:51)
Offline
The flash algorithms are a bit different, it's not only a matter of shifting addresses. Product ID must be read doing 3 read cycles (instead of just one) and autoselect sequence must be aborted writing a single 0xF0 at any address.
About the problem... Nintendo logo is not entirely black, but I wouldn't say it is recognizable. It looks like random crap (but the same random crap each boot). I like your theory about reading from another ROM bank, I'll check that. What really bugs me is that the programmer reads the ROM perfectly when I hit "Read Flash" button, but fails reading the header when I hit the "Cart info" button. I'll have to check the sources to see if there is a difference in the way reads are done in these two scenarios.
Also, I have a question about MBC5. Which ROM bank should I select at reset? IIRC, MBC1 must select ROM bank 1, but I cannot find information about the initial MBC5 bank. Actually I'm also setting it to bank 1, but I wonder if this is not correct.
Offline
You were 100% correct, I was not reading from bank 0 for addresses lower than 0x4000. Stupid me!
IT WORKS NOW!!!
I have flashed Aladding (MBC5, 1 MiB) and it boots and plays nicely. Will have to do a lot more tests, and I still have to solder and test the RAM block. perfect!
Again, thanks a whole lot! It would have taken a lot more time to reach here without your help!
Offline
doragasu wrote:
You were 100% correct, I was not reading from bank 0 for addresses lower than 0x4000. Stupid me! IT WORKS NOW!!!
Congratulations
doragasu wrote:
The flash algorithms are a bit different, it's not only a matter of shifting addresses. Product ID must be read doing 3 read cycles (instead of just one) and autoselect sequence must be aborted writing a single 0xF0 at any address.
Well, you aren't supposed to abort auto-select. If you check out the table on pg. 50, it says Device ID in 4 cycles is valid while in auto-select mode (using the auto-select unlock sequence that is shown). You just cannot random-read the full device ID, but that's not what the flash tool does. It only uses the first device ID byte anyway. So instead of reading from addresses 0x00, 0x01, 0x02, the read should be to 0x00, 0x02, 0x04.
I guess I'll have to finally produce some code to flash my MBC5D rumble dev carts
doragasu wrote:
Also, I have a question about MBC5. Which ROM bank should I select at reset? IIRC, MBC1 must select ROM bank 1, but I cannot find information about the initial MBC5 bank. Actually I'm also setting it to bank 1, but I wonder if this is not correct.
I'm like 75% sure it's RB 0x01, but my MBC reverse-engineering is at MBC2 right now
EDIT: Also, I'd be grateful if you could fork the current git repo, rebase your changes onto it and share with the world. It'll probably help when I redesign that stuff a bit.
cYa,
Tauwasser
Last edited by Tauwasser (2015-06-06 06:13:24)
Offline
Thanks!
I can fork your repo and share the changes, but I don't know if they are useful, since I deleted stuff that I think you would like to keep (like writes using WR line).
More interesting I think, are changes I made to gbcflsh v1.1 to add "-ultraspeed" switch for 1.5 Mbps. I already posted a patch file above.
EDIT: I'm also tempted about doing my own firmware + command line application to flash the carts, to see if I can make it faster. But I don't think I'll do it since I'm pretty busy (and yours works BTW).
Last edited by doragasu (2015-06-06 15:39:20)
Offline
I have soldered the SRAM and the remaining components, including the battery holder. I have burned Zelda DX and SRAM works just fine, I can save and load games! Too bad I have not a CR2032 battery lying around to test if the SRAM can keep saves (I'm at work right now). I'll try testing when I arrive home.
I have also enclosed the PCB inside a GBC case (Wario Land 3). Although it fits, it's really tight. The rib (is this the right english word?) on the upper side of the cart cover hits the battery holder, and you must push a bit the cover until it fits and slides to its place. Once it's closed, it's so tight that it's really difficult to open the case, you have to force it a bit. I don't like this... For the next revision (in case I do one), I'll either try moving the battery holder a bit, or use a smaller battery.
PS: @Tauwasser: I think I have made a pull request to your repo by mistake. I cloned your repo as a submodule of my cart repo, and when I made the latest "git commit -a" I didn't notice changes to your code were also commited. Once I pushed them, I saw the pull request (this is the first time I use git submodules and didn't know they worked like this).
Offline
Tested the battery for keeping SRAM data. It didn't work at first because the negative battery terminal didn't make proper contact with the PCB (I think it was because of the solder mask surrounding the pad, I might try removing all the solder mask under the battery for next revision). I added a bit of solder to the pad to raise it a bit, and now it's working perfect! Zelda DX works 100%, I can save, take the cart out of the console, put it some hours later and load the game without a problem! I'll have to monitor the battery voltage to verify it isn't drained fast, but it looks great so far. BTW I'm using a 47 ohm series resistance to power the SRAM from the battery.
I have started writing from scratch a firmware for the cart flasher, and a command line application to use it, but I'm not sure I'll finish them...
Offline
Argh, forgot about the 2mm tab that's on the upper shell. Kind of sucks that it's so hard to close and open :-/
It's good that the SRAM works now. So basically, you've accomplished all you wanted with this cartridge, which is awesome
cYa,
Tauwasser
Offline