How to program a NINTENDO POWER Cartridge ?

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by tepples »

Can the data bus be observed non-invasively by hooking a logic analyzer up to the clock port on the bottom of the Super NES? Or is the clock port driven only when the B address bus is also driven?
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

Amiga clock port like this: http://www.ianstedman.co.uk/Amiga/amiga ... _port.html ? I don't see too much relation between the 80pin/22pin Amiga Clock Ports and the 28pin EXT port on SNES.

For hooking the EXT port, nobody is having a connector for it, so one could only connect wires to the EXT port solder pads (which are quite well accessible, so the EXT port may be actually good for such stuff). It doesn't have a good clock signal (ideally the 21MHz master clock), so that would need to be picked up elsewhere (to get an idea when new data values are being output).

Anyways, sanni and skaman are already having fully working hardware attached to the nintendo power cartridge (except still needing to output the "21MHz" in slow-motion on one pin). So they would essentially need to switch the data direction to "input", and then just READ what is happening on the databus on each clock cycle. That should be the simpliest solution, and the data could be logged as desired (plain ASCII HEX values, or plain binary file) (logic analyzers could probably do that, too, but usually they are producing bitmap graphics with waveforms instead of raw data).

What I would have in mind, could look as so (showing input from /RESET pin as one digit, and input from DATA as two digits):
1 FF
0 03
0 07
0 A3
0 80
0 5C
0 7F
1 FF
1 FF
1 FF
Then one could see which values are read during /RESET=0, and search those values in the ROM-image, and probably guess the addresses where they are read from (=presumably from the menu's directory entry for overall mapping, and from the game's cart header for lorom/hirom detection).
User avatar
sanni
Posts: 44
Joined: Sat Jul 20, 2013 2:21 pm

Re: How to program a NINTENDO POWER Cartridge ?

Post by sanni »

Never could get the Nintendo Power or even any SA-1 game to work on my Arduino cart reader, skaman got them to work though, must be some hardware issue on my side. So we'll have to wait for him.
Last edited by sanni on Sun Sep 27, 2015 6:34 am, edited 2 times in total.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by qwertymodo »

That doesn't mean much without the /OE and /WE signals. For all we know, that's just the ROM data being read by the console.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by qwertymodo »

nocash wrote:Trying to write a different value didn't work as expected, the result got ANDed with the old value (I was thinking that the chip would automatically erase/rewrite the written page, which should works as so on modern FLASH chips, but the 29F1601 can apparently only change bits from 1 to 0).
This is an expected behavior for any Flash/EPROM. Erasing sets all of the bits to 1, and programming can only set them to 0. In order to set a bit to a 1, you have to erase it, then reprogram the new value. So, by writing two different bytes to the same address, since you can't set any of the bits back to 1, you end up writing all of the 0's from each byte, aka ANDing them together.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

Tried some more "commands":

Code: Select all

;mov a,00h // mov  [002400h],a   ;-NP_CMD_00h RESET and map GAME14 ? (issues /RESET pulse) (and ONCE: did held /RESET=LOW forever) (somehow IGNORED when followed by further 240xh writes?)
;mov a,01h // mov  [002400h],a   ;-NP_CMD_01h  causes always 8x7D
;mov a,02h // mov  [002400h],a   ;-NP_CMD_02h /WP=1 causes 2A,04,2A,2A instead of 2A,00,2A,2A --- and does set /WP=HIGH
;mov a,03h // mov  [002400h],a   ;-NP_CMD_03h /WP=0 no effect? but ONCE caused 2A,E0,2A,2A,FF,FF,FF,FF and /WP=LOW
;mov a,04h // mov  [002400h],a   ;-NP_CMD_04h HIROM:ALL  ("MENU" at 40:7FC0h) causes FE,61,A5,00 instead of 03,AA,AA,00   ;and remaps ROM: eg. ..IJKL...RSTU... at 10FFC0h <-- part of GAME1 (though MENU is ar 407FC0)
 mov a,05h // mov  [002400h],a   ;-NP_CMD_05h HIROM:MENU ("MENU" at 40:7FC0h) causes 83 D5 7F 00 instead of 03,AA,AA,00   ;and remaps ROM: all ................ at 10FFC0h (no ASCII)   <-- MENU-only (if if GAME1 is selected)
