3DS Virtual Console: Difference between revisions
AuroraWright (talk | contribs) Add SNES VC documentation |
Fix confusion about CAA descriptor type |
||
(17 intermediate revisions by 8 users not shown) | |||
Line 3: | Line 3: | ||
=NES/GB/GBC VC= | =NES/GB/GBC VC= | ||
An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS). The emulator | An emulator application + VC ROM in the NCCH [[RomFS]] (among other things in the RomFS). | ||
The original emulator builds include support for all these three platforms, not specific to just the included ROM platform. However, releases intended for NES games have a red menu, optional switching between the two controllers, a different X button mapping (B instead of menu), optional [[Download Play]] support, and [http://s27.postimg.org/60v4yuw8z/IMG_20140921_001103.jpg a never used multi-rom support]; while Game Boy versions have a green theme and optional 3D border. | |||
Early builds (of Ambassador NES games at least) did not support savestates. | |||
The emulator officially used for Pokemon games removes savestate support in favor of a Link Cable "implementation" involving hooking the games' network functions according to the patch files. ([https://gbatemp.net/attachments/vc-wireless-link-patch-documentation-txt.72966/ Partial documentation of the patch format]) | |||
This emulator includes GBA support, however the GBA emulation for this this is somewhat slow. This was presumably implemented before AGB_FIRM was. | This emulator includes GBA support, however the GBA emulation for this this is somewhat slow. This was presumably implemented before AGB_FIRM was. | ||
Line 45: | Line 51: | ||
===data.bin structure=== | ===data.bin structure=== | ||
The file begins with a header (all values are little-endian): | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 98: | Line 104: | ||
| 0x30 | | 0x30 | ||
| 0x1 | | 0x1 | ||
| | | Emulation speed in FPS (always 0x3C in official VC) | ||
|- | |- | ||
| 0x31 | | 0x31 | ||
Line 110: | Line 116: | ||
| 0x35 | | 0x35 | ||
| 0x3 | | 0x3 | ||
| Size of the converted PCM audio samples region (starting after ROM). 0 | | Size of the converted PCM audio samples region (starting after ROM). 0 if PCM data is missing | ||
|- | |- | ||
| 0x38 | | 0x38 | ||
Line 118: | Line 124: | ||
| 0x39 | | 0x39 | ||
| 0x2 | | 0x2 | ||
| Footer region size | | Footer region size. 0 if PCM data is missing | ||
|- | |- | ||
| 0x3B | | 0x3B | ||
Line 126: | Line 132: | ||
| 0x3D | | 0x3D | ||
| 0x2 | | 0x2 | ||
| | | Preset ID (varies for each game). A full list of know Preset IDs (shared by WiiU/SNESC/Switch SNES emulators) can be found [https://docs.google.com/spreadsheets/d/1PbIPVA4NpFEXs1zk249aR3FSuBTY3r-ajpTq3dP3GnQ here] | ||
|- | |- | ||
| 0x3F | | 0x3F | ||
Line 158: | Line 164: | ||
The 0x60 header is followed by the SNES ROM, often altered to replace audio samples with pointers to external PCM audio files converted from the game, presumably to speed up emulation (these pointers can be found by looking for "PCMF" in the ROM, as seen on [https://github.com/Plombo/vcromclaim/blob/master/snesrestore.py Wii VC]). | The 0x60 header is followed by the SNES ROM, often altered to replace audio samples with pointers to external PCM audio files converted from the game, presumably to speed up emulation (these pointers can be found by looking for "PCMF" in the ROM, as seen on [https://github.com/Plombo/vcromclaim/blob/master/snesrestore.py Wii VC]). | ||
The ROM is then followed by the PCM audio files, | The ROM is then optionally followed by the PCM audio files, by the SDD-1 decompressed graphics data (the emulator doesn't properly emulate the chip, presumably because of hardware constraints) and by a footer which appears to be an index for the PCM audio data. | ||
There are no | There are no separate setting fields for individual cart features, and it appears that the emulator has "game presets" stored in its own code, which determine the game-specific settings (such as the expansion chip, and presumably the presence of SRAM), selectable via the preset ID in the header. Each official VC release has [https://docs.google.com/spreadsheets/d/1PbIPVA4NpFEXs1zk249aR3FSuBTY3r-ajpTq3dP3GnQ/edit#gid=490971147 a different preset ID]. The supported SNES expansion chips are: DSP1, C4 and DSP2. | ||
A similar structure can be found on the Wii U, SNES Classic and Switch Mini emulator [https://gist.github.com/anpage/c1085055db0242ea3c7558dab56712a5] | |||
==Savedata== | ==Savedata== | ||
The savedata | The savedata contains: | ||
* "KTR-XXXX.cfg": Appears to contain the "preset ID" and possibly more game/save information. | * "KTR-XXXX.cfg": Appears to contain the "preset ID" and possibly more game/save information. | ||
* "KTR-XXXX.vea": Current emulator save-state, for storing/loading state at VC-title launch/exit. | * "KTR-XXXX.vea": Current emulator save-state, for storing/loading state at VC-title launch/exit. | ||
Line 173: | Line 181: | ||
===Footer=== | ===Footer=== | ||
All values in the GBA VC footer are little-endian. | All values in the GBA VC footer and related structures are little-endian. | ||
{| class="wikitable" border="1" | |||
|- | |||
! START | |||
! SIZE | |||
! DESCRIPTION | |||
|- | |||
| 0x00 | |||
| 0x4 | |||
| Magic '.CAA' | |||
|- | |||
| 0x04 | |||
| 0x4 | |||
| Must be 1 | |||
|- | |||
| 0x08 | |||
| 0x4 | |||
| Offset to array of config descriptors | |||
|- | |||
| 0x0C | |||
| 0x4 | |||
| Number of config descriptors << 4 | |||
|} | |||
====Config descriptor==== | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 179: | Line 212: | ||
! SIZE | ! SIZE | ||
! DESCRIPTION | ! DESCRIPTION | ||
|- | |||
| 0x0 | |||
| 0x4 | |||
| Entry type. 0 is the ROM itself (without the CAA stuff) and offset must be 0 (otherwise fails w/ result 0xC900464F). 1 is ROM metadata, see below | |||
|- | |||
| 0x4 | |||
| 0x4 | |||
| Offset to entry data | |||
|- | |||
| 0x8 | |||
| 0x4 | |||
| Size of entry data (unused by the function that parses this, which hardcodes the config size (0x324) to memcpy for type 1) | |||
|- | |||
| 0xC | |||
| 0x4 | |||
| Padding | |||
|} | |||
====AGB ROM metadata==== | |||
{| class="wikitable" border="1" | |||
|- | |||
! START | |||
! SIZE | |||
! DESCRIPTION | |||
|- | |||
| 0x000 | |||
| 0x4 | |||
| Padding | |||
|- | |- | ||
| 0x004 | | 0x004 | ||
Line 186: | Line 248: | ||
| 0x008 | | 0x008 | ||
| 0x4 | | 0x4 | ||
| Save type (see below) | | Save type (see below for supported values and [[ARM7_Registers#ARM7_SAVE_MODE|here]] for details) | ||
|- | |||
| 0x00C | |||
| 0x2 | |||
| Padding (set to FF FF usually?) | |||
|- | |||
| 0x00E | |||
| 0x2 | |||
| Sleep mode button combo (utilizes the same bit masks as the [[HID_Registers#HID_PAD|HID_PAD register]], with flipped bits).<br/>If the GBA title supports a button-combo based sleep mode and it's set here, Agbbg spoofs this combo when closing the 3DS' lid to enter proper sleep mode. | |||
|- | |||
| 0x010 | |||
| 0x10 | |||
| Flash and EEPROM configuration (see the target registers [[ARM7_Registers|here]]) | |||
|- | |- | ||
| 0x020 | | 0x020 | ||
| 0x4 | | 0x4 | ||
| | | "Accumulated" interframe alpha blending (01-FF, lower values equal more "ghosting"). Uses previous *output* instead of previous input | ||
|- | |- | ||
| 0x024 | | 0x024 | ||
| 0x300 | | 0x300 | ||
| Video LUT (black to full, rgbrgbrgb...)?,<br/>three different types of this data have been observed. | | Video LUT (black to full, rgbrgbrgb...)?,<br/>three different types of this data have been observed. | ||
|} | |} | ||
Save types: | Save types: | ||
* 0x0: EEPROM 8k | * 0x0: EEPROM 8k for < 256 Mbit titles | ||
* 0x1: EEPROM 8k | * 0x1: EEPROM 8k for 256 Mbit titles | ||
* 0x2: EEPROM 64k | * 0x2: EEPROM 64k for < 256 Mbit titles | ||
* 0x3: EEPROM 64k | * 0x3: EEPROM 64k for 256 Mbit titles | ||
* 0x4: Flash 512k (Atmel, ID: 0x3D1F) + RTC | * 0x4: Flash 512k (Atmel, ID: 0x3D1F) + RTC | ||
* 0x5: Flash 512k (Atmel, ID: 0x3D1F) | * 0x5: Flash 512k (Atmel, ID: 0x3D1F) | ||
Line 228: | Line 286: | ||
* 0xC: Flash 1Mbit (Sanyo, ID: 0x1362) + RTC | * 0xC: Flash 1Mbit (Sanyo, ID: 0x1362) + RTC | ||
* 0xD: Flash 1Mbit (Sanyo, ID: 0x1362) | * 0xD: Flash 1Mbit (Sanyo, ID: 0x1362) | ||
* 0xE: SRAM/FRAM | * 0xE: SRAM/FRAM 256k | ||
Everything above 0xE results in no save chip and nothing being saved to NAND. | Everything above 0xE results in no save chip and nothing being saved to NAND. | ||
===NAND Savegame=== | ===NAND Savegame=== | ||
AGB_FIRM saves its active save memory to NAND on exit, this is then immediately picked up by NATIVE_FIRM on reboot by checking [[CONFIG_Registers#CFG_BOOTENV|CFG_BOOTENV]]. From there, this is verified and copied out to SD. The savegame format is as follows: | AGB_FIRM saves its active save memory to NAND on exit, this is then immediately picked up by NATIVE_FIRM on reboot by checking [[CONFIG_Registers#CFG_BOOTENV|CFG_BOOTENV]]. From there, this is verified and copied out to SD (also see below). The savegame format is as follows: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 297: | Line 355: | ||
| Always 0xFF | | Always 0xFF | ||
|} | |} | ||
===NAND Savegame on SD=== | |||
A NAND savegame copied to the SD by process9 is identical to its counterpart on the NAND partition, save for the CMAC. For SD copies on retail units, the CMAC is recalculated as the AES-CMAC of the (SHA256 hash of ("CTR-SIGN" + AGB TitleID (little endian) + SHA256 hash of ("CTR-SAV0" + SHA256 hash of (0x30..0x200 + the entire save itself)))), using keyslot 0x30 set up with the keyY from movable.sed. For SD copies on devkit units, the CMAC is recalculated using the SHA256 hash of 0x30..0x200 + the entire save itself, using a different key from process9 .rodata. |