NDS Cartridge ROM specs

Discussion of development of software for any "obsolete" computer or video game system.
Arisotura
Posts: 27
Joined: Sun May 19, 2019 7:01 am

Re: NDS Cartridge ROM specs

Post by Arisotura » Thu May 06, 2021 8:20 am

the Bad Apple demo uses hardcoded ROMCTRL values, not these in its ROM header (whatever these are).

re: headers for NAND carts

I can provide those, but I doubt they are of any use as far as NAND write commands are involved. as I understand, the values in the ROM header are only really useful for the BIOS/firmware when loading the cart. once the game is running it can pretty much use its own hardcoded settings.

anyway: header[0x60/0x64] for Jam with the Band are 0x00416657 and 0x081808F8, respectively. WarioWare DIY uses the same values. Face Training uses the same values too.

re: DLDI. I load things from the NDS cart slot, but with a slot-1 flashcart (it has a file menu and loads files from a MicroSD card). in this case, having both DLDI and NitroFS drivers makes sense. the loader, atleast on my flashcart, does fill in the argv structure.

nocash
Posts: 1396
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Fri May 07, 2021 5:51 am

Arisotura wrote:
Thu May 06, 2021 8:20 am
anyway: header[0x60/0x64] for Jam with the Band are 0x00416657 and 0x081808F8, respectively. WarioWare DIY uses the same values. Face Training uses the same values too.
Okay, that's same as in the 1T-ROM carts, then I guess the secure area delay in hdr[6Eh] is also same as for 1T-ROM?

I've found another DSi cartridge: Biggest Loser, with same chip ID as System Flaw, and also supporting command F1h:

Code: Select all

Biggest Loser cmd F1 response:
  0000..0DFF  FF-filled
  0E00        11 16 08 5A FF FF 0D 0B  39 7C 40 8E 2A 53 FF FF
  0E10        03 0A 07 05 05 04 00 00  07 00 7F FF 00 FF FF FF
  0E20        FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
  0E30        FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
  0E40        FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
  0E50        FF FF FF FF FF 5A FF 5E  FF FF FF FF FF FF 5A FF
  0E60        FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
  0E70        FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF
  0E80..0FFF  FF-filled
  1000..3FFF  mirrors of 0000-0FFF
The FF's and 5E and 5A's are there, too. But most of the other bytes are all different. I can't see a pattern which value have changed what for.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

nocash
Posts: 1396
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Wed Jun 09, 2021 7:51 am

I've got a cheap DSi cart with NAND (Face Training). The health and safety warnings in the instruction booklet are saying that I should consult my dentist (whomever that is) before using the cartridge. Ignoring that, I have cracked it open, the components are:

Code: Select all

  PCB "DI X-8 C17-01"
  U1 "SAMSUNG 031, KLC2811UOC-P309, TWL-USKV-0, WKE114(80?)"
The chip name is more or less same as for NDS carts, but with the TWL gamecode indicating additional support for DSi commands.

The timings in cart header are same as for 1T-ROM carts, including the hdr[6Eh] setting:

Code: Select all

  hdr[60h]   hdr[64h]   hdr[6Eh]
  00586000h  001808F8h  051Eh     ;older/faster MROM
  00416657h  081808F8h  0D7Eh     ;newer/slower 1T-ROM
  00416657h  081808F8h  0D7Eh     ;NAND carts
However, the cart requires an extra delay after power-up/reset, which isn't needed for any MROM or 1T-ROM carts. Without the delay, the chip ID response is 00000000h, and even after receiving nonzero IDs, it still takes a bit more time before one can read the cart header.

Searching undocumented commands is also a bit more difficult. Other carts are always surviving undoc commands (no matter of how many data bytes are transferred for the command). The Face Training cart survives only when transferring the correct expected number of data bytes. So far I have tested only 0 and 4 bytes, and detected these commands:

Code: Select all

 ;Face Training (DSi Nand) E9007FEC  B2 B5       - len=0
 ;Face Training (DSi Nand) E9007FEC  B0 B3 B8 D6 - len=4
Another issue is that the cart stops responding after certain commands (even though I am resetting the cart after each tested command) (for some reason it does resume working after rebooting by tapping the power button; which might envolve a longer delay or longer reset pulse).
Testing command 00h..FFh didn't reveal any supported commands. Testing FFh..00h (in that order) did reveal the above commands (B0, B2, B3,
B5, B8, D6).
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

nocash
Posts: 1396
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Wed Jun 09, 2021 12:25 pm

