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.
BennVenn
Posts: 107
Joined: Sat Mar 29, 2014 10:01 pm
Location: Australia
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by BennVenn »

Great work!

Just something to keep in mind when re-flashing the flash. Unlock sector 0 first.

main_JPN_F1(0x5555,0xAA)
main_JPN_F1(0x2AAA,0x55)
main_JPN_F1(0x5555,0x60)
main_JPN_F1(0x5555,0xAA)
main_JPN_F1(0x2AAA,0x55)
main_JPN_F1(0x0000,0x40)
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:If I use only 0x40, then the contents of the register becomes the result of merging the two register files (original and new) like using a bitwise AND.
Okay, the bitwise ANDing would be the normal case when erase didn't occur.
On a normal flash chip, that six-byte sequence (AA-55-60 plus AA-55-40) would be the sector unprotect command. The sixth byte (40h) should be normally written to the desired sector address (not to AAAAh) though, but I guess the chip might accept any address in range 0..1FFFFh for unprotecting the first 128Kbyte-page.
Maybe the command is just doing the same thing on the chip in the gameboy cart, too. Maybe that command (or some other command) does also allow to protect/unprotect the hidden sector. But either way, if you have the /WP pin switched high (did you?) then the whole chip should be always write-able (going by the datasheet, the protect flags are used only when /WP=LOW).
skaman wrote:If I use only 0x04, then the register get erased to FFs but only 0x80-0xFF is written the first time. I have to add another 0x04, then 0x0-0x7F is written. It looks like the 0x40 function can be replaced by a 2nd 0x04 function.
Odd. The first write to 00h..7Fh is ignored, and only the second write to 80h..FFh is taken?
Sounds a bit as if the erase wasn't finished yet, so the chip refused the first write command when erase was still busy.

How are you handling the Write/Erase busy stuff? Ie. those "Loop (0x100 times) ... until 0x0000 reads 0x80" parts?
Correct should be reading until Bit7 of the returned data becomes 1=Ready. You may also add a timeout so that the program won't hang if something gets wrong, but make sure that the timeout is big enough (like one second, or at least several milliseconds). Doing the timeout after looping "0x100 times" sounds a bit short (depends on how much time your program needs to execute one of those loop cycles, of course).

Btw. also in the Write/Erase busy stuff: Is that "Write 0x03" really needed for anything? Normally it should be enough to READ the status byte several times (until it indicates ready), but without needing to write anything during (or after) that period.
BennVenn wrote:Just something to keep in mind when re-flashing the flash. Unlock sector 0 first.
Yes, just mentioned that sector protect stuff too, while you've sent your post. I think it's needed only when /WP=LOW though.
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:The standard flash command 0x90 can retrieve the flash ID C2/89
BennVenn wrote:ID's are $C2 and $83.
That are different chips with different IDs?
skaman wrote:I hooked up a logic analyzer to my GB cart interface that sits between the GB cart and the GB XChanger.
If you have spare time to do more soldering... How about wiring it up directly to the GB cart - and then logging what happens when running the cart on a real gameboy?
Theoretically it should read the hidden data on power-up, and also after selecting a game in the menu. Going by mootan's code, that would be done by sending AA-55-77 twice, but as far as I understand, mootan has found that command by trial-and-error - which is great - but it would be also interesting if Nintendo is really using the exact same sequence.
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

All of the carts that I have on hand report C2/89 which matches what Nitro found.

I did some logging with the cart interface sitting between the cart and Gameboy. I'll look and see what is there.
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

Here's what I've got so far on the GB NP mapping:

Code: Select all

GB Mapping Info
Entries start at 0x0 divided into 3 Byte segments

For example, let's look at the start of the mapping for a multi-game cart:  
A8 00 00 71 04 00 48 94 04 separates into
A8 00 00 MENU
71 04 00 GAME 1
48 94 04 GAME 2

Byte 00 of each entry contains the MBC Type, ROM Size, and SRAM Size (start).  
SRAM Size is 3 bits across Byte 00 and Byte 01.
     MBC SZE SRAM 
A8 = 101 010 00  0 MBC5, size 2 = 128KB
71 = 011 100 01  0 MBC3, size 4 = 512KB, SRAM 8KB
48 = 010 010 00  1 MBC2, size 2 = 128KB, SRAM MBC2

