notes:flashcart:r4ds
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
notes:flashcart:r4ds [2023/10/16 13:51] – asie | notes: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 |
===== Control flags ===== | ===== Control flags ===== | ||
Line 13: | Line 13: | ||
===== Commands ===== | ===== Commands ===== | ||
- | ==== Get card status (B0 ?? ?? ?? ?? ?? ?? ??) ==== | + | ==== Get card status (B0 00 00 00 00 00 00 00) ==== |
< | < | ||
31 | 31 | ||
- | ???? ???? ???? ???? ???? ???? ???? ?sss | + | ???? ???? ???? ???? ???? ???L LLml lsss |
- | | + | | |||| |||| |
- | | + | | |||| |+++- Initialization status: |
- | | + | | |||| | |
- | | + | | |||| | |
- | | + | | |||| | |
- | | + | | |||| | |
- | | + | | |||| | |
+ | | |||+-+---- Language: | ||
+ | | ||| 1 - Japanese | ||
+ | | ||| 2 - English | ||
+ | | ||| 3 - Chinese | ||
+ | | ||+------- Model: | ||
+ | | || 0 - M3DS Simply | ||
+ | | || 1 - R4 Revolution for DS | ||
+ | | ||
+ | | ||
+ | | ||
+ | 3:0? - Simplified Chinese | ||
+ | 3:1? - Traditional Chinese | ||
</ | </ | ||
- | ==== Save read request (B2 sd sc sb sa ?? ?? ??) ==== | + | ==== Save read request (B2 sd sc sb sa 00 00 00) ==== |
SD read request, but using the " | SD read request, but using the " | ||
- | ==== Save read data (B3 ?? ?? ?? ?? ?? ?? ??) ==== | + | ==== Save read data (B3 00 00 00 00 00 00 00) ==== |
SD read data, but using the " | SD read data, but using the " | ||
Line 51: | Line 62: | ||
</ | </ | ||
- | ==== ROM read request (B6 ?? ?? ?? ?? ?? ?? ??) ==== | + | ==== ROM read request (B6 sd sc sb sa 00 00 00) ==== |
SD read request, but using the " | SD read request, but using the " | ||
Line 57: | Line 68: | ||
Points to _DS_MENU.DAT on initialization. | Points to _DS_MENU.DAT on initialization. | ||
- | ==== ROM read data (B7 ad ac ab aa ?? ?? ??) ==== | + | ==== ROM read data (B7 00 00 00 00 00 00 00) ==== |
SD read data, but using the " | SD read data, but using the " | ||
- | ==== ? Get card ID ? (B8 ?? ?? ?? ?? ?? ?? ??) ==== | + | ==== Get card ID (B8 00 00 00 00 00 00 00) ==== |
+ | |||
+ | [[https:// | ||
+ | |||
+ | > Card ID commands are not patched and use the timings from the retail game ROM header, but without L1 latency (that' | ||
==== SD read request (B9 sd sc sb sa 00 00 00) ==== | ==== SD read request (B9 sd sc sb sa 00 00 00) ==== | ||
Line 67: | Line 82: | ||
* (MSB) sd sc sb sa (LSB) - sector address, in bytes | * (MSB) sd sc sb sa (LSB) - sector address, in bytes | ||
- | Returns | + | Returns |
==== SD read data (BA 00 00 00 00 00 00 00) ==== | ==== SD read data (BA 00 00 00 00 00 00 00) ==== | ||
Line 83: | Line 98: | ||
* (MSB) sd sc sb sa (LSB) - sector address, in bytes | * (MSB) sd sc sb sa (LSB) - sector address, in bytes | ||
- | Returns | + | Returns |
- | ==== Save write start (BD ?? ?? ?? ?? ?? ?? ??) ==== | + | ==== Save write start (BD sd sc sb sa 00 00 00) ==== |
SD write start, but using the " | SD write start, but using the " | ||
- | ==== Save write status (BE ?? ?? ?? ?? ?? ?? ??) ==== | + | ==== Save write status (BE sd sc sb sa 00 00 00) ==== |
SD write status, but using the " | SD write status, but using the " | ||
- | ==== 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' | Same as SD read data, but applying a XOR-based obfuscation algorithm to the buffer' | ||
Line 102: | Line 117: | ||
< | < | ||
- | | + | uint8_t[512] in; |
- | uint8_t[512] out; | + | uint8_t[512] out; |
- | uint16_t key1 = key ^ currentSector; | + | uint16_t key1 = key ^ currentSector; |
| | ||
- | | + | for (int i = 0; i < 512; i++) |
- | { | + | { |
- | // Derive key2 from key1. | + | // Derive key2 from key1. |
- | uint8_t key2 = ((key1 >> 7) & 0x80) | + | uint8_t key2 = ((key1 >> 7) & 0x80) |
- | | ((key1 >> 6) & 0x60) | + | | ((key1 >> 6) & 0x60) |
- | | ((key1 >> 5) & 0x10) | + | | ((key1 >> 5) & 0x10) |
- | | ((key1 >> 4) & 0x0C) | + | | ((key1 >> 4) & 0x0C) |
- | | (key1 & 0x03); | + | | (key1 & 0x03); |
| | ||
- | | + | |
- | dest[i] = src[i] ^ key2; | + | dest[i] = src[i] ^ key2; |
- | | + | |
- | uint16_t tmp = ((src[i] << 8) ^ key1); | + | uint16_t tmp = ((src[i] << 8) ^ key1); |
- | uint16_t tmpXor = 0; | + | uint16_t tmpXor = 0; |
- | for (int ii = 0; ii < 16; ii++) | + | for (int ii = 0; ii < 16; ii++) |
- | tmpXor ^= (tmp >> ii); | + | tmpXor ^= (tmp >> ii); |
- | | + | |
- | newKey1 |= ((tmpXor & 0x80) | (tmp & 0x7C)) << 8; | + | newKey1 |= ((tmpXor & 0x80) | (tmp & 0x7C)) << 8; |
- | newKey1 |= ((tmp ^ (tmpXor >> 14)) << 8) & 0x0300; | + | newKey1 |= ((tmp ^ (tmpXor >> 14)) << 8) & 0x0300; |
- | newKey1 |= (((tmp >> 1) ^ tmp) >> 6) & 0xFC; | + | newKey1 |= (((tmp >> 1) ^ tmp) >> 6) & 0xFC; |
- | newKey1 |= ((tmp ^ (tmpXor >> 1)) >> 8) & 0x03; | + | newKey1 |= ((tmp ^ (tmpXor >> 1)) >> 8) & 0x03; |
- | | + | |
- | } | + | |
} | } | ||
</ | </ |
notes/flashcart/r4ds.1697464278.txt.gz · Last modified: 2023/10/16 13:51 by asie