I've tried Face Training with all eight data length settings, and found commands aplenty:

Code: Select all

 ;Face Training (DSi Nand) E9007FEC  (58 59 5A 5B 5C 5D 5E 5F) B2 B5 - len=0
 ;Face Training (DSi Nand) E9007FEC  B0 B3 B8 D6                     - len=4
 ;Face Training (DSi Nand) E9007FEC  0B 0C 94 B7 BB                  - len=200h
 ;Face Training (DSi Nand) E9007FEC  -                               - len=400h
 ;Face Training (DSi Nand) E9007FEC  60 61 62 63 64 65 66 67 68      - len=800h
 ;Face Training (DSi Nand) E9007FEC  -                               - len=1000h
 ;Face Training (DSi Nand) E9007FEC  -                               - len=2000h
 ;Face Training (DSi Nand) E9007FEC  -                               - len=4000h
Using SCFG_MC to reset the cartridge does work after some commands, but some other commands do additinally require to completely power off the cart via SCFG_MC, otherwise the reset doesn't happen.
Without power-off and testing FFh..00h (backwards): My tool did not detect 0B, 0C, and 60-66.
Without power-off and testing 00h..FFh (forwards): My tool did detect only 0B, 0C, 67, 68.
So... it seems as if power-off is required after 67. And also after something in range 0C or 58-5F. Hmmm.

I haven't yet dumped the Face Training cart. With plain hardware tests, I couldn't yet find any traces of commands in range 80-8F. Did you debug or emulate Face Training and check if it's using commands 81,82,84,85,8B like the other NAND carts, too?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

nocash
Posts: 1396
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Fri Jun 11, 2021 1:22 am

There's another cartridge with special hardware:

Code: Select all

NTR-UNSJ - Japanese TV Tuner
Some huge cartridge with digital TV receiver.
Unknown if the "U" in the gamecode means that it contains NAND, too.
DSi Launcher sets BPTWL[21h].bit0=0 for this cartridge (unknown what for).
And, unrelated to above, the DSi Launcher seems to have some special code for reading a 200h-byte "extended header" from rom offset 3E00h (via command 00aaaaaaaa000000h, with aaaaaaaa=3E00h). After reading, it checks if the first 4 bytes are "TWLD", whatever that is good for. I don't know when it is reading that extended header though (presumably it's done only when some flag in cart header or chip id is set).

Dumping the Face Training cart isn't easy...

