NDS Cartridge ROM specs

Discussion of development of software for any "obsolete" computer or video game system.
nocash
Posts: 1366
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Cartridge ROM specs

Post by nocash » Tue Mar 23, 2021 3:06 pm

I've finished the specs for the nds infrared port and pedometers:
http://problemkaputt.de/gbatek-ds-cart- ... meters.htm
That was quite a huge project, the SPI commands for the infrared port have been quite harmless, but then I couldn't stop adding more and more specs for the infrared commands, instruction set, memory maps, accelerometer and lcd controller.

Maybe the hardest part were the P-walker IR commands, they were already documented on dmitry's webpage, but I couldn't make any sense of that table. I've spent several days on sorting and reformatting the table (like moving the word EEPROM to the begin of each line for EEPROM related commands), but that didn't really help on making it more legible.
I've finally spent some more days on disassembling the firmware myself and making two new separate tables from scratch up (one for incoming packets, and one for outgoing packets). I hope it's a bit more clear which commands/replies have what parameter bytes. The overall descriptions are ripped from dmitry's table - I didn't reverse-engineer everything from scratch up.

Alongsides, I've noticed a few things that appear to be wrong on dmitry's webpage:

Code: Select all

 Cmd 16h has 38h-byte data (not 34h-byte data)
 Cmd 40h,42h,44h are mis-numbered (and one of them is completely missing)
 Cmd 2Ah,2Ch are said to have incoming data for "RTC" (seems to be wrong?)
 Cmd 32h,40h,52h,60h are said to have incoming data for "RTC" (seems true?)
 Cmd WHAT is used to set RTC? (2Ah/2Ch don't? and 32h/etc are said to be unused)
 Elsewhere CMD_52 is said TO BE USED from nds, hence "dir=g2w", not "?2w"?
 Cmd F0h is marked as unknown/unused transfer direction, but also says from NDS
 struct EnrollData is missing the last byte (that says if/how to init LCD)
 struct EventBitmap might mean a boolean array (probably not bitmap graphics)?
 0x0172-0x017F unused does actually start at 0171h, not 0172h?
 does "0xCE88" (aka CE44h+4) really relate to "99999 steps reached"??? (looks more like 9999999 decimal?)
 the 16bit value "copied from unk_0" (32bit) probably means "unk_2" (16bit)
 small typos: fine=find, intead=instead, tmie=time
For the RTC, I am unsure what is used to set the RTC time, it sounds as if it's done using Cmd 52h, probably with a 32bit "seconds since 2001" value in the "Identity" data packet.
For reading the p-walker step counters, several data structures are containing "steps", but it isn't always clear which "steps since when" are meant, since today, since last sync, since forever? So it's still kinda unknown how to use which values for reading the step counters.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

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

Re: NDS Cartridge ROM specs

Post by nocash » Fri Mar 26, 2021 3:35 am

The display controller being SSD1854 isn't quite right. The firmware uses a 1-byte page select command (BYh), but SSD1854 is using a 2-byte command (B0h,YYh). There are a number of similar grayscale LCD chips, most of them having the correct 1-byte command:

Code: Select all

  SSD0852  128x128 would allow double-buffer, but extended commands are wrong
  SSD0858  104x65  close, but extended commands are wrong
  SSD0859  128x81  could be correct (almost same as SSD1850)
  SSD1820  128x65  wrong, lacks palette (command 88h-8Fh)
  SSD1820A 128x65  wrong, lacks palette (command 88h-8Fh)
  SSD1821  128x81  wrong, lacks palette (command 88h-8Fh)
  SSD1850  128x65  could be correct (ysiz is good, but no double-buffering)
  SSD1851  128x81  as above, but more lines than needed
  SSD1852  128x128 would allow double-buffer, but extended commands are wrong
  SSD1854  128x160 wrong, uses 2-byte command B0h,YYh lacks extended commands
                   (also cmd 18h,20h,4xh,50h,60h-63h,64h,82h,83h,etc. differ)
  SSD1858  104x65  close, but lacks many extended commands
  SSD1859  128x81  could be correct (almost same as SSD1850)
But, none of them is mentioning the extended 2-byte command F7h,02h. And none is mentioning VRAM double buffering (though one could probably abuse the 128-line SSD0852/SSD1852 chips for 64-line double buffering).
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

Arisotura
Posts: 25
Joined: Sun May 19, 2019 7:01 am

Re: NDS Cartridge ROM specs

Post by Arisotura » Tue Apr 27, 2021 8:02 am

if that's of interest: I reverse-engineered the NAND thing used in Jam with the Band (and WarioWare DIY, too, but the cart I had was JwtB)

basically:


basic info

the NAND save memory is probably the same memory as the ROM itself, but they can't be accessed at the same time -- there are mutually-exclusive modes for each.

the two halfwords in the ROM header at 0x94 and 0x96 specify where the ROM address space ends, and where the SRAM address space begins, in 128K units.

the SRAM space is 8MB for Jam with the Band, and 16MB for WarioWare DIY.

in the former, it's been observed that the last 128K block in SRAM space is read-only. it's all FF except for some ID data in the last 0x800 bytes. this is probably also the case in WarioWare, but I can't check now.


command 81

SRAM write.

the command is issued 4 times with the same address (seems to use the address from the first command). a full write is 0x800 bytes.

this command doesn't directly write to NAND, instead it stores the incoming data in a 0x800-byte write buffer (latter committed using command 82). things fuck up if the buffer isn't filled enough. not sure what happens if you overfill it.

the provided address needs to be within the access window specified by command B2.


command 82

commit SRAM write.

the data in the write buffer is written to the actual NAND, and the write-enable bit in the status register is cleared.


command 84

discard SRAM write.

the data in the write buffer is discarded. (a subsequent command 82 would have no effect)

games seem to always use this after a 82, so maybe it's required even after a write.


command 85

SRAM write enable.

the write-enable bit in the status register is set.

only works in SRAM access mode.


command 8B

switch to ROM access mode.


command B2

switch to SRAM access mode.

the provided address defines an accessible 128K window in SRAM address space, reads and writes may only take place within that window. the lower 17 bits of the address are ignored.

the window needs to be within SRAM address space. the NAND gets stuck permanently busy if the window address is lower than the start of the SRAM address space. addresses that go past the end of the SRAM address space will just read all FF's.


command B7

this command is used for reading data under both ROM and SRAM modes.

under ROM mode: returns data from the ROM space, pretty much like the 'regular' B7 command. trying to read from SRAM space in this mode will return all FF's.

under SRAM mode: returns data from the SRAM space. the provided address needs to be within the access window specified by command B2.


command D6

returns the NAND status register repeated over and over.

status register bits:
* bit4: write enable
* bit5: NAND status (0=busy, 1=ready)
* bit6: ??
* bit7: possible error flag?

value on startup is 0x20.

not sure what bit6 is supposed to be, seeing as DeSmuME sets that...


command 94

returns NAND ID data of sorts.

example from my Jam with the Band cart:

Code: Select all

EC F1 00 95 40 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 EC 00 9E A1 51 65 34 35
30 35 30 31 19 19 02 0A 00 00 00 00 00 00 00 00
(past that it's all FF's)

the 16 bytes at 0x18 are also found in the last 0x800 bytes of the SRAM space: (Jam with the Band checks these)

Code: Select all

EC 00 9E A1 51 65 34 35 30 35 30 31 19 19 02 0A 
00 00 00 00 6D D6 DA 9B B0 24 22 88 79 3B BF EA 
E6 AC 5E FA 69 12 0D 52 5D 5B F5 80 FF FF FF FF
not sure what all the data in either block is about.


side note

maybe there exists a cmd83 for write-disable? or cmd86?



process for writing data to the cart

1. set ROMCTRL appropriately (with WR bit set)
2. wait for DRQ flag to be set
3. write data word to 0x04100010
4. advance position, repeat from 2. until all data has been written

notes on this:

not sure how to differentiate between read and write commands? write commands need the WR bit set, but it seems it's also possible to read just fine with the WR bit set.

maybe KEY1 delays apply at the end of datablocks, in write mode? that would make sense. atleast I know they don't apply at the beginning.


-


I also tried to look into the Pokémon Typing Adventure cartridge thing, but the cart is being exceptionally uncooperative. like, any attempt at using it outside of its intended setting will result in it behaving erratically.

anyway, I opened the cart, and here are the contents:

* typical Macronix ROM
* STMicroelectronics M25PE10 SPI FLASH memory, presumably 128K
* Broadcom BCM2070 Bluetooth controller
* 26MHz crystal oscillator

the FLASH chip isn't connected directly to the cart-SPI bus, instead it's prolly accessed through the BT controller.

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

Re: NDS Cartridge ROM specs

Post by nocash » Wed Apr 28, 2021 6:34 pm

Cool, that's interesting, to know how it works, instead of just knowing that it does exist.

The header entries at 094h and 096h are both set to the same value? Is there a way to tell which value is which, 94h=End, 96h=Start, or vice-versa?
Are there more special header entries, like separate ROMCTRL timings for reading and writing?
SRAM doesn't sound quite right... how about "NAND" for the whole chip, and "ROM area" and "RW area" for the two memory regions?

I guess encryption is kept enabled for all commands, as for normal ROM reads. And if it's all the same memory, reading the RW area should have same timings as reading ROM area. If I got you right, three commands have address bits (in bit24-55 of the 64bit command value?) and four commands have additional data after the command, like this...

Code: Select all

  command 81aaaaaaaa000000h - NAND Write to Write Buffer        + Data[200h]
  command 8200000000000000h - NAND Forward Write Buffer to NAND
  command 8400000000000000h - NAND discard SRAM write
  command 8500000000000000h - NAND write enable
  command 8B00000000000000h - NAND switch to ROM access mode
  command B2aaaaaaaa000000h - NAND switch to RW access mode
  command B7aaaaaaaa000000h - NAND read from ROM or RW area     + Data[200h]
  command D600000000000000h - NAND read status                  + Data[4]
  command 9400000000000000h - NAND read ID                      + Data[200h]
For the status command, does it return a status-word, or status-byte (ie. 20202020h when reading four bytes)?

And its main purpose is polling the ready flag after writing? I am not sure which commands are sent in which order (with write enable before or after writing to write buffer), somehow like this?

Code: Select all

  command B2aaaaaaaa000000h - NAND switch to RW access mode (unlesss already)
  command 8500000000000000h - NAND write enable
  command 81aaaaaaaa000000h - NAND Write to Write Buffer        + Data[200h]
  command 81aaaaaaaa000000h - NAND Write to Write Buffer        + Data[200h]
  command 81aaaaaaaa000000h - NAND Write to Write Buffer        + Data[200h]
  command 81aaaaaaaa000000h - NAND Write to Write Buffer        + Data[200h]
  command 8200000000000000h - NAND Forward Write Buffer to NAND
  command D600000000000000h - NAND read status                  + Data[4]
  (...repeat reading status until ready...)
  command 8400000000000000h - NAND discard SRAM write
The addressing with the 20000h-byte access window and 800h-byte write buffer, which gets filled with four 200h-byte writes with same address is a bit confusing. Some of it might be related to the physical write/erase sector size (=seemingly 800h bytes)... whilst restricting writes (and even reads) to a 20000h-byte window, I couldn't imagine what that could be good for.
Looking at SD/MMC card writes: Those can be written in 200h-byte (or smaller) units, although the physical sector size is usually larger than that (and the carts can somehow group continous 200h-byte writes into a single 4000h-byte write/erase operation). Well, no idea if that applies here, too.

The ECh in the ID bytes looks a bit like the manufacturer ID byte in ROM chip ID (from command B8h), the following bytes could be anything, chip name, unique serial number, date codes, game id, whatever. Did you open the cartridge and check the part number on the chip? I guess there is only chip in there?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

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

Re: NDS Cartridge ROM specs

Post by nocash » Wed Apr 28, 2021 6:58 pm

PS. There seem to be three NAND carts (two for NDS, one for DSi), with these ROM chip IDs:

Code: Select all

  ECh,7Fh,00h,88h NDS Samsung  128MB NAND (eg. Warioware D.I.Y.)
  ECh,7Fh,01h,88h NDS Samsung? 128MB NAND+What? (eg. Jam with the Band, UXBP)
  ECh,7Fh,00h,E8h DSi Samsung? 128MB NAND (eg. Face Training, USKV)
I am still confused about the 01h in above ID (which would be usually found in IR carts, but maybe it's just meaningless).
The chip in the DSi cart might be a bit different (with separate NDS-mode ROM, and DSi-mode-only ROM areas, plus the read/write able area... though that part might be same as in the NDS carts).

I think nintendo has also made official flash carts for prototype testing... I wonder if those are accessed similarily.

Btw. DSi Launcher contains some code for command D6h (nand status, with 4-byte data), and B5h (whatever, with 0-byte data).

The dump of the last 800h-bytes...

Code: Select all

  EC 00 9E A1 51 65 34 35 30 35 30 31 19 19 02 0A
  00 00 00 00 6D D6 DA 9B B0 24 22 88 79 3B BF EA
  E6 AC 5E FA 69 12 0D 52 5D 5B F5 80 FF FF FF FF
Is that also followed by padding with FFh bytes?

Oh, and for emulating the chip... are the ID bytes from command 94h required to be emulated with "correct" values?
And for emulating the read/write-able area (and the last 800h-bytes): Do you know if there are ROM-dumping tools that are (or aren't) able to dump the whole 128byte ROM-image including those areas? (Don't know if the games insist on that area to be non-empty).
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

Arisotura
Posts: 25
Joined: Sun May 19, 2019 7:01 am

Re: NDS Cartridge ROM specs

Post by Arisotura » Thu Apr 29, 2021 2:08 pm

re: header 94/96

I don't recall which one is which, I'd have to make a new disassembly of JwtB or WWDIY to see which value they use when accessing savemem. the two values are identical in both games, so I guessed the first one would be the end of the ROM region.

that is also the case in Face Training. by the way the values there are quite small, that would make for quite a hefty savemem area (up to 64MB assuming they kept it power-of-two, up to 123MB otherwise). not sure what the size actually is.


re: DSi menu

would be interesting if that had code for interacting with a NAND, and if there's a cmd B5 that does something...


re: weird chip ID in Jam with the Band

prolly a mistake or smth? I don't see what would warrant it. atleast the cart doesn't contain any sort of IR hardware, and there's nothing besides the NAND chip.


re: last 0x800 bytes

these are FF-padded, yup.

btw I should make a tool that checks where that block is, or whether it exists it all, would also be useful in determine the actual savemem region size.


re: NAND command listing and order

you pretty much got that right. of course, might also want to use cmd 8B to revert to ROM mode after doing savemem accesses.

and, yup, when using command D6, every response word would be 0x20202020 for a status register of 0x20.


re: SRAM

yeah, referring to the memory type wouldn't be right, sorry for the confusion. I used the term SRAM because in melonDS terminology we used it as a shorthand for save RAM. I also believe that as far as the NAND is concerned, the ROM and save regions are part of the same memory.


re: NAND chip markings

I opened my Jam with the Band cart. the markings on the chip are:

Code: Select all

SAMSUNG 013
KLC2811UOC-P30A
NTR-UXBP-0
WKA069J2
nothing else of interest in the cart (just a couple bypass caps).

not sure if that says a lot.

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

Re: NDS Cartridge ROM specs

Post by nocash » Sat May 01, 2021 2:23 pm

Thanks for the chip part number! Hmmm, yeah, that doesn't exactly resemble any of the NAND ID bytes. But I just noticed that KLC2811 is same as in Warioware D.I.Y. (which has chip marked "SAMSUNG 004, KLC2811ANB-P204, NTR-UORE-0", and PCB name "DI X-7 C17-01"). Just for completeness: Do you have that same PCB name, too?

Hefty savemem in Face Training sounds about right, after all that's the main purpose of the NAND FLASH versus smaller SPI FLASH.
If you are unsure if the hdr[094h] entry is correct: It should be smaller than the total DSi ROM size in hdr[210h].
For detecting the whole NAND size, I think the size bits in the Chip ID should do it (ie. via command 90h), or when not having the physical cartridge, just trust the ROM-image size, hoping that it was fully dumped with correct size.

Btw. can you post or PM the cart headers for the NAND carts (just the first 200h bytes, or first 1000h bytes for the DSi Face Training cart). Would be nice to see how those look like... and especially the boot timings at hdr[60h], hdr[64h], hdr[6Eh]... I have currently documented them as:

Code: Select all

  hdr[60h]   hdr[64h]   hdr[6Eh]
  00586000h  001808F8h  051Eh     ;older/faster MROM
  00416657h  081808F8h  0D7Eh     ;newer/slower 1T-ROM
  ?          ?          ?         ;whatever NAND
DSi Launcher is using only two special commands (B5h and D6h) (plus the normal ROM cart commands, of course).
The special commands are used only if bit5 in 4th byte of Chip ID is set (aka test 20000000h). The bit is set in Face Training NAND cart, but not in the other NAND carts. The bit is also set in some ROM carts (eg. Walk with Me). The Launcher code does this:

Code: Select all

 if chip_id AND 20000000h
   get_nand_status(cmd_D6h)
   if (nand_status AND 0Ch)<>0                    ;whatever bits
     whatever(cmd_B5h)                            ;whatever command
    loop:
     get_nand_status(cmd_D6h)
     if (nand_status AND 20h)=0 then goto loop    ;wait for ready flag
The extra status bits and extra command might be unrelated to NAND, no idea what else they could be doing though.

The Launcher has separate functions for sending the above commands in encrypted or unencrypted form. I've tested the unencrypted cmd D6h variant with Walk with Me (right after cart reset, before even doing the secure area stuff). It's actually working in that game, and returns this:

Code: Select all

   with faster 6.7MHz clk: returns 20,20,20,20,20,20,3F,FF,FF
   with slower 4.2MHz clk: returns 20,20,20,20,20,3F,FF,FF,FF (or BF instead 3F)
Ie. it seems to be outputting the status in first four bytes, and then outputs open bus HighZ in further bytes (it's using 1T-ROM, which does also switch to HighZ after outputting the 4-byte Chip ID, instead of endlessly repeating the ID).
Well, and the status bit2-3 are initially zero on that cart, so the DSi Launcher wouldn't execute command B5h in that state.
Last edited by nocash on Mon May 03, 2021 4:11 pm, edited 1 time in total.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

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

Re: NDS Cartridge ROM specs

Post by nocash » Sat May 01, 2021 3:24 pm

Arisotura wrote:
Tue Apr 27, 2021 8:02 am
not sure how to differentiate between read and write commands? write commands need the WR bit set, but it seems it's also possible to read just fine with the WR bit set.
Are you sure? With the WR bit set (bit30 in Port 40001A4h), my data read function does just hang. It does receive one DRQ (bit23), but - in lack of handling the write-request in the read-function - it does never reach the transfer done state (bit31=0). My read function is manually polling the bits & data register, without using DMA.
Only exception is sending commands with "0-byte" data transfers, in that case the WR bit is actually ignored.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

Arisotura
Posts: 25
Joined: Sun May 19, 2019 7:01 am

Re: NDS Cartridge ROM specs

Post by Arisotura » Sun May 02, 2021 6:13 am

(having to log in again? what's the difference between checking 'remember me' and leaving it unchecked?)

I will get back to you about the ROM headers, for now I wanna address the 'reading data with WR bit set' thing

this issue we had in melonDS, was caused by a demo abusing that, basically it's reading its data with B7 commands, but ROMCTRL is set to 0xE97F3FFF.

the demo runs fine on actual hardware btw. the gist of the Github issue is that we hit a timing issue from erroneously applying the KEY1 delays when the WR bit suppresses them.

not sure if it works due to flashcarts being lenient, but I assume the WR bit thing would be enforced on the DS hardware side? the cart interface doesn't have any pin for explicitly specifying the I/O direction.

I also noticed that NO$GBA avoids that issue entirely because it maps the ROM in GBA ROM space (akin to some old linkers, I guess), which causes the demo to use a different codepath to load its data.

that's all weird.

EDIT-

it's even weirder that when I try to reproduce this, it, uh, freezes. weird shit. I need to disassemble that demo and look deeper.

okay, uh

two code paths use the ROMCNT value E79F3FFF, and the third possible codepath uses the more normal A97F3FFF. so, prolly, some emulation bug is just causing the demo to choose the wrong codepath.

well, that demo only really works thanks to DLDI patching -- if I remove the DLDI structure, it breaks, confirming my suspicion that its NitroFS driver is faulty. now I just gotta see why on melonDS it goes with that driver instead of DLDI, since melonDS patches in its own DLDI driver...

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

Re: NDS Cartridge ROM specs

Post by nocash » Mon May 03, 2021 5:48 pm

I thought DLDI is for loading data that isn't inside of the ROM-image... that could work only if your data actually isn't inside of the ROM-image. I haven't downloaded that huge 100MByte Bad Apple demo, but I guess it contains two versions; one with data inside of the ROM-image, one with external data for DLDI?

I think E79F3FFFh (or E97F3FFFh) won't work at all. And A97F3FFFh should work, but raises the loading time from 200h clks to 223Eh clks per 200h bytes, that's weirdly slow, although it might still work for video streaming, unless the compression ratio is crap.
Anyways, if that's all about driver bugs or emulation bugs... that does probably also ditch the theory that the WR bit suppresses gaps?

Yes, no$gba does map the ROM-image to both NDS and GBA cart slot, the latter was useful for ancient passme homebrews (and also useful for having a quick glance at the ROM-image in the debugger). I didn't consider that it could encourage people to keep using ancient passme drivers in newer homebrews (perhaps unintentionally bundled with bugged drivers for newer non-passme carts).

Now I am wondering if there's a bigger problem. I am more in favour of "real ROM-images" instead of "DLDI hacks with external files", but if the homebrew scene prefers to use DLDI, then I am now afraid that anybody who as ever released "real ROM-images" did only do so to "make it work in no$gba", without ever testing them on real hardware.

Or the other way around: Now I am wondering if the existing flashcarts do even support loading data from unpatched "real ROM-images" (or if they do only work by patching either Nintendo's loading functions, or homebrew DLDI functions).

---

At the moment I am trying to send encrypted D6h/B5h commands to the Walk with Me cartridge. The problem is that my test code is testing a bunch of uncommon things (like reading 1000h-byte data without 0-byte gap from commands that do usually return 4-byte data with 910h-byte gap), which, I think that simply doesn't work on 1T-ROM carts. So, for reacing the encrypted stage, I guess I'll have to write a new test function that avoids doing those uncommon things.

Btw. the 4 commands with 200h-byte data for writing 800h bytes of NAND, that does resemble the secure area loading on 1T-ROM carts (which do use 9 commands (one with 0-byte data and eight with 200h-byte data for loading 1000h bytes). Except, by that logic, I would have expected it to use 5 commands (one with 0-byte, and four with 200h-byte).

PS. remember me should usually work without needing to login. Unless the server (or your browser) does occassionally forget something. That normally happens only every some months though.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

tepples
Posts: 22361
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: NDS Cartridge ROM specs

Post by tepples » Mon May 03, 2021 10:05 pm

During the heyday of DS homebrew, ds.gba and .sc.nds were the common suffixes for PassMe ROMs, the latter used especially with the SLOT-2 SuperCard CF and SD adapters. Be careful with ds.gba, as the user would expect "Sounds.gba" to run as a GBA ROM. If you're automatically detecting these, I'd suggest requiring punctuation or punctuation followed by n before the ds.)

DLDI is useful for making a DS program that the user can mod after the fact with extra files, such as MP3 or Ogg files for a media player, WAD files for a source port of Id's Doom, or TXT files for reading Carroll's Alice's Adventures in Wonderland on Alice's birthday (4 May). It's also useful for running DS programs from GBA Movie Player, an adapter that eventually gained the feature to load a DS executable from the CF card and use DLDI to access other files, but which couldn't load ROMs with the Nitro file system. This limitation was a bit of virtue signaling against mass copyright infringement of commercial DS game ROMs, and it managed to keep GBA Movie Player available on eBay even while eBay was diligently taking down listings for SuperCard and M3.

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

Re: NDS Cartridge ROM specs

Post by nocash » Tue May 04, 2021 2:53 am

Got my test code working, and now I could test something new... NDS carts do somehow lock up after sending invalid commands, but on NDS hardware it was more or less impossible to test which commands are invalid (unless when rebooting or ejecting the cartridge after each command)... but the DSi can comfortably reset the cartridge via software, the reset isn't too fast, but good enough to test all 8bit command numbers in range 00h..FFh in a few seconds. And here they are, all valid command numbers:

Code: Select all

 Metroid First Hunt    B7 B8 D8
 Meine Tierarztpraxis  B7 B8 D8
 Nanostray             B7 B8 D8
 Over the Hedge        B7 B8 D8
 System Flaw (DSi)     B7 B8 F1
 Cooking Coach (DSi)   58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 B7 B8
 Walk with Me          69 6A 6B 6C B5 B7 B8 D6
That is, the command number was zeropadded (eg. B700000000000000h), executed with standard timings, with 0-byte data transfer, and, after executing that command, one could still read the 3rd chip ID (via cmd B8h).
The two DSi carts were tested in NDS mode, haven't checked if they support different commands when in DSi mode.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

Arisotura
Posts: 25
Joined: Sun May 19, 2019 7:01 am

Re: NDS Cartridge ROM specs

Post by Arisotura » Wed May 05, 2021 5:07 am

nocash wrote:
Mon May 03, 2021 5:48 pm
I thought DLDI is for loading data that isn't inside of the ROM-image... that could work only if your data actually isn't inside of the ROM-image. I haven't downloaded that huge 100MByte Bad Apple demo, but I guess it contains two versions; one with data inside of the ROM-image, one with external data for DLDI?
newer libnds supports embedding data in the ROM via NitroFS, and there seems to be atleast two ways of retrieving the data:

* NitroFS driver -- using standard B7 cart commands to read the ROM

* DLDI driver -- using DLDI to access the ROM file itself. this requires knowing the full path to the ROM file, which is passed via some argv structure.

the Bad Apple demo checks for that structure before using the DLDI driver. if it's not there, or if DLDI fails in any way, it will fall back to its broken NitroFS driver.

this is problematic in the case of melonDS as for now we rely on external DLDI SD images and can't guarantee the ROM file being loaded is contained within the image.


also re: undocumented ROM commands. that's interesting.

makes me wonder if these are related to factory-flashing the carts? like how pin 3 of the cart interface is of unknown function, connects to the cart's ROM chip, and is apparently not connected in the DS -- that pin might be used to program the carts. I don't think retail carts can be reprogrammed, but we should ask those who have dev hardware (dev flashcarts that can be reprogrammed, and matching dev-unit).

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

Re: NDS Cartridge ROM specs

Post by nocash » Wed May 05, 2021 2:13 pm

Tested a few more carts, and added the Chip ID values. The two 64Mbyte Macronix carts don't support any undocumented commands, all older carts from Macronix and Noname manufacturers seem to support command D8h.

Code: Select all

Metroid First Hunt    00000FC2  B7 B8 D8
Meine Tierarztpraxis  00000FAE  B7 B8 D8
Meine Tierpension     00000FC2  B7 B8 D8
Nanostray             00000FC2  B7 B8 D8
Over the Hedge        00001FC2  B7 B8 D8
Tony Hawk's Skateland 00003FC2  B7 B8
Ultimate Spiderman    00003FC2  B7 B8
System Flaw (DSi)     40001FC2  B7 B8 F1
Cooking Coach (DSi)   C0007FC2  58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 B7 B8
Walk with Me          E0013F80  69 6A 6B 6C B5 B7 B8 D6
And also tested the responses for those commands. Most seem to return just zeroes, or some kind of garbage, which might be just HighZ FFh's that got garbled during decryption.
I haven't tested that garbage replies with decryption disabled yet - if it's HighZ then the commands apparently don't send any reply data, but might expect incoming "write" data.
The all zeroes replies don't look too useful, though maybe they do reply something when adding nonzero parameter bits, or when executing several commands in sequence.

Code: Select all

58..5F --> cook: returns random junk? (unencrypted FFh's?)
60..68 --> cook: returns at least 4000h encrypted 00h bytes
69,6A,6B,6C --> walk: returns at least 4000h encrypted 00h bytes
B5 --> walk: returns random junk? (unencrypted FFh's?)
D6 --> walk: returns 20,20,20,20 then random junk (unencrypted FFh's?)
D8 --> returns at least 4000h encrypted 00h bytes
F1 --> returns E00h encrypted FFh bytes, then special data  ;repeats each 1000h
The only command that does clearly send some data is System Flaw's command F1h.

Code: Select all

system flaw cmd F1 response:
0000..0DFF  FF-filled
0E00        1E 40 05 5A FF FF 0D 01  32 68 38 7A 23 3F FF FF
0E10        03 0B 00 00 03 09 FF FF  FF FF FF FF FF FF FF FF
0E20        1E 40 05 03 0B 00 00 03  09 00 00 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
I can't spot any obvious meaning for that values. Value "5A" occurs thrice, and "1E 40 05" and "03 0B 00 00 03 09" occur twice.
Last edited by nocash on Thu May 06, 2021 2:48 am, edited 1 time in total.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

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

Re: NDS Cartridge ROM specs

Post by nocash » Thu May 06, 2021 2:44 am

Arisotura wrote:
Wed May 05, 2021 5:07 am
the Bad Apple demo checks for that structure before using the DLDI driver. if it's not there, or if DLDI fails in any way, it will fall back to its broken NitroFS driver.
Okay, that's confusing, but I got it.
The DLDI driver doesn't make too much sense in that case, except for people whom want to load from GBA slot (and are capable of providing that argv thing). I wouldn't go into supporting that. Or well, in no$gba, I seem to have (unintentionally) supported something similar, but without needing argv.
The NitroFS driver seems to be the more common intended case, and if that does set the WR bit and doesn't work, then it would be most accurate to emulate it exactly like that.

Retail titles seem to take the ROMCTRL timings from the cart header (and maybe also WR flag). If the Bad Apple demo is also doing that, then it might be more of a header issue (or feature) rather than a software bug. Theoretically it could even be an intended (but undocumented) feature:
If different flashcarts should happen to require different timings then it would make sense to read variable timing settings from the cart header, allowing the flashcart loader to fill in the required setting (but even then, releasing a demo with anything like E79F3FFFh as default setting is nonsense).

Apropos header, do you still have the headers for NAND carts?
Oh, and do you have a DSi console? I could upload the "search undocumented commands" tool for finding more commands on other carts, but it works on DSi only, not on classic NDS.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty

Post Reply