7
7
#include " common/flashcard.h"
8
8
#include " common/bootstrappaths.h"
9
9
#include " common/inifile.h"
10
+ #include " common/lzss.h"
10
11
#include " common/systemdetails.h"
12
+ #include " common/tonccpy.h"
11
13
#include " read_card.h"
12
14
13
15
/* TWL_CODE bool UpdateCardInfo(char* gameid, char* gamename) {
14
- cardReadHeader((uint8*)&ndsCardHeader);
15
16
memcpy(gameid, ndsCardHeader.gameCode, 4);
16
17
gameid[4] = 0x00;
17
18
memcpy(gamename, ndsCardHeader.gameTitle, 12);
@@ -23,6 +24,183 @@ TWL_CODE void ShowGameInfo(const char gameid[], const char gamename[]) {
23
24
iprintf("Game id: %s\nName: %s", gameid, gamename);
24
25
}*/
25
26
27
+ typedef signed int addr_t ;
28
+ typedef unsigned char data_t ;
29
+
30
+ #define FIX_ALL 0x01
31
+ #define FIX_GLUE 0x02
32
+ #define FIX_GOT 0x04
33
+ #define FIX_BSS 0x08
34
+
35
+ enum DldiOffsets {
36
+ DO_magicString = 0x00 , // "\xED\xA5\x8D\xBF Chishm"
37
+ DO_magicToken = 0x00 , // 0xBF8DA5ED
38
+ DO_magicShortString = 0x04 , // " Chishm"
39
+ DO_version = 0x0C ,
40
+ DO_driverSize = 0x0D ,
41
+ DO_fixSections = 0x0E ,
42
+ DO_allocatedSpace = 0x0F ,
43
+
44
+ DO_friendlyName = 0x10 ,
45
+
46
+ DO_text_start = 0x40 , // Data start
47
+ DO_data_end = 0x44 , // Data end
48
+ DO_glue_start = 0x48 , // Interworking glue start -- Needs address fixing
49
+ DO_glue_end = 0x4C , // Interworking glue end
50
+ DO_got_start = 0x50 , // GOT start -- Needs address fixing
51
+ DO_got_end = 0x54 , // GOT end
52
+ DO_bss_start = 0x58 , // bss start -- Needs setting to zero
53
+ DO_bss_end = 0x5C , // bss end
54
+
55
+ // IO_INTERFACE data
56
+ DO_ioType = 0x60 ,
57
+ DO_features = 0x64 ,
58
+ DO_startup = 0x68 ,
59
+ DO_isInserted = 0x6C ,
60
+ DO_readSectors = 0x70 ,
61
+ DO_writeSectors = 0x74 ,
62
+ DO_clearStatus = 0x78 ,
63
+ DO_shutdown = 0x7C ,
64
+ DO_code = 0x80
65
+ };
66
+
67
+ static addr_t readAddr (data_t *mem, addr_t offset) {
68
+ return ((addr_t *)mem)[offset/sizeof (addr_t )];
69
+ }
70
+
71
+ static void writeAddr (data_t *mem, addr_t offset, addr_t value) {
72
+ ((addr_t *)mem)[offset/sizeof (addr_t )] = value;
73
+ }
74
+
75
+ TWL_CODE static void dldiRelocateBinary (data_t *binData, size_t dldiFileSize)
76
+ {
77
+ addr_t memOffset; // Offset of DLDI after the file is loaded into memory
78
+ addr_t relocationOffset; // Value added to all offsets within the patch to fix it properly
79
+ addr_t ddmemOffset; // Original offset used in the DLDI file
80
+ addr_t ddmemStart; // Start of range that offsets can be in the DLDI file
81
+ addr_t ddmemEnd; // End of range that offsets can be in the DLDI file
82
+ addr_t ddmemSize; // Size of range that offsets can be in the DLDI file
83
+
84
+ addr_t addrIter;
85
+
86
+ data_t *pDH = binData;
87
+ data_t *pAH = (data_t *)(io_dldi_data);
88
+
89
+ // size_t dldiFileSize = 1 << pDH[DO_driverSize];
90
+
91
+ memOffset = readAddr (pAH, DO_text_start);
92
+ if (memOffset == 0 ) {
93
+ memOffset = readAddr (pAH, DO_startup) - DO_code;
94
+ }
95
+ ddmemOffset = readAddr (pDH, DO_text_start);
96
+ relocationOffset = memOffset - ddmemOffset;
97
+
98
+ ddmemStart = readAddr (pDH, DO_text_start);
99
+ ddmemSize = (1 << pDH[DO_driverSize]);
100
+ ddmemEnd = ddmemStart + ddmemSize;
101
+
102
+ // Remember how much space is actually reserved
103
+ pDH[DO_allocatedSpace] = pAH[DO_allocatedSpace];
104
+ // Copy the DLDI patch into the application
105
+ tonccpy (pAH, pDH, dldiFileSize);
106
+
107
+ // Fix the section pointers in the header
108
+ writeAddr (pAH, DO_text_start, readAddr (pAH, DO_text_start) + relocationOffset);
109
+ writeAddr (pAH, DO_data_end, readAddr (pAH, DO_data_end) + relocationOffset);
110
+ writeAddr (pAH, DO_glue_start, readAddr (pAH, DO_glue_start) + relocationOffset);
111
+ writeAddr (pAH, DO_glue_end, readAddr (pAH, DO_glue_end) + relocationOffset);
112
+ writeAddr (pAH, DO_got_start, readAddr (pAH, DO_got_start) + relocationOffset);
113
+ writeAddr (pAH, DO_got_end, readAddr (pAH, DO_got_end) + relocationOffset);
114
+ writeAddr (pAH, DO_bss_start, readAddr (pAH, DO_bss_start) + relocationOffset);
115
+ writeAddr (pAH, DO_bss_end, readAddr (pAH, DO_bss_end) + relocationOffset);
116
+ // Fix the function pointers in the header
117
+ writeAddr (pAH, DO_startup, readAddr (pAH, DO_startup) + relocationOffset);
118
+ writeAddr (pAH, DO_isInserted, readAddr (pAH, DO_isInserted) + relocationOffset);
119
+ writeAddr (pAH, DO_readSectors, readAddr (pAH, DO_readSectors) + relocationOffset);
120
+ writeAddr (pAH, DO_writeSectors, readAddr (pAH, DO_writeSectors) + relocationOffset);
121
+ writeAddr (pAH, DO_clearStatus, readAddr (pAH, DO_clearStatus) + relocationOffset);
122
+ writeAddr (pAH, DO_shutdown, readAddr (pAH, DO_shutdown) + relocationOffset);
123
+
124
+ if (pDH[DO_fixSections] & FIX_ALL) {
125
+ // Search through and fix pointers within the data section of the file
126
+ for (addrIter = (readAddr (pDH, DO_text_start) - ddmemStart); addrIter < (readAddr (pDH, DO_data_end) - ddmemStart); addrIter++) {
127
+ if ((ddmemStart <= readAddr (pAH, addrIter)) && (readAddr (pAH, addrIter) < ddmemEnd)) {
128
+ writeAddr (pAH, addrIter, readAddr (pAH, addrIter) + relocationOffset);
129
+ }
130
+ }
131
+ }
132
+
133
+ if (pDH[DO_fixSections] & FIX_GLUE) {
134
+ // Search through and fix pointers within the glue section of the file
135
+ for (addrIter = (readAddr (pDH, DO_glue_start) - ddmemStart); addrIter < (readAddr (pDH, DO_glue_end) - ddmemStart); addrIter++) {
136
+ if ((ddmemStart <= readAddr (pAH, addrIter)) && (readAddr (pAH, addrIter) < ddmemEnd)) {
137
+ writeAddr (pAH, addrIter, readAddr (pAH, addrIter) + relocationOffset);
138
+ }
139
+ }
140
+ }
141
+
142
+ if (pDH[DO_fixSections] & FIX_GOT) {
143
+ // Search through and fix pointers within the Global Offset Table section of the file
144
+ for (addrIter = (readAddr (pDH, DO_got_start) - ddmemStart); addrIter < (readAddr (pDH, DO_got_end) - ddmemStart); addrIter++) {
145
+ if ((ddmemStart <= readAddr (pAH, addrIter)) && (readAddr (pAH, addrIter) < ddmemEnd)) {
146
+ writeAddr (pAH, addrIter, readAddr (pAH, addrIter) + relocationOffset);
147
+ }
148
+ }
149
+ }
150
+
151
+ if (pDH[DO_fixSections] & FIX_BSS) {
152
+ // Initialise the BSS to 0
153
+ toncset (&pAH[readAddr (pDH, DO_bss_start) - ddmemStart] , 0 , readAddr (pDH, DO_bss_end) - readAddr (pDH, DO_bss_start));
154
+ }
155
+ }
156
+
157
+ TWL_CODE void myDldiLoadFromFile (const char * filename) {
158
+ extern bool extension (const std::string_view filename, const std::vector<std::string_view> extensions);
159
+
160
+ u32 * dldiAddr = new u32 [0x8000 /sizeof (u32 )];
161
+
162
+ FILE* file = fopen (filename, " rb" );
163
+ if (extension (filename, {" .lz77" })) {
164
+ fread ((void *)0x02FF8004 , 1 , 0x3FFC , file);
165
+
166
+ *(u32 *)0x02FF8000 = 0x53535A4C ;
167
+ LZ77_Decompress ((u8 *)0x02FF8004 , (u8 *)dldiAddr);
168
+ } else {
169
+ fread (dldiAddr, 1 , 0x8000 , file);
170
+ }
171
+ fclose (file);
172
+
173
+ // Check that it is a valid DLDI
174
+ if (!dldiIsValid ((DLDI_INTERFACE*)dldiAddr)) {
175
+ delete[] dldiAddr;
176
+ return ;
177
+ }
178
+
179
+ DLDI_INTERFACE* device = (DLDI_INTERFACE*)dldiAddr;
180
+ size_t dldiSize;
181
+
182
+ // Calculate actual size of DLDI
183
+ // Although the file may only go to the dldiEnd, the BSS section can extend past that
184
+ if (device->dldiEnd > device->bssEnd ) {
185
+ dldiSize = (char *)device->dldiEnd - (char *)device->dldiStart ;
186
+ } else {
187
+ dldiSize = (char *)device->bssEnd - (char *)device->dldiStart ;
188
+ }
189
+ dldiSize = (dldiSize + 0x03 ) & ~0x03 ; // Round up to nearest integer multiple
190
+
191
+ dldiRelocateBinary ((data_t *)dldiAddr, dldiSize);
192
+ delete[] dldiAddr;
193
+ }
194
+
195
+ TWL_CODE const DISC_INTERFACE *dldiGet (void ) {
196
+ if (io_dldi_data->ioInterface .features & FEATURE_SLOT_GBA)
197
+ sysSetCartOwner (BUS_OWNER_ARM9);
198
+ if (io_dldi_data->ioInterface .features & FEATURE_SLOT_NDS)
199
+ sysSetCardOwner (BUS_OWNER_ARM9);
200
+
201
+ return &io_dldi_data->ioInterface ;
202
+ }
203
+
26
204
TWL_CODE void twl_flashcardInit (void ) {
27
205
if (REG_SCFG_MC != 0x11 && !sys ().arm7SCFGLocked ()) {
28
206
// Reset Slot-1 to allow reading title name and ID
@@ -31,23 +209,19 @@ TWL_CODE void twl_flashcardInit(void) {
31
209
CIniFile settingsini ( DSIMENUPP_INI );
32
210
33
211
if (settingsini.GetInt (" SRLOADER" , " SECONDARY_ACCESS" , 0 ) == false ) {
212
+ disableSlot1 ();
34
213
return ;
35
214
}
36
215
37
216
// Read title name and ID
38
217
cardInit ();
39
218
40
- // char gamename[13];
41
- // char gameid[5];
219
+ /* char gamename[13];
220
+ char gameid[5];
42
221
43
- /* fifoSendValue32(FIFO_USER_04, 1);
44
- for (int i = 0; i < 10; i++) {
45
- swiWaitForVBlank();
46
- }
47
- memcpy(&nds, (void*)0x02000000, sizeof(nds));*/
48
- // UpdateCardInfo(&gameid[0], &gamename[0]);
222
+ UpdateCardInfo(&gameid[0], &gamename[0]);
49
223
50
- /* consoleDemoInit();
224
+ consoleDemoInit();
51
225
iprintf("REG_SCFG_MC: %x\n", REG_SCFG_MC);
52
226
ShowGameInfo(gameid, gamename);
53
227
@@ -72,8 +246,11 @@ TWL_CODE void twl_flashcardInit(void) {
72
246
fatMountSimple("fat", &io_dldi_data->ioInterface);
73
247
} else*/ if (!memcmp (ndsCardHeader.gameTitle , " QMATETRIAL" , 9 ) || !memcmp (ndsCardHeader.gameTitle , " R4DSULTRA" , 9 ) // R4iDSN/R4 Ultra
74
248
|| !memcmp (ndsCardHeader.gameCode , " ACEK" , 4 ) || !memcmp (ndsCardHeader.gameCode , " YCEP" , 4 ) || !memcmp (ndsCardHeader.gameCode , " AHZH" , 4 ) || !memcmp (ndsCardHeader.gameCode , " CHPJ" , 4 ) || !memcmp (ndsCardHeader.gameCode , " ADLP" , 4 )) { // Acekard 2(i)
75
- io_dldi_data = dldiLoadFromFile (" nitro:/dldi/ak2.dldi" );
76
- fatMountSimple (" fat" , &io_dldi_data->ioInterface );
249
+ myDldiLoadFromFile (" nitro:/dldi/ak2.dldi" );
250
+ fatMountSimple (" fat" , dldiGet ());
251
+ } else if (!memcmp (ndsCardHeader.gameCode , " DSGB" , 4 )) {
252
+ myDldiLoadFromFile (" nitro:/dldi/nrio.lz77" );
253
+ fatMountSimple (" fat" , dldiGet ());
77
254
} /* else if (!memcmp(ndsCardHeader.gameCode, "ALXX", 4)) {
78
255
io_dldi_data = dldiLoadFromFile("nitro:/dldi/dstwo.dldi");
79
256
fatMountSimple("fat", &io_dldi_data->ioInterface);
@@ -82,6 +259,7 @@ TWL_CODE void twl_flashcardInit(void) {
82
259
fatMountSimple("fat", &io_dldi_data->ioInterface);
83
260
} */
84
261
262
+ flashcardFoundReset ();
85
263
if (!flashcardFound ()) {
86
264
disableSlot1 ();
87
265
}
0 commit comments