Byte 00: 1st 3 Bits = MBC Type
        000 = MBC0
        001 = MBC1
        010 = MBC2
        011 = MBC3
        101 = MBC5
 
Byte 00: 2nd 3 Bits = ROM Size (minimum size is 128KB due to block size)
        010 = Size 2 - 128KB
        011 = Size 3 - 256KB
        100 = Size 4 - 512KB
        101 = Size 5 - 1MB

Byte 00: Last 2 Bits (bit1..bit0) + Byte 01: 1st Bit (bit7) = SRAM Size
        00 0 = NONE
        00 1 = SRAM MBC2
        01 0 = SRAM 8KB
        01 1 = SRAM 32KB

Byte 01 contains the SRAM Size (end) and ROM Block in the Flash.
ROM Blocks are 128KB (8 total)
Byte 01: Last 7 Bits (bit6..bit0) = ROM Block
			00 = ROM Block 0  start offset 0KB
			04 = ROM Block 1  start offset 128KB
			08 = ROM Block 2  start offset 256KB
			0C = ROM Block 3  start offset 384KB
			10 = ROM Block 4  start offset 512KB
			14 = ROM Block 5  start offset 640KB
			18 = ROM Block 6  start offset 768KB
			1C = ROM Block 7  start offset 896KB

Byte 02 contains the RAM Block in the SRAM.
RAM Blocks are 8KB (16 total)
Byte 02: RAM Block:
			00 = RAM Block 0  start offset 0KB
			04 = RAM Block 1  start offset 8KB
			08 = RAM Block 2  start offset 16KB
			0C = RAM Block 3  start offset 24KB			
			and so on until RAM Block 15.

Going back to our example cart:
A8 00 00 MENU:  MBC5, size 2 = 128KB, ROM Block 0, RAM Block 0 (Ignored since SRAM is 000)
71 04 00 GAME 1:  MBC3, size 4 = 512KB, SRAM 8KB, ROM Block 1, RAM Block 0
48 94 04 GAME 2:  MBC2, size 2 = 128KB, SRAM MBC2, ROM Block 5, RAM Block 1
EDIT: Fixed the SRAM Size. Uses 3 bits spread across Byte 00 and 01.
Last edited by skaman on Sun Jan 24, 2016 6:20 am, edited 5 times 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 »

Looks good! And looks as if you've already found out everything. Or do you still have some games that have non-zero bits in unexpected locations (like bit5-6 of byte1, for example)?

One thing that is missing is the RAM size. Common would be None, 2K, 8K, 32K (maybe also 128K in some newer titles), maybe that's somehow encoded in the 2bit "SRAM Flag" entry... do you have games with different size in your collection? The size can be seen in the gameboy cart ROM header (entry 0149h).

MBC1, MBC2, MBC3 and MBC5 should cover the most common mappers, do you have NP games of all those types in your collection, for confirming that they are all supported?

There are few more mappers like Huc1 or MBC4, but they are rarely used, so Nintendo might have considered as not worth being implemented in NP cartridges.

What is MBC0? Does that mean small games with only 32Kbyte ROM (=without any ROM bank switching)? Don't know if Nintendo sold any such small games as NP titles - or did they sell only newer/bigger titles? Oh, and did they sold both classic monochrome games and gameboy color games, or only color ones?
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

nocash wrote:Looks good! And looks as if you've already found out everything. Or do you still have some games that have non-zero bits in unexpected locations (like bit5-6 of byte1, for example)?

One thing that is missing is the RAM size. Common would be None, 2K, 8K, 32K (maybe also 128K in some newer titles), maybe that's somehow encoded in the 2bit "SRAM Flag" entry... do you have games with different size in your collection? The size can be seen in the gameboy cart ROM header (entry 0149h).

MBC1, MBC2, MBC3 and MBC5 should cover the most common mappers, do you have NP games of all those types in your collection, for confirming that they are all supported?

There are few more mappers like Huc1 or MBC4, but they are rarely used, so Nintendo might have considered as not worth being implemented in NP cartridges.

