- For making cartridges of your Super NES games, see Reproduction.
For direct ROM writes, CMD_10h seems to disable writes to the ROM Bank register at 2100h (and instead, any writes to 2100h are probably directly going to FLASH memory address 2100h). There are probably two commands needed for direct ROM writes:
- CMD_10h disable writes to normal MBC registers (such like 2100h)
- CMD_08h disable writes/reads to/from special Nintendo Power registers (those at 0120h..013Fh)
Okay so far, but I can't figure out how to undo CMD_10h and re-enable writes to ROM bank register. Going by skaman's logged code shown above, CMD_01h would look like a good candidate, but it doesn't seem to work. I've also tried to reproduce the whole log (except the data write): Ie. using CMD_10h, CMD_08h, CMD_09h, CMD_0Ah, CMD_01h, CMD_02h (in that order), but the cart still doesn't react to ROM bank writes (and stays stuck in the most recently ROM bank).
- CMD_09h: re-enable access to port 0120h..013Fh
- CMD_11h: re-enable access to MBC registers like 2100h
The write to 2100h in the logged hidden-data-write sequence probably doesn't work since the log doesn't contain CMD_11h. But then, hidden-data-writes don't require any rom banks at all (except that, the bank must be 01h (or some other odd value) for writes to 5555h).
Writing the whole 1024K flash memory is a different thing: That does definitely require writing different values to the ROM bank register - so that would require using CMD_11h (or maybe one could work around it by issuing a /RESET to the cart instead of using that command). Would be (slightly) interesting if mootan's tool used CMD_11h for flash memory writing.
EDIT: And, two other details concerning clearing bit0 and bit1 in the status register at [0121h]:
CMD_03h does clear status bit1.
CMD_09h (the "Wakeup" command) does clear status bit0.
Located at ROM offset 1C000h (aka 7:4000h in gameboy memory).
Entries are 200h bytes in size, the GUI supports max 8 entries at 7:4000h..7:4FFFh.
The first entry is a dummy entry for the menu, the other entries are for game(s), unused entries are FFh-filled.
The format is almost exactly same as in SNES version (but using only 200h bytes per entry, using a smaller bitmap, and without the SNES's weird overlapping bitmap tiles, and with different granularity for the ROM/SRAM values).
Code: Select all
000h 1 Index (00h..07h) (or FFh=Unused) (or initially 07h for menu) 001h 1 ROM base in 128K units 002h 1 maybe SRAM base? in ???-units 003h 2 ROM size in 128Kbyte units (0001h..0007h = 128K..896K) 005h 2 SRAM size in 32-byte units (0000h,00xxh,01xxh,xxxxh=0,MBC2,8K,32K) 007h 12 Title ASCII "DMP -xxxx- " 013h 44 Title SHIFT-JIS 03Fh 100h Title Bitmap (128x8 pixels, 16 tiles at 2bpp) 13Fh 80h Zerofilled 1BFh 10 Date ASCII "MM/DD/YYYY" 1C9h 8 Time ASCII "HH:MM:SS" 1D1h 8 LAW ASCII "LAWnnnnn" 1D9h .. Unused (FFh-filled) 1F0h 16 Unused (FFh-filled)(game entries) or "MULTICARTRIDGE 8"(menu entry) bitmap palette: DMG/SGB: (0=white, 1=light gray, 2=dark gray, 3=black) CGB/GBA: (0=white, 1=dark red, 2=dark magenta, 3=black)
Aside from the directory, the programming stations are also updating data at bank 6:4000h (ROM offset 18000h). Which contains the scrolling text that is shown at the bottom of the menu. There are at least two variants, one found in blank carts (with only the menu installed), and one other variant found in my cart with Puyo Puyo 2 installed.
Don't know how often that text has been updated. Skaman, if you compare the ROM offsets at 18000h..1BFFFFh from your cartridge collection, are there lots of different variants?
The Menu contains some selftest function which seems to be activated when pressing all four buttons plus all four DPAD directions (which normally isn't mechanically possible). The test is barely testing the MENU's memory mapping, not testing the mapping or checksums of the other installed games. And, the test is working ONLY on blank carts, for two reasons:
The checksum in cart header isn't adjusted for changed data at 6:4000h (news ticker) or 7:4000h (directory).
The bank test expects 7:4000h to contain 07h (whilst non-empty carts are storing the menu index (00h) in that location).
Your earlier question regarding writing a dummy byte to actually write to the flash. Yes you must do it every byte written unless using the write buffer then its just once per 32bytes written.
That's working? You can write data to any FLASH address using "[2100h]=(Addr/4000h)" combined with "[4000h+(Addr AND 3FFFh)]=Data"? That would be neat - but it doesn't seem to work for me. Did you test that on a real Nintendo Power cart? If it would work, then it should be possible to access the 2AAAh/5555h addresses using the same technique, ie. for requesting the FLASH chip ID, one could do either this (tested/working):BennVenn wrote:Nocash, no need to lock out bank select registers when flashing as writing to bank0 at $6000 is the same as $2000 and the mbc won't trap the write.
Code: Select all
[2100h]=01h ;-bank for 4000h..7FFFh (ie. needed for 5555h) [0120h]=0Fh ;\ [0125h]=55h ; [0126h]=55h ; [5555h]=AAh [0127h]=AAh ; [013Fh]=A5h ;/ [0120h]=0Fh ;\ [0125h]=2Ah ; [0126h]=AAh ; [2AAAh]=55h [0127h]=55h ; [013Fh]=A5h ;/ [0120h]=0Fh ;\ [0125h]=55h ; [0126h]=55h ; [5555h]=90h [0127h]=90h ; [013Fh]=A5h ;/
Code: Select all
[2100h]=01h ;\[5555h]=AAh [5555h]=AAh ;/ [2100h]=00h ;\[2AAAh]=55h [6AAAh]=55h ;/ [2100h]=01h ;\[5555h]=90h [5555h]=90h ;/
Uh, I lost track of what I was asking about which dummy byte.BennVenn wrote:Your earlier question regarding writing a dummy byte to actually write to the flash. Yes you must do it every byte written unless using the write buffer then its just once per 32bytes written.
There's a dummy byte needed every byte written? And there's a 32-byte write buffer in nintendo power carts? Was that already mentioned anywhere? Maybe I haven't followed the gameboy-stuff too carefully before getting my own cartridge (I've tried to review the gameboy related posts last week though).
Sorry, I misread. Yes, issue it 128 times.
And, after sending a data write command via CMD_0Fh, the actual data seems to be needed to be written via CMD_0Fh, too. skaman? BennVenn? Is that right? When writing 128 bytes of data, does one NEED to issue CMD_0Fh 128 times? Or is there some way to write the data part directly?
Code: Select all
2in1/3in1: ニュース！ いよいよニンテンドウパワーでのゲームボーイの書き換えサービスがスタート！！ これからも強力タイトルが続々登場しますので是非ご利用ください。 Puyo Puyo/5in1: ニュース！ 大好評！サービス実施中のニンテンドウパワー・ゲームボーイ用ソフト書き換えサービス！！ ローソンだけで販売中のニンテンドウパワー・オリジナル新作ソフトから、 なつかしいあの名作ソフトまで豊富なラインナップが勢揃い。 1つのカートリッジに複数のゲームを入れて、あなただけのオリジナル・カートリッジをつくっちゃう、 といった楽しみ方もオススメです。 2in1 Harvest Moon: ニュース！ ラインナップがますます充実！ 絶好調サービス実施中のＮＩＮＴＥＮＤＯ ＰＯＷＥＲゲームボーイ書き換え！！ Menu Only (No Game): ゲームはありません。 ニュース！ このカートリッジには、ゲームが書き込まれておりません。 ・・・・Nintendoの書き換えサービスを行っているお店でゲームを書き込んで下さい。 Unknown (Posted on Japanese BB): ニュース！ あなたはロールプレイング・ゲーム派？ それともアクション・ゲーム派？ ニンテンドウパワー・ゲームボーイ用ソフト書き換えサービスにはオリジナル新作ソフトから、 なつかしいあの名作ソフトまで豊富なラインナップが勢ぞろい。 1つのカートリッジに複数のゲームを入れて、あなただけのオリジナル・カートリッジを作っちゃう、 といった楽しみ方もオススメです。
First of, issue the chip erase command. BennVenn has been right about needing to unprotect sector 0 first (some macronix datasheet sounded as if the protect flags would be don't care when /WP=HIGH, but that seems to have been wrong, or doesn't apply for the chip used in the gameboy cart; the first 128Kbyte will remain unerase without the unprotect). Also as BennVenn mentioned, the chip erase command does erase only the 1024-Kbyte area (not the 256-byte hidden sector).
For writing 128-byte fragments:
- Use CMD_09h + CMD_11h to enable I/O access
- Use CMD_0Ah + CMD_02h to get /WP=HIGH
- Set Bank 01h and use CMD_0Fh to send the FLASH write command to 5555h/2AAAh/5555h
- Set Bank (addr/4000h) for the write destination
- Do the 128-byte data write (see below, method 1 and 2)
- Read status and wait until bit7=1
Then repeat for next 128-byte fragment.
Bank 0 must be written to 0000h..3FFFh. Trying to write bank 0 to 0:4000h..7FFFh doesn't work (at least not when using CMD_04h to map the entire FLASH memory; it might work in MBC5 mode, but that won't help since CMD_04h doesn't use MBC5 mapping).
Data Write Method 1 - direct writes:
- Send CMD_10h + CMD_08h to disable I/O ports and get direct FLASH write access
- Send 128 bytes, then terminate by writing FFh to the last written address
Normally: That method is best & fastest. It should be also the easiest way if you have direct access to the gameboy cartridge bus.
With Bung hardware: It can be a bit difficult when squeezing the data through the Bung parallel port device: Transferring address+data through parallel port works, but it's rather slow. Better would be using Bung's auto-incrementing address mode (done setting bung's mode byte to 81h, 82h, or 83h). Write+Increment is normally done by using 82h or 83h, but that didn't seemed to work at all, the Nintendo Power cart totally ignored all written bytes (and instead it did eventually write the following control bytes like 55h and AAh to unintended addresses). The mode value 81h is normally used for Read+Increment, but for some reason that value does work well for writing to Nintendo Power carts. And, another issue with Bung+DirectWrites (with or without auto-increment) is that the programming does occassionally start before writing all 128 bytes (so the last bytes of that area stay FFh-filled), that's probably some timing issue where the cart believes to have received two /WE pulses at the same address.
Data Write Method 2 - indirect writes via CMD_0Fh:
- Send 128 bytes via CMD_0Fh, then terminate by writing FFh to the last write address also via CMD_0Fh
That's just endless slow (with the bung hardware in SPP mode it's taking about 5 seconds per 16Kbyte). And, it turned that CMD_0Fh can't write to 0120h..013Fh (so any cart programmed that way won't boot due to invalid Nintendo logo in cart header); in MBC5 mode it might be possible to write that area via 0:4120h..413Fh, but that would require the mapping info in hidden sector to be (re-)programmed to use MBC5 mapping for file 0. So essentially, CMD_0Fh would be painfully slow and overcomplicated.
2in1 / 3in1:
Rewriting service Gameboy the start at finally Nintendo Power! !
Please use all means because it appeared one after another even stronger title now.
Puyo Puyo / 5in1:
From Nintendo Power original new software for sale only in the large popular! Software rewriting service !! Lawson for Nintendo Power Game Boy in the service implementation, nostalgic rich lineup Gotham to that masterpiece software.
Put one force one more game in the cartridge, this may create your own original force one cartridge of, it is also recommended way of enjoying such.
2in1 Harvest Moon:
Lineup is increasingly rich!
NINTENDO POWER Gameboy rewriting of the best condition service underway! !
Menu Only (No Game): the game does not have.
This cartridge, the game has not been written.
Please write the game in the shop ... it is doing a rewrite service of Nintendo.
Unknown (Posted on Japanese BB):
You are role-playing game school? Or action game faction?
From the original new software in Nintendo Power Game Boy for rewriting software services,
Nostalgic rich lineup Get to that masterpiece software.
One to put more than one game in the cartridge, this may create your own original cartridge,
How to enjoy, such as is also recommended.
For reading hidden data, send 55-AA-55-77 twice, then read 100h bytes from 0000h..00FFh (though that 100h bytes seem to be mirrored to all other FLASH addresses, too).
For erasing hidden data, send AA-55-60, then AA-55-04h.
In skaman's log, that's preceeded by AA-55-60 and AA-55-40h, that command is somewhat required for unprotecting the first 128Kbytes, but it isn't directly related to erasing hidden data (unless, maybe it's also unprotecting the hidden data, but anyways, there's no need to use that command as prefix right before sending the hidden erase command).
For writing hidden data, send AA-55-60, then AA-55-E0, followed by 128-byte data (transferred the same way as normal writes mentioned two posts earlier).
In skaman's log, that's preceeded by AA-55-A0h-FFh-FFh, ie. writing FFh (=nothing) to some FLASH address, which really isn't required.
Alltogether, everything seems to be working. Except, I should spend some more time on making my transfer program more stable, and write some documentation that summarizes all the NP commands and FLASH commands and data structures. And, just for curiosity, test if there some more hidden commands, like [0120h]=12h..7Fh. And of course write/erase is still needed for the SNES cart (although skaman seems to have already managed to get a SNES cart erased via some relative simple looking command sequence, and writing is hopefully not much more complex).
Code: Select all
0x0000, 0x38 ;\ 0x0000, 0xD0 ; sharp-style stuff, might be required to enter the hidden mode 0x0000, 0x71 ; (once when erase is working, one could try to remove this part) 0x0000, 0x72 ;/ 0x5555, 0xAA ;\macronix-style prepare erase command 0x2AAA, 0x55 ; (on gameboy that would be x=60h) 0x5555, x ;/ 0x5555, 0xAA ;\macronix-style start erase command 0x2AAA, 0x55 ; (on gameboy that would be y=04h) 0x5555, y ;/
Code: Select all
AA-55-77 - AA-55-99 = write hidden data AA-55-77 - AA-55-E0 = erase hidden data
Also thanks to sanni (especially for the initial databus log with the 38h-D0h values), and to BennVenn for details on the gameboy cart (especially the don't-write-F0h part), and credits to mootan for originally hacking the gameboy cart (which doesn't have the confusing sharp-style commands, but looks even more difficult than the SNES cart in other aspects).
The code I'm using right now seems to be doing something wrong though but strangely it only affects the first flashrom.
While all works perfectly fine with the second flashrom(0xE0 when in HiRom All mode) for me the first flashrom(0xC0) always locks up when I try to erase/write the hidden mapping information.
Even weirder I got the same issue with the sector protection. I can set/remove the sector protection byte for the 0xE0 chip just fine but the 0xC0 chip always locks up.
I tested two different NP carts, both behave the same.
I switched the code to use Bank 0xD0 and the 1st chip can be erased and programmed.