1 | /* |
---|
2 | * Includes |
---|
3 | */ |
---|
4 | #include "ndstool.h" |
---|
5 | #include "crc.h" |
---|
6 | #include "passme_sram.h" |
---|
7 | |
---|
8 | /* |
---|
9 | * |
---|
10 | */ |
---|
11 | #define DS_RAM 0x02000000 |
---|
12 | #define RAM_SIZE (4*1024*1024) |
---|
13 | unsigned char *pc_ram; |
---|
14 | |
---|
15 | /* |
---|
16 | * Find |
---|
17 | */ |
---|
18 | template <typename T> unsigned long Find(FILE *f, const char *fmt, unsigned long begin, unsigned long end, T data, T mask, int thumb, int armnr) |
---|
19 | { |
---|
20 | for (unsigned long i=begin; i<end; i+=sizeof(T)) |
---|
21 | { |
---|
22 | T w = *(T *)(pc_ram + i - DS_RAM); |
---|
23 | w &= mask; |
---|
24 | if (w == data) |
---|
25 | { |
---|
26 | if (armnr == 7) |
---|
27 | header.arm7_entry_address = i + thumb; // ARM7 entry |
---|
28 | else |
---|
29 | header.arm9_entry_address = i + thumb; // ARM9 entry |
---|
30 | if (f) fprintf(f, fmt, i + thumb); |
---|
31 | printf(fmt, i + thumb); |
---|
32 | return i; |
---|
33 | } |
---|
34 | } |
---|
35 | return 0; |
---|
36 | } |
---|
37 | |
---|
38 | /* |
---|
39 | * PassMe |
---|
40 | */ |
---|
41 | int PassMe(char *ndsfilename, char *vhdfilename, char *sramfilename) |
---|
42 | { |
---|
43 | fNDS = fopen(ndsfilename, "rb"); |
---|
44 | if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); } |
---|
45 | |
---|
46 | FILE *fVHD = fopen(vhdfilename, "wt"); |
---|
47 | if (vhdfilename && !fVHD) { fprintf(stderr, "Cannot open file '%s'.\n", vhdfilename); exit(1); } |
---|
48 | |
---|
49 | fread(&header, 512, 1, fNDS); |
---|
50 | |
---|
51 | if (fVHD) |
---|
52 | { |
---|
53 | fprintf(fVHD, "-- PassMe generated CPLD code\n"); |
---|
54 | fprintf(fVHD, "-- Game code: \t"); for (unsigned int i=0; i<sizeof(header.gamecode); i++) fprintf(fVHD, "%c", header.gamecode[i]); fprintf(fVHD, "\n"); |
---|
55 | fprintf(fVHD, "-- ROM version: \t"); fprintf(fVHD, "%d\n", header.romversion); |
---|
56 | fprintf(fVHD, "-- Game title: \t"); for (unsigned int i=0; i<sizeof(header.title); i++) if (header.title[i]) fprintf(fVHD, "%c", header.title[i]); |
---|
57 | fprintf(fVHD, "\n\n"); |
---|
58 | } |
---|
59 | |
---|
60 | pc_ram = new unsigned char[RAM_SIZE]; |
---|
61 | |
---|
62 | // load ARM7 binary |
---|
63 | fseek(fNDS, header.arm7_rom_offset, SEEK_SET); |
---|
64 | fread(pc_ram + header.arm7_ram_address - DS_RAM, 1, header.arm7_size, fNDS); |
---|
65 | |
---|
66 | // load ARM9 binary |
---|
67 | fseek(fNDS, header.arm9_rom_offset, SEEK_SET); |
---|
68 | fread(pc_ram + header.arm9_ram_address - DS_RAM, 1, header.arm9_size, fNDS); |
---|
69 | |
---|
70 | |
---|
71 | header.arm7_entry_address = 0x55555555; |
---|
72 | header.arm9_entry_address = 0x55555555; |
---|
73 | |
---|
74 | |
---|
75 | unsigned char old_header[512]; |
---|
76 | memcpy(old_header, &header, 512); |
---|
77 | |
---|
78 | bool bError = false; |
---|
79 | |
---|
80 | unsigned int begin9 = 0x02000000, end9 = 0x02280000; |
---|
81 | //unsigned int begin9 = header.arm9_ram_address, end9 = header.arm9_ram_address + header.arm9_size; |
---|
82 | if (!Find<unsigned long>(fVHD, "-- BX LR @ 0x%08X\n", begin9, end9, 0xE120001E, 0xFFF000FF, 0, 9)) // BX LR |
---|
83 | // if (!Find<unsigned short>(fVHD, "-- BX LR @ 0x%08X\n", begin9, end9, 0x4770, 0xFFFF, 1, 9)) // BX LR |
---|
84 | { printf("BX LR instruction not found!\n"); bError = true; } |
---|
85 | |
---|
86 | unsigned int begin7 = 0x02000000, end7 = 0x023FE000; |
---|
87 | //unsigned int begin7 = header.arm7_ram_address, end7 = header.arm7_ram_address + header.arm7_size; |
---|
88 | // if (!Find<unsigned long>(fVHD, "-- SWI 0xAF @ 0x%08X\n", begin7, end7, 0xEFAF0000, 0xFFFF0000, 0, 7)) // SWI |
---|
89 | // if (!Find<unsigned long>(fVHD, "-- SWI 0xFF @ 0x%08X\n", begin7, end7, 0xEFFF0000, 0xFFFF0000, 0, 7)) // SWI |
---|
90 | // if (!Find<unsigned long>(fVHD, "-- SWI 0xA4 @ 0x%08X\n", begin7, end7, 0xEFA40000, 0xFFFF0000, 0, 7)) // SWI |
---|
91 | // if (!Find<unsigned long>(fVHD, "-- SWI 0xEA @ 0x%08X\n", begin7, end7, 0xEFEA0000, 0xFFFF0000, 0, 7)) // SWI |
---|
92 | if (!Find<unsigned short>(fVHD, "-- SWI 0xAF @ 0x%08X\n", begin7, end7, 0xDFAF, 0xFFFF, 1, 7)) // SWI |
---|
93 | if (!Find<unsigned short>(fVHD, "-- SWI 0xFF @ 0x%08X\n", begin7, end7, 0xDFFF, 0xFFFF, 1, 7)) // SWI |
---|
94 | if (!Find<unsigned short>(fVHD, "-- SWI 0xA4 @ 0x%08X\n", begin7, end7, 0xDFA4, 0xFFFF, 1, 7)) // SWI |
---|
95 | if (!Find<unsigned short>(fVHD, "-- SWI 0xEA @ 0x%08X\n", begin7, end7, 0xDFEA, 0xFFFF, 1, 7)) // SWI |
---|
96 | { printf("SWI instruction not found!\n"); bError = true; } |
---|
97 | |
---|
98 | //Find<unsigned long>("%08X\n", 0x037F8000, 0x0380F000, 0xEFEA0000, 0xFFFF0000, 0); // SWI |
---|
99 | //... |
---|
100 | |
---|
101 | //Find<unsigned short>("%08X\n", 0x037F8000, 0x0380F000, 0xDFA4, 0xFFFF, 1); // SWI |
---|
102 | //... |
---|
103 | |
---|
104 | if (bError) |
---|
105 | { |
---|
106 | printf("Cannot patch.\n"); |
---|
107 | return -1; |
---|
108 | } |
---|
109 | else |
---|
110 | { |
---|
111 | /* |
---|
112 | * VHD |
---|
113 | */ |
---|
114 | |
---|
115 | header.reserved2 |= 0x04; // set autostart bit |
---|
116 | |
---|
117 | bool forcepatch[512]; |
---|
118 | memset(forcepatch, 0, sizeof(forcepatch)); |
---|
119 | |
---|
120 | // ldr pc, 0x027FFE24 |
---|
121 | ((unsigned char *)&header)[0x4] = 0x18; |
---|
122 | ((unsigned char *)&header)[0x5] = 0xF0; |
---|
123 | ((unsigned char *)&header)[0x6] = 0x9F; |
---|
124 | ((unsigned char *)&header)[0x7] = 0xE5; |
---|
125 | |
---|
126 | header.header_crc = CalcCrc16((unsigned char *)&header, 0x15E); |
---|
127 | |
---|
128 | if (fVHD) fputs( |
---|
129 | #include "passme_vhd1.h" |
---|
130 | , fVHD |
---|
131 | ); |
---|
132 | |
---|
133 | for (int i=0; i<512; i++) |
---|
134 | { |
---|
135 | if (((unsigned char *)&header)[i] != old_header[i]) |
---|
136 | { |
---|
137 | printf("Patch:\t0x%03X\t0x%02X\n", i, ((unsigned char *)&header)[i]); |
---|
138 | if (fVHD) fprintf(fVHD, "\t\t\twhen 16#%03X# => patched_data <= X\"%02X\";\n", i, ((unsigned char *)&header)[i]); |
---|
139 | } |
---|
140 | } |
---|
141 | |
---|
142 | if (fVHD) fputs( |
---|
143 | #include "passme_vhd2.h" |
---|
144 | , fVHD |
---|
145 | ); |
---|
146 | |
---|
147 | if (fVHD) fclose(fVHD); |
---|
148 | |
---|
149 | /* |
---|
150 | * SRAM |
---|
151 | */ |
---|
152 | |
---|
153 | printf("ARM9 patched entry address: \t0x%08X\n", (unsigned int)header.arm9_entry_address); |
---|
154 | |
---|
155 | FILE *fSRAM = fopen(sramfilename, "wb"); |
---|
156 | if (sramfilename && !fSRAM) { fprintf(stderr, "Cannot open file '%s'.\n", sramfilename); exit(1); } |
---|
157 | if (fSRAM) |
---|
158 | { |
---|
159 | for (int i=0; i<passme_sram_size; i++) |
---|
160 | { |
---|
161 | unsigned char c = passme_sram[i]; |
---|
162 | // patch with address of ARM9 loop so it can be redirected by the code in SRAM. |
---|
163 | if ((i &~ 1) == 0x764) c = header.arm9_entry_address >> 0 & 0xFF; |
---|
164 | if ((i &~ 1) == 0x796) c = header.arm9_entry_address >> 8 & 0xFF; |
---|
165 | if ((i &~ 1) == 0x7C8) c = header.arm9_entry_address >> 16 & 0xFF; |
---|
166 | if ((i &~ 1) == 0x7FA) c = header.arm9_entry_address >> 24 & 0xFF; |
---|
167 | fputc(c, fSRAM); |
---|
168 | } |
---|
169 | fclose(fSRAM); |
---|
170 | } |
---|
171 | } |
---|
172 | |
---|
173 | fclose(fNDS); |
---|
174 | |
---|
175 | return 0; |
---|
176 | } |
---|