What is MBC0? Does that mean small games with only 32Kbyte ROM (=without any ROM bank switching)? Don't know if Nintendo sold any such small games as NP titles - or did they sell only newer/bigger titles? Oh, and did they sold both classic monochrome games and gameboy color games, or only color ones?
The SRAM Flag could be the RAM Size. I only have games that use 8KB saves. So those 2 bits could be used to encode something larger. The minimum RAM size would be 8KB (like the minimum ROM size is 128KB) due to the block size.

Code: Select all

Byte 0: Last 2 Bits = RAM Size
        00 = NONE
        01 = SRAM 8KB
//      10 = SRAM ? (No Example)
//      11 = SRAM ? (No Example)
I have carts with MBC 0, 1, 2, 3 and 5. Entries for MBC 4, 6, and 7 are possible but I'm not sure if they're actually supported. I'll have to give those mappers a try when I find some time.

Yes, MBC0 = No Mapper. Sorry, went with the MBC# theme when typing it out. In my multi-game carts, I have NO_MBC games: Alleyway, Tennis and Yakuman.
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

nocash wrote:Theoretically it should read the hidden data on power-up, and also after selecting a game in the menu. Going by mootan's code, that would be done by sending AA-55-77 twice, but as far as I understand, mootan has found that command by trial-and-error - which is great - but it would be also interesting if Nintendo is really using the exact same sequence.
I looked at the startup sequence and also when the cart switches between games.

The cart does use the AA-55-77 sequence.

Code: Select all

STARTUP:  MENU MAPPING: A8 00 00
0x8000, 0xFF (RD LOW) (RESET LOW)
0x8000, 0xF0 (RD LOW) (RESET LOW)
0x8000, 0xAA (RD LOW) (RESET LOW)
0x8000, 0x55 (RD LOW) (RESET LOW)
0x8000, 0x77 (RD LOW) (RESET LOW)
0x8000, 0xAA (RD LOW) (RESET LOW)
0x8000, 0x55 (RD LOW) (RESET LOW)
0x8000, 0x77 (RD LOW) (RESET LOW)
0x8000, 0xFF (RD LOW) (RESET LOW)
0x8000, 0x00 (RD LOW) (RESET LOW)
0x8000, 0xA8 (RD LOW) (RESET LOW)  (MAPPING BYTE 00)
0x8000, 0x00 (RD LOW) (RESET LOW)  (MAPPING BYTE 01 & 02 - DURATION IS 2X)
0x8000, 0xF0 (RD LOW) (RESET LOW)
0x8000, 0xFF (RD LOW) (RESET LOW)

SWITCHING TO GAME 1 MAPPING:  31 04 00
0x8000, 0xFF (RD LOW) (RESET LOW)
0x8000, 0xF0 (RD LOW) (RESET LOW)
0x8000, 0xAA (RD LOW) (RESET LOW)
0x8000, 0x55 (RD LOW) (RESET LOW)
0x8000, 0x77 (RD LOW) (RESET LOW)
0x8000, 0xAA (RD LOW) (RESET LOW)
0x8000, 0x55 (RD LOW) (RESET LOW)
0x8000, 0x77 (RD LOW) (RESET LOW)
0x8000, 0xFF (RD LOW) (RESET LOW)
0x8000, 0x00 (RD LOW) (RESET LOW)
0x8000, 0x31 (RD LOW) (RESET LOW)  (MAPPING BYTE 00)
0x8000, 0x04 (RD LOW) (RESET LOW)  (MAPPING BYTE 01)
0x8000, 0x00 (RD LOW) (RESET LOW)  (MAPPING BYTE 02)
0x8000, 0xF0 (RD LOW) (RESET LOW)
RESET GOES HIGH
0x8000, 0xFF (RD LOW)

SWITCHING TO GAME 2 MAPPING:  2D 14 04
0x8000, 0xFF (RD LOW) (RESET LOW)
0x8000, 0xF0 (RD LOW) (RESET LOW)
0x8000, 0xAA (RD LOW) (RESET LOW)
0x8000, 0x55 (RD LOW) (RESET LOW)
0x8000, 0x77 (RD LOW) (RESET LOW)
0x8000, 0xAA (RD LOW) (RESET LOW)
0x8000, 0x55 (RD LOW) (RESET LOW)
0x8000, 0x77 (RD LOW) (RESET LOW)
0x8000, 0xFF (RD LOW) (RESET LOW)
0x8000, 0x00 (RD LOW) (RESET LOW)
0x8000, 0x2D (RD LOW) (RESET LOW)  (MAPPING BYTE 00)
0x8000, 0x14 (RD LOW) (RESET LOW)  (MAPPING BYTE 01)
0x8000, 0x04 (RD LOW) (RESET LOW)  (MAPPING BYTE 02)
0x8000, 0xF0 (RD LOW) (RESET LOW)
RESET GOES HIGH
0x8000, 0xFF (RD LOW)
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

