User Tools

Site Tools


notes:flashcart:r4ds

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
notes:flashcart:r4ds [2023/10/15 06:21] 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.
  
 ==== Set FAT table entry (B4 sd sc sb sa 00 00 00) ==== ==== Set FAT table entry (B4 sd sc sb sa 00 00 00) ====
Line 40: Line 62:
 </code> </code>
  
-==== ROM read request (B6 ?? ?? ?? ?? ?? ?? ??) ====+==== ROM read request (B6 sd sc sb sa 00 00 00) ====
  
-Possibly works the same as SD read request, but in ROM space?+SD read request, but using the "ROM" FAT entry table.
  
-==== ROM read data (B7 ad ac ab aa ?? ?? ??) ====+Points to _DS_MENU.DAT on initialization.
  
-Possibly works the same as SD read data, but in ROM space?+==== ROM read data (B7 00 00 00 00 00 00 00) ====
  
-==== ? Reset ? (B8 ?? ?? ?? ?? ?? ?? ??) ====+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 54: 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 70: 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 ?? ?? ?? ?? ?? ?? ??) ====+==== Save write start (BD sd sc sb sa 00 00 00) ====
  
-Possibly works the same as SD write start, but in save data space?+SD write start, but using the "save" FAT entry table.
  
-==== Save write status (BE ?? ?? ?? ?? ?? ?? ??) ====+==== Save write status (BE sd sc sb sa 00 00 00) ====
  
-Possibly works the same as SD write status, but in save data space?+SD write status, but using the "save" FAT entry table.
  
-==== ROM read decrypted data (BF ?? ?? ?? ?? ?? ?? ??) ====+==== 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: 
 + 
 +<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; 
 + 
 +    // 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); 
 + 
 +    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; 
 + 
 +    key1 = newKey1; 
 +
 +</code>
notes/flashcart/r4ds.1697350904.txt.gz · Last modified: 2023/10/15 06:21 by asie