1 // Copyright 2010 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include "Core/HW/Sram.h"
6 
7 #include "Common/CommonTypes.h"
8 #include "Common/File.h"
9 #include "Common/Logging/Log.h"
10 #include "Common/Swap.h"
11 #include "Core/ConfigManager.h"
12 
13 // English
14 // This is just a template. Most/all fields are updated with sane(r) values at runtime.
15 // clang-format off
16 const Sram sram_dump = {Common::BigEndianValue<u32>{0},
17                         {Common::BigEndianValue<u16>{0x2c}, Common::BigEndianValue<u16>{0xffd0}, 0,
18                          0, 0, 0, 0, 0, {0x20 | SramFlags::kOobeDone | SramFlags::kStereo}},
19                         {{
20                              {'D', 'O', 'L', 'P', 'H', 'I', 'N', 'S', 'L', 'O', 'T', 'A'},
21                              {'D', 'O', 'L', 'P', 'H', 'I', 'N', 'S', 'L', 'O', 'T', 'B'},
22                          },
23                          0,
24                          {},
25                          0,
26                          0,
27                          {0x6E, 0x6D},
28                          0,
29                          {}}};
30 // clang-format on
31 
32 #if 0
33 // german
34 const SRAM sram_dump_german = {{
35 	0x1F, 0x66,
36 	0xE0, 0x96,
37 	0x00, 0x00, 0x00, 0x00,
38 	0x00, 0x00, 0x00, 0x00,
39 	0x04, 0xEA, 0x19, 0x40,
40 	0x00,
41 	0x00,
42 	0x01,
43 	0x3C,
44 	0x12, 0xD5, 0xEA, 0xD3, 0x00, 0xFA, 0x2D, 0x33, 0x13, 0x41, 0x26, 0x03,
45 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 	0x00, 0x00, 0x00, 0x00,
47 	0x00, 0x00,
48 	0x00, 0x00,
49 	0x00, 0x00,
50 	0x00, 0x00,
51 	0x00,
52 	0x00,
53 	0x84, 0xFF,
54 	0x00, 0x00,
55 	0x00, 0x00
56 }};
57 #endif
58 
InitSRAM()59 void InitSRAM()
60 {
61   File::IOFile file(SConfig::GetInstance().m_strSRAM, "rb");
62   if (file)
63   {
64     if (!file.ReadArray(&g_SRAM, 1))
65     {
66       ERROR_LOG(EXPANSIONINTERFACE, "EXI IPL-DEV: Could not read all of SRAM");
67       g_SRAM = sram_dump;
68     }
69   }
70   else
71   {
72     g_SRAM = sram_dump;
73   }
74 }
75 
SetCardFlashID(const u8 * buffer,u8 card_index)76 void SetCardFlashID(const u8* buffer, u8 card_index)
77 {
78   u64 rand = Common::swap64(&buffer[12]);
79   u8 csum = 0;
80   for (int i = 0; i < 12; i++)
81   {
82     rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16);
83     csum += g_SRAM.settings_ex.flash_id[card_index][i] = buffer[i] - ((u8)rand & 0xff);
84     rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16);
85     rand &= (u64)0x0000000000007fffULL;
86   }
87   g_SRAM.settings_ex.flash_id_checksum[card_index] = csum ^ 0xFF;
88 }
89 
FixSRAMChecksums()90 void FixSRAMChecksums()
91 {
92   // 16bit big-endian additive checksum
93   u16 checksum = 0;
94   u16 checksum_inv = 0;
95   for (auto p = reinterpret_cast<u16*>(&g_SRAM.settings.rtc_bias);
96        p != reinterpret_cast<u16*>(&g_SRAM.settings_ex); p++)
97   {
98     u16 value = Common::FromBigEndian(*p);
99     checksum += value;
100     checksum_inv += ~value;
101   }
102   g_SRAM.settings.checksum = checksum;
103   g_SRAM.settings.checksum_inv = checksum_inv;
104 }
105