Nice to see that the gameboy chip is holding reset low (like the snes version), and that it does really use twice AA-55-77 (unlike snes version).

The address 8000h and the /RD LOW stuff are logged that values from the cart-edge connector? Ie. those values are coming from the gameboy cpu during reset... which would be don't care since the cartridge is internally using it's own address bus and /RD and /WR signals for communicating between the FLASH and MX15002 chip.

For the data values, the leading/trailing FF's might be just openbus. The F0's might be the "reset-to-read-mode" command, though that should be three bytes long, AA-55-F0. Don't know what's happening there, maybe one can omit "AA-55" for command? I guess your logging hardware is more than fast enough, so it couldn't have missed the AA-55 bytes (even if they were only half as long in duration as the other bytes).

And the FF-00 (after the second AA-55-77 command, and before reading the 3-byte mapping data)... what could that be? Some status byte and/or open-bus? Or something read from the hidden flash sector? The latter one could be verified by filling the whole hidden sector values with some other value (like all bytes set to 33 for example), and then checking if the cart is still coming up with FF-00.
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

Found a GB Memory cart with a game that uses a 32KB SRAM. The SRAM size is actually 3 bits. The last two bits of Byte 00 (bit1..bit0) and the uppermost bit of Byte 01 (bit7) make up the SRAM size. The uppermost bit of Byte 01 (bit7) by itself appears to only be used for MBC2 games.

Code: Select all

Byte 00: Last 2 Bits (bit1..bit0) + Byte 01: 1st Bit (bit7) = SRAM Size
        000 = NONE
        001 = SRAM MBC2
        010 = SRAM 8KB
        011 = SRAM 32KB
I'll update my earlier post with the corrected mapping details some time.
Last edited by skaman on Sun Jan 24, 2016 6:26 am, edited 3 times in total.
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

Going back to work on the SF Memory cart, I found the Intel Software Driver for the 16Mbit Flash Family (28F016). The command set appears identical to the Sharp (and Elisra) chips cited previously by nocash and includes the page buffer commands. The PDF is Intel Application Note 377 which includes C and ASM code: ftp://download.intel.com/design/archive ... 212603.pdf

I also extracted a copy of the Intel 28F016SA User's Manual (297372) from the Intel FlashBuilder software. I'll try to convert it from the current Windows help file format to PDF.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

I've got a Nintendo Power cart for gameboy, too (thanks again, skaman). First thing that I've looked at are the pinouts of the chips:

Code: Select all

MX15002UCA (G-MMC1)
  1  VCC
  2  GND
  3  Gameboy /WR
  4  Gameboy /RD
  5  Gameboy /RAM_CS (addr A000h..FDFFh)
  6  Gameboy A0
  7  Gameboy A1
  8  Gameboy A2
  9  Gameboy A3
  10 Gameboy A4
  11 Gameboy A5
  12 GND
  13 Gameboy A6
  14 Gameboy A7
  15 Gameboy A8
  16 Gameboy A9
  17 Gameboy A10
  18 Gameboy A11
  19 Gameboy A12
  20 Gameboy A13
  ---
  21 Gameboy A14
  22 Gameboy /ROM_CS (aka A15)
  23 Gameboy /RESET
  24 Gameboy /RESET (too)
  25 MEM A0
  26 MEM A13
  27 MEM A12
  28 GND
  29 MEM A11
  30 MEM A9
  31 MEM A8
  32 MEM A7
  33 VCC
  34 MEM A6
  35 MEM A5
  36 MEM A4
  37 MEM A10
  38 GND
  39 MEM A3
  40 MEM A2
  ---
  41 MEM A1
  42 MEM A14
  43 MEM A15
  44 MEM A16
  45 FLASH A17
  46 FLASH A18
  47 FLASH A19
  48 GND
  49 FLASH /CE
  50 FLASH /WP
  51 MEM /OE
  52 MEM /WE
  53 VCC
  54 NC
  55 NC
  56 GND
  57 GND
  58 NC
  59 to C2
  60 FLASH /RP
  ---
  61 SRAM /CE
  62 VBAT (via R1 from battery)
  63 VCC
  64 SRAM VCC
  65 GND
  66 GND
  67 MODESEL (to R4/R5)
  68 GND
  69 VCC
  70 Gameboy D7
  71 Gameboy D6
  72 Gameboy D5
  73 Gameboy D4
  74 Gameboy D3
  75 Gameboy D0
  76 Gameboy D1
  77 Gameboy D2
  78 GND
  79 OSC1 (NC)   unused, replaced by internal OSC?
  80 OSC2 (NC)   ... or MAYBE (unlikely) for RTC support ??