;mov a,06h // mov  [002400h],a   ;-NP_CMD_06h  causes always 8x7D (aka, undoes toggle?)
;mov a,07h // mov  [002400h],a   ;-NP_CMD_07h  causes always 8x7D
;mov a,08h // mov  [002400h],a   ;-NP_CMD_08h  causes always 8x7D
;mov a,09h // mov  [002400h],a   ;-NP_CMD_09h  no effect  ;\sending BOTH does have effect (remaps ROM) (happened only ONCE though)
;mov a,0ah // mov  [002400h],a   ;-NP_CMD_0ah  no effect  ;/
;mov a,0bh // mov  [002400h],a   ;-NP_CMD_0bh  causes always 8x7D
;mov a,0ch // mov  [002400h],a   ;-NP_CMD_0ch  causes always 8x7D
;mov a,0dh // mov  [002400h],a   ;-NP_CMD_0dh  causes always 8x7D
;mov a,0eh // mov  [002400h],a   ;-NP_CMD_0eh  causes always 8x7D
;mov a,0fh // mov  [002400h],a   ;-NP_CMD_0fh  causes always 8x7D
;mov a,10h // mov  [002400h],a   ;-NP_CMD_10h  causes always 8x7D
;mov a,14h // mov  [002400h],a   ;-NP_CMD_14h  causes always 8x7D
;mov a,24h // mov  [002400h],a   ;-NP_CMD_24h  causes always 8x7D
;mov a,44h // mov  [002400h],a   ;-NP_CMD_44h  no effect (once caused crash with green rectange)
;mov a,81h // mov  [002400h],a   ;-NP_CMD_81h RESET and map GAME1  ;/
;mov a,84h // mov  [002400h],a   ;-NP_CMD_84h RESET and map GAME4  ;\works even if MENU was already deselected
;mov a,85h // mov  [002400h],a   ;-NP_CMD_85h RESET and map GAME5  ; odd: MENU in bank 48h, GAME1 in bank 50h (probably because BASE is FFh aka -1)
;mov a,89h // mov  [002400h],a   ;-NP_CMD_89h RESET and map GAME9  ;
;mov a,8fh // mov  [002400h],a   ;-NP_CMD_8Fh RESET and map GAME15 ;/
;mov a,0c5h // mov  [002400h],a  ;-NP_CMD_C5h  causes always 8x7D
Some odd effects happened only once (that might have been unintended/unstable effects for whatever reason).
Some commands might do something when adding whatever parameters (eg. as known for commands 09h and 06h).
There stable/interesting commands are:
- 80h..8Fh: RESET and map GAME0..15 (aka 80h=MENU)
- 02h,03h: Controls /WP pin
- 04h/05h: Force HIROM mapping (either ALL memory, or only MENU)
With the "HIROM:ALL" command (04h) it should be possible to write the whole FLASH memory, so programming cartridges should be solved; unless there are some hidden configuration bits required for different games.

