Line |
Branch |
Exec |
Source |
1 |
|
|
#pragma once |
2 |
|
|
#include <vector> |
3 |
|
|
|
4 |
|
|
#include "errors.h" |
5 |
|
|
#include "autoarray.h" |
6 |
|
|
#include <cstdint> |
7 |
|
|
|
8 |
|
|
extern const unsigned char * romdata; |
9 |
|
|
extern int romlen; |
10 |
|
|
extern unsigned char default_freespacebyte; |
11 |
|
|
extern asar_error_id openromerror; |
12 |
|
|
bool openrom(const char * filename, bool confirm=true); |
13 |
|
|
uint32_t closerom(bool save = true); |
14 |
|
|
|
15 |
|
|
enum mapper_t { |
16 |
|
|
invalid_mapper, |
17 |
|
|
lorom, |
18 |
|
|
hirom, |
19 |
|
|
sa1rom, |
20 |
|
|
bigsa1rom, |
21 |
|
|
sfxrom, |
22 |
|
|
exlorom, |
23 |
|
|
exhirom, |
24 |
|
|
norom |
25 |
|
|
} extern mapper; |
26 |
|
|
|
27 |
|
|
extern int sa1banks[8];//only 0, 1, 4, 5 are used |
28 |
|
|
|
29 |
|
|
void addromwrite(int pcoffset, int numbytes); |
30 |
|
|
void writeromdata(int pcoffset, const void * indata, int numbytes); |
31 |
|
|
// optionally don't add the romwrite, because sometimes we did that in an earlier pass already |
32 |
|
|
// (or sometimes the bytes are just rom size padding) |
33 |
|
|
void writeromdata_byte(int pcoffset, unsigned char indata, bool add_write = true); |
34 |
|
|
void writeromdata_bytes(int pcoffset, unsigned char indata, int numbytes, bool add_write = true); |
35 |
|
|
|
36 |
|
|
struct writtenblockdata { |
37 |
|
|
int pcoffset; |
38 |
|
|
int snesoffset; |
39 |
|
|
int numbytes; |
40 |
|
|
}; |
41 |
|
|
|
42 |
|
|
extern autoarray<writtenblockdata> writtenblocks; |
43 |
|
|
extern std::vector<writtenblockdata> found_rats_tags; |
44 |
|
|
extern bool found_rats_tags_initialized; |
45 |
|
|
|
46 |
|
890981 |
inline int snestopc(int addr) |
47 |
|
|
{ |
48 |
3/4
✓ Branch 0 taken 889511 times.
✓ Branch 1 taken 1470 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 444900 times.
|
890981 |
if (addr<0 || addr>0xFFFFFF) return -1;//not 24bit |
49 |
2/2
✓ Branch 0 taken 881128 times.
✓ Branch 1 taken 8383 times.
|
889511 |
if (mapper==lorom) |
50 |
|
|
{ |
51 |
|
|
// randomdude999: The low pages ($0000-$7FFF) of banks 70-7D are used |
52 |
|
|
// for SRAM, the high pages are available for ROM data though |
53 |
1/2
✓ Branch 0 taken 881128 times.
✗ Branch 1 not taken.
|
881128 |
if ((addr&0xFE0000)==0x7E0000 ||//wram |
54 |
2/2
✓ Branch 0 taken 881116 times.
✓ Branch 1 taken 12 times.
|
881128 |
(addr&0x408000)==0x000000 ||//hardware regs, ram mirrors, other strange junk |
55 |
2/2
✓ Branch 0 taken 440456 times.
✓ Branch 1 taken 440660 times.
|
881116 |
(addr&0x708000)==0x700000)//sram (low parts of banks 70-7D) |
56 |
|
6 |
return -1; |
57 |
|
881116 |
addr=((addr&0x7F0000)>>1|(addr&0x7FFF)); |
58 |
|
881116 |
return addr; |
59 |
|
|
} |
60 |
2/2
✓ Branch 0 taken 1117 times.
✓ Branch 1 taken 3117 times.
|
4234 |
if (mapper==hirom) |
61 |
|
|
{ |
62 |
1/2
✓ Branch 0 taken 2212 times.
✗ Branch 1 not taken.
|
2212 |
if ((addr&0xFE0000)==0x7E0000 ||//wram |
63 |
2/2
✓ Branch 0 taken 1095 times.
✓ Branch 1 taken 1117 times.
|
2212 |
(addr&0x408000)==0x000000)//hardware regs, ram mirrors, other strange junk |
64 |
|
✗ |
return -1; |
65 |
|
2212 |
return addr&0x3FFFFF; |
66 |
|
|
} |
67 |
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 2203 times.
|
3117 |
if (mapper==exlorom) |
68 |
|
|
{ |
69 |
1/2
✓ Branch 0 taken 1818 times.
✗ Branch 1 not taken.
|
1818 |
if ((addr&0xF00000)==0x700000 ||//wram, sram |
70 |
2/2
✓ Branch 0 taken 904 times.
✓ Branch 1 taken 914 times.
|
1818 |
(addr&0x408000)==0x000000)//area that shouldn't be used in lorom |
71 |
|
✗ |
return -1; |
72 |
2/2
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 1362 times.
|
1818 |
if (addr&0x800000) |
73 |
|
|
{ |
74 |
|
456 |
addr=((addr&0x7F0000)>>1|(addr&0x7FFF)); |
75 |
|
|
} |
76 |
|
|
else |
77 |
|
|
{ |
78 |
|
1362 |
addr=((addr&0x7F0000)>>1|(addr&0x7FFF))+0x400000; |
79 |
|
|
} |
80 |
|
1818 |
return addr; |
81 |
|
|
} |
82 |
2/2
✓ Branch 0 taken 956 times.
✓ Branch 1 taken 1247 times.
|
2203 |
if (mapper==exhirom) |
83 |
|
|
{ |
84 |
1/2
✓ Branch 0 taken 1902 times.
✗ Branch 1 not taken.
|
1902 |
if ((addr&0xFE0000)==0x7E0000 ||//wram |
85 |
2/2
✓ Branch 0 taken 946 times.
✓ Branch 1 taken 956 times.
|
1902 |
(addr&0x408000)==0x000000)//hardware regs, ram mirrors, other strange junk |
86 |
|
✗ |
return -1; |
87 |
2/2
✓ Branch 0 taken 1368 times.
✓ Branch 1 taken 534 times.
|
1902 |
if ((addr&0x800000)==0x000000) return (addr&0x3FFFFF)|0x400000; |
88 |
|
534 |
return addr&0x3FFFFF; |
89 |
|
|
} |
90 |
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 1137 times.
|
1247 |
if (mapper==sfxrom) |
91 |
|
|
{ |
92 |
|
|
// Asar emulates GSU1, because apparently emulators don't support the extra ROM data from GSU2 |
93 |
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
|
210 |
if ((addr&0x600000)==0x600000 ||//wram, sram, open bus |
94 |
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
|
210 |
(addr&0x408000)==0x000000 ||//hardware regs, ram mirrors, rom mirrors, other strange junk |
95 |
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 110 times.
|
210 |
(addr&0x800000)==0x800000)//fastrom isn't valid either in superfx |
96 |
|
✗ |
return -1; |
97 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
|
210 |
if (addr&0x400000) return addr&0x3FFFFF; |
98 |
|
210 |
else return (addr&0x7F0000)>>1|(addr&0x7FFF); |
99 |
|
|
} |
100 |
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 907 times.
|
1137 |
if (mapper==sa1rom) |
101 |
|
|
{ |
102 |
1/2
✓ Branch 0 taken 450 times.
✗ Branch 1 not taken.
|
450 |
if ((addr&0x408000)==0x008000) |
103 |
|
|
{ |
104 |
|
450 |
return sa1banks[(addr&0xE00000)>>21]|((addr&0x1F0000)>>1)|(addr&0x007FFF); |
105 |
|
|
} |
106 |
|
✗ |
if ((addr&0xC00000)==0xC00000) |
107 |
|
|
{ |
108 |
|
✗ |
return sa1banks[((addr&0x100000)>>20)|((addr&0x200000)>>19)]|(addr&0x0FFFFF); |
109 |
|
|
} |
110 |
|
✗ |
return -1; |
111 |
|
|
} |
112 |
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 541 times.
|
907 |
if (mapper==bigsa1rom) |
113 |
|
|
{ |
114 |
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 386 times.
|
722 |
if ((addr&0xC00000)==0xC00000)//hirom |
115 |
|
|
{ |
116 |
|
336 |
return (addr&0x3FFFFF)|0x400000; |
117 |
|
|
} |
118 |
3/4
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 168 times.
✗ Branch 3 not taken.
|
386 |
if ((addr&0xC00000)==0x000000 || (addr&0xC00000)==0x800000)//lorom |
119 |
|
|
{ |
120 |
2/2
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 198 times.
|
386 |
if ((addr&0x008000)==0x000000) return -1; |
121 |
|
386 |
return (addr&0x800000)>>2 | (addr&0x3F0000)>>1 | (addr&0x7FFF); |
122 |
|
|
} |
123 |
|
✗ |
return -1; |
124 |
|
|
} |
125 |
1/2
✓ Branch 0 taken 541 times.
✗ Branch 1 not taken.
|
541 |
if (mapper==norom) |
126 |
|
|
{ |
127 |
|
1069 |
return addr; |
128 |
|
|
} |
129 |
|
✗ |
return -1; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
456457 |
inline int pctosnes(int addr) |
133 |
|
|
{ |
134 |
2/2
✓ Branch 0 taken 228163 times.
✓ Branch 1 taken 228294 times.
|
456457 |
if (addr<0) return -1; |
135 |
2/2
✓ Branch 0 taken 454012 times.
✓ Branch 1 taken 2445 times.
|
456457 |
if (mapper==lorom) |
136 |
|
|
{ |
137 |
2/2
✓ Branch 0 taken 226960 times.
✓ Branch 1 taken 227052 times.
|
454012 |
if (addr>=0x400000) return -1; |
138 |
|
454012 |
addr=((addr<<1)&0x7F0000)|(addr&0x7FFF)|0x8000; |
139 |
|
454012 |
return addr|0x800000; |
140 |
|
|
} |
141 |
2/2
✓ Branch 0 taken 345 times.
✓ Branch 1 taken 897 times.
|
1242 |
if (mapper==hirom) |
142 |
|
|
{ |
143 |
2/2
✓ Branch 0 taken 337 times.
✓ Branch 1 taken 345 times.
|
682 |
if (addr>=0x400000) return -1; |
144 |
|
682 |
return addr|0xC00000; |
145 |
|
|
} |
146 |
2/2
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 766 times.
|
897 |
if (mapper == exlorom) |
147 |
|
|
{ |
148 |
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 131 times.
|
257 |
if (addr>=0x800000) return -1; |
149 |
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 234 times.
|
257 |
if (addr&0x400000) |
150 |
|
|
{ |
151 |
|
23 |
addr-=0x400000; |
152 |
|
23 |
addr=((addr<<1)&0x7F0000)|(addr&0x7FFF)|0x8000; |
153 |
|
23 |
return addr; |
154 |
|
|
} |
155 |
|
|
else |
156 |
|
|
{ |
157 |
|
234 |
addr=((addr<<1)&0x7F0000)|(addr&0x7FFF)|0x8000; |
158 |
|
234 |
return addr|0x800000; |
159 |
|
|
} |
160 |
|
|
} |
161 |
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 617 times.
|
766 |
if (mapper == exhirom) |
162 |
|
|
{ |
163 |
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 149 times.
|
293 |
if (addr>=0x800000) return -1; |
164 |
2/2
✓ Branch 0 taken 149 times.
✓ Branch 1 taken 144 times.
|
293 |
if (addr&0x400000) return addr; |
165 |
|
270 |
return addr|0xC00000; |
166 |
|
|
} |
167 |
2/2
✓ Branch 0 taken 121 times.
✓ Branch 1 taken 496 times.
|
617 |
if (mapper==sa1rom) |
168 |
|
|
{ |
169 |
1/2
✓ Branch 0 taken 477 times.
✗ Branch 1 not taken.
|
477 |
for (int i=0;i<8;i++) |
170 |
|
|
{ |
171 |
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 240 times.
|
477 |
if (sa1banks[i]==(addr&0x700000)){ return 0x008000|(i<<21)|((addr&0x0F8000)<<1)|(addr&0x7FFF);} |
172 |
|
|
} |
173 |
|
✗ |
return -1; |
174 |
|
|
} |
175 |
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 337 times.
|
496 |
if (mapper==bigsa1rom) |
176 |
|
|
{ |
177 |
2/2
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 159 times.
|
313 |
if (addr>=0x800000) return -1; |
178 |
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 169 times.
|
313 |
if ((addr&0x400000)==0x400000) |
179 |
|
|
{ |
180 |
|
144 |
return addr|0xC00000; |
181 |
|
|
} |
182 |
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 72 times.
|
169 |
if ((addr&0x600000)==0x000000) |
183 |
|
|
{ |
184 |
|
97 |
return ((addr<<1)&0x3F0000)|0x8000|(addr&0x7FFF); |
185 |
|
|
} |
186 |
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
|
72 |
if ((addr&0x600000)==0x200000) |
187 |
|
|
{ |
188 |
|
72 |
return 0x800000|((addr<<1)&0x3F0000)|0x8000|(addr&0x7FFF); |
189 |
|
|
} |
190 |
|
✗ |
return -1; |
191 |
|
|
} |
192 |
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 261 times.
|
337 |
if (mapper==sfxrom) |
193 |
|
|
{ |
194 |
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 76 times.
|
147 |
if (addr>=0x200000) return -1; |
195 |
|
141 |
return ((addr<<1)&0x7F0000)|(addr&0x7FFF)|0x8000; |
196 |
|
|
} |
197 |
1/2
✓ Branch 0 taken 261 times.
✗ Branch 1 not taken.
|
261 |
if (mapper==norom) |
198 |
|
|
{ |
199 |
|
516 |
return addr; |
200 |
|
|
} |
201 |
|
✗ |
return -1; |
202 |
|
|
} |
203 |
|
|
|
204 |
|
|
int getpcfreespace(int size, int target_bank, bool autoexpand=true, bool respectbankborders=true, bool align=false, unsigned char freespacebyte=0x00, bool write_rats=true, int search_start=-1); |
205 |
|
|
int getsnesfreespace(int size, int target_bank, bool autoexpand=true, bool respectbankborders=true, bool align=false, unsigned char freespacebyte=0x00, bool write_rats=true, int search_start=-1); |
206 |
|
|
|
207 |
|
|
void removerats(int snesaddr, unsigned char clean_byte); |
208 |
|
|
void handle_cleared_rats_tags(); |
209 |
|
|
int ratsstart(int pcaddr); |
210 |
|
|
|
211 |
|
|
void fixchecksum(); |
212 |
|
|
|
213 |
|
|
void WalkMetadata(int loc, void(*func)(int loc, char * name, int len, const unsigned char * contents));//This one calls func() for each metadata block in the RATS tag whose contents (metadata) start at loc in the ROM. Do not replace name with an invalid metadata name, and note that name is not null terminated. |
214 |
|
|
|