Gameboy Cartridge Slot
  Pin   Name    Expl.
  1     VDD5    Power Supply +5V DC
  2     PHI     System Clock (1.05MHz) (2.10MHz in CGB double speed mode)
  3     /WR     Write
  4     /RD     Read
  5     /CS     WRAM/SRAM Chip Select (Low on address A000h-FDFFh)
  6-21  A0-A15  Address Lines (A15 used as ROM Chip Select)
  22-29 D0-D7   Data Lines
  30    /RES    Reset signal
  31    Vin     External Sound Input
  32    GND     Ground
PHI and Vin aren't used for Nintendo Power carts.

MX29F008ATC-14 FLASH
  1  A16
  2  A15
  3  A14
  4  A13
  5  A12
  6  A11
  7  A9
  8  A8
  9  /WE
  10 /RP
  11 VPP
  12 /WP
  13 A18
  14 A7
  15 A6
  16 A5
  17 A4
  18 A3
  19 A2
  20 A1
  ---
  21 A0
  22 /CE
  23 GND
  24 /OE
  25 D0
  26 D1
  27 D2
  28 D3
  29 NC
  30 VCC
  31 VCC
  32 D4
  33 D5
  34 D6
  35 D7
  36 A10
  37 A19
  38 NC
  39 GND
  40 A17
The FLASH pinout is same as for Micron MT28F008 and Sharp LH28F008 (Macronix
themselves didn't publish any MX29F008 datasheet, and their other chips like
MX29F080, MX29F004, and MX29F016 are having different pinouts).

SRAM Pinouts
         .----__-----.
      NC |1        32| VCC
     A16 |2        31| A15
     A14 |3        30| VCC
     A12 |4        29| /WE
      A7 |5        28| A13
      A6 |6        27| A8
      A5 |7        26| A9
      A4 |8  SRAM  25| A11
      A3 |9        24| /OE
      A2 |10       23| A10
      A1 |11       22| /CE
      A0 |12       21| D7
      D0 |13       20| D6
      D1 |14       19| D5
      D2 |15       18| D4
     GND |16       17| D3
         '-----------'
The "MEM" pins are meant to be shared for FLASH and SRAM.
Don't know what pin 54, 55, 58, 59, 60, 67, 79, 80 on the MX15002 chip are good for.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: How to program a NINTENDO POWER Cartridge ?

Post by nocash »

And, tested some software stuff, too. I've been using an old parallel port cart reader from Bung, getting that thing to do what it should was a bit difficult (bung seems to have used a MODE byte that can be 00h,80h,81h,82h,83h, bit7 seems to control the /RESET line, and bit1 seems to be auto-incremented on write, and bit0 auto-increment on read - sending nintendo power commands seems to work best with those two bits cleared, and bit7 set to release /RESET). Some of the nintendo power commands take over control of the databus - but seems to be no problem with the bung hardware (ie. it seems to disable its databus output shortly after each writing).

The command values for port 0120h-013Fh known so far:

