User Tools

Site Tools


notes:flashcart:r4ds

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
notes:flashcart:r4ds [2023/10/14 16:51] – created asienotes:flashcart:r4ds [2023/10/16 15:03] (current) asie
Line 1: Line 1:
 ====== R4 (NDS) programming ====== ====== R4 (NDS) programming ======
  
-Original research provided mostly by lifehackerhansol.+Original research provided mostly [[https://github.com/DS-Homebrew/DLDI/wiki/Original-R4-and-M3-Simply|by lifehackerhansol]].
  
 ===== Control flags ===== ===== Control flags =====
Line 13: Line 13:
 ===== Commands ===== ===== Commands =====
  
-==== Get card information (B0 ?? ?? ?? ?? ?? ?? ??) ====+==== Get card status (B0 00 00 00 00 00 00 00) ====
  
-If bit 0-2 are equal to 0x4, the card is an R4.+<code> 
 +31                 bit                 0 
 + ???? ???? ???? ???? ???? ???L LLml lsss 
 +                             | |||| |||| 
 +                             | |||| |+++Initialization status: 
 +                             | |||| |      0 - (in progress) 
 +                             | |||| |      1 - SD/TF card not found 
 +                             | |||| |      - SD/TF card read error 
 +                             | |||| |      3 - could not find _DS_MENU.DAT 
 +                             | |||| |      4 - success 
 +                             | |||+-+---- Language: 
 +                             | |||         1 - Japanese 
 +                             | |||         2 - English 
 +                             | |||         3 - Chinese 
 +                             | ||+------- Model: 
 +                             | ||          0 - M3DS Simply 
 +                             | ||          1 - R4 Revolution for DS 
 +                             +-++-------- Sub-language: 
 +                                           2: - French 
 +                                           2: - Korean 
 +                                           3:0? - Simplified Chinese 
 +                                           3:1? - Traditional Chinese 
 +</code>
  
-==== Save read request (B2 ?? ?? ?? ?? ?? ?? ??) ====+==== Save read request (B2 sd sc sb sa 00 00 00) ====
  
-Possibly works the same as SD read request, but in save data space?+SD read request, but using the "save" FAT entry table.
  
-==== Save read data (B3 ?? ?? ?? ?? ?? ?? ??) ====+==== Save read data (B3 00 00 00 00 00 00 00) ====
  
-Possibly works the same as SD read data, but in save data space?+SD read data, but using the "save" FAT entry table.
  
-==== FAT entry send ? (B4 sd sc sb sa 00 00 00) ====+==== Set FAT table entry (B4 sd sc sb sa 00 00 00) ====
  
-  * (MSB) sd sc sb sa (LSB) - sector address, in bytes+  * (MSB) sd sc sb sa (LSB) - as follows:
  
-==== ROM read request (B6 ?? ?? ?? ?? ?? ?? ??) ====+<code> 
 +31                 bit                 0 
 + ssss ssss ssss ssss ssss ssss sss? ???
 + |||| |||| |||| |||| |||| |||| |||     | 
 + |||| |||| |||| |||| |||| |||| |||     +- Type: 
 + |||| |||| |||| |||| |||| |||| |||         0 - ROM 
 + |||| |||| |||| |||| |||| |||| |||         1 - Save 
 + ++++-++++-++++-++++-++++-++++-+++------- Directory table address 
 +                                           (aligned to 0x20 per FAT spec) 
 +</code>
  
-Possibly works the same as SD read request, but in ROM space?+==== ROM read request (B6 sd sc sb sa 00 00 00) ====
  
-==== ROM read data (B7 ad ac ab aa ?? ?? ??) ====+SD read request, but using the "ROM" FAT entry table.
  
-Possibly works the same as SD read data, but in ROM space?+Points to _DS_MENU.DAT on initialization. 
 + 
 +==== ROM read data (B7 00 00 00 00 00 00 00) ==== 
 + 
 +SD read data, but using the "ROM" FAT entry table. 
 + 
 +==== Get card ID (B8 00 00 00 00 00 00 00) ==== 
 + 
 +[[https://github.com/DS-Homebrew/DLDI/wiki/Original-R4-and-M3-Simply#original-r4--m3-ds-simply|Quoting lifehackerhansol]]: 
 + 
 +> Card ID commands are not patched and use the timings from the retail game ROM header, but without L1 latency (that's what the SDK does). Those can be as fast as a single cycle of L2 latency, depending on the game.
  
 ==== SD read request (B9 sd sc sb sa 00 00 00) ==== ==== SD read request (B9 sd sc sb sa 00 00 00) ====
Line 41: Line 82:
   * (MSB) sd sc sb sa (LSB) - sector address, in bytes   * (MSB) sd sc sb sa (LSB) - sector address, in bytes
  
-Returns zero when data is ready to access, non-zero if ongoing.+Returns ''0x00000000'' when data is ready to access, ''0x00000001'' if ongoing.
  
 ==== SD read data (BA 00 00 00 00 00 00 00) ==== ==== SD read data (BA 00 00 00 00 00 00 00) ====
Line 57: Line 98:
   * (MSB) sd sc sb sa (LSB) - sector address, in bytes   * (MSB) sd sc sb sa (LSB) - sector address, in bytes
  
-Returns zero if donenon-zero if ongoing.+Returns ''0x00000000'' when data is ready to access''0x00000001'' if ongoing. 
 + 
 +==== Save write start (BD sd sc sb sa 00 00 00) ==== 
 + 
 +SD write start, but using the "save" FAT entry table. 
 + 
 +==== Save write status (BE sd sc sb sa 00 00 00) ==== 
 + 
 +SD write status, but using the "save" FAT entry table. 
 + 
 +==== ROM read decrypted data (BF 00 00 00 00 00 00 00) ==== 
 + 
 +Same as SD read data, but applying a XOR-based obfuscation algorithm to the buffer's contents. 
 + 
 +This is used by the stage 1 loader to decrypt _DS_MENU.DAT. 
 + 
 +The algorithm was initially discovered by Yasu in 2007, and example source code is provided as follows, where ''key'' is a 16-bit constant:
  
-==== Save write start (BD ?? ?? ?? ?? ?? ?? ??) ====+<code> 
 +uint8_t[512] in; 
 +uint8_t[512] out; 
 +uint16_t key1 key ^ currentSector; 
 +     
 +for (int i 0; i < 512; i++) 
 +
 +    // Derive key2 from key1. 
 +    uint8_t key2 = ((key1 >> 7& 0x80) 
 +        | ((key1 >> 6) & 0x60) 
 +        | ((key1 >> 5) & 0x10) 
 +        | ((key1 >> 4) & 0x0C) 
 +        | (key1 & 0x03); 
 +         
 +    // Decrypt byte. 
 +    dest[i] src[i] ^ key2;
  
-Possibly works the same as SD write start, but in save data space?+    // Derive next key1 from key2. 
 +    uint16_t tmp = ((src[i] << 8) ^ key1); 
 +    uint16_t tmpXor = 0; 
 +    for (int ii = 0; ii < 16; ii++) 
 +        tmpXor ^= (tmp >> ii);
  
-==== Save write status (BE ?? ?? ?? ?? ?? ?? ??) ====+    uint16_t newKey1 0; 
 +    newKey1 |((tmpXor & 0x80) | (tmp & 0x7C)) << 8; 
 +    newKey1 |((tmp ^ (tmpXor >> 14)) << 8) & 0x0300; 
 +    newKey1 |= (((tmp >> 1^ tmp) >> 6) & 0xFC; 
 +    newKey1 |((tmp ^ (tmpXor >> 1)) >> 8) & 0x03;
  
-Possibly works the same as SD write status, but in save data space?+    key1 = newKey1; 
 +
 +</code>
notes/flashcart/r4ds.1697302269.txt.gz · Last modified: 2023/10/14 16:51 by asie