With different mappings (MENU, GAME's, or special HIROM modes), Port 2400h..2407h return different values (this on a cart with MENU and one 3MByte LOROM game (FIGHTING ELEVEN) installed):

Code: Select all

  ;MENU:      2A,04,2A,2A,03,AA,AA,00
  ;GAME1:     2A,14,2A,2A,15,29,4A,10
  ;GAME4:     2A,44,2A,2A,FF,FF,FF,FF
  ;GAME5:     2A,54,2A,2A,FF,FF,FF,FF
  ;HIROM:ALL: 2A,04,2A,2A,FE,61,A5,00
  ;HIROM:MENU:2A,04,2A,2A,83,D5,7F,00
Port 2400h,2402h,2403h are always 2Ah.
Port 2401h.bit4-7 is the selected GAME number (or 0=MENU).
Port 2401h.bit2 is the /WP pin state.
Port 2404h..2407h are "strange values". The FFh's for the empty game slots would suggest that they are simply read somewhere from FLASH memory (either from the GAME memory, or from the DIRECTORY entries). For the other mappings, they are just "strange values", I can't find those values being stored anywhere in FLASH (at least not in continous 4-byte memory blocks, and they don't seem to match for separate bytes in the directory region).
Can somebody dump those values on other carts? Would be interesting if you are getting the same values.

Concerning hidden stuff, I have dumped the "sector protect" bytes for the MENU sectors, and for the first some sectors of the GAME.
The first sector (lorom banks 00h..03h) of the MENU returns C2h (which should mean "protected", although I can write to that sector). The other three MENU sectors, and all GAME sectors are returning 00h (which should mean "unprotected") (and yes, writing to those sectors does work, too).
So, those bytes are apparently having a different meaning as described in the MX29F1610A/B datasheet. So they might contain hidden info about game mapping. Or they are just garbage because the "write protect" feature isn't implemented in MX29F1601 chip, though then it would be odd that different "write protect" have different values.
When dumping those bytes on other cartridges, are you getting the same results, first sector C2h, other sectors zero?
User avatar
sanni
Posts: 44
Joined: Sat Jul 20, 2013 2:21 pm

Re: How to program a NINTENDO POWER Cartridge ?

Post by sanni »

I added your findings to my MX29F1601 Arduino flasher, so it now can flash the complete NP cart without desoldering the flashroms, it's also alot faster than before.

This allowed me to do a couple of tests and it seems that the only thing that boots without a menu are games/programs that are 512K in size and lorom, like Super Mario World, the 240p Test Suite homebrew and ofc the NP menu.
Games like Super Bomberman(512K, hirom) or Super Mario Allstars(2M, lorom) won't boot.
I also flashed the japanese versions of DKC3(4M hirom) and Fire Emblem Thracia(4M lorom) and they didn't boot either even though they were available for the NP cart and Markfrizb stated that his DKC3 dump was identical to the retail rom.
On the other hand I flashed back the original content of my NP cart and that worked flawlessly, but then again it had a bootable menu.

So there must be a permanent hirom all/lorom all switch that can be toggled and if it's not the NP cart will just boot the 512k lorom menu or any other 512k lorom rom. Maybe some configuration bits are saved in the carts SRAM?

I'll try to write the suggested databus logger next to see what is happening right after powering up the NP cart.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

sanni wrote:I'll try to write the suggested databus logger next to see what is happening right after powering up the NP cart.
That would be great to see if/what kind of mapping info it's reading from FLASH (or SRAM) chips!

As far as I understood, mark has swapped FLASH chips with lorom/hirom games, viewtopic.php?p=131832#p131832 so, theoretically, all mapping info should be located in the FLASH chip. The best candidate for hidden mapping info might be the 32 "sector protect" bytes for the 128Kbyte memory blocks. Would be interesting to dump those bytes, especially if somebody has a cart with a 4Mbyte hirom game on it.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

skaman wrote:when you were investigating the NP Ports 2400-2407, did you determine if Ports 2401-2407 were read-only?

My test cart was blank with only the Menu repeated 8x. I uploaded a new Menu along two new games but neither game works. Using the console, selecting the first game goes right back to the Menu. Selecting the second game results in a black screen. I experience the same results when using the reader with the reprogrammed cart, I can select the first game and it switches but right back to the Menu. If I select the second game, then the reader hangs waiting for the switch to occur (which never happens).

I then flashed the cart with FE776. Confirmed the flash was successful then I switched to the reader code. The reader starts up no problem with the reprogrammed cart. When I dumped the game, I got the first 512kb block of FE776 8x which exactly how the cart was mapped with the menu only.

Using CMD 0x5 on this Menu-only (blank) cart, I get: 2A,0,2A,2A,83,8A,8A,80
Carts with normal menus usually send: 2A,0,2A,2A,83,D5,7F,00
I've tested only writing to 2400h. The menu code is also writing to 2401h, so that should be writeable, too. Although, as one can see, the values writting to 2400h/2401h have no direct relation to the the values being returned when reading from 2400h/2401h, so it seems that there are read-only registers at 2400h/2401h, and separate write-only registers at 2400h/2401h. No idea if 2402h-2407h are also writeable.

What new menu and new games did you upload? If you've tried to create a custum menu with hand-edited directory entries, then you might have just screwed up that part - better would be dumping a working cart in HIROM:ALL mode to a 4Mbyte flash image, and then programming that image to another cart, in HIROM:ALL mode, too.
Btw. mind that the SNES memory map doesn't have FLASH/ROM in bank 7Eh-7Fh (ie. you can't access the whole hirom at 40h-7Fh), accessing the whole hirom should work in bank C0h-FFh.

On a blank cart, I would expect the menu being located in first 512K, and the remaining memory being FFh-filled. That, when using the HIROM:ALL mode for dumping the cart. If you are mapping game#0, or use the HIROM:MENU mode, then you would obviously see only the menu, repeated 8x aka mirrored throughout the whole memory space.

Currently, it does look as if there's some hidden mapping info required...

If it's in SRAM, then you could simply copy the SRAM image alongsides with the FLASH image from one cart to another. That would be easy and worth testing, though it'd be a pretty bad design as it would brick the cartridge as soon as the battery becomes empty.

If there's an EEPROM in the MX15001 chip, then one may need to send further stuff to port 2400h-2407h, which might be difficult: doing stuff like guessing how to enter the EEPROM programming sequence, and guessing which values being needed to be written to the EEPROM.

If it's in the FLASH chip, then the "sector protect" bytes would still seem like the best candidates to me. Dumping those bytes would be easy as they are documented in the official datasheet, and from my tests, the chip does actually allow to read those bytes, but without actually using them for write-protection, so it wouldn't be unlikely that they are misused as mapping flags. Just DUMP those bytes, and check if you get different values on different carts! Somewhat like so:

Code: Select all

 after entering HIROM:ALL mode...
 [C0AAAAh]=AAh  ;\for 1st flash chip:
 [C05554h]=55h  ; enter read chip id / read sector protect mode
 [C0AAAAh]=90h  ;/
 [E0AAAAh]=AAh  ;\for 2nd flash chip:
 [E05554h]=55h  ; enter read chip id / read sector protect mode
 [E0AAAAh]=90h  ;/
 for i=0 to 1Fh
   DisplayHexValue([C00004h+i*20000h])   ;display sector protect bytes
 next i
On my cart, the first byte would be C2h, followed by 00h-bytes.
User avatar
sanni
Posts: 44
Joined: Sat Jul 20, 2013 2:21 pm

Re: How to program a NINTENDO POWER Cartridge ?

Post by sanni »

I tried the SRAM theory, sadly it was a dead end. Even after I flashed both the SRAM and the complete 4MB dump of skaman's Fire Emblem NP cart to my former menu+DerbyStallion98 cart it didn't boot.

I also tried listening to the databus with the Arduino but I'm not sure if I'm doing it right.
To me it looks like the MX15001 chip is resetting the flash and then doing some other stuff and sometimes it then resets the flash a second time.

In case it matters, I removed the CIC and all clocks for this test, and just manually clocked the expclk pin with a pin from the arduino, maybe about 500-700khz 50% duty cycle or something like that.
And the NP cart is a working Menu+Derby Stallion 98.
Writing and reading the complete NP cart also works this way.

Code: Select all

(0)Menu 0x80
Data: 0x2A Reset: 1
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x38 Reset: 0
Data: 0xD0 Reset: 0
Data: 0x71 Reset: 0
Data: 0x88 Reset: 0
Data: 0xFF Reset: 0
Data: 0x72 Reset: 0
Data: 0x75 Reset: 0
Data: 0x3 Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0xFF Reset: 0
Data: 0x0 Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x7D Reset: 1
Somtimes it does the same but without second flash reset

Code: Select all

(0)Menu 0x80
Data: 0x2A Reset: 1
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x38 Reset: 0
Data: 0xD0 Reset: 0
Data: 0x71 Reset: 0
Data: 0x88 Reset: 0
Data: 0xFF Reset: 0
Data: 0x72 Reset: 0
Data: 0x75 Reset: 0
Data: 0x3 Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0xFF Reset: 0
Data: 0x0 Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x7D Reset: 1
"Hirom All" and "hirom menu" don't do any reset, it's just 0x2A all the time with them

Code: Select all

(1)GAME1 0x81
Data: 0x2A Reset: 1
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x38 Reset: 0
Data: 0xD0 Reset: 0
Data: 0x71 Reset: 0
Data: 0x88 Reset: 0
Data: 0xFF Reset: 0
Data: 0x72 Reset: 0
Data: 0x75 Reset: 0
Data: 0x16 Reset: 0
Data: 0xFF Reset: 0
Data: 0x29 Reset: 0
Data: 0xFF Reset: 0
Data: 0x4A Reset: 0
Data: 0xFF Reset: 0
Data: 0x10 Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x7D Reset: 1

Code: Select all

(2)GAME2 0x82
Data: 0x2A Reset: 1
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x38 Reset: 0
Data: 0xD0 Reset: 0
Data: 0x71 Reset: 0
Data: 0x88 Reset: 0
Data: 0xFF Reset: 0
Data: 0x72 Reset: 0
Data: 0x75 Reset: 0
Data: 0xFF Reset: 0
Data: 0xAA Reset: 0
Data: 0x55 Reset: 0
Data: 0xF0 Reset: 0
Data: 0x7D Reset: 1
Last edited by sanni on Mon Feb 15, 2016 3:23 pm, edited 1 time in total.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

Cool, many thanks! That values do actually make sense: They seem to be the standard FLASH read/reset commands (as you said), plus additional Satellaview-style custom extra FLASH commands for reading the per-game mapping info from the FLASH chip.
Arranging your four dumps next to each other:

Code: Select all

Menu 0x80    Menu 0x80    GAME1 0x81   GAME2 0x82
Data: 0x2A   Data: 0x2A   Data: 0x2A   Data: 0x2A   Reset: 1    ;-Port 2400h (before /RESET)
Data: 0xFF   Data: 0xFF   Data: 0xFF   Data: 0xFF   Reset: 0    ;-HighZ
Data: 0xAA   Data: 0xAA   Data: 0xAA   Data: 0xAA   Reset: 0    ;\
Data: 0x55   Data: 0x55   Data: 0x55   Data: 0x55   Reset: 0    ; FLASH read/reset command
Data: 0xF0   Data: 0xF0   Data: 0xF0   Data: 0xF0   Reset: 0    ;/
Data: 0x38   Data: 0x38   Data: 0x38   Data: 0x38   Reset: 0    ;\
Data: 0xD0   Data: 0xD0   Data: 0xD0   Data: 0xD0   Reset: 0    ; FLASH request chip info part 1
Data: 0x71   Data: 0x71   Data: 0x71   Data: 0x71   Reset: 0    ;/
Data: 0x88   Data: 0x88   Data: 0x88   Data: 0x88   Reset: 0    ;-Read Ready-status (bit7=1=ready)
Data: 0xFF   Data: 0xFF   Data: 0xFF   Data: 0xFF   Reset: 0    ;-HighZ
Data: 0x72   Data: 0x72   Data: 0x72   Data: 0x72   Reset: 0    ;\FLASH request chip info part 2
Data: 0x75   Data: 0x75   Data: 0x75   Data: 0x75   Reset: 0    ;/
Data: 0x3    Data: 0x3    Data: 0x16   Data: 0xFF   Reset: 0    ;-Read value for Port 2404h
Data: 0xFF   Data: 0xFF   Data: 0xFF   -            Reset: 0    ;-HighZ
Data: 0xAA   Data: 0xAA   Data: 0x29   -            Reset: 0    ;-Read value for Port 2405h
Data: 0xFF   Data: 0xFF   Data: 0xFF   -            Reset: 0    ;-HighZ
Data: 0xAA   Data: 0xAA   Data: 0x4A   -            Reset: 0    ;-Read value for Port 2406h
Data: 0xFF   Data: 0xFF   Data: 0xFF   -            Reset: 0    ;-HighZ
Data: 0x0    Data: 0x0    Data: 0x10   -            Reset: 0    ;-Read value for Port 2407h
Data: 0xFF   Data: 0xFF   Data: 0xFF   -            Reset: 0    ;-HighZ and/or TERMINATE status mode
Data: 0xAA   Data: 0xAA   Data: 0xAA   Data: 0xAA   Reset: 0    ;\
Data: 0x55   -            Data: 0x55   Data: 0x55   Reset: 0    ; FLASH read/reset command
Data: 0xF0   -            Data: 0xF0   Data: 0xF0   Reset: 0    ;/
Data: 0x7D   Data: 0x7D   Data: 0x7D   Data: 0x7D   Reset: 1    ;-Port 2400h (after /RESET)
The leading/ending 2Ah/7Dh values seem to be just read from Port 2400h (assuming that you are still outputting address 2400h on address bus, as a relict from the preceeding Port 2400h game selection write) (and assuming that you have /OE switched LOW for some reason).
The AAh,55h,F0h values are just resetting the FLASH chip to read mode.
The 38h,D0h,71h, and 72h,75h values are custom FLASH commands, exactly same as used for Satelleview FLASH cart chip detection (though in this case they seem to be used for reading mapping info, not for chip detection).
The various FFh-bytes are probably just HighZ (at least most of them) occuring for a short moment when neither /OE nor /WE is output to the FLASH chip (yesterday you had posted a "dirtier" dump that showed each value repeated several times, and the FFh's were repeated only 2 times, unlike as the other values which occurred repeated 6-8 times). Looking at the above table, it does look as if the FFh/HighZ's do occur after READing from FLASH chip, so they do help on guessing the Read/Write-direction of the separate bytes.
The last FFh byte might be just another HighZ... or, if occurs for a longer duration, then it would be probably a FFh value written to terminate the chip-info mode (as done by satellaview).
The 88h byte being read after the writing 38h,D0h,71h seems to be just a status byte with bit7=ready, the Satellaview bios is reading that kind of status value in that place, too.
The remaining four bytes are supposedly mapping info being read from the chip, and then copied to port 2404h-2407h.

The missing two bytes in the second dump: That looks as if something went wrong, either your dumping software missed the 55h,F0h bytes, or the MX150001 chip somehow failed to output those bytes; maybe related to absent CIC. Anyways, just let's ignore that.
The missing seven bytes in the fourth dump: As there's no GAME2 on that cart, two things could have happened: The chip did output four FFh bytes (plus four HighZ bytes) in that case you should see about thirty-two repeated FFh's. Or the chip did output only one FFh byte, and the MX150001 did treat that as "no game" and aborted reading the other bytes.

For the address bus values, the AAh,55h,F0h values are obviously written to standard FLASH addresses (AAAAh and 5554h). The 38h,D0h,71h, and 72h,75h bytes are probably just written to FLASH address 0000h (the satellaview bios is doing it that way), the 88h ready byte is probably read from address 0002h (also as done by satellaview), and the four mapping bytes are probably read somewhere from FF00h..FFxxh (also as done by satellaview, but in this case using different addresses based on the preceeding port 2400h game selection).

Next steps should be:
Trying to read the mapping info manually from the FLASH chips.
Somehow "decrypt" those values & figure out which bits do affect the ROM/SRAM mapping base/size and lorom/hirom mode. For that purpose, it would be helpful to collect mapping bytes from different nintendo power carts.
And try to erase/rewrite the mapping bytes via whatever FLASH commands, which may require some guessing or brute forcing. Or, as skaman asked if port 2404h-2407h are write-able: That might be also worth trying. If it works then one could completely bypass the hidden mapping bytes, and just use a custom menu which is manually applying the mapping based on the directory and cart-header's (instead of using the [002400h]=8xh game selection).
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

Tried to write port 2401h..2407h: It didn't change any values read from 2400h..2407h, so that ports aren't writeable (or writing works only indirectly in form of command parameters, as done with port 2401h during initialization).

And, tried dumping the hidden memory of my menu+fighting eleven cart, that worked well:

Code: Select all

menu+fighting eleven - chip 1:
 C0FF00  03 11 AA 50 AA 98 00 10  ;Menu (512Kbyte Lorom)
 C0FF08  15 25 29 05 4A 47 10 54  ;Fighting Eleven (3072Kbyte Lorom, 8Kbyte SRAM)
 C0FF10  FF FF FF FF FF FF FF FF  ;unused
 ...     FF FF FF ...             ;...
 C0FFF8  FF FF FF FF FF FF FF FF  ;unused
menu+fighting eleven - chip 2:
 E0FF00  FF FF FF FF FF FF FF FF
 ...     FF FF FF ...
 E0FF88  FF FF FF FF FF FF FF FF
 E0FF90  FF FF 55 00 FF FF FF FF  ;<--
 E0FF98  FF FF FF FF FF FF FF FF
 E0FFA0  FF FF FF FF FF FF 55 00  ;<--
 E0FFA8  FF FF FF FF FF FF FF FF
 E0FFB0  FF FF FF FF FF FF 00 00  ;<--
 E0FFB8  FF FF FF FF FF FF FF FF
 ...     FF FF FF ...
 E0FFF8  FF FF FF FF FF FF FF FF
The bytes at even addresses are the values for port 2404h..2407h (eg. 03,AA,AA,00 for menu). Confusingly there are further values at odd addresses (eg. 11,50,98,10 for menu). Going by sanni's databus dump that values aren't used during game selection, so they seem to be just unused garbage... unless they are checked on power-up, or are used internally by the FLASH chip for whatever purpose.
The data repeats every 100h bytes. The satellaview uses address 0FFxxh, but one could as well read anywhere from 000xxh to 1FFxxh. Assuming that the whole 100h bytes are writeable, then the whole mapping info for ALL games will be probably stored in the first chip, and the other 100h bytes in second chip would be always FFh-filled (apart from those 55h/00h values seen in above dump, which might be some chip-testing relicts or so).

The dumping function looks as so:

Code: Select all

 mov  a,038h // mov [far 0c00000h],a
 mov  a,0d0h // mov [far 0c00000h],a
 mov  a,071h // mov [far 0c00000h],a
 mov  a,[far 0c00004h] // call wrhexa // call wrcrlf   ;<-- addr=4 required (unlike satellaview's addr=2)
 mov  a,072h // mov [far 0c00000h],a
 mov  a,075h // mov [far 0c00000h],a
 mov  x,0
@@show_hidden_info_ylop:
 mov  a,x
 call wrhexa
 call wrspc
@@show_hidden_info_xlop:
 call wrspc
 mov  a,[far 0c0ff00h+x+0h] // call wrhexa    ;this data repeats every 100h bytes (at C000xxh..DFFFxxh)
 inc  x
 mov  a,x
 and  a,07h
 jnz  @@show_hidden_info_xlop
 call wrcrlf
 cmp  x,00h   ;aka 100h when using non-8bit maths
 jnz  @@show_hidden_info_ylop
 mov  a,0ffh // mov [far 0c00000h],a   ;<-- no effect (use below AAAAh/5554h/AAAAh stuff instead)
 mov  a,[far 0c00000h] // call wrhexa // call wrcrlf   ;still returns HIDDEN data
 mov  a,0aah // mov  [far 0c0aaaah],a  ;\
 mov  a,055h // mov  [far 0c05554h],a  ; return to normal read mode
 mov  a,0f0h // mov  [far 0c0aaaah],a  ;/
 mov  a,[far 0c00000h] // call wrhexa // call wrcrlf   ;returns normal FLASH data
For the second chip use address E0xxxxh instead C0xxxxh. Switch to HIROM:ALL mode before using above function.
User avatar
sanni
Posts: 44
Joined: Sat Jul 20, 2013 2:21 pm

Re: How to program a NINTENDO POWER Cartridge ?

Post by sanni »

Wow so much info, thank you, I read through it three times already and am still amazed. This is one very interesting cartridge. :beer: :D
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

Got some more mapping bytes from skaman:

Code: Select all

;------------------
blank cart (menu only):
 C0FF00      03 11 AA 56 AA 97 00 11  ;Menu (512Kbyte Lorom)
 C0FF08      00 25 00 10 00 25 00 02  ;empty (no game installed)
 C0FF10..FF  FF-filled
 E0FF00..8F  FF-filled
 E0FF90      FF FF 55 00 FF FF FF FF FF FF FF FF FF FF FF FF
 E0FFA0      FF FF FF FF FF FF 55 00 FF FF FF FF FF FF FF FF
 E0FFB0      FF FF FF FF FF FF 55 00 FF FF FF FF FF FF FF FF
 E0FFC0..FF  FF-filled
;------------------
FE776 (no menu):
 C0FF00      1E 11 29 45 4A 97 00 12  ;Fire Emblem Thracia 776 (4Mbyte Lorom, 32Kbyte SRAM)
 C0FF08      FF 11 FF 12 FF 04 FF 11  ;unused
 C0FF10..7E  FF-filled
 C0FF7F      00
 C0FF80..FF  FF-filled
 E0FF00..FF  same as the blank cart
;------------------
*** Edit: This is a bad dump of DKC3 (with bit4 set in all bytes) ***
DKC3 (no menu):
 C0FF00      5C 11 71 52 B5 97 10 11  ;Donkey Kong Country 3 (4Mbyte Hirom, 2Kbyte SRAM)
 C0FF08      FF 17 FF 10 FF 32 FF 15  ;unused
 C0FF10..FF  FF-filled
 E0FF00..8F  FF-filled
 E0FF90      FF FF 55 10 FF FF FF FF FF FF FF FF FF FF FF FF
 E0FFA0      FF FF FF FF FF FF 55 10 FF FF FF FF FF FF FF FF
 E0FFB0..FF  FF-filled
;------------------
Derby 98 (with menu):
 C0FF00      03 11 AA 86 AA 97 00 11  ;Menu (512Kbyte Lorom)
 C0FF08      16 17 29 10 4A 55 10 44  ;Derby Stallion '98 (3Mbyte Lorom, 32Kbyte SRAM)
 C0FF10..FF  FF-filled
 E0FF00..8F  FF-filled
 E0FF90      FF FF 55 00 FF FF FF FF FF FF FF FF FF FF FF FF
 E0FFA0      FF FF FF FF FF FF 55 00 FF FF FF FF FF FF FF FF
 E0FFB0..FF  FF-filled
;------------------
Mother2 (with menu):
 C0FF00      03 11 AA 77 AA 97 00 10  ;Menu (512Kbyte Lorom)
 C0FF08      55 20 61 15 A5 55 10 18  ;Mother 2 (3Mbyte Hirom, 8Kbyte SRAM)
 C0FF10..7E  FF-filled
 C0FF7F      00
 C0FF80..FF  FF-filled
 E0FF00..7F  FF-filled
 E0FF80..7F  AA 00 42 00 FF FF FF FF FF FF AA 00 42 00 AA 00
 E0FF90..7F  FF FF 55 00 FF FF FF FF FF FF FF FF FF FF FF FF
 E0FFA0..7F  55 00 FF FF FF FF 55 00 FF FF FF FF FF FF FF FF
 E0FFB0..FF  FF-filled
;------------------
SMW + Torneko no Daibouken (with Menu):
 C0FF00      03 11 AA 92 AA 97 00 11  ;Menu (512Kbyte Lorom)
 C0FF08      00 28 29 11 4A 33 10 45  ;Super Mario World (512Kbyte Lorom, 2Kbyte SRAM)
 C0FF10      09 FF 29 FF 4A FF 21 FF  ;Torneco no Daibouken (1.5Mbyte Lorom, 8Kbyte SRAM)
 C0FF18..7E  FF-filled
 C0FF7F      00
 C0FF80..FF  FF-filled
 E0FF00..FF  same as the blank cart
There are always 8 bytes at odd addresses at C0FF01..0F, interleaved with the mapping entries 0 and 1 (though no matter if the cart uses 1, 2, or 3 mapping entries). The 'odd' bytes are always in BCD range, probably some serial number, apart from the first two bytes, it seems to be just a date/time stamp, ie. formatted as 11-xx-YY-MM-DD-HH-MM-SS.

Some carts have extra 'garbage' at C0FF7F and E0FF80..BF.

And the actual mapping info, might be as so:

Port 2404h = Size:
Bit0-1 SRAM Size (0=2K, 1=8K, 2=32K, 3=None) ;ie. 2K SHL (N*2)
Bit2-4 ROM Size (0=512K, 2=1.5M, 5=3M, 7=4M) ;ie. 512K*(N+1)
Bit5 Zero (maybe MSB of ROM Size for carts with three FLASH chips) (set for HIROM:ALL)
Bit6-7 Mode (0=Lorom, 1=Hirom, 2=Forced HIROM:MENU, 3=Forced HIROM:ALL)


Port 2407h = Base:
Bit0-3 SRAM Base in 2K units
Bit4-6 ROM Base in 512K units
Bit7 Zero (maybe MSB of ROM Base for carts with three FLASH chips) (set when forcing HIROM:MENU on skaman's blank cart)

Would need more dumps to confirm that (especially carts with multiple games on them).
Edit: below DKC3 issue was due to bad dump
The DKC3 cart is already somewhat blowing that theory: It's having the "ROM Base" set to 1 (although not having a menu), so the game's cart header would be at FLASH offset 08FFC0h rather than 00FFC0h, which looks wrong... unless the cart is really programmed in that fashion, that could be verified by dumping it in HIROM:ALL mode.

Port 2405h,2406h = Whatever:
AA,AA ;Menu (512Kbyte Lorom)
29,4A ;Fighting Eleven (3072Kbyte Lorom, 8Kbyte SRAM)
29,4A ;Fire Emblem Thracia 776 (4Mbyte Lorom, 32Kbyte SRAM)
29,4A ;Derby Stallion '98 (3Mbyte Lorom, 32Kbyte SRAM)
29,4A ;Super Mario World (512Kbyte Lorom, 2Kbyte SRAM)
29,4A ;Torneco no Daibouken (1.5Mbyte Lorom, 8Kbyte SRAM)
71,B5 ;Donkey Kong Country 3 (4Mbyte Hirom, 2Kbyte SRAM)
61,A5 ;Mother 2 (3Mbyte Hirom, 8Kbyte SRAM)
61,A5 ;(when forcing HIROM:ALL)
D5,7F ;(when forcing HIROM:MENU)
8A,8A ;(when forcing HIROM:MENU on skaman's blank cart)

That stuff looks kinda meaningless. For Lorom (except menu) it's always 29,4A. And for Hirom it's either 61,A5 or 71,B5. Maybe more dumps will reveal some purpose, like some extra SRAM-disable flag, or selecting which bank(s) the ROM/SRAM is mapped/mirrored in the SNES memory space or so.
Last edited by nocash on Fri Oct 02, 2015 7:39 am, edited 11 times in total.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: How to program a NINTENDO POWER Cartridge ?

Post by Near »

So without including the sector protect bytes of the flash chips, Nintendo Power cart dumps are incomplete. Yet with the traditional ROM format, there's no place to put this data.

We could probably apply traditional "LoROM / HiROM detection" heuristics every 512KiB of ROM to generate valid information ourselves dynamically, but it wouldn't be accurate nor complete as we don't know exactly what every bit is for.

One could also claim a similar issue with BS-X Satellaview packs, but there's really only two types of values there: one for FlashROM (all the same size), one for MaskROM (only three such packs.)

Given the extreme difficulty and low utility in dumping these (NP-only games are already extracted to standard 'ROMs', eg Metal Slader Glory), there's not much point in worrying about it, I suppose.

But if there were complete images (with sector protect info) out in the wild, I'd be up for emulating this.
Post Reply