Code: Select all

 [0120h]=00h, ...                                                ;-?
 [0120h]=01h, ...                                                ;-?
 [0120h]=02h, [013Fh]=A5h                                        ;-Wrpot.Step2 (set stat.bit1)
 [0120h]=03h, [013Fh]=A5h                                        ;-EDIT: Undo.Step2  (clr stat.bit1)
 [0120h]=04h, [013Fh]=A5h                                        ;-Map Entire
 [0120h]=05h, [013Fh]=A5h                                        ;-Map Menu
 [0120h]=06h, ...                                                ;-?
 [0120h]=07h, ...                                                ;-?
 [0120h]=08h, [013Fh]=A5h                                        ;-Undo Wakeup
 [0120h]=09h, [0121h]=AAh, [0122h]=55h, [013Fh]=A5h              ;-Wakeup (EDIT: and, clr stat.bit0)
 [0120h]=0Ah, [0125h]=62h, [0126h]=04h, [013Fh]=A5h              ;-Wrpot.Step1 (set stat.bit0)
 [0120h]=0Bh, ...                                                ;-?
 [0120h]=0Ch, ...                                                ;-Undo Wakeup, too
 [0120h]=0Dh, ...                                                ;-?
 [0120h]=0Eh, ...                                                ;-?
 [0120h]=0Fh, [0125h]=hi,  [0126h]=lo,  [0127h]=dta, [013Fh]=A5h ;-Write Byte
 [0120h]=10h, [013Fh]=A5h                                        ;-EDIT: Disable writes to MBC registers
 [0120h]=11h, [013Fh]=A5h                                        ;-EDIT: Re-Enable writes to MBC registers
 [0120h]=12h..7Fh ...                                            ;-?
 [0120h]=80h..BFh, [013Fh]=A5h             ;-Map 0..3Fh with RESET (for CGB/GBA) (set stat.bit2-7 to 0..3Fh)
 [0120h]=C0h..FFh, [013Fh]=A5h             ;-Map 0..3Fh without RESET (for DMG/SGB) (set stat.bit2-7 to 0..3Fh)
CMD_09h (Wakeup) is probably needed before sending any other commands, and, more eye-catching: It's activating read-access to port 0120h..013Fh. That's making it impossible to read normal ROM data from that locations, unless using CMD_08h (Undo Wakeup), or CMD_0Ch (seems to act same/similar as CMD_08h).

CMD_0Ah and CMD_02h seem to be both required for switching /WP to HIGH. They seem to be working only when sending them in order first CMD_0Ah, followed by CMD02h.

CMD_80h..BFh and CMD_C0h..FFh are used for mapping a selected game. The menu contains three different mapping methods (depending on what console it's running on):
For CGB and GBA consoles: Mapping is done via CMD_8xh, this selects game "x", and issues a /RESET to the gameboy. The advantage is that /RESET does reinitialize everything, AND, allows to switch between color gameboy and monochrome gameboy mode (which possible only after /RESET or power-up). The downside is that it's displaying the "Nintendo" logo another time after game selection.
For classic gameboy and gameboy pocket consoles: Mapping is done via CMD_Cxh, that selects game "x", but doesn't issue a /RESET (maybe because the /RESET pin doesn't work as input on older consoles). Instead, the menu is reinitializing some stuff by software, and does then jump to 0100h (the game entrypoint).
For SGB and SGB consoles: These are using CMD_Cxh, too, ie. without /RESET issued by the MX15002 chip, but instead doing some special SGB stuff: Uploading some code to SNES memory, and then executing that code on the SNES cpu (and that code does issue a /RESET to the gameboy cpu (via SNES port 6003h) and does restart the SNES (via jump to [FFFCh] on SNES side)).
In all three cases, for CMD_8xh/CXh, the final write to [013Fh] is done by code in the gameboy's High RAM at FF80h and up, followed by a short delay also executed in High RAM - that allows the MX15002 chip to read mapping info from the FLASH chip via databus without running into conflicts with the gameboy cpu's opcode fetches.

CMD_0Fh allows to write a single byte to FLASH memory. From the older posts, my impressions has been that it's needed only for writing to 5555h and 2AAAh, and that it's main purpose would be to access those two addresses regardless of the current ROM bank setting...
But, I seem to have been wrong on both. Using CMD_0Fh to write to 5555h is getting redirected to "RomBank*4000h+1555h", ie. the RomBank must be previously set via [2000h]=01h (or actually and ODD value written to [2xxxh] appears to be working).
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?