After releasing the cartridge reset signal, my power up function is doing a 1ms delay, but Face Training requires at least 19ms (Nintendo's insane default is 150ms).

Unlike as on all other DSi carts, reading the 1000h-byte DSi cart header via command 0000000000000000h doesn't work, instead it must be read in eight 200h-byte snippets via command 00aaaaaaaa000000h. The Launcher has some complex conditions for when to read 1x1000h bytes and when to read 8x200h byte snippets, I don't fully understand when it does what, but the general rule seems to be: 8x200h is used if it is a DSi cartridge AND chip id has bit31=1 (that would also apply for all DSi 1T-ROM carts, but those do also work when reading 1x1000h bytes, it seems to be required only for DSi NAND carts).

The chip id command, 9000000000000000h derails when trying to read more than 4 bytes (causing Face Training to reply garbage for following commands).

With that stuff sorted out, I can now read the 1st chip id, cart header, secure area, and intact 2nd and 3rd chip ids... But the main data reading via command B7aaaaaaaa000000h doesn't to work, it returns garbage (or reads from wrong address)... I have tried to use the full official delays/gaps, and to use only small 200h-byte block reads, but that didn't help : /
EDIT: Dumping is fully working now (I had just forgotten to implement inserting the DSi secure area in the current version of my dumping tool, the main data areas were fine, they just looked a bit weird because everything at offset 8000h and up is compressed somehow (and main data reads do work only with gap1 delays yet longer as in slow 1T-ROM carts)).
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

nocash
Posts: 1396
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Sat Jun 12, 2021 7:32 am

I think I have found most Face Training commands, it required some guessing how to use & unlock which commands because the auto-detection fails if the cart isn't in the correct mode (ROM or RW mode, and NDS or DSi mode), and also fails with wrong data length, and can behave differently on different address params).

Code: Select all

 ---- DSi NAND Face Training Commands ----
 In ROM access mode:
   94h          Len=200h    NAND Read ID
   B2h          Len=0       NAND Select 128Kbyte RW access mode
   B3h          Len=04h     Unknown
   BBh          Len=200h    Unknown
 In RW access mode (works only in DSi mode):
   81h          Len=200h    NAND Write to Write Buffer (must be issued 4x)
   82h          Len=0       NAND Forward Write Buffer to NAND
   84h          Len=0       NAND Discard Write Buffer
   85h          Len=0       NAND Write Enable
   86h          Len=0       Unknown
   87h          Len=0       Unknown
   8Bh          Len=0       NAND Select ROM access mode
 In either mode:
   0Bh..0Ch     Len=200h    Unknown
   58h..5Fh     Len=0       Unknown (looks same/similar as in 1T-ROM carts)
   60h..68h     Len=800h    Unknown (looks same/similar as in 1T-ROM carts)
   B0h          Len=04h     Unknown
   B5h          Len=0       Unknown (looks same/similar as in SanDisk carts)
   B7h          Len=200h    NAND Read from ROM or RW area
   B8h          Len=04h     Read Chip ID
   D6h          Len=04h     NAND Read Status
 Further command(s) spotted in disassembly:
   88h          Len=?       Unknown (is in disassembly, but fails on HW?)
Command B2h with address 2800000h crashes if the cart is in NDS mode (no problem since the camera based Face Training game is DSi-exclusive, but the chip couldn't be used in NDS+DSi hybrid games).
Command B2h with address 0000000h survives even when in NDS mode (but it's ignored, the cart stays in ROM access mode).
Command 81h must be issued 4 times (sending other commands won't work until all 4 commands are sent).
Command 8Bh/B2h do crash if the cart is already in the desired mode (so one must keep track of the current mode, or always return to ROM mode after RW access, or at least temporarily return to ROM mode before switching to a different RW window address).

The cart header isn't exactly what I had expected:

Code: Select all

  hdr[080h]=0174D800h  ;total size excluding dsi areas 0174D800h
  hdr[090h]=002Fh      ;end of nds area   ;mul80000h = 01780000h
  hdr[092h]=002Fh      ;start of dsi area ;mul80000h = 01780000h
  hdr[094h]=0050h      ;end of rom area   ;mul20000h = 02800000h (not mul20000h !!!)  ;=40Mbyte ROM
  hdr[096h]=0050h      ;start of rw area  ;mul80000h = 02800000h (not mul20000h !!!)  ;=88Mbyte RW
  hdr[210h]=01B0A000h  ;total size including dsi area  01B0A000h
Face Training is using "hdr[96h] shl 13h" to determine the start of the RW area, the shift amount (13h, aka mul 80000h, aka 512Kbyte) is hardcoded.
To detect the shift amount from the cart header... one could perhaps test the dsi flag in hdr[012h].bit1.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

nocash
Posts: 1396
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Sun Jun 13, 2021 3:08 pm

Timings
Today the 20ms delay after releasing reset isn't long enough, don't know why, maybe it's temperature related. With 30ms it's working again.

For ROM data reads, gap1=380h works only 99% stable, but it returns corrupt 200h-byte sectors at 00EC7200h and 018BAE00h. Dunno, maybe that two sectors do require error correction, making them slower to read? The reading is 100% stable with the official gap1=657h setting.

Also with gap1=380h, most of the RW area returns zeroes with a handful of nonzero junk values here and there. With gap1=657h most of the RW area is FFh-filled (which looks more plausible). Dunno either, maybe uninitialized FFh-filled sectors are slower to read?

Read ID
With command 94h, I am getting these bytes in Face Training:

Code: Select all

  000h  EC F1 00 95 40 00 00 00 00 00 00 00 00 00 00 00  ....@...........
  010h  00 00 00 00 00 00 00 00 EC 00 5A 36 5C 14 35 35  ..........Z6\.55
  020h  32 36 30 36 04 04 08 0A 00 00 00 00 00 00 00 00  2606............
  030h  00 00 00 .. (1D0h bytes)                         ................
Bytes 000h-017h are same as in the NDS NAND cart.
Bytes 018h-027h contain slightly different values.
Bytes 030h-1FFh are 00h-filled (unlike NDS cart not FFh-filled)

RW area
That has some non-FFh-filled bytes at 2800000h and up, then followed by a large FFh-filled chunk, and then some more non-FFh-filled bytes at 7A00200h.
Oddly including some ARM opcodes at 7FD5E40h and up.I haven't disassembled that it check if it's DS/DSi code, or if it's some kind of firmware code.
As far as I understand, the last 800h-bytes at 07FFF800h should contain some ID stuff, but that doesn't seem be the case here, especially I can't see a copy of the Byte 018h-027h from Read ID command in that location (nor anywhere else in the ROM or RW areas).

I am not sure about the capacity. Going by the Chip ID command reply it would be 128Mbyte. But if the chip supports broken sector replacement, or even stores error correction information, then there must be some memory reserved for that, leaving less user space.
If there's a reserved area, it might be at 027xxxxxh (before RW area) or 07Fxxxxxh (at end of RW area). Hmmm, maybe the write-protected last 128Kbytes at 07FE0000h are for that purpose, but on the other hand, 128Kbyte looks a bit small for that.

Ah, or did I misunderstand that... the last 128Kbyte of the RW area are at the end of 128MByte memory space, ie. at 07FE0000h, right?

EDIT: Tested writing several addresses in Face Training...

Code: Select all

 ; ldr r0,=0000000h // bl  nand_rw_test   ;crashes ;\
 ; ldr r0,=2000000h // bl  nand_rw_test   ;crashes ; ROM area (40 Mbytes)
 ; ldr r0,=27ff800h // bl  nand_rw_test   ;crashes ;/
   ldr r0,=2800000h // bl  nand_rw_test   ;works   ;\
   ldr r0,=4000000h // bl  nand_rw_test   ;works   ;
   ldr r0,=7800000h // bl  nand_rw_test   ;works   ; RW area  (66 Mbytes)
   ldr r0,=7900000h // bl  nand_rw_test   ;works   ;
   ldr r0,=79ff800h // bl  nand_rw_test   ;works   ;/
 ; ldr r0,=7a00000h // bl  nand_rw_test   ;crashes ;\
 ; ldr r0,=7b00000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7c00000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7e00000h // bl  nand_rw_test   ;crashes ; Reserved (22 Mbytes)
 ; ldr r0,=7f00000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7f80000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7fc0000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7fe0000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7fff000h // bl  nand_rw_test   ;crashes ;
 ; ldr r0,=7fff800h // bl  nand_rw_test   ;crashes ;/
The ones marked "crashes" causes the cart to stop responding to further commands when trying to write there.

I've dumped the cart after writing and compared it with the old rom-image, the written data is there... and the Reserved 22 Mbytes seems to be entirely different (it looks as if it might be just random, no actual stable legible data) (even if reading the Reserved area doesn't work, it seems quite likely that it does contain stuff for broken sector handling).

The Jam with Band cart doesn't anything resembled that reserved 22 Mbytes (apart from the non-writeable last 128Kbyte at 07FE0000h)?

Looking at the cart header & read Id commands, I can't see anything that would indicated the size of the RW area or Reserved area.

EDIT2: When trying to do "RW area reads" from the reserved area at 7A00000h and up...
It does contain the blowfish key (with the game code pre-applied), so that's definetely allowing to read some secret internal memory.
The ARM+THUMB code (also in the reserved area 7A00000h and up) is internal cartridge firmware code, but it looks slightly distorted: There are some STR opcodes writing to unaligned addresses, some undefined opcodes, some literal pool values containing nonsense (especially if the pool is in a different 200h-byte sector). It looks a bit as if the reading (or possible error correction) hasn't finished, that might also explain why the reserved area contains different data when dumping the cart multiple times.
Maybe it could be fixed with longer gap1 delays, or by dumping the code multiple times and trying to extract the "best" results, there are several backup copies of the code, so that could be merged to "best" results, too.

Note: More at the end of the reserved area at 7F00000h, there is some more ARM code, containing backup copies of the secure area (so that code block is unrelated to the internal firmware).

Unknown commands
Testing some of the unknown commands...

Code: Select all

   0Bh          Len=200h    Returns cart header[000h..1FFh] (requires gap1=657h, or some similar large value)
   0Ch          Len=200h    Returns corrupted cart header[1F8h..3F7h] ?? (corrupt even with very large gap1=1F00h)
   87h          Len=0       NAND Write Disable (or does it have MORE effects?)
   B0h          Len=04h     Unknown (returns 01010101h) (maybe another status byte?)
   B3h          Len=04h     Unknown (returns 00000000h)
   BBh          Len=200h    Unknown (returns 10 04 09 20 04, plus 1FBh zeroes) (maybe a BCD timestamp, yy mm dd hh mm?)
PS. Attached a copy of the Face Training cart header.
Yes, I am still looking for the cart headers from Jam with Band and Warioware DIY, please post them here somebody.
Attachments
FaceTrainingDSiCartHeaderEur.bin
(4 KiB) Downloaded 3 times
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

Post Reply