mirror of
https://github.com/flyinghead/flycast.git
synced 2026-11-10 10:01:28 -10:00
Compare commits
2259
Commits
fh/rec-doublefp
...
v2.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1f0a5a15f | ||
|
|
f640b32cc9 | ||
|
|
93e47dd410 | ||
|
|
8fb3def2d5 | ||
|
|
98a0f2b821 | ||
|
|
4fafa91506 | ||
|
|
09a1fea40f | ||
|
|
e55d70c0e6 | ||
|
|
ca45ff3834 | ||
|
|
35c71ebcfd | ||
|
|
33edcca348 | ||
|
|
dac5b991e0 | ||
|
|
8ba5e05421 | ||
|
|
35b7be3905 | ||
|
|
b7d923e02b | ||
|
|
eaf2c0064c | ||
|
|
a65cd9e5f9 | ||
|
|
e94b26f1df | ||
|
|
e96b38ff5c | ||
|
|
e894d4df5c | ||
|
|
c58ae4daac | ||
|
|
cb9af7d742 | ||
|
|
2a364dee67 | ||
|
|
56107b3667 | ||
|
|
31aab32d95 | ||
|
|
0b66409ed2 | ||
|
|
8ae288d2ca | ||
|
|
4419ff310a | ||
|
|
2f524923da | ||
|
|
07d761a880 | ||
|
|
f6f6637973 | ||
|
|
2cd3ffb33f | ||
|
|
abd9219347 | ||
|
|
417a42ae10 | ||
|
|
0e12153c45 | ||
|
|
cb33387ed6 | ||
|
|
38d4689b63 | ||
|
|
23d1db9c75 | ||
|
|
4e079b5d0b | ||
|
|
3fcbdd3fc5 | ||
|
|
78b44919c5 | ||
|
|
13a8d49c90 | ||
|
|
7308f9a704 | ||
|
|
18f9b84af6 | ||
|
|
56517b027a | ||
|
|
d4a02e3c2b | ||
|
|
33131e1395 | ||
|
|
73ac46f421 | ||
|
|
7fc70ee1f4 | ||
|
|
d9b5f27311 | ||
|
|
252838d896 | ||
|
|
cb91ad3ae0 | ||
|
|
60f3d718ac | ||
|
|
e8e382372a | ||
|
|
205c365b1b | ||
|
|
09857008bd | ||
|
|
5eddc26850 | ||
|
|
496429d6f4 | ||
|
|
a915f185f8 | ||
|
|
0f6e1752e3 | ||
|
|
e57ccde532 | ||
|
|
f75a16f40c | ||
|
|
a869e183db | ||
|
|
c60edb0090 | ||
|
|
84d82f360b | ||
|
|
b002bdff39 | ||
|
|
5ffcdb5f1e | ||
|
|
79bbd86c2f | ||
|
|
39a212140a | ||
|
|
dddd712f08 | ||
|
|
a7dbbbe578 | ||
|
|
2445739c0e | ||
|
|
403f1f635b | ||
|
|
879372cb79 | ||
|
|
6b05c0ab01 | ||
|
|
289f264371 | ||
|
|
869ddb643d | ||
|
|
c63f1a9997 | ||
|
|
0fc0dc5101 | ||
|
|
213bc70e2d | ||
|
|
c839bc89eb | ||
|
|
84f2871650 | ||
|
|
e1b4d4d703 | ||
|
|
b564b0bf91 | ||
|
|
7e1dcf9003 | ||
|
|
0f4c903fed | ||
|
|
0ac483acfc | ||
|
|
f4835a89d3 | ||
|
|
139f248572 | ||
|
|
b23d37f76f | ||
|
|
56358be542 | ||
|
|
1377e61d03 | ||
|
|
ce694ba8b5 | ||
|
|
8eae6b97fc | ||
|
|
d29645cc49 | ||
|
|
f870ccc23c | ||
|
|
3aa2f922e7 | ||
|
|
129fff1c2a | ||
|
|
10b13dfe9c | ||
|
|
d506cc40a2 | ||
|
|
358a54152b | ||
|
|
06e2c455e8 | ||
|
|
a1838eee30 | ||
|
|
56b082def7 | ||
|
|
92a10ba0f0 | ||
|
|
c637ae8281 | ||
|
|
40953b17c4 | ||
|
|
a473154250 | ||
|
|
13f3c3e228 | ||
|
|
817cc87c8c | ||
|
|
ab09efa762 | ||
|
|
7061c043d9 | ||
|
|
92a19e9250 | ||
|
|
4f5fd31d81 | ||
|
|
1b565f9879 | ||
|
|
d2b475ae41 | ||
|
|
9c61006941 | ||
|
|
4db26bc092 | ||
|
|
8c0f543bc8 | ||
|
|
8e3a48eb6f | ||
|
|
7a22318b0f | ||
|
|
a0bf24f7cc | ||
|
|
3c6eaa4d34 | ||
|
|
3bf817aea1 | ||
|
|
a3ebe02f85 | ||
|
|
4eda9ebffc | ||
|
|
278f26aadd | ||
|
|
17b82ab5d3 | ||
|
|
30e66d1c17 | ||
|
|
2089015221 | ||
|
|
e19a62aa07 | ||
|
|
42d003597e | ||
|
|
f9da57d87f | ||
|
|
daf8230cca | ||
|
|
f02265b662 | ||
|
|
5eb893a995 | ||
|
|
dfd517706a | ||
|
|
b47f4f56ef | ||
|
|
a870fb7f6c | ||
|
|
7cd308fcae | ||
|
|
6e6f75386b | ||
|
|
aad4921e09 | ||
|
|
8b8113b482 | ||
|
|
98acd1178d | ||
|
|
0070f9abad | ||
|
|
dca048981f | ||
|
|
74b98d85ed | ||
|
|
67a7637b9f | ||
|
|
2511a19d2d | ||
|
|
f04ddad94f | ||
|
|
b4e5af6346 | ||
|
|
f679fd9ba9 | ||
|
|
b6930a2a9e | ||
|
|
4db7137dbf | ||
|
|
bee534922b | ||
|
|
d6fe46649c | ||
|
|
236539c881 | ||
|
|
2644c2ef47 | ||
|
|
f590766421 | ||
|
|
fa1c62d11a | ||
|
|
ffc0a42c18 | ||
|
|
bc3c1ab628 | ||
|
|
6c249ee4d2 | ||
|
|
3330f01267 | ||
|
|
bd946bfbea | ||
|
|
bb92e9f7a4 | ||
|
|
63686eeee1 | ||
|
|
c0a286532a | ||
|
|
ce0354f294 | ||
|
|
231a1b624f | ||
|
|
9b8fd39d12 | ||
|
|
90c4e42c11 | ||
|
|
ee806bc035 | ||
|
|
d76611730e | ||
|
|
bdd677d66a | ||
|
|
2299c9fade | ||
|
|
885714e883 | ||
|
|
f95c7212bf | ||
|
|
bb0da9488f | ||
|
|
1aeacb0297 | ||
|
|
b92b7a3ece | ||
|
|
0a1fe0135f | ||
|
|
4391058563 | ||
|
|
ea9bdd03e4 | ||
|
|
ed99c96232 | ||
|
|
755e17dc97 | ||
|
|
76af42ae6e | ||
|
|
e94babe57e | ||
|
|
416e4c5366 | ||
|
|
6b9840268f | ||
|
|
415d8c2ea3 | ||
|
|
3f456c6738 | ||
|
|
59480ea5a6 | ||
|
|
920666bc70 | ||
|
|
eebcb322cf | ||
|
|
04b0489ff3 | ||
|
|
dd5f44ff91 | ||
|
|
a7b89ba06a | ||
|
|
e5344d37d0 | ||
|
|
c07f862ef2 | ||
|
|
8b0add47a2 | ||
|
|
fe9ce46ab1 | ||
|
|
01c5c98396 | ||
|
|
d00f07acb8 | ||
|
|
83bfa9158d | ||
|
|
ac2637286b | ||
|
|
541544292a | ||
|
|
97bd3fc082 | ||
|
|
71ce2a2415 | ||
|
|
4b0d377e66 | ||
|
|
ae2bc8182f | ||
|
|
d9ec14e048 | ||
|
|
c0f0a758df | ||
|
|
06270e66c8 | ||
|
|
75fe707de3 | ||
|
|
1a5a2f64d4 | ||
|
|
220fd51b27 | ||
|
|
29cdc77817 | ||
|
|
483c59f2e4 | ||
|
|
1fdab613fd | ||
|
|
539b9e7746 | ||
|
|
045f693eef | ||
|
|
3192f84576 | ||
|
|
27038d4cf9 | ||
|
|
4acb670b88 | ||
|
|
79b9b49218 | ||
|
|
5f161df06b | ||
|
|
fc3b9046d8 | ||
|
|
754d2a53a0 | ||
|
|
e913bae9e3 | ||
|
|
22d228c1b0 | ||
|
|
d3a3cab425 | ||
|
|
1fe7352ed0 | ||
|
|
9d1a5cf0d3 | ||
|
|
c8a45d95a7 | ||
|
|
92a1c1891b | ||
|
|
858174791f | ||
|
|
fb4e653269 | ||
|
|
210100a108 | ||
|
|
edd1487378 | ||
|
|
68f4ce1ec5 | ||
|
|
c3c355a8c5 | ||
|
|
70d3e221a9 | ||
|
|
b556617e1d | ||
|
|
e327172fd0 | ||
|
|
c5f82483e6 | ||
|
|
a418b05272 | ||
|
|
5c3f66fe05 | ||
|
|
81ce3f7d10 | ||
|
|
64cfba735e | ||
|
|
8828b4fe52 | ||
|
|
87fdd203b5 | ||
|
|
187674ddac | ||
|
|
f94a08f12f | ||
|
|
252ad711f1 | ||
|
|
9d6bfd4786 | ||
|
|
d3690b12c6 | ||
|
|
32e08ca165 | ||
|
|
bc4f8fbe60 | ||
|
|
fd3deeb318 | ||
|
|
7108358ebd | ||
|
|
98daea0e97 | ||
|
|
48acb03b81 | ||
|
|
08ac485eac | ||
|
|
c033a81eca | ||
|
|
5df9127add | ||
|
|
b9e9cc534c | ||
|
|
79be464326 | ||
|
|
f67aad0b2d | ||
|
|
55b36fe719 | ||
|
|
7cce77cccd | ||
|
|
170f794c3a | ||
|
|
ae4bd79ca1 | ||
|
|
d76982bbeb | ||
|
|
fb4229c4ae | ||
|
|
caec338d25 | ||
|
|
b94200233d | ||
|
|
eb3ebe24e8 | ||
|
|
4514a4bfcc | ||
|
|
5e4e48fffe | ||
|
|
47a33f97f9 | ||
|
|
b36ef9da1e | ||
|
|
068861d0cc | ||
|
|
f2f8f3ccd2 | ||
|
|
2d7a1ce71a | ||
|
|
74d72eb257 | ||
|
|
9512ee657a | ||
|
|
78f80eb7dc | ||
|
|
fa525b4488 | ||
|
|
ee3e83e09c | ||
|
|
ea4354ba2e | ||
|
|
5c5c872afc | ||
|
|
9f2ffd102c | ||
|
|
34f8941868 | ||
|
|
07b217d9f8 | ||
|
|
cb83d319b9 | ||
|
|
23daa3efdf | ||
|
|
3a1ffceb58 | ||
|
|
f3431bd95d | ||
|
|
01c7250be2 | ||
|
|
e6bc36e110 | ||
|
|
afc1f5f4e1 | ||
|
|
4a2ad8b145 | ||
|
|
17ab0aba26 | ||
|
|
cc1b45b7cc | ||
|
|
4d990947de | ||
|
|
5542d6db21 | ||
|
|
8ca89ead0e | ||
|
|
ebf5f24487 | ||
|
|
90269d5204 | ||
|
|
e4332f6275 | ||
|
|
cd7168772d | ||
|
|
77ded80450 | ||
|
|
fbc69b6ae1 | ||
|
|
ea7dd699b9 | ||
|
|
018a852995 | ||
|
|
8a28ddbfe6 | ||
|
|
f186046c98 | ||
|
|
5644e834fa | ||
|
|
0b1f69bfd2 | ||
|
|
4eb5cd928e | ||
|
|
b8d47fe0a8 | ||
|
|
abcd9d77d4 | ||
|
|
095e5ede81 | ||
|
|
52754cbbbb | ||
|
|
ea9d048bc9 | ||
|
|
942224c685 | ||
|
|
670a25b039 | ||
|
|
cab02c86bc | ||
|
|
b4a67460e0 | ||
|
|
b56750df30 | ||
|
|
aa5fd64777 | ||
|
|
5a13b4df28 | ||
|
|
67bba95dd1 | ||
|
|
cd6152b193 | ||
|
|
67c070c20f | ||
|
|
2355bb8bb5 | ||
|
|
c4d24254db | ||
|
|
27b6bafd0f | ||
|
|
9cbdcc6260 | ||
|
|
192bbb715e | ||
|
|
014da3a225 | ||
|
|
803f4cd298 | ||
|
|
885a0508c0 | ||
|
|
a1472fb190 | ||
|
|
b86df7217c | ||
|
|
26815d042a | ||
|
|
026f21eddf | ||
|
|
30501aebb1 | ||
|
|
4014b1b574 | ||
|
|
8d54382b10 | ||
|
|
47dd8241b6 | ||
|
|
195da2adcc | ||
|
|
2b430eec6f | ||
|
|
d51e36998b | ||
|
|
a970a1263c | ||
|
|
cf9ccea70b | ||
|
|
f885cbb4ea | ||
|
|
97dfabc416 | ||
|
|
8d2b0749a0 | ||
|
|
a3acf4a8cc | ||
|
|
e505ab6019 | ||
|
|
9b24984b07 | ||
|
|
7ce08ea860 | ||
|
|
a156edbd73 | ||
|
|
9dae5827cc | ||
|
|
5da799244f | ||
|
|
bf79183bd6 | ||
|
|
afcb3b7ad8 | ||
|
|
5bfbcb210c | ||
|
|
4f65d45e55 | ||
|
|
3f8ecfedbb | ||
|
|
d8137a967c | ||
|
|
ffec935e2f | ||
|
|
253301ba4f | ||
|
|
a21b79cfbe | ||
|
|
3f4c24d350 | ||
|
|
645f413523 | ||
|
|
08478aa757 | ||
|
|
4aef8667b7 | ||
|
|
9d08da1fc9 | ||
|
|
4408aa7dbe | ||
|
|
d2e8c9465b | ||
|
|
04df0da7cb | ||
|
|
5eeddecb40 | ||
|
|
71aea45811 | ||
|
|
cf690fbb61 | ||
|
|
85b286ec47 | ||
|
|
07d0cf6839 | ||
|
|
5e43b603ac | ||
|
|
69d2cfd56d | ||
|
|
0f90293252 | ||
|
|
0d166e1403 | ||
|
|
b5879e6e1d | ||
|
|
5b169b7f9d | ||
|
|
099a758c94 | ||
|
|
638e5d233a | ||
|
|
a23362cee0 | ||
|
|
040db856f8 | ||
|
|
8d0654c323 | ||
|
|
cacfdbad90 | ||
|
|
811bf6f449 | ||
|
|
43f8f3e4ad | ||
|
|
a045c52146 | ||
|
|
98531e07ea | ||
|
|
5020a267af | ||
|
|
debe21de7b | ||
|
|
084066bde7 | ||
|
|
46d7dfc750 | ||
|
|
37c17e4300 | ||
|
|
3a21f545d8 | ||
|
|
f35167a0de | ||
|
|
0b6c09da02 | ||
|
|
d9c08bd081 | ||
|
|
927db7f189 | ||
|
|
badf36899e | ||
|
|
d3aed076a6 | ||
|
|
962b0bb65c | ||
|
|
6e940e4d08 | ||
|
|
90e9f70a1a | ||
|
|
bfdab4db20 | ||
|
|
f0e4574132 | ||
|
|
c461624a67 | ||
|
|
e6060aff6b | ||
|
|
d1e6ee9cd7 | ||
|
|
6480a6e4e5 | ||
|
|
6cfbdf6586 | ||
|
|
6b2063b06f | ||
|
|
301a7c5dcd | ||
|
|
e70a0dcf3d | ||
|
|
d1ab3461a6 | ||
|
|
b81a6762bc | ||
|
|
5875eda4d0 | ||
|
|
04c418d02a | ||
|
|
02a002d55b | ||
|
|
0305904873 | ||
|
|
ee84567c17 | ||
|
|
528235ce9d | ||
|
|
27ea6ca092 | ||
|
|
cb94354099 | ||
|
|
53dab29ddb | ||
|
|
b1479e6e34 | ||
|
|
ea3262f7b0 | ||
|
|
143073b61d | ||
|
|
c472d60f80 | ||
|
|
0c01075ba8 | ||
|
|
1149d499a8 | ||
|
|
85a941d6c6 | ||
|
|
0a27b63584 | ||
|
|
6f5f91245b | ||
|
|
234955ac01 | ||
|
|
99d5266aa0 | ||
|
|
a5967a283f | ||
|
|
21a4935ec4 | ||
|
|
610e3cf968 | ||
|
|
45c9d6185b | ||
|
|
e18a4afcbb | ||
|
|
499f86b065 | ||
|
|
80cf4406a7 | ||
|
|
cc4e3875f3 | ||
|
|
1c4871acb3 | ||
|
|
3b683648fa | ||
|
|
3923f10277 | ||
|
|
1a681746b5 | ||
|
|
5703ef26cf | ||
|
|
5096d50d37 | ||
|
|
f7e227a4aa | ||
|
|
bbff377ceb | ||
|
|
f8372c51a7 | ||
|
|
31debefbe1 | ||
|
|
c7d214e55a | ||
|
|
e3e2c3a0d2 | ||
|
|
f96ce85365 | ||
|
|
aa79196d38 | ||
|
|
2b14c3e605 | ||
|
|
41ba110ef4 | ||
|
|
ad42a32260 | ||
|
|
cc408f9688 | ||
|
|
520e96a039 | ||
|
|
db9fbbaebf | ||
|
|
88384ad7d1 | ||
|
|
464b459073 | ||
|
|
aea228c3df | ||
|
|
8cdd171ab7 | ||
|
|
9473c235f2 | ||
|
|
b443467770 | ||
|
|
a6bf9dd39c | ||
|
|
8fdcea2e20 | ||
|
|
31bd943d67 | ||
|
|
ba78a3aa5b | ||
|
|
1948c66c11 | ||
|
|
3cf7cf0a7f | ||
|
|
a593cddf52 | ||
|
|
cecf16e65e | ||
|
|
458b233e16 | ||
|
|
cca7ed6bf7 | ||
|
|
f63cf7406a | ||
|
|
e21d666328 | ||
|
|
ab3f5dbc4c | ||
|
|
528f15f117 | ||
|
|
7c72aa8a80 | ||
|
|
2420c05930 | ||
|
|
3a312f3814 | ||
|
|
bac67bd91a | ||
|
|
36e67203a4 | ||
|
|
a52d1c97ec | ||
|
|
9d3125c546 | ||
|
|
86a6d7a4f5 | ||
|
|
0f214b1441 | ||
|
|
a0b50cd41d | ||
|
|
1d1754dc98 | ||
|
|
b8464ef6c5 | ||
|
|
692ca52182 | ||
|
|
b4ecaecd45 | ||
|
|
9954768636 | ||
|
|
cbffc5cade | ||
|
|
4bbf5c562e | ||
|
|
329e5ed467 | ||
|
|
19a160695c | ||
|
|
1e195b7237 | ||
|
|
2b37a5dc08 | ||
|
|
8aadf5b097 | ||
|
|
13428ba696 | ||
|
|
52f2ca7ff6 | ||
|
|
174ce8786b | ||
|
|
fc118f295d | ||
|
|
18cfe2f92f | ||
|
|
0d4a7dbac9 | ||
|
|
a370851494 | ||
|
|
7b49cc73ee | ||
|
|
a8c5af8425 | ||
|
|
3441a9ccf0 | ||
|
|
659d21680b | ||
|
|
2da833883b | ||
|
|
c301bf0827 | ||
|
|
1c4303b76d | ||
|
|
170a6ac36e | ||
|
|
92fa4c041d | ||
|
|
f34a9f6eac | ||
|
|
9fb69af355 | ||
|
|
59606d8935 | ||
|
|
bd7f5ec4c1 | ||
|
|
d082993a7a | ||
|
|
640d4162b6 | ||
|
|
66eb08f2d1 | ||
|
|
93fbd67a85 | ||
|
|
cf031717dd | ||
|
|
075ec1cf98 | ||
|
|
8f3b6a2371 | ||
|
|
ac24d9be5b | ||
|
|
a0e800f102 | ||
|
|
7e4572a86a | ||
|
|
4f0d3a958d | ||
|
|
06c5ba7f0e | ||
|
|
673fb26d6e | ||
|
|
5fa98da17e | ||
|
|
9b2f33f7bd | ||
|
|
2b70c73f80 | ||
|
|
1aec64cbae | ||
|
|
611946559c | ||
|
|
2997c6396f | ||
|
|
859d5df056 | ||
|
|
8a1902e5a8 | ||
|
|
285655f52d | ||
|
|
fceb170a2a | ||
|
|
4376e89149 | ||
|
|
cbd1d3134e | ||
|
|
fc479dbcc0 | ||
|
|
ae47ac19b8 | ||
|
|
84f6bd3fef | ||
|
|
d3b2da8e3b | ||
|
|
493ccc27d1 | ||
|
|
b37e6dc28d | ||
|
|
8cd6a94e26 | ||
|
|
13df32ba3f | ||
|
|
262a39cafb | ||
|
|
480f2e31b0 | ||
|
|
d0bb0aea97 | ||
|
|
bf3f927a99 | ||
|
|
19818e717f | ||
|
|
b6491a3842 | ||
|
|
c04c696ba6 | ||
|
|
17474bf005 | ||
|
|
756ec0e672 | ||
|
|
3dfdb60139 | ||
|
|
5a409dbe2c | ||
|
|
9ef37d9776 | ||
|
|
ba0a357d48 | ||
|
|
659ffa4406 | ||
|
|
12bba31270 | ||
|
|
dd66e44871 | ||
|
|
c5c87522ca | ||
|
|
5ef80f0a17 | ||
|
|
7372df3aff | ||
|
|
cf514b0d6b | ||
|
|
b232a10167 | ||
|
|
2a465d2f03 | ||
|
|
802f70fedd | ||
|
|
5acfa7d3d6 | ||
|
|
85188bf137 | ||
|
|
bfc44f2b4e | ||
|
|
96aaa8b14a | ||
|
|
53ed006a54 | ||
|
|
171c41df12 | ||
|
|
4b53edb3bd | ||
|
|
62085539a7 | ||
|
|
1c8e558e25 | ||
|
|
568145c247 | ||
|
|
5703bc7df2 | ||
|
|
95a00a165a | ||
|
|
599bc8a823 | ||
|
|
9578841480 | ||
|
|
5387a6b534 | ||
|
|
bf09e96e04 | ||
|
|
b5d8cecd91 | ||
|
|
6d913f42c8 | ||
|
|
1e0a875fa3 | ||
|
|
4d77ce5a66 | ||
|
|
f3a6fb7d8b | ||
|
|
b6f73d96ca | ||
|
|
13f3c8281f | ||
|
|
0107435a73 | ||
|
|
ce674a872a | ||
|
|
51758b965e | ||
|
|
7fec511463 | ||
|
|
1dd006d846 | ||
|
|
2800927fa1 | ||
|
|
f133e3cccb | ||
|
|
b0a520fe18 | ||
|
|
3f30dd01ad | ||
|
|
0c081a9597 | ||
|
|
7176460de3 | ||
|
|
733a1fa73d | ||
|
|
e3809ba058 | ||
|
|
4d3de39c64 | ||
|
|
1765e50703 | ||
|
|
f9feaa313b | ||
|
|
9781d8971a | ||
|
|
a0a9b5bbc5 | ||
|
|
c684faf423 | ||
|
|
cdca559d99 | ||
|
|
d76dff8594 | ||
|
|
223504a206 | ||
|
|
1ab4eb00c0 | ||
|
|
32e3e7d9c5 | ||
|
|
98123b9215 | ||
|
|
9069a49145 | ||
|
|
d417237e64 | ||
|
|
648f33473f | ||
|
|
446619ce85 | ||
|
|
f5fa1f6210 | ||
|
|
976fb99aa3 | ||
|
|
a0529d1cfc | ||
|
|
8001af9743 | ||
|
|
e48b72a859 | ||
|
|
71ba018782 | ||
|
|
59ff44132b | ||
|
|
8a0323ec08 | ||
|
|
4c7df6c7f4 | ||
|
|
676cd3104b | ||
|
|
a40210c55c | ||
|
|
034f90c1e0 | ||
|
|
64223927b8 | ||
|
|
e2c03255bb | ||
|
|
63495d3a6a | ||
|
|
88466ec352 | ||
|
|
1995eb935b | ||
|
|
f6532ca27a | ||
|
|
75dd5305c4 | ||
|
|
76cf989455 | ||
|
|
5b8e932509 | ||
|
|
993b705d8b | ||
|
|
19204882c4 | ||
|
|
605dc59f8d | ||
|
|
2332884d8b | ||
|
|
94f3d80a75 | ||
|
|
0b0e64304e | ||
|
|
5a1a766bd4 | ||
|
|
c15f446ffc | ||
|
|
c88cdde9ec | ||
|
|
40dbf53792 | ||
|
|
0cbf6f6601 | ||
|
|
c8fc873cf9 | ||
|
|
b935bef906 | ||
|
|
c1f0dd81d2 | ||
|
|
5722dc90f0 | ||
|
|
e3c260f4ca | ||
|
|
d1e48c657e | ||
|
|
decf70c87c | ||
|
|
4de9076b49 | ||
|
|
922df88cdd | ||
|
|
f25aeee756 | ||
|
|
2b36953fdc | ||
|
|
1dcf302665 | ||
|
|
1fd95c2886 | ||
|
|
93e1d7fcee | ||
|
|
b2b860bb8e | ||
|
|
0bd88fc9d9 | ||
|
|
20f9450218 | ||
|
|
401c402afc | ||
|
|
77a105d888 | ||
|
|
257c6b729f | ||
|
|
c5c941e928 | ||
|
|
092006fbbe | ||
|
|
6add19fb04 | ||
|
|
02d4b821d7 | ||
|
|
3d00ac338b | ||
|
|
387b9778f3 | ||
|
|
582876b99e | ||
|
|
3b3391c0d1 | ||
|
|
df61b1046a | ||
|
|
8426bcad27 | ||
|
|
d22fa54f7b | ||
|
|
2d56dddf7a | ||
|
|
7da0549b8c | ||
|
|
b821ece052 | ||
|
|
b240da41e0 | ||
|
|
d85baba1d3 | ||
|
|
8a44b909a4 | ||
|
|
5362264b18 | ||
|
|
1858cf3b33 | ||
|
|
1f876cde39 | ||
|
|
7288c7b541 | ||
|
|
2b8f5a7b9d | ||
|
|
c2e1425209 | ||
|
|
c9c1218234 | ||
|
|
11d776aea1 | ||
|
|
1386744fe0 | ||
|
|
da0d012328 | ||
|
|
f88abf9987 | ||
|
|
4a4fa7792f | ||
|
|
73adbc660b | ||
|
|
aa97a6d64f | ||
|
|
e0d87eb093 | ||
|
|
85b8c599c4 | ||
|
|
72136c2bfc | ||
|
|
71e9420929 | ||
|
|
7457db8bba | ||
|
|
69125b490e | ||
|
|
3c94cd3194 | ||
|
|
a6ac753c64 | ||
|
|
55600c40a9 | ||
|
|
9070c246d4 | ||
|
|
75ff5409f4 | ||
|
|
642fad9a6e | ||
|
|
5ae7ac3eca | ||
|
|
885862a45e | ||
|
|
9b751fced8 | ||
|
|
19ccc6a38d | ||
|
|
ad8b41adb0 | ||
|
|
807b8dea91 | ||
|
|
8e8935b9c4 | ||
|
|
76bf574668 | ||
|
|
9d17fc15a3 | ||
|
|
1cadd4e923 | ||
|
|
ab791d1b9c | ||
|
|
4f206d2773 | ||
|
|
7f9d9b81aa | ||
|
|
c77c3ab015 | ||
|
|
8acd81cc43 | ||
|
|
c0e52b9a1a | ||
|
|
0840da1bd5 | ||
|
|
852df89f93 | ||
|
|
b5eb8694f6 | ||
|
|
f4986008fe | ||
|
|
d6644c4935 | ||
|
|
19112aecb2 | ||
|
|
5bb8c86903 | ||
|
|
a659b57e63 | ||
|
|
44e96c544b | ||
|
|
0a5b8891a8 | ||
|
|
6a5db32d5d | ||
|
|
b0f3e065be | ||
|
|
b5b0875203 | ||
|
|
9a557978c4 | ||
|
|
fe895211c1 | ||
|
|
907131b7f5 | ||
|
|
76508146ae | ||
|
|
7f28b767e4 | ||
|
|
5f5a748031 | ||
|
|
867b519a2b | ||
|
|
74852520dc | ||
|
|
faec4d8e50 | ||
|
|
d2aca1d621 | ||
|
|
7bcd8c819a | ||
|
|
7209a61583 | ||
|
|
1523fafce0 | ||
|
|
3915c55251 | ||
|
|
5259aa20e6 | ||
|
|
11ecb473b6 | ||
|
|
7982fdac1c | ||
|
|
54d92a11e8 | ||
|
|
5eb302898f | ||
|
|
5b3a414987 | ||
|
|
05961ac883 | ||
|
|
afd07c25ba | ||
|
|
7ab92d88b1 | ||
|
|
3780299803 | ||
|
|
d78bb9ed3f | ||
|
|
b5f1552ed8 | ||
|
|
917cc7f27c | ||
|
|
2327e73ee7 | ||
|
|
397ddef68c | ||
|
|
3ec7f293ee | ||
|
|
26c8e8dab8 | ||
|
|
fdcea88519 | ||
|
|
bf6c73060b | ||
|
|
ddcd3861d3 | ||
|
|
971d47eb42 | ||
|
|
13bd42bdab | ||
|
|
71ac212dc7 | ||
|
|
2319a00c4f | ||
|
|
1268077f6b | ||
|
|
5c579de459 | ||
|
|
167faff1f3 | ||
|
|
22ad95cbfe | ||
|
|
db8508cefc | ||
|
|
5ac0772a2a | ||
|
|
e2c2d6606d | ||
|
|
48361f58b6 | ||
|
|
dcb439f74a | ||
|
|
739a27be63 | ||
|
|
e84cdce398 | ||
|
|
af2fe242f9 | ||
|
|
0fb177bf85 | ||
|
|
baab70c509 | ||
|
|
bc1c70bd1a | ||
|
|
12929c4571 | ||
|
|
62522e4eb3 | ||
|
|
221060cc70 | ||
|
|
58d1f7cee1 | ||
|
|
430256266f | ||
|
|
f9e38b11d9 | ||
|
|
78e075546a | ||
|
|
658e111e3c | ||
|
|
0e23b0bedd | ||
|
|
903c768f7f | ||
|
|
d08f0e6599 | ||
|
|
cd22ba1a2b | ||
|
|
77a11d2a2e | ||
|
|
cce8cb8528 | ||
|
|
6c6b447ea1 | ||
|
|
4554450d1d | ||
|
|
a0d1dbf833 | ||
|
|
a1a89df17f | ||
|
|
cf36384481 | ||
|
|
9103371362 | ||
|
|
1b5ad34c8e | ||
|
|
c57e88850c | ||
|
|
101a831534 | ||
|
|
3cc991fa4f | ||
|
|
c348f4ccad | ||
|
|
0181685d2f | ||
|
|
39bb94dd55 | ||
|
|
77a2bbbb8d | ||
|
|
afb0a80de1 | ||
|
|
49932e02a6 | ||
|
|
990a4ad583 | ||
|
|
fc9e1e401b | ||
|
|
15ca7e82bd | ||
|
|
3b81bbcae5 | ||
|
|
902fc2cbe8 | ||
|
|
50f5dabf4a | ||
|
|
aa6c9e2106 | ||
|
|
919fdb3594 | ||
|
|
c625cc68bf | ||
|
|
d732140bf9 | ||
|
|
db525bd5db | ||
|
|
039c666247 | ||
|
|
ed5c24c281 | ||
|
|
f2f4010203 | ||
|
|
a9e261d280 | ||
|
|
a710674cd4 | ||
|
|
ddfc00ed9f | ||
|
|
ac71970561 | ||
|
|
fd50529d86 | ||
|
|
52d95e537c | ||
|
|
15b21fff2b | ||
|
|
f46bccfecd | ||
|
|
1f55973f72 | ||
|
|
3d5fd61285 | ||
|
|
069b501ca3 | ||
|
|
d035af7ff0 | ||
|
|
20302cd378 | ||
|
|
959685e260 | ||
|
|
e0058c17ff | ||
|
|
bf61f5cfe8 | ||
|
|
8dcc25e1a9 | ||
|
|
a428167dc6 | ||
|
|
e46d819c46 | ||
|
|
48e3a3eb68 | ||
|
|
a635fb3f77 | ||
|
|
274f2fe10d | ||
|
|
320f679038 | ||
|
|
94c20ba29f | ||
|
|
8baebcfb5b | ||
|
|
2c96d49cf2 | ||
|
|
a9cabdc342 | ||
|
|
90a95b4688 | ||
|
|
7fcce4a59b | ||
|
|
554ffcd08f | ||
|
|
0c46ea13c7 | ||
|
|
af0574c04e | ||
|
|
6c38295d62 | ||
|
|
1e01dbb151 | ||
|
|
be270259ee | ||
|
|
03f9955f8b | ||
|
|
55e613fae5 | ||
|
|
a5bad2b9b7 | ||
|
|
ebb251d8cf | ||
|
|
56768f2d3d | ||
|
|
5b3d36e081 | ||
|
|
ad08590197 | ||
|
|
53b5588bda | ||
|
|
1015a8c098 | ||
|
|
27ddc215cc | ||
|
|
c11a6cd432 | ||
|
|
514eedbc63 | ||
|
|
1f61f80c92 | ||
|
|
830ffd0559 | ||
|
|
ed066df469 | ||
|
|
e6676c7d09 | ||
|
|
33115a39a3 | ||
|
|
6538360fe1 | ||
|
|
3a62e432da | ||
|
|
9c3f60c26c | ||
|
|
ed0e5b8c5a | ||
|
|
c75d94bd90 | ||
|
|
a8d6374d76 | ||
|
|
4b10402c5b | ||
|
|
e5863920c4 | ||
|
|
7f61b44d42 | ||
|
|
a5660fa2b4 | ||
|
|
ecc03e3ebc | ||
|
|
a92c2899c8 | ||
|
|
af4638e83f | ||
|
|
cecf1a5497 | ||
|
|
f2374982b8 | ||
|
|
d736dd027d | ||
|
|
214db9e0b1 | ||
|
|
3bbc89afc9 | ||
|
|
e35ccbbb18 | ||
|
|
20571c5aa1 | ||
|
|
3872a6b475 | ||
|
|
083a1c85a8 | ||
|
|
943e0285ac | ||
|
|
d7abfc688c | ||
|
|
8f01ef90cf | ||
|
|
8d071bf4ea | ||
|
|
3929fe64a3 | ||
|
|
a14086d484 | ||
|
|
20d25059bf | ||
|
|
ccee7162bc | ||
|
|
4fe8e40569 | ||
|
|
b91b3d5da6 | ||
|
|
debbae6ab1 | ||
|
|
2c6f01ae38 | ||
|
|
92f81fa054 | ||
|
|
0362fd1079 | ||
|
|
38765dc89a | ||
|
|
78306b3c12 | ||
|
|
e51a291195 | ||
|
|
d551848a9b | ||
|
|
fe6247dded | ||
|
|
5fb8b458bb | ||
|
|
4e21391f8c | ||
|
|
9ab4bb963f | ||
|
|
340c55c570 | ||
|
|
de1322b928 | ||
|
|
010d257b69 | ||
|
|
58f05f74cf | ||
|
|
e5d517dad2 | ||
|
|
965dea5fe6 | ||
|
|
1ffcc75031 | ||
|
|
e084cc9a3a | ||
|
|
6ed78d1202 | ||
|
|
270eaa1452 | ||
|
|
e1038ea632 | ||
|
|
8947100701 | ||
|
|
cb99e7d920 | ||
|
|
a4b0a69c45 | ||
|
|
2a364910c0 | ||
|
|
45ba648622 | ||
|
|
dcd48f4264 | ||
|
|
b048921c11 | ||
|
|
8ee9f1b1d9 | ||
|
|
f2c39e4004 | ||
|
|
4335aa563f | ||
|
|
62ec3546d6 | ||
|
|
8bb0bd05f9 | ||
|
|
e538242962 | ||
|
|
d70d2ad405 | ||
|
|
4f638f6d77 | ||
|
|
80d78705b0 | ||
|
|
140cec7c59 | ||
|
|
746b3c5a54 | ||
|
|
a4788b5b24 | ||
|
|
8dcf0f58b5 | ||
|
|
a8080c5db3 | ||
|
|
a52977d1cf | ||
|
|
0bb6fed822 | ||
|
|
d86305a7c3 | ||
|
|
5aeef17d09 | ||
|
|
2d41d993e3 | ||
|
|
503cc7ea97 | ||
|
|
7f41847c5c | ||
|
|
fde683a82e | ||
|
|
4feff7d917 | ||
|
|
e61951a319 | ||
|
|
da81274eb9 | ||
|
|
8740141a93 | ||
|
|
9223a2b530 | ||
|
|
300c74e3fc | ||
|
|
3f82c7fb6f | ||
|
|
2cb7a1d96c | ||
|
|
00562455e0 | ||
|
|
bb88dcfe66 | ||
|
|
970e594009 | ||
|
|
cd5a784277 | ||
|
|
771f653174 | ||
|
|
109cb81ab7 | ||
|
|
bf87f7ba84 | ||
|
|
92b8eae2dc | ||
|
|
776f86c7f2 | ||
|
|
c10c3a1cfe | ||
|
|
94fccc5112 | ||
|
|
73fa0e3efc | ||
|
|
2b827e43d7 | ||
|
|
e706368225 | ||
|
|
2f5271ab83 | ||
|
|
4e448b23a8 | ||
|
|
38002d4907 | ||
|
|
fd81f9b1b4 | ||
|
|
77900f5745 | ||
|
|
8684aac4f2 | ||
|
|
b1e0bc90ba | ||
|
|
8e305bfd0f | ||
|
|
32716e1480 | ||
|
|
833eccb6c4 | ||
|
|
f64b3618f2 | ||
|
|
325cd9a066 | ||
|
|
544c711fd7 | ||
|
|
e02afb34d1 | ||
|
|
dc5acd24b2 | ||
|
|
7555263e38 | ||
|
|
71d016722e | ||
|
|
96560e4914 | ||
|
|
04be40767b | ||
|
|
5a6197cfc6 | ||
|
|
5fca12af49 | ||
|
|
853830a446 | ||
|
|
2f47f72957 | ||
|
|
de35cf9840 | ||
|
|
18d8107992 | ||
|
|
2478b72a3e | ||
|
|
4d60150345 | ||
|
|
6a3a8d5578 | ||
|
|
08828991e7 | ||
|
|
4c14a96888 | ||
|
|
0478ec9696 | ||
|
|
46044c068b | ||
|
|
c6fe6b83ac | ||
|
|
cc39d4dd7d | ||
|
|
b79c049bd4 | ||
|
|
4cbf19c97e | ||
|
|
27041cbf59 | ||
|
|
8e2c72ed1b | ||
|
|
7820c9bc44 | ||
|
|
92fff9acf5 | ||
|
|
91da49dc52 | ||
|
|
b5a45417d9 | ||
|
|
3db4993077 | ||
|
|
bc1a5fdd8d | ||
|
|
191f1c38df | ||
|
|
adb61259c1 | ||
|
|
ddc2e84e45 | ||
|
|
a050a61f2e | ||
|
|
99195c3f4c | ||
|
|
280c159078 | ||
|
|
6a8f1b941e | ||
|
|
8a6ce19e1e | ||
|
|
d071adea9a | ||
|
|
3d7455316f | ||
|
|
3f50baa318 | ||
|
|
8164c96379 | ||
|
|
4ab3f01867 | ||
|
|
dbb277f749 | ||
|
|
0579f2ede6 | ||
|
|
ef3af9aad3 | ||
|
|
d5694036fa | ||
|
|
f91847dad0 | ||
|
|
c4eaa973f0 | ||
|
|
42fa77c81f | ||
|
|
e4bfeb9e44 | ||
|
|
67f2162fb3 | ||
|
|
465499f6c3 | ||
|
|
ea75311a34 | ||
|
|
33fd8a9ec7 | ||
|
|
417ffc09f8 | ||
|
|
1057f50f86 | ||
|
|
5b933cde61 | ||
|
|
47442d1bc9 | ||
|
|
f25c83e006 | ||
|
|
bc34024e32 | ||
|
|
628bef9094 | ||
|
|
63598019e1 | ||
|
|
501244ed25 | ||
|
|
e12912450c | ||
|
|
8262c9ece7 | ||
|
|
cc208ce451 | ||
|
|
c6374a899c | ||
|
|
8f80bcb159 | ||
|
|
e56ecfec40 | ||
|
|
80cf422a5e | ||
|
|
d788c310ee | ||
|
|
7583db3bef | ||
|
|
ac5abd96bb | ||
|
|
aa944ac5e8 | ||
|
|
35e1fb9ae5 | ||
|
|
a15863ae35 | ||
|
|
a04fd06e38 | ||
|
|
f6cc2c7b91 | ||
|
|
99ee526ac5 | ||
|
|
d100067e02 | ||
|
|
f777c62a66 | ||
|
|
06ef0e5fdc | ||
|
|
5209623064 | ||
|
|
7c53413bc5 | ||
|
|
42f92b8dc1 | ||
|
|
986baccf83 | ||
|
|
32d31e7644 | ||
|
|
03161446b9 | ||
|
|
17bbb7f145 | ||
|
|
71c4ec34d5 | ||
|
|
da3ed74c4e | ||
|
|
46ae8f92cc | ||
|
|
9b3dec5f70 | ||
|
|
146bfb28d1 | ||
|
|
46fb331275 | ||
|
|
ff39b8b252 | ||
|
|
004250ed23 | ||
|
|
037339f3be | ||
|
|
e0437ab447 | ||
|
|
808a161d39 | ||
|
|
6d8e1794a0 | ||
|
|
89338c0b4b | ||
|
|
7f7cbd5666 | ||
|
|
846ed76808 | ||
|
|
ab45b5ec8a | ||
|
|
db93a4c4a7 | ||
|
|
59566eb363 | ||
|
|
7fb85e5b25 | ||
|
|
c061912574 | ||
|
|
3eeb7e7cae | ||
|
|
cf653640b3 | ||
|
|
5cfd897298 | ||
|
|
7ecb6a6d96 | ||
|
|
c08f177d3b | ||
|
|
1c6e722961 | ||
|
|
0d49817f00 | ||
|
|
85c21df5e7 | ||
|
|
f9d5b8eb74 | ||
|
|
bcc3337c58 | ||
|
|
163888f329 | ||
|
|
8b986dfab3 | ||
|
|
19bd6d0bca | ||
|
|
c2caef4ad5 | ||
|
|
1d9ac4918c | ||
|
|
bc3be1029c | ||
|
|
bc238de5ce | ||
|
|
1072235b1a | ||
|
|
3c2c7b379d | ||
|
|
4af194035c | ||
|
|
3171cfd381 | ||
|
|
8183bf7f95 | ||
|
|
82bec1e324 | ||
|
|
897cc01f93 | ||
|
|
5bcfa35737 | ||
|
|
c1bcf91dd6 | ||
|
|
621e4d196e | ||
|
|
45ebc2239f | ||
|
|
a6248905a0 | ||
|
|
699dcdaf5b | ||
|
|
23d1f6b507 | ||
|
|
f72f4c49fb | ||
|
|
2803ee8274 | ||
|
|
0d2e6f5e98 | ||
|
|
99bf7f77c4 | ||
|
|
7fe2ab720f | ||
|
|
18cecc8d38 | ||
|
|
5d068fc2d4 | ||
|
|
84d98763f1 | ||
|
|
86356c737c | ||
|
|
1fa233aae7 | ||
|
|
1dc01314a1 | ||
|
|
fb40bb22df | ||
|
|
1dc22ec76c | ||
|
|
41ac140076 | ||
|
|
4e019cc233 | ||
|
|
36007ceb68 | ||
|
|
25fdeac697 | ||
|
|
07d27edb76 | ||
|
|
39fabf39ae | ||
|
|
945a483e9b | ||
|
|
1725dbfa98 | ||
|
|
67790abf0e | ||
|
|
3ec08f6ae1 | ||
|
|
c419654a11 | ||
|
|
51ad6094e8 | ||
|
|
5b7d189058 | ||
|
|
7d57d55414 | ||
|
|
65956dbc8d | ||
|
|
d75072362a | ||
|
|
22947af854 | ||
|
|
50a67dbd3e | ||
|
|
7fd954e10d | ||
|
|
4c53fcecfa | ||
|
|
17348dae8a | ||
|
|
05d495b282 | ||
|
|
3b7a940e9b | ||
|
|
501c6f260a | ||
|
|
e1fa2b9831 | ||
|
|
043175ae4d | ||
|
|
8b266b1327 | ||
|
|
f7abe3bb34 | ||
|
|
480e85f615 | ||
|
|
0182d1ca09 | ||
|
|
99a0dce8cd | ||
|
|
badcace987 | ||
|
|
e8b73e22b7 | ||
|
|
45f68d59ff | ||
|
|
1762987aae | ||
|
|
ad2e142b01 | ||
|
|
88fa5d5c41 | ||
|
|
e45ec4324f | ||
|
|
d9a8e29a94 | ||
|
|
3ced57a263 | ||
|
|
458868a634 | ||
|
|
7ecc0543f4 | ||
|
|
6d6f3d38d4 | ||
|
|
a4e715fa71 | ||
|
|
8594d11693 | ||
|
|
a4c14ebef7 | ||
|
|
599874c9c1 | ||
|
|
5121b0df93 | ||
|
|
e3a2f1cfbe | ||
|
|
414fb9dba2 | ||
|
|
a402c69c55 | ||
|
|
c007165a0f | ||
|
|
a3d50fc197 | ||
|
|
baa0ac44ca | ||
|
|
6768901446 | ||
|
|
35e77976a6 | ||
|
|
dba805e8c4 | ||
|
|
e3aca85efd | ||
|
|
f35a18bb63 | ||
|
|
a6ad0208db | ||
|
|
e02ccbf32a | ||
|
|
b362a55c04 | ||
|
|
69d0801121 | ||
|
|
f85bca06d7 | ||
|
|
3589e94121 | ||
|
|
2baf2cfed6 | ||
|
|
4d5c93adfa | ||
|
|
93eff7fac6 | ||
|
|
ce68a9c708 | ||
|
|
280dad1c07 | ||
|
|
c3d954263b | ||
|
|
e058ba5d3b | ||
|
|
05d51cc35c | ||
|
|
a51f310e96 | ||
|
|
89ccdf2814 | ||
|
|
52af352fcd | ||
|
|
088287227e | ||
|
|
ad1f9527c1 | ||
|
|
ca17717af7 | ||
|
|
2a849ccba5 | ||
|
|
4bf20846bc | ||
|
|
ad80184e7f | ||
|
|
e5ca63db20 | ||
|
|
7a33ae35e0 | ||
|
|
ce58ba3472 | ||
|
|
43ae2ea5f5 | ||
|
|
2f03922b43 | ||
|
|
5db2856270 | ||
|
|
e3e3229612 | ||
|
|
8b2ed736a6 | ||
|
|
27da5f84c4 | ||
|
|
98d04702ae | ||
|
|
a0664a49d2 | ||
|
|
55fb0a6efb | ||
|
|
7fb83f4f77 | ||
|
|
3006cd4f60 | ||
|
|
970f8c6dcd | ||
|
|
c99de2370f | ||
|
|
8c9ff4a66f | ||
|
|
42eeddcbfb | ||
|
|
8b0f17fb25 | ||
|
|
a3900495d5 | ||
|
|
d7bc1f0f77 | ||
|
|
281a04837f | ||
|
|
3ea688be69 | ||
|
|
c27180fb32 | ||
|
|
1bea7853ef | ||
|
|
104521517c | ||
|
|
bb217e5c49 | ||
|
|
12f302d356 | ||
|
|
6f233462c1 | ||
|
|
77e7c25e9c | ||
|
|
b027a6b9a1 | ||
|
|
6bb4575c95 | ||
|
|
37eace9db4 | ||
|
|
0414406471 | ||
|
|
8c000f327e | ||
|
|
951e70328f | ||
|
|
2dd7717128 | ||
|
|
9d6c548730 | ||
|
|
8a46853dfd | ||
|
|
789fd21bb7 | ||
|
|
3fa97b5ce7 | ||
|
|
c8ebbc657a | ||
|
|
b59585437c | ||
|
|
6f4e1365b1 | ||
|
|
fcef404f50 | ||
|
|
aabb492d01 | ||
|
|
cfa21934bb | ||
|
|
7561ce753a | ||
|
|
5ac0e58886 | ||
|
|
a14fc35e47 | ||
|
|
5fd00e3063 | ||
|
|
a46a012c3c | ||
|
|
3072105efe | ||
|
|
8f09ac2611 | ||
|
|
e12be7cf29 | ||
|
|
588d79641a | ||
|
|
daac6de533 | ||
|
|
c6d7307efe | ||
|
|
710f379bd3 | ||
|
|
e4d9be86b4 | ||
|
|
3c483c61e7 | ||
|
|
c453d14352 | ||
|
|
de060d66ab | ||
|
|
c458a8f5e7 | ||
|
|
4a77f847b4 | ||
|
|
edc6474f27 | ||
|
|
117f47e3a2 | ||
|
|
4f11ff76a5 | ||
|
|
10e97b63be | ||
|
|
af76a09e03 | ||
|
|
147bd8341d | ||
|
|
5c0dd67094 | ||
|
|
49688d6523 | ||
|
|
850f23be82 | ||
|
|
9e5769912b | ||
|
|
ab50bc9936 | ||
|
|
a604a3904f | ||
|
|
e112f2d8af | ||
|
|
376d2e1433 | ||
|
|
ed0caa119a | ||
|
|
f768146d8e | ||
|
|
412083d9ea | ||
|
|
07cdb42ff7 | ||
|
|
1e37e8f333 | ||
|
|
4fa89c4a45 | ||
|
|
0d7a2128b6 | ||
|
|
9aa3d8b987 | ||
|
|
eaf44bc18c | ||
|
|
ae33c8de18 | ||
|
|
b12e82c344 | ||
|
|
8dee648d01 | ||
|
|
8e6dc54b16 | ||
|
|
db9c48b085 | ||
|
|
c0171f5fd1 | ||
|
|
9a5a55d074 | ||
|
|
855836d9aa | ||
|
|
8a0a0bcdfc | ||
|
|
43c00568c6 | ||
|
|
31be731de0 | ||
|
|
113ef66e26 | ||
|
|
4d38e69f63 | ||
|
|
8c02345dfd | ||
|
|
a2efde1103 | ||
|
|
eb81583d9f | ||
|
|
44213bf830 | ||
|
|
f187f77e3d | ||
|
|
63a3f02368 | ||
|
|
994e6826b4 | ||
|
|
97991fd8fc | ||
|
|
1fdda98d8d | ||
|
|
a73ca94124 | ||
|
|
82d2aa8a47 | ||
|
|
75af07331a | ||
|
|
4be4ad07f3 | ||
|
|
57874a9bcb | ||
|
|
ec7968b2f4 | ||
|
|
81546fe727 | ||
|
|
7948bac6ba | ||
|
|
eceb5ba982 | ||
|
|
345dab9633 | ||
|
|
5c952021b7 | ||
|
|
80a5b44fe9 | ||
|
|
b66e6560ca | ||
|
|
673c2988d6 | ||
|
|
042f2e0224 | ||
|
|
b300bb9f7a | ||
|
|
205f2690d6 | ||
|
|
aeea301ee3 | ||
|
|
8e6bbed74f | ||
|
|
ef506d49aa | ||
|
|
c205a888a9 | ||
|
|
a3b66aec1f | ||
|
|
68f4c50bd3 | ||
|
|
7dbd79750c | ||
|
|
fd301186c7 | ||
|
|
b40328e621 | ||
|
|
7cd832e914 | ||
|
|
44feea4c01 | ||
|
|
c5ce475359 | ||
|
|
894a0540b9 | ||
|
|
967f4570ed | ||
|
|
14360beaf7 | ||
|
|
46e3258629 | ||
|
|
b3ad0a62c1 | ||
|
|
a5edd9c7ff | ||
|
|
7f49accc22 | ||
|
|
b8c2a695b8 | ||
|
|
c73bbc85bd | ||
|
|
d6545b253b | ||
|
|
293761bdf5 | ||
|
|
d862453956 | ||
|
|
58974c9305 | ||
|
|
cddb6609f1 | ||
|
|
4a9c51a6c8 | ||
|
|
329ae11d2f | ||
|
|
c3bc5cfc3b | ||
|
|
24f9003cd3 | ||
|
|
4c2bf59c46 | ||
|
|
642a89733b | ||
|
|
2b3d9427e1 | ||
|
|
6368241b77 | ||
|
|
57ae9022dd | ||
|
|
d6e15544bc | ||
|
|
3eeab5b74a | ||
|
|
7ed68952ba | ||
|
|
4696733eb4 | ||
|
|
86d014c3e4 | ||
|
|
35d3a0362d | ||
|
|
9f60c5e854 | ||
|
|
9564a947e8 | ||
|
|
878fbedcbe | ||
|
|
2b62f8c607 | ||
|
|
fa217e4cd0 | ||
|
|
6d32ad2ac8 | ||
|
|
d29d43e5d6 | ||
|
|
6cd99da6df | ||
|
|
54c492cac6 | ||
|
|
628b7b7dd9 | ||
|
|
c44493cd8a | ||
|
|
d36960bb03 | ||
|
|
20b838b968 | ||
|
|
741b21f508 | ||
|
|
c68f3bcc42 | ||
|
|
4cced8ffa0 | ||
|
|
8644f7777b | ||
|
|
5f5d31730c | ||
|
|
9d4711a95d | ||
|
|
041e29d1ae | ||
|
|
3a1ae0db00 | ||
|
|
a56f45af98 | ||
|
|
7eabf0d43c | ||
|
|
eb5a3bfd01 | ||
|
|
2d2ab0b99a | ||
|
|
f616fe25bb | ||
|
|
f6114f4c93 | ||
|
|
373dffc65a | ||
|
|
00a74d81c2 | ||
|
|
da40297810 | ||
|
|
0966a092af | ||
|
|
025b447a9c | ||
|
|
92abf760de | ||
|
|
2e0c15bae7 | ||
|
|
1464c02903 | ||
|
|
23f483cd01 | ||
|
|
65fe71341a | ||
|
|
aae3ae988f | ||
|
|
36576713af | ||
|
|
d7ec3bec1d | ||
|
|
5769d7e64f | ||
|
|
0df6a686d9 | ||
|
|
095c6d2adc | ||
|
|
408c65fcbf | ||
|
|
b27fa63aea | ||
|
|
fb38b224f4 | ||
|
|
a4019dd205 | ||
|
|
e07977eea9 | ||
|
|
b56c5b1c51 | ||
|
|
d7fd6658f6 | ||
|
|
71fb024061 | ||
|
|
d0659521eb | ||
|
|
affc9f262c | ||
|
|
f2b74de9dd | ||
|
|
d20fc971c9 | ||
|
|
1ddb82f334 | ||
|
|
5dd15e2942 | ||
|
|
6dfa9f7786 | ||
|
|
acd8620139 | ||
|
|
54cfc6e09b | ||
|
|
150cfa29e7 | ||
|
|
b90cdf9588 | ||
|
|
6316479930 | ||
|
|
92ccd6eb26 | ||
|
|
805dac3039 | ||
|
|
5f665fb82a | ||
|
|
2bd77ba9c4 | ||
|
|
ba955f6659 | ||
|
|
01898d5f41 | ||
|
|
a9e22c2e20 | ||
|
|
3dd3595a79 | ||
|
|
c0b5721920 | ||
|
|
44fd67ffd2 | ||
|
|
3474901e58 | ||
|
|
d55a26c242 | ||
|
|
e04516f7b3 | ||
|
|
1ec154ec77 | ||
|
|
c90073572b | ||
|
|
5eba9f72fb | ||
|
|
8909368033 | ||
|
|
4ffb9e8089 | ||
|
|
098be9c69e | ||
|
|
f9603dc11a | ||
|
|
5359e9a09d | ||
|
|
d11055cef2 | ||
|
|
28d2c6db73 | ||
|
|
abc8b18b78 | ||
|
|
68111e2932 | ||
|
|
c889bfa6d4 | ||
|
|
f2a0098fed | ||
|
|
b549c56b23 | ||
|
|
f107d380b9 | ||
|
|
4a8ce39bfd | ||
|
|
499d06ea83 | ||
|
|
24d172bd51 | ||
|
|
72968290bf | ||
|
|
2fa3cfea8d | ||
|
|
6438747649 | ||
|
|
90de080eba | ||
|
|
e6a49ca4ec | ||
|
|
87f6bf2d77 | ||
|
|
b3de6a166d | ||
|
|
4d815570d0 | ||
|
|
3ff457f4e8 | ||
|
|
6af509159e | ||
|
|
a8929170f3 | ||
|
|
a5eecf59b3 | ||
|
|
a7d8d31566 | ||
|
|
904bed862e | ||
|
|
65290a70f3 | ||
|
|
e2f309b5cc | ||
|
|
ed25d45adb | ||
|
|
f1b4b78e4c | ||
|
|
9e9aa5b4d9 | ||
|
|
dc0c5baece | ||
|
|
569c23ca95 | ||
|
|
61d1a836a2 | ||
|
|
767a1b6a8d | ||
|
|
9c8082fb16 | ||
|
|
3cdff93e26 | ||
|
|
e4a084b290 | ||
|
|
3c2445fb82 | ||
|
|
f7d8557030 | ||
|
|
754c0e234b | ||
|
|
d0c2c269b0 | ||
|
|
2b41d9684f | ||
|
|
972f945058 | ||
|
|
7205068809 | ||
|
|
73a969b1a4 | ||
|
|
a4120ef075 | ||
|
|
6b11674949 | ||
|
|
0f6dda9cb1 | ||
|
|
630d31ba20 | ||
|
|
1e6874c5eb | ||
|
|
d8a25e73f2 | ||
|
|
06be0d927b | ||
|
|
685dcd1c8a | ||
|
|
7af667cdf8 | ||
|
|
1abfa19636 | ||
|
|
0b6420d90a | ||
|
|
9bc832c4c6 | ||
|
|
ee109d0fec | ||
|
|
58c936fa6c | ||
|
|
bceed97817 | ||
|
|
cd47633810 | ||
|
|
8542675488 | ||
|
|
67435c71e8 | ||
|
|
092ee6d8a5 | ||
|
|
f1c8679df7 | ||
|
|
913fbef952 | ||
|
|
901e58573e | ||
|
|
ee7684abfc | ||
|
|
de363f176f | ||
|
|
26ebcdf9f5 | ||
|
|
5e619a70d4 | ||
|
|
a60ed281a1 | ||
|
|
ee5b1d3264 | ||
|
|
06879c65bc | ||
|
|
90c1cd0d5c | ||
|
|
24fe77e4f0 | ||
|
|
004b238fb7 | ||
|
|
de8382b4d0 | ||
|
|
d20ba556a9 | ||
|
|
6ac1e1df0e | ||
|
|
fe17d79e8d | ||
|
|
af0c267d96 | ||
|
|
d1239dea89 | ||
|
|
ae47ff9875 | ||
|
|
28d7227ba5 | ||
|
|
d715836c40 | ||
|
|
e76a73f871 | ||
|
|
1cc3490f51 | ||
|
|
c61a66257f | ||
|
|
5227259048 | ||
|
|
77bb6eade5 | ||
|
|
cb52d0b6ec | ||
|
|
99e37500e9 | ||
|
|
3314e9f3d7 | ||
|
|
478b9a9f68 | ||
|
|
31e0b3ab51 | ||
|
|
0e20d5976b | ||
|
|
ee9e64a253 | ||
|
|
45fcd811ec | ||
|
|
3d5e648b96 | ||
|
|
80386d45b9 | ||
|
|
ca107953fe | ||
|
|
60ae4bcfc1 | ||
|
|
4d5c6e1551 | ||
|
|
3c8a2f2372 | ||
|
|
af650c7c31 | ||
|
|
641da3a771 | ||
|
|
424736961b | ||
|
|
c99b34e60c | ||
|
|
0c8815549c | ||
|
|
77961d2c33 | ||
|
|
8259b8ba02 | ||
|
|
72a61786f4 | ||
|
|
c3a95594f9 | ||
|
|
51b2e30af8 | ||
|
|
f7e391dd2f | ||
|
|
8845f4eb3d | ||
|
|
91aae459d3 | ||
|
|
ae260370d6 | ||
|
|
987b83def6 | ||
|
|
af1b2e2e69 | ||
|
|
bbcfc8354a | ||
|
|
c6389de3b3 | ||
|
|
859a8dc8fb | ||
|
|
17e46a1d8f | ||
|
|
25e66d6972 | ||
|
|
21ab1111ad | ||
|
|
50ece2a831 | ||
|
|
521d69f5e0 | ||
|
|
db910b379f | ||
|
|
eb5ebbc0aa | ||
|
|
c504cb50dc | ||
|
|
e78b4decae | ||
|
|
c4cb055e3f | ||
|
|
a920ae5901 | ||
|
|
2d8bc6d6ee | ||
|
|
89274248ed | ||
|
|
07d9a7ec4b | ||
|
|
485ce40d33 | ||
|
|
30278a5511 | ||
|
|
594a66efa4 | ||
|
|
556bf3f970 | ||
|
|
605c4a4056 | ||
|
|
263c968ad0 | ||
|
|
30b54694aa | ||
|
|
78aaf39792 | ||
|
|
4bbf4e3b65 | ||
|
|
eda6603808 | ||
|
|
94caf86d4d | ||
|
|
98c4343410 | ||
|
|
7d73920ac2 | ||
|
|
1a8b25cc34 | ||
|
|
3f4993979f | ||
|
|
d98462b192 | ||
|
|
3dfe4f96fa | ||
|
|
a71c897d56 | ||
|
|
6105365065 | ||
|
|
3892fb6825 | ||
|
|
89fe36b881 | ||
|
|
e773880e6f | ||
|
|
8e22116a17 | ||
|
|
80782475da | ||
|
|
594241ffa3 | ||
|
|
3bd34e1d9b | ||
|
|
75f7b92342 | ||
|
|
1b47ef0ab1 | ||
|
|
0fe0c6c653 | ||
|
|
958775ffbe | ||
|
|
4c262deff6 | ||
|
|
882e14f13f | ||
|
|
93ceb92c12 | ||
|
|
562660134e | ||
|
|
4215f7090f | ||
|
|
c344903a23 | ||
|
|
7697d37ec6 | ||
|
|
4a81430da7 | ||
|
|
d217f5232a | ||
|
|
6894fb0245 | ||
|
|
c44302a477 | ||
|
|
ed7bd06f96 | ||
|
|
9ce66231a1 | ||
|
|
119948cfdb | ||
|
|
00413a6ad2 | ||
|
|
71e9b94a84 | ||
|
|
a23c895668 | ||
|
|
3d570f8008 | ||
|
|
87e9fdd0ac | ||
|
|
b47e2abb7c | ||
|
|
16dec49e08 | ||
|
|
0c62231b54 | ||
|
|
417b470cbb | ||
|
|
49627eaf53 | ||
|
|
87812a7f82 | ||
|
|
287836803d | ||
|
|
3dc3f7b7c2 | ||
|
|
f3b86f6c14 | ||
|
|
1727413247 | ||
|
|
4a103a1de3 | ||
|
|
36451614d2 | ||
|
|
e5b3c5268b | ||
|
|
0b5c19f634 | ||
|
|
ed6e544e11 | ||
|
|
baa36925e2 | ||
|
|
46b48dcc68 | ||
|
|
d97d1048fb | ||
|
|
5e4194b719 | ||
|
|
65563942cd | ||
|
|
8d5708e255 | ||
|
|
f906d08376 | ||
|
|
a576c43ed5 | ||
|
|
ac7bd2a6a0 | ||
|
|
99bd8b4972 | ||
|
|
eeca82b4e2 | ||
|
|
2c8b5aa7f8 | ||
|
|
d7fcd3d47c | ||
|
|
0fd9912f02 | ||
|
|
767445e05c | ||
|
|
de260b89af | ||
|
|
889fc8256d | ||
|
|
6d96981dc4 | ||
|
|
62a1e29670 | ||
|
|
bbedcaa37b | ||
|
|
467e7954a5 | ||
|
|
cc7a292591 | ||
|
|
227195e87b | ||
|
|
3244d980e4 | ||
|
|
78dee58811 | ||
|
|
b8d89da8ab | ||
|
|
a1984a026f | ||
|
|
c522d7386d | ||
|
|
ed28cc36a9 | ||
|
|
9c43a55c42 | ||
|
|
6e1bba851b | ||
|
|
e7ae03ded9 | ||
|
|
a859effa04 | ||
|
|
6f27b9b6b7 | ||
|
|
1b2de1a4c9 | ||
|
|
a0b099df7c | ||
|
|
7a889803fd | ||
|
|
060650e0d8 | ||
|
|
544c55d848 | ||
|
|
a00aad5fa7 | ||
|
|
b9d7c11936 | ||
|
|
ee157db078 | ||
|
|
46bb7d3b88 | ||
|
|
1a59f8bade | ||
|
|
5905b8c148 | ||
|
|
632731bede | ||
|
|
d0d9712545 | ||
|
|
0d81c9fb0b | ||
|
|
4ca0b56106 | ||
|
|
e94e757743 | ||
|
|
a7a70f9900 | ||
|
|
34d86500fa | ||
|
|
650c3ff8ae | ||
|
|
3f1326a3ac | ||
|
|
190ab6690a | ||
|
|
bb5b5d4512 | ||
|
|
04cd7db2cd | ||
|
|
c03cf8eb45 | ||
|
|
93523df804 | ||
|
|
9191795b4c | ||
|
|
d960f8e9f5 | ||
|
|
a0b73a5919 | ||
|
|
897141833a | ||
|
|
fd244eb8b9 | ||
|
|
b147f71ffa | ||
|
|
cfed5e7a29 | ||
|
|
d1fbbac0ae | ||
|
|
a39199d379 | ||
|
|
d7c49c6522 | ||
|
|
14393ea6b1 | ||
|
|
08e191d7cc | ||
|
|
579db85b3b | ||
|
|
6154cc08db | ||
|
|
adeacd89f4 | ||
|
|
9a61407125 | ||
|
|
8905410aa4 | ||
|
|
ef16842074 | ||
|
|
c6f5a406a7 | ||
|
|
1d17dbd121 | ||
|
|
8f77a5482a | ||
|
|
d485da19b7 | ||
|
|
93dc87f17f | ||
|
|
fad94ca759 | ||
|
|
289ff59008 | ||
|
|
276b59b24e | ||
|
|
cffb272abd | ||
|
|
305ab38ac8 | ||
|
|
4dd05ca23f | ||
|
|
7744e1a262 | ||
|
|
370c470bd9 | ||
|
|
2a5b303b70 | ||
|
|
fd16c7f28f | ||
|
|
a7979d4695 | ||
|
|
eb2c762214 | ||
|
|
99b01536bc | ||
|
|
525c2dc88c | ||
|
|
b0f8d947ad | ||
|
|
4cb361bf9f | ||
|
|
30b8c0d4d4 | ||
|
|
3e3fa08430 | ||
|
|
ee66afb7f6 | ||
|
|
47f262a2c6 | ||
|
|
953200b87b | ||
|
|
03e5988397 | ||
|
|
6280ed1507 | ||
|
|
643961f9e6 | ||
|
|
ed888076c6 | ||
|
|
f2893b7c17 | ||
|
|
58bc744ec3 | ||
|
|
11336a3e1f | ||
|
|
4516f9790a | ||
|
|
fe1c77b9ae | ||
|
|
4bd50b9182 | ||
|
|
2bb5a5de9b | ||
|
|
1f97d59325 | ||
|
|
621083c035 | ||
|
|
99bfbeb3bc | ||
|
|
170ae3477c | ||
|
|
063c7f7d18 | ||
|
|
a9f1a896c5 | ||
|
|
32dc99032e | ||
|
|
734514c1fe | ||
|
|
d7b1ad61f3 | ||
|
|
493a833f56 | ||
|
|
3bc508deea | ||
|
|
a53fe5eba0 | ||
|
|
0942032f3c | ||
|
|
5f76370121 | ||
|
|
dfda9c764b | ||
|
|
125c1ff37d | ||
|
|
dd102c806c | ||
|
|
700994340b | ||
|
|
860425b3cc | ||
|
|
df392b8376 | ||
|
|
f39d11ef7e | ||
|
|
75bb7483df | ||
|
|
4ecf43a08d | ||
|
|
1713124711 | ||
|
|
a1dd76818e | ||
|
|
7449230af8 | ||
|
|
fbe9cc3936 | ||
|
|
a1f0053be6 | ||
|
|
bd35dfbce3 | ||
|
|
adf5a7e8e4 | ||
|
|
fee28194fb | ||
|
|
42cb880538 | ||
|
|
cc2bb61b86 | ||
|
|
a446199312 | ||
|
|
89842c6d30 | ||
|
|
3694e8e87a | ||
|
|
74aae115ee | ||
|
|
6402c8e7ed | ||
|
|
8b44ebbdab | ||
|
|
959b6344b3 | ||
|
|
15a99aeebe | ||
|
|
8192eea387 | ||
|
|
5cfed1e482 | ||
|
|
22dcb1ec99 | ||
|
|
d29797988e | ||
|
|
333df13fce | ||
|
|
18790901b1 | ||
|
|
8740f22c0a | ||
|
|
0fd51fb52a | ||
|
|
002a05f866 | ||
|
|
1301103245 | ||
|
|
5de78a4687 | ||
|
|
df97c42e4e | ||
|
|
2e9238d719 | ||
|
|
fec79624df | ||
|
|
9df8e83ef0 | ||
|
|
5b1d093778 | ||
|
|
b907aa2d98 | ||
|
|
34575d577c | ||
|
|
e30bf5205e | ||
|
|
02f38267a8 | ||
|
|
68fe119344 | ||
|
|
2ee8ca37c0 | ||
|
|
cb889ad36e | ||
|
|
1e14e12015 | ||
|
|
8a6dbef775 | ||
|
|
10bd4dd9b4 | ||
|
|
9552b10d32 | ||
|
|
e8a655d99b | ||
|
|
d75d4400f0 | ||
|
|
7c739d5a7f | ||
|
|
dd32e76dc6 | ||
|
|
700d14be2f | ||
|
|
433f23dd04 | ||
|
|
b5fcea7135 | ||
|
|
c797bd6f72 | ||
|
|
836780d8a7 | ||
|
|
28ccab67fa | ||
|
|
0ddcce4854 | ||
|
|
6ee4b6de85 | ||
|
|
a04b7f88fa | ||
|
|
aac8b30bce | ||
|
|
c9d8222889 | ||
|
|
e1bd8a4ea7 | ||
|
|
edda259adc | ||
|
|
01682fc966 | ||
|
|
2d9390df9f | ||
|
|
2c54dfd132 | ||
|
|
482b7427f0 | ||
|
|
cd63ab8be4 | ||
|
|
0b1d739673 | ||
|
|
0b9ecd35c6 | ||
|
|
429957f830 | ||
|
|
adfe30cf4c | ||
|
|
1d1cd347ef | ||
|
|
bec7a9f452 | ||
|
|
65f156817c | ||
|
|
8b7fcc4084 | ||
|
|
58abddfd27 | ||
|
|
64249eb68e | ||
|
|
17a2c3644f | ||
|
|
06313dd540 | ||
|
|
98b2a32eae | ||
|
|
3660cf49f4 | ||
|
|
7058ffeb61 | ||
|
|
c364d6379b | ||
|
|
ed1a9fabd0 | ||
|
|
a9fc78b88e | ||
|
|
62afe5714a | ||
|
|
2d1c3fa307 | ||
|
|
be1f2138e7 | ||
|
|
3495a0b53e | ||
|
|
477bbe935f | ||
|
|
0d762b9307 | ||
|
|
645c771af2 | ||
|
|
2d67334cb4 | ||
|
|
cb8308387a | ||
|
|
17c7e0b3ed | ||
|
|
c86fd8498f | ||
|
|
c4f0dbab09 | ||
|
|
a41a81f5dd | ||
|
|
6215623640 | ||
|
|
381f0f0f95 | ||
|
|
786c8e7744 | ||
|
|
55b26fa28f | ||
|
|
5b60e3e47b | ||
|
|
2711912bcf | ||
|
|
b2af81cdb0 | ||
|
|
f03de11521 | ||
|
|
cc2ddad53b | ||
|
|
f5887d64c2 | ||
|
|
b393a35325 | ||
|
|
f05121b52f | ||
|
|
d001b40430 | ||
|
|
df7bb18e2c | ||
|
|
71c1bb0670 | ||
|
|
553447ed76 | ||
|
|
8482b9130c | ||
|
|
d4cb599b36 | ||
|
|
63ffb2efe0 | ||
|
|
1ce40ff0ec | ||
|
|
0077bbe295 | ||
|
|
d1b29a59d2 | ||
|
|
3f29bac591 | ||
|
|
37d3625bf3 | ||
|
|
578071e8f9 | ||
|
|
ca3c2a2387 | ||
|
|
320d0a5ce7 | ||
|
|
188558d302 | ||
|
|
769770ab81 | ||
|
|
a155282fd0 | ||
|
|
3198cf65d9 | ||
|
|
e99aac3575 | ||
|
|
c1b37b56bc | ||
|
|
9a420b0093 | ||
|
|
b3e466afed | ||
|
|
403d5d77d5 | ||
|
|
0038dc3ae8 | ||
|
|
4bf6802855 | ||
|
|
21ef50b589 | ||
|
|
efd0856ef0 | ||
|
|
65590e8c49 | ||
|
|
427b428718 | ||
|
|
fef96c125a | ||
|
|
484a7cdd10 | ||
|
|
c731cbcaf8 | ||
|
|
5a9ad280a5 | ||
|
|
472053df42 | ||
|
|
f8ca801877 | ||
|
|
9ba34aefa1 | ||
|
|
9ce25a4e72 | ||
|
|
40854fbf31 | ||
|
|
0035871422 | ||
|
|
6a447cb0b5 | ||
|
|
c5a42a57bc | ||
|
|
ed1c9c9091 | ||
|
|
96c8353364 | ||
|
|
adbd69c8b6 | ||
|
|
255d19d40f | ||
|
|
8ada1d5320 | ||
|
|
f7823f206a | ||
|
|
4fa187035c | ||
|
|
c4fc93768f | ||
|
|
3ccd8c624f | ||
|
|
f4aefe4fd1 | ||
|
|
7e4a31c786 | ||
|
|
5894992f70 | ||
|
|
c098790f3b | ||
|
|
09c439bbe8 | ||
|
|
c5b56b874c | ||
|
|
39d81923c9 | ||
|
|
f99d7fa262 | ||
|
|
8db02cf503 | ||
|
|
6831258a57 | ||
|
|
4544674784 | ||
|
|
e3b4ca705d | ||
|
|
8f92315207 | ||
|
|
5a1b7374e5 | ||
|
|
0c2e95185c | ||
|
|
bccea0e991 | ||
|
|
6b2e815b49 | ||
|
|
e44ed4a8e8 | ||
|
|
34ac18479f | ||
|
|
54261b69c9 | ||
|
|
268b0cdcfd | ||
|
|
ef223bb20d | ||
|
|
bb345bf291 | ||
|
|
d5cd4e5834 | ||
|
|
6dd35cc811 | ||
|
|
39af255335 | ||
|
|
1afc102910 | ||
|
|
1abfdaf64e | ||
|
|
ad3dce1102 | ||
|
|
e3313d27b2 | ||
|
|
4e73af0f94 | ||
|
|
aff2b9e1af | ||
|
|
8567c42b30 | ||
|
|
a5171a1d09 | ||
|
|
0b6b6339ed | ||
|
|
5b644cf1ca | ||
|
|
03f096384b | ||
|
|
015dcf117d | ||
|
|
797dabe11f | ||
|
|
93bedb91f1 | ||
|
|
53bde38035 | ||
|
|
21f1517a5f | ||
|
|
99f04ec753 | ||
|
|
1b8c2a63c2 | ||
|
|
f7e811e463 | ||
|
|
091c14c78a | ||
|
|
6bfde76514 | ||
|
|
0ef54aa16b | ||
|
|
dd29a62811 | ||
|
|
0ff22ed0a6 | ||
|
|
75bfd25224 | ||
|
|
e2b3ef147d | ||
|
|
1cf4c36ede | ||
|
|
9f565f2d41 | ||
|
|
3ddce6dd45 | ||
|
|
8a9400ca29 | ||
|
|
84ba8afe0f | ||
|
|
c126880e57 | ||
|
|
38c81dd212 | ||
|
|
29f2391230 | ||
|
|
3f7ea1fda9 | ||
|
|
391cbdc044 | ||
|
|
dd80114bf7 | ||
|
|
9826afa063 | ||
|
|
49c6a55f24 | ||
|
|
333b21fac4 | ||
|
|
5f604d3bcb | ||
|
|
dcf5444acc | ||
|
|
f9d8733604 | ||
|
|
b79c074444 | ||
|
|
d476b7901a | ||
|
|
80a0f467d7 | ||
|
|
2510964047 | ||
|
|
276a77ec26 | ||
|
|
79fef77099 | ||
|
|
e017fba9c1 | ||
|
|
d6fe3526a4 | ||
|
|
aaaf093af7 | ||
|
|
1d72f66de9 | ||
|
|
a45bd364ba | ||
|
|
4161ca9b07 | ||
|
|
aac665e617 | ||
|
|
76d7e8b653 | ||
|
|
476f6245b1 | ||
|
|
0ba07d98e7 | ||
|
|
0d9214df40 | ||
|
|
12193f9510 | ||
|
|
5c33ae47b3 | ||
|
|
81c9312fb4 | ||
|
|
7d33816d25 | ||
|
|
48efdac9b4 | ||
|
|
573a298bba | ||
|
|
2181508eed | ||
|
|
9266457c62 | ||
|
|
ff69efff48 | ||
|
|
ef3512a2f3 | ||
|
|
31651c2ac6 | ||
|
|
81c7c37707 | ||
|
|
3e6bef3cc0 | ||
|
|
3b83a4e4d5 | ||
|
|
cbf81e772f | ||
|
|
2b389a2142 | ||
|
|
7f30c7078d | ||
|
|
8cadf0a775 | ||
|
|
ed1bea6a35 | ||
|
|
4fa18dbaea | ||
|
|
ad67f9bbb9 | ||
|
|
4973c5a27d | ||
|
|
678fc54934 | ||
|
|
d8cef3f6a9 | ||
|
|
36a7c00507 | ||
|
|
17501e880e | ||
|
|
efdc92479a | ||
|
|
1b49bdd31e | ||
|
|
2f3b4fae53 | ||
|
|
43d924ceae | ||
|
|
73d34a9ab5 | ||
|
|
a6839f57e7 | ||
|
|
f7655091b0 | ||
|
|
cdeba9b03e | ||
|
|
214a15073e | ||
|
|
76b7970589 | ||
|
|
d49373b0f9 | ||
|
|
be50fca2d6 | ||
|
|
b975f5d4bd | ||
|
|
13de6b9a1e | ||
|
|
3415ce5577 | ||
|
|
424a02cdf3 | ||
|
|
a5a71bec0b | ||
|
|
3294b36961 | ||
|
|
12b9b7254a | ||
|
|
7ab275d4b5 | ||
|
|
29fd406dd8 | ||
|
|
553343e698 | ||
|
|
530cdaa23f | ||
|
|
c683e0ded8 | ||
|
|
78987074a6 | ||
|
|
5ac104fb0e | ||
|
|
066093553f | ||
|
|
637ad3b214 | ||
|
|
3b86c57d0e | ||
|
|
a1981c48b6 | ||
|
|
6439e01087 | ||
|
|
369624b28f | ||
|
|
a331c7bd84 | ||
|
|
9acbfae25d | ||
|
|
e14115683e | ||
|
|
4730da31d5 | ||
|
|
21b2eb3e5d | ||
|
|
cd49b32473 | ||
|
|
8f80b427df | ||
|
|
5f265d03fe | ||
|
|
6865d74a85 | ||
|
|
cf7aa4f310 | ||
|
|
0280fcc9d4 | ||
|
|
dae0908735 | ||
|
|
ed538f7dce | ||
|
|
554d8005fa | ||
|
|
a944cd08c6 | ||
|
|
2c26d379df | ||
|
|
a4053715af | ||
|
|
01af8e5f5e | ||
|
|
78eb1829d8 | ||
|
|
09f5d25133 | ||
|
|
9928af2506 | ||
|
|
72c2ee1008 | ||
|
|
7b8840a330 | ||
|
|
8f86be37f0 | ||
|
|
25fb888d26 | ||
|
|
c10f075266 | ||
|
|
b8c1d6657d | ||
|
|
4cc199b2b7 | ||
|
|
5d6ac0acbb | ||
|
|
ba51c873d0 | ||
|
|
920e2bf039 | ||
|
|
4ca5d4f577 | ||
|
|
5e4dacfa67 | ||
|
|
07958f08ae | ||
|
|
2f363a7355 | ||
|
|
0dc4b07538 | ||
|
|
d27142f565 | ||
|
|
86818389ac | ||
|
|
2a89874812 | ||
|
|
ca4753cf7c | ||
|
|
664bfe6fa3 | ||
|
|
fe1f2dc93a | ||
|
|
6611e9bf5e | ||
|
|
ac310114fe | ||
|
|
dffaed7dd9 | ||
|
|
589cd5c52f | ||
|
|
c3cbfbdfb0 | ||
|
|
a6c56ba748 | ||
|
|
43d87877be | ||
|
|
d28a7f45c5 | ||
|
|
e3a997b642 | ||
|
|
fb52b38ac3 | ||
|
|
f8d4b08618 | ||
|
|
4c29a9bad7 | ||
|
|
af0b0eac42 | ||
|
|
06e1456d4f | ||
|
|
6304b1e9c1 | ||
|
|
459a2b973e | ||
|
|
2bac2afe98 | ||
|
|
abf8dd42c3 | ||
|
|
e9ecda2b31 | ||
|
|
970d959772 | ||
|
|
becdd213fe | ||
|
|
6406523720 | ||
|
|
38f50c1b5a | ||
|
|
e09e895f22 | ||
|
|
b790a336e9 | ||
|
|
8d520fa5e4 | ||
|
|
b82a97853f | ||
|
|
8f8f270cfc | ||
|
|
751f30003d | ||
|
|
ebec2966d7 | ||
|
|
5b35b52fda | ||
|
|
929976c147 | ||
|
|
fc752e6efb | ||
|
|
bbab62810a | ||
|
|
d23b7bff7b | ||
|
|
27e9acaac6 | ||
|
|
355ed998e5 | ||
|
|
b1defae3f7 | ||
|
|
8202ac420b | ||
|
|
24b973f763 | ||
|
|
cf22e942cb | ||
|
|
93e009bf1a |
No files matched your search
+14
@@ -0,0 +1,14 @@
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-2
|
||||
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
CIRRUS_CLONE_SUBMODULES: true
|
||||
|
||||
task:
|
||||
install_script: pkg install -y alsa-lib ccache cmake evdev-proto git libao libevdev libudev-devd libzip mesa-libs miniupnpc ninja pkgconf pulseaudio sdl2
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache
|
||||
script:
|
||||
- cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
- cmake --build build --config Release
|
||||
@@ -0,0 +1 @@
|
||||
custom: ['https://www.paypal.com/paypalme/FlycastEmu']
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Please Note: This form is the minimum required information for submitting bugs.**
|
||||
**Removing this form may lead to your issue being closed until it is completed.**
|
||||
|
||||
Platform / OS / Hardware:
|
||||
|
||||
Github hash:
|
||||
|
||||
Hardware:
|
||||
|
||||
**_Description of the Issue_**
|
||||
|
||||
Add a short, concise description of the issue here
|
||||
|
||||
**_Debugging Steps Tested_**
|
||||
|
||||
* Fill in any steps already tried here
|
||||
* Begin each new line with an asterisk
|
||||
* If no steps are required, please skip
|
||||
|
||||
**_Logs Gathered_**
|
||||
|
||||
```
|
||||
|
||||
Please paste the contents of the log / logs here
|
||||
You may leave this field blank if you have none.
|
||||
|
||||
```
|
||||
|
||||
|
||||
**_Screenshots_**
|
||||
|
||||
(Replace this line with any issue screenshots)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,94 @@
|
||||
name: Android CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set up build environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ccache libcurl4-openssl-dev ninja-build
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
cache: 'gradle'
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: android-ccache-${{ github.sha }}
|
||||
restore-keys: android-ccache-
|
||||
|
||||
- name: Gradle
|
||||
working-directory: shell/android-studio
|
||||
run: ./gradlew assembleRelease --parallel
|
||||
env:
|
||||
SENTRY_UPLOAD_URL: ${{ secrets.SENTRY_UPLOAD_URL }}
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: flycast-release.apk
|
||||
path: shell/android-studio/flycast/build/outputs/apk/release/flycast-release.apk
|
||||
|
||||
- name: Build dump_syms
|
||||
working-directory: core/deps/breakpad
|
||||
run: |
|
||||
./configure --prefix=$PWD
|
||||
make -j2
|
||||
make install
|
||||
|
||||
- name: Extract symbols
|
||||
run: |
|
||||
DUMP_SYMS=./core/deps/breakpad/bin/dump_syms
|
||||
SO_DIR=shell/android-studio/flycast/build/intermediates/merged_native_libs/release/out/lib
|
||||
for arch in arm64-v8a armeabi-v7a x86 x86_64 ; do
|
||||
$DUMP_SYMS $SO_DIR/$arch/libflycast.so > libflycast.so.sym
|
||||
BUILD_ID=`head -1 libflycast.so.sym | awk '{ print $4 }'`
|
||||
mkdir -p symbols/libflycast.so/$BUILD_ID
|
||||
mv libflycast.so.sym symbols/libflycast.so/$BUILD_ID
|
||||
done
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
aws-region: us-east-2
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
|
||||
|
||||
- name: Upload to S3
|
||||
run: aws s3 sync shell/android-studio/flycast/build/outputs/apk/release s3://flycast-builds/android/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --exclude='*.json' --follow-symlinks
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
|
||||
- name: Setup Sentry CLI
|
||||
uses: mathieu-bour/setup-sentry-cli@v1
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
with:
|
||||
url: https://sentry.io
|
||||
token: ${{ env.SENTRY_TOKEN }}
|
||||
organization: flycast
|
||||
project: minidump
|
||||
if: ${{ env.SENTRY_TOKEN != '' }}
|
||||
|
||||
- name: Upload symbols to Sentry
|
||||
run: |
|
||||
VERSION=$(git describe --tags --always)
|
||||
sentry-cli releases new "$VERSION"
|
||||
sentry-cli releases set-commits "$VERSION" --auto
|
||||
sentry-cli debug-files upload symbols
|
||||
shell: bash
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
if: ${{ env.SENTRY_TOKEN != '' }}
|
||||
@@ -0,0 +1,180 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.config.shell }}
|
||||
|
||||
env:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {name: i686-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x86, cmakeArgs: -G Ninja, buildType: Release}
|
||||
- {name: apple-darwin, os: macos-latest, shell: sh, cmakeArgs: -G Xcode -DAPPLE_BREAKPAD=ON, destDir: osx, buildType: RelWithDebInfo}
|
||||
- {name: apple-ios, os: macos-latest, shell: sh, cmakeArgs: -DCMAKE_SYSTEM_NAME=iOS -G Xcode, destDir: ios, buildType: Release}
|
||||
- {name: x86_64-pc-linux-gnu, os: ubuntu-20.04, shell: sh, cmakeArgs: -G Ninja, destDir: linux, buildType: RelWithDebInfo}
|
||||
- {name: x86_64-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x64, cmakeArgs: -G Ninja, buildType: Release}
|
||||
- {name: x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -G Ninja, destDir: win, buildType: RelWithDebInfo}
|
||||
- {name: libretro-x86_64-pc-linux-gnu, os: ubuntu-latest, shell: sh, cmakeArgs: -DLIBRETRO=ON -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -G Ninja, buildType: Release}
|
||||
- {name: libretro-x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -DLIBRETRO=ON -G Ninja, buildType: Release}
|
||||
|
||||
steps:
|
||||
- name: Set up build environment (macOS)
|
||||
run: |
|
||||
# Unlink and re-link to prevent errors when github mac runner images install python outside of brew. See https://github.com/actions/setup-python/issues/577
|
||||
brew list -1 | grep python | while read formula; do brew unlink $formula; brew link --overwrite $formula; done
|
||||
brew update || :
|
||||
brew install libao ldid ninja pulseaudio
|
||||
VULKAN_VER=1.3.261.1 && aria2c https://sdk.lunarg.com/sdk/download/$VULKAN_VER/mac/vulkansdk-macos-$VULKAN_VER.dmg
|
||||
hdiutil attach ./vulkansdk-macos-*.dmg -mountpoint /Volumes/VulkanSDK
|
||||
sudo /Volumes/VulkanSDK/InstallVulkan.app/Contents/MacOS/InstallVulkan --root $HOME/VulkanSDK --accept-licenses --default-answer --confirm-command install
|
||||
hdiutil detach /Volumes/VulkanSDK
|
||||
echo "VULKAN_SDK=$HOME/VulkanSDK/macOS" >> $GITHUB_ENV
|
||||
if: runner.os == 'macOS'
|
||||
|
||||
- name: Set up build environment (Linux)
|
||||
run: |
|
||||
sudo add-apt-repository ppa:christianrauch/libdecoration
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ccache libao-dev libasound2-dev libevdev-dev libgl1-mesa-dev liblua5.3-dev libminiupnpc-dev libpulse-dev libsdl2-dev libudev-dev libzip-dev ninja-build libcurl4-openssl-dev
|
||||
sudo apt-get -y install libwayland-dev libdecor-0-dev libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxkbcommon-dev libdrm-dev libgbm-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
|
||||
if: runner.os == 'Linux'
|
||||
|
||||
- name: Set up build environment (Windows, MinGW)
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
install: git make mingw-w64-x86_64-ccache mingw-w64-x86_64-cmake mingw-w64-x86_64-lua mingw-w64-x86_64-ninja mingw-w64-x86_64-SDL2 mingw-w64-x86_64-toolchain
|
||||
if: matrix.config.shell == 'msys2 {0}'
|
||||
|
||||
- name: Set up build environment (Windows, Visual Studio)
|
||||
run: |
|
||||
choco install ccache directx-sdk ninja
|
||||
echo DXSDK_DIR=C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)>> %GITHUB_ENV%
|
||||
if: matrix.config.shell == 'cmd'
|
||||
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.config.arch }}
|
||||
if: matrix.config.shell == 'cmd'
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Compile a universal OpenMP (macOS)
|
||||
run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew reinstall --build-from-source --formula ./shell/apple/libomp.rb
|
||||
if: matrix.config.name == 'apple-darwin'
|
||||
|
||||
- name: Compile OpenMP.xcframework (iOS)
|
||||
run: ./shell/apple/emulator-ios/OpenMP/build_ios_openmp.sh --disableSimulator
|
||||
if: matrix.config.name == 'apple-ios'
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ccache-${{ matrix.config.name }}-${{ github.sha }}
|
||||
restore-keys: ccache-${{ matrix.config.name }}-
|
||||
if: runner.os != 'macOS'
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.buildType }} -DCMAKE_INSTALL_PREFIX=artifact ${{ matrix.config.cmakeArgs }} -DSENTRY_UPLOAD_URL=${{ env.SENTRY_UPLOAD_URL }}
|
||||
cmake --build build --config ${{ matrix.config.buildType }} --target install
|
||||
env:
|
||||
SENTRY_UPLOAD_URL: ${{ secrets.SENTRY_UPLOAD_URL }}
|
||||
|
||||
- name: Unit Tests
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.buildType }} -DCMAKE_INSTALL_PREFIX=artifact -DENABLE_CTEST=ON ${{ matrix.config.cmakeArgs }}
|
||||
cmake --build build --config ${{ matrix.config.buildType }}
|
||||
./build/flycast
|
||||
if: matrix.config.name == 'x86_64-pc-linux-gnu'
|
||||
|
||||
- name: Dump symbols
|
||||
run: |
|
||||
mkdir -p symbols
|
||||
core/deps/breakpad/bin/dump_syms artifact/bin/flycast.exe > symbols/flycast.sym 2>/dev/null
|
||||
strip artifact/bin/flycast.exe
|
||||
if: matrix.config.name == 'x86_64-w64-mingw32'
|
||||
|
||||
- name: Build breakpad (linux)
|
||||
working-directory: core/deps/breakpad
|
||||
run: |
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
if: matrix.config.name == 'x86_64-pc-linux-gnu'
|
||||
|
||||
- name: Dump symbols and make AppImage (linux)
|
||||
run: |
|
||||
mkdir -p symbols
|
||||
dump_syms artifact/bin/flycast > symbols/flycast.sym 2>/dev/null
|
||||
strip artifact/bin/flycast
|
||||
shell/linux/make-appimage.sh . artifact/bin appimage
|
||||
mv flycast-x86_64.AppImage artifact/bin
|
||||
rm artifact/bin/flycast
|
||||
if: matrix.config.name == 'x86_64-pc-linux-gnu'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: flycast-${{ matrix.config.name }}
|
||||
path: artifact/bin
|
||||
|
||||
- name: Package app (macos)
|
||||
run: |
|
||||
cd artifact/bin
|
||||
zip -rm flycast.app.zip Flycast.app
|
||||
if: matrix.config.name == 'apple-darwin'
|
||||
|
||||
- name: Package app (windows)
|
||||
run: |
|
||||
powershell Compress-Archive artifact/bin/flycast.exe artifact/bin/flycast.zip
|
||||
rm artifact/bin/flycast.exe
|
||||
if: matrix.config.name == 'x86_64-w64-mingw32'
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
aws-region: us-east-2
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push' && matrix.config.destDir != ''
|
||||
|
||||
- name: Upload to S3
|
||||
run: aws s3 sync artifact/bin s3://flycast-builds/${{ matrix.config.destDir }}/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --follow-symlinks
|
||||
shell: bash
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
|
||||
- name: Setup Sentry CLI
|
||||
uses: mathieu-bour/setup-sentry-cli@v1
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
with:
|
||||
url: https://sentry.io
|
||||
token: ${{ env.SENTRY_TOKEN }}
|
||||
organization: flycast
|
||||
project: minidump
|
||||
if: ${{ env.SENTRY_TOKEN != '' }}
|
||||
|
||||
- name: Upload symbols to Sentry (Windows, macOS, Linux)
|
||||
run: |
|
||||
VERSION=$(git describe --tags --always)
|
||||
sentry-cli releases new "$VERSION"
|
||||
sentry-cli releases set-commits "$VERSION" --auto
|
||||
sentry-cli debug-files upload symbols
|
||||
shell: bash
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
if: ${{ env.SENTRY_TOKEN != '' && (matrix.config.name == 'x86_64-w64-mingw32' || matrix.config.name == 'apple-darwin' || matrix.config.name == 'x86_64-pc-linux-gnu') }}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Prepare source texts & upload them to Crowdin
|
||||
|
||||
name: Crowdin Source Texts Upload
|
||||
|
||||
# on change to the English texts
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'shell/libretro/libretro_core_options.h'
|
||||
|
||||
jobs:
|
||||
upload_source_file:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 18
|
||||
distribution: zulu
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Upload Source
|
||||
shell: bash
|
||||
env:
|
||||
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
|
||||
run: |
|
||||
python3 intl/upload_workflow.py $CROWDIN_API_KEY "flyinghead-flycast" "shell/libretro/libretro_core_options.h"
|
||||
@@ -0,0 +1,49 @@
|
||||
# Download translations form Crowdin & Recreate libretro_core_options_intl.h
|
||||
|
||||
name: Crowdin Translation Integration
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# please choose a random time & weekday to avoid all repos synching at the same time
|
||||
- cron: '15 22 * * 5' # Fridays at 10:15 PM, UTC
|
||||
|
||||
jobs:
|
||||
create_intl_file:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 18
|
||||
distribution: zulu
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
|
||||
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
|
||||
|
||||
- name: Create intl file
|
||||
shell: bash
|
||||
env:
|
||||
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
|
||||
run: |
|
||||
python3 intl/download_workflow.py $CROWDIN_API_KEY "flyinghead-flycast" "shell/libretro/libretro_core_options_intl.h"
|
||||
|
||||
- name: Commit files
|
||||
run: |
|
||||
git config --local user.email "[email protected]"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git add intl/*_workflow.py "shell/libretro/libretro_core_options_intl.h"
|
||||
git commit -m "Fetch translations & Recreate libretro_core_options_intl.h"
|
||||
|
||||
- name: GitHub Push
|
||||
uses: ad-m/[email protected]
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
@@ -0,0 +1,59 @@
|
||||
name: Nintendo Switch CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ubuntu-latest
|
||||
container: devkitpro/devkita64:20220128
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {name: standalone, destDir: switch}
|
||||
- {name: libretro, cmakeArgs: -DLIBRETRO=ON}
|
||||
|
||||
steps:
|
||||
- name: Set up build environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install awscli ccache ninja-build
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-switch-${{ matrix.config.name }}-${{ github.sha }}
|
||||
restore-keys: ccache-switch-${{ matrix.config.name }}-
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
$DEVKITPRO/portlibs/switch/bin/aarch64-none-elf-cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=artifact -G Ninja ${{ matrix.config.cmakeArgs }}
|
||||
cmake --build build --config Release --target install
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: flycast-switch-${{ matrix.config.name }}
|
||||
path: artifact/bin
|
||||
|
||||
- name: Package app
|
||||
run: zip -m artifact/bin/flycast.nro.zip artifact/bin/flycast.nro
|
||||
if: hashFiles('artifact/bin/flycast.nro') != ''
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
aws-region: us-east-2
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push' && matrix.config.destDir != ''
|
||||
|
||||
- name: Upload to S3
|
||||
run: aws s3 sync artifact/bin s3://flycast-builds/${{ matrix.config.destDir }}/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --follow-symlinks
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
@@ -0,0 +1,69 @@
|
||||
name: Windows UWP CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg/bincache
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: bootstrap vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
mkdir vcpkg\bincache
|
||||
vcpkg\bootstrap-vcpkg.bat
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: vcpkg-${{ hashFiles( 'vcpkg.json' ) }}
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.22000.0 -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake
|
||||
cmake --build build --config Release --parallel 2
|
||||
shell: cmd
|
||||
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Package app
|
||||
run: |
|
||||
mkdir build\artifact
|
||||
cd build\AppPackages\flycast\flycast_*_x64_Test
|
||||
mkdir tmp
|
||||
ren *.msix flycast.msix
|
||||
makeappx.exe unpack /p .\flycast.msix /d tmp
|
||||
copy ..\..\..\Release\*.dll tmp
|
||||
makeappx pack /d tmp /p ..\..\..\artifact\flycast.appx
|
||||
|
||||
- name: Sign app
|
||||
run: signtool sign /f shell\uwp\sign_cert.pfx /p '${{ secrets.SIGN_CERT_PWD }}' /v /fd SHA256 build\artifact\flycast.appx
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: flycast-uwp
|
||||
path: build/artifact
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
aws-region: us-east-2
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
|
||||
|
||||
- name: Upload to S3
|
||||
run: aws s3 sync build/artifact s3://flycast-builds/xbox/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --follow-symlinks
|
||||
shell: bash
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
+11
-68
@@ -1,76 +1,19 @@
|
||||
.DS_Store
|
||||
*.class
|
||||
*.orig
|
||||
*build_obj
|
||||
Workdir/data
|
||||
Workdir/reicast*
|
||||
Workdir/vmu*
|
||||
Workdir/webui*
|
||||
Workdir/emu.cfg
|
||||
Workdir/lib*ant.properties
|
||||
build/
|
||||
artifact/
|
||||
|
||||
# iOS General
|
||||
# macOS
|
||||
.DS_Store
|
||||
*/build/*
|
||||
**/build/*
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.hmap
|
||||
emulator.xccheckout
|
||||
reicast.xccheckout
|
||||
build/*
|
||||
*.so
|
||||
*Karen_angelXwind*
|
||||
local.properties
|
||||
ant.properties
|
||||
*build_obj
|
||||
*.d
|
||||
Workdir/data
|
||||
Workdir/reicast*
|
||||
Workdir/vmu*
|
||||
Workdir/webui*
|
||||
Workdir/emu.cfg
|
||||
Workdir/lib*ant.properties
|
||||
reicast-ios.xccheckout
|
||||
|
||||
# Linux General
|
||||
shell/linux/.map
|
||||
shell/linux/nosym-reicast.elf
|
||||
shell/linux/reicast.elf
|
||||
shell/linux/reicast_naomi.elf
|
||||
shell/linux/reicast_awave.elf
|
||||
shell/linux/dispframe.elf
|
||||
shell/apple/emulator-ios/OpenMP/OpenMP.xcframework
|
||||
|
||||
# Visual Studio
|
||||
generated
|
||||
.vs
|
||||
|
||||
# Android General
|
||||
bin/
|
||||
gen/
|
||||
obj/
|
||||
build/*
|
||||
*.so
|
||||
local.properties
|
||||
ant.properties
|
||||
|
||||
# Android Studio
|
||||
.gradle
|
||||
*.iml
|
||||
.externalNativeBuild
|
||||
gradle.properties
|
||||
shell/android-studio/reicast/src/main/assets/build
|
||||
.vs/
|
||||
.vscode/
|
||||
out/
|
||||
|
||||
# JetBrains IDES
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
|
||||
# Dependencies from .gitmodules
|
||||
core/deps/breakpad/
|
||||
core/deps/glslang/
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
|
||||
|
||||
##############################################################################
|
||||
################################# BOILERPLATE ################################
|
||||
##############################################################################
|
||||
|
||||
# Core definitions
|
||||
.core-defs:
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
CORENAME: flycast
|
||||
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
.core-defs-linux:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
.core-defs-osx-x64:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64
|
||||
EXTRA_PATH: Release
|
||||
|
||||
.core-defs-osx-arm64:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release
|
||||
EXTRA_PATH: Release
|
||||
|
||||
.core-defs-ios-arm64:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
.core-defs-android:
|
||||
extends: .core-defs
|
||||
script:
|
||||
- cmake $CORE_ARGS -DANDROID_PLATFORM=android-$API_LEVEL -DCMAKE_TOOLCHAIN_FILE=$NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_STL=c++_static -DANDROID_ABI=$ANDROID_ABI -DANDROID_ARM_MODE=arm "$CMAKE_SOURCE_ROOT" -B$BUILD_DIR
|
||||
- cmake --build $BUILD_DIR --target ${CORENAME}_libretro --config Release -- -j $NUMPROC
|
||||
- mv $BUILD_DIR/${CORENAME}_libretro.so $LIBNAME
|
||||
- if [ $STRIP_CORE_LIB -eq 1 ]; then $NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip $LIBNAME; fi
|
||||
variables:
|
||||
API_LEVEL: 18
|
||||
|
||||
# Inclusion templates, required for the build to work
|
||||
include:
|
||||
################################## DESKTOPS ################################
|
||||
# Windows
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-cmake-mingw.yml'
|
||||
|
||||
# MacOS
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: 'osx-cmake-x86.yml'
|
||||
|
||||
# MacOS arm64
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: 'osx-cmake-arm64.yml'
|
||||
|
||||
# Linux
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/linux-cmake.yml'
|
||||
|
||||
################################## CELLULAR ################################
|
||||
# Android
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/android-cmake.yml'
|
||||
|
||||
# iOS arm64
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios-cmake.yml'
|
||||
|
||||
################################## CONSOLES ################################
|
||||
# Nintendo Switch
|
||||
# - project: 'libretro-infrastructure/ci-templates'
|
||||
# file: '/libnx-static.yml'
|
||||
|
||||
# tvOS arm64
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/tvos-cmake.yml'
|
||||
|
||||
# Stages for building
|
||||
stages:
|
||||
- build-prepare
|
||||
- build-shared
|
||||
# - build-static
|
||||
|
||||
##############################################################################
|
||||
#################################### STAGES ##################################
|
||||
##############################################################################
|
||||
#
|
||||
################################### DESKTOPS #################################
|
||||
# Windows 64-bit
|
||||
libretro-build-windows-x64:
|
||||
extends:
|
||||
- .libretro-windows-cmake-x86_64
|
||||
- .core-defs
|
||||
|
||||
# Windows 32-bit
|
||||
libretro-build-windows-i686:
|
||||
extends:
|
||||
- .libretro-windows-cmake-x86
|
||||
- .core-defs
|
||||
|
||||
# Linux 64-bit
|
||||
libretro-build-linux-x64:
|
||||
extends:
|
||||
- .libretro-linux-cmake-x86_64
|
||||
- .core-defs-linux
|
||||
|
||||
# Linux 32-bit
|
||||
libretro-build-linux-i686:
|
||||
extends:
|
||||
- .libretro-linux-cmake-x86
|
||||
- .core-defs-linux
|
||||
|
||||
# MacOS 64-bit
|
||||
libretro-build-osx-x64:
|
||||
extends:
|
||||
- .libretro-osx-cmake-x86
|
||||
- .core-defs-osx-x64
|
||||
|
||||
# MacOS arm 64-bit
|
||||
libretro-build-osx-arm64:
|
||||
extends:
|
||||
- .libretro-osx-cmake-arm64
|
||||
- .core-defs-osx-arm64
|
||||
|
||||
################################### CELLULAR #################################
|
||||
# Android ARMv7a
|
||||
android-armeabi-v7a:
|
||||
extends:
|
||||
- .libretro-android-cmake-armeabi-v7a
|
||||
- .core-defs-android
|
||||
|
||||
# Android ARMv8a
|
||||
android-arm64-v8a:
|
||||
extends:
|
||||
- .libretro-android-cmake-arm64-v8a
|
||||
- .core-defs-android
|
||||
|
||||
# Android 64-bit x86
|
||||
android-x86_64:
|
||||
extends:
|
||||
- .libretro-android-cmake-x86_64
|
||||
- .core-defs-android
|
||||
|
||||
# Android 32-bit x86
|
||||
android-x86:
|
||||
extends:
|
||||
- .libretro-android-cmake-x86
|
||||
- .core-defs-android
|
||||
|
||||
libretro-build-ios-arm64:
|
||||
extends:
|
||||
- .libretro-ios-cmake-arm64
|
||||
- .core-defs-ios-arm64
|
||||
|
||||
################################### CONSOLES #################################
|
||||
# Nintendo Switch
|
||||
#libretro-build-libnx-aarch64:
|
||||
# extends:
|
||||
# - .libretro-libnx-static-retroarch-master
|
||||
# - .core-defs
|
||||
|
||||
# tvOS arm64
|
||||
libretro-build-tvos-arm64:
|
||||
extends:
|
||||
- .libretro-tvos-cmake-arm64
|
||||
- .core-defs-ios-arm64
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
[submodule "core/deps/SDL"]
|
||||
path = core/deps/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "core/deps/libchdr"]
|
||||
path = core/deps/libchdr
|
||||
url = https://github.com/flyinghead/libchdr.git
|
||||
[submodule "core/deps/luabridge"]
|
||||
path = core/deps/luabridge
|
||||
url = https://github.com/vinniefalco/LuaBridge.git
|
||||
[submodule "core/deps/breakpad"]
|
||||
path = core/deps/breakpad
|
||||
url = https://github.com/flyinghead/mingw-breakpad
|
||||
[submodule "core/deps/Vulkan-Headers"]
|
||||
path = core/deps/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "core/deps/VulkanMemoryAllocator"]
|
||||
path = core/deps/VulkanMemoryAllocator
|
||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||
[submodule "core/deps/glslang"]
|
||||
path = core/deps/glslang
|
||||
url = https://github.com/KhronosGroup/glslang.git
|
||||
[submodule "core/deps/oboe"]
|
||||
path = core/deps/oboe
|
||||
url = https://github.com/google/oboe.git
|
||||
[submodule "core/deps/Syphon"]
|
||||
path = core/deps/Syphon
|
||||
url=https://github.com/vkedwardli/Syphon-Framework.git
|
||||
[submodule "core/deps/Spout"]
|
||||
path = core/deps/Spout
|
||||
url = https://github.com/vkedwardli/Spout2.git
|
||||
@@ -1,4 +0,0 @@
|
||||
extraction:
|
||||
cpp:
|
||||
index:
|
||||
build_command: cd shell/linux && make
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
language: android
|
||||
dist: trusty
|
||||
android:
|
||||
components:
|
||||
- platform-tools
|
||||
- tools
|
||||
- build-tools-27.0.3
|
||||
- android-25
|
||||
- extra-google-m2repository
|
||||
- extra-android-m2repository
|
||||
licenses:
|
||||
- android-sdk-preview-license-.+
|
||||
- android-sdk-license-.+
|
||||
sudo: false
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.gradle/caches/"
|
||||
- "$HOME/.gradle/wrapper/"
|
||||
- "$HOME/.android/build-cache"
|
||||
before_install:
|
||||
- GIT_HASH=`git log --pretty=format:'%h' -n 1`
|
||||
- GIT_BUILD=`git describe --all --always`-$GIT_HASH
|
||||
- mkdir "$ANDROID_HOME/licenses" || true
|
||||
- echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
|
||||
- echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
|
||||
- chmod +x shell/android-studio/gradlew
|
||||
install:
|
||||
- sudo apt-get -qq update
|
||||
- touch ~/.android/repositories.cfg
|
||||
- echo y | sdkmanager 'ndk-bundle'
|
||||
- export NDK=ANDROID_NDK=ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
|
||||
- export PATH=${PATH}:$ANDROID_HOME/tools
|
||||
- export PATH=${PATH}:$ANDROID_HOME/platform-tools
|
||||
- export PATH=${PATH}:$NDK
|
||||
- mkdir -p ~/.android
|
||||
before_script:
|
||||
script:
|
||||
- git fetch --depth 250
|
||||
- cd shell/android-studio
|
||||
- export NUMBER_OF_PROCESSORS=2
|
||||
- sudo chmod 755 travis-build.sh
|
||||
- "./travis-build.sh"
|
||||
before_deploy:
|
||||
- cd ../../
|
||||
- mkdir -p artifacts/$GIT_BUILD/
|
||||
- cp shell/android-studio/reicast/build/outputs/apk/dreamcast/debug/reicast-dreamcast-debug.apk artifacts/$GIT_BUILD/flycast-debug-$GIT_HASH.apk
|
||||
deploy:
|
||||
provider: s3
|
||||
access_key_id: AKIAJOZQS4H2PHQWYFCA
|
||||
secret_access_key:
|
||||
secure: $S3_SECRET_KEY
|
||||
bucket: flycast-builds
|
||||
local-dir: artifacts
|
||||
upload-dir: android
|
||||
acl: public_read
|
||||
skip_cleanup: true
|
||||
on:
|
||||
all_branches: true
|
||||
repo: flyinghead/flycast
|
||||
|
||||
+1796
-287
File diff suppressed because it is too large.
Load diff
@@ -1,220 +0,0 @@
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
"environment": "toolchain.generic",
|
||||
"TOOLCHAIN_FILE": "ps4sdk.cmake"
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "win-x86-Debug",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_x86Debug",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x86"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "win-x86-Release",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_x86Release",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x86"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "win-x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_x64Debug",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64_x64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "-DNINJA=1",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "win-x64-Release",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_x64Release",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64_x64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "-DNINJA=1",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "win-x64-Clang-RelWithDebInfo",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_x64Release",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64_x64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"variables": [
|
||||
{
|
||||
"name": "CMAKE_C_COMPILER",
|
||||
"value": "clang-cl.exe"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_CXX_COMPILER",
|
||||
"value": "clang-cl.exe"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// Console SDK's
|
||||
{
|
||||
"name": "PS4 SDK",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_PS4SDK",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"toolchain.generic"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "-DCMAKE_TOOLCHAIN_FILE=${projectDir}\\cmake\\ps4sdk.cmake",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "NSW SDK",
|
||||
"generator": "Ninja",
|
||||
"description": "TemplateDescription_Localize_PS4SDK",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"toolchain.generic"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "-DCMAKE_TOOLCHAIN_FILE=${projectDir}\\cmake\\devkitA64.cmake",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
|
||||
// UWP and VS Gen (temp?)
|
||||
{
|
||||
"name": "uwp-x64-Release",
|
||||
"generator": "Visual Studio 15 2017 Win64",
|
||||
"description": "TemplateDescription_Localize_x64Release",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64_x64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "-DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "win-x64-MSBuild-Release",
|
||||
"generator": "Visual Studio 15 2017 Win64",
|
||||
"description": "TemplateDescription_Localize_x64Release",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"msvc_x64_x64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
//"MINGW64_ROOT": "C:\\msys64\\mingw64",
|
||||
"BIN_ROOT": "${env.MINGW64_ROOT}\\bin",
|
||||
"FLAVOR": "x86_64-w64-mingw32",
|
||||
"TOOLSET_VERSION": "7.3.0",
|
||||
"PATH": "${env.MINGW64_ROOT}\\bin;${env.MINGW64_ROOT}\\..\\usr\\local\\bin;${env.MINGW64_ROOT}\\..\\usr\\bin;${env.MINGW64_ROOT}\\..\\bin;${env.PATH}",
|
||||
"INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\tr1;${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\${env.FLAVOR}",
|
||||
"environment": "mingw_64"
|
||||
}
|
||||
],
|
||||
"name": "Mingw64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [
|
||||
"mingw_64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"variables": [
|
||||
{
|
||||
"name": "CMAKE_C_COMPILER",
|
||||
"value": "${env.BIN_ROOT}\\gcc.exe"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_CXX_COMPILER",
|
||||
"value": "${env.BIN_ROOT}\\g++.exe"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
//"MINGW64_ROOT": "C:\\msys64\\mingw64",
|
||||
"BIN_ROOT": "${env.MINGW64_ROOT}\\bin",
|
||||
"FLAVOR": "x86_64-w64-mingw32",
|
||||
"TOOLSET_VERSION": "7.3.0",
|
||||
"PATH": "${env.MINGW64_ROOT}\\bin;${env.MINGW64_ROOT}\\..\\usr\\local\\bin;${env.MINGW64_ROOT}\\..\\usr\\bin;${env.MINGW64_ROOT}\\..\\bin;${env.PATH}",
|
||||
"INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\tr1;${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\${env.FLAVOR}",
|
||||
"environment": "mingw_64"
|
||||
}
|
||||
],
|
||||
"name": "Mingw64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [
|
||||
"mingw_64"
|
||||
],
|
||||
"buildRoot": "${projectDir}\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\build\\${name}\\install",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"variables": [
|
||||
{
|
||||
"name": "CMAKE_C_COMPILER",
|
||||
"value": "${env.BIN_ROOT}\\gcc.exe"
|
||||
},
|
||||
{
|
||||
"name": "CMAKE_CXX_COMPILER",
|
||||
"value": "${env.BIN_ROOT}\\g++.exe"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,15 +1,59 @@
|
||||
flycast
|
||||
===========
|
||||
**flycast** is a multi-platform Sega Dreamcast, Naomi and Atomiswave emulator derived from [**reicast**](https://reicast.com/)
|
||||
# Flycast
|
||||
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/android.yml)
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/c-cpp.yml)
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/switch.yml)
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml)
|
||||
|
||||

|
||||
|
||||
**Flycast** is a multi-platform Sega Dreamcast, Naomi, Naomi 2, and Atomiswave emulator derived from [**reicast**](https://github.com/skmp/reicast-emulator).
|
||||
|
||||
Information about configuration and supported features can be found on [**TheArcadeStriker's flycast wiki**](https://github.com/TheArcadeStriker/flycast-wiki/wiki).
|
||||
|
||||
Join us on our [**Discord server**](https://discord.gg/X8YWP8w) for a chat.
|
||||
|
||||
Binaries
|
||||
========
|
||||
Get fresh builds for your system [on the builds page](https://flyinghead.github.io/flycast-builds/).
|
||||
## Install
|
||||
|
||||
**New:** Now automated test results are available as well.
|
||||
### Flatpak (Linux )
|
||||
|
||||
Disclaimer
|
||||
==========
|
||||
All code contritbuted to this fork is *not* bound by the Individual Contributor License Agreement of the upstream repository (https://github.com/reicast/reicast-emulator) and shall *not* be considered as a contribution to the upstream repository.
|
||||
1. [Set up Flatpak](https://www.flatpak.org/setup/).
|
||||
|
||||
2. Install Flycast from [Flathub](https://flathub.org/apps/details/org.flycast.Flycast):
|
||||
|
||||
`flatpak install -y org.flycast.Flycast`
|
||||
|
||||
3. Run Flycast:
|
||||
|
||||
`flatpak run org.flycast.Flycast`
|
||||
|
||||
### Homebrew (MacOS )
|
||||
|
||||
1. [Set up Homebrew](https://brew.sh).
|
||||
|
||||
2. Install Flycast via Homebrew:
|
||||
|
||||
`brew install --cask flycast`
|
||||
|
||||
### Xbox One/Series 
|
||||
|
||||
Grab the latest build from [**the builds page**](https://flyinghead.github.io/flycast-builds/), or the [**GitHub Actions**](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml). Then install it using the **Xbox Device Portal**.
|
||||
|
||||
### Binaries      
|
||||
|
||||
Get fresh builds for your system [**on the builds page**](https://flyinghead.github.io/flycast-builds/).
|
||||
|
||||
**New:** Now automated test results are available as well.
|
||||
|
||||
### Build instructions:
|
||||
`git clone https://github.com/flyinghead/flycast.git`
|
||||
|
||||
`cd flycast`
|
||||
|
||||
`git submodule update --init --recursive`
|
||||
|
||||
`mkdir build && cd build`
|
||||
|
||||
`cmake ..`
|
||||
|
||||
`make`
|
||||
@@ -1,46 +0,0 @@
|
||||
version: git-{branch}-{build}
|
||||
image: Visual Studio 2017
|
||||
|
||||
configuration:
|
||||
- fast
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
before_build:
|
||||
- cmd: >-
|
||||
set BUILD_PATH=shell\linux
|
||||
|
||||
set EXTRA_PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin\
|
||||
|
||||
set PATH=%EXTRA_PATH%;%PATH%
|
||||
|
||||
if not exist %BUILD_PATH% (mkdir %BUILD_PATH%)
|
||||
|
||||
cd %BUILD_PATH%
|
||||
|
||||
build_script:
|
||||
- cmd: >-
|
||||
if "%CONFIGURATION%"=="fast" (mingw32-make platform=win32)
|
||||
|
||||
after_build:
|
||||
- cmd: >-
|
||||
if "%CONFIGURATION%"=="fast" (cd ..\.. && set EXE_PATH=shell\linux\nosym-reicast.exe)
|
||||
|
||||
mkdir artifacts
|
||||
|
||||
move %EXE_PATH% artifacts\flycast-win_%PLATFORM%-%CONFIGURATION%-%APPVEYOR_REPO_COMMIT%.exe
|
||||
|
||||
artifacts:
|
||||
- path: artifacts
|
||||
name: flycast-win_$(PLATFORM)-$(CONFIGURATION)-$(APPVEYOR_REPO_COMMIT)
|
||||
deploy:
|
||||
- provider: S3
|
||||
access_key_id: AKIAJOZQS4H2PHQWYFCA
|
||||
secret_access_key:
|
||||
secure: Y/QobuGrBsa137sbi9a+UnvSLqpWITTCp5yFTgDJ4i1Gduyi9V7i/g3zLZ4s2J7d
|
||||
bucket: flycast-builds
|
||||
folder: 'win/heads/$(APPVEYOR_REPO_BRANCH)-$(APPVEYOR_REPO_COMMIT)'
|
||||
artifact: flycast-win_$(PLATFORM)-$(CONFIGURATION)-$(APPVEYOR_REPO_COMMIT)
|
||||
region: us-east-2
|
||||
set_public: true
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
---
|
||||
format_version: '7'
|
||||
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
|
||||
project_type: macos
|
||||
trigger_map:
|
||||
- push_branch: "*"
|
||||
workflow: deploy
|
||||
- pull_request_source_branch: "*"
|
||||
workflow: deploy
|
||||
workflows:
|
||||
deploy:
|
||||
envs:
|
||||
- opts:
|
||||
is_expand: false
|
||||
BITRISE_SCHEME: reicast-osx
|
||||
steps:
|
||||
- [email protected]:
|
||||
run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
|
||||
- brew-install:
|
||||
title: Install SDL2
|
||||
inputs:
|
||||
- packages: "sdl2"
|
||||
- [email protected]: {}
|
||||
- [email protected]: {}
|
||||
- [email protected]:
|
||||
inputs:
|
||||
- content: |
|
||||
#!/bin/bash
|
||||
export GIT_HASH=`git log --pretty=format:'%h' -n 1`
|
||||
envman add --key GIT_HASH --value $GIT_HASH
|
||||
envman add --key GIT_BUILD --value `git describe --all --always | sed 's/remotes\/origin/heads/'`-$GIT_HASH
|
||||
- [email protected]: {}
|
||||
- [email protected]:
|
||||
inputs:
|
||||
- project_path: "$BITRISE_PROJECT_PATH"
|
||||
- [email protected]:
|
||||
inputs:
|
||||
- project_path: "$BITRISE_PROJECT_PATH"
|
||||
- scheme: "$BITRISE_SCHEME"
|
||||
- export_method: "$BITRISE_EXPORT_METHOD"
|
||||
- [email protected]:
|
||||
inputs:
|
||||
- aws_access_key: AKIAJOZQS4H2PHQWYFCA
|
||||
- aws_secret_key: "$S3_SECRET_KEY"
|
||||
- bucket_name: flycast-builds
|
||||
- path_in_bucket: osx/$GIT_BUILD
|
||||
- file_path: "$BITRISE_EXPORTED_FILE_PATH"
|
||||
- [email protected]: {}
|
||||
app:
|
||||
envs:
|
||||
- opts:
|
||||
is_expand: false
|
||||
BITRISE_PROJECT_PATH: shell/apple/reicast.xcworkspace
|
||||
- opts:
|
||||
is_expand: false
|
||||
BITRISE_EXPORT_METHOD: none
|
||||
+8
-7
@@ -1,4 +1,4 @@
|
||||
# core/libdreamcast
|
||||
# core
|
||||
===========
|
||||
|
||||
Here lies the core of our codebase. Everything that's OS inspecific rests here.
|
||||
@@ -6,10 +6,11 @@ Here lies the core of our codebase. Everything that's OS inspecific rests here.
|
||||
|
||||
### Some rudimentary categories are:
|
||||
- hw -- DC Hardware Components Implementation
|
||||
- nullDC.cpp -- NullDC, thy mighty child (also referenced as "debugger")
|
||||
- emitter -- Cookie machine
|
||||
- khronos -- Vulkan stuff
|
||||
- oslib -- Codebase abstraction effort
|
||||
- nullDC.cpp -- Main entry points
|
||||
- oslib -- Audio drivers
|
||||
- cfg -- Configuration backend structure
|
||||
- reios -- (Our)Implementation of the DreamCast BIOS (Not functional)
|
||||
- deps -- External C libraries (hackish, hand-written versions)
|
||||
- reios -- (Our) Implementation of the DreamCast BIOS
|
||||
- deps -- External dependencies
|
||||
- imgread -- Content drivers
|
||||
- rec-* -- Recompilers
|
||||
- rend -- Graphics renderers and UI
|
||||
@@ -23,21 +23,28 @@
|
||||
#include "deps/lzma/7zCrc.h"
|
||||
#include "deps/lzma/Alloc.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define kInputBufSize ((size_t)1 << 18)
|
||||
|
||||
static bool crc_tables_generated;
|
||||
|
||||
bool SzArchive::Open(const char* path)
|
||||
bool SzArchive::Open(FILE *file)
|
||||
{
|
||||
SzArEx_Init(&szarchive);
|
||||
|
||||
if (InFile_Open(&archiveStream.file, path))
|
||||
return false;
|
||||
File_Close(&archiveStream.file);
|
||||
File_Construct(&archiveStream.file);
|
||||
archiveStream.file.file = file;
|
||||
|
||||
FileInStream_CreateVTable(&archiveStream);
|
||||
LookToRead2_CreateVTable(&lookStream, false);
|
||||
LookToRead2_CreateVTable(&lookStream, 0);
|
||||
lookStream.buf = (Byte *)ISzAlloc_Alloc(&g_Alloc, kInputBufSize);
|
||||
if (lookStream.buf == NULL)
|
||||
{
|
||||
File_Close(&archiveStream.file);
|
||||
return false;
|
||||
}
|
||||
lookStream.bufSize = kInputBufSize;
|
||||
lookStream.realStream = &archiveStream.vt;
|
||||
LookToRead2_Init(&lookStream);
|
||||
@@ -55,14 +62,14 @@ bool SzArchive::Open(const char* path)
|
||||
ArchiveFile* SzArchive::OpenFile(const char* name)
|
||||
{
|
||||
u16 fname[512];
|
||||
for (int i = 0; i < szarchive.NumFiles; i++)
|
||||
for (UInt32 i = 0; i < szarchive.NumFiles; i++)
|
||||
{
|
||||
if (SzArEx_IsDir(&szarchive, i))
|
||||
continue;
|
||||
|
||||
int len = SzArEx_GetFileNameUtf16(&szarchive, i, fname);
|
||||
size_t len = SzArEx_GetFileNameUtf16(&szarchive, i, fname);
|
||||
char szname[512];
|
||||
int j = 0;
|
||||
size_t j = 0;
|
||||
for (; j < len && j < sizeof(szname) - 1; j++)
|
||||
szname[j] = fname[j];
|
||||
szname[j] = 0;
|
||||
@@ -80,6 +87,30 @@ ArchiveFile* SzArchive::OpenFile(const char* name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArchiveFile* SzArchive::OpenFileByCrc(u32 crc)
|
||||
{
|
||||
if (crc == 0)
|
||||
return NULL;
|
||||
for (UInt32 i = 0; i < szarchive.NumFiles; i++)
|
||||
{
|
||||
unsigned isDir = SzArEx_IsDir(&szarchive, i);
|
||||
if (isDir)
|
||||
continue;
|
||||
|
||||
if (crc != szarchive.CRCs.Vals[i])
|
||||
continue;
|
||||
|
||||
size_t offset = 0;
|
||||
size_t out_size_processed = 0;
|
||||
SRes res = SzArEx_Extract(&szarchive, &lookStream.vt, i, &block_idx, &out_buffer, &out_buffer_size, &offset, &out_size_processed, &g_Alloc, &g_Alloc);
|
||||
if (res != SZ_OK)
|
||||
return NULL;
|
||||
|
||||
return new SzArchiveFile(out_buffer, offset, (u32)out_size_processed);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SzArchive::~SzArchive()
|
||||
{
|
||||
if (lookStream.buf != NULL)
|
||||
|
||||
+12
-11
@@ -18,14 +18,15 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CORE_ARCHIVE_7ZARCHIVE_H_
|
||||
#define CORE_ARCHIVE_7ZARCHIVE_H_
|
||||
#pragma once
|
||||
|
||||
#include "archive.h"
|
||||
#include "deps/lzma/7z.h"
|
||||
#include "deps/lzma/7zFile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
class SzArchive : public Archive
|
||||
{
|
||||
public:
|
||||
@@ -33,13 +34,15 @@ public:
|
||||
memset(&archiveStream, 0, sizeof(archiveStream));
|
||||
memset(&lookStream, 0, sizeof(lookStream));
|
||||
}
|
||||
virtual ~SzArchive();
|
||||
~SzArchive() override;
|
||||
|
||||
virtual ArchiveFile* OpenFile(const char* name) override;
|
||||
ArchiveFile* OpenFile(const char* name) override;
|
||||
ArchiveFile *OpenFileByCrc(u32 crc) override;
|
||||
|
||||
protected:
|
||||
bool Open(FILE *file) override;
|
||||
|
||||
private:
|
||||
virtual bool Open(const char* path) override;
|
||||
|
||||
CSzArEx szarchive;
|
||||
UInt32 block_idx; /* it can have any value before first call (if outBuffer = 0) */
|
||||
Byte *out_buffer; /* it must be 0 before first call for each new archive. */
|
||||
@@ -53,9 +56,9 @@ class SzArchiveFile : public ArchiveFile
|
||||
{
|
||||
public:
|
||||
SzArchiveFile(u8 *data, u32 offset, u32 length) : data(data), offset(offset), length(length) {}
|
||||
virtual u32 Read(void *buffer, u32 length) override
|
||||
u32 Read(void *buffer, u32 length) override
|
||||
{
|
||||
length = min(length, this->length);
|
||||
length = std::min(length, this->length);
|
||||
memcpy(buffer, data + offset, length);
|
||||
return length;
|
||||
}
|
||||
@@ -65,5 +68,3 @@ private:
|
||||
u32 offset;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
#endif /* CORE_ARCHIVE_7ZARCHIVE_H_ */
|
||||
@@ -25,10 +25,19 @@ ZipArchive::~ZipArchive()
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
bool ZipArchive::Open(const char* path)
|
||||
bool ZipArchive::Open(FILE *file)
|
||||
{
|
||||
zip = zip_open(path, 0, NULL);
|
||||
return (zip != NULL);
|
||||
zip_error_t error;
|
||||
zip_source_t *source = zip_source_filep_create(file, 0, -1, &error);
|
||||
if (source == nullptr)
|
||||
{
|
||||
std::fclose(file);
|
||||
return false;
|
||||
}
|
||||
zip = zip_open_from_source(source, 0, NULL);
|
||||
if (zip == nullptr)
|
||||
zip_source_free(source);
|
||||
return zip != nullptr;
|
||||
}
|
||||
|
||||
ArchiveFile* ZipArchive::OpenFile(const char* name)
|
||||
@@ -40,7 +49,60 @@ ArchiveFile* ZipArchive::OpenFile(const char* name)
|
||||
return new ZipArchiveFile(zip_file);
|
||||
}
|
||||
|
||||
struct zip_file *zip_fopen_by_crc(struct zip *za, u32 crc, int flags)
|
||||
{
|
||||
zip_uint64_t i;
|
||||
zip_int64_t n;
|
||||
struct zip_stat stat;
|
||||
|
||||
if (crc == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = zip_get_num_entries(za, 0);
|
||||
for (i = 0; i < (zip_uint64_t)n; i++) {
|
||||
if (zip_stat_index(za, i, flags, &stat) < -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stat.crc == crc) {
|
||||
return zip_fopen_index(za, i, flags);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArchiveFile* ZipArchive::OpenFileByCrc(u32 crc)
|
||||
{
|
||||
zip_file *zip_file = zip_fopen_by_crc(zip, crc, 0);
|
||||
if (zip_file == NULL)
|
||||
return NULL;
|
||||
|
||||
return new ZipArchiveFile(zip_file);
|
||||
}
|
||||
|
||||
u32 ZipArchiveFile::Read(void* buffer, u32 length)
|
||||
{
|
||||
return zip_fread(zip_file, buffer, length);
|
||||
}
|
||||
|
||||
bool ZipArchive::Open(const void *data, size_t size)
|
||||
{
|
||||
zip_error_t error;
|
||||
zip_source_t *source = zip_source_buffer_create(data, size, 0, &error);
|
||||
if (source == nullptr)
|
||||
return false;
|
||||
zip = zip_open_from_source(source, 0, NULL);
|
||||
if (zip == nullptr)
|
||||
zip_source_free(source);
|
||||
return zip != nullptr;
|
||||
}
|
||||
|
||||
ArchiveFile *ZipArchive::OpenFirstFile()
|
||||
{
|
||||
zip_file *zipFile = zip_fopen_index(zip, 0, 0);
|
||||
if (zipFile == nullptr)
|
||||
return nullptr;
|
||||
return new ZipArchiveFile(zipFile);
|
||||
}
|
||||
+13
-11
@@ -18,23 +18,27 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef CORE_ARCHIVE_ZIPARCHIVE_H_
|
||||
#define CORE_ARCHIVE_ZIPARCHIVE_H_
|
||||
#include "archive.h"
|
||||
#include "deps/libzip/zip.h"
|
||||
#include <zip.h>
|
||||
|
||||
class ZipArchive : public Archive
|
||||
{
|
||||
public:
|
||||
ZipArchive() : zip(NULL) {}
|
||||
virtual ~ZipArchive();
|
||||
~ZipArchive() override;
|
||||
|
||||
virtual ArchiveFile* OpenFile(const char* name) override;
|
||||
ArchiveFile* OpenFile(const char* name) override;
|
||||
ArchiveFile* OpenFileByCrc(u32 crc) override;
|
||||
|
||||
bool Open(const void *data, size_t size);
|
||||
ArchiveFile *OpenFirstFile();
|
||||
|
||||
protected:
|
||||
bool Open(FILE *file) override;
|
||||
|
||||
private:
|
||||
virtual bool Open(const char* path) override;
|
||||
|
||||
struct zip *zip;
|
||||
};
|
||||
|
||||
@@ -42,11 +46,9 @@ class ZipArchiveFile : public ArchiveFile
|
||||
{
|
||||
public:
|
||||
ZipArchiveFile(struct zip_file *zip_file) : zip_file(zip_file) {}
|
||||
virtual ~ZipArchiveFile() { zip_fclose(zip_file); }
|
||||
virtual u32 Read(void* buffer, u32 length) override;
|
||||
~ZipArchiveFile() override { zip_fclose(zip_file); }
|
||||
u32 Read(void* buffer, u32 length) override;
|
||||
|
||||
private:
|
||||
struct zip_file *zip_file;
|
||||
};
|
||||
|
||||
#endif /* CORE_ARCHIVE_ZIPARCHIVE_H_ */
|
||||
+49
-16
@@ -20,30 +20,63 @@
|
||||
*/
|
||||
|
||||
#include "archive.h"
|
||||
#ifndef _MSC_VER
|
||||
#include "7zArchive.h"
|
||||
#include "ZipArchive.h"
|
||||
#endif
|
||||
#include "oslib/storage.h"
|
||||
|
||||
Archive *OpenArchive(const char *path)
|
||||
Archive *OpenArchive(const std::string& path)
|
||||
{
|
||||
std::string base_path(path);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
Archive *sz_archive = new SzArchive();
|
||||
if (sz_archive->Open(base_path.c_str()) || sz_archive->Open((base_path + ".7z").c_str()) || sz_archive->Open((base_path + ".7Z").c_str()))
|
||||
return sz_archive;
|
||||
delete sz_archive;
|
||||
|
||||
FILE *file = nullptr;
|
||||
hostfs::FileInfo fileInfo;
|
||||
try {
|
||||
fileInfo = hostfs::storage().getFileInfo(path);
|
||||
if (!fileInfo.isDirectory)
|
||||
file = hostfs::storage().openFile(path, "rb");
|
||||
} catch (const hostfs::StorageException& e) {
|
||||
}
|
||||
if (file == nullptr)
|
||||
{
|
||||
file = hostfs::storage().openFile(path + ".7z", "rb");
|
||||
if (file == nullptr)
|
||||
file = hostfs::storage().openFile(path + ".7Z", "rb");
|
||||
}
|
||||
if (file != nullptr)
|
||||
{
|
||||
Archive *sz_archive = new SzArchive();
|
||||
if (sz_archive->Open(file))
|
||||
return sz_archive;
|
||||
delete sz_archive;
|
||||
file = nullptr;
|
||||
}
|
||||
// Retry as a zip file
|
||||
try {
|
||||
if (!fileInfo.isDirectory)
|
||||
file = hostfs::storage().openFile(path, "rb");
|
||||
} catch (const hostfs::StorageException& e) {
|
||||
}
|
||||
if (file == nullptr)
|
||||
{
|
||||
file = hostfs::storage().openFile(path + ".zip", "rb");
|
||||
if (file == nullptr)
|
||||
{
|
||||
file = hostfs::storage().openFile(path + ".ZIP", "rb");
|
||||
if (file == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Archive *zip_archive = new ZipArchive();
|
||||
if (zip_archive->Open(base_path.c_str()) || zip_archive->Open((base_path + ".zip").c_str()) || zip_archive->Open((base_path + ".ZIP").c_str()))
|
||||
if (zip_archive->Open(file))
|
||||
return zip_archive;
|
||||
delete zip_archive;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Archive::Open(const char* path)
|
||||
{
|
||||
FILE *file = nowide::fopen(path, "rb");
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
return Open(file);
|
||||
}
|
||||
|
||||
+10
-9
@@ -18,30 +18,31 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CORE_ARCHIVE_ARCHIVE_H_
|
||||
#define CORE_ARCHIVE_ARCHIVE_H_
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class ArchiveFile
|
||||
{
|
||||
public:
|
||||
virtual ~ArchiveFile() {}
|
||||
virtual ~ArchiveFile() = default;
|
||||
virtual u32 Read(void *buffer, u32 length) = 0;
|
||||
};
|
||||
|
||||
class Archive
|
||||
{
|
||||
public:
|
||||
virtual ~Archive() {}
|
||||
virtual ~Archive() = default;
|
||||
virtual ArchiveFile *OpenFile(const char *name) = 0;
|
||||
virtual ArchiveFile *OpenFileByCrc(u32 crc) = 0;
|
||||
|
||||
friend Archive *OpenArchive(const char *path);
|
||||
protected:
|
||||
virtual bool Open(FILE *file) = 0;
|
||||
|
||||
private:
|
||||
virtual bool Open(const char *name) = 0;
|
||||
bool Open(const char *name);
|
||||
|
||||
friend Archive *OpenArchive(const std::string& path);
|
||||
};
|
||||
|
||||
Archive *OpenArchive(const char *path);
|
||||
|
||||
#endif
|
||||
Archive *OpenArchive(const std::string& path);
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
Copyright 2020 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rzip.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
const u8 RZipHeader[8] = { '#', 'R', 'Z', 'I', 'P', 'v', 1, '#' };
|
||||
|
||||
bool RZipFile::Open(const std::string& path, bool write)
|
||||
{
|
||||
verify(file == nullptr);
|
||||
this->write = write;
|
||||
|
||||
file = nowide::fopen(path.c_str(), write ? "wb" : "rb");
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
if (!write)
|
||||
{
|
||||
u8 header[sizeof(RZipHeader)];
|
||||
if (std::fread(header, sizeof(header), 1, file) != 1
|
||||
|| memcmp(header, RZipHeader, sizeof(header))
|
||||
|| std::fread(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|
||||
|| std::fread(&size, sizeof(size), 1, file) != 1)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
// savestates created on 32-bit platforms used to have a 32-bit size
|
||||
if (size >> 32 != 0)
|
||||
{
|
||||
size &= 0xffffffff;
|
||||
std::fseek(file, -4, SEEK_CUR);
|
||||
}
|
||||
chunk = new u8[maxChunkSize];
|
||||
chunkIndex = 0;
|
||||
chunkSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxChunkSize = 1_MB;
|
||||
if (std::fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|
||||
|| std::fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|
||||
|| std::fwrite(&size, sizeof(size), 1, file) != 1)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RZipFile::Close()
|
||||
{
|
||||
if (file != nullptr)
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
std::fseek(file, sizeof(RZipHeader) + sizeof(maxChunkSize), SEEK_SET);
|
||||
std::fwrite(&size, sizeof(size), 1, file);
|
||||
}
|
||||
std::fclose(file);
|
||||
file = nullptr;
|
||||
if (chunk != nullptr)
|
||||
{
|
||||
delete [] chunk;
|
||||
chunk = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t RZipFile::Read(void *data, size_t length)
|
||||
{
|
||||
verify(file != nullptr);
|
||||
verify(!write);
|
||||
|
||||
u8 *p = (u8 *)data;
|
||||
size_t rv = 0;
|
||||
while (rv < length)
|
||||
{
|
||||
if (chunkIndex == chunkSize)
|
||||
{
|
||||
chunkSize = 0;
|
||||
chunkIndex = 0;
|
||||
u32 zippedSize;
|
||||
if (std::fread(&zippedSize, sizeof(zippedSize), 1, file) != 1)
|
||||
break;
|
||||
if (zippedSize == 0)
|
||||
continue;
|
||||
u8 *zipped = new u8[zippedSize];
|
||||
if (std::fread(zipped, zippedSize, 1, file) != 1)
|
||||
{
|
||||
delete [] zipped;
|
||||
break;
|
||||
}
|
||||
uLongf tl = maxChunkSize;
|
||||
if (uncompress(chunk, &tl, zipped, zippedSize) != Z_OK)
|
||||
{
|
||||
delete [] zipped;
|
||||
break;
|
||||
}
|
||||
delete [] zipped;
|
||||
chunkSize = (u32)tl;
|
||||
}
|
||||
u32 l = std::min(chunkSize - chunkIndex, (u32)(length - rv));
|
||||
memcpy(p, chunk + chunkIndex, l);
|
||||
p += l;
|
||||
chunkIndex += l;
|
||||
rv += l;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
size_t RZipFile::Write(const void *data, size_t length)
|
||||
{
|
||||
verify(file != nullptr);
|
||||
verify(write);
|
||||
|
||||
size += length;
|
||||
const u8 *p = (const u8 *)data;
|
||||
// compression output buffer must be 0.1% larger + 12 bytes
|
||||
uLongf maxZippedSize = maxChunkSize + maxChunkSize / 1000 + 12;
|
||||
u8 *zipped = new u8[maxZippedSize];
|
||||
size_t rv = 0;
|
||||
while (rv < length)
|
||||
{
|
||||
uLongf zippedSize = maxZippedSize;
|
||||
uLongf uncompressedSize = std::min(maxChunkSize, (u32)(length - rv));
|
||||
u32 rc = compress(zipped, &zippedSize, p, uncompressedSize);
|
||||
if (rc != Z_OK)
|
||||
{
|
||||
WARN_LOG(SAVESTATE, "Compression error: %d", rc);
|
||||
break;
|
||||
}
|
||||
u32 sz = (u32)zippedSize;
|
||||
if (std::fwrite(&sz, sizeof(sz), 1, file) != 1
|
||||
|| std::fwrite(zipped, zippedSize, 1, file) != 1)
|
||||
{
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
p += uncompressedSize;
|
||||
rv += uncompressedSize;
|
||||
}
|
||||
delete [] zipped;
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2020 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Implementation of the RZIP stream format as defined by libretro
|
||||
// https://github.com/libretro/libretro-common/blob/master/include/streams/rzip_stream.h
|
||||
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
class RZipFile
|
||||
{
|
||||
public:
|
||||
~RZipFile() { Close(); }
|
||||
|
||||
bool Open(const std::string& path, bool write);
|
||||
void Close();
|
||||
size_t Size() const { return size; }
|
||||
size_t Read(void *data, size_t length);
|
||||
size_t Write(const void *data, size_t length);
|
||||
FILE *rawFile() const { return file; }
|
||||
|
||||
private:
|
||||
FILE *file = nullptr;
|
||||
u64 size = 0;
|
||||
u32 maxChunkSize = 0;
|
||||
u8 *chunk = nullptr;
|
||||
u32 chunkSize = 0;
|
||||
u32 chunkIndex = 0;
|
||||
bool write = false;
|
||||
};
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* E_Branches.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
EAPI B(u32 sImm24, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0A000000);
|
||||
|
||||
SET_CC;
|
||||
I |= ((sImm24>>2)&0xFFFFFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI BL(u32 sImm24, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0B000000);
|
||||
|
||||
SET_CC;
|
||||
I |= ((sImm24>>2)&0xFFFFFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
// Note: Either X variant will switch to THUMB* if bit0 of addr is 1
|
||||
//
|
||||
|
||||
EAPI BX(eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x012FFF10);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI BLX(eReg Rm, ConditionCode CC=AL) // Form II
|
||||
{
|
||||
DECL_Id(0x012FFF30);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI BXJ(eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x012FFF20);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// This encoding looks correct, but segfaults, the pc val is align(pc,4) but this should be right in ARM
|
||||
//
|
||||
#if defined(_DEVEL)
|
||||
EAPI BLX(u32 sImm24, bool toThumb) // Form I * H is derived so not needed, fixup sImm24 so one can just pass a real addr
|
||||
{
|
||||
DECL_Id(0xFA000000);
|
||||
|
||||
if(toThumb)
|
||||
I |= 1<<24; // SET_H
|
||||
|
||||
I |= ((sImm24>>2)&0xFFFFFF);
|
||||
EMIT_I;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,860 +0,0 @@
|
||||
/*
|
||||
* <E_DataOp.h Title="ARMv7 ISA Emitter Middle-ware: Data-Processing Instructions" />
|
||||
*
|
||||
* <?CTYPE
|
||||
*
|
||||
* <opcode1>{<cond>}{S} <Rd>, <shifter_operand>
|
||||
* <opcode1> := MOV | MVN
|
||||
*
|
||||
* <opcode2>{<cond>} <Rn>, <shifter_operand>
|
||||
* <opcode2> := CMP | CMN | TST | TEQ
|
||||
*
|
||||
* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
|
||||
* <opcode3> := ADD | SUB | RSB | ADC | SBC | RSC | AND | BIC | EOR | ORR
|
||||
*
|
||||
* ?/>
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* imm Rd,[Rn,] imm
|
||||
* reg Rd,Rn,Rm shift
|
||||
* rsr Rd,Rn,Rm type Rs
|
||||
*
|
||||
* sp.imm Rd {SP} imm
|
||||
* sp.reg Rd {SP} Rm shift
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
#define dpInstr(iName, iId) \
|
||||
EAPI iName (eReg Rd, eReg Rn, u32 Imm) ; \
|
||||
EAPI iName (eReg Rd, eReg Rn, eReg Rm, eShiftOp type=S_LSL, u32 Imm=0) ; \
|
||||
EAPI iName (eReg Rd, eReg Rn, eReg Rm, eShiftOp type, eReg Rs) ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
ADC IMM 0x02A00000
|
||||
ADC REG 0x00A00000
|
||||
ADC RSR 0x00A00010
|
||||
|
||||
ADD IMM 0x02800000
|
||||
ADD REG 0x00800000
|
||||
ADD RSR 0x00800010
|
||||
ADD.SP.IMM 0x028D0000
|
||||
ADD.SP.REG 0x008D0000
|
||||
|
||||
AND IMM 0x02000000
|
||||
AND REG 0x00000000
|
||||
AND RSR 0x00000010
|
||||
|
||||
|
||||
// ASR's do not fit this pattern moved elsewhere //
|
||||
|
||||
|
||||
|
||||
BIC IMM 0x03C00000
|
||||
BIC REG 0x01C00000
|
||||
BIC RSR 0x01C00010
|
||||
|
||||
CMN IMM 0x03700000 // N imm
|
||||
CMN REG 0x01700000 // NMshift
|
||||
CMN RSR 0x01700010 // NMtypeS
|
||||
|
||||
CMP IMM 0x03500000 // N imm
|
||||
CMP REG 0x01500000
|
||||
CMP RSR 0x01500010
|
||||
|
||||
|
||||
EOR IMM 0x02200000
|
||||
EOR REG 0x00200000
|
||||
EOR REG 0x00200010
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#define DP_PARAMS (eReg Rd, eReg Rn, ShiftOp Shift, ConditionCode CC=AL)
|
||||
#define DP_RPARAMS (eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
|
||||
#define DP_COMMON \
|
||||
DECL_I; \
|
||||
\
|
||||
SET_CC; \
|
||||
I |= (Rn&15)<<16; \
|
||||
I |= (Rd&15)<<12; \
|
||||
I |= (Shift&0xFFF)
|
||||
|
||||
#define DP_RCOMMON \
|
||||
DECL_I; \
|
||||
\
|
||||
SET_CC; \
|
||||
I |= (Rn&15)<<16; \
|
||||
I |= (Rd&15)<<12; \
|
||||
I |= (Rm&15)
|
||||
|
||||
#define DP_OPCODE(opcode) \
|
||||
I |= (opcode)<<21
|
||||
|
||||
|
||||
|
||||
EAPI AND DP_PARAMS { DP_COMMON; DP_OPCODE(DP_AND); EMIT_I; }
|
||||
EAPI EOR DP_PARAMS { DP_COMMON; DP_OPCODE(DP_EOR); EMIT_I; }
|
||||
EAPI SUB DP_PARAMS { DP_COMMON; DP_OPCODE(DP_SUB); EMIT_I; }
|
||||
EAPI RSB DP_PARAMS { DP_COMMON; DP_OPCODE(DP_RSB); EMIT_I; }
|
||||
EAPI ADD DP_PARAMS { DP_COMMON; DP_OPCODE(DP_ADD); EMIT_I; }
|
||||
EAPI ADC DP_PARAMS { DP_COMMON; DP_OPCODE(DP_ADC); EMIT_I; }
|
||||
EAPI SBC DP_PARAMS { DP_COMMON; DP_OPCODE(DP_SBC); EMIT_I; }
|
||||
EAPI RSC DP_PARAMS { DP_COMMON; DP_OPCODE(DP_RSC); EMIT_I; }
|
||||
EAPI TST DP_PARAMS { DP_COMMON; DP_OPCODE(DP_TST); EMIT_I; }
|
||||
EAPI TEQ DP_PARAMS { DP_COMMON; DP_OPCODE(DP_TEQ); EMIT_I; }
|
||||
// EAPI CMP DP_PARAMS { DP_COMMON; DP_OPCODE(DP_CMP); EMIT_I; }
|
||||
EAPI CMN DP_PARAMS { DP_COMMON; DP_OPCODE(DP_CMN); EMIT_I; }
|
||||
EAPI ORR DP_PARAMS { DP_COMMON; DP_OPCODE(DP_ORR); EMIT_I; }
|
||||
EAPI MOV DP_PARAMS { DP_COMMON; DP_OPCODE(DP_MOV); EMIT_I; }
|
||||
EAPI BIC DP_PARAMS { DP_COMMON; DP_OPCODE(DP_BIC); EMIT_I; }
|
||||
EAPI MVN DP_PARAMS { DP_COMMON; DP_OPCODE(DP_MVN); EMIT_I; }
|
||||
|
||||
#if defined(_DEVEL) && defined(_NODEF_) // These require testing -> CMP/MOV Shifter(Reg)? fmt broken? // Simple third reg type w/ no shifter
|
||||
EAPI AND DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_AND); EMIT_I; }
|
||||
EAPI EOR DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_EOR); EMIT_I; }
|
||||
EAPI SUB DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_SUB); EMIT_I; }
|
||||
EAPI RSB DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_RSB); EMIT_I; }
|
||||
EAPI ADD DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_ADD); EMIT_I; }
|
||||
EAPI ADC DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_ADC); EMIT_I; }
|
||||
EAPI SBC DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_SBC); EMIT_I; }
|
||||
EAPI RSC DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_RSC); EMIT_I; }
|
||||
EAPI TST DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_TST); EMIT_I; }
|
||||
EAPI TEQ DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_TEQ); EMIT_I; }
|
||||
EAPI CMP DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_CMP); EMIT_I; }
|
||||
EAPI CMN DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_CMN); EMIT_I; }
|
||||
EAPI ORR DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_ORR); EMIT_I; }
|
||||
EAPI MOV DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_MOV); EMIT_I; }
|
||||
EAPI BIC DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_BIC); EMIT_I; }
|
||||
EAPI MVN DP_PARAMS { DP_RCOMMON; DP_OPCODE(DP_MVN); EMIT_I; }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static u32 ARMImmid8r4_enc(u32 imm32)
|
||||
{
|
||||
for (int i=0;i<=30;i+=2)
|
||||
{
|
||||
u32 immv=(imm32<<i) | (imm32>>(32-i));
|
||||
if (i == 0)
|
||||
immv = imm32;
|
||||
if (immv<256)
|
||||
{
|
||||
return ((i/2)<<8) | immv;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u32 ARMImmid8r4(u32 imm8r4)
|
||||
{
|
||||
u32 rv = ARMImmid8r4_enc(imm8r4);
|
||||
|
||||
verify(rv!=-1);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static bool is_i8r4(u32 i32) { return ARMImmid8r4_enc(i32) != -1; }
|
||||
|
||||
|
||||
|
||||
EAPI ADD(eReg Rd, eReg Rn, eReg Rm, u32 RmLSL, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00800000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
I |= (RmLSL&31)<<7;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ADD(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
ADD(Rd,Rn,Rm,0,S,CC);
|
||||
}
|
||||
|
||||
EAPI ADD(eReg Rd, eReg Rn, eReg Rm, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00800000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Imm8&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ADD(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
ADD(Rd,Rn,Rm,false,CC);
|
||||
}
|
||||
|
||||
|
||||
EAPI ADD(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02800000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ADC(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00A00000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ADC(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
ADC(Rd,Rn,Rm,false,CC);
|
||||
}
|
||||
|
||||
EAPI ADC(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02A00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ADC(eReg Rd, eReg Rn, eReg Rm, bool S, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00A00000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Imm8&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EAPI ADR(eReg Rd, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x028F0000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ADR_Zero(eReg Rd, s32 Imm8, ConditionCode CC=AL) // Special case for subtraction of 0
|
||||
{
|
||||
DECL_Id(0x024F0000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI ORR(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01800000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ORR(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03800000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ORR(eReg Rd, eReg Rn, eReg Rm, ShiftOp Shift, eReg Rs, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01800000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= 1<<4;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ORR(eReg Rd, eReg Rn, eReg Rm, bool S, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01800000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Imm8&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI AND(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00000000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI AND(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00000000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI AND(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02000000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI AND(eReg Rd, eReg Rn, s32 Imm8, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02000000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI EOR(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00200000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI EOR(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00200000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI EOR(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02200000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EAPI SUB(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00400000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SUB(eReg Rd, eReg Rn, s32 Imm8, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02400000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI SUB(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL) { SUB(Rd,Rn,Imm8,false,CC); }
|
||||
|
||||
EAPI SBC(eReg Rd, eReg Rn, eReg Rm, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00C00000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SBC(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
SBC(Rd,Rn,Rm,false,CC);
|
||||
}
|
||||
|
||||
EAPI RSB(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x00600000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI RSB(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02600000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI RSB(eReg Rd, eReg Rn, s32 Imm8, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x02600000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI MVN(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01E00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI MVN(eReg Rd, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03E00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI TST(eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01100000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI TST(eReg Rn, u32 Imm12, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03100000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= ARMImmid8r4(Imm12);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI BIC(eReg Rd, eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03C00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
EAPI UBFX(eReg Rd, eReg Rm, u8 lsb, u8 width, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x07E00050);
|
||||
verify(lsb+width<=32);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= (lsb&31)<<7;
|
||||
I |= ((width-1)&31)<<16;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SBFX(eReg Rd, eReg Rm, u8 lsb, u8 width, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x07A00050);
|
||||
verify(lsb+width<=32);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= (lsb&31)<<7;
|
||||
I |= ((width-1)&31)<<16;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOV(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOV(eReg Rd, eReg Rm, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00000);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOV(eReg Rd, eReg Rm, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Imm8&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOV(eReg Rd, eReg Rm, ShiftOp Shift, eReg Rs, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= 1<<4;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOVW(eReg Rd, u32 Imm16, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03000000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Imm16&0xF000)<<4;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Imm16&0x0FFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOVT(eReg Rd, u32 Imm16, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03400000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Imm16&0xF000)<<4;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Imm16&0x0FFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MOV(eReg Rd, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03A00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= ARMImmid8r4(Imm8); // * 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
EAPI CMP(eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01500000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI CMP(eReg Rn, s32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03500000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= ARMImmid8r4(Imm8); // *FIXME* 12b imm is 8b imm 4b rot. spec, add rot support!
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI CMP(eReg Rd, eReg Rm, ShiftOp Shift, eReg Rs, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01500000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= 1<<4;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI CMP(eReg Rd, eReg Rm, ShiftOp Shift, u32 Imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01500000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
I |= Shift<<5;
|
||||
I |= (Imm8&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI LSL(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00010);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<8;
|
||||
I |= (Rn&15)<<0;
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI LSL(eReg Rd, eReg Rm, s32 imm5, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00000);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<0;
|
||||
I |= (imm5&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI LSR(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00030);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<8;
|
||||
I |= (Rn&15)<<0;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI RRX(eReg Rd, eReg Rm,bool S=false, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00060);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<0;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI LSR(eReg Rd, eReg Rm, s32 imm5, bool S, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00020);
|
||||
|
||||
if (S)
|
||||
I |= 1<<20;
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<0;
|
||||
I |= (imm5&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI LSR(eReg Rd, eReg Rm, s32 imm5, ConditionCode CC=AL)
|
||||
{
|
||||
LSR(Rd,Rm,imm5,false,CC);
|
||||
}
|
||||
|
||||
|
||||
EAPI ASR(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00050);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<8;
|
||||
I |= (Rn&15)<<0;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ASR(eReg Rd, eReg Rm, s32 imm5, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00040);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<0;
|
||||
I |= (imm5&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ROR(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<8;
|
||||
I |= (Rn&15)<<0;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ROR(eReg Rd, eReg Rm, s32 imm5, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01A00060);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15)<<0;
|
||||
I |= (imm5&31)<<7;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#undef DP_PARAMS
|
||||
#undef DP_RPARAMS
|
||||
|
||||
#undef DP_COMMON
|
||||
#undef DP_RCOMMON
|
||||
|
||||
#undef DP_OPCODE
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* E_Extend.h
|
||||
*
|
||||
|
||||
There are six basic instructions:
|
||||
XTAB16 Extend bits[23:16] and bits[7:0] of one register to 16 bits, and add corresponding halfwordsto the values in another register.
|
||||
XTAB Extend bits[ 7: 0] of one register to 32 bits, and add to the value in another register.
|
||||
XTAH Extend bits[15: 0] of one register to 32 bits, and add to the value in another register.
|
||||
XTB16 Extend bits[23:16] and bits[7:0] to 16 bits each.
|
||||
XTB Extend bits[ 7: 0] to 32 bits.
|
||||
XTH Extend bits[15: 0] to 32 bits.
|
||||
|
||||
Each of the six instructions is available in the following variations, indicated by the prefixes shown:
|
||||
S Sign extension, with or without addition modulo 216 or 232.
|
||||
U Zero (unsigned) extension, with or without addition modulo 216 or 232.
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
EAPI SXTAB16(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06800070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SXTAB(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06A00070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SXTAH(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06B00070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SXTB16(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x068F0070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SXTB(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06AF0070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SXTH(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06BF0070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UXTAB16(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06C00070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UXTAB(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06E00070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UXTAH(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06F00070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UXTB16(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06CF0070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UXTB(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06EF0070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UXTH(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06FF0070);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
* E_LoadStore.h
|
||||
*
|
||||
* LDR|STR{<cond>}{B}{T} Rd, <addressing_mode>
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
enum AddrMode {
|
||||
|
||||
Offset, // [Rn, offset] - Base:Offset used for access, no writeback
|
||||
PostIndexed, // [Rn, offset] ! - Base:Offset used for access, written back to Base reg.
|
||||
PreIndexed // [Rn],offset - Base used then Base:Offset written back to Base reg.
|
||||
|
||||
// offset: imm{8,12}, Rm, Rm <Shifter> #Shift
|
||||
};
|
||||
|
||||
|
||||
#define SET_Rn I |= (Rn&15)<<16
|
||||
#define SET_Rt I |= (Rt&15)<<12
|
||||
#define SET_Rm I |= (Rm&15)
|
||||
|
||||
|
||||
#define SET_Rtn SET_Rt; SET_Rn
|
||||
#define SET_Rtnm SET_Rt; SET_Rn; SET_Rm
|
||||
|
||||
|
||||
|
||||
#define SET_I I |= (1<<25) // Sets Register (Rather than Immediate) Addressing
|
||||
#define SET_P I |= (1<<24) // If NOT Set: post-indexed, else offset||pre-indexed (W. determines which)
|
||||
#define SET_U I |= (1<<23) // If SET: Offset is added to base, else its subtracted (Sign of sImm12)
|
||||
#define SET_B I |= (1<<22) // If SET: Access is a byte access, else its a word access.
|
||||
#define SET_W I |= (1<<21) // (P==0) [ W==0: reg. post indexed, W==1: Unprivileged T variant ] (P==1) [ W==0: Offset , W==1: Pre-indexed ]
|
||||
#define SET_L I |= (1<<20) // (L==1) Load / Store
|
||||
|
||||
|
||||
#define SET_AddrMode \
|
||||
if(mode==Offset) { SET_P; } \
|
||||
else if(mode==PreIndexed) { SET_P; SET_W; }
|
||||
|
||||
/*
|
||||
#define SET_AddrMode \
|
||||
\
|
||||
switch(mode) { \
|
||||
case PostIndexed: break; \
|
||||
case Offset: SET_P; break; \
|
||||
case PreIndexed: SET_P; SET_W; break; \
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#define SET_sImm12 \
|
||||
\
|
||||
if (0 != sImm12) { \
|
||||
if (sImm12 > 0) { SET_U; } \
|
||||
I |= (abs(sImm12) &0xFFF); \
|
||||
}
|
||||
|
||||
#define SET_sImm8 \
|
||||
\
|
||||
if(0 != sImm8) { \
|
||||
verify(is_s8(sImm8)); \
|
||||
if(sImm8 > 0) { SET_U; } \
|
||||
sImm8 = abs(sImm8); \
|
||||
I |= ((u32)sImm8 &0x0F); \
|
||||
I |= ((u32)sImm8 &0xF0)<<4; \
|
||||
}
|
||||
|
||||
|
||||
#define SET_Imm5 I |= ((Imm5&0x1F)<<7)
|
||||
#define SET_type I |= ((type&3)<<5)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* - Load/Store Encoding
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
cond 01-IPUBWL Rn Rt addr_mode -- Load/Store Word || Unsigned Byte
|
||||
|
||||
I,P,U,W - Specify type of addressing mode
|
||||
L - Specify Load (L==1), else Store
|
||||
B - Specify Byte (B==1), else Word
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
cond 000-PUIWL Rn Rt addr_mode 1SH1 addr_mode -- Load/Store Halfword || Signed byte
|
||||
|
||||
I,P,U,W - Specify type of addressing mode
|
||||
L - Specify Load (L==1), else Store
|
||||
S - Specify signed (S==1), else unsigned access
|
||||
H - Specify Halfword access, else signed byte
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
cond 010-PUBWL Rn Rt sImm12-iiii-iiii Imm Offset
|
||||
cond 011-PUBWL Rn Rt #sft sft_op 0 Rm Reg Offset
|
||||
|
||||
cond 000 PU1WL Rn Rt imHI 1011 imLO Imm Offset - halfword
|
||||
cond 000 PU0WL Rn Rt SBZ 1011 Rm Reg Offset - halfword
|
||||
cond 000 PU1W1 Rn Rt imHI 11H1 imLO Imm Offset - signed halfword/byte
|
||||
cond 000 PU0W1 Rn Rt SBZ 11H1 Rm Reg Offset - signed halfword/byte
|
||||
cond 000 PU1W0 Rn Rt imHI 11S1 imLO Imm Offset - two words
|
||||
cond 000 PU0W0 Rn Rt SBZ 11S1 Rm Reg Offset - two words
|
||||
|
||||
cond 100-PUSWL Rn Register-list Multiple
|
||||
cond 110-PUNWL Rn CRd cp_num offs8 COP & double reg xfer
|
||||
|
||||
cond 0001 0B00 Rn Rt SBZ 1001 Rm Swap [byte]
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
LDR L 010 1U001 11 Rt imm12 - *no literal stores*
|
||||
LDR I 010 PU0W1 Rn Rt imm12 - STR I 010 PU0W0 Rn Rt imm12
|
||||
LDR R 011 PU0W1 Rn Rt imm5 type 0 Rm - STR R 011 PU0W0 Rn Rt imm5 type 0 Rm
|
||||
|
||||
LDRT I 010 0U011 Rn Rt imm12 - STRT I 010 0U010 Rn Rt imm12
|
||||
LDRT R 011 0U011 Rn Rt imm5 type 0 Rm - STRT R 011 0U010 Rn Rt imm5 type 0 Rm
|
||||
|
||||
LDRB L 010 1U101 11 Rt imm12 - *^^
|
||||
LDRB I 010 PU1W1 Rn Rt imm12 - STRB I 010 PU1W0 Rn Rt imm12
|
||||
LDRB R 011 PU1W1 Rn Rt imm5 type 0 Rm - STRB R 011 PU1W0 Rn Rt imm5 type 0 Rm
|
||||
|
||||
LDRBT I
|
||||
LDRBT R
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
LDRH L 000 1U101 11 Rt imm4H 1011 imm4L - *^^
|
||||
LDRH I 000 PU1W1 Rn Rt imm4H 1011 imm4L - STRH I 000 PU1W0 Rn Rt imm4H 1011 imm4L
|
||||
LDRH R 000 PU0W1 Rn Rt 0000 1011 Rm - STRH R 000 PU0W0 Rn Rt 0000 1011 Rm
|
||||
|
||||
LDRD L 000 1U100 11 Rt imm4H 1101 imm4L - *^^
|
||||
LDRD I 000 PU1W0 Rn Rt imm4H 1101 imm4L - STRD I 000 PU1W0 Rn Rt imm4H 1111 imm4L
|
||||
LDRD R 000 PU0W0 Rn Rt 0000 1101 Rm - STRD R 000 PU0W0 Rn Rt 0000 1111 Rm
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
LDRHT/STRHT
|
||||
|
||||
LDREX/STREX
|
||||
LDREXB/STREXB
|
||||
LDREXH/STREXH
|
||||
LDREXD/STREXD
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
EAPI LDR 0x04100000 // These were all the A1 Versions for Imm IIRC
|
||||
EAPI LDRB 0x04500000
|
||||
EAPI LDRBT 0x06700000
|
||||
EAPI LDRD 0x00000000
|
||||
EAPI LDREX 0x01900090
|
||||
EAPI LDRH 0x00100090
|
||||
EAPI LDRSB 0x00100000
|
||||
EAPI LDRSH 0x00100000
|
||||
EAPI LDRT 0x04300000
|
||||
|
||||
EAPI STR 0x04000000
|
||||
EAPI STRB 0x04400000
|
||||
EAPI STRBT 0x06600000
|
||||
EAPI STRD 0x00000000
|
||||
EAPI STREX 0x01800090
|
||||
EAPI STRH 0x00000090
|
||||
EAPI STRT 0x04200000
|
||||
|
||||
*/
|
||||
|
||||
|
||||
extern u8* emit_opt;
|
||||
extern eReg reg_addr;
|
||||
extern eReg reg_dst;
|
||||
extern s32 imma;
|
||||
|
||||
EAPI LDR (eReg Rt, eReg Rn, s32 sImm12=0, AddrMode mode=Offset, ConditionCode CC=AL)
|
||||
{
|
||||
if (emit_opt+4==(u8*)EMIT_GET_PTR() && reg_addr==Rn && imma==sImm12)
|
||||
{
|
||||
if (reg_dst!=Rt)
|
||||
MOV(Rt,reg_dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
DECL_Id(0x04100000); SET_CC; SET_Rtn; SET_AddrMode; SET_sImm12; EMIT_I;
|
||||
}
|
||||
}
|
||||
EAPI STR (eReg Rt, eReg Rn, s32 sImm12=0, AddrMode mode=Offset, ConditionCode CC=AL)
|
||||
{
|
||||
emit_opt=0;//(u8*)EMIT_GET_PTR();
|
||||
reg_addr=Rn;
|
||||
reg_dst=Rt;
|
||||
imma=sImm12;
|
||||
DECL_Id(0x04000000); SET_CC; SET_Rtn; SET_AddrMode; SET_sImm12; EMIT_I;
|
||||
}
|
||||
EAPI LDRB(eReg Rt, eReg Rn, s32 sImm12=0, AddrMode mode=Offset, ConditionCode CC=AL) { DECL_Id(0x04500000); SET_CC; SET_Rtn; SET_AddrMode; SET_sImm12; SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
EAPI STRB(eReg Rt, eReg Rn, s32 sImm12=0, AddrMode mode=Offset, ConditionCode CC=AL) { DECL_Id(0x04400000); SET_CC; SET_Rtn; SET_AddrMode; SET_sImm12; SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
|
||||
EAPI LDRT (eReg Rt, eReg Rn, s32 sImm12=0, ConditionCode CC=AL) { DECL_Id(0x04300000); SET_CC; SET_Rtn; SET_sImm12; EMIT_I; }
|
||||
EAPI STRT (eReg Rt, eReg Rn, s32 sImm12=0, ConditionCode CC=AL) { DECL_Id(0x04200000); SET_CC; SET_Rtn; SET_sImm12; EMIT_I; }
|
||||
EAPI LDRBT(eReg Rt, eReg Rn, s32 sImm12=0, ConditionCode CC=AL) { DECL_Id(0x04700000); SET_CC; SET_Rtn; SET_sImm12; SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
EAPI STRBT(eReg Rt, eReg Rn, s32 sImm12=0, ConditionCode CC=AL) { DECL_Id(0x04600000); SET_CC; SET_Rtn; SET_sImm12; SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
|
||||
// LDR(r1,r2,r3, Offset, true, L_LSL, 5, EQ); ... LDR r1, r2, +r3 LSL #5
|
||||
EAPI LDR (eReg Rt, eReg Rn, eReg Rm, AddrMode mode=Offset, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06100000); SET_CC; SET_Rtnm; SET_AddrMode; SET_Imm5; SET_type; if(Add){ SET_U; } EMIT_I; }
|
||||
EAPI STR (eReg Rt, eReg Rn, eReg Rm, AddrMode mode=Offset, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06000000); SET_CC; SET_Rtnm; SET_AddrMode; SET_Imm5; SET_type; if(Add){ SET_U; } EMIT_I; }
|
||||
EAPI LDRB(eReg Rt, eReg Rn, eReg Rm, AddrMode mode=Offset, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06500000); SET_CC; SET_Rtnm; SET_AddrMode; SET_Imm5; SET_type; if(Add){ SET_U; } SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
EAPI STRB(eReg Rt, eReg Rn, eReg Rm, AddrMode mode=Offset, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06400000); SET_CC; SET_Rtnm; SET_AddrMode; SET_Imm5; SET_type; if(Add){ SET_U; } SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
|
||||
EAPI LDRT (eReg Rt, eReg Rn, eReg Rm, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06300000); SET_CC; SET_Rtnm; SET_Imm5; SET_type; if(Add){ SET_U; } EMIT_I; }
|
||||
EAPI STRT (eReg Rt, eReg Rn, eReg Rm, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06200000); SET_CC; SET_Rtnm; SET_Imm5; SET_type; if(Add){ SET_U; } EMIT_I; }
|
||||
EAPI LDRBT(eReg Rt, eReg Rn, eReg Rm, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06700000); SET_CC; SET_Rtnm; SET_Imm5; SET_type; if(Add){ SET_U; } SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
EAPI STRBT(eReg Rt, eReg Rn, eReg Rm, bool Add=false, ShiftOp type=S_LSL, u32 Imm5=0, ConditionCode CC=AL) { DECL_Id(0x06600000); SET_CC; SET_Rtnm; SET_Imm5; SET_type; if(Add){ SET_U; } SET_B; EMIT_I; } // Prob don't need SET_B, in iID
|
||||
|
||||
|
||||
|
||||
// LDR Rt,[PC, #(s:+/-)Imm12] *Special Case - Literal / PC Relative
|
||||
EAPI LDR(eReg Rt, s32 sImm12, ConditionCode CC=AL) {
|
||||
DECL_Id(0x051F0000); SET_CC; SET_Rt; SET_sImm12; EMIT_I;
|
||||
}
|
||||
|
||||
// LDRB Rt,[PC, #(s:+/-)Imm12] *Special Case - Literal / PC Relative
|
||||
EAPI LDRB(eReg Rt, s32 sImm12, ConditionCode CC=AL) {
|
||||
DECL_Id(0x055F0000); SET_CC; SET_Rt; SET_sImm12; EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Note: Following support Post-Indexed addressing only //
|
||||
|
||||
|
||||
EAPI LDRH(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x005000B0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; }
|
||||
EAPI STRH(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x004000B0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; }
|
||||
EAPI LDRD(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x004000D0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; }
|
||||
EAPI STRD(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x004000F0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; }
|
||||
EAPI LDRSB(eReg Rt, eReg Rn, s32 sImm8 = 0, ConditionCode CC = AL) { DECL_Id(0x005000D0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; }
|
||||
EAPI LDRSH(eReg Rt, eReg Rn, s32 sImm8 = 0, ConditionCode CC = AL) { DECL_Id(0x005000F0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; }
|
||||
|
||||
EAPI LDRH(eReg Rt, eReg Rn, eReg Rm, bool Add=true,ConditionCode CC=AL) { DECL_Id(0x001000B0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; }
|
||||
EAPI STRH(eReg Rt, eReg Rn, eReg Rm, bool Add=true,ConditionCode CC=AL) { DECL_Id(0x000000B0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; }
|
||||
EAPI LDRD(eReg Rt, eReg Rn, eReg Rm, bool Add=true, ConditionCode CC=AL) { DECL_Id(0x000000D0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; }
|
||||
EAPI STRD(eReg Rt, eReg Rn, eReg Rm, bool Add=true, ConditionCode CC=AL) { DECL_Id(0x000000F0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; }
|
||||
|
||||
EAPI LDRSB(eReg Rt, eReg Rn, eReg Rm, bool Add=true,ConditionCode CC=AL) { DECL_Id(0x001000D0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; }
|
||||
EAPI LDRSH(eReg Rt, eReg Rn, eReg Rm, bool Add=true,ConditionCode CC=AL) { DECL_Id(0x001000F0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; }
|
||||
|
||||
|
||||
EAPI LDRH(eReg Rt, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x015F00B0); SET_CC; SET_Rt; SET_sImm8; EMIT_I; } // *Special Case - Literal / PC Relative
|
||||
EAPI STRH(eReg Rt, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x014F00D0); SET_CC; SET_Rt; SET_sImm8; EMIT_I; } // *Special Case - Literal / PC Relative
|
||||
|
||||
|
||||
|
||||
// TODO: {LD,ST}R{SB,EX*} && friends (If required).
|
||||
|
||||
|
||||
// Must use _Reg format
|
||||
EAPI PUSH(u32 RegList, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x092D0000);
|
||||
|
||||
SET_CC;
|
||||
I |= (RegList&0xFFFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI POP(u32 RegList, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x08BD0000);
|
||||
|
||||
SET_CC;
|
||||
I |= (RegList&0xFFFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
#undef SET_Rtn
|
||||
#undef SET_Rtnm
|
||||
|
||||
#undef SET_Rn
|
||||
#undef SET_Rt
|
||||
#undef SET_Rm
|
||||
|
||||
#undef SET_I
|
||||
#undef SET_P
|
||||
#undef SET_U
|
||||
#undef SET_B
|
||||
#undef SET_W
|
||||
#undef SET_L
|
||||
|
||||
#undef SET_AddrMode
|
||||
|
||||
#undef SET_sImm12
|
||||
#undef SET_sImm8
|
||||
#undef SET_Imm5
|
||||
#undef SET_type
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* E_Misc.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
/*
|
||||
* Misc. Arithmetic Instructions
|
||||
*/
|
||||
|
||||
// Count Leading Zero's
|
||||
//
|
||||
EAPI CLZ(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x016F0F10);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
// Unsigned sum of absolute differences
|
||||
//
|
||||
EAPI USAD8(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0780F010);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<16;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI USADA8(eReg Rd, eReg Rm, eReg Rs, eReg Rn, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x07800010);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<16;
|
||||
I |= (Rn&15)<<12;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Packing Instructions
|
||||
*/
|
||||
|
||||
|
||||
EAPI PKHBT(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) // * shift_imm
|
||||
{
|
||||
DECL_Id(0x06800010);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI PKHTB(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL) // * shift_imm
|
||||
{
|
||||
DECL_Id(0x06800050);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Swapping Instructions
|
||||
*/
|
||||
|
||||
EAPI REV(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06BF0F30);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI REV16(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06BF0FB0);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI REVSH(eReg Rd, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06FF0F30);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI SEL(eReg Rd, eReg Rn, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06800FB0);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rn&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Saturate Instructions
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// SSAT{<cond>} <Rd>, #<immed>, <Rm>{, <shift>}
|
||||
//
|
||||
EAPI SSAT(eReg Rd, u32 sat_imm, eReg Rm, u32 sft_imm, ConditionCode CC=AL) // sh&1 << 6
|
||||
{
|
||||
DECL_Id(0x06A00010);
|
||||
|
||||
SET_CC;
|
||||
I |= (sat_imm&31)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (sft_imm&31)<<7;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
// SSAT16{<cond>} <Rd>, #<immed>, <Rm>
|
||||
//
|
||||
EAPI SSAT16(eReg Rd, u32 sat_imm, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06A00030);
|
||||
|
||||
SET_CC;
|
||||
I |= (sat_imm&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= 15<<8; // * SBO
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
// USAT{<cond>} <Rd>, #<immed>, <Rm>{, <shift>}
|
||||
//
|
||||
EAPI USAT(eReg Rd, u32 sat_imm, eReg Rm, u32 sft_imm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06E00010);
|
||||
|
||||
SET_CC;
|
||||
I |= (sat_imm&31)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= (sft_imm&31)<<7;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
// USAT16{<cond>} <Rd>, #<immed>, <Rm>
|
||||
//
|
||||
EAPI USAT16(eReg Rd, u32 sat_imm, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x06E00030);
|
||||
|
||||
SET_CC;
|
||||
I |= (sat_imm&15)<<16;
|
||||
I |= (Rd&15)<<12;
|
||||
I |= 15<<8; // * SBO
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* E_Multiply.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
EAPI MLA(eReg Rd, eReg Rn, eReg Rs, eReg Rm, ConditionCode CC=AL) // *FIXME* S
|
||||
{
|
||||
DECL_Id(0x00200090);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<16;
|
||||
I |= (Rn&15)<<12;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI MUL(eReg Rd, eReg Rs, eReg Rm, ConditionCode CC=AL) // *FIXME* S
|
||||
{
|
||||
DECL_Id(0x00000090);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rd&15)<<16;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI UMULL(eReg Rdhi, eReg Rdlo, eReg Rs, eReg Rm, ConditionCode CC=AL) // *FIXME* S
|
||||
{
|
||||
DECL_Id(0x00800090);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rdhi&15)<<16;
|
||||
I |= (Rdlo&15)<<12;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SMULL(eReg Rdhi, eReg Rdlo, eReg Rs, eReg Rm, ConditionCode CC=AL) // *FIXME* S
|
||||
{
|
||||
DECL_Id(0x00C00090);
|
||||
|
||||
SET_CC;
|
||||
I |= (Rdhi&15)<<16;
|
||||
I |= (Rdlo&15)<<12;
|
||||
I |= (Rs&15)<<8;
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
SMLA<x><y> Signed halfword Multiply Accumulate.
|
||||
SMLAD Signed halfword Multiply Accumulate, Dual.
|
||||
SMLAL Signed Multiply Accumulate Long.
|
||||
SMLAL<x><y> Signed halfword Multiply Accumulate Long.
|
||||
SMLALD Signed halfword Multiply Accumulate Long, Dual.
|
||||
SMLAW<y> Signed halfword by word Multiply Accumulate.
|
||||
SMLSD Signed halfword Multiply Subtract, Dual.
|
||||
SMLSLD Signed halfword Multiply Subtract Long Dual.
|
||||
SMMLA Signed Most significant word Multiply Accumulate.
|
||||
SMMLS Signed Most significant word Multiply Subtract.
|
||||
SMMUL Signed Most significant word Multiply.
|
||||
SMUAD Signed halfword Multiply, Add, Dual.
|
||||
SMUL<x><y> Signed halfword Multiply.
|
||||
SMULL Signed Multiply Long.
|
||||
SMULW<y> Signed halfword by word Multiply.
|
||||
SMUSD Signed halfword Multiply, Subtract, Dual.
|
||||
UMAAL Unsigned Multiply Accumulate significant Long.
|
||||
UMLAL Unsigned Multiply Accumulate Long.
|
||||
UMULL Unsigned Multiply Long.
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* E_Parallel.h
|
||||
*
|
||||
|
||||
ADD8 Adds each byte of the second operand register to the corresponding byte of the first operand
|
||||
register to form the corresponding byte of the result.
|
||||
|
||||
ADD16 Adds the top halfwords of two registers to form the top halfword of the result.
|
||||
Adds the bottom halfwords of the same two registers to form the bottom halfword of the result.
|
||||
|
||||
SUB8 Subtracts each byte of the second operand register from the corresponding byte of the first
|
||||
operand register to form the corresponding byte of the result.
|
||||
|
||||
SUB16 Subtracts the top halfword of the first operand register from the top halfword of the second operand register to form the top halfword of the result.
|
||||
Subtracts the bottom halfword of the second operand registers from the bottom halfword of
|
||||
the first operand register to form the bottom halfword of the result.
|
||||
|
||||
ADDSUBX Does the following:
|
||||
1. Exchanges halfwords of the second operand register.
|
||||
2. Adds top halfwords and subtracts bottom halfwords.
|
||||
|
||||
SUBADDX Does the following:
|
||||
1. Exchanges halfwords of the second operand register.
|
||||
2. Subtracts top halfwords and adds bottom halfwords.
|
||||
|
||||
|
||||
Each of the six instructions is available in the following variations, indicated by the prefixes shown:
|
||||
|
||||
S Signed arithmetic modulo 28 or 216. Sets the CPSR GE bits (see The GE[3:0] bits on page A2-13).
|
||||
Q Signed saturating arithmetic.
|
||||
SH Signed arithmetic, halving the results to avoid overflow.
|
||||
U Unsigned arithmetic modulo 28 or 216. Sets the CPSR GE bits (see The GE[3:0] bits on page A2-13).
|
||||
UQ Unsigned saturating arithmetic.
|
||||
UH Unsigned arithmetic, halving the results to avoid overflow.
|
||||
|
||||
|
||||
Status:
|
||||
These routines require implementation if needed.
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
#if defined(_DEVEL) && 0
|
||||
|
||||
// S
|
||||
//
|
||||
EAPI SADD8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SADD16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SSUB8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SSUB16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SADDSUBX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SSUBADDX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
|
||||
|
||||
// Q
|
||||
//
|
||||
EAPI QADD8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI QADD16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI QSUB8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI QSUB16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI QADDSUBX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI QSUBADDX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
|
||||
|
||||
// SH
|
||||
//
|
||||
EAPI SHADD8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SHADD16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SHSUB8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SHSUB16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SHADDSUBX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI SHSUBADDX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
|
||||
|
||||
// U
|
||||
//
|
||||
EAPI UADD8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UADD16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI USUB8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI USUB16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UADDSUBX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI USUBADDX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
|
||||
|
||||
// UQ
|
||||
//
|
||||
EAPI UQADD8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UQADD16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UQSUB8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UQSUB16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UQADDSUBX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UQSUBADDX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
|
||||
|
||||
// UH
|
||||
//
|
||||
EAPI UHADD8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UHADD16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UHSUB8 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UHSUB16 (eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UHADDSUBX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
EAPI UHSUBADDX(eReg Rd, eReg Rm, eReg Rs, ConditionCode CC=AL) ;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* E_Special.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
EAPI ARMERROR()
|
||||
{
|
||||
DECL_Id(0xFFFFFFFF);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI NOP()
|
||||
{
|
||||
DECL_Id(0xE320F000);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI SVC(u32 code)
|
||||
{
|
||||
DECL_Id(0x0F000000);
|
||||
I |= code&0xFFFFFF;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI BKPT()
|
||||
{
|
||||
DECL_Id(0x01200070);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
#define SWI SVC
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Synchronization & Barrier Instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
EAPI DSB()
|
||||
{
|
||||
DECL_Id(0xF57FF04F);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI DMB()
|
||||
{
|
||||
DECL_Id(0xF57FF05F);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI ISB()
|
||||
{
|
||||
DECL_Id(0xF57FF06F);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* E_Status.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
#if defined(_DEVEL)
|
||||
|
||||
// MRS Move PSR to General-purpose Register.
|
||||
//
|
||||
EAPI MRS(eReg Rd, u32 R, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01000000);
|
||||
|
||||
SET_CC;
|
||||
I |= (R&1) << 22;
|
||||
I |= 15<<16; // * SBO
|
||||
I |= (Rd &15)<<12;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
/* MSR Move General-purpose Register to PSR.
|
||||
|
||||
MSR{<cond>} CPSR_<fields>, #<immediate>
|
||||
MSR{<cond>} CPSR_<fields>, <Rm>
|
||||
MSR{<cond>} SPSR_<fields>, #<immediate>
|
||||
MSR{<cond>} SPSR_<fields>, <Rm>
|
||||
*/
|
||||
|
||||
|
||||
// MSR: Immediate operand
|
||||
//
|
||||
EAPI MSR(u32 R, u32 fmask, u32 rot_imm, u32 imm8, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x03200000);
|
||||
|
||||
SET_CC;
|
||||
I |= (R&1) << 22;
|
||||
I |= (fmask &15)<<16;
|
||||
I |= 15<<12; // * SBO
|
||||
I |= (rot_imm &15)<<8;
|
||||
I |= (imm8 &255);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
// MSR: Register operand
|
||||
//
|
||||
EAPI MSR(u32 R, u32 fmask, eReg Rm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x01200000);
|
||||
|
||||
SET_CC;
|
||||
I |= (R&1) << 22;
|
||||
I |= (fmask &15)<<16;
|
||||
I |= 15<<12; // * SBO
|
||||
I |= (Rm&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// CPS Change Processor State.
|
||||
//
|
||||
EAPI CPS(u32 imod, u32 mmod, u32 mode) // ** [A|I|F]
|
||||
{
|
||||
DECL_Id(0xF1000000);
|
||||
|
||||
// Note: UNconditional instruction!
|
||||
I |= (imod&3)<<18;
|
||||
I |= (mmod&1)<<17;
|
||||
I |= (mode&15);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SETEND Modifies the CPSR endianness, E, bit, without changing any other bits in the CPSR.
|
||||
//
|
||||
EAPI SETEND(u32 E)
|
||||
{
|
||||
DECL_Id(0xF1010000);
|
||||
|
||||
// Note: UNconditional instruction!
|
||||
I |= (E &1) << 9;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
@@ -1,667 +0,0 @@
|
||||
/*
|
||||
* E_VDataOp.h * VFP/A.SIMD Data Processing Instruction Set Encoding
|
||||
*
|
||||
* V{<modifier>}<operation>{<shape>}<c><q>{.<dt>} {<dest>,} <src1>, <src2>
|
||||
*
|
||||
* <modifier> Meaning
|
||||
* Q The operation uses saturating arithmetic.
|
||||
* R The operation performs rounding.
|
||||
* D The operation doubles the result (before accumulation, if any).
|
||||
* H The operation halves the result.
|
||||
*
|
||||
* <shape> Meaning Typical register shape
|
||||
* (none) The operands and result are all the same width. Dd, Dn, Dm - Qd, Qn, Qm
|
||||
* L Long operation - result is 2 x width of both operands Qd, Dn, Dm
|
||||
* N Narrow operation - result is width/2 both operands Dd, Qn, Qm
|
||||
* W Wide operation - result and oper[1] are 2x width oper[2] Qd, Qn, Dm
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
#define SET_Qd \
|
||||
I |= (((Qd<<1)&0x0E)<<12); \
|
||||
I |= (((Qd<<1)&0x10)<<18)
|
||||
|
||||
#define SET_Qn \
|
||||
I |= (((Qn<<1)&0x0E)<<16); \
|
||||
I |= (((Qn<<1)&0x10)<<3)
|
||||
|
||||
#define SET_Qm \
|
||||
I |= (((Qm<<1)&0x0E)); \
|
||||
I |= (((Qm<<1)&0x10)<<1)
|
||||
|
||||
|
||||
|
||||
#define SET_Dd \
|
||||
I |= ((Dd&0x0F)<<12); \
|
||||
I |= ((Dd&0x10)<<18)
|
||||
|
||||
#define SET_Dn \
|
||||
I |= ((Dn&0x0F)<<16); \
|
||||
I |= ((Dn&0x10)<<3)
|
||||
|
||||
#define SET_Dm \
|
||||
I |= ((Dm&0x0F)); \
|
||||
I |= ((Dm&0x10)<<1)
|
||||
|
||||
|
||||
|
||||
|
||||
#define SET_Q I |= 0x40
|
||||
#define SET_U I |= ((U&1)<<24);
|
||||
#define SET_Size I |= (((Size>>4)&3)<<20) // 8,16,32 -> 0,1,2
|
||||
|
||||
|
||||
#define SET_Qdnm \
|
||||
SET_Qd; SET_Qn; SET_Qm; SET_Q
|
||||
|
||||
#define SET_Ddnm \
|
||||
SET_Dd; SET_Dn; SET_Dm
|
||||
|
||||
#define DECL_Qdnm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define VdpInstrF(viName, viId) \
|
||||
EAPI V##viName##_F32 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { DECL_Id(viId); SET_Qdnm; EMIT_I; } \
|
||||
EAPI V##viName##_F32 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { DECL_Id(viId); SET_Ddnm; EMIT_I; }
|
||||
|
||||
|
||||
#define VdpInstrI_EOR(viName, viId) \
|
||||
EAPI V##viName (eFQReg Qd, eFQReg Qn, eFQReg Qm) { DECL_Id(viId); SET_Qdnm; EMIT_I; } \
|
||||
EAPI V##viName (eFDReg Dd, eFDReg Dn, eFDReg Dm) { DECL_Id(viId); SET_Ddnm; EMIT_I; } \
|
||||
|
||||
#define VdpInstrI(viName, viId) \
|
||||
EAPI V##viName (eFQReg Qd, eFQReg Qn, eFQReg Qm, u32 Size=32) { DECL_Id(viId); SET_Qdnm; SET_Size; EMIT_I; } \
|
||||
EAPI V##viName (eFDReg Dd, eFDReg Dn, eFDReg Dm, u32 Size=32) { DECL_Id(viId); SET_Ddnm; SET_Size; EMIT_I; } \
|
||||
\
|
||||
EAPI V##viName##_I8 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 8); } \
|
||||
EAPI V##viName##_I8 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 8); } \
|
||||
EAPI V##viName##_I16 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 16); } \
|
||||
EAPI V##viName##_I16 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 16); } \
|
||||
EAPI V##viName##_I32 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 32); } \
|
||||
EAPI V##viName##_I32 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 32); }
|
||||
|
||||
#define VdpInstrU(viName, viId) \
|
||||
EAPI V##viName (eFQReg Qd, eFQReg Qn, eFQReg Qm, u32 Size=32, u32 U=0) { DECL_Id(viId); SET_Qdnm; SET_U; SET_Size; EMIT_I; } \
|
||||
EAPI V##viName (eFDReg Dd, eFDReg Dn, eFDReg Dm, u32 Size=32, u32 U=0) { DECL_Id(viId); SET_Ddnm; SET_U; SET_Size; EMIT_I; } \
|
||||
\
|
||||
EAPI V##viName##_U8 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 8, 1); } \
|
||||
EAPI V##viName##_U8 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 8, 1); } \
|
||||
EAPI V##viName##_S8 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 8, 0); } \
|
||||
EAPI V##viName##_S8 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 8, 0); } \
|
||||
EAPI V##viName##_U16 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 16, 1); } \
|
||||
EAPI V##viName##_U16 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 16, 1); } \
|
||||
EAPI V##viName##_S16 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 16, 0); } \
|
||||
EAPI V##viName##_S16 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 16, 0); } \
|
||||
EAPI V##viName##_U32 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 32, 1); } \
|
||||
EAPI V##viName##_U32 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 32, 1); } \
|
||||
EAPI V##viName##_S32 (eFQReg Qd, eFQReg Qn, eFQReg Qm) { V##viName (Qd, Qn, Qm, 32, 0); } \
|
||||
EAPI V##viName##_S32 (eFDReg Dd, eFDReg Dn, eFDReg Dm) { V##viName (Dd, Dn, Dm, 32, 0); }
|
||||
|
||||
//# define VdpInstrImm (viName, viId)
|
||||
|
||||
|
||||
// Another three or four like the above .. immN, above w/ size, F32 w/ sz
|
||||
|
||||
|
||||
/*
|
||||
* A.SIMD Parallel Add/Sub
|
||||
*
|
||||
Vector Add VADD (integer), VADD (floating-point)
|
||||
Vector Add and Narrow, returning High Half VADDHN
|
||||
Vector Add Long, Vector Add Wide VADDL, VADDW
|
||||
Vector Halving Add, Vector Halving Subtract VHADD, VHSUB
|
||||
Vector Pairwise Add and Accumulate Long VPADAL
|
||||
Vector Pairwise Add VPADD (integer) , VPADD (floating-point)
|
||||
Vector Pairwise Add Long VPADDL
|
||||
Vector Rounding Add & Narrow, returning High Half VRADDHN
|
||||
Vector Rounding Halving Add VRHADD
|
||||
Vector Rounding Subtract & Narrow, ret. High Half VRSUBHN
|
||||
Vector Saturating Add VQADD
|
||||
Vector Saturating Subtract VQSUB
|
||||
Vector Subtract VSUB (integer), VSUB (floating-point)
|
||||
Vector Subtract and Narrow, returning High Half VSUBHN
|
||||
Vector Subtract Long, Vector Subtract Wide VSUBL, VSUBW
|
||||
*/
|
||||
|
||||
VdpInstrI(ADD, 0xF2000800)
|
||||
VdpInstrF(ADD, 0xF2000D00)
|
||||
|
||||
|
||||
VdpInstrI(HADD, 0xF2000800)
|
||||
VdpInstrI(HSUB, 0xF2000A00)
|
||||
|
||||
VdpInstrI(PADD, 0xF2000B10)
|
||||
VdpInstrF(PADD, 0xF3000D00)
|
||||
|
||||
|
||||
VdpInstrU(RHADD, 0xF3000100)
|
||||
VdpInstrU(QADD, 0xF2000010)
|
||||
VdpInstrU(QSUB, 0xF3000210)
|
||||
|
||||
VdpInstrI(SUB, 0xF3000800)
|
||||
VdpInstrF(SUB, 0xF2200D00)
|
||||
|
||||
|
||||
// VADD I { DECL_Id(0xF2000800); SET_Qdnm; EMIT_I; }
|
||||
// VADD F { DECL_Id(0xF2000D00); SET_Qdnm; EMIT_I; }
|
||||
// VADDHN { DECL_Id(0xF2800400); SET_Qdnm; EMIT_I; } // DQQ
|
||||
// VADD{L,W} { DECL_Id(0xF2800000); SET_Qdnm; EMIT_I; } // QDD || QQD
|
||||
// VH{ADD,SUB} { DECL_Id(0xF2000000); SET_Qdnm; EMIT_I; }
|
||||
// VPADAL { DECL_Id(0xF3B00600); SET_Qdnm; EMIT_I; } // QdQm || DdDm
|
||||
// VPADD I { DECL_Id(0xF2000B10); SET_Qdnm; EMIT_I; } // DDD only
|
||||
// VPADD F { DECL_Id(0xF3000D00); SET_Qdnm; EMIT_I; } // DDD only
|
||||
// VPADDL { DECL_Id(0xF3B00200); SET_Qdnm; EMIT_I; } // QdQm || DdDm
|
||||
// VRADDHN { DECL_Id(0xF3800400); SET_Qdnm; EMIT_I; } // DQQ
|
||||
// VRHADD { DECL_Id(0xF3000100); SET_Qdnm; EMIT_I; }
|
||||
// VRSUBHN { DECL_Id(0xF3800600); SET_Qdnm; EMIT_I; } // DQQ
|
||||
// VQADD { DECL_Id(0xF2000010); SET_Qdnm; EMIT_I; }
|
||||
// VQSUB { DECL_Id(0xF3000210); SET_Qdnm; EMIT_I; }
|
||||
// VSUB I { DECL_Id(0xF3000800); SET_Qdnm; EMIT_I; }
|
||||
// VSUB F { DECL_Id(0xF2200D00); SET_Qdnm; EMIT_I; }
|
||||
// VSUBHN { DECL_Id(0xF2800600); SET_Qdnm; EMIT_I; } // DQQ
|
||||
// VSUB{L,W} { DECL_Id(0xF2800200); SET_Qdnm; EMIT_I; } // QDD || QQD
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A.SIMD Bitwise
|
||||
*
|
||||
Vector Bitwise AND VAND (register)
|
||||
Vector Bitwise Bit Clear (AND complement) VBIC (immediate), VBIC (register)
|
||||
Vector Bitwise Exclusive OR VEOR
|
||||
Vector Bitwise Move VMOV (immediate), VMOV (register)
|
||||
Vector Bitwise NOT VMVN (immediate), VMVN (register)
|
||||
Vector Bitwise OR VORR (immediate), VORR (register)
|
||||
Vector Bitwise OR NOT VORN (register)
|
||||
Vector Bitwise Insert if False VBIF
|
||||
Vector Bitwise Insert if True VBIT
|
||||
Vector Bitwise Select VBSL
|
||||
*/
|
||||
|
||||
VdpInstrI(AND, 0xF2000110)
|
||||
VdpInstrI(BIC, 0xF2100110)
|
||||
VdpInstrI_EOR(EOR, 0xF3000110)
|
||||
VdpInstrI_EOR(BSL, 0xF3100110)
|
||||
VdpInstrI_EOR(BIT, 0xF3200110)
|
||||
VdpInstrI_EOR(BIF, 0xF3300110)
|
||||
VdpInstrI(ORN, 0xF2300110)
|
||||
// VAND R { DECL_Id(0xF2000110); SET_Qdnm; EMIT_I; }
|
||||
// VBIC R { DECL_Id(0xF2100110); SET_Qdnm; EMIT_I; }
|
||||
// VEOR { DECL_Id(0xF3000110); SET_Qdnm; EMIT_I; }
|
||||
// VBSL { DECL_Id(0xF3100110); SET_Qdnm; EMIT_I; }
|
||||
// VBIT { DECL_Id(0xF3200110); SET_Qdnm; EMIT_I; }
|
||||
// VBIF { DECL_Id(0xF3300110); SET_Qdnm; EMIT_I; }
|
||||
// VORN R { DECL_Id(0xF2300110); SET_Qdnm; EMIT_I; }
|
||||
|
||||
// VBIC I { DECL_Id(0xF2800030); SET_Qd; SET_IMM??; EMIT_I; }
|
||||
// VMOV I { DECL_Id(0xF2800010); SET_Qd; SET_IMM??; EMIT_I; }
|
||||
// VMVN I { DECL_Id(0xF2800030); SET_Qd; SET_IMM??; EMIT_I; }
|
||||
// VORR I { DECL_Id(0xF2800010); SET_Qd; SET_IMM??; EMIT_I; }
|
||||
// VAND I VBIC I
|
||||
// VORN I VORR I
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A.SIMD comparison
|
||||
*
|
||||
Vector Absolute Compare VACGE, VACGT, VACLE,VACLT
|
||||
Vector Compare Equal VCEQ (register)
|
||||
Vector Compare Equal to Zer VCEQ (immediate #0)
|
||||
Vector Compare Greater Than or Equal VCGE (register)
|
||||
Vector Compare Greater Than or Equal to Zero VCGE (immediate #0)
|
||||
Vector Compare Greater Than VCGT (register)
|
||||
Vector Compare Greater Than Zero VCGT (immediate #0)
|
||||
Vector Compare Less Than or Equal to Zero VCLE (immediate #0)
|
||||
Vector Compare Less Than Zero VCLT (immediate #0)
|
||||
Vector Test Bits VTST
|
||||
*/
|
||||
// VAC{COND} { DECL_Id(0xF3000E10); SET_Vdnm; EMIT_I; }
|
||||
|
||||
// VCEQ { DECL_Id(0xF3000810); SET_Vdnm; EMIT_I; } .F32 { DECL_Id(0xF2000E00); SET_Vdnm; EMIT_I; }
|
||||
VdpInstrI(CEQ, 0xF3200810)
|
||||
// VdpInstrF(CEQ, 0xF2000e00)
|
||||
// VCGE { DECL_Id(0xF2000310); SET_Vdnm; EMIT_I; } .F32 { DECL_Id(0xF3000E00); SET_Vdnm; EMIT_I; }
|
||||
VdpInstrI(CGE, 0xF2200310)
|
||||
// VdpInstrF(CGE, 0xF3000e00)
|
||||
// VCGT { DECL_Id(0xF2000300); SET_Vdnm; EMIT_I; } .F32 { DECL_Id(0xF3200E00); SET_Vdnm; EMIT_I; }
|
||||
//*SEB* 0xF220030 for S32, 0xF3200300 for U32, 0xF2000300 is for S8.
|
||||
VdpInstrI(CGT, 0xF2200300)
|
||||
//VdpInstrF(CGT, 0xF3200e00)
|
||||
// VCLE { DECL_Id(0xF3B10180); SET_Vdnm; EMIT_I; } // R is VCGE w/ operands reversed
|
||||
// VCLT { DECL_Id(0xF3B10200); SET_Vdnm; EMIT_I; } // R is VCGT w/ operands reversed
|
||||
// VTST { DECL_Id(0xF2000810); SET_Vdnm; EMIT_I; }
|
||||
|
||||
// VCEQZ { DECL_Id(0xF3B10100); SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VCGEZ { DECL_Id(0xF3B10080); SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VCGTZ { DECL_Id(0xF3B10000); SET_Vd; SET_Vm; EMIT_I; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A.SIMD shift ** SET_imm6; needed for non Vdnm
|
||||
*
|
||||
Vector Saturating Rounding Shift Left VQRSHL
|
||||
Vector Saturating Rounding Shift Right and Narrow VQRSHRN, VQRSHRUN
|
||||
Vector Saturating Shift Left VQSHL (register), VQSHL, VQSHLU (immediate)
|
||||
Vector Saturating Shift Right and Narrow VQSHRN, VQSHRUN
|
||||
Vector Rounding Shift Left VRSHL
|
||||
Vector Rounding Shift Right VRSHR
|
||||
Vector Rounding Shift Right and Accumulate VRSRA
|
||||
Vector Rounding Shift Right and Narrow VRSHRN
|
||||
Vector Shift Left VSHL (immediate) on page A8-750 VSHL (register)
|
||||
Vector Shift Left Long VSHLL
|
||||
Vector Shift Right VSHR
|
||||
Vector Shift Right and Narrow VSHRN
|
||||
Vector Shift Left and Insert VSLI
|
||||
Vector Shift Right and Accumulate VSRA
|
||||
Vector Shift Right and Insert VSRI
|
||||
*/
|
||||
// VQRSHL { DECL_Id(0xF SET_Vdnm; EMIT_I; } // * TODO
|
||||
// VQRSHRN { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VQRSHRUN { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VQSHL R { DECL_Id(0xF SET_Vdnm; EMIT_I; }
|
||||
// VQSHL I { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VQSHLU { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VQSHRN { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VQSHRUN { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VRSHL { DECL_Id(0xF SET_Vdnm; EMIT_I; }
|
||||
// VRSHR { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VRSRA { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VRSHRN { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSHL I { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSHL R { DECL_Id(0xF SET_Vdnm; EMIT_I; }
|
||||
// VSHLL { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSHR { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSHRN { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSLI { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSRA { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VSRI { DECL_Id(0xF SET_Vd; SET_Vm; EMIT_I; }
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A.SIMD multiply
|
||||
*
|
||||
Vector Multiply Accumulate VMLA, VMLAL, VMLS, VMLSL (integer) , VMLA, VMLS (floating-point), VMLA, VMLAL, VMLS, VMLSL (by scalar)
|
||||
Vector Multiply Accumulate Long
|
||||
Vector Multiply Subtract
|
||||
Vector Multiply Subtract Long
|
||||
Vector Multiply VMUL, VMULL (integer and polynomial)
|
||||
Vector Multiply Long VMUL (floating-point) on page A8-664 VMUL, VMULL (by scalar)
|
||||
Vector Saturating Doubling Multiply Accumulate Long VQDMLAL, VQDMLSL
|
||||
Vector Saturating Doubling Multiply Subtract Long
|
||||
Vector Saturating Doubling Multiply Returning High Half VQDMULH
|
||||
Vector Saturating Rounding Doubling Multiply Ret. High Half VQRDMULH
|
||||
Vector Saturating Doubling Multiply Long VQDMULL
|
||||
*/
|
||||
|
||||
VdpInstrI(MLA, 0xF2000900)
|
||||
VdpInstrI(MLS, 0xF3000900)
|
||||
|
||||
VdpInstrF(MLA, 0xF2000D10)
|
||||
VdpInstrF(MLS, 0xF2200D10)
|
||||
|
||||
//by scalar
|
||||
//this should be really qd,dn,sm not dm
|
||||
EAPI VMUL_F32(eFQReg Qd,eFQReg Qn, eFDReg Dm, int idx)
|
||||
{
|
||||
DECL_Id(0xF2800840);
|
||||
|
||||
SET_Qd;
|
||||
SET_Qn;
|
||||
I |= 1<<8; //SET_F
|
||||
|
||||
SET_Dm;
|
||||
I |= 0x1<<24; //SET_Q not compatible
|
||||
|
||||
I |= 2<<20; //size to 32
|
||||
|
||||
I |= Dm&15; //only lower 15 regs are avail
|
||||
|
||||
|
||||
//set register sub index
|
||||
if (idx)
|
||||
I |= 1<<5;
|
||||
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VMLA_F32(eFQReg Qd,eFQReg Qn, eFDReg Dm, int idx)
|
||||
{
|
||||
DECL_Id(0xF2800040);
|
||||
|
||||
SET_Qd;
|
||||
SET_Qn;
|
||||
I |= 1<<8; //SET_F
|
||||
|
||||
SET_Dm;
|
||||
I |= 0x1<<24; //SET_Q not compatible
|
||||
|
||||
I |= 2<<20; //size to 32
|
||||
|
||||
I |= Dm&15; //only lower 15 regs are avail
|
||||
|
||||
|
||||
//set register sub index
|
||||
if (idx)
|
||||
I |= 1<<5;
|
||||
|
||||
EMIT_I;
|
||||
}
|
||||
// VdpInstrU(MLAL, 0xF2000D10) *QDD
|
||||
// VdpInstrU(MLSL, 0xF2200D10) *QDD
|
||||
|
||||
|
||||
VdpInstrI(MUL, 0xF2000910)
|
||||
|
||||
VdpInstrF(MUL, 0xF3000D10)
|
||||
|
||||
// VdpInstrU(MULL, 0xF3000D10) *QDD
|
||||
|
||||
// VMLA I { DECL_Id(0xF2000900); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VMLS I { DECL_Id(0xF3000900); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VMLAL I { DECL_Id(0xF2800800); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= ((U&1)<<24)
|
||||
// VMLSL I { DECL_Id(0xF2800A00); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= ((U&1)<<24)
|
||||
|
||||
// VMLA F { DECL_Id(0xF2000D10); SET_Vdnm; EMIT_I; } // * I |= ((sz&1)<<20)
|
||||
// VMLS F { DECL_Id(0xF2200D10); SET_Vdnm; EMIT_I; } // * I |= ((sz&1)<<20)
|
||||
|
||||
// VMLA S { DECL_Id(0xF2800040); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VMLS S { DECL_Id(0xF2800440); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// CMLAL S { DECL_Id(0xF2800240); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= ((U&1)<<24)
|
||||
// VMLSL S { DECL_Id(0xF2800640); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= ((U&1)<<24)
|
||||
|
||||
// VMUL IP { DECL_Id(0xF2000910); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= 1<<24 for polynomial
|
||||
// VMULL IP { DECL_Id(0xF2800C00); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= 1<<9 for polynomial * I |= ((U&1)<<24)
|
||||
|
||||
// VMUL F { DECL_Id(0xF3000D10); SET_Vdnm; EMIT_I; } // * I |= ((sz&1)<<20)
|
||||
|
||||
// VMUL S { DECL_Id(0xF2800840); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VMULL S { DECL_Id(0xF2800A40); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20) * I |= ((U&1)<<24)
|
||||
// VQDMLAL { DECL_Id(0xF2800900); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VQDMLSL { DECL_Id(0xF2800B00); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VQDMULH { DECL_Id(0xF2000B00); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VQRDMULH { DECL_Id(0xF3000B00); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
// VQDMULL { DECL_Id(0xF2800D00); SET_Vdnm; EMIT_I; } // * I |= ((size&3)<<20)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A.SIMD misc
|
||||
*
|
||||
Vector Absolute Difference and Accumulate VABA, VABAL
|
||||
Vector Absolute Difference VABD, VABDL (integer) , VABD (floating-point)
|
||||
Vector Absolute VABS
|
||||
Vector Convert between floating-point and fixed point VCVT (between floating-point and fixed-point, Advanced SIMD)
|
||||
Vector Convert between floating-point and integer VCVT (between floating-point and integer, Advanced SIMD)
|
||||
Vector Convert between half-precision and single-precision VCVT (between half-precision and single-precision, Advanced SIMD)
|
||||
Vector Count Leading Sign Bits VCLS
|
||||
Vector Count Leading Zeros VCLZ
|
||||
Vector Count Set Bits VCNT
|
||||
Vector Duplicate scalar VDUP (scalar)
|
||||
Vector Extract VEXT
|
||||
Vector Move and Narrow VMOVN
|
||||
Vector Move Long VMOVL
|
||||
Vector Maximum, Minimum VMAX, VMIN (integer) , VMAX, VMIN (floating-point)
|
||||
Vector Negate VNEG
|
||||
Vector Pairwise Maximum, Minimum VPMAX, VPMIN (integer) , VPMAX, VPMIN (floating-point)
|
||||
Vector Reciprocal Estimate VRECPE
|
||||
Vector Reciprocal Step VRECPS
|
||||
Vector Reciprocal Square Root Estimate VRSQRTE
|
||||
Vector Reciprocal Square Root Step VRSQRTS
|
||||
Vector Reverse VREV16, VREV32, VREV64
|
||||
Vector Saturating Absolute VQABS
|
||||
Vector Saturating Move and Narrow VQMOVN, VQMOVUN
|
||||
Vector Saturating Negate VQNEG
|
||||
Vector Swap VSWP
|
||||
Vector Table Lookup VTBL, VTBX
|
||||
Vector Transpose VTRN
|
||||
Vector Unzip VUZP
|
||||
Vector Zip VZIP
|
||||
*/
|
||||
// VABA { DECL_Id(0xF2000710); // WIP
|
||||
// VABAL { DECL_Id(0xF2800500);
|
||||
|
||||
// VABD I { DECL_Id(0xF);
|
||||
// VABDL I { DECL_Id(0xF);
|
||||
|
||||
// VABD F { DECL_Id(0xF);
|
||||
|
||||
// VABS { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
|
||||
EAPI VSQRT_F32(eFSReg Sd, eFSReg Sm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EB10AC0); SET_CC;
|
||||
|
||||
I |= ((Sd&0x1E)<<11) | ((Sd&1)<<22);
|
||||
I |= ((Sm&0x1E)>>1) | ((Sm&1)<<5);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VABS_F32(eFSReg Sd, eFSReg Sm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EB00AC0); SET_CC;
|
||||
|
||||
I |= ((Sd&0x1E)<<11) | ((Sd&1)<<22);
|
||||
I |= ((Sm&0x1E)>>1) | ((Sm&1)<<5);
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI VNEG_F32(eFSReg Sd, eFSReg Sm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EB10A40); SET_CC;
|
||||
|
||||
I |= ((Sd&0x1E)<<11) | ((Sd&1)<<22);
|
||||
I |= ((Sm&0x1E)>>1) | ((Sm&1)<<5);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
//imm move, fpu
|
||||
EAPI VMOV(eFSReg Sd, u32 imm8_fpu, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EB10A00); SET_CC;
|
||||
|
||||
I |= (imm8_fpu&0x0F); //bits 3:0
|
||||
I |= (imm8_fpu&0xF0)<<12; //bits 19:16
|
||||
|
||||
I |= ((Sd&0x1E)<<11) | ((Sd&1)<<22);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
const u32 fpu_imm_1=0x70;//01110000
|
||||
|
||||
EAPI VCMP_F32(eFSReg Sd, eFSReg Sm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EB40A40); SET_CC;
|
||||
|
||||
I |= ((Sd&0x1E)<<11) | ((Sd&1)<<22);
|
||||
I |= ((Sm&0x1E)>>1) | ((Sm&1)<<5);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
VdpInstrF(CEQ, 0xF2000E00)
|
||||
VdpInstrF(CGE, 0xF3000E00)
|
||||
VdpInstrF(CGT, 0xF3200E00)
|
||||
|
||||
// VCVT FFP { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VCVT FI { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VCVT HS { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
|
||||
// VCLS { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VCLZ { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
// VCNT { DECL_Id(0xF); SET_Vd; SET_Vm; EMIT_I; }
|
||||
|
||||
|
||||
// VEXT { DECL_Id(0xF); SET_Vdnm; EMIT_I; }
|
||||
|
||||
// VMAX I { DECL_Id(0xF);
|
||||
// VMIN I { DECL_Id(0xF);
|
||||
// VMAX F { DECL_Id(0xF);
|
||||
// VMIN F { DECL_Id(0xF);
|
||||
// VNEG { DECL_Id(0xF);
|
||||
|
||||
// VPMAX I { DECL_Id(0xF);
|
||||
// VPMIN I { DECL_Id(0xF);
|
||||
// VPMAX F { DECL_Id(0xF);
|
||||
// VPMIN F { DECL_Id(0xF);
|
||||
|
||||
// VRECPE { DECL_Id(0xF3B30400); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
// VRECPS { DECL_Id(0xF2000F10); SET_Vdnm; EMIT_I; } // sz&1<<20 (.F32)
|
||||
// VRSQRTE { DECL_Id(0xF3B30480); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18 F&1<<8 ***
|
||||
// VRSQRTS { DECL_Id(0xF2200F10); SET_Vdnm; EMIT_I; } // sz&1<<20 (.F32)
|
||||
// VREVsz { DECL_Id(0xF3B00000); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18 op&3<<7 ***
|
||||
|
||||
// VQABS { DECL_Id(0xF3B00700); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
// VQMOVN { DECL_Id(0xF3B20200); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18 op&3<<6 op:00=MOVN op11=srcUnsigned op:x1=dstUnsigned
|
||||
// VQMOVUN { DECL_Id(0xF3B20200); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
// VQNEG { DECL_Id(0xF3B00780); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
|
||||
// VSWP { DECL_Id(0xF3B20000); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
// VTBL { DECL_Id(0xF3B00800); SET_Vdnm; EMIT_I; } // len&3<<8
|
||||
// VTBX { DECL_Id(0xF3B00840); SET_Vdnm; EMIT_I; } // len&3<<8
|
||||
// VTRN { DECL_Id(0xF3B20080); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
// VUZP { DECL_Id(0xF3B20100); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
// VZIP { DECL_Id(0xF3B20180); SET_Vd; SET_Vm; EMIT_I; } // size&3<<18
|
||||
//
|
||||
|
||||
|
||||
// VDUP & VMOVN & VMOVL are implemented in VRegXfer.h ...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VFPv3 Instructions
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#define SET_Sd \
|
||||
I |= ((Sd&0x1E)<<11); \
|
||||
I |= ((Sd&0x01)<<22)
|
||||
|
||||
#define SET_Sn \
|
||||
I |= ((Sn&0x1E)<<15); \
|
||||
I |= ((Sn&0x01)<<7)
|
||||
|
||||
#define SET_Sm \
|
||||
I |= ((Sm&0x1E)>>1); \
|
||||
I |= ((Sm&0x01)<<5)
|
||||
|
||||
|
||||
|
||||
#define SET_Sdnm SET_Sd; SET_Sn; SET_Sm
|
||||
|
||||
|
||||
#define VfpInstrS(viName, viId) EAPI V##viName##_VFP (eFSReg Sd, eFSReg Sn, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(viId); SET_CC; SET_Sdnm; EMIT_I; }
|
||||
|
||||
VfpInstrS(MLA, 0x0E000A00)
|
||||
VfpInstrS(MLS, 0x0E000A40)
|
||||
|
||||
VfpInstrS(NMLA, 0x0E100A40)
|
||||
VfpInstrS(NMLS, 0x0E100A00)
|
||||
VfpInstrS(NMUL, 0x0E200A40)
|
||||
|
||||
|
||||
VfpInstrS(MUL, 0x0E200A00)
|
||||
|
||||
VfpInstrS(ADD, 0x0E300A00)
|
||||
VfpInstrS(SUB, 0x0E300A40)
|
||||
|
||||
VfpInstrS(DIV, 0x0E800A00)
|
||||
|
||||
|
||||
EAPI VCVT_to_S32_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EBD0AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm
|
||||
// 0x0EB80A40 is to_U32. to_S32 is 0x0EB80AC0
|
||||
EAPI VCVT_from_S32_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB80AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm
|
||||
|
||||
EAPI VABS_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB00AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(ABS, 0x0EB00AC0) ** {D,S}dm
|
||||
EAPI VNEG_VFP (eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB10A40); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(NEG, 0x0EB10A40) ** {D,S}dm
|
||||
EAPI VSQRT_VFP(eFSReg Sd, eFSReg Sm, ConditionCode CC=CC_AL) { DECL_Id(0x0EB10AC0); SET_CC; SET_Sd; SET_Sm; EMIT_I; } // VfpInstrS(SQRT, 0x0EB10AC0) ** {D,S}dm
|
||||
|
||||
// - x0 Vector Move VMOV (immediate) on page A8-640
|
||||
// 0000 01 Vector Move VMOV (register) on page A8-642
|
||||
|
||||
// 001x x1 Vector Convert VCVTB, VCVTT (between half-precision and single-precision, VFP) on page A8-588
|
||||
// 010x x1 Vector Compare VCMP, VCMPE on page A8-572
|
||||
// 0111 11 Vector Convert VCVT (between double-precision and single-precision) on page A8-584
|
||||
// 1000 x1 Vector Convert VCVT, VCVTR (between floating-point and integer, VFP) on page A8-578
|
||||
// 101x x1 Vector Convert VCVT (between floating-point and fixed-point, VFP) on page A8-582
|
||||
// 110x x1 Vector Convert VCVT, VCVTR (between floating-point and integer, VFP) on page A8-578
|
||||
// 111x x1 Vector Convert VCVT (between floating-point and fixed-point, VFP) on page A8-582
|
||||
|
||||
////// hack
|
||||
|
||||
EAPI VDIV_HACKF32(eFDReg Sd, eFDReg Sn, eFDReg Sm)
|
||||
{
|
||||
ConditionCode CC=AL;
|
||||
|
||||
eFSReg SdS=(eFSReg)(Sd*2);
|
||||
eFSReg SnS=(eFSReg)(Sn*2);
|
||||
eFSReg SmS=(eFSReg)(Sm*2);
|
||||
|
||||
verify((int)Sd < 32 && (int)Sn < 32 && (int)Sm < 32);
|
||||
|
||||
VDIV_VFP(SdS,SnS,SmS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#undef SET_Qd
|
||||
#undef SET_Dd
|
||||
|
||||
#undef SET_Qn
|
||||
#undef SET_Dn
|
||||
|
||||
#undef SET_Qm
|
||||
#undef SET_Dm
|
||||
|
||||
#undef SET_Q
|
||||
|
||||
#undef SET_Qdnm
|
||||
#undef SET_Ddnm
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* E_VLoadStore.h * VFP/A.SIMD Load/Store Instruction Set Encoding
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
// [cond][110][Opcode][-Rn-][----][101][---------]
|
||||
//
|
||||
// cond != 0b1111 | LDC && STC consume these
|
||||
|
||||
|
||||
|
||||
#define SET_Dd \
|
||||
I |= ((Dd&0x0F)<<12); \
|
||||
I |= ((Dd&0x10)<<18)
|
||||
|
||||
#define SET_Sd \
|
||||
I |= ((Sd&0x1E)<<11); \
|
||||
I |= ((Sd&0x01)<<22)
|
||||
|
||||
|
||||
#define SET_Rn \
|
||||
I |= ((Rn&15)<<16)
|
||||
|
||||
#define SET_uImm8 \
|
||||
I |= (uImm8 & 255)
|
||||
|
||||
#define SET_sImm8 \
|
||||
if (sImm8 > 0) { \
|
||||
I |= (1<<23); \
|
||||
} \
|
||||
I |= (abs(sImm8) & 255)
|
||||
|
||||
|
||||
#define SET_PUW(_P,_U,_W) \
|
||||
I |= ( ((_P&1)<<24) | ((_U&1)<<23) | ((_W&1)<<21) )
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* V{LD,ST}R: Vector Load/Store Register
|
||||
*
|
||||
* V{LD,ST}R.64 // VFP && A.SIMD
|
||||
* V{LD,ST}R.32 // VFP
|
||||
*/
|
||||
|
||||
EAPI VLDR(eFDReg Dd, eReg Rn, s32 sImm8, ConditionCode CC=AL) // VLDR.64
|
||||
{
|
||||
DECL_Id(0x0D100B00); SET_CC;
|
||||
SET_Dd; SET_Rn; SET_sImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VLDR(eFSReg Sd, eReg Rn, s32 sImm8, ConditionCode CC=AL) // VLDR.32
|
||||
{
|
||||
DECL_Id(0x0D100A00); SET_CC;
|
||||
SET_Sd; SET_Rn; SET_sImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI VSTR(eFDReg Dd, eReg Rn, s32 sImm8, ConditionCode CC=AL) // VSTR.64
|
||||
{
|
||||
DECL_Id(0x0D000B00); SET_CC;
|
||||
SET_Dd; SET_Rn; SET_sImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VSTR(eFSReg Sd, eReg Rn, s32 sImm8, ConditionCode CC=AL) // VSTR.32
|
||||
{
|
||||
DECL_Id(0x0D000A00); SET_CC;
|
||||
SET_Sd; SET_Rn; SET_sImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* V{LD,ST}M: Vector Load/Store Multiple
|
||||
*
|
||||
* V{LD,ST}R.64 // VFP && A.SIMD
|
||||
* V{LD,ST}R.32 // VFP
|
||||
*
|
||||
* uImm8: directional count, abs(sImm8) is the reg. count
|
||||
* Dd: Register to start sequential operation from..
|
||||
*
|
||||
* suffix DB: P=1 U=0 W=1, Decrement Before, Addresses end just before the address in Rn.
|
||||
* suffix IA: P=0 U=1 W=?, Increment After, Addresses start at address in Rn
|
||||
*
|
||||
* ** These are very complicated encoding and require a lot of error checking and even more thought when used. **
|
||||
* ** Simply using, MOV32(R4, &double_array[0]); VLDM(D0, R4, 4); should however work to load an array of 4 doubles **
|
||||
*/
|
||||
|
||||
EAPI VLDM(eFDReg Dd, eReg Rn, u32 uImm8, u32 WB=0, ConditionCode CC=AL) // VLDM.64
|
||||
{
|
||||
// ASSERT( (uImm8>0) && (uImm8<=16) && ((Dd+uImm8) <= 32) )
|
||||
uImm8<<=1;
|
||||
DECL_Id(0x0C100B00); SET_CC;
|
||||
SET_Dd; SET_Rn;
|
||||
SET_uImm8; SET_PUW(0,1,WB); // Defaulting to IA w/o ! (Write-back)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VLDM(eFSReg Sd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VLDM.32
|
||||
{
|
||||
// ASSERT( (uImm8>0) && ((Dd+uImm8) <= 32) )
|
||||
DECL_Id(0x0C100A00); SET_CC;
|
||||
SET_Sd; SET_Rn;
|
||||
SET_uImm8; SET_PUW(0,1,0); // Defaulting to IA w/o ! (Write-back)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI VSTM(eFDReg Dd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VSTM.64
|
||||
{
|
||||
// ASSERT( (uImm8>0) && (uImm8<=16) && ((Dd+uImm8) <= 32) )
|
||||
uImm8<<=1;
|
||||
DECL_Id(0x0C000B00); SET_CC;
|
||||
SET_Dd; SET_Rn;
|
||||
SET_uImm8; SET_PUW(0,1,0); // Defaulting to IA w/o ! (Write-back)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VSTM(eFSReg Sd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VSTM.32
|
||||
{
|
||||
// ASSERT( (uImm8>0) && ((Dd+uImm8) <= 32) )
|
||||
DECL_Id(0x0C000A00); SET_CC;
|
||||
SET_Sd; SET_Rn;
|
||||
SET_uImm8; SET_PUW(0,1,0); // Defaulting to IA w/o ! (Write-back)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* V{LD,ST}n: Various extra load/store multiple.
|
||||
*
|
||||
* Not Implemented.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VPUSH/VPOP: Vector Load/Store multiple consecutive vector registers to the stack.
|
||||
*
|
||||
* V{PUSH,POP} .64: A.SIMD .32 VFP
|
||||
*/
|
||||
|
||||
EAPI VPUSH(eFDReg Dd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VPUSH.64
|
||||
{
|
||||
uImm8<<=1;
|
||||
DECL_Id(0x0D2D0B00); SET_CC;
|
||||
SET_Dd; SET_uImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VPUSH(eFSReg Sd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VPUSH.32
|
||||
{
|
||||
DECL_Id(0x0D2D0A00); SET_CC;
|
||||
SET_Sd; SET_uImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
EAPI VPOP(eFDReg Dd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VPOP.64
|
||||
{
|
||||
uImm8<<=1;
|
||||
DECL_Id(0x0CBD0B00); SET_CC;
|
||||
SET_Dd; SET_uImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VPOP(eFSReg Sd, eReg Rn, u32 uImm8, ConditionCode CC=AL) // VPOP.32
|
||||
{
|
||||
DECL_Id(0x0CBD0A00); SET_CC;
|
||||
SET_Sd; SET_uImm8;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Best practice is to remove macro definitions,
|
||||
* this way they can't affect subsequent headers.
|
||||
*/
|
||||
|
||||
#undef SET_Dd
|
||||
#undef SET_Sd
|
||||
|
||||
#undef SET_Rn
|
||||
|
||||
#undef SET_uImm8
|
||||
#undef SET_sImm8
|
||||
|
||||
#undef SET_PUW
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* E_VRegXfer.h * VFP/A.SIMD Register Transfer Instruction Set Encoding
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
|
||||
/////// REPLACE THIS MESS W. SET_Rto16 / SET_Rto16_H22 , SET_Rto12 , SET_Rto0_H5 OR just leave it all in the fn's //////
|
||||
|
||||
|
||||
#define SET_Qd \
|
||||
I |= (((Qd<<1)&0x0E)<<16); \
|
||||
I |= (((Qd<<1)&0x10)<<3)
|
||||
|
||||
#define SET_Qm \
|
||||
I |= (((Qm<<1)&0x0E)); \
|
||||
I |= (((Qm<<1)&0x10)<<1)
|
||||
|
||||
|
||||
#define SET_Dd \
|
||||
I |= ((Dd&0x0F)<<16); \
|
||||
I |= ((Dd&0x10)<<3)
|
||||
|
||||
#define SET_Dm \
|
||||
I |= ((Dm&0x0F)); \
|
||||
I |= ((Dm&0x10)<<1)
|
||||
|
||||
|
||||
#define SET_Sn \
|
||||
I |= ((Sn&0x1E)<<15); \
|
||||
I |= ((Sn&0x01)<<7)
|
||||
|
||||
#define SET_Sm \
|
||||
I |= ((Sm&0x1E)>>1); \
|
||||
I |= ((Sm&0x01)<<5)
|
||||
|
||||
|
||||
#define SET_Rn \
|
||||
I |= ((Rn&15)<<16)
|
||||
|
||||
#define SET_Rt \
|
||||
I |= ((Rt&15)<<12)
|
||||
|
||||
#define SET_Rtx2 \
|
||||
I |= ((Rt&15)<<12) | ((Rt2&15)<<16)
|
||||
|
||||
// VDUP VMOV VMRS VMSR
|
||||
|
||||
/*
|
||||
* VDUP.SZ: Duplicates an element from ARM reg Rt into every element of {Q,D}d A.SIMD
|
||||
*
|
||||
*/
|
||||
EAPI VDUP(eFQReg Qd, eReg Rt, u32 Size=32, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0E800B10); SET_CC;
|
||||
SET_Qd; SET_Rt; I |= (1<<21); // Q
|
||||
if (Size==16) { I |= (1<<5); } // e
|
||||
if (Size==8) { I |= (1<<22); } // b
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VDUP(eFDReg Dd, eReg Rt, u32 Size=32, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0E800B10); SET_CC;
|
||||
SET_Dd; SET_Rt; // No Q
|
||||
if (Size==16) { I |= (1<<5); } // e
|
||||
if (Size==8) { I |= (1<<22); } // b
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VDUP8 (eFQReg Qd, eReg Rt, ConditionCode=AL) { VDUP(Qd,Rt,8, CC); }
|
||||
EAPI VDUP8 (eFDReg Dd, eReg Rt, ConditionCode=AL) { VDUP(Dd,Rt,8, CC); }
|
||||
EAPI VDUP16(eFQReg Qd, eReg Rt, ConditionCode=AL) { VDUP(Qd,Rt,16,CC); }
|
||||
EAPI VDUP16(eFDReg Dd, eReg Rt, ConditionCode=AL) { VDUP(Dd,Rt,16,CC); }
|
||||
EAPI VDUP32(eFQReg Qd, eReg Rt, ConditionCode=AL) { VDUP(Qd,Rt,32,CC); }
|
||||
EAPI VDUP32(eFDReg Dd, eReg Rt, ConditionCode=AL) { VDUP(Dd,Rt,32,CC); }
|
||||
|
||||
EAPI VDUP32(eFQReg Qd, eFDReg Dm, int idx)
|
||||
{
|
||||
DECL_Id(0xF3B00C00);
|
||||
|
||||
//Set_Qd seems to be incompitable here ?
|
||||
I |= (((Qd<<1)&0x0E)<<12); \
|
||||
I |= (((Qd<<1)&0x10)<<18);
|
||||
SET_Dm;
|
||||
I |= 0x40; //SET_Q
|
||||
I |= 0x4 << 16; // 32 bits 4=0100
|
||||
I |= (idx&1) << 19; // set idx
|
||||
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (register)
|
||||
*
|
||||
* VMOV { <Qd, Qm> , <Dd, Dm> } A.SIMD
|
||||
* VMOV { <Dd, Dm> , <Sd, Sm> } VFP sz1 UNDEFINED in single only VFP
|
||||
*/
|
||||
|
||||
EAPI VMOV(eFQReg Qd, eFQReg Qm) // UNCONDITIONAL
|
||||
{
|
||||
DECL_Id(0xF2200110);
|
||||
|
||||
I |= ((Qd&0x0F)<<12) | ((Qd&0x10)<<18);
|
||||
I |= ((Qm&0x0F)<<16) | ((Qm&0x10)<<1); // If !Consistent(M:Qm) then its VORR
|
||||
I |= ((Qm&0x0F)) | ((Qm&0x10)<<3); // If !Consistent(M:Qm) then its VORR
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VMOV(eFDReg Dd, eFDReg Dm) // UNCONDITIONAL
|
||||
{
|
||||
DECL_Id(0xF2200110);
|
||||
|
||||
I |= ((Dd&0x0F)<<12) | ((Dd&0x10)<<18);
|
||||
I |= ((Dm&0x0F)<<16) | ((Dm&0x10)<<3); // If !Consistent(M:Dm) then its VORR
|
||||
I |= ((Dm&0x0F)) | ((Dm&0x10)<<1); // If !Consistent(M:Dm) then its VORR
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
// EAPI VMOV(eFDReg Dd, eFDReg Dm, ConditionCode CC=AL) {} VFP Double Version Not Implemented here for obvious reasons : same as below except would set SZ @bit8 : 0x0EB00B40
|
||||
|
||||
EAPI VMOV(eFSReg Sd, eFSReg Sm, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EB00A40); SET_CC;
|
||||
|
||||
I |= ((Sd&0x1E)<<11) | ((Sd&1)<<22);
|
||||
I |= ((Sm&0x1E)>>1) | ((Sm&1)<<5);
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (Immediate) A.SIMD / VFP
|
||||
*
|
||||
*/
|
||||
|
||||
//// TO BE IMPLEMENTED ////
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (ARM to scalar) A.SIMD / VFP IF Size=32
|
||||
*
|
||||
*/
|
||||
EAPI VMOV(eFDReg Dd, u32 Index, eReg Rt, u32 Size=32, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0E000B10); SET_CC;
|
||||
SET_Dd; SET_Rt;
|
||||
// Dd[x] where x==Index Dd is 64b, 2x32[0,1](1bit) 4x16[0-3](2bits) 8x8[0-7](3bits)
|
||||
if (Size== 8) { I |= (1<<22) | ((Index&4)<<18) | ((Index&3)<<5) ; } // x -> opc1:0, opc2 (3bits) | opc1:1 SET
|
||||
if (Size==16) { I |= (1<<5) | ((Index&2)<<20) | ((Index&1<<6)) ; } // x -> opc1:0, opc2:1 (2bits) | opc2:0 SET
|
||||
if (Size==32) { I |= ((Index&1)<<21) ; } // x -> opc1:0 (1bit)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (scalar to ARM) A.SIMD / VFP IF Size=32
|
||||
*
|
||||
* Note: U (bit32) is unsigned bit, invalid for 32b and we do not handle it at all.. might want to set it for byte,short
|
||||
*/
|
||||
EAPI VMOV(eReg Rt, eFDReg Dd, u32 Index, u32 Size=32, ConditionCode CC=AL) // This is really Vn, but we'll use the same macros..
|
||||
{
|
||||
DECL_Id(0x0E100B10); SET_CC;
|
||||
SET_Dd; SET_Rt;
|
||||
// Dd[x] where x==Index Dd is 64b, 2x32[0,1](1bit) 4x16[0-3](2bits) 8x8[0-7](3bits)
|
||||
if (Size== 8) { I |= (1<<22) | ((Index&4)<<18) | ((Index&3)<<5) ; } // x -> opc1:0, opc2 (3bits) | opc1:1 SET
|
||||
if (Size==16) { I |= (1<<5) | ((Index&2)<<20) | ((Index&1<<6)) ; } // x -> opc1:0, opc2:1 (2bits) | opc2:0 SET
|
||||
if (Size==32) { I |= ((Index&1)<<21) ; } // x -> opc1:0 (1bit)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (between ARM and single either direction) VFP
|
||||
*
|
||||
*/
|
||||
EAPI VMOV(eReg Rt, eFSReg Sn, ConditionCode CC=AL) // Sn !d
|
||||
{
|
||||
DECL_Id(0x0E000A10); SET_CC;
|
||||
SET_Sn; SET_Rt; I |= (1<<20); // op set = TO ARM reg
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI VMOV(eFSReg Sn, eReg Rt, ConditionCode CC=AL) // Sn !d
|
||||
{
|
||||
DECL_Id(0x0E000A10); SET_CC;
|
||||
SET_Sn; SET_Rt; // op NOT set = TO FP Single reg
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (between two ARM regs and two contiguous singles either direction) VFP
|
||||
*
|
||||
*/
|
||||
EAPI VMOV(eReg Rt, eReg Rt2, eFSReg Sm, ConditionCode CC=AL) // Sn !d
|
||||
{
|
||||
DECL_Id(0x0E000A10); SET_CC;
|
||||
SET_Sm; SET_Rtx2; I |= (1<<20); // op set = TO ARM regs
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI VMOV(eFSReg Sm, eReg Rt, eReg Rt2, ConditionCode CC=AL) // Sn !d
|
||||
{
|
||||
DECL_Id(0x0E000A10); SET_CC;
|
||||
SET_Sm; SET_Rtx2; // op NOT set = TO FP Single(s)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOV: (between two ARM regs and a Double) Dm <-> Rt2:Rt A.SIMD/VFP
|
||||
*
|
||||
*/
|
||||
EAPI VMOV(eReg Rt, eReg Rt2, eFDReg Dm, ConditionCode CC=AL) // Sn !d
|
||||
{
|
||||
DECL_Id(0x0C400B10); SET_CC;
|
||||
SET_Dm; SET_Rtx2; I |= (1<<20); // op set = TO ARM regs
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI VMOV(eFDReg Dm, eReg Rt, eReg Rt2, ConditionCode CC=AL) // Sn !d
|
||||
{
|
||||
DECL_Id(0x0C400B10); SET_CC;
|
||||
SET_Dm; SET_Rtx2; // op NOT set = TO FP Single(s)
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOVL: Takes each element in a VDouble && Sign or Zero extends into a VQuad A.SIMD
|
||||
*
|
||||
*/
|
||||
EAPI VMOVL(eFQReg Qd, eFDReg Dm, u32 Size=32, u32 Sign=0) // UNCONDITIONAL Q & ~1
|
||||
{
|
||||
Size >>= 3; // Sz/8 = 1,2 or 4 else if >0 its VSHLL
|
||||
Sign = (Sign>0)?0:1; // Invert to Unsigned
|
||||
DECL_Id(0xF2800A10);
|
||||
|
||||
SET_Dm;
|
||||
I |= ((Qd&0x0F)<<12);
|
||||
I |= ((Qd&0x10)<<18);
|
||||
I |= ((Size &7)<<19); // imm3
|
||||
I |= ((Sign &1)<<24); // U
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VMOVL_S8 (eFQReg Qd, eFDReg Dm) { VMOVL(Qd,Dm,8,1); }
|
||||
EAPI VMOVL_U8 (eFQReg Qd, eFDReg Dm) { VMOVL(Qd,Dm,8,0); }
|
||||
EAPI VMOVL_S16(eFQReg Qd, eFDReg Dm) { VMOVL(Qd,Dm,16,1); }
|
||||
EAPI VMOVL_U16(eFQReg Qd, eFDReg Dm) { VMOVL(Qd,Dm,16,0); }
|
||||
EAPI VMOVL_S32(eFQReg Qd, eFDReg Dm) { VMOVL(Qd,Dm,32,1); }
|
||||
EAPI VMOVL_U32(eFQReg Qd, eFDReg Dm) { VMOVL(Qd,Dm,32,0); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VMOVN: Copies least significant half of each element of a VQuad into the elements of a VDouble A.SIMD
|
||||
*
|
||||
*/
|
||||
EAPI VMOVN(eFDReg Dd, eFQReg Qm, u32 Size=32) // UNCONDITIONAL Q & ~1
|
||||
{
|
||||
Size >>= 4; // Sz/32 = 0,1 or 2
|
||||
DECL_Id(0xF3B20200);
|
||||
|
||||
SET_Qm;
|
||||
I |= ((Dd&0x0F)<<12);
|
||||
I |= ((Dd&0x10)<<18);
|
||||
I |= ((Size &3)<<18); // size
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
EAPI VMOVN16(eFDReg Dd, eFQReg Qm) { VMOVN(Dd,Qm,16); }
|
||||
EAPI VMOVN32(eFDReg Dd, eFQReg Qm) { VMOVN(Dd,Qm,32); }
|
||||
EAPI VMOVN64(eFDReg Dd, eFQReg Qm) { VMOVN(Dd,Qm,64); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* VM{RS,SR} Move ARM reg To/From FPSCR A.SIMD/VFP
|
||||
*/
|
||||
EAPI VMRS(eReg Rt, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EF10A10);
|
||||
SET_CC; SET_Rt;
|
||||
EMIT_I;
|
||||
}
|
||||
EAPI VMSR(eReg Rt, ConditionCode CC=AL)
|
||||
{
|
||||
DECL_Id(0x0EE10A10);
|
||||
SET_CC; SET_Rt;
|
||||
EMIT_I;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#undef SET_Qd
|
||||
#undef SET_Qm
|
||||
|
||||
#undef SET_Dd
|
||||
#undef SET_Dm
|
||||
|
||||
#undef SET_Sn
|
||||
#undef SET_Sm
|
||||
|
||||
#undef SET_Rn
|
||||
#undef SET_Rt
|
||||
#undef SET_Rtx2
|
||||
|
||||
|
||||
};
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* H_Branches.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
|
||||
inline static snat Literal(unat FnAddr)
|
||||
{
|
||||
u8* pc_addr = (u8*)EMIT_GET_PTR();
|
||||
return (snat)((snat)FnAddr - ((snat)pc_addr+8));
|
||||
//return -(snat)((pc_addr+8)-(snat)FnAddr);
|
||||
}
|
||||
|
||||
EAPI CALL(unat FnAddr, ConditionCode CC=AL)
|
||||
{
|
||||
bool isThumb = FnAddr & 1;
|
||||
FnAddr &= ~1;
|
||||
snat lit = Literal(FnAddr);
|
||||
|
||||
if(0==lit) {
|
||||
printf("Error, Compiler caught NULL literal, CALL(%08zX)\n", FnAddr);
|
||||
verify(false);
|
||||
return;
|
||||
}
|
||||
if( (lit<-33554432) || (lit>33554428) ) // ..28 for BL ..30 for BLX
|
||||
{
|
||||
printf("Warning, CALL(%08zX) is out of range for literal(%08zX)\n", FnAddr, lit);
|
||||
// verify(false);
|
||||
|
||||
MOV32(IP, FnAddr, CC);
|
||||
BLX(IP, CC);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isThumb) {
|
||||
verify (CC==CC_EQ);
|
||||
BLX(lit, isThumb);
|
||||
} else {
|
||||
BL(lit,CC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
EAPI JUMP(unat FnAddr, ConditionCode CC=AL)
|
||||
{
|
||||
bool isThumb = FnAddr & 1;
|
||||
FnAddr &= ~1;
|
||||
|
||||
verify(!isThumb);
|
||||
snat lit = Literal(FnAddr);
|
||||
|
||||
/*if(0==lit) {
|
||||
printf("Error, Compiler caught NULL literal, JUMP(%08X)\n", FnAddr);
|
||||
verify(false);
|
||||
return;
|
||||
}*/
|
||||
if( (lit<-33554432) || (lit>33554428) ) // ..28 for BL ..30 for BLX
|
||||
{
|
||||
printf("Warning, %zX is out of range for imm jump! \n", FnAddr);
|
||||
//verify(false);
|
||||
|
||||
MOV32(IP, FnAddr, CC);
|
||||
BX(IP, CC);
|
||||
return;
|
||||
}
|
||||
B(lit,CC); // Note, wont work for THUMB*, have to use bx which is reg only !
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* H_LoadStore.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
/*
|
||||
* Load Helpers
|
||||
*/
|
||||
|
||||
EAPI LoadImmBase(eReg Rt, u32 Base, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rt, Base, CC);
|
||||
|
||||
#if defined(_DEVEL)
|
||||
LDR(Rt,Rt,0, Offset, CC);
|
||||
#else
|
||||
LDR(Rt,Rt,0, CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI LoadImmBase(eReg Rt, eReg Rn, u32 Base, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rn, Base, CC);
|
||||
|
||||
#if defined(_DEVEL)
|
||||
LDR(Rt,Rn,0, Offset, CC);
|
||||
#else
|
||||
LDR(Rt,Rn,0, CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI LoadImmBase16(eReg Rt, u32 Base, bool Extend=false, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rt, Base, CC);
|
||||
LDRH(Rt,Rt,0, CC);
|
||||
|
||||
if(Extend)
|
||||
SXTH(Rt,Rt);
|
||||
}
|
||||
|
||||
EAPI LoadImmBase16(eReg Rt, eReg Rn, u32 Base, bool Extend=false, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rn, Base, CC);
|
||||
LDRH(Rt,Rn,0, CC);
|
||||
|
||||
if(Extend)
|
||||
SXTH(Rt,Rt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Store Helpers
|
||||
*/
|
||||
|
||||
// you pick regs, loads Base with reg addr, you supply data in Rt
|
||||
EAPI StoreImmBase(eReg Rt, eReg Rn, u32 Base, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rn, Base, CC);
|
||||
|
||||
#if defined(_DEVEL)
|
||||
STR(Rt,Rn,0, Offset, CC);
|
||||
#else
|
||||
STR(Rt,Rn,0, CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
// you pick regs, loads Rt with const val, you supply base for Rn
|
||||
EAPI StoreImmVal(eReg Rt, eReg Rn, u32 Val, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rt, Val, CC);
|
||||
|
||||
#if defined(_DEVEL)
|
||||
STR(Rt,Rn,0, Offset, CC);
|
||||
#else
|
||||
STR(Rt,Rn,0, CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
// you pick regs, loads Base with reg addr, loads Rt with const val
|
||||
EAPI StoreImms(eReg Rt, eReg Rn, u32 Base, u32 Val, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rn, Base, CC);
|
||||
MOV32(Rt, Val, CC);
|
||||
|
||||
#if defined(_DEVEL)
|
||||
STR(Rt,Rn,0, Offset, CC);
|
||||
#else
|
||||
STR(Rt,Rn,0, CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(_DEVEL) && 0 // These require testing //
|
||||
|
||||
EAPI LoadImmBase8(eReg Rt, u32 Base, bool Extend=false, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rt, Base, CC);
|
||||
LDRB(Rt,Rt,0, CC);
|
||||
|
||||
if(Extend)
|
||||
SXTB(Rt,Rt);
|
||||
}
|
||||
|
||||
EAPI LoadImmBase8(eReg Rt, eReg Rn, u32 Base, bool Extend=false, ConditionCode CC=AL)
|
||||
{
|
||||
MOV32(Rn, Base, CC);
|
||||
LDRB(Rt,Rn,0, CC);
|
||||
|
||||
if(Extend)
|
||||
SXTB(Rt,Rt);
|
||||
}
|
||||
|
||||
#endif // defined(_DEVEL)
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* H_fp.h
|
||||
*
|
||||
* ARMv7 floating point help routines.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
/// WIP ///
|
||||
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
#if defined(_DEVEL)
|
||||
|
||||
|
||||
/*
|
||||
* vfpVersion(): Returns VFP Arch. Version, or -1 if not supported
|
||||
*/
|
||||
int vfpVersion()
|
||||
{
|
||||
// FPSID bits [22:16] contain version
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int neonVersion()
|
||||
{
|
||||
// ??
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define VFP_SINGLE (1<<0)
|
||||
#define VFP_DOUBLE (1<<1)
|
||||
#define NEON_INTEGER (1<<2)
|
||||
#define NEON_SINGLE (1<<3)
|
||||
#define VFP_TRAPS (1<<8) // VFPv3U
|
||||
#define FPEXT_HALF (1<<16) // Half precision extension
|
||||
|
||||
u32 fpFeatures()
|
||||
{
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // _DEVEL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
Version 1 of the Common VFP subarchitecture has special behavior when the FPSCR.IXE bit is set to 1.
|
||||
The Common VFP subarchitecture version can be identified by checking FPSID bits [22:16]. This field is
|
||||
0b0000001 for version 1. In version 1 of the Common VFP subarchitecture the FPEXC.DEX bit is RAZ/WI.
|
||||
|
||||
|
||||
Detecting which VFP Common subarchitecture registers are implemented
|
||||
An implementation can choose not to implement FPINST and FPINST2, if these registers are not required.
|
||||
|
||||
Set FPEXC.EX=1 and FPEXC.FP2V=1
|
||||
Read back the FPEXC register
|
||||
if FPEXC.EX == 0 then
|
||||
Neither FPINST nor FPINST2 are implemented
|
||||
else
|
||||
if FPEXC.FP2V == 0 then
|
||||
FPINST is implemented, FPINST2 is not implemented.
|
||||
else
|
||||
Both FPINST and FPINST2 are implemented.
|
||||
Clean up
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* H_psuedo.h
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
EAPI MOV32(eReg Rd, u32 Imm32, ConditionCode CC=AL)
|
||||
{
|
||||
MOVW(Rd,((Imm32)&0xFFFF),CC);
|
||||
if (Imm32>>16)
|
||||
MOVT(Rd,((Imm32>>16)&0xFFFF),CC);
|
||||
}
|
||||
#if 0
|
||||
EAPI NEG(eReg Rd,eReg Rs)
|
||||
{
|
||||
RSB(Rd,Rs,0);
|
||||
}
|
||||
#endif
|
||||
EAPI NOT(eReg Rd,eReg Rs)
|
||||
{
|
||||
MVN(Rd,Rs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* H_state.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
enum InstructionSet {
|
||||
IS_ARM,
|
||||
IS_Thumb,
|
||||
IS_Jazelle,
|
||||
IS_ThumbEE
|
||||
};
|
||||
|
||||
enum Endian {
|
||||
E_Little,
|
||||
E_Big
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* coding.h, arm binary instruction coding
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
* Encoding Hi-Order 4bits, ConditionCode
|
||||
*
|
||||
*/
|
||||
|
||||
enum ConditionCode
|
||||
{
|
||||
EQ = 0x00, Equal = EQ, // 0000 Equal Z set
|
||||
NE = 0x01, NotEqual = NE, // 0001 Not equal Z clear
|
||||
CS = 0x02, CarrySet = CS, // 0010 Carry set/unsigned higher or same C set
|
||||
CC = 0x03, CarryClr = CC, // 0011 Carry clear/unsigned lowe C clear
|
||||
MI = 0x04, Minus = MI, // 0100 Minus/negative N set
|
||||
PL = 0x05, Plus = PL, // 0101 Plus/positive or zero N clear
|
||||
VS = 0x06, Overflow = VS, // 0110 Overflow V set
|
||||
VC = 0x07, NoOverflow = VC, // 0111 No overflow V clear
|
||||
|
||||
HI = 0x08, UnHigher = HI, // 1000 Unsigned higher C set and Z clear
|
||||
LS = 0x09, UnLower = LS, // 1001 Unsigned lower or same C clear or Z set
|
||||
|
||||
GE = 0x0A, GrOrEqual = GE, // 1010 Signed greater than or equal N set and V set, or N clear and V clear (N == V)
|
||||
LT = 0x0B, Less = LT, // 1011 Signed less than N set and V clear, or N clear and V set (N != V)
|
||||
GT = 0x0C, Greater = GT, // 1100 Signed greater than Z clear, and either N set and V set, or N clear and V clear (Z == 0,N == V)
|
||||
LE = 0x0D, LessOrEqual = LE, // 1101 Signed less than or equal Z set, or N set and V clear, or N clear and V set (Z == 1 or N != V)
|
||||
|
||||
AL = 0x0E, Always = AL, // 1110 Always (unconditional) -
|
||||
|
||||
|
||||
UC = 0x0F, Unconditional= UC, // 1111 Unconditional Special Instruction for ARMv5? and above
|
||||
|
||||
#define _ARM_COMPAT
|
||||
#if defined(_ARM_COMPAT)
|
||||
CC_EQ=EQ, CC_NE=NE, CC_CS=CS, CC_CC=CC, CC_MI=MI, CC_PL=PL, CC_VS=VS, CC_VC=VC,
|
||||
CC_HI=HI, CC_LS=LS, CC_GE=GE, CC_LT=LT, CC_GT=GT, CC_LE=LE, CC_AL=AL, CC_UC=UC,
|
||||
|
||||
CC_HS=CS, CC_LO=CC,
|
||||
#endif
|
||||
|
||||
ConditionCode_Size
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Data-processing OPCODE 4bits, DPOP
|
||||
*
|
||||
*/
|
||||
|
||||
enum DPOP
|
||||
{
|
||||
DP_AND, // 0000 Logical AND Rd := Rn AND shifter_operand
|
||||
DP_EOR, // 0001 Logical Exclusive OR Rd := Rn EOR shifter_operand
|
||||
DP_SUB, // 0010 Subtract Rd := Rn - shifter_operand
|
||||
DP_RSB, // 0011 Reverse Subtract Rd := shifter_operand - Rn
|
||||
DP_ADD, // 0100 Add Rd := Rn + shifter_operand
|
||||
DP_ADC, // 0101 Add with Carry Rd := Rn + shifter_operand + Carry Flag
|
||||
DP_SBC, // 0110 Subtract with Carry Rd := Rn - shifter_operand - NOT(Carry Flag)
|
||||
DP_RSC, // 0111 Reverse Subtract with Carry Rd := shifter_operand - Rn - NOT(Carry Flag)
|
||||
DP_TST, // 1000 Test Update flags after Rn AND shifter_operand
|
||||
DP_TEQ, // 1001 Test Equivalence Update flags after Rn EOR shifter_operand
|
||||
DP_CMP, // 1010 Compare Update flags after Rn - shifter_operand
|
||||
DP_CMN, // 1011 Compare Negated Update flags after Rn + shifter_operand
|
||||
DP_ORR, // 1100 Logical (inclusive) OR Rd := Rn OR shifter_operand
|
||||
DP_MOV, // 1101 Move Rd := shifter_operand (no first operand)
|
||||
DP_BIC, // 1110 Bit Clear Rd := Rn AND NOT(shifter_operand)
|
||||
DP_MVN // 1111 Move Not Rd := NOT shifter_operand (no first operand)
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum ShiftOp {
|
||||
S_LSL,
|
||||
S_LSR,
|
||||
S_ASR,
|
||||
S_ROR,
|
||||
S_RRX=S_ROR
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* eReg: ARM Register ID
|
||||
*
|
||||
*/
|
||||
enum eReg
|
||||
{
|
||||
r0=0,r1, r2, r3,
|
||||
r4, r5, r6, r7,
|
||||
r8, r9, r10, r11,
|
||||
r12, r13, r14, r15,
|
||||
|
||||
R0=0,R1, R2, R3,
|
||||
R4, R5, R6, R7,
|
||||
R8, R9, R10, R11,
|
||||
R12, R13, R14, R15,
|
||||
|
||||
// Aliases
|
||||
|
||||
a1 = r0, a2 = r1, a3 = r2, a4 = r3,
|
||||
A1 = R0, A2 = R1, A3 = R2, A4 = R3,
|
||||
|
||||
v1 = r4, v2 = r5, v3 = r6, v4 = r7, v5 = r8, v6 = r9,
|
||||
V1 = R4, V2 = R5, V3 = R6, V4 = R7, V5 = R8, V6 = R9,
|
||||
|
||||
rfp = r9, sl = r10, fp = r11, ip = r12, sp = r13, lr = r14, pc = r15,
|
||||
RFP = R9, SL = R10, FP = R11, IP = R12, SP = R13, LR = R14, PC = R15,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* eFQReg: Float [Quad] Register ID (A.SIMD)
|
||||
*
|
||||
*/
|
||||
enum eFQReg
|
||||
{
|
||||
q0=0,q1, q2, q3,
|
||||
q4, q5, q6, q7,
|
||||
q8, q9, q10, q11,
|
||||
q12, q13, q14, q15,
|
||||
|
||||
Q0=0,Q1, Q2, Q3,
|
||||
Q4, Q5, Q6, Q7,
|
||||
Q8, Q9, Q10, Q11,
|
||||
Q12, Q13, Q14, Q15
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* eFDReg: Float [Double] Register ID (VFP / A.SIMD)
|
||||
*
|
||||
*/
|
||||
enum eFDReg
|
||||
{
|
||||
d0=0,d1, d2, d3,
|
||||
d4, d5, d6, d7,
|
||||
d8, d9, d10, d11,
|
||||
d12, d13, d14, d15,
|
||||
d16, d17, d18, d19,
|
||||
d20, d21, d22, d23,
|
||||
d24, d25, d26, d27,
|
||||
d28, d29, d30, d31,
|
||||
|
||||
D0=0,D1, D2, D3,
|
||||
D4, D5, D6, D7,
|
||||
D8, D9, D10, D11,
|
||||
D12, D13, D14, D15,
|
||||
D16, D17, D18, D19,
|
||||
D20, D21, D22, D23,
|
||||
D24, D25, D26, D27,
|
||||
D28, D29, D30, D31
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* eFSReg: Float [Single] Register ID (VFP)
|
||||
*
|
||||
* Note: Using [f,F]regN syntax to avoid clash with s{8,16,32} types.
|
||||
*/
|
||||
enum eFSReg
|
||||
{
|
||||
f0=0,f1, f2, f3,
|
||||
f4, f5, f6, f7,
|
||||
f8, f9, f10, f11,
|
||||
f12, f13, f14, f15,
|
||||
f16, f17, f18, f19,
|
||||
f20, f21, f22, f23,
|
||||
f24, f25, f26, f27,
|
||||
f28, f29, f30, f31,
|
||||
|
||||
F0=0,F1, F2, F3,
|
||||
F4, F5, F6, F7,
|
||||
F8, F9, F10, F11,
|
||||
F12, F13, F14, F15,
|
||||
F16, F17, F18, F19,
|
||||
F20, F21, F22, F23,
|
||||
F24, F25, F26, F27,
|
||||
F28, F29, F30, F31
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum eFSpecialReg
|
||||
{
|
||||
|
||||
// VM**
|
||||
|
||||
FPINST = 9,
|
||||
FPINST2=10,
|
||||
|
||||
FP_R_ERROR=0xFF
|
||||
};
|
||||
|
||||
|
||||
enum ePushPopReg
|
||||
{
|
||||
_r0 =0x0001, _r1 =0x0002, _r2 =0x0004, _r3 =0x0008,
|
||||
_r4 =0x0010, _r5 =0x0020, _r6 =0x0040, _r7 =0x0080,
|
||||
_r8 =0x0100, _r9 =0x0200, _r10=0x0400, _r11=0x0800,
|
||||
_r12=0x1000, _r13=0x2000, _r14=0x4000, _r15=0x8000,
|
||||
|
||||
_a1 = _r0, _a2 = _r1, _a3 = _r2, _a4 = _r3,
|
||||
_v1 = _r4, _v2 = _r5, _v3 = _r6, _v4 = _r7,
|
||||
_v5 = _r8, _v6 = _r9, _rfp = _r9, _sl = _r10,
|
||||
_fp = _r11, _ip = _r12, _sp = _r13, _lr = _r14,
|
||||
_pc = _r15,
|
||||
|
||||
_push_all = 0xFFFF, // Save All 15
|
||||
_push_call = _lr|_rfp, // Save lr && _rfb(cycle count)
|
||||
|
||||
_push_eabi = _lr|_v1|_v2|_v3|_v4|_v5|_v6|_sl|_fp|_ip, // this is guesswork ..
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// WIP ///
|
||||
|
||||
struct FPReg
|
||||
{
|
||||
union
|
||||
{
|
||||
u8 vQ8[16];
|
||||
u8 vD8[8];
|
||||
u8 vS8[4];
|
||||
|
||||
u16 vQ16[8]; // *VFP: If half-word extensions are enabled
|
||||
u16 vD16[4]; // *VFP: If half-word extensions are enabled
|
||||
u16 vS16[2]; // *VFP: If half-word extensions are enabled
|
||||
|
||||
u32 vQ32[4];
|
||||
u32 vD32[2];
|
||||
u32 S;
|
||||
|
||||
// u64 vQ64[2];
|
||||
// u64 D;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* disasm.h, a horribly static yet (hopefully) correct disassembler
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
|
||||
|
||||
inline static void armdis_cc(u32 cond, char *ccbuff) // Length is always 8 for our static'{n,m}ess
|
||||
{
|
||||
switch(cond)
|
||||
{
|
||||
case EQ: sprintf(ccbuff, "EQ"); return;
|
||||
case NE: sprintf(ccbuff, "NE"); return;
|
||||
case CS: sprintf(ccbuff, "CS"); return;
|
||||
case CC: sprintf(ccbuff, "CC"); return;
|
||||
case MI: sprintf(ccbuff, "MI"); return;
|
||||
case PL: sprintf(ccbuff, "PL"); return;
|
||||
case VS: sprintf(ccbuff, "VS"); return;
|
||||
case VC: sprintf(ccbuff, "VC"); return;
|
||||
|
||||
case HI: sprintf(ccbuff, "HI"); return;
|
||||
case LS: sprintf(ccbuff, "LS"); return;
|
||||
|
||||
case GE: sprintf(ccbuff, "GE"); return;
|
||||
case LT: sprintf(ccbuff, "LT"); return;
|
||||
case GT: sprintf(ccbuff, "GT"); return;
|
||||
case LE: sprintf(ccbuff, "LE"); return;
|
||||
|
||||
case AL: return; // sprintf(ccbuff, "AL"); -- ALways doesn't need to be specified
|
||||
|
||||
case UC: //
|
||||
default: return; // DIE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline static void armdis_dp(u32 dpop, char *dpbuff) // Length is always 8 ...
|
||||
{
|
||||
switch(dpop)
|
||||
{
|
||||
case DP_AND: sprintf(dpbuff, "AND"); return;
|
||||
case DP_EOR: sprintf(dpbuff, "EOR"); return;
|
||||
case DP_SUB: sprintf(dpbuff, "SUB"); return;
|
||||
case DP_RSB: sprintf(dpbuff, "RSB"); return;
|
||||
case DP_ADD: sprintf(dpbuff, "ADD"); return;
|
||||
case DP_ADC: sprintf(dpbuff, "ADC"); return;
|
||||
case DP_SBC: sprintf(dpbuff, "SBC"); return;
|
||||
case DP_RSC: sprintf(dpbuff, "RSC"); return;
|
||||
case DP_TST: sprintf(dpbuff, "TST"); return;
|
||||
case DP_TEQ: sprintf(dpbuff, "TEQ"); return;
|
||||
case DP_CMP: sprintf(dpbuff, "CMP"); return;
|
||||
case DP_CMN: sprintf(dpbuff, "CMN"); return;
|
||||
case DP_ORR: sprintf(dpbuff, "ORR"); return;
|
||||
case DP_MOV: sprintf(dpbuff, "MOV"); return;
|
||||
case DP_BIC: sprintf(dpbuff, "BIC"); return;
|
||||
case DP_MVN: sprintf(dpbuff, "MVN"); return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline static void armdis(u32 op, char *disbuf, u32 len=512)
|
||||
{
|
||||
char ipref[8]={0}, isuff[8]={0}, icond[8]={0} ;
|
||||
|
||||
|
||||
// u32 uOP = ((op>>12)&0xFF00) | ((op>>4)&255) ;
|
||||
|
||||
u32 uCC = ((op>>28) & 0x0F) ; //
|
||||
|
||||
u32 uO1 = ((op>>25) & 0x07) ; //
|
||||
u32 uO2 = ((op>> 4) & 0x01) ; //
|
||||
u32 uC1 = ((op>>21) & 0x0F) ; //
|
||||
u32 uC2 = ((op>> 5) & 0x07) ; //
|
||||
u32 uSB = ((op>>20) & 0x01) ; // Sign Change Bit
|
||||
|
||||
|
||||
/*
|
||||
if (uCC == UC) {
|
||||
|
||||
printf ("DBG armdis has UC instruction %X\n", op);
|
||||
sprintf (disbuf, "UNCONDITIONAL / UNHANDLED INSTRUCTION");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (uCC != AL) {
|
||||
armdis_cc(uCC,isuff);
|
||||
}
|
||||
|
||||
|
||||
if (uO1 == 0)
|
||||
{
|
||||
|
||||
if (uO2 == 0) {
|
||||
|
||||
if ((uC1 & 0xC) == 8) {
|
||||
printf ("DBG armdis 0:0 10xx misc instruction \n", uCC);
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 0:");
|
||||
return;
|
||||
}
|
||||
|
||||
// DP imm.shift
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
else if (uO2 == 1) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 0:");
|
||||
}
|
||||
|
||||
}
|
||||
else if (uO1 == 1) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 1:");
|
||||
}
|
||||
else if (uO1 == 2) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 2:");
|
||||
}
|
||||
else if (uO1 == 3) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 3:");
|
||||
}
|
||||
else if (uO1 == 4) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 4:");
|
||||
}
|
||||
else if (uO1 == 5) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 5:");
|
||||
}
|
||||
else if (uO1 == 6) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 6:");
|
||||
}
|
||||
else if (uO1 == 7) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 7:");
|
||||
}
|
||||
else if (uO1 == 8) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 8:");
|
||||
}
|
||||
else if (uO1 == 9) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 9:");
|
||||
}
|
||||
else if (uO1 == 10) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 10:");
|
||||
}
|
||||
else if (uO1 == 11) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 11:");
|
||||
}
|
||||
else if (uO1 == 12) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 12:");
|
||||
}
|
||||
else if (uO1 == 13) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 13:");
|
||||
}
|
||||
else if (uO1 == 14) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 14:");
|
||||
}
|
||||
else if (uO1 == 15) {
|
||||
|
||||
sprintf (disbuf, "UNHANDLED INSTRUCTION 15:");
|
||||
}
|
||||
else {
|
||||
|
||||
sprintf (disbuf, "INVALID INSTRUCTION");
|
||||
}
|
||||
*/
|
||||
if (!uC1 && uO1==5) {
|
||||
//B
|
||||
char tmp[20];
|
||||
tmp[0]='\0';
|
||||
armdis_cc(uCC, tmp);
|
||||
sprintf(disbuf, "B%s %08X", tmp, (op&0xffffff)<<2);
|
||||
} else {
|
||||
armdis_dp(uC1, disbuf);
|
||||
char tmp[20];
|
||||
tmp[0]='\0';
|
||||
armdis_cc(uCC, tmp);
|
||||
if (tmp[0]) {
|
||||
strcat(disbuf, ".\0");
|
||||
strcat(disbuf, tmp);
|
||||
}
|
||||
if (uSB) strcat(disbuf, ".S\0");
|
||||
bool shifter=false;
|
||||
switch (uO1) {
|
||||
case 0:
|
||||
// reg_reg
|
||||
sprintf(tmp,"\tr%d, r%d", (op>>12)&0x0f, (op)&0x0f);
|
||||
shifter=true;
|
||||
break;
|
||||
case 1:
|
||||
// reg_imm
|
||||
sprintf(tmp,"\tr%d, %04X", (op>>16)&0x0f, (op)&0xffff);
|
||||
break;
|
||||
default:
|
||||
shifter=true;
|
||||
sprintf(tmp, " 0x%0X", uO1);
|
||||
}
|
||||
strcat(disbuf, tmp);
|
||||
char* ShiftOpStr[]={"LSL","LSR","ASR","ROR"};
|
||||
u32 shiftop=(op>>5)&0x3;
|
||||
u32 shiftoptype=(op>>4)&0x1;
|
||||
u32 shiftopreg=(op>>8)&0xf;
|
||||
u32 shiftopimm=(op>>7)&0x1f;
|
||||
if (shifter) {
|
||||
if (!shiftop && !shiftoptype && !shiftopimm)
|
||||
{
|
||||
//nothing
|
||||
} else {
|
||||
if ((shiftop==1) || (shiftop==2)) if (!shiftoptype) if (!shiftopimm) shiftopimm=32;
|
||||
sprintf(tmp, " ,%s %s%d", ShiftOpStr[shiftop], (shiftoptype)?" r":" #", (shiftoptype)?shiftopreg:shiftopimm);
|
||||
strcat(disbuf, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Emitter.h
|
||||
*
|
||||
* ARMv7 ISA Emitter for code generation.
|
||||
*
|
||||
* David Miller, 2011.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "arm_coding.h"
|
||||
#include "arm_registers.h"
|
||||
//#include "arm_disasm.h"
|
||||
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
/*
|
||||
* Emitter - Reserved for use w/ static members ..
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class Emitter
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
|
||||
#define EAPI static void
|
||||
|
||||
#define DECL_I \
|
||||
u32 Instruction=0
|
||||
|
||||
#define DECL_Id(d) \
|
||||
u32 Instruction=(d)
|
||||
|
||||
#else
|
||||
|
||||
// #define _inlineExSVoidA __extension__ static __inline void __attribute__ ((__always_inline__))
|
||||
|
||||
#define EAPI \
|
||||
inline static void
|
||||
|
||||
#define DECL_I \
|
||||
static u32 Instruction; \
|
||||
Instruction=0
|
||||
|
||||
#define DECL_Id(d) \
|
||||
static u32 Instruction; \
|
||||
Instruction=(d)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TEMP
|
||||
*/
|
||||
|
||||
|
||||
#define I (Instruction)
|
||||
|
||||
#define SET_CC I |= (((u32)CC&15)<<28)
|
||||
|
||||
#ifndef EMIT_I
|
||||
#define EMIT_I emit_Write32((I));
|
||||
#endif
|
||||
|
||||
#ifndef EMIT_GET_PTR
|
||||
#define EMIT_GET_PTR() emit_GetCCPtr()
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ARM Core Instructions
|
||||
*/
|
||||
|
||||
#include "E_Branches.h"
|
||||
#include "E_DataOp.h"
|
||||
#include "E_Multiply.h"
|
||||
#include "E_Parallel.h"
|
||||
#include "E_Extend.h"
|
||||
#include "E_Misc.h"
|
||||
#include "E_Status.h"
|
||||
#include "E_LoadStore.h"
|
||||
#include "E_Special.h"
|
||||
|
||||
|
||||
/*
|
||||
* ARM VFP/A.SIMD Extension Instructions
|
||||
*/
|
||||
|
||||
#include "E_VLoadStore.h"
|
||||
#include "E_VRegXfer.h"
|
||||
#include "E_VDataOp.h"
|
||||
|
||||
|
||||
/*
|
||||
* Helper Routines & Psuedo-Instructions
|
||||
*/
|
||||
|
||||
#include "H_psuedo.h"
|
||||
|
||||
#include "H_Branches.h"
|
||||
#include "H_LoadStore.h"
|
||||
|
||||
//#include "H_state.h"
|
||||
//#include "H_fp.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
* registers.h
|
||||
*
|
||||
* ARMv7-A system register(s).
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace ARM
|
||||
{
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 Registers for VMSA Implementation. [ref.DDI0406B B3.12]
|
||||
*************************************************************************************************/
|
||||
/*
|
||||
<CRn> <opc1> <CRm> <opc2> [NAME,] Description [Flags]
|
||||
c0 {
|
||||
0 c0 {
|
||||
0 MIDR, Main ID RO
|
||||
1 CTR, Cache Type RO
|
||||
2 TCMTR, TCM Type RO, IMPL.DEFINED
|
||||
3 TLBTR, TLB Type RO, IMPL.DEFINED
|
||||
5 MPIDR, Multiprocessor Affinity RO
|
||||
{4,6,7} MIDR$, Main ID Aliases RO
|
||||
}
|
||||
|
||||
0 c[1-7] [0-7] CPUID ID_{PFRn,DFRn,AFR0,MMFRn,ISARn} RO
|
||||
|
||||
1 c0 0 CCSIDR, Cache Size ID RO
|
||||
1 c0 1 CLIDR, Cache Level ID RO
|
||||
1 c0 7 AIDR, Aux ID RO, IMPL.DEFINED
|
||||
|
||||
2 c0 0 CSSELR, Cache Size Selection RW
|
||||
}
|
||||
|
||||
c1 0 c0 [0-2] System Control RW
|
||||
c1 0 c1 [0-2] Security Extension RW, IMPL.OPTIONAL
|
||||
|
||||
c2 0 c0 [0-2] Translation Table Base RW
|
||||
|
||||
c3 0 c0 0 DACR, Domain Access Control RW
|
||||
|
||||
c5 0 c{0,1} {0,1} Fault Status RW
|
||||
|
||||
c6 0 c0 {0,2] Fault Address RW
|
||||
|
||||
c7 0 {
|
||||
c0 4 NOP WO
|
||||
c1 {0,6} Cache Maintenance operations, Multiprocessing Extensions WO
|
||||
c4 0 PAR, Physical Address RW
|
||||
c5 {0,1,6,7} Cache and branch predictor maintenance operations WO
|
||||
c5 4 CP15ISB, Instruction barrier operation WO, USER
|
||||
c6 {1,2} Cache Maintenance operations WO
|
||||
c8 [0-7] VA to PA translation ops. WO
|
||||
c10 {1,2} Cache management ops. WO
|
||||
c10 {4,5} Data barrier ops. WO, USER
|
||||
c11 1 DCCMVAU, Cache barrier ops. WO
|
||||
c13 1 NOP WO
|
||||
c14 {1,2} Cache management ops. WO
|
||||
}
|
||||
|
||||
c8 0 c{3,5,6,7} [0-3] TLB maintenance ops. * WO
|
||||
|
||||
c9 [0-7] c{0,2,5,8} [0-7] Reserved for Branch Predictor, Cache and TCM ops. RSVD, OP.ACCESS
|
||||
c9 [0-7] c[12-15] [0-7] Reserved for Performance monitors. RSVD, OP.ACCESS
|
||||
|
||||
c10 0 c{0,1,4,8} [0-7] Reserved for TLB lockdown ops. RSVD, OP.ACCESS
|
||||
c10 0 c2 {0,1} PRRR, NMRRR, TEX Remap RW
|
||||
|
||||
c11 [0-7] c{0,8,15} [0-7] Reserved for DMA ops. TCM access. RSVD, OP.ACCESS
|
||||
|
||||
c12 0 c0 {0,1} Security Extensions RW, IMPL.OPTIONAL
|
||||
c12 0 c1 0 ISR, Security Extensions RO, IMPL.OPTIONAL
|
||||
|
||||
c13 0 c0 0 FCSEIDR, FCSE PID RO-if-FCSE-!IMPL / RW?
|
||||
c13 0 c0 [1-4] Software Thread and Context ID RW
|
||||
|
||||
c15 * * * IMPLEMENTATION DEFINED IMPL.DEFINED
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 c0: ID codes registers
|
||||
*************************************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* MIDR: Main ID Register
|
||||
*/
|
||||
struct MIDR
|
||||
{
|
||||
u32 Revision : 4;
|
||||
u32 PriPartNum : 12; // IF Impl:ARM && PriPartNo top 4bits are 0 || 7: arch&variant encoding differs
|
||||
u32 Architecture : 4;
|
||||
u32 Variant : 4;
|
||||
u32 Implementer : 8;
|
||||
};
|
||||
|
||||
enum MIDR_Implementer
|
||||
{
|
||||
ARM_Ltd = 0x41, // 'A'
|
||||
DigitalEquipment_Corp = 0x44, // 'D'
|
||||
Motorola_FreescaleSemi_Inc = 0x4D, // 'M'
|
||||
QUALCOMM_Inc = 0x51, // 'Q'
|
||||
MarvellSemi_Inc = 0x56, // 'V'
|
||||
Intel_Corp = 0x69, // 'i'
|
||||
|
||||
TexasInstruments_Inc = 0xFF // 'T' ???
|
||||
};
|
||||
|
||||
enum MIDR_Arch
|
||||
{
|
||||
ARMv4 = 1,
|
||||
ARMv4T = 2,
|
||||
ARMv5 = 3, // obselete
|
||||
ARMv5T = 4,
|
||||
ARMv5TE = 5,
|
||||
ARMv5TEJ = 6,
|
||||
ARMv6 = 7,
|
||||
CPUID_Defined = 15
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CTR, Cache Type Register
|
||||
*/
|
||||
struct CTR
|
||||
{
|
||||
u32 IminLine : 4;
|
||||
u32 SBZ : 10;
|
||||
u32 L1Ip : 2;
|
||||
u32 DminLine : 4; //
|
||||
u32 ERG : 4; // Exclusives Reservation Granule.
|
||||
u32 CWG : 4; // Cache Writeback Granule.
|
||||
u32 RAZ : 1;
|
||||
u32 REGFMT : 3; // Set to 0b100 for ARMv7 register format, or 0b000 for <=ARMv6 format
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TCMTR, TCM Type Register
|
||||
*/
|
||||
// High 3 bits is 0b100, the rest is IMPL.DEFINED
|
||||
typedef u32 TCMTR;
|
||||
|
||||
|
||||
/*
|
||||
* TLBTR, TLB Type Register
|
||||
*/
|
||||
// Low bit is nU : SET:1: Not unified ( separate instruction and data TLBs )
|
||||
typedef u32 TLBTR;
|
||||
|
||||
|
||||
/*
|
||||
* MPIDR, Multiprocessor Affinity Register
|
||||
*/
|
||||
|
||||
struct MPIDR
|
||||
{
|
||||
u32 AffinityLevel0 : 8;
|
||||
u32 AffinityLevel1 : 8;
|
||||
u32 AffinityLevel2 : 8;
|
||||
u32 MT : 1;
|
||||
u32 RAZ : 5; // Reserved As Zero
|
||||
u32 U : 1; // Set: Processor is part of a Uniprocessor system.
|
||||
u32 MP_Impl : 1; // RAO if MP Extensions are implemented.
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CCSIDR, Cache Size ID Registers
|
||||
*/
|
||||
struct CCSIDR
|
||||
{
|
||||
u32 LineSize : 3;
|
||||
u32 Associativity : 10;
|
||||
u32 NumSets : 15;
|
||||
u32 WA : 1;
|
||||
u32 RA : 1;
|
||||
u32 WB : 1;
|
||||
u32 WT : 1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CLIDR, Cache Level ID Register
|
||||
*/
|
||||
struct CLIDR
|
||||
{
|
||||
u32 Ctype1 : 3;
|
||||
u32 Ctype2 : 3;
|
||||
u32 Ctype3 : 3;
|
||||
u32 Ctype4 : 3;
|
||||
u32 Ctype5 : 3;
|
||||
u32 Ctype6 : 3;
|
||||
u32 Ctype7 : 3;
|
||||
u32 LoUIS : 3;
|
||||
u32 LoC : 3;
|
||||
u32 LoUU : 3;
|
||||
u32 RAZ : 2; // RAZ
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* AIDR, Auxiliary ID Register.
|
||||
*/
|
||||
typedef u32 AIDR; // IMPLEMENTATION DEFINED
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CSSELR, Cache Size Selection Register
|
||||
*/
|
||||
struct CSSELR
|
||||
{
|
||||
u32 InD : 1;
|
||||
u32 Level : 3;
|
||||
u32 SBZP : 28;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 c1: System control registers
|
||||
*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
// SCTRL, ACTLR ////////////////////// TODO ///////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* CPACR: Coprocessor Access Control Register.
|
||||
*
|
||||
* Controls access to all coprocessors other than CP14 & CP15.
|
||||
* It may be used to check for their presence by testing modification to cpN bits.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* D32DIS:1 && ASEDIS:0 is INVALID
|
||||
* ASEDIS on hw { w. VFP & w.o A.SIMD } is RAO/WI, if bit is not supported it is RAZ/WI.
|
||||
*
|
||||
* When Security Extensions are enabled, NSACR controls CP access from non-secure state.
|
||||
*
|
||||
* VFP uses CP10 && CP11, the values of .cp10 && .cp11 should be the same.
|
||||
*/
|
||||
union CPACR
|
||||
{
|
||||
struct {
|
||||
u32 cp0 : 2; // cpN [0-13]:
|
||||
u32 cp1 : 2; // Defines access rights for individual coprocessors.
|
||||
u32 cp2 : 2; // See CP_Access enum below for possible values;
|
||||
u32 cp3 : 2; //
|
||||
u32 cp4 : 2; // To test
|
||||
u32 cp5 : 2;
|
||||
u32 cp6 : 2;
|
||||
u32 cp7 : 2;
|
||||
u32 cp8 : 2;
|
||||
u32 cp9 : 2;
|
||||
u32 cp10 : 2;
|
||||
u32 cp11 : 2;
|
||||
u32 cp12 : 2;
|
||||
u32 cp13 : 2;
|
||||
u32 rsvcd: 2; // SBZP
|
||||
u32 D32DIS:1; // SET: Disables use of D16-D32 of the VFP register file.
|
||||
u32 ASEDIS:1; // SET: Disables all A.SIMD Instructions, VFPv3 shall remain valid.
|
||||
};
|
||||
|
||||
u32 R;
|
||||
};
|
||||
|
||||
/*
|
||||
* CP_Access: Enumerates access rights for CPACR.cpN
|
||||
*
|
||||
*/
|
||||
enum CP_Access
|
||||
{
|
||||
A_Deny, // Deny Access, Attempts to access cause Exception::Undefined_Instruction
|
||||
A_Privileged, // Privileged Access, Attempts to access cause Exception::Undefined_Instruction in User mode.
|
||||
A_Reserved, // Reserved Value, Use of this value is UNPREDICTABLE.
|
||||
A_Full // Full Access, Access is defined by coprocessor.
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* SCR: Secure Configuration Register.
|
||||
*
|
||||
* Requires: Security Extension.
|
||||
*/
|
||||
union SCR
|
||||
{
|
||||
struct {
|
||||
u32 NS : 1; //
|
||||
u32 IRQ : 1; //
|
||||
u32 FIQ : 1; //
|
||||
u32 EA : 1; //
|
||||
u32 FW : 1; //
|
||||
u32 AW : 1; //
|
||||
u32 nET : 1; //
|
||||
u32 SBZP:25;
|
||||
};
|
||||
|
||||
u32 R;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// SDER, Secure Debug Enable Register
|
||||
|
||||
// NSACR, Non-Secure Access Control Register
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 c{2,3}: Memory protection and control registers
|
||||
*************************************************************************************************/
|
||||
|
||||
|
||||
// TTBR0 TTVR1 TTVCR
|
||||
// DACR, Domain Access Control Register
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 c4: Not used
|
||||
*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 c{5,6}: Memory system fault registers
|
||||
*************************************************************************************************/
|
||||
|
||||
// DFSR, Data Fault Status Register
|
||||
// IFSR, Instruction Fault Status Register
|
||||
// ADFSR, Aux. DFSR
|
||||
// AIFSR, Aux. IFSR
|
||||
// DFAR, Data Fault Address Register
|
||||
// IFAR, Instruction Fault Address Register
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* CP15 c7: Cache maintenance / misc
|
||||
*************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
*************************************************************************************************
|
||||
* A.SIMD and VFP extension system registers
|
||||
*************************************************************************************************
|
||||
*************************************************************************************************/
|
||||
|
||||
enum FP_SysRegs
|
||||
{
|
||||
R_FPSID = 0, // 0b0000
|
||||
R_MVFR1 = 6, // 0b0110
|
||||
R_MVFR0 = 7, // 0b0111
|
||||
};
|
||||
|
||||
|
||||
// FPSID Floating Point System ID Register
|
||||
// MVFR1 Media and VFP Feature Register 1
|
||||
// MVFR0 Media and VFP Feature Register 0
|
||||
|
||||
struct FPSID
|
||||
{
|
||||
u32 Revision : 4; // IMPL.DEFINED
|
||||
u32 Variant : 4; // IMPL.DEFINED
|
||||
u32 PartNumber : 8; // IMPL.DEFINED
|
||||
u32 SubArch : 7; // MSB:1 when designed by ARM
|
||||
u32 SW : 1; // Is a software impl. if set
|
||||
u32 Implementer : 8; // Same as MIDR.Implementer
|
||||
};
|
||||
|
||||
enum FP_SubArch
|
||||
{
|
||||
VFPv1 = 0, // Not Permitted in ARMv7
|
||||
VFPv2_Cv1, // Not Permitted in ARMv7
|
||||
VFPv3_Cv2, //
|
||||
VFPv3_Null, // Full hardware, no trap
|
||||
VFPv3_Cv3, //
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Floating-point status and control register
|
||||
//
|
||||
struct FPSCR
|
||||
{
|
||||
u32 IOC : 1; // * All * bits are cumulative exception bits
|
||||
u32 DZC : 1; // *
|
||||
u32 OFC : 1; // *
|
||||
u32 UFC : 1; // *
|
||||
u32 IXC : 1; // *
|
||||
u32 SBZP1 : 2; //
|
||||
u32 IDC : 1; // *
|
||||
u32 IOE : 1; // ** All ** bits are FP trap enable bits
|
||||
u32 DZE : 1; // ** only supported in VFPv2 && VFPv3U
|
||||
u32 OFE : 1; // ** - RAZ elsewhere -
|
||||
u32 UFE : 1; // **
|
||||
u32 IXE : 1; // **
|
||||
u32 SBZP2 : 2; //
|
||||
u32 IDE : 1; // **
|
||||
u32 Len : 3; // SBZ for ARMv7 VFP, ignored for A.SIMD
|
||||
u32 SBZP3 : 1; //
|
||||
u32 Stride : 2; // SBZ for ARMv7 VFP, ignored for A.SIMD
|
||||
u32 RMode : 2; // Rounding Mode
|
||||
u32 FZ : 1; // Flush-to-Zero
|
||||
u32 DN : 1; // Default NaN mode control
|
||||
u32 AHP : 1; // Alt. Half-precision
|
||||
u32 QC : 1; // Cumulative saturation, A.SIMD
|
||||
u32 V : 1; // CC Overflow
|
||||
u32 C : 1; // CC Carry
|
||||
u32 Z : 1; // CC Zero
|
||||
u32 N : 1; // CC Negative
|
||||
};
|
||||
|
||||
enum FP_RoundingMode // A.SIMD Always uses RN !
|
||||
{
|
||||
RN, // Round to Nearest
|
||||
RP, // Round towards Plus Infinity
|
||||
RM, // Round towards Minus Infinity
|
||||
RZ // Round towards Zero
|
||||
};
|
||||
|
||||
|
||||
struct MVFR0
|
||||
{
|
||||
u32 A_SIMD : 4;
|
||||
u32 Single : 4;
|
||||
u32 Double : 4;
|
||||
u32 Trap : 4;
|
||||
u32 Divide : 4;
|
||||
u32 Sqrt : 4;
|
||||
u32 ShortVec: 4;
|
||||
u32 Rounding: 4;
|
||||
};
|
||||
|
||||
struct MVFR1
|
||||
{
|
||||
u32 FtZ_mode : 4;
|
||||
u32 D_NaN_mode : 4;
|
||||
u32 NFP_LdStr : 4;
|
||||
u32 NFP_int : 4;
|
||||
u32 NFP_SPFP : 4;
|
||||
u32 NFP_HPFP : 4;
|
||||
u32 VFP_HPFP : 4;
|
||||
u32 RAZ : 4;
|
||||
|
||||
};
|
||||
};
|
||||
+49
-278
@@ -1,146 +1,16 @@
|
||||
/*
|
||||
reicast build options
|
||||
|
||||
Reicast can support a lot of stuff, and this is an attempt
|
||||
to organize the build time options
|
||||
|
||||
Option categories
|
||||
|
||||
BUILD_* - BUILD_COMPILER, etc...
|
||||
definitions about the build machine
|
||||
|
||||
HOST_*
|
||||
definitions about the host machine
|
||||
|
||||
FEAT_*
|
||||
definitions about the features that this build targets
|
||||
This is higly related to HOST_*, but it's for options that might
|
||||
or might not be avaiable depending on the target host, or that
|
||||
features that are irrelevant of the host
|
||||
|
||||
Eg, Alsa, Pulse Audio and OSS might sense as HOST dedinitions
|
||||
but it usually makes more sense to detect them as runtime. In
|
||||
that context, HOST_ALSA makes no sense because the host might
|
||||
or might not have alsa installed/ running
|
||||
|
||||
MMU makes no sense as a HOST definition at all, so it should
|
||||
be FEAT_HAS_MMU
|
||||
|
||||
TARGET_*
|
||||
A preconfigured default. Eg TARGET_WIN86.
|
||||
|
||||
Naming of options, option values, and how to use them
|
||||
|
||||
for options that makes sense to have a list of values
|
||||
{CATEGORY}_{OPTION}
|
||||
{OPTION}_{VALUE}
|
||||
|
||||
eg.
|
||||
BUILD_COMPILER == COMPILER_GCC, HOST_CPU != CPU_X64, ...
|
||||
|
||||
for options that are boolean
|
||||
{CATEGORY}_IS_{OPTION} or {CATEGORY}_HAS_{OPTION}
|
||||
|
||||
Evaluates to 0 or 1
|
||||
|
||||
If an configuration cannot be neatly split into a set of
|
||||
of orthogonal options, then it makes sense to break things
|
||||
to "sets" or have a hierarchy of options.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
In the beggining it made sense to have an audio backend
|
||||
per operating system. It made sense to have it depend
|
||||
on HOST_OS and seleect DirectSound or alsa.
|
||||
|
||||
// no option needed
|
||||
|
||||
Then, as android was introduced, which also uses OS_LINUX
|
||||
atm, the audio could have been made an option. It could be
|
||||
a HOST_* option, or FEAT_* one. I'd prefer FEAT_*.
|
||||
FEAT_* makes more sense as future wise we might want
|
||||
to support multiple backends.
|
||||
|
||||
FEAT_AUDIO_BACKEND
|
||||
AUDIO_BACKEND_NONE
|
||||
AUDIO_BACKEND_DS
|
||||
AUDIO_BACKEND_ALSA
|
||||
AUDIO_BACKEND_ANDROID
|
||||
|
||||
Used like
|
||||
#if FEAT_AUDIO_BACKEND == AUDIO_BACKEND_DS ....
|
||||
|
||||
At some point, we might have multiple audio backends that
|
||||
can be compiled in and autodetected/selected at runtime.
|
||||
In that case, it might make sense to have the options like
|
||||
|
||||
FEAT_HAS_ALSA
|
||||
FEAT_HAS_DIRECTSOUND
|
||||
FEAT_HAS_ANDROID_AUDIO
|
||||
|
||||
or
|
||||
FEAT_HAS_AUDIO_ALSA
|
||||
FEAT_HAS_AUDIO_DS
|
||||
FEAT_HAS_AUDIO_ANDROID
|
||||
|
||||
The none option might or might not make sense. In this
|
||||
case it can be removed, as it should always be avaiable.
|
||||
|
||||
Guidelines
|
||||
----------
|
||||
|
||||
General rule of thumb, don't overcomplicate things. Start
|
||||
with a simple option, and then make it more complicated
|
||||
as new uses apply (see the example above)
|
||||
|
||||
Don't use too long names, don't use too cryptic names.
|
||||
Most team developers should be able to understand or
|
||||
figure out most of the acronyms used.
|
||||
|
||||
Try to be consistent on the acronyms across all definitions
|
||||
|
||||
Code shouldn't depend on build level options whenever possible
|
||||
|
||||
Generally, the file should compile even if the option/module is
|
||||
disabled. This makes makefiles etc much easier to write
|
||||
|
||||
TARGET_* options should generally only be used in this file
|
||||
|
||||
The current source is *not* good example of these guidelines
|
||||
|
||||
We'll try to be smart and figure out some options/defaults on this file
|
||||
but this shouldn't get too complicated
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//#define NO_MMU
|
||||
#pragma once
|
||||
//#define STRICT_MODE
|
||||
#ifndef STRICT_MODE
|
||||
#define FAST_MMU
|
||||
#define USE_WINCE_HACK
|
||||
#endif
|
||||
|
||||
#define DC_PLATFORM_MASK 7
|
||||
#define DC_PLATFORM_DREAMCAST 0 /* Works, for the most part */
|
||||
#define DC_PLATFORM_DEV_UNIT 1 /* This is missing hardware */
|
||||
#define DC_PLATFORM_NAOMI 2 /* Works, for the most part */
|
||||
#define DC_PLATFORM_NAOMI2 3 /* Needs to be done, 2xsh4 + 2xpvr + custom TNL */
|
||||
#define DC_PLATFORM_ATOMISWAVE 4 /* Works, for the most part */
|
||||
#define DC_PLATFORM_HIKARU 5 /* Needs to be done, 2xsh4, 2x aica , custom vpu */
|
||||
#define DC_PLATFORM_AURORA 6 /* Needs to be done, Uses newer 300 mhz sh4 + 150 mhz pvr mbx SoC */
|
||||
|
||||
|
||||
|
||||
//HOST_OS
|
||||
#define OS_WINDOWS 0x10000001
|
||||
#define OS_LINUX 0x10000002
|
||||
#define OS_DARWIN 0x10000003
|
||||
#define OS_IOS 0x10000004
|
||||
#define OS_ANDROID 0x10000005
|
||||
|
||||
#define OS_UWP 0x10000011
|
||||
#define OS_NSW_HOS 0x80000001
|
||||
#define OS_PS4_BSD 0x80000002
|
||||
|
||||
#define DC_PLATFORM_DREAMCAST 0
|
||||
#define DC_PLATFORM_DEV_UNIT 1
|
||||
#define DC_PLATFORM_NAOMI 2
|
||||
#define DC_PLATFORM_NAOMI2 3
|
||||
#define DC_PLATFORM_ATOMISWAVE 4
|
||||
#define DC_PLATFORM_SYSTEMSP 5
|
||||
|
||||
//HOST_CPU
|
||||
#define CPU_X86 0x20000001
|
||||
@@ -151,77 +21,25 @@
|
||||
#define CPU_PPC 0x20000006
|
||||
#define CPU_PPC64 0x20000007
|
||||
#define CPU_ARM64 0x20000008
|
||||
#define CPU_MIPS64 0x20000009
|
||||
|
||||
//BUILD_COMPILER
|
||||
#define COMPILER_VC 0x30000001
|
||||
#define COMPILER_GCC 0x30000002
|
||||
#define COMPILER_CLANG 0x30000003
|
||||
#define COMPILER_INTEL 0x30000004
|
||||
|
||||
//FEAT_SHREC, FEAT_AREC, FEAT_DSPREC
|
||||
#define DYNAREC_NONE 0x40000001
|
||||
#define DYNAREC_JIT 0x40000002
|
||||
#define DYNAREC_CPP 0x40000003
|
||||
|
||||
|
||||
//automatic
|
||||
|
||||
#ifndef CMAKE_BUILD
|
||||
|
||||
#if defined(_WIN32) && !defined(TARGET_WIN86) && !defined(TARGET_WIN64)
|
||||
#if !defined(_M_AMD64) && !defined(__x86_64__)
|
||||
#define TARGET_WIN86
|
||||
#else
|
||||
#define TARGET_WIN64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define BUILD_COMPILER COMPILER_GCC
|
||||
#else
|
||||
#define BUILD_COMPILER COMPILER_VC
|
||||
#endif
|
||||
|
||||
//Targets
|
||||
#if defined(TARGET_WIN86)
|
||||
#define HOST_OS OS_WINDOWS
|
||||
#define HOST_CPU CPU_X86
|
||||
#elif defined(TARGET_WIN64)
|
||||
#define HOST_OS OS_WINDOWS
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#define HOST_CPU CPU_X64
|
||||
#elif defined(TARGET_PANDORA)
|
||||
#define HOST_OS OS_LINUX
|
||||
#elif defined(__i386__) || defined(_M_IX86)
|
||||
#define HOST_CPU CPU_X86
|
||||
#elif defined(__arm__) || defined (_M_ARM)
|
||||
#define HOST_CPU CPU_ARM
|
||||
#elif defined(TARGET_LINUX_ARMELv7)
|
||||
#define HOST_OS OS_LINUX
|
||||
#define HOST_CPU CPU_ARM
|
||||
#elif defined(TARGET_LINUX_ARMv8)
|
||||
#define HOST_OS OS_LINUX
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define HOST_CPU CPU_ARM64
|
||||
#elif defined(TARGET_LINUX_x86)
|
||||
#define HOST_OS OS_LINUX
|
||||
#define HOST_CPU CPU_X86
|
||||
#elif defined(TARGET_LINUX_x64)
|
||||
#define HOST_OS OS_LINUX
|
||||
#define HOST_CPU CPU_X64
|
||||
#elif defined(TARGET_LINUX_MIPS)
|
||||
#define HOST_OS OS_LINUX
|
||||
#elif defined(__mips__)
|
||||
#define HOST_CPU CPU_MIPS
|
||||
#elif defined(TARGET_GCW0)
|
||||
#define HOST_OS OS_LINUX
|
||||
#define HOST_CPU CPU_MIPS
|
||||
#elif defined(TARGET_IPHONE)
|
||||
#define HOST_OS OS_DARWIN
|
||||
#define HOST_CPU CPU_ARM
|
||||
#elif defined(TARGET_OSX)
|
||||
#define HOST_OS OS_DARWIN
|
||||
#define HOST_CPU CPU_X86
|
||||
#elif defined(TARGET_OSX_X64)
|
||||
#define HOST_OS OS_DARWIN
|
||||
#define HOST_CPU CPU_X64
|
||||
#else
|
||||
#error Invalid Target: TARGET_* not defined
|
||||
#define HOST_CPU CPU_GENERIC
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NO_REC)
|
||||
@@ -236,35 +54,22 @@
|
||||
#define FEAT_DSPREC DYNAREC_NONE
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NO_JIT)
|
||||
#define FEAT_SHREC DYNAREC_CPP
|
||||
#define FEAT_AREC DYNAREC_NONE
|
||||
#define FEAT_DSPREC DYNAREC_NONE
|
||||
#endif
|
||||
|
||||
#endif // !CMAKE_BUILD
|
||||
|
||||
|
||||
#if defined(TARGET_NO_NIXPROF)
|
||||
#define FEAT_HAS_NIXPROF 0
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NO_COREIO_HTTP)
|
||||
#define FEAT_HAS_COREIO_HTTP 0
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_SOFTREND)
|
||||
#define FEAT_HAS_SOFTREND 1
|
||||
#ifdef __SWITCH__
|
||||
#define FEAT_NO_RWX_PAGES
|
||||
#endif
|
||||
|
||||
//defaults
|
||||
|
||||
#ifndef FEAT_SHREC
|
||||
#define FEAT_SHREC DYNAREC_JIT
|
||||
#if HOST_CPU == CPU_ARM || HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
|
||||
#define FEAT_SHREC DYNAREC_JIT
|
||||
#else
|
||||
#define FEAT_SHREC DYNAREC_NONE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FEAT_AREC
|
||||
#if HOST_CPU == CPU_ARM || HOST_CPU == CPU_ARM64
|
||||
#if HOST_CPU == CPU_ARM || HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X64
|
||||
#define FEAT_AREC DYNAREC_JIT
|
||||
#else
|
||||
#define FEAT_AREC DYNAREC_NONE
|
||||
@@ -272,54 +77,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef FEAT_DSPREC
|
||||
#if HOST_CPU == CPU_X86 || HOST_CPU == CPU_ARM64
|
||||
#if HOST_CPU == CPU_ARM || HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
|
||||
#define FEAT_DSPREC DYNAREC_JIT
|
||||
#else
|
||||
#define FEAT_DSPREC DYNAREC_NONE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FEAT_HAS_NIXPROF
|
||||
#ifndef _WIN32
|
||||
#define FEAT_HAS_NIXPROF 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FEAT_HAS_COREIO_HTTP
|
||||
#define FEAT_HAS_COREIO_HTTP 1
|
||||
#endif
|
||||
|
||||
#ifndef FEAT_HAS_SOFTREND
|
||||
#define FEAT_HAS_SOFTREND BUILD_COMPILER == COMPILER_VC //GCC wants us to enable sse4 globaly to enable intrins
|
||||
#endif
|
||||
|
||||
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
|
||||
#define HOST_64BIT_CPU
|
||||
#endif
|
||||
|
||||
//Depricated build configs
|
||||
#ifdef HOST_NO_REC
|
||||
#error Dont use HOST_NO_REC
|
||||
#endif
|
||||
|
||||
#ifdef HOST_NO_AREC
|
||||
#error Dont use HOST_NO_AREC
|
||||
#endif
|
||||
|
||||
|
||||
// Compiler Related
|
||||
|
||||
#define COMPILER_VC_OR_CLANG_WIN32 ((BUILD_COMPILER == COMPILER_VC) || (BUILD_COMPILER == COMPILER_CLANG) && HOST_OS == OS_WINDOWS)
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define ATTR_USED __attribute__((used))
|
||||
#define ATTR_UNUSED __attribute__((used))
|
||||
#else
|
||||
#define ATTR_USED
|
||||
#define ATTR_UNUSED
|
||||
#endif
|
||||
|
||||
|
||||
// Some restrictions on FEAT_NO_RWX_PAGES
|
||||
#if defined(FEAT_NO_RWX_PAGES) && FEAT_SHREC == DYNAREC_JIT
|
||||
#if HOST_CPU != CPU_X64 && HOST_CPU != CPU_ARM64
|
||||
@@ -327,25 +91,32 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
#define TARGET_UWP
|
||||
#endif
|
||||
#ifdef HAVE_D3D11
|
||||
#define USE_DX11
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LIBRETRO) && !defined(TARGET_NO_EXCEPTIONS)
|
||||
#define USE_GGPO
|
||||
#endif
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(TARGET_IPHONE) && !defined(TARGET_UWP) \
|
||||
&& !defined(__SWITCH__) && !defined(LIBRETRO) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
#define NAOMI_MULTIBOARD
|
||||
#endif
|
||||
|
||||
// TARGET PLATFORM
|
||||
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
|
||||
#define AICA_CORE_CLOCK (GD_CLOCK * 4 / 3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
|
||||
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK / 2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
|
||||
#define SH4_MAIN_CLOCK (200 * 1000 * 1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)
|
||||
#define G2_BUS_CLOCK (25 * 1000 * 1000) //[25000000] from Holly, from SH4_RAM_CLOCK w/ 2 2:1 plls
|
||||
|
||||
#define RAM_SIZE_MAX (32*1024*1024)
|
||||
#define VRAM_SIZE_MAX (16*1024*1024)
|
||||
#define ARAM_SIZE_MAX (8*1024*1024)
|
||||
#define BUILD_DREAMCAST 1
|
||||
|
||||
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
|
||||
|
||||
#define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
|
||||
#define ADAC_CLOCK (AICA_CORE_CLOCK/2) //[11289600] 44100*256, AICA CORE -> PLL 4:1 -> ADAC -- 256fs
|
||||
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK/2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
|
||||
#define AICA_SDRAM_CLOCK (GD_CLOCK*2) //[67737600] GD-> PLL 2 -> SDRAM
|
||||
#define SH4_MAIN_CLOCK (200*1000*1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)
|
||||
#define SH4_RAM_CLOCK (100*1000*1000) //[100000000] XTal(13.5) -> PLL (33.3) -> PLL 1:3 (100) , also suplied to HOLLY chip
|
||||
#define G2_BUS_CLOCK (25*1000*1000) //[25000000] from Holly, from SH4_RAM_CLOCK w/ 2 2:1 plls
|
||||
|
||||
#if defined(GLES) && !defined(GLES3)
|
||||
#if defined(GLES) && !defined(GLES3) && !defined(GLES2)
|
||||
// Only use GL ES 2.0 API functions
|
||||
#define GLES2
|
||||
#endif
|
||||
+47
-122
@@ -1,24 +1,18 @@
|
||||
/*
|
||||
Config file crap
|
||||
Supports various things, as virtual config entries and such crap
|
||||
Works surprisingly well considering how old it is ...
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE (1)
|
||||
#include <cerrno>
|
||||
#include "cfg.h"
|
||||
#include "ini.h"
|
||||
#include "stdclass.h"
|
||||
|
||||
static string cfgPath;
|
||||
#include <cerrno>
|
||||
|
||||
static std::string cfgPath;
|
||||
static bool save_config = true;
|
||||
static bool autoSave = true;
|
||||
|
||||
static emucfg::ConfigFile cfgdb;
|
||||
static string game_id;
|
||||
static bool has_game_specific_config = false;
|
||||
|
||||
void savecfgf()
|
||||
static void saveConfigFile()
|
||||
{
|
||||
FILE* cfgfile = fopen(cfgPath.c_str(),"wt");
|
||||
FILE* cfgfile = nowide::fopen(cfgPath.c_str(), "wt");
|
||||
if (!cfgfile)
|
||||
{
|
||||
WARN_LOG(COMMON, "Error: Unable to open file '%s' for saving", cfgPath.c_str());
|
||||
@@ -26,53 +20,16 @@ void savecfgf()
|
||||
else
|
||||
{
|
||||
cfgdb.save(cfgfile);
|
||||
fclose(cfgfile);
|
||||
std::fclose(cfgfile);
|
||||
}
|
||||
}
|
||||
void cfgSaveStr(const wchar * Section, const wchar * Key, const wchar * String)
|
||||
void cfgSaveStr(const std::string& section, const std::string& key, const std::string& value)
|
||||
{
|
||||
const std::string section(Section);
|
||||
const std::string key(Key);
|
||||
const std::string value(String);
|
||||
if (cfgHasGameSpecificConfig())
|
||||
{
|
||||
if (cfgdb.get(section, key, "") == value)
|
||||
// Same value as main config: delete entry
|
||||
cfgdb.delete_entry(game_id, key);
|
||||
else
|
||||
cfgdb.set(game_id, key, value);
|
||||
}
|
||||
else
|
||||
cfgdb.set(section, key, value);
|
||||
if(save_config)
|
||||
{
|
||||
savecfgf();
|
||||
}
|
||||
cfgdb.set(section, key, value);
|
||||
|
||||
if (save_config && autoSave)
|
||||
saveConfigFile();
|
||||
}
|
||||
//New config code
|
||||
|
||||
/*
|
||||
I want config to be really flexible .. so , here is the new implementation :
|
||||
|
||||
Functions :
|
||||
cfgLoadInt : Load an int , if it does not exist save the default value to it and return it
|
||||
cfgSaveInt : Save an int
|
||||
cfgLoadStr : Load a str , if it does not exist save the default value to it and return it
|
||||
cfgSaveStr : Save a str
|
||||
cfgExists : Returns true if the Section:Key exists. If Key is null , it retuns true if Section exists
|
||||
|
||||
Config parameters can be read from the config file , and can be given at the command line
|
||||
-cfg section:key=value -> defines a value at command line
|
||||
If a cfgSave* is made on a value defined by command line , then the command line value is replaced by it
|
||||
|
||||
cfg values set by command line are not written to the cfg file , unless a cfgSave* is used
|
||||
*/
|
||||
|
||||
///////////////////////////////
|
||||
/*
|
||||
** This will verify there is a working file @ ./szIniFn
|
||||
** - if not present, it will write defaults
|
||||
*/
|
||||
|
||||
bool cfgOpen()
|
||||
{
|
||||
@@ -80,14 +37,14 @@ bool cfgOpen()
|
||||
// Config dir not set (android onboarding)
|
||||
return false;
|
||||
|
||||
const char* filename = "/emu.cfg";
|
||||
string config_path_read = get_readonly_config_path(filename);
|
||||
const char* filename = "emu.cfg";
|
||||
std::string config_path_read = get_readonly_config_path(filename);
|
||||
cfgPath = get_writable_config_path(filename);
|
||||
|
||||
FILE* cfgfile = fopen(config_path_read.c_str(),"r");
|
||||
FILE* cfgfile = nowide::fopen(config_path_read.c_str(), "r");
|
||||
if(cfgfile != NULL) {
|
||||
cfgdb.parse(cfgfile);
|
||||
fclose(cfgfile);
|
||||
std::fclose(cfgfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -98,7 +55,7 @@ bool cfgOpen()
|
||||
{
|
||||
// Config file didn't exist
|
||||
INFO_LOG(COMMON, "Creating new empty config file at '%s'", cfgPath.c_str());
|
||||
savecfgf();
|
||||
saveConfigFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -110,98 +67,66 @@ bool cfgOpen()
|
||||
return true;
|
||||
}
|
||||
|
||||
//Implementations of the interface :)
|
||||
//Section must be set
|
||||
//If key is 0 , it looks for the section
|
||||
//0 : not found
|
||||
//1 : found section , key was 0
|
||||
//2 : found section & key
|
||||
s32 cfgExists(const wchar * Section, const wchar * Key)
|
||||
std::string cfgLoadStr(const std::string& section, const std::string& key, const std::string& def)
|
||||
{
|
||||
if(cfgdb.has_entry(string(Section), string(Key)))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (cfgdb.has_section(string(Section)) ? 1 : 0);
|
||||
}
|
||||
return cfgdb.get(section, key, def);
|
||||
}
|
||||
|
||||
void cfgLoadStr(const wchar * Section, const wchar * Key, wchar * Return,const wchar* Default)
|
||||
void cfgSaveInt(const std::string& section, const std::string& key, s32 value)
|
||||
{
|
||||
string value = cfgdb.get(Section, Key, Default);
|
||||
// FIXME: Buffer overflow possible
|
||||
strcpy(Return, value.c_str());
|
||||
cfgSaveStr(section, key, std::to_string(value));
|
||||
}
|
||||
|
||||
string cfgLoadStr(const wchar * Section, const wchar * Key, const wchar* Default)
|
||||
s32 cfgLoadInt(const std::string& section, const std::string& key, s32 def)
|
||||
{
|
||||
std::string v = cfgdb.get(string(Section), string(Key), string(Default));
|
||||
if (cfgHasGameSpecificConfig())
|
||||
v = cfgdb.get(game_id, string(Key), v);
|
||||
|
||||
return v;
|
||||
return cfgdb.get_int(section, key, def);
|
||||
}
|
||||
|
||||
//These are helpers , mainly :)
|
||||
void cfgSaveInt(const wchar * Section, const wchar * Key, s32 Int)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "%d", Int);
|
||||
cfgSaveStr(Section, Key, str);
|
||||
int64_t cfgLoadInt64(const std::string& section, const std::string& key, int64_t def) {
|
||||
return cfgdb.get_int64(section, key, def);
|
||||
}
|
||||
void cfgSaveInt64(const std::string& section, const std::string& key, int64_t value) {
|
||||
cfgdb.set_int64(section, key, value);
|
||||
}
|
||||
|
||||
s32 cfgLoadInt(const wchar * Section, const wchar * Key,s32 Default)
|
||||
void cfgSaveBool(const std::string& section, const std::string& key, bool value)
|
||||
{
|
||||
s32 v = cfgdb.get_int(string(Section), string(Key), Default);
|
||||
if (cfgHasGameSpecificConfig())
|
||||
v = cfgdb.get_int(game_id, string(Key), v);
|
||||
|
||||
return v;
|
||||
cfgSaveStr(section, key, value ? "yes" : "no");
|
||||
}
|
||||
|
||||
void cfgSaveBool(const wchar * Section, const wchar * Key, bool BoolValue)
|
||||
bool cfgLoadBool(const std::string& section, const std::string& key, bool def)
|
||||
{
|
||||
cfgSaveStr(Section, Key, BoolValue ? "yes" : "no");
|
||||
return cfgdb.get_bool(section, key, def);
|
||||
}
|
||||
|
||||
bool cfgLoadBool(const wchar * Section, const wchar * Key,bool Default)
|
||||
void cfgSetVirtual(const std::string& section, const std::string& key, const std::string& value)
|
||||
{
|
||||
bool v = cfgdb.get_bool(string(Section), string(Key), Default);
|
||||
if (cfgHasGameSpecificConfig())
|
||||
v = cfgdb.get_bool(game_id, string(Key), v);
|
||||
|
||||
return v;
|
||||
cfgdb.set(section, key, value, true);
|
||||
}
|
||||
|
||||
void cfgSetVirtual(const wchar * Section, const wchar * Key, const wchar * String)
|
||||
bool cfgIsVirtual(const std::string& section, const std::string& key)
|
||||
{
|
||||
cfgdb.set(string(Section), string(Key), string(String), true);
|
||||
return cfgdb.is_virtual(section, key);
|
||||
}
|
||||
|
||||
void cfgSetGameId(const char *id)
|
||||
bool cfgHasSection(const std::string& section)
|
||||
{
|
||||
game_id = id;
|
||||
return cfgdb.has_section(section);
|
||||
}
|
||||
|
||||
const char *cfgGetGameId()
|
||||
void cfgDeleteSection(const std::string& section)
|
||||
{
|
||||
return game_id.c_str();
|
||||
cfgdb.delete_section(section);
|
||||
}
|
||||
|
||||
bool cfgHasGameSpecificConfig()
|
||||
void cfgDeleteEntry(const std::string& section, const std::string& key)
|
||||
{
|
||||
return has_game_specific_config || cfgdb.has_section(game_id);
|
||||
cfgdb.delete_entry(section, key);
|
||||
}
|
||||
|
||||
void cfgMakeGameSpecificConfig()
|
||||
void cfgSetAutoSave(bool autoSave)
|
||||
{
|
||||
has_game_specific_config = true;
|
||||
}
|
||||
|
||||
void cfgDeleteGameSpecificConfig()
|
||||
{
|
||||
has_game_specific_config = false;
|
||||
cfgdb.delete_section(game_id);
|
||||
::autoSave = autoSave;
|
||||
if (autoSave)
|
||||
saveConfigFile();
|
||||
}
|
||||
+15
-21
@@ -1,28 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
/*
|
||||
** cfg* prototypes, if you pass NULL to a cfgSave* it will wipe out the section
|
||||
** } if you pass it to lpKey it will wipe out that particular entry
|
||||
** } if you add write to something it will create it if its not present
|
||||
** } ** Strings passed to LoadStr should be MAX_PATH in size ! **
|
||||
*/
|
||||
|
||||
bool cfgOpen();
|
||||
s32 cfgLoadInt(const wchar * lpSection, const wchar * lpKey,s32 Default);
|
||||
void cfgSaveInt(const wchar * lpSection, const wchar * lpKey, s32 Int);
|
||||
void cfgLoadStr(const wchar * lpSection, const wchar * lpKey, wchar * lpReturn,const wchar* lpDefault);
|
||||
string cfgLoadStr(const wchar * Section, const wchar * Key, const wchar* Default);
|
||||
void cfgSaveStr(const wchar * lpSection, const wchar * lpKey, const wchar * lpString);
|
||||
void cfgSaveBool(const wchar * Section, const wchar * Key, bool BoolValue);
|
||||
bool cfgLoadBool(const wchar * Section, const wchar * Key,bool Default);
|
||||
s32 cfgExists(const wchar * Section, const wchar * Key);
|
||||
void cfgSetVirtual(const wchar * lpSection, const wchar * lpKey, const wchar * lpString);
|
||||
s32 cfgLoadInt(const std::string& section, const std::string& key, s32 def);
|
||||
void cfgSaveInt(const std::string& section, const std::string& key, s32 value);
|
||||
int64_t cfgLoadInt64(const std::string& section, const std::string& key, int64_t def);
|
||||
void cfgSaveInt64(const std::string& section, const std::string& key, int64_t value);
|
||||
std::string cfgLoadStr(const std::string& section, const std::string& key, const std::string& def);
|
||||
void cfgSaveStr(const std::string& section, const std::string& key, const std::string& value);
|
||||
void cfgSaveBool(const std::string& section, const std::string& key, bool value);
|
||||
bool cfgLoadBool(const std::string& section, const std::string& key, bool def);
|
||||
void cfgSetVirtual(const std::string& section, const std::string& key, const std::string& value);
|
||||
bool cfgIsVirtual(const std::string& section, const std::string& key);
|
||||
|
||||
bool ParseCommandLine(int argc,wchar* argv[]);
|
||||
void ParseCommandLine(int argc, char *argv[]);
|
||||
|
||||
void cfgSetGameId(const char *id);
|
||||
const char *cfgGetGameId();
|
||||
bool cfgHasGameSpecificConfig();
|
||||
void cfgMakeGameSpecificConfig();
|
||||
void cfgDeleteGameSpecificConfig();
|
||||
void cfgSetAutoSave(bool autoSave);
|
||||
bool cfgHasSection(const std::string& section);
|
||||
void cfgDeleteSection(const std::string& section);
|
||||
void cfgDeleteEntry(const std::string& section, const std::string& key);
|
||||
+65
-79
@@ -1,92 +1,66 @@
|
||||
/*
|
||||
Command line parsing
|
||||
~yay~
|
||||
|
||||
Nothing too interesting here, really
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
|
||||
#include "cfg/cfg.h"
|
||||
#include "stdclass.h"
|
||||
|
||||
wchar* trim_ws(wchar* str)
|
||||
{
|
||||
if (str==0 || strlen(str)==0)
|
||||
return 0;
|
||||
|
||||
while(*str)
|
||||
{
|
||||
if (!isspace(*str))
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
|
||||
size_t l=strlen(str);
|
||||
|
||||
if (l==0)
|
||||
return 0;
|
||||
|
||||
while(l>0)
|
||||
{
|
||||
if (!isspace(str[l-1]))
|
||||
break;
|
||||
str[l-1]=0;
|
||||
l--;
|
||||
}
|
||||
|
||||
if (l==0)
|
||||
return 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
int setconfig(wchar** arg,int cl)
|
||||
static int setconfig(char *arg[], int cl)
|
||||
{
|
||||
int rv=0;
|
||||
for(;;)
|
||||
|
||||
if (cl < 1)
|
||||
{
|
||||
if (cl<1)
|
||||
WARN_LOG(COMMON, "-config : invalid number of parameters, format is section:key=value,section:key=value,...");
|
||||
return rv;
|
||||
}
|
||||
|
||||
std::string value(arg[1]);
|
||||
for(;;)
|
||||
{
|
||||
auto seppos = value.find(':');
|
||||
if (seppos == std::string::npos)
|
||||
{
|
||||
WARN_LOG(COMMON, "-config : invalid number of parameters, format is section:key=value");
|
||||
return rv;
|
||||
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value,section:key=value,...", value.c_str());
|
||||
break;
|
||||
}
|
||||
wchar* sep=strstr(arg[1],":");
|
||||
if (sep==0)
|
||||
auto eqpos = value.find('=', seppos);
|
||||
if (eqpos == std::string::npos)
|
||||
{
|
||||
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value", arg[1]);
|
||||
return rv;
|
||||
}
|
||||
wchar* value=strstr(sep+1,"=");
|
||||
if (value==0)
|
||||
{
|
||||
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value", arg[1]);
|
||||
return rv;
|
||||
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value,section:key=value,...", value.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
*sep++=0;
|
||||
*value++=0;
|
||||
auto commapos = value.find(',', eqpos);
|
||||
|
||||
wchar* sect=trim_ws(arg[1]);
|
||||
wchar* key=trim_ws(sep);
|
||||
value=trim_ws(value);
|
||||
std::string sect = trim_ws(value.substr(0, seppos));
|
||||
std::string key = trim_ws(value.substr(seppos + 1, eqpos - seppos - 1));
|
||||
auto endofcurrent = (commapos == std::string::npos) ? value.size() : commapos;
|
||||
std::string next = (commapos == std::string::npos) ? "" : trim_ws(value.substr(endofcurrent + 1, value.size() - endofcurrent));
|
||||
value = trim_ws(value.substr(eqpos + 1, endofcurrent - eqpos - 1));
|
||||
|
||||
if (sect==0 || key==0)
|
||||
if (sect.empty() || key.empty())
|
||||
{
|
||||
WARN_LOG(COMMON, "-config : invalid parameter, format is section:key=value");
|
||||
return rv;
|
||||
WARN_LOG(COMMON, "-config : invalid parameter, format is section:key=value,section:key=value,...");
|
||||
break;
|
||||
}
|
||||
|
||||
const wchar* constval = value;
|
||||
if (constval==0)
|
||||
constval="";
|
||||
INFO_LOG(COMMON, "Virtual cfg %s:%s=%s", sect, key, value);
|
||||
INFO_LOG(COMMON, "Virtual cfg %s:%s=%s", sect.c_str(), key.c_str(), value.c_str());
|
||||
|
||||
cfgSetVirtual(sect,key,value);
|
||||
rv++;
|
||||
cfgSetVirtual(sect, key, value);
|
||||
|
||||
if (cl>=3 && stricmp(arg[2],",")==0)
|
||||
if (commapos == std::string::npos)
|
||||
rv++;
|
||||
|
||||
if (commapos != std::string::npos)
|
||||
{
|
||||
value = next;
|
||||
continue;
|
||||
}
|
||||
else if (cl>=3 && strcmp(arg[2],",")==0)
|
||||
{
|
||||
cl-=2;
|
||||
arg+=2;
|
||||
@@ -99,27 +73,29 @@ int setconfig(wchar** arg,int cl)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int showhelp(wchar** arg,int cl)
|
||||
static int showhelp()
|
||||
{
|
||||
NOTICE_LOG(COMMON, "Available commands:");
|
||||
|
||||
NOTICE_LOG(COMMON, "-config section:key=value [, ..]: add a virtual config value\n Virtual config values won't be saved to the .cfg file\n unless a different value is written to em\nNote :\n You can specify many settings in the xx:yy=zz , gg:hh=jj , ...\n format.The spaces between the values and ',' are needed.");
|
||||
NOTICE_LOG(COMMON, "-help: show help info");
|
||||
printf("Usage: flycast [OPTION]... [CONTENT]\n\n");
|
||||
printf("Options:\n");
|
||||
printf("-config section:key=value add a virtual config value;\n");
|
||||
printf(" virtual config values won't be saved to the .cfg file\n");
|
||||
printf(" unless a different value is written to them\n");
|
||||
printf("-help display this help\n");
|
||||
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ParseCommandLine(int argc,wchar* argv[])
|
||||
void ParseCommandLine(int argc,char* argv[])
|
||||
{
|
||||
cfgSetVirtual("config", "image", "");
|
||||
settings.content.path.clear();
|
||||
int cl=argc-2;
|
||||
wchar** arg=argv+1;
|
||||
char** arg=argv+1;
|
||||
while(cl>=0)
|
||||
{
|
||||
if (stricmp(*arg,"-help")==0 || stricmp(*arg,"--help")==0)
|
||||
{
|
||||
showhelp(arg,cl);
|
||||
return true;
|
||||
showhelp();
|
||||
}
|
||||
else if (stricmp(*arg,"-config")==0 || stricmp(*arg,"--config")==0)
|
||||
{
|
||||
@@ -127,6 +103,17 @@ bool ParseCommandLine(int argc,wchar* argv[])
|
||||
cl-=as;
|
||||
arg+=as;
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
else if (!strncmp(*arg, "-NSDocumentRevisions", 20))
|
||||
{
|
||||
arg++;
|
||||
cl--;
|
||||
}
|
||||
#endif
|
||||
else if ((*arg)[0] == '-')
|
||||
{
|
||||
WARN_LOG(COMMON, "Ignoring unknown command line option '%s'", *arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* extension = strrchr(*arg, '.');
|
||||
@@ -136,22 +123,21 @@ bool ParseCommandLine(int argc,wchar* argv[])
|
||||
|| stricmp(extension, ".gdi") == 0 || stricmp(extension, ".cue") == 0))
|
||||
{
|
||||
INFO_LOG(COMMON, "Using '%s' as cd image", *arg);
|
||||
cfgSetVirtual("config", "image", *arg);
|
||||
settings.content.path = *arg;
|
||||
}
|
||||
else if (extension && stricmp(extension, ".elf") == 0)
|
||||
{
|
||||
INFO_LOG(COMMON, "Using '%s' as reios elf file", *arg);
|
||||
cfgSetVirtual("config", "bios.UseReios", "yes");
|
||||
cfgSetVirtual("reios", "ElfFile", *arg);
|
||||
settings.content.path = *arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(COMMON, "Using '%s' as rom", *arg);
|
||||
cfgSetVirtual("config", "image", *arg);
|
||||
settings.content.path = *arg;
|
||||
}
|
||||
}
|
||||
arg++;
|
||||
cl--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
+69
-74
@@ -1,13 +1,13 @@
|
||||
#include "ini.h"
|
||||
#include "types.h"
|
||||
#include <sstream>
|
||||
|
||||
wchar* trim_ws(wchar* str);
|
||||
#include "stdclass.h"
|
||||
|
||||
namespace emucfg {
|
||||
|
||||
/* ConfigEntry */
|
||||
|
||||
const string& ConfigEntry::get_string() const
|
||||
const std::string& ConfigEntry::get_string() const
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
@@ -16,7 +16,7 @@ int ConfigEntry::get_int()
|
||||
{
|
||||
if (strstr(this->value.c_str(), "0x") != NULL)
|
||||
{
|
||||
return strtol(this->value.c_str(), NULL, 16);
|
||||
return (int)strtoul(this->value.c_str(), NULL, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -24,6 +24,14 @@ int ConfigEntry::get_int()
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ConfigEntry::get_int64()
|
||||
{
|
||||
int base = 10;
|
||||
if (strstr(this->value.c_str(), "0x") != nullptr)
|
||||
base = 16;
|
||||
return (int64_t)strtoll(this->value.c_str(), nullptr, base);
|
||||
}
|
||||
|
||||
bool ConfigEntry::get_bool()
|
||||
{
|
||||
if (stricmp(this->value.c_str(), "yes") == 0 ||
|
||||
@@ -132,7 +140,7 @@ ConfigEntry* ConfigFile::get_entry(const std::string& section_name, const std::s
|
||||
|
||||
}
|
||||
|
||||
string ConfigFile::get(const std::string& section_name, const std::string& entry_name, const std::string& default_value)
|
||||
std::string ConfigFile::get(const std::string& section_name, const std::string& entry_name, const std::string& default_value)
|
||||
{
|
||||
ConfigEntry* entry = this->get_entry(section_name, entry_name);
|
||||
if (entry == NULL)
|
||||
@@ -158,6 +166,19 @@ int ConfigFile::get_int(const std::string& section_name, const std::string& entr
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ConfigFile::get_int64(const std::string& section_name, const std::string& entry_name, int64_t default_value)
|
||||
{
|
||||
ConfigEntry* entry = this->get_entry(section_name, entry_name);
|
||||
if (entry == NULL)
|
||||
{
|
||||
return default_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return entry->get_int64();
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigFile::get_bool(const std::string& section_name, const std::string& entry_name, bool default_value)
|
||||
{
|
||||
ConfigEntry* entry = this->get_entry(section_name, entry_name);
|
||||
@@ -188,102 +209,68 @@ void ConfigFile::set_int(const std::string& section_name, const std::string& ent
|
||||
this->set(section_name, entry_name, str_value.str(), is_virtual);
|
||||
}
|
||||
|
||||
void ConfigFile::set_int64(const std::string& section_name, const std::string& entry_name, int64_t value, bool is_virtual)
|
||||
{
|
||||
std::stringstream str_value;
|
||||
str_value << value;
|
||||
this->set(section_name, entry_name, str_value.str(), is_virtual);
|
||||
}
|
||||
|
||||
void ConfigFile::set_bool(const std::string& section_name, const std::string& entry_name, bool value, bool is_virtual)
|
||||
{
|
||||
string str_value = (value ? "yes" : "no");
|
||||
std::string str_value = (value ? "yes" : "no");
|
||||
this->set(section_name, entry_name, str_value, is_virtual);
|
||||
}
|
||||
|
||||
void ConfigFile::parse(FILE* file)
|
||||
{
|
||||
if(file == NULL)
|
||||
{
|
||||
if (file == nullptr)
|
||||
return;
|
||||
}
|
||||
|
||||
char line[512];
|
||||
char current_section[512] = { '\0' };
|
||||
std::string section;
|
||||
int cline = 0;
|
||||
while(file && !feof(file))
|
||||
while (true)
|
||||
{
|
||||
if (fgets(line, 512, file) == NULL || feof(file))
|
||||
{
|
||||
if (std::fgets(line, sizeof(line), file) == nullptr)
|
||||
break;
|
||||
}
|
||||
|
||||
cline++;
|
||||
|
||||
if (strlen(line) < 3)
|
||||
std::string s(line);
|
||||
s = trim_ws(s, " \r\n");
|
||||
if (s.empty())
|
||||
continue;
|
||||
if (s.length() >= 3 && s[0] == '[' && s[s.length() - 1] == ']')
|
||||
{
|
||||
section = s.substr(1, s.length() - 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[strlen(line)-1] == '\r' ||
|
||||
line[strlen(line)-1] == '\n')
|
||||
auto eqpos = s.find('=');
|
||||
if (eqpos == std::string::npos)
|
||||
{
|
||||
line[strlen(line)-1] = '\0';
|
||||
}
|
||||
|
||||
char* tl = trim_ws(line);
|
||||
|
||||
if (tl[0] == '[' && tl[strlen(tl)-1] == ']')
|
||||
{
|
||||
tl[strlen(tl)-1] = '\0';
|
||||
|
||||
// FIXME: Data loss if buffer is too small
|
||||
strncpy(current_section, tl+1, sizeof(current_section));
|
||||
current_section[sizeof(current_section) - 1] = '\0';
|
||||
|
||||
trim_ws(current_section);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(current_section) == 0)
|
||||
{
|
||||
continue; //no open section
|
||||
}
|
||||
|
||||
char* separator = strstr(tl, "=");
|
||||
|
||||
if (!separator)
|
||||
{
|
||||
WARN_LOG(COMMON, "Malformed entry on config - ignoring @ %d(%s)", cline, tl);
|
||||
continue;
|
||||
}
|
||||
|
||||
*separator = '\0';
|
||||
|
||||
char* name = trim_ws(tl);
|
||||
char* value = trim_ws(separator + 1);
|
||||
if (name == NULL || value == NULL)
|
||||
{
|
||||
//printf("Malformed entry on config - ignoring @ %d(%s)\n",cline, tl);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->set(string(current_section), string(name), string(value));
|
||||
}
|
||||
WARN_LOG(COMMON, "Malformed entry on config - ignoring line %d: %s", cline, s.c_str());
|
||||
continue;
|
||||
}
|
||||
std::string property = trim_ws(s.substr(0, eqpos));
|
||||
std::string value = trim_ws(s.substr(eqpos + 1));
|
||||
if (value.length() >= 2 && value[0] == '"' && value[value.length() - 1] == '"')
|
||||
value = value.substr(1, value.length() - 2);
|
||||
set(section, property, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigFile::save(FILE* file)
|
||||
{
|
||||
for (const auto& section_it : this->sections)
|
||||
for (const auto& [section_name, section] : this->sections)
|
||||
{
|
||||
const string& section_name = section_it.first;
|
||||
const ConfigSection& section = section_it.second;
|
||||
if (!section_name.empty())
|
||||
std::fprintf(file, "[%s]\n", section_name.c_str());
|
||||
|
||||
fprintf(file, "[%s]\n", section_name.c_str());
|
||||
|
||||
for (const auto& entry_it : section.entries)
|
||||
for (const auto& [entry_name, entry] : section.entries)
|
||||
{
|
||||
const string& entry_name = entry_it.first;
|
||||
const ConfigEntry& entry = entry_it.second;
|
||||
fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
|
||||
std::fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
|
||||
}
|
||||
|
||||
fputs("\n", file);
|
||||
if (!section_name.empty())
|
||||
std::fputc('\n', file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,5 +286,13 @@ void ConfigFile::delete_entry(const std::string& section_name, const std::string
|
||||
section->delete_entry(entry_name);
|
||||
}
|
||||
|
||||
bool ConfigFile::is_virtual(const std::string& section_name, const std::string& entry_name)
|
||||
{
|
||||
ConfigSection *section = get_section(section_name, true);
|
||||
if (section == nullptr)
|
||||
return false;
|
||||
return section->has_entry(entry_name);
|
||||
}
|
||||
|
||||
} // namespace emucfg
|
||||
|
||||
+11
-4
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace emucfg {
|
||||
|
||||
@@ -9,6 +12,7 @@ struct ConfigEntry {
|
||||
const std::string& get_string() const;
|
||||
int get_int();
|
||||
bool get_bool();
|
||||
int64_t get_int64();
|
||||
};
|
||||
|
||||
struct ConfigSection {
|
||||
@@ -31,17 +35,20 @@ struct ConfigFile {
|
||||
public:
|
||||
bool has_section(const std::string& name);
|
||||
bool has_entry(const std::string& section_name, const std::string& entry_name);
|
||||
bool is_virtual(const std::string& section_name, const std::string& entry_name);
|
||||
|
||||
void parse(FILE* fd);
|
||||
void save(FILE* fd);
|
||||
void parse(FILE* file);
|
||||
void save(FILE* file);
|
||||
|
||||
/* getting values */
|
||||
string get(const std::string& section_name, const std::string& entry_name, const std::string& default_value = "");
|
||||
std::string get(const std::string& section_name, const std::string& entry_name, const std::string& default_value = "");
|
||||
int get_int(const std::string& section_name, const std::string& entry_name, int default_value = 0);
|
||||
int64_t get_int64(const std::string& section_name, const std::string& entry_name, int64_t default_value = 0);
|
||||
bool get_bool(const std::string& section_name, const std::string& entry_name, bool default_value = false);
|
||||
/* setting values */
|
||||
void set(const std::string& section_name, const std::string& entry_name, const std::string& value, bool is_virtual = false);
|
||||
void set_int(const std::string& section_name, const std::string& entry_name, int value, bool is_virtual = false);
|
||||
void set_int64(const std::string& section_name, const std::string& entry_name, int64_t value, bool is_virtual = false);
|
||||
void set_bool(const std::string& section_name, const std::string& entry_name, bool value, bool is_virtual = false);
|
||||
|
||||
void delete_section(const std::string& section_name);
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "option.h"
|
||||
#include "network/naomi_network.h"
|
||||
#include "debug/gdb_server.h"
|
||||
|
||||
namespace config {
|
||||
|
||||
// Dynarec
|
||||
|
||||
Option<bool> DynarecEnabled("Dynarec.Enabled", true);
|
||||
Option<int> Sh4Clock("Sh4Clock", 200);
|
||||
|
||||
// General
|
||||
|
||||
Option<int> Cable("Dreamcast.Cable", 3); // TV Composite
|
||||
Option<int> Region("Dreamcast.Region", 1); // USA
|
||||
Option<int> Broadcast("Dreamcast.Broadcast", 0); // NTSC
|
||||
Option<int> Language("Dreamcast.Language", 1); // English
|
||||
Option<bool> ForceWindowsCE("Dreamcast.ForceWindowsCE");
|
||||
Option<bool> AutoLoadState("Dreamcast.AutoLoadState");
|
||||
Option<bool> AutoSaveState("Dreamcast.AutoSaveState");
|
||||
Option<int, false> SavestateSlot("Dreamcast.SavestateSlot");
|
||||
Option<bool> ForceFreePlay("ForceFreePlay", true);
|
||||
Option<bool, false> FetchBoxart("FetchBoxart", true);
|
||||
Option<bool, false> BoxartDisplayMode("BoxartDisplayMode", true);
|
||||
|
||||
// Sound
|
||||
|
||||
Option<bool> DSPEnabled("aica.DSPEnabled", false);
|
||||
#if HOST_CPU == CPU_ARM
|
||||
Option<int> AudioBufferSize("aica.BufferSize", 5644); // 128 ms
|
||||
#else
|
||||
Option<int> AudioBufferSize("aica.BufferSize", 2822); // 64 ms
|
||||
#endif
|
||||
Option<bool> AutoLatency("aica.AutoLatency",
|
||||
#ifdef __ANDROID__
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
|
||||
OptionString AudioBackend("backend", "auto", "audio");
|
||||
AudioVolumeOption AudioVolume;
|
||||
Option<bool> VmuSound("VmuSound", false, "audio");
|
||||
|
||||
// Rendering
|
||||
|
||||
RendererOption RendererType;
|
||||
Option<bool> UseMipmaps("rend.UseMipmaps", true);
|
||||
Option<bool> Widescreen("rend.WideScreen");
|
||||
Option<bool> SuperWidescreen("rend.SuperWideScreen");
|
||||
Option<bool> ShowFPS("rend.ShowFPS");
|
||||
Option<bool> RenderToTextureBuffer("rend.RenderToTextureBuffer");
|
||||
Option<bool> TranslucentPolygonDepthMask("rend.TranslucentPolygonDepthMask");
|
||||
Option<bool> ModifierVolumes("rend.ModifierVolumes", true);
|
||||
Option<int> TextureUpscale("rend.TextureUpscale", 1);
|
||||
Option<int> MaxFilteredTextureSize("rend.MaxFilteredTextureSize", 256);
|
||||
Option<float> ExtraDepthScale("rend.ExtraDepthScale", 1.f);
|
||||
Option<bool> CustomTextures("rend.CustomTextures");
|
||||
Option<bool> DumpTextures("rend.DumpTextures");
|
||||
Option<int> ScreenStretching("rend.ScreenStretching", 100);
|
||||
Option<bool> Fog("rend.Fog", true);
|
||||
Option<bool> FloatVMUs("rend.FloatVMUs");
|
||||
Option<bool> Rotate90("rend.Rotate90");
|
||||
Option<bool> PerStripSorting("rend.PerStripSorting");
|
||||
#ifdef __APPLE__
|
||||
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping", false);
|
||||
#else
|
||||
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping", true);
|
||||
#endif
|
||||
Option<bool> WidescreenGameHacks("rend.WidescreenGameHacks");
|
||||
std::array<Option<int>, 4> CrosshairColor {
|
||||
Option<int>("rend.CrossHairColor1"),
|
||||
Option<int>("rend.CrossHairColor2"),
|
||||
Option<int>("rend.CrossHairColor3"),
|
||||
Option<int>("rend.CrossHairColor4"),
|
||||
};
|
||||
Option<int> SkipFrame("ta.skip");
|
||||
Option<int> MaxThreads("pvr.MaxThreads", 3);
|
||||
Option<int> AutoSkipFrame("pvr.AutoSkipFrame", 0);
|
||||
Option<int> RenderResolution("rend.Resolution", 480);
|
||||
Option<bool> VSync("rend.vsync", true);
|
||||
Option<int64_t> PixelBufferSize("rend.PixelBufferSize", 512_MB);
|
||||
Option<int> AnisotropicFiltering("rend.AnisotropicFiltering", 1);
|
||||
Option<int> TextureFiltering("rend.TextureFiltering", 0); // Default
|
||||
Option<bool> ThreadedRendering("rend.ThreadedRendering", true);
|
||||
Option<bool> DupeFrames("rend.DupeFrames", false);
|
||||
Option<int> PerPixelLayers("rend.PerPixelLayers", 32);
|
||||
Option<bool> NativeDepthInterpolation("rend.NativeDepthInterpolation", false);
|
||||
Option<bool> EmulateFramebuffer("rend.EmulateFramebuffer", false);
|
||||
#ifdef VIDEO_ROUTING
|
||||
Option<bool> VideoRouting("rend.VideoRouting", false);
|
||||
Option<bool> VideoRoutingScale("rend.VideoRoutingScale", false);
|
||||
Option<int> VideoRoutingVRes("rend.VideoRoutingVRes", 720);
|
||||
#endif
|
||||
|
||||
// Misc
|
||||
|
||||
Option<bool> SerialConsole("Debug.SerialConsoleEnabled");
|
||||
Option<bool> SerialPTY("Debug.SerialPTY");
|
||||
Option<bool> GDB("Debug.GDBEnabled");
|
||||
Option<int> GDBPort("Debug.GDBPort", debugger::DEFAULT_PORT);
|
||||
Option<bool> GDBWaitForConnection("Debug.GDBWaitForConnection");
|
||||
Option<bool> UseReios("UseReios");
|
||||
Option<bool> FastGDRomLoad("FastGDRomLoad", false);
|
||||
Option<bool> RamMod32MB("Dreamcast.RamMod32MB", false);
|
||||
|
||||
Option<bool> OpenGlChecks("OpenGlChecks", false, "validate");
|
||||
|
||||
Option<std::vector<std::string>, false> ContentPath("Dreamcast.ContentPath");
|
||||
Option<bool, false> HideLegacyNaomiRoms("Dreamcast.HideLegacyNaomiRoms", true);
|
||||
Option<bool, false> UploadCrashLogs("UploadCrashLogs", true);
|
||||
|
||||
// Profiler
|
||||
Option<bool> ProfilerEnabled("Profiler.Enabled");
|
||||
Option<bool> ProfilerDrawToGUI("Profiler.DrawGUI");
|
||||
Option<bool> ProfilerOutputTTY("Profiler.OutputTTY");
|
||||
Option<float> ProfilerFrameWarningTime("Profiler.FrameWarningTime", 1.0f / 55.0f);
|
||||
|
||||
// Network
|
||||
|
||||
Option<bool> NetworkEnable("Enable", false, "network");
|
||||
Option<bool> ActAsServer("ActAsServer", false, "network");
|
||||
OptionString DNS("DNS", "46.101.91.123", "network");
|
||||
OptionString NetworkServer("server", "", "network");
|
||||
Option<int> LocalPort("LocalPort", NaomiNetwork::SERVER_PORT, "network");
|
||||
Option<bool> EmulateBBA("EmulateBBA", false, "network");
|
||||
Option<bool> EnableUPnP("EnableUPnP", true, "network");
|
||||
Option<bool> GGPOEnable("GGPO", false, "network");
|
||||
Option<int> GGPODelay("GGPODelay", 0, "network");
|
||||
Option<bool> NetworkStats("Stats", true, "network");
|
||||
Option<int> GGPOAnalogAxes("GGPOAnalogAxes", 0, "network");
|
||||
Option<bool> GGPOChat("GGPOChat", true, "network");
|
||||
Option<bool> GGPOChatTimeoutToggle("GGPOChatTimeoutToggle", true, "network");
|
||||
Option<int> GGPOChatTimeout("GGPOChatTimeout", 10, "network");
|
||||
Option<bool> NetworkOutput("NetworkOutput", false, "network");
|
||||
Option<int> MultiboardSlaves("MultiboardSlaves", 1, "network");
|
||||
|
||||
#ifdef SUPPORT_DISPMANX
|
||||
Option<bool> DispmanxMaintainAspect("maintain_aspect", true, "dispmanx");
|
||||
#endif
|
||||
|
||||
#ifdef USE_OMX
|
||||
Option<int> OmxAudioLatency("audio_latency", 100, "omx");
|
||||
Option<bool> OmxAudioHdmi("audio_hdmi", true, "omx");
|
||||
#endif
|
||||
|
||||
// Maple
|
||||
|
||||
Option<int> MouseSensitivity("MouseSensitivity", 100, "input");
|
||||
Option<int> VirtualGamepadVibration("VirtualGamepadVibration", 20, "input");
|
||||
|
||||
std::array<Option<MapleDeviceType>, 4> MapleMainDevices {
|
||||
Option<MapleDeviceType>("device1", MDT_SegaController, "input"),
|
||||
Option<MapleDeviceType>("device2", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device3", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device4", MDT_None, "input"),
|
||||
};
|
||||
std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices {
|
||||
Option<MapleDeviceType>("device1.1", MDT_SegaVMU, "input"),
|
||||
Option<MapleDeviceType>("device1.2", MDT_SegaVMU, "input"),
|
||||
|
||||
Option<MapleDeviceType>("device2.1", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device2.2", MDT_None, "input"),
|
||||
|
||||
Option<MapleDeviceType>("device3.1", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device3.2", MDT_None, "input"),
|
||||
|
||||
Option<MapleDeviceType>("device4.1", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device4.2", MDT_None, "input"),
|
||||
};
|
||||
Option<bool> PerGameVmu("PerGameVmu", false, "config");
|
||||
#ifdef _WIN32
|
||||
Option<bool, false> UseRawInput("RawInput", false, "input");
|
||||
#endif
|
||||
|
||||
#ifdef USE_LUA
|
||||
Option<std::string, false> LuaFileName("LuaFileName", "flycast.lua");
|
||||
#endif
|
||||
|
||||
} // namespace config
|
||||
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
#include "cfg.h"
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
#ifdef LIBRETRO
|
||||
#include <libretro.h>
|
||||
#endif
|
||||
|
||||
namespace config {
|
||||
|
||||
class BaseOption {
|
||||
public:
|
||||
virtual ~BaseOption() = default;
|
||||
virtual void save() const = 0;
|
||||
virtual void load() = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
|
||||
#ifdef LIBRETRO
|
||||
#include "option_lr.h"
|
||||
#else
|
||||
|
||||
class Settings {
|
||||
public:
|
||||
void reset() {
|
||||
for (const auto& o : options)
|
||||
o->reset();
|
||||
gameId.clear();
|
||||
perGameConfig = false;
|
||||
}
|
||||
|
||||
void load(bool gameSpecific) {
|
||||
if (gameSpecific)
|
||||
{
|
||||
if (gameId.empty())
|
||||
return;
|
||||
if (!cfgHasSection(gameId))
|
||||
return;
|
||||
perGameConfig = true;
|
||||
}
|
||||
for (const auto& o : options)
|
||||
o->load();
|
||||
}
|
||||
|
||||
void save() {
|
||||
cfgSetAutoSave(false);
|
||||
for (const auto& o : options)
|
||||
o->save();
|
||||
cfgSetAutoSave(true);
|
||||
}
|
||||
|
||||
void setGameId(const std::string& gameId) {
|
||||
this->gameId = gameId;
|
||||
}
|
||||
|
||||
bool hasPerGameConfig() const {
|
||||
return perGameConfig;
|
||||
}
|
||||
void setPerGameConfig(bool perGameConfig) {
|
||||
this->perGameConfig = perGameConfig;
|
||||
if (!perGameConfig) {
|
||||
if (!gameId.empty())
|
||||
cfgDeleteSection(gameId);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
static Settings& instance() {
|
||||
static Settings *_instance = new Settings();
|
||||
return *_instance;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<BaseOption *> options;
|
||||
std::string gameId;
|
||||
bool perGameConfig = false;
|
||||
|
||||
template<typename T, bool PerGameOption>
|
||||
friend class Option;
|
||||
};
|
||||
|
||||
template<typename T, bool PerGameOption = true>
|
||||
class Option : public BaseOption {
|
||||
public:
|
||||
Option(const std::string& name, T defaultValue = T(), const std::string& section = "config")
|
||||
: section(section), name(name), value(defaultValue), defaultValue(defaultValue),
|
||||
settings(Settings::instance())
|
||||
{
|
||||
settings.options.push_back(this);
|
||||
}
|
||||
|
||||
void reset() override {
|
||||
set(defaultValue);
|
||||
overridden = false;
|
||||
}
|
||||
|
||||
void load() override {
|
||||
if (PerGameOption && settings.hasPerGameConfig())
|
||||
set(doLoad(settings.gameId, section + "." + name));
|
||||
else
|
||||
{
|
||||
set(doLoad(section, name));
|
||||
if (cfgIsVirtual(section, name))
|
||||
override(value);
|
||||
}
|
||||
}
|
||||
|
||||
void save() const override
|
||||
{
|
||||
if (overridden) {
|
||||
if (value == overriddenDefault)
|
||||
return;
|
||||
if (!settings.hasPerGameConfig())
|
||||
// overridden options can only be saved in per-game settings
|
||||
return;
|
||||
}
|
||||
else if (PerGameOption && settings.hasPerGameConfig())
|
||||
{
|
||||
if (value == doLoad(section, name))
|
||||
{
|
||||
// delete existing per-game option if any
|
||||
cfgDeleteEntry(settings.gameId, section + "." + name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (PerGameOption && settings.hasPerGameConfig())
|
||||
doSave(settings.gameId, section + "." + name);
|
||||
else
|
||||
doSave(section, name);
|
||||
}
|
||||
|
||||
T& get() { return value; }
|
||||
void set(T v) { value = v; }
|
||||
|
||||
void override(T v)
|
||||
{
|
||||
overriddenDefault = v;
|
||||
overridden = true;
|
||||
value = v;
|
||||
}
|
||||
bool isReadOnly() const {
|
||||
return overridden && !settings.hasPerGameConfig();
|
||||
}
|
||||
|
||||
explicit operator T() const { return value; }
|
||||
operator T&() { return value; }
|
||||
T& operator=(const T& v) { set(v); return value; }
|
||||
|
||||
protected:
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<U, bool>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return cfgLoadBool(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same<U, int64_t>::value, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return cfgLoadInt64(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<(std::is_integral_v<U> || std::is_enum_v<U>)
|
||||
&& !std::is_same_v<U, bool> && !std::is_same_v<U, int64_t>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return (T)cfgLoadInt(section, name, (int)value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<U, std::string>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return cfgLoadStr(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<float, U>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
std::string strValue = cfgLoadStr(section, name, "");
|
||||
if (strValue.empty())
|
||||
return value;
|
||||
else
|
||||
return (float)atof(strValue.c_str());
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<std::vector<std::string>, U>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
std::string paths = cfgLoadStr(section, name, "");
|
||||
if (paths.empty())
|
||||
return value;
|
||||
std::string::size_type start = 0;
|
||||
std::vector<std::string> newValue;
|
||||
while (true)
|
||||
{
|
||||
if (paths[start] == '"')
|
||||
{
|
||||
std::string v;
|
||||
start++;
|
||||
while (true)
|
||||
{
|
||||
if (paths[start] == '"')
|
||||
{
|
||||
if (start + 1 >= paths.size())
|
||||
{
|
||||
newValue.push_back(v);
|
||||
return newValue;
|
||||
}
|
||||
if (paths[start + 1] == '"')
|
||||
{
|
||||
v += paths[start++];
|
||||
start++;
|
||||
}
|
||||
else if (paths[start + 1] == ';')
|
||||
{
|
||||
newValue.push_back(v);
|
||||
start += 2;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
v += paths[start++];
|
||||
}
|
||||
}
|
||||
else
|
||||
v += paths[start++];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string::size_type end = paths.find(';', start);
|
||||
if (end == std::string::npos)
|
||||
end = paths.size();
|
||||
if (start != end)
|
||||
newValue.push_back(paths.substr(start, end - start));
|
||||
if (end == paths.size())
|
||||
break;
|
||||
start = end + 1;
|
||||
}
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<U, bool>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveBool(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same<U, int64_t>::value>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveInt64(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<(std::is_integral_v<U> || std::is_enum_v<U>)
|
||||
&& !std::is_same_v<U, bool> && !std::is_same_v<U, int64_t>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveInt(section, name, (int)value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<U, std::string>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveStr(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<float, U>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "%f", value);
|
||||
cfgSaveStr(section, name, buf);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_same_v<std::vector<std::string>, U>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
std::string s;
|
||||
for (const auto& v : value)
|
||||
{
|
||||
if (!s.empty())
|
||||
s += ';';
|
||||
if (v.find(';') != std::string::npos || (!v.empty() && v[0] == '"'))
|
||||
{
|
||||
s += '"';
|
||||
std::string v2 = v;
|
||||
while (true)
|
||||
{
|
||||
auto pos = v2.find('"');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
s += v2.substr(0, pos + 1) + '"';
|
||||
v2 = v2.substr(pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
s += v2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s += '"';
|
||||
}
|
||||
else
|
||||
s += v;
|
||||
}
|
||||
cfgSaveStr(section, name, s);
|
||||
}
|
||||
|
||||
std::string section;
|
||||
std::string name;
|
||||
T value;
|
||||
T defaultValue;
|
||||
T overriddenDefault = T();
|
||||
bool overridden = false;
|
||||
Settings& settings;
|
||||
};
|
||||
#endif
|
||||
|
||||
using OptionString = Option<std::string>;
|
||||
|
||||
// Dynarec
|
||||
|
||||
extern Option<bool> DynarecEnabled;
|
||||
#ifndef LIBRETRO
|
||||
extern Option<int> Sh4Clock;
|
||||
#endif
|
||||
|
||||
// General
|
||||
|
||||
extern Option<int> Cable; // 0 -> VGA, 1 -> VGA, 2 -> RGB, 3 -> TV Composite
|
||||
extern Option<int> Region; // 0 -> JP, 1 -> USA, 2 -> EU, 3 -> default
|
||||
extern Option<int> Broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4 -> default
|
||||
extern Option<int> Language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default
|
||||
extern Option<bool> ForceWindowsCE;
|
||||
extern Option<bool> AutoLoadState;
|
||||
extern Option<bool> AutoSaveState;
|
||||
extern Option<int, false> SavestateSlot;
|
||||
extern Option<bool> ForceFreePlay;
|
||||
extern Option<bool, false> FetchBoxart;
|
||||
extern Option<bool, false> BoxartDisplayMode;
|
||||
|
||||
// Sound
|
||||
|
||||
constexpr bool LimitFPS = true;
|
||||
extern Option<bool> DSPEnabled;
|
||||
extern Option<int> AudioBufferSize; //In samples ,*4 for bytes
|
||||
extern Option<bool> AutoLatency;
|
||||
|
||||
extern OptionString AudioBackend;
|
||||
|
||||
class AudioVolumeOption : public Option<int> {
|
||||
public:
|
||||
AudioVolumeOption() : Option<int>("aica.Volume", 100) {};
|
||||
float logarithmic_volume_scale = 1.0;
|
||||
|
||||
void load() override {
|
||||
Option<int>::load();
|
||||
calcDbPower();
|
||||
}
|
||||
|
||||
float dbPower()
|
||||
{
|
||||
return logarithmic_volume_scale;
|
||||
}
|
||||
void calcDbPower()
|
||||
{
|
||||
// dB scaling calculation: https://www.dr-lex.be/info-stuff/volumecontrols.html
|
||||
logarithmic_volume_scale = std::min(std::exp(4.605f * float(value) / 100.f) / 100.f, 1.f);
|
||||
if (value < 10)
|
||||
logarithmic_volume_scale *= value / 10.f;
|
||||
}
|
||||
};
|
||||
extern AudioVolumeOption AudioVolume;
|
||||
extern Option<bool> VmuSound;
|
||||
|
||||
// Rendering
|
||||
|
||||
class RendererOption : public Option<RenderType> {
|
||||
public:
|
||||
RendererOption() : Option<RenderType>("pvr.rend",
|
||||
#if defined(USE_DX11)
|
||||
RenderType::DirectX11
|
||||
#elif defined(USE_DX9)
|
||||
RenderType::DirectX9
|
||||
#elif !defined(USE_OPENGL)
|
||||
RenderType::Vulkan
|
||||
#else
|
||||
RenderType::OpenGL
|
||||
#endif
|
||||
) {}
|
||||
|
||||
RenderType& operator=(const RenderType& v) { set(v); return value; }
|
||||
|
||||
void reset() override {
|
||||
// don't reset the value to avoid quick switching when starting a game
|
||||
overridden = false;
|
||||
}
|
||||
};
|
||||
extern RendererOption RendererType;
|
||||
extern Option<bool> UseMipmaps;
|
||||
extern Option<bool> Widescreen;
|
||||
extern Option<bool> SuperWidescreen;
|
||||
extern Option<bool> ShowFPS;
|
||||
extern Option<bool> RenderToTextureBuffer;
|
||||
extern Option<bool> TranslucentPolygonDepthMask;
|
||||
extern Option<bool> ModifierVolumes;
|
||||
constexpr bool Clipping = true;
|
||||
#ifndef LIBRETRO
|
||||
extern Option<int> TextureUpscale;
|
||||
extern Option<int> MaxFilteredTextureSize;
|
||||
extern Option<int> PerPixelLayers;
|
||||
#endif
|
||||
extern Option<float> ExtraDepthScale;
|
||||
extern Option<bool> CustomTextures;
|
||||
extern Option<bool> DumpTextures;
|
||||
extern Option<int> ScreenStretching; // in percent. 150 means stretch from 4/3 to 6/3
|
||||
extern Option<bool> Fog;
|
||||
extern Option<bool> FloatVMUs;
|
||||
extern Option<bool> Rotate90;
|
||||
extern Option<bool> PerStripSorting;
|
||||
extern Option<bool> DelayFrameSwapping; // Delay swapping frame until FB_R_SOF matches FB_W_SOF
|
||||
extern Option<bool> WidescreenGameHacks;
|
||||
extern std::array<Option<int>, 4> CrosshairColor;
|
||||
extern Option<int> SkipFrame;
|
||||
extern Option<int> MaxThreads;
|
||||
extern Option<int> AutoSkipFrame; // 0: none, 1: some, 2: more
|
||||
extern Option<int> RenderResolution;
|
||||
extern Option<bool> VSync;
|
||||
extern Option<int64_t> PixelBufferSize;
|
||||
extern Option<int> AnisotropicFiltering;
|
||||
extern Option<int> TextureFiltering; // 0: default, 1: force nearest, 2: force linear
|
||||
extern Option<bool> ThreadedRendering;
|
||||
extern Option<bool> DupeFrames;
|
||||
extern Option<bool> NativeDepthInterpolation;
|
||||
extern Option<bool> EmulateFramebuffer;
|
||||
#ifdef VIDEO_ROUTING
|
||||
extern Option<bool> VideoRouting;
|
||||
extern Option<bool> VideoRoutingScale;
|
||||
extern Option<int> VideoRoutingVRes;
|
||||
#endif
|
||||
|
||||
// Misc
|
||||
|
||||
extern Option<bool> SerialConsole;
|
||||
extern Option<bool> SerialPTY;
|
||||
extern Option<bool> GDB;
|
||||
extern Option<int> GDBPort;
|
||||
extern Option<bool> GDBWaitForConnection;
|
||||
extern Option<bool> UseReios;
|
||||
extern Option<bool> FastGDRomLoad;
|
||||
extern Option<bool> RamMod32MB;
|
||||
|
||||
extern Option<bool> OpenGlChecks;
|
||||
|
||||
extern Option<std::vector<std::string>, false> ContentPath;
|
||||
extern Option<bool, false> HideLegacyNaomiRoms;
|
||||
extern Option<bool, false> UploadCrashLogs;
|
||||
|
||||
// Profiling
|
||||
extern Option<bool> ProfilerEnabled;
|
||||
extern Option<bool> ProfilerDrawToGUI;
|
||||
extern Option<bool> ProfilerOutputTTY;
|
||||
extern Option<float> ProfilerFrameWarningTime;
|
||||
|
||||
// Network
|
||||
|
||||
extern Option<bool> NetworkEnable;
|
||||
extern Option<bool> ActAsServer;
|
||||
extern OptionString DNS;
|
||||
extern OptionString NetworkServer;
|
||||
extern Option<int> LocalPort;
|
||||
extern Option<bool> EmulateBBA;
|
||||
extern Option<bool> EnableUPnP;
|
||||
extern Option<bool> GGPOEnable;
|
||||
extern Option<int> GGPODelay;
|
||||
extern Option<bool> NetworkStats;
|
||||
extern Option<int> GGPOAnalogAxes;
|
||||
extern Option<bool> GGPOChat;
|
||||
extern Option<bool> GGPOChatTimeoutToggle;
|
||||
extern Option<int> GGPOChatTimeout;
|
||||
extern Option<bool> NetworkOutput;
|
||||
extern Option<int> MultiboardSlaves;
|
||||
|
||||
#ifdef SUPPORT_DISPMANX
|
||||
extern Option<bool> DispmanxMaintainAspect;
|
||||
#endif
|
||||
|
||||
#ifdef USE_OMX
|
||||
extern Option<int> OmxAudioLatency;
|
||||
extern Option<bool> OmxAudioHdmi;
|
||||
#endif
|
||||
|
||||
// Maple
|
||||
|
||||
extern Option<int> MouseSensitivity;
|
||||
extern Option<int> VirtualGamepadVibration;
|
||||
extern std::array<Option<MapleDeviceType>, 4> MapleMainDevices;
|
||||
extern std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices;
|
||||
extern Option<bool> PerGameVmu;
|
||||
#ifdef _WIN32
|
||||
extern Option<bool, false> UseRawInput;
|
||||
#else
|
||||
constexpr bool UseRawInput = false;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LUA
|
||||
extern Option<std::string, false> LuaFileName;
|
||||
#endif
|
||||
|
||||
} // namespace config
|
||||
+870
-240
File diff suppressed because it is too large.
Load diff
+70
-10
@@ -3,41 +3,101 @@
|
||||
|
||||
Copyright 2019 flyinghead
|
||||
|
||||
This file is part of reicast.
|
||||
This file is part of Flycast.
|
||||
|
||||
reicast is free software: you can redistribute it and/or modify
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
reicast is distributed in the hope that it will be useful,
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
struct Cheat
|
||||
#include <vector>
|
||||
|
||||
struct WidescreenCheat
|
||||
{
|
||||
const char *game_id;
|
||||
const char *area_or_version;
|
||||
u32 addresses[16];
|
||||
u32 values[16];
|
||||
u32 origValues[16];
|
||||
};
|
||||
|
||||
struct Cheat
|
||||
{
|
||||
enum class Type {
|
||||
disabled,
|
||||
setValue,
|
||||
increase,
|
||||
decrease,
|
||||
runNextIfEq,
|
||||
runNextIfNeq,
|
||||
runNextIfGt,
|
||||
runNextIfLt,
|
||||
copy
|
||||
};
|
||||
Type type;
|
||||
std::string description;
|
||||
bool enabled;
|
||||
u32 size;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u8 valueMask;
|
||||
u32 repeatCount;
|
||||
u32 repeatValueIncrement;
|
||||
u32 repeatAddressIncrement;
|
||||
u32 destAddress;
|
||||
bool builtIn;
|
||||
|
||||
Cheat(Type type = Type::disabled, const std::string& description = "", bool enabled = false, u32 size = 0, u32 address = 0,
|
||||
u32 value = 0, u8 valueMask = 0, u32 repeatCount = 1, u32 repeatValueIncrement = 0,
|
||||
u32 repeatAddressIncrement = 0, u32 destAddress = 0, bool builtIn = false)
|
||||
: type(type), description(description), enabled(enabled), size(size), address(address), value(value), valueMask(valueMask),
|
||||
repeatCount(repeatCount), repeatValueIncrement(repeatValueIncrement), repeatAddressIncrement(repeatAddressIncrement),
|
||||
destAddress(destAddress), builtIn(builtIn)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class CheatManager
|
||||
{
|
||||
public:
|
||||
CheatManager() : _widescreen_cheat(nullptr) {}
|
||||
bool Reset(); // Returns true if using 16:9 anamorphic screen ratio
|
||||
void Apply();
|
||||
void reset(const std::string& gameId);
|
||||
void apply();
|
||||
size_t cheatCount() const { return cheats.size(); }
|
||||
const std::string& cheatDescription(size_t index) const { return cheats[index].description; }
|
||||
bool cheatEnabled(size_t index) const { return cheats[index].enabled; }
|
||||
void enableCheat(size_t index, bool enabled) { cheats[index].enabled = enabled; }
|
||||
void loadCheatFile(const std::string& filename);
|
||||
void saveCheatFile(const std::string& filename);
|
||||
// Returns true if using 16:9 anamorphic screen ratio
|
||||
bool isWidescreen() const { return widescreen_cheat != nullptr; }
|
||||
void addGameSharkCheat(const std::string& name, const std::string& s);
|
||||
|
||||
private:
|
||||
static const Cheat _widescreen_cheats[];
|
||||
const Cheat *_widescreen_cheat;
|
||||
u32 readRam(u32 addr, u32 bits);
|
||||
void writeRam(u32 addr, u32 value, u32 bits);
|
||||
void setActive(bool active);
|
||||
|
||||
static const WidescreenCheat widescreen_cheats[];
|
||||
static const WidescreenCheat naomi_widescreen_cheats[];
|
||||
const WidescreenCheat *widescreen_cheat = nullptr;
|
||||
bool active = false;
|
||||
std::vector<Cheat> cheats;
|
||||
std::string gameId;
|
||||
|
||||
friend class CheatManagerTest_TestLoad_Test;
|
||||
friend class CheatManagerTest_TestGameShark_Test;
|
||||
friend class CheatManagerTest_TestSave_Test;
|
||||
};
|
||||
|
||||
extern CheatManager cheatManager;
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
#LOCAL_PATH:=
|
||||
|
||||
#MFLAGS := -marm -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=softfp
|
||||
#ASFLAGS := -march=armv7-a -mfpu=vfp-d16 -mfloat-abi=softfp
|
||||
#LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common
|
||||
|
||||
RZDCY_SRC_DIR ?= $(call my-dir)
|
||||
VERSION_HEADER := $(RZDCY_SRC_DIR)/version.h
|
||||
|
||||
RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \
|
||||
hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \
|
||||
hw/extdev/ hw/arm/ hw/naomi/ imgread/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \
|
||||
deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/ deps/xbrz/ \
|
||||
deps/libzip/ deps/imgui/ archive/ input/ log/
|
||||
|
||||
ifndef NOT_ARM
|
||||
RZDCY_MODULES += rec-ARM/
|
||||
endif
|
||||
|
||||
ifdef X86_REC
|
||||
RZDCY_MODULES += rec-x86/ emitter/
|
||||
endif
|
||||
|
||||
ifdef X64_REC
|
||||
RZDCY_MODULES += rec-x64/
|
||||
endif
|
||||
|
||||
ifdef CPP_REC
|
||||
RZDCY_MODULES += rec-cpp/
|
||||
endif
|
||||
|
||||
ifdef ARM64_REC
|
||||
RZDCY_MODULES += rec-ARM64/ deps/vixl/ deps/vixl/aarch64/
|
||||
endif
|
||||
|
||||
ifndef NO_REND
|
||||
RZDCY_MODULES += rend/gles/
|
||||
ifndef USE_GLES
|
||||
ifndef USE_DISPMANX
|
||||
RZDCY_MODULES += rend/gl4/
|
||||
endif
|
||||
endif
|
||||
else
|
||||
RZDCY_MODULES += rend/norend/
|
||||
endif
|
||||
|
||||
ifndef NO_NIXPROF
|
||||
RZDCY_MODULES += linux/nixprof/
|
||||
endif
|
||||
|
||||
ifdef FOR_ANDROID
|
||||
RZDCY_MODULES += android/ deps/libandroid/ linux/
|
||||
endif
|
||||
|
||||
ifdef USE_SDL
|
||||
RZDCY_MODULES += sdl/
|
||||
endif
|
||||
|
||||
ifdef FOR_LINUX
|
||||
ifndef UNIT_TESTS
|
||||
RZDCY_MODULES += linux-dist/
|
||||
endif
|
||||
RZDCY_MODULES += linux/
|
||||
endif
|
||||
|
||||
ifdef FOR_WINDOWS
|
||||
RZDCY_MODULES += windows/
|
||||
endif
|
||||
|
||||
ifdef FOR_PANDORA
|
||||
RZDCY_CFLAGS := \
|
||||
$(CFLAGS) -c -O3 \
|
||||
-DRELEASE -DPANDORA\
|
||||
-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp \
|
||||
-frename-registers -fsingle-precision-constant -ffast-math \
|
||||
-ftree-vectorize -fomit-frame-pointer
|
||||
RZDCY_CFLAGS += -march=armv7-a -mtune=cortex-a8 -mfpu=neon
|
||||
RZDCY_CFLAGS += -DTARGET_LINUX_ARMELv7
|
||||
else
|
||||
ifdef FOR_ANDROID
|
||||
RZDCY_CFLAGS := \
|
||||
$(CFLAGS) -c -O3 \
|
||||
-D_ANDROID -DRELEASE \
|
||||
-frename-registers -fsingle-precision-constant -ffast-math \
|
||||
-ftree-vectorize -fomit-frame-pointer
|
||||
|
||||
ifndef NOT_ARM
|
||||
RZDCY_CFLAGS += -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16
|
||||
RZDCY_CFLAGS += -DTARGET_LINUX_ARMELv7
|
||||
else
|
||||
ifdef ISARM64
|
||||
RZDCY_CFLAGS += -march=armv8-a
|
||||
RZDCY_CFLAGS += -DTARGET_LINUX_ARMv8
|
||||
else
|
||||
ifdef ISMIPS
|
||||
RZDCY_CFLAGS += -DTARGET_LINUX_MIPS
|
||||
else
|
||||
RZDCY_CFLAGS += -DTARGET_LINUX_x86
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
else
|
||||
RZDCY_CFLAGS :=
|
||||
endif
|
||||
endif
|
||||
|
||||
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/rend/gles -I$(RZDCY_SRC_DIR)/deps \
|
||||
-I$(RZDCY_SRC_DIR)/deps/vixl -I$(RZDCY_SRC_DIR)/khronos
|
||||
|
||||
ifdef USE_MODEM
|
||||
RZDCY_CFLAGS += -DENABLE_MODEM -I$(RZDCY_SRC_DIR)/deps/picotcp/include -I$(RZDCY_SRC_DIR)/deps/picotcp/modules
|
||||
RZDCY_MODULES += hw/modem/ deps/picotcp/modules/ deps/picotcp/stack/
|
||||
endif
|
||||
|
||||
ifdef NO_REC
|
||||
RZDCY_CFLAGS += -DTARGET_NO_REC
|
||||
else
|
||||
RZDCY_MODULES += hw/sh4/dyna/
|
||||
endif
|
||||
|
||||
ifdef USE_GLES
|
||||
RZDCY_CFLAGS += -DGLES -fPIC
|
||||
endif
|
||||
|
||||
ifdef HAS_SOFTREND
|
||||
RZDCY_CFLAGS += -DTARGET_SOFTREND
|
||||
RZDCY_MODULES += rend/soft/
|
||||
endif
|
||||
|
||||
ifdef CHD5_FLAC
|
||||
RZDCY_CFLAGS += -DCHD5_FLAC -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/ -I$(RZDCY_SRC_DIR)/deps/flac/include
|
||||
RZDCY_CFLAGS += -DHAVE_CONFIG_H
|
||||
RZDCY_MODULES += deps/flac/src/libFLAC/
|
||||
endif
|
||||
|
||||
# 7-Zip/LZMA settings (CHDv5)
|
||||
ifdef CHD5_LZMA
|
||||
RZDCY_MODULES += deps/lzma/
|
||||
RZDCY_CFLAGS += -D_7ZIP_ST -DCHD5_LZMA
|
||||
endif
|
||||
|
||||
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/libpng -I$(RZDCY_SRC_DIR)/deps/zlib
|
||||
RZDCY_CFLAGS += -DXXH_INLINE_ALL -I$(RZDCY_SRC_DIR)/deps/xxhash
|
||||
|
||||
RZDCY_CXXFLAGS := $(RZDCY_CFLAGS) -fno-exceptions -fno-rtti -std=gnu++11
|
||||
|
||||
RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp))
|
||||
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cc))
|
||||
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c))
|
||||
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S))
|
||||
|
||||
$(VERSION_HEADER):
|
||||
echo "#define REICAST_VERSION \"`git describe --tags --always`\"" > $(VERSION_HEADER)
|
||||
echo "#define GIT_HASH \"`git rev-parse --short HEAD`\"" >> $(VERSION_HEADER)
|
||||
echo "#define BUILD_DATE \"`date '+%Y-%m-%d %H:%M:%S %Z'`\"" >> $(VERSION_HEADER)
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
#include "emulator.h"
|
||||
#include "hw/sh4/sh4_if.h"
|
||||
#include "hw/sh4/sh4_mem.h"
|
||||
#include "hw/sh4/sh4_interpreter.h"
|
||||
#include "cfg/option.h"
|
||||
#include <array>
|
||||
#include <signal.h>
|
||||
#include <map>
|
||||
|
||||
#ifndef SIGTRAP
|
||||
#define SIGTRAP 5
|
||||
#endif
|
||||
#ifndef SIGBUS
|
||||
#define SIGBUS 7
|
||||
#endif
|
||||
|
||||
const std::array<Sh4RegType, 59> Sh4RegList {
|
||||
reg_r0,
|
||||
reg_r1,
|
||||
reg_r2,
|
||||
reg_r3,
|
||||
reg_r4,
|
||||
reg_r5,
|
||||
reg_r6,
|
||||
reg_r7,
|
||||
reg_r8,
|
||||
reg_r9,
|
||||
reg_r10,
|
||||
reg_r11,
|
||||
reg_r12,
|
||||
reg_r13,
|
||||
reg_r14,
|
||||
reg_r15,
|
||||
reg_nextpc,
|
||||
reg_pr,
|
||||
reg_gbr,
|
||||
reg_vbr,
|
||||
reg_mach,
|
||||
reg_macl,
|
||||
reg_sr_status,
|
||||
|
||||
reg_fpul,
|
||||
reg_fpscr,
|
||||
reg_fr_0, reg_fr_1, reg_fr_2, reg_fr_3, reg_fr_4, reg_fr_5, reg_fr_6, reg_fr_7,
|
||||
reg_fr_8, reg_fr_9, reg_fr_10, reg_fr_11, reg_fr_12, reg_fr_13, reg_fr_14, reg_fr_15,
|
||||
reg_ssr,
|
||||
reg_spc,
|
||||
// correct?
|
||||
reg_r0, reg_r1, reg_r2, reg_r3, reg_r4, reg_r5, reg_r6, reg_r7,
|
||||
reg_r0_Bank, reg_r1_Bank, reg_r2_Bank, reg_r3_Bank, reg_r4_Bank, reg_r5_Bank, reg_r6_Bank, reg_r7_Bank,
|
||||
};
|
||||
|
||||
class DebugAgent
|
||||
{
|
||||
public:
|
||||
struct Breakpoint {
|
||||
enum Type
|
||||
{
|
||||
BP_TYPE_SOFTWARE_BREAK,
|
||||
BP_TYPE_HARDWARE_BREAK,
|
||||
BP_TYPE_WRITE_WATCHPOINT,
|
||||
BP_TYPE_READ_WATCHPOINT,
|
||||
BP_TYPE_ACCESS_WATCHPOINT,
|
||||
BP_TYPE_COUNT
|
||||
};
|
||||
|
||||
Breakpoint() = default;
|
||||
Breakpoint(u16 type, u32 addr) : addr(addr), type(type) { }
|
||||
u32 addr = 0;
|
||||
u16 type = 0;
|
||||
u16 savedOp = 0;
|
||||
};
|
||||
|
||||
void doContinue(u32 pc = 1)
|
||||
{
|
||||
if (pc != 1)
|
||||
Sh4cntx.pc = pc;
|
||||
emu.start();
|
||||
}
|
||||
|
||||
void step()
|
||||
{
|
||||
bool restoreBreakpoint = removeMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
|
||||
u32 savedPc = Sh4cntx.pc;
|
||||
emu.step();
|
||||
if (restoreBreakpoint)
|
||||
insertMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
|
||||
}
|
||||
|
||||
void stepRange(u32 from, u32 to)
|
||||
{
|
||||
bool restoreBreakpoint = removeMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
|
||||
u32 savedPc = Sh4cntx.pc;
|
||||
emu.stepRange(from, to);
|
||||
if (restoreBreakpoint)
|
||||
insertMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
|
||||
}
|
||||
|
||||
int readAllRegs(u32 **regs)
|
||||
{
|
||||
static std::array<u32, Sh4RegList.size()> allregs;
|
||||
for (u32 i = 0; i < Sh4RegList.size(); i++)
|
||||
{
|
||||
if (Sh4RegList[i] == reg_sr_status)
|
||||
allregs[i] = sh4_sr_GetFull();
|
||||
else if (Sh4RegList[i] != NoReg)
|
||||
allregs[i] = *GetRegPtr(Sh4RegList[i]);
|
||||
}
|
||||
*regs = &allregs[0];
|
||||
return allregs.size();
|
||||
}
|
||||
|
||||
void writeAllRegs(const std::vector<u32>& regs)
|
||||
{
|
||||
for (u32 i = 0; i < Sh4RegList.size(); i++)
|
||||
if (Sh4RegList[i] != NoReg)
|
||||
*GetRegPtr(Sh4RegList[i]) = regs[i];
|
||||
}
|
||||
|
||||
u32 readReg(u32 regNum)
|
||||
{
|
||||
if (regNum >= Sh4RegList.size())
|
||||
return 0;
|
||||
Sh4RegType reg = Sh4RegList[regNum];
|
||||
if (reg == reg_sr_status)
|
||||
return sh4_sr_GetFull();
|
||||
if (reg != NoReg)
|
||||
return *GetRegPtr(reg);
|
||||
return 0;
|
||||
}
|
||||
void writeReg(u32 regNum, u32 value)
|
||||
{
|
||||
if (regNum >= Sh4RegList.size())
|
||||
return;
|
||||
Sh4RegType reg = Sh4RegList[regNum];
|
||||
if (reg == reg_sr_status)
|
||||
sh4_sr_SetFull(value);
|
||||
else if (reg != NoReg)
|
||||
*GetRegPtr(reg) = value;
|
||||
}
|
||||
|
||||
const u8 *readMem(u32 addr, u32 len)
|
||||
{
|
||||
static std::vector<u8> data;
|
||||
data.resize(len);
|
||||
u8 *p = &data[0];
|
||||
while (len > 0)
|
||||
{
|
||||
if (len >= 4 && (addr & 3) == 0)
|
||||
{
|
||||
*(u32 *)p = ReadMem32_nommu(addr);
|
||||
addr += 4;
|
||||
len -= 4;
|
||||
p += 4;
|
||||
}
|
||||
else if (len >= 2 && (addr & 1) == 0)
|
||||
{
|
||||
*(u16 *)p = ReadMem16_nommu(addr);
|
||||
addr += 2;
|
||||
len -= 2;
|
||||
p += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = ReadMem8_nommu(addr);
|
||||
addr++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
return &data[0];
|
||||
}
|
||||
void writeMem(u32 addr, const std::vector<u8>& data)
|
||||
{
|
||||
const u8 *p = &data[0];
|
||||
u32 len = data.size();
|
||||
while (len > 0)
|
||||
{
|
||||
if (len >= 4 && (addr & 3) == 0)
|
||||
{
|
||||
WriteMem32_nommu(addr, *(u32 *)p);
|
||||
addr += 4;
|
||||
len -= 4;
|
||||
p += 4;
|
||||
}
|
||||
else if (len >= 2 && (addr & 3) == 0)
|
||||
{
|
||||
WriteMem16_nommu(addr, *(u16 *)p);
|
||||
addr += 2;
|
||||
len -= 2;
|
||||
p += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteMem8_nommu(addr, *p++);
|
||||
addr++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool insertMatchpoint(Breakpoint::Type type, u32 addr, u32 len)
|
||||
{
|
||||
if (type == Breakpoint::BP_TYPE_SOFTWARE_BREAK && len != 2) {
|
||||
WARN_LOG(COMMON, "insertMatchpoint: length != 2: %d", len);
|
||||
return false;
|
||||
}
|
||||
// TODO other matchpoint types
|
||||
if (breakpoints[type].find(addr) != breakpoints[type].end())
|
||||
return true;
|
||||
breakpoints[type][addr] = Breakpoint(type, addr);
|
||||
breakpoints[type][addr].savedOp = ReadMem16_nommu(addr);
|
||||
WriteMem16_nommu(addr, 0xC308); // trapa #0x20
|
||||
return true;
|
||||
}
|
||||
bool removeMatchpoint(Breakpoint::Type type, u32 addr, u32 len)
|
||||
{
|
||||
if (type == Breakpoint::BP_TYPE_SOFTWARE_BREAK && len != 2) {
|
||||
WARN_LOG(COMMON, "removeMatchpoint: length != 2: %d", len);
|
||||
return false;
|
||||
}
|
||||
auto it = breakpoints[type].find(addr);
|
||||
if (it == breakpoints[type].end())
|
||||
return false;
|
||||
WriteMem16_nommu(addr, it->second.savedOp);
|
||||
breakpoints[type].erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 interrupt()
|
||||
{
|
||||
config::DynarecEnabled = false;
|
||||
exception = SIGINT;
|
||||
emu.stop();
|
||||
return exception;
|
||||
}
|
||||
|
||||
// called on the emu thread
|
||||
void debugTrap(u32 event)
|
||||
{
|
||||
exception = findException(event);
|
||||
Sh4cntx.pc -= 2; // FIXME delay slot
|
||||
}
|
||||
|
||||
void postDebugTrap()
|
||||
{
|
||||
// needed to join the emu thread since debugTrap() is called by it
|
||||
emu.stop();
|
||||
}
|
||||
|
||||
u32 currentException()
|
||||
{
|
||||
return exception;
|
||||
}
|
||||
|
||||
void restart()
|
||||
{
|
||||
emu.unloadGame();
|
||||
emu.loadGame(settings.content.path.c_str());
|
||||
emu.start();
|
||||
}
|
||||
|
||||
void detach()
|
||||
{
|
||||
emu.start();
|
||||
}
|
||||
|
||||
void kill()
|
||||
{
|
||||
dc_exit();
|
||||
}
|
||||
|
||||
void resetAgent()
|
||||
{
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
int findException(u32 event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case 0x0A0: // Instruction/data TLB protection violation exception (read)
|
||||
case 0x0C0: // Data TLB protection violation exception (write)
|
||||
return SIGSEGV;
|
||||
case 0x0E0: // Instruction/data address error (read)
|
||||
case 0x100: // data address error (write)
|
||||
return SIGBUS;
|
||||
case 0x160: // trapa
|
||||
case 0x1E0: // User break before/after instruction execution
|
||||
return SIGTRAP;
|
||||
case 0x180: // General illegal instruction exception
|
||||
case 0x1A0: // Slot illegal instruction exception
|
||||
return SIGILL;
|
||||
case 0x120: // FPU exception
|
||||
case 0x800: // General FPU disable exception
|
||||
case 0x820: // Slot FPU disable exception
|
||||
return SIGFPE;
|
||||
default:
|
||||
return SIGABRT;
|
||||
}
|
||||
}
|
||||
|
||||
const u32 *getStack(u32& size)
|
||||
{
|
||||
verify(!Sh4cntx.CpuRunning);
|
||||
size = stack.size() * 8;
|
||||
if (!stack.empty())
|
||||
return (const u32 *)&stack[0];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void subroutineCall()
|
||||
{
|
||||
subroutineReturn();
|
||||
stack.push_back(std::make_pair(Sh4cntx.pc, Sh4cntx.r[15]));
|
||||
}
|
||||
|
||||
void subroutineReturn()
|
||||
{
|
||||
while (!stack.empty() && Sh4cntx.r[15] >= stack.back().second)
|
||||
stack.pop_back();
|
||||
}
|
||||
|
||||
u32 exception = 0;
|
||||
|
||||
std::map<u32, Breakpoint> breakpoints[Breakpoint::Type::BP_TYPE_COUNT];
|
||||
std::vector<std::pair<u32, u32>> stack;
|
||||
};
|
||||
@@ -0,0 +1,974 @@
|
||||
/*
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "types.h"
|
||||
|
||||
#ifdef GDB_SERVER
|
||||
#include "gdb_server.h"
|
||||
#include "debug_agent.h"
|
||||
#include "network/net_platform.h"
|
||||
#include "cfg/option.h"
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <cassert>
|
||||
|
||||
#define MAX_PACKET_LEN 4096
|
||||
|
||||
namespace debugger {
|
||||
|
||||
static void emuEventCallback(Event event, void *);
|
||||
|
||||
class GdbServer
|
||||
{
|
||||
public:
|
||||
struct Error : public std::runtime_error {
|
||||
Error(const char *reason) : std::runtime_error(reason) {}
|
||||
};
|
||||
|
||||
void init(int port)
|
||||
{
|
||||
if (VALID(serverSocket))
|
||||
return;
|
||||
|
||||
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (!VALID(serverSocket))
|
||||
throw Error("gdb: Cannot create server socket");
|
||||
|
||||
int option = 1;
|
||||
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&option, sizeof(option));
|
||||
|
||||
struct sockaddr_in serveraddr;
|
||||
memset(&serveraddr, 0, sizeof(serveraddr));
|
||||
serveraddr.sin_family = AF_INET;
|
||||
serveraddr.sin_port = htons(port);
|
||||
|
||||
if (::bind(serverSocket, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
|
||||
{
|
||||
closesocket(serverSocket);
|
||||
throw Error("gdb: bind() failed");
|
||||
}
|
||||
if (::listen(serverSocket, 5) < 0)
|
||||
{
|
||||
closesocket(serverSocket);
|
||||
throw Error("gdb: listen() failed");
|
||||
}
|
||||
EventManager::listen(Event::Resume, emuEventCallback);
|
||||
EventManager::listen(Event::Terminate, emuEventCallback);
|
||||
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
void term()
|
||||
{
|
||||
if (!initialised)
|
||||
return;
|
||||
EventManager::unlisten(Event::Resume, emuEventCallback);
|
||||
EventManager::unlisten(Event::Terminate, emuEventCallback);
|
||||
stop();
|
||||
if (VALID(clientSocket))
|
||||
{
|
||||
closesocket(clientSocket);
|
||||
clientSocket = INVALID_SOCKET;
|
||||
}
|
||||
if (VALID(serverSocket))
|
||||
{
|
||||
closesocket(serverSocket);
|
||||
serverSocket = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
if (!initialised || thread.joinable())
|
||||
return;
|
||||
DEBUG_LOG(COMMON, "GdbServer starting");
|
||||
thread = std::thread(&GdbServer::serverThread, this);
|
||||
if (config::GDBWaitForConnection)
|
||||
{
|
||||
DEBUG_LOG(COMMON, "Waiting for GDB connection...");
|
||||
agentInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (!initialised)
|
||||
return;
|
||||
if (thread.joinable())
|
||||
{
|
||||
DEBUG_LOG(COMMON, "GdbServer stopping");
|
||||
agent.resetAgent();
|
||||
stopRequested = true;
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
bool isRunning() const {
|
||||
return initialised && thread.joinable();
|
||||
}
|
||||
|
||||
// called on the emu thread
|
||||
void debugTrap(u32 event)
|
||||
{
|
||||
if (!attached)
|
||||
return;
|
||||
agent.debugTrap(event);
|
||||
reportException();
|
||||
postDebugTrapNeeded = true;
|
||||
throw Stop();
|
||||
}
|
||||
|
||||
private:
|
||||
const u32 EXCEPT_NONE = 1;
|
||||
|
||||
void serverThread()
|
||||
{
|
||||
while (!stopRequested)
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
sock_t max_fd = serverSocket;
|
||||
FD_SET(serverSocket, &fds);
|
||||
if (VALID(clientSocket))
|
||||
{
|
||||
max_fd = std::max(max_fd, clientSocket);
|
||||
FD_SET(clientSocket, &fds);
|
||||
}
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000;
|
||||
if (::select(max_fd + 1, &fds, nullptr, nullptr, &tv) > 0)
|
||||
{
|
||||
if (FD_ISSET(serverSocket, &fds))
|
||||
{
|
||||
try {
|
||||
acceptClientConnection();
|
||||
} catch (const Error& e) {
|
||||
ERROR_LOG(COMMON, "%s", e.what());
|
||||
closesocket(serverSocket);
|
||||
serverSocket = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET(clientSocket, &fds))
|
||||
{
|
||||
readCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (VALID(clientSocket))
|
||||
{
|
||||
closesocket(clientSocket);
|
||||
clientSocket = INVALID_SOCKET;
|
||||
}
|
||||
attached = false;
|
||||
stopRequested = false;
|
||||
}
|
||||
|
||||
void acceptClientConnection()
|
||||
{
|
||||
if (VALID(clientSocket))
|
||||
closesocket(clientSocket);
|
||||
sockaddr_in src_addr{};
|
||||
socklen_t addr_len = sizeof(src_addr);
|
||||
clientSocket = ::accept(serverSocket, (sockaddr *)&src_addr, &addr_len);
|
||||
if (!VALID(clientSocket))
|
||||
{
|
||||
if (get_last_error() != L_EAGAIN && get_last_error() != L_EWOULDBLOCK)
|
||||
throw Error("accept failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
NOTICE_LOG(NETWORK, "gdb: client connection");
|
||||
attached = true;
|
||||
agentInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void readCommand()
|
||||
{
|
||||
try {
|
||||
if (postDebugTrapNeeded)
|
||||
{
|
||||
postDebugTrapNeeded = false;
|
||||
try {
|
||||
agent.postDebugTrap();
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
std::string packet = recvPacket();
|
||||
if (packet.empty())
|
||||
return;
|
||||
|
||||
DEBUG_LOG(NETWORK, "gdb: recv %s", packet.c_str());
|
||||
switch (packet[0])
|
||||
{
|
||||
case '!': // Enable extended mode
|
||||
sendPacket("OK");
|
||||
break;
|
||||
case '?': // Sent when connection is first established to query the reason the target halted
|
||||
reportException();
|
||||
break;
|
||||
case 'A': // Initialized argv[] array passed into program. not supported
|
||||
sendPacket("E01");
|
||||
break;;
|
||||
case 'b': // Change the serial line speed to baud. deprecated
|
||||
break;
|
||||
case 'B': // Set or clear a breakpoint at addr. deprecated
|
||||
break;
|
||||
case 'c': // Continue at addr, which is the address to resume.
|
||||
// If addr is omitted, resume at current address
|
||||
sendContinue(packet);
|
||||
break;
|
||||
case 'C': // Continue with signal sig
|
||||
sendContinue(packet);
|
||||
break;
|
||||
case 'd': // Toggle debug flag. deprecated
|
||||
break;
|
||||
case 'D': // Detach GDB from the remote system
|
||||
sendPacket("OK");
|
||||
agent.detach();
|
||||
break;
|
||||
case 'F': // File-I/O protocol extension not currently supported
|
||||
break;;
|
||||
case 'g': // Read general registers
|
||||
readAllRegs();
|
||||
break;
|
||||
case 'G': // Write general registers
|
||||
writeAllRegs(packet);
|
||||
break;
|
||||
case 'H': // Set thread for subsequent operations
|
||||
sendPacket("OK");
|
||||
break;
|
||||
case 'i': // Step the remote target by a single clock cycle
|
||||
case 'I': // Signal, then cycle step
|
||||
// not supported
|
||||
sendPacket("");
|
||||
break;
|
||||
case 'k': // Kill request. Stop process/system
|
||||
agent.kill();
|
||||
break;
|
||||
case 'm': // Read length addressable memory units
|
||||
readMem(packet);
|
||||
break;
|
||||
case 'M': // Write length addressable memory units
|
||||
writeMem(packet);
|
||||
break;
|
||||
case 'p': // Read the value of register
|
||||
readReg(packet);
|
||||
break;
|
||||
case 'P': // Write register
|
||||
writeReg(packet);
|
||||
break;
|
||||
case 'q': // General query packets
|
||||
query(packet);
|
||||
break;
|
||||
case 'Q': // General set packets
|
||||
set(packet);
|
||||
break;
|
||||
case 'r': // Reset the entire system. Deprecated (use 'R' instead)
|
||||
break;
|
||||
case 'R': // Restart the program being debugged.
|
||||
restart();
|
||||
break;
|
||||
case 's': // Single step
|
||||
step(EXCEPT_NONE);
|
||||
break;
|
||||
case 'S': // Step with signal
|
||||
step();
|
||||
break;
|
||||
case 't': // Search backwards. unsupported
|
||||
break;
|
||||
case 'T': // Find out if the thread is alive
|
||||
sendPacket("OK");
|
||||
break;
|
||||
case 'v': // 'v' packets to control execution
|
||||
vpacket(packet);
|
||||
break;
|
||||
case 'X': // Write binary data to memory
|
||||
writeMemBin(packet);
|
||||
break;
|
||||
case 'z': // Remove a breakpoint/watchpoint.
|
||||
removeMatchpoint(packet);
|
||||
break;
|
||||
case 'Z': // Insert a breakpoint/watchpoint.
|
||||
insertMatchpoint(packet);
|
||||
break;
|
||||
case 3:
|
||||
interrupt();
|
||||
break;
|
||||
default:
|
||||
// Unknown commands are ignored
|
||||
WARN_LOG(COMMON, "Unknown gdb command: %s", packet.c_str());
|
||||
break;;
|
||||
}
|
||||
} catch (const Error& e) {
|
||||
ERROR_LOG(COMMON, "%s", e.what());
|
||||
closesocket(clientSocket);
|
||||
clientSocket = INVALID_SOCKET;
|
||||
attached = false;
|
||||
}
|
||||
}
|
||||
|
||||
void reportException()
|
||||
{
|
||||
char s[4];
|
||||
sprintf(s, "S%02X", agent.currentException());
|
||||
sendPacket(s);
|
||||
}
|
||||
|
||||
void sendContinue(const std::string& pkt)
|
||||
{
|
||||
if (pkt[0] != 'c') {
|
||||
WARN_LOG(COMMON, "Continue with signal not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pkt == "c")
|
||||
agent.doContinue();
|
||||
else
|
||||
{
|
||||
// Get the pc at which to resume
|
||||
u32 addr;
|
||||
if (sscanf(pkt.c_str(), "c%x", &addr) != 1)
|
||||
{
|
||||
WARN_LOG(COMMON, "Continue address invalid %s", pkt.c_str());
|
||||
return;
|
||||
}
|
||||
agent.doContinue(addr);
|
||||
}
|
||||
}
|
||||
|
||||
void readAllRegs()
|
||||
{
|
||||
u32 *regs;
|
||||
int c = agent.readAllRegs(®s);
|
||||
std::string outpkt;
|
||||
for (int i = 0; i < c; i++)
|
||||
outpkt += pack(regs[i]);
|
||||
sendPacket(outpkt);
|
||||
}
|
||||
|
||||
void writeAllRegs(const std::string& pkt)
|
||||
{
|
||||
std::vector<u32> regs;
|
||||
for (auto it = pkt.begin() + 1; it <= pkt.end() - 8; it += 8)
|
||||
regs.push_back(unpack(&*it, 8));
|
||||
|
||||
agent.writeAllRegs(regs);
|
||||
sendPacket("OK");
|
||||
}
|
||||
|
||||
void readMem(const std::string& pkt)
|
||||
{
|
||||
u32 addr;
|
||||
u32 len;
|
||||
if (sscanf(pkt.c_str(), "m%x,%x:", &addr, &len) != 2)
|
||||
{
|
||||
WARN_LOG(COMMON, "readMem: invalid packet %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
return;
|
||||
}
|
||||
const u8 *mem = agent.readMem(addr, len);
|
||||
std::string outpkt;
|
||||
for (u32 i = 0; i < len; i++)
|
||||
{
|
||||
char s[3];
|
||||
sprintf(s,"%02x", mem[i]);
|
||||
outpkt += s;
|
||||
}
|
||||
sendPacket(outpkt);
|
||||
}
|
||||
|
||||
void writeMem(const std::string& pkt)
|
||||
{
|
||||
u32 addr;
|
||||
u32 len;
|
||||
if (sscanf(pkt.c_str(), "M%x,%x:", &addr, &len) != 2)
|
||||
{
|
||||
WARN_LOG(COMMON, "writeMem: invalid packet %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
return;
|
||||
}
|
||||
std::vector<u8> data(len);
|
||||
const char *p = &pkt[pkt.find(':')] + 1;
|
||||
for (u32 i = 0; i < len; i++, p += 2)
|
||||
{
|
||||
u32 b;
|
||||
sscanf(p,"%2x", &b);
|
||||
data[i] = (u8)b;
|
||||
}
|
||||
agent.writeMem(addr, data);
|
||||
sendPacket("OK");
|
||||
}
|
||||
|
||||
void writeMemBin(const std::string& pkt)
|
||||
{
|
||||
u32 addr;
|
||||
u32 len;
|
||||
if (sscanf(pkt.c_str(), "X%x,%x:", &addr, &len) != 2)
|
||||
{
|
||||
WARN_LOG(COMMON, "writeMemBin invalid command: %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
return;
|
||||
}
|
||||
const char *p = &pkt[pkt.find(':')] + 1;
|
||||
std::vector<u8> data;
|
||||
data.reserve(pkt.length() - (p - &pkt[0]));
|
||||
for (; p <= &pkt.back(); p++)
|
||||
{
|
||||
u8 b = *p;
|
||||
if (b == '}')
|
||||
{
|
||||
b = *++p ^ 0x20;
|
||||
}
|
||||
data.push_back(b);
|
||||
}
|
||||
agent.writeMem(addr, data);
|
||||
sendPacket("OK");
|
||||
}
|
||||
|
||||
void readReg(const std::string& pkt)
|
||||
{
|
||||
u32 regNum;
|
||||
if (sscanf(pkt.c_str(), "p%x", ®Num) != 1)
|
||||
{
|
||||
WARN_LOG(COMMON, "readReg: invalid packet %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
return;
|
||||
}
|
||||
u32 v = agent.readReg(regNum);
|
||||
sendPacket(pack(v));
|
||||
}
|
||||
|
||||
void writeReg(const std::string& pkt)
|
||||
{
|
||||
u32 regNum;
|
||||
char vstr[9];
|
||||
if (sscanf(pkt.c_str(), "P%x=%8s", ®Num, vstr) != 2)
|
||||
{
|
||||
WARN_LOG(COMMON, "writeReg: invalid packet %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
return;
|
||||
}
|
||||
agent.writeReg(regNum, unpack(vstr, 8));
|
||||
sendPacket("OK");
|
||||
}
|
||||
|
||||
void query(const std::string& pkt)
|
||||
{
|
||||
if (pkt == "qC")
|
||||
// Return the current thread ID. 0 is "any thread"
|
||||
sendPacket("QC0.01");
|
||||
else if (pkt.rfind("qCRC", 0) == 0)
|
||||
{
|
||||
WARN_LOG(COMMON, "CRC compute not supported %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
}
|
||||
else if (pkt == "qfThreadInfo")
|
||||
// Obtain a list of all active thread IDs (first call)
|
||||
sendPacket("m0");
|
||||
else if (pkt == "qsThreadInfo")
|
||||
// Obtain a list of all active thread IDs (subsequent calls -> 'l' == end of list)
|
||||
sendPacket("l");
|
||||
else if (pkt.rfind("qGetTLSAddr:", 0) == 0)
|
||||
// Fetch the address associated with thread local storage
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("qL", 0) == 0)
|
||||
// Obtain thread information. deprecated
|
||||
sendPacket("qM001");
|
||||
else if (pkt == "qOffsets")
|
||||
// Get section offsets. Not supported
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("qP", 0) == 0)
|
||||
// Returns information on thread. deprecated
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("qRcmd,", 0) == 0)
|
||||
{
|
||||
std::string customCmd;
|
||||
for (const char *p = pkt.c_str() + 6; *p != '\0'; p += 2)
|
||||
customCmd += (char)unpack(p, 2);
|
||||
DEBUG_LOG(COMMON, "query: custom command %s", customCmd.c_str());
|
||||
if (customCmd == "reset")
|
||||
restart();
|
||||
else if (customCmd == "stack")
|
||||
{
|
||||
u32 len;
|
||||
const u32 *data = agent.getStack(len);
|
||||
len /= 4;
|
||||
|
||||
#if _MSC_VER // Non-const array size is a GCC extension
|
||||
assert((len * 9 * 2 + 1) < MAX_PACKET_LEN);
|
||||
char reply[MAX_PACKET_LEN];
|
||||
#else
|
||||
char reply[len * 9 * 2 + 1];
|
||||
#endif
|
||||
char *r = reply;
|
||||
for (u32 i = 0; i < len; i++)
|
||||
{
|
||||
char n[10];
|
||||
sprintf(n, "%08x ", *data++);
|
||||
for (char *p = n; *p != 0; p++)
|
||||
{
|
||||
*r++ = packnb((*p >> 4) & 0xf);
|
||||
*r++ = packnb(*p & 0xf);
|
||||
}
|
||||
}
|
||||
*r = 0;
|
||||
sendPacket(reply);
|
||||
}
|
||||
else
|
||||
sendPacket("");
|
||||
}
|
||||
else if (pkt.rfind("qSupported", 0) == 0)
|
||||
{
|
||||
// Tell the remote stub about features supported by GDB,
|
||||
// and query the stub for features it supports
|
||||
char qsupported[128];
|
||||
snprintf(qsupported, 128, "PacketSize=%i;vContSupported+", MAX_PACKET_LEN);
|
||||
sendPacket(qsupported);
|
||||
}
|
||||
else if (pkt.rfind("qSymbol:", 0) == 0)
|
||||
// Notify the target that GDB is prepared to serve symbol lookup requests
|
||||
sendPacket("OK");
|
||||
else if (pkt.rfind("qThreadExtraInfo,", 0) == 0)
|
||||
{
|
||||
// Obtain from the target OS a printable string description of thread attributes
|
||||
char s[19];
|
||||
sprintf(s, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
|
||||
sendPacket(std::string(s, 18));
|
||||
}
|
||||
else if (pkt.rfind("qXfer:", 0) == 0)
|
||||
// Read uninterpreted bytes from the target’s special data area identified by the keyword object
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("qAttached", 0) == 0)
|
||||
// Return an indication of whether the remote server attached to an existing process
|
||||
// or created a new process
|
||||
sendPacket("1"); // existing process
|
||||
else if (pkt.rfind("qTfV", 0) == 0)
|
||||
// request data about trace state variables
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("qTfP", 0) == 0)
|
||||
// request data about tracepoints
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("qTStatus", 0) == 0)
|
||||
// Ask the stub if there is a trace experiment running right now
|
||||
sendPacket("");
|
||||
else
|
||||
WARN_LOG(COMMON, "query not supported %s", pkt.c_str());
|
||||
}
|
||||
|
||||
void set(const std::string& pkt)
|
||||
{
|
||||
if (pkt.rfind("QPassSignals:", 0) == 0)
|
||||
// Passing signals not supported
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("QTDP", 0) == 0
|
||||
|| pkt.rfind("QFrame", 0) == 0
|
||||
|| pkt.rfind("QTStart", 0) == 0
|
||||
|| pkt.rfind("QTStop", 0) == 0
|
||||
|| pkt.rfind("QTinit", 0) == 0
|
||||
|| pkt.rfind("QTro", 0) == 0)
|
||||
// No tracepoint feature supported
|
||||
sendPacket("");
|
||||
else
|
||||
WARN_LOG(COMMON, "set not supported %s", pkt.c_str());
|
||||
}
|
||||
|
||||
void vpacket(const std::string& pkt)
|
||||
{
|
||||
if (pkt.rfind("vAttach;", 0) == 0)
|
||||
sendPacket("S05");
|
||||
else if (pkt.rfind("vCont?", 0) == 0)
|
||||
// supported vCont actions - (c)ontinue, (C)ontinue with signal, (s)tep, (S)tep with signal, (r)ange-step
|
||||
sendPacket("vCont;c;C;s;S;t;r");
|
||||
else if (pkt.rfind("vCont", 0) == 0)
|
||||
{
|
||||
std::string vContCmd = pkt.substr(strlen("vCont;"));
|
||||
switch (vContCmd[0])
|
||||
{
|
||||
case 'c':
|
||||
case 'C':
|
||||
sendContinue(vContCmd);
|
||||
break;
|
||||
case 's':
|
||||
step(EXCEPT_NONE);
|
||||
break;
|
||||
case 'S':
|
||||
step();
|
||||
case 'r':
|
||||
{
|
||||
u32 from, to;
|
||||
if (sscanf(vContCmd.c_str(), "r%x,%x", &from, &to) == 2)
|
||||
{
|
||||
stepRange(from, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(COMMON, "Unsupported vCont:r format %s", pkt.c_str());
|
||||
sendContinue("c");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN_LOG(COMMON, "vCont action not supported %s", pkt.c_str());
|
||||
}
|
||||
}
|
||||
else if (pkt.rfind("vFile:", 0) == 0)
|
||||
// not supported
|
||||
sendPacket("");
|
||||
else if (pkt.rfind("vFlashErase:", 0) == 0)
|
||||
// not supported
|
||||
sendPacket("E01");
|
||||
else if (pkt.rfind("vFlashWrite:", 0) == 0)
|
||||
// not supported
|
||||
sendPacket("E01");
|
||||
else if (pkt.rfind("vFlashDone:", 0) == 0)
|
||||
// not supported
|
||||
sendPacket("E01");
|
||||
else if (pkt.rfind("vRun;", 0) == 0)
|
||||
{
|
||||
if (pkt != "vRun;")
|
||||
WARN_LOG(COMMON, "unexpected vRun args ignored: %s", pkt.c_str());
|
||||
agent.restart();
|
||||
sendPacket("S05");
|
||||
}
|
||||
else if (pkt.rfind("vKill", 0) == 0)
|
||||
{
|
||||
sendPacket("OK");
|
||||
agent.kill();
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(COMMON, "unknown v packet: %s", pkt.c_str());
|
||||
sendPacket("");
|
||||
}
|
||||
}
|
||||
|
||||
void restart()
|
||||
{
|
||||
agent.restart();
|
||||
}
|
||||
|
||||
void step(u32 what = 0)
|
||||
{
|
||||
try {
|
||||
agent.step();
|
||||
sendPacket("S05");
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void stepRange(u32 from, u32 to)
|
||||
{
|
||||
try {
|
||||
sendPacket("OK");
|
||||
agent.stepRange(from, to);
|
||||
sendPacket("S05");
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void insertMatchpoint(const std::string& pkt)
|
||||
{
|
||||
u32 type;
|
||||
u32 addr;
|
||||
u32 len;
|
||||
if (sscanf(pkt.c_str(), "Z%1d,%x,%1d", &type, &addr, &len) != 3) {
|
||||
WARN_LOG(COMMON, "insertMatchpoint: unknown packet: %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
}
|
||||
switch (type) {
|
||||
case DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK: // soft bp
|
||||
if (agent.insertMatchpoint(DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK,
|
||||
addr, len))
|
||||
sendPacket("OK");
|
||||
else
|
||||
sendPacket("E01");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::BP_TYPE_HARDWARE_BREAK: // hardware bp
|
||||
sendPacket("");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::BP_TYPE_WRITE_WATCHPOINT: // write watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::BP_TYPE_READ_WATCHPOINT: // read watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::BP_TYPE_ACCESS_WATCHPOINT: // access watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
default:
|
||||
sendPacket("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void removeMatchpoint(const std::string& pkt)
|
||||
{
|
||||
u32 type;
|
||||
u32 addr;
|
||||
u32 len;
|
||||
if (sscanf(pkt.c_str(), "z%1d,%x,%1d", &type, &addr, &len) != 3) {
|
||||
WARN_LOG(COMMON, "removeMatchpoint: unknown packet: %s", pkt.c_str());
|
||||
sendPacket("E01");
|
||||
}
|
||||
switch (type) {
|
||||
case 0: // soft bp
|
||||
if (agent.removeMatchpoint(DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK,
|
||||
addr, len))
|
||||
sendPacket("OK");
|
||||
else
|
||||
sendPacket("E01");
|
||||
break;
|
||||
case 1: // hardware bp
|
||||
sendPacket("");
|
||||
break;
|
||||
case 2: // write watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
case 3: // read watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
case 4: // access watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
default:
|
||||
sendPacket("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void interrupt()
|
||||
{
|
||||
u32 signal = agentInterrupt();
|
||||
char s[10];
|
||||
sprintf(s, "S%02x", signal);
|
||||
sendPacket(s);
|
||||
}
|
||||
|
||||
char recvChar()
|
||||
{
|
||||
char c;
|
||||
int rc = ::recv(clientSocket, &c, 1, 0);
|
||||
if (rc <= 0)
|
||||
throw Error("gdb: I/O error");
|
||||
return c;
|
||||
}
|
||||
|
||||
void sendChar(char c)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(outMutex);
|
||||
int rc = ::send(clientSocket, &c, 1, 0);
|
||||
if (rc <= 0)
|
||||
throw Error("gdb: I/O error");
|
||||
}
|
||||
|
||||
u8 unpack(char c)
|
||||
{
|
||||
c = std::tolower(c);
|
||||
if (c <= '9')
|
||||
return c - '0';
|
||||
else
|
||||
return c - 'a' + 10;
|
||||
}
|
||||
|
||||
char packnb(u8 b)
|
||||
{
|
||||
if (b < 10)
|
||||
return '0' + b;
|
||||
else
|
||||
return 'a' + b - 10;
|
||||
}
|
||||
|
||||
std::string packb(u8 v)
|
||||
{
|
||||
std::string s(1, packnb((v >> 4) & 0xf));
|
||||
s += packnb(v & 0xf);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string pack(u32 v)
|
||||
{
|
||||
return packb(v & 0xff) + packb((v >> 8) & 0xff)
|
||||
+ packb((v >> 16) & 0xff) + packb((v >> 24) & 0xff);
|
||||
}
|
||||
|
||||
u32 unpack(const char *s, int l)
|
||||
{
|
||||
u32 r = 0;
|
||||
for (int i = 0; i < l && *s != '\0'; i += 2, s += 2)
|
||||
{
|
||||
r |= (unpack(s[0]) << 4 | unpack(s[1])) << (i * 4);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string recvPacket()
|
||||
{
|
||||
std::string pkt;
|
||||
// look for start character ('$') or BREAK
|
||||
char c = recvChar();
|
||||
if (c == 3)
|
||||
return std::string("\03");
|
||||
if (c != '$')
|
||||
return pkt;
|
||||
|
||||
// read until '#'
|
||||
u8 checksum = 0;
|
||||
while (!stopRequested)
|
||||
{
|
||||
c = recvChar();
|
||||
if (c == '$')
|
||||
{
|
||||
checksum = 0;
|
||||
pkt.clear();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '#')
|
||||
break;
|
||||
|
||||
checksum += (u8)c;
|
||||
pkt.push_back(c);
|
||||
}
|
||||
if (stopRequested)
|
||||
{
|
||||
pkt.clear();
|
||||
return pkt;
|
||||
}
|
||||
u8 recvchk = unpack(recvChar()) << 4;
|
||||
recvchk |= unpack(recvChar());
|
||||
|
||||
// If the checksums don't match print a warning, and put the
|
||||
// negative ack back to the client. Otherwise put a positive ack.
|
||||
if (checksum != recvchk)
|
||||
{
|
||||
sendChar('-'); // Failed checksum
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
sendChar('+'); // Successful transfer
|
||||
return pkt;
|
||||
}
|
||||
}
|
||||
|
||||
void sendPacket(const std::string& pkt)
|
||||
{ DEBUG_LOG(NETWORK, "gdb: sending pkt");
|
||||
std::unique_lock<std::mutex> lock(outMutex);
|
||||
std::string data{'$'};
|
||||
u8 checksum = 0;
|
||||
for (char c : pkt)
|
||||
{
|
||||
if (c == '$' || c == '#' || c == '*' || c == '}')
|
||||
{
|
||||
c ^= 0x20;
|
||||
checksum += (u8)'}';
|
||||
data.push_back('}');
|
||||
}
|
||||
checksum += (u8)c;
|
||||
data.push_back(c);
|
||||
}
|
||||
data.push_back('#');
|
||||
char s[9];
|
||||
sprintf(s, "%02x", checksum);
|
||||
data += s;
|
||||
DEBUG_LOG(NETWORK, "gdb: sent %s", data.c_str());
|
||||
int ret = ::send(clientSocket, data.c_str(), data.length(), 0);
|
||||
if (ret < (int)data.length())
|
||||
throw Error("I/O error");
|
||||
}
|
||||
|
||||
u32 agentInterrupt()
|
||||
{
|
||||
try {
|
||||
return agent.interrupt();
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool initialised = false;
|
||||
bool stopRequested = false;
|
||||
bool attached = false;
|
||||
bool postDebugTrapNeeded = false;
|
||||
sock_t serverSocket = INVALID_SOCKET;
|
||||
sock_t clientSocket = INVALID_SOCKET;
|
||||
std::thread thread;
|
||||
std::mutex outMutex;
|
||||
public:
|
||||
DebugAgent agent;
|
||||
};
|
||||
|
||||
static GdbServer gdbServer;
|
||||
|
||||
void init(int port)
|
||||
{
|
||||
gdbServer.init(port);
|
||||
}
|
||||
|
||||
void term()
|
||||
{
|
||||
gdbServer.term();
|
||||
}
|
||||
|
||||
void debugTrap(u32 event)
|
||||
{
|
||||
gdbServer.debugTrap(event);
|
||||
}
|
||||
|
||||
void subroutineCall()
|
||||
{
|
||||
gdbServer.agent.subroutineCall();
|
||||
}
|
||||
|
||||
void subroutineReturn()
|
||||
{
|
||||
gdbServer.agent.subroutineReturn();
|
||||
}
|
||||
|
||||
static void emuEventCallback(Event event, void *)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case Event::Resume:
|
||||
try {
|
||||
if (!gdbServer.isRunning())
|
||||
gdbServer.run();
|
||||
} catch (const GdbServer::Error& e) {
|
||||
ERROR_LOG(COMMON, "%s", e.what());
|
||||
}
|
||||
break;
|
||||
case Event::Terminate:
|
||||
gdbServer.stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace debugger {
|
||||
|
||||
// exception thrown in response to trap
|
||||
struct Stop { };
|
||||
|
||||
static const int DEFAULT_PORT = 3263;
|
||||
|
||||
#ifdef GDB_SERVER
|
||||
|
||||
void init(int port);
|
||||
void term();
|
||||
void run();
|
||||
void debugTrap(u32 event);
|
||||
void subroutineCall();
|
||||
void subroutineReturn();
|
||||
|
||||
#else
|
||||
static inline void init(int port) {}
|
||||
static inline void term() {}
|
||||
static inline void run() {}
|
||||
static inline void debugTrap(u32 event) {}
|
||||
static inline void subroutineCall() {}
|
||||
static inline void subroutineReturn() {}
|
||||
#endif
|
||||
}
|
||||
Submodule
+1
Submodule core/deps/SDL added at cc016b0046.
Submodule
+1
Submodule core/deps/Spout added at ce94918ea3.
Submodule
+1
Submodule core/deps/Syphon added at 486dd8e4ef.
Submodule
+1
Submodule core/deps/Vulkan-Headers added at 85c2334e92.
Submodule
+1
Submodule core/deps/VulkanMemoryAllocator added at 6eb62e1515.
Submodule
+1
Submodule core/deps/breakpad added at 1ab24bcc81.
@@ -2,7 +2,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "deps/coreio/coreio.h"
|
||||
#include "cdipsr.h"
|
||||
|
||||
// Global variables
|
||||
@@ -12,11 +11,6 @@ unsigned long temp_value;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FILE core_file
|
||||
#define fread(buff,sz,cnt,fc) core_fread(fc,buff,sz*cnt)
|
||||
#define fseek core_fseek
|
||||
#define ftell core_ftell
|
||||
|
||||
unsigned long ask_type(FILE *fsource, long header_position)
|
||||
{
|
||||
|
||||
@@ -117,7 +111,8 @@ void CDI_get_tracks (FILE *fsource, image_s *image)
|
||||
|
||||
bool CDI_init (FILE *fsource, image_s *image, const char *fsourcename)
|
||||
{
|
||||
image->length = core_fsize(fsource);
|
||||
fseek(fsource, 0, SEEK_END);
|
||||
image->length = ftell(fsource);
|
||||
|
||||
if (image->length < 8)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#ifndef __CDI_H__
|
||||
#define __CDI_H__
|
||||
|
||||
#include "deps/coreio/coreio.h"
|
||||
|
||||
/* Basic structures */
|
||||
|
||||
typedef struct image_s
|
||||
@@ -38,11 +36,11 @@ typedef struct track_s
|
||||
#define CDI_V3 0x80000005
|
||||
#define CDI_V35 0x80000006
|
||||
|
||||
unsigned long ask_type(core_file *fsource, long header_position);
|
||||
bool CDI_init(core_file *fsource, image_s *image, const char *fsourcename);
|
||||
void CDI_get_sessions(core_file *fsource, image_s *image);
|
||||
void CDI_get_tracks(core_file *fsource, image_s *image);
|
||||
void CDI_read_track(core_file *fsource, image_s *image, track_s *track);
|
||||
void CDI_skip_next_session(core_file *fsource, image_s *image);
|
||||
unsigned long ask_type(FILE *fsource, long header_position);
|
||||
bool CDI_init(FILE *fsource, image_s *image, const char *fsourcename);
|
||||
void CDI_get_sessions(FILE *fsource, image_s *image);
|
||||
void CDI_get_tracks(FILE *fsource, image_s *image);
|
||||
void CDI_read_track(FILE *fsource, image_s *image, track_s *track);
|
||||
void CDI_skip_next_session(FILE *fsource, image_s *image);
|
||||
|
||||
#endif
|
||||
@@ -1,125 +0,0 @@
|
||||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
bitstream.c
|
||||
|
||||
Helper classes for reading/writing at the bit level.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "bitstream.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/***************************************************************************
|
||||
* INLINE FUNCTIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
int bitstream_overflow(struct bitstream* bitstream) { return ((bitstream->doffset - bitstream->bits / 8) > bitstream->dlength); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
* create_bitstream - constructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
struct bitstream* create_bitstream(const void *src, uint32_t srclength)
|
||||
{
|
||||
struct bitstream* bitstream = (struct bitstream*)malloc(sizeof(struct bitstream));
|
||||
bitstream->buffer = 0;
|
||||
bitstream->bits = 0;
|
||||
bitstream->read = (const uint8_t*)src;
|
||||
bitstream->doffset = 0;
|
||||
bitstream->dlength = srclength;
|
||||
return bitstream;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* bitstream_peek - fetch the requested number of bits
|
||||
* but don't advance the input pointer
|
||||
*-----------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_peek(struct bitstream* bitstream, int numbits)
|
||||
{
|
||||
if (numbits == 0)
|
||||
return 0;
|
||||
|
||||
/* fetch data if we need more */
|
||||
if (numbits > bitstream->bits)
|
||||
{
|
||||
while (bitstream->bits <= 24)
|
||||
{
|
||||
if (bitstream->doffset < bitstream->dlength)
|
||||
bitstream->buffer |= bitstream->read[bitstream->doffset] << (24 - bitstream->bits);
|
||||
bitstream->doffset++;
|
||||
bitstream->bits += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the data */
|
||||
return bitstream->buffer >> (32 - numbits);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* bitstream_remove - advance the input pointer by the
|
||||
* specified number of bits
|
||||
*-----------------------------------------------------
|
||||
*/
|
||||
|
||||
void bitstream_remove(struct bitstream* bitstream, int numbits)
|
||||
{
|
||||
bitstream->buffer <<= numbits;
|
||||
bitstream->bits -= numbits;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* bitstream_read - fetch the requested number of bits
|
||||
*-----------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_read(struct bitstream* bitstream, int numbits)
|
||||
{
|
||||
uint32_t result = bitstream_peek(bitstream, numbits);
|
||||
bitstream_remove(bitstream, numbits);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
* read_offset - return the current read offset
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_read_offset(struct bitstream* bitstream)
|
||||
{
|
||||
uint32_t result = bitstream->doffset;
|
||||
int bits = bitstream->bits;
|
||||
while (bits >= 8)
|
||||
{
|
||||
result--;
|
||||
bits -= 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flush - flush to the nearest byte
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_flush(struct bitstream* bitstream)
|
||||
{
|
||||
while (bitstream->bits >= 8)
|
||||
{
|
||||
bitstream->doffset--;
|
||||
bitstream->bits -= 8;
|
||||
}
|
||||
bitstream->bits = bitstream->buffer = 0;
|
||||
return bitstream->doffset;
|
||||
}
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
cdrom.c
|
||||
|
||||
Generic MAME CD-ROM utilties - build IDE and SCSI CD-ROMs on top of this
|
||||
|
||||
****************************************************************************
|
||||
|
||||
IMPORTANT:
|
||||
"physical" block addresses are the actual addresses on the emulated CD.
|
||||
"chd" block addresses are the block addresses in the CHD file.
|
||||
Because we pad each track to a 4-frame boundary, these addressing
|
||||
schemes will differ after track 1!
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cdrom.h"
|
||||
|
||||
/***************************************************************************
|
||||
DEBUGGING
|
||||
***************************************************************************/
|
||||
|
||||
/** @brief The verbose. */
|
||||
#define VERBOSE (0)
|
||||
#if VERBOSE
|
||||
|
||||
/**
|
||||
* @def LOG(x) do
|
||||
*
|
||||
* @brief A macro that defines log.
|
||||
*
|
||||
* @param x The void to process.
|
||||
*/
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
/**
|
||||
* @fn void CLIB_DECL logerror(const char *text, ...) ATTR_PRINTF(1,2);
|
||||
*
|
||||
* @brief Logerrors the given text.
|
||||
*
|
||||
* @param text The text.
|
||||
*
|
||||
* @return A CLIB_DECL.
|
||||
*/
|
||||
|
||||
void CLIB_DECL logerror(const char *text, ...) ATTR_PRINTF(1,2);
|
||||
#else
|
||||
|
||||
/**
|
||||
* @def LOG(x);
|
||||
*
|
||||
* @brief A macro that defines log.
|
||||
*
|
||||
* @param x The void to process.
|
||||
*/
|
||||
|
||||
#define LOG(x)
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
/** @brief offset within sector. */
|
||||
#define SYNC_OFFSET 0x000
|
||||
/** @brief 12 bytes. */
|
||||
#define SYNC_NUM_BYTES 12
|
||||
|
||||
/** @brief offset within sector. */
|
||||
#define MODE_OFFSET 0x00f
|
||||
|
||||
/** @brief offset within sector. */
|
||||
#define ECC_P_OFFSET 0x81c
|
||||
/** @brief 2 lots of 86. */
|
||||
#define ECC_P_NUM_BYTES 86
|
||||
/** @brief 24 bytes each. */
|
||||
#define ECC_P_COMP 24
|
||||
|
||||
/** @brief The ECC q offset. */
|
||||
#define ECC_Q_OFFSET (ECC_P_OFFSET + 2 * ECC_P_NUM_BYTES)
|
||||
/** @brief 2 lots of 52. */
|
||||
#define ECC_Q_NUM_BYTES 52
|
||||
/** @brief 43 bytes each. */
|
||||
#define ECC_Q_COMP 43
|
||||
|
||||
/**
|
||||
* @brief -------------------------------------------------
|
||||
* ECC lookup tables pre-calculated tables for ECC data calcs
|
||||
* -------------------------------------------------.
|
||||
*/
|
||||
|
||||
static const uint8_t ecclow[256] =
|
||||
{
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
|
||||
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
|
||||
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
|
||||
0x1d, 0x1f, 0x19, 0x1b, 0x15, 0x17, 0x11, 0x13, 0x0d, 0x0f, 0x09, 0x0b, 0x05, 0x07, 0x01, 0x03,
|
||||
0x3d, 0x3f, 0x39, 0x3b, 0x35, 0x37, 0x31, 0x33, 0x2d, 0x2f, 0x29, 0x2b, 0x25, 0x27, 0x21, 0x23,
|
||||
0x5d, 0x5f, 0x59, 0x5b, 0x55, 0x57, 0x51, 0x53, 0x4d, 0x4f, 0x49, 0x4b, 0x45, 0x47, 0x41, 0x43,
|
||||
0x7d, 0x7f, 0x79, 0x7b, 0x75, 0x77, 0x71, 0x73, 0x6d, 0x6f, 0x69, 0x6b, 0x65, 0x67, 0x61, 0x63,
|
||||
0x9d, 0x9f, 0x99, 0x9b, 0x95, 0x97, 0x91, 0x93, 0x8d, 0x8f, 0x89, 0x8b, 0x85, 0x87, 0x81, 0x83,
|
||||
0xbd, 0xbf, 0xb9, 0xbb, 0xb5, 0xb7, 0xb1, 0xb3, 0xad, 0xaf, 0xa9, 0xab, 0xa5, 0xa7, 0xa1, 0xa3,
|
||||
0xdd, 0xdf, 0xd9, 0xdb, 0xd5, 0xd7, 0xd1, 0xd3, 0xcd, 0xcf, 0xc9, 0xcb, 0xc5, 0xc7, 0xc1, 0xc3,
|
||||
0xfd, 0xff, 0xf9, 0xfb, 0xf5, 0xf7, 0xf1, 0xf3, 0xed, 0xef, 0xe9, 0xeb, 0xe5, 0xe7, 0xe1, 0xe3
|
||||
};
|
||||
|
||||
/** @brief The ecchigh[ 256]. */
|
||||
static const uint8_t ecchigh[256] =
|
||||
{
|
||||
0x00, 0xf4, 0xf5, 0x01, 0xf7, 0x03, 0x02, 0xf6, 0xf3, 0x07, 0x06, 0xf2, 0x04, 0xf0, 0xf1, 0x05,
|
||||
0xfb, 0x0f, 0x0e, 0xfa, 0x0c, 0xf8, 0xf9, 0x0d, 0x08, 0xfc, 0xfd, 0x09, 0xff, 0x0b, 0x0a, 0xfe,
|
||||
0xeb, 0x1f, 0x1e, 0xea, 0x1c, 0xe8, 0xe9, 0x1d, 0x18, 0xec, 0xed, 0x19, 0xef, 0x1b, 0x1a, 0xee,
|
||||
0x10, 0xe4, 0xe5, 0x11, 0xe7, 0x13, 0x12, 0xe6, 0xe3, 0x17, 0x16, 0xe2, 0x14, 0xe0, 0xe1, 0x15,
|
||||
0xcb, 0x3f, 0x3e, 0xca, 0x3c, 0xc8, 0xc9, 0x3d, 0x38, 0xcc, 0xcd, 0x39, 0xcf, 0x3b, 0x3a, 0xce,
|
||||
0x30, 0xc4, 0xc5, 0x31, 0xc7, 0x33, 0x32, 0xc6, 0xc3, 0x37, 0x36, 0xc2, 0x34, 0xc0, 0xc1, 0x35,
|
||||
0x20, 0xd4, 0xd5, 0x21, 0xd7, 0x23, 0x22, 0xd6, 0xd3, 0x27, 0x26, 0xd2, 0x24, 0xd0, 0xd1, 0x25,
|
||||
0xdb, 0x2f, 0x2e, 0xda, 0x2c, 0xd8, 0xd9, 0x2d, 0x28, 0xdc, 0xdd, 0x29, 0xdf, 0x2b, 0x2a, 0xde,
|
||||
0x8b, 0x7f, 0x7e, 0x8a, 0x7c, 0x88, 0x89, 0x7d, 0x78, 0x8c, 0x8d, 0x79, 0x8f, 0x7b, 0x7a, 0x8e,
|
||||
0x70, 0x84, 0x85, 0x71, 0x87, 0x73, 0x72, 0x86, 0x83, 0x77, 0x76, 0x82, 0x74, 0x80, 0x81, 0x75,
|
||||
0x60, 0x94, 0x95, 0x61, 0x97, 0x63, 0x62, 0x96, 0x93, 0x67, 0x66, 0x92, 0x64, 0x90, 0x91, 0x65,
|
||||
0x9b, 0x6f, 0x6e, 0x9a, 0x6c, 0x98, 0x99, 0x6d, 0x68, 0x9c, 0x9d, 0x69, 0x9f, 0x6b, 0x6a, 0x9e,
|
||||
0x40, 0xb4, 0xb5, 0x41, 0xb7, 0x43, 0x42, 0xb6, 0xb3, 0x47, 0x46, 0xb2, 0x44, 0xb0, 0xb1, 0x45,
|
||||
0xbb, 0x4f, 0x4e, 0xba, 0x4c, 0xb8, 0xb9, 0x4d, 0x48, 0xbc, 0xbd, 0x49, 0xbf, 0x4b, 0x4a, 0xbe,
|
||||
0xab, 0x5f, 0x5e, 0xaa, 0x5c, 0xa8, 0xa9, 0x5d, 0x58, 0xac, 0xad, 0x59, 0xaf, 0x5b, 0x5a, 0xae,
|
||||
0x50, 0xa4, 0xa5, 0x51, 0xa7, 0x53, 0x52, 0xa6, 0xa3, 0x57, 0x56, 0xa2, 0x54, 0xa0, 0xa1, 0x55
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief -------------------------------------------------
|
||||
* poffsets - each row represents the addresses used to calculate a byte of the ECC P
|
||||
* data 86 (*2) ECC P bytes, 24 values represented by each
|
||||
* -------------------------------------------------.
|
||||
*/
|
||||
|
||||
static const uint16_t poffsets[ECC_P_NUM_BYTES][ECC_P_COMP] =
|
||||
{
|
||||
{ 0x000,0x056,0x0ac,0x102,0x158,0x1ae,0x204,0x25a,0x2b0,0x306,0x35c,0x3b2,0x408,0x45e,0x4b4,0x50a,0x560,0x5b6,0x60c,0x662,0x6b8,0x70e,0x764,0x7ba },
|
||||
{ 0x001,0x057,0x0ad,0x103,0x159,0x1af,0x205,0x25b,0x2b1,0x307,0x35d,0x3b3,0x409,0x45f,0x4b5,0x50b,0x561,0x5b7,0x60d,0x663,0x6b9,0x70f,0x765,0x7bb },
|
||||
{ 0x002,0x058,0x0ae,0x104,0x15a,0x1b0,0x206,0x25c,0x2b2,0x308,0x35e,0x3b4,0x40a,0x460,0x4b6,0x50c,0x562,0x5b8,0x60e,0x664,0x6ba,0x710,0x766,0x7bc },
|
||||
{ 0x003,0x059,0x0af,0x105,0x15b,0x1b1,0x207,0x25d,0x2b3,0x309,0x35f,0x3b5,0x40b,0x461,0x4b7,0x50d,0x563,0x5b9,0x60f,0x665,0x6bb,0x711,0x767,0x7bd },
|
||||
{ 0x004,0x05a,0x0b0,0x106,0x15c,0x1b2,0x208,0x25e,0x2b4,0x30a,0x360,0x3b6,0x40c,0x462,0x4b8,0x50e,0x564,0x5ba,0x610,0x666,0x6bc,0x712,0x768,0x7be },
|
||||
{ 0x005,0x05b,0x0b1,0x107,0x15d,0x1b3,0x209,0x25f,0x2b5,0x30b,0x361,0x3b7,0x40d,0x463,0x4b9,0x50f,0x565,0x5bb,0x611,0x667,0x6bd,0x713,0x769,0x7bf },
|
||||
{ 0x006,0x05c,0x0b2,0x108,0x15e,0x1b4,0x20a,0x260,0x2b6,0x30c,0x362,0x3b8,0x40e,0x464,0x4ba,0x510,0x566,0x5bc,0x612,0x668,0x6be,0x714,0x76a,0x7c0 },
|
||||
{ 0x007,0x05d,0x0b3,0x109,0x15f,0x1b5,0x20b,0x261,0x2b7,0x30d,0x363,0x3b9,0x40f,0x465,0x4bb,0x511,0x567,0x5bd,0x613,0x669,0x6bf,0x715,0x76b,0x7c1 },
|
||||
{ 0x008,0x05e,0x0b4,0x10a,0x160,0x1b6,0x20c,0x262,0x2b8,0x30e,0x364,0x3ba,0x410,0x466,0x4bc,0x512,0x568,0x5be,0x614,0x66a,0x6c0,0x716,0x76c,0x7c2 },
|
||||
{ 0x009,0x05f,0x0b5,0x10b,0x161,0x1b7,0x20d,0x263,0x2b9,0x30f,0x365,0x3bb,0x411,0x467,0x4bd,0x513,0x569,0x5bf,0x615,0x66b,0x6c1,0x717,0x76d,0x7c3 },
|
||||
{ 0x00a,0x060,0x0b6,0x10c,0x162,0x1b8,0x20e,0x264,0x2ba,0x310,0x366,0x3bc,0x412,0x468,0x4be,0x514,0x56a,0x5c0,0x616,0x66c,0x6c2,0x718,0x76e,0x7c4 },
|
||||
{ 0x00b,0x061,0x0b7,0x10d,0x163,0x1b9,0x20f,0x265,0x2bb,0x311,0x367,0x3bd,0x413,0x469,0x4bf,0x515,0x56b,0x5c1,0x617,0x66d,0x6c3,0x719,0x76f,0x7c5 },
|
||||
{ 0x00c,0x062,0x0b8,0x10e,0x164,0x1ba,0x210,0x266,0x2bc,0x312,0x368,0x3be,0x414,0x46a,0x4c0,0x516,0x56c,0x5c2,0x618,0x66e,0x6c4,0x71a,0x770,0x7c6 },
|
||||
{ 0x00d,0x063,0x0b9,0x10f,0x165,0x1bb,0x211,0x267,0x2bd,0x313,0x369,0x3bf,0x415,0x46b,0x4c1,0x517,0x56d,0x5c3,0x619,0x66f,0x6c5,0x71b,0x771,0x7c7 },
|
||||
{ 0x00e,0x064,0x0ba,0x110,0x166,0x1bc,0x212,0x268,0x2be,0x314,0x36a,0x3c0,0x416,0x46c,0x4c2,0x518,0x56e,0x5c4,0x61a,0x670,0x6c6,0x71c,0x772,0x7c8 },
|
||||
{ 0x00f,0x065,0x0bb,0x111,0x167,0x1bd,0x213,0x269,0x2bf,0x315,0x36b,0x3c1,0x417,0x46d,0x4c3,0x519,0x56f,0x5c5,0x61b,0x671,0x6c7,0x71d,0x773,0x7c9 },
|
||||
{ 0x010,0x066,0x0bc,0x112,0x168,0x1be,0x214,0x26a,0x2c0,0x316,0x36c,0x3c2,0x418,0x46e,0x4c4,0x51a,0x570,0x5c6,0x61c,0x672,0x6c8,0x71e,0x774,0x7ca },
|
||||
{ 0x011,0x067,0x0bd,0x113,0x169,0x1bf,0x215,0x26b,0x2c1,0x317,0x36d,0x3c3,0x419,0x46f,0x4c5,0x51b,0x571,0x5c7,0x61d,0x673,0x6c9,0x71f,0x775,0x7cb },
|
||||
{ 0x012,0x068,0x0be,0x114,0x16a,0x1c0,0x216,0x26c,0x2c2,0x318,0x36e,0x3c4,0x41a,0x470,0x4c6,0x51c,0x572,0x5c8,0x61e,0x674,0x6ca,0x720,0x776,0x7cc },
|
||||
{ 0x013,0x069,0x0bf,0x115,0x16b,0x1c1,0x217,0x26d,0x2c3,0x319,0x36f,0x3c5,0x41b,0x471,0x4c7,0x51d,0x573,0x5c9,0x61f,0x675,0x6cb,0x721,0x777,0x7cd },
|
||||
{ 0x014,0x06a,0x0c0,0x116,0x16c,0x1c2,0x218,0x26e,0x2c4,0x31a,0x370,0x3c6,0x41c,0x472,0x4c8,0x51e,0x574,0x5ca,0x620,0x676,0x6cc,0x722,0x778,0x7ce },
|
||||
{ 0x015,0x06b,0x0c1,0x117,0x16d,0x1c3,0x219,0x26f,0x2c5,0x31b,0x371,0x3c7,0x41d,0x473,0x4c9,0x51f,0x575,0x5cb,0x621,0x677,0x6cd,0x723,0x779,0x7cf },
|
||||
{ 0x016,0x06c,0x0c2,0x118,0x16e,0x1c4,0x21a,0x270,0x2c6,0x31c,0x372,0x3c8,0x41e,0x474,0x4ca,0x520,0x576,0x5cc,0x622,0x678,0x6ce,0x724,0x77a,0x7d0 },
|
||||
{ 0x017,0x06d,0x0c3,0x119,0x16f,0x1c5,0x21b,0x271,0x2c7,0x31d,0x373,0x3c9,0x41f,0x475,0x4cb,0x521,0x577,0x5cd,0x623,0x679,0x6cf,0x725,0x77b,0x7d1 },
|
||||
{ 0x018,0x06e,0x0c4,0x11a,0x170,0x1c6,0x21c,0x272,0x2c8,0x31e,0x374,0x3ca,0x420,0x476,0x4cc,0x522,0x578,0x5ce,0x624,0x67a,0x6d0,0x726,0x77c,0x7d2 },
|
||||
{ 0x019,0x06f,0x0c5,0x11b,0x171,0x1c7,0x21d,0x273,0x2c9,0x31f,0x375,0x3cb,0x421,0x477,0x4cd,0x523,0x579,0x5cf,0x625,0x67b,0x6d1,0x727,0x77d,0x7d3 },
|
||||
{ 0x01a,0x070,0x0c6,0x11c,0x172,0x1c8,0x21e,0x274,0x2ca,0x320,0x376,0x3cc,0x422,0x478,0x4ce,0x524,0x57a,0x5d0,0x626,0x67c,0x6d2,0x728,0x77e,0x7d4 },
|
||||
{ 0x01b,0x071,0x0c7,0x11d,0x173,0x1c9,0x21f,0x275,0x2cb,0x321,0x377,0x3cd,0x423,0x479,0x4cf,0x525,0x57b,0x5d1,0x627,0x67d,0x6d3,0x729,0x77f,0x7d5 },
|
||||
{ 0x01c,0x072,0x0c8,0x11e,0x174,0x1ca,0x220,0x276,0x2cc,0x322,0x378,0x3ce,0x424,0x47a,0x4d0,0x526,0x57c,0x5d2,0x628,0x67e,0x6d4,0x72a,0x780,0x7d6 },
|
||||
{ 0x01d,0x073,0x0c9,0x11f,0x175,0x1cb,0x221,0x277,0x2cd,0x323,0x379,0x3cf,0x425,0x47b,0x4d1,0x527,0x57d,0x5d3,0x629,0x67f,0x6d5,0x72b,0x781,0x7d7 },
|
||||
{ 0x01e,0x074,0x0ca,0x120,0x176,0x1cc,0x222,0x278,0x2ce,0x324,0x37a,0x3d0,0x426,0x47c,0x4d2,0x528,0x57e,0x5d4,0x62a,0x680,0x6d6,0x72c,0x782,0x7d8 },
|
||||
{ 0x01f,0x075,0x0cb,0x121,0x177,0x1cd,0x223,0x279,0x2cf,0x325,0x37b,0x3d1,0x427,0x47d,0x4d3,0x529,0x57f,0x5d5,0x62b,0x681,0x6d7,0x72d,0x783,0x7d9 },
|
||||
{ 0x020,0x076,0x0cc,0x122,0x178,0x1ce,0x224,0x27a,0x2d0,0x326,0x37c,0x3d2,0x428,0x47e,0x4d4,0x52a,0x580,0x5d6,0x62c,0x682,0x6d8,0x72e,0x784,0x7da },
|
||||
{ 0x021,0x077,0x0cd,0x123,0x179,0x1cf,0x225,0x27b,0x2d1,0x327,0x37d,0x3d3,0x429,0x47f,0x4d5,0x52b,0x581,0x5d7,0x62d,0x683,0x6d9,0x72f,0x785,0x7db },
|
||||
{ 0x022,0x078,0x0ce,0x124,0x17a,0x1d0,0x226,0x27c,0x2d2,0x328,0x37e,0x3d4,0x42a,0x480,0x4d6,0x52c,0x582,0x5d8,0x62e,0x684,0x6da,0x730,0x786,0x7dc },
|
||||
{ 0x023,0x079,0x0cf,0x125,0x17b,0x1d1,0x227,0x27d,0x2d3,0x329,0x37f,0x3d5,0x42b,0x481,0x4d7,0x52d,0x583,0x5d9,0x62f,0x685,0x6db,0x731,0x787,0x7dd },
|
||||
{ 0x024,0x07a,0x0d0,0x126,0x17c,0x1d2,0x228,0x27e,0x2d4,0x32a,0x380,0x3d6,0x42c,0x482,0x4d8,0x52e,0x584,0x5da,0x630,0x686,0x6dc,0x732,0x788,0x7de },
|
||||
{ 0x025,0x07b,0x0d1,0x127,0x17d,0x1d3,0x229,0x27f,0x2d5,0x32b,0x381,0x3d7,0x42d,0x483,0x4d9,0x52f,0x585,0x5db,0x631,0x687,0x6dd,0x733,0x789,0x7df },
|
||||
{ 0x026,0x07c,0x0d2,0x128,0x17e,0x1d4,0x22a,0x280,0x2d6,0x32c,0x382,0x3d8,0x42e,0x484,0x4da,0x530,0x586,0x5dc,0x632,0x688,0x6de,0x734,0x78a,0x7e0 },
|
||||
{ 0x027,0x07d,0x0d3,0x129,0x17f,0x1d5,0x22b,0x281,0x2d7,0x32d,0x383,0x3d9,0x42f,0x485,0x4db,0x531,0x587,0x5dd,0x633,0x689,0x6df,0x735,0x78b,0x7e1 },
|
||||
{ 0x028,0x07e,0x0d4,0x12a,0x180,0x1d6,0x22c,0x282,0x2d8,0x32e,0x384,0x3da,0x430,0x486,0x4dc,0x532,0x588,0x5de,0x634,0x68a,0x6e0,0x736,0x78c,0x7e2 },
|
||||
{ 0x029,0x07f,0x0d5,0x12b,0x181,0x1d7,0x22d,0x283,0x2d9,0x32f,0x385,0x3db,0x431,0x487,0x4dd,0x533,0x589,0x5df,0x635,0x68b,0x6e1,0x737,0x78d,0x7e3 },
|
||||
{ 0x02a,0x080,0x0d6,0x12c,0x182,0x1d8,0x22e,0x284,0x2da,0x330,0x386,0x3dc,0x432,0x488,0x4de,0x534,0x58a,0x5e0,0x636,0x68c,0x6e2,0x738,0x78e,0x7e4 },
|
||||
{ 0x02b,0x081,0x0d7,0x12d,0x183,0x1d9,0x22f,0x285,0x2db,0x331,0x387,0x3dd,0x433,0x489,0x4df,0x535,0x58b,0x5e1,0x637,0x68d,0x6e3,0x739,0x78f,0x7e5 },
|
||||
{ 0x02c,0x082,0x0d8,0x12e,0x184,0x1da,0x230,0x286,0x2dc,0x332,0x388,0x3de,0x434,0x48a,0x4e0,0x536,0x58c,0x5e2,0x638,0x68e,0x6e4,0x73a,0x790,0x7e6 },
|
||||
{ 0x02d,0x083,0x0d9,0x12f,0x185,0x1db,0x231,0x287,0x2dd,0x333,0x389,0x3df,0x435,0x48b,0x4e1,0x537,0x58d,0x5e3,0x639,0x68f,0x6e5,0x73b,0x791,0x7e7 },
|
||||
{ 0x02e,0x084,0x0da,0x130,0x186,0x1dc,0x232,0x288,0x2de,0x334,0x38a,0x3e0,0x436,0x48c,0x4e2,0x538,0x58e,0x5e4,0x63a,0x690,0x6e6,0x73c,0x792,0x7e8 },
|
||||
{ 0x02f,0x085,0x0db,0x131,0x187,0x1dd,0x233,0x289,0x2df,0x335,0x38b,0x3e1,0x437,0x48d,0x4e3,0x539,0x58f,0x5e5,0x63b,0x691,0x6e7,0x73d,0x793,0x7e9 },
|
||||
{ 0x030,0x086,0x0dc,0x132,0x188,0x1de,0x234,0x28a,0x2e0,0x336,0x38c,0x3e2,0x438,0x48e,0x4e4,0x53a,0x590,0x5e6,0x63c,0x692,0x6e8,0x73e,0x794,0x7ea },
|
||||
{ 0x031,0x087,0x0dd,0x133,0x189,0x1df,0x235,0x28b,0x2e1,0x337,0x38d,0x3e3,0x439,0x48f,0x4e5,0x53b,0x591,0x5e7,0x63d,0x693,0x6e9,0x73f,0x795,0x7eb },
|
||||
{ 0x032,0x088,0x0de,0x134,0x18a,0x1e0,0x236,0x28c,0x2e2,0x338,0x38e,0x3e4,0x43a,0x490,0x4e6,0x53c,0x592,0x5e8,0x63e,0x694,0x6ea,0x740,0x796,0x7ec },
|
||||
{ 0x033,0x089,0x0df,0x135,0x18b,0x1e1,0x237,0x28d,0x2e3,0x339,0x38f,0x3e5,0x43b,0x491,0x4e7,0x53d,0x593,0x5e9,0x63f,0x695,0x6eb,0x741,0x797,0x7ed },
|
||||
{ 0x034,0x08a,0x0e0,0x136,0x18c,0x1e2,0x238,0x28e,0x2e4,0x33a,0x390,0x3e6,0x43c,0x492,0x4e8,0x53e,0x594,0x5ea,0x640,0x696,0x6ec,0x742,0x798,0x7ee },
|
||||
{ 0x035,0x08b,0x0e1,0x137,0x18d,0x1e3,0x239,0x28f,0x2e5,0x33b,0x391,0x3e7,0x43d,0x493,0x4e9,0x53f,0x595,0x5eb,0x641,0x697,0x6ed,0x743,0x799,0x7ef },
|
||||
{ 0x036,0x08c,0x0e2,0x138,0x18e,0x1e4,0x23a,0x290,0x2e6,0x33c,0x392,0x3e8,0x43e,0x494,0x4ea,0x540,0x596,0x5ec,0x642,0x698,0x6ee,0x744,0x79a,0x7f0 },
|
||||
{ 0x037,0x08d,0x0e3,0x139,0x18f,0x1e5,0x23b,0x291,0x2e7,0x33d,0x393,0x3e9,0x43f,0x495,0x4eb,0x541,0x597,0x5ed,0x643,0x699,0x6ef,0x745,0x79b,0x7f1 },
|
||||
{ 0x038,0x08e,0x0e4,0x13a,0x190,0x1e6,0x23c,0x292,0x2e8,0x33e,0x394,0x3ea,0x440,0x496,0x4ec,0x542,0x598,0x5ee,0x644,0x69a,0x6f0,0x746,0x79c,0x7f2 },
|
||||
{ 0x039,0x08f,0x0e5,0x13b,0x191,0x1e7,0x23d,0x293,0x2e9,0x33f,0x395,0x3eb,0x441,0x497,0x4ed,0x543,0x599,0x5ef,0x645,0x69b,0x6f1,0x747,0x79d,0x7f3 },
|
||||
{ 0x03a,0x090,0x0e6,0x13c,0x192,0x1e8,0x23e,0x294,0x2ea,0x340,0x396,0x3ec,0x442,0x498,0x4ee,0x544,0x59a,0x5f0,0x646,0x69c,0x6f2,0x748,0x79e,0x7f4 },
|
||||
{ 0x03b,0x091,0x0e7,0x13d,0x193,0x1e9,0x23f,0x295,0x2eb,0x341,0x397,0x3ed,0x443,0x499,0x4ef,0x545,0x59b,0x5f1,0x647,0x69d,0x6f3,0x749,0x79f,0x7f5 },
|
||||
{ 0x03c,0x092,0x0e8,0x13e,0x194,0x1ea,0x240,0x296,0x2ec,0x342,0x398,0x3ee,0x444,0x49a,0x4f0,0x546,0x59c,0x5f2,0x648,0x69e,0x6f4,0x74a,0x7a0,0x7f6 },
|
||||
{ 0x03d,0x093,0x0e9,0x13f,0x195,0x1eb,0x241,0x297,0x2ed,0x343,0x399,0x3ef,0x445,0x49b,0x4f1,0x547,0x59d,0x5f3,0x649,0x69f,0x6f5,0x74b,0x7a1,0x7f7 },
|
||||
{ 0x03e,0x094,0x0ea,0x140,0x196,0x1ec,0x242,0x298,0x2ee,0x344,0x39a,0x3f0,0x446,0x49c,0x4f2,0x548,0x59e,0x5f4,0x64a,0x6a0,0x6f6,0x74c,0x7a2,0x7f8 },
|
||||
{ 0x03f,0x095,0x0eb,0x141,0x197,0x1ed,0x243,0x299,0x2ef,0x345,0x39b,0x3f1,0x447,0x49d,0x4f3,0x549,0x59f,0x5f5,0x64b,0x6a1,0x6f7,0x74d,0x7a3,0x7f9 },
|
||||
{ 0x040,0x096,0x0ec,0x142,0x198,0x1ee,0x244,0x29a,0x2f0,0x346,0x39c,0x3f2,0x448,0x49e,0x4f4,0x54a,0x5a0,0x5f6,0x64c,0x6a2,0x6f8,0x74e,0x7a4,0x7fa },
|
||||
{ 0x041,0x097,0x0ed,0x143,0x199,0x1ef,0x245,0x29b,0x2f1,0x347,0x39d,0x3f3,0x449,0x49f,0x4f5,0x54b,0x5a1,0x5f7,0x64d,0x6a3,0x6f9,0x74f,0x7a5,0x7fb },
|
||||
{ 0x042,0x098,0x0ee,0x144,0x19a,0x1f0,0x246,0x29c,0x2f2,0x348,0x39e,0x3f4,0x44a,0x4a0,0x4f6,0x54c,0x5a2,0x5f8,0x64e,0x6a4,0x6fa,0x750,0x7a6,0x7fc },
|
||||
{ 0x043,0x099,0x0ef,0x145,0x19b,0x1f1,0x247,0x29d,0x2f3,0x349,0x39f,0x3f5,0x44b,0x4a1,0x4f7,0x54d,0x5a3,0x5f9,0x64f,0x6a5,0x6fb,0x751,0x7a7,0x7fd },
|
||||
{ 0x044,0x09a,0x0f0,0x146,0x19c,0x1f2,0x248,0x29e,0x2f4,0x34a,0x3a0,0x3f6,0x44c,0x4a2,0x4f8,0x54e,0x5a4,0x5fa,0x650,0x6a6,0x6fc,0x752,0x7a8,0x7fe },
|
||||
{ 0x045,0x09b,0x0f1,0x147,0x19d,0x1f3,0x249,0x29f,0x2f5,0x34b,0x3a1,0x3f7,0x44d,0x4a3,0x4f9,0x54f,0x5a5,0x5fb,0x651,0x6a7,0x6fd,0x753,0x7a9,0x7ff },
|
||||
{ 0x046,0x09c,0x0f2,0x148,0x19e,0x1f4,0x24a,0x2a0,0x2f6,0x34c,0x3a2,0x3f8,0x44e,0x4a4,0x4fa,0x550,0x5a6,0x5fc,0x652,0x6a8,0x6fe,0x754,0x7aa,0x800 },
|
||||
{ 0x047,0x09d,0x0f3,0x149,0x19f,0x1f5,0x24b,0x2a1,0x2f7,0x34d,0x3a3,0x3f9,0x44f,0x4a5,0x4fb,0x551,0x5a7,0x5fd,0x653,0x6a9,0x6ff,0x755,0x7ab,0x801 },
|
||||
{ 0x048,0x09e,0x0f4,0x14a,0x1a0,0x1f6,0x24c,0x2a2,0x2f8,0x34e,0x3a4,0x3fa,0x450,0x4a6,0x4fc,0x552,0x5a8,0x5fe,0x654,0x6aa,0x700,0x756,0x7ac,0x802 },
|
||||
{ 0x049,0x09f,0x0f5,0x14b,0x1a1,0x1f7,0x24d,0x2a3,0x2f9,0x34f,0x3a5,0x3fb,0x451,0x4a7,0x4fd,0x553,0x5a9,0x5ff,0x655,0x6ab,0x701,0x757,0x7ad,0x803 },
|
||||
{ 0x04a,0x0a0,0x0f6,0x14c,0x1a2,0x1f8,0x24e,0x2a4,0x2fa,0x350,0x3a6,0x3fc,0x452,0x4a8,0x4fe,0x554,0x5aa,0x600,0x656,0x6ac,0x702,0x758,0x7ae,0x804 },
|
||||
{ 0x04b,0x0a1,0x0f7,0x14d,0x1a3,0x1f9,0x24f,0x2a5,0x2fb,0x351,0x3a7,0x3fd,0x453,0x4a9,0x4ff,0x555,0x5ab,0x601,0x657,0x6ad,0x703,0x759,0x7af,0x805 },
|
||||
{ 0x04c,0x0a2,0x0f8,0x14e,0x1a4,0x1fa,0x250,0x2a6,0x2fc,0x352,0x3a8,0x3fe,0x454,0x4aa,0x500,0x556,0x5ac,0x602,0x658,0x6ae,0x704,0x75a,0x7b0,0x806 },
|
||||
{ 0x04d,0x0a3,0x0f9,0x14f,0x1a5,0x1fb,0x251,0x2a7,0x2fd,0x353,0x3a9,0x3ff,0x455,0x4ab,0x501,0x557,0x5ad,0x603,0x659,0x6af,0x705,0x75b,0x7b1,0x807 },
|
||||
{ 0x04e,0x0a4,0x0fa,0x150,0x1a6,0x1fc,0x252,0x2a8,0x2fe,0x354,0x3aa,0x400,0x456,0x4ac,0x502,0x558,0x5ae,0x604,0x65a,0x6b0,0x706,0x75c,0x7b2,0x808 },
|
||||
{ 0x04f,0x0a5,0x0fb,0x151,0x1a7,0x1fd,0x253,0x2a9,0x2ff,0x355,0x3ab,0x401,0x457,0x4ad,0x503,0x559,0x5af,0x605,0x65b,0x6b1,0x707,0x75d,0x7b3,0x809 },
|
||||
{ 0x050,0x0a6,0x0fc,0x152,0x1a8,0x1fe,0x254,0x2aa,0x300,0x356,0x3ac,0x402,0x458,0x4ae,0x504,0x55a,0x5b0,0x606,0x65c,0x6b2,0x708,0x75e,0x7b4,0x80a },
|
||||
{ 0x051,0x0a7,0x0fd,0x153,0x1a9,0x1ff,0x255,0x2ab,0x301,0x357,0x3ad,0x403,0x459,0x4af,0x505,0x55b,0x5b1,0x607,0x65d,0x6b3,0x709,0x75f,0x7b5,0x80b },
|
||||
{ 0x052,0x0a8,0x0fe,0x154,0x1aa,0x200,0x256,0x2ac,0x302,0x358,0x3ae,0x404,0x45a,0x4b0,0x506,0x55c,0x5b2,0x608,0x65e,0x6b4,0x70a,0x760,0x7b6,0x80c },
|
||||
{ 0x053,0x0a9,0x0ff,0x155,0x1ab,0x201,0x257,0x2ad,0x303,0x359,0x3af,0x405,0x45b,0x4b1,0x507,0x55d,0x5b3,0x609,0x65f,0x6b5,0x70b,0x761,0x7b7,0x80d },
|
||||
{ 0x054,0x0aa,0x100,0x156,0x1ac,0x202,0x258,0x2ae,0x304,0x35a,0x3b0,0x406,0x45c,0x4b2,0x508,0x55e,0x5b4,0x60a,0x660,0x6b6,0x70c,0x762,0x7b8,0x80e },
|
||||
{ 0x055,0x0ab,0x101,0x157,0x1ad,0x203,0x259,0x2af,0x305,0x35b,0x3b1,0x407,0x45d,0x4b3,0x509,0x55f,0x5b5,0x60b,0x661,0x6b7,0x70d,0x763,0x7b9,0x80f }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief -------------------------------------------------
|
||||
* qoffsets - each row represents the addresses used to calculate a byte of the ECC Q
|
||||
* data 52 (*2) ECC Q bytes, 43 values represented by each
|
||||
* -------------------------------------------------.
|
||||
*/
|
||||
|
||||
static const uint16_t qoffsets[ECC_Q_NUM_BYTES][ECC_Q_COMP] =
|
||||
{
|
||||
{ 0x000,0x058,0x0b0,0x108,0x160,0x1b8,0x210,0x268,0x2c0,0x318,0x370,0x3c8,0x420,0x478,0x4d0,0x528,0x580,0x5d8,0x630,0x688,0x6e0,0x738,0x790,0x7e8,0x840,0x898,0x034,0x08c,0x0e4,0x13c,0x194,0x1ec,0x244,0x29c,0x2f4,0x34c,0x3a4,0x3fc,0x454,0x4ac,0x504,0x55c,0x5b4 },
|
||||
{ 0x001,0x059,0x0b1,0x109,0x161,0x1b9,0x211,0x269,0x2c1,0x319,0x371,0x3c9,0x421,0x479,0x4d1,0x529,0x581,0x5d9,0x631,0x689,0x6e1,0x739,0x791,0x7e9,0x841,0x899,0x035,0x08d,0x0e5,0x13d,0x195,0x1ed,0x245,0x29d,0x2f5,0x34d,0x3a5,0x3fd,0x455,0x4ad,0x505,0x55d,0x5b5 },
|
||||
{ 0x056,0x0ae,0x106,0x15e,0x1b6,0x20e,0x266,0x2be,0x316,0x36e,0x3c6,0x41e,0x476,0x4ce,0x526,0x57e,0x5d6,0x62e,0x686,0x6de,0x736,0x78e,0x7e6,0x83e,0x896,0x032,0x08a,0x0e2,0x13a,0x192,0x1ea,0x242,0x29a,0x2f2,0x34a,0x3a2,0x3fa,0x452,0x4aa,0x502,0x55a,0x5b2,0x60a },
|
||||
{ 0x057,0x0af,0x107,0x15f,0x1b7,0x20f,0x267,0x2bf,0x317,0x36f,0x3c7,0x41f,0x477,0x4cf,0x527,0x57f,0x5d7,0x62f,0x687,0x6df,0x737,0x78f,0x7e7,0x83f,0x897,0x033,0x08b,0x0e3,0x13b,0x193,0x1eb,0x243,0x29b,0x2f3,0x34b,0x3a3,0x3fb,0x453,0x4ab,0x503,0x55b,0x5b3,0x60b },
|
||||
{ 0x0ac,0x104,0x15c,0x1b4,0x20c,0x264,0x2bc,0x314,0x36c,0x3c4,0x41c,0x474,0x4cc,0x524,0x57c,0x5d4,0x62c,0x684,0x6dc,0x734,0x78c,0x7e4,0x83c,0x894,0x030,0x088,0x0e0,0x138,0x190,0x1e8,0x240,0x298,0x2f0,0x348,0x3a0,0x3f8,0x450,0x4a8,0x500,0x558,0x5b0,0x608,0x660 },
|
||||
{ 0x0ad,0x105,0x15d,0x1b5,0x20d,0x265,0x2bd,0x315,0x36d,0x3c5,0x41d,0x475,0x4cd,0x525,0x57d,0x5d5,0x62d,0x685,0x6dd,0x735,0x78d,0x7e5,0x83d,0x895,0x031,0x089,0x0e1,0x139,0x191,0x1e9,0x241,0x299,0x2f1,0x349,0x3a1,0x3f9,0x451,0x4a9,0x501,0x559,0x5b1,0x609,0x661 },
|
||||
{ 0x102,0x15a,0x1b2,0x20a,0x262,0x2ba,0x312,0x36a,0x3c2,0x41a,0x472,0x4ca,0x522,0x57a,0x5d2,0x62a,0x682,0x6da,0x732,0x78a,0x7e2,0x83a,0x892,0x02e,0x086,0x0de,0x136,0x18e,0x1e6,0x23e,0x296,0x2ee,0x346,0x39e,0x3f6,0x44e,0x4a6,0x4fe,0x556,0x5ae,0x606,0x65e,0x6b6 },
|
||||
{ 0x103,0x15b,0x1b3,0x20b,0x263,0x2bb,0x313,0x36b,0x3c3,0x41b,0x473,0x4cb,0x523,0x57b,0x5d3,0x62b,0x683,0x6db,0x733,0x78b,0x7e3,0x83b,0x893,0x02f,0x087,0x0df,0x137,0x18f,0x1e7,0x23f,0x297,0x2ef,0x347,0x39f,0x3f7,0x44f,0x4a7,0x4ff,0x557,0x5af,0x607,0x65f,0x6b7 },
|
||||
{ 0x158,0x1b0,0x208,0x260,0x2b8,0x310,0x368,0x3c0,0x418,0x470,0x4c8,0x520,0x578,0x5d0,0x628,0x680,0x6d8,0x730,0x788,0x7e0,0x838,0x890,0x02c,0x084,0x0dc,0x134,0x18c,0x1e4,0x23c,0x294,0x2ec,0x344,0x39c,0x3f4,0x44c,0x4a4,0x4fc,0x554,0x5ac,0x604,0x65c,0x6b4,0x70c },
|
||||
{ 0x159,0x1b1,0x209,0x261,0x2b9,0x311,0x369,0x3c1,0x419,0x471,0x4c9,0x521,0x579,0x5d1,0x629,0x681,0x6d9,0x731,0x789,0x7e1,0x839,0x891,0x02d,0x085,0x0dd,0x135,0x18d,0x1e5,0x23d,0x295,0x2ed,0x345,0x39d,0x3f5,0x44d,0x4a5,0x4fd,0x555,0x5ad,0x605,0x65d,0x6b5,0x70d },
|
||||
{ 0x1ae,0x206,0x25e,0x2b6,0x30e,0x366,0x3be,0x416,0x46e,0x4c6,0x51e,0x576,0x5ce,0x626,0x67e,0x6d6,0x72e,0x786,0x7de,0x836,0x88e,0x02a,0x082,0x0da,0x132,0x18a,0x1e2,0x23a,0x292,0x2ea,0x342,0x39a,0x3f2,0x44a,0x4a2,0x4fa,0x552,0x5aa,0x602,0x65a,0x6b2,0x70a,0x762 },
|
||||
{ 0x1af,0x207,0x25f,0x2b7,0x30f,0x367,0x3bf,0x417,0x46f,0x4c7,0x51f,0x577,0x5cf,0x627,0x67f,0x6d7,0x72f,0x787,0x7df,0x837,0x88f,0x02b,0x083,0x0db,0x133,0x18b,0x1e3,0x23b,0x293,0x2eb,0x343,0x39b,0x3f3,0x44b,0x4a3,0x4fb,0x553,0x5ab,0x603,0x65b,0x6b3,0x70b,0x763 },
|
||||
{ 0x204,0x25c,0x2b4,0x30c,0x364,0x3bc,0x414,0x46c,0x4c4,0x51c,0x574,0x5cc,0x624,0x67c,0x6d4,0x72c,0x784,0x7dc,0x834,0x88c,0x028,0x080,0x0d8,0x130,0x188,0x1e0,0x238,0x290,0x2e8,0x340,0x398,0x3f0,0x448,0x4a0,0x4f8,0x550,0x5a8,0x600,0x658,0x6b0,0x708,0x760,0x7b8 },
|
||||
{ 0x205,0x25d,0x2b5,0x30d,0x365,0x3bd,0x415,0x46d,0x4c5,0x51d,0x575,0x5cd,0x625,0x67d,0x6d5,0x72d,0x785,0x7dd,0x835,0x88d,0x029,0x081,0x0d9,0x131,0x189,0x1e1,0x239,0x291,0x2e9,0x341,0x399,0x3f1,0x449,0x4a1,0x4f9,0x551,0x5a9,0x601,0x659,0x6b1,0x709,0x761,0x7b9 },
|
||||
{ 0x25a,0x2b2,0x30a,0x362,0x3ba,0x412,0x46a,0x4c2,0x51a,0x572,0x5ca,0x622,0x67a,0x6d2,0x72a,0x782,0x7da,0x832,0x88a,0x026,0x07e,0x0d6,0x12e,0x186,0x1de,0x236,0x28e,0x2e6,0x33e,0x396,0x3ee,0x446,0x49e,0x4f6,0x54e,0x5a6,0x5fe,0x656,0x6ae,0x706,0x75e,0x7b6,0x80e },
|
||||
{ 0x25b,0x2b3,0x30b,0x363,0x3bb,0x413,0x46b,0x4c3,0x51b,0x573,0x5cb,0x623,0x67b,0x6d3,0x72b,0x783,0x7db,0x833,0x88b,0x027,0x07f,0x0d7,0x12f,0x187,0x1df,0x237,0x28f,0x2e7,0x33f,0x397,0x3ef,0x447,0x49f,0x4f7,0x54f,0x5a7,0x5ff,0x657,0x6af,0x707,0x75f,0x7b7,0x80f },
|
||||
{ 0x2b0,0x308,0x360,0x3b8,0x410,0x468,0x4c0,0x518,0x570,0x5c8,0x620,0x678,0x6d0,0x728,0x780,0x7d8,0x830,0x888,0x024,0x07c,0x0d4,0x12c,0x184,0x1dc,0x234,0x28c,0x2e4,0x33c,0x394,0x3ec,0x444,0x49c,0x4f4,0x54c,0x5a4,0x5fc,0x654,0x6ac,0x704,0x75c,0x7b4,0x80c,0x864 },
|
||||
{ 0x2b1,0x309,0x361,0x3b9,0x411,0x469,0x4c1,0x519,0x571,0x5c9,0x621,0x679,0x6d1,0x729,0x781,0x7d9,0x831,0x889,0x025,0x07d,0x0d5,0x12d,0x185,0x1dd,0x235,0x28d,0x2e5,0x33d,0x395,0x3ed,0x445,0x49d,0x4f5,0x54d,0x5a5,0x5fd,0x655,0x6ad,0x705,0x75d,0x7b5,0x80d,0x865 },
|
||||
{ 0x306,0x35e,0x3b6,0x40e,0x466,0x4be,0x516,0x56e,0x5c6,0x61e,0x676,0x6ce,0x726,0x77e,0x7d6,0x82e,0x886,0x022,0x07a,0x0d2,0x12a,0x182,0x1da,0x232,0x28a,0x2e2,0x33a,0x392,0x3ea,0x442,0x49a,0x4f2,0x54a,0x5a2,0x5fa,0x652,0x6aa,0x702,0x75a,0x7b2,0x80a,0x862,0x8ba },
|
||||
{ 0x307,0x35f,0x3b7,0x40f,0x467,0x4bf,0x517,0x56f,0x5c7,0x61f,0x677,0x6cf,0x727,0x77f,0x7d7,0x82f,0x887,0x023,0x07b,0x0d3,0x12b,0x183,0x1db,0x233,0x28b,0x2e3,0x33b,0x393,0x3eb,0x443,0x49b,0x4f3,0x54b,0x5a3,0x5fb,0x653,0x6ab,0x703,0x75b,0x7b3,0x80b,0x863,0x8bb },
|
||||
{ 0x35c,0x3b4,0x40c,0x464,0x4bc,0x514,0x56c,0x5c4,0x61c,0x674,0x6cc,0x724,0x77c,0x7d4,0x82c,0x884,0x020,0x078,0x0d0,0x128,0x180,0x1d8,0x230,0x288,0x2e0,0x338,0x390,0x3e8,0x440,0x498,0x4f0,0x548,0x5a0,0x5f8,0x650,0x6a8,0x700,0x758,0x7b0,0x808,0x860,0x8b8,0x054 },
|
||||
{ 0x35d,0x3b5,0x40d,0x465,0x4bd,0x515,0x56d,0x5c5,0x61d,0x675,0x6cd,0x725,0x77d,0x7d5,0x82d,0x885,0x021,0x079,0x0d1,0x129,0x181,0x1d9,0x231,0x289,0x2e1,0x339,0x391,0x3e9,0x441,0x499,0x4f1,0x549,0x5a1,0x5f9,0x651,0x6a9,0x701,0x759,0x7b1,0x809,0x861,0x8b9,0x055 },
|
||||
{ 0x3b2,0x40a,0x462,0x4ba,0x512,0x56a,0x5c2,0x61a,0x672,0x6ca,0x722,0x77a,0x7d2,0x82a,0x882,0x01e,0x076,0x0ce,0x126,0x17e,0x1d6,0x22e,0x286,0x2de,0x336,0x38e,0x3e6,0x43e,0x496,0x4ee,0x546,0x59e,0x5f6,0x64e,0x6a6,0x6fe,0x756,0x7ae,0x806,0x85e,0x8b6,0x052,0x0aa },
|
||||
{ 0x3b3,0x40b,0x463,0x4bb,0x513,0x56b,0x5c3,0x61b,0x673,0x6cb,0x723,0x77b,0x7d3,0x82b,0x883,0x01f,0x077,0x0cf,0x127,0x17f,0x1d7,0x22f,0x287,0x2df,0x337,0x38f,0x3e7,0x43f,0x497,0x4ef,0x547,0x59f,0x5f7,0x64f,0x6a7,0x6ff,0x757,0x7af,0x807,0x85f,0x8b7,0x053,0x0ab },
|
||||
{ 0x408,0x460,0x4b8,0x510,0x568,0x5c0,0x618,0x670,0x6c8,0x720,0x778,0x7d0,0x828,0x880,0x01c,0x074,0x0cc,0x124,0x17c,0x1d4,0x22c,0x284,0x2dc,0x334,0x38c,0x3e4,0x43c,0x494,0x4ec,0x544,0x59c,0x5f4,0x64c,0x6a4,0x6fc,0x754,0x7ac,0x804,0x85c,0x8b4,0x050,0x0a8,0x100 },
|
||||
{ 0x409,0x461,0x4b9,0x511,0x569,0x5c1,0x619,0x671,0x6c9,0x721,0x779,0x7d1,0x829,0x881,0x01d,0x075,0x0cd,0x125,0x17d,0x1d5,0x22d,0x285,0x2dd,0x335,0x38d,0x3e5,0x43d,0x495,0x4ed,0x545,0x59d,0x5f5,0x64d,0x6a5,0x6fd,0x755,0x7ad,0x805,0x85d,0x8b5,0x051,0x0a9,0x101 },
|
||||
{ 0x45e,0x4b6,0x50e,0x566,0x5be,0x616,0x66e,0x6c6,0x71e,0x776,0x7ce,0x826,0x87e,0x01a,0x072,0x0ca,0x122,0x17a,0x1d2,0x22a,0x282,0x2da,0x332,0x38a,0x3e2,0x43a,0x492,0x4ea,0x542,0x59a,0x5f2,0x64a,0x6a2,0x6fa,0x752,0x7aa,0x802,0x85a,0x8b2,0x04e,0x0a6,0x0fe,0x156 },
|
||||
{ 0x45f,0x4b7,0x50f,0x567,0x5bf,0x617,0x66f,0x6c7,0x71f,0x777,0x7cf,0x827,0x87f,0x01b,0x073,0x0cb,0x123,0x17b,0x1d3,0x22b,0x283,0x2db,0x333,0x38b,0x3e3,0x43b,0x493,0x4eb,0x543,0x59b,0x5f3,0x64b,0x6a3,0x6fb,0x753,0x7ab,0x803,0x85b,0x8b3,0x04f,0x0a7,0x0ff,0x157 },
|
||||
{ 0x4b4,0x50c,0x564,0x5bc,0x614,0x66c,0x6c4,0x71c,0x774,0x7cc,0x824,0x87c,0x018,0x070,0x0c8,0x120,0x178,0x1d0,0x228,0x280,0x2d8,0x330,0x388,0x3e0,0x438,0x490,0x4e8,0x540,0x598,0x5f0,0x648,0x6a0,0x6f8,0x750,0x7a8,0x800,0x858,0x8b0,0x04c,0x0a4,0x0fc,0x154,0x1ac },
|
||||
{ 0x4b5,0x50d,0x565,0x5bd,0x615,0x66d,0x6c5,0x71d,0x775,0x7cd,0x825,0x87d,0x019,0x071,0x0c9,0x121,0x179,0x1d1,0x229,0x281,0x2d9,0x331,0x389,0x3e1,0x439,0x491,0x4e9,0x541,0x599,0x5f1,0x649,0x6a1,0x6f9,0x751,0x7a9,0x801,0x859,0x8b1,0x04d,0x0a5,0x0fd,0x155,0x1ad },
|
||||
{ 0x50a,0x562,0x5ba,0x612,0x66a,0x6c2,0x71a,0x772,0x7ca,0x822,0x87a,0x016,0x06e,0x0c6,0x11e,0x176,0x1ce,0x226,0x27e,0x2d6,0x32e,0x386,0x3de,0x436,0x48e,0x4e6,0x53e,0x596,0x5ee,0x646,0x69e,0x6f6,0x74e,0x7a6,0x7fe,0x856,0x8ae,0x04a,0x0a2,0x0fa,0x152,0x1aa,0x202 },
|
||||
{ 0x50b,0x563,0x5bb,0x613,0x66b,0x6c3,0x71b,0x773,0x7cb,0x823,0x87b,0x017,0x06f,0x0c7,0x11f,0x177,0x1cf,0x227,0x27f,0x2d7,0x32f,0x387,0x3df,0x437,0x48f,0x4e7,0x53f,0x597,0x5ef,0x647,0x69f,0x6f7,0x74f,0x7a7,0x7ff,0x857,0x8af,0x04b,0x0a3,0x0fb,0x153,0x1ab,0x203 },
|
||||
{ 0x560,0x5b8,0x610,0x668,0x6c0,0x718,0x770,0x7c8,0x820,0x878,0x014,0x06c,0x0c4,0x11c,0x174,0x1cc,0x224,0x27c,0x2d4,0x32c,0x384,0x3dc,0x434,0x48c,0x4e4,0x53c,0x594,0x5ec,0x644,0x69c,0x6f4,0x74c,0x7a4,0x7fc,0x854,0x8ac,0x048,0x0a0,0x0f8,0x150,0x1a8,0x200,0x258 },
|
||||
{ 0x561,0x5b9,0x611,0x669,0x6c1,0x719,0x771,0x7c9,0x821,0x879,0x015,0x06d,0x0c5,0x11d,0x175,0x1cd,0x225,0x27d,0x2d5,0x32d,0x385,0x3dd,0x435,0x48d,0x4e5,0x53d,0x595,0x5ed,0x645,0x69d,0x6f5,0x74d,0x7a5,0x7fd,0x855,0x8ad,0x049,0x0a1,0x0f9,0x151,0x1a9,0x201,0x259 },
|
||||
{ 0x5b6,0x60e,0x666,0x6be,0x716,0x76e,0x7c6,0x81e,0x876,0x012,0x06a,0x0c2,0x11a,0x172,0x1ca,0x222,0x27a,0x2d2,0x32a,0x382,0x3da,0x432,0x48a,0x4e2,0x53a,0x592,0x5ea,0x642,0x69a,0x6f2,0x74a,0x7a2,0x7fa,0x852,0x8aa,0x046,0x09e,0x0f6,0x14e,0x1a6,0x1fe,0x256,0x2ae },
|
||||
{ 0x5b7,0x60f,0x667,0x6bf,0x717,0x76f,0x7c7,0x81f,0x877,0x013,0x06b,0x0c3,0x11b,0x173,0x1cb,0x223,0x27b,0x2d3,0x32b,0x383,0x3db,0x433,0x48b,0x4e3,0x53b,0x593,0x5eb,0x643,0x69b,0x6f3,0x74b,0x7a3,0x7fb,0x853,0x8ab,0x047,0x09f,0x0f7,0x14f,0x1a7,0x1ff,0x257,0x2af },
|
||||
{ 0x60c,0x664,0x6bc,0x714,0x76c,0x7c4,0x81c,0x874,0x010,0x068,0x0c0,0x118,0x170,0x1c8,0x220,0x278,0x2d0,0x328,0x380,0x3d8,0x430,0x488,0x4e0,0x538,0x590,0x5e8,0x640,0x698,0x6f0,0x748,0x7a0,0x7f8,0x850,0x8a8,0x044,0x09c,0x0f4,0x14c,0x1a4,0x1fc,0x254,0x2ac,0x304 },
|
||||
{ 0x60d,0x665,0x6bd,0x715,0x76d,0x7c5,0x81d,0x875,0x011,0x069,0x0c1,0x119,0x171,0x1c9,0x221,0x279,0x2d1,0x329,0x381,0x3d9,0x431,0x489,0x4e1,0x539,0x591,0x5e9,0x641,0x699,0x6f1,0x749,0x7a1,0x7f9,0x851,0x8a9,0x045,0x09d,0x0f5,0x14d,0x1a5,0x1fd,0x255,0x2ad,0x305 },
|
||||
{ 0x662,0x6ba,0x712,0x76a,0x7c2,0x81a,0x872,0x00e,0x066,0x0be,0x116,0x16e,0x1c6,0x21e,0x276,0x2ce,0x326,0x37e,0x3d6,0x42e,0x486,0x4de,0x536,0x58e,0x5e6,0x63e,0x696,0x6ee,0x746,0x79e,0x7f6,0x84e,0x8a6,0x042,0x09a,0x0f2,0x14a,0x1a2,0x1fa,0x252,0x2aa,0x302,0x35a },
|
||||
{ 0x663,0x6bb,0x713,0x76b,0x7c3,0x81b,0x873,0x00f,0x067,0x0bf,0x117,0x16f,0x1c7,0x21f,0x277,0x2cf,0x327,0x37f,0x3d7,0x42f,0x487,0x4df,0x537,0x58f,0x5e7,0x63f,0x697,0x6ef,0x747,0x79f,0x7f7,0x84f,0x8a7,0x043,0x09b,0x0f3,0x14b,0x1a3,0x1fb,0x253,0x2ab,0x303,0x35b },
|
||||
{ 0x6b8,0x710,0x768,0x7c0,0x818,0x870,0x00c,0x064,0x0bc,0x114,0x16c,0x1c4,0x21c,0x274,0x2cc,0x324,0x37c,0x3d4,0x42c,0x484,0x4dc,0x534,0x58c,0x5e4,0x63c,0x694,0x6ec,0x744,0x79c,0x7f4,0x84c,0x8a4,0x040,0x098,0x0f0,0x148,0x1a0,0x1f8,0x250,0x2a8,0x300,0x358,0x3b0 },
|
||||
{ 0x6b9,0x711,0x769,0x7c1,0x819,0x871,0x00d,0x065,0x0bd,0x115,0x16d,0x1c5,0x21d,0x275,0x2cd,0x325,0x37d,0x3d5,0x42d,0x485,0x4dd,0x535,0x58d,0x5e5,0x63d,0x695,0x6ed,0x745,0x79d,0x7f5,0x84d,0x8a5,0x041,0x099,0x0f1,0x149,0x1a1,0x1f9,0x251,0x2a9,0x301,0x359,0x3b1 },
|
||||
{ 0x70e,0x766,0x7be,0x816,0x86e,0x00a,0x062,0x0ba,0x112,0x16a,0x1c2,0x21a,0x272,0x2ca,0x322,0x37a,0x3d2,0x42a,0x482,0x4da,0x532,0x58a,0x5e2,0x63a,0x692,0x6ea,0x742,0x79a,0x7f2,0x84a,0x8a2,0x03e,0x096,0x0ee,0x146,0x19e,0x1f6,0x24e,0x2a6,0x2fe,0x356,0x3ae,0x406 },
|
||||
{ 0x70f,0x767,0x7bf,0x817,0x86f,0x00b,0x063,0x0bb,0x113,0x16b,0x1c3,0x21b,0x273,0x2cb,0x323,0x37b,0x3d3,0x42b,0x483,0x4db,0x533,0x58b,0x5e3,0x63b,0x693,0x6eb,0x743,0x79b,0x7f3,0x84b,0x8a3,0x03f,0x097,0x0ef,0x147,0x19f,0x1f7,0x24f,0x2a7,0x2ff,0x357,0x3af,0x407 },
|
||||
{ 0x764,0x7bc,0x814,0x86c,0x008,0x060,0x0b8,0x110,0x168,0x1c0,0x218,0x270,0x2c8,0x320,0x378,0x3d0,0x428,0x480,0x4d8,0x530,0x588,0x5e0,0x638,0x690,0x6e8,0x740,0x798,0x7f0,0x848,0x8a0,0x03c,0x094,0x0ec,0x144,0x19c,0x1f4,0x24c,0x2a4,0x2fc,0x354,0x3ac,0x404,0x45c },
|
||||
{ 0x765,0x7bd,0x815,0x86d,0x009,0x061,0x0b9,0x111,0x169,0x1c1,0x219,0x271,0x2c9,0x321,0x379,0x3d1,0x429,0x481,0x4d9,0x531,0x589,0x5e1,0x639,0x691,0x6e9,0x741,0x799,0x7f1,0x849,0x8a1,0x03d,0x095,0x0ed,0x145,0x19d,0x1f5,0x24d,0x2a5,0x2fd,0x355,0x3ad,0x405,0x45d },
|
||||
{ 0x7ba,0x812,0x86a,0x006,0x05e,0x0b6,0x10e,0x166,0x1be,0x216,0x26e,0x2c6,0x31e,0x376,0x3ce,0x426,0x47e,0x4d6,0x52e,0x586,0x5de,0x636,0x68e,0x6e6,0x73e,0x796,0x7ee,0x846,0x89e,0x03a,0x092,0x0ea,0x142,0x19a,0x1f2,0x24a,0x2a2,0x2fa,0x352,0x3aa,0x402,0x45a,0x4b2 },
|
||||
{ 0x7bb,0x813,0x86b,0x007,0x05f,0x0b7,0x10f,0x167,0x1bf,0x217,0x26f,0x2c7,0x31f,0x377,0x3cf,0x427,0x47f,0x4d7,0x52f,0x587,0x5df,0x637,0x68f,0x6e7,0x73f,0x797,0x7ef,0x847,0x89f,0x03b,0x093,0x0eb,0x143,0x19b,0x1f3,0x24b,0x2a3,0x2fb,0x353,0x3ab,0x403,0x45b,0x4b3 },
|
||||
{ 0x810,0x868,0x004,0x05c,0x0b4,0x10c,0x164,0x1bc,0x214,0x26c,0x2c4,0x31c,0x374,0x3cc,0x424,0x47c,0x4d4,0x52c,0x584,0x5dc,0x634,0x68c,0x6e4,0x73c,0x794,0x7ec,0x844,0x89c,0x038,0x090,0x0e8,0x140,0x198,0x1f0,0x248,0x2a0,0x2f8,0x350,0x3a8,0x400,0x458,0x4b0,0x508 },
|
||||
{ 0x811,0x869,0x005,0x05d,0x0b5,0x10d,0x165,0x1bd,0x215,0x26d,0x2c5,0x31d,0x375,0x3cd,0x425,0x47d,0x4d5,0x52d,0x585,0x5dd,0x635,0x68d,0x6e5,0x73d,0x795,0x7ed,0x845,0x89d,0x039,0x091,0x0e9,0x141,0x199,0x1f1,0x249,0x2a1,0x2f9,0x351,0x3a9,0x401,0x459,0x4b1,0x509 },
|
||||
{ 0x866,0x002,0x05a,0x0b2,0x10a,0x162,0x1ba,0x212,0x26a,0x2c2,0x31a,0x372,0x3ca,0x422,0x47a,0x4d2,0x52a,0x582,0x5da,0x632,0x68a,0x6e2,0x73a,0x792,0x7ea,0x842,0x89a,0x036,0x08e,0x0e6,0x13e,0x196,0x1ee,0x246,0x29e,0x2f6,0x34e,0x3a6,0x3fe,0x456,0x4ae,0x506,0x55e },
|
||||
{ 0x867,0x003,0x05b,0x0b3,0x10b,0x163,0x1bb,0x213,0x26b,0x2c3,0x31b,0x373,0x3cb,0x423,0x47b,0x4d3,0x52b,0x583,0x5db,0x633,0x68b,0x6e3,0x73b,0x793,0x7eb,0x843,0x89b,0x037,0x08f,0x0e7,0x13f,0x197,0x1ef,0x247,0x29f,0x2f7,0x34f,0x3a7,0x3ff,0x457,0x4af,0x507,0x55f }
|
||||
};
|
||||
|
||||
/*-------------------------------------------------
|
||||
* ecc_source_byte - return data from the sector
|
||||
* at the given offset, masking anything
|
||||
* particular to a mode
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline uint8_t ecc_source_byte(const uint8_t *sector, uint32_t offset)
|
||||
{
|
||||
/* in mode 2 always treat these as 0 bytes */
|
||||
return (sector[MODE_OFFSET] == 2 && offset < 4) ? 0x00 : sector[SYNC_OFFSET + SYNC_NUM_BYTES + offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t &val1, uint8_t &val2)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_compute_bytes - calculate an ECC value (P or Q)
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param sector The sector.
|
||||
* @param row The row.
|
||||
* @param rowlen The rowlen.
|
||||
* @param [in,out] val1 The first value.
|
||||
* @param [in,out] val2 The second value.
|
||||
*/
|
||||
|
||||
void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t *val1, uint8_t *val2)
|
||||
{
|
||||
int component;
|
||||
*val1 = *val2 = 0;
|
||||
for (component = 0; component < rowlen; component++)
|
||||
{
|
||||
*val1 ^= ecc_source_byte(sector, row[component]);
|
||||
*val2 ^= ecc_source_byte(sector, row[component]);
|
||||
*val1 = ecclow[*val1];
|
||||
}
|
||||
*val1 = ecchigh[ecclow[*val1] ^ *val2];
|
||||
*val2 ^= *val1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn int ecc_verify(const uint8_t *sector)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_verify - verify the P and Q ECC codes in a sector
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param sector The sector.
|
||||
*
|
||||
* @return true if it succeeds, false if it fails.
|
||||
*/
|
||||
|
||||
int ecc_verify(const uint8_t *sector)
|
||||
{
|
||||
int byte;
|
||||
/* first verify P bytes */
|
||||
for (byte = 0; byte < ECC_P_NUM_BYTES; byte++)
|
||||
{
|
||||
uint8_t val1, val2;
|
||||
ecc_compute_bytes(sector, poffsets[byte], ECC_P_COMP, &val1, &val2);
|
||||
if (sector[ECC_P_OFFSET + byte] != val1 || sector[ECC_P_OFFSET + ECC_P_NUM_BYTES + byte] != val2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* then verify Q bytes */
|
||||
for (byte = 0; byte < ECC_Q_NUM_BYTES; byte++)
|
||||
{
|
||||
uint8_t val1, val2;
|
||||
ecc_compute_bytes(sector, qoffsets[byte], ECC_Q_COMP, &val1, &val2);
|
||||
if (sector[ECC_Q_OFFSET + byte] != val1 || sector[ECC_Q_OFFSET + ECC_Q_NUM_BYTES + byte] != val2)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void ecc_generate(uint8_t *sector)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_generate - generate the P and Q ECC codes for a sector, overwriting any
|
||||
* existing codes
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param [in,out] sector If non-null, the sector.
|
||||
*/
|
||||
|
||||
void ecc_generate(uint8_t *sector)
|
||||
{
|
||||
int byte;
|
||||
/* first verify P bytes */
|
||||
for (byte = 0; byte < ECC_P_NUM_BYTES; byte++)
|
||||
ecc_compute_bytes(sector, poffsets[byte], ECC_P_COMP, §or[ECC_P_OFFSET + byte], §or[ECC_P_OFFSET + ECC_P_NUM_BYTES + byte]);
|
||||
|
||||
/* then verify Q bytes */
|
||||
for (byte = 0; byte < ECC_Q_NUM_BYTES; byte++)
|
||||
ecc_compute_bytes(sector, qoffsets[byte], ECC_Q_COMP, §or[ECC_Q_OFFSET + byte], §or[ECC_Q_OFFSET + ECC_Q_NUM_BYTES + byte]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void ecc_clear(uint8_t *sector)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_clear - erase the ECC P and Q cods to 0 within a sector
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param [in,out] sector If non-null, the sector.
|
||||
*/
|
||||
|
||||
void ecc_clear(uint8_t *sector)
|
||||
{
|
||||
memset(§or[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES);
|
||||
memset(§or[ECC_Q_OFFSET], 0, 2 * ECC_Q_NUM_BYTES);
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
cdrom.h
|
||||
|
||||
Generic MAME cd-rom implementation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CDROM_H__
|
||||
#define __CDROM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define CD_MAX_TRACKS (99) /* AFAIK the theoretical limit */
|
||||
#define CD_MAX_SECTOR_DATA (2352)
|
||||
#define CD_MAX_SUBCODE_DATA (96)
|
||||
|
||||
#define CD_FRAME_SIZE (CD_MAX_SECTOR_DATA + CD_MAX_SUBCODE_DATA)
|
||||
#define CD_FRAMES_PER_HUNK (8)
|
||||
|
||||
#define CD_METADATA_WORDS (1+(CD_MAX_TRACKS * 6))
|
||||
|
||||
enum
|
||||
{
|
||||
CD_TRACK_MODE1 = 0, /* mode 1 2048 bytes/sector */
|
||||
CD_TRACK_MODE1_RAW, /* mode 1 2352 bytes/sector */
|
||||
CD_TRACK_MODE2, /* mode 2 2336 bytes/sector */
|
||||
CD_TRACK_MODE2_FORM1, /* mode 2 2048 bytes/sector */
|
||||
CD_TRACK_MODE2_FORM2, /* mode 2 2324 bytes/sector */
|
||||
CD_TRACK_MODE2_FORM_MIX, /* mode 2 2336 bytes/sector */
|
||||
CD_TRACK_MODE2_RAW, /* mode 2 2352 bytes / sector */
|
||||
CD_TRACK_AUDIO, /* redbook audio track 2352 bytes/sector (588 samples) */
|
||||
|
||||
CD_TRACK_RAW_DONTCARE /* special flag for cdrom_read_data: just return me whatever is there */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CD_SUB_NORMAL = 0, /* "cooked" 96 bytes per sector */
|
||||
CD_SUB_RAW, /* raw uninterleaved 96 bytes per sector */
|
||||
CD_SUB_NONE /* no subcode data stored */
|
||||
};
|
||||
|
||||
#define CD_FLAG_GDROM 0x00000001 /* disc is a GD-ROM, all tracks should be stored with GD-ROM metadata */
|
||||
#define CD_FLAG_GDROMLE 0x00000002 /* legacy GD-ROM, with little-endian CDDA data */
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* ECC utilities */
|
||||
int ecc_verify(const uint8_t *sector);
|
||||
void ecc_generate(uint8_t *sector);
|
||||
void ecc_clear(uint8_t *sector);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
static inline uint32_t msf_to_lba(uint32_t msf)
|
||||
{
|
||||
return ( ((msf&0x00ff0000)>>16) * 60 * 75) + (((msf&0x0000ff00)>>8) * 75) + ((msf&0x000000ff)>>0);
|
||||
}
|
||||
|
||||
static inline uint32_t lba_to_msf(uint32_t lba)
|
||||
{
|
||||
uint8_t m, s, f;
|
||||
|
||||
m = lba / (60 * 75);
|
||||
lba -= m * (60 * 75);
|
||||
s = lba / 75;
|
||||
f = lba % 75;
|
||||
|
||||
return ((m / 10) << 20) | ((m % 10) << 16) |
|
||||
((s / 10) << 12) | ((s % 10) << 8) |
|
||||
((f / 10) << 4) | ((f % 10) << 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* segacd needs it like this.. investigate
|
||||
* Angelo also says PCE tracks often start playing at the
|
||||
* wrong address.. related?
|
||||
**/
|
||||
static inline uint32_t lba_to_msf_alt(int lba)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
ret |= ((lba / (60 * 75))&0xff)<<16;
|
||||
ret |= (((lba / 75) % 60)&0xff)<<8;
|
||||
ret |= ((lba % 75)&0xff)<<0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __CDROM_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,34 +0,0 @@
|
||||
#ifndef __CORETYPES_H__
|
||||
#define __CORETYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
typedef uint64_t UINT64;
|
||||
typedef uint32_t UINT32;
|
||||
typedef uint16_t UINT16;
|
||||
typedef uint8_t UINT8;
|
||||
|
||||
typedef int64_t INT64;
|
||||
typedef int32_t INT32;
|
||||
typedef int16_t INT16;
|
||||
typedef int8_t INT8;
|
||||
|
||||
#define core_file FILE
|
||||
#define core_fopen(file) fopen(file, "rb")
|
||||
#define core_fseek fseek
|
||||
#define core_fread(fc, buff, len) fread(buff, 1, len, fc)
|
||||
#define core_fclose fclose
|
||||
#define core_ftell ftell
|
||||
static size_t core_fsize(core_file *f)
|
||||
{
|
||||
long p = ftell(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
long rv = ftell(f);
|
||||
fseek(f, p, SEEK_SET);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,333 +0,0 @@
|
||||
#if defined(CHD5_FLAC)
|
||||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
flac.c
|
||||
|
||||
FLAC compression wrappers
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "flac.h"
|
||||
|
||||
/***************************************************************************
|
||||
* FLAC DECODER
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
static FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes);
|
||||
static void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
||||
static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
|
||||
static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void* client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
|
||||
static void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
|
||||
|
||||
/* getters (valid after reset) */
|
||||
static uint32_t sample_rate(flac_decoder *decoder) { return decoder->sample_rate; }
|
||||
static uint8_t channels(flac_decoder *decoder) { return decoder->channels; }
|
||||
static uint8_t bits_per_sample(flac_decoder *decoder) { return decoder->bits_per_sample; }
|
||||
static uint32_t total_samples(flac_decoder *decoder) { return FLAC__stream_decoder_get_total_samples(decoder->decoder); }
|
||||
static FLAC__StreamDecoderState state(flac_decoder *decoder) { return FLAC__stream_decoder_get_state(decoder->decoder); }
|
||||
static const char *state_string(flac_decoder *decoder) { return FLAC__stream_decoder_get_resolved_state_string(decoder->decoder); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flac_decoder - constructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_init(flac_decoder *decoder)
|
||||
{
|
||||
decoder->decoder = FLAC__stream_decoder_new();
|
||||
decoder->sample_rate = 0;
|
||||
decoder->channels = 0;
|
||||
decoder->bits_per_sample = 0;
|
||||
decoder->compressed_offset = 0;
|
||||
decoder->compressed_start = NULL;
|
||||
decoder->compressed_length = 0;
|
||||
decoder->compressed2_start = NULL;
|
||||
decoder->compressed2_length = 0;
|
||||
decoder->uncompressed_offset = 0;
|
||||
decoder->uncompressed_length = 0;
|
||||
decoder->uncompressed_swap = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flac_decoder - destructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_free(flac_decoder* decoder)
|
||||
{
|
||||
if ((decoder != NULL) && (decoder->decoder != NULL))
|
||||
FLAC__stream_decoder_delete(decoder->decoder);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* reset - reset state with the original
|
||||
* parameters
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static int flac_decoder_internal_reset(flac_decoder* decoder)
|
||||
{
|
||||
decoder->compressed_offset = 0;
|
||||
if (FLAC__stream_decoder_init_stream(decoder->decoder,
|
||||
&flac_decoder_read_callback_static,
|
||||
NULL,
|
||||
&flac_decoder_tell_callback_static,
|
||||
NULL,
|
||||
NULL,
|
||||
&flac_decoder_write_callback_static,
|
||||
&flac_decoder_metadata_callback_static,
|
||||
&flac_decoder_error_callback_static, decoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
||||
return 0;
|
||||
return FLAC__stream_decoder_process_until_end_of_metadata(decoder->decoder);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* reset - reset state with new memory parameters
|
||||
* and a custom-generated header
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length)
|
||||
{
|
||||
/* modify the template header with our parameters */
|
||||
static const uint8_t s_header_template[0x2a] =
|
||||
{
|
||||
0x66, 0x4C, 0x61, 0x43, /* +00: 'fLaC' stream header */
|
||||
0x80, /* +04: metadata block type 0 (STREAMINFO), */
|
||||
/* flagged as last block */
|
||||
0x00, 0x00, 0x22, /* +05: metadata block length = 0x22 */
|
||||
0x00, 0x00, /* +08: minimum block size */
|
||||
0x00, 0x00, /* +0A: maximum block size */
|
||||
0x00, 0x00, 0x00, /* +0C: minimum frame size (0 == unknown) */
|
||||
0x00, 0x00, 0x00, /* +0F: maximum frame size (0 == unknown) */
|
||||
0x0A, 0xC4, 0x42, 0xF0, 0x00, 0x00, 0x00, 0x00, /* +12: sample rate (0x0ac44 == 44100), */
|
||||
/* numchannels (2), sample bits (16), */
|
||||
/* samples in stream (0 == unknown) */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* +1A: MD5 signature (0 == none) */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
|
||||
};
|
||||
memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
|
||||
decoder->custom_header[0x08] = decoder->custom_header[0x0a] = block_size >> 8;
|
||||
decoder->custom_header[0x09] = decoder->custom_header[0x0b] = block_size & 0xff;
|
||||
decoder->custom_header[0x12] = sample_rate >> 12;
|
||||
decoder->custom_header[0x13] = sample_rate >> 4;
|
||||
decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
|
||||
|
||||
/* configure the header ahead of the provided buffer */
|
||||
decoder->compressed_start = (const FLAC__byte *)(decoder->custom_header);
|
||||
decoder->compressed_length = sizeof(decoder->custom_header);
|
||||
decoder->compressed2_start = (const FLAC__byte *)(buffer);
|
||||
decoder->compressed2_length = length;
|
||||
return flac_decoder_internal_reset(decoder);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* decode_interleaved - decode to an interleaved
|
||||
* sound stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian)
|
||||
{
|
||||
/* configure the uncompressed buffer */
|
||||
memset(decoder->uncompressed_start, 0, sizeof(decoder->uncompressed_start));
|
||||
decoder->uncompressed_start[0] = samples;
|
||||
decoder->uncompressed_offset = 0;
|
||||
decoder->uncompressed_length = num_samples;
|
||||
decoder->uncompressed_swap = swap_endian;
|
||||
|
||||
/* loop until we get everything we want */
|
||||
while (decoder->uncompressed_offset < decoder->uncompressed_length)
|
||||
if (!FLAC__stream_decoder_process_single(decoder->decoder))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*-------------------------------------------------
|
||||
* decode - decode to an multiple independent
|
||||
* data streams
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_endian)
|
||||
{
|
||||
/* make sure we don't have too many channels */
|
||||
int chans = channels();
|
||||
if (chans > ARRAY_LENGTH(m_uncompressed_start))
|
||||
return false;
|
||||
|
||||
/* configure the uncompressed buffer */
|
||||
memset(m_uncompressed_start, 0, sizeof(m_uncompressed_start));
|
||||
for (int curchan = 0; curchan < chans; curchan++)
|
||||
m_uncompressed_start[curchan] = samples[curchan];
|
||||
m_uncompressed_offset = 0;
|
||||
m_uncompressed_length = num_samples;
|
||||
m_uncompressed_swap = swap_endian;
|
||||
|
||||
/* loop until we get everything we want */
|
||||
while (m_uncompressed_offset < m_uncompressed_length)
|
||||
if (!FLAC__stream_decoder_process_single(m_decoder))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------
|
||||
* finish - finish up the decode
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t flac_decoder_finish(flac_decoder* decoder)
|
||||
{
|
||||
/* get the final decoding position and move forward */
|
||||
FLAC__uint64 position = 0;
|
||||
FLAC__stream_decoder_get_decode_position(decoder->decoder, &position);
|
||||
FLAC__stream_decoder_finish(decoder->decoder);
|
||||
|
||||
/* adjust position if we provided the header */
|
||||
if (position == 0)
|
||||
return 0;
|
||||
if (decoder->compressed_start == (const FLAC__byte *)(decoder->custom_header))
|
||||
position -= decoder->compressed_length;
|
||||
return position;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* read_callback - handle reads from the input
|
||||
* stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
|
||||
{
|
||||
return flac_decoder_read_callback(client_data, buffer, bytes);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes)
|
||||
{
|
||||
flac_decoder* decoder = (flac_decoder*)client_data;
|
||||
|
||||
uint32_t expected = *bytes;
|
||||
|
||||
/* copy from primary buffer first */
|
||||
uint32_t outputpos = 0;
|
||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length)
|
||||
{
|
||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
|
||||
memcpy(&buffer[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
|
||||
outputpos += bytes_to_copy;
|
||||
decoder->compressed_offset += bytes_to_copy;
|
||||
}
|
||||
|
||||
/* once we're out of that, copy from the secondary buffer */
|
||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
|
||||
{
|
||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed2_length - (decoder->compressed_offset - decoder->compressed_length));
|
||||
memcpy(&buffer[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
|
||||
outputpos += bytes_to_copy;
|
||||
decoder->compressed_offset += bytes_to_copy;
|
||||
}
|
||||
*bytes = outputpos;
|
||||
|
||||
/* return based on whether we ran out of data */
|
||||
return (*bytes < expected) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* metadata_callback - handle STREAMINFO metadata
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||
{
|
||||
flac_decoder *fldecoder;
|
||||
/* ignore all but STREAMINFO metadata */
|
||||
if (metadata->type != FLAC__METADATA_TYPE_STREAMINFO)
|
||||
return;
|
||||
|
||||
/* parse out the data we care about */
|
||||
fldecoder = (flac_decoder *)(client_data);
|
||||
fldecoder->sample_rate = metadata->data.stream_info.sample_rate;
|
||||
fldecoder->bits_per_sample = metadata->data.stream_info.bits_per_sample;
|
||||
fldecoder->channels = metadata->data.stream_info.channels;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* tell_callback - handle requests to find out
|
||||
* where in the input stream we are
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
|
||||
{
|
||||
*absolute_byte_offset = ((flac_decoder *)client_data)->compressed_offset;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* write_callback - handle writes to the output
|
||||
* stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||
{
|
||||
return flac_decoder_write_callback(client_data, frame, buffer);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void *client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
|
||||
{
|
||||
int sampnum, chan;
|
||||
int shift, blocksize;
|
||||
flac_decoder * decoder = (flac_decoder *)client_data;
|
||||
|
||||
assert(frame->header.channels == channels(decoder));
|
||||
|
||||
/* interleaved case */
|
||||
shift = decoder->uncompressed_swap ? 8 : 0;
|
||||
blocksize = frame->header.blocksize;
|
||||
if (decoder->uncompressed_start[1] == NULL)
|
||||
{
|
||||
int16_t *dest = decoder->uncompressed_start[0] + decoder->uncompressed_offset * frame->header.channels;
|
||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
||||
for (chan = 0; chan < frame->header.channels; chan++)
|
||||
*dest++ = (int16_t)((((uint16_t)buffer[chan][sampnum]) << shift) | (((uint16_t)buffer[chan][sampnum]) >> shift));
|
||||
}
|
||||
|
||||
/* non-interleaved case */
|
||||
else
|
||||
{
|
||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
||||
for (chan = 0; chan < frame->header.channels; chan++)
|
||||
if (decoder->uncompressed_start[chan] != NULL)
|
||||
decoder->uncompressed_start[chan][decoder->uncompressed_offset] = (int16_t) ( (((uint16_t)(buffer[chan][sampnum])) << shift) | ( ((uint16_t)(buffer[chan][sampnum])) >> shift) );
|
||||
}
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void flac_decoder::error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* error_callback - handle errors (ignore them)
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param decoder The decoder.
|
||||
* @param status The status.
|
||||
* @param [in,out] client_data If non-null, information describing the client.
|
||||
*/
|
||||
|
||||
void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
{
|
||||
}
|
||||
#endif // CHD5_FLAC
|
||||
@@ -1,521 +0,0 @@
|
||||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
****************************************************************************
|
||||
|
||||
huffman.c
|
||||
|
||||
Static Huffman compression and decompression helpers.
|
||||
|
||||
****************************************************************************
|
||||
|
||||
Maximum codelength is officially (alphabetsize - 1). This would be 255 bits
|
||||
(since we use 1 byte values). However, it is also dependent upon the number
|
||||
of samples used, as follows:
|
||||
|
||||
2 bits -> 3..4 samples
|
||||
3 bits -> 5..7 samples
|
||||
4 bits -> 8..12 samples
|
||||
5 bits -> 13..20 samples
|
||||
6 bits -> 21..33 samples
|
||||
7 bits -> 34..54 samples
|
||||
8 bits -> 55..88 samples
|
||||
9 bits -> 89..143 samples
|
||||
10 bits -> 144..232 samples
|
||||
11 bits -> 233..376 samples
|
||||
12 bits -> 377..609 samples
|
||||
13 bits -> 610..986 samples
|
||||
14 bits -> 987..1596 samples
|
||||
15 bits -> 1597..2583 samples
|
||||
16 bits -> 2584..4180 samples -> note that a 4k data size guarantees codelength <= 16 bits
|
||||
17 bits -> 4181..6764 samples
|
||||
18 bits -> 6765..10945 samples
|
||||
19 bits -> 10946..17710 samples
|
||||
20 bits -> 17711..28656 samples
|
||||
21 bits -> 28657..46367 samples
|
||||
22 bits -> 46368..75024 samples
|
||||
23 bits -> 75025..121392 samples
|
||||
24 bits -> 121393..196417 samples
|
||||
25 bits -> 196418..317810 samples
|
||||
26 bits -> 317811..514228 samples
|
||||
27 bits -> 514229..832039 samples
|
||||
28 bits -> 832040..1346268 samples
|
||||
29 bits -> 1346269..2178308 samples
|
||||
30 bits -> 2178309..3524577 samples
|
||||
31 bits -> 3524578..5702886 samples
|
||||
32 bits -> 5702887..9227464 samples
|
||||
|
||||
Looking at it differently, here is where powers of 2 fall into these buckets:
|
||||
|
||||
256 samples -> 11 bits max
|
||||
512 samples -> 12 bits max
|
||||
1k samples -> 14 bits max
|
||||
2k samples -> 15 bits max
|
||||
4k samples -> 16 bits max
|
||||
8k samples -> 18 bits max
|
||||
16k samples -> 19 bits max
|
||||
32k samples -> 21 bits max
|
||||
64k samples -> 22 bits max
|
||||
128k samples -> 24 bits max
|
||||
256k samples -> 25 bits max
|
||||
512k samples -> 27 bits max
|
||||
1M samples -> 28 bits max
|
||||
2M samples -> 29 bits max
|
||||
4M samples -> 31 bits max
|
||||
8M samples -> 32 bits max
|
||||
|
||||
****************************************************************************
|
||||
|
||||
Delta-RLE encoding works as follows:
|
||||
|
||||
Starting value is assumed to be 0. All data is encoded as a delta
|
||||
from the previous value, such that final[i] = final[i - 1] + delta.
|
||||
Long runs of 0s are RLE-encoded as follows:
|
||||
|
||||
0x100 = repeat count of 8
|
||||
0x101 = repeat count of 9
|
||||
0x102 = repeat count of 10
|
||||
0x103 = repeat count of 11
|
||||
0x104 = repeat count of 12
|
||||
0x105 = repeat count of 13
|
||||
0x106 = repeat count of 14
|
||||
0x107 = repeat count of 15
|
||||
0x108 = repeat count of 16
|
||||
0x109 = repeat count of 32
|
||||
0x10a = repeat count of 64
|
||||
0x10b = repeat count of 128
|
||||
0x10c = repeat count of 256
|
||||
0x10d = repeat count of 512
|
||||
0x10e = repeat count of 1024
|
||||
0x10f = repeat count of 2048
|
||||
|
||||
Note that repeat counts are reset at the end of a row, so if a 0 run
|
||||
extends to the end of a row, a large repeat count may be used.
|
||||
|
||||
The reason for starting the run counts at 8 is that 0 is expected to
|
||||
be the most common symbol, and is typically encoded in 1 or 2 bits.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "huffman.h"
|
||||
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
/***************************************************************************
|
||||
* MACROS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define MAKE_LOOKUP(code,bits) (((code) << 5) | ((bits) & 0x1f))
|
||||
|
||||
/***************************************************************************
|
||||
* IMPLEMENTATION
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* huffman_context_base - create an encoding/
|
||||
* decoding context
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
struct huffman_decoder* create_huffman_decoder(int numcodes, int maxbits)
|
||||
{
|
||||
/* limit to 24 bits */
|
||||
if (maxbits > 24)
|
||||
return NULL;
|
||||
|
||||
struct huffman_decoder* decoder = (struct huffman_decoder*)malloc(sizeof(struct huffman_decoder));
|
||||
decoder->numcodes = numcodes;
|
||||
decoder->maxbits = maxbits;
|
||||
decoder->lookup = (lookup_value*)malloc(sizeof(lookup_value) * (1 << maxbits));
|
||||
decoder->huffnode = (struct node_t*)malloc(sizeof(struct node_t) * numcodes);
|
||||
decoder->datahisto = NULL;
|
||||
decoder->prevdata = 0;
|
||||
decoder->rleremaining = 0;
|
||||
return decoder;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* decode_one - decode a single code from the
|
||||
* huffman stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
/* peek ahead to get maxbits worth of data */
|
||||
uint32_t bits = bitstream_peek(bitbuf, decoder->maxbits);
|
||||
|
||||
/* look it up, then remove the actual number of bits for this code */
|
||||
lookup_value lookup = decoder->lookup[bits];
|
||||
bitstream_remove(bitbuf, lookup & 0x1f);
|
||||
|
||||
/* return the value */
|
||||
return lookup >> 5;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* import_tree_rle - import an RLE-encoded
|
||||
* huffman tree from a source data stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
/* bits per entry depends on the maxbits */
|
||||
int numbits;
|
||||
if (decoder->maxbits >= 16)
|
||||
numbits = 5;
|
||||
else if (decoder->maxbits >= 8)
|
||||
numbits = 4;
|
||||
else
|
||||
numbits = 3;
|
||||
|
||||
/* loop until we read all the nodes */
|
||||
int curnode;
|
||||
for (curnode = 0; curnode < decoder->numcodes; )
|
||||
{
|
||||
/* a non-one value is just raw */
|
||||
int nodebits = bitstream_read(bitbuf, numbits);
|
||||
if (nodebits != 1)
|
||||
decoder->huffnode[curnode++].numbits = nodebits;
|
||||
|
||||
/* a one value is an escape code */
|
||||
else
|
||||
{
|
||||
/* a double 1 is just a single 1 */
|
||||
nodebits = bitstream_read(bitbuf, numbits);
|
||||
if (nodebits == 1)
|
||||
decoder->huffnode[curnode++].numbits = nodebits;
|
||||
|
||||
/* otherwise, we need one for value for the repeat count */
|
||||
else
|
||||
{
|
||||
int repcount = bitstream_read(bitbuf, numbits) + 3;
|
||||
while (repcount--)
|
||||
decoder->huffnode[curnode++].numbits = nodebits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure we ended up with the right number */
|
||||
if (curnode != decoder->numcodes)
|
||||
return HUFFERR_INVALID_DATA;
|
||||
|
||||
/* assign canonical codes for all nodes based on their code lengths */
|
||||
enum huffman_error error = huffman_assign_canonical_codes(decoder);
|
||||
if (error != HUFFERR_NONE)
|
||||
return error;
|
||||
|
||||
/* build the lookup table */
|
||||
huffman_build_lookup_table(decoder);
|
||||
|
||||
/* determine final input length and report errors */
|
||||
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
* import_tree_huffman - import a huffman-encoded
|
||||
* huffman tree from a source data stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
/* start by parsing the lengths for the small tree */
|
||||
struct huffman_decoder* smallhuff = create_huffman_decoder(24, 6);
|
||||
smallhuff->huffnode[0].numbits = bitstream_read(bitbuf, 3);
|
||||
int start = bitstream_read(bitbuf, 3) + 1;
|
||||
int count = 0;
|
||||
for (int index = 1; index < 24; index++)
|
||||
{
|
||||
if (index < start || count == 7)
|
||||
smallhuff->huffnode[index].numbits = 0;
|
||||
else
|
||||
{
|
||||
count = bitstream_read(bitbuf, 3);
|
||||
smallhuff->huffnode[index].numbits = (count == 7) ? 0 : count;
|
||||
}
|
||||
}
|
||||
|
||||
/* then regenerate the tree */
|
||||
enum huffman_error error = huffman_assign_canonical_codes(smallhuff);
|
||||
if (error != HUFFERR_NONE)
|
||||
return error;
|
||||
huffman_build_lookup_table(smallhuff);
|
||||
|
||||
/* determine the maximum length of an RLE count */
|
||||
uint32_t temp = decoder->numcodes - 9;
|
||||
uint8_t rlefullbits = 0;
|
||||
while (temp != 0)
|
||||
temp >>= 1, rlefullbits++;
|
||||
|
||||
/* now process the rest of the data */
|
||||
int last = 0;
|
||||
int curcode;
|
||||
for (curcode = 0; curcode < decoder->numcodes; )
|
||||
{
|
||||
int value = huffman_decode_one(smallhuff, bitbuf);
|
||||
if (value != 0)
|
||||
decoder->huffnode[curcode++].numbits = last = value - 1;
|
||||
else
|
||||
{
|
||||
int count = bitstream_read(bitbuf, 3) + 2;
|
||||
if (count == 7+2)
|
||||
count += bitstream_read(bitbuf, rlefullbits);
|
||||
for ( ; count != 0 && curcode < decoder->numcodes; count--)
|
||||
decoder->huffnode[curcode++].numbits = last;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure we ended up with the right number */
|
||||
if (curcode != decoder->numcodes)
|
||||
return HUFFERR_INVALID_DATA;
|
||||
|
||||
/* assign canonical codes for all nodes based on their code lengths */
|
||||
error = huffman_assign_canonical_codes(decoder);
|
||||
if (error != HUFFERR_NONE)
|
||||
return error;
|
||||
|
||||
/* build the lookup table */
|
||||
huffman_build_lookup_table(decoder);
|
||||
|
||||
/* determine final input length and report errors */
|
||||
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* compute_tree_from_histo - common backend for
|
||||
* computing a tree based on the data histogram
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder)
|
||||
{
|
||||
/* compute the number of data items in the histogram */
|
||||
uint32_t sdatacount = 0;
|
||||
for (int i = 0; i < decoder->numcodes; i++)
|
||||
sdatacount += decoder->datahisto[i];
|
||||
|
||||
/* binary search to achieve the optimum encoding */
|
||||
uint32_t lowerweight = 0;
|
||||
uint32_t upperweight = sdatacount * 2;
|
||||
while (1)
|
||||
{
|
||||
/* build a tree using the current weight */
|
||||
uint32_t curweight = (upperweight + lowerweight) / 2;
|
||||
int curmaxbits = huffman_build_tree(decoder, sdatacount, curweight);
|
||||
|
||||
/* apply binary search here */
|
||||
if (curmaxbits <= decoder->maxbits)
|
||||
{
|
||||
lowerweight = curweight;
|
||||
|
||||
/* early out if it worked with the raw weights, or if we're done searching */
|
||||
if (curweight == sdatacount || (upperweight - lowerweight) <= 1)
|
||||
break;
|
||||
}
|
||||
else
|
||||
upperweight = curweight;
|
||||
}
|
||||
|
||||
/* assign canonical codes for all nodes based on their code lengths */
|
||||
return huffman_assign_canonical_codes(decoder);
|
||||
}
|
||||
|
||||
void free_huffman_decoder(struct huffman_decoder* decoder)
|
||||
{
|
||||
free(decoder->lookup);
|
||||
free(decoder->huffnode);
|
||||
free(decoder);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* INTERNAL FUNCTIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* tree_node_compare - compare two tree nodes
|
||||
* by weight
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static int huffman_tree_node_compare(const void *item1, const void *item2)
|
||||
{
|
||||
const struct node_t *node1 = *(const struct node_t **)item1;
|
||||
const struct node_t *node2 = *(const struct node_t **)item2;
|
||||
if (node2->weight != node1->weight)
|
||||
return node2->weight - node1->weight;
|
||||
if (node2->bits - node1->bits == 0)
|
||||
fprintf(stderr, "identical node sort keys, should not happen!\n");
|
||||
return (int)node1->bits - (int)node2->bits;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* build_tree - build a huffman tree based on the
|
||||
* data distribution
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight)
|
||||
{
|
||||
/* make a list of all non-zero nodes */
|
||||
struct node_t** list = (struct node_t**)malloc(sizeof(struct node_t*) * decoder->numcodes * 2);
|
||||
int listitems = 0;
|
||||
memset(decoder->huffnode, 0, decoder->numcodes * sizeof(decoder->huffnode[0]));
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
if (decoder->datahisto[curcode] != 0)
|
||||
{
|
||||
list[listitems++] = &decoder->huffnode[curcode];
|
||||
decoder->huffnode[curcode].count = decoder->datahisto[curcode];
|
||||
decoder->huffnode[curcode].bits = curcode;
|
||||
|
||||
/* scale the weight by the current effective length, ensuring we don't go to 0 */
|
||||
decoder->huffnode[curcode].weight = ((uint64_t)decoder->datahisto[curcode]) * ((uint64_t)totalweight) / ((uint64_t)totaldata);
|
||||
if (decoder->huffnode[curcode].weight == 0)
|
||||
decoder->huffnode[curcode].weight = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Pre-sort:\n");
|
||||
for (int i = 0; i < listitems; i++) {
|
||||
fprintf(stderr, "weight: %d code: %d\n", list[i]->m_weight, list[i]->m_bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sort the list by weight, largest weight first */
|
||||
qsort(&list[0], listitems, sizeof(list[0]), huffman_tree_node_compare);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Post-sort:\n");
|
||||
for (int i = 0; i < listitems; i++) {
|
||||
fprintf(stderr, "weight: %d code: %d\n", list[i]->m_weight, list[i]->m_bits);
|
||||
}
|
||||
fprintf(stderr, "===================\n");
|
||||
#endif
|
||||
|
||||
/* now build the tree */
|
||||
int nextalloc = decoder->numcodes;
|
||||
while (listitems > 1)
|
||||
{
|
||||
/* remove lowest two items */
|
||||
struct node_t* node1 = &(*list[--listitems]);
|
||||
struct node_t* node0 = &(*list[--listitems]);
|
||||
|
||||
/* create new node */
|
||||
struct node_t* newnode = &decoder->huffnode[nextalloc++];
|
||||
newnode->parent = NULL;
|
||||
node0->parent = node1->parent = newnode;
|
||||
newnode->weight = node0->weight + node1->weight;
|
||||
|
||||
/* insert into list at appropriate location */
|
||||
int curitem;
|
||||
for (curitem = 0; curitem < listitems; curitem++)
|
||||
if (newnode->weight > list[curitem]->weight)
|
||||
{
|
||||
memmove(&list[curitem+1], &list[curitem], (listitems - curitem) * sizeof(list[0]));
|
||||
break;
|
||||
}
|
||||
list[curitem] = newnode;
|
||||
listitems++;
|
||||
}
|
||||
|
||||
/* compute the number of bits in each code, and fill in another histogram */
|
||||
int maxbits = 0;
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
node->numbits = 0;
|
||||
node->bits = 0;
|
||||
|
||||
/* if we have a non-zero weight, compute the number of bits */
|
||||
if (node->weight > 0)
|
||||
{
|
||||
/* determine the number of bits for this node */
|
||||
for (struct node_t *curnode = node; curnode->parent != NULL; curnode = curnode->parent)
|
||||
node->numbits++;
|
||||
if (node->numbits == 0)
|
||||
node->numbits = 1;
|
||||
|
||||
/* keep track of the max */
|
||||
maxbits = MAX(maxbits, ((int)node->numbits));
|
||||
}
|
||||
}
|
||||
return maxbits;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* assign_canonical_codes - assign canonical codes
|
||||
* to all the nodes based on the number of bits
|
||||
* in each
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder)
|
||||
{
|
||||
/* build up a histogram of bit lengths */
|
||||
uint32_t bithisto[33] = { 0 };
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
if (node->numbits > decoder->maxbits)
|
||||
return HUFFERR_INTERNAL_INCONSISTENCY;
|
||||
if (node->numbits <= 32)
|
||||
bithisto[node->numbits]++;
|
||||
}
|
||||
|
||||
/* for each code length, determine the starting code number */
|
||||
uint32_t curstart = 0;
|
||||
for (int codelen = 32; codelen > 0; codelen--)
|
||||
{
|
||||
uint32_t nextstart = (curstart + bithisto[codelen]) >> 1;
|
||||
if (codelen != 1 && nextstart * 2 != (curstart + bithisto[codelen]))
|
||||
return HUFFERR_INTERNAL_INCONSISTENCY;
|
||||
bithisto[codelen] = curstart;
|
||||
curstart = nextstart;
|
||||
}
|
||||
|
||||
/* now assign canonical codes */
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
if (node->numbits > 0)
|
||||
node->bits = bithisto[node->numbits]++;
|
||||
}
|
||||
return HUFFERR_NONE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* build_lookup_table - build a lookup table for
|
||||
* fast decoding
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void huffman_build_lookup_table(struct huffman_decoder* decoder)
|
||||
{
|
||||
/* iterate over all codes */
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
/* process all nodes which have non-zero bits */
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
if (node->numbits > 0)
|
||||
{
|
||||
/* set up the entry */
|
||||
lookup_value value = MAKE_LOOKUP(curcode, node->numbits);
|
||||
|
||||
/* fill all matching entries */
|
||||
int shift = decoder->maxbits - node->numbits;
|
||||
lookup_value *dest = &decoder->lookup[node->bits << shift];
|
||||
lookup_value *destend = &decoder->lookup[((node->bits + 1) << shift) - 1];
|
||||
while (dest <= destend)
|
||||
*dest++ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,307 +0,0 @@
|
||||
|
||||
#include "coreio.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <cctype>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#if FEAT_HAS_COREIO_HTTP
|
||||
#if HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#pragma comment (lib, "wsock32.lib")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if FEAT_HAS_COREIO_HTTP
|
||||
string url_encode(const string &value) {
|
||||
ostringstream escaped;
|
||||
escaped.fill('0');
|
||||
escaped << hex;
|
||||
|
||||
for (string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
|
||||
string::value_type c = (*i);
|
||||
|
||||
// Keep alphanumeric and other accepted characters intact
|
||||
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~' || c == '/' || c =='%' ) {
|
||||
escaped << c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Any other characters are percent-encoded
|
||||
escaped << '%' << setw(2) << int((unsigned char)c);
|
||||
}
|
||||
|
||||
return escaped.str();
|
||||
}
|
||||
|
||||
size_t HTTP_GET(string host, int port,string path, size_t offs, size_t len, void* pdata){
|
||||
string request;
|
||||
string response;
|
||||
|
||||
struct sockaddr_in serveraddr;
|
||||
int sock;
|
||||
|
||||
std::stringstream request2;
|
||||
|
||||
if (len) {
|
||||
request2 << "GET " << path << " HTTP/1.1"<<endl;
|
||||
request2 << "User-Agent: reicastdc" << endl;
|
||||
//request2 << "" << endl;
|
||||
request2 << "Host: " << host << endl;
|
||||
request2 << "Accept: */*" << endl;
|
||||
request2 << "Range: bytes=" << offs << "-" << (offs + len-1) << endl;
|
||||
request2 << endl;
|
||||
}
|
||||
else {
|
||||
request2 << "HEAD " << path << " HTTP/1.1"<<endl;
|
||||
request2 << "User-Agent: reicastdc" << endl;
|
||||
//request2 << "" << endl;
|
||||
request2 << "Host: " << host << endl;
|
||||
request2 << endl;
|
||||
}
|
||||
|
||||
request = request2.str();
|
||||
//init winsock
|
||||
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
#ifdef _WIN32
|
||||
static WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
|
||||
die("WSAStartup fail");
|
||||
#endif
|
||||
init = true;
|
||||
}
|
||||
|
||||
//open socket
|
||||
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
||||
return -1;
|
||||
|
||||
|
||||
//connect
|
||||
memset(&serveraddr, 0, sizeof(serveraddr));
|
||||
serveraddr.sin_family = AF_INET;
|
||||
serveraddr.sin_addr.s_addr = *(int*)gethostbyname( host.c_str() )->h_addr_list[0];
|
||||
serveraddr.sin_port = htons((unsigned short) port);
|
||||
if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL v = TRUE;
|
||||
#else
|
||||
int v = 1;
|
||||
#endif
|
||||
|
||||
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&v, sizeof(v));
|
||||
//send request
|
||||
if (send(sock, request.c_str(), request.length(), 0) != request.length())
|
||||
return -1;
|
||||
|
||||
/*
|
||||
//get response
|
||||
response = "";
|
||||
resp_leng= BUFFERSIZE;
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
parse headers ..
|
||||
*/
|
||||
size_t content_length = 0;
|
||||
|
||||
size_t rv = 0;
|
||||
|
||||
for (;;) {
|
||||
stringstream ss;
|
||||
for (;;) {
|
||||
char t;
|
||||
if (recv(sock, &t, 1, 0) <= 0)
|
||||
goto _cleanup;
|
||||
|
||||
if (t != '\n'){
|
||||
ss << t;
|
||||
continue;
|
||||
}
|
||||
|
||||
string ln = ss.str();
|
||||
|
||||
if (ln.size() == 1)
|
||||
goto _data;
|
||||
string CL = "Content-Length:";
|
||||
|
||||
if (ln.substr(0, CL.size()) == CL) {
|
||||
sscanf(ln.substr(CL.size(), ln.npos).c_str(),"%zd", &content_length);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_data:
|
||||
|
||||
if (len == 0) {
|
||||
rv = content_length;
|
||||
}
|
||||
else {
|
||||
verify(len == content_length); //crash is a bit too harsh here perhaps?
|
||||
u8* ptr = (u8*)pdata;
|
||||
do
|
||||
{
|
||||
int rcv = recv(sock, (char*)ptr, len, 0);
|
||||
verify(rcv > 0 && len>= rcv);
|
||||
len -= rcv;
|
||||
ptr += rcv;
|
||||
}
|
||||
while (len >0);
|
||||
|
||||
rv = content_length;
|
||||
}
|
||||
|
||||
_cleanup:
|
||||
//disconnect
|
||||
#ifdef _WIN32
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
/*
|
||||
//cleanup
|
||||
WSACleanup();
|
||||
*/
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct CORE_FILE {
|
||||
FILE* f;
|
||||
string path;
|
||||
size_t seek_ptr;
|
||||
|
||||
string host;
|
||||
int port;
|
||||
};
|
||||
|
||||
core_file* core_fopen(const char* filename)
|
||||
{
|
||||
string p = filename;
|
||||
|
||||
CORE_FILE* rv = new CORE_FILE();
|
||||
rv->f = 0;
|
||||
rv->path = p;
|
||||
#if FEAT_HAS_COREIO_HTTP
|
||||
if (p.substr(0,7)=="http://") {
|
||||
rv->host = p.substr(7,p.npos);
|
||||
rv->host = rv->host.substr(0, rv->host.find_first_of("/"));
|
||||
|
||||
rv->path = url_encode(p.substr(p.find("/", 7), p.npos));
|
||||
|
||||
rv->port = 80;
|
||||
size_t pos = rv->host.find_first_of(":");
|
||||
if (pos != rv->host.npos) {
|
||||
string port = rv->host.substr(pos, rv->host.npos );
|
||||
rv->host = rv->host.substr(0, rv->host.find_first_of(":"));
|
||||
sscanf(port.c_str(),"%d",&rv->port);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rv->f = fopen(filename, "rb");
|
||||
|
||||
if (!rv->f) {
|
||||
delete rv;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
core_fseek((core_file*)rv, 0, SEEK_SET);
|
||||
return (core_file*)rv;
|
||||
}
|
||||
|
||||
size_t core_fseek(core_file* fc, size_t offs, size_t origin) {
|
||||
CORE_FILE* f = (CORE_FILE*)fc;
|
||||
|
||||
if (origin == SEEK_SET)
|
||||
f->seek_ptr = offs;
|
||||
else if (origin == SEEK_CUR)
|
||||
f->seek_ptr += offs;
|
||||
else
|
||||
die("Invalid code path");
|
||||
|
||||
if (f->f)
|
||||
fseek(f->f, f->seek_ptr, SEEK_SET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t core_ftell(core_file* fc) {
|
||||
CORE_FILE* f = (CORE_FILE*)fc;
|
||||
return f->seek_ptr;
|
||||
}
|
||||
int core_fread(core_file* fc, void* buff, size_t len)
|
||||
{
|
||||
CORE_FILE* f = (CORE_FILE*)fc;
|
||||
|
||||
if (f->f) {
|
||||
fread(buff,1,len,f->f);
|
||||
} else {
|
||||
#if FEAT_HAS_COREIO_HTTP
|
||||
HTTP_GET(f->host, f->port, f->path, f->seek_ptr, len, buff);
|
||||
#endif
|
||||
}
|
||||
|
||||
f->seek_ptr += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int core_fclose(core_file* fc)
|
||||
{
|
||||
CORE_FILE* f = (CORE_FILE*)fc;
|
||||
|
||||
if (f->f) {
|
||||
fclose(f->f);
|
||||
}
|
||||
|
||||
delete f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t core_fsize(core_file* fc)
|
||||
{
|
||||
CORE_FILE* f = (CORE_FILE*)fc;
|
||||
|
||||
if (f->f) {
|
||||
size_t p=ftell(f->f);
|
||||
fseek(f->f,0,SEEK_END);
|
||||
size_t rv=ftell(f->f);
|
||||
fseek(f->f,p,SEEK_SET);
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
#if FEAT_HAS_COREIO_HTTP
|
||||
return HTTP_GET(f->host, f->port, f->path, 0, 0,0);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
//#define core_file FILE
|
||||
typedef void* core_file;
|
||||
|
||||
|
||||
core_file* core_fopen(const char* filename);
|
||||
size_t core_fseek(core_file* fc, size_t offs, size_t origin);
|
||||
int core_fread(core_file* fc, void* buff, size_t len);
|
||||
int core_fclose(core_file* fc);
|
||||
size_t core_fsize(core_file* fc);
|
||||
size_t core_ftell(core_file* fc);
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
|
||||
* definitions; now uses stuff from dpkg's config.h.
|
||||
* - Ian Jackson <[email protected]>.
|
||||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#ifndef LSB_FIRST
|
||||
void
|
||||
byteSwap(UWORD32 *buf, unsigned words)
|
||||
{
|
||||
md5byte *p = (md5byte *)buf;
|
||||
|
||||
do {
|
||||
*buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
|
||||
((unsigned)p[1] << 8 | p[0]);
|
||||
p += 4;
|
||||
} while (--words);
|
||||
}
|
||||
#else
|
||||
#define byteSwap(buf,words)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void
|
||||
MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bytes[0] = 0;
|
||||
ctx->bytes[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void
|
||||
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
|
||||
{
|
||||
UWORD32 t;
|
||||
|
||||
/* Update byte count */
|
||||
|
||||
t = ctx->bytes[0];
|
||||
if ((ctx->bytes[0] = t + len) < t)
|
||||
ctx->bytes[1]++; /* Carry from low to high */
|
||||
|
||||
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
|
||||
if (t > len) {
|
||||
memcpy((md5byte *)ctx->in + 64 - t, buf, len);
|
||||
return;
|
||||
}
|
||||
/* First chunk is an odd size */
|
||||
memcpy((md5byte *)ctx->in + 64 - t, buf, t);
|
||||
byteSwap(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
|
||||
/* Process data in 64-byte chunks */
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteSwap(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void
|
||||
MD5Final(md5byte digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
||||
md5byte *p = (md5byte *)ctx->in + count;
|
||||
|
||||
/* Set the first char of padding to 0x80. There is always room. */
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 56 bytes (-8..55) */
|
||||
count = 56 - 1 - count;
|
||||
|
||||
if (count < 0) { /* Padding forces an extra block */
|
||||
memset(p, 0, count + 8);
|
||||
byteSwap(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
p = (md5byte *)ctx->in;
|
||||
count = 56;
|
||||
}
|
||||
memset(p, 0, count);
|
||||
byteSwap(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ctx->in[14] = ctx->bytes[0] << 3;
|
||||
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
|
||||
MD5Transform(ctx->buf, ctx->in);
|
||||
|
||||
byteSwap(ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
#ifndef ASM_MD5
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f,w,x,y,z,in,s) \
|
||||
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void
|
||||
MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
|
||||
{
|
||||
register UWORD32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* This is the header file for the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h'
|
||||
* header definitions; now uses stuff from dpkg's config.h
|
||||
* - Ian Jackson <[email protected]>.
|
||||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
typedef unsigned int UWORD32;
|
||||
|
||||
#define md5byte unsigned char
|
||||
|
||||
struct MD5Context {
|
||||
UWORD32 buf[4];
|
||||
UWORD32 bytes[2];
|
||||
UWORD32 in[16];
|
||||
};
|
||||
|
||||
void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
|
||||
|
||||
#endif /* !MD5_H */
|
||||
|
||||
@@ -1,387 +0,0 @@
|
||||
/* sha1.h
|
||||
*
|
||||
* The sha1 hash function.
|
||||
*/
|
||||
|
||||
/* nettle, low-level cryptographics library
|
||||
*
|
||||
* Copyright 2001 Peter Gutmann, Andrew Kuchling, Niels Moeller
|
||||
*
|
||||
* The nettle library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The nettle library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the nettle library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static unsigned int READ_UINT32(const UINT8* data)
|
||||
{
|
||||
return ((UINT32)data[0] << 24) |
|
||||
((UINT32)data[1] << 16) |
|
||||
((UINT32)data[2] << 8) |
|
||||
((UINT32)data[3]);
|
||||
}
|
||||
|
||||
static void WRITE_UINT32(unsigned char* data, UINT32 val)
|
||||
{
|
||||
data[0] = (val >> 24) & 0xFF;
|
||||
data[1] = (val >> 16) & 0xFF;
|
||||
data[2] = (val >> 8) & 0xFF;
|
||||
data[3] = (val >> 0) & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
/* A block, treated as a sequence of 32-bit words. */
|
||||
#define SHA1_DATA_LENGTH 16
|
||||
|
||||
/* The SHA f()-functions. The f1 and f3 functions can be optimized to
|
||||
save one boolean operation each - thanks to Rich Schroeppel,
|
||||
[email protected] for discovering this */
|
||||
|
||||
/* #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) Rounds 0-19 */
|
||||
#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
|
||||
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
|
||||
/* #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) Rounds 40-59 */
|
||||
#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
|
||||
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
|
||||
|
||||
/* The SHA Mysterious Constants */
|
||||
|
||||
#define K1 0x5A827999L /* Rounds 0-19 */
|
||||
#define K2 0x6ED9EBA1L /* Rounds 20-39 */
|
||||
#define K3 0x8F1BBCDCL /* Rounds 40-59 */
|
||||
#define K4 0xCA62C1D6L /* Rounds 60-79 */
|
||||
|
||||
/* SHA initial values */
|
||||
|
||||
#define h0init 0x67452301L
|
||||
#define h1init 0xEFCDAB89L
|
||||
#define h2init 0x98BADCFEL
|
||||
#define h3init 0x10325476L
|
||||
#define h4init 0xC3D2E1F0L
|
||||
|
||||
/* 32-bit rotate left - kludged with shifts */
|
||||
#ifdef _MSC_VER
|
||||
#define ROTL(n,X) _lrotl(X, n)
|
||||
#else
|
||||
#define ROTL(n,X) ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
|
||||
#endif
|
||||
|
||||
/* The initial expanding function. The hash function is defined over an
|
||||
80-word expanded input array W, where the first 16 are copies of the input
|
||||
data, and the remaining 64 are defined by
|
||||
|
||||
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
|
||||
|
||||
This implementation generates these values on the fly in a circular
|
||||
buffer - thanks to Colin Plumb, [email protected] for this
|
||||
optimization.
|
||||
|
||||
The updated SHA changes the expanding function by adding a rotate of 1
|
||||
bit. Thanks to Jim Gillogly, [email protected], and an anonymous contributor
|
||||
for this information */
|
||||
|
||||
#define expand(W,i) ( W[ i & 15 ] = \
|
||||
ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
|
||||
W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
|
||||
|
||||
|
||||
/* The prototype SHA sub-round. The fundamental sub-round is:
|
||||
|
||||
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
|
||||
b' = a;
|
||||
c' = ROTL( 30, b );
|
||||
d' = c;
|
||||
e' = d;
|
||||
|
||||
but this is implemented by unrolling the loop 5 times and renaming the
|
||||
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
|
||||
This code is then replicated 20 times for each of the 4 functions, using
|
||||
the next 20 values from the W[] array each time */
|
||||
|
||||
#define subRound(a, b, c, d, e, f, k, data) \
|
||||
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
|
||||
|
||||
/* Initialize the SHA values */
|
||||
|
||||
void
|
||||
sha1_init(struct sha1_ctx *ctx)
|
||||
{
|
||||
/* Set the h-vars to their initial values */
|
||||
ctx->digest[ 0 ] = h0init;
|
||||
ctx->digest[ 1 ] = h1init;
|
||||
ctx->digest[ 2 ] = h2init;
|
||||
ctx->digest[ 3 ] = h3init;
|
||||
ctx->digest[ 4 ] = h4init;
|
||||
|
||||
/* Initialize bit count */
|
||||
ctx->count_low = ctx->count_high = 0;
|
||||
|
||||
/* Initialize buffer */
|
||||
ctx->index = 0;
|
||||
}
|
||||
|
||||
/* Perform the SHA transformation. Note that this code, like MD5, seems to
|
||||
break some optimizing compilers due to the complexity of the expressions
|
||||
and the size of the basic block. It may be necessary to split it into
|
||||
sections, e.g. based on the four subrounds
|
||||
|
||||
Note that this function destroys the data area */
|
||||
|
||||
static void
|
||||
sha1_transform(UINT32 *state, UINT32 *data)
|
||||
{
|
||||
UINT32 A, B, C, D, E; /* Local vars */
|
||||
|
||||
/* Set up first buffer and local data buffer */
|
||||
A = state[0];
|
||||
B = state[1];
|
||||
C = state[2];
|
||||
D = state[3];
|
||||
E = state[4];
|
||||
|
||||
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
|
||||
subRound( A, B, C, D, E, f1, K1, data[ 0] );
|
||||
subRound( E, A, B, C, D, f1, K1, data[ 1] );
|
||||
subRound( D, E, A, B, C, f1, K1, data[ 2] );
|
||||
subRound( C, D, E, A, B, f1, K1, data[ 3] );
|
||||
subRound( B, C, D, E, A, f1, K1, data[ 4] );
|
||||
subRound( A, B, C, D, E, f1, K1, data[ 5] );
|
||||
subRound( E, A, B, C, D, f1, K1, data[ 6] );
|
||||
subRound( D, E, A, B, C, f1, K1, data[ 7] );
|
||||
subRound( C, D, E, A, B, f1, K1, data[ 8] );
|
||||
subRound( B, C, D, E, A, f1, K1, data[ 9] );
|
||||
subRound( A, B, C, D, E, f1, K1, data[10] );
|
||||
subRound( E, A, B, C, D, f1, K1, data[11] );
|
||||
subRound( D, E, A, B, C, f1, K1, data[12] );
|
||||
subRound( C, D, E, A, B, f1, K1, data[13] );
|
||||
subRound( B, C, D, E, A, f1, K1, data[14] );
|
||||
subRound( A, B, C, D, E, f1, K1, data[15] );
|
||||
subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) );
|
||||
subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) );
|
||||
subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) );
|
||||
subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) );
|
||||
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) );
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) );
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) );
|
||||
subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) );
|
||||
subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) );
|
||||
subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) );
|
||||
subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) );
|
||||
subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) );
|
||||
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) );
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) );
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) );
|
||||
subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) );
|
||||
subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) );
|
||||
subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) );
|
||||
subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) );
|
||||
subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) );
|
||||
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) );
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) );
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) );
|
||||
subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) );
|
||||
subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) );
|
||||
subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) );
|
||||
subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) );
|
||||
subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) );
|
||||
|
||||
/* Build message digest */
|
||||
state[0] += A;
|
||||
state[1] += B;
|
||||
state[2] += C;
|
||||
state[3] += D;
|
||||
state[4] += E;
|
||||
}
|
||||
|
||||
static void
|
||||
sha1_block(struct sha1_ctx *ctx, const UINT8 *block)
|
||||
{
|
||||
UINT32 data[SHA1_DATA_LENGTH];
|
||||
int i;
|
||||
|
||||
/* Update block count */
|
||||
if (!++ctx->count_low)
|
||||
++ctx->count_high;
|
||||
|
||||
/* Endian independent conversion */
|
||||
for (i = 0; i<SHA1_DATA_LENGTH; i++, block += 4)
|
||||
data[i] = READ_UINT32(block);
|
||||
|
||||
sha1_transform(ctx->digest, data);
|
||||
}
|
||||
|
||||
void
|
||||
sha1_update(struct sha1_ctx *ctx,
|
||||
unsigned length, const UINT8 *buffer)
|
||||
{
|
||||
if (ctx->index)
|
||||
{ /* Try to fill partial block */
|
||||
unsigned left = SHA1_DATA_SIZE - ctx->index;
|
||||
if (length < left)
|
||||
{
|
||||
memcpy(ctx->block + ctx->index, buffer, length);
|
||||
ctx->index += length;
|
||||
return; /* Finished */
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ctx->block + ctx->index, buffer, left);
|
||||
sha1_block(ctx, ctx->block);
|
||||
buffer += left;
|
||||
length -= left;
|
||||
}
|
||||
}
|
||||
while (length >= SHA1_DATA_SIZE)
|
||||
{
|
||||
sha1_block(ctx, buffer);
|
||||
buffer += SHA1_DATA_SIZE;
|
||||
length -= SHA1_DATA_SIZE;
|
||||
}
|
||||
ctx->index = length;
|
||||
if (length)
|
||||
/* Buffer leftovers */
|
||||
memcpy(ctx->block, buffer, length);
|
||||
}
|
||||
|
||||
/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern
|
||||
1 0* (64-bit count of bits processed, MSB-first) */
|
||||
|
||||
void
|
||||
sha1_final(struct sha1_ctx *ctx)
|
||||
{
|
||||
UINT32 data[SHA1_DATA_LENGTH];
|
||||
int i;
|
||||
int words;
|
||||
|
||||
i = ctx->index;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
|
||||
assert(i < SHA1_DATA_SIZE);
|
||||
ctx->block[i++] = 0x80;
|
||||
|
||||
/* Fill rest of word */
|
||||
for( ; i & 3; i++)
|
||||
ctx->block[i] = 0;
|
||||
|
||||
/* i is now a multiple of the word size 4 */
|
||||
words = i >> 2;
|
||||
for (i = 0; i < words; i++)
|
||||
data[i] = READ_UINT32(ctx->block + 4*i);
|
||||
|
||||
if (words > (SHA1_DATA_LENGTH-2))
|
||||
{ /* No room for length in this block. Process it and
|
||||
* pad with another one */
|
||||
for (i = words ; i < SHA1_DATA_LENGTH; i++)
|
||||
data[i] = 0;
|
||||
sha1_transform(ctx->digest, data);
|
||||
for (i = 0; i < (SHA1_DATA_LENGTH-2); i++)
|
||||
data[i] = 0;
|
||||
}
|
||||
else
|
||||
for (i = words ; i < SHA1_DATA_LENGTH - 2; i++)
|
||||
data[i] = 0;
|
||||
|
||||
/* There are 512 = 2^9 bits in one block */
|
||||
data[SHA1_DATA_LENGTH-2] = (ctx->count_high << 9) | (ctx->count_low >> 23);
|
||||
data[SHA1_DATA_LENGTH-1] = (ctx->count_low << 9) | (ctx->index << 3);
|
||||
sha1_transform(ctx->digest, data);
|
||||
}
|
||||
|
||||
void
|
||||
sha1_digest(const struct sha1_ctx *ctx,
|
||||
unsigned length,
|
||||
UINT8 *digest)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned words;
|
||||
unsigned leftover;
|
||||
|
||||
assert(length <= SHA1_DIGEST_SIZE);
|
||||
|
||||
words = length / 4;
|
||||
leftover = length % 4;
|
||||
|
||||
for (i = 0; i < words; i++, digest += 4)
|
||||
WRITE_UINT32(digest, ctx->digest[i]);
|
||||
|
||||
if (leftover)
|
||||
{
|
||||
UINT32 word;
|
||||
unsigned j = leftover;
|
||||
|
||||
assert(i < _SHA1_DIGEST_LENGTH);
|
||||
|
||||
word = ctx->digest[i];
|
||||
|
||||
switch (leftover)
|
||||
{
|
||||
default:
|
||||
/* this is just here to keep the compiler happy; it can never happen */
|
||||
case 3:
|
||||
digest[--j] = (word >> 8) & 0xff;
|
||||
/* Fall through */
|
||||
case 2:
|
||||
digest[--j] = (word >> 16) & 0xff;
|
||||
/* Fall through */
|
||||
case 1:
|
||||
digest[--j] = (word >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/* sha1.h
|
||||
*
|
||||
* The sha1 hash function.
|
||||
*/
|
||||
|
||||
/* nettle, low-level cryptographics library
|
||||
*
|
||||
* Copyright 2001 Niels Moeller
|
||||
*
|
||||
* The nettle library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The nettle library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the nettle library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef NETTLE_SHA1_H_INCLUDED
|
||||
#define NETTLE_SHA1_H_INCLUDED
|
||||
|
||||
#include "../chdr/coretypes.h"
|
||||
|
||||
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
#define SHA1_DATA_SIZE 64
|
||||
|
||||
/* Digest is kept internally as 4 32-bit words. */
|
||||
#define _SHA1_DIGEST_LENGTH 5
|
||||
|
||||
struct sha1_ctx
|
||||
{
|
||||
UINT32 digest[_SHA1_DIGEST_LENGTH]; /* Message digest */
|
||||
UINT32 count_low, count_high; /* 64-bit block count */
|
||||
UINT8 block[SHA1_DATA_SIZE]; /* SHA1 data buffer */
|
||||
unsigned int index; /* index into buffer */
|
||||
};
|
||||
|
||||
void
|
||||
sha1_init(struct sha1_ctx *ctx);
|
||||
|
||||
void
|
||||
sha1_update(struct sha1_ctx *ctx,
|
||||
unsigned length,
|
||||
const UINT8 *data);
|
||||
|
||||
void
|
||||
sha1_final(struct sha1_ctx *ctx);
|
||||
|
||||
void
|
||||
sha1_digest(const struct sha1_ctx *ctx,
|
||||
unsigned length,
|
||||
UINT8 *digest);
|
||||
|
||||
#endif /* NETTLE_SHA1_H_INCLUDED */
|
||||
@@ -1,161 +0,0 @@
|
||||
/*********************************************************************
|
||||
* Filename: sha256.c
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Implementation of the SHA-256 hashing algorithm.
|
||||
SHA-256 is one of the three algorithms in the SHA2
|
||||
specification. The others, SHA-384 and SHA-512, are not
|
||||
offered in this implementation.
|
||||
Algorithm specification can be found here:
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
|
||||
This implementation uses little endian byte order.
|
||||
*********************************************************************/
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sha256.h"
|
||||
|
||||
#define WORD uint32_t
|
||||
#define BYTE uint8_t
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
|
||||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
|
||||
|
||||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
|
||||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
|
||||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
|
||||
|
||||
/**************************** VARIABLES *****************************/
|
||||
static const WORD k[64] = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
|
||||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
|
||||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
|
||||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
|
||||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
|
||||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
|
||||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
|
||||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
/*********************** FUNCTION DEFINITIONS ***********************/
|
||||
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
|
||||
{
|
||||
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
|
||||
|
||||
for (i = 0, j = 0; i < 16; ++i, j += 4)
|
||||
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
|
||||
for ( ; i < 64; ++i)
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
|
||||
a = ctx->state[0];
|
||||
b = ctx->state[1];
|
||||
c = ctx->state[2];
|
||||
d = ctx->state[3];
|
||||
e = ctx->state[4];
|
||||
f = ctx->state[5];
|
||||
g = ctx->state[6];
|
||||
h = ctx->state[7];
|
||||
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a,b,c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
|
||||
ctx->state[0] += a;
|
||||
ctx->state[1] += b;
|
||||
ctx->state[2] += c;
|
||||
ctx->state[3] += d;
|
||||
ctx->state[4] += e;
|
||||
ctx->state[5] += f;
|
||||
ctx->state[6] += g;
|
||||
ctx->state[7] += h;
|
||||
}
|
||||
|
||||
void sha256_init(SHA256_CTX *ctx)
|
||||
{
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
sha256_transform(ctx, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
|
||||
{
|
||||
WORD i;
|
||||
|
||||
i = ctx->datalen;
|
||||
|
||||
// Pad whatever data is left in the buffer.
|
||||
if (ctx->datalen < 56) {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 56)
|
||||
ctx->data[i++] = 0x00;
|
||||
}
|
||||
else {
|
||||
ctx->data[i++] = 0x80;
|
||||
while (i < 64)
|
||||
ctx->data[i++] = 0x00;
|
||||
sha256_transform(ctx, ctx->data);
|
||||
memset(ctx->data, 0, 56);
|
||||
}
|
||||
|
||||
// Append to the padding the total message's length in bits and transform.
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = (BYTE)(ctx->bitlen);
|
||||
ctx->data[62] = (BYTE)(ctx->bitlen >> 8);
|
||||
ctx->data[61] = (BYTE)(ctx->bitlen >> 16);
|
||||
ctx->data[60] = (BYTE)(ctx->bitlen >> 24);
|
||||
ctx->data[59] = (BYTE)(ctx->bitlen >> 32);
|
||||
ctx->data[58] = (BYTE)(ctx->bitlen >> 40);
|
||||
ctx->data[57] = (BYTE)(ctx->bitlen >> 48);
|
||||
ctx->data[56] = (BYTE)(ctx->bitlen >> 56);
|
||||
sha256_transform(ctx, ctx->data);
|
||||
|
||||
// Since this implementation uses little endian byte ordering and SHA uses big endian,
|
||||
// reverse all the bytes when copying the final state to the output hash.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*********************************************************************
|
||||
* Filename: sha256.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding SHA1 implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
/*
|
||||
typedef uint8_t BYTE; // 8-bit byte
|
||||
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[64];
|
||||
uint32_t datalen;
|
||||
uint64_t bitlen;
|
||||
uint32_t state[8];
|
||||
} SHA256_CTX;
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
void sha256_init(SHA256_CTX *ctx);
|
||||
void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len);
|
||||
void sha256_final(SHA256_CTX *ctx, uint8_t hash[]);
|
||||
|
||||
#endif // SHA256_H
|
||||
@@ -29,6 +29,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
#define FindFirstFileExW FindFirstFileExFromAppW
|
||||
#endif
|
||||
|
||||
/* Indicates that d_type field is available in dirent structure */
|
||||
#define _DIRENT_HAVE_D_TYPE
|
||||
|
||||
@@ -455,7 +459,7 @@ _wopendir(
|
||||
* Returns pointer to static directory entry which may be overwritten by
|
||||
* subsequent calls to _wreaddir().
|
||||
*/
|
||||
static struct _wdirent*
|
||||
inline static struct _wdirent*
|
||||
_wreaddir(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
@@ -613,7 +617,7 @@ dirent_first(
|
||||
/* Failed to re-open directory: no directory entry in memory */
|
||||
dirp->cached = 0;
|
||||
datap = NULL;
|
||||
|
||||
dirent_set_errno(GetLastError()); /* Not a valid errno but better than nothing */
|
||||
}
|
||||
return datap;
|
||||
}
|
||||
@@ -647,6 +651,8 @@ dirent_next(
|
||||
FindClose (dirp->handle);
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
p = NULL;
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
dirent_set_errno(GetLastError());
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -723,7 +729,7 @@ opendir(
|
||||
/*
|
||||
* Read next directory entry.
|
||||
*/
|
||||
static struct dirent*
|
||||
inline static struct dirent*
|
||||
readdir(
|
||||
DIR *dirp)
|
||||
{
|
||||
@@ -861,7 +867,7 @@ closedir(
|
||||
/*
|
||||
* Rewind directory stream to beginning.
|
||||
*/
|
||||
static void
|
||||
inline static void
|
||||
rewinddir(
|
||||
DIR* dirp)
|
||||
{
|
||||
@@ -872,7 +878,7 @@ rewinddir(
|
||||
/*
|
||||
* Scan directory for entries.
|
||||
*/
|
||||
static int
|
||||
inline static int
|
||||
scandir(
|
||||
const char *dirname,
|
||||
struct dirent ***namelist,
|
||||
@@ -1019,7 +1025,7 @@ alphasort(
|
||||
}
|
||||
|
||||
/* Sort versions */
|
||||
static int
|
||||
inline static int
|
||||
versionsort(
|
||||
const struct dirent **a, const struct dirent **b)
|
||||
{
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ALL_H
|
||||
#define FLAC__ALL_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "callback.h"
|
||||
#include "format.h"
|
||||
#include "metadata.h"
|
||||
#include "ordinals.h"
|
||||
#include "stream_decoder.h"
|
||||
#include "stream_encoder.h"
|
||||
|
||||
/** \mainpage
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* This is the documentation for the FLAC C and C++ APIs. It is
|
||||
* highly interconnected; this introduction should give you a top
|
||||
* level idea of the structure and how to find the information you
|
||||
* need. As a prerequisite you should have at least a basic
|
||||
* knowledge of the FLAC format, documented
|
||||
* <A HREF="../format.html">here</A>.
|
||||
*
|
||||
* \section c_api FLAC C API
|
||||
*
|
||||
* The FLAC C API is the interface to libFLAC, a set of structures
|
||||
* describing the components of FLAC streams, and functions for
|
||||
* encoding and decoding streams, as well as manipulating FLAC
|
||||
* metadata in files. The public include files will be installed
|
||||
* in your include area (for example /usr/include/FLAC/...).
|
||||
*
|
||||
* By writing a little code and linking against libFLAC, it is
|
||||
* relatively easy to add FLAC support to another program. The
|
||||
* library is licensed under <A HREF="../license.html">Xiph's BSD license</A>.
|
||||
* Complete source code of libFLAC as well as the command-line
|
||||
* encoder and plugins is available and is a useful source of
|
||||
* examples.
|
||||
*
|
||||
* Aside from encoders and decoders, libFLAC provides a powerful
|
||||
* metadata interface for manipulating metadata in FLAC files. It
|
||||
* allows the user to add, delete, and modify FLAC metadata blocks
|
||||
* and it can automatically take advantage of PADDING blocks to avoid
|
||||
* rewriting the entire FLAC file when changing the size of the
|
||||
* metadata.
|
||||
*
|
||||
* libFLAC usually only requires the standard C library and C math
|
||||
* library. In particular, threading is not used so there is no
|
||||
* dependency on a thread library. However, libFLAC does not use
|
||||
* global variables and should be thread-safe.
|
||||
*
|
||||
* libFLAC also supports encoding to and decoding from Ogg FLAC.
|
||||
* However the metadata editing interfaces currently have limited
|
||||
* read-only support for Ogg FLAC files.
|
||||
*
|
||||
* \section cpp_api FLAC C++ API
|
||||
*
|
||||
* The FLAC C++ API is a set of classes that encapsulate the
|
||||
* structures and functions in libFLAC. They provide slightly more
|
||||
* functionality with respect to metadata but are otherwise
|
||||
* equivalent. For the most part, they share the same usage as
|
||||
* their counterparts in libFLAC, and the FLAC C API documentation
|
||||
* can be used as a supplement. The public include files
|
||||
* for the C++ API will be installed in your include area (for
|
||||
* example /usr/include/FLAC++/...).
|
||||
*
|
||||
* libFLAC++ is also licensed under
|
||||
* <A HREF="../license.html">Xiph's BSD license</A>.
|
||||
*
|
||||
* \section getting_started Getting Started
|
||||
*
|
||||
* A good starting point for learning the API is to browse through
|
||||
* the <A HREF="modules.html">modules</A>. Modules are logical
|
||||
* groupings of related functions or classes, which correspond roughly
|
||||
* to header files or sections of header files. Each module includes a
|
||||
* detailed description of the general usage of its functions or
|
||||
* classes.
|
||||
*
|
||||
* From there you can go on to look at the documentation of
|
||||
* individual functions. You can see different views of the individual
|
||||
* functions through the links in top bar across this page.
|
||||
*
|
||||
* If you prefer a more hands-on approach, you can jump right to some
|
||||
* <A HREF="../documentation_example_code.html">example code</A>.
|
||||
*
|
||||
* \section porting_guide Porting Guide
|
||||
*
|
||||
* Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink
|
||||
* has been introduced which gives detailed instructions on how to
|
||||
* port your code to newer versions of FLAC.
|
||||
*
|
||||
* \section embedded_developers Embedded Developers
|
||||
*
|
||||
* libFLAC has grown larger over time as more functionality has been
|
||||
* included, but much of it may be unnecessary for a particular embedded
|
||||
* implementation. Unused parts may be pruned by some simple editing of
|
||||
* src/libFLAC/Makefile.am. In general, the decoders, encoders, and
|
||||
* metadata interface are all independent from each other.
|
||||
*
|
||||
* It is easiest to just describe the dependencies:
|
||||
*
|
||||
* - All modules depend on the \link flac_format Format \endlink module.
|
||||
* - The decoders and encoders depend on the bitbuffer.
|
||||
* - The decoder is independent of the encoder. The encoder uses the
|
||||
* decoder because of the verify feature, but this can be removed if
|
||||
* not needed.
|
||||
* - Parts of the metadata interface require the stream decoder (but not
|
||||
* the encoder).
|
||||
* - Ogg support is selectable through the compile time macro
|
||||
* \c FLAC__HAS_OGG.
|
||||
*
|
||||
* For example, if your application only requires the stream decoder, no
|
||||
* encoder, and no metadata interface, you can remove the stream encoder
|
||||
* and the metadata interface, which will greatly reduce the size of the
|
||||
* library.
|
||||
*
|
||||
* Also, there are several places in the libFLAC code with comments marked
|
||||
* with "OPT:" where a #define can be changed to enable code that might be
|
||||
* faster on a specific platform. Experimenting with these can yield faster
|
||||
* binaries.
|
||||
*/
|
||||
|
||||
/** \defgroup porting Porting Guide for New Versions
|
||||
*
|
||||
* This module describes differences in the library interfaces from
|
||||
* version to version. It assists in the porting of code that uses
|
||||
* the libraries to newer versions of FLAC.
|
||||
*
|
||||
* One simple facility for making porting easier that has been added
|
||||
* in FLAC 1.1.3 is a set of \c #defines in \c export.h of each
|
||||
* library's includes (e.g. \c include/FLAC/export.h). The
|
||||
* \c #defines mirror the libraries'
|
||||
* <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>,
|
||||
* e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT,
|
||||
* \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE.
|
||||
* These can be used to support multiple versions of an API during the
|
||||
* transition phase, e.g.
|
||||
*
|
||||
* \code
|
||||
* #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
||||
* legacy code
|
||||
* #else
|
||||
* new code
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* The source will work for multiple versions and the legacy code can
|
||||
* easily be removed when the transition is complete.
|
||||
*
|
||||
* Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in
|
||||
* include/FLAC/export.h), which can be used to determine whether or not
|
||||
* the library has been compiled with support for Ogg FLAC. This is
|
||||
* simpler than trying to call an Ogg init function and catching the
|
||||
* error.
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.2 to FLAC 1.1.3.
|
||||
*
|
||||
* The main change between the APIs in 1.1.2 and 1.1.3 is that they have
|
||||
* been simplified. First, libOggFLAC has been merged into libFLAC and
|
||||
* libOggFLAC++ has been merged into libFLAC++. Second, both the three
|
||||
* decoding layers and three encoding layers have been merged into a
|
||||
* single stream decoder and stream encoder. That is, the functionality
|
||||
* of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged
|
||||
* into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and
|
||||
* FLAC__FileEncoder into FLAC__StreamEncoder. Only the
|
||||
* FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means
|
||||
* is there is now a single API that can be used to encode or decode
|
||||
* streams to/from native FLAC or Ogg FLAC and the single API can work
|
||||
* on both seekable and non-seekable streams.
|
||||
*
|
||||
* Instead of creating an encoder or decoder of a certain layer, now the
|
||||
* client will always create a FLAC__StreamEncoder or
|
||||
* FLAC__StreamDecoder. The old layers are now differentiated by the
|
||||
* initialization function. For example, for the decoder,
|
||||
* FLAC__stream_decoder_init() has been replaced by
|
||||
* FLAC__stream_decoder_init_stream(). This init function takes
|
||||
* callbacks for the I/O, and the seeking callbacks are optional. This
|
||||
* allows the client to use the same object for seekable and
|
||||
* non-seekable streams. For decoding a FLAC file directly, the client
|
||||
* can use FLAC__stream_decoder_init_file() and pass just a filename
|
||||
* and fewer callbacks; most of the other callbacks are supplied
|
||||
* internally. For situations where fopen()ing by filename is not
|
||||
* possible (e.g. Unicode filenames on Windows) the client can instead
|
||||
* open the file itself and supply the FILE* to
|
||||
* FLAC__stream_decoder_init_FILE(). The init functions now returns a
|
||||
* FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState.
|
||||
* Since the callbacks and client data are now passed to the init
|
||||
* function, the FLAC__stream_decoder_set_*_callback() functions and
|
||||
* FLAC__stream_decoder_set_client_data() are no longer needed. The
|
||||
* rest of the calls to the decoder are the same as before.
|
||||
*
|
||||
* There are counterpart init functions for Ogg FLAC, e.g.
|
||||
* FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls
|
||||
* and callbacks are the same as for native FLAC.
|
||||
*
|
||||
* As an example, in FLAC 1.1.2 a seekable stream decoder would have
|
||||
* been set up like so:
|
||||
*
|
||||
* \code
|
||||
* FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new();
|
||||
* if(decoder == NULL) do_something;
|
||||
* FLAC__seekable_stream_decoder_set_md5_checking(decoder, true);
|
||||
* [... other settings ...]
|
||||
* FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback);
|
||||
* FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback);
|
||||
* FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback);
|
||||
* FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback);
|
||||
* FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback);
|
||||
* FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback);
|
||||
* FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback);
|
||||
* FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback);
|
||||
* FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data);
|
||||
* if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* In FLAC 1.1.3 it is like this:
|
||||
*
|
||||
* \code
|
||||
* FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
|
||||
* if(decoder == NULL) do_something;
|
||||
* FLAC__stream_decoder_set_md5_checking(decoder, true);
|
||||
* [... other settings ...]
|
||||
* if(FLAC__stream_decoder_init_stream(
|
||||
* decoder,
|
||||
* my_read_callback,
|
||||
* my_seek_callback, // or NULL
|
||||
* my_tell_callback, // or NULL
|
||||
* my_length_callback, // or NULL
|
||||
* my_eof_callback, // or NULL
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* or you could do;
|
||||
*
|
||||
* \code
|
||||
* [...]
|
||||
* FILE *file = fopen("somefile.flac","rb");
|
||||
* if(file == NULL) do_somthing;
|
||||
* if(FLAC__stream_decoder_init_FILE(
|
||||
* decoder,
|
||||
* file,
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* or just:
|
||||
*
|
||||
* \code
|
||||
* [...]
|
||||
* if(FLAC__stream_decoder_init_file(
|
||||
* decoder,
|
||||
* "somefile.flac",
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* Another small change to the decoder is in how it handles unparseable
|
||||
* streams. Before, when the decoder found an unparseable stream
|
||||
* (reserved for when the decoder encounters a stream from a future
|
||||
* encoder that it can't parse), it changed the state to
|
||||
* \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead
|
||||
* drops sync and calls the error callback with a new error code
|
||||
* \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is
|
||||
* more robust. If your error callback does not discriminate on the the
|
||||
* error state, your code does not need to be changed.
|
||||
*
|
||||
* The encoder now has a new setting:
|
||||
* FLAC__stream_encoder_set_apodization(). This is for setting the
|
||||
* method used to window the data before LPC analysis. You only need to
|
||||
* add a call to this function if the default is not suitable. There
|
||||
* are also two new convenience functions that may be useful:
|
||||
* FLAC__metadata_object_cuesheet_calculate_cddb_id() and
|
||||
* FLAC__metadata_get_cuesheet().
|
||||
*
|
||||
* The \a bytes parameter to FLAC__StreamDecoderReadCallback,
|
||||
* FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback
|
||||
* is now \c size_t instead of \c unsigned.
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.3 to FLAC 1.1.4.
|
||||
*
|
||||
* There were no changes to any of the interfaces from 1.1.3 to 1.1.4.
|
||||
* There was a slight change in the implementation of
|
||||
* FLAC__stream_encoder_set_metadata(); the function now makes a copy
|
||||
* of the \a metadata array of pointers so the client no longer needs
|
||||
* to maintain it after the call. The objects themselves that are
|
||||
* pointed to by the array are still not copied though and must be
|
||||
* maintained until the call to FLAC__stream_encoder_finish().
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.4 to FLAC 1.2.0.
|
||||
*
|
||||
* There were only very minor changes to the interfaces from 1.1.4 to 1.2.0.
|
||||
* In libFLAC, \c FLAC__format_sample_rate_is_subset() was added.
|
||||
* In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added.
|
||||
*
|
||||
* Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN
|
||||
* has changed to reflect the conversion of one of the reserved bits
|
||||
* into active use. It used to be \c 2 and now is \c 1. However the
|
||||
* FLAC frame header length has not changed, so to skip the proper
|
||||
* number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN +
|
||||
* \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
|
||||
*/
|
||||
|
||||
/** \defgroup flac FLAC C API
|
||||
*
|
||||
* The FLAC C API is the interface to libFLAC, a set of structures
|
||||
* describing the components of FLAC streams, and functions for
|
||||
* encoding and decoding streams, as well as manipulating FLAC
|
||||
* metadata in files.
|
||||
*
|
||||
* You should start with the format components as all other modules
|
||||
* are dependent on it.
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ASSERT_H
|
||||
#define FLAC__ASSERT_H
|
||||
|
||||
/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */
|
||||
#ifdef DEBUG
|
||||
#include <assert.h>
|
||||
#define FLAC__ASSERT(x) assert(x)
|
||||
#define FLAC__ASSERT_DECLARATION(x) x
|
||||
#else
|
||||
#define FLAC__ASSERT(x)
|
||||
#define FLAC__ASSERT_DECLARATION(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,185 +0,0 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__CALLBACK_H
|
||||
#define FLAC__CALLBACK_H
|
||||
|
||||
#include "ordinals.h"
|
||||
#include <stdlib.h> /* for size_t */
|
||||
|
||||
/** \file include/FLAC/callback.h
|
||||
*
|
||||
* \brief
|
||||
* This module defines the structures for describing I/O callbacks
|
||||
* to the other FLAC interfaces.
|
||||
*
|
||||
* See the detailed documentation for callbacks in the
|
||||
* \link flac_callbacks callbacks \endlink module.
|
||||
*/
|
||||
|
||||
/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures
|
||||
* \ingroup flac
|
||||
*
|
||||
* \brief
|
||||
* This module defines the structures for describing I/O callbacks
|
||||
* to the other FLAC interfaces.
|
||||
*
|
||||
* The purpose of the I/O callback functions is to create a common way
|
||||
* for the metadata interfaces to handle I/O.
|
||||
*
|
||||
* Originally the metadata interfaces required filenames as the way of
|
||||
* specifying FLAC files to operate on. This is problematic in some
|
||||
* environments so there is an additional option to specify a set of
|
||||
* callbacks for doing I/O on the FLAC file, instead of the filename.
|
||||
*
|
||||
* In addition to the callbacks, a FLAC__IOHandle type is defined as an
|
||||
* opaque structure for a data source.
|
||||
*
|
||||
* The callback function prototypes are similar (but not identical) to the
|
||||
* stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use
|
||||
* stdio streams to implement the callbacks, you can pass fread, fwrite, and
|
||||
* fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or
|
||||
* FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle
|
||||
* is required. \warning You generally CANNOT directly use fseek or ftell
|
||||
* for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems
|
||||
* these use 32-bit offsets and FLAC requires 64-bit offsets to deal with
|
||||
* large files. You will have to find an equivalent function (e.g. ftello),
|
||||
* or write a wrapper. The same is true for feof() since this is usually
|
||||
* implemented as a macro, not as a function whose address can be taken.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** This is the opaque handle type used by the callbacks. Typically
|
||||
* this is a \c FILE* or address of a file descriptor.
|
||||
*/
|
||||
typedef void* FLAC__IOHandle;
|
||||
|
||||
/** Signature for the read callback.
|
||||
* The signature and semantics match POSIX fread() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param ptr The address of the read buffer.
|
||||
* \param size The size of the records to be read.
|
||||
* \param nmemb The number of records to be read.
|
||||
* \param handle The handle to the data source.
|
||||
* \retval size_t
|
||||
* The number of records read.
|
||||
*/
|
||||
typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the write callback.
|
||||
* The signature and semantics match POSIX fwrite() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param ptr The address of the write buffer.
|
||||
* \param size The size of the records to be written.
|
||||
* \param nmemb The number of records to be written.
|
||||
* \param handle The handle to the data source.
|
||||
* \retval size_t
|
||||
* The number of records written.
|
||||
*/
|
||||
typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the seek callback.
|
||||
* The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT
|
||||
* EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long'
|
||||
* and 32-bits wide.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \param offset The new position, relative to \a whence
|
||||
* \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END
|
||||
* \retval int
|
||||
* \c 0 on success, \c -1 on error.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
|
||||
|
||||
/** Signature for the tell callback.
|
||||
* The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT
|
||||
* EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long'
|
||||
* and 32-bits wide.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval FLAC__int64
|
||||
* The current position on success, \c -1 on error.
|
||||
*/
|
||||
typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the EOF callback.
|
||||
* The signature and semantics mostly match POSIX feof() but WATCHOUT:
|
||||
* on many systems, feof() is a macro, so in this case a wrapper function
|
||||
* must be provided instead.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval int
|
||||
* \c 0 if not at end of file, nonzero if at end of file.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the close callback.
|
||||
* The signature and semantics match POSIX fclose() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval int
|
||||
* \c 0 on success, \c EOF on error.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle);
|
||||
|
||||
/** A structure for holding a set of callbacks.
|
||||
* Each FLAC interface that requires a FLAC__IOCallbacks structure will
|
||||
* describe which of the callbacks are required. The ones that are not
|
||||
* required may be set to NULL.
|
||||
*
|
||||
* If the seek requirement for an interface is optional, you can signify that
|
||||
* a data sorce is not seekable by setting the \a seek field to \c NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
FLAC__IOCallback_Read read;
|
||||
FLAC__IOCallback_Write write;
|
||||
FLAC__IOCallback_Seek seek;
|
||||
FLAC__IOCallback_Tell tell;
|
||||
FLAC__IOCallback_Eof eof;
|
||||
FLAC__IOCallback_Close close;
|
||||
} FLAC__IOCallbacks;
|
||||
|
||||
/* \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,97 +0,0 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__EXPORT_H
|
||||
#define FLAC__EXPORT_H
|
||||
|
||||
/** \file include/FLAC/export.h
|
||||
*
|
||||
* \brief
|
||||
* This module contains #defines and symbols for exporting function
|
||||
* calls, and providing version information and compiled-in features.
|
||||
*
|
||||
* See the \link flac_export export \endlink module.
|
||||
*/
|
||||
|
||||
/** \defgroup flac_export FLAC/export.h: export symbols
|
||||
* \ingroup flac
|
||||
*
|
||||
* \brief
|
||||
* This module contains #defines and symbols for exporting function
|
||||
* calls, and providing version information and compiled-in features.
|
||||
*
|
||||
* If you are compiling with MSVC and will link to the static library
|
||||
* (libFLAC.lib) you should define FLAC__NO_DLL in your project to
|
||||
* make sure the symbols are exported properly.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if defined(FLAC__NO_DLL)
|
||||
#define FLAC_API
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#ifdef FLAC_API_EXPORTS
|
||||
#define FLAC_API __declspec(dllexport)
|
||||
#else
|
||||
#define FLAC_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#elif defined(FLAC__USE_VISIBILITY_ATTR)
|
||||
#define FLAC_API __attribute__ ((visibility ("default")))
|
||||
|
||||
#else
|
||||
#define FLAC_API
|
||||
|
||||
#endif
|
||||
|
||||
/** These #defines will mirror the libtool-based library version number, see
|
||||
* http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
|
||||
*/
|
||||
#define FLAC_API_VERSION_CURRENT 11
|
||||
#define FLAC_API_VERSION_REVISION 0 /**< see above */
|
||||
#define FLAC_API_VERSION_AGE 3 /**< see above */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */
|
||||
extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,86 +0,0 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ORDINALS_H
|
||||
#define FLAC__ORDINALS_H
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
|
||||
/* Microsoft Visual Studio earlier than the 2010 version did not provide
|
||||
* the 1999 ISO C Standard header file <stdint.h>.
|
||||
*/
|
||||
|
||||
typedef __int8 FLAC__int8;
|
||||
typedef unsigned __int8 FLAC__uint8;
|
||||
|
||||
typedef __int16 FLAC__int16;
|
||||
typedef __int32 FLAC__int32;
|
||||
typedef __int64 FLAC__int64;
|
||||
typedef unsigned __int16 FLAC__uint16;
|
||||
typedef unsigned __int32 FLAC__uint32;
|
||||
typedef unsigned __int64 FLAC__uint64;
|
||||
|
||||
#else
|
||||
|
||||
/* For MSVC 2010 and everything else which provides <stdint.h>. */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int8_t FLAC__int8;
|
||||
typedef uint8_t FLAC__uint8;
|
||||
|
||||
typedef int16_t FLAC__int16;
|
||||
typedef int32_t FLAC__int32;
|
||||
typedef int64_t FLAC__int64;
|
||||
typedef uint16_t FLAC__uint16;
|
||||
typedef uint32_t FLAC__uint32;
|
||||
typedef uint64_t FLAC__uint64;
|
||||
|
||||
#endif
|
||||
|
||||
typedef int FLAC__bool;
|
||||
|
||||
typedef FLAC__uint8 FLAC__byte;
|
||||
|
||||
|
||||
#ifdef true
|
||||
#undef true
|
||||
#endif
|
||||
#ifdef false
|
||||
#undef false
|
||||
#endif
|
||||
#ifndef __cplusplus
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,10 +0,0 @@
|
||||
#define PACKAGE_VERSION "1.3.2"
|
||||
#define FLAC__HAS_OGG 0
|
||||
#define FLAC__NO_DLL 1
|
||||
#define HAVE_LROUND 1
|
||||
#define HAVE_STDINT_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#ifndef _MSC_VER
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
#endif
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
/* alloc - Convenience routines for safely allocating memory
|
||||
* Copyright (C) 2007-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__ALLOC_H
|
||||
#define FLAC__SHARE__ALLOC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
|
||||
* before #including this file, otherwise SIZE_MAX might not be defined
|
||||
*/
|
||||
|
||||
#include <limits.h> /* for SIZE_MAX */
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
|
||||
#endif
|
||||
#include <stdlib.h> /* for size_t, malloc(), etc */
|
||||
#include "share/compat.h"
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# ifndef SIZE_T_MAX
|
||||
# ifdef _MSC_VER
|
||||
# ifdef _WIN64
|
||||
# define SIZE_T_MAX FLAC__U64L(0xffffffffffffffff)
|
||||
# else
|
||||
# define SIZE_T_MAX 0xffffffff
|
||||
# endif
|
||||
# else
|
||||
# error
|
||||
# endif
|
||||
# endif
|
||||
# define SIZE_MAX SIZE_T_MAX
|
||||
#endif
|
||||
|
||||
/* avoid malloc()ing 0 bytes, see:
|
||||
* https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
|
||||
*/
|
||||
static inline void *safe_malloc_(size_t size)
|
||||
{
|
||||
/* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(!size)
|
||||
size++;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static inline void *safe_calloc_(size_t nmemb, size_t size)
|
||||
{
|
||||
if(!nmemb || !size)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
return calloc(nmemb, size);
|
||||
}
|
||||
|
||||
/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
|
||||
|
||||
static inline void *safe_malloc_add_2op_(size_t size1, size_t size2)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
return safe_malloc_(size2);
|
||||
}
|
||||
|
||||
static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
return safe_malloc_(size3);
|
||||
}
|
||||
|
||||
static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
size4 += size3;
|
||||
if(size4 < size3)
|
||||
return 0;
|
||||
return safe_malloc_(size4);
|
||||
}
|
||||
|
||||
void *safe_malloc_mul_2op_(size_t size1, size_t size2) ;
|
||||
|
||||
static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || !size2 || !size3)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
size1 *= size2;
|
||||
if(size1 > SIZE_MAX / size3)
|
||||
return 0;
|
||||
return malloc(size1*size3);
|
||||
}
|
||||
|
||||
/* size1*size2 + size3 */
|
||||
static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return safe_malloc_(size3);
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return safe_malloc_add_2op_(size1*size2, size3);
|
||||
}
|
||||
|
||||
/* size1 * (size2 + size3) */
|
||||
static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || (!size2 && !size3))
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
size2 += size3;
|
||||
if(size2 < size3)
|
||||
return 0;
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return malloc(size1*size2);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_(void *ptr, size_t size)
|
||||
{
|
||||
void *oldptr = ptr;
|
||||
void *newptr = realloc(ptr, size);
|
||||
if(size > 0 && newptr == 0)
|
||||
free(oldptr);
|
||||
return newptr;
|
||||
}
|
||||
static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1) {
|
||||
free(ptr);
|
||||
return 0;
|
||||
}
|
||||
return realloc(ptr, size2);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
return realloc(ptr, size3);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
size4 += size3;
|
||||
if(size4 < size3)
|
||||
return 0;
|
||||
return realloc(ptr, size4);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return safe_realloc_(ptr, size1*size2);
|
||||
}
|
||||
|
||||
/* size1 * (size2 + size3) */
|
||||
static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || (!size2 && !size3))
|
||||
return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
|
||||
size2 += size3;
|
||||
if(size2 < size3)
|
||||
return 0;
|
||||
return safe_realloc_mul_2op_(ptr, size1, size2);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,209 +0,0 @@
|
||||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2016 Xiph.org Foundation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is the prefered location of all CPP hackery to make $random_compiler
|
||||
* work like something approaching a C99 (or maybe more accurately GNU99)
|
||||
* compiler.
|
||||
*
|
||||
* It is assumed that this header will be included after "config.h".
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__COMPAT_H
|
||||
#define FLAC__SHARE__COMPAT_H
|
||||
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
/* where MSVC puts unlink() */
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */
|
||||
#if !defined __MINGW32__
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#else /* MinGW */
|
||||
#if !defined(HAVE_FSEEKO)
|
||||
#define fseeko fseeko64
|
||||
#define ftello ftello64
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define FLAC__off_t off_t
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strtoll _strtoi64
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64)
|
||||
/* MSVS generates VERY slow 32-bit code with __restrict */
|
||||
#define flac_restrict __restrict
|
||||
#elif defined __GNUC__
|
||||
#define flac_restrict __restrict__
|
||||
#else
|
||||
#define flac_restrict
|
||||
#endif
|
||||
|
||||
#define FLAC__U64L(x) x##ULL
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
#define FLAC__STRCASECMP _stricmp
|
||||
#define FLAC__STRNCASECMP _strnicmp
|
||||
#elif defined __BORLANDC__
|
||||
#define FLAC__STRCASECMP stricmp
|
||||
#define FLAC__STRNCASECMP strnicmp
|
||||
#else
|
||||
#define FLAC__STRCASECMP strcasecmp
|
||||
#define FLAC__STRNCASECMP strncasecmp
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__
|
||||
#include <io.h> /* for _setmode(), chmod() */
|
||||
#include <fcntl.h> /* for _O_BINARY */
|
||||
#else
|
||||
#include <unistd.h> /* for chown(), unlink() */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#if defined __BORLANDC__
|
||||
#include <utime.h> /* for utime() */
|
||||
#else
|
||||
#include <sys/utime.h> /* for utime() */
|
||||
#endif
|
||||
#else
|
||||
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
|
||||
#include <utime.h> /* for utime() */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
# if _MSC_VER >= 1800
|
||||
# include <inttypes.h>
|
||||
# elif _MSC_VER >= 1600
|
||||
/* Visual Studio 2010 has decent C99 support */
|
||||
# include <stdint.h>
|
||||
# define PRIu64 "llu"
|
||||
# define PRId64 "lld"
|
||||
# define PRIx64 "llx"
|
||||
# else
|
||||
# include <limits.h>
|
||||
# ifndef UINT32_MAX
|
||||
# define UINT32_MAX _UI32_MAX
|
||||
# endif
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
# define PRIu64 "I64u"
|
||||
# define PRId64 "I64d"
|
||||
# define PRIx64 "I64x"
|
||||
# endif
|
||||
#endif /* defined _MSC_VER */
|
||||
|
||||
#ifdef _WIN32
|
||||
/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */
|
||||
|
||||
#include "share/win_utf8_io.h"
|
||||
#define flac_printf printf_utf8
|
||||
#define flac_fprintf fprintf_utf8
|
||||
#define flac_vfprintf vfprintf_utf8
|
||||
|
||||
#include "share/windows_unicode_filenames.h"
|
||||
#define flac_fopen flac_internal_fopen_utf8
|
||||
#define flac_chmod flac_internal_chmod_utf8
|
||||
#define flac_utime flac_internal_utime_utf8
|
||||
#define flac_unlink flac_internal_unlink_utf8
|
||||
#define flac_rename flac_internal_rename_utf8
|
||||
#define flac_stat flac_internal_stat64_utf8
|
||||
|
||||
#else
|
||||
|
||||
#define flac_printf printf
|
||||
#define flac_fprintf fprintf
|
||||
#define flac_vfprintf vfprintf
|
||||
|
||||
#define flac_fopen fopen
|
||||
#define flac_chmod chmod
|
||||
#define flac_utime utime
|
||||
#define flac_unlink unlink
|
||||
#define flac_rename rename
|
||||
#define flac_stat stat
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define flac_stat_s __stat64 /* stat struct */
|
||||
#define flac_fstat _fstat64
|
||||
#else
|
||||
#define flac_stat_s stat /* stat struct */
|
||||
#define flac_fstat fstat
|
||||
#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* FLAC needs to compile and work correctly on systems with a normal ISO C99
|
||||
* snprintf as well as Microsoft Visual Studio which has an non-standards
|
||||
* conformant snprint_s function.
|
||||
*
|
||||
* This function wraps the MS version to behave more like the ISO version.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int flac_snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* FLAC__SHARE__COMPAT_H */
|
||||
Loaded 100 of 3795 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user