CMD_04h (Map Entire) does map the whole 1024Kbyte of FLASH memory, and CMD_05h (Map Menu) restores the normal mapping. The menu is using CMD_04h to "preview" the cartridge header of the different games (namely, checking header entry 143h via reading "Bank(N):4143h", if the byte is C0h=CGB only, then it's supposedly preventing to select that games on non-CGB consoles).
Theoretically, CMD_04h should be also nice for dumping the whole 1024Kbytes of FLASH memory. But somehow, I am having problems to get that working, CMD_04h is in fact mapping the MENU and GAME and unused sectors on my cart. But, it appears to be also causing the cart to return several FFh-filled 100h-byte blocks at random locations.
Am I doing something wrong, or is that happening to other people, too? And is there some way around it? My overall dumping code seems to be okay, ie. dumping only the MENU (without CMD_04h) does work without problems.

Oh, and reading ports 0120h..13Fh returns these values (when enabled via CMD_09h):

Code: Select all

  0120h         Fixed 21h
  0121h         Stat (bit0=/WP.step1, bit1=/WP.step2, bit2..7=Slot)
  0122h..0124h  Mapping (eg. A8,00,00 for MENU: MBC5 with 128K ROM at block 0, no SRAM)
  0125h         Fixed 87h
  0126h         Fixed 78h
  0127h         Unknown, varies (3Eh or FFh or 5Ah)
  0128h..013Eh  Fixed Zero
  013Fh         Fixed A5h
  4120h..413Fh  Mirror of above (but only in SOME rom banks?)
Whereas, when using CMD_04h (Map Entire), the mapping bytes at 0122h..0124h are changing to 9A,80,00 = Whole ("MBC4", 1024K ROM at block 0, whatever SRAM). Note that the 3bit mapper type is "4", which should probably mean "MBC4". The problem is that nobody seems to know how a "MBC4" is working, and there don't seem to be any gameboy titles known to be using a "MBC4" mapper - so maybe MBC4 didn't exist at all, or it did exist only as prototype. Anyways, maybe that "MBC4" mapping mode is causing the problems that I am having when trying to dump the whole 1024Kbytes.

Oh, and skaman, what did you mean by saying that the program uses CMD_CFh? The MENU program doesn't seem to use it... or did you mean mootan's tool using it... for dumping the whole 1024Kbytes?
The way how CMD_CFh is affecting the status bits at 0121h makes me think that it's just selecting "game 15" using the mapping data at hidden sector address 0Fh*3, which would be normally FFh-filled since the menu uses only entry 0..7. The FFh-filled values would probably map the biggest possible ROM size (ie. all 1024K), starting at the LAST 128K-block (and then wrap to the first block at higher ROM bank numbers), so CMD_CFh could be probably really used to dump the whole memory (when reordering the 128K blocks accordingly).
The only issue would be when the corresponding mapping bytes aren't FFh-filled (eg. the cartridges WITHOUT menu are having ASCII strings in that location, so one should avoid using CMD_CFh on such carts; instead one could just leave the default mapping mode for file 0, which should map all 1024Kbytes for menu-less single-game carts).
Last edited by nocash on Fri Jan 22, 2016 3:30 pm, edited 1 time in total.
skaman
Posts: 88
Joined: Fri Oct 24, 2014 1:56 am

Re: How to program a NINTENDO POWER Cartridge ?

Post by skaman »

Lots of good info to read.

Thanks for identifying the differences between the game selection modes. I tried 0x8xh and 0xCxh but couldn't get my GB cart reader switching between games like I can with my SF cart reader. I'll try to apply your findings to get this working. There's something satisfying about watching a cart switch between menu and the selected game while running on my cart reader.

Things make more sense after reading your notes and looking at the logic analyzer captures. The 2100, 01 (WR LOW) stuff prior to CMD_0Fh is in the logs that I typed out. viewtopic.php?f=12&t=11453&start=128

CMD_0Fh doesn't need to be called repeatedly to write bytes. I think it depends on the last flash command sent to the chip. The termination is generally a read of 0x0000 (waiting for 0x80) followed by a write of 0x3 to 0x0000. Or sometimes the program writes to 0x2100 again.

I couldn't get CMD_CFh to work on my cart reader but then again I couldn't get any game selections working. Mootan's program sends 0xCF when initializing the cart so I assumed it was setting up the cart to read the entire flash.

Great work!
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:CMD_0Fh doesn't need to be called repeatedly to write bytes. I think it depends on the last flash command sent to the chip. The termination is generally a read of 0x0000 (waiting for 0x80) followed by a write of 0x3 to 0x0000.
Thanks for confirming! And good to know that it's possible to write data directly. Allowing to do that must be related to the MX15002 chip (not to the MX29F080), ie. it must be enabled via some command written to [0120h] (not by writing anything to 5555h or 2AAAh).
Let's see, at the end of the viewtopic.php?f=12&t=11453&start=128 post, you've logged this:

Code: Select all

120, 0F (WR LOW)   ;\
125, 55 (WR LOW)   ;
126, 55 (WR LOW)   ; last byte of the FLASH write command
127, E0 (WR LOW)   ;
13F, A5 (WR LOW)   ;/

2100, 00 (WR LOW)  ;-bank select (still goes to MX15002, not to MX29F080)

120, 10 (WR LOW)   ;\whatever command (is that really needed here?)
13F, A5 (WR LOW)   ;/

120, 08 (WR LOW)   ;\"Undo Wakeup" command (disables I/O ports and maps ROM for READING, and, as following
13F, A5 (WR LOW)   ;/writes are going directly to FLASH, it does also seem to map ROM for direct WRITING)

0000, B4 (WR LOW) (NEW REGISTER FILE BEGINS)
0001, 00 (WR LOW)
0002, 00 (WR LOW)
0003, FF (WR LOW)
...
So CMD_08h seems to be the important part for activating direct ROM writes (and unlike the "normal" state, it should even disable the "standard" functions like writing [2000h]=RomBank). Maybe the difference between CMD_08h and CMD_0Ch is that the latter one does disable only port 0120h..013Fh, but keeps ports like 2000h working as usually? Gotta test that!

Anyways, going on with the bytes that were sent after the above logged stuff:

Code: Select all

...
007D, FF (WR LOW)
007E, 00 (WR LOW)
007F, 00 (WR LOW) (LAST BYTE OF FIRST HALF OF REGISTER)
007F, FF (WR LOW)

REPEAT 90X
0000, 00 (RD LOW)   ;\this is just waiting for status bit7=1=ready
0000, 03 (WR LOW)   ;/(dunno what the write [0000h]=03h could be good for, it looks like nonsense)

0000, 80 (RD LOW)   ;\as above, but now having reached status bit7=1=ready
0000, 03 (WR LOW)   ;/(again no idea, what the write could be good for)

120, 09 (WR LOW)   ;\
121, AA (WR LOW)   ; the "Wakeup" command, re-activating port 0120h..013Fh, and as it seems now,
122, 55 (WR LOW)   ; also reactivating ports like 2000h for bank selection
13F, A5 (WR LOW)   ;/
So the above CMD_09h seems to be terminating the direct-rom-write mode. However, in order to issue that command, one needs to write to 0120h..013Fh (which are apparently recognized by the MX15002 chip, but which are theoretically also still sent to the MX29F080 chip).
In so far, the special sequence "09,AA,55,A5" might be intended distinguish the command-write from normal FLASH data-writes (rather than being intended as secret "password" for preventing hackers to access the chip).
The chip might get confused when you try to program those 09,AA,55,A5 values to the corresponding FLASH memory addresses; but that should never happen in practice since those addresses are containing the Nintendo logo, which consists of different values.

And, before doing a write to the RomBank register, a few more commands are sent:

Code: Select all

120, 0A (WR LOW)   ;\
125, 62 (WR LOW)   ; release /WP step 1
126, 04 (WR LOW)   ;
13F, A5 (WR LOW)   ;/

120, 01 (WR LOW)   ;\whatever ???
13F, A5 (WR LOW)   ;/

120, 02 (WR LOW)   ;\release /WP step 2
13F, A5 (WR LOW)   ;/

2100, 01 (WR LOW)   ;-write RomBank, ie. port 2000h (and mirrors like 2100h) are now writeable again)
In the above part, CMD_0Ah and CMD_02h should be needed only if the cart has somehow forgetten the /WP state (which probably isn't the case, so I guess they aren't really needed here; the commands should have no effect on RomBank writes either).
And CMD_01h, I've no clue what that command is doing... theoretically it could be needed for reactivating RomBank writes (instead of, or additionally to CMD_09h).
Post Reply