mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-05 04:29:29 +00:00
Compare commits
566 Commits
2.5_201907
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
4b6beeca17 | ||
|
5d84c6d0fc | ||
|
d7c030312d | ||
|
be389a9f11 | ||
|
a07cc8ae56 | ||
|
293ef33a28 | ||
|
979523b5ca | ||
|
076390e911 | ||
|
db897d0d42 | ||
|
e12789a57e | ||
|
aa9f112de3 | ||
|
784ac7bb7e | ||
|
45e3bd1d3e | ||
|
08707d3a25 | ||
|
0a1d9c35bf | ||
|
3176aa887d | ||
|
9088a674ad | ||
|
1d8dd979ab | ||
|
1ddb7d3a42 | ||
|
e059b64ac8 | ||
|
b6d62c2f14 | ||
|
9395e119af | ||
|
021bb50149 | ||
|
3d49e9790b | ||
|
19308135c3 | ||
|
2533f7ac05 | ||
|
9a7751f1a2 | ||
|
0942bdcbf9 | ||
|
d2c2647e3a | ||
|
1d8e348e4b | ||
|
81bdda2a5b | ||
|
e90180a2c3 | ||
|
a94a41885b | ||
|
6f94fdd7b0 | ||
|
51fc1905c4 | ||
|
c4c153c49c | ||
|
d66da33874 | ||
|
c4a22a51d6 | ||
|
1199f8115e | ||
|
ef3f61c30d | ||
|
36de3833bf | ||
|
aa6f09ec7a | ||
|
5739ba9e8a | ||
|
cfec811999 | ||
|
5915d869fa | ||
|
78a4e7212b | ||
|
92c4c72000 | ||
|
0365386fa1 | ||
|
d6112f4a30 | ||
|
ed3decddf1 | ||
|
d4ec4e5323 | ||
|
1a2d818e47 | ||
|
db877c0443 | ||
|
4217fc73cd | ||
|
b3ebcd595c | ||
|
3f7896976a | ||
|
ae9d917d5e | ||
|
0118e99764 | ||
|
cb67534d28 | ||
|
f61701df3c | ||
|
4b58ce3ea8 | ||
|
c727bc0df7 | ||
|
fdeb8617da | ||
|
6da609938e | ||
|
aaf67fd59a | ||
|
af96a51acb | ||
|
bf784a2c30 | ||
|
094995722b | ||
|
604baaa289 | ||
|
2a74fdaab6 | ||
|
1dd1d2713d | ||
|
01ba8564ed | ||
|
d284e9976b | ||
|
7482de353b | ||
|
3f00759e54 | ||
|
a9d1f35cdf | ||
|
0083bc7ea7 | ||
|
2fa17a0783 | ||
|
811dddf70b | ||
|
29d0ea13ae | ||
|
249dfc84ae | ||
|
4c1c549ed6 | ||
|
1b36e7e118 | ||
|
ffb525800b | ||
|
3b7a89aad9 | ||
|
4724ce7aee | ||
|
95f1d46bae | ||
|
92778586de | ||
|
988eef8c5c | ||
|
cfb9d5a501 | ||
|
05adbff2f5 | ||
|
1de48de65d | ||
|
36b2862d21 | ||
|
e28a9fc3a9 | ||
|
6edec590ab | ||
|
75cdbd1d7b | ||
|
bfad0d3bba | ||
|
dae2be8c48 | ||
|
177a297527 | ||
|
b1ab353085 | ||
|
4ac4cbba45 | ||
|
ed86a18497 | ||
|
481b675e1a | ||
|
befe6d2db0 | ||
|
03ed87c966 | ||
|
4b1bc7c38c | ||
|
756021f267 | ||
|
5777129302 | ||
|
d9e0761bd9 | ||
|
11e88dd94f | ||
|
41648c23c5 | ||
|
d36be9168d | ||
|
4f94ef52c1 | ||
|
f017f9df58 | ||
|
5900e4895a | ||
|
9009a2741f | ||
|
d7e93d8f37 | ||
|
2e9eea3201 | ||
|
d03303cdf7 | ||
|
b4be0cdbb2 | ||
|
45578ddd45 | ||
|
e933e7885f | ||
|
2666bef882 | ||
|
81ccbfa1e7 | ||
|
a66b73a516 | ||
|
425dac6a7c | ||
|
d4baa318e4 | ||
|
1f5465ad77 | ||
|
fcf2c1d9b6 | ||
|
0f7f1543ed | ||
|
732029a512 | ||
|
3b1868ae56 | ||
|
86665c4c30 | ||
|
6285165090 | ||
|
789a39a2c6 | ||
|
2ea84d86c7 | ||
|
e069d84f5b | ||
|
f07b34a451 | ||
|
33c3419b08 | ||
|
c359aabc2d | ||
|
d993158df8 | ||
|
2a5ac90370 | ||
|
d05e5ab711 | ||
|
88a1fb2921 | ||
|
44f6eff928 | ||
|
a3534d2eea | ||
|
f1502fb6bd | ||
|
a5064455cb | ||
|
f385c22ed2 | ||
|
ad6047ea24 | ||
|
a722785575 | ||
|
b2df4fed1f | ||
|
ab586a5a09 | ||
|
90edd35246 | ||
|
cce0ed4c87 | ||
|
763fe81f0d | ||
|
0538eb0cc0 | ||
|
56343905e3 | ||
|
ef2f8724fe | ||
|
15f56749ba | ||
|
ea3832423c | ||
|
d346521b92 | ||
|
9621850735 | ||
|
4d16bb88b4 | ||
|
42e70e85c6 | ||
|
6385243609 | ||
|
bdcc9d2da4 | ||
|
1de3d694f2 | ||
|
ac68d68920 | ||
|
5d1bfd1059 | ||
|
e9a9573a20 | ||
|
c28a00f58a | ||
|
420dc1d504 | ||
|
ba89fc7a72 | ||
|
78fdb44d02 | ||
|
bc9c7675f9 | ||
|
caf10f1223 | ||
|
5862662bc9 | ||
|
e42b8f6076 | ||
|
ce00063701 | ||
|
164aa8c3fe | ||
|
9cf0c98dd6 | ||
|
1d710a0cad | ||
|
1aaeaf05c4 | ||
|
65028aec4a | ||
|
8a28ad6e39 | ||
|
4f0743562e | ||
|
49eee29597 | ||
|
20d2de95ce | ||
|
a39eff553c | ||
|
e750aecafe | ||
|
72989fffe2 | ||
|
176da65363 | ||
|
8064215081 | ||
|
7471c357c3 | ||
|
ce3e2f3693 | ||
|
6d3fbba4cd | ||
|
65772919a1 | ||
|
623abaa243 | ||
|
2e5654e583 | ||
|
2f1f196251 | ||
|
39cbc73a9f | ||
|
e75d2ca5d6 | ||
|
09046e0a2f | ||
|
4cf65a3faf | ||
|
fbddf063cb | ||
|
89e8a05815 | ||
|
556ec0cf80 | ||
|
8ebc4c90c3 | ||
|
73fc469c4c | ||
|
5620ef8c43 | ||
|
b539de9753 | ||
|
3f4eed670f | ||
|
0fd17a98ff | ||
|
69bf439fac | ||
|
144b117886 | ||
|
6d92f13bcd | ||
|
cad8df587d | ||
|
eb9142ac14 | ||
|
0c8529eca1 | ||
|
436c5df15f | ||
|
cadd3350ea | ||
|
f198632834 | ||
|
85f8971d8d | ||
|
497b5bc5a9 | ||
|
e00c6f2091 | ||
|
b6725730f5 | ||
|
6f6e9b8d82 | ||
|
d684527b27 | ||
|
6c38946bf0 | ||
|
0d213f9d00 | ||
|
c151e24bb8 | ||
|
6a88d08551 | ||
|
a179f00a62 | ||
|
62081d50d1 | ||
|
faeb5fa2e1 | ||
|
ff0a825356 | ||
|
6d74ff5600 | ||
|
5163e17f14 | ||
|
a1ef6be18a | ||
|
a453ae105a | ||
|
d7215df688 | ||
|
cff2024c2e | ||
|
0df082d4e1 | ||
|
991496a4f4 | ||
|
c0ceb74931 | ||
|
d547db0648 | ||
|
d0b3dcd623 | ||
|
271b7322d3 | ||
|
6b4cc38de6 | ||
|
c8c1a76381 | ||
|
af8e91f446 | ||
|
b1a7f71ef4 | ||
|
a897561c11 | ||
|
85da18e38f | ||
|
c044312b3c | ||
|
0a79f5d1b1 | ||
|
6c20f2c4d9 | ||
|
87d4660aa6 | ||
|
0b9b6401d6 | ||
|
3ce86cee1f | ||
|
a14362b183 | ||
|
cc5d99431f | ||
|
1892cf0a7e | ||
|
73f194f422 | ||
|
232efdaa8c | ||
|
edf8d14f09 | ||
|
83d7702f28 | ||
|
43cb7718e6 | ||
|
d20ba5d179 | ||
|
dd9cfec0e7 | ||
|
02c037b5cb | ||
|
ca9191fcb1 | ||
|
561f1dfcde | ||
|
9708089c1e | ||
|
37b36ef332 | ||
|
4e98699ee1 | ||
|
be17ba9044 | ||
|
7313b0284c | ||
|
d851a65548 | ||
|
6de9a5032d | ||
|
21c16f991e | ||
|
3cf23176f6 | ||
|
25e2d4af6f | ||
|
40e2d3d84b | ||
|
833f21c225 | ||
|
2a904af8e7 | ||
|
177555e0d1 | ||
|
95437fbf89 | ||
|
09429e6021 | ||
|
07880c76ed | ||
|
98e12fbc2e | ||
|
d58aa827a4 | ||
|
722b777ee8 | ||
|
3861177919 | ||
|
6f87eaca84 | ||
|
92a1ee2128 | ||
|
4b93738773 | ||
|
ec032ffd75 | ||
|
64b38dbec8 | ||
|
413190d12f | ||
|
0eae77599e | ||
|
4da2082c07 | ||
|
bb5caf093a | ||
|
565c133662 | ||
|
e5c4699923 | ||
|
639f05da7e | ||
|
d853f9abae | ||
|
ba111a5cb7 | ||
|
bb080a262e | ||
|
b4b652d696 | ||
|
d1fcff0a08 | ||
|
792ad5ccff | ||
|
ffee1ebad2 | ||
|
6985ad67fe | ||
|
630f4ffafb | ||
|
1f2b35fef2 | ||
|
d906fb23b0 | ||
|
7c6b9a67f6 | ||
|
1da83854b0 | ||
|
29bb3d5a5a | ||
|
13017f711f | ||
|
82524ba034 | ||
|
2e96512f26 | ||
|
5f1b41eb42 | ||
|
03ebc5375b | ||
|
8f12a0fffb | ||
|
7513fab5ad | ||
|
342fbbce34 | ||
|
5b31736785 | ||
|
478fc39650 | ||
|
d7fb0ac298 | ||
|
8124b61d2b | ||
|
4191a86895 | ||
|
c7a7e034ed | ||
|
2c8678417c | ||
|
059d88ce75 | ||
|
12ac0d3032 | ||
|
ed5f7f22b8 | ||
|
7441d04a28 | ||
|
3e32a6da32 | ||
|
47fca465ba | ||
|
084a8fbd74 | ||
|
1775fb3776 | ||
|
80399941b2 | ||
|
a5e7e80cda | ||
|
c3ccdcec5d | ||
|
30cf26e1f6 | ||
|
66a69dc79b | ||
|
6d522db16c | ||
|
245da3b142 | ||
|
89bcd3dc3e | ||
|
2595059146 | ||
|
bae7a4d16b | ||
|
e63c6b91dc | ||
|
40f6c77775 | ||
|
7e83b9c49e | ||
|
a21ad0d7c4 | ||
|
98f3cab953 | ||
|
ef57fd2c5f | ||
|
6f4da45eeb | ||
|
864b4a1652 | ||
|
b49d9b7485 | ||
|
03f5cc8c79 | ||
|
0b38469385 | ||
|
d30528795b | ||
|
bdf5a276d3 | ||
|
56665d30a3 | ||
|
16081b2878 | ||
|
18701c97df | ||
|
8e88e462ee | ||
|
e6cd178881 | ||
|
1bfb0e94a3 | ||
|
9ef2f87adb | ||
|
dc8bb7e2a3 | ||
|
d28599f49d | ||
|
a46759990d | ||
|
5cbf07e9f5 | ||
|
b0bdceac34 | ||
|
b2d281e5ab | ||
|
f13f25db3e | ||
|
607f4ed354 | ||
|
9895200f79 | ||
|
23da9e72eb | ||
|
bebeacc895 | ||
|
8e110b063c | ||
|
eb722fc799 | ||
|
7eb7a477d0 | ||
|
a01387b1af | ||
|
a528b0a40f | ||
|
cbad6f95ea | ||
|
9a905723db | ||
|
8a4b84b9d7 | ||
|
7790aa7e0c | ||
|
5670c82b0d | ||
|
c6e1af7ff4 | ||
|
767b97311b | ||
|
617a723a16 | ||
|
0e01e5c91e | ||
|
27d3d93b7c | ||
|
c0dfecdd1a | ||
|
8ca7815baf | ||
|
946f4bb77d | ||
|
b3c4d46ca9 | ||
|
ecef51bc47 | ||
|
c4956c40f8 | ||
|
6fe0d3ab7c | ||
|
573adb507f | ||
|
9dabd45086 | ||
|
2a6dc7e328 | ||
|
40cb4bf236 | ||
|
12f8469172 | ||
|
d936e9938d | ||
|
a667dc9787 | ||
|
ef2f205d6b | ||
|
cd269a9ce1 | ||
|
f1b0a20b37 | ||
|
aeb585527d | ||
|
a4a2c88ed7 | ||
|
1918557e78 | ||
|
00f02d9d0c | ||
|
59ce931955 | ||
|
f9eae2025f | ||
|
7062e864c8 | ||
|
e4ee28b199 | ||
|
0ad7a968ba | ||
|
1601829d22 | ||
|
ef1569b4d1 | ||
|
831e7a2268 | ||
|
8b44b00da3 | ||
|
837c82d8b8 | ||
|
07e9db881c | ||
|
7c61312974 | ||
|
744df7adf3 | ||
|
28e0485156 | ||
|
7b13571587 | ||
|
c4570fe272 | ||
|
6d2acbb07b | ||
|
d83c53437e | ||
|
ccf38a4005 | ||
|
f86b9b2abd | ||
|
bb69145861 | ||
|
1a875b1c10 | ||
|
899734d81d | ||
|
57b3f7cf21 | ||
|
c23967b03b | ||
|
eb35678f0d | ||
|
19033a4a39 | ||
|
f5b277548b | ||
|
7ad9ab0da2 | ||
|
2e001f465e | ||
|
507508b66d | ||
|
36b6d0769b | ||
|
cfcfde0480 | ||
|
63ddee1be1 | ||
|
193a7d56c5 | ||
|
b5fbba6e53 | ||
|
9dc485c56a | ||
|
67dd2e6676 | ||
|
71cbb23b42 | ||
|
35439819d3 | ||
|
281a8a9f68 | ||
|
18a908c770 | ||
|
a84735d3e9 | ||
|
02c0627452 | ||
|
9817848482 | ||
|
ae6d8239db | ||
|
75b333f805 | ||
|
45f57ceca1 | ||
|
f07cc69531 | ||
|
28cd764a31 | ||
|
447c7b365d | ||
|
9a18393fc5 | ||
|
539e436893 | ||
|
35e6d4fcdf | ||
|
f7da6ba4e5 | ||
|
2ba2d12f8b | ||
|
f171c611c2 | ||
|
8e9fa50385 | ||
|
96a42689fd | ||
|
858f8257a6 | ||
|
977056a075 | ||
|
03fc337242 | ||
|
28bc58ccd2 | ||
|
48a41966fd | ||
|
730ca109b7 | ||
|
fcdfd2f799 | ||
|
a489b71bb2 | ||
|
6bfe17c3fc | ||
|
2a691ce7d4 | ||
|
c7594f569a | ||
|
64d6c0668f | ||
|
e4c34683a4 | ||
|
ff2dc11f09 | ||
|
2bcfae861f | ||
|
01052ca89d | ||
|
9a3bd0b258 | ||
|
a25325fc7d | ||
|
6267af0315 | ||
|
668c2ba107 | ||
|
143b0827dd | ||
|
5d77f86575 | ||
|
507813529e | ||
|
e583d05868 | ||
|
242e8af3a7 | ||
|
2bc581d4f6 | ||
|
cf406ec953 | ||
|
76c5a97efe | ||
|
ddf1bcf094 | ||
|
0c622863cf | ||
|
30fdd103a2 | ||
|
50c98de60f | ||
|
320fae37a4 | ||
|
e4332cc72a | ||
|
5f04c95b79 | ||
|
f7023246d9 | ||
|
90b65715ae | ||
|
8c0a84c536 | ||
|
e99d4e579c | ||
|
8353a9ed44 | ||
|
77e20bda2a | ||
|
1758ef58b5 | ||
|
1bf6e93461 | ||
|
023251dee1 | ||
|
76d285a6f2 | ||
|
c4b1b1937e | ||
|
dee3f7e1c5 | ||
|
1d84d40518 | ||
|
7710322fd3 | ||
|
fcc1598086 | ||
|
b8fb05fbd0 | ||
|
24005dc4ed | ||
|
b1270264a1 | ||
|
4f162dc6e3 | ||
|
3c6788fd26 | ||
|
c01bd008db | ||
|
1c99d52b91 | ||
|
c4276955ba | ||
|
45a34e2763 | ||
|
b609065bc4 | ||
|
3583b00a77 | ||
|
e08090095f | ||
|
9aec39d3cb | ||
|
b7cfe89445 | ||
|
ce68f366cb | ||
|
eedf6880db | ||
|
8a02128473 | ||
|
5db556214c | ||
|
fc8835aa6f | ||
|
8f863effbc | ||
|
5aa782acc0 | ||
|
f994087291 | ||
|
19b53082a3 | ||
|
c939be2d2d | ||
|
531b1d7df4 | ||
|
0e667be7be | ||
|
15e47a1f07 | ||
|
241162f261 | ||
|
e91a03f40f | ||
|
57b9ad0d95 | ||
|
f1c78e659c | ||
|
01ba04139f | ||
|
94b790728e | ||
|
cf3b2786ae | ||
|
a250b40c80 | ||
|
772bb53d88 |
20
.travis.yml
20
.travis.yml
|
@ -1,20 +0,0 @@
|
|||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libsdl1.2-dev
|
||||
- libgtk2.0-dev
|
||||
|
||||
script:
|
||||
- cd BasiliskII/src/Unix
|
||||
- NO_CONFIGURE=1 ./autogen.sh
|
||||
- ./configure --enable-sdl-video --enable-sdl-audio --disable-vosf --disable-jit-compiler --with-x --with-gtk --with-mon
|
||||
- make -j 4
|
153
BasiliskII/src/CrossPlatform/sigsegv.cpp
Executable file → Normal file
153
BasiliskII/src/CrossPlatform/sigsegv.cpp
Executable file → Normal file
|
@ -274,13 +274,20 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
|||
#define SIGSEGV_REGISTER_FILE ((unsigned long *)SIGSEGV_CONTEXT_REGS), SIGSEGV_SPARC_GWINDOWS, SIGSEGV_SPARC_RWINDOW
|
||||
#define SIGSEGV_SKIP_INSTRUCTION sparc_skip_instruction
|
||||
#endif
|
||||
#if defined(__i386__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
#include <sys/regset.h>
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[EIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#endif
|
||||
#if (defined(x86_64) || defined(__x86_64__))
|
||||
#include <sys/regset.h>
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_RIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
|
@ -302,6 +309,12 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
|||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_EIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
#include <sys/ucontext.h>
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_RIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#endif
|
||||
#if (defined(powerpc) || defined(__powerpc__))
|
||||
#include <sys/ucontext.h>
|
||||
|
@ -323,12 +336,12 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
|||
#endif
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[14] /* should use REG_EIP instead */
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_EIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_RIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#elif (defined(ia64) || defined(__ia64__))
|
||||
|
@ -346,6 +359,11 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
|||
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.arm_pc)
|
||||
#define SIGSEGV_REGISTER_FILE (&SIGSEGV_CONTEXT_REGS.arm_r0)
|
||||
#define SIGSEGV_SKIP_INSTRUCTION arm_skip_instruction
|
||||
#elif (defined(aarch64) || defined(__aarch64__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.pc)
|
||||
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&SIGSEGV_CONTEXT_REGS.regs)
|
||||
#define SIGSEGV_SKIP_INSTRUCTION aarch64_skip_instruction
|
||||
#elif (defined(mips) || defined(__mips__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.pc)
|
||||
|
@ -747,38 +765,37 @@ handleExceptions(void *priv)
|
|||
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
// Decode and skip X86 instruction
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86)) || (defined(__x86_64__) || defined(_M_X64))
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || defined(x86_64) || defined(__x86_64__) || defined(_M_X64))
|
||||
#if defined(__linux__)
|
||||
enum {
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
X86_REG_EIP = 14,
|
||||
X86_REG_EAX = 11,
|
||||
X86_REG_ECX = 10,
|
||||
X86_REG_EDX = 9,
|
||||
X86_REG_EBX = 8,
|
||||
X86_REG_ESP = 7,
|
||||
X86_REG_EBP = 6,
|
||||
X86_REG_ESI = 5,
|
||||
X86_REG_EDI = 4
|
||||
#endif
|
||||
#if defined(__x86_64__)
|
||||
X86_REG_R8 = 0,
|
||||
X86_REG_R9 = 1,
|
||||
X86_REG_R10 = 2,
|
||||
X86_REG_R11 = 3,
|
||||
X86_REG_R12 = 4,
|
||||
X86_REG_R13 = 5,
|
||||
X86_REG_R14 = 6,
|
||||
X86_REG_R15 = 7,
|
||||
X86_REG_EDI = 8,
|
||||
X86_REG_ESI = 9,
|
||||
X86_REG_EBP = 10,
|
||||
X86_REG_EBX = 11,
|
||||
X86_REG_EDX = 12,
|
||||
X86_REG_EAX = 13,
|
||||
X86_REG_ECX = 14,
|
||||
X86_REG_ESP = 15,
|
||||
X86_REG_EIP = 16
|
||||
X86_REG_EIP = REG_EIP,
|
||||
X86_REG_EAX = REG_EAX,
|
||||
X86_REG_ECX = REG_ECX,
|
||||
X86_REG_EDX = REG_EDX,
|
||||
X86_REG_EBX = REG_EBX,
|
||||
X86_REG_ESP = REG_ESP,
|
||||
X86_REG_EBP = REG_EBP,
|
||||
X86_REG_ESI = REG_ESI,
|
||||
X86_REG_EDI = REG_EDI
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_R8 = REG_R8,
|
||||
X86_REG_R9 = REG_R9,
|
||||
X86_REG_R10 = REG_R10,
|
||||
X86_REG_R11 = REG_R11,
|
||||
X86_REG_R12 = REG_R12,
|
||||
X86_REG_R13 = REG_R13,
|
||||
X86_REG_R14 = REG_R14,
|
||||
X86_REG_R15 = REG_R15,
|
||||
X86_REG_EDI = REG_RDI,
|
||||
X86_REG_ESI = REG_RSI,
|
||||
X86_REG_EBP = REG_RBP,
|
||||
X86_REG_EBX = REG_RBX,
|
||||
X86_REG_EDX = REG_RDX,
|
||||
X86_REG_EAX = REG_RAX,
|
||||
X86_REG_ECX = REG_RCX,
|
||||
X86_REG_ESP = REG_RSP,
|
||||
X86_REG_EIP = REG_RIP
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
@ -794,6 +811,24 @@ enum {
|
|||
X86_REG_EBP = _REG_EBP,
|
||||
X86_REG_ESI = _REG_ESI,
|
||||
X86_REG_EDI = _REG_EDI
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_EIP = _REG_RIP,
|
||||
X86_REG_EAX = _REG_RAX,
|
||||
X86_REG_ECX = _REG_RCX,
|
||||
X86_REG_EDX = _REG_RDX,
|
||||
X86_REG_EBX = _REG_RBX,
|
||||
X86_REG_ESP = _REG_RSP,
|
||||
X86_REG_EBP = _REG_RBP,
|
||||
X86_REG_ESI = _REG_RSI,
|
||||
X86_REG_EDI = _REG_RDI,
|
||||
X86_REG_R8 = _REG_R8,
|
||||
X86_REG_R9 = _REG_R9,
|
||||
X86_REG_R10 = _REG_R10,
|
||||
X86_REG_R11 = _REG_R11,
|
||||
X86_REG_R12 = _REG_R12,
|
||||
X86_REG_R13 = _REG_R13,
|
||||
X86_REG_R14 = _REG_R14,
|
||||
X86_REG_R15 = _REG_R15
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
@ -809,8 +844,7 @@ enum {
|
|||
X86_REG_EBP = 2,
|
||||
X86_REG_ESI = 1,
|
||||
X86_REG_EDI = 0
|
||||
#endif
|
||||
#if (defined(x86_64) || defined(__x86_64__))
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_EDI = 0,
|
||||
X86_REG_ESI = 1,
|
||||
X86_REG_EDX = 2,
|
||||
|
@ -833,7 +867,7 @@ enum {
|
|||
#endif
|
||||
#if defined(__OpenBSD__)
|
||||
enum {
|
||||
#if defined(__i386__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
// EDI is the first register we consider
|
||||
#define OREG(REG) offsetof(struct sigcontext, sc_##REG)
|
||||
#define DREG(REG) ((OREG(REG) - OREG(edi)) / 4)
|
||||
|
@ -854,7 +888,7 @@ enum {
|
|||
#if defined(__sun__)
|
||||
// Same as for Linux, need to check for x86-64
|
||||
enum {
|
||||
#if defined(__i386__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
X86_REG_EIP = EIP,
|
||||
X86_REG_EAX = EAX,
|
||||
X86_REG_ECX = ECX,
|
||||
|
@ -864,6 +898,24 @@ enum {
|
|||
X86_REG_EBP = EBP,
|
||||
X86_REG_ESI = ESI,
|
||||
X86_REG_EDI = EDI
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_R8 = REG_R8,
|
||||
X86_REG_R9 = REG_R9,
|
||||
X86_REG_R10 = REG_R10,
|
||||
X86_REG_R11 = REG_R11,
|
||||
X86_REG_R12 = REG_R12,
|
||||
X86_REG_R13 = REG_R13,
|
||||
X86_REG_R14 = REG_R14,
|
||||
X86_REG_R15 = REG_R15,
|
||||
X86_REG_EDI = REG_RDI,
|
||||
X86_REG_ESI = REG_RSI,
|
||||
X86_REG_EBP = REG_RBP,
|
||||
X86_REG_EBX = REG_RBX,
|
||||
X86_REG_EDX = REG_RDX,
|
||||
X86_REG_EAX = REG_RAX,
|
||||
X86_REG_ECX = REG_RCX,
|
||||
X86_REG_ESP = REG_RSP,
|
||||
X86_REG_EIP = REG_RIP
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
@ -1018,6 +1070,15 @@ static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs)
|
|||
transfer_size = SIZE_WORD;
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
// Address size override
|
||||
if (*eip == 0x67) {
|
||||
// 32-bit address
|
||||
eip++;
|
||||
len++;
|
||||
}
|
||||
#endif
|
||||
|
||||
// REX prefix
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
struct rex_t {
|
||||
|
@ -2499,6 +2560,22 @@ static bool arm_skip_instruction(unsigned long * regs)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef _STRUCT_ARM_THREAD_STATE64
|
||||
static bool aarch64_skip_instruction(unsigned long *regs) {
|
||||
_STRUCT_ARM_THREAD_STATE64 *ts = (_STRUCT_ARM_THREAD_STATE64 *)regs;
|
||||
if (!ts->__pc) return false;
|
||||
ts->__pc += 4;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
static bool aarch64_skip_instruction(unsigned long *regs) {
|
||||
unsigned long long *r = (unsigned long long *)regs;
|
||||
if (!r[32]) return false;
|
||||
r[32] += 4;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fallbacks
|
||||
#ifndef SIGSEGV_FAULT_ADDRESS_FAST
|
||||
|
@ -3230,7 +3307,7 @@ static sigsegv_return_t sigsegv_insn_handler(sigsegv_info_t *sip)
|
|||
// More sophisticated tests for instruction skipper
|
||||
static bool arch_insn_skipper_tests()
|
||||
{
|
||||
#if (defined(i386) || defined(__i386__)) || (defined(__x86_64__) || defined(_M_X64))
|
||||
#if (defined(i386) || defined(__i386__) || defined(x86_64) || defined(__x86_64__) || defined(_M_X64))
|
||||
static const unsigned char code[] = {
|
||||
0x8a, 0x00, // mov (%eax),%al
|
||||
0x8a, 0x2c, 0x18, // mov (%eax,%ebx,1),%ch
|
||||
|
@ -3244,7 +3321,7 @@ static bool arch_insn_skipper_tests()
|
|||
0x8b, 0x0c, 0x18, // mov (%eax,%ebx,1),%ecx
|
||||
0x89, 0x00, // mov %eax,(%eax)
|
||||
0x89, 0x0c, 0x18, // mov %ecx,(%eax,%ebx,1)
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#if defined(x86_64) || defined(__x86_64__) || defined(_M_X64)
|
||||
0x44, 0x8a, 0x00, // mov (%rax),%r8b
|
||||
0x44, 0x8a, 0x20, // mov (%rax),%r12b
|
||||
0x42, 0x8a, 0x3c, 0x10, // mov (%rax,%r10,1),%dil
|
||||
|
|
|
@ -105,6 +105,22 @@ extern "C" {
|
|||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */
|
||||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
#if __DARWIN_UNIX03 && defined _STRUCT_ARM_THREAD_STATE64
|
||||
#define MACH_FIELD_NAME(X) __CONCAT(__,X)
|
||||
#endif
|
||||
#define SIGSEGV_EXCEPTION_STATE_TYPE arm_exception_state64_t
|
||||
#define SIGSEGV_EXCEPTION_STATE_FLAVOR ARM_EXCEPTION_STATE64
|
||||
#define SIGSEGV_EXCEPTION_STATE_COUNT ARM_EXCEPTION_STATE64_COUNT
|
||||
#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(far)
|
||||
#define SIGSEGV_THREAD_STATE_TYPE arm_thread_state64_t
|
||||
#define SIGSEGV_THREAD_STATE_FLAVOR ARM_THREAD_STATE64
|
||||
#define SIGSEGV_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT
|
||||
#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(x[0])) /* x[0] is the first GPR we consider */
|
||||
#define SIGSEGV_SKIP_INSTRUCTION aarch64_skip_instruction
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define SIGSEGV_FAULT_ADDRESS_FAST (((uint64_t)code[1])|0x100000000)
|
||||
#else
|
||||
|
|
|
@ -305,6 +305,7 @@ static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
|
|||
#define FB_DEPTH 24
|
||||
#include "video_blit.h"
|
||||
|
||||
#if !(REAL_ADDRESSING || DIRECT_ADDRESSING || USE_SDL_VIDEO)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- 1-bit indexed to 8-bit color mode conversion --- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -325,6 +326,7 @@ static void Blit_Expand_1_To_8_Color(uint8 * dest, const uint8 * p, uint32 lengt
|
|||
*q++ = CONVERT_BW(c & 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- 1/2/4-bit indexed to 8-bit mode conversion --- */
|
||||
|
@ -507,7 +509,11 @@ static Screen_blit_func_info Screen_blitters[] = {
|
|||
{ 16, 0x00f800, 0x0007e0, 0x00001f, Blit_RGB565_NBO , Blit_RGB565_OBO }, // OK (NBO)
|
||||
{ 24, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
|
||||
{ 24, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
|
||||
#ifdef ENABLE_VOSF
|
||||
{ 32, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
|
||||
#else
|
||||
{ 32, 0xff000000, 0x00ff0000, 0x0000ff00, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
|
||||
#endif
|
||||
{ 32, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
|
||||
#endif
|
||||
{ 32, 0xff00, 0xff0000, 0xff000000, Blit_Copy_Raw , Blit_Copy_Raw } // OK
|
||||
|
@ -529,9 +535,7 @@ bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_or
|
|||
// Windowed 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines
|
||||
Screen_blit = Blit_Copy_Raw;
|
||||
|
||||
#if __MACOSX__ && !defined(SHEEPSHAVER)
|
||||
// dludwig@pobox.com, HACK: This works on OSX (64-bit, at least), but not Linux (32-bit?). Why?
|
||||
// To note, __MACOSX__ is an SDL-declared macro (for platform identification at compile time).
|
||||
#if !DIRECT_ADDRESSING && defined(__aarch64__)
|
||||
} else if (mac_depth == 16) {
|
||||
|
||||
Screen_blit = Blit_Copy_Raw;
|
||||
|
|
|
@ -540,6 +540,7 @@ static void update_display_window_vosf(VIDEO_DRV_WIN_INIT)
|
|||
|
||||
#ifndef TEST_VOSF_PERFORMANCE
|
||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||
|
||||
static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
||||
{
|
||||
VIDEO_MODE_INIT;
|
||||
|
@ -574,8 +575,10 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
|||
const uint32 n_pixels = 64;
|
||||
const uint32 n_chunks = VIDEO_MODE_X / n_pixels;
|
||||
const uint32 n_pixels_left = VIDEO_MODE_X - (n_chunks * n_pixels);
|
||||
const uint32 src_chunk_size = src_bytes_per_row / n_chunks;
|
||||
const uint32 dst_chunk_size = dst_bytes_per_row / n_chunks;
|
||||
const uint32 src_chunk_size = TrivialBytesPerRow(n_pixels, VIDEO_MODE_DEPTH);
|
||||
const uint32 dst_chunk_size = TrivialBytesPerRow(n_pixels, DepthModeForPixelDepth(VIDEO_DRV_DEPTH));
|
||||
assert(src_chunk_size * n_chunks <= src_bytes_per_row);
|
||||
assert(dst_chunk_size * n_chunks <= dst_bytes_per_row);
|
||||
const uint32 src_chunk_size_left = src_bytes_per_row - (n_chunks * src_chunk_size);
|
||||
const uint32 dst_chunk_size_left = dst_bytes_per_row - (n_chunks * dst_chunk_size);
|
||||
|
||||
|
@ -643,8 +646,6 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
|||
memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left);
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size_left);
|
||||
}
|
||||
i1 += src_chunk_size_left;
|
||||
i2 += dst_chunk_size_left;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
const int x = n_chunks * n_pixels;
|
||||
if (x < bb[bbi].x) {
|
||||
|
@ -658,7 +659,8 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
|||
bb[bbi].w = x + n_pixels_left - bb[bbi].x;
|
||||
#endif
|
||||
}
|
||||
i2 += scr_bytes_left;
|
||||
i1 += src_chunk_size_left;
|
||||
i2 += dst_chunk_size_left + scr_bytes_left;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
bb[bbi].h++;
|
||||
if (bb[bbi].w && (j == y1 || j == y2 - 1 || j == y2)) {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include "vm_alloc.h"
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
|
@ -71,7 +72,7 @@ typedef unsigned long vm_uintptr_t;
|
|||
#ifndef MAP_32BIT
|
||||
#define MAP_32BIT 0
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#define FORCE_MAP_32BIT MAP_FIXED
|
||||
#else
|
||||
#define FORCE_MAP_32BIT MAP_32BIT
|
||||
|
@ -86,7 +87,7 @@ typedef unsigned long vm_uintptr_t;
|
|||
#define MAP_EXTRA_FLAGS (MAP_32BIT)
|
||||
|
||||
#ifdef HAVE_MMAP_VM
|
||||
#if (defined(__linux__) && defined(__i386__)) || defined(__FreeBSD__) || HAVE_LINKER_SCRIPT
|
||||
#if (defined(__linux__) && defined(__i386__)) || defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || HAVE_LINKER_SCRIPT
|
||||
/* Force a reasonnable address below 0x80000000 on x86 so that we
|
||||
don't get addresses above when the program is run on AMD64.
|
||||
NOTE: this is empirically determined on Linux/x86. */
|
||||
|
@ -222,6 +223,21 @@ void vm_exit(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void *reserved_buf;
|
||||
static const size_t RESERVED_SIZE = 80 * 1024 * 1024; // for 6K Retina
|
||||
|
||||
void *vm_acquire_reserved(size_t size) {
|
||||
assert(reserved_buf && size <= RESERVED_SIZE);
|
||||
return reserved_buf;
|
||||
}
|
||||
|
||||
int vm_init_reserved(void *hostAddress) {
|
||||
int result = vm_acquire_fixed(hostAddress, RESERVED_SIZE);
|
||||
if (result >= 0)
|
||||
reserved_buf = hostAddress;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Allocate zero-filled memory of SIZE bytes. The mapping is private
|
||||
and default protection bits are read / write. The return value
|
||||
is the actual mapping address chosen or VM_MAP_FAILED for errors. */
|
||||
|
@ -243,22 +259,30 @@ void * vm_acquire(size_t size, int options)
|
|||
|
||||
#if defined(HAVE_MACH_VM)
|
||||
// vm_allocate() returns a zero-filled memory region
|
||||
kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, TRUE);
|
||||
kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, reserved_buf ? size : size + RESERVED_SIZE, TRUE);
|
||||
if (ret_code != KERN_SUCCESS) {
|
||||
errno = vm_error(ret_code);
|
||||
return VM_MAP_FAILED;
|
||||
}
|
||||
if (!reserved_buf)
|
||||
reserved_buf = (char *)addr + size;
|
||||
#elif defined(HAVE_MMAP_VM)
|
||||
int fd = zero_fd;
|
||||
int the_map_flags = translate_map_flags(options) | map_flags;
|
||||
|
||||
#ifdef __aarch64__
|
||||
if ((addr = mmap((caddr_t)next_address, reserved_buf ? size : size + RESERVED_SIZE, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
if (!reserved_buf)
|
||||
reserved_buf = (char *)addr + size;
|
||||
#else
|
||||
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
#endif
|
||||
#if USE_JIT
|
||||
// Sanity checks for 64-bit platforms
|
||||
if (sizeof(void *) == 8 && (options & VM_MAP_32BIT) && !((char *)addr <= (char *)0xffffffff))
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
#endif
|
||||
next_address = (char *)addr + size;
|
||||
#elif defined(HAVE_WIN32_VM)
|
||||
int alloc_type = MEM_RESERVE | MEM_COMMIT;
|
||||
|
|
|
@ -99,6 +99,10 @@ extern void vm_exit(void);
|
|||
|
||||
extern void * vm_acquire(size_t size, int options = VM_MAP_DEFAULT);
|
||||
|
||||
extern void * vm_acquire_reserved(size_t size);
|
||||
|
||||
extern int vm_init_reserved(void * host_address);
|
||||
|
||||
/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned).
|
||||
Returns 0 if successful, -1 on errors. */
|
||||
|
||||
|
|
|
@ -51,23 +51,23 @@ void AudioDevice::Init(AudioDeviceID devid, bool isInput)
|
|||
UInt32 propsize;
|
||||
|
||||
propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset));
|
||||
|
||||
propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
|
||||
propsize = sizeof(AudioStreamBasicDescription);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat));
|
||||
|
||||
}
|
||||
|
||||
void AudioDevice::SetBufferSize(UInt32 size)
|
||||
{
|
||||
UInt32 propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size));
|
||||
__Verify_noErr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size));
|
||||
|
||||
propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
}
|
||||
|
||||
int AudioDevice::CountChannels()
|
||||
|
@ -92,6 +92,6 @@ int AudioDevice::CountChannels()
|
|||
|
||||
char * AudioDevice::GetName(char *buf, UInt32 maxlen)
|
||||
{
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf));
|
||||
return buf;
|
||||
}
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -11,7 +11,7 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>BasiliskII.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string></string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef MACOSX_SOUND_IF
|
||||
#define MACOSX_SOUND_IF
|
||||
|
||||
typedef int (*audioCallback)(void);
|
||||
|
||||
|
@ -39,3 +41,5 @@ class OSXsoundOutput {
|
|||
unsigned int bufferSizeFrames();
|
||||
int sendAudioBuffer(void *buffer, int numFrames);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
29
BasiliskII/src/MacOSX/Makefile.gencpu
Normal file
29
BasiliskII/src/MacOSX/Makefile.gencpu
Normal file
|
@ -0,0 +1,29 @@
|
|||
SRC = $(PROJECT_DIR)/../uae_cpu
|
||||
DST = $(BUILT_PRODUCTS_DIR)/gencpu_output
|
||||
VPATH = $(SRC) $(SRC)/compiler
|
||||
CFLAGS = -DUSE_XCODE=1 -DUSE_JIT_FPU -I. -I../uae_cpu -I../UNIX
|
||||
CXXFLAGS = -stdlib=libc++ $(CFLAGS)
|
||||
|
||||
all: $(DST)/gencpu $(DST)/gencomp
|
||||
cd $(DST); ./gencpu; ./gencomp
|
||||
|
||||
$(DST)/gencpu: $(addprefix $(DST)/, defs68k.o readcpu.o gencpu.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/gencomp: $(addprefix $(DST)/, defs68k.o readcpu.o gencomp.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/defs68k.c: $(DST)/build68k
|
||||
$< < $(SRC)/table68k > $@
|
||||
|
||||
$(DST)/build68k: $(SRC)/build68k.c
|
||||
mkdir -p $(DST)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:; rm -fr $(DST)
|
29
BasiliskII/src/MacOSX/Makefile.gencpu_2021
Normal file
29
BasiliskII/src/MacOSX/Makefile.gencpu_2021
Normal file
|
@ -0,0 +1,29 @@
|
|||
SRC = $(PROJECT_DIR)/../uae_cpu_2021
|
||||
DST = $(BUILT_PRODUCTS_DIR)/gencpu_output_2021
|
||||
VPATH = $(SRC) $(SRC)/compiler
|
||||
CFLAGS = -DUSE_XCODE=1 -DUSE_JIT_FPU -I. -I../uae_cpu_2021 -I../UNIX
|
||||
CXXFLAGS = -stdlib=libc++ $(CFLAGS)
|
||||
|
||||
all: $(DST)/gencpu $(DST)/gencomp
|
||||
cd $(DST); ./gencpu; ./gencomp
|
||||
|
||||
$(DST)/gencpu: $(addprefix $(DST)/, defs68k.o readcpu.o gencpu.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/gencomp: $(addprefix $(DST)/, defs68k.o readcpu.o gencomp.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/defs68k.c: $(DST)/build68k
|
||||
$< < $(SRC)/table68k > $@
|
||||
|
||||
$(DST)/build68k: $(SRC)/build68k.c
|
||||
mkdir -p $(DST)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:; rm -fr $(DST)
|
|
@ -19,6 +19,8 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef USE_SDL_AUDIO
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -269,3 +271,5 @@ static int audioInt(void)
|
|||
TriggerInterrupt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,12 +59,6 @@ static bool should_clear = false;
|
|||
|
||||
static NSMutableDictionary *g_macScrap;
|
||||
|
||||
// flavor UTIs
|
||||
|
||||
static NSString * const UTF16_TEXT_FLAVOR_NAME = @"public.utf16-plain-text";
|
||||
static NSString * const TEXT_FLAVOR_NAME = @"com.apple.traditional-mac-plain-text";
|
||||
static NSString * const STYL_FLAVOR_NAME = @"net.cebix.basilisk.styl-data";
|
||||
|
||||
// font face types
|
||||
|
||||
enum {
|
||||
|
|
|
@ -681,7 +681,11 @@
|
|||
#define SIZEOF_LONG 8
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#ifdef CPU_x86_64
|
||||
#define SIZEOF_LONG_DOUBLE 16
|
||||
#else
|
||||
#define SIZEOF_LONG_DOUBLE 8
|
||||
#endif
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
|
@ -815,7 +819,32 @@
|
|||
<inttypes.h> don't define. */
|
||||
/* #undef uintmax_t */
|
||||
|
||||
#define FPU_UAE 1
|
||||
//#define FPU_IMPLEMENTATION 1
|
||||
#ifndef CPU_x86_64
|
||||
#define UPDATE_UAE
|
||||
#endif
|
||||
|
||||
#ifdef UPDATE_UAE
|
||||
#define DIRECT_ADDRESSING 1
|
||||
#define CPU_64_BIT
|
||||
#define USE_INLINING
|
||||
#ifdef CPU_x86_64
|
||||
#define FPU_IEEE
|
||||
#define WINUAE_ARANYM
|
||||
#else
|
||||
#define FPU_MPFR
|
||||
#endif
|
||||
#else
|
||||
#define FPU_IEEE
|
||||
#endif
|
||||
|
||||
#if USE_JIT
|
||||
#define DIRECT_ADDRESSING 1
|
||||
#define USE_JIT_FPU
|
||||
#define X86_64_ASSEMBLY
|
||||
#define OPTIMIZED_FLAGS
|
||||
#endif
|
||||
|
||||
#define ENABLE_MACOSX_ETHERHELPER
|
||||
#define BINCUE 1
|
||||
|
||||
#endif
|
||||
|
|
580
BasiliskII/src/MacOSX/etherhelpertool.c
Normal file
580
BasiliskII/src/MacOSX/etherhelpertool.c
Normal file
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
* etherhelpertool.c - Reads and writes raw ethernet packets usng bpf
|
||||
* interface.
|
||||
*
|
||||
* Copyright (C) 2010, Daniel Sumorok
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#define STR_MAX 256
|
||||
#define MAX_ARGV 10
|
||||
|
||||
static int open_bpf(char *ifname);
|
||||
static int open_tap(char *ifname);
|
||||
static int retreive_auth_info(void);
|
||||
static int main_loop(int sd, int use_bpf);
|
||||
static int run_cmd(const char *cmd);
|
||||
static void handler(int signum);
|
||||
static int install_signal_handlers();
|
||||
static void do_exit();
|
||||
|
||||
static char remove_bridge[STR_MAX];
|
||||
static const char *exec_name = "etherhelpertool";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *if_name;
|
||||
int ret = 255;
|
||||
int sd;
|
||||
int tapNum;
|
||||
int use_bpf;
|
||||
|
||||
if (argc != 2) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
if_name = argv[1];
|
||||
|
||||
do {
|
||||
ret = retreive_auth_info();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s: authorization failed.\n",
|
||||
exec_name);
|
||||
ret = 254;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp(if_name, "tap", 3) == 0) {
|
||||
sd = open_tap(if_name);
|
||||
use_bpf = 0;
|
||||
} else {
|
||||
sd = open_bpf(if_name);
|
||||
use_bpf = 1;
|
||||
}
|
||||
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: open device failed.\n",
|
||||
exec_name);
|
||||
ret = 253;
|
||||
break;
|
||||
}
|
||||
|
||||
if (install_signal_handlers() != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: failed to install signal handers.\n",
|
||||
exec_name);
|
||||
ret = 252;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = main_loop(sd, use_bpf);
|
||||
close(sd);
|
||||
} while (0);
|
||||
|
||||
do_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int main_loop(int sd, int use_bpf)
|
||||
{
|
||||
fd_set readSet;
|
||||
char *outgoing, *incoming;
|
||||
unsigned short *out_len;
|
||||
unsigned short *in_len;
|
||||
int in_index, out_index;
|
||||
u_int blen = 0;
|
||||
int ret;
|
||||
int fret = 0;
|
||||
struct bpf_hdr *hdr;
|
||||
int pkt_len;
|
||||
int frame_len;
|
||||
int pad;
|
||||
char c = 0;
|
||||
|
||||
if (use_bpf) {
|
||||
if (ioctl(sd, BIOCGBLEN, &blen) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: ioctl() failed.\n",
|
||||
exec_name);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
blen = 4096;
|
||||
}
|
||||
|
||||
incoming = malloc(blen);
|
||||
if (incoming == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -2;
|
||||
}
|
||||
|
||||
outgoing = malloc(blen);
|
||||
if (outgoing == NULL) {
|
||||
free(outgoing);
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -3;
|
||||
}
|
||||
|
||||
in_index = 0;
|
||||
out_index = 0;
|
||||
|
||||
out_len = (unsigned short *)outgoing;
|
||||
|
||||
/* Let our parent know we are ready for business. */
|
||||
write(0, &c, 1);
|
||||
|
||||
while (1) {
|
||||
int i;
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(0, &readSet);
|
||||
FD_SET(sd, &readSet);
|
||||
|
||||
ret = select(sd + 1, &readSet, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: select() failed.\n",
|
||||
exec_name);
|
||||
fret = -4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(0, &readSet)) {
|
||||
if (out_index < 2) {
|
||||
ret = read(0, outgoing + out_index, 2-out_index);
|
||||
} else {
|
||||
ret = read(0, outgoing + out_index, *out_len - out_index + 2);
|
||||
}
|
||||
|
||||
if (ret < 1) {
|
||||
if(ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: read() failed.\n",
|
||||
exec_name);
|
||||
}
|
||||
fret = -5;
|
||||
break;
|
||||
}
|
||||
|
||||
out_index += ret;
|
||||
if (out_index > 1) {
|
||||
if ((*out_len + 2) > blen) {
|
||||
fret = -6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (out_index == (*out_len + 2)) {
|
||||
ret = write(sd, out_len + 1, *out_len);
|
||||
if (ret != *out_len) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed.\n",
|
||||
exec_name);
|
||||
fret = -7;
|
||||
break;
|
||||
}
|
||||
out_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (use_bpf && FD_ISSET(sd, &readSet)) {
|
||||
int i;
|
||||
|
||||
ret = read(sd, incoming, blen);
|
||||
if (ret < 1) {
|
||||
if(ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: read() failed %d.\n",
|
||||
exec_name, errno);
|
||||
}
|
||||
fret = -8;
|
||||
break;
|
||||
}
|
||||
|
||||
hdr = (struct bpf_hdr *)incoming;
|
||||
in_len = (unsigned short *)(incoming + 16);
|
||||
|
||||
do {
|
||||
pkt_len = hdr->bh_caplen;
|
||||
frame_len = pkt_len + 18;
|
||||
|
||||
if ((pkt_len < 0) || (frame_len > ret) || (frame_len < 0)) {
|
||||
fret = -9;
|
||||
break;
|
||||
}
|
||||
*in_len = pkt_len;
|
||||
|
||||
if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) {
|
||||
fret = -10;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((frame_len & 0x03) == 0) {
|
||||
pad = 0;
|
||||
} else {
|
||||
pad = 4 - (frame_len & 0x03);
|
||||
}
|
||||
|
||||
ret -= (frame_len + pad);
|
||||
hdr = (struct bpf_hdr *)((unsigned char *)hdr + frame_len + pad);
|
||||
in_len = (unsigned short *)((unsigned char *)hdr + 16);
|
||||
} while (ret > 0);
|
||||
|
||||
if (fret != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: fret == %d.\n",
|
||||
exec_name, fret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_bpf && FD_ISSET(sd, &readSet)) {
|
||||
in_len = (unsigned short *)incoming;
|
||||
|
||||
pkt_len = read(sd, in_len + 1, blen-2);
|
||||
if (pkt_len < 14) {
|
||||
fprintf(stderr,
|
||||
"%s: read() returned %d.\n",
|
||||
exec_name, pkt_len);
|
||||
fret = -8;
|
||||
break;
|
||||
}
|
||||
|
||||
*in_len = pkt_len;
|
||||
if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed\n",
|
||||
exec_name);
|
||||
fret = -10;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(incoming);
|
||||
free(outgoing);
|
||||
|
||||
return fret;
|
||||
}
|
||||
|
||||
static int retreive_auth_info(void)
|
||||
{
|
||||
AuthorizationRef aRef;
|
||||
OSStatus status;
|
||||
AuthorizationRights myRights;
|
||||
AuthorizationRights *newRights;
|
||||
AuthorizationItem *myItem;
|
||||
AuthorizationItem myItems[1];
|
||||
AuthorizationItemSet *mySet;
|
||||
int i;
|
||||
|
||||
status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults);
|
||||
if (status != errAuthorizationSuccess) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = AuthorizationCopyInfo(aRef, NULL, &mySet);
|
||||
if (status != errAuthorizationSuccess) {
|
||||
AuthorizationFree(aRef, kAuthorizationFlagDestroyRights);
|
||||
return -1;
|
||||
}
|
||||
|
||||
myItems[0].name = "system.privilege.admin";
|
||||
myItems[0].valueLength = 0;
|
||||
myItems[0].value = NULL;
|
||||
myItems[0].flags = 0;
|
||||
|
||||
myRights.count = sizeof (myItems) / sizeof (myItems[0]);
|
||||
myRights.items = myItems;
|
||||
|
||||
status = AuthorizationCopyRights(aRef, &myRights, NULL,
|
||||
kAuthorizationFlagExtendRights,
|
||||
&newRights);
|
||||
if (status != errAuthorizationSuccess) {
|
||||
AuthorizationFreeItemSet(mySet);
|
||||
AuthorizationFree(aRef, kAuthorizationFlagDestroyRights);
|
||||
return -2;
|
||||
}
|
||||
|
||||
AuthorizationFreeItemSet(newRights);
|
||||
AuthorizationFreeItemSet(mySet);
|
||||
AuthorizationFree(aRef, kAuthorizationFlagDestroyRights);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_tap(char *ifname)
|
||||
{
|
||||
char str[STR_MAX] = {0};
|
||||
char ifstr[STR_MAX] = {0};
|
||||
char *interface;
|
||||
char *address = NULL;
|
||||
char *netmask = NULL;
|
||||
char *bridge = NULL;
|
||||
char *bridged_if = NULL;
|
||||
int sd;
|
||||
|
||||
snprintf(ifstr, STR_MAX, "%s", ifname);
|
||||
interface = strtok(ifstr, "/");
|
||||
bridge = strtok(NULL, "/");
|
||||
if (bridge != NULL) {
|
||||
bridged_if = strtok(NULL, "/");
|
||||
}
|
||||
interface = strtok(ifstr, ":");
|
||||
|
||||
address = strtok(NULL, ":");
|
||||
|
||||
if (address != NULL) {
|
||||
netmask = strtok(NULL, ":");
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/dev/%s", interface);
|
||||
|
||||
sd = open(str, O_RDWR);
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, interface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (address == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface);
|
||||
} else if (netmask == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s",
|
||||
interface, address);
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s",
|
||||
interface, address, netmask);
|
||||
}
|
||||
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to configure %s\n",
|
||||
exec_name, interface);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridge != NULL) {
|
||||
/* Check to see if bridge is alread up */
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge);
|
||||
if (run_cmd(str) == 0) {
|
||||
/* bridge is already up */
|
||||
if (bridged_if != NULL) {
|
||||
fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n",
|
||||
exec_name, bridge, bridged_if);
|
||||
}
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to create %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
strlcpy(remove_bridge, bridge, STR_MAX);
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridged_if != NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s",
|
||||
bridge, bridged_if);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, bridged_if, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s",
|
||||
bridge, interface);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, interface, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static int open_bpf(char *ifname)
|
||||
{
|
||||
u_int blen = 0;
|
||||
struct ifreq ifreq;
|
||||
u_int arg;
|
||||
|
||||
int sd = open("/dev/bpf2", O_RDWR);
|
||||
|
||||
if (sd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(sd, BIOCGBLEN, &blen) < 0) {
|
||||
close(sd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
bzero(&ifreq, sizeof(ifreq));
|
||||
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
|
||||
|
||||
arg = 0;
|
||||
if (ioctl(sd, BIOCSETIF, &ifreq) < 0) {
|
||||
close(sd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
arg = 0;
|
||||
if (ioctl(sd, BIOCSSEESENT, &arg) < 0) {
|
||||
close(sd);
|
||||
return -4;
|
||||
}
|
||||
|
||||
arg = 1;
|
||||
if (ioctl(sd, BIOCPROMISC, &arg) < 0) {
|
||||
close(sd);
|
||||
return -5;
|
||||
}
|
||||
|
||||
arg = 1;
|
||||
if (ioctl(sd, BIOCIMMEDIATE, &arg) < 0) {
|
||||
close(sd);
|
||||
return -6;
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static int run_cmd(const char *cmd) {
|
||||
char cmd_buffer[STR_MAX] = {0};
|
||||
char *argv[MAX_ARGV + 1] = {0};
|
||||
int i;
|
||||
pid_t pid, waitpid;
|
||||
int status = 0;
|
||||
|
||||
/* Collect arguments */
|
||||
strncpy(cmd_buffer, cmd, STR_MAX-1);
|
||||
|
||||
argv[0] = strtok(cmd_buffer, " ");
|
||||
for (i=1; i<MAX_ARGV; ++i) {
|
||||
argv[i] = strtok(NULL, " ");
|
||||
if (argv[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run sub process */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
|
||||
/* Child process */
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
if (execve(argv[0], argv, NULL) < 0) {
|
||||
perror("execve");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Wait for child to exit */
|
||||
waitpid = wait(&status);
|
||||
if (waitpid < 0) {
|
||||
perror("wait");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handler(int signum) {
|
||||
do_exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int install_signal_handlers() {
|
||||
struct sigaction act = {0};
|
||||
|
||||
act.sa_handler = handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
|
||||
if (sigaction(SIGINT, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGHUP, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_exit() {
|
||||
if (*remove_bridge) {
|
||||
char str[STR_MAX];
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s destroy", remove_bridge);
|
||||
run_cmd(str);
|
||||
}
|
||||
}
|
|
@ -251,7 +251,9 @@ static int open_rsrc(const char *path, int flag)
|
|||
char rsrc_path[MAX_PATH_LENGTH];
|
||||
make_rsrc_path(path, rsrc_path);
|
||||
|
||||
return open(rsrc_path, flag);
|
||||
int fd = open(rsrc_path, flag);
|
||||
if (fd < 0 && (flag == O_WRONLY || flag == O_RDWR)) fd = open(rsrc_path, flag | O_CREAT); // for APFS
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
|
@ -418,9 +420,9 @@ void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
|
|||
|
||||
// No native Finder info, translate file name extension to MacOS type/creator
|
||||
if (!is_dir) {
|
||||
int path_len = strlen(path);
|
||||
size_t path_len = strlen(path);
|
||||
for (int i=0; e2t_translation[i].ext; i++) {
|
||||
int ext_len = strlen(e2t_translation[i].ext);
|
||||
size_t ext_len = strlen(e2t_translation[i].ext);
|
||||
if (path_len < ext_len)
|
||||
continue;
|
||||
if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) {
|
||||
|
@ -624,11 +626,11 @@ const char *convert_string(const char *str, CFStringEncoding from, CFStringEncod
|
|||
// Convert from the host OS filename encoding to MacRoman
|
||||
const char *host_encoding_to_macroman(const char *filename)
|
||||
{
|
||||
return convert_string(filename, kCFStringEncodingUTF8, kCFStringEncodingMacRoman);
|
||||
return convert_string(filename, kCFStringEncodingUTF8, PrefsFindInt32("name_encoding"));
|
||||
}
|
||||
|
||||
// Convert from MacRoman to host OS filename encoding
|
||||
const char *macroman_to_host_encoding(const char *filename)
|
||||
{
|
||||
return convert_string(filename, kCFStringEncodingMacRoman, kCFStringEncodingUTF8);
|
||||
return convert_string(filename, PrefsFindInt32("name_encoding"), kCFStringEncodingUTF8);
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
#
|
||||
# run_build68k_for_xcode.sh
|
||||
#
|
||||
# Generates files for 68k emulation, via UAE's virtual cpu, for use on Mac OS X hosts
|
||||
#
|
||||
|
||||
if [ ! "$BUILT_PRODUCTS_DIR" ] || [ ! "$PROJECT_DIR" ]; then
|
||||
echo "ERROR: $(basename $0) must be run from an Xcode 'External Build System' target"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log some debugging information
|
||||
echo "1=$1"
|
||||
echo "BUILT_PRODUCTS_DIR=$BUILT_PRODUCTS_DIR"
|
||||
echo "PROJECT_DIR=$PROJECT_DIR"
|
||||
|
||||
# Perform actions, given the passed-in build step
|
||||
case "$1" in
|
||||
"clean")
|
||||
echo "Cleaning build68k output(s)"
|
||||
rm -rf "$BUILT_PRODUCTS_DIR/build68k_output"
|
||||
;;
|
||||
"")
|
||||
if [ ! -d "$BUILT_PRODUCTS_DIR" ]; then
|
||||
echo "No built products directory"
|
||||
exit 1
|
||||
fi
|
||||
echo "Running build68k"
|
||||
cd "$BUILT_PRODUCTS_DIR"
|
||||
mkdir -p build68k_output
|
||||
cd build68k_output
|
||||
cat "$PROJECT_DIR/../uae_cpu/table68k" | "$BUILT_PRODUCTS_DIR/build68k" > "./defs68k.c"
|
||||
ls -al
|
||||
;;
|
||||
esac
|
|
@ -1,37 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
#
|
||||
# run_gemcpu_for_xcode.sh
|
||||
#
|
||||
# Generates files for 68k emulation, via UAE's virtual cpu, for use on Mac OS X hosts
|
||||
#
|
||||
|
||||
if [ ! "$BUILT_PRODUCTS_DIR" ] || [ ! "$PROJECT_DIR" ]; then
|
||||
echo "ERROR: $(basename $0) must be run from an Xcode 'External Build System' target"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log some debugging information
|
||||
echo "1=$1"
|
||||
echo "BUILT_PRODUCTS_DIR=$BUILT_PRODUCTS_DIR"
|
||||
echo "PROJECT_DIR=$PROJECT_DIR"
|
||||
|
||||
# Perform actions, given the passed-in build step
|
||||
case "$1" in
|
||||
"clean")
|
||||
echo "Cleaning gencpu output(s)"
|
||||
rm -rf "$BUILT_PRODUCTS_DIR/gencpu_output"
|
||||
;;
|
||||
"")
|
||||
if [ ! -d "$BUILT_PRODUCTS_DIR" ]; then
|
||||
echo "No built products directory"
|
||||
exit 1
|
||||
fi
|
||||
echo "Running gencpu"
|
||||
cd "$BUILT_PRODUCTS_DIR"
|
||||
mkdir -p gencpu_output
|
||||
cd gencpu_output
|
||||
"$BUILT_PRODUCTS_DIR/gencpu"
|
||||
ls -al
|
||||
;;
|
||||
esac
|
135
BasiliskII/src/MacOSX/runtool.c
Normal file
135
BasiliskII/src/MacOSX/runtool.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* runtool.m - Run an external program as root for networking
|
||||
* Copyright (C) 2010, Daniel Sumorok
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
FILE * run_tool(const char *if_name, const char *tool_name);
|
||||
|
||||
FILE * run_tool(const char *if_name, const char *tool_name)
|
||||
{
|
||||
OSStatus auth_status;
|
||||
FILE *fp = NULL;
|
||||
char *args[] = {NULL, NULL, NULL};
|
||||
char path_buffer[256];
|
||||
AuthorizationFlags auth_flags;
|
||||
AuthorizationRef auth_ref;
|
||||
AuthorizationItem auth_items[1];
|
||||
AuthorizationRights auth_rights;
|
||||
CFBundleRef bundle_ref;
|
||||
CFURLRef url_ref;
|
||||
CFStringRef path_str;
|
||||
CFStringRef tool_name_str;
|
||||
char c;
|
||||
|
||||
bundle_ref = CFBundleGetMainBundle();
|
||||
if(bundle_ref == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tool_name_str = CFStringCreateWithCString(NULL, tool_name,
|
||||
kCFStringEncodingUTF8);
|
||||
|
||||
url_ref = CFBundleCopyResourceURL(bundle_ref, tool_name_str,
|
||||
NULL, NULL);
|
||||
CFRelease(tool_name_str);
|
||||
|
||||
if(url_ref == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path_str = CFURLCopyFileSystemPath(url_ref, kCFURLPOSIXPathStyle);
|
||||
CFRelease(url_ref);
|
||||
|
||||
if(path_str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!CFStringGetCString(path_str, path_buffer, sizeof(path_buffer),
|
||||
kCFStringEncodingUTF8)) {
|
||||
CFRelease(path_str);
|
||||
return NULL;
|
||||
}
|
||||
CFRelease(path_str);
|
||||
|
||||
args[0] = (char *)tool_name;
|
||||
args[1] = (char *)if_name;
|
||||
|
||||
auth_flags = kAuthorizationFlagExtendRights |
|
||||
kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize;
|
||||
|
||||
auth_items[0].name = "system.privilege.admin";
|
||||
auth_items[0].valueLength = 0;
|
||||
auth_items[0].value = NULL;
|
||||
auth_items[0].flags = 0;
|
||||
|
||||
auth_rights.count = sizeof (auth_items) / sizeof (auth_items[0]);
|
||||
auth_rights.items = auth_items;
|
||||
|
||||
auth_status = AuthorizationCreate(&auth_rights,
|
||||
kAuthorizationEmptyEnvironment,
|
||||
auth_flags,
|
||||
&auth_ref);
|
||||
|
||||
if (auth_status != errAuthorizationSuccess) {
|
||||
fprintf(stderr, "%s: AuthorizationCreate() failed.\n",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auth_status = AuthorizationExecuteWithPrivileges(auth_ref,
|
||||
path_buffer,
|
||||
kAuthorizationFlagDefaults,
|
||||
args + 1,
|
||||
&fp);
|
||||
|
||||
if (auth_status != errAuthorizationSuccess) {
|
||||
fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(fread(&c, 1, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
|
@ -350,8 +350,9 @@ void DarwinAddSerialPrefs(void)
|
|||
{
|
||||
D(bug("Modem BSD path: %s\n", bsdPath));
|
||||
|
||||
// Note that if there are multiple modems, we only get the last
|
||||
// Note that if there are multiple modems, we only get the first
|
||||
PrefsAddString("seriala", bsdPath);
|
||||
break;
|
||||
}
|
||||
else
|
||||
D(bug("Could not get BSD device path for modem\n"));
|
||||
|
|
489
BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj
Normal file
489
BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj
Normal file
|
@ -0,0 +1,489 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E4C1B4A32642B05A00EB55A0 /* compemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49A2642B05A00EB55A0 /* compemu.cpp */; };
|
||||
E4C1B4A42642B05A00EB55A0 /* compstbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */; };
|
||||
E4C1B4A52642B05A00EB55A0 /* comptbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C1B49C2642B05A00EB55A0 /* comptbl.h */; };
|
||||
E4C1B4A62642B05A00EB55A0 /* cpuemu_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */; };
|
||||
E4C1B4A72642B05A00EB55A0 /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */; };
|
||||
E4C1B4A82642B05A00EB55A0 /* cpustbl_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */; };
|
||||
E4C1B4A92642B05A00EB55A0 /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */; };
|
||||
E4C1B4AA2642B05A00EB55A0 /* cputbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C1B4A12642B05A00EB55A0 /* cputbl.h */; };
|
||||
E4C1B4AB2642B05A00EB55A0 /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B4A22642B05A00EB55A0 /* defs68k.c */; };
|
||||
E4F537C92642A8BA008B27DF /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */; };
|
||||
E4F537CD2642A8C2008B27DF /* cpu_emulation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537CB2642A8C2008B27DF /* cpu_emulation.h */; };
|
||||
E4F537DB2642A8CC008B27DF /* m68k.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D02642A8CC008B27DF /* m68k.h */; };
|
||||
E4F537DC2642A8CC008B27DF /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D12642A8CC008B27DF /* memory.cpp */; };
|
||||
E4F537DD2642A8CC008B27DF /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D22642A8CC008B27DF /* memory.h */; };
|
||||
E4F537DE2642A8CC008B27DF /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D32642A8CC008B27DF /* newcpu.cpp */; };
|
||||
E4F537DF2642A8CC008B27DF /* newcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D42642A8CC008B27DF /* newcpu.h */; };
|
||||
E4F537E02642A8CC008B27DF /* noflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D52642A8CC008B27DF /* noflags.h */; };
|
||||
E4F537E12642A8CC008B27DF /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D62642A8CC008B27DF /* readcpu.cpp */; };
|
||||
E4F537E22642A8CC008B27DF /* readcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D72642A8CC008B27DF /* readcpu.h */; };
|
||||
E4F537E32642A8CC008B27DF /* spcflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D82642A8CC008B27DF /* spcflags.h */; };
|
||||
E4F537EE2642A8E8008B27DF /* codegen_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537E62642A8E8008B27DF /* codegen_x86.h */; };
|
||||
E4F537EF2642A8E8008B27DF /* compemu_fpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */; };
|
||||
E4F537F02642A8E8008B27DF /* compemu_support.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537E82642A8E8008B27DF /* compemu_support.cpp */; };
|
||||
E4F537F12642A8E8008B27DF /* compemu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537E92642A8E8008B27DF /* compemu.h */; };
|
||||
E4F537F22642A8E8008B27DF /* flags_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537EA2642A8E8008B27DF /* flags_x86.h */; };
|
||||
E4F537F32642A8E8008B27DF /* gencomp.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F537EB2642A8E8008B27DF /* gencomp.c */; };
|
||||
E4F538092642A904008B27DF /* core.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537F62642A904008B27DF /* core.h */; };
|
||||
E4F5380A2642A904008B27DF /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537F72642A904008B27DF /* exceptions.cpp */; };
|
||||
E4F5380B2642A904008B27DF /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537F82642A904008B27DF /* exceptions.h */; };
|
||||
E4F5380C2642A904008B27DF /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537F92642A904008B27DF /* flags.cpp */; };
|
||||
E4F5380D2642A904008B27DF /* flags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537FA2642A904008B27DF /* flags.h */; };
|
||||
E4F5380E2642A904008B27DF /* fpu_ieee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537FB2642A904008B27DF /* fpu_ieee.cpp */; };
|
||||
E4F5380F2642A904008B27DF /* fpu_ieee.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537FC2642A904008B27DF /* fpu_ieee.h */; };
|
||||
E4F538152642A904008B27DF /* fpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538022642A904008B27DF /* fpu.h */; };
|
||||
E4F538162642A904008B27DF /* impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538032642A904008B27DF /* impl.h */; };
|
||||
E4F538172642A904008B27DF /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F538042642A904008B27DF /* mathlib.cpp */; };
|
||||
E4F538182642A904008B27DF /* mathlib.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538052642A904008B27DF /* mathlib.h */; };
|
||||
E4F538192642A904008B27DF /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F538062642A904008B27DF /* rounding.cpp */; };
|
||||
E4F5381A2642A904008B27DF /* rounding.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538072642A904008B27DF /* rounding.h */; };
|
||||
E4F5381B2642A904008B27DF /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538082642A904008B27DF /* types.h */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E4C1B49A2642B05A00EB55A0 /* compemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu.cpp; path = gencpu_output/compemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compstbl.cpp; path = gencpu_output/compstbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49C2642B05A00EB55A0 /* comptbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = comptbl.h; path = gencpu_output/comptbl.h; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu_nf.cpp; path = gencpu_output/cpuemu_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl_nf.cpp; path = gencpu_output/cpustbl_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B4A12642B05A00EB55A0 /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B4A22642B05A00EB55A0 /* defs68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libuae_cpu_x86_64.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basilisk_glue.cpp; path = ../uae_cpu/basilisk_glue.cpp; sourceTree = "<group>"; };
|
||||
E4F537CB2642A8C2008B27DF /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpu_emulation.h; path = ../uae_cpu/cpu_emulation.h; sourceTree = "<group>"; };
|
||||
E4F537D02642A8CC008B27DF /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68k.h; path = ../uae_cpu/m68k.h; sourceTree = "<group>"; };
|
||||
E4F537D12642A8CC008B27DF /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.cpp; path = ../uae_cpu/memory.cpp; sourceTree = "<group>"; };
|
||||
E4F537D22642A8CC008B27DF /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../uae_cpu/memory.h; sourceTree = "<group>"; };
|
||||
E4F537D32642A8CC008B27DF /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = newcpu.cpp; path = ../uae_cpu/newcpu.cpp; sourceTree = "<group>"; };
|
||||
E4F537D42642A8CC008B27DF /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = newcpu.h; path = ../uae_cpu/newcpu.h; sourceTree = "<group>"; };
|
||||
E4F537D52642A8CC008B27DF /* noflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = noflags.h; path = ../uae_cpu/noflags.h; sourceTree = "<group>"; };
|
||||
E4F537D62642A8CC008B27DF /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readcpu.cpp; path = ../uae_cpu/readcpu.cpp; sourceTree = "<group>"; };
|
||||
E4F537D72642A8CC008B27DF /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = readcpu.h; path = ../uae_cpu/readcpu.h; sourceTree = "<group>"; };
|
||||
E4F537D82642A8CC008B27DF /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spcflags.h; path = ../uae_cpu/spcflags.h; sourceTree = "<group>"; };
|
||||
E4F537D92642A8CC008B27DF /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = table68k; path = ../uae_cpu/table68k; sourceTree = "<group>"; };
|
||||
E4F537E62642A8E8008B27DF /* codegen_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codegen_x86.h; path = ../uae_cpu/compiler/codegen_x86.h; sourceTree = "<group>"; };
|
||||
E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu_fpp.cpp; path = ../uae_cpu/compiler/compemu_fpp.cpp; sourceTree = "<group>"; };
|
||||
E4F537E82642A8E8008B27DF /* compemu_support.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu_support.cpp; path = ../uae_cpu/compiler/compemu_support.cpp; sourceTree = "<group>"; };
|
||||
E4F537E92642A8E8008B27DF /* compemu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = compemu.h; path = ../uae_cpu/compiler/compemu.h; sourceTree = "<group>"; };
|
||||
E4F537EA2642A8E8008B27DF /* flags_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags_x86.h; path = ../uae_cpu/compiler/flags_x86.h; sourceTree = "<group>"; };
|
||||
E4F537EB2642A8E8008B27DF /* gencomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gencomp.c; path = ../uae_cpu/compiler/gencomp.c; sourceTree = "<group>"; };
|
||||
E4F537F62642A904008B27DF /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../uae_cpu/fpu/core.h; sourceTree = "<group>"; };
|
||||
E4F537F72642A904008B27DF /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exceptions.cpp; path = ../uae_cpu/fpu/exceptions.cpp; sourceTree = "<group>"; };
|
||||
E4F537F82642A904008B27DF /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exceptions.h; path = ../uae_cpu/fpu/exceptions.h; sourceTree = "<group>"; };
|
||||
E4F537F92642A904008B27DF /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flags.cpp; path = ../uae_cpu/fpu/flags.cpp; sourceTree = "<group>"; };
|
||||
E4F537FA2642A904008B27DF /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags.h; path = ../uae_cpu/fpu/flags.h; sourceTree = "<group>"; };
|
||||
E4F537FB2642A904008B27DF /* fpu_ieee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fpu_ieee.cpp; path = ../uae_cpu/fpu/fpu_ieee.cpp; sourceTree = "<group>"; };
|
||||
E4F537FC2642A904008B27DF /* fpu_ieee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu_ieee.h; path = ../uae_cpu/fpu/fpu_ieee.h; sourceTree = "<group>"; };
|
||||
E4F538022642A904008B27DF /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu.h; path = ../uae_cpu/fpu/fpu.h; sourceTree = "<group>"; };
|
||||
E4F538032642A904008B27DF /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = impl.h; path = ../uae_cpu/fpu/impl.h; sourceTree = "<group>"; };
|
||||
E4F538042642A904008B27DF /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mathlib.cpp; path = ../uae_cpu/fpu/mathlib.cpp; sourceTree = "<group>"; };
|
||||
E4F538052642A904008B27DF /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mathlib.h; path = ../uae_cpu/fpu/mathlib.h; sourceTree = "<group>"; };
|
||||
E4F538062642A904008B27DF /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rounding.cpp; path = ../uae_cpu/fpu/rounding.cpp; sourceTree = "<group>"; };
|
||||
E4F538072642A904008B27DF /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rounding.h; path = ../uae_cpu/fpu/rounding.h; sourceTree = "<group>"; };
|
||||
E4F538082642A904008B27DF /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../uae_cpu/fpu/types.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
E4F537BD2642A86D008B27DF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
E4C1B4982642AF3400EB55A0 /* generated */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4C1B49A2642B05A00EB55A0 /* compemu.cpp */,
|
||||
E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */,
|
||||
E4C1B49C2642B05A00EB55A0 /* comptbl.h */,
|
||||
E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */,
|
||||
E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */,
|
||||
E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */,
|
||||
E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */,
|
||||
E4C1B4A12642B05A00EB55A0 /* cputbl.h */,
|
||||
E4C1B4A22642B05A00EB55A0 /* defs68k.c */,
|
||||
);
|
||||
name = generated;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537B72642A86D008B27DF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */,
|
||||
E4F537E42642A8D2008B27DF /* compiler */,
|
||||
E4F537CB2642A8C2008B27DF /* cpu_emulation.h */,
|
||||
E4F537F52642A8ED008B27DF /* fpu */,
|
||||
E4F537D02642A8CC008B27DF /* m68k.h */,
|
||||
E4F537D12642A8CC008B27DF /* memory.cpp */,
|
||||
E4F537D22642A8CC008B27DF /* memory.h */,
|
||||
E4F537D32642A8CC008B27DF /* newcpu.cpp */,
|
||||
E4F537D42642A8CC008B27DF /* newcpu.h */,
|
||||
E4F537D52642A8CC008B27DF /* noflags.h */,
|
||||
E4F537D62642A8CC008B27DF /* readcpu.cpp */,
|
||||
E4F537D72642A8CC008B27DF /* readcpu.h */,
|
||||
E4F537D82642A8CC008B27DF /* spcflags.h */,
|
||||
E4F537D92642A8CC008B27DF /* table68k */,
|
||||
E4C1B4982642AF3400EB55A0 /* generated */,
|
||||
E4F537C12642A86D008B27DF /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537C12642A86D008B27DF /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537E42642A8D2008B27DF /* compiler */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537E62642A8E8008B27DF /* codegen_x86.h */,
|
||||
E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */,
|
||||
E4F537E82642A8E8008B27DF /* compemu_support.cpp */,
|
||||
E4F537E92642A8E8008B27DF /* compemu.h */,
|
||||
E4F537EA2642A8E8008B27DF /* flags_x86.h */,
|
||||
E4F537EB2642A8E8008B27DF /* gencomp.c */,
|
||||
);
|
||||
name = compiler;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537F52642A8ED008B27DF /* fpu */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537F62642A904008B27DF /* core.h */,
|
||||
E4F537F72642A904008B27DF /* exceptions.cpp */,
|
||||
E4F537F82642A904008B27DF /* exceptions.h */,
|
||||
E4F537F92642A904008B27DF /* flags.cpp */,
|
||||
E4F537FA2642A904008B27DF /* flags.h */,
|
||||
E4F537FB2642A904008B27DF /* fpu_ieee.cpp */,
|
||||
E4F537FC2642A904008B27DF /* fpu_ieee.h */,
|
||||
E4F538022642A904008B27DF /* fpu.h */,
|
||||
E4F538032642A904008B27DF /* impl.h */,
|
||||
E4F538042642A904008B27DF /* mathlib.cpp */,
|
||||
E4F538052642A904008B27DF /* mathlib.h */,
|
||||
E4F538062642A904008B27DF /* rounding.cpp */,
|
||||
E4F538072642A904008B27DF /* rounding.h */,
|
||||
E4F538082642A904008B27DF /* types.h */,
|
||||
);
|
||||
name = fpu;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
E4F537BE2642A86D008B27DF /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E4F538182642A904008B27DF /* mathlib.h in Headers */,
|
||||
E4F538152642A904008B27DF /* fpu.h in Headers */,
|
||||
E4F5380F2642A904008B27DF /* fpu_ieee.h in Headers */,
|
||||
E4F537F12642A8E8008B27DF /* compemu.h in Headers */,
|
||||
E4F538092642A904008B27DF /* core.h in Headers */,
|
||||
E4C1B4AA2642B05A00EB55A0 /* cputbl.h in Headers */,
|
||||
E4F5381B2642A904008B27DF /* types.h in Headers */,
|
||||
E4F537DF2642A8CC008B27DF /* newcpu.h in Headers */,
|
||||
E4F5380D2642A904008B27DF /* flags.h in Headers */,
|
||||
E4F537E22642A8CC008B27DF /* readcpu.h in Headers */,
|
||||
E4F5381A2642A904008B27DF /* rounding.h in Headers */,
|
||||
E4C1B4A52642B05A00EB55A0 /* comptbl.h in Headers */,
|
||||
E4F5380B2642A904008B27DF /* exceptions.h in Headers */,
|
||||
E4F537E32642A8CC008B27DF /* spcflags.h in Headers */,
|
||||
E4F537DB2642A8CC008B27DF /* m68k.h in Headers */,
|
||||
E4F537F22642A8E8008B27DF /* flags_x86.h in Headers */,
|
||||
E4F538162642A904008B27DF /* impl.h in Headers */,
|
||||
E4F537CD2642A8C2008B27DF /* cpu_emulation.h in Headers */,
|
||||
E4F537EE2642A8E8008B27DF /* codegen_x86.h in Headers */,
|
||||
E4F537DD2642A8CC008B27DF /* memory.h in Headers */,
|
||||
E4F537E02642A8CC008B27DF /* noflags.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
E4F537BF2642A86D008B27DF /* uae_cpu_x86_64 */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E4F537C42642A86D008B27DF /* Build configuration list for PBXNativeTarget "uae_cpu_x86_64" */;
|
||||
buildPhases = (
|
||||
E4C1B4992642AF5100EB55A0 /* ShellScript */,
|
||||
E4F537BC2642A86D008B27DF /* Sources */,
|
||||
E4F537BD2642A86D008B27DF /* Frameworks */,
|
||||
E4F537BE2642A86D008B27DF /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = uae_cpu_x86_64;
|
||||
productName = uae_cpu;
|
||||
productReference = E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
E4F537B82642A86D008B27DF /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0820;
|
||||
TargetAttributes = {
|
||||
E4F537BF2642A86D008B27DF = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = E4F537BB2642A86D008B27DF /* Build configuration list for PBXProject "uae_cpu" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = E4F537B72642A86D008B27DF;
|
||||
productRefGroup = E4F537C12642A86D008B27DF /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E4F537BF2642A86D008B27DF /* uae_cpu_x86_64 */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
E4C1B4992642AF5100EB55A0 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpuemu.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpuemu_nf.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpustbl.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpustbl_nf.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/defs68k.c,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/compemu.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/compstbl.cpp,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "make -f Makefile.gencpu\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
E4F537BC2642A86D008B27DF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E4C1B4A62642B05A00EB55A0 /* cpuemu_nf.cpp in Sources */,
|
||||
E4C1B4A32642B05A00EB55A0 /* compemu.cpp in Sources */,
|
||||
E4F538192642A904008B27DF /* rounding.cpp in Sources */,
|
||||
E4F537E12642A8CC008B27DF /* readcpu.cpp in Sources */,
|
||||
E4F5380C2642A904008B27DF /* flags.cpp in Sources */,
|
||||
E4F537EF2642A8E8008B27DF /* compemu_fpp.cpp in Sources */,
|
||||
E4F538172642A904008B27DF /* mathlib.cpp in Sources */,
|
||||
E4F537F02642A8E8008B27DF /* compemu_support.cpp in Sources */,
|
||||
E4F537DC2642A8CC008B27DF /* memory.cpp in Sources */,
|
||||
E4C1B4A42642B05A00EB55A0 /* compstbl.cpp in Sources */,
|
||||
E4C1B4AB2642B05A00EB55A0 /* defs68k.c in Sources */,
|
||||
E4C1B4A92642B05A00EB55A0 /* cpustbl.cpp in Sources */,
|
||||
E4F537C92642A8BA008B27DF /* basilisk_glue.cpp in Sources */,
|
||||
E4F537F32642A8E8008B27DF /* gencomp.c in Sources */,
|
||||
E4F5380E2642A904008B27DF /* fpu_ieee.cpp in Sources */,
|
||||
E4C1B4A72642B05A00EB55A0 /* cpuemu.cpp in Sources */,
|
||||
E4C1B4A82642B05A00EB55A0 /* cpustbl_nf.cpp in Sources */,
|
||||
E4F537DE2642A8CC008B27DF /* newcpu.cpp in Sources */,
|
||||
E4F5380A2642A904008B27DF /* exceptions.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
E4F537C22642A86D008B27DF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E4F537C32642A86D008B27DF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E4F537C52642A86D008B27DF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = x86_64;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"USE_XCODE=1",
|
||||
CPU_x86_64,
|
||||
JIT,
|
||||
"USE_JIT=1",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu,
|
||||
../Unix,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E4F537C62642A86D008B27DF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = x86_64;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"USE_XCODE=1",
|
||||
CPU_x86_64,
|
||||
JIT,
|
||||
"USE_JIT=1",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu,
|
||||
../Unix,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
E4F537BB2642A86D008B27DF /* Build configuration list for PBXProject "uae_cpu" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E4F537C22642A86D008B27DF /* Debug */,
|
||||
E4F537C32642A86D008B27DF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E4F537C42642A86D008B27DF /* Build configuration list for PBXNativeTarget "uae_cpu_x86_64" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E4F537C52642A86D008B27DF /* Debug */,
|
||||
E4F537C62642A86D008B27DF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = E4F537B82642A86D008B27DF /* Project object */;
|
||||
}
|
429
BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj
Normal file
429
BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj
Normal file
|
@ -0,0 +1,429 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E41D7AAA2642C070005E8093 /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AA82642C070005E8093 /* basilisk_glue.cpp */; };
|
||||
E41D7AAE2642C07C005E8093 /* cpu_emulation.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AAC2642C07C005E8093 /* cpu_emulation.h */; };
|
||||
E41D7AAF2642C07C005E8093 /* cpummu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AAD2642C07C005E8093 /* cpummu.h */; };
|
||||
E41D7ABB2642C087005E8093 /* m68k.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB12642C087005E8093 /* m68k.h */; };
|
||||
E41D7ABC2642C087005E8093 /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB22642C087005E8093 /* memory.h */; };
|
||||
E41D7ABD2642C087005E8093 /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AB32642C087005E8093 /* newcpu.cpp */; };
|
||||
E41D7ABE2642C087005E8093 /* newcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB42642C087005E8093 /* newcpu.h */; };
|
||||
E41D7ABF2642C087005E8093 /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AB52642C087005E8093 /* readcpu.cpp */; };
|
||||
E41D7AC02642C087005E8093 /* readcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB62642C087005E8093 /* readcpu.h */; };
|
||||
E41D7AC12642C087005E8093 /* registers.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB72642C087005E8093 /* registers.h */; };
|
||||
E41D7AC22642C087005E8093 /* spcflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB82642C087005E8093 /* spcflags.h */; };
|
||||
E41D7AD82642C0A4005E8093 /* core.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC42642C0A4005E8093 /* core.h */; };
|
||||
E41D7AD92642C0A4005E8093 /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AC52642C0A4005E8093 /* exceptions.cpp */; };
|
||||
E41D7ADA2642C0A4005E8093 /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC62642C0A4005E8093 /* exceptions.h */; };
|
||||
E41D7ADB2642C0A4005E8093 /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AC72642C0A4005E8093 /* flags.cpp */; };
|
||||
E41D7ADC2642C0A4005E8093 /* flags.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC82642C0A4005E8093 /* flags.h */; };
|
||||
E41D7ADF2642C0A4005E8093 /* fpu_mpfr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */; };
|
||||
E41D7AE52642C0A4005E8093 /* fpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD12642C0A4005E8093 /* fpu.h */; };
|
||||
E41D7AE62642C0A4005E8093 /* impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD22642C0A4005E8093 /* impl.h */; };
|
||||
E41D7AE72642C0A4005E8093 /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AD32642C0A4005E8093 /* mathlib.cpp */; };
|
||||
E41D7AE82642C0A4005E8093 /* mathlib.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD42642C0A4005E8093 /* mathlib.h */; };
|
||||
E41D7AE92642C0A4005E8093 /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AD52642C0A4005E8093 /* rounding.cpp */; };
|
||||
E41D7AEA2642C0A4005E8093 /* rounding.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD62642C0A4005E8093 /* rounding.h */; };
|
||||
E41D7AEB2642C0A4005E8093 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD72642C0A4005E8093 /* types.h */; };
|
||||
E4FC27512642C45E00C64E21 /* cpufunctbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */; };
|
||||
E4FC27522642C45E00C64E21 /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274D2642C45E00C64E21 /* cpuemu.cpp */; };
|
||||
E4FC27532642C45E00C64E21 /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274E2642C45E00C64E21 /* cpustbl.cpp */; };
|
||||
E4FC27542642C45E00C64E21 /* cputbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4FC274F2642C45E00C64E21 /* cputbl.h */; };
|
||||
E4FC27552642C45E00C64E21 /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E4FC27502642C45E00C64E21 /* defs68k.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libuae_cpu_arm64.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E41D7AA82642C070005E8093 /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basilisk_glue.cpp; path = ../uae_cpu_2021/basilisk_glue.cpp; sourceTree = "<group>"; };
|
||||
E41D7AAC2642C07C005E8093 /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpu_emulation.h; path = ../uae_cpu_2021/cpu_emulation.h; sourceTree = "<group>"; };
|
||||
E41D7AAD2642C07C005E8093 /* cpummu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpummu.h; path = ../uae_cpu_2021/cpummu.h; sourceTree = "<group>"; };
|
||||
E41D7AB12642C087005E8093 /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68k.h; path = ../uae_cpu_2021/m68k.h; sourceTree = "<group>"; };
|
||||
E41D7AB22642C087005E8093 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../uae_cpu_2021/memory.h; sourceTree = "<group>"; };
|
||||
E41D7AB32642C087005E8093 /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = newcpu.cpp; path = ../uae_cpu_2021/newcpu.cpp; sourceTree = "<group>"; };
|
||||
E41D7AB42642C087005E8093 /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = newcpu.h; path = ../uae_cpu_2021/newcpu.h; sourceTree = "<group>"; };
|
||||
E41D7AB52642C087005E8093 /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readcpu.cpp; path = ../uae_cpu_2021/readcpu.cpp; sourceTree = "<group>"; };
|
||||
E41D7AB62642C087005E8093 /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = readcpu.h; path = ../uae_cpu_2021/readcpu.h; sourceTree = "<group>"; };
|
||||
E41D7AB72642C087005E8093 /* registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = registers.h; path = ../uae_cpu_2021/registers.h; sourceTree = "<group>"; };
|
||||
E41D7AB82642C087005E8093 /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spcflags.h; path = ../uae_cpu_2021/spcflags.h; sourceTree = "<group>"; };
|
||||
E41D7AB92642C087005E8093 /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = table68k; path = ../uae_cpu_2021/table68k; sourceTree = "<group>"; };
|
||||
E41D7AC42642C0A4005E8093 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../uae_cpu_2021/fpu/core.h; sourceTree = "<group>"; };
|
||||
E41D7AC52642C0A4005E8093 /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exceptions.cpp; path = ../uae_cpu_2021/fpu/exceptions.cpp; sourceTree = "<group>"; };
|
||||
E41D7AC62642C0A4005E8093 /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exceptions.h; path = ../uae_cpu_2021/fpu/exceptions.h; sourceTree = "<group>"; };
|
||||
E41D7AC72642C0A4005E8093 /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flags.cpp; path = ../uae_cpu_2021/fpu/flags.cpp; sourceTree = "<group>"; };
|
||||
E41D7AC82642C0A4005E8093 /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags.h; path = ../uae_cpu_2021/fpu/flags.h; sourceTree = "<group>"; };
|
||||
E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fpu_mpfr.cpp; path = ../uae_cpu_2021/fpu/fpu_mpfr.cpp; sourceTree = "<group>"; };
|
||||
E41D7AD12642C0A4005E8093 /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu.h; path = ../uae_cpu_2021/fpu/fpu.h; sourceTree = "<group>"; };
|
||||
E41D7AD22642C0A4005E8093 /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = impl.h; path = ../uae_cpu_2021/fpu/impl.h; sourceTree = "<group>"; };
|
||||
E41D7AD32642C0A4005E8093 /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mathlib.cpp; path = ../uae_cpu_2021/fpu/mathlib.cpp; sourceTree = "<group>"; };
|
||||
E41D7AD42642C0A4005E8093 /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mathlib.h; path = ../uae_cpu_2021/fpu/mathlib.h; sourceTree = "<group>"; };
|
||||
E41D7AD52642C0A4005E8093 /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rounding.cpp; path = ../uae_cpu_2021/fpu/rounding.cpp; sourceTree = "<group>"; };
|
||||
E41D7AD62642C0A4005E8093 /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rounding.h; path = ../uae_cpu_2021/fpu/rounding.h; sourceTree = "<group>"; };
|
||||
E41D7AD72642C0A4005E8093 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../uae_cpu_2021/fpu/types.h; sourceTree = "<group>"; };
|
||||
E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpufunctbl.cpp; path = gencpu_output_2021/cpufunctbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC274D2642C45E00C64E21 /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output_2021/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC274E2642C45E00C64E21 /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output_2021/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC274F2642C45E00C64E21 /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output_2021/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC27502642C45E00C64E21 /* defs68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output_2021/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
E41D7A9E2642C004005E8093 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
E41D7A982642C004005E8093 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E41D7AA82642C070005E8093 /* basilisk_glue.cpp */,
|
||||
E41D7AC32642C08E005E8093 /* fpu */,
|
||||
E41D7AAC2642C07C005E8093 /* cpu_emulation.h */,
|
||||
E41D7AAD2642C07C005E8093 /* cpummu.h */,
|
||||
E41D7AB12642C087005E8093 /* m68k.h */,
|
||||
E41D7AB22642C087005E8093 /* memory.h */,
|
||||
E41D7AB32642C087005E8093 /* newcpu.cpp */,
|
||||
E41D7AB42642C087005E8093 /* newcpu.h */,
|
||||
E41D7AB52642C087005E8093 /* readcpu.cpp */,
|
||||
E41D7AB62642C087005E8093 /* readcpu.h */,
|
||||
E41D7AB72642C087005E8093 /* registers.h */,
|
||||
E41D7AB82642C087005E8093 /* spcflags.h */,
|
||||
E41D7AB92642C087005E8093 /* table68k */,
|
||||
E4FC274B2642C44A00C64E21 /* generated */,
|
||||
E41D7AA22642C004005E8093 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E41D7AA22642C004005E8093 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E41D7AC32642C08E005E8093 /* fpu */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E41D7AC42642C0A4005E8093 /* core.h */,
|
||||
E41D7AC52642C0A4005E8093 /* exceptions.cpp */,
|
||||
E41D7AC62642C0A4005E8093 /* exceptions.h */,
|
||||
E41D7AC72642C0A4005E8093 /* flags.cpp */,
|
||||
E41D7AC82642C0A4005E8093 /* flags.h */,
|
||||
E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */,
|
||||
E41D7AD12642C0A4005E8093 /* fpu.h */,
|
||||
E41D7AD22642C0A4005E8093 /* impl.h */,
|
||||
E41D7AD32642C0A4005E8093 /* mathlib.cpp */,
|
||||
E41D7AD42642C0A4005E8093 /* mathlib.h */,
|
||||
E41D7AD52642C0A4005E8093 /* rounding.cpp */,
|
||||
E41D7AD62642C0A4005E8093 /* rounding.h */,
|
||||
E41D7AD72642C0A4005E8093 /* types.h */,
|
||||
);
|
||||
name = fpu;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4FC274B2642C44A00C64E21 /* generated */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4FC274D2642C45E00C64E21 /* cpuemu.cpp */,
|
||||
E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */,
|
||||
E4FC274E2642C45E00C64E21 /* cpustbl.cpp */,
|
||||
E4FC274F2642C45E00C64E21 /* cputbl.h */,
|
||||
E4FC27502642C45E00C64E21 /* defs68k.c */,
|
||||
);
|
||||
path = generated;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
E41D7A9F2642C004005E8093 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E41D7AE82642C0A4005E8093 /* mathlib.h in Headers */,
|
||||
E41D7ADA2642C0A4005E8093 /* exceptions.h in Headers */,
|
||||
E41D7ABB2642C087005E8093 /* m68k.h in Headers */,
|
||||
E41D7AC02642C087005E8093 /* readcpu.h in Headers */,
|
||||
E41D7AEA2642C0A4005E8093 /* rounding.h in Headers */,
|
||||
E41D7AAE2642C07C005E8093 /* cpu_emulation.h in Headers */,
|
||||
E41D7AC22642C087005E8093 /* spcflags.h in Headers */,
|
||||
E41D7AE52642C0A4005E8093 /* fpu.h in Headers */,
|
||||
E41D7AAF2642C07C005E8093 /* cpummu.h in Headers */,
|
||||
E41D7AC12642C087005E8093 /* registers.h in Headers */,
|
||||
E41D7AD82642C0A4005E8093 /* core.h in Headers */,
|
||||
E4FC27542642C45E00C64E21 /* cputbl.h in Headers */,
|
||||
E41D7ABE2642C087005E8093 /* newcpu.h in Headers */,
|
||||
E41D7AE62642C0A4005E8093 /* impl.h in Headers */,
|
||||
E41D7ABC2642C087005E8093 /* memory.h in Headers */,
|
||||
E41D7AEB2642C0A4005E8093 /* types.h in Headers */,
|
||||
E41D7ADC2642C0A4005E8093 /* flags.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
E41D7AA02642C004005E8093 /* uae_cpu_arm64 */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E41D7AA52642C004005E8093 /* Build configuration list for PBXNativeTarget "uae_cpu_arm64" */;
|
||||
buildPhases = (
|
||||
E4FC27492642C2E600C64E21 /* ShellScript */,
|
||||
E41D7A9D2642C004005E8093 /* Sources */,
|
||||
E41D7A9E2642C004005E8093 /* Frameworks */,
|
||||
E41D7A9F2642C004005E8093 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = uae_cpu_arm64;
|
||||
productName = uae_cpu_2021;
|
||||
productReference = E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
E41D7A992642C004005E8093 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0820;
|
||||
TargetAttributes = {
|
||||
E41D7AA02642C004005E8093 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = E41D7A9C2642C004005E8093 /* Build configuration list for PBXProject "uae_cpu_2021" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = E41D7A982642C004005E8093;
|
||||
productRefGroup = E41D7AA22642C004005E8093 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E41D7AA02642C004005E8093 /* uae_cpu_arm64 */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
E4FC27492642C2E600C64E21 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cpuemu.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cpufunctbl.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cpustbl.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cputbl.h,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/defs68k.c,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "make -f Makefile.gencpu_2021\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
E41D7A9D2642C004005E8093 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E4FC27512642C45E00C64E21 /* cpufunctbl.cpp in Sources */,
|
||||
E41D7ADB2642C0A4005E8093 /* flags.cpp in Sources */,
|
||||
E41D7ADF2642C0A4005E8093 /* fpu_mpfr.cpp in Sources */,
|
||||
E41D7ABD2642C087005E8093 /* newcpu.cpp in Sources */,
|
||||
E4FC27552642C45E00C64E21 /* defs68k.c in Sources */,
|
||||
E41D7AE72642C0A4005E8093 /* mathlib.cpp in Sources */,
|
||||
E4FC27522642C45E00C64E21 /* cpuemu.cpp in Sources */,
|
||||
E4FC27532642C45E00C64E21 /* cpustbl.cpp in Sources */,
|
||||
E41D7AD92642C0A4005E8093 /* exceptions.cpp in Sources */,
|
||||
E41D7AAA2642C070005E8093 /* basilisk_glue.cpp in Sources */,
|
||||
E41D7ABF2642C087005E8093 /* readcpu.cpp in Sources */,
|
||||
E41D7AE92642C0A4005E8093 /* rounding.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
E41D7AA32642C004005E8093 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E41D7AA42642C004005E8093 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E41D7AA62642C004005E8093 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"USE_XCODE=1",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
/usr/local/include,
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu_2021,
|
||||
../Unix,
|
||||
);
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALID_ARCHS = arm64;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E41D7AA72642C004005E8093 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "USE_XCODE=1";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
/usr/local/include,
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu_2021,
|
||||
../Unix,
|
||||
);
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALID_ARCHS = arm64;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
E41D7A9C2642C004005E8093 /* Build configuration list for PBXProject "uae_cpu_2021" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E41D7AA32642C004005E8093 /* Debug */,
|
||||
E41D7AA42642C004005E8093 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E41D7AA52642C004005E8093 /* Build configuration list for PBXNativeTarget "uae_cpu_arm64" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E41D7AA62642C004005E8093 /* Debug */,
|
||||
E41D7AA72642C004005E8093 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = E41D7A992642C004005E8093 /* Project object */;
|
||||
}
|
|
@ -24,4 +24,17 @@
|
|||
// Invokes the specified function with an NSAutoReleasePool in place.
|
||||
void NSAutoReleasePool_wrap(void (*fn)(void));
|
||||
|
||||
#ifdef USE_SDL
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
void disable_SDL2_macosx_menu_bar_keyboard_shortcuts();
|
||||
bool is_fullscreen_osx(SDL_Window * window);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void set_menu_bar_visible_osx(bool visible);
|
||||
|
||||
void set_current_directory();
|
||||
|
||||
bool MetalIsAvailable();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,13 +20,16 @@
|
|||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include "sysdeps.h"
|
||||
#include "utils_macosx.h"
|
||||
#include <SDL.h>
|
||||
#include "utils_macosx.h"
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0) && !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
// This is used from video_sdl.cpp.
|
||||
void NSAutoReleasePool_wrap(void (*fn)(void))
|
||||
{
|
||||
|
@ -58,13 +61,16 @@ bool is_fullscreen_osx(SDL_Window * window)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(window);
|
||||
NSWindow *nswindow = (NSWindow *)SDL_GetProperty(props, "SDL.window.cocoa.window", NULL);
|
||||
#else
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
if (!SDL_GetWindowWMInfo(window, &wmInfo)) {
|
||||
return false;
|
||||
}
|
||||
NSWindow *nswindow = SDL_GetWindowWMInfo(window, &wmInfo) ? wmInfo.info.cocoa.window : nil;
|
||||
#endif
|
||||
|
||||
const NSWindowStyleMask styleMask = [wmInfo.info.cocoa.window styleMask];
|
||||
const NSWindowStyleMask styleMask = [nswindow styleMask];
|
||||
return (styleMask & NSWindowStyleMaskFullScreen) != 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -81,3 +87,14 @@ void set_current_directory()
|
|||
[pool release];
|
||||
}
|
||||
|
||||
bool MetalIsAvailable() {
|
||||
const int EL_CAPITAN = 15; // Darwin major version of El Capitan
|
||||
char s[16];
|
||||
size_t size = sizeof(s);
|
||||
int v;
|
||||
if (sysctlbyname("kern.osrelease", s, &size, NULL, 0) || sscanf(s, "%d", &v) != 1 || v < EL_CAPITAN) return false;
|
||||
id<MTLDevice> dev = MTLCreateSystemDefaultDevice();
|
||||
bool r = dev != nil;
|
||||
[dev release];
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -29,12 +29,15 @@
|
|||
#include <SDL_mutex.h>
|
||||
#include <SDL_audio.h>
|
||||
#include <SDL_version.h>
|
||||
#include <SDL_timer.h>
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue_unix.h"
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -49,11 +52,14 @@ static int audio_channel_count_index = 0;
|
|||
static SDL_sem *audio_irq_done_sem = NULL; // Signal from interrupt to streaming thread: data block read
|
||||
static uint8 silence_byte; // Byte value to use to fill sound buffers with silence
|
||||
static uint8 *audio_mix_buf = NULL;
|
||||
static int audio_volume = SDL_MIX_MAXVOLUME;
|
||||
static bool audio_mute = false;
|
||||
static int main_volume = MAC_MAX_VOLUME;
|
||||
static int speaker_volume = MAC_MAX_VOLUME;
|
||||
static bool main_mute = false;
|
||||
static bool speaker_mute = false;
|
||||
|
||||
// Prototypes
|
||||
static void stream_func(void *arg, uint8 *stream, int stream_len);
|
||||
static int get_audio_volume();
|
||||
|
||||
|
||||
/*
|
||||
|
@ -92,7 +98,7 @@ static bool open_sdl_audio(void)
|
|||
audio_spec.freq = audio_sample_rates[audio_sample_rate_index] >> 16;
|
||||
audio_spec.format = (audio_sample_sizes[audio_sample_size_index] == 8) ? AUDIO_U8 : AUDIO_S16MSB;
|
||||
audio_spec.channels = audio_channel_counts[audio_channel_count_index];
|
||||
audio_spec.samples = 4096;
|
||||
audio_spec.samples = 4096 >> PrefsFindInt32("sound_buffer");
|
||||
audio_spec.callback = stream_func;
|
||||
audio_spec.userdata = NULL;
|
||||
|
||||
|
@ -112,7 +118,7 @@ static bool open_sdl_audio(void)
|
|||
|
||||
#if defined(BINCUE)
|
||||
OpenAudio_bincue(audio_spec.freq, audio_spec.format, audio_spec.channels,
|
||||
audio_spec.silence);
|
||||
audio_spec.silence, get_audio_volume());
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
|
@ -228,7 +234,7 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
|
|||
|
||||
// Get size of audio data
|
||||
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
|
||||
if (apple_stream_info && !audio_mute) {
|
||||
if (apple_stream_info && !main_mute && !speaker_mute) {
|
||||
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
|
||||
D(bug("stream: work_size %d\n", work_size));
|
||||
if (work_size > stream_len)
|
||||
|
@ -239,7 +245,7 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
|
|||
// Send data to audio device
|
||||
Mac2Host_memcpy(audio_mix_buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
|
||||
memset((uint8 *)stream, silence_byte, stream_len);
|
||||
SDL_MixAudio(stream, audio_mix_buf, work_size, audio_volume);
|
||||
SDL_MixAudio(stream, audio_mix_buf, work_size, get_audio_volume());
|
||||
|
||||
D(bug("stream: data written\n"));
|
||||
|
||||
|
@ -249,11 +255,13 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
|
|||
} else {
|
||||
|
||||
// Audio not active, play silence
|
||||
silence: memset(stream, silence_byte, stream_len);
|
||||
silence: memset(stream, silence_byte, stream_len);
|
||||
}
|
||||
|
||||
#if defined(BINCUE)
|
||||
MixAudio_bincue(stream, stream_len);
|
||||
MixAudio_bincue(stream, stream_len, get_audio_volume());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -317,43 +325,84 @@ bool audio_set_channels(int index)
|
|||
|
||||
bool audio_get_main_mute(void)
|
||||
{
|
||||
return audio_mute;
|
||||
return main_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_main_volume(void)
|
||||
{
|
||||
uint32 chan = (audio_volume * MAC_MAX_VOLUME / SDL_MIX_MAXVOLUME);
|
||||
uint32 chan = main_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
bool audio_get_speaker_mute(void)
|
||||
{
|
||||
return audio_mute;
|
||||
return speaker_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_speaker_volume(void)
|
||||
{
|
||||
return audio_get_main_volume();
|
||||
uint32 chan = speaker_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
void audio_set_main_mute(bool mute)
|
||||
{
|
||||
audio_mute = mute;
|
||||
main_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_main_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
uint32 avg = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (avg > MAC_MAX_VOLUME)
|
||||
avg = MAC_MAX_VOLUME;
|
||||
audio_volume = avg * SDL_MIX_MAXVOLUME / MAC_MAX_VOLUME;
|
||||
main_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (main_volume > MAC_MAX_VOLUME)
|
||||
main_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
void audio_set_speaker_mute(bool mute)
|
||||
{
|
||||
speaker_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_speaker_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
speaker_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (speaker_volume > MAC_MAX_VOLUME)
|
||||
speaker_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
static int get_audio_volume() {
|
||||
return main_volume * speaker_volume * SDL_MIX_MAXVOLUME / (MAC_MAX_VOLUME * MAC_MAX_VOLUME);
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
static int play_startup(void *arg) {
|
||||
SDL_AudioSpec wav_spec;
|
||||
Uint8 *wav_buffer;
|
||||
Uint32 wav_length;
|
||||
if (SDL_LoadWAV("startup.wav", &wav_spec, &wav_buffer, &wav_length)) {
|
||||
SDL_AudioSpec obtained;
|
||||
SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &obtained, 0);
|
||||
if (deviceId) {
|
||||
SDL_QueueAudio(deviceId, wav_buffer, wav_length);
|
||||
SDL_PauseAudioDevice(deviceId, 0);
|
||||
while (SDL_GetQueuedAudioSize(deviceId)) SDL_Delay(10);
|
||||
SDL_Delay(500);
|
||||
SDL_CloseAudioDevice(deviceId);
|
||||
}
|
||||
else printf("play_startup: Audio driver failed to initialize\n");
|
||||
SDL_FreeWAV(wav_buffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PlayStartupSound() {
|
||||
SDL_CreateThread(play_startup, "", NULL);
|
||||
}
|
||||
#else
|
||||
void PlayStartupSound() {
|
||||
// Not implemented
|
||||
}
|
||||
#endif
|
||||
#endif // SDL_VERSION_ATLEAST
|
||||
|
||||
|
|
388
BasiliskII/src/SDL/audio_sdl3.cpp
Normal file
388
BasiliskII/src/SDL/audio_sdl3.cpp
Normal file
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* audio_sdl3.cpp - Audio support, SDL implementation
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "main.h"
|
||||
#include "prefs.h"
|
||||
#include "user_strings.h"
|
||||
#include "audio.h"
|
||||
#include "audio_defs.h"
|
||||
|
||||
#include <SDL_mutex.h>
|
||||
#include <SDL_audio.h>
|
||||
#include <SDL_version.h>
|
||||
#include <SDL_timer.h>
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#include <SDL_init.h>
|
||||
#include <queue>
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define MAC_MAX_VOLUME 0x0100
|
||||
|
||||
// The currently selected audio parameters (indices in audio_sample_rates[] etc. vectors)
|
||||
static int audio_sample_rate_index = 0;
|
||||
static int audio_sample_size_index = 0;
|
||||
static int audio_channel_count_index = 0;
|
||||
|
||||
// Global variables
|
||||
static SDL_Semaphore *audio_irq_done_sem = NULL; // Signal from interrupt to streaming thread: data block read
|
||||
static uint8 silence_byte; // Byte value to use to fill sound buffers with silence
|
||||
static int main_volume = MAC_MAX_VOLUME;
|
||||
static int speaker_volume = MAC_MAX_VOLUME;
|
||||
static bool main_mute = false;
|
||||
static bool speaker_mute = false;
|
||||
|
||||
volatile static bool playing_startup, exit_startup;
|
||||
SDL_AudioSpec audio_spec;
|
||||
|
||||
// Prototypes
|
||||
static void SDLCALL stream_func(void *arg, SDL_AudioStream *stream, int additional_amount, int total_amount);
|
||||
static int get_audio_volume();
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
// Set AudioStatus to reflect current audio stream format
|
||||
static void set_audio_status_format(void)
|
||||
{
|
||||
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
|
||||
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
|
||||
AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
|
||||
}
|
||||
|
||||
// Init SDL audio system
|
||||
static bool open_sdl_audio(void)
|
||||
{
|
||||
// SDL supports a variety of twisted little audio formats, all different
|
||||
if (audio_sample_sizes.empty()) {
|
||||
audio_sample_rates.push_back(11025 << 16);
|
||||
audio_sample_rates.push_back(22050 << 16);
|
||||
audio_sample_rates.push_back(44100 << 16);
|
||||
audio_sample_sizes.push_back(8);
|
||||
audio_sample_sizes.push_back(16);
|
||||
audio_channel_counts.push_back(1);
|
||||
audio_channel_counts.push_back(2);
|
||||
|
||||
// Default to highest supported values
|
||||
audio_sample_rate_index = (int)audio_sample_rates.size() - 1;
|
||||
audio_sample_size_index = (int)audio_sample_sizes.size() - 1;
|
||||
audio_channel_count_index = (int)audio_channel_counts.size() - 1;
|
||||
}
|
||||
|
||||
//memset(&audio_spec, 0, sizeof(audio_spec));
|
||||
audio_spec.format = (audio_sample_sizes[audio_sample_size_index] == 8) ? SDL_AUDIO_U8 : SDL_AUDIO_S16BE;
|
||||
audio_spec.channels = audio_channel_counts[audio_channel_count_index];
|
||||
audio_spec.freq = audio_sample_rates[audio_sample_rate_index] >> 16;
|
||||
|
||||
// Open the audio device, forcing the desired format
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &audio_spec, stream_func, NULL);
|
||||
if (stream == NULL) {
|
||||
fprintf(stderr, "WARNING: Cannot open audio: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
silence_byte = SDL_GetSilenceValueForFormat(audio_spec.format);
|
||||
#if defined(BINCUE)
|
||||
OpenAudio_bincue(audio_spec.freq, audio_spec.format, audio_spec.channels, silence_byte, get_audio_volume());
|
||||
#endif
|
||||
|
||||
printf("Using SDL/%s audio output\n", SDL_GetCurrentAudioDriver());
|
||||
audio_frames_per_block = 4096 >> PrefsFindInt32("sound_buffer");
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool open_audio(void)
|
||||
{
|
||||
// Try to open SDL audio
|
||||
if (!open_sdl_audio()) {
|
||||
WarningAlert(GetString(STR_NO_AUDIO_WARN));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Device opened, set AudioStatus
|
||||
set_audio_status_format();
|
||||
|
||||
// Everything went fine
|
||||
audio_open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioInit(void)
|
||||
{
|
||||
// Init audio status and feature flags
|
||||
AudioStatus.sample_rate = 44100 << 16;
|
||||
AudioStatus.sample_size = 16;
|
||||
AudioStatus.channels = 2;
|
||||
AudioStatus.mixer = 0;
|
||||
AudioStatus.num_sources = 0;
|
||||
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
|
||||
|
||||
// Sound disabled in prefs? Then do nothing
|
||||
if (PrefsFindBool("nosound"))
|
||||
return;
|
||||
|
||||
// Init semaphore
|
||||
audio_irq_done_sem = SDL_CreateSemaphore(0);
|
||||
|
||||
// Open and initialize audio device
|
||||
open_audio();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
*/
|
||||
|
||||
static void close_audio(void)
|
||||
{
|
||||
exit_startup = true;
|
||||
while (playing_startup)
|
||||
SDL_Delay(10);
|
||||
exit_startup = false;
|
||||
// Close audio device
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
audio_open = false;
|
||||
}
|
||||
|
||||
void AudioExit(void)
|
||||
{
|
||||
// Close audio device
|
||||
close_audio();
|
||||
|
||||
// Delete semaphore
|
||||
if (audio_irq_done_sem)
|
||||
SDL_DestroySemaphore(audio_irq_done_sem);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* First source added, start audio stream
|
||||
*/
|
||||
|
||||
void audio_enter_stream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Last source removed, stop audio stream
|
||||
*/
|
||||
|
||||
void audio_exit_stream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Streaming function
|
||||
*/
|
||||
|
||||
static void SDLCALL stream_func(void *, SDL_AudioStream *stream, int stream_len, int /*total_amount*/)
|
||||
{
|
||||
static std::queue<uint8> q;
|
||||
if (AudioStatus.num_sources) {
|
||||
while (q.size() < stream_len) {
|
||||
// Trigger audio interrupt to get new buffer
|
||||
D(bug("stream: triggering irq\n"));
|
||||
SetInterruptFlag(INTFLAG_AUDIO);
|
||||
TriggerInterrupt();
|
||||
D(bug("stream: waiting for ack\n"));
|
||||
SDL_WaitSemaphore(audio_irq_done_sem);
|
||||
D(bug("stream: ack received\n"));
|
||||
|
||||
// Get size of audio data
|
||||
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
|
||||
if (apple_stream_info && !main_mute && !speaker_mute) {
|
||||
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
|
||||
uint8 buf[work_size];
|
||||
Mac2Host_memcpy(buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
|
||||
for (int i = 0; i < work_size; i++) q.push(buf[i]);
|
||||
}
|
||||
else {
|
||||
while (!q.empty()) q.pop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8 src[stream_len], dst[stream_len];
|
||||
for (int i = 0; i < stream_len; i++)
|
||||
if (q.empty()) src[i] = silence_byte;
|
||||
else {
|
||||
src[i] = q.front();
|
||||
q.pop();
|
||||
}
|
||||
memset(dst, silence_byte, stream_len);
|
||||
//SDL_AudioSpec audio_spec;
|
||||
//int r = SDL_GetAudioStreamFormat(stream, NULL, &audio_spec);// little endianが帰ってくる
|
||||
SDL_MixAudioFormat(dst, src, audio_spec.format, stream_len, get_audio_volume());
|
||||
#if defined(BINCUE)
|
||||
MixAudio_bincue(dst, stream_len, get_audio_volume());
|
||||
#endif
|
||||
SDL_PutAudioStreamData(stream, dst, stream_len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MacOS audio interrupt, read next data block
|
||||
*/
|
||||
|
||||
void AudioInterrupt(void)
|
||||
{
|
||||
D(bug("AudioInterrupt\n"));
|
||||
|
||||
// Get data from apple mixer
|
||||
if (AudioStatus.mixer) {
|
||||
M68kRegisters r;
|
||||
r.a[0] = audio_data + adatStreamInfo;
|
||||
r.a[1] = AudioStatus.mixer;
|
||||
Execute68k(audio_data + adatGetSourceData, &r);
|
||||
D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
|
||||
} else
|
||||
WriteMacInt32(audio_data + adatStreamInfo, 0);
|
||||
|
||||
// Signal stream function
|
||||
SDL_PostSemaphore(audio_irq_done_sem);
|
||||
D(bug("AudioInterrupt done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set sampling parameters
|
||||
* "index" is an index into the audio_sample_rates[] etc. vectors
|
||||
* It is guaranteed that AudioStatus.num_sources == 0
|
||||
*/
|
||||
|
||||
bool audio_set_sample_rate(int index)
|
||||
{
|
||||
close_audio();
|
||||
audio_sample_rate_index = index;
|
||||
return open_audio();
|
||||
}
|
||||
|
||||
bool audio_set_sample_size(int index)
|
||||
{
|
||||
close_audio();
|
||||
audio_sample_size_index = index;
|
||||
return open_audio();
|
||||
}
|
||||
|
||||
bool audio_set_channels(int index)
|
||||
{
|
||||
close_audio();
|
||||
audio_channel_count_index = index;
|
||||
return open_audio();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get/set volume controls (volume values received/returned have the left channel
|
||||
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
|
||||
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
|
||||
*/
|
||||
|
||||
bool audio_get_main_mute(void)
|
||||
{
|
||||
return main_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_main_volume(void)
|
||||
{
|
||||
uint32 chan = main_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
bool audio_get_speaker_mute(void)
|
||||
{
|
||||
return speaker_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_speaker_volume(void)
|
||||
{
|
||||
uint32 chan = speaker_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
void audio_set_main_mute(bool mute)
|
||||
{
|
||||
main_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_main_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
main_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (main_volume > MAC_MAX_VOLUME)
|
||||
main_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
void audio_set_speaker_mute(bool mute)
|
||||
{
|
||||
speaker_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_speaker_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
speaker_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (speaker_volume > MAC_MAX_VOLUME)
|
||||
speaker_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
static int get_audio_volume() {
|
||||
return main_volume * speaker_volume * SDL_MIX_MAXVOLUME / (MAC_MAX_VOLUME * MAC_MAX_VOLUME);
|
||||
}
|
||||
|
||||
static int play_startup(void *arg) {
|
||||
SDL_AudioSpec wav_spec;
|
||||
Uint8 *wav_buffer;
|
||||
Uint32 wav_length;
|
||||
if (!playing_startup && !SDL_LoadWAV("startup.wav", &wav_spec, &wav_buffer, &wav_length)) {
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &wav_spec, NULL, NULL);
|
||||
if (stream) {
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
SDL_PutAudioStreamData(stream, wav_buffer, wav_length);
|
||||
playing_startup = true;
|
||||
while (!exit_startup && SDL_GetAudioStreamAvailable(stream)) SDL_Delay(10);
|
||||
if (!exit_startup) SDL_Delay(500);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
}
|
||||
else printf("play_startup: Audio driver failed to initialize\n");
|
||||
SDL_free(wav_buffer);
|
||||
playing_startup = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PlayStartupSound() {
|
||||
SDL_CreateThread(play_startup, "play_startup", NULL);
|
||||
}
|
||||
|
||||
#endif // SDL_VERSION_ATLEAST
|
|
@ -67,7 +67,9 @@ void LoadPrefs(const char * vmdir) // TODO: load prefs from 'vmdir'
|
|||
fclose(f);
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef __linux__
|
||||
PrefsAddString("cdrom", "/dev/cdrom");
|
||||
#endif
|
||||
// No prefs file, save defaults
|
||||
SavePrefs();
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <SDL_thread.h>
|
||||
#include <errno.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <malloc.h> /* alloca() */
|
||||
|
@ -118,7 +119,9 @@ static bool use_vosf = false; // Flag: VOSF enabled
|
|||
static const bool use_vosf = false; // VOSF not possible
|
||||
#endif
|
||||
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed (for use with hotkeys)
|
||||
static bool opt_down = false; // Flag: Opt/Alt key pressed (for use with hotkeys)
|
||||
static bool cmd_down = false; // Flag: Cmd/Super/Win key pressed (for use with hotkeys)
|
||||
static bool caps_on = false; // Flag: Caps Lock on
|
||||
static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread
|
||||
static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread
|
||||
|
@ -155,6 +158,11 @@ static SDL_mutex *frame_buffer_lock = NULL;
|
|||
#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock)
|
||||
#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock)
|
||||
|
||||
// Previously set gamma tables
|
||||
static uint16 last_gamma_red[256];
|
||||
static uint16 last_gamma_green[256];
|
||||
static uint16 last_gamma_blue[256];
|
||||
|
||||
// Video refresh function
|
||||
static void VideoRefreshInit(void);
|
||||
static void (*video_refresh)(void);
|
||||
|
@ -360,6 +368,7 @@ public:
|
|||
|
||||
virtual void switch_to_current_mode(void);
|
||||
virtual void set_palette(uint8 *pal, int num);
|
||||
virtual void set_gamma(uint8 *gamma, int num);
|
||||
|
||||
bool video_open(void);
|
||||
void video_close(void);
|
||||
|
@ -515,12 +524,26 @@ static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth)
|
|||
}
|
||||
|
||||
// Set window name and class
|
||||
static void set_window_name(int name)
|
||||
static void set_window_name(bool mouse_grabbed)
|
||||
{
|
||||
const char *title = PrefsFindString("title");
|
||||
std::string s = title ? title : GetString(STR_WINDOW_TITLE);
|
||||
int grabbed = 0;
|
||||
if (mouse_grabbed)
|
||||
{
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_PRE);
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
hotkey = hotkey ? hotkey : 1;
|
||||
if (hotkey & 1) s += GetString(STR_WINDOW_TITLE_GRABBED1);
|
||||
if (hotkey & 2) s += GetString(STR_WINDOW_TITLE_GRABBED2);
|
||||
if (hotkey & 4) s += GetString(STR_WINDOW_TITLE_GRABBED4);
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_POST);
|
||||
}
|
||||
const SDL_VideoInfo *vi = SDL_GetVideoInfo();
|
||||
if (vi && vi->wm_available) {
|
||||
const char *str = GetString(name);
|
||||
SDL_WM_SetCaption(str, str);
|
||||
if (vi && vi->wm_available)
|
||||
{
|
||||
//The icon name should stay the same
|
||||
SDL_WM_SetCaption(s.c_str(), GetString(STR_WINDOW_TITLE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -731,7 +754,7 @@ void driver_base::adapt_to_video_mode() {
|
|||
SDL_ShowCursor(hardware_cursor);
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(STR_WINDOW_TITLE);
|
||||
set_window_name(false);
|
||||
|
||||
// Everything went well
|
||||
init_ok = true;
|
||||
|
@ -1299,8 +1322,8 @@ void VideoVBL(void)
|
|||
// Setting the window name must happen on the main thread, else it doesn't work on
|
||||
// some platforms - e.g. macOS Sierra.
|
||||
if (mouse_grabbed_window_name_status != mouse_grabbed) {
|
||||
set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE);
|
||||
mouse_grabbed_window_name_status = mouse_grabbed;
|
||||
set_window_name(mouse_grabbed);
|
||||
mouse_grabbed_window_name_status = mouse_grabbed;
|
||||
}
|
||||
|
||||
// Temporarily give up frame buffer lock (this is the point where
|
||||
|
@ -1328,7 +1351,7 @@ void VideoInterrupt(void)
|
|||
// Setting the window name must happen on the main thread, else it doesn't work on
|
||||
// some platforms - e.g. macOS Sierra.
|
||||
if (mouse_grabbed_window_name_status != mouse_grabbed) {
|
||||
set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE);
|
||||
set_window_name(mouse_grabbed);
|
||||
mouse_grabbed_window_name_status = mouse_grabbed;
|
||||
}
|
||||
|
||||
|
@ -1363,9 +1386,51 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in)
|
|||
{
|
||||
const VIDEO_MODE &mode = get_current_mode();
|
||||
|
||||
// FIXME: how can we handle the gamma ramp?
|
||||
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT)
|
||||
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) {
|
||||
// handle the gamma ramp
|
||||
|
||||
if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey
|
||||
return; // ignore
|
||||
|
||||
uint16 red[256];
|
||||
uint16 green[256];
|
||||
uint16 blue[256];
|
||||
|
||||
int repeats = 256 / num_in;
|
||||
|
||||
for (int i = 0; i < num_in; i++) {
|
||||
for (int j = 0; j < repeats; j++) {
|
||||
red[i*repeats + j] = pal[i*3 + 0] << 8;
|
||||
green[i*repeats + j] = pal[i*3 + 1] << 8;
|
||||
blue[i*repeats + j] = pal[i*3 + 2] << 8;
|
||||
}
|
||||
}
|
||||
|
||||
// fill remaining entries (if any) with last value
|
||||
for (int i = num_in * repeats; i < 256; i++) {
|
||||
red[i] = pal[(num_in - 1) * 3] << 8;
|
||||
green[i] = pal[(num_in - 1) * 3 + 1] << 8;
|
||||
blue[i] = pal[(num_in - 1) * 3 + 2] << 8;
|
||||
}
|
||||
|
||||
bool changed = (memcmp(red, last_gamma_red, 512) != 0 ||
|
||||
memcmp(green, last_gamma_green, 512) != 0 ||
|
||||
memcmp(blue, last_gamma_blue, 512) != 0);
|
||||
|
||||
if (changed) {
|
||||
int result = SDL_SetGammaRamp(red, green, blue);
|
||||
|
||||
if (result < 0) {
|
||||
fprintf(stderr, "SDL_SetGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError());
|
||||
}
|
||||
|
||||
memcpy(last_gamma_red, red, 512);
|
||||
memcpy(last_gamma_green, green, 512);
|
||||
memcpy(last_gamma_blue, blue, 512);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK_PALETTE;
|
||||
|
||||
|
@ -1405,6 +1470,10 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in)
|
|||
UNLOCK_PALETTE;
|
||||
}
|
||||
|
||||
void SDL_monitor_desc::set_gamma(uint8 *gamma, int num_in)
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch video mode
|
||||
|
@ -1564,11 +1633,29 @@ static bool is_modifier_key(SDL_KeyboardEvent const & e)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool is_ctrl_down(SDL_keysym const & ks)
|
||||
static bool is_hotkey_down(SDL_keysym const & ks)
|
||||
{
|
||||
return ctrl_down || (ks.mod & KMOD_CTRL);
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
if (!hotkey) hotkey = 1;
|
||||
return (ctrl_down || (ks.mod & KMOD_CTRL) || !(hotkey & 1)) &&
|
||||
(opt_down || (ks.mod & KMOD_ALT) || !(hotkey & 2)) &&
|
||||
(cmd_down || (ks.mod & KMOD_META) || !(hotkey & 4));
|
||||
}
|
||||
|
||||
static int modify_opt_cmd(int code) {
|
||||
static bool f, c;
|
||||
if (!f) {
|
||||
f = true;
|
||||
c = PrefsFindBool("swap_opt_cmd");
|
||||
}
|
||||
if (c) {
|
||||
switch (code) {
|
||||
case 0x37: return 0x3a;
|
||||
case 0x3a: return 0x37;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate key event to Mac keycode, returns -1 if no keycode was found
|
||||
|
@ -1628,8 +1715,8 @@ static int kc_decode(SDL_keysym const & ks, bool key_down)
|
|||
case SDLK_PERIOD: case SDLK_GREATER: return 0x2f;
|
||||
case SDLK_SLASH: case SDLK_QUESTION: return 0x2c;
|
||||
|
||||
case SDLK_TAB: if (is_ctrl_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case SDLK_RETURN: if (is_ctrl_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24;
|
||||
case SDLK_TAB: if (is_hotkey_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case SDLK_RETURN: if (is_hotkey_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24;
|
||||
case SDLK_SPACE: return 0x31;
|
||||
case SDLK_BACKSPACE: return 0x33;
|
||||
|
||||
|
@ -1644,19 +1731,9 @@ static int kc_decode(SDL_keysym const & ks, bool key_down)
|
|||
case SDLK_RCTRL: return 0x36;
|
||||
case SDLK_LSHIFT: return 0x38;
|
||||
case SDLK_RSHIFT: return 0x38;
|
||||
#if (defined(__APPLE__) && defined(__MACH__))
|
||||
case SDLK_LALT: return 0x3a;
|
||||
case SDLK_RALT: return 0x3a;
|
||||
case SDLK_LMETA: return 0x37;
|
||||
case SDLK_RMETA: return 0x37;
|
||||
#else
|
||||
case SDLK_LALT: return 0x37;
|
||||
case SDLK_RALT: return 0x37;
|
||||
case SDLK_LMETA: return 0x3a;
|
||||
case SDLK_RMETA: return 0x3a;
|
||||
#endif
|
||||
case SDLK_LSUPER: return 0x3a; // "Windows" key
|
||||
case SDLK_RSUPER: return 0x3a;
|
||||
case SDLK_LALT: case SDLK_RALT: return 0x3a;
|
||||
case SDLK_LMETA: case SDLK_RMETA: return 0x37;
|
||||
case SDLK_LSUPER: case SDLK_RSUPER: return 0x37; // "Windows" key
|
||||
case SDLK_MENU: return 0x32;
|
||||
case SDLK_CAPSLOCK: return 0x39;
|
||||
case SDLK_NUMLOCK: return 0x47;
|
||||
|
@ -1666,13 +1743,13 @@ static int kc_decode(SDL_keysym const & ks, bool key_down)
|
|||
case SDLK_LEFT: return 0x3b;
|
||||
case SDLK_RIGHT: return 0x3c;
|
||||
|
||||
case SDLK_ESCAPE: if (is_ctrl_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
case SDLK_ESCAPE: if (is_hotkey_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
|
||||
case SDLK_F1: if (is_ctrl_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case SDLK_F1: if (is_hotkey_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case SDLK_F2: return 0x78;
|
||||
case SDLK_F3: return 0x63;
|
||||
case SDLK_F4: return 0x76;
|
||||
case SDLK_F5: if (is_ctrl_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case SDLK_F5: if (is_hotkey_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case SDLK_F6: return 0x61;
|
||||
case SDLK_F7: return 0x62;
|
||||
case SDLK_F8: return 0x64;
|
||||
|
@ -1795,6 +1872,15 @@ static void handle_events(void)
|
|||
code = event2keycode(event.key, true);
|
||||
if (code >= 0) {
|
||||
if (!emul_suspended) {
|
||||
if (code == 0x36) {
|
||||
ctrl_down = true;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
if (code == 0x39) { // Caps Lock pressed
|
||||
if (caps_on) {
|
||||
ADBKeyUp(code);
|
||||
|
@ -1805,8 +1891,6 @@ static void handle_events(void)
|
|||
}
|
||||
} else
|
||||
ADBKeyDown(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = true;
|
||||
} else {
|
||||
if (code == 0x31)
|
||||
drv->resume(); // Space wakes us up
|
||||
|
@ -1822,6 +1906,15 @@ static void handle_events(void)
|
|||
} else
|
||||
code = event2keycode(event.key, false);
|
||||
if (code >= 0) {
|
||||
if (code == 0x36) {
|
||||
ctrl_down = false;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
if (code == 0x39) { // Caps Lock released
|
||||
if (caps_on) {
|
||||
ADBKeyUp(code);
|
||||
|
@ -1832,8 +1925,6 @@ static void handle_events(void)
|
|||
}
|
||||
} else
|
||||
ADBKeyUp(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2290,4 +2381,11 @@ void video_set_dirty_area(int x, int y, int w, int h)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
void video_set_gamma(int n_colors)
|
||||
{
|
||||
// Not supported in SDL 1.2
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ends: SDL version check
|
||||
|
|
File diff suppressed because it is too large
Load Diff
2847
BasiliskII/src/SDL/video_sdl3.cpp
Normal file
2847
BasiliskII/src/SDL/video_sdl3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -71,7 +71,7 @@ void SaveXPRAM(void)
|
|||
SDL_snprintf(full_path, sizeof(full_path), "%s/%s", dir, XPRAM_FILE_NAME);
|
||||
|
||||
// Save the XPRAM file
|
||||
FILE *f = fopen(XPRAM_FILE_NAME, "wb");
|
||||
FILE *f = fopen(full_path, "wb");
|
||||
if (f != NULL) {
|
||||
fwrite(XPRAM, 256, 1, f);
|
||||
fclose(f);
|
||||
|
|
1
BasiliskII/src/Unix/.gitignore
vendored
1
BasiliskII/src/Unix/.gitignore
vendored
|
@ -19,6 +19,7 @@ cpustbl.cpp
|
|||
cputbl.h
|
||||
cpuemu_nf.cpp
|
||||
cpustbl_nf.cpp
|
||||
cpufunctbl.cpp
|
||||
|
||||
patches/*
|
||||
.pc*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,166 +0,0 @@
|
|||
/* GIMP RGBA C-Source image dump (BasiliskII_32x32x32_icon.c) */
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[32 * 32 * 4 + 1];
|
||||
} icon_32x32x32 = {
|
||||
32, 32, 4,
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q'\17s\377s\0\377q\37\6s\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0JJJ\377\7\7\7!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0h(\16k\377\214\0\377"
|
||||
"\356b\16\357\36\27\27!\12\12\12\30%%%)\356b\16\357\315Y\40\316\263I\40\326"
|
||||
"\245B)\377\203\27\0\204z\16\0{z\16\0{\203\27\0\204z\16\0{\203\27\0\204z\16"
|
||||
"\0{z\16\0{\203\27\0\204\264I\27\265,\26\15""9\0\0\0\10\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\377{\0\377\377\204"
|
||||
"\0\377%\22\22)\27\27\27!AAARbbb\224jjj\224\377\224\0\377\377\214\0\377\377"
|
||||
"\224\0\377\377\224\0\377\377\214\0\377\377\224\0\377\377\224\0\377\377\224"
|
||||
"\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0"
|
||||
"\377\377s\0\377,((9\37\37\37)\0\0\0\0\0\0\0\0,,,9jjj\204jjj\204aaa{jjj\204"
|
||||
"\2138\40\224\377\224\0\377\377k\0\377bbb\204jjj\234zzz\306zzz\326\203\203"
|
||||
"\203\316zzz\245\377\224\0\377\377\204\0\377\377s\0\377\377s\0\377\377{\0"
|
||||
"\377\377s\0\377\377s\0\377\377s\0\377\377{\0\377\377s\0\377\377s\0\377\377"
|
||||
"s\0\377\377s\0\377\377c\0\377zzz\306rrr\265\0\0\0\0\0\0\0\0jjj\204\234\234"
|
||||
"\234\377\234\234\234\377\245\245\245\377\357c\30\377\377\224\0\377\367c\0"
|
||||
"\377\224\224\224\377{{{\377ccc\377sss\377\214\214\214\377\234\234\234\377"
|
||||
"\234\234\234\377\377\224\0\377\377{\0\377\377s\0\377\377k\0\377\377k\0\377"
|
||||
"\377s\0\377\377k\0\377\377s\0\377\377k\0\377\377s\0\377\377s\0\377\377s\0"
|
||||
"\377\377s\0\377\306Z9\377{{{\377rrr\275\0\0\0\0\0\0\0\0bbb\204\234\234\234"
|
||||
"\377\245\245\245\377\367s\20\377\377\204\0\377\377k\0\377\214\214\214\377"
|
||||
"kkk\377ZZZ\377{{{\377\224\224\224\377\234\234\234\377\245\245\245\377\224"
|
||||
"\224\224\377\2559!\377\306\224\204\377\214kk\377kkk\377sss\377sss\377sss"
|
||||
"\377sss\377sss\377sss\377sss\377\367R\10\377\377k\0\377{{{\377\203\203\203"
|
||||
"\367XXX\204\0\0\0\0\0\0\0\0jjj\204\245\245\245\377\357c\30\377\377\204\0"
|
||||
"\377\377s\0\377\224\204\204\377ccc\377ZZZ\377{{{\377\234\234\234\377\245"
|
||||
"\245\245\377\245\245\245\377\234\234\234\377RRR\377sss\377\306\306\306\377"
|
||||
"\214\214\214\377\214\214\214\377\214\214\214\377\214\214\214\377\214\214"
|
||||
"\214\377\224\224\224\377\214\214\214\377\214\214\214\377\224\224\224\377"
|
||||
"\377c\0\377\357R\30\377\204\204\204\377zzz\326666B\0\0\0\0\0\0\0\0aaa{\306"
|
||||
"sR\377\377\224\0\377\377{\0\377\316R1\377ccc\377RRR\377JJJ\377{{{\377\234"
|
||||
"\234\234\377\245\245\245\377\234\234\234\377\224\224\224\377RRR\377\336\336"
|
||||
"\336\377\336\336\336\377\316\316\316\377\316\316\316\377\224\224\224\377"
|
||||
"RRR\377\326\326\326\377\326\326\326\377\326\326\326\377\326\326\326\377\326"
|
||||
"\306\306\377\377k\0\377\306\275\265\377\203\203\203\357jjj\234\25\25\25\30"
|
||||
"\0\0\0\0\0\0\0\0jbb\204\377\224\0\377\377{\0\377\377k\0\377ccc\377RRR\377"
|
||||
"kkk\377ccc\377\204\204\204\377\245\245\245\377\245\245\245\377\234\234\234"
|
||||
"\377ZZZ\377ccc\377\347\347\347\377\347\347\347\377\347\347\347\377\347\347"
|
||||
"\347\377\224\224\224\377RRR\377\347\347\347\377\336\336\336\377\347\347\347"
|
||||
"\377\347\347\347\377\367k9\377\377c\0\377\275\275\275\377\203\203\203\347"
|
||||
"IIIZ\0\0\0\0\0\0\0\0\0\0\0\0\356j\16\357\377\204\0\377\377s\0\377\234R9\377"
|
||||
"RRR\377ZZZ\377\214\214\214\377ccc\377\204\204\204\377\234\234\234\377\234"
|
||||
"\234\234\377\245\245\245\377RRR\377\326\326\326\377\347\347\347\377\336\336"
|
||||
"\336\377\347\347\347\377\336\336\336\377\234\234\234\377JJJ\377\347\347\347"
|
||||
"\377\347\347\347\377\347\347\347\377\336\336\336\377\377k\0\377\347\224\204"
|
||||
"\377\234\234\234\377\203\203\203\326\36\36\36!\0\0\0\0\0\0\0\0\0\0\0\10\377"
|
||||
"\224\0\377\377{\0\377\377k\0\377RRR\377RRR\377sss\377\224\224\224\377\234"
|
||||
"\234\234\377\245\245\245\377\245\245\245\377\234\234\234\377\214\214\214"
|
||||
"\377JJJ\377\347\347\347\377\347\347\347\377\347\347\347\377\336\336\336\377"
|
||||
"\347\347\347\377\347\347\347\377\347\347\347\377\347\347\347\377\347\347"
|
||||
"\347\377\336\336\336\377\347\275\265\377\377s\0\377\316\316\316\377\214\214"
|
||||
"\214\377\203\203\203\265\0\0\0\10\0\0\0\0\0\0\0\0\335Y\26\336\377\214\0\377"
|
||||
"\377s\0\377\316B\30\377JJJ\377ZZZ\377\204\204\204\377\234\234\234\377\245"
|
||||
"\245\245\377\245\245\245\377\234\234\234\377\245\245\245\377ccc\377kkk\377"
|
||||
"\347\347\347\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347"
|
||||
"\347\377\336\336\336\377\336\336\336\377\347\347\347\377\336\336\336\377"
|
||||
"\347\347\347\377\377c!\377\367c)\377\265\265\265\377\214\214\214\377zzz\224"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\377\224\0\377\377{\0\377\377k\0\377ZRR\377RRR\377"
|
||||
"{kk\377\377Z\10\377\377s\0\377\377s\0\377\377s\0\377\357R\30\377\245\245"
|
||||
"\245\377RRR\377\255\255\255\377\347\347\347\377\336\336\336\377\347\347\347"
|
||||
"\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347\347\377\347"
|
||||
"\347\347\377\347\347\347\377\347\347\347\377\377k\0\377\336\316\316\377\234"
|
||||
"\234\234\377\245\245\245\377yyy\204\0\0\0\0\0\0\0\0\36\27\27!\377\224\0\377"
|
||||
"\377s\0\377\377k\0\377RRR\377ZRR\377\377k\0\377\316cJ\377\316cJ\377\377\214"
|
||||
"\0\377\377s\0\377\377s\0\377\377c\0\377RRR\377\326\326\326\377\336\336\336"
|
||||
"\377\347\347\347\377\347\347\347\377\347\347\347\377\336\336\336\377\347"
|
||||
"\347\347\377\336\336\336\377\347\347\347\377\336\336\336\377\357\245\224"
|
||||
"\377\377c\0\377\306\306\306\377\214\214\214\377\275\275\275\377yyy\204\0"
|
||||
"\0\0\0\0\0\0\0\212(\16\214\377\224\0\377\377k\0\377\377R\0\377RRR\377ccc"
|
||||
"\377\224\224\224\377\234\234\234\377{{{\377ccc\377\377\214\0\377\377s\0\377"
|
||||
"\377s\0\377\347B\10\377\316\316\316\377\347\347\347\377\347\347\347\377\347"
|
||||
"\347\347\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347\347"
|
||||
"\377\347\347\347\377\347\347\347\377\377R\0\377\357\204c\377\255\255\255"
|
||||
"\377\224\224\224\377\326\326\326\377zzz{\0\0\0\0\0\0\0\0\335b\26\336\377"
|
||||
"\214\0\377\377s\0\377\336J\20\377RRR\377kkk\377\224\224\224\377\204\204\204"
|
||||
"\377kkk\377{{{\377\265ZJ\377\377\214\0\377\377s\0\377\377s\0\377111\377J"
|
||||
"JJ\377RRR\377JJJ\377RRR\377\347\347\347\377\347\347\347\377\347\347\347\377"
|
||||
"\336\336\336\377\347\347\347\377\377k\0\377\326\326\326\377\234\234\234\377"
|
||||
"\255\255\255\377\336\336\336\377yyy\204\0\0\0\0\0\0\0\0\377Z\0\377\377\204"
|
||||
"\0\377\377k\0\377\275B\30\377JJJ\377{{{\377\234\234\234\377\234\234\234\377"
|
||||
"\234\234\234\377\234\234\234\377\234\234\234\377\377\224\0\377\377{\0\377"
|
||||
"\377s\0\377\265B)\377sss\377\224\224\224\377kkk\377ZZZ\377\336\336\336\377"
|
||||
"\336\336\336\377\347\347\347\377\347\347\347\377\367\224{\377\377Z\10\377"
|
||||
"\306\306\306\377\214\214\214\377\306\306\306\377\336\336\336\377\203\203"
|
||||
"\203\204\0\0\0\0\0\0\0\0\377c\0\377\377\204\0\377\377s\0\377\275B!\377RR"
|
||||
"R\377{{{\377\234\234\234\377\245\245\245\377\234\234\234\377\245\245\245"
|
||||
"\377\234\234\234\377\377c\0\377\377\214\0\377\377k\0\377\357J\10\377ccc\377"
|
||||
"\224\224\224\377RRR\377\214\214\214\377\347\347\347\377\347\347\347\377\347"
|
||||
"\347\347\377\336\336\336\377\377Z\0\377\347\245\234\377\255\255\255\377\234"
|
||||
"\234\234\377\326\326\326\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0\377c\0\377"
|
||||
"\377\204\0\377\377s\0\377\316J\30\377RRR\377\204\204\204\377\224\224\224"
|
||||
"\377kkk\377{{{\377\234\234\234\377\245\245\245\377\347c)\377\377\224\0\377"
|
||||
"\377s\0\377\377R\0\377RRR\377\204\204\204\377JJJ\377\265\265\265\377\347"
|
||||
"\347\347\377\336\336\336\377\347\347\347\377\336\336\336\377\377k\0\377J"
|
||||
"JJ\377\214\214\214\377\265\265\265\377\336\336\336\377\347\347\347\377zz"
|
||||
"z{\0\0\0\0\0\0\0\0\346b\17\347\377\214\0\377\377k\0\377\347J\10\377ZZZ\377"
|
||||
"\204\204\204\377\245\245\245\377\214\214\214\377kkk\377kkk\377kkk\377\275"
|
||||
"J1\377\377\224\0\377\377s\0\377\377Z\0\377JJJ\377sss\377RRR\377\214\214\214"
|
||||
"\377sss\377ZZZ\377JJJ\377\275B!\377\336J\20\377\255\255\255\377\224\224\224"
|
||||
"\377\316\316\316\377\336\336\336\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0"
|
||||
"\2437\27\245\377\214\0\377\377s\0\377\377Z\0\377RRR\377\204\204\204\377\234"
|
||||
"\234\234\377\245\245\245\377\234\234\234\377\245\245\245\377\234\234\234"
|
||||
"\377\306ZB\377\377\224\0\377\377s\0\377\367J\0\377111\377RRR\377RRR\377Z"
|
||||
"ZZ\377sss\377\224\224\224\377\326\326\326\377\377c\0\377\336\326\316\377"
|
||||
"\245\245\245\377\245\245\245\377\336\336\336\377\347\347\347\377\347\347"
|
||||
"\347\377zzz{\0\0\0\0\0\0\0\0%\22\22)\377\214\0\377\377s\0\377\377k\0\377"
|
||||
"RRR\377{{{\377\234\234\234\377\245\245\245\377\234\234\234\377\245\245\245"
|
||||
"\377\234\234\234\377\326kJ\377\377\214\0\377\377s\0\377\306J!\377RRR\377"
|
||||
"sss\377JJJ\377\265\265\265\377\336\336\336\377\347\347\347\377\347\326\326"
|
||||
"\377\377c\0\377\316\316\316\377\224\224\224\377\275\275\275\377\336\336\336"
|
||||
"\377\347\347\347\377\336\336\336\377zzz{\0\0\0\0\0\0\0\0\0\0\0\0\377\224"
|
||||
"\0\377\377\204\0\377\377s\0\377kJJ\377kkk\377\234\234\234\377\245\245\245"
|
||||
"\377\234\234\234\377\245\245\245\377\245\245\245\377\347c)\377\377\214\0"
|
||||
"\377\377s\0\377cJB\377ZZZ\377{{{\377RRR\377\224\224\224\377\347\347\347\377"
|
||||
"\347\347\347\377\367c)\377\367\204c\377\275\275\275\377\224\224\224\377\316"
|
||||
"\316\316\377\347\347\347\377\347\347\347\377\347\347\347\377yyy\204\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\264@\27\265\377\214\0\377\377s\0\377\357J\10\377kkk\377"
|
||||
"\224\224\224\377\245\245\245\377\234\234\234\377\245\245\245\377\234\234"
|
||||
"\234\377\377c\0\377\377\204\0\377\377c\0\377RRR\377ZZZ\377\204\204\204\377"
|
||||
"ccc\377ccc\377\336\336\336\377\347\347\347\377\377s\0\377\326\326\326\377"
|
||||
"\245\245\245\377\245\245\245\377\336\336\336\377\336\336\336\377\336\336"
|
||||
"\336\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\377\224\0\377"
|
||||
"\377\204\0\377\377k\0\377kkc\377\245\245\245\377\265\265\265\377\275\275"
|
||||
"\275\377\265\265\265\377\265\265\265\377\377\224\0\377\377s\0\377\234ZR\377"
|
||||
"ccc\377kkk\377\245\245\245\377\245\245\245\377RRR\377\357\357\357\377\357"
|
||||
"\255\234\377\377R\0\377\326\326\326\377\234\234\234\377\326\326\326\377\357"
|
||||
"\357\357\377\357\357\357\377\367\367\367\377\357\357\357\377zzz{\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0H%\37J\377\214\0\377\377{\0\377\367Z\0\377XXX\204"
|
||||
"\17\17\17\20\0\0\0\0\0\0\0\0\2128\27\214\377{\0\377\335Q\16\336zzz\326zz"
|
||||
"z\367bbb\224\17\17\17\20\0\0\0\0RRR\377\0\0\0\0\377Z\0\377W\37\26ZQQQkjj"
|
||||
"j\234\27\27\27!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0yA0\204\377\224\0\377\377{\0\377\367Z\10\3776..B\0"
|
||||
"\0\0\0P\37\17R\377{\0\377\346Y\16\357QQQk\203\203\203\357zzz\316666B\0\0"
|
||||
"\0\10\0\0\0\0III\336777\234\377s\0\377\27\27\27!rrr\245QQQk\0\0\0\10\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\17\17\17\20YYY{\356Y\7\367\377k\0\377\377k\0\377\377s\0\377\377c\0\377"
|
||||
"a&\27c%%%)rrr\265zzz\326QQQk\0\0\0\10\0\0\0\0\0\0\0\0\0\0\0\20RRR\377\0\0"
|
||||
"\0\0""777Jrrr\265$$$1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\25\25\25\30YYY{zzz\336\203\203"
|
||||
"\203\357rrr\255IIIZIIIZjjj\245zzz\316QQQk\17\17\17\20\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\10IIIZXXXs\17\17\17\20\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\10\17\17\17\20AAAJbbb\224rrr\275zzz\275jjj\255bbb\214666B\17\17\17"
|
||||
"\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\0\0\0\20\17"
|
||||
"\17\17\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0",
|
||||
};
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
sw_vers > /dev/null && exit 0
|
||||
|
||||
PAGEZERO_SIZE=0x2000
|
||||
[[ -n "$1" ]] && PAGEZERO_SIZE=$1
|
||||
# You want all the output to go to stderr so that configure is quiet but
|
||||
|
|
506
BasiliskII/src/Unix/Linux/etherhelpertool.c
Normal file
506
BasiliskII/src/Unix/Linux/etherhelpertool.c
Normal file
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* etherhelpertool.c - Reads and writes raw ethernet packets usng bpf
|
||||
* interface.
|
||||
*
|
||||
* Copyright (C) 2010, Daniel Sumorok
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <linux/if_tun.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#define STR_MAX 256
|
||||
#define MAX_ARGV 10
|
||||
|
||||
static int remove_bridge = 0;
|
||||
static char bridge_name[STR_MAX];
|
||||
static const char *exec_name = "etherhelpertool";
|
||||
|
||||
static int main_loop(int sd, int use_bpf);
|
||||
static int open_tap(char *ifname);
|
||||
static int run_cmd(const char *cmd);
|
||||
static void handler(int signum);
|
||||
static int install_signal_handlers(void);
|
||||
static void do_exit(void);
|
||||
static int open_bpf(char *ifname);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *if_name;
|
||||
int ret = 255;
|
||||
int sd = -1;
|
||||
int tapNum;
|
||||
int use_bpf;
|
||||
|
||||
if (argc != 2) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
if_name = argv[1];
|
||||
|
||||
do {
|
||||
if (strncmp(if_name, "tap", 3) == 0) {
|
||||
sd = open_tap(if_name);
|
||||
use_bpf = 0;
|
||||
} else {
|
||||
sd = open_bpf(if_name);
|
||||
use_bpf = 1;
|
||||
}
|
||||
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: open device failed.\n",
|
||||
exec_name);
|
||||
ret = 253;
|
||||
break;
|
||||
}
|
||||
|
||||
if (install_signal_handlers() != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: failed to install signal handers.\n",
|
||||
exec_name);
|
||||
ret = 252;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = main_loop(sd, use_bpf);
|
||||
close(sd);
|
||||
} while (0);
|
||||
|
||||
do_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int main_loop(int sd, int use_bpf)
|
||||
{
|
||||
fd_set readSet;
|
||||
char *outgoing, *incoming;
|
||||
unsigned short *out_len;
|
||||
unsigned short *in_len;
|
||||
int in_index, out_index;
|
||||
u_int blen = 0;
|
||||
int ret;
|
||||
int fret = 0;
|
||||
int pkt_len;
|
||||
int frame_len;
|
||||
int pad;
|
||||
char c = 0;
|
||||
|
||||
blen = 4096;
|
||||
|
||||
incoming = malloc(blen);
|
||||
if (incoming == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -2;
|
||||
}
|
||||
|
||||
outgoing = malloc(blen);
|
||||
if (outgoing == NULL) {
|
||||
free(incoming);
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -3;
|
||||
}
|
||||
|
||||
in_index = 0;
|
||||
out_index = 0;
|
||||
|
||||
out_len = (unsigned short *)outgoing;
|
||||
|
||||
/* Let our parent know we are ready for business. */
|
||||
if(write(0, &c, 1) != 1) {
|
||||
fprintf(stderr, "%s: Failed to notify main application: %s\n",
|
||||
__func__, strerror(errno));
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int i;
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(0, &readSet);
|
||||
FD_SET(sd, &readSet);
|
||||
|
||||
ret = select(sd + 1, &readSet, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: select() failed.\n",
|
||||
exec_name);
|
||||
fret = -4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(0, &readSet)) {
|
||||
if (out_index < 2) {
|
||||
ret = read(0, outgoing + out_index, 2-out_index);
|
||||
} else {
|
||||
ret = read(0, outgoing + out_index, *out_len - out_index + 2);
|
||||
}
|
||||
|
||||
if (ret < 1) {
|
||||
if(ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: read() failed.\n",
|
||||
exec_name);
|
||||
}
|
||||
fret = -5;
|
||||
break;
|
||||
}
|
||||
|
||||
out_index += ret;
|
||||
|
||||
if (out_index > 1) {
|
||||
if ((*out_len + 2) > blen) {
|
||||
fret = -6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (out_index == (*out_len + 2)) {
|
||||
if(use_bpf) {
|
||||
ret = write(sd, out_len + 1, *out_len);
|
||||
if (ret != *out_len) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed.\n",
|
||||
exec_name);
|
||||
fret = -7;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = write(sd, out_len + 1, *out_len);
|
||||
if (ret != *out_len) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed.\n",
|
||||
exec_name);
|
||||
fret = -7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sd, &readSet)) {
|
||||
in_len = (unsigned short *)incoming;
|
||||
|
||||
pkt_len = read(sd, in_len + 1, blen-2);
|
||||
if (pkt_len < 14) {
|
||||
fprintf(stderr,
|
||||
"%s: read() returned %d.\n",
|
||||
exec_name, pkt_len);
|
||||
fret = -8;
|
||||
break;
|
||||
}
|
||||
*in_len = pkt_len;
|
||||
|
||||
if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed\n",
|
||||
exec_name);
|
||||
fret = -10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(incoming);
|
||||
free(outgoing);
|
||||
|
||||
return fret;
|
||||
}
|
||||
|
||||
|
||||
static int open_tap(char *ifname)
|
||||
{
|
||||
char str[STR_MAX] = {0};
|
||||
char ifstr[STR_MAX] = {0};
|
||||
char *interface;
|
||||
char *address = NULL;
|
||||
char *netmask = NULL;
|
||||
char *bridge = NULL;
|
||||
char *bridged_if = NULL;
|
||||
int sd;
|
||||
struct ifreq ifr = {0};
|
||||
|
||||
snprintf(ifstr, STR_MAX, "%s", ifname);
|
||||
interface = strtok(ifstr, "/");
|
||||
bridge = strtok(NULL, "/");
|
||||
if (bridge != NULL) {
|
||||
bridged_if = strtok(NULL, "/");
|
||||
}
|
||||
interface = strtok(ifstr, ":");
|
||||
|
||||
address = strtok(NULL, ":");
|
||||
|
||||
if (address != NULL) {
|
||||
netmask = strtok(NULL, ":");
|
||||
}
|
||||
|
||||
sd = open("/dev/net/tun", O_RDWR);
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, interface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/dev/%s", interface);
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
|
||||
|
||||
if(ioctl(sd, TUNSETIFF, (void *)&ifr) != 0) {
|
||||
fprintf(stderr, "%s: ioctl(TUNSETIFF): %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (address == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface);
|
||||
} else if (netmask == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s",
|
||||
interface, address);
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s",
|
||||
interface, address, netmask);
|
||||
}
|
||||
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to configure %s\n",
|
||||
exec_name, interface);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridge != NULL) {
|
||||
/* Check to see if bridge is alread up */
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge);
|
||||
if (run_cmd(str) == 0) {
|
||||
/* bridge is already up */
|
||||
if (bridged_if != NULL) {
|
||||
fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n",
|
||||
exec_name, bridge, bridged_if);
|
||||
}
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/brctl addbr %s", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to create %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
remove_bridge = 1;
|
||||
|
||||
strncpy(bridge_name, bridge, STR_MAX);
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridged_if != NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/brctl addif %s %s",
|
||||
bridge, bridged_if);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, bridged_if, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/brctl addif %s %s",
|
||||
bridge, interface);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, interface, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static int run_cmd(const char *cmd) {
|
||||
char cmd_buffer[STR_MAX] = {0};
|
||||
char *argv[MAX_ARGV + 1] = {0};
|
||||
int i;
|
||||
pid_t pid, waitpid;
|
||||
int status = 0;
|
||||
|
||||
/* Collect arguments */
|
||||
strncpy(cmd_buffer, cmd, STR_MAX-1);
|
||||
|
||||
argv[0] = strtok(cmd_buffer, " ");
|
||||
for (i=1; i<MAX_ARGV; ++i) {
|
||||
argv[i] = strtok(NULL, " ");
|
||||
if (argv[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run sub process */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
|
||||
/* Child process */
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
if (execve(argv[0], argv, NULL) < 0) {
|
||||
perror("execve");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Wait for child to exit */
|
||||
waitpid = wait(&status);
|
||||
if (waitpid < 0) {
|
||||
perror("wait");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handler(int signum) {
|
||||
do_exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int install_signal_handlers() {
|
||||
struct sigaction act = {0};
|
||||
|
||||
act.sa_handler = handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
|
||||
if (sigaction(SIGINT, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGHUP, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_exit() {
|
||||
char cmd[STR_MAX];
|
||||
|
||||
if (remove_bridge) {
|
||||
snprintf(cmd, STR_MAX, "/sbin/ifconfig %s down",
|
||||
bridge_name);
|
||||
|
||||
if(run_cmd(cmd) != 0) {
|
||||
fprintf(stderr, "Failed to bring bridge down\n");
|
||||
}
|
||||
|
||||
snprintf(cmd, STR_MAX, "/sbin/brctl delbr %s",
|
||||
bridge_name);
|
||||
|
||||
if(run_cmd(cmd) != 0) {
|
||||
fprintf(stderr, "Failed to destroy bridge\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int open_bpf(char *ifname)
|
||||
{
|
||||
int sd;
|
||||
struct sockaddr_ll sockaddr = {0};
|
||||
struct ifreq ifreq = {0};
|
||||
struct packet_mreq pmreq = {0};
|
||||
socklen_t socklen = sizeof(struct packet_mreq);
|
||||
|
||||
sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
if(sd < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
|
||||
if(ioctl(sd, SIOCGIFINDEX, &ifreq) != 0) {
|
||||
fprintf(stderr, "%s: ioctl(SIOCGIFINDEX): %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pmreq.mr_ifindex = ifreq.ifr_ifindex;
|
||||
pmreq.mr_type = PACKET_MR_PROMISC;
|
||||
if(setsockopt(sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
|
||||
&pmreq, socklen) != 0) {
|
||||
fprintf(stderr, "%s: setsockopt() failed: %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sockaddr.sll_family = AF_PACKET;
|
||||
sockaddr.sll_ifindex = ifreq.ifr_ifindex;
|
||||
sockaddr.sll_protocol = htons(ETH_P_ALL);
|
||||
if(bind(sd, (struct sockaddr *)&sockaddr,
|
||||
sizeof(struct sockaddr_ll)) != 0) {
|
||||
fprintf(stderr, "%s: bind failed: %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
58
BasiliskII/src/Unix/Linux/runtool.c
Normal file
58
BasiliskII/src/Unix/Linux/runtool.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define STR_MAX 1024
|
||||
#define MAX_ARGV 10
|
||||
|
||||
FILE * run_tool(const char *if_name, const char *tool_name) {
|
||||
char cmd_buffer[STR_MAX] = {0};
|
||||
char * const argv[3] = {NULL, NULL, NULL};
|
||||
int i;
|
||||
pid_t pid, waitpid;
|
||||
int status = 0;
|
||||
int fds[2];
|
||||
char c;
|
||||
|
||||
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
|
||||
fprintf(stderr, "%s: socketpair() failed: %s\n",
|
||||
__func__, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
((const char**)argv)[0] = tool_name;
|
||||
((const char**)argv)[1] = if_name;
|
||||
|
||||
/* Run sub process */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
/* Child process */
|
||||
fclose(stdout);
|
||||
fclose(stdin);
|
||||
dup2(fds[0], 0);
|
||||
close(fds[1]);
|
||||
close(fds[0]);
|
||||
|
||||
if (execve(tool_name, argv, NULL) < 0) {
|
||||
perror("execve");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
close(fds[0]);
|
||||
|
||||
if(read(fds[1], &c, 1) < 1) {
|
||||
close(fds[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fdopen(fds[1], "rw");
|
||||
}
|
|
@ -100,7 +100,7 @@ define GUI_SRCS_LIST_TO_OBJS
|
|||
endef
|
||||
GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS)
|
||||
ifeq ($(USE_BINCUE),yes)
|
||||
GUI_OBJS += bincue_unix.o
|
||||
GUI_OBJS += bincue.o
|
||||
endif
|
||||
GUI_SRCS := $(GUI_SRCS:%=@top_srcdir@/%)
|
||||
|
||||
|
@ -161,7 +161,9 @@ installdirs:
|
|||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(bindir)/$(APP)$(EXEEXT)
|
||||
rm -f $(DESTDIR)$(bindir)/$(GUI_APP)$(EXEEXT)
|
||||
if test -f "$(GUI_APP_EXE)"; then \
|
||||
rm -f $(DESTDIR)$(bindir)/$(GUI_APP_EXE); \
|
||||
fi
|
||||
rm -f $(DESTDIR)$(man1dir)/$(APP).1
|
||||
rm -f $(DESTDIR)$(datadir)/$(APP)/keycodes
|
||||
rm -f $(DESTDIR)$(datadir)/$(APP)/fbdevices
|
||||
|
@ -212,13 +214,16 @@ $(OBJ_DIR)/gencpu$(EXEEXT): $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/
|
|||
$(OBJ_DIR)/gencomp$(EXEEXT): $(OBJ_DIR)/gencomp.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
|
||||
$(CXX) $(LDFLAGS) -o $(OBJ_DIR)/gencomp$(EXEEXT) $(OBJ_DIR)/gencomp.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
|
||||
|
||||
cpudefs.cpp: $(OBJ_DIR)/build68k$(EXEEXT) @top_srcdir@/../uae_cpu/table68k
|
||||
$(OBJ_DIR)/build68k$(EXEEXT) <@top_srcdir@/../uae_cpu/table68k >cpudefs.cpp
|
||||
UAE_PATH = @UAE_PATH@
|
||||
|
||||
cpudefs.cpp: $(OBJ_DIR)/build68k$(EXEEXT) @top_srcdir@/$(UAE_PATH)/table68k
|
||||
$(OBJ_DIR)/build68k$(EXEEXT) <@top_srcdir@/$(UAE_PATH)/table68k >cpudefs.cpp
|
||||
cpustbl.cpp: cpuemu.cpp
|
||||
cpustbl_nf.cpp: cpustbl.cpp
|
||||
compstbl.cpp: compemu.cpp
|
||||
cputbl.h: cpuemu.cpp
|
||||
comptbl.h: compemu.cpp
|
||||
cpufunctbl.cpp: cputbl.h
|
||||
|
||||
cpuemu.cpp: $(OBJ_DIR)/gencpu$(EXEEXT)
|
||||
$(OBJ_DIR)/gencpu$(EXEEXT)
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
# serial 1
|
||||
dnl Additional macros for Basilisk II
|
||||
|
||||
dnl Check for libgnomeui
|
||||
dnl B2_PATH_GNOMEUI([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test to see if libgnomeui is installed, and define GNOMEUI_CFLAGS, LIBS
|
||||
AC_DEFUN([B2_PATH_GNOMEUI],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the gnome-config script
|
||||
dnl
|
||||
AC_ARG_WITH(gnome-config,
|
||||
[ --with-gnome-config=GNOME_CONFIG Location of gnome-config],
|
||||
GNOME_CONFIG="$withval")
|
||||
|
||||
AC_PATH_PROG(GNOME_CONFIG, gnome-config, no)
|
||||
AC_MSG_CHECKING(for libgnomeui)
|
||||
if test "$GNOME_CONFIG" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
GNOMEUI_CFLAGS=`$GNOME_CONFIG --cflags gnomeui`
|
||||
GNOMEUI_LIBS=`$GNOME_CONFIG --libs gnomeui`
|
||||
ifelse([$1], , :, [$1])
|
||||
fi
|
||||
AC_SUBST(GNOMEUI_CFLAGS)
|
||||
AC_SUBST(GNOMEUI_LIBS)
|
||||
])
|
1756
BasiliskII/src/Unix/config.guess
vendored
1756
BasiliskII/src/Unix/config.guess
vendored
File diff suppressed because it is too large
Load Diff
2550
BasiliskII/src/Unix/config.sub
vendored
2550
BasiliskII/src/Unix/config.sub
vendored
File diff suppressed because it is too large
Load Diff
224
BasiliskII/src/Unix/configure.ac
Executable file → Normal file
224
BasiliskII/src/Unix/configure.ac
Executable file → Normal file
|
@ -28,7 +28,7 @@ dnl Video options.
|
|||
AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes])
|
||||
AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes])
|
||||
AC_ARG_ENABLE(fbdev-dga, [ --enable-fbdev-dga use direct frame buffer access via /dev/fb [default=yes]], [WANT_FBDEV_DGA=$enableval], [WANT_FBDEV_DGA=yes])
|
||||
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=yes])
|
||||
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=no]], [WANT_VOSF=$enableval], [WANT_VOSF=no])
|
||||
|
||||
dnl SDL options.
|
||||
AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no])
|
||||
|
@ -37,9 +37,10 @@ AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [defau
|
|||
AC_ARG_ENABLE(sdl-framework, [ --enable-sdl-framework use SDL framework [default=no]], [WANT_SDL_FRAMEWORK=$enableval], [WANT_SDL_FRAMEWORK=no])
|
||||
AC_ARG_ENABLE(sdl-framework-prefix, [ --enable-sdl-framework-prefix=PFX default=/Library/Frameworks], [SDL_FRAMEWORK="$enableval"], [SDL_FRAMEWORK=/Library/Frameworks])
|
||||
AC_ARG_WITH(sdl1, [ --with-sdl1 use SDL 1.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=1], [])
|
||||
AC_ARG_WITH(sdl3, [ --with-sdl3 use SDL 3.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=3], [])
|
||||
|
||||
dnl JIT compiler options.
|
||||
AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=no]], [WANT_JIT=$enableval], [WANT_JIT=yes])
|
||||
AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes])
|
||||
AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no])
|
||||
|
||||
dnl FPU emulation core.
|
||||
|
@ -75,13 +76,11 @@ dnl External packages.
|
|||
AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes])
|
||||
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]],
|
||||
[case "$withval" in
|
||||
gtk1) WANT_GTK="gtk";;
|
||||
gtk|gtk2) WANT_GTK="$withval";;
|
||||
yes) WANT_GTK="gtk2 gtk";;
|
||||
yes|gtk2) WANT_GTK="gtk2";;
|
||||
*) WANT_GTK="no";;
|
||||
esac],
|
||||
[WANT_GTK="gtk2 gtk"])
|
||||
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes])
|
||||
[WANT_GTK="gtk2"])
|
||||
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=no]], [WANT_MON=$withval], [WANT_MON=no])
|
||||
|
||||
AC_ARG_WITH(bincue,
|
||||
AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode]))
|
||||
|
@ -89,6 +88,11 @@ AC_ARG_WITH(bincue,
|
|||
AC_ARG_WITH(libvhd,
|
||||
AS_HELP_STRING([--with-libvhd], [Enable VHD disk images]))
|
||||
|
||||
AC_ARG_WITH(vdeplug,
|
||||
AS_HELP_STRING([--with-vdeplug], [Enable VDE virtual network support]),
|
||||
[],
|
||||
[with_vdeplug=yes])
|
||||
|
||||
|
||||
dnl Cross Compiling results in 'guesses' being made about the target system. These defaults are oftetimes incorrect.
|
||||
dnl The following Environment variables allow you to configure the default guess value for each option in the configure script.
|
||||
|
@ -213,7 +217,7 @@ if [[ "x$HAVE_I386" = "xyes" ]]; then
|
|||
fi
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
|
@ -326,9 +330,18 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then
|
|||
dnl never got defined (bizarrely-enough). -- dludwig@pobox.com
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x3" ]]; then
|
||||
PKG_CHECK_MODULES([sdl3], [sdl3 >= 3.0], [
|
||||
CXXFLAGS="$CXXFLAGS $sdl3_CFLAGS"
|
||||
CXXFLAGS+=`echo " $sdl3_CFLAGS" | sed -e 's/\(-I.*include\)/\1\/SDL3/'`
|
||||
LIBS="$LIBS $sdl3_LIBS"
|
||||
WANT_SDL_VERSION_MAJOR=3
|
||||
], [
|
||||
TEMP_WANT_SDL_VERSION_MAJOR=1
|
||||
])
|
||||
fi
|
||||
if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x2" ]]; then
|
||||
PKG_CHECK_MODULES([sdl2], [sdl2 >= 2.0], [
|
||||
CFLAGS="$CFLAGS $sdl2_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $sdl2_CFLAGS"
|
||||
LIBS="$LIBS $sdl2_LIBS"
|
||||
WANT_SDL_VERSION_MAJOR=2
|
||||
|
@ -369,6 +382,7 @@ AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no])
|
|||
AS_IF([test "x$have_bincue" = "xyes" ], [
|
||||
if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then
|
||||
DEFINES="$DEFINES -DBINCUE"
|
||||
CPPFLAGS="$CPPFLAGS -DBINCUE"
|
||||
AC_SUBST(USE_BINCUE, yes)
|
||||
else
|
||||
AC_MSG_ERROR([You need SDL Audio to use BINCUE support.])
|
||||
|
@ -446,41 +460,13 @@ fi
|
|||
|
||||
dnl We use GTK+ if possible.
|
||||
UISRCS=../dummy/prefs_editor_dummy.cpp
|
||||
case "x$WANT_GTK" in
|
||||
xgtk2*)
|
||||
AM_PATH_GTK_2_0(1.3.15, [
|
||||
if [[ "x$WANT_GTK" = "xgtk2" ]]; then
|
||||
AM_PATH_GTK_2_0(2.6.4, [
|
||||
GUI_CFLAGS="$GTK_CFLAGS"
|
||||
GUI_LIBS="$GTK_LIBS"
|
||||
WANT_GTK=gtk2
|
||||
], [
|
||||
case "x${WANT_GTK}x" in
|
||||
*gtkx)
|
||||
AC_MSG_WARN([Could not find GTK+ 2.0, trying with GTK+ 1.2.])
|
||||
WANT_GTK=gtk
|
||||
;;
|
||||
*)
|
||||
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
||||
WANT_GTK=no
|
||||
;;
|
||||
esac
|
||||
])
|
||||
;;
|
||||
esac
|
||||
if [[ "x$WANT_GTK" = "xgtk" ]]; then
|
||||
AM_PATH_GTK(1.2.0, [
|
||||
GUI_CFLAGS="$GTK_CFLAGS"
|
||||
GUI_LIBS="$GTK_LIBS"
|
||||
dnl somehow, <gnome-i18n.h> would redefine gettext() to nothing if
|
||||
dnl ENABLE_NLS is not set, thusly conflicting with C++ <string> which
|
||||
dnl includes <libintl.h>
|
||||
AM_GNU_GETTEXT
|
||||
B2_PATH_GNOMEUI([
|
||||
AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.])
|
||||
GUI_CFLAGS="$GUI_CFLAGS $GNOMEUI_CFLAGS"
|
||||
GUI_LIBS="$GUI_LIBS $GNOMEUI_LIBS"
|
||||
], [])
|
||||
], [
|
||||
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
||||
AC_MSG_WARN([Could not find GTK+ 2.0, disabling user interface.])
|
||||
WANT_GTK=no
|
||||
])
|
||||
fi
|
||||
|
@ -588,7 +574,8 @@ dnl Check for headers and functions related to pty support (sshpty.c)
|
|||
dnl From openssh-3.2.2p1 configure.ac
|
||||
|
||||
AC_CHECK_HEADERS(strings.h login.h sys/bsdtty.h sys/stat.h util.h pty.h)
|
||||
AC_CHECK_FUNCS(_getpty vhangup strlcpy)
|
||||
AC_SEARCH_LIBS([openpty], [util bsd])
|
||||
AC_CHECK_FUNCS(_getpty openpty vhangup strlcpy)
|
||||
|
||||
case "$host" in
|
||||
*-*-hpux10.26)
|
||||
|
@ -611,11 +598,13 @@ mips-sony-bsd|mips-sony-newsos4)
|
|||
;;
|
||||
*-*-darwin*)
|
||||
no_dev_ptmx=1
|
||||
LIBS="$LIBS -lstdc++"
|
||||
;;
|
||||
*-*-freebsd*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
*-*-netbsd*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
esac
|
||||
|
||||
if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
|
||||
|
@ -725,6 +714,7 @@ AC_CHECK_FRAMEWORK(AppKit, [])
|
|||
AC_CHECK_FRAMEWORK(Carbon, [#include <Carbon/Carbon.h>])
|
||||
AC_CHECK_FRAMEWORK(IOKit, [#include <IOKit/IOKitLib.h>])
|
||||
AC_CHECK_FRAMEWORK(CoreFoundation, [#include <CoreFoundation/CoreFoundation.h>])
|
||||
AC_CHECK_FRAMEWORK(Metal, [])
|
||||
|
||||
dnl Select system-dependant source files.
|
||||
SERIALSRC=serial_unix.cpp
|
||||
|
@ -768,8 +758,11 @@ netbsd*)
|
|||
ETHERSRC=ether_unix.cpp
|
||||
;;
|
||||
solaris*)
|
||||
AUDIOSRC=Solaris/audio_solaris.cpp
|
||||
DEFINES="$DEFINES -DBSD_COMP -D_POSIX_PTHREAD_SEMANTICS"
|
||||
dnl Needed for sys/socket.h
|
||||
LIBS="$LIBS -lsocket -lnsl"
|
||||
dnl Needed for SDL2
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
;;
|
||||
irix*)
|
||||
AUDIOSRC=Irix/audio_irix.cpp
|
||||
|
@ -822,6 +815,13 @@ if [[ -n "$CAN_SLIRP" ]]; then
|
|||
fi
|
||||
AC_SUBST(SLIRP_SRCS)
|
||||
|
||||
dnl Is libvdeplug available?
|
||||
have_vdeplug=no
|
||||
AS_IF([test "x$with_vdeplug" = "xyes"], [
|
||||
have_vdeplug=yes
|
||||
AC_CHECK_LIB(vdeplug, vde_close, [], [have_vdeplug=no])
|
||||
])
|
||||
|
||||
if [[ "x$WANT_MACOSX_GUI" = "xyes" ]]; then
|
||||
CPPFLAGS="$CPPFLAGS -I../MacOSX"
|
||||
LIBS="$LIBS -framework CoreAudio -framework AudioUnit -framework AudioToolbox"
|
||||
|
@ -855,7 +855,7 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then
|
|||
fi
|
||||
if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
|
||||
AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support])
|
||||
VIDEOSRCS="../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp"
|
||||
VIDEOSRCS="../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp ../SDL/video_sdl3.cpp "
|
||||
KEYCODES="../SDL/keycodes"
|
||||
if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then
|
||||
AC_MSG_CHECKING([whether __LP64__ is defined])
|
||||
|
@ -881,6 +881,9 @@ if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
|
|||
EXTRASYSSRCS="$EXTRASYSSRCS ../dummy/clip_dummy.cpp"
|
||||
;;
|
||||
esac
|
||||
if [[ "$WANT_GTK" != "no" ]]; then
|
||||
LIBS="$LIBS -lX11"
|
||||
fi
|
||||
fi
|
||||
elif [[ "x$WANT_MACOSX_GUI" != "xyes" ]]; then
|
||||
VIDEOSRCS="video_x.cpp"
|
||||
|
@ -889,13 +892,13 @@ elif [[ "x$WANT_MACOSX_GUI" != "xyes" ]]; then
|
|||
fi
|
||||
if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then
|
||||
AC_DEFINE(USE_SDL_AUDIO, 1, [Define to enable SDL audio support])
|
||||
AUDIOSRC="../SDL/audio_sdl.cpp"
|
||||
AUDIOSRC="../SDL/audio_sdl.cpp ../SDL/audio_sdl3.cpp"
|
||||
fi
|
||||
|
||||
dnl BINCUE overrides
|
||||
|
||||
if [[ "x$have_bincue" = "xyes" ]]; then
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS bincue_unix.cpp"
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS bincue.cpp"
|
||||
fi
|
||||
|
||||
dnl libvhd overrides
|
||||
|
@ -947,6 +950,9 @@ AC_CACHE_CHECK([whether TUN/TAP is supported],
|
|||
#include <net/if.h>
|
||||
#include <net/if_tun.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
], [
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
|
@ -1104,42 +1110,37 @@ AC_TRANSLATE_DEFINE(HAVE_MMAP_VM, "$have_mmap_vm",
|
|||
|
||||
fi dnl HAVE_MMAP_VM
|
||||
|
||||
if [[ "$OS_TYPE" != "darwin" ]]; then
|
||||
dnl Check if we can disable position-independent code
|
||||
AC_CACHE_CHECK([whether the compiler supports -no-pie],
|
||||
ac_cv_no_pie, [
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -no-pie"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM()],[
|
||||
ac_cv_no_pie="yes"],[
|
||||
ac_cv_no_pie="no"
|
||||
])
|
||||
if [[ "$ac_cv_no_pie" = "no" ]]; then
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
fi
|
||||
])
|
||||
fi
|
||||
|
||||
dnl Check if we can modify the __PAGEZERO segment for use as Low Memory
|
||||
AC_CACHE_CHECK([whether __PAGEZERO can be Low Memory area 0x0000-0x2000],
|
||||
ac_cv_pagezero_hack, [
|
||||
ac_cv_pagezero_hack=no
|
||||
if AC_TRY_COMMAND([Darwin/testlmem.sh 0x2000]); then
|
||||
case $target_os:$target_cpu in
|
||||
darwin*:x86_64)
|
||||
ac_cv_pagezero_hack=yes
|
||||
dnl might as well skip the test for mmap-able low memory
|
||||
ac_cv_can_map_lm=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
])
|
||||
AC_TRANSLATE_DEFINE(PAGEZERO_HACK, "$ac_cv_pagezero_hack",
|
||||
[Define if the __PAGEZERO Mach-O Low Memory Globals hack works on this system.])
|
||||
|
||||
dnl Check if we can mmap 0x2000 bytes from 0x0000
|
||||
AC_CACHE_CHECK([whether we can map Low Memory area 0x0000-0x2000],
|
||||
ac_cv_can_map_lm, [
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_RUN([
|
||||
#include "../CrossPlatform/vm_alloc.cpp"
|
||||
int main(void) { /* returns 0 if we could map the lowmem globals */
|
||||
volatile char * lm = 0;
|
||||
if (vm_init() < 0) exit(1);
|
||||
if (vm_acquire_fixed(0, 0x2000) < 0) exit(1);
|
||||
lm[0] = 'z';
|
||||
if (vm_release((char *)lm, 0x2000) < 0) exit(1);
|
||||
vm_exit(); exit(0);
|
||||
}
|
||||
], ac_cv_can_map_lm=yes, ac_cv_can_map_lm=no,
|
||||
dnl When cross-compiling, do not assume anything.
|
||||
ac_cv_can_map_lm="$BII_CROSS_MAP_LOW_AREA"
|
||||
)
|
||||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
dnl Check signal handlers need to be reinstalled
|
||||
AC_CACHE_CHECK([whether signal handlers need to be reinstalled],
|
||||
ac_cv_signal_need_reinstall, [
|
||||
|
@ -1224,6 +1225,11 @@ AC_CACHE_CHECK([whether your system supports Mach exceptions],
|
|||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
case $target_os:$target_cpu in
|
||||
darwin*:arm) ac_cv_have_mach_exceptions=yes;;
|
||||
esac
|
||||
|
||||
AC_TRANSLATE_DEFINE(HAVE_MACH_EXCEPTIONS, "$ac_cv_have_mach_exceptions",
|
||||
[Define if your system supports Mach exceptions.])
|
||||
|
||||
|
@ -1360,6 +1366,11 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler],
|
|||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
ac_cv_have_skip_instruction=yes
|
||||
fi
|
||||
|
||||
AC_TRANSLATE_DEFINE(HAVE_SIGSEGV_SKIP_INSTRUCTION, "$ac_cv_have_skip_instruction",
|
||||
[Define if we can ignore the fault (instruction skipping in SIGSEGV handler).])
|
||||
|
||||
|
@ -1375,11 +1386,10 @@ AC_PATH_PROG([BLESS], "true")
|
|||
dnl Check for linker script support
|
||||
case $target_os:$target_cpu in
|
||||
linux*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";;
|
||||
linux*:x86_64) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-x86_64.ld";;
|
||||
linux*:powerpc) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-ppc.ld";;
|
||||
netbsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";;
|
||||
freebsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/freebsd-i386.ld";;
|
||||
darwin*:*) LINKER_SCRIPT_FLAGS="-Wl,-seg1addr,0x78048000";;
|
||||
#darwin*:*) LINKER_SCRIPT_FLAGS="-Wl,-seg1addr,0x78048000";;
|
||||
esac
|
||||
if [[ -n "$LINKER_SCRIPT_FLAGS" ]]; then
|
||||
AC_CACHE_CHECK([whether linker script is usable],
|
||||
|
@ -1414,17 +1424,12 @@ else
|
|||
for am in $ADDRESSING_TEST_ORDER; do
|
||||
case $am in
|
||||
real)
|
||||
dnl Requires ability to mmap() Low Memory globals
|
||||
if [[ "x$ac_cv_can_map_lm$ac_cv_pagezero_hack" = "xnono" ]]; then
|
||||
continue
|
||||
fi
|
||||
dnl Requires VOSF screen updates
|
||||
if [[ "x$CAN_VOSF" = "xno" ]]; then
|
||||
continue
|
||||
fi
|
||||
dnl Real addressing will probably work.
|
||||
ADDRESSING_MODE="real"
|
||||
WANT_VOSF=yes dnl we can use VOSF and we need it actually
|
||||
DEFINES="$DEFINES -DREAL_ADDRESSING"
|
||||
if [[ "x$ac_cv_pagezero_hack" = "xyes" ]]; then
|
||||
BLESS=Darwin/lowmem
|
||||
|
@ -1436,7 +1441,6 @@ else
|
|||
dnl Requires VOSF screen updates
|
||||
if [[ "x$CAN_VOSF" = "xyes" ]]; then
|
||||
ADDRESSING_MODE="direct"
|
||||
WANT_VOSF=yes dnl we can use VOSF and we need it actually
|
||||
DEFINES="$DEFINES -DDIRECT_ADDRESSING"
|
||||
break
|
||||
fi
|
||||
|
@ -1459,7 +1463,15 @@ fi
|
|||
|
||||
dnl Banked Memory Addressing mode is not supported by the JIT compiler
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$ADDRESSING_MODE" = "xmemory banks" ]]; then
|
||||
AC_MSG_ERROR([Sorry, the JIT Compiler requires Direct Addressing, at least])
|
||||
AC_MSG_WARN([The JIT Compiler requires Direct Addressing, disabling])
|
||||
WANT_JIT="no"
|
||||
fi
|
||||
|
||||
if [[ "x$OS_TYPE" = "xdarwin" ]]; then
|
||||
WANT_VOSF=no
|
||||
if [[ "$target_cpu" != "arm" ]]; then
|
||||
LDFLAGS="$LDFLAGS -Wl,-no_pie -pagezero_size 0x1000"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Enable VOSF screen updates with this feature is requested and feasible
|
||||
|
@ -1635,9 +1647,15 @@ elif [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then
|
|||
CPUSRCS="asm_support.s"
|
||||
fi
|
||||
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
UAE_PATH="../uae_cpu_2021"
|
||||
else
|
||||
UAE_PATH="../uae_cpu"
|
||||
fi
|
||||
|
||||
dnl Enable JIT compiler, if possible.
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then
|
||||
JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o"
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" = "xyes" ]]; then
|
||||
JITSRCS="$JITSRCS $UAE_PATH/compiler/compemu_support.cpp $UAE_PATH/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o"
|
||||
DEFINES="$DEFINES -DUSE_JIT -DUSE_JIT_FPU"
|
||||
|
||||
if [[ "x$WANT_JIT_DEBUG" = "xyes" ]]; then
|
||||
|
@ -1685,7 +1703,19 @@ cat > conftest.$ac_ext <<EOF
|
|||
#include "confdefs.h"
|
||||
$1
|
||||
]EOF
|
||||
ac_save_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -fno-lto"
|
||||
gcc_ac_compile_ok=0
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
gcc_ac_compile_ok=1
|
||||
else
|
||||
CFLAGS=$ac_save_CFLAGS
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
gcc_ac_compile_ok=1
|
||||
fi
|
||||
fi
|
||||
CFLAGS=$ac_save_CFLAGS
|
||||
if test "$gcc_ac_compile_ok" = 1; then
|
||||
od -c conftest.o |
|
||||
sed ['s/^[0-7]*[ ]*/ /
|
||||
s/\*/./g
|
||||
|
@ -1807,9 +1837,16 @@ for fpe in $FPE_CORE_TEST_ORDER; do
|
|||
ieee)
|
||||
case $ac_cv_c_float_format in
|
||||
IEEE*)
|
||||
FPE_CORE="IEEE fpu core"
|
||||
DEFINES="$DEFINES -DFPU_IEEE"
|
||||
FPUSRCS="../uae_cpu/fpu/fpu_ieee.cpp"
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
FPE_CORE="IEEE fpu core (MPFR)"
|
||||
DEFINES="$DEFINES -DFPU_MPFR"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_mpfr.cpp"
|
||||
LIBS="$LIBS -lmpfr -lgmp"
|
||||
else
|
||||
FPE_CORE="IEEE fpu core"
|
||||
DEFINES="$DEFINES -DFPU_IEEE"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_ieee.cpp"
|
||||
fi
|
||||
dnl Math functions not mandated by C99 standard
|
||||
AC_CHECK_FUNCS(isnanl isinfl)
|
||||
dnl Math functions required by C99 standard, but probably not
|
||||
|
@ -1827,14 +1864,14 @@ for fpe in $FPE_CORE_TEST_ORDER; do
|
|||
if [[ ":$HAVE_GCC27:$HAVE_I386:$HAVE_GAS:" = ":yes:yes:yes:" ]]; then
|
||||
FPE_CORE="i387 fpu core"
|
||||
DEFINES="$DEFINES -DFPU_X86"
|
||||
FPUSRCS="../uae_cpu/fpu/fpu_x86.cpp"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_x86.cpp"
|
||||
break
|
||||
fi
|
||||
;;
|
||||
uae)
|
||||
FPE_CORE="uae fpu core"
|
||||
DEFINES="$DEFINES -DFPU_UAE"
|
||||
FPUSRCS="../uae_cpu/fpu/fpu_uae.cpp"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_uae.cpp"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
|
@ -1852,8 +1889,12 @@ AC_CHECK_FUNCS(isnan isinf finite isnormal signbit)
|
|||
|
||||
dnl UAE CPU sources for all non-m68k-native architectures.
|
||||
if [[ "x$WANT_NATIVE_M68K" = "xno" ]]; then
|
||||
CPUINCLUDES="-I../uae_cpu"
|
||||
CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS"
|
||||
CPUINCLUDES="-I$UAE_PATH"
|
||||
CPUSRCS="$UAE_PATH/basilisk_glue.cpp $UAE_PATH/memory.cpp $UAE_PATH/newcpu.cpp $UAE_PATH/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS"
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
CPUSRCS="$CPUSRCS cpufunctbl.cpp"
|
||||
DEFINES="$DEFINES -DUPDATE_UAE"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Or if we have -IPA (MIPSPro compilers)
|
||||
|
@ -1864,6 +1905,9 @@ if [[ "x$HAVE_IPA" = "xyes" ]]; then
|
|||
LDFLAGS="$LDFLAGS -O3 -OPT:Olimit=0 -IPA"
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -fwrapv"
|
||||
CXXFLAGS="$CXXFLAGS -fwrapv"
|
||||
|
||||
dnl Generate Makefile.
|
||||
AC_SUBST(DEFINES)
|
||||
AC_SUBST(SYSSRCS)
|
||||
|
@ -1871,6 +1915,7 @@ AC_SUBST(CPUINCLUDES)
|
|||
AC_SUBST(CPUSRCS)
|
||||
AC_SUBST(BLESS)
|
||||
AC_SUBST(KEYCODES)
|
||||
AC_SUBST(UAE_PATH)
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
|
@ -1884,6 +1929,7 @@ echo SDL support ............................ : $SDL_SUPPORT
|
|||
echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR
|
||||
echo BINCUE support ......................... : $have_bincue
|
||||
echo LIBVHD support ......................... : $have_libvhd
|
||||
echo VDE support ............................ : $have_vdeplug
|
||||
echo XFree86 DGA support .................... : $WANT_XF86_DGA
|
||||
echo XFree86 VidMode support ................ : $WANT_XF86_VIDMODE
|
||||
echo fbdev DGA support ...................... : $WANT_FBDEV_DGA
|
||||
|
|
|
@ -39,8 +39,28 @@
|
|||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sun__
|
||||
#define BSD_COMP 1
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <net/if_dl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/if_packet.h>
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
|
@ -49,8 +69,9 @@
|
|||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#if defined(__FreeBSD__) || defined (__sun__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
|
@ -69,6 +90,12 @@
|
|||
#include "ctl.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
extern "C" {
|
||||
#include <libvdeplug.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "cpu_emulation.h"
|
||||
#include "main.h"
|
||||
#include "macos_util.h"
|
||||
|
@ -93,9 +120,18 @@ enum {
|
|||
NET_IF_SHEEPNET,
|
||||
NET_IF_ETHERTAP,
|
||||
NET_IF_TUNTAP,
|
||||
NET_IF_SLIRP
|
||||
NET_IF_SLIRP,
|
||||
NET_IF_VDE,
|
||||
NET_IF_ETHERHELPER
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
extern "C" {
|
||||
extern FILE * run_tool(const char *if_name, const char *tool_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
#if ENABLE_TUNTAP
|
||||
static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig";
|
||||
|
@ -115,6 +151,9 @@ static pthread_t slirp_thread; // Slirp reception thread
|
|||
static bool slirp_thread_active = false; // Flag: Slirp reception threadinstalled
|
||||
static int slirp_output_fd = -1; // fd of slirp output pipe
|
||||
static int slirp_input_fds[2] = { -1, -1 }; // fds of slirp input pipe
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
static VDECONN *vde_conn;
|
||||
#endif
|
||||
#ifdef SHEEPSHAVER
|
||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||
static uint8 ether_addr[6]; // Our Ethernet address
|
||||
|
@ -122,6 +161,11 @@ static uint8 ether_addr[6]; // Our Ethernet address
|
|||
const bool ether_driver_opened = true; // Flag: is the MacOS driver opened?
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
static uint8 packet_buffer[2048];
|
||||
#endif
|
||||
|
||||
// Attached network protocols, maps protocol type to MacOS handler address
|
||||
static map<uint16, uint32> net_protocols;
|
||||
|
||||
|
@ -135,6 +179,11 @@ static void ether_do_interrupt(void);
|
|||
static void slirp_add_redirs();
|
||||
static int slirp_add_redir(const char *redir_str);
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
static int get_mac_address(const char* dev, unsigned char *addr);
|
||||
static bool open_ether_helper(const std::string &if_name);
|
||||
static int read_packet(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start packet reception thread
|
||||
|
@ -235,23 +284,44 @@ bool ether_init(void)
|
|||
|
||||
// Do nothing if no Ethernet device specified
|
||||
const char *name = PrefsFindString("ether");
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
std::string slave_dev;
|
||||
#endif
|
||||
if (name == NULL)
|
||||
return false;
|
||||
|
||||
// Determine Ethernet device type
|
||||
net_if_type = -1;
|
||||
if (strncmp(name, "tap", 3) == 0)
|
||||
if (strncmp(name, "tap", 3) == 0) {
|
||||
net_if_type = NET_IF_ETHERTAP;
|
||||
printf("selected Ethernet device type tap\n");
|
||||
}
|
||||
#if ENABLE_TUNTAP
|
||||
else if (strcmp(name, "tun") == 0)
|
||||
else if (strcmp(name, "tun") == 0) {
|
||||
net_if_type = NET_IF_TUNTAP;
|
||||
printf("selected Ethernet device type tun\n");
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SLIRP
|
||||
else if (strcmp(name, "slirp") == 0)
|
||||
else if (strcmp(name, "slirp") == 0) {
|
||||
net_if_type = NET_IF_SLIRP;
|
||||
printf("selected Ethernet device type slirp\n");
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
else if (strcmp(name, "vde") == 0) {
|
||||
net_if_type = NET_IF_VDE;
|
||||
printf("selected Ethernet device type VDE\n");
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
else if (strncmp(name, "etherhelper", 10) == 0)
|
||||
net_if_type = NET_IF_ETHERHELPER;
|
||||
#endif
|
||||
else {
|
||||
net_if_type = NET_IF_SHEEPNET;
|
||||
printf("selected Ethernet device type sheep_net\n");
|
||||
}
|
||||
|
||||
// Don't raise SIGPIPE, let errno be set to EPIPE
|
||||
struct sigaction sigpipe_sa;
|
||||
|
@ -300,8 +370,55 @@ bool ether_init(void)
|
|||
case NET_IF_SHEEPNET:
|
||||
strcpy(dev_name, "/dev/sheep_net");
|
||||
break;
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
case NET_IF_ETHERHELPER: {
|
||||
std::string device(name);
|
||||
size_t pos;
|
||||
|
||||
pos = device.find('/');
|
||||
if(pos != device.npos) {
|
||||
slave_dev = device.substr(pos + 1);
|
||||
}
|
||||
|
||||
if(slave_dev.size() == 0) {
|
||||
WarningAlert("No network device specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return open_ether_helper(slave_dev);
|
||||
}
|
||||
if (net_if_type != NET_IF_SLIRP) {
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
//vde switch information
|
||||
int port = 0;
|
||||
char *init_group = NULL;
|
||||
mode_t mode = 0700;
|
||||
|
||||
struct vde_open_args args = {
|
||||
.port = port,
|
||||
.group = init_group,
|
||||
.mode = mode,
|
||||
};
|
||||
|
||||
if (net_if_type == NET_IF_VDE) {
|
||||
/* calling vde open to open the vde connection to the vde switch */
|
||||
vde_conn = vde_open(vde_sock, (char *)"macemu", &args);
|
||||
|
||||
if (!vde_conn) {
|
||||
D(bug("VDE open failed\n"));
|
||||
return -1;
|
||||
} else {
|
||||
/* for select/poll when this fd receive data, there are
|
||||
* packets to recv(call vde_recv) */
|
||||
fd = vde_datafd(vde_conn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (net_if_type != NET_IF_SLIRP && net_if_type != NET_IF_VDE) {
|
||||
fd = open(dev_name, O_RDWR);
|
||||
if (fd < 0) {
|
||||
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
|
||||
|
@ -387,6 +504,15 @@ bool ether_init(void)
|
|||
ether_addr[3] = 0x12;
|
||||
ether_addr[4] = 0x34;
|
||||
ether_addr[5] = 0x56;
|
||||
#endif
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
} else if (net_if_type == NET_IF_VDE) {
|
||||
ether_addr[0] = 0x52;
|
||||
ether_addr[1] = 0x54;
|
||||
ether_addr[2] = 0x00;
|
||||
ether_addr[3] = 0x12;
|
||||
ether_addr[4] = 0x34;
|
||||
ether_addr[5] = 0x56;
|
||||
#endif
|
||||
} else
|
||||
ioctl(fd, SIOCGIFADDR, ether_addr);
|
||||
|
@ -453,6 +579,11 @@ void ether_exit(void)
|
|||
if (slirp_output_fd > 0)
|
||||
close(slirp_output_fd);
|
||||
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
// Close vde_connection
|
||||
if (net_if_type == NET_IF_VDE)
|
||||
vde_close(vde_conn);
|
||||
#endif
|
||||
#if STATISTICS
|
||||
// Show statistics
|
||||
printf("%ld messages put on write queue\n", num_wput);
|
||||
|
@ -750,6 +881,40 @@ static int16 ether_do_write(uint32 arg)
|
|||
write(slirp_input_fd, packet, len);
|
||||
return noErr;
|
||||
} else
|
||||
#endif
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
if (net_if_type == NET_IF_VDE) {
|
||||
if (fd == -1) { // which means vde service is not running
|
||||
D(bug("WARNING: Couldn't transmit VDE packet\n"));
|
||||
return excessCollsns;
|
||||
}
|
||||
|
||||
if (vde_conn == NULL) {
|
||||
D(bug("WARNING: vde_conn is NULL\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
len = vde_send(vde_conn, packet, sizeof(packet), 0);
|
||||
} while (len < 0);
|
||||
|
||||
return noErr;
|
||||
} else
|
||||
#endif
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
if (net_if_type == NET_IF_ETHERHELPER) {
|
||||
unsigned short pkt_len;
|
||||
|
||||
pkt_len = len;
|
||||
if (write(fd, &pkt_len, 2) < 2) {
|
||||
return excessCollsns;
|
||||
}
|
||||
|
||||
if (write(fd, packet, len) < len) {
|
||||
return excessCollsns;
|
||||
}
|
||||
return noErr;
|
||||
} else
|
||||
#endif
|
||||
if (write(fd, packet, len) < 0) {
|
||||
D(bug("WARNING: Couldn't transmit packet\n"));
|
||||
|
@ -884,6 +1049,13 @@ static void *receive_func(void *arg)
|
|||
if (res <= 0)
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
if (net_if_type == NET_IF_ETHERHELPER) {
|
||||
if (read_packet() < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ether_driver_opened) {
|
||||
// Trigger Ethernet interrupt
|
||||
D(bug(" packet received, triggering Ethernet interrupt\n"));
|
||||
|
@ -924,14 +1096,33 @@ void ether_do_interrupt(void)
|
|||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
if (net_if_type == NET_IF_ETHERHELPER) {
|
||||
unsigned short *pkt_len;
|
||||
uint32 p = packet;
|
||||
|
||||
// Read packet from sheep_net device
|
||||
#if defined(__linux__)
|
||||
length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514);
|
||||
#else
|
||||
length = read(fd, Mac2HostAddr(packet), 1514);
|
||||
pkt_len = (unsigned short *)packet_buffer;
|
||||
length = *pkt_len;
|
||||
memcpy(Mac2HostAddr(packet), pkt_len + 1, length);
|
||||
ether_dispatch_packet(p, length);
|
||||
break;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
if (net_if_type == NET_IF_VDE) {
|
||||
length = vde_recv(vde_conn, Mac2HostAddr(packet), 1514, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Read packet from sheep_net device
|
||||
#if defined(__linux__)
|
||||
length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514);
|
||||
#else
|
||||
length = read(fd, Mac2HostAddr(packet), 1514);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (length < 14)
|
||||
break;
|
||||
|
||||
|
@ -1049,3 +1240,144 @@ static int slirp_add_redir(const char *redir_str)
|
|||
WarningAlert(str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
static int get_mac_address(const char* dev, unsigned char *addr)
|
||||
{
|
||||
struct ifaddrs *ifaddrs, *next;
|
||||
int ret = -1;
|
||||
#ifdef __APPLE__
|
||||
struct sockaddr_dl *sa;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
struct sockaddr_ll *sa;
|
||||
#endif
|
||||
if (getifaddrs(&ifaddrs) != 0) {
|
||||
perror("getifaddrs");
|
||||
return -1;
|
||||
}
|
||||
|
||||
next = ifaddrs;
|
||||
while (next != NULL) {
|
||||
switch (next->ifa_addr->sa_family) {
|
||||
#ifdef __APPLE__
|
||||
case AF_LINK:
|
||||
if (!strcmp(dev, next->ifa_name)) {
|
||||
sa = (struct sockaddr_dl *)next->ifa_addr;
|
||||
memcpy(addr, LLADDR(sa), 6);
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
case AF_PACKET:
|
||||
if (!strcmp(dev, next->ifa_name)) {
|
||||
sa = (struct sockaddr_ll *)next->ifa_addr;
|
||||
memcpy(addr, sa->sll_addr, 6);
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
next = next->ifa_next;
|
||||
}
|
||||
|
||||
freeifaddrs(ifaddrs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool open_ether_helper(const std::string &if_name)
|
||||
{
|
||||
FILE *fp;
|
||||
char str[64];
|
||||
std::string dev_name;
|
||||
size_t pos;
|
||||
|
||||
fp = run_tool(if_name.c_str(), "etherhelpertool");
|
||||
if (fp == NULL) {
|
||||
snprintf(str, sizeof(str), "Unable to run ether helper helper tool.");
|
||||
WarningAlert(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
pos = if_name.find('/');
|
||||
dev_name = if_name;
|
||||
if(pos != if_name.npos) {
|
||||
dev_name.erase(pos);
|
||||
}
|
||||
|
||||
if(strncmp(if_name.c_str(), "tap", 3) != 0) {
|
||||
if (get_mac_address(dev_name.c_str(), ether_addr) != 0) {
|
||||
snprintf(str, sizeof(str), "Unable to find interface %s.",
|
||||
dev_name.c_str());
|
||||
WarningAlert(str);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* There is something special about this address. */
|
||||
pid_t p = getpid();
|
||||
ether_addr[0] = 0xfe;
|
||||
ether_addr[1] = 0xfd;
|
||||
ether_addr[2] = p >> 24;
|
||||
ether_addr[3] = p >> 16;
|
||||
ether_addr[4] = p >> 8;
|
||||
ether_addr[5] = p;
|
||||
}
|
||||
|
||||
fd = dup(fileno(fp));
|
||||
fclose(fp);
|
||||
|
||||
if (start_thread() == false) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int read_packet()
|
||||
{
|
||||
int index;
|
||||
unsigned short *pkt_len;
|
||||
int ret = -1;
|
||||
|
||||
pkt_len = (unsigned short *)packet_buffer;
|
||||
|
||||
index = 0;
|
||||
while (1) {
|
||||
if (index < 2) {
|
||||
ret = read(fd, packet_buffer + index, 2 - index);
|
||||
} else {
|
||||
ret = read(fd, packet_buffer + index, *pkt_len - index + 2);
|
||||
}
|
||||
|
||||
if (ret < 1) {
|
||||
fprintf(stderr, "%s: read() returned %d.\n", __func__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
index += ret;
|
||||
|
||||
if (index > 1) {
|
||||
if (*pkt_len > (sizeof(packet_buffer) + 2)) {
|
||||
fprintf(stderr, "%s: pkt_len (%d) too large.\n", __func__, *pkt_len);
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == (*pkt_len + 2)) {
|
||||
ret = *pkt_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,29 +2,696 @@
|
|||
#
|
||||
# Basilisk II (C) 1997-2005 Christian Bauer
|
||||
#
|
||||
# This file is used to translate the (server-specific) X11 keycodes to Mac
|
||||
# keycodes depending on the X11 server being used.
|
||||
# This file is used to translate the (server-specific) scancodes to
|
||||
# Mac keycodes depending on the window server being used.
|
||||
#
|
||||
# The format of this file is as follows:
|
||||
#
|
||||
# sdl <driver string>
|
||||
# <SDL scancode> <Mac keycode>
|
||||
# <SDL scancode> <Mac keycode>
|
||||
# <SDL scancode> <Mac keycode>
|
||||
# ...
|
||||
# <vendor string>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# ...
|
||||
# <vendor string>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# ...
|
||||
#
|
||||
# The "vendor string" must match the first part of the X11 server vendor
|
||||
# description as reported by ServerVendor(). If a match is found, the keycode
|
||||
# translation table is constructed from the following lines. Each line
|
||||
# contains an X11 keycode followed by its associated Mac keycode. Both
|
||||
# keycodes have to be given in decimal. Lines beginning with "#" or ";" are
|
||||
# treated as comments and ignored.
|
||||
# The "driver string" must match the first part of the SDL driver
|
||||
# vendor description as reported by SDL_VideoDriverName(), while the
|
||||
# "vendor string" must match the first part of the X11 server vendor
|
||||
# description as reported by ServerVendor(). If a match is found,
|
||||
# the keycode translation table is constructed from the following
|
||||
# lines. Each line contains an SDL scancode or X11 keycode followed
|
||||
# by its associated Mac keycode. Both keycodes have to be given in
|
||||
# decimal. Lines beginning with "#" or ";" are treated as comments
|
||||
# and ignored.
|
||||
#
|
||||
|
||||
#
|
||||
# X11 server
|
||||
# X.Org
|
||||
# Wayland
|
||||
#
|
||||
sdl x11
|
||||
sdl wayland
|
||||
sdl dga
|
||||
The X.Org Foundation
|
||||
9 53 # Esc
|
||||
67 122 # F1
|
||||
68 120 # F2
|
||||
69 99 # F3
|
||||
70 118 # F4
|
||||
71 96 # F5
|
||||
72 97 # F6
|
||||
73 98 # F7
|
||||
74 100 # F8
|
||||
75 101 # F9
|
||||
76 109 # F10
|
||||
95 103 # F11
|
||||
96 111 # F12
|
||||
111 105 # PrintScrn
|
||||
78 107 # Scroll Lock
|
||||
110 113 # Pause
|
||||
49 50 # `
|
||||
10 18 # 1
|
||||
11 19 # 2
|
||||
12 20 # 3
|
||||
13 21 # 4
|
||||
14 23 # 5
|
||||
15 22 # 6
|
||||
16 26 # 7
|
||||
17 28 # 8
|
||||
18 25 # 9
|
||||
19 29 # 0
|
||||
20 27 # -
|
||||
21 24 # =
|
||||
22 51 # Backspace
|
||||
106 114 # Insert
|
||||
97 115 # Home
|
||||
99 116 # Page Up
|
||||
77 71 # Num Lock
|
||||
112 75 # KP /
|
||||
63 67 # KP *
|
||||
82 78 # KP -
|
||||
23 48 # Tab
|
||||
24 12 # Q
|
||||
25 13 # W
|
||||
26 14 # E
|
||||
27 15 # R
|
||||
28 17 # T
|
||||
29 16 # Y
|
||||
30 32 # U
|
||||
31 34 # I
|
||||
32 31 # O
|
||||
33 35 # P
|
||||
34 33 # [
|
||||
35 30 # ]
|
||||
36 36 # Return
|
||||
107 117 # Delete
|
||||
103 119 # End
|
||||
105 121 # Page Down
|
||||
79 89 # KP 7
|
||||
80 91 # KP 8
|
||||
81 92 # KP 9
|
||||
86 69 # KP +
|
||||
66 57 # Caps Lock
|
||||
38 0 # A
|
||||
39 1 # S
|
||||
40 2 # D
|
||||
41 3 # F
|
||||
42 5 # G
|
||||
43 4 # H
|
||||
44 38 # J
|
||||
45 40 # K
|
||||
46 37 # L
|
||||
47 41 # ;
|
||||
48 39 # '
|
||||
83 86 # KP 4
|
||||
84 87 # KP 5
|
||||
85 88 # KP 6
|
||||
50 56 # Shift Left
|
||||
94 50 # International
|
||||
52 6 # Z
|
||||
53 7 # X
|
||||
54 8 # C
|
||||
55 9 # V
|
||||
56 11 # B
|
||||
57 45 # N
|
||||
58 46 # M
|
||||
59 43 # ,
|
||||
60 47 # .
|
||||
61 44 # /
|
||||
62 56 # Shift Right
|
||||
51 42 # \
|
||||
98 62 # Cursor Up
|
||||
87 83 # KP 1
|
||||
88 84 # KP 2
|
||||
89 85 # KP 3
|
||||
108 76 # KP Enter
|
||||
37 54 # Ctrl Left
|
||||
115 58 # Logo Left (-> Option)
|
||||
64 55 # Alt Left (-> Command)
|
||||
65 49 # Space
|
||||
113 55 # Alt Right (-> Command)
|
||||
116 58 # Logo Right (-> Option)
|
||||
117 50 # Menu (-> International)
|
||||
109 54 # Ctrl Right
|
||||
100 59 # Cursor Left
|
||||
104 61 # Cursor Down
|
||||
102 60 # Cursor Right
|
||||
90 82 # KP 0
|
||||
91 65 # KP .
|
||||
|
||||
#
|
||||
# Linux Framebuffer Console
|
||||
#
|
||||
sdl fbcon
|
||||
1 53 # Esc
|
||||
59 122 # F1
|
||||
60 120 # F2
|
||||
61 99 # F3
|
||||
62 118 # F4
|
||||
63 96 # F5
|
||||
64 97 # F6
|
||||
65 98 # F7
|
||||
66 100 # F8
|
||||
67 101 # F9
|
||||
68 109 # F10
|
||||
87 103 # F11
|
||||
88 111 # F12
|
||||
99 105 # PrintScrn
|
||||
70 107 # Scroll Lock
|
||||
119 113 # Pause
|
||||
41 50 # `
|
||||
2 18 # 1
|
||||
3 19 # 2
|
||||
4 20 # 3
|
||||
5 21 # 4
|
||||
6 23 # 5
|
||||
7 22 # 6
|
||||
8 26 # 7
|
||||
9 28 # 8
|
||||
10 25 # 9
|
||||
11 29 # 0
|
||||
12 27 # -
|
||||
13 24 # =
|
||||
14 51 # Backspace
|
||||
110 114 # Insert
|
||||
102 115 # Home
|
||||
104 116 # Page Up
|
||||
69 71 # Num Lock
|
||||
98 75 # KP /
|
||||
55 67 # KP *
|
||||
74 78 # KP -
|
||||
15 48 # Tab
|
||||
16 12 # Q
|
||||
17 13 # W
|
||||
18 14 # E
|
||||
19 15 # R
|
||||
20 17 # T
|
||||
21 16 # Y
|
||||
22 32 # U
|
||||
23 34 # I
|
||||
24 31 # O
|
||||
25 35 # P
|
||||
26 33 # [
|
||||
27 30 # ]
|
||||
28 36 # Return
|
||||
111 117 # Delete
|
||||
107 119 # End
|
||||
109 121 # Page Down
|
||||
71 89 # KP 7
|
||||
72 91 # KP 8
|
||||
73 92 # KP 9
|
||||
78 69 # KP +
|
||||
58 57 # Caps Lock
|
||||
30 0 # A
|
||||
31 1 # S
|
||||
32 2 # D
|
||||
33 3 # F
|
||||
34 5 # G
|
||||
35 4 # H
|
||||
36 38 # J
|
||||
37 40 # K
|
||||
38 37 # L
|
||||
39 41 # ;
|
||||
40 39 # '
|
||||
75 86 # KP 4
|
||||
76 87 # KP 5
|
||||
77 88 # KP 6
|
||||
42 56 # Shift Left
|
||||
86 50 # International
|
||||
44 6 # Z
|
||||
45 7 # X
|
||||
46 8 # C
|
||||
47 9 # V
|
||||
48 11 # B
|
||||
49 45 # N
|
||||
50 46 # M
|
||||
51 43 # ,
|
||||
52 47 # .
|
||||
53 44 # /
|
||||
54 56 # Shift Right
|
||||
43 42 # \
|
||||
103 62 # Cursor Up
|
||||
79 83 # KP 1
|
||||
80 84 # KP 2
|
||||
81 85 # KP 3
|
||||
96 76 # KP Enter
|
||||
29 54 # Ctrl Left
|
||||
125 58 # Logo Left (-> Option)
|
||||
56 55 # Alt Left (-> Command)
|
||||
57 49 # Space
|
||||
100 55 # Alt Right (-> Command)
|
||||
126 58 # Logo Right (-> Option)
|
||||
97 54 # Ctrl Right
|
||||
105 59 # Cursor Left
|
||||
108 61 # Cursor Down
|
||||
106 60 # Cursor Right
|
||||
82 82 # KP 0
|
||||
83 65 # KP .
|
||||
|
||||
#
|
||||
# Quartz (1:1 translation actually)
|
||||
#
|
||||
sdl Quartz
|
||||
53 53 # Esc
|
||||
122 122 # F1
|
||||
120 120 # F2
|
||||
99 99 # F3
|
||||
118 118 # F4
|
||||
96 96 # F5
|
||||
97 97 # F6
|
||||
98 98 # F7
|
||||
100 100 # F8
|
||||
101 101 # F9
|
||||
109 109 # F10
|
||||
103 103 # F11
|
||||
111 111 # F12
|
||||
105 105 # F13/PrintScrn
|
||||
107 107 # F14/Scroll Lock
|
||||
113 113 # F15/Pause
|
||||
10 10 # `
|
||||
18 18 # 1
|
||||
19 19 # 2
|
||||
20 20 # 3
|
||||
21 21 # 4
|
||||
23 23 # 5
|
||||
22 22 # 6
|
||||
26 26 # 7
|
||||
28 28 # 8
|
||||
25 25 # 9
|
||||
29 29 # 0
|
||||
27 27 # -
|
||||
24 24 # =
|
||||
51 51 # Backspace
|
||||
114 114 # Help/Insert
|
||||
115 115 # Home
|
||||
116 116 # Page Up
|
||||
71 71 # Num Lock
|
||||
81 81 # KP =
|
||||
75 75 # KP /
|
||||
67 67 # KP *
|
||||
48 48 # Tab
|
||||
12 12 # Q
|
||||
13 13 # W
|
||||
14 14 # E
|
||||
15 15 # R
|
||||
17 17 # T
|
||||
16 16 # Y
|
||||
32 32 # U
|
||||
34 34 # I
|
||||
31 31 # O
|
||||
35 35 # P
|
||||
33 33 # [
|
||||
30 30 # ]
|
||||
36 36 # Return
|
||||
117 117 # Delete
|
||||
119 119 # End
|
||||
121 121 # Page Down
|
||||
89 89 # KP 7
|
||||
91 91 # KP 8
|
||||
92 92 # KP 9
|
||||
78 78 # KP -
|
||||
57 57 # Caps Lock
|
||||
0 0 # A
|
||||
1 1 # S
|
||||
2 2 # D
|
||||
3 3 # F
|
||||
5 5 # G
|
||||
4 4 # H
|
||||
38 38 # J
|
||||
40 40 # K
|
||||
37 37 # L
|
||||
41 41 # ;
|
||||
39 39 # '
|
||||
42 42 # \
|
||||
86 86 # KP 4
|
||||
87 87 # KP 5
|
||||
88 88 # KP 6
|
||||
69 69 # KP +
|
||||
56 56 # Shift
|
||||
50 50 # International
|
||||
6 6 # Z
|
||||
7 7 # X
|
||||
8 8 # C
|
||||
9 9 # V
|
||||
11 11 # B
|
||||
45 45 # N
|
||||
46 46 # M
|
||||
43 43 # ,
|
||||
47 47 # .
|
||||
44 44 # /
|
||||
126 62 # Cursor Up
|
||||
123 59 # Cursor Left
|
||||
125 61 # Cursor Down
|
||||
124 60 # Cursor Right
|
||||
83 83 # KP 1
|
||||
84 84 # KP 2
|
||||
85 85 # KP 3
|
||||
76 76 # KP Enter
|
||||
54 54 # Ctrl
|
||||
58 58 # Option
|
||||
55 55 # Command
|
||||
54 54 # Ctrl Left
|
||||
49 49 # Space
|
||||
82 82 # KP 0
|
||||
65 65 # KP .
|
||||
|
||||
#
|
||||
# cocoa (SDL2)
|
||||
#
|
||||
sdl cocoa
|
||||
41 53 # Esc
|
||||
58 122 # F1
|
||||
59 120 # F2
|
||||
60 99 # F3
|
||||
61 118 # F4
|
||||
62 96 # F5
|
||||
63 97 # F6
|
||||
64 98 # F7
|
||||
65 100 # F8
|
||||
66 101 # F9
|
||||
67 109 # F10
|
||||
68 103 # F11
|
||||
69 111 # F12
|
||||
70 105 # F13/PrintScrn
|
||||
71 107 # F14/Scroll Lock
|
||||
72 113 # F15/Pause
|
||||
53 10 # `
|
||||
30 18 # 1
|
||||
31 19 # 2
|
||||
32 20 # 3
|
||||
33 21 # 4
|
||||
34 23 # 5
|
||||
35 22 # 6
|
||||
36 26 # 7
|
||||
37 28 # 8
|
||||
38 25 # 9
|
||||
39 29 # 0
|
||||
45 27 # -
|
||||
46 24 # =
|
||||
42 51 # Backspace
|
||||
73 114 # Help/Insert
|
||||
74 115 # Home
|
||||
75 116 # Page Up
|
||||
83 71 # Num Lock
|
||||
103 81 # KP =
|
||||
84 75 # KP /
|
||||
85 67 # KP *
|
||||
43 48 # Tab
|
||||
20 12 # Q
|
||||
26 13 # W
|
||||
8 14 # E
|
||||
21 15 # R
|
||||
23 17 # T
|
||||
28 16 # Y
|
||||
24 32 # U
|
||||
12 34 # I
|
||||
18 31 # O
|
||||
19 35 # P
|
||||
47 33 # [
|
||||
48 30 # ]
|
||||
40 36 # Return
|
||||
76 117 # Delete
|
||||
77 119 # End
|
||||
78 121 # Page Down
|
||||
95 89 # KP 7
|
||||
96 91 # KP 8
|
||||
97 92 # KP 9
|
||||
86 78 # KP -
|
||||
57 57 # Caps Lock
|
||||
4 0 # A
|
||||
22 1 # S
|
||||
7 2 # D
|
||||
9 3 # F
|
||||
10 5 # G
|
||||
11 4 # H
|
||||
13 38 # J
|
||||
14 40 # K
|
||||
15 37 # L
|
||||
51 41 # ;
|
||||
52 39 # '
|
||||
49 42 # \
|
||||
92 86 # KP 4
|
||||
93 87 # KP 5
|
||||
94 88 # KP 6
|
||||
87 69 # KP +
|
||||
100 50 # International
|
||||
29 6 # Z
|
||||
27 7 # X
|
||||
6 8 # C
|
||||
25 9 # V
|
||||
5 11 # B
|
||||
17 45 # N
|
||||
16 46 # M
|
||||
54 43 # ,
|
||||
55 47 # .
|
||||
56 44 # /
|
||||
82 62 # Cursor Up
|
||||
80 59 # Cursor Left
|
||||
81 61 # Cursor Down
|
||||
79 60 # Cursor Right
|
||||
89 83 # KP 1
|
||||
90 84 # KP 2
|
||||
91 85 # KP 3
|
||||
88 76 # KP Enter
|
||||
225 56 # Shift Left
|
||||
224 54 # Ctrl Left
|
||||
226 58 # Option Left
|
||||
227 55 # Command Left
|
||||
44 49 # Space
|
||||
231 55 # Command Right
|
||||
230 58 # Option Right
|
||||
228 54 # Ctrl Right
|
||||
229 56 # Shift Right
|
||||
98 82 # KP 0
|
||||
99 65 # KP .
|
||||
|
||||
#
|
||||
# Windows (SDL2)
|
||||
#
|
||||
sdl windows
|
||||
41 53 # Esc
|
||||
58 122 # F1
|
||||
59 120 # F2
|
||||
60 99 # F3
|
||||
61 118 # F4
|
||||
62 96 # F5
|
||||
63 97 # F6
|
||||
64 98 # F7
|
||||
65 100 # F8
|
||||
66 101 # F9
|
||||
67 109 # F10
|
||||
68 103 # F11
|
||||
69 111 # F12
|
||||
70 105 # F13/PrintScrn
|
||||
71 107 # F14/Scroll Lock
|
||||
72 113 # F15/Pause
|
||||
53 50 # `
|
||||
30 18 # 1
|
||||
31 19 # 2
|
||||
32 20 # 3
|
||||
33 21 # 4
|
||||
34 23 # 5
|
||||
35 22 # 6
|
||||
36 26 # 7
|
||||
37 28 # 8
|
||||
38 25 # 9
|
||||
39 29 # 0
|
||||
45 27 # -
|
||||
46 24 # =
|
||||
42 51 # Backspace
|
||||
73 114 # Help/Insert
|
||||
74 115 # Home
|
||||
75 116 # Page Up
|
||||
83 71 # Num Lock
|
||||
103 81 # KP =
|
||||
84 75 # KP /
|
||||
85 67 # KP *
|
||||
43 48 # Tab
|
||||
20 12 # Q
|
||||
26 13 # W
|
||||
8 14 # E
|
||||
21 15 # R
|
||||
23 17 # T
|
||||
28 16 # Y
|
||||
24 32 # U
|
||||
12 34 # I
|
||||
18 31 # O
|
||||
19 35 # P
|
||||
47 33 # [
|
||||
48 30 # ]
|
||||
40 36 # Return
|
||||
76 117 # Delete
|
||||
77 119 # End
|
||||
78 121 # Page Down
|
||||
95 89 # KP 7
|
||||
96 91 # KP 8
|
||||
97 92 # KP 9
|
||||
86 78 # KP -
|
||||
57 57 # Caps Lock
|
||||
4 0 # A
|
||||
22 1 # S
|
||||
7 2 # D
|
||||
9 3 # F
|
||||
10 5 # G
|
||||
11 4 # H
|
||||
13 38 # J
|
||||
14 40 # K
|
||||
15 37 # L
|
||||
51 41 # ;
|
||||
52 39 # '
|
||||
49 42 # \
|
||||
92 86 # KP 4
|
||||
93 87 # KP 5
|
||||
94 88 # KP 6
|
||||
87 69 # KP +
|
||||
100 50 # International
|
||||
29 6 # Z
|
||||
27 7 # X
|
||||
6 8 # C
|
||||
25 9 # V
|
||||
5 11 # B
|
||||
17 45 # N
|
||||
16 46 # M
|
||||
54 43 # ,
|
||||
55 47 # .
|
||||
56 44 # /
|
||||
82 62 # Cursor Up
|
||||
80 59 # Cursor Left
|
||||
81 61 # Cursor Down
|
||||
79 60 # Cursor Right
|
||||
89 83 # KP 1
|
||||
90 84 # KP 2
|
||||
91 85 # KP 3
|
||||
88 76 # KP Enter
|
||||
225 56 # Shift Left
|
||||
224 58 # Ctrl Left (--> Option)
|
||||
# 227 # Logo Left
|
||||
226 55 # Alt Left (--> Command)
|
||||
44 49 # Space
|
||||
230 58 # Alt Right (--> Option)
|
||||
# 231 # Logo Right
|
||||
101 50 # Menu (--> International)
|
||||
228 54 # Ctrl Right
|
||||
229 56 # Shift Right
|
||||
98 82 # KP 0
|
||||
99 65 # KP .
|
||||
|
||||
#
|
||||
# Windows
|
||||
#
|
||||
sdl windib
|
||||
sdl directx
|
||||
1 53 # Esc
|
||||
59 122 # F1
|
||||
60 120 # F2
|
||||
61 99 # F3
|
||||
62 118 # F4
|
||||
63 96 # F5
|
||||
64 97 # F6
|
||||
65 98 # F7
|
||||
66 100 # F8
|
||||
67 101 # F9
|
||||
68 109 # F10
|
||||
87 103 # F11
|
||||
88 111 # F12
|
||||
183 105 # PrintScrn
|
||||
70 107 # Scroll Lock
|
||||
197 113 # Pause
|
||||
41 50 # `
|
||||
2 18 # 1
|
||||
3 19 # 2
|
||||
4 20 # 3
|
||||
5 21 # 4
|
||||
6 23 # 5
|
||||
7 22 # 6
|
||||
8 26 # 7
|
||||
9 28 # 8
|
||||
10 25 # 9
|
||||
11 29 # 0
|
||||
12 27 # -
|
||||
13 24 # =
|
||||
14 51 # Backspace
|
||||
210 114 # Insert
|
||||
199 115 # Home
|
||||
201 116 # Page Up
|
||||
69 71 # Num Lock
|
||||
181 75 # KP /
|
||||
55 67 # KP *
|
||||
74 78 # KP -
|
||||
15 48 # Tab
|
||||
16 12 # Q
|
||||
17 13 # W
|
||||
18 14 # E
|
||||
19 15 # R
|
||||
20 17 # T
|
||||
21 16 # Y
|
||||
22 32 # U
|
||||
23 34 # I
|
||||
24 31 # O
|
||||
25 35 # P
|
||||
26 33 # [
|
||||
27 30 # ]
|
||||
28 36 # Return
|
||||
211 117 # Delete
|
||||
207 119 # End
|
||||
209 121 # Page Down
|
||||
71 89 # KP 7
|
||||
72 91 # KP 8
|
||||
73 92 # KP 9
|
||||
78 69 # KP +
|
||||
58 57 # Caps Lock
|
||||
30 0 # A
|
||||
31 1 # S
|
||||
32 2 # D
|
||||
33 3 # F
|
||||
34 5 # G
|
||||
35 4 # H
|
||||
36 38 # J
|
||||
37 40 # K
|
||||
38 37 # L
|
||||
39 41 # ;
|
||||
40 39 # '
|
||||
75 86 # KP 4
|
||||
76 87 # KP 5
|
||||
77 88 # KP 6
|
||||
42 56 # Shift Left
|
||||
86 50 # International
|
||||
44 6 # Z
|
||||
45 7 # X
|
||||
46 8 # C
|
||||
47 9 # V
|
||||
48 11 # B
|
||||
49 45 # N
|
||||
50 46 # M
|
||||
51 43 # ,
|
||||
52 47 # .
|
||||
53 44 # /
|
||||
54 56 # Shift Right
|
||||
43 42 # \
|
||||
200 62 # Cursor Up
|
||||
79 83 # KP 1
|
||||
80 84 # KP 2
|
||||
81 85 # KP 3
|
||||
156 76 # KP Enter
|
||||
29 54 # Ctrl Left
|
||||
219 58 # Logo Left (-> Option)
|
||||
56 55 # Alt Left (-> Command)
|
||||
57 49 # Space
|
||||
184 55 # Alt Right (-> Command)
|
||||
220 58 # Logo Right (-> Option)
|
||||
221 50 # Menu (-> International)
|
||||
157 54 # Ctrl Right
|
||||
203 59 # Cursor Left
|
||||
208 61 # Cursor Down
|
||||
205 60 # Cursor Right
|
||||
82 82 # KP 0
|
||||
83 65 # KP .
|
||||
|
||||
#
|
||||
# XFree86
|
||||
#
|
||||
|
|
103
BasiliskII/src/Unix/main_unix.cpp
Normal file → Executable file
103
BasiliskII/src/Unix/main_unix.cpp
Normal file → Executable file
|
@ -29,6 +29,9 @@
|
|||
#ifdef USE_SDL
|
||||
# include <SDL.h>
|
||||
# include <SDL_main.h>
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define SDL_PLATFORM_MACOS __MACOSX__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL_VIDEO
|
||||
|
@ -43,6 +46,10 @@
|
|||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#if SDL_PLATFORM_MACOS
|
||||
#include "utils_macosx.h"
|
||||
#endif
|
||||
|
||||
#if !EMULATED_68K && defined(__NetBSD__)
|
||||
# include <m68k/sync_icache.h>
|
||||
# include <m68k/frame.h>
|
||||
|
@ -60,8 +67,8 @@ struct sigstate {
|
|||
#ifdef ENABLE_GTK
|
||||
# include <gtk/gtk.h>
|
||||
# include <gdk/gdk.h>
|
||||
# ifdef HAVE_GNOMEUI
|
||||
# include <gnome.h>
|
||||
# if !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND)
|
||||
# include <X11/Xlib.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -91,8 +98,13 @@ using std::string;
|
|||
#include "rpc.h"
|
||||
|
||||
#if USE_JIT
|
||||
#ifdef UPDATE_UAE
|
||||
extern void (*flush_icache)(void); // from compemu_support.cpp
|
||||
extern bool UseJIT;
|
||||
#else
|
||||
extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MON
|
||||
# include "mon.h"
|
||||
|
@ -208,6 +220,8 @@ static void sigill_handler(int sig, int code, struct sigcontext *scp);
|
|||
extern "C" void EmulOpTrampoline(void);
|
||||
#endif
|
||||
|
||||
// vde switch variable
|
||||
char* vde_sock;
|
||||
|
||||
/*
|
||||
* Ersatz functions
|
||||
|
@ -237,11 +251,12 @@ void *vm_acquire_mac(size_t size)
|
|||
return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT);
|
||||
}
|
||||
|
||||
#if REAL_ADDRESSING
|
||||
static int vm_acquire_mac_fixed(void *addr, size_t size)
|
||||
{
|
||||
return vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_32BIT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SIGSEGV handler
|
||||
|
@ -284,9 +299,14 @@ static void sigsegv_dump_state(sigsegv_info_t *sip)
|
|||
fprintf(stderr, "\n");
|
||||
#if EMULATED_68K
|
||||
uaecptr nextpc;
|
||||
#ifdef UPDATE_UAE
|
||||
extern void m68k_dumpstate(FILE *, uaecptr *nextpc);
|
||||
m68k_dumpstate(stderr, &nextpc);
|
||||
#else
|
||||
extern void m68k_dumpstate(uaecptr *nextpc);
|
||||
m68k_dumpstate(&nextpc);
|
||||
#endif
|
||||
#endif
|
||||
#if USE_JIT && JIT_DEBUG
|
||||
extern void compiler_dumpstate(void);
|
||||
compiler_dumpstate();
|
||||
|
@ -359,6 +379,16 @@ void cpu_do_check_ticks(void)
|
|||
if (emulated_ticks <= 0)
|
||||
emulated_ticks += emulated_ticks_quantum;
|
||||
}
|
||||
#else
|
||||
uint16 emulated_ticks;
|
||||
void cpu_do_check_ticks(void)
|
||||
{
|
||||
static int delay = -1;
|
||||
if (delay < 0)
|
||||
delay = PrefsFindInt32("delay");
|
||||
if (delay)
|
||||
usleep(delay);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -375,15 +405,20 @@ static void usage(const char *prg_name)
|
|||
" --display STRING\n X display to use\n"
|
||||
" --break ADDRESS\n set ROM breakpoint in hexadecimal\n"
|
||||
" --loadbreak FILE\n load breakpoint from FILE\n"
|
||||
" --rominfo\n dump ROM information\n", prg_name
|
||||
" --rominfo\n dump ROM information\n"
|
||||
" --switch SWITCH_PATH\n vde_switch address\n", prg_name
|
||||
);
|
||||
LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values
|
||||
PrefsPrintUsage();
|
||||
printf("\nBuild Date: %s\n", __DATE__);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if defined(ENABLE_GTK) && !defined(GDK_WINDOWING_QUARTZ) && !defined(GDK_WINDOWING_WAYLAND)
|
||||
XInitThreads();
|
||||
#endif
|
||||
const char *vmdir = NULL;
|
||||
char str[256];
|
||||
|
||||
|
@ -437,19 +472,27 @@ int main(int argc, char **argv)
|
|||
} else if (strcmp(argv[i], "--rominfo") == 0) {
|
||||
argv[i] = NULL;
|
||||
PrintROMInfo = true;
|
||||
} else if (strcmp(argv[i], "--switch") == 0) {
|
||||
argv[i] = NULL;
|
||||
if (argv[++i] == NULL) {
|
||||
printf("switch address not defined\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
vde_sock = argv[i];
|
||||
argv[i] = NULL;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
// Mac OS X likes to pass in various options of its own, when launching an app.
|
||||
// Attempt to ignore these.
|
||||
if (argv[i]) {
|
||||
const char * mac_psn_prefix = "-psn_";
|
||||
if (strcmp(argv[i], "-NSDocumentRevisionsDebugMode") == 0) {
|
||||
argv[i] = NULL;
|
||||
} else if (strncmp(mac_psn_prefix, argv[i], strlen(mac_psn_prefix)) == 0) {
|
||||
argv[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (argv[i]) {
|
||||
const char * mac_psn_prefix = "-psn_";
|
||||
if (strcmp(argv[i], "-NSDocumentRevisionsDebugMode") == 0) {
|
||||
argv[i] = NULL;
|
||||
} else if (strncmp(mac_psn_prefix, argv[i], strlen(mac_psn_prefix)) == 0) {
|
||||
argv[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -477,16 +520,9 @@ int main(int argc, char **argv)
|
|||
|
||||
#ifdef ENABLE_GTK
|
||||
if (!gui_connection) {
|
||||
#ifdef HAVE_GNOMEUI
|
||||
// Init GNOME/GTK
|
||||
char version[16];
|
||||
sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
|
||||
gnome_init("Basilisk II", version, argc, argv);
|
||||
#else
|
||||
// Init GTK
|
||||
gtk_set_locale();
|
||||
gtk_init(&argc, &argv);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -535,14 +571,13 @@ int main(int argc, char **argv)
|
|||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
#if __MACOSX__ && SDL_VERSION_ATLEAST(2,0,0)
|
||||
#if SDL_PLATFORM_MACOS && SDL_VERSION_ATLEAST(2,0,0)
|
||||
// On Mac OS X hosts, SDL2 will create its own menu bar. This is mostly OK,
|
||||
// except that it will also install keyboard shortcuts, such as Command + Q,
|
||||
// which can interfere with keyboard shortcuts in the guest OS.
|
||||
//
|
||||
// HACK: disable these shortcuts, while leaving all other pieces of SDL2's
|
||||
// menu bar in-place.
|
||||
extern void disable_SDL2_macosx_menu_bar_keyboard_shortcuts();
|
||||
disable_SDL2_macosx_menu_bar_keyboard_shortcuts();
|
||||
#endif
|
||||
|
||||
|
@ -659,10 +694,8 @@ int main(int argc, char **argv)
|
|||
RAMBaseMac = Host2MacAddr(RAMBaseHost);
|
||||
ROMBaseMac = Host2MacAddr(ROMBaseHost);
|
||||
#endif
|
||||
D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
|
||||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
#if __MACOSX__
|
||||
|
||||
#if SDL_PLATFORM_MACOS
|
||||
extern void set_current_directory();
|
||||
set_current_directory();
|
||||
#endif
|
||||
|
@ -724,6 +757,9 @@ int main(int argc, char **argv)
|
|||
QuitEmulator();
|
||||
D(bug("Initialization complete\n"));
|
||||
|
||||
D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
|
||||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
#if !EMULATED_68K
|
||||
// (Virtual) supervisor mode, disable interrupts
|
||||
EmulatedSR = 0x2700;
|
||||
|
@ -972,8 +1008,12 @@ void FlushCodeCache(void *start, uint32 size)
|
|||
{
|
||||
#if USE_JIT
|
||||
if (UseJIT)
|
||||
#ifdef UPDATE_UAE
|
||||
flush_icache();
|
||||
#else
|
||||
flush_icache_range((uint8 *)start, size);
|
||||
#endif
|
||||
#endif
|
||||
#if !EMULATED_68K && defined(__NetBSD__)
|
||||
m68k_sync_icache(start, size);
|
||||
#endif
|
||||
|
@ -989,8 +1029,13 @@ static void sigint_handler(...)
|
|||
{
|
||||
#if EMULATED_68K
|
||||
uaecptr nextpc;
|
||||
#ifdef UPDATE_UAE
|
||||
extern void m68k_dumpstate(FILE *, uaecptr *nextpc);
|
||||
m68k_dumpstate(stderr, &nextpc);
|
||||
#else
|
||||
extern void m68k_dumpstate(uaecptr *nextpc);
|
||||
m68k_dumpstate(&nextpc);
|
||||
#endif
|
||||
#endif
|
||||
VideoQuitFullScreen();
|
||||
const char *arg[4] = {"mon", "-m", "-r", NULL};
|
||||
|
@ -1223,13 +1268,15 @@ static void one_tick(...)
|
|||
}
|
||||
|
||||
#ifdef USE_PTHREADS_SERVICES
|
||||
bool tick_inhibit;
|
||||
static void *tick_func(void *arg)
|
||||
{
|
||||
uint64 start = GetTicks_usec();
|
||||
int64 ticks = 0;
|
||||
uint64 next = GetTicks_usec();
|
||||
uint64 next = start;
|
||||
while (!tick_thread_cancel) {
|
||||
one_tick();
|
||||
if (!tick_inhibit)
|
||||
one_tick();
|
||||
next += 16625;
|
||||
int64 delay = next - GetTicks_usec();
|
||||
if (delay > 0)
|
||||
|
@ -1238,8 +1285,10 @@ static void *tick_func(void *arg)
|
|||
next = GetTicks_usec();
|
||||
ticks++;
|
||||
}
|
||||
#if DEBUG
|
||||
uint64 end = GetTicks_usec();
|
||||
D(bug("%lld ticks in %lld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* prefs_unix.cpp - Preferences handling, Unix specific stuff
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
* Basilisk II, SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,28 +19,27 @@
|
|||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include "prefs.h"
|
||||
|
||||
|
||||
// Platform-specific preferences items
|
||||
prefs_desc platform_prefs_items[] = {
|
||||
#ifdef SHEEPSHAVER
|
||||
{"ether", TYPE_STRING, false, "device name of Mac ethernet adapter"},
|
||||
{"etherconfig", TYPE_STRING, false, "path of network config script"},
|
||||
{"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"},
|
||||
{"keycodefile", TYPE_STRING, false, "path of keycode translation file"},
|
||||
{"fbdevicefile", TYPE_STRING, false, "path of frame buffer device specification file"},
|
||||
{"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"},
|
||||
{"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"},
|
||||
#else
|
||||
{"fbdevicefile", TYPE_STRING, false, "path of frame buffer device specification file"},
|
||||
#endif
|
||||
{"dsp", TYPE_STRING, false, "audio output (dsp) device name"},
|
||||
{"mixer", TYPE_STRING, false, "audio mixer device name"},
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
{"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"},
|
||||
#endif
|
||||
{"idlewait", TYPE_BOOLEAN, false, "sleep when idle"},
|
||||
#ifdef USE_SDL_VIDEO
|
||||
{"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"},
|
||||
|
@ -49,8 +48,222 @@ prefs_desc platform_prefs_items[] = {
|
|||
};
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
|
||||
// Standard file names and paths
|
||||
#ifdef SHEEPSHAVER
|
||||
static const char PREFS_FILE_NAME[] = "/.sheepshaver_prefs";
|
||||
static const char XDG_PREFS_FILE_NAME[] = "/prefs";
|
||||
static const char XPRAM_FILE_NAME[] = "/.sheepshaver_nvram";
|
||||
static const char XDG_XPRAM_FILE_NAME[] = "/nvram";
|
||||
static const char XDG_CONFIG_SUBDIR[] = "/SheepShaver";
|
||||
#else
|
||||
static const char PREFS_FILE_NAME[] = "/.basilisk_ii_prefs";
|
||||
static const char XDG_PREFS_FILE_NAME[] = "/prefs";
|
||||
static const char XPRAM_FILE_NAME[] = "/.basilisk_ii_xpram";
|
||||
static const char XDG_XPRAM_FILE_NAME[] = "/xpram";
|
||||
static const char XDG_CONFIG_SUBDIR[] = "/BasiliskII";
|
||||
#endif
|
||||
|
||||
// Prefs file name and path
|
||||
const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs";
|
||||
string UserPrefsPath;
|
||||
static string home_dir;
|
||||
static string xdg_config_dir;
|
||||
static string prefs_name;
|
||||
extern string xpram_name;
|
||||
|
||||
static string get_xdg_config_dir(void)
|
||||
{
|
||||
char *env;
|
||||
if (env = getenv("XDG_CONFIG_HOME"))
|
||||
return string(env) + XDG_CONFIG_SUBDIR;
|
||||
if (env = getenv("HOME"))
|
||||
return string(env) + "/.config" + XDG_CONFIG_SUBDIR;
|
||||
return "";
|
||||
}
|
||||
|
||||
static string get_home_dir(void)
|
||||
{
|
||||
char *env;
|
||||
if(env = getenv("HOME"))
|
||||
return string(env);
|
||||
return "."; // last resort, use the current directory
|
||||
}
|
||||
|
||||
static string get_dir(string *path)
|
||||
{
|
||||
int pos = path->find_last_of('/');
|
||||
if (pos == 0)
|
||||
return ""; // file is in root folder
|
||||
if (pos == std::string::npos)
|
||||
return "."; // file is in current folder
|
||||
return path->substr(0, pos);
|
||||
}
|
||||
|
||||
static void exit_if_dir(const string& path)
|
||||
{
|
||||
struct stat info;
|
||||
if (stat(path.c_str(), &info) != 0){
|
||||
return;
|
||||
}
|
||||
if ((info.st_mode & S_IFDIR) != 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Cannot open %s (Is a directory)\n", prefs_name.c_str());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static bool load_prefs_file(const string& path, bool exit_on_failure)
|
||||
{
|
||||
exit_if_dir(path);
|
||||
FILE *prefs = fopen(path.c_str(), "r");
|
||||
if (prefs != NULL)
|
||||
{
|
||||
LoadPrefsFromStream(prefs);
|
||||
fclose(prefs);
|
||||
printf("Using prefs file at %s\n", prefs_name.c_str());
|
||||
return true;
|
||||
}
|
||||
else if (exit_on_failure)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Could not load prefs file from %s (%s)\n",
|
||||
path.c_str(), strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for prefs file in the following locations (in order of priority):
|
||||
* 1. From vmdir/.basilisk_ii_prefs if a vmdir has been specified
|
||||
* 2. From path specified with --config command line
|
||||
* 3. From $HOME/.basilisk_ii_prefs if it exists
|
||||
* 4. From $XDG_CONFIG_HOME/BasiliskII/prefs if it exists
|
||||
* 5. Create a new prefs file at $XDG_CONFIG_HOME/BasiliskII/prefs
|
||||
* (or the equivalent paths for SheepShaver)
|
||||
* If $XDG_CONFIG_HOME doesn't exist, $HOME/.config is used instead,
|
||||
* in accordance with XDG Base Directory Specification:
|
||||
* https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
*/
|
||||
|
||||
void LoadPrefs(const char* vmdir)
|
||||
{
|
||||
home_dir = get_home_dir();
|
||||
xdg_config_dir = get_xdg_config_dir();
|
||||
|
||||
// vmdir was specified on the command line
|
||||
if (vmdir)
|
||||
{
|
||||
prefs_name = string(vmdir) + XDG_PREFS_FILE_NAME;
|
||||
xpram_name = string(vmdir) + XDG_XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, true))
|
||||
return;
|
||||
}
|
||||
|
||||
// --config was specified
|
||||
if (!UserPrefsPath.empty())
|
||||
{
|
||||
prefs_name = UserPrefsPath;
|
||||
xpram_name = get_dir(&prefs_name) + XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, true))
|
||||
return;
|
||||
}
|
||||
|
||||
// Load .basilisk_ii_prefs from $HOME if it exists
|
||||
if (!home_dir.empty())
|
||||
{
|
||||
prefs_name = home_dir + PREFS_FILE_NAME;
|
||||
xpram_name = home_dir + XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, false))
|
||||
return;
|
||||
}
|
||||
|
||||
// If no other prefs file exists, try the $XDG_CONFIG_HOME directory
|
||||
if (!xdg_config_dir.empty())
|
||||
{
|
||||
prefs_name = xdg_config_dir + XDG_PREFS_FILE_NAME;
|
||||
xpram_name = xdg_config_dir + XDG_XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, false))
|
||||
return;
|
||||
}
|
||||
|
||||
// No prefs file, save defaults in $XDG_CONFIG_HOME directory
|
||||
//#ifdef __linux__
|
||||
PrefsAddString("cdrom", "/dev/cdrom");
|
||||
//#endif
|
||||
printf("No prefs file found, creating new one at %s\n", prefs_name.c_str());
|
||||
SavePrefs();
|
||||
}
|
||||
|
||||
static bool is_dir(const string& path)
|
||||
{
|
||||
struct stat info;
|
||||
if (stat(path.c_str(), &info) != 0){
|
||||
return false;
|
||||
}
|
||||
return (info.st_mode & S_IFDIR) != 0;
|
||||
}
|
||||
|
||||
static bool create_directories(const string& path, mode_t mode)
|
||||
{
|
||||
if (mkdir(path.c_str(), mode) == 0)
|
||||
return true;
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case ENOENT:
|
||||
{
|
||||
int pos = path.find_last_of('/');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
if (!create_directories(path.substr(0,pos),mode))
|
||||
return false;
|
||||
}
|
||||
return 0 == mkdir(path.c_str(),mode);
|
||||
|
||||
case EEXIST:
|
||||
return is_dir(path);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save preferences to settings file
|
||||
*/
|
||||
|
||||
|
||||
void SavePrefs(void)
|
||||
{
|
||||
FILE *f;
|
||||
string prefs_dir = get_dir(&prefs_name);
|
||||
if (!prefs_dir.empty() && !is_dir(prefs_dir))
|
||||
{
|
||||
create_directories(prefs_dir, 0700);
|
||||
}
|
||||
if ((f = fopen(prefs_name.c_str(), "w")) != NULL)
|
||||
{
|
||||
SavePrefsToStream(f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Unable to save %s (%s)\n",
|
||||
prefs_name.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else // __linux__
|
||||
|
||||
|
||||
// Prefs file name and path
|
||||
#ifdef SHEEPSHAVER
|
||||
static const char PREFS_FILE_NAME[] = ".sheepshaver_prefs";
|
||||
#else
|
||||
static const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs";
|
||||
#endif
|
||||
string UserPrefsPath;
|
||||
static string prefs_path;
|
||||
|
||||
|
@ -91,7 +304,9 @@ void LoadPrefs(const char *vmdir)
|
|||
fclose(f);
|
||||
|
||||
} else {
|
||||
|
||||
//#ifdef __linux__
|
||||
// PrefsAddString("cdrom", "/dev/cdrom");
|
||||
//#endif
|
||||
// No prefs file, save defaults
|
||||
SavePrefs();
|
||||
}
|
||||
|
@ -112,6 +327,9 @@ void SavePrefs(void)
|
|||
}
|
||||
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
|
||||
/*
|
||||
* Add defaults of platform-specific prefs items
|
||||
* You may also override the defaults set in PrefsInit()
|
||||
|
@ -124,22 +342,28 @@ void AddPlatformPrefsDefaults(void)
|
|||
PrefsReplaceInt32("mousewheelmode", 1);
|
||||
PrefsReplaceInt32("mousewheellines", 3);
|
||||
#ifdef __linux__
|
||||
if (access("/dev/sound/dsp", F_OK) == 0) {
|
||||
if (access("/dev/sound/dsp", F_OK) == 0)
|
||||
{
|
||||
PrefsReplaceString("dsp", "/dev/sound/dsp");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PrefsReplaceString("dsp", "/dev/dsp");
|
||||
}
|
||||
if (access("/dev/sound/mixer", F_OK) == 0) {
|
||||
if (access("/dev/sound/mixer", F_OK) == 0)
|
||||
{
|
||||
PrefsReplaceString("mixer", "/dev/sound/mixer");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PrefsReplaceString("mixer", "/dev/mixer");
|
||||
}
|
||||
#elif defined (__NetBSD__)
|
||||
PrefsReplaceString("dsp", "/dev/audio");
|
||||
PrefsReplaceString("mixer", "/dev/mixer");
|
||||
#else
|
||||
PrefsReplaceString("dsp", "/dev/dsp");
|
||||
PrefsReplaceString("mixer", "/dev/mixer");
|
||||
#endif
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
PrefsAddBool("ignoresegv", false);
|
||||
#endif
|
||||
PrefsAddBool("idlewait", true);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,18 @@
|
|||
#include "sysdeps.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef HAVE_SYS_FILIO_H
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/lp.h>
|
||||
#include <linux/major.h>
|
||||
|
@ -648,16 +654,16 @@ bool XSERDPort::configure(uint16 config)
|
|||
// Set number of data bits
|
||||
switch (config & 0x0c00) {
|
||||
case data5:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS5;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS5;
|
||||
break;
|
||||
case data6:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS6;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS6;
|
||||
break;
|
||||
case data7:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS7;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS7;
|
||||
break;
|
||||
case data8:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS8;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS8;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@ RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
|||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> /* For O_NONBLOCK */
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
|
@ -45,10 +50,6 @@ RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
|||
# include <sys/bsdtty.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> /* For S_* constants and macros */
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_TTY
|
||||
# define _PATH_TTY "/dev/tty"
|
||||
#endif
|
||||
|
@ -73,7 +74,12 @@ RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
|||
#define fatal(x) do { printf("Fatal error: %s", x); return 0; } while(0)
|
||||
#endif /* not in BasiliskII */
|
||||
|
||||
#ifdef __sun__
|
||||
#define mysig_t void*
|
||||
#else
|
||||
#define mysig_t sig_t
|
||||
#endif
|
||||
|
||||
#define mysignal signal
|
||||
#include <signal.h>
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#include "disk_unix.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue_unix.h"
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -369,6 +369,9 @@ void SysAddCDROMPrefs(void)
|
|||
closedir(cd_dir);
|
||||
}
|
||||
}
|
||||
#elif defined __FreeBSD__
|
||||
if (access("/cdrom", F_OK) == 0)
|
||||
PrefsAddString("cdrom", "/cdrom");
|
||||
#elif defined __MACOSX__
|
||||
// There is no predefined path for CD-ROMs on MacOS X. Rather, we
|
||||
// define a single fake CD-ROM entry for the emulated MacOS.
|
||||
|
@ -396,8 +399,8 @@ void SysAddSerialPrefs(void)
|
|||
PrefsAddString("serialb", "/dev/tts/1");
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
PrefsAddString("seriala", "/dev/cuaa0");
|
||||
PrefsAddString("serialb", "/dev/cuaa1");
|
||||
PrefsAddString("seriala", "/dev/cuau0");
|
||||
PrefsAddString("serialb", "/dev/cuau1");
|
||||
#elif defined(__NetBSD__)
|
||||
PrefsAddString("seriala", "/dev/tty00");
|
||||
PrefsAddString("serialb", "/dev/tty01");
|
||||
|
@ -537,14 +540,14 @@ static mac_file_handle *open_filehandle(const char *name)
|
|||
return fh;
|
||||
}
|
||||
|
||||
void *Sys_open(const char *name, bool read_only)
|
||||
void *Sys_open(const char *name, bool read_only, bool is_cdrom)
|
||||
{
|
||||
bool is_file = strncmp(name, "/dev/", 5) != 0;
|
||||
#if defined(__FreeBSD__)
|
||||
// SCSI IDE
|
||||
bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0;
|
||||
is_cdrom |= strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0;
|
||||
#else
|
||||
bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0;
|
||||
is_cdrom |= strncmp(name, "/dev/cd", 7) == 0;
|
||||
#endif
|
||||
bool is_floppy = strncmp(name, "/dev/fd", 7) == 0;
|
||||
|
||||
|
@ -1407,8 +1410,13 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve
|
|||
mac_file_handle *fh = (mac_file_handle *)arg;
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
// Not supported under Linux
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDScan_bincue(fh->bincue_fd,start_m,start_s,start_f,reverse);
|
||||
#endif
|
||||
|
||||
// Not supported outside bincue
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1422,6 +1430,11 @@ void SysCDSetVolume(void *arg, uint8 left, uint8 right)
|
|||
mac_file_handle *fh = (mac_file_handle *)arg;
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDSetVol_bincue(fh->bincue_fd,left,right);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
#if defined(__linux__)
|
||||
|
@ -1450,6 +1463,12 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right)
|
|||
return;
|
||||
|
||||
left = right = 0;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDGetVol_bincue(fh->bincue_fd,&left,&right);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
#if defined(__linux__)
|
||||
cdrom_volctrl vol;
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
#include <config.h>
|
||||
#include "user_strings_unix.h"
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#error "You don't have ANSI C header files."
|
||||
#endif
|
||||
//#ifndef STDC_HEADERS
|
||||
//#error "You don't have ANSI C header files."
|
||||
//#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <sys/types.h>
|
||||
|
@ -42,6 +42,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
# include <pthread.h>
|
||||
|
@ -51,6 +52,10 @@
|
|||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> /* For S_* constants and macros */
|
||||
#endif
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
|
@ -117,11 +122,6 @@
|
|||
#ifdef HAVE_PTHREADS
|
||||
#define USE_PTHREADS_SERVICES
|
||||
#endif
|
||||
#if EMULATED_68K
|
||||
#if defined(__NetBSD__)
|
||||
#define USE_CPU_EMUL_SERVICES
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USE_CPU_EMUL_SERVICES
|
||||
#undef USE_PTHREADS_SERVICES
|
||||
#endif
|
||||
|
@ -490,4 +490,21 @@ static inline uae_u32 do_byteswap_16(uae_u32 v)
|
|||
#endif
|
||||
#define REGPARAM2
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)x)
|
||||
#endif
|
||||
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#define ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
#define memptr uint32
|
||||
|
||||
// High-precision timing
|
||||
#if defined(HAVE_PTHREADS) && defined(HAVE_CLOCK_NANOSLEEP)
|
||||
#define PRECISE_TIMING 1
|
||||
#define PRECISE_TIMING_POSIX 1
|
||||
#elif defined(HAVE_PTHREADS) && defined(__MACH__)
|
||||
#define PRECISE_TIMING 1
|
||||
#define PRECISE_TIMING_MACH 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,7 @@ user_string_def platform_strings[] = {
|
|||
|
||||
{STR_PREFS_MENU_FILE_GTK, "/_File"},
|
||||
{STR_PREFS_ITEM_START_GTK, "/File/_Start Basilisk II"},
|
||||
{STR_PREFS_ITEM_SAVE_GTK, "/File/Save _Preferences"},
|
||||
{STR_PREFS_ITEM_ZAP_PRAM_GTK, "/File/_Zap PRAM File"},
|
||||
{STR_PREFS_ITEM_SEPL_GTK, "/File/sepl"},
|
||||
{STR_PREFS_ITEM_QUIT_GTK, "/File/_Quit Basilisk II"},
|
||||
|
@ -73,7 +74,8 @@ user_string_def platform_strings[] = {
|
|||
{STR_DSPDEVICE_FILE_CTRL, "Audio Output Device"},
|
||||
{STR_MIXERDEVICE_FILE_CTRL, "Audio Mixer Device"},
|
||||
|
||||
{STR_BROWSE_TITLE, "Browse file"},
|
||||
{STR_BROWSE_TITLE, "Select File"},
|
||||
{STR_BROWSE_FOLDER_TITLE, "Select Folder"},
|
||||
{STR_BROWSE_CTRL, "Browse..."},
|
||||
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
|
||||
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
|
||||
|
@ -87,6 +89,22 @@ user_string_def platform_strings[] = {
|
|||
|
||||
{STR_NO_B2_EXE_FOUND, "Could not start %s (%s)."},
|
||||
|
||||
{STR_ABOUT_COPYRIGHT, "© 1997-2008 Christian Bauer et al."},
|
||||
{STR_ABOUT_LICENSE, "This program 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.\n\n\
|
||||
This program 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.\n\n\
|
||||
You should have received a copy of the GNU General Public License \
|
||||
along with this program; if not, write to the Free Software \
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"},
|
||||
{STR_ABOUT_COMMENTS, "Open source 68k Mac emulator"},
|
||||
{STR_ABOUT_WEBSITE, "http://basilisk.cebix.net"},
|
||||
{STR_ABOUT_WEBSITE_LABEL, "Website"},
|
||||
|
||||
{-1, NULL} // End marker
|
||||
};
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ enum {
|
|||
|
||||
STR_PREFS_MENU_FILE_GTK,
|
||||
STR_PREFS_ITEM_START_GTK,
|
||||
STR_PREFS_ITEM_SAVE_GTK,
|
||||
STR_PREFS_ITEM_ZAP_PRAM_GTK,
|
||||
STR_PREFS_ITEM_SEPL_GTK,
|
||||
STR_PREFS_ITEM_QUIT_GTK,
|
||||
|
@ -66,6 +67,7 @@ enum {
|
|||
|
||||
STR_BROWSE_CTRL,
|
||||
STR_BROWSE_TITLE,
|
||||
STR_BROWSE_FOLDER_TITLE,
|
||||
STR_INPUT_PANE_TITLE,
|
||||
STR_KEYCODES_CTRL,
|
||||
STR_KEYCODE_FILE_CTRL,
|
||||
|
@ -76,7 +78,13 @@ enum {
|
|||
|
||||
STR_IGNORESEGV_CTRL,
|
||||
|
||||
STR_NO_B2_EXE_FOUND
|
||||
STR_NO_B2_EXE_FOUND,
|
||||
|
||||
STR_ABOUT_COPYRIGHT,
|
||||
STR_ABOUT_LICENSE,
|
||||
STR_ABOUT_COMMENTS,
|
||||
STR_ABOUT_WEBSITE,
|
||||
STR_ABOUT_WEBSITE_LABEL
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -113,7 +114,9 @@ static bool use_vosf = true; // Flag: VOSF enabled
|
|||
static const bool use_vosf = false; // VOSF not possible
|
||||
#endif
|
||||
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed (for use with hotkeys)
|
||||
static bool opt_down = false; // Flag: Opt/Alt key pressed (for use with hotkeys)
|
||||
static bool cmd_down = false; // Flag: Cmd/Super/Win key pressed (for use with hotkeys)
|
||||
static bool caps_on = false; // Flag: Caps Lock on
|
||||
static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread
|
||||
static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread
|
||||
|
@ -215,6 +218,7 @@ public:
|
|||
|
||||
virtual void switch_to_current_mode(void);
|
||||
virtual void set_palette(uint8 *pal, int num);
|
||||
virtual void set_gamma(uint8 *gamma, int num);
|
||||
|
||||
bool video_open(void);
|
||||
void video_close(void);
|
||||
|
@ -225,6 +229,30 @@ public:
|
|||
* Utility functions
|
||||
*/
|
||||
|
||||
static bool is_hotkey_down()
|
||||
{
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
if (!hotkey) hotkey = 1;
|
||||
return (ctrl_down || !(hotkey & 1)) &&
|
||||
(opt_down || !(hotkey & 2)) &&
|
||||
(cmd_down || !(hotkey & 4));
|
||||
}
|
||||
|
||||
static int modify_opt_cmd(int code) {
|
||||
static bool f, c;
|
||||
if (!f) {
|
||||
f = true;
|
||||
c = PrefsFindBool("swap_opt_cmd");
|
||||
}
|
||||
if (c) {
|
||||
switch (code) {
|
||||
case 0x37: return 0x3a;
|
||||
case 0x3a: return 0x37;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
// Map video_mode depth ID to numerical depth value
|
||||
static inline int depth_of_video_mode(video_mode const & mode)
|
||||
{
|
||||
|
@ -439,92 +467,38 @@ static void set_window_name(Window w, int name)
|
|||
XClassHint *hints;
|
||||
hints = XAllocClassHint();
|
||||
if (hints) {
|
||||
hints->res_name = "BasiliskII";
|
||||
hints->res_class = "BasiliskII";
|
||||
hints->res_name = (char*) GetString(STR_WINDOW_TITLE);
|
||||
hints->res_class = (char*) GetString(STR_WINDOW_TITLE);
|
||||
XSetClassHint(x_display, w, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
}
|
||||
|
||||
// This struct is designed to match the ones generated by GIMP in
|
||||
// BasiliskII_*_icon.c
|
||||
struct gimp_image {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel;
|
||||
unsigned char pixel_data[0]; // Variable-length
|
||||
};
|
||||
|
||||
// These were generated by using 'icns2png -x
|
||||
// ../MacOSX/BasiliskII.icns', then using GIMP to convert the
|
||||
// resulting .png files into "C source code (*.c)". GIMP doesn't
|
||||
// generate corresponding .h files with extern declarations, so just
|
||||
// #include the .c files here.
|
||||
#include "BasiliskII_32x32x32_icon.c"
|
||||
#include "BasiliskII_128x128x32_icon.c"
|
||||
|
||||
// Set window icons
|
||||
static void set_window_icons(Window w)
|
||||
{
|
||||
// As per the _NET_WM_ICON documentation at
|
||||
// https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472568384,
|
||||
// "The first two cardinals are width, height."
|
||||
const unsigned int HEADER_SIZE = 2;
|
||||
// We will pass 32-bit values to XChangeProperty()
|
||||
const unsigned int FORMAT = 32;
|
||||
|
||||
// Icon data from GIMP to be converted and passed to the
|
||||
// Window Manager
|
||||
const struct gimp_image* const icons[] =
|
||||
{(struct gimp_image *) &icon_32x32x32,
|
||||
(struct gimp_image *) &icon_128x128x32};
|
||||
const unsigned int num_icons = sizeof(icons) / sizeof(icons[0]);
|
||||
unsigned int icon;
|
||||
|
||||
// Work out how big the buffer needs to be to store all of our icons
|
||||
unsigned int buffer_size = 0;
|
||||
for (icon = 0; icon < num_icons; icon++) {
|
||||
buffer_size += HEADER_SIZE +
|
||||
icons[icon]->width * icons[icon]->height;
|
||||
// Set window name and class (ported from SDL implementation)
|
||||
static void set_window_name(Window w, bool mouse_grabbed) {
|
||||
const char *title = PrefsFindString("title");
|
||||
std::string s = title ? title : GetString(STR_WINDOW_TITLE);
|
||||
if (mouse_grabbed)
|
||||
{
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_PRE);
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
hotkey = hotkey ? hotkey : 1;
|
||||
if (hotkey & 1) s += GetString(STR_WINDOW_TITLE_GRABBED1);
|
||||
if (hotkey & 2) s += GetString(STR_WINDOW_TITLE_GRABBED2);
|
||||
if (hotkey & 4) s += GetString(STR_WINDOW_TITLE_GRABBED4);
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_POST);
|
||||
}
|
||||
XStoreName(x_display, w, s.c_str());
|
||||
XSetIconName(x_display, w, GetString(STR_WINDOW_TITLE));
|
||||
|
||||
// As per the XChangeProperty() man page, "If the specified
|
||||
// format is 32, the property data must be a long array."
|
||||
unsigned long buffer[buffer_size];
|
||||
// This points to the start of the current icon within buffer
|
||||
unsigned long *buffer_icon = buffer;
|
||||
|
||||
// Copy the icons into the buffer
|
||||
for (icon = 0; icon < num_icons; icon++) {
|
||||
const unsigned int pixel_count = icons[icon]->width *
|
||||
icons[icon]->height;
|
||||
assert(icons[icon]->bytes_per_pixel == 4);
|
||||
buffer_icon[0] = icons[icon]->width;
|
||||
buffer_icon[1] = icons[icon]->height;
|
||||
unsigned long *const buffer_pixels = buffer_icon + HEADER_SIZE;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < pixel_count; i++) {
|
||||
const unsigned char *src =
|
||||
&icons[icon]->pixel_data[i * icons[icon]->bytes_per_pixel];
|
||||
buffer_pixels[i] = (src[3] << 24 |
|
||||
src[0] << 16 |
|
||||
src[1] << 8 |
|
||||
src[2]);
|
||||
}
|
||||
|
||||
buffer_icon += HEADER_SIZE + pixel_count;
|
||||
XClassHint *hints;
|
||||
hints = XAllocClassHint();
|
||||
if (hints) {
|
||||
hints->res_name = (char*) GetString(STR_WINDOW_TITLE);
|
||||
hints->res_class = (char*) GetString(STR_WINDOW_TITLE);
|
||||
XSetClassHint(x_display, w, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
||||
Atom net_wm_icon = XInternAtom(x_display, "_NET_WM_ICON", False);
|
||||
if (net_wm_icon == None) {
|
||||
ErrorAlert(STR_X_ICON_ATOM_ALLOC_ERR);
|
||||
// We can still continue running, just without an icon
|
||||
return;
|
||||
}
|
||||
XChangeProperty(x_display, w, net_wm_icon, XA_CARDINAL, FORMAT,
|
||||
PropModeReplace, (const unsigned char *) buffer,
|
||||
buffer_size);
|
||||
}
|
||||
|
||||
// Set window input focus flag
|
||||
|
@ -813,10 +787,7 @@ driver_window::driver_window(X11_monitor_desc &m)
|
|||
D(bug(" window created\n"));
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(w, STR_WINDOW_TITLE);
|
||||
|
||||
// Set window icons
|
||||
set_window_icons(w);
|
||||
set_window_name(w, mouse_grabbed);
|
||||
|
||||
// Indicate that we want keyboard input
|
||||
set_window_focus(w);
|
||||
|
@ -972,7 +943,7 @@ void driver_window::grab_mouse(void)
|
|||
Delay_usec(100000);
|
||||
}
|
||||
if (result == GrabSuccess) {
|
||||
XStoreName(x_display, w, GetString(STR_WINDOW_TITLE_GRABBED));
|
||||
set_window_name(w, true);
|
||||
ADBSetRelMouseMode(mouse_grabbed = true);
|
||||
disable_mouse_accel();
|
||||
}
|
||||
|
@ -983,7 +954,7 @@ void driver_window::ungrab_mouse(void)
|
|||
{
|
||||
if (mouse_grabbed) {
|
||||
XUngrabPointer(x_display, CurrentTime);
|
||||
XStoreName(x_display, w, GetString(STR_WINDOW_TITLE));
|
||||
set_window_name(w, false);
|
||||
ADBSetRelMouseMode(mouse_grabbed = false);
|
||||
restore_mouse_accel();
|
||||
}
|
||||
|
@ -1053,9 +1024,13 @@ driver_dga::~driver_dga()
|
|||
// Suspend emulation
|
||||
void driver_dga::suspend(void)
|
||||
{
|
||||
// Release ctrl key
|
||||
// Release hotkeys
|
||||
ADBKeyUp(0x36);
|
||||
ctrl_down = false;
|
||||
ADBKeyUp(0x37);
|
||||
cmd_down = false;
|
||||
ADBKeyUp(0x3a);
|
||||
opt_down = false;
|
||||
|
||||
// Lock frame buffer (this will stop the MacOS thread)
|
||||
LOCK_FRAME_BUFFER;
|
||||
|
@ -1233,7 +1208,7 @@ driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m)
|
|||
&wattr);
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(w, STR_WINDOW_TITLE);
|
||||
set_window_name(w, false);
|
||||
|
||||
// Indicate that we want keyboard input
|
||||
set_window_focus(w);
|
||||
|
@ -1370,7 +1345,7 @@ driver_xf86dga::driver_xf86dga(X11_monitor_desc &m)
|
|||
(color_class == DirectColor ? CWColormap : 0), &wattr);
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(w, STR_WINDOW_TITLE);
|
||||
set_window_name(w, false);
|
||||
|
||||
// Indicate that we want keyboard input
|
||||
set_window_focus(w);
|
||||
|
@ -1780,7 +1755,7 @@ bool VideoInit(bool classic)
|
|||
default_width = -1; default_height = -1; // use entire screen
|
||||
#endif
|
||||
#ifdef ENABLE_XF86_DGA
|
||||
} else if (has_dga && sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) {
|
||||
} else if (has_dga & sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) {
|
||||
display_type = DISPLAY_DGA;
|
||||
#endif
|
||||
}
|
||||
|
@ -2015,6 +1990,10 @@ void X11_monitor_desc::set_palette(uint8 *pal, int num_in)
|
|||
UNLOCK_PALETTE;
|
||||
}
|
||||
|
||||
void X11_monitor_desc::set_gamma(uint8* gamma, int num)
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch video mode
|
||||
|
@ -2091,7 +2070,7 @@ static int kc_decode(KeySym ks, bool key_down)
|
|||
case XK_period: case XK_greater: return 0x2f;
|
||||
case XK_slash: case XK_question: return 0x2c;
|
||||
|
||||
case XK_Tab: if (ctrl_down) {if (key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case XK_Tab: if (is_hotkey_down()) {if (key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case XK_Return: return 0x24;
|
||||
case XK_space: return 0x31;
|
||||
case XK_BackSpace: return 0x33;
|
||||
|
@ -2112,10 +2091,10 @@ static int kc_decode(KeySym ks, bool key_down)
|
|||
case XK_Control_R: return 0x36;
|
||||
case XK_Shift_L: return 0x38;
|
||||
case XK_Shift_R: return 0x38;
|
||||
case XK_Alt_L: return 0x37;
|
||||
case XK_Alt_R: return 0x37;
|
||||
case XK_Meta_L: return 0x3a;
|
||||
case XK_Meta_R: return 0x3a;
|
||||
case XK_Alt_L: return 0x3a;
|
||||
case XK_Alt_R: return 0x3a;
|
||||
case XK_Meta_L: return 0x37;
|
||||
case XK_Meta_R: return 0x37;
|
||||
case XK_Menu: return 0x32;
|
||||
case XK_Caps_Lock: return 0x39;
|
||||
case XK_Num_Lock: return 0x47;
|
||||
|
@ -2125,13 +2104,13 @@ static int kc_decode(KeySym ks, bool key_down)
|
|||
case XK_Left: return 0x3b;
|
||||
case XK_Right: return 0x3c;
|
||||
|
||||
case XK_Escape: if (ctrl_down) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
case XK_Escape: if (is_hotkey_down()) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
|
||||
case XK_F1: if (ctrl_down) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case XK_F1: if (is_hotkey_down()) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case XK_F2: return 0x78;
|
||||
case XK_F3: return 0x63;
|
||||
case XK_F4: return 0x76;
|
||||
case XK_F5: if (ctrl_down) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case XK_F5: if (is_hotkey_down()) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case XK_F6: return 0x61;
|
||||
case XK_F7: return 0x62;
|
||||
case XK_F8: return 0x64;
|
||||
|
@ -2267,12 +2246,23 @@ static void handle_events(void)
|
|||
|
||||
// Keyboard
|
||||
case KeyPress: {
|
||||
int code = -1;
|
||||
int code = event2keycode(event.xkey, true);
|
||||
if(!emul_suspended)
|
||||
{
|
||||
if (code == 0x36) {
|
||||
ctrl_down = true;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
}
|
||||
if (use_keycodes) {
|
||||
if (event2keycode(event.xkey, true) != -2) // This is called to process the hotkeys
|
||||
if (code != -2) // This is called to process the hotkeys
|
||||
code = keycode_table[event.xkey.keycode & 0xff];
|
||||
} else
|
||||
code = event2keycode(event.xkey, true);
|
||||
}
|
||||
if (code >= 0) {
|
||||
if (!emul_suspended) {
|
||||
if (code == 0x39) { // Caps Lock pressed
|
||||
|
@ -2285,8 +2275,6 @@ static void handle_events(void)
|
|||
}
|
||||
} else
|
||||
ADBKeyDown(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = true;
|
||||
} else {
|
||||
if (code == 0x31)
|
||||
drv->resume(); // Space wakes us up
|
||||
|
@ -2295,16 +2283,25 @@ static void handle_events(void)
|
|||
break;
|
||||
}
|
||||
case KeyRelease: {
|
||||
int code = -1;
|
||||
int code = event2keycode(event.xkey, false);
|
||||
if(!emul_suspended)
|
||||
{
|
||||
if (code == 0x36) {
|
||||
ctrl_down = false;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
}
|
||||
if (use_keycodes) {
|
||||
if (event2keycode(event.xkey, false) != -2) // This is called to process the hotkeys
|
||||
if (code != -2) // This is called to process the hotkeys
|
||||
code = keycode_table[event.xkey.keycode & 0xff];
|
||||
} else
|
||||
code = event2keycode(event.xkey, false);
|
||||
}
|
||||
if (code >= 0 && code != 0x39) { // Don't propagate Caps Lock releases
|
||||
ADBKeyUp(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2359,10 +2356,10 @@ static void update_display_dynamic(int ticker, driver_window *drv)
|
|||
y2s = sm_uptd[ticker % 8];
|
||||
y2a = 8;
|
||||
for (i = 0; i < 6; i++) {
|
||||
max_box = sm_no_boxes[i];
|
||||
if (ticker % (2 << i))
|
||||
break;
|
||||
}
|
||||
max_box = sm_no_boxes[i];
|
||||
|
||||
if (y2a) {
|
||||
for (y1=0; y1<16; y1++) {
|
||||
|
|
|
@ -20,11 +20,68 @@
|
|||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include "xpram.h"
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
|
||||
// XPRAM file name, set by LoadPrefs() in prefs_unix.cpp
|
||||
string xpram_name;
|
||||
|
||||
/*
|
||||
* Load XPRAM from settings file
|
||||
*/
|
||||
|
||||
void LoadXPRAM(const char* vmdir)
|
||||
{
|
||||
assert(!xpram_name.empty());
|
||||
int fd;
|
||||
if ((fd = open(xpram_name.c_str(), O_RDONLY)) >= 0)
|
||||
{
|
||||
read(fd, XPRAM, XPRAM_SIZE);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save XPRAM to settings file
|
||||
*/
|
||||
|
||||
void SaveXPRAM(void)
|
||||
{
|
||||
assert(!xpram_name.empty());
|
||||
int fd;
|
||||
if ((fd = open(xpram_name.c_str(), O_WRONLY | O_CREAT, 0666)) >= 0)
|
||||
{
|
||||
write(fd, XPRAM, XPRAM_SIZE);
|
||||
close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Unable to save %s (%s)\n",
|
||||
xpram_name.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete PRAM file
|
||||
*/
|
||||
|
||||
void ZapPRAM(void)
|
||||
{
|
||||
// Delete file
|
||||
assert(!xpram_name.empty());
|
||||
unlink(xpram_name.c_str());
|
||||
}
|
||||
|
||||
|
||||
#else // __linux__
|
||||
|
||||
|
||||
// XPRAM file name and path
|
||||
#if POWERPC_ROM
|
||||
const char XPRAM_FILE_NAME[] = ".sheepshaver_nvram";
|
||||
|
@ -98,3 +155,7 @@ void ZapPRAM(void)
|
|||
// Delete file
|
||||
unlink(xpram_path);
|
||||
}
|
||||
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 141 KiB |
14
BasiliskII/src/Windows/Makefile.in
Executable file → Normal file
14
BasiliskII/src/Windows/Makefile.in
Executable file → Normal file
|
@ -31,6 +31,8 @@ SLIRP_SRCS = \
|
|||
../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c
|
||||
SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=$(OBJ_DIR)/slirp-%.o)
|
||||
|
||||
USE_BINCUE = @USE_BINCUE@
|
||||
|
||||
LN_S = @LN_S@
|
||||
WINDRES = @WINDRES@
|
||||
CC = @CC@
|
||||
|
@ -42,6 +44,7 @@ DEFS = @DEFS@ @DEFINES@
|
|||
LDFLAGS = @LDFLAGS@ -Wl,-Bstatic
|
||||
LIBS = @LIBS@ -lws2_32 -lwsock32 -liphlpapi
|
||||
CPUSRCS = @CPUSRCS@
|
||||
EXTRASRCS = @EXTRASRCS@
|
||||
|
||||
HOST_CC = gcc
|
||||
HOST_CXX = g++
|
||||
|
@ -63,12 +66,13 @@ SRCS = ../main.cpp main_windows.cpp ../prefs.cpp ../prefs_items.cpp prefs_window
|
|||
../emul_op.cpp ../macos_util.cpp ../xpram.cpp xpram_windows.cpp ../timer.cpp \
|
||||
timer_windows.cpp ../adb.cpp ../serial.cpp serial_windows.cpp \
|
||||
../ether.cpp ether_windows.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp \
|
||||
../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp ../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp \
|
||||
video_blit.cpp ../audio.cpp ../SDL/audio_sdl.cpp clip_windows.cpp \
|
||||
../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp \
|
||||
../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp ../SDL/video_sdl3.cpp \
|
||||
video_blit.cpp ../audio.cpp ../SDL/audio_sdl.cpp ../SDL/audio_sdl3.cpp clip_windows.cpp \
|
||||
../extfs.cpp extfs_windows.cpp ../user_strings.cpp user_strings_windows.cpp \
|
||||
vm_alloc.cpp sigsegv.cpp posix_emu.cpp util_windows.cpp \
|
||||
../dummy/prefs_editor_dummy.cpp BasiliskII.rc \
|
||||
$(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(SLIRP_OBJS)
|
||||
$(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(EXTRASRCS) $(SLIRP_OBJS)
|
||||
|
||||
UI_SRCS = ../prefs.cpp prefs_windows.cpp prefs_editor_gtk.cpp xpram_windows.cpp \
|
||||
../prefs_items.cpp ../user_strings.cpp user_strings_windows.cpp util_windows.cpp \
|
||||
|
@ -118,7 +122,7 @@ $(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS)
|
|||
$(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS)
|
||||
|
||||
$(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) -Wl,-Bdynamic $(GTK_LIBS) -Wl,-Bstatic -mwindows -static-libgcc
|
||||
|
||||
mostlyclean:
|
||||
rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak
|
||||
|
@ -149,7 +153,7 @@ $(OBJ_DIR)/%.o : %.cpp
|
|||
$(OBJ_DIR)/%.o : %.s
|
||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||
$(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp
|
||||
$(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
$(CXX) -O2 -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
|
||||
# Windows resources
|
||||
$(OBJ_DIR)/%.o: %.rc
|
||||
|
|
62
BasiliskII/src/Windows/configure.ac
Executable file → Normal file
62
BasiliskII/src/Windows/configure.ac
Executable file → Normal file
|
@ -11,9 +11,6 @@ dnl Aliases for PACKAGE and VERSION macros.
|
|||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE_NAME", [Define this program name.])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$PACKAGE_VERSION", [Define this program version.])
|
||||
|
||||
dnl SDL options.
|
||||
#AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no])
|
||||
|
||||
dnl JIT compiler options.
|
||||
AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes])
|
||||
AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no])
|
||||
|
@ -35,6 +32,10 @@ AC_ARG_ENABLE(fpe,
|
|||
|
||||
dnl External packages.
|
||||
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes])
|
||||
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=no]], [WANT_VOSF=$enableval], [WANT_VOSF=no])
|
||||
|
||||
AC_ARG_WITH(bincue,
|
||||
AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode]))
|
||||
|
||||
dnl Addressing modes.
|
||||
AC_ARG_ENABLE(addressing,
|
||||
|
@ -49,6 +50,8 @@ AC_ARG_ENABLE(addressing,
|
|||
[ ADDRESSING_TEST_ORDER="direct banks"
|
||||
])
|
||||
|
||||
AC_ARG_WITH(sdl3, [ --with-sdl3 use SDL 3.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=3], [WANT_SDL_VERSION_MAJOR=2])
|
||||
|
||||
dnl Canonical system information.
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
|
@ -85,6 +88,14 @@ AC_SUBST(WANT_GTK)
|
|||
dnl We use 64-bit file size support if possible.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
dnl BINCUE
|
||||
AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no])
|
||||
AS_IF([test "x$have_bincue" = "xyes" ], [
|
||||
DEFINES="$DEFINES -DBINCUE"
|
||||
CPPFLAGS="$CPPFLAGS -DBINCUE"
|
||||
AC_SUBST(USE_BINCUE, yes)
|
||||
], [AC_SUBST(USE_BINCUE, no)])
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
|
||||
|
@ -200,8 +211,12 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler],
|
|||
AC_TRANSLATE_DEFINE(HAVE_SIGSEGV_SKIP_INSTRUCTION, "$ac_cv_have_skip_instruction",
|
||||
[Define if we can ignore the fault (instruction skipping in SIGSEGV handler).])
|
||||
|
||||
dnl We really want VOSF (Video on SEGV Signals) screen updates acceleration
|
||||
AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.])
|
||||
dnl Enable VOSF screen updates with this feature is requested
|
||||
if [[ "x$WANT_VOSF" = "xyes" ]]; then
|
||||
AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.])
|
||||
else
|
||||
WANT_VOSF=no
|
||||
fi
|
||||
|
||||
dnl Determine the addressing mode to use
|
||||
ADDRESSING_MODE=""
|
||||
|
@ -269,10 +284,13 @@ if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
|||
AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing],
|
||||
ac_cv_gcc_no_strict_aliasing, [
|
||||
AC_TRY_COMPILE([],[],
|
||||
[ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")],
|
||||
[ac_cv_gcc_no_strict_aliasing=yes],
|
||||
[ac_cv_gcc_no_strict_aliasing=no])
|
||||
])
|
||||
CFLAGS="$SAVED_CFLAGS"
|
||||
if test "x$ac_cv_gcc_no_strict_aliasing" = xyes; then
|
||||
AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Select appropriate CPU source and REGPARAM define.
|
||||
|
@ -304,6 +322,11 @@ elif [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_X86_64" = "xyes" ]]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
dnl BINCUE overrides
|
||||
if [[ "x$have_bincue" = "xyes" ]]; then
|
||||
EXTRASRCS="$EXTRASRCS bincue.cpp"
|
||||
fi
|
||||
|
||||
dnl Enable JIT compiler, if possible.
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then
|
||||
JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o"
|
||||
|
@ -524,19 +547,15 @@ CPUINCLUDES="-I../uae_cpu"
|
|||
CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS"
|
||||
|
||||
dnl We really want SDL for now
|
||||
AC_CHECK_TOOL(sdl_config, sdl2-config, [AC_MSG_ERROR([Sorry, you currently need SDL for this port])])
|
||||
SDL_CFLAGS=`$sdl_config --cflags`
|
||||
if [[ "x$WANT_SDL_VERSION_MAJOR" = "x3" ]]; then
|
||||
SDL_CFLAGS=`pkg-config sdl3 --cflags`
|
||||
SDL_CFLAGS+=`echo " $SDL_CFLAGS" | sed -e 's/\(-I.*include\)/\1\/SDL3/'`
|
||||
SDL_LIBS=`pkg-config sdl3 --libs | sed -e 's/-lSDL3/-lSDL3.dll/'`
|
||||
else
|
||||
SDL_CFLAGS=`sdl2-config --cflags`
|
||||
SDL_LIBS=`sdl2-config --static-libs`
|
||||
fi
|
||||
AC_SUBST(SDL_CFLAGS)
|
||||
#if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then
|
||||
SDL_LIBS=`$sdl_config --static-libs`
|
||||
# sdl_prefix=`$sdl_config --exec-prefix`
|
||||
# if [[ -n "$sdl_prefix" ]]; then
|
||||
# SDL_LIBS=`echo "$SDL_LIBS" | sed -e "s,-l\(SDLmain\|SDL\),$sdl_prefix/lib/lib\1.a,g"`
|
||||
# fi
|
||||
# SDL_LIBS="$SDL_LIBS -lwinmm"
|
||||
#else
|
||||
# SDL_LIBS=`$sdl_config --libs`
|
||||
#fi
|
||||
AC_SUBST(SDL_LIBS)
|
||||
AC_DEFINE(USE_SDL, 1, [Define to enble SDL support])
|
||||
AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support])
|
||||
|
@ -548,10 +567,14 @@ if [[ "x$HAVE_GCC27" = "xyes" ]]; then
|
|||
CXXFLAGS=`echo $CXXFLAGS | sed -e 's/-g\b//g'`
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -fwrapv"
|
||||
CXXFLAGS="$CXXFLAGS -fwrapv"
|
||||
|
||||
dnl Generate Makefile.
|
||||
AC_SUBST(DEFINES)
|
||||
AC_SUBST(CPUINCLUDES)
|
||||
AC_SUBST(CPUSRCS)
|
||||
AC_SUBST(EXTRASRCS)
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
|
@ -559,11 +582,14 @@ dnl Print summary.
|
|||
echo
|
||||
echo Basilisk II configuration summary:
|
||||
echo
|
||||
echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR
|
||||
echo Use JIT compiler ....................... : $WANT_JIT
|
||||
echo JIT debug mode ......................... : $WANT_JIT_DEBUG
|
||||
echo Floating-Point emulation core .......... : $FPE_CORE
|
||||
echo Assembly optimizations ................. : $ASM_OPTIMIZATIONS
|
||||
echo Addressing mode ........................ : $ADDRESSING_MODE
|
||||
echo BINCUE support ......................... : $have_bincue
|
||||
echo GTK user interface ..................... : $WANT_GTK
|
||||
echo Enable VOSF ............................ : $WANT_VOSF
|
||||
echo
|
||||
echo "Configuration done. Now type \"make\" (or \"gmake\")."
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
// somehow util_windows undefines min
|
||||
#define min(x,y) ((x) < (y) ? (x) : (y))
|
||||
#include "libslirp.h"
|
||||
#include "ctl.h"
|
||||
|
||||
// Define to let the slirp library determine the right timeout for select()
|
||||
#define USE_SLIRP_TIMEOUT 1
|
||||
|
@ -101,6 +102,14 @@ static int net_if_type = -1; // Ethernet device type
|
|||
#ifdef SHEEPSHAVER
|
||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||
uint8 ether_addr[6]; // Our Ethernet address
|
||||
|
||||
#else
|
||||
const bool ether_driver_opened = true; // Flag: Driver is open on MacOS side
|
||||
// so ether.h layer is ready for
|
||||
// calls.
|
||||
// B2 doesn't provide this
|
||||
// but also calls don't need it
|
||||
|
||||
#endif
|
||||
|
||||
// These are protected by queue_csection
|
||||
|
@ -136,6 +145,8 @@ static LPPACKET send_queue = 0;
|
|||
static CRITICAL_SECTION wpool_csection;
|
||||
static LPPACKET write_packet_pool = 0;
|
||||
|
||||
// Calling slirp functions from multiple threads concurrently is unsafe; guard it
|
||||
static CRITICAL_SECTION slirp_single_call_csection;
|
||||
|
||||
|
||||
// Try to deal with echos. Protected by fetch_csection.
|
||||
|
@ -190,6 +201,8 @@ static int16 ether_do_add_multicast(uint8 *addr);
|
|||
static int16 ether_do_del_multicast(uint8 *addr);
|
||||
static int16 ether_do_write(uint32 arg);
|
||||
static void ether_do_interrupt(void);
|
||||
static void slirp_add_redirs();
|
||||
static int slirp_add_redir(const char *redir_str);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -253,6 +266,7 @@ bool ether_init(void)
|
|||
WarningAlert(GetString(STR_SLIRP_NO_DNS_FOUND_WARN));
|
||||
return false;
|
||||
}
|
||||
slirp_add_redirs();
|
||||
}
|
||||
|
||||
// Open ethernet device
|
||||
|
@ -408,6 +422,8 @@ bool ether_init(void)
|
|||
InitializeCriticalSectionAndSpinCount( &send_csection, 5000 );
|
||||
InitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 );
|
||||
|
||||
InitializeCriticalSection( &slirp_single_call_csection );
|
||||
|
||||
ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid );
|
||||
if (!ether_th) {
|
||||
D(bug("Failed to create ethernet thread\n"));
|
||||
|
@ -557,6 +573,7 @@ void ether_exit(void)
|
|||
DeleteCriticalSection( &queue_csection );
|
||||
DeleteCriticalSection( &send_csection );
|
||||
DeleteCriticalSection( &wpool_csection );
|
||||
DeleteCriticalSection( &slirp_single_call_csection );
|
||||
|
||||
D(bug("Freeing read packets\n"));
|
||||
free_read_packets();
|
||||
|
@ -1010,7 +1027,9 @@ unsigned int WINAPI ether_thread_write_packets(void *arg)
|
|||
}
|
||||
break;
|
||||
case NET_IF_SLIRP:
|
||||
EnterCriticalSection( &slirp_single_call_csection );
|
||||
slirp_input((uint8 *)Packet->Buffer, Packet->Length);
|
||||
LeaveCriticalSection( &slirp_single_call_csection );
|
||||
Packet->bIoComplete = TRUE;
|
||||
recycle_write_packet(Packet);
|
||||
break;
|
||||
|
@ -1364,7 +1383,9 @@ unsigned int WINAPI slirp_receive_func(void *arg)
|
|||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&xfds);
|
||||
EnterCriticalSection( &slirp_single_call_csection );
|
||||
timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
|
||||
LeaveCriticalSection( &slirp_single_call_csection );
|
||||
#if ! USE_SLIRP_TIMEOUT
|
||||
timeout = 10000;
|
||||
#endif
|
||||
|
@ -1380,8 +1401,11 @@ unsigned int WINAPI slirp_receive_func(void *arg)
|
|||
tv.tv_usec = timeout;
|
||||
ret = select(0, &rfds, &wfds, &xfds, &tv);
|
||||
}
|
||||
if (ret >= 0)
|
||||
if (ret >= 0) {
|
||||
EnterCriticalSection( &slirp_single_call_csection );
|
||||
slirp_select_poll(&rfds, &wfds, &xfds);
|
||||
LeaveCriticalSection( &slirp_single_call_csection );
|
||||
}
|
||||
}
|
||||
|
||||
D(bug("slirp_receive_func exit\n"));
|
||||
|
@ -1571,10 +1595,16 @@ unsigned int WINAPI ether_thread_feed_int(void *arg)
|
|||
D(bug("Triggering\n"));
|
||||
looping = true;
|
||||
while(thread_active && looping) {
|
||||
trigger_queue();
|
||||
// Wait for interrupt acknowledge by EtherInterrupt()
|
||||
WaitForSingleObject(int_ack,INFINITE);
|
||||
if(thread_active) looping = set_wait_request();
|
||||
if (ether_driver_opened) {
|
||||
trigger_queue();
|
||||
// Wait for interrupt acknowledge by EtherInterrupt()
|
||||
WaitForSingleObject(int_ack,INFINITE);
|
||||
if(thread_active) looping = set_wait_request();
|
||||
} else {
|
||||
// Ether driver is closed on the MacOS side
|
||||
// ether.h calls in this case are undefined
|
||||
Delay_usec(20000);
|
||||
}
|
||||
}
|
||||
D(bug("Queue empty.\n"));
|
||||
}
|
||||
|
@ -1614,6 +1644,97 @@ static void ether_do_interrupt(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Helper function for port forwarding
|
||||
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
|
||||
{
|
||||
const char *p, *p1;
|
||||
int len;
|
||||
p = *pp;
|
||||
p1 = strchr(p, sep);
|
||||
if (!p1)
|
||||
return -1;
|
||||
len = p1 - p;
|
||||
p1++;
|
||||
if (buf_size > 0) {
|
||||
if (len > buf_size - 1)
|
||||
len = buf_size - 1;
|
||||
memcpy(buf, p, len);
|
||||
buf[len] = '\0';
|
||||
}
|
||||
*pp = p1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set up port forwarding for slirp
|
||||
static void slirp_add_redirs()
|
||||
{
|
||||
int index = 0;
|
||||
const char *str;
|
||||
while ((str = PrefsFindString("redir", index++)) != NULL) {
|
||||
slirp_add_redir(str);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a port forward/redirection for slirp
|
||||
static int slirp_add_redir(const char *redir_str)
|
||||
{
|
||||
// code adapted from qemu source
|
||||
struct in_addr guest_addr = {0};
|
||||
int host_port, guest_port;
|
||||
const char *p;
|
||||
char buf[256];
|
||||
int is_udp;
|
||||
char *end;
|
||||
char str[256];
|
||||
|
||||
p = redir_str;
|
||||
if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
if (!strcmp(buf, "tcp") || buf[0] == '\0') {
|
||||
is_udp = 0;
|
||||
} else if (!strcmp(buf, "udp")) {
|
||||
is_udp = 1;
|
||||
} else {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
host_port = strtol(buf, &end, 0);
|
||||
if (*end != '\0' || host_port < 1 || host_port > 65535) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
// 0.0.0.0 doesn't seem to work, so default to a client address
|
||||
// if none is specified
|
||||
if (buf[0] == '\0' ?
|
||||
!inet_pton(AF_INET, CTL_LOCAL, &guest_addr) :
|
||||
!inet_pton(AF_INET, buf, &guest_addr)) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
guest_port = strtol(p, &end, 0);
|
||||
if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
|
||||
sprintf(str, "could not set up host forwarding rule '%s'", redir_str);
|
||||
WarningAlert(str);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail_syntax:
|
||||
sprintf(str, "invalid host forwarding rule '%s'", redir_str);
|
||||
WarningAlert(str);
|
||||
return -1;
|
||||
}
|
||||
#if DEBUG
|
||||
#pragma optimize("",on)
|
||||
#endif
|
||||
|
|
98
BasiliskII/src/Windows/main_windows.cpp
Executable file → Normal file
98
BasiliskII/src/Windows/main_windows.cpp
Executable file → Normal file
|
@ -61,6 +61,11 @@ extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_suppo
|
|||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define SDL_Mutex SDL_mutex
|
||||
#define SDL_EVENT_KEY_UP SDL_KEYUP
|
||||
#define SDL_EVENT_KEY_DOWN SDL_KEYDOWN
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
const TCHAR ROM_FILE_NAME[] = TEXT("ROM");
|
||||
|
@ -86,7 +91,7 @@ static bool tick_thread_active = false; // Flag: 60Hz thread installed
|
|||
static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread
|
||||
static SDL_Thread *tick_thread; // 60Hz thread
|
||||
|
||||
static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags
|
||||
static SDL_Mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags
|
||||
#define LOCK_INTFLAGS SDL_LockMutex(intflag_lock)
|
||||
#define UNLOCK_INTFLAGS SDL_UnlockMutex(intflag_lock)
|
||||
|
||||
|
@ -98,11 +103,14 @@ uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
|
|||
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
|
||||
#endif
|
||||
|
||||
static HHOOK keyboard_hook; // Hook for intercepting windows key events
|
||||
|
||||
|
||||
// Prototypes
|
||||
static int xpram_func(void *arg);
|
||||
static int tick_func(void *arg);
|
||||
static void one_tick(...);
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -187,6 +195,16 @@ static void sigsegv_dump_state(sigsegv_info_t *sip)
|
|||
#endif
|
||||
}
|
||||
|
||||
uint16 emulated_ticks;
|
||||
void cpu_do_check_ticks(void)
|
||||
{
|
||||
static int delay = -1;
|
||||
if (delay < 0)
|
||||
delay = PrefsFindInt32("delay");
|
||||
if (delay)
|
||||
usleep(delay);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main program
|
||||
|
@ -204,6 +222,7 @@ static void usage(const char *prg_name)
|
|||
);
|
||||
LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values
|
||||
PrefsPrintUsage();
|
||||
printf("\nBuild Date: %s\n", __DATE__);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -283,6 +302,12 @@ int main(int argc, char **argv)
|
|||
QuitEmulator();
|
||||
#endif
|
||||
|
||||
// Install keyboard hook to block Windows key if enabled in prefs
|
||||
if (PrefsFindBool("reservewindowskey"))
|
||||
{
|
||||
keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, low_level_keyboard_hook, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
|
||||
// Initialize SDL system
|
||||
int sdl_flags = 0;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
|
@ -361,10 +386,10 @@ int main(int argc, char **argv)
|
|||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
// Get rom file path from preferences
|
||||
auto rom_path = tstr(PrefsFindString("rom"));
|
||||
const char* rom_path = PrefsFindString("rom");
|
||||
|
||||
// Load Mac ROM
|
||||
HANDLE rom_fh = CreateFile(rom_path ? rom_path.get() : ROM_FILE_NAME,
|
||||
HANDLE rom_fh = CreateFile((rom_path != NULL) ? rom_path : ROM_FILE_NAME,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING,
|
||||
|
@ -500,7 +525,7 @@ void FlushCodeCache(void *start, uint32 size)
|
|||
struct B2_mutex {
|
||||
B2_mutex() { m = SDL_CreateMutex(); }
|
||||
~B2_mutex() { if (m) SDL_DestroyMutex(m); }
|
||||
SDL_mutex *m;
|
||||
SDL_Mutex *m;
|
||||
};
|
||||
|
||||
B2_mutex *B2_create_mutex(void)
|
||||
|
@ -598,13 +623,15 @@ static void one_tick(...)
|
|||
}
|
||||
}
|
||||
|
||||
bool tick_inhibit;
|
||||
static int tick_func(void *arg)
|
||||
{
|
||||
uint64 start = GetTicks_usec();
|
||||
int64 ticks = 0;
|
||||
uint64 next = GetTicks_usec();
|
||||
while (!tick_thread_cancel) {
|
||||
one_tick();
|
||||
if (!tick_inhibit)
|
||||
one_tick();
|
||||
next += 16625;
|
||||
int64 delay = next - GetTicks_usec();
|
||||
if (delay > 0)
|
||||
|
@ -624,22 +651,25 @@ static int tick_func(void *arg)
|
|||
*/
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#include <SDL_video.h>
|
||||
#else
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
extern SDL_Window *sdl_window;
|
||||
HWND GetMainWindowHandle(void)
|
||||
{
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
if (!sdl_window) {
|
||||
return NULL;
|
||||
}
|
||||
if (!SDL_GetWindowWMInfo(sdl_window, &wmInfo)) {
|
||||
return NULL;
|
||||
}
|
||||
if (wmInfo.subsystem != SDL_SYSWM_WINDOWS) {
|
||||
return NULL;
|
||||
}
|
||||
return wmInfo.info.win.window;
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(sdl_window);
|
||||
return (HWND)SDL_GetProperty(props, "SDL.window.cocoa.window", NULL);
|
||||
#else
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
return SDL_GetWindowWMInfo(sdl_window, &wmInfo) ? wmInfo.info.win.window : NULL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -711,3 +741,43 @@ bool ChoiceAlert(const char *text, const char *pos, const char *neg)
|
|||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||
return false; //!!
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level keyboard hook allowing us to intercept events involving the Windows key
|
||||
*/
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Not a relevant event, immediately pass it on
|
||||
if (nCode != HC_ACTION)
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
|
||||
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
|
||||
switch (wParam) {
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
// Intercept left/right windows keys when we have keyboard focus so Windows doesn't handle them
|
||||
if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN) {
|
||||
bool intercept_event = false;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
if (sdl_window && (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_INPUT_FOCUS)) {
|
||||
intercept_event = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we've determined we should intercept the event, intercept it. But pass the event onto SDL so Basilisk handles it.
|
||||
if (intercept_event) {
|
||||
SDL_Event e;
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.type = (wParam == WM_KEYDOWN) ? SDL_EVENT_KEY_DOWN : SDL_EVENT_KEY_UP;
|
||||
e.key.keysym.sym = (p->vkCode == VK_LWIN) ? SDLK_LGUI : SDLK_RGUI;
|
||||
e.key.keysym.scancode = (p->vkCode == VK_LWIN) ? SDL_SCANCODE_LGUI : SDL_SCANCODE_RGUI;
|
||||
SDL_PushEvent(&e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If we fall here, we weren't supposed to intercept it.
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
}
|
||||
|
|
|
@ -392,14 +392,23 @@ void init_posix_emu(void)
|
|||
int fd = my_creat( custom_icon_name, 0 );
|
||||
if(fd >= 0) {
|
||||
my_close(fd);
|
||||
struct my_stat custom_icon_stat;
|
||||
int stat_result = my_stat( custom_icon_name, &custom_icon_stat );
|
||||
fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT );
|
||||
if(fd >= 0) {
|
||||
my_write( fd, my_comp_icon, sizeof(my_comp_icon) );
|
||||
my_close(fd);
|
||||
static uint8 host_finfo[SIZEOF_FInfo];
|
||||
// need room for the things from around the finfo that set_finfo reads
|
||||
static uint8 custom_icon_hfile[ioFlXFndrInfo + SIZEOF_FXInfo];
|
||||
memset(custom_icon_hfile, 0, ioFlXFndrInfo + SIZEOF_FXInfo);
|
||||
static uint8 * host_finfo = custom_icon_hfile + ioFlFndrInfo;
|
||||
uint32 finfo = Host2MacAddr(host_finfo);
|
||||
get_finfo(custom_icon_name, finfo, 0, false);
|
||||
WriteMacInt16(finfo + fdFlags, kIsInvisible);
|
||||
if (stat_result == 0) {
|
||||
WriteMacInt32(finfo - ioFlFndrInfo + ioFlCrDat, TimeToMacTime(custom_icon_stat.st_ctime));
|
||||
WriteMacInt32(finfo - ioFlFndrInfo + ioFlMdDat, TimeToMacTime(custom_icon_stat.st_mtime));
|
||||
}
|
||||
set_finfo(custom_icon_name, finfo, 0, false);
|
||||
get_finfo(my_computer, finfo, 0, true);
|
||||
WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon);
|
||||
|
|
|
@ -79,24 +79,33 @@ extern int my_errno;
|
|||
|
||||
// must hook all other functions that manipulate file names
|
||||
#ifndef NO_POSIX_API_HOOK
|
||||
#define stat my_stat
|
||||
#define fstat my_fstat
|
||||
#define open my_open
|
||||
#define rename my_rename
|
||||
#define access my_access
|
||||
#define mkdir my_mkdir
|
||||
#define remove my_remove
|
||||
#define creat my_creat
|
||||
#define close my_close
|
||||
#define lseek my_lseek
|
||||
#define read my_read
|
||||
#define write my_write
|
||||
#define ftruncate my_chsize
|
||||
#define locking my_locking
|
||||
#define utime my_utime
|
||||
# ifdef stat
|
||||
# undef stat
|
||||
# endif
|
||||
# define stat my_stat
|
||||
# ifdef fstat
|
||||
# undef fstat
|
||||
# endif
|
||||
# define fstat my_fstat
|
||||
# define open my_open
|
||||
# define rename my_rename
|
||||
# define access my_access
|
||||
# define mkdir my_mkdir
|
||||
# define remove my_remove
|
||||
# define creat my_creat
|
||||
# define close my_close
|
||||
# ifdef lseek
|
||||
# undef lseek
|
||||
# endif
|
||||
# define lseek my_lseek
|
||||
# define read my_read
|
||||
# define write my_write
|
||||
# define ftruncate my_chsize
|
||||
# define locking my_locking
|
||||
# define utime my_utime
|
||||
|
||||
#undef errno
|
||||
#define errno my_errno
|
||||
# undef errno
|
||||
# define errno my_errno
|
||||
#endif //!NO_POSIX_API_HOOK
|
||||
|
||||
#ifndef S_ISDIR
|
||||
|
@ -125,6 +134,6 @@ struct my_utimbuf
|
|||
};
|
||||
|
||||
// Your compiler may have different "struct stat" -> edit "struct my_stat"
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) )
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct _stat) )
|
||||
|
||||
#define st_crtime st_ctime
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <sys/stat.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "user_strings.h"
|
||||
#include "version.h"
|
||||
#include "cdrom.h"
|
||||
|
@ -76,6 +78,27 @@ enum {
|
|||
* Utility functions
|
||||
*/
|
||||
|
||||
gchar * tchar_to_g_utf8(const TCHAR * str) {
|
||||
gchar * out;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
int len = _tcslen(str) + 1;
|
||||
#ifdef _UNICODE
|
||||
/* First call just to find what the output size will be */
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
out = (gchar *) g_malloc(size);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
WideCharToMultiByte(CP_UTF8, 0, str, len, out, size, NULL, NULL);
|
||||
#else /* _UNICODE */
|
||||
out = g_locale_to_utf8(str, -1, NULL, NULL, NULL);
|
||||
#endif /* _UNICODE */
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
struct opt_desc {
|
||||
int label_id;
|
||||
GtkSignalFunc func;
|
||||
|
@ -672,11 +695,11 @@ static GList *add_cdrom_names(void)
|
|||
{
|
||||
GList *glist = NULL;
|
||||
|
||||
char rootdir[4] = "X:\\";
|
||||
for (char letter = 'C'; letter <= 'Z'; letter++) {
|
||||
TCHAR rootdir[4] = TEXT("X:\\");
|
||||
for (TCHAR letter = TEXT('C'); letter <= TEXT('Z'); letter++) {
|
||||
rootdir[0] = letter;
|
||||
if (GetDriveType(rootdir) == DRIVE_CDROM)
|
||||
glist = g_list_append(glist, strdup(rootdir));
|
||||
glist = g_list_append(glist, _tcsdup(rootdir));
|
||||
}
|
||||
|
||||
return glist;
|
||||
|
@ -887,11 +910,12 @@ static void create_jit_pane(GtkWidget *top)
|
|||
#endif
|
||||
|
||||
set_jit_sensitive();
|
||||
#endif
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -951,30 +975,14 @@ static int dis_width, dis_height;
|
|||
// Hide/show graphics widgets
|
||||
static void hide_show_graphics_widgets(void)
|
||||
{
|
||||
switch (display_type) {
|
||||
case DISPLAY_WINDOW:
|
||||
gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
|
||||
break;
|
||||
case DISPLAY_SCREEN:
|
||||
gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// "Window" video type selected
|
||||
static void mn_window(...)
|
||||
{
|
||||
display_type = DISPLAY_WINDOW;
|
||||
hide_show_graphics_widgets();
|
||||
}
|
||||
static void mn_window(...) {display_type = DISPLAY_WINDOW;}
|
||||
|
||||
// "Fullscreen" video type selected
|
||||
static void mn_fullscreen(...)
|
||||
{
|
||||
display_type = DISPLAY_SCREEN;
|
||||
hide_show_graphics_widgets();
|
||||
PrefsReplaceInt32("frameskip", 1);
|
||||
}
|
||||
static void mn_fullscreen(...) {display_type = DISPLAY_SCREEN;}
|
||||
|
||||
// "5 Hz".."60Hz" selected
|
||||
static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
|
||||
|
@ -1006,6 +1014,33 @@ static void tb_nosound(GtkWidget *widget)
|
|||
set_graphics_sensitive();
|
||||
}
|
||||
|
||||
// SDL Graphics
|
||||
#ifdef USE_SDL_VIDEO
|
||||
// SDL Renderer Render Driver
|
||||
enum {
|
||||
RENDER_SOFTWARE = 0,
|
||||
RENDER_OPENGL = 1,
|
||||
RENDER_DIRECT3D = 2
|
||||
};
|
||||
|
||||
GtkWidget *w_render_driver;
|
||||
GtkWidget *l_render_driver;
|
||||
static int render_driver;
|
||||
static int sdl_vsync;
|
||||
|
||||
// Render Driver selected
|
||||
static void mn_sdl_software(...) {render_driver = RENDER_SOFTWARE;}
|
||||
static void mn_sdl_opengl(...) {render_driver = RENDER_OPENGL;}
|
||||
static void mn_sdl_direct3d(...) {render_driver = RENDER_DIRECT3D;}
|
||||
|
||||
// SDL Renderer Vertical Sync
|
||||
static void tb_sdl_vsync(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("sdl_vsync", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Read graphics preferences
|
||||
static void parse_graphics_prefs(void)
|
||||
{
|
||||
|
@ -1025,6 +1060,40 @@ static void parse_graphics_prefs(void)
|
|||
else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
|
||||
display_type = DISPLAY_SCREEN;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
render_driver = RENDER_SOFTWARE;
|
||||
|
||||
const char *drv = PrefsFindString("sdlrender");
|
||||
if (drv && drv[0]) {
|
||||
if (strcmp(drv, "software") == 0)
|
||||
render_driver = RENDER_SOFTWARE;
|
||||
else if (strcmp(drv, "opengl") == 0)
|
||||
render_driver = RENDER_OPENGL;
|
||||
else if (strcmp(drv, "direct3d") == 0)
|
||||
render_driver = RENDER_DIRECT3D;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void read_SDL_graphics_settings(void)
|
||||
{
|
||||
const char *rpref;
|
||||
switch (render_driver) {
|
||||
case RENDER_SOFTWARE:
|
||||
rpref = "software";
|
||||
break;
|
||||
case RENDER_OPENGL:
|
||||
rpref = "opengl";
|
||||
break;
|
||||
case RENDER_DIRECT3D:
|
||||
rpref = "direct3d";
|
||||
break;
|
||||
default:
|
||||
PrefsRemoveItem("sdlrender");
|
||||
return;
|
||||
}
|
||||
PrefsReplaceString("sdlrender", rpref);
|
||||
}
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
|
@ -1051,6 +1120,10 @@ static void read_graphics_settings(void)
|
|||
return;
|
||||
}
|
||||
PrefsReplaceString("screen", pref);
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
read_SDL_graphics_settings();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create "Graphics/Sound" pane
|
||||
|
@ -1160,6 +1233,39 @@ static void create_graphics_pane(GtkWidget *top)
|
|||
make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel));
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
make_separator(box);
|
||||
|
||||
table = make_table(box, 2, 5);
|
||||
|
||||
l_render_driver = gtk_label_new(GetString(STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL));
|
||||
gtk_widget_show(l_render_driver);
|
||||
gtk_table_attach(GTK_TABLE(table), l_render_driver, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
w_render_driver = gtk_option_menu_new();
|
||||
gtk_widget_show(w_render_driver);
|
||||
menu = gtk_menu_new();
|
||||
|
||||
add_menu_item(menu, STR_SOFTWARE_LAB, GTK_SIGNAL_FUNC(mn_sdl_software));
|
||||
add_menu_item(menu, STR_OPENGL_LAB, GTK_SIGNAL_FUNC(mn_sdl_opengl));
|
||||
add_menu_item(menu, STR_DIRECT3D_LAB, GTK_SIGNAL_FUNC(mn_sdl_direct3d));
|
||||
switch (render_driver) {
|
||||
case RENDER_SOFTWARE:
|
||||
gtk_menu_set_active(GTK_MENU(menu), 0);
|
||||
break;
|
||||
case RENDER_OPENGL:
|
||||
gtk_menu_set_active(GTK_MENU(menu), 1);
|
||||
break;
|
||||
case RENDER_DIRECT3D:
|
||||
gtk_menu_set_active(GTK_MENU(menu), 2);
|
||||
break;
|
||||
}
|
||||
gtk_option_menu_set_menu(GTK_OPTION_MENU(w_render_driver), menu);
|
||||
gtk_table_attach(GTK_TABLE(table), w_render_driver, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
opt = make_checkbox(box, STR_GRAPHICS_SDL_VSYNC_CTRL, "sdl_vsync", GTK_SIGNAL_FUNC(tb_sdl_vsync));
|
||||
#endif
|
||||
|
||||
make_separator(box);
|
||||
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
|
||||
|
||||
|
@ -1192,6 +1298,12 @@ static void tb_keycodes(GtkWidget *widget)
|
|||
set_input_sensitive();
|
||||
}
|
||||
|
||||
// "Reserve Windows Key" button toggled
|
||||
static void tb_reservewindowskey(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("reservewindowskey", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// "Mouse Wheel Mode" selected
|
||||
static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
|
||||
static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
|
||||
|
@ -1239,6 +1351,8 @@ static void create_input_pane(GtkWidget *top)
|
|||
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
|
||||
g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
|
||||
|
||||
make_checkbox(box, STR_RESERVE_WINDOWS_KEY_CTRL, "reservewindowskey", GTK_SIGNAL_FUNC(tb_reservewindowskey));
|
||||
|
||||
make_separator(box);
|
||||
|
||||
static const opt_desc options[] = {
|
||||
|
@ -1466,24 +1580,25 @@ static int create_ether_menu(GtkWidget *menu)
|
|||
n_items++;
|
||||
|
||||
// Basilisk II Ethernet Adapter
|
||||
PacketOpenAdapter("", 0);
|
||||
PacketOpenAdapter(TEXT(""), 0);
|
||||
{
|
||||
ULONG sz;
|
||||
char names[1024];
|
||||
TCHAR names[1024];
|
||||
sz = sizeof(names);
|
||||
if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) {
|
||||
char *p = names;
|
||||
TCHAR *p = names;
|
||||
while (*p) {
|
||||
const char DEVICE_HEADER[] = "\\Device\\B2ether_";
|
||||
if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
|
||||
const TCHAR DEVICE_HEADER[] = TEXT("\\Device\\B2ether_");
|
||||
if (_tcsnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
|
||||
LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0);
|
||||
if (fd) {
|
||||
char guid[256];
|
||||
sprintf(guid, "%s", p + sizeof(DEVICE_HEADER) - 1);
|
||||
const char *name = ether_guid_to_name(guid);
|
||||
if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(guid));
|
||||
if (etherguid && strcmp(guid, etherguid) == 0 &&
|
||||
TCHAR guid[256];
|
||||
_stprintf(guid, TEXT("%s"), p + sizeof(DEVICE_HEADER) - 1);
|
||||
const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid));
|
||||
if (name) {
|
||||
std::string str_guid = to_string(guid);
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(str_guid.c_str()));
|
||||
if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 &&
|
||||
ether && strcmp(ether, "b2ether") == 0)
|
||||
active = n_items;
|
||||
n_items++;
|
||||
|
@ -1491,26 +1606,27 @@ static int create_ether_menu(GtkWidget *menu)
|
|||
PacketCloseAdapter(fd);
|
||||
}
|
||||
}
|
||||
p += strlen(p) + 1;
|
||||
p += _tcslen(p) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
PacketCloseAdapter(NULL);
|
||||
|
||||
// TAP-Win32
|
||||
const char *tap_devices;
|
||||
const TCHAR *tap_devices;
|
||||
if ((tap_devices = ether_tap_devices()) != NULL) {
|
||||
const char *guid = tap_devices;
|
||||
const TCHAR *guid = tap_devices;
|
||||
while (*guid) {
|
||||
const char *name = ether_guid_to_name(guid);
|
||||
if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(guid));
|
||||
if (etherguid && strcmp(guid, etherguid) == 0 &&
|
||||
const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid));
|
||||
if (name) {
|
||||
std::string str_guid = to_string(guid);
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(str_guid.c_str()));
|
||||
if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 &&
|
||||
ether && strcmp(ether, "tap") == 0)
|
||||
active = n_items;
|
||||
n_items++;
|
||||
}
|
||||
guid += strlen(guid) + 1;
|
||||
guid += _tcslen(guid) + 1;
|
||||
}
|
||||
free((char *)tap_devices);
|
||||
}
|
||||
|
@ -1734,21 +1850,66 @@ void SysAddSerialPrefs(void)
|
|||
* Display alerts
|
||||
*/
|
||||
|
||||
static HWND GetMainWindowHandle() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void display_alert(int title_id, const char *text, int flags)
|
||||
{
|
||||
MessageBox(NULL, text, GetString(title_id), MB_OK | flags);
|
||||
HWND hMainWnd = GetMainWindowHandle();
|
||||
MessageBoxA(hMainWnd, text, GetString(title_id), MB_OK | flags);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
static void display_alert(int title_id, const wchar_t *text, int flags)
|
||||
{
|
||||
HWND hMainWnd = GetMainWindowHandle();
|
||||
MessageBoxW(hMainWnd, text, GetStringW(title_id).get(), MB_OK | flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display error alert
|
||||
*/
|
||||
|
||||
void ErrorAlert(const char *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
void ErrorAlert(const wchar_t *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display warning alert
|
||||
*/
|
||||
|
||||
void WarningAlert(const char *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
void WarningAlert(const wchar_t *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start standalone GUI
|
||||
|
@ -1774,23 +1935,23 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Transfer control to the executable
|
||||
if (start) {
|
||||
char path[_MAX_PATH];
|
||||
TCHAR path[_MAX_PATH];
|
||||
bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0;
|
||||
if (ok) {
|
||||
char b2_path[_MAX_PATH];
|
||||
char *p = strrchr(path, '\\');
|
||||
*++p = '\0';
|
||||
TCHAR b2_path[_MAX_PATH];
|
||||
TCHAR *p = _tcsrchr(path, TEXT('\\'));
|
||||
*++p = TEXT('\0');
|
||||
SetCurrentDirectory(path);
|
||||
strcpy(b2_path, path);
|
||||
strcat(b2_path, PROGRAM_NAME);
|
||||
strcat(b2_path, ".exe");
|
||||
HINSTANCE h = ShellExecute(GetDesktopWindow(), "open",
|
||||
b2_path, "", path, SW_SHOWNORMAL);
|
||||
_tcscpy(b2_path, path);
|
||||
_tcscat(b2_path, TEXT(PROGRAM_NAME));
|
||||
_tcscat(b2_path, TEXT(".exe"));
|
||||
HINSTANCE h = ShellExecute(GetDesktopWindow(), TEXT("open"),
|
||||
b2_path, TEXT(""), path, SW_SHOWNORMAL);
|
||||
if ((int)h <= 32)
|
||||
ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
ErrorAlert("Coult not start " PROGRAM_NAME " executable");
|
||||
ErrorAlert(TEXT("Could not start ") TEXT(PROGRAM_NAME) TEXT(" executable"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,6 @@ prefs_desc platform_prefs_items[] = {
|
|||
{"keycodefile", TYPE_STRING, false, "path of keycode translation file"},
|
||||
{"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"},
|
||||
{"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"},
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
{"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"},
|
||||
#endif
|
||||
{"idlewait", TYPE_BOOLEAN, false, "sleep when idle"},
|
||||
{"enableextfs", TYPE_BOOLEAN, false, "enable extfs system"},
|
||||
{"debugextfs", TYPE_BOOLEAN, false, "debug extfs system"},
|
||||
|
@ -52,6 +49,12 @@ prefs_desc platform_prefs_items[] = {
|
|||
{"tcp_port", TYPE_STRING, false, "TCP ports list"},
|
||||
{"portfile0", TYPE_STRING, false, "output file for serial port 0"},
|
||||
{"portfile1", TYPE_STRING, false, "output file for serial port 1"},
|
||||
#ifdef USE_SDL_VIDEO
|
||||
{"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"},
|
||||
{"sdl_vsync", TYPE_BOOLEAN, false, "Make SDL_Renderer vertical sync frames to host (eg. with software renderer)"},
|
||||
#endif
|
||||
{"reservewindowskey", TYPE_BOOLEAN, false, "block Windows key from activating start menu"},
|
||||
|
||||
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
|
@ -123,9 +126,6 @@ void AddPlatformPrefsDefaults(void)
|
|||
PrefsReplaceString("extdrives", "CDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
PrefsReplaceInt32("mousewheelmode", 1);
|
||||
PrefsReplaceInt32("mousewheellines", 3);
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
PrefsAddBool("ignoresegv", false);
|
||||
#endif
|
||||
PrefsAddBool("idlewait", true);
|
||||
PrefsReplaceBool("etherpermanentaddress", true);
|
||||
PrefsReplaceInt32("ethermulticastmode", 0);
|
||||
|
@ -134,4 +134,9 @@ void AddPlatformPrefsDefaults(void)
|
|||
PrefsReplaceString("serialb", "COM2");
|
||||
PrefsReplaceString("portfile0", "C:\\B2TEMP0.OUT");
|
||||
PrefsReplaceString("portfile1", "C:\\B2TEMP1.OUT");
|
||||
#ifdef USE_SDL_VIDEO
|
||||
PrefsReplaceString("sdlrender", "software");
|
||||
PrefsReplaceBool("sdl_vsync", false);
|
||||
#endif
|
||||
PrefsAddBool("reservewindowskey", false);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ using std::min;
|
|||
#include "cdenable/cache.h"
|
||||
#include "cdenable/eject_nt.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
@ -56,6 +60,12 @@ struct file_handle {
|
|||
loff_t file_size; // Size of file data (only valid if is_file is true)
|
||||
cachetype cache;
|
||||
bool is_media_present;
|
||||
|
||||
#if defined(BINCUE)
|
||||
bool is_bincue; // Flag: BIN CUE file
|
||||
void *bincue_fd;
|
||||
file_handle() {is_bincue = false;} // default bincue false
|
||||
#endif
|
||||
};
|
||||
|
||||
// Open file handles
|
||||
|
@ -74,7 +84,7 @@ static char *sector_buffer = NULL;
|
|||
|
||||
// Prototypes
|
||||
static bool is_cdrom_readable(file_handle *fh);
|
||||
|
||||
static DWORD file_offset_read(HANDLE fh, loff_t offset, int count, char *buf);
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
|
@ -256,12 +266,42 @@ void SysAddSerialPrefs(void)
|
|||
* Can't give too much however, would be annoying, this is difficult..
|
||||
*/
|
||||
|
||||
static inline int cd_read_with_retry(file_handle *fh, ULONG LBA, int count, char *buf )
|
||||
static inline int cd_read_with_retry(file_handle *fh, ULONG offset, int count, char *buf )
|
||||
{
|
||||
if (!fh || !fh->fh)
|
||||
return 0;
|
||||
|
||||
return CdenableSysReadCdBytes(fh->fh, LBA, count, buf);
|
||||
DWORD bytes_read = CdenableSysReadCdBytes(fh->fh, offset, count, buf);
|
||||
|
||||
if (bytes_read == 0) {
|
||||
// fall back to logical volume handle read in the case where there's no cdenable
|
||||
bytes_read = file_offset_read(fh->fh, offset, count, buf);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic offset read function for a file or a device that behaves like one
|
||||
*/
|
||||
|
||||
static DWORD file_offset_read(HANDLE fh, loff_t offset, int count, char *buf)
|
||||
{
|
||||
// Seek to position
|
||||
LONG lo = (LONG)offset;
|
||||
LONG hi = (LONG)(offset >> 32);
|
||||
DWORD r = SetFilePointer(fh, lo, &hi, FILE_BEGIN);
|
||||
if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD bytes_read;
|
||||
|
||||
// Read data
|
||||
if (ReadFile(fh, buf, count, &bytes_read, NULL) == 0)
|
||||
bytes_read = 0;
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
static int cd_read(file_handle *fh, cachetype *cptr, ULONG LBA, int count, char *buf)
|
||||
|
@ -406,7 +446,7 @@ static bool is_read_only_path(const TCHAR *name)
|
|||
* Open file/device, create new file handle (returns NULL on error)
|
||||
*/
|
||||
|
||||
void *Sys_open(const char *path_name, bool read_only)
|
||||
void *Sys_open(const char *path_name, bool read_only, bool is_cdrom)
|
||||
{
|
||||
file_handle * fh = NULL;
|
||||
|
||||
|
@ -462,6 +502,11 @@ void *Sys_open(const char *path_name, bool read_only)
|
|||
read_only = true;
|
||||
|
||||
// Open file
|
||||
|
||||
#if defined(BINCUE)
|
||||
void *binfd = open_bincue(name); // check if bincue
|
||||
#endif
|
||||
|
||||
HANDLE h = CreateFile(
|
||||
name,
|
||||
read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||
|
@ -486,6 +531,16 @@ void *Sys_open(const char *path_name, bool read_only)
|
|||
fh->is_floppy = false;
|
||||
fh->is_cdrom = false;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (binfd) {
|
||||
fh->bincue_fd = binfd;
|
||||
fh->is_bincue = true;
|
||||
fh->is_media_present = true;
|
||||
sys_add_file_handle(fh);
|
||||
return fh;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detect disk image file layout
|
||||
loff_t size = GetFileSize(h, NULL);
|
||||
DWORD bytes_read;
|
||||
|
@ -517,6 +572,11 @@ void Sys_close(void *arg)
|
|||
|
||||
sys_remove_file_handle(fh);
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
close_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
cache_final(&fh->cache);
|
||||
SysAllowRemoval((void *)fh);
|
||||
|
@ -543,19 +603,15 @@ size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length)
|
|||
if (!fh)
|
||||
return 0;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return read_bincue(fh->bincue_fd, buffer, offset, length);
|
||||
#endif
|
||||
|
||||
DWORD bytes_read = 0;
|
||||
|
||||
if (fh->is_file) {
|
||||
// Seek to position
|
||||
LONG lo = (LONG)offset;
|
||||
LONG hi = (LONG)(offset >> 32);
|
||||
DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN);
|
||||
if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
return 0;
|
||||
|
||||
// Read data
|
||||
if (ReadFile(fh->fh, buffer, length, &bytes_read, NULL) == 0)
|
||||
bytes_read = 0;
|
||||
bytes_read = file_offset_read(fh->fh, offset, length, (char *)buffer);
|
||||
}
|
||||
else if (fh->is_cdrom) {
|
||||
int bytes_left, try_bytes, got_bytes;
|
||||
|
@ -623,6 +679,11 @@ loff_t SysGetFileSize(void *arg)
|
|||
if (!fh)
|
||||
return true;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return size_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_file)
|
||||
return fh->file_size;
|
||||
else if (fh->is_cdrom)
|
||||
|
@ -644,6 +705,13 @@ void SysEject(void *arg)
|
|||
if (!fh)
|
||||
return;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue) {
|
||||
fh->is_media_present = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom && fh->fh) {
|
||||
fh->is_media_present = false;
|
||||
// Commented out because there was some problems, but can't remember
|
||||
|
@ -782,16 +850,26 @@ void SysAllowRemoval(void *arg)
|
|||
bool SysCDReadTOC(void *arg, uint8 *toc)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dummy;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_TOC,
|
||||
NULL, 0,
|
||||
toc, min((int)sizeof(CDROM_TOC), 804),
|
||||
&dummy,
|
||||
NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return readtoc_bincue(fh->bincue_fd, toc);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
DWORD dummy;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_TOC,
|
||||
NULL, 0,
|
||||
toc, min((int)sizeof(CDROM_TOC), 804),
|
||||
&dummy,
|
||||
NULL) != FALSE;
|
||||
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -802,26 +880,34 @@ bool SysCDReadTOC(void *arg, uint8 *toc)
|
|||
bool SysCDGetPosition(void *arg, uint8 *pos)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
SUB_Q_CHANNEL_DATA q_data;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return GetPosition_bincue(fh->bincue_fd, pos);
|
||||
#endif
|
||||
|
||||
CDROM_SUB_Q_DATA_FORMAT q_format;
|
||||
q_format.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
q_format.Track = 0; // used only by ISRC reads
|
||||
if (fh->is_cdrom) {
|
||||
SUB_Q_CHANNEL_DATA q_data;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
bool ok = DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_Q_CHANNEL,
|
||||
&q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT),
|
||||
&q_data, sizeof(SUB_Q_CHANNEL_DATA),
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (ok)
|
||||
memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION));
|
||||
CDROM_SUB_Q_DATA_FORMAT q_format;
|
||||
q_format.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
q_format.Track = 0; // used only by ISRC reads
|
||||
|
||||
return ok;
|
||||
DWORD dwBytesReturned = 0;
|
||||
bool ok = DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_Q_CHANNEL,
|
||||
&q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT),
|
||||
&q_data, sizeof(SUB_Q_CHANNEL_DATA),
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (ok)
|
||||
memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION));
|
||||
|
||||
return ok;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -832,24 +918,32 @@ bool SysCDGetPosition(void *arg, uint8 *pos)
|
|||
bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
CDROM_PLAY_AUDIO_MSF msf;
|
||||
msf.StartingM = start_m;
|
||||
msf.StartingS = start_s;
|
||||
msf.StartingF = start_f;
|
||||
msf.EndingM = end_m;
|
||||
msf.EndingS = end_s;
|
||||
msf.EndingF = end_f;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDPlay_bincue(fh->bincue_fd, start_m, start_s, start_f, end_m, end_s, end_f);
|
||||
#endif
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PLAY_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_PLAY_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (fh->is_cdrom) {
|
||||
CDROM_PLAY_AUDIO_MSF msf;
|
||||
msf.StartingM = start_m;
|
||||
msf.StartingS = start_s;
|
||||
msf.StartingF = start_f;
|
||||
msf.EndingM = end_m;
|
||||
msf.EndingS = end_s;
|
||||
msf.EndingF = end_f;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PLAY_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_PLAY_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -860,16 +954,24 @@ bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end
|
|||
bool SysCDPause(void *arg)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PAUSE_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDPause_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PAUSE_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -880,15 +982,23 @@ bool SysCDPause(void *arg)
|
|||
bool SysCDResume(void *arg)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_RESUME_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned, NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDResume_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_RESUME_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned, NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -899,16 +1009,24 @@ bool SysCDResume(void *arg)
|
|||
bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_STOP_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDStop_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_STOP_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -919,21 +1037,30 @@ bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f)
|
|||
bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
CDROM_SEEK_AUDIO_MSF msf;
|
||||
msf.M = start_m;
|
||||
msf.S = start_s;
|
||||
msf.F = start_f;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDScan_bincue(fh->bincue_fd,start_m,start_s,start_f,reverse);
|
||||
#endif
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SEEK_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_SEEK_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
CDROM_SEEK_AUDIO_MSF msf;
|
||||
msf.M = start_m;
|
||||
msf.S = start_s;
|
||||
msf.F = start_f;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SEEK_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_SEEK_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -944,22 +1071,30 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve
|
|||
void SysCDSetVolume(void *arg, uint8 left, uint8 right)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
VOLUME_CONTROL vc;
|
||||
vc.PortVolume[0] = left;
|
||||
vc.PortVolume[1] = right;
|
||||
vc.PortVolume[2] = left;
|
||||
vc.PortVolume[3] = right;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDSetVol_bincue(fh->bincue_fd,left,right);
|
||||
#endif
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SET_VOLUME,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
VOLUME_CONTROL vc;
|
||||
vc.PortVolume[0] = left;
|
||||
vc.PortVolume[1] = right;
|
||||
vc.PortVolume[2] = left;
|
||||
vc.PortVolume[3] = right;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SET_VOLUME,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -974,21 +1109,27 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right)
|
|||
return;
|
||||
|
||||
left = right = 0;
|
||||
if (!fh->fh || !fh->is_cdrom)
|
||||
return;
|
||||
|
||||
VOLUME_CONTROL vc;
|
||||
memset(&vc, 0, sizeof(vc));
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDGetVol_bincue(fh->bincue_fd,&left,&right);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
if (DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_GET_VOLUME,
|
||||
NULL, 0,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
{
|
||||
left = vc.PortVolume[0];
|
||||
right = vc.PortVolume[1];
|
||||
VOLUME_CONTROL vc;
|
||||
memset(&vc, 0, sizeof(vc));
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
if (DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_GET_VOLUME,
|
||||
NULL, 0,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
{
|
||||
left = vc.PortVolume[0];
|
||||
right = vc.PortVolume[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
#ifndef SYSDEPS_H
|
||||
#define SYSDEPS_H
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
#if !defined _MSC_VER && !defined __STDC__
|
||||
#error "Your compiler is not ANSI. Get a real one."
|
||||
#endif
|
||||
|
@ -32,9 +28,9 @@
|
|||
#include "config.h"
|
||||
#include "user_strings_windows.h"
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#error "You don't have ANSI C header files."
|
||||
#endif
|
||||
//#ifndef STDC_HEADERS
|
||||
//#error "You don't have ANSI C header files."
|
||||
//#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "sysdeps.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
#include "util_windows.h"
|
||||
|
||||
// Platform-specific string definitions
|
||||
user_string_def platform_strings[] = {
|
||||
|
@ -56,6 +56,7 @@ user_string_def platform_strings[] = {
|
|||
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
|
||||
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
|
||||
{STR_KEYCODE_FILE_CTRL, "Keycode Translation File"},
|
||||
{STR_RESERVE_WINDOWS_KEY_CTRL, "Reserve Windows Key"},
|
||||
{STR_MOUSEWHEELMODE_CTRL, "Mouse Wheel Function"},
|
||||
{STR_MOUSEWHEELMODE_PAGE_LAB, "Page Up/Down"},
|
||||
{STR_MOUSEWHEELMODE_CURSOR_LAB, "Cursor Up/Down"},
|
||||
|
@ -81,7 +82,11 @@ static const char *get_volume_name(void)
|
|||
HKEY hHelpKey;
|
||||
DWORD key_type, cbData;
|
||||
|
||||
static char volume[256];
|
||||
#ifdef _UNICODE
|
||||
static char out_volume[256];
|
||||
#endif
|
||||
|
||||
static TCHAR volume[256];
|
||||
memset(volume, 0, sizeof(volume));
|
||||
|
||||
// Try Windows 2000 key first
|
||||
|
@ -118,14 +123,20 @@ static const char *get_volume_name(void)
|
|||
}
|
||||
|
||||
// Fix the error that some "tweak" apps do.
|
||||
if (_stricmp(volume, "%USERNAME% on %COMPUTER%") == 0)
|
||||
volume[0] = '\0';
|
||||
if (_tcsicmp(volume, TEXT("%USERNAME% on %COMPUTER%")) == 0)
|
||||
volume[0] = TEXT('\0');
|
||||
|
||||
// No volume name found, default to "My Computer"
|
||||
if (volume[0] == 0)
|
||||
strcpy(volume, "My Computer");
|
||||
_tcscpy(volume, TEXT("My Computer"));
|
||||
|
||||
|
||||
#ifdef _UNICODE
|
||||
strlcpy(out_volume, volume, 256);
|
||||
return out_volume;
|
||||
#else
|
||||
return volume;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ enum {
|
|||
STR_INPUT_PANE_TITLE,
|
||||
STR_KEYCODES_CTRL,
|
||||
STR_KEYCODE_FILE_CTRL,
|
||||
STR_RESERVE_WINDOWS_KEY_CTRL,
|
||||
STR_MOUSEWHEELMODE_CTRL,
|
||||
STR_MOUSEWHEELMODE_PAGE_LAB,
|
||||
STR_MOUSEWHEELMODE_CURSOR_LAB,
|
||||
|
|
|
@ -401,7 +401,7 @@ const TCHAR *ether_guid_to_name(const TCHAR *guid)
|
|||
|
||||
#define ADAPTER_KEY TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}")
|
||||
|
||||
const _TCHAR * tap_component_ids[] = { TEXT("tap0801"), TEXT("tap0901"), 0 };
|
||||
const _TCHAR * tap_component_ids[] = { TEXT("root\\tap0801"), TEXT("root\\tap0901"), 0 };
|
||||
|
||||
const TCHAR *ether_tap_devices(void)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,11 @@ const int KEY_BUFFER_SIZE = 16;
|
|||
static uint8 key_buffer[KEY_BUFFER_SIZE];
|
||||
static unsigned int key_read_ptr = 0, key_write_ptr = 0;
|
||||
|
||||
// O2S: Button event buffer (Mac button with up/down flag) -> avoid to loose tap on a trackpad
|
||||
const int BUTTON_BUFFER_SIZE = 32;
|
||||
static uint8 button_buffer[BUTTON_BUFFER_SIZE];
|
||||
static unsigned int button_read_ptr = 0, button_write_ptr = 0;
|
||||
|
||||
static uint8 mouse_reg_3[2] = {0x63, 0x01}; // Mouse ADB register 3
|
||||
|
||||
static uint8 key_reg_2[2] = {0xff, 0xff}; // Keyboard ADB register 2
|
||||
|
@ -245,13 +250,17 @@ void ADBMouseMoved(int x, int y)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Mouse button pressed
|
||||
*/
|
||||
|
||||
void ADBMouseDown(int button)
|
||||
{
|
||||
mouse_button[button] = true;
|
||||
// O2S: Add button to buffer
|
||||
button_buffer[button_write_ptr] = button;
|
||||
button_write_ptr = (button_write_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
|
||||
// O2S: mouse_button[button] = true;
|
||||
SetInterruptFlag(INTFLAG_ADB);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
|
@ -263,7 +272,11 @@ void ADBMouseDown(int button)
|
|||
|
||||
void ADBMouseUp(int button)
|
||||
{
|
||||
mouse_button[button] = false;
|
||||
// O2S: Add button to buffer
|
||||
button_buffer[button_write_ptr] = button | 0x80;
|
||||
button_write_ptr = (button_write_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
|
||||
// O2S: mouse_button[button] = false;
|
||||
SetInterruptFlag(INTFLAG_ADB);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
|
@ -278,7 +291,7 @@ void ADBSetRelMouseMode(bool relative)
|
|||
if (relative_mouse != relative) {
|
||||
relative_mouse = relative;
|
||||
mouse_x = mouse_y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -340,41 +353,45 @@ void ADBInterrupt(void)
|
|||
int my = mouse_y;
|
||||
if (relative_mouse)
|
||||
mouse_x = mouse_y = 0;
|
||||
bool mb[3] = {mouse_button[0], mouse_button[1], mouse_button[2]};
|
||||
B2_unlock_mutex(mouse_lock);
|
||||
|
||||
uint32 key_base = adb_base + 4;
|
||||
uint32 mouse_base = adb_base + 16;
|
||||
|
||||
if (relative_mouse) {
|
||||
while (mx != 0 || my != 0 || button_read_ptr != button_write_ptr) {
|
||||
if (button_read_ptr != button_write_ptr) {
|
||||
// Read button event
|
||||
uint8 button = button_buffer[button_read_ptr];
|
||||
button_read_ptr = (button_read_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
mouse_button[button & 0x3] = (button & 0x80) ? false : true;
|
||||
}
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mouse_button[2] ? 0x08 : 0x88));
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80));
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
|
||||
// Mouse movement (relative) and buttons
|
||||
if (mx != 0 || my != 0 || mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) {
|
||||
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mb[2] ? 0x08 : 0x88));
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80));
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
|
||||
old_mouse_button[0] = mb[0];
|
||||
old_mouse_button[1] = mb[1];
|
||||
old_mouse_button[2] = mb[2];
|
||||
}
|
||||
old_mouse_button[0] = mouse_button[0];
|
||||
old_mouse_button[1] = mouse_button[1];
|
||||
old_mouse_button[2] = mouse_button[2];
|
||||
mx = 0;
|
||||
my = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -405,34 +422,42 @@ void ADBInterrupt(void)
|
|||
old_mouse_y = my;
|
||||
}
|
||||
|
||||
// Send mouse button events
|
||||
if (mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) {
|
||||
uint32 mouse_base = adb_base + 16;
|
||||
// O2S: Process accumulated button events
|
||||
while (button_read_ptr != button_write_ptr) {
|
||||
// Read button event
|
||||
uint8 button = button_buffer[button_read_ptr];
|
||||
button_read_ptr = (button_read_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
mouse_button[button & 0x3] = (button & 0x80) ? false : true;
|
||||
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 3, mb[2] ? 0x08 : 0x88);
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80);
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
if (mouse_button[0] != old_mouse_button[0] || mouse_button[1] != old_mouse_button[1] || mouse_button[2] != old_mouse_button[2]) {
|
||||
uint32 mouse_base = adb_base + 16;
|
||||
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 3, mouse_button[2] ? 0x08 : 0x88);
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80);
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
|
||||
old_mouse_button[0] = mouse_button[0];
|
||||
old_mouse_button[1] = mouse_button[1];
|
||||
old_mouse_button[2] = mouse_button[2];
|
||||
}
|
||||
}
|
||||
|
||||
old_mouse_button[0] = mb[0];
|
||||
old_mouse_button[1] = mb[1];
|
||||
old_mouse_button[2] = mb[2];
|
||||
}
|
||||
}
|
||||
|
||||
// Process accumulated keyboard events
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "main.h"
|
||||
#include "audio.h"
|
||||
#include "audio_defs.h"
|
||||
#include "user_strings.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
@ -51,6 +53,9 @@ static int open_count = 0; // Open/close nesting count
|
|||
|
||||
bool AudioAvailable = false; // Flag: audio output available (from the software point of view)
|
||||
|
||||
int SoundInSource = 2;
|
||||
int SoundInPlaythrough = 7;
|
||||
int SoundInGain = 65536; // FIXED 4-byte from 0.5 to 1.5; this is middle value (1) as int
|
||||
|
||||
/*
|
||||
* Reset audio emulation
|
||||
|
@ -406,8 +411,8 @@ adat_error: printf("FATAL: audio component data block initialization error\n");
|
|||
// Close Apple Mixer
|
||||
r.a[0] = AudioStatus.mixer;
|
||||
Execute68k(audio_data + adatCloseMixer, &r);
|
||||
D(bug(" CloseMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer));
|
||||
AudioStatus.mixer = 0;
|
||||
return r.d[0];
|
||||
}
|
||||
r.a[0] = audio_data;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr()
|
||||
|
@ -533,7 +538,7 @@ delegate: // Delegate call to Apple Mixer
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// not currently using these functions
|
||||
/*
|
||||
* Sound input driver Open() routine
|
||||
*/
|
||||
|
@ -553,7 +558,20 @@ int16 SoundInPrime(uint32 pb, uint32 dce)
|
|||
{
|
||||
D(bug("SoundInPrime\n"));
|
||||
//!!
|
||||
return paramErr;
|
||||
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
D(bug("SoundInControl %d\n", code));
|
||||
|
||||
if (code == 1) {
|
||||
D(bug(" SoundInKillIO\n"));
|
||||
//!!
|
||||
return noErr;
|
||||
}
|
||||
|
||||
if (code != 2)
|
||||
return -231; // siUnknownInfoType
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -574,12 +592,39 @@ int16 SoundInControl(uint32 pb, uint32 dce)
|
|||
|
||||
if (code != 2)
|
||||
return -231; // siUnknownInfoType
|
||||
|
||||
uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
|
||||
uint32 selector = param[0];
|
||||
D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
|
||||
|
||||
uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above)
|
||||
|
||||
switch (selector) {
|
||||
case siInitializeDriver: {
|
||||
// If possible, the driver initializes the device to a sampling rate of 22 kHz, a sample size of 8 bits, mono recording, no compression, automatic gain control on, and all other features off.
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siCloseDriver: {
|
||||
// The sound input device driver should stop any recording in progress, deallocate the input hardware, and initialize local variables to default settings.
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputSource: {
|
||||
SoundInSource = ReadMacInt16(pb + csParam + 4);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siPlayThruOnOff: {
|
||||
SoundInPlaythrough = ReadMacInt16(pb + csParam + 4);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siOptionsDialog: {
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputGain: {
|
||||
SoundInGain = ReadMacInt32(pb + csParam + 4);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
default:
|
||||
return -231; // siUnknownInfoType
|
||||
}
|
||||
|
@ -590,58 +635,187 @@ int16 SoundInControl(uint32 pb, uint32 dce)
|
|||
* Sound input driver Status() routine
|
||||
*/
|
||||
|
||||
int16 SoundInStatus(uint32 pb, uint32 dce)
|
||||
int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parameter block (pb) and A1 to device control entry (dce)
|
||||
{
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
D(bug("SoundInStatus %d\n", code));
|
||||
if (code != 2)
|
||||
return -231; // siUnknownInfoType
|
||||
|
||||
// two choices on return
|
||||
// 1: if under 18 bytes, place # of bytes at (pb+csParam) and write from (pb+csParam+4) on
|
||||
// 2: if over 18 bytes, place 0 at (pb+csParam) and directly write into address pointed to by (pb+csParam+4)
|
||||
uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above)
|
||||
uint32 bufferptr = ReadMacInt32(pb + csParam + 4); // 4-byte address to the buffer in vm memory
|
||||
|
||||
uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
|
||||
uint32 selector = param[0];
|
||||
D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
|
||||
switch (selector) {
|
||||
#if 0
|
||||
case siDeviceName: {
|
||||
const char *str = GetString(STR_SOUND_IN_NAME);
|
||||
param[0] = 0;
|
||||
memcpy((void *)param[1], str, strlen(str));
|
||||
case siDeviceName: { // return name in STR255 format
|
||||
const uint8 str[] = { // size 9
|
||||
0x08, // 1-byte length
|
||||
0x42, 0x75, // Bu
|
||||
0x69, 0x6c, // il
|
||||
0x74, 0x2d, // t-
|
||||
0x69, 0x6e // in
|
||||
};
|
||||
// const uint8 str[] = { // size 12
|
||||
// 0x0b, // 1-byte length
|
||||
// 0x53, 0x68, // Sh
|
||||
// 0x65, 0x65, // ee
|
||||
// 0x70, 0x73, // ps
|
||||
// 0x68, 0x61, // ha
|
||||
// 0x76, 0x65, // ve
|
||||
// 0x72 // r
|
||||
// };
|
||||
WriteMacInt32(pb + csParam, 0); // response will be written directly into buffer
|
||||
Host2Mac_memcpy(bufferptr, str, sizeof(str));
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siDeviceIcon: {
|
||||
// todo: add soundin ICN, borrow from CD ROM for now
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
|
||||
M68kRegisters r;
|
||||
static const uint8 proc[] = {
|
||||
0x55, 0x8f, // subq.l #2,sp
|
||||
0xa9, 0x94, // CurResFile
|
||||
0x42, 0x67, // clr.w -(sp)
|
||||
0xa9, 0x98, // UseResFile
|
||||
0x59, 0x8f, // subq.l #4,sp
|
||||
0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp)
|
||||
0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp)
|
||||
0xa9, 0xa0, // GetResource
|
||||
0x24, 0x5f, // move.l (sp)+,a2
|
||||
0xa9, 0x98, // UseResFile
|
||||
0x20, 0x0a, // move.l a2,d0
|
||||
0x66, 0x04, // bne 1
|
||||
0x70, 0x00, // moveq #0,d0
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff,
|
||||
0x2f, 0x0a, //1 move.l a2,-(sp)
|
||||
0xa9, 0x92, // DetachResource
|
||||
0x20, 0x4a, // move.l a2,a0
|
||||
0xa0, 0x4a, // HNoPurge
|
||||
0x70, 0x01, // moveq #1,d0
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
Execute68k(Host2MacAddr((uint8 *)proc), &r);
|
||||
if (r.d[0]) {
|
||||
param[0] = 4; // Length of returned data
|
||||
param[1] = r.a[2]; // Handle to icon suite
|
||||
return noErr;
|
||||
} else
|
||||
return -192; // resNotFound
|
||||
r.d[0] = sizeof(CDROMIcon);
|
||||
Execute68kTrap(0xa122, &r); // NewHandle()
|
||||
uint32 h = r.a[0];
|
||||
if (h == 0)
|
||||
return memFullErr;
|
||||
WriteMacInt32(bufferptr, h);
|
||||
uint32 sp = ReadMacInt32(h);
|
||||
Host2Mac_memcpy(sp, CDROMIcon, sizeof(CDROMIcon));
|
||||
|
||||
return noErr;
|
||||
|
||||
// 68k code causes crash in sheep and link error in basilisk
|
||||
// M68kRegisters r;
|
||||
// static const uint8 proc[] = {
|
||||
// 0x55, 0x8f, // subq.l #2,sp
|
||||
// 0xa9, 0x94, // CurResFile
|
||||
// 0x42, 0x67, // clr.w -(sp)
|
||||
// 0xa9, 0x98, // UseResFile
|
||||
// 0x59, 0x8f, // subq.l #4,sp
|
||||
// 0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp)
|
||||
// 0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp)
|
||||
// 0xa9, 0xa0, // GetResource
|
||||
// 0x24, 0x5f, // move.l (sp)+,a2
|
||||
// 0xa9, 0x98, // UseResFile
|
||||
// 0x20, 0x0a, // move.l a2,d0
|
||||
// 0x66, 0x04, // bne 1
|
||||
// 0x70, 0x00, // moveq #0,d0
|
||||
// M68K_RTS >> 8, M68K_RTS & 0xff,
|
||||
// 0x2f, 0x0a, //1 move.l a2,-(sp)
|
||||
// 0xa9, 0x92, // DetachResource
|
||||
// 0x20, 0x4a, // move.l a2,a0
|
||||
// 0xa0, 0x4a, // HNoPurge
|
||||
// 0x70, 0x01, // moveq #1,d0
|
||||
// M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
// };
|
||||
// Execute68k(Host2MacAddr((uint8 *)proc), &r);
|
||||
// if (r.d[0]) {
|
||||
// WriteMacInt32(pb + csParam, 4); // Length of returned data
|
||||
// WriteMacInt32(pb + csParam + 4, r.a[2]); // Handle to icon suite
|
||||
// return noErr;
|
||||
// } else
|
||||
// return -192; // resNotFound
|
||||
}
|
||||
#endif
|
||||
|
||||
case siInputSource: {
|
||||
// return -231 if only 1 or index of current source if more
|
||||
|
||||
WriteMacInt32(pb + csParam, 2);
|
||||
WriteMacInt16(pb + csParam + 4, SoundInSource); // index of selected source
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputSourceNames: {
|
||||
// return -231 if only 1 or handle to STR# resource if more
|
||||
|
||||
const uint8 str[] = {
|
||||
0x00, 0x02, // 2-byte count of #strings
|
||||
// byte size indicator (up to 255 length supported)
|
||||
0x0a, // size is 10
|
||||
0x4d, 0x69, // Mi
|
||||
0x63, 0x72, // cr
|
||||
0x6f, 0x70, // op
|
||||
0x68, 0x6f, // ho
|
||||
0x6e, 0x65, // ne
|
||||
0x0b, // size is 11
|
||||
0x49, 0x6e, // start of string in ASCII, In
|
||||
0x74, 0x65, // te
|
||||
0x72, 0x6e, // rn
|
||||
0x61, 0x6c, // al
|
||||
0x20, 0x43, // C
|
||||
0x44, // D
|
||||
};
|
||||
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
|
||||
M68kRegisters r;
|
||||
r.d[0] = sizeof(str);
|
||||
Execute68kTrap(0xa122, &r); // NewHandle()
|
||||
uint32 h = r.a[0];
|
||||
if (h == 0)
|
||||
return memFullErr;
|
||||
WriteMacInt32(bufferptr, h);
|
||||
uint32 sp = ReadMacInt32(h);
|
||||
Host2Mac_memcpy(sp, str, sizeof(str));
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siOptionsDialog: {
|
||||
// 0 if no options box supported and 1 if so
|
||||
WriteMacInt32(pb + csParam, 2); // response not in buffer, need to copy integer
|
||||
WriteMacInt16(pb + csParam + 4, 1); // Integer data type
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siPlayThruOnOff: {
|
||||
// playthrough volume, 0 is off and 7 is max
|
||||
WriteMacInt32(pb + csParam, 2);
|
||||
WriteMacInt16(pb + csParam + 4, SoundInPlaythrough);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siNumberChannels: {
|
||||
// 1 is mono and 2 is stereo
|
||||
WriteMacInt32(pb + csParam, 2);
|
||||
WriteMacInt16(pb + csParam + 4, 2);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siSampleRate: {
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
WriteMacInt32(bufferptr, 0xac440000); // 44100.00000 Hz, of Fixed data type
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siSampleRateAvailable: {
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
|
||||
M68kRegisters r;
|
||||
r.d[0] = 4;
|
||||
Execute68kTrap(0xa122, &r); // NewHandle()
|
||||
uint32 h = r.a[0];
|
||||
if (h == 0)
|
||||
return memFullErr;
|
||||
WriteMacInt16(bufferptr, 1); // 1 sample rate available
|
||||
WriteMacInt32(bufferptr + 2, h); // handle to sample rate list
|
||||
uint32 sp = ReadMacInt32(h);
|
||||
WriteMacInt32(sp, 0xac440000); // 44100.00000 Hz, of Fixed data type
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputGain: {
|
||||
WriteMacInt32(pb + csParam, 4);
|
||||
WriteMacInt32(pb + csParam + 4, SoundInGain);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
return -231; // siUnknownInfoType
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
#include "../MacOSX/MacOSX_sound_if.h"
|
||||
static int bincue_core_audio_callback(void);
|
||||
|
@ -51,15 +53,20 @@ static int bincue_core_audio_callback(void);
|
|||
#include <SDL_audio.h>
|
||||
#endif
|
||||
|
||||
#include "bincue_unix.h"
|
||||
#ifdef WIN32
|
||||
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
|
||||
#define bcopy(b1,b2,len) (memmove((b2), (b1), (len)), (void) 0)
|
||||
#endif
|
||||
|
||||
#include "bincue.h"
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define MAXTRACK 100
|
||||
#define MAXLINE 512
|
||||
#define CD_FRAMES 75
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
//#define RAW_SECTOR_SIZE 2352
|
||||
//#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
// Bits of Track Control Field -- These are standard for scsi cd players
|
||||
|
||||
|
@ -91,6 +98,7 @@ typedef struct {
|
|||
unsigned int length; // Track length in frames
|
||||
loff_t fileoffset; // Track frame start within file
|
||||
unsigned int pregap; // Silence in frames to generate
|
||||
unsigned int postgap; // Silence in frames to generate at end
|
||||
unsigned char tcf; // Track control field
|
||||
} Track;
|
||||
|
||||
|
@ -99,10 +107,13 @@ typedef struct {
|
|||
unsigned int length; // file length in frames
|
||||
int binfh; // binary file handle
|
||||
int tcnt; // number of tracks
|
||||
Track tracks[MAXTRACK];
|
||||
Track tracks[MAXTRACK]; // Track management
|
||||
int raw_sector_size; // Raw bytes to read per sector
|
||||
int cooked_sector_size; // Actual data bytes per sector (depends on Mode)
|
||||
int header_size; // Number of bytes used in header
|
||||
} CueSheet;
|
||||
|
||||
typedef struct {
|
||||
typedef struct CDPlayer {
|
||||
CueSheet *cs; // cue sheet to play from
|
||||
int audiofh; // file handle for audio data
|
||||
unsigned int audioposition; // current position from audiostart (bytes)
|
||||
|
@ -110,10 +121,17 @@ typedef struct {
|
|||
unsigned int audioend; // end position if playing (frames)
|
||||
unsigned int silence; // pregap (silence) bytes
|
||||
unsigned char audiostatus; // See defines above for status
|
||||
uint8 volume_left; // CD player volume (left)
|
||||
uint8 volume_right; // CD player volume (right)
|
||||
uint8 volume_mono; // CD player single-channel volume
|
||||
loff_t fileoffset; // offset from file beginning to audiostart
|
||||
bool audio_enabled = false; // audio initialized for this player?
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
OSXsoundOutput soundoutput;
|
||||
#endif
|
||||
#ifdef USE_SDL_AUDIO
|
||||
SDL_AudioStream *stream;
|
||||
#endif
|
||||
} CDPlayer;
|
||||
|
||||
// Minute,Second,Frame data type
|
||||
|
@ -127,15 +145,24 @@ typedef struct {
|
|||
static unsigned int totalPregap;
|
||||
static unsigned int prestart;
|
||||
|
||||
// Audio System State
|
||||
// Audio System Variables
|
||||
|
||||
static bool audio_enabled = false;
|
||||
static uint8 silence_byte;
|
||||
|
||||
|
||||
// CD Player state. Note only one player is supported !
|
||||
// CD Player state; multiple players supported through vectors
|
||||
|
||||
static CDPlayer player;
|
||||
std::vector<CDPlayer*> players;
|
||||
|
||||
CDPlayer* currently_playing = NULL;
|
||||
|
||||
CDPlayer* CSToPlayer(CueSheet* cs)
|
||||
{
|
||||
for (std::vector<CDPlayer*>::iterator it = players.begin(); it != players.end(); ++it)
|
||||
if (cs == (*it)->cs) // look for cuesheet matching existing player
|
||||
return *it;
|
||||
return NULL; // if no player with the cuesheet found, return null player
|
||||
}
|
||||
|
||||
static void FramesToMSF(unsigned int frames, MSF *msf)
|
||||
{
|
||||
|
@ -181,7 +208,7 @@ static bool AddTrack(CueSheet *cs)
|
|||
}
|
||||
}
|
||||
|
||||
curr->fileoffset = curr->start * RAW_SECTOR_SIZE;
|
||||
curr->fileoffset = curr->start * cs->raw_sector_size;
|
||||
|
||||
// now we patch up the indicated time
|
||||
|
||||
|
@ -236,6 +263,11 @@ static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile)
|
|||
|
||||
totalPregap = 0;
|
||||
prestart = 0;
|
||||
|
||||
// Use Audio CD settings by default, otherwise data mode will be specified
|
||||
cs->raw_sector_size = 2352;
|
||||
cs->cooked_sector_size = 2352;
|
||||
cs->header_size = 0;
|
||||
|
||||
while (fgets(line, MAXLINE, fh) != NULL) {
|
||||
Track *curr = &cs->tracks[cs->tcnt];
|
||||
|
@ -294,11 +326,24 @@ static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile)
|
|||
}
|
||||
curr->number = i_track;
|
||||
|
||||
// parse track type
|
||||
// parse track type and update sector size for data discs if applicable
|
||||
|
||||
field = strtok(NULL, " \t\n\r");
|
||||
if (!strcmp("MODE1/2352", field)) {
|
||||
if (!strcmp("MODE1/2352", field)) { // red-book CD-ROM standard
|
||||
curr->tcf = DATA;
|
||||
cs->raw_sector_size = 2352;
|
||||
cs->cooked_sector_size = 2048;
|
||||
cs->header_size = 16; // remaining 288 bytes for error detection
|
||||
} else if (!strcmp("MODE2/2352", field)) { // yellow-book CD-ROM standard
|
||||
curr->tcf = DATA;
|
||||
cs->raw_sector_size = 2352;
|
||||
cs->cooked_sector_size = 2336; // no error bytes at end
|
||||
cs->header_size = 16;
|
||||
} else if (!strcmp("MODE1/2048", field)) { // pure data CD-ROM
|
||||
curr->tcf = DATA;
|
||||
cs->raw_sector_size = 2048;
|
||||
cs->cooked_sector_size = 2048;
|
||||
cs->header_size = 0; // no header or error bytes
|
||||
} else if (!strcmp("AUDIO", field)) {
|
||||
curr->tcf = AUDIO;
|
||||
} else {
|
||||
|
@ -342,8 +387,18 @@ static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile)
|
|||
}
|
||||
curr->pregap = MSFToFrames(msf);
|
||||
|
||||
} else if (!strcmp("POSTGAP", keyword)) {
|
||||
MSF msf;
|
||||
char *field = strtok(NULL, " \t\n\r");
|
||||
if (3 != sscanf(field, "%d:%d:%d",
|
||||
&msf.m, &msf.s, &msf.f)) {
|
||||
D(bug("Expected postgap frame\n"));
|
||||
goto fail;
|
||||
}
|
||||
curr->postgap = MSFToFrames(msf);
|
||||
|
||||
// Ignored directives
|
||||
|
||||
|
||||
} else if (!strcmp("TITLE", keyword)) {
|
||||
} else if (!strcmp("PERFORMER", keyword)) {
|
||||
} else if (!strcmp("REM", keyword)) {
|
||||
|
@ -377,8 +432,12 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs)
|
|||
if (!ParseCueSheet(fh, cs, cuefile)) goto fail;
|
||||
|
||||
// Open bin file and find length
|
||||
|
||||
if ((binfh = open(cs->binfile,O_RDONLY)) < 0) {
|
||||
#ifdef WIN32
|
||||
binfh = open(cs->binfile,O_RDONLY|O_BINARY);
|
||||
#else
|
||||
binfh = open(cs->binfile,O_RDONLY);
|
||||
#endif
|
||||
if (binfh < 0) {
|
||||
D(bug("Can't read bin file %s\n", cs->binfile));
|
||||
goto fail;
|
||||
}
|
||||
|
@ -392,7 +451,7 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs)
|
|||
|
||||
|
||||
tlast = &cs->tracks[cs->tcnt - 1];
|
||||
tlast->length = buf.st_size/RAW_SECTOR_SIZE
|
||||
tlast->length = buf.st_size/cs->raw_sector_size
|
||||
- tlast->start + totalPregap;
|
||||
|
||||
if (tlast->length < 0) {
|
||||
|
@ -402,7 +461,7 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs)
|
|||
|
||||
// save bin file length and pointer
|
||||
|
||||
cs->length = buf.st_size/RAW_SECTOR_SIZE;
|
||||
cs->length = buf.st_size/cs->raw_sector_size;
|
||||
cs->binfh = binfh;
|
||||
|
||||
fclose(fh);
|
||||
|
@ -423,45 +482,65 @@ static bool LoadCueSheet(const char *cuefile, CueSheet *cs)
|
|||
|
||||
void *open_bincue(const char *name)
|
||||
{
|
||||
CueSheet *cs;
|
||||
|
||||
if (player.cs == NULL) {
|
||||
cs = (CueSheet *) malloc(sizeof(CueSheet));
|
||||
if (!cs) {
|
||||
D(bug("malloc failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LoadCueSheet(name, cs)) {
|
||||
player.cs = cs;
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
audio_enabled = true;
|
||||
#endif
|
||||
if (audio_enabled)
|
||||
player.audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
else
|
||||
player.audiostatus = CDROM_AUDIO_INVALID;
|
||||
player.audiofh = dup(cs->binfh);
|
||||
return cs;
|
||||
}
|
||||
else
|
||||
free(cs);
|
||||
CueSheet *cs = (CueSheet *) malloc(sizeof(CueSheet));
|
||||
if (!cs) {
|
||||
D(bug("malloc failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LoadCueSheet(name, cs)) {
|
||||
CDPlayer *player = (CDPlayer *) malloc(sizeof(CDPlayer));
|
||||
player->cs = cs;
|
||||
player->volume_left = 0;
|
||||
player->volume_right = 0;
|
||||
player->volume_mono = 0;
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
player->audio_enabled = true;
|
||||
#endif
|
||||
if (player->audio_enabled)
|
||||
player->audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
else
|
||||
player->audiostatus = CDROM_AUDIO_INVALID;
|
||||
player->audiofh = dup(cs->binfh);
|
||||
|
||||
// add to list of available CD players
|
||||
players.push_back(player);
|
||||
|
||||
return cs;
|
||||
}
|
||||
else
|
||||
free(cs);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void close_bincue(void *fh)
|
||||
{
|
||||
|
||||
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
free(cs);
|
||||
#ifdef USE_SDL_AUDIO
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define SDL_DestroyAudioStream SDL_FreeAudioStream
|
||||
#endif
|
||||
if (player->stream) // if audiostream has been opened, free it as well
|
||||
SDL_DestroyAudioStream(player->stream);
|
||||
#endif
|
||||
free(player);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* File read (cooked)
|
||||
* Data are stored in raw sectors of which only COOKED_SECTOR_SIZE
|
||||
* bytes are valid -- the remaining include 16 bytes at the beginning
|
||||
* bytes are valid -- the remaining include header bytes at the beginning
|
||||
* of each raw sector and RAW_SECTOR_SIZE - COOKED_SECTOR_SIZE - bytes
|
||||
* at the end
|
||||
* at the end for error correction
|
||||
*
|
||||
* The actual number of bytes used for header, raw, cooked, error depend
|
||||
* on mode specified in the cuesheet
|
||||
*
|
||||
* We assume that a read request can land in the middle of
|
||||
* sector. We compute the byte address of that sector (sec)
|
||||
|
@ -473,20 +552,20 @@ void close_bincue(void *fh)
|
|||
|
||||
size_t read_bincue(void *fh, void *b, loff_t offset, size_t len)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
|
||||
size_t bytes_read = 0; // bytes read so far
|
||||
unsigned char *buf = (unsigned char *) b; // target buffer
|
||||
unsigned char secbuf[RAW_SECTOR_SIZE]; // temporary buffer
|
||||
unsigned char secbuf[cs->raw_sector_size]; // temporary buffer
|
||||
|
||||
off_t sec = ((offset/COOKED_SECTOR_SIZE) * RAW_SECTOR_SIZE);
|
||||
off_t secoff = offset % COOKED_SECTOR_SIZE;
|
||||
off_t sec = ((offset/cs->cooked_sector_size) * cs->raw_sector_size);
|
||||
off_t secoff = offset % cs->cooked_sector_size;
|
||||
|
||||
// sec contains location (in bytes) of next raw sector to read
|
||||
// secoff contains offset within that sector at which to start
|
||||
// reading since we can request a read that starts in the middle
|
||||
// of a sector
|
||||
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
|
||||
if (cs == NULL || lseek(cs->binfh, sec, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -495,19 +574,19 @@ size_t read_bincue(void *fh, void *b, loff_t offset, size_t len)
|
|||
// bytes available in next raw sector or len (bytes)
|
||||
// we want whichever is less
|
||||
|
||||
size_t available = COOKED_SECTOR_SIZE - secoff;
|
||||
size_t available = cs->cooked_sector_size - secoff;
|
||||
available = (available > len) ? len : available;
|
||||
|
||||
// read the next raw sector
|
||||
|
||||
if (read(cs->binfh, secbuf, RAW_SECTOR_SIZE) != RAW_SECTOR_SIZE) {
|
||||
if (read(cs->binfh, secbuf, cs->raw_sector_size) != cs->raw_sector_size) {
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
// copy cooked sector bytes (skip first 16)
|
||||
// copy cooked sector bytes (skip header if needed, typically 16 bytes)
|
||||
// we want out of those available
|
||||
|
||||
bcopy(&secbuf[16+secoff], &buf[bytes_read], available);
|
||||
bcopy(&secbuf[cs->header_size+secoff], &buf[bytes_read], available);
|
||||
|
||||
// next sector we start at the beginning
|
||||
|
||||
|
@ -524,7 +603,7 @@ size_t read_bincue(void *fh, void *b, loff_t offset, size_t len)
|
|||
loff_t size_bincue(void *fh)
|
||||
{
|
||||
if (fh) {
|
||||
return ((CueSheet *)fh)->length * COOKED_SECTOR_SIZE;
|
||||
return ((CueSheet *)fh)->length * ((CueSheet *)fh)->cooked_sector_size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -571,20 +650,22 @@ bool readtoc_bincue(void *fh, unsigned char *toc)
|
|||
bool GetPosition_bincue(void *fh, uint8 *pos)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs && player.cs == cs) {
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
MSF abs, rel;
|
||||
int fpos = player.audioposition / RAW_SECTOR_SIZE + player.audiostart;
|
||||
int fpos = player->audioposition / cs->raw_sector_size + player->audiostart;
|
||||
int trackno = PositionToTrack(cs, fpos);
|
||||
|
||||
if (!audio_enabled)
|
||||
if (!(player->audio_enabled))
|
||||
return false;
|
||||
|
||||
FramesToMSF(fpos, &abs);
|
||||
if (trackno < cs->tcnt) {
|
||||
// compute position relative to start of frame
|
||||
|
||||
unsigned int position = player.audioposition/RAW_SECTOR_SIZE +
|
||||
player.audiostart - player.cs->tracks[trackno].start;
|
||||
unsigned int position = player->audioposition/cs->raw_sector_size +
|
||||
player->audiostart - player->cs->tracks[trackno].start;
|
||||
|
||||
FramesToMSF(position, &rel);
|
||||
}
|
||||
|
@ -592,7 +673,7 @@ bool GetPosition_bincue(void *fh, uint8 *pos)
|
|||
FramesToMSF(0, &rel);
|
||||
|
||||
*pos++ = 0;
|
||||
*pos++ = player.audiostatus;
|
||||
*pos++ = player->audiostatus;
|
||||
*pos++ = 0;
|
||||
*pos++ = 12; // Sub-Q data length
|
||||
*pos++ = 0;
|
||||
|
@ -608,7 +689,7 @@ bool GetPosition_bincue(void *fh, uint8 *pos)
|
|||
*pos++ = rel.m;
|
||||
*pos++ = rel.s;
|
||||
*pos++ = rel.f;
|
||||
*pos++ = 0;
|
||||
// *pos++ = 0;
|
||||
// D(bug("CDROM position %02d:%02d:%02d track %02d\n", abs.m, abs.s, abs.f, trackno));
|
||||
return true;
|
||||
}
|
||||
|
@ -616,14 +697,26 @@ bool GetPosition_bincue(void *fh, uint8 *pos)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CDPause_playing(CDPlayer* player) {
|
||||
if (currently_playing && currently_playing != player) {
|
||||
currently_playing->audiostatus = CDROM_AUDIO_PAUSED;
|
||||
currently_playing = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool CDPause_bincue(void *fh)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs && cs == player.cs) {
|
||||
if (player.audiostatus == CDROM_AUDIO_PLAY) {
|
||||
player.audiostatus = CDROM_AUDIO_PAUSED;
|
||||
return true;
|
||||
}
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
// Pause another player if needed
|
||||
CDPause_playing(player);
|
||||
|
||||
// doesn't matter if it was playing, just ensure it's now paused
|
||||
player->audiostatus = CDROM_AUDIO_PAUSED;
|
||||
currently_playing = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -631,13 +724,19 @@ bool CDPause_bincue(void *fh)
|
|||
bool CDStop_bincue(void *fh)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
|
||||
if (cs && cs == player.cs) {
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
// Pause another player if needed
|
||||
CDPause_playing(player);
|
||||
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
player.soundoutput.stop();
|
||||
player->soundoutput.stop();
|
||||
#endif
|
||||
if (player.audiostatus != CDROM_AUDIO_INVALID)
|
||||
player.audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
if (player->audiostatus != CDROM_AUDIO_INVALID)
|
||||
player->audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
|
||||
currently_playing = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -646,11 +745,16 @@ bool CDStop_bincue(void *fh)
|
|||
bool CDResume_bincue(void *fh)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs && cs == player.cs) {
|
||||
if (player.audiostatus == CDROM_AUDIO_PAUSED) {
|
||||
player.audiostatus = CDROM_AUDIO_PLAY;
|
||||
return true;
|
||||
}
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
// Pause another player if needed
|
||||
CDPause_playing(player);
|
||||
|
||||
// doesn't matter if it was paused, just ensure this one plays now
|
||||
player->audiostatus = CDROM_AUDIO_PLAY;
|
||||
currently_playing = player;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -658,75 +762,130 @@ bool CDResume_bincue(void *fh)
|
|||
bool CDPlay_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f,
|
||||
uint8 end_m, uint8 end_s, uint8 end_f)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *)fh;
|
||||
if (cs && cs == player.cs) {
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
// Pause another player if needed
|
||||
CDPause_playing(player);
|
||||
|
||||
int track;
|
||||
MSF msf;
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
#if defined(USE_SDL_AUDIO) && !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_LockAudio();
|
||||
#endif
|
||||
|
||||
player.audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
player->audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
|
||||
player.audiostart = (start_m * 60 * CD_FRAMES) +
|
||||
player->audiostart = (start_m * 60 * CD_FRAMES) +
|
||||
(start_s * CD_FRAMES) + start_f;
|
||||
player.audioend = (end_m * 60 * CD_FRAMES) + (end_s * CD_FRAMES) + end_f;
|
||||
player->audioend = (end_m * 60 * CD_FRAMES) + (end_s * CD_FRAMES) + end_f;
|
||||
|
||||
track = PositionToTrack(player.cs, player.audiostart);
|
||||
track = PositionToTrack(player->cs, player->audiostart);
|
||||
|
||||
if (track < player.cs->tcnt) {
|
||||
player.audioposition = 0;
|
||||
if (track < player->cs->tcnt) {
|
||||
player->audioposition = 0;
|
||||
|
||||
// here we need to compute silence
|
||||
|
||||
if (player.audiostart - player.cs->tracks[track].start >
|
||||
player.cs->tracks[track].pregap)
|
||||
player.silence = 0;
|
||||
if (player->audiostart - player->cs->tracks[track].start >
|
||||
player->cs->tracks[track].pregap)
|
||||
player->silence = 0;
|
||||
else
|
||||
player.silence = (player.cs->tracks[track].pregap -
|
||||
player.audiostart +
|
||||
player.cs->tracks[track].start) * RAW_SECTOR_SIZE;
|
||||
player->silence = (player->cs->tracks[track].pregap -
|
||||
player->audiostart +
|
||||
player->cs->tracks[track].start) * cs->raw_sector_size;
|
||||
|
||||
player.fileoffset = player.cs->tracks[track].fileoffset;
|
||||
player->fileoffset = player->cs->tracks[track].fileoffset;
|
||||
|
||||
D(bug("file offset %d\n", (unsigned int) player.fileoffset));
|
||||
D(bug("file offset %d\n", (unsigned int) player->fileoffset));
|
||||
|
||||
// fix up file offset if beyond the silence bytes
|
||||
|
||||
if (!player.silence) // not at the beginning
|
||||
player.fileoffset += (player.audiostart -
|
||||
player.cs->tracks[track].start -
|
||||
player.cs->tracks[track].pregap) * RAW_SECTOR_SIZE;
|
||||
if (!player->silence) // not at the beginning
|
||||
player->fileoffset += (player->audiostart -
|
||||
player->cs->tracks[track].start -
|
||||
player->cs->tracks[track].pregap) * cs->raw_sector_size;
|
||||
|
||||
FramesToMSF(player.cs->tracks[track].start, &msf);
|
||||
FramesToMSF(player->cs->tracks[track].start, &msf);
|
||||
D(bug("CDPlay_bincue track %02d start %02d:%02d:%02d silence %d",
|
||||
player.cs->tracks[track].number, msf.m, msf.s, msf.f,
|
||||
player.silence/RAW_SECTOR_SIZE));
|
||||
player->cs->tracks[track].number, msf.m, msf.s, msf.f,
|
||||
player->silence/cs->raw_sector_size));
|
||||
D(bug(" Stop %02u:%02u:%02u\n", end_m, end_s, end_f));
|
||||
}
|
||||
else
|
||||
D(bug("CDPlay_bincue: play beyond last track !\n"));
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
#if defined(USE_SDL_AUDIO) && !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_UnlockAudio();
|
||||
#endif
|
||||
|
||||
if (audio_enabled) {
|
||||
player.audiostatus = CDROM_AUDIO_PLAY;
|
||||
if (player->audio_enabled) {
|
||||
player->audiostatus = CDROM_AUDIO_PLAY;
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
D(bug("starting os x sound"));
|
||||
player.soundoutput.setCallback(bincue_core_audio_callback);
|
||||
player->soundoutput.setCallback(bincue_core_audio_callback);
|
||||
// should be from current track !
|
||||
player.soundoutput.start(16, 2, 44100);
|
||||
player->soundoutput.start(16, 2, 44100);
|
||||
#endif
|
||||
currently_playing = player;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8 *fill_buffer(int stream_len)
|
||||
bool CDScan_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse) {
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
uint8 scanrate = 8; // 8x scan default but could use different value or make configurable
|
||||
|
||||
MSF msf;
|
||||
msf.m = start_m; msf.s = start_s; msf.f = start_f;
|
||||
int current_frame = MSFToFrames(msf);
|
||||
|
||||
if (reverse) {
|
||||
msf.s -= scanrate;
|
||||
int goto_frame = MSFToFrames(msf);
|
||||
player->audioposition -= (current_frame - goto_frame) * player->cs->raw_sector_size;
|
||||
}
|
||||
else {
|
||||
msf.s += scanrate;
|
||||
int goto_frame = MSFToFrames(msf);
|
||||
player->audioposition += (goto_frame - current_frame) * player->cs->raw_sector_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDSetVol_bincue(void* fh, uint8 left, uint8 right) {
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) {
|
||||
// Convert from classic Mac's 0-255 to 0-128;
|
||||
// calculate mono mix as well in place of panning
|
||||
player->volume_left = (left*128)/255;
|
||||
player->volume_right = (right*128)/255;
|
||||
player->volume_mono = (player->volume_left + player->volume_right)/2; // use avg
|
||||
}
|
||||
}
|
||||
|
||||
void CDGetVol_bincue(void* fh, uint8* left, uint8* right) {
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
CDPlayer *player = CSToPlayer(cs);
|
||||
|
||||
if (cs && player) { // Convert from 0-128 to 0-255 scale
|
||||
*left = (player->volume_left*255)/128;
|
||||
*right = (player->volume_right*255)/128;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 *fill_buffer(int stream_len, CDPlayer* player)
|
||||
{
|
||||
static uint8 *buf = 0;
|
||||
static int bufsize = 0;
|
||||
|
@ -745,44 +904,44 @@ static uint8 *fill_buffer(int stream_len)
|
|||
}
|
||||
|
||||
memset(buf, silence_byte, stream_len);
|
||||
|
||||
if (player->audiostatus == CDROM_AUDIO_PLAY) {
|
||||
int remaining_silence = player->silence - player->audioposition;
|
||||
|
||||
if (player.audiostatus == CDROM_AUDIO_PLAY) {
|
||||
int remaining_silence = player.silence - player.audioposition;
|
||||
|
||||
if (player.audiostart + player.audioposition/RAW_SECTOR_SIZE
|
||||
>= player.audioend) {
|
||||
player.audiostatus = CDROM_AUDIO_COMPLETED;
|
||||
if (player->audiostart + player->audioposition/player->cs->raw_sector_size
|
||||
>= player->audioend) {
|
||||
player->audiostatus = CDROM_AUDIO_COMPLETED;
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (remaining_silence >= stream_len) {
|
||||
player.audioposition += stream_len;
|
||||
player->audioposition += stream_len;
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (remaining_silence > 0) {
|
||||
offset += remaining_silence;
|
||||
player.audioposition += remaining_silence;
|
||||
player->audioposition += remaining_silence;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int available = ((player.audioend - player.audiostart) *
|
||||
RAW_SECTOR_SIZE) - player.audioposition;
|
||||
int available = ((player->audioend - player->audiostart) *
|
||||
player->cs->raw_sector_size) - player->audioposition;
|
||||
if (available > (stream_len - offset))
|
||||
available = stream_len - offset;
|
||||
|
||||
if (lseek(player.audiofh,
|
||||
player.fileoffset + player.audioposition - player.silence,
|
||||
if (lseek(player->audiofh,
|
||||
player->fileoffset + player->audioposition - player->silence,
|
||||
SEEK_SET) < 0)
|
||||
return NULL;
|
||||
|
||||
if (available < 0) {
|
||||
player.audioposition += available; // correct end !;
|
||||
player->audioposition += available; // correct end !;
|
||||
available = 0;
|
||||
}
|
||||
|
||||
if ((ret = read(player.audiofh, &buf[offset], available)) >= 0) {
|
||||
player.audioposition += ret;
|
||||
ssize_t ret = 0;
|
||||
if ((ret = read(player->audiofh, &buf[offset], available)) >= 0) {
|
||||
player->audioposition += ret;
|
||||
offset += ret;
|
||||
available -= ret;
|
||||
}
|
||||
|
@ -790,33 +949,73 @@ static uint8 *fill_buffer(int stream_len)
|
|||
while (offset < stream_len) {
|
||||
buf[offset++] = silence_byte;
|
||||
if (available-- > 0){
|
||||
player.audioposition++;
|
||||
player->audioposition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
void MixAudio_bincue(uint8 *stream, int stream_len)
|
||||
void MixAudio_bincue(uint8 *stream, int stream_len, int volume)
|
||||
{
|
||||
if (audio_enabled && (player.audiostatus == CDROM_AUDIO_PLAY)) {
|
||||
uint8 *buf = fill_buffer(stream_len);
|
||||
if (buf)
|
||||
SDL_MixAudio(stream, buf, stream_len, SDL_MIX_MAXVOLUME);
|
||||
if (currently_playing) {
|
||||
|
||||
CDPlayer *player = currently_playing;
|
||||
|
||||
if (player->audiostatus == CDROM_AUDIO_PLAY) {
|
||||
uint8 *buf = fill_buffer(stream_len, player);
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
if (buf)
|
||||
SDL_PutAudioStreamData(player->stream, buf, stream_len);
|
||||
int avail = SDL_GetAudioStreamAvailable(player->stream);
|
||||
if (avail >= stream_len) {
|
||||
extern SDL_AudioSpec audio_spec;
|
||||
uint8 converted[stream_len];
|
||||
SDL_GetAudioStreamData(player->stream, converted, stream_len);
|
||||
SDL_MixAudioFormat(stream, converted, audio_spec.format, stream_len, player->volume_mono);
|
||||
}
|
||||
#else
|
||||
if (buf)
|
||||
SDL_AudioStreamPut(player->stream, buf, stream_len);
|
||||
int avail = SDL_AudioStreamAvailable(player->stream);
|
||||
if (avail >= stream_len) {
|
||||
uint8 converted[stream_len];
|
||||
SDL_AudioStreamGet(player->stream, converted, stream_len);
|
||||
SDL_MixAudio(stream, converted, stream_len, player->volume_mono);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void OpenAudio_bincue(int freq, int format, int channels, uint8 silence)
|
||||
void OpenAudio_bincue(int freq, int format, int channels, uint8 silence, int volume)
|
||||
{
|
||||
if (freq == 44100 && format == AUDIO_S16MSB && channels == 2) {
|
||||
audio_enabled = true;
|
||||
silence_byte = silence;
|
||||
}
|
||||
else {
|
||||
D(bug("unexpected frequency %d , format %d, or channels %d\n",
|
||||
freq, format, channels));
|
||||
// setup silence at init
|
||||
silence_byte = silence;
|
||||
|
||||
// init players
|
||||
for (std::vector<CDPlayer*>::iterator it = players.begin(); it != players.end(); ++it)
|
||||
{
|
||||
CDPlayer *player = *it;
|
||||
|
||||
// set player volume based on SDL volume
|
||||
player->volume_left = player->volume_right = player->volume_mono = volume;
|
||||
// audio stream handles converting cd audio to destination output
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_AudioSpec src = { SDL_AUDIO_S16LE, 2, 44100 }, dst = { (SDL_AudioFormat)format, channels, freq };
|
||||
player->stream = SDL_CreateAudioStream(&src, &dst);
|
||||
#else
|
||||
player->stream = SDL_NewAudioStream(AUDIO_S16LSB, 2, 44100, format, channels, freq);
|
||||
#endif
|
||||
if (player->stream == NULL) {
|
||||
D(bug("Failed to open CD player audio stream using SDL!"));
|
||||
}
|
||||
else {
|
||||
player->audio_enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -824,13 +1023,18 @@ void OpenAudio_bincue(int freq, int format, int channels, uint8 silence)
|
|||
#ifdef OSX_CORE_AUDIO
|
||||
static int bincue_core_audio_callback(void)
|
||||
{
|
||||
int frames = player.soundoutput.bufferSizeFrames();
|
||||
uint8 *buf = fill_buffer(frames*4);
|
||||
for (std::vector<CDPlayer*>::iterator it = players.begin(); it != players.end(); ++it)
|
||||
{
|
||||
CDPlayer *player = *it;
|
||||
|
||||
int frames = player->soundoutput.bufferSizeFrames();
|
||||
uint8 *buf = fill_buffer(frames*4);
|
||||
|
||||
// D(bug("Audio request %d\n", stream_len));
|
||||
// D(bug("Audio request %d\n", stream_len));
|
||||
|
||||
player.soundoutput.sendAudioBuffer((void *) buf, (buf ? frames : 0));
|
||||
player->soundoutput.sendAudioBuffer((void *) buf, (buf ? frames : 0));
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#ifndef NO_STD_NAMESPACE
|
||||
using std::vector;
|
||||
|
@ -58,7 +59,7 @@ const uint8 CDROMIcon[258] = {
|
|||
0x8a, 0xaa, 0xaa, 0xe4, 0x8d, 0x55, 0x55, 0xc4, 0x86, 0xaa, 0xab, 0xc4, 0x83, 0x55, 0x57, 0x84,
|
||||
0x81, 0xaa, 0xaf, 0x04, 0x80, 0xf5, 0x7e, 0x04, 0x80, 0x3f, 0xf8, 0x04, 0x80, 0x0f, 0xe0, 0x04,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x80, 0x00, 0x00, 0x04, 0x80, 0x1f, 0xf0, 0x04, 0x7f, 0xff, 0xff, 0xf8,
|
||||
|
||||
|
||||
0x3f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc,
|
||||
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc,
|
||||
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc,
|
||||
|
@ -67,7 +68,7 @@ const uint8 CDROMIcon[258] = {
|
|||
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc,
|
||||
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc,
|
||||
0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xf8,
|
||||
|
||||
|
||||
0, 0
|
||||
};
|
||||
|
||||
|
@ -103,7 +104,7 @@ static const uint8 bin2bcd[256] = {
|
|||
};
|
||||
|
||||
static const uint8 bcd2bin[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
|
@ -124,11 +125,11 @@ static const uint8 bcd2bin[256] = {
|
|||
|
||||
// Struct for each drive
|
||||
struct cdrom_drive_info {
|
||||
cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0) {}
|
||||
cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0) {}
|
||||
|
||||
cdrom_drive_info() : num(0), fh(NULL), start_byte(0), status(0), drop(false) {}
|
||||
cdrom_drive_info(void *fh_) : num(0), fh(fh_), start_byte(0), status(0), drop(false) {}
|
||||
|
||||
void close_fh(void) { SysAllowRemoval(fh); Sys_close(fh); }
|
||||
|
||||
|
||||
int num; // Drive number
|
||||
void *fh; // File handle
|
||||
int block_size; // CD-ROM block size
|
||||
|
@ -136,26 +137,33 @@ struct cdrom_drive_info {
|
|||
loff_t start_byte; // Start of HFS partition on disk
|
||||
bool to_be_mounted; // Flag: drive must be mounted in accRun
|
||||
bool mount_non_hfs; // Flag: Issue disk-inserted events for non-HFS disks
|
||||
|
||||
|
||||
uint8 toc[804]; // TOC of currently inserted disk
|
||||
uint8 lead_out[3]; // MSF address of lead-out track
|
||||
uint8 stop_at[3]; // MSF address of audio play stopping point
|
||||
|
||||
uint8 start_at[3]; // MSF address of position set by track search or audio play
|
||||
|
||||
uint8 play_mode; // Audio play mode
|
||||
uint8 play_order; // Play mode order (normal, shuffle, program)
|
||||
bool repeat; // Repeat flag
|
||||
uint8 power_mode; // Power mode
|
||||
uint32 status; // Mac address of drive status record
|
||||
bool drop;
|
||||
};
|
||||
|
||||
// List of drives handled by this driver
|
||||
typedef vector<cdrom_drive_info> drive_vec;
|
||||
static drive_vec drives;
|
||||
|
||||
int last_drive_num; // track last drive called to support multiple audio CDs
|
||||
|
||||
// Icon address (Mac address space, set by PatchROM())
|
||||
uint32 CDROMIconAddr;
|
||||
|
||||
// Flag: Control(accRun) has been called, interrupt routine is now active
|
||||
static bool acc_run_called = false;
|
||||
|
||||
static std::map<int, void *> remount_map;
|
||||
|
||||
/*
|
||||
* Get pointer to drive info or drives.end() if not found
|
||||
|
@ -165,8 +173,10 @@ static drive_vec::iterator get_drive_info(int num)
|
|||
{
|
||||
drive_vec::iterator info, end = drives.end();
|
||||
for (info = drives.begin(); info != end; ++info) {
|
||||
if (info->num == num)
|
||||
if (info->num == num) {
|
||||
last_drive_num = num;
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
@ -181,23 +191,25 @@ static void find_hfs_partition(cdrom_drive_info &info)
|
|||
info.start_byte = 0;
|
||||
uint8 *map = new uint8[512];
|
||||
D(bug("Looking for HFS partitions on CD-ROM...\n"));
|
||||
|
||||
|
||||
// Search first 64 blocks for HFS partition
|
||||
for (int i=0; i<64; i++) {
|
||||
if (Sys_read(info.fh, map, i * 512, 512) != 512)
|
||||
break;
|
||||
D(bug(" block %d, signature '%c%c' (%02x%02x)\n", i, map[0], map[1], map[0], map[1]));
|
||||
|
||||
|
||||
// Not a partition map block? Then look at next block
|
||||
uint16 sig = (map[0] << 8) | map[1];
|
||||
if (sig != 0x504d)
|
||||
continue;
|
||||
|
||||
|
||||
// Partition map block found, Apple HFS partition?
|
||||
if (strcmp((char *)(map + 48), "Apple_HFS") == 0) {
|
||||
info.start_byte = (loff_t)((map[8] << 24) | (map[9] << 16) | (map[10] << 8) | map[11]) << 9;
|
||||
#if DEBUG
|
||||
uint32 num_blocks = (map[12] << 24) | (map[13] << 16) | (map[14] << 8) | map[15];
|
||||
D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, num_blocks));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +226,7 @@ static void read_toc(cdrom_drive_info &info)
|
|||
// Read TOC
|
||||
memset(info.toc, 0, sizeof(info.toc));
|
||||
SysCDReadTOC(info.fh, info.toc);
|
||||
|
||||
|
||||
#if DEBUG
|
||||
// Dump TOC for debugging
|
||||
D(bug(" TOC:\n %02x%02x%02x%02x : %d bytes, first track = %d, last track = %d\n", info.toc[0], info.toc[1], info.toc[2], info.toc[3], (info.toc[0] << 8) | info.toc[1], info.toc[2], info.toc[3]));
|
||||
|
@ -226,7 +238,12 @@ static void read_toc(cdrom_drive_info &info)
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Default start
|
||||
info.start_at[0] = 0;
|
||||
info.start_at[1] = 0;
|
||||
info.start_at[2] = 0;
|
||||
|
||||
// Find lead-out track
|
||||
info.lead_out[0] = 0;
|
||||
info.lead_out[1] = 0;
|
||||
|
@ -287,20 +304,35 @@ static bool position2msf(const cdrom_drive_info &info, uint16 postype, uint32 po
|
|||
|
||||
void CDROMInit(void)
|
||||
{
|
||||
// No drives specified in prefs? Then add defaults
|
||||
if (PrefsFindString("cdrom", 0) == NULL)
|
||||
SysAddCDROMPrefs();
|
||||
|
||||
SysAddCDROMPrefs();
|
||||
|
||||
// Add drives specified in preferences
|
||||
int index = 0;
|
||||
const char *str;
|
||||
while ((str = PrefsFindString("cdrom", index++)) != NULL) {
|
||||
void *fh = Sys_open(str, true);
|
||||
void *fh = Sys_open(str, true, true);
|
||||
if (fh)
|
||||
drives.push_back(cdrom_drive_info(fh));
|
||||
}
|
||||
|
||||
if (!drives.empty()) { // set to first drive by default
|
||||
last_drive_num = drives.begin()->num;
|
||||
}
|
||||
else {
|
||||
last_drive_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CDROMDrop(const char *path) {
|
||||
if (!drives.empty()) {
|
||||
cdrom_drive_info &info = drives.back();
|
||||
if (!info.drop) {
|
||||
info.fh = Sys_open(path, true, true);
|
||||
if (info.fh)
|
||||
info.drop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
|
@ -338,6 +370,17 @@ bool CDROMMountVolume(void *fh)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CDROMRemount() {
|
||||
for (std::map<int, void *>::iterator i = remount_map.begin(); i != remount_map.end(); ++i)
|
||||
for (drive_vec::iterator info = drives.begin(); info != drives.end(); ++info)
|
||||
if (info->num == i->first) {
|
||||
last_drive_num = i->first;
|
||||
info->fh = i->second;
|
||||
break;
|
||||
}
|
||||
remount_map.clear();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mount volumes for which the to_be_mounted flag is set
|
||||
|
@ -348,15 +391,15 @@ static void mount_mountable_volumes(void)
|
|||
{
|
||||
drive_vec::iterator info, end = drives.end();
|
||||
for (info = drives.begin(); info != end; ++info) {
|
||||
|
||||
|
||||
// Disk in drive?
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
|
||||
|
||||
|
||||
// No, check if disk was inserted
|
||||
if (SysIsDiskInserted(info->fh))
|
||||
CDROMMountVolume(info->fh);
|
||||
}
|
||||
|
||||
|
||||
// Mount disk if flagged
|
||||
if (info->to_be_mounted) {
|
||||
D(bug(" mounting drive %d\n", info->num));
|
||||
|
@ -377,25 +420,27 @@ static void mount_mountable_volumes(void)
|
|||
int16 CDROMOpen(uint32 pb, uint32 dce)
|
||||
{
|
||||
D(bug("CDROMOpen\n"));
|
||||
|
||||
|
||||
// Set up DCE
|
||||
WriteMacInt32(dce + dCtlPosition, 0);
|
||||
acc_run_called = false;
|
||||
|
||||
|
||||
// Install drives
|
||||
drive_vec::iterator info, end = drives.end();
|
||||
for (info = drives.begin(); info != end; ++info) {
|
||||
|
||||
|
||||
info->num = FindFreeDriveNumber(1);
|
||||
info->to_be_mounted = false;
|
||||
|
||||
|
||||
if (info->fh) {
|
||||
info->mount_non_hfs = true;
|
||||
info->block_size = 512;
|
||||
info->twok_offset = -1;
|
||||
info->play_mode = 0x09;
|
||||
info->play_order = 0;
|
||||
info->repeat = 0;
|
||||
info->power_mode = 0;
|
||||
|
||||
|
||||
// Allocate drive status record
|
||||
M68kRegisters r;
|
||||
r.d[0] = SIZEOF_DrvSts;
|
||||
|
@ -404,12 +449,12 @@ int16 CDROMOpen(uint32 pb, uint32 dce)
|
|||
continue;
|
||||
info->status = r.a[0];
|
||||
D(bug(" DrvSts at %08lx\n", info->status));
|
||||
|
||||
|
||||
// Set up drive status
|
||||
WriteMacInt8(info->status + dsWriteProt, 0x80);
|
||||
WriteMacInt8(info->status + dsInstalled, 1);
|
||||
WriteMacInt8(info->status + dsSides, 1);
|
||||
|
||||
|
||||
// Disk in drive?
|
||||
if (SysIsDiskInserted(info->fh)) {
|
||||
SysPreventRemoval(info->fh);
|
||||
|
@ -418,7 +463,7 @@ int16 CDROMOpen(uint32 pb, uint32 dce)
|
|||
find_hfs_partition(*info);
|
||||
info->to_be_mounted = true;
|
||||
}
|
||||
|
||||
|
||||
// Add drive to drive queue
|
||||
D(bug(" adding drive %d\n", info->num));
|
||||
r.d[0] = (info->num << 16) | (CDROMRefNum & 0xffff);
|
||||
|
@ -426,6 +471,9 @@ int16 CDROMOpen(uint32 pb, uint32 dce)
|
|||
Execute68kTrap(0xa04e, &r); // AddDrive()
|
||||
}
|
||||
}
|
||||
|
||||
CDROMOpenDone();
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
@ -437,14 +485,14 @@ int16 CDROMOpen(uint32 pb, uint32 dce)
|
|||
int16 CDROMPrime(uint32 pb, uint32 dce)
|
||||
{
|
||||
WriteMacInt32(pb + ioActCount, 0);
|
||||
|
||||
|
||||
// Drive valid and disk inserted?
|
||||
drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
|
||||
if (info == drives.end())
|
||||
return nsDrvErr;
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
|
||||
// Get parameters
|
||||
void *buffer = Mac2HostAddr(ReadMacInt32(pb + ioBuffer));
|
||||
size_t length = ReadMacInt32(pb + ioReqCount);
|
||||
|
@ -452,17 +500,17 @@ int16 CDROMPrime(uint32 pb, uint32 dce)
|
|||
if ((length & (info->block_size - 1)) || (position & (info->block_size - 1)))
|
||||
return paramErr;
|
||||
info->twok_offset = (position + info->start_byte) & 0x7ff;
|
||||
|
||||
|
||||
size_t actual = 0;
|
||||
if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) {
|
||||
|
||||
|
||||
// Read
|
||||
actual = Sys_read(info->fh, buffer, position + info->start_byte, length);
|
||||
if (actual != length) {
|
||||
|
||||
|
||||
// Read error, tried to read HFS root block?
|
||||
if (length == 0x200 && position == 0x400) {
|
||||
|
||||
|
||||
// Yes, fake (otherwise audio CDs won't get mounted)
|
||||
memset(buffer, 0, 0x200);
|
||||
actual = 0x200;
|
||||
|
@ -473,7 +521,7 @@ int16 CDROMPrime(uint32 pb, uint32 dce)
|
|||
} else {
|
||||
return wPrErr;
|
||||
}
|
||||
|
||||
|
||||
// Update ParamBlock and DCE
|
||||
WriteMacInt32(pb + ioActCount, actual);
|
||||
WriteMacInt32(dce + dCtlPosition, ReadMacInt32(dce + dCtlPosition) + actual);
|
||||
|
@ -489,34 +537,37 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
{
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
D(bug("CDROMControl %d\n", code));
|
||||
|
||||
|
||||
// General codes
|
||||
switch (code) {
|
||||
case 1: // KillIO
|
||||
return noErr;
|
||||
|
||||
|
||||
case 65: { // Periodic action (accRun, "insert" disks on startup)
|
||||
mount_mountable_volumes();
|
||||
WriteMacInt16(dce + dCtlFlags, ReadMacInt16(dce + dCtlFlags) & ~0x2000); // Disable periodic action
|
||||
acc_run_called = true;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
case 81: // Set poll freq
|
||||
WriteMacInt16(dce + dCtlDelay, ReadMacInt16(pb + csParam));
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
// Drive valid?
|
||||
drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
|
||||
if (info == drives.end()) {
|
||||
if (drives.empty()) {
|
||||
return nsDrvErr;
|
||||
} else {
|
||||
info = drives.begin(); // This is needed for Apple's Audio CD program
|
||||
// Audio calls tend to end up without correct reference
|
||||
// Real mac would just play first disc, but we can guess correct one from last data call
|
||||
info = get_drive_info(last_drive_num);
|
||||
if (info == drives.end()) return nsDrvErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Drive-specific codes
|
||||
switch (code) {
|
||||
case 5: // VerifyTheDisc
|
||||
|
@ -524,28 +575,60 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
return noErr;
|
||||
else
|
||||
return offLinErr;
|
||||
|
||||
|
||||
case 6: // FormatTheDisc
|
||||
return writErr;
|
||||
|
||||
|
||||
case 7: // EjectTheDisc
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
|
||||
SysAllowRemoval(info->fh);
|
||||
SysEject(info->fh);
|
||||
if (info->drop) {
|
||||
SysAllowRemoval(info->fh);
|
||||
SysEject(info->fh);
|
||||
info->twok_offset = -1;
|
||||
info->close_fh();
|
||||
info->drop = false;
|
||||
}
|
||||
else remount_map.insert(std::make_pair(ReadMacInt16(pb + ioVRefNum), info->fh));
|
||||
info->fh = NULL;
|
||||
WriteMacInt8(info->status + dsDiskInPlace, 0);
|
||||
info->twok_offset = -1;
|
||||
return noErr;
|
||||
} else {
|
||||
return offLinErr;
|
||||
}
|
||||
return noErr;
|
||||
|
||||
|
||||
case 21: // GetDriveIcon
|
||||
case 22: // GetMediaIcon
|
||||
WriteMacInt32(pb + csParam, CDROMIconAddr);
|
||||
return noErr;
|
||||
|
||||
|
||||
case 23: // GetDriveInfo
|
||||
WriteMacInt32(pb + csParam, 0x00000b01); // Unspecified external removable SCSI disk
|
||||
return noErr;
|
||||
|
||||
|
||||
// TODO: revist this section, is it necessary with DriverGestalt also in Status section?
|
||||
case 43: { // DriverGestalt
|
||||
int selector = ReadMacInt32(pb + csParam);
|
||||
switch (selector) {
|
||||
case FOURCC('v','e','r','s'):
|
||||
WriteMacInt32(pb + csParam + 4, 0x05208000); // vers 5.2.0
|
||||
break;
|
||||
case FOURCC('d','e','v','t'):
|
||||
WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m'));
|
||||
break;
|
||||
case FOURCC('i','n','t','f'):
|
||||
case FOURCC('d','A','P','I'):
|
||||
WriteMacInt32(pb + csParam + 4, FOURCC('a','t','p','i'));
|
||||
break;
|
||||
case FOURCC('s','y','n','c'):
|
||||
WriteMacInt32(pb + csParam + 4, 1); // true/false = sync/async
|
||||
break;
|
||||
case FOURCC('c','d','3','d'):
|
||||
WriteMacInt32(pb + csParam + 4, 0);
|
||||
break;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case 70: { // SetPowerMode
|
||||
uint8 mode = ReadMacInt8(pb + csParam);
|
||||
if (mode > 3) {
|
||||
|
@ -555,11 +638,11 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
return noErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case 76: // ModifyPostEvent
|
||||
info->mount_non_hfs = ReadMacInt16(pb + csParam) != 0;
|
||||
return noErr;
|
||||
|
||||
|
||||
case 79: { // Change block size
|
||||
uint16 size = ReadMacInt16(pb + csParam);
|
||||
D(bug(" change block size to %d bytes\n", size));
|
||||
|
@ -570,7 +653,7 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
return noErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case 80: // SetUserEject
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
|
||||
if (ReadMacInt16(pb + csParam) == 1)
|
||||
|
@ -581,11 +664,11 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
} else {
|
||||
return offLinErr;
|
||||
}
|
||||
|
||||
|
||||
case 100: { // ReadTOC
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
|
||||
int action = ReadMacInt16(pb + csParam);
|
||||
D(bug(" read TOC %d\n", action));
|
||||
switch (action) {
|
||||
|
@ -594,26 +677,26 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
WriteMacInt8(pb + csParam + 1, bin2bcd[info->toc[3]]);
|
||||
WriteMacInt16(pb + csParam + 2, 0);
|
||||
break;
|
||||
|
||||
|
||||
case 2: // Get lead out MSF starting address
|
||||
WriteMacInt8(pb + csParam, bin2bcd[info->lead_out[0]]);
|
||||
WriteMacInt8(pb + csParam + 1, bin2bcd[info->lead_out[1]]);
|
||||
WriteMacInt8(pb + csParam + 2, bin2bcd[info->lead_out[2]]);
|
||||
WriteMacInt8(pb + csParam + 3, 0);
|
||||
break;
|
||||
|
||||
|
||||
case 3: { // Get track starting address
|
||||
uint32 buf = ReadMacInt32(pb + csParam + 2);
|
||||
uint16 buf_size = ReadMacInt16(pb + csParam + 6);
|
||||
int track = bcd2bin[ReadMacInt8(pb + csParam + 8)];
|
||||
|
||||
|
||||
// Search start track in TOC
|
||||
int i;
|
||||
for (i=4; i<804; i+=8) {
|
||||
if (info->toc[i+2] == track)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Fill buffer
|
||||
if (i != 804) {
|
||||
while (buf_size > 0) {
|
||||
|
@ -621,18 +704,91 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++; // M
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++; // S
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++; // F
|
||||
|
||||
|
||||
// Lead-Out? Then stop
|
||||
if (info->toc[i+2] == 0xaa)
|
||||
break;
|
||||
|
||||
|
||||
buf_size -= 4;
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 4: { // Type 4 TOC for non-AppleCD SC
|
||||
uint32 buf = ReadMacInt32(pb + csParam + 2);
|
||||
uint16 buf_size = 512; // buffer must be 512 bytes for this TOC type
|
||||
|
||||
// start filling buffer
|
||||
WriteMacInt8(buf, 0); buf++; // first byte reserved for 0
|
||||
buf_size--;
|
||||
|
||||
int i = 4;
|
||||
// in TOC, first 4 are session and/or track number; so tracks start at i = 4
|
||||
// (info->toc[2] is first track num and info->toc[3] is last num)
|
||||
// each track entry is 8 bytes:
|
||||
// 0: unused, 1: control, 2: tracknum, 3: unused
|
||||
// 4: unused, 5: MIN, 6: SEC, 7: FRAME
|
||||
|
||||
// entry for point A0 (first track num)
|
||||
WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++; // control field
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[2]]); buf++; // track number
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++; // PMIN
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++; // PSEC
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++; // PFRAME
|
||||
buf_size -= 5; // every 8 bits written decreases byte buffer size by 1
|
||||
|
||||
// entry for point A1 (last track)
|
||||
int buf_a1 = buf; // save for filling last track num
|
||||
buf += 5; buf_size -= 5;
|
||||
|
||||
// entry for point A2 (address of start of lead out)
|
||||
int buf_a2 = buf; // save for filling at end
|
||||
buf += 5; buf_size -= 5;
|
||||
|
||||
// Fill buffer
|
||||
while (i <= 804 && buf_size > 1) { // index 511 never used
|
||||
// Lead out? then fill a2 and stop
|
||||
if (info->toc[i+2] == 0xaa) {
|
||||
// entry for point a2
|
||||
WriteMacInt8(buf_a2, info->toc[i+1] & 0x0f); // Control
|
||||
WriteMacInt8(buf_a2 + 1, bin2bcd[info->toc[i+2]]); // tracknum
|
||||
WriteMacInt8(buf_a2 + 2, bin2bcd[info->lead_out[0]]); // M, same as toc[i+5]
|
||||
WriteMacInt8(buf_a2 + 3, bin2bcd[info->lead_out[1]]); // S
|
||||
WriteMacInt8(buf_a2 + 4, bin2bcd[info->lead_out[2]]); // F
|
||||
break;
|
||||
}
|
||||
|
||||
WriteMacInt8(buf, info->toc[i+1] & 0x0f); buf++; // Control
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+2]]); buf++; // tracknum
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+5]]); buf++; // M
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+6]]); buf++; // S
|
||||
WriteMacInt8(buf, bin2bcd[info->toc[i+7]]); buf++; // F
|
||||
|
||||
// Last track? fill a1 as well
|
||||
if (info->toc[i+2] == info->toc[3]) {
|
||||
// entry for point a1
|
||||
WriteMacInt8(buf_a1, info->toc[i+1] & 0x0f); // Control
|
||||
WriteMacInt8(buf_a1 + 1, bin2bcd[info->toc[3]]); // tracknum
|
||||
WriteMacInt8(buf_a1 + 2, bin2bcd[info->toc[i+5]]); // M
|
||||
WriteMacInt8(buf_a1 + 3, bin2bcd[info->toc[i+6]]); // S
|
||||
WriteMacInt8(buf_a1 + 4, bin2bcd[info->toc[i+7]]); // F
|
||||
}
|
||||
|
||||
buf_size -= 5;
|
||||
i += 8;
|
||||
}
|
||||
|
||||
// fill rest of buffer with zeroes
|
||||
while (buf_size > 0) {
|
||||
WriteMacInt8(buf, 0); buf++;
|
||||
buf_size--;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: // Get session information
|
||||
WriteMacInt16(pb + csParam, 1); // First session number
|
||||
WriteMacInt16(pb + csParam + 2, 1); // Last session number
|
||||
|
@ -642,20 +798,20 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
WriteMacInt8(pb + csParam + 8, bin2bcd[info->toc[10]]); // S
|
||||
WriteMacInt8(pb + csParam + 9, bin2bcd[info->toc[11]]); // F
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("FATAL: .AppleCD/Control(100): unimplemented TOC type\n");
|
||||
return paramErr;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
case 101: { // ReadTheQSubcode
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0) {
|
||||
Mac_memset(pb + csParam, 0, 10);
|
||||
return offLinErr;
|
||||
}
|
||||
|
||||
|
||||
uint8 pos[16];
|
||||
if (SysCDGetPosition(info->fh, pos)) {
|
||||
uint32 p = pb + csParam;
|
||||
|
@ -674,51 +830,51 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
return ioErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case 102: // ReadHeader
|
||||
printf("FATAL: .AppleCD/Control(102): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 103: { // AudioTrackSearch
|
||||
D(bug(" AudioTrackSearch postype %d, pos %08x, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
uint8 start_m, start_s, start_f;
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
|
||||
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, info->start_at[0], info->start_at[1], info->start_at[2]))
|
||||
return paramErr;
|
||||
info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
|
||||
if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
|
||||
if (!SysCDPlay(info->fh, info->start_at[0], info->start_at[1], info->start_at[2], info->stop_at[0], info->stop_at[1], info->stop_at[2]))
|
||||
return paramErr;
|
||||
if (ReadMacInt16(pb + csParam + 6) == 0) // Hold
|
||||
SysCDPause(info->fh);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
case 104: // AudioPlay
|
||||
D(bug(" AudioPlay postype %d, pos %08lx, hold %d\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), ReadMacInt16(pb + csParam + 6)));
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
|
||||
|
||||
if (ReadMacInt16(pb + csParam + 6)) {
|
||||
// Given stopping address
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), true, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
|
||||
return paramErr;
|
||||
} else {
|
||||
// Given starting address
|
||||
uint8 start_m, start_s, start_f;
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
|
||||
return paramErr;
|
||||
info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
|
||||
if (!SysCDPlay(info->fh, start_m, start_s, start_f, info->stop_at[0], info->stop_at[1], info->stop_at[2]))
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, info->start_at[0], info->start_at[1], info->start_at[2]))
|
||||
return paramErr;
|
||||
}
|
||||
// Still need to process the AudioPlay command
|
||||
info->play_mode = ReadMacInt8(pb + csParam + 9) & 0x0f;
|
||||
if (!SysCDPlay(info->fh, info->start_at[0], info->start_at[1], info->start_at[2], info->stop_at[0], info->stop_at[1], info->stop_at[2]))
|
||||
return paramErr;
|
||||
return noErr;
|
||||
|
||||
|
||||
case 105: // AudioPause
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
|
||||
switch (ReadMacInt32(pb + csParam)) {
|
||||
case 0:
|
||||
if (!SysCDResume(info->fh))
|
||||
|
@ -732,12 +888,12 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
return paramErr;
|
||||
}
|
||||
return noErr;
|
||||
|
||||
|
||||
case 106: // AudioStop
|
||||
D(bug(" AudioStop postype %d, pos %08lx\n", ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2)));
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
|
||||
if (ReadMacInt16(pb + csParam) == 0 && ReadMacInt32(pb + csParam + 2) == 0) {
|
||||
// Stop immediately
|
||||
if (!SysCDStop(info->fh, info->lead_out[0], info->lead_out[1], info->lead_out[2]))
|
||||
|
@ -748,15 +904,15 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
return paramErr;
|
||||
}
|
||||
return noErr;
|
||||
|
||||
|
||||
case 107: { // AudioStatus
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
|
||||
uint8 pos[16];
|
||||
if (!SysCDGetPosition(info->fh, pos))
|
||||
return paramErr;
|
||||
|
||||
|
||||
uint32 p = pb + csParam;
|
||||
switch (pos[1]) {
|
||||
case 0x11:
|
||||
|
@ -783,34 +939,33 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
WriteMacInt8(p, bin2bcd[pos[11]]); p++; // F (abs)
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
case 108: { // AudioScan
|
||||
if (ReadMacInt8(info->status + dsDiskInPlace) == 0)
|
||||
return offLinErr;
|
||||
|
||||
uint8 start_m, start_s, start_f;
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, start_m, start_s, start_f))
|
||||
|
||||
if (!position2msf(*info, ReadMacInt16(pb + csParam), ReadMacInt32(pb + csParam + 2), false, info->start_at[0], info->start_at[1], info->start_at[2]))
|
||||
return paramErr;
|
||||
|
||||
if (!SysCDScan(info->fh, start_m, start_s, start_f, ReadMacInt16(pb + csParam + 6) != 0)) {
|
||||
|
||||
if (!SysCDScan(info->fh, info->start_at[0], info->start_at[1], info->start_at[2], ReadMacInt16(pb + csParam + 6) != 0)) {
|
||||
return paramErr;
|
||||
} else {
|
||||
return noErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case 109: // AudioControl
|
||||
SysCDSetVolume(info->fh, ReadMacInt8(pb + csParam), ReadMacInt8(pb + csParam + 1));
|
||||
return noErr;
|
||||
|
||||
|
||||
case 110: // ReadMCN
|
||||
printf("FATAL: .AppleCD/Control(110): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 111: // ReadISRC
|
||||
printf("FATAL: .AppleCD/Control(111): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 112: { // ReadAudioVolume
|
||||
uint8 left = 0, right = 0;
|
||||
SysCDGetVolume(info->fh, left, right);
|
||||
|
@ -818,43 +973,50 @@ int16 CDROMControl(uint32 pb, uint32 dce)
|
|||
WriteMacInt8(pb + csParam + 1, right);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
case 113: // GetSpindleSpeed
|
||||
WriteMacInt16(pb + csParam, 0xff);
|
||||
return noErr;
|
||||
|
||||
|
||||
case 114: // SetSpindleSpeed
|
||||
return noErr;
|
||||
|
||||
|
||||
case 115: // ReadAudio
|
||||
printf("FATAL: .AppleCD/Control(115): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 116: // ReadAllSubcodes
|
||||
printf("FATAL: .AppleCD/Control(116): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 122: // SetTrackList
|
||||
printf("FATAL: .AppleCD/Control(122): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 123: // GetTrackList
|
||||
printf("FATAL: .AppleCD/Control(123): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 124: // GetTrackIndex
|
||||
printf("FATAL: .AppleCD/Control(124): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
|
||||
case 125: // SetPlayMode
|
||||
D(bug(" SetPlayMode %04x\n", ReadMacInt16(pb + csParam)));
|
||||
printf("FATAL: .AppleCD/Control(125): unimplemented call\n");
|
||||
return controlErr;
|
||||
|
||||
case 126: // GetPlayMode (Apple's Audio CD program needs this)
|
||||
WriteMacInt16(pb + csParam, 0);
|
||||
// repeat flag (0 is off, 1 is on)
|
||||
info->repeat = ReadMacInt8(pb + csParam);
|
||||
// playmode (0 is normal, 1 is shuffle, 2 is program mode)
|
||||
info->play_order = ReadMacInt8(pb + csParam + 1);
|
||||
// D(bug(" SetPlayMode %04x\n", ReadMacInt16(pb + csParam)));
|
||||
// printf("FATAL: .AppleCD/Control(125): unimplemented call\n");
|
||||
return noErr;
|
||||
|
||||
|
||||
case 126: // GetPlayMode (Apple's Audio CD program needs this)
|
||||
// repeat flag
|
||||
WriteMacInt8(pb + csParam, bcd2bin[info->repeat]);
|
||||
// playmode
|
||||
WriteMacInt8(pb + csParam + 1, bcd2bin[info->play_order]);
|
||||
return noErr;
|
||||
|
||||
default:
|
||||
printf("WARNING: Unknown CDROMControl(%d)\n", code);
|
||||
return controlErr;
|
||||
|
@ -871,7 +1033,7 @@ int16 CDROMStatus(uint32 pb, uint32 dce)
|
|||
drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
D(bug("CDROMStatus %d\n", code));
|
||||
|
||||
|
||||
// General codes (we can get these even if the drive was invalid)
|
||||
switch (code) {
|
||||
case 43: { // DriverGestalt
|
||||
|
@ -885,10 +1047,12 @@ int16 CDROMStatus(uint32 pb, uint32 dce)
|
|||
WriteMacInt32(pb + csParam + 4, FOURCC('c','d','r','m'));
|
||||
break;
|
||||
case FOURCC('i','n','t','f'): // Interface type
|
||||
WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4);
|
||||
// WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4);
|
||||
WriteMacInt32(pb + csParam + 4, FOURCC('a','t','p','i'));
|
||||
break;
|
||||
case FOURCC('s','y','n','c'): // Only synchronous operation?
|
||||
WriteMacInt32(pb + csParam + 4, 0x01000000);
|
||||
// WriteMacInt32(pb + csParam + 4, 1);
|
||||
break;
|
||||
case FOURCC('b','o','o','t'): // Boot ID
|
||||
if (info != drives.end())
|
||||
|
@ -912,12 +1076,15 @@ int16 CDROMStatus(uint32 pb, uint32 dce)
|
|||
case FOURCC('v','m','o','p'): // Virtual memory attributes
|
||||
WriteMacInt32(pb + csParam + 4, 0); // Drive not available for VM
|
||||
break;
|
||||
case FOURCC('c', 'd', '3', 'd'):
|
||||
WriteMacInt16(pb + csParam + 4, 0);
|
||||
break;
|
||||
default:
|
||||
return statusErr;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
case 97: { // WhoIsThere
|
||||
uint8 drives_present = 0;
|
||||
drive_vec::iterator info, end = drives.end();
|
||||
|
@ -929,15 +1096,17 @@ int16 CDROMStatus(uint32 pb, uint32 dce)
|
|||
return noErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Drive valid?
|
||||
if (info == drives.end()) {
|
||||
if (drives.empty())
|
||||
if (drives.empty()) {
|
||||
return nsDrvErr;
|
||||
else
|
||||
info = drives.begin(); // This is needed for Apple's Audio CD program
|
||||
} else {
|
||||
info = get_drive_info(last_drive_num);
|
||||
if (info == drives.end()) return nsDrvErr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Drive-specific codes
|
||||
switch (code) {
|
||||
case 6: // Return format list
|
||||
|
@ -950,15 +1119,15 @@ int16 CDROMStatus(uint32 pb, uint32 dce)
|
|||
} else {
|
||||
return paramErr;
|
||||
}
|
||||
|
||||
|
||||
case 8: // DriveStatus
|
||||
Mac2Mac_memcpy(pb + csParam, info->status, 22);
|
||||
return noErr;
|
||||
|
||||
|
||||
case 70: // GetPowerMode
|
||||
WriteMacInt16(pb + csParam, info->power_mode << 8);
|
||||
return noErr;
|
||||
|
||||
|
||||
case 95: // Get2KOffset
|
||||
if (info->twok_offset > 0) {
|
||||
WriteMacInt16(pb + csParam, info->twok_offset);
|
||||
|
@ -966,24 +1135,24 @@ int16 CDROMStatus(uint32 pb, uint32 dce)
|
|||
} else {
|
||||
return statusErr;
|
||||
}
|
||||
|
||||
|
||||
case 96: // Get drive type
|
||||
WriteMacInt16(pb + csParam, 3); // Apple CD 300 or newer
|
||||
return noErr;
|
||||
|
||||
|
||||
case 98: // Get block size
|
||||
WriteMacInt16(pb + csParam, info->block_size);
|
||||
return noErr;
|
||||
|
||||
|
||||
case 120: // Return device ident
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
return noErr;
|
||||
|
||||
|
||||
case 121: // Get CD features
|
||||
WriteMacInt16(pb + csParam, 0x0200); // 300 KB/s
|
||||
WriteMacInt16(pb + csParam + 2, 0x0c00); // SCSI-2, stereo
|
||||
return noErr;
|
||||
|
||||
|
||||
default:
|
||||
printf("WARNING: Unknown CDROMStatus(%d)\n", code);
|
||||
return statusErr;
|
||||
|
@ -999,6 +1168,6 @@ void CDROMInterrupt(void)
|
|||
{
|
||||
if (!acc_run_called)
|
||||
return;
|
||||
|
||||
|
||||
mount_mountable_volumes();
|
||||
}
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
extern bool tick_inhibit;
|
||||
|
||||
void PlayStartupSound();
|
||||
|
||||
/*
|
||||
* Execute EMUL_OP opcode (called by 68k emulator or Illegal Instruction trap handler)
|
||||
|
@ -83,10 +86,14 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
|||
|
||||
case M68K_EMUL_OP_RESET: { // MacOS reset
|
||||
D(bug("*** RESET ***\n"));
|
||||
tick_inhibit = true;
|
||||
CDROMRemount(); // for System 7.x
|
||||
TimerReset();
|
||||
EtherReset();
|
||||
AudioReset();
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
PlayStartupSound();
|
||||
#endif
|
||||
// Create BootGlobs at top of memory
|
||||
Mac_memset(RAMBaseMac + RAMSize - 4096, 0, 4096);
|
||||
uint32 boot_globs = RAMBaseMac + RAMSize - 0x1c;
|
||||
|
@ -107,6 +114,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
|||
r->a[1] = ROMBaseMac + UniversalInfo; // UniversalInfo
|
||||
r->a[6] = boot_globs; // BootGlobs
|
||||
r->a[7] = RAMBaseMac + 0x10000; // Boot stack
|
||||
tick_inhibit = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -114,7 +122,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
|||
bool is_read = (r->d[1] & 0x80) != 0;
|
||||
if ((r->d[1] & 0x78) == 0x38) {
|
||||
// XPRAM
|
||||
uint8 reg = (r->d[1] << 5) & 0xe0 | (r->d[1] >> 10) & 0x1f;
|
||||
uint8 reg = ((r->d[1] << 5) & 0xe0) | ((r->d[1] >> 10) & 0x1f);
|
||||
if (is_read) {
|
||||
r->d[2] = XPRAM[reg];
|
||||
bool localtalk = !(XPRAM[0xe0] || XPRAM[0xe1]); // LocalTalk enabled?
|
||||
|
@ -453,7 +461,9 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
|||
if (HasMacStarted()) {
|
||||
|
||||
// Mac has started, execute all 60Hz interrupt functions
|
||||
#if !PRECISE_TIMING
|
||||
TimerInterrupt();
|
||||
#endif
|
||||
VideoInterrupt();
|
||||
|
||||
// Call DoVBLTask(0)
|
||||
|
@ -485,7 +495,12 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
|||
ClearInterruptFlag(INTFLAG_ETHER);
|
||||
EtherInterrupt();
|
||||
}
|
||||
|
||||
#if PRECISE_TIMING
|
||||
if (InterruptFlags & INTFLAG_TIMER) {
|
||||
ClearInterruptFlag(INTFLAG_TIMER);
|
||||
TimerInterrupt();
|
||||
}
|
||||
#endif
|
||||
if (InterruptFlags & INTFLAG_AUDIO) {
|
||||
ClearInterruptFlag(INTFLAG_AUDIO);
|
||||
AudioInterrupt();
|
||||
|
|
|
@ -72,14 +72,21 @@ const uint32 siHardwareMute = FOURCC('h','m','u','t'); // mute state of all ha
|
|||
const uint32 siHardwareVolume = FOURCC('h','v','o','l'); // volume level of all hardware
|
||||
const uint32 siHardwareVolumeSteps = FOURCC('h','s','t','p'); // number of volume steps for hardware
|
||||
const uint32 siHardwareBusy = FOURCC('h','w','b','s'); // sound hardware is in use
|
||||
const uint32 siHardwareFormat = FOURCC('h','w','f','m'); // hardware format
|
||||
const uint32 siHeadphoneMute = FOURCC('p','m','u','t'); // mute state of headphone
|
||||
const uint32 siHeadphoneVolume = FOURCC('p','v','o','l'); // volume level of headphone
|
||||
const uint32 siHeadphoneVolumeSteps = FOURCC('h','d','s','t'); // number of volume steps for headphone
|
||||
const uint32 siSpeakerMute = FOURCC('s','m','u','t'); // mute state of all built-in speakers
|
||||
const uint32 siSpeakerVolume = FOURCC('s','v','o','l'); // volume level of built-in speaker
|
||||
const uint32 siDeviceName = FOURCC('n','a','m','e');
|
||||
const uint32 siDeviceIcon = FOURCC('i','c','o','n');
|
||||
const uint32 siHardwareFormat = FOURCC('h','w','f','m');
|
||||
const uint32 siDeviceName = FOURCC('n','a','m','e'); // sound input name
|
||||
const uint32 siDeviceIcon = FOURCC('i','c','o','n'); // sound input icon resource location
|
||||
const uint32 siInputSourceNames = FOURCC('s','n','a','m'); // sound input source names
|
||||
const uint32 siInputSource = FOURCC('s','o','u','r'); // sound input source selector
|
||||
const uint32 siInputGain = FOURCC('g','a','i','n'); // sound input gain
|
||||
const uint32 siOptionsDialog = FOURCC('o','p','t','d'); // display options dialog box
|
||||
const uint32 siPlayThruOnOff = FOURCC('p','l','t','h'); // play-through state
|
||||
const uint32 siInitializeDriver = FOURCC('i','n','i','t'); // open sound input device
|
||||
const uint32 siCloseDriver = FOURCC('c','l','o','s'); // close sound input device
|
||||
|
||||
enum { // ComponentResource struct
|
||||
componentType = 0,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* bincue_unix.h -- support for cdrom image files in bin/cue format
|
||||
* bincue.h -- support for cdrom image files in bin/cue format
|
||||
*
|
||||
* (C) 2010 Geoffrey Brown
|
||||
*
|
||||
|
@ -34,10 +34,13 @@ extern bool CDPlay_bincue(void *, uint8, uint8,
|
|||
extern bool CDPause_bincue(void *);
|
||||
extern bool CDResume_bincue(void *);
|
||||
extern bool CDStop_bincue(void *);
|
||||
extern bool CDScan_bincue(void *, uint8, uint8, uint8, bool);
|
||||
extern void CDSetVol_bincue(void *, uint8, uint8);
|
||||
extern void CDGetVol_bincue(void *, uint8 *, uint8 *);
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
extern void OpenAudio_bincue(int, int, int, uint8);
|
||||
extern void MixAudio_bincue(uint8 *, int);
|
||||
extern void OpenAudio_bincue(int, int, int, uint8, int);
|
||||
extern void MixAudio_bincue(uint8 *, int, int);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -40,4 +40,9 @@ extern int16 CDROMPrime(uint32 pb, uint32 dce);
|
|||
extern int16 CDROMControl(uint32 pb, uint32 dce);
|
||||
extern int16 CDROMStatus(uint32 pb, uint32 dce);
|
||||
|
||||
extern void CDROMOpenDone(void); // Called by CDROMOpen() once drives have been to the drive queue
|
||||
|
||||
void CDROMDrop(const char *path);
|
||||
void CDROMRemount();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,8 +34,15 @@ extern bool TwentyFourBitAddressing;
|
|||
// 68k register structure (for Execute68k())
|
||||
struct M68kRegisters {
|
||||
uint32 d[8];
|
||||
#ifdef UPDATE_UAE
|
||||
memptr a[8];
|
||||
uint16 sr;
|
||||
memptr usp, isp, msp;
|
||||
memptr pc;
|
||||
#else
|
||||
uint32 a[8];
|
||||
uint16 sr;
|
||||
#endif
|
||||
};
|
||||
|
||||
// General functions
|
||||
|
@ -74,6 +81,9 @@ extern uint32 InterruptFlags; // Currently pending interrupts
|
|||
extern void SetInterruptFlag(uint32 flag); // Set/clear interrupt flags
|
||||
extern void ClearInterruptFlag(uint32 flag);
|
||||
|
||||
// vde switch variable
|
||||
extern char* vde_sock;
|
||||
|
||||
// Array length
|
||||
#if __cplusplus >= 201103L || (_MSC_VER >= 1900 && defined __cplusplus)
|
||||
template <typename T, size_t size>
|
||||
|
|
|
@ -48,6 +48,7 @@ extern void PrefsReplaceBool(const char *name, bool b);
|
|||
extern void PrefsReplaceInt32(const char *name, int32 val);
|
||||
|
||||
extern const char *PrefsFindString(const char *name, int index = 0);
|
||||
extern "C" const char *PrefsFindStringC(const char *name, int index = 0);
|
||||
extern bool PrefsFindBool(const char *name);
|
||||
extern int32 PrefsFindInt32(const char *name);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ extern void SysAddSerialPrefs(void);
|
|||
* that is freed by Sys_close().
|
||||
*/
|
||||
|
||||
extern void *Sys_open(const char *name, bool read_only);
|
||||
extern void *Sys_open(const char *name, bool read_only, bool is_cdrom = false);
|
||||
extern void Sys_close(void *fh);
|
||||
extern size_t Sys_read(void *fh, void *buffer, loff_t offset, size_t length);
|
||||
extern size_t Sys_write(void *fh, void *buffer, loff_t offset, size_t length);
|
||||
|
|
|
@ -162,6 +162,12 @@ enum {
|
|||
STR_24_BIT_1600x1200_LAB,
|
||||
STR_SOUND_CTRL,
|
||||
STR_NOSOUND_CTRL,
|
||||
STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL,
|
||||
STR_SOFTWARE_LAB,
|
||||
STR_OPENGL_LAB,
|
||||
STR_DIRECT3D_LAB,
|
||||
STR_GRAPHICS_SDL_VSYNC_CTRL,
|
||||
STR_DEFAULT_LAB,
|
||||
|
||||
STR_SERIAL_NETWORK_PANE_TITLE = 3500, // Serial/Networking pane
|
||||
STR_SERIALA_CTRL,
|
||||
|
@ -212,19 +218,20 @@ enum {
|
|||
|
||||
// Mac window
|
||||
STR_WINDOW_TITLE = 4000,
|
||||
STR_WINDOW_TITLE_FROZEN,
|
||||
STR_WINDOW_TITLE_GRABBED,
|
||||
STR_WINDOW_TITLE_GRABBED0,
|
||||
STR_WINDOW_TITLE_GRABBED_PRE,
|
||||
STR_WINDOW_TITLE_GRABBED1,
|
||||
STR_WINDOW_TITLE_GRABBED2,
|
||||
STR_WINDOW_TITLE_GRABBED3,
|
||||
STR_WINDOW_TITLE_GRABBED4,
|
||||
STR_WINDOW_TITLE_GRABBED_POST,
|
||||
STR_WINDOW_MENU = 4050,
|
||||
STR_WINDOW_ITEM_ABOUT,
|
||||
STR_WINDOW_ITEM_REFRESH,
|
||||
STR_WINDOW_ITEM_MOUNT,
|
||||
STR_SUSPEND_WINDOW_TITLE,
|
||||
|
||||
// Audio
|
||||
STR_SOUND_IN_NAME = 6000,
|
||||
|
||||
// External file system
|
||||
STR_EXTFS_NAME = 5000,
|
||||
STR_EXTFS_VOLUME_NAME
|
||||
|
|
|
@ -79,13 +79,13 @@ inline video_depth DepthModeForPixelDepth(int depth)
|
|||
// Returns the name of a video_depth, or an empty string if the depth is unknown
|
||||
const char * NameOfDepth(video_depth depth);
|
||||
|
||||
// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width
|
||||
// Return a bytes-per-row value (assuming enough bytes to fit the bits but no further padding) for the specified depth and pixel width
|
||||
inline uint32 TrivialBytesPerRow(uint32 width, video_depth depth)
|
||||
{
|
||||
switch (depth) {
|
||||
case VDEPTH_1BIT: return width / 8;
|
||||
case VDEPTH_2BIT: return width / 4;
|
||||
case VDEPTH_4BIT: return width / 2;
|
||||
case VDEPTH_1BIT: return (width + 7) / 8;
|
||||
case VDEPTH_2BIT: return (width + 3) / 4;
|
||||
case VDEPTH_4BIT: return (width + 1) / 2;
|
||||
case VDEPTH_8BIT: return width;
|
||||
case VDEPTH_16BIT: return width * 2;
|
||||
case VDEPTH_32BIT: return width * 4;
|
||||
|
@ -205,8 +205,8 @@ private:
|
|||
// Set palette to 50% gray
|
||||
void set_gray_palette(void);
|
||||
|
||||
// Load gamma-corrected black-to-white ramp to palette for direct-color mode
|
||||
void load_ramp_palette(void);
|
||||
// Load gamma-corrected black-to-white ramp
|
||||
void load_gamma_ramp(void);
|
||||
|
||||
// Allocate gamma table of specified size
|
||||
bool allocate_gamma_table(int size);
|
||||
|
@ -250,8 +250,10 @@ public:
|
|||
virtual void switch_to_current_mode(void) = 0;
|
||||
|
||||
// Called by the video driver to set the color palette (in indexed modes)
|
||||
// or the gamma table (in direct modes)
|
||||
virtual void set_palette(uint8 *pal, int num) = 0;
|
||||
|
||||
// Called by the video driver to set the gamma table
|
||||
virtual void set_gamma(uint8 *gamma, int num) = 0;
|
||||
};
|
||||
|
||||
// Vector of pointers to available monitor descriptions, filled by VideoInit()
|
||||
|
|
|
@ -133,6 +133,13 @@ uint32 TimeToMacTime(time_t t)
|
|||
// This code is taken from glibc 2.2
|
||||
|
||||
// Convert to number of seconds elapsed since 1-Jan-1904
|
||||
|
||||
#ifdef WIN32
|
||||
if (t == -1) {
|
||||
// failsafe as this will segfault
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
struct tm *local = localtime(&t);
|
||||
const int TM_EPOCH_YEAR = 1900;
|
||||
const int MAC_EPOCH_YEAR = 1904;
|
||||
|
|
|
@ -202,6 +202,8 @@ bool InitAll(const char *vmdir)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CDROMOpenDone() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize everything
|
||||
|
|
|
@ -328,6 +328,11 @@ const char *PrefsFindString(const char *name, int index)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" const char *PrefsFindStringC(const char *name, int index)
|
||||
{
|
||||
return PrefsFindString(name, index);
|
||||
}
|
||||
|
||||
bool PrefsFindBool(const char *name)
|
||||
{
|
||||
prefs_node *p = find_node(name, TYPE_BOOLEAN, 0);
|
||||
|
|
|
@ -68,15 +68,25 @@ prefs_desc common_prefs_items[] = {
|
|||
{"jitinline", TYPE_BOOLEAN, false, "enable translation through constant jumps"},
|
||||
{"jitblacklist", TYPE_STRING, false, "blacklist opcodes from translation"},
|
||||
{"keyboardtype", TYPE_INT32, false, "hardware keyboard type"},
|
||||
{"keycodes",TYPE_BOOLEAN,false,"use raw keycode"},
|
||||
{"keycodefile",TYPE_STRING,"Keycode file"},
|
||||
{"mousewheelmode",TYPE_BOOLEAN,"Use WheelMode"},
|
||||
{"mousewheellines",TYPE_INT32,"wheel line nb"},
|
||||
{"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"},
|
||||
{"keycodefile", TYPE_STRING, false, "path of keycode translation file"},
|
||||
{"mousewheelmode", TYPE_INT32, false, "mouse wheel support (0=page up/down, 1=cursor up/down)"},
|
||||
{"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"},
|
||||
{"hotkey",TYPE_INT32,false,"hotkey modifier"},
|
||||
{"scale_nearest",TYPE_BOOLEAN,false,"nearest neighbor scaling"},
|
||||
{"scale_integer",TYPE_BOOLEAN,false,"integer scaling"},
|
||||
{"yearofs", TYPE_INT32, 0, "year offset"},
|
||||
{"dayofs", TYPE_INT32, 0, "day offset"},
|
||||
{"mag_rate", TYPE_INT32, 0, "rate of magnification"},
|
||||
{"gammaramp", TYPE_STRING, false, "gamma ramp (on, off or fullscreen)"},
|
||||
{"swap_opt_cmd", TYPE_BOOLEAN, false, "swap option and command key"},
|
||||
{"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"},
|
||||
{"host_domain", TYPE_STRING, true, "handle DNS requests for this domain on the host (slirp only)"},
|
||||
{"title", TYPE_STRING, false, "window title"},
|
||||
{"sound_buffer", TYPE_INT32, false, "sound buffer length"},
|
||||
{"name_encoding", TYPE_INT32, false, "file name encoding"},
|
||||
{"delay", TYPE_INT32, false, "additional delay [uS] every 64k instructions"},
|
||||
{"init_grab", TYPE_BOOLEAN, false, "initially grabbing mouse"},
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
|
||||
|
@ -105,7 +115,7 @@ void AddPrefsDefaults(void)
|
|||
|
||||
#if USE_JIT
|
||||
// JIT compiler specific options
|
||||
PrefsAddBool("jit", true);
|
||||
// PrefsAddBool("jit", true);
|
||||
PrefsAddBool("jitfpu", true);
|
||||
PrefsAddBool("jitdebug", false);
|
||||
PrefsAddInt32("jitcachesize", 8192);
|
||||
|
@ -116,4 +126,11 @@ void AddPrefsDefaults(void)
|
|||
#endif
|
||||
|
||||
PrefsAddInt32("keyboardtype", 5);
|
||||
|
||||
#ifdef __APPLE__
|
||||
PrefsAddBool("swap_opt_cmd", false);
|
||||
#else
|
||||
PrefsAddBool("swap_opt_cmd", true);
|
||||
#endif
|
||||
PrefsAddBool("ignoresegv", true);
|
||||
}
|
||||
|
|
|
@ -695,7 +695,8 @@ static const uint8 adbop_patch[] = { // Call ADBOp() completion procedure
|
|||
0x4e, 0x91, // jsr (a1)
|
||||
0x70, 0x00, // moveq #0,d0
|
||||
0x60, 0x00, 0x00, 0x04, // bra 2
|
||||
0x70, 0xff, //1 moveq #-1,d0
|
||||
// 0x70, 0xff, //1 moveq #-1,d0
|
||||
0x70, 0x00, //1 moveq #0,d0 copy from BasiliskII-build142
|
||||
0x4c, 0xdf, 0x0f, 0x0e, //2 movem.l (sp)+,d1-d3/a0-a3
|
||||
0x46, 0xdf, // move (sp)+,sr
|
||||
0x4e, 0x75 // rts
|
||||
|
|
|
@ -201,12 +201,12 @@ end_error:
|
|||
|
||||
#define ICMP_MAXDATALEN (IP_MSS-28)
|
||||
void
|
||||
icmp_error(msrc, type, code, minsize, message)
|
||||
struct mbuf *msrc;
|
||||
u_char type;
|
||||
u_char code;
|
||||
int minsize;
|
||||
char *message;
|
||||
icmp_error(
|
||||
struct mbuf *msrc,
|
||||
u_char type,
|
||||
u_char code,
|
||||
int minsize,
|
||||
char *message)
|
||||
{
|
||||
unsigned hlen, shlen, s_ip_len;
|
||||
register struct ip *ip;
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#include <slirp.h>
|
||||
#include "ip_icmp.h"
|
||||
|
||||
static struct ip *ip_reass(register struct ip *ip, register struct ipq *fp);
|
||||
|
||||
int ip_defttl;
|
||||
struct ipstat ipstat;
|
||||
struct ipq ipq;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* terms and conditions of the copyright.
|
||||
*/
|
||||
|
||||
// #include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <slirp.h>
|
||||
|
||||
/* Done as a macro in socket.h */
|
||||
|
|
|
@ -87,7 +87,7 @@ static int get_dns_addr(struct in_addr *pdns_addr)
|
|||
static int get_dns_addr(struct in_addr *pdns_addr)
|
||||
{
|
||||
char buff[512];
|
||||
char buff2[256];
|
||||
char buff2[257];
|
||||
FILE *f;
|
||||
int found = 0;
|
||||
struct in_addr tmp_addr;
|
||||
|
@ -127,12 +127,15 @@ static int get_dns_addr(struct in_addr *pdns_addr)
|
|||
void slirp_cleanup(void)
|
||||
{
|
||||
WSACleanup();
|
||||
unload_host_domains();
|
||||
}
|
||||
#endif
|
||||
|
||||
int slirp_init(void)
|
||||
{
|
||||
// debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
|
||||
|
||||
load_host_domains();
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
|
@ -427,7 +430,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
|
|||
/* Connected */
|
||||
so->so_state &= ~SS_ISFCONNECTING;
|
||||
|
||||
ret = send(so->s, &ret, 0, 0);
|
||||
ret = send(so->s, NULL, 0, 0);
|
||||
if (ret < 0) {
|
||||
/* XXXXX Must fix, zero bytes is a NOP */
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK ||
|
||||
|
|
|
@ -32,21 +32,6 @@ typedef unsigned long ioctlsockopt_t;
|
|||
# include <winsock2.h>
|
||||
# include <WS2tcpip.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
char * WSAAPI inet_ntop(
|
||||
INT Family,
|
||||
PVOID pAddr,
|
||||
PTSTR pStringBuf,
|
||||
size_t StringBufSize
|
||||
);
|
||||
|
||||
INT WSAAPI inet_pton(
|
||||
INT Family,
|
||||
const char * pszAddrString,
|
||||
PVOID pAddrBuf
|
||||
);
|
||||
#endif
|
||||
|
||||
# include <sys/timeb.h>
|
||||
# include <iphlpapi.h>
|
||||
|
||||
|
@ -347,8 +332,6 @@ void if_output _P((struct socket *, struct mbuf *));
|
|||
/* ip_input.c */
|
||||
void ip_init _P((void));
|
||||
void ip_input _P((struct mbuf *));
|
||||
static struct ip *
|
||||
ip_reass(register struct ip *ip, register struct ipq *);
|
||||
void ip_freef _P((struct ipq *));
|
||||
void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *));
|
||||
void ip_deq _P((register struct ipasfrag *));
|
||||
|
@ -385,6 +368,9 @@ int tcp_emu _P((struct socket *, struct mbuf *));
|
|||
int tcp_ctl _P((struct socket *));
|
||||
struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
|
||||
|
||||
void load_host_domains();
|
||||
void unload_host_domains();
|
||||
|
||||
#ifdef USE_PPP
|
||||
#define MIN_MRU MINMRU
|
||||
#define MAX_MRU MAXMRU
|
||||
|
|
|
@ -13,6 +13,106 @@
|
|||
#ifdef __sun__
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define DEBUG_HOST_RESOLVED_DNS 0
|
||||
|
||||
/**
|
||||
* DNS requests for these domain suffixes will be
|
||||
* looked up on the host to allow for host-supported DNS alternatives
|
||||
* (e.g. MDNS, hosts file, etc.)
|
||||
**/
|
||||
static const char ** host_resolved_domain_suffixes = NULL;
|
||||
|
||||
#define HOST_DOMAIN_TTL 60 // In seconds.
|
||||
|
||||
#if DEBUG_HOST_RESOLVED_DNS
|
||||
#define D(...) printf(__VA_ARGS__); fflush(stdout);
|
||||
#else
|
||||
#define D(...)
|
||||
#endif
|
||||
|
||||
const char *PrefsFindStringC(const char *name, int index);
|
||||
|
||||
int prepare_host_domain_suffixes(char * buf) {
|
||||
/**
|
||||
* Set up the list of domain suffixes to match from the host_domain prefs.
|
||||
* Call first with buf NULL to figure out the size of buffer needed.
|
||||
**/
|
||||
int pos = 0;
|
||||
const char ** host_resolved_domain_suffixes_pos = NULL;
|
||||
|
||||
if (buf) {
|
||||
D("Setting up slirp host domain suffixes for matching:\n");
|
||||
host_resolved_domain_suffixes_pos = (const char **) buf;
|
||||
}
|
||||
|
||||
// find out how many values there are
|
||||
int host_domain_count = 0;
|
||||
while (PrefsFindStringC("host_domain", host_domain_count) != NULL) {
|
||||
host_domain_count ++;
|
||||
}
|
||||
|
||||
// leave space for the top array
|
||||
pos += (host_domain_count + 1) * sizeof(const char *);
|
||||
|
||||
const char *str;
|
||||
int host_domain_num = 0;
|
||||
while ((str = PrefsFindStringC("host_domain", host_domain_num++)) != NULL) {
|
||||
if (str[0] == '\0') continue;
|
||||
if (buf) {
|
||||
const char * cur_entry = (const char *) (buf + pos);
|
||||
*host_resolved_domain_suffixes_pos = cur_entry;
|
||||
host_resolved_domain_suffixes_pos++;
|
||||
}
|
||||
|
||||
// this is a suffix to match so it must have a leading dot
|
||||
if (str[0] != '.') {
|
||||
if (buf) buf[pos] = '.';
|
||||
pos++;
|
||||
}
|
||||
const char * str_pos = str;
|
||||
while (*str_pos != '\0') {
|
||||
if (buf) buf[pos] = tolower(*str_pos);
|
||||
++pos;
|
||||
++str_pos;
|
||||
}
|
||||
// domain to be checked will be FQDN so suffix must have a trailing dot
|
||||
if (str[strlen(str) - 1] != '.') {
|
||||
if (buf) buf[pos] = '.';
|
||||
pos++;
|
||||
}
|
||||
if (buf) {
|
||||
buf[pos] = '\0';
|
||||
D(" %d. %s\n", host_domain_num, *(host_resolved_domain_suffixes_pos-1));
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
// end of list marker
|
||||
if (buf) *host_resolved_domain_suffixes_pos = NULL;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void load_host_domains() {
|
||||
const int size = prepare_host_domain_suffixes(NULL);
|
||||
char * buf = malloc(size);
|
||||
if (buf) {
|
||||
const int second_size = prepare_host_domain_suffixes(buf);
|
||||
assert(size == second_size);
|
||||
host_resolved_domain_suffixes = (const char **) buf;
|
||||
}
|
||||
}
|
||||
|
||||
void unload_host_domains() {
|
||||
if (host_resolved_domain_suffixes) {
|
||||
free((char *) host_resolved_domain_suffixes);
|
||||
host_resolved_domain_suffixes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
so_init()
|
||||
|
@ -482,6 +582,300 @@ sorecvfrom(so)
|
|||
} /* if ping packet */
|
||||
}
|
||||
|
||||
// Commented structs from silv3rm00n's example code
|
||||
// https://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/
|
||||
|
||||
struct DNS_HEADER
|
||||
{
|
||||
unsigned short id; // identification number
|
||||
|
||||
unsigned char rd :1; // recursion desired
|
||||
unsigned char tc :1; // truncated message
|
||||
unsigned char aa :1; // authoritive answer
|
||||
unsigned char opcode :4; // purpose of message
|
||||
unsigned char qr :1; // query/response flag
|
||||
|
||||
unsigned char rcode :4; // response code
|
||||
unsigned char cd :1; // checking disabled
|
||||
unsigned char ad :1; // authenticated data
|
||||
unsigned char z :1; // its z! reserved
|
||||
unsigned char ra :1; // recursion available
|
||||
|
||||
unsigned short q_count; // number of question entries
|
||||
unsigned short ans_count; // number of answer entries
|
||||
unsigned short auth_count; // number of authority entries
|
||||
unsigned short add_count; // number of resource entries
|
||||
};
|
||||
|
||||
struct QUESTION
|
||||
{
|
||||
unsigned short qtype;
|
||||
unsigned short qclass;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct R_DATA
|
||||
{
|
||||
unsigned short type;
|
||||
unsigned short _class;
|
||||
unsigned int ttl;
|
||||
unsigned short data_len;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/** Create local variable varname of type vartype,
|
||||
* fill it from the buffer data, observing its length len,
|
||||
* and adjust data and len to reflect the remaining data */
|
||||
#define POP_DATA(vartype, varname, data, len) \
|
||||
assert(len >= sizeof(vartype)); \
|
||||
vartype varname; \
|
||||
memcpy(&varname, data, sizeof(vartype)); \
|
||||
data += sizeof(vartype); \
|
||||
len -= sizeof(vartype)
|
||||
|
||||
|
||||
/** Create local const char * varname pointing
|
||||
* to the C string in the buffer data, observing its length len,
|
||||
* and adjust data and len to reflect the remaining data */
|
||||
#define POP_STR(varname, data, len) \
|
||||
const char * varname; \
|
||||
{ \
|
||||
int pop_str_len = strnlen(data, len); \
|
||||
if (pop_str_len == len) { \
|
||||
varname = NULL; \
|
||||
} else { \
|
||||
varname = data; \
|
||||
} \
|
||||
data += pop_str_len + 1; \
|
||||
len -= pop_str_len + 1; \
|
||||
}
|
||||
|
||||
|
||||
static void inject_udp_packet_to_guest(struct socket * so, struct sockaddr_in addr, caddr_t packet_data, int packet_len) {
|
||||
struct mbuf *m;
|
||||
int len;
|
||||
|
||||
/** This is like sorecvfrom(), but just adds a packet with the
|
||||
* supplied data instead of reading the packet to add from the socket */
|
||||
|
||||
if (!(m = m_get())) return;
|
||||
m->m_data += if_maxlinkhdr;
|
||||
|
||||
len = M_FREEROOM(m);
|
||||
|
||||
if (packet_len > len) {
|
||||
packet_len = (m->m_data - m->m_dat) + m->m_len + packet_len + 1;
|
||||
m_inc(m, packet_len);
|
||||
len = M_FREEROOM(m);
|
||||
}
|
||||
|
||||
assert(len >= packet_len);
|
||||
m->m_len = packet_len;
|
||||
memcpy(m->m_data, packet_data, packet_len);
|
||||
|
||||
udp_output(so, m, &addr);
|
||||
}
|
||||
|
||||
/* Decode hostname from the format used in DNS
|
||||
e.g. "\009something\004else\003com" for "something.else.com." */
|
||||
static char * decode_dns_name(const char * data) {
|
||||
|
||||
int query_str_len = strlen(data);
|
||||
char * decoded_name_str = malloc(query_str_len + 1);
|
||||
if (decoded_name_str == NULL) {
|
||||
D("decode_dns_name(): out of memory\n");
|
||||
return NULL; // oom
|
||||
}
|
||||
|
||||
char * decoded_name_str_pos = decoded_name_str;
|
||||
while (*data != '\0') {
|
||||
int part_len = *data++;
|
||||
query_str_len--;
|
||||
if (query_str_len < part_len) {
|
||||
D("decode_dns_name(): part went off the end of the string\n");
|
||||
free(decoded_name_str);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(decoded_name_str_pos, data, part_len);
|
||||
decoded_name_str_pos[part_len] = '.';
|
||||
decoded_name_str_pos += part_len + 1;
|
||||
query_str_len -= part_len;
|
||||
data += part_len;
|
||||
}
|
||||
*decoded_name_str_pos = '\0';
|
||||
return decoded_name_str;
|
||||
}
|
||||
|
||||
/** Take a look at a UDP DNS request the client has made and see if we want to resolve it internally.
|
||||
* Returns true if the request has been internally and can be dropped,
|
||||
* false otherwise
|
||||
**/
|
||||
static bool resolve_dns_request(struct socket * so, struct sockaddr_in addr, caddr_t data, int len) {
|
||||
bool drop_dns_request = false;
|
||||
|
||||
D("Checking outgoing DNS UDP packet\n");
|
||||
|
||||
if (len < sizeof(struct DNS_HEADER)) {
|
||||
D("Packet too short for DNS header\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const caddr_t packet = data;
|
||||
const int packet_len = len;
|
||||
|
||||
POP_DATA(struct DNS_HEADER, h, data, len);
|
||||
|
||||
if (h.qr != 0) {
|
||||
D("DNS packet is not a request\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ntohs(h.q_count) == 0) {
|
||||
D("DNS request has no queries\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ntohs(h.q_count) > 1) {
|
||||
D("DNS request has multiple queries (not supported)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ntohs(h.ans_count != 0) || ntohs(h.auth_count != 0) || ntohs(h.add_count != 0)) {
|
||||
D("DNS request has unsupported extra contents\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
D("Packet too short for DNS query string\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
POP_STR(original_query_str, data, len);
|
||||
if (original_query_str == NULL) {
|
||||
// went off end of packet
|
||||
D("Unterminated DNS query string\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char * decoded_name_str = decode_dns_name(original_query_str);
|
||||
if (decoded_name_str == NULL) {
|
||||
D("Error while decoding DNS query string");
|
||||
return false;
|
||||
}
|
||||
|
||||
D("DNS host query for %s\n", decoded_name_str);
|
||||
|
||||
POP_DATA(struct QUESTION, qinfo, data, len);
|
||||
|
||||
if (ntohs(qinfo.qtype) != 1 /* type A */ || ntohs(qinfo.qclass) != 1 /* class IN */ ) {
|
||||
D("DNS host query for %s: Request isn't the supported type (INET A query)\n", decoded_name_str);
|
||||
free(decoded_name_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
D("DNS host query for %s: Request is eligible to check for host resolution suffix\n", decoded_name_str);
|
||||
|
||||
const char * matched_suffix = NULL;
|
||||
|
||||
for (const char ** suffix_ptr = host_resolved_domain_suffixes; *suffix_ptr != NULL; suffix_ptr++) {
|
||||
const char * suffix = *suffix_ptr;
|
||||
|
||||
// ends with suffix?
|
||||
int suffix_pos = strlen(decoded_name_str) - strlen(suffix);
|
||||
if (suffix_pos > 0 && strcmp(decoded_name_str + suffix_pos, suffix) == 0) {
|
||||
matched_suffix = suffix;
|
||||
break;
|
||||
}
|
||||
|
||||
// also check if the domain exactly matched the one the suffix is for
|
||||
if (strcmp(decoded_name_str, suffix + 1) == 0) {
|
||||
matched_suffix = suffix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matched_suffix == NULL) {
|
||||
D("DNS host query for %s: No suffix matched\n", decoded_name_str);
|
||||
} else {
|
||||
|
||||
D("DNS host query for %s: Matched for suffix: %s\n", decoded_name_str, matched_suffix);
|
||||
|
||||
// we are going to take this request and resolve it on the host
|
||||
drop_dns_request = true;
|
||||
|
||||
D("DNS host query for %s: Doing lookup on host\n", decoded_name_str);
|
||||
|
||||
int results_count = 0;
|
||||
struct hostent * host_lookup_result = gethostbyname(decoded_name_str);
|
||||
|
||||
if (host_lookup_result && host_lookup_result->h_addrtype == AF_INET) {
|
||||
|
||||
D("DNS host query for %s: Host response has results for AF_INET\n", decoded_name_str);
|
||||
|
||||
for (char ** addr_entry = host_lookup_result->h_addr_list; *addr_entry != NULL; addr_entry++) {
|
||||
++results_count;
|
||||
}
|
||||
}
|
||||
|
||||
D("DNS host query for %s: result count %d\n", decoded_name_str, results_count);
|
||||
|
||||
int original_query_str_size = strlen(original_query_str) + 1;
|
||||
int response_size = packet_len + results_count * (original_query_str_size + sizeof(struct R_DATA) + sizeof(struct in_addr));
|
||||
|
||||
caddr_t response_packet = malloc(response_size);
|
||||
if (response_packet == NULL) {
|
||||
D("DNS host query for %s: Out of memory while allocating DNS response packet\n", decoded_name_str);
|
||||
} else {
|
||||
D("DNS host query for %s: Preparing DNS response\n", decoded_name_str);
|
||||
|
||||
// use the request DNS header as our starting point for the response
|
||||
h.qr = 1;
|
||||
h.ans_count = htons(results_count);
|
||||
memcpy(response_packet, &h, sizeof(struct DNS_HEADER));
|
||||
|
||||
// other sections verbatim out of the request
|
||||
memcpy(response_packet + sizeof(struct DNS_HEADER), packet + sizeof(struct DNS_HEADER), packet_len - sizeof(struct DNS_HEADER));
|
||||
|
||||
int response_pos = packet_len;
|
||||
|
||||
if (results_count > 0) {
|
||||
for (char ** addr_entry = host_lookup_result->h_addr_list; *addr_entry != NULL; addr_entry++) {
|
||||
// answer string is verbatim from question
|
||||
memcpy(response_packet + response_pos, original_query_str, original_query_str_size);
|
||||
|
||||
response_pos += original_query_str_size;
|
||||
|
||||
struct R_DATA resource;
|
||||
resource.type = htons(1);
|
||||
resource._class = htons(1);
|
||||
resource.ttl = htonl(HOST_DOMAIN_TTL);
|
||||
resource.data_len = htons(sizeof(struct in_addr));
|
||||
|
||||
memcpy(response_packet + response_pos, &resource, sizeof(struct R_DATA));
|
||||
response_pos += sizeof(struct R_DATA);
|
||||
|
||||
struct in_addr * cur_addr = (struct in_addr *)*addr_entry;
|
||||
memcpy(response_packet + response_pos, cur_addr, sizeof(struct in_addr));
|
||||
response_pos += sizeof(struct in_addr);
|
||||
}
|
||||
}
|
||||
|
||||
assert(response_pos == response_size);
|
||||
|
||||
D("DNS host query for %s: Injecting DNS response directly to guest\n", decoded_name_str);
|
||||
inject_udp_packet_to_guest(so, addr, response_packet, response_size);
|
||||
|
||||
free(response_packet);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(decoded_name_str);
|
||||
|
||||
D("DNS host request drop: %s\n", drop_dns_request? "yes" : "no");
|
||||
return drop_dns_request;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto() a socket
|
||||
*/
|
||||
|
@ -503,6 +897,10 @@ sosendto(so, m)
|
|||
switch(ntohl(so->so_faddr.s_addr) & 0xff) {
|
||||
case CTL_DNS:
|
||||
addr.sin_addr = dns_addr;
|
||||
if (host_resolved_domain_suffixes != NULL) {
|
||||
if (resolve_dns_request(so, addr, m->m_data, m->m_len))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case CTL_ALIAS:
|
||||
default:
|
||||
|
|
|
@ -644,8 +644,8 @@ tcp_emu(so, m)
|
|||
DEBUG_ARG("so = %lx", (long)so);
|
||||
DEBUG_ARG("m = %lx", (long)m);
|
||||
|
||||
int x, i;
|
||||
switch(so->so_emu) {
|
||||
int x, i;
|
||||
|
||||
case EMU_IDENT:
|
||||
/*
|
||||
|
|
|
@ -263,7 +263,7 @@ int16 SonyOpen(uint32 pb, uint32 dce)
|
|||
|
||||
// Set up DCE
|
||||
WriteMacInt32(dce + dCtlPosition, 0);
|
||||
WriteMacInt16(dce + dCtlQHdr + qFlags, ReadMacInt16(dce + dCtlQHdr + qFlags) & 0xff00 | 3); // Version number, must be >=3 or System 8 will replace us
|
||||
WriteMacInt16(dce + dCtlQHdr + qFlags, (ReadMacInt16(dce + dCtlQHdr + qFlags) & 0xff00) | 3); // Version number, must be >=3 or System 8 will replace us
|
||||
acc_run_called = false;
|
||||
|
||||
// Install driver again with refnum -2 (HD20)
|
||||
|
@ -520,7 +520,7 @@ int16 SonyStatus(uint32 pb, uint32 dce)
|
|||
break;
|
||||
|
||||
case 10: // Get disk type and MFM info
|
||||
WriteMacInt32(pb + csParam, ReadMacInt32(info->status + dsMFMDrive) & 0xffffff00 | 0xfe); // 0xfe = SWIM2 controller
|
||||
WriteMacInt32(pb + csParam, (ReadMacInt32(info->status + dsMFMDrive) & 0xffffff00) | 0xfe); // 0xfe = SWIM2 controller
|
||||
break;
|
||||
|
||||
// case 0x4350: // Measure disk speed at a given track ('CP') (not supported)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* timer.cpp - Time Manager emulation
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,26 +18,26 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* SEE ALSO
|
||||
* Inside Macintosh: Processes, chapter 3 "Time Manager"
|
||||
* Technote 1063: "Inside Macintosh: Processes: Time Manager Addenda"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "cpu_emulation.h"
|
||||
#include "main.h"
|
||||
#include "macos_util.h"
|
||||
#include "timer.h"
|
||||
#include "macos_util.h"
|
||||
#include "main.h"
|
||||
#include "cpu_emulation.h"
|
||||
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// Set this to 1 to enable TMQueue management (doesn't work)
|
||||
#define TM_QUEUE 0
|
||||
#define TM_QUEUE 0 // Enable TMQueue management (doesn't work)
|
||||
|
||||
|
||||
// Definitions for Time Manager
|
||||
|
@ -53,50 +53,70 @@ enum { // TMTask struct
|
|||
struct TMDesc {
|
||||
uint32 task; // Mac address of associated TMTask
|
||||
tm_time_t wakeup; // Time this task is scheduled for execution
|
||||
bool in_use; // Flag: descriptor in use
|
||||
TMDesc *next;
|
||||
};
|
||||
|
||||
const int NUM_DESCS = 64; // Maximum number of descriptors
|
||||
static TMDesc desc[NUM_DESCS];
|
||||
static TMDesc *tmDescList;
|
||||
|
||||
#if PRECISE_TIMING
|
||||
#ifdef PRECISE_TIMING_BEOS
|
||||
static thread_id timer_thread = -1;
|
||||
static bool thread_active = true;
|
||||
static const tm_time_t wakeup_time_max = 0x7fffffffffffffff;
|
||||
static volatile tm_time_t wakeup_time = wakeup_time_max;
|
||||
static sem_id wakeup_time_sem = -1;
|
||||
static int32 timer_func(void *arg);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
static pthread_t timer_thread;
|
||||
static bool timer_thread_active = false;
|
||||
static volatile bool timer_thread_cancel = false;
|
||||
static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
|
||||
static tm_time_t wakeup_time = wakeup_time_max;
|
||||
static pthread_mutex_t wakeup_time_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void *timer_func(void *arg);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
static clock_serv_t system_clock;
|
||||
static thread_act_t timer_thread;
|
||||
static bool timer_thread_active = false;
|
||||
static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
|
||||
static tm_time_t wakeup_time = wakeup_time_max;
|
||||
static semaphore_t wakeup_time_sem;
|
||||
static void *timer_func(void *arg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Allocate descriptor for given TMTask in list
|
||||
*/
|
||||
|
||||
static int alloc_desc(uint32 tm)
|
||||
inline static void free_desc(TMDesc *desc)
|
||||
{
|
||||
// Search for first free descriptor
|
||||
for (int i=0; i<NUM_DESCS; i++)
|
||||
if (!desc[i].in_use) {
|
||||
desc[i].task = tm;
|
||||
desc[i].in_use = true;
|
||||
return i;
|
||||
if (desc == tmDescList) {
|
||||
tmDescList = desc->next;
|
||||
} else {
|
||||
for (TMDesc *d = tmDescList; d; d = d->next) {
|
||||
if (d->next == desc) {
|
||||
d->next = desc->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
delete desc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free descriptor in list
|
||||
*/
|
||||
|
||||
inline static void free_desc(int i)
|
||||
{
|
||||
desc[i].in_use = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find descriptor associated with given TMTask
|
||||
*/
|
||||
|
||||
inline static int find_desc(uint32 tm)
|
||||
inline static TMDesc *find_desc(uint32 tm)
|
||||
{
|
||||
for (int i=0; i<NUM_DESCS; i++)
|
||||
if (desc[i].in_use && desc[i].task == tm)
|
||||
return i;
|
||||
return -1;
|
||||
TMDesc *desc = tmDescList;
|
||||
while (desc) {
|
||||
if (desc->task == tm) {
|
||||
return desc;
|
||||
}
|
||||
desc = desc->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,15 +153,135 @@ static void dequeue_tm(uint32 tm)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Timer thread operations
|
||||
*/
|
||||
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
const int SIGSUSPEND = SIGRTMIN + 6;
|
||||
const int SIGRESUME = SIGRTMIN + 7;
|
||||
static struct sigaction sigsuspend_action;
|
||||
static struct sigaction sigresume_action;
|
||||
|
||||
static int suspend_count = 0;
|
||||
static pthread_mutex_t suspend_count_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static sem_t suspend_ack_sem;
|
||||
static sigset_t suspend_handler_mask;
|
||||
|
||||
// Signal handler for suspended thread
|
||||
static void sigsuspend_handler(int sig)
|
||||
{
|
||||
sem_post(&suspend_ack_sem);
|
||||
sigsuspend(&suspend_handler_mask);
|
||||
}
|
||||
|
||||
// Signal handler for resumed thread
|
||||
static void sigresume_handler(int sig)
|
||||
{
|
||||
/* simply trigger a signal to stop clock_nanosleep() */
|
||||
}
|
||||
|
||||
// Initialize timer thread
|
||||
static bool timer_thread_init(void)
|
||||
{
|
||||
// Install suspend signal handler
|
||||
sigemptyset(&sigsuspend_action.sa_mask);
|
||||
sigaddset(&sigsuspend_action.sa_mask, SIGRESUME);
|
||||
sigsuspend_action.sa_handler = sigsuspend_handler;
|
||||
sigsuspend_action.sa_flags = SA_RESTART;
|
||||
#ifdef HAVE_SIGNAL_SA_RESTORER
|
||||
sigsuspend_action.sa_restorer = NULL;
|
||||
#endif
|
||||
if (sigaction(SIGSUSPEND, &sigsuspend_action, NULL) < 0)
|
||||
return false;
|
||||
|
||||
// Install resume signal handler
|
||||
sigemptyset(&sigresume_action.sa_mask);
|
||||
sigresume_action.sa_handler = sigresume_handler;
|
||||
sigresume_action.sa_flags = SA_RESTART;
|
||||
#ifdef HAVE_SIGNAL_SA_RESTORER
|
||||
sigresume_action.sa_restorer = NULL;
|
||||
#endif
|
||||
if (sigaction(SIGRESUME, &sigresume_action, NULL) < 0)
|
||||
return false;
|
||||
|
||||
// Initialize semaphore
|
||||
if (sem_init(&suspend_ack_sem, 0, 0) < 0)
|
||||
return false;
|
||||
|
||||
// Initialize suspend_handler_mask, it excludes SIGRESUME
|
||||
if (sigfillset(&suspend_handler_mask) != 0)
|
||||
return false;
|
||||
if (sigdelset(&suspend_handler_mask, SIGRESUME) != 0)
|
||||
return false;
|
||||
|
||||
// Create thread in running state
|
||||
suspend_count = 0;
|
||||
return (pthread_create(&timer_thread, NULL, timer_func, NULL) == 0);
|
||||
}
|
||||
|
||||
// Kill timer thread
|
||||
static void timer_thread_kill(void)
|
||||
{
|
||||
timer_thread_cancel = true;
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
pthread_cancel(timer_thread);
|
||||
#endif
|
||||
pthread_join(timer_thread, NULL);
|
||||
}
|
||||
|
||||
// Suspend timer thread
|
||||
static void timer_thread_suspend(void)
|
||||
{
|
||||
pthread_mutex_lock(&suspend_count_lock);
|
||||
if (suspend_count == 0) {
|
||||
suspend_count ++;
|
||||
if (pthread_kill(timer_thread, SIGSUSPEND) == 0)
|
||||
sem_wait(&suspend_ack_sem);
|
||||
}
|
||||
pthread_mutex_unlock(&suspend_count_lock);
|
||||
}
|
||||
|
||||
// Resume timer thread
|
||||
static void timer_thread_resume(void)
|
||||
{
|
||||
pthread_mutex_lock(&suspend_count_lock);
|
||||
assert(suspend_count > 0);
|
||||
if (suspend_count == 1) {
|
||||
suspend_count = 0;
|
||||
pthread_kill(timer_thread, SIGRESUME);
|
||||
}
|
||||
pthread_mutex_unlock(&suspend_count_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize Time Manager
|
||||
*/
|
||||
|
||||
void TimerInit(void)
|
||||
{
|
||||
// Mark all descriptors as inactive
|
||||
for (int i=0; i<NUM_DESCS; i++)
|
||||
free_desc(i);
|
||||
TimerReset();
|
||||
|
||||
#if PRECISE_TIMING
|
||||
// Start timer thread
|
||||
#ifdef PRECISE_TIMING_BEOS
|
||||
wakeup_time_sem = create_sem(1, "Wakeup Time");
|
||||
timer_thread = spawn_thread(timer_func, "Time Manager", B_REAL_TIME_PRIORITY, NULL);
|
||||
resume_thread(timer_thread);
|
||||
#elif PRECISE_TIMING_MACH
|
||||
pthread_t pthread;
|
||||
|
||||
host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &system_clock);
|
||||
semaphore_create(mach_task_self(), &wakeup_time_sem, SYNC_POLICY_FIFO, 1);
|
||||
|
||||
pthread_create(&pthread, NULL, &timer_func, NULL);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
timer_thread_active = timer_thread_init();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,6 +291,26 @@ void TimerInit(void)
|
|||
|
||||
void TimerExit(void)
|
||||
{
|
||||
#if PRECISE_TIMING
|
||||
// Quit timer thread
|
||||
if (timer_thread > 0) {
|
||||
#ifdef PRECISE_TIMING_BEOS
|
||||
status_t l;
|
||||
thread_active = false;
|
||||
suspend_thread(timer_thread);
|
||||
resume_thread(timer_thread);
|
||||
wait_for_thread(timer_thread, &l);
|
||||
delete_sem(wakeup_time_sem);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
timer_thread_active = false;
|
||||
semaphore_destroy(mach_task_self(), wakeup_time_sem);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
timer_thread_kill();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,9 +320,13 @@ void TimerExit(void)
|
|||
|
||||
void TimerReset(void)
|
||||
{
|
||||
// Mark all descriptors as inactive
|
||||
for (int i=0; i<NUM_DESCS; i++)
|
||||
free_desc(i);
|
||||
TMDesc *desc = tmDescList;
|
||||
while (desc) {
|
||||
TMDesc *next = desc->next;
|
||||
delete desc;
|
||||
desc = next;
|
||||
}
|
||||
tmDescList = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,12 +338,13 @@ int16 InsTime(uint32 tm, uint16 trap)
|
|||
{
|
||||
D(bug("InsTime %08lx, trap %04x\n", tm, trap));
|
||||
WriteMacInt16(tm + qType, (ReadMacInt16(tm + qType) & 0x1fff) | ((trap << 4) & 0x6000));
|
||||
if (find_desc(tm) >= 0)
|
||||
printf("WARNING: InsTime(): Task re-inserted\n");
|
||||
if (find_desc(tm))
|
||||
printf("WARNING: InsTime(%08x): Task re-inserted\n", tm);
|
||||
else {
|
||||
int i = alloc_desc(tm);
|
||||
if (i < 0)
|
||||
printf("FATAL: InsTime(): No free Time Manager descriptor\n");
|
||||
TMDesc *desc = new TMDesc;
|
||||
desc->task = tm;
|
||||
desc->next = tmDescList;
|
||||
tmDescList = desc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -194,30 +359,68 @@ int16 RmvTime(uint32 tm)
|
|||
D(bug("RmvTime %08lx\n", tm));
|
||||
|
||||
// Find descriptor
|
||||
int i = find_desc(tm);
|
||||
if (i < 0) {
|
||||
TMDesc *desc = find_desc(tm);
|
||||
if (!desc) {
|
||||
printf("WARNING: RmvTime(%08x): Descriptor not found\n", tm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Task active?
|
||||
#if PRECISE_TIMING_BEOS
|
||||
while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
|
||||
suspend_thread(timer_thread);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
semaphore_wait(wakeup_time_sem);
|
||||
thread_suspend(timer_thread);
|
||||
#endif
|
||||
#if PRECISE_TIMING_POSIX
|
||||
pthread_mutex_lock(&wakeup_time_lock);
|
||||
timer_thread_suspend();
|
||||
#endif
|
||||
if (ReadMacInt16(tm + qType) & 0x8000) {
|
||||
|
||||
// Yes, make task inactive and remove it from the Time Manager queue
|
||||
WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
|
||||
dequeue_tm(tm);
|
||||
#if PRECISE_TIMING
|
||||
// Look for next task to be called and set wakeup_time
|
||||
wakeup_time = wakeup_time_max;
|
||||
for (TMDesc *d = tmDescList; d; d = d->next)
|
||||
if ((ReadMacInt16(d->task + qType) & 0x8000))
|
||||
if (timer_cmp_time(d->wakeup, wakeup_time) < 0)
|
||||
wakeup_time = d->wakeup;
|
||||
#endif
|
||||
|
||||
// Compute remaining time
|
||||
tm_time_t remaining, current;
|
||||
timer_current_time(current);
|
||||
timer_sub_time(remaining, desc[i].wakeup, current);
|
||||
timer_sub_time(remaining, desc->wakeup, current);
|
||||
WriteMacInt32(tm + tmCount, timer_host2mac_time(remaining));
|
||||
} else
|
||||
WriteMacInt32(tm + tmCount, 0);
|
||||
D(bug(" tmCount %d\n", ReadMacInt32(tm + tmCount)));
|
||||
#if PRECISE_TIMING_BEOS
|
||||
release_sem(wakeup_time_sem);
|
||||
thread_info info;
|
||||
do {
|
||||
resume_thread(timer_thread); // This will unblock the thread
|
||||
get_thread_info(timer_thread, &info);
|
||||
} while (info.state == B_THREAD_SUSPENDED); // Sometimes, resume_thread() doesn't work (BeOS bug?)
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
semaphore_signal(wakeup_time_sem);
|
||||
thread_abort(timer_thread);
|
||||
thread_resume(timer_thread);
|
||||
#endif
|
||||
#if PRECISE_TIMING_POSIX
|
||||
pthread_mutex_unlock(&wakeup_time_lock);
|
||||
timer_thread_resume();
|
||||
assert(suspend_count == 0);
|
||||
#endif
|
||||
|
||||
// Free descriptor
|
||||
free_desc(i);
|
||||
free_desc(desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -231,38 +434,41 @@ int16 PrimeTime(uint32 tm, int32 time)
|
|||
D(bug("PrimeTime %08x, time %d\n", tm, time));
|
||||
|
||||
// Find descriptor
|
||||
int i = find_desc(tm);
|
||||
if (i < 0) {
|
||||
printf("FATAL: PrimeTime(): Descriptor not found\n");
|
||||
TMDesc *desc = find_desc(tm);
|
||||
if (!desc) {
|
||||
printf("FATAL: PrimeTime(%08x): Descriptor not found\n", tm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert delay time
|
||||
tm_time_t delay;
|
||||
timer_mac2host_time(delay, time);
|
||||
|
||||
// Extended task?
|
||||
if (ReadMacInt16(tm + qType) & 0x4000) {
|
||||
|
||||
// Convert delay time
|
||||
tm_time_t delay;
|
||||
timer_mac2host_time(delay, time);
|
||||
|
||||
// Yes, tmWakeUp set?
|
||||
if (ReadMacInt32(tm + tmWakeUp)) {
|
||||
|
||||
//!! PrimeTime(0) means continue previous delay
|
||||
// (save wakeup time in RmvTime?)
|
||||
if (time == 0)
|
||||
printf("WARNING: Unsupported PrimeTime(0)\n");
|
||||
// PrimeTime(0) can either mean (a) "the task runs as soon as interrupts are enabled"
|
||||
// or (b) "continue previous delay" if an expired task was stopped via RmvTime() and
|
||||
// then re-installed using InsXTime(). Since tmWakeUp was set, this is case (b).
|
||||
// The remaining time was saved in tmCount by RmvTime().
|
||||
if (time == 0) {
|
||||
timer_mac2host_time(delay, ReadMacInt16(tm + tmCount));
|
||||
}
|
||||
|
||||
// Yes, calculate wakeup time relative to last scheduled time
|
||||
tm_time_t wakeup;
|
||||
timer_add_time(wakeup, desc[i].wakeup, delay);
|
||||
desc[i].wakeup = wakeup;
|
||||
timer_add_time(wakeup, desc->wakeup, delay);
|
||||
desc->wakeup = wakeup;
|
||||
|
||||
} else {
|
||||
|
||||
// No, calculate wakeup time relative to current time
|
||||
tm_time_t now;
|
||||
timer_current_time(now);
|
||||
timer_add_time(desc[i].wakeup, now, delay);
|
||||
timer_add_time(desc->wakeup, now, delay);
|
||||
}
|
||||
|
||||
// Set tmWakeUp to indicate that task was scheduled
|
||||
|
@ -271,19 +477,130 @@ int16 PrimeTime(uint32 tm, int32 time)
|
|||
} else {
|
||||
|
||||
// Not extended task, calculate wakeup time relative to current time
|
||||
tm_time_t delay;
|
||||
timer_mac2host_time(delay, time);
|
||||
timer_current_time(desc[i].wakeup);
|
||||
timer_add_time(desc[i].wakeup, desc[i].wakeup, delay);
|
||||
tm_time_t now;
|
||||
timer_current_time(now);
|
||||
timer_add_time(desc->wakeup, now, delay);
|
||||
}
|
||||
|
||||
// Make task active and enqueue it in the Time Manager queue
|
||||
#if PRECISE_TIMING_BEOS
|
||||
while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
|
||||
suspend_thread(timer_thread);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
semaphore_wait(wakeup_time_sem);
|
||||
thread_suspend(timer_thread);
|
||||
#endif
|
||||
#if PRECISE_TIMING_POSIX
|
||||
pthread_mutex_lock(&wakeup_time_lock);
|
||||
timer_thread_suspend();
|
||||
#endif
|
||||
WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
|
||||
enqueue_tm(tm);
|
||||
#if PRECISE_TIMING
|
||||
// Look for next task to be called and set wakeup_time
|
||||
wakeup_time = wakeup_time_max;
|
||||
for (TMDesc *d = tmDescList; d; d = d->next)
|
||||
if ((ReadMacInt16(d->task + qType) & 0x8000))
|
||||
if (timer_cmp_time(d->wakeup, wakeup_time) < 0)
|
||||
wakeup_time = d->wakeup;
|
||||
#ifdef PRECISE_TIMING_BEOS
|
||||
release_sem(wakeup_time_sem);
|
||||
thread_info info;
|
||||
do {
|
||||
resume_thread(timer_thread); // This will unblock the thread
|
||||
get_thread_info(timer_thread, &info);
|
||||
} while (info.state == B_THREAD_SUSPENDED); // Sometimes, resume_thread() doesn't work (BeOS bug?)
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
semaphore_signal(wakeup_time_sem);
|
||||
thread_abort(timer_thread);
|
||||
thread_resume(timer_thread);
|
||||
#endif
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
pthread_mutex_unlock(&wakeup_time_lock);
|
||||
timer_thread_resume();
|
||||
assert(suspend_count == 0);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Time Manager thread
|
||||
*/
|
||||
|
||||
#ifdef PRECISE_TIMING_BEOS
|
||||
static int32 timer_func(void *arg)
|
||||
{
|
||||
while (thread_active) {
|
||||
|
||||
// Wait until time specified by wakeup_time
|
||||
snooze_until(wakeup_time, B_SYSTEM_TIMEBASE);
|
||||
|
||||
while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
|
||||
if (wakeup_time < system_time()) {
|
||||
|
||||
// Timer expired, trigger interrupt
|
||||
wakeup_time = 0x7fffffffffffffff;
|
||||
SetInterruptFlag(INTFLAG_TIMER);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
release_sem(wakeup_time_sem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PRECISE_TIMING_MACH
|
||||
static void *timer_func(void *arg)
|
||||
{
|
||||
timer_thread = mach_thread_self();
|
||||
timer_thread_active = true;
|
||||
|
||||
while (timer_thread_active) {
|
||||
clock_sleep(system_clock, TIME_ABSOLUTE, wakeup_time, NULL);
|
||||
semaphore_wait(wakeup_time_sem);
|
||||
|
||||
tm_time_t system_time;
|
||||
|
||||
timer_current_time(system_time);
|
||||
if (timer_cmp_time(wakeup_time, system_time) < 0) {
|
||||
wakeup_time = wakeup_time_max;
|
||||
SetInterruptFlag(INTFLAG_TIMER);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
semaphore_signal(wakeup_time_sem);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PRECISE_TIMING_POSIX
|
||||
static void *timer_func(void *arg)
|
||||
{
|
||||
while (!timer_thread_cancel) {
|
||||
// Wait until time specified by wakeup_time
|
||||
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wakeup_time, NULL);
|
||||
|
||||
tm_time_t system_time;
|
||||
timer_current_time(system_time);
|
||||
if (timer_cmp_time(wakeup_time, system_time) < 0) {
|
||||
|
||||
// Timer expired, trigger interrupt
|
||||
pthread_mutex_lock(&wakeup_time_lock);
|
||||
wakeup_time = wakeup_time_max;
|
||||
pthread_mutex_unlock(&wakeup_time_lock);
|
||||
SetInterruptFlag(INTFLAG_TIMER);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Timer interrupt function (executed as part of 60Hz interrupt)
|
||||
*/
|
||||
|
@ -293,24 +610,66 @@ void TimerInterrupt(void)
|
|||
// Look for active TMTasks that have expired
|
||||
tm_time_t now;
|
||||
timer_current_time(now);
|
||||
for (int i=0; i<NUM_DESCS; i++)
|
||||
if (desc[i].in_use) {
|
||||
uint32 tm = desc[i].task;
|
||||
if ((ReadMacInt16(tm + qType) & 0x8000) && timer_cmp_time(desc[i].wakeup, now) < 0) {
|
||||
TMDesc *desc = tmDescList;
|
||||
while (desc) {
|
||||
TMDesc *next = desc->next;
|
||||
uint32 tm = desc->task;
|
||||
if ((ReadMacInt16(tm + qType) & 0x8000) && timer_cmp_time(desc->wakeup, now) <= 0) {
|
||||
|
||||
// Found one, mark as inactive and remove it from the Time Manager queue
|
||||
WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
|
||||
dequeue_tm(tm);
|
||||
// Found one, mark as inactive and remove it from the Time Manager queue
|
||||
WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
|
||||
dequeue_tm(tm);
|
||||
|
||||
// Call timer function
|
||||
uint32 addr = ReadMacInt32(tm + tmAddr);
|
||||
if (addr) {
|
||||
D(bug("Calling TimeTask %08lx, addr %08lx\n", tm, addr));
|
||||
M68kRegisters r;
|
||||
r.a[0] = addr;
|
||||
r.a[1] = tm;
|
||||
Execute68k(addr, &r);
|
||||
}
|
||||
// Call timer function
|
||||
uint32 addr = ReadMacInt32(tm + tmAddr);
|
||||
if (addr) {
|
||||
D(bug("Calling TimeTask %08lx, addr %08lx\n", tm, addr));
|
||||
M68kRegisters r;
|
||||
r.a[0] = addr;
|
||||
r.a[1] = tm;
|
||||
Execute68k(r.a[0], &r);
|
||||
D(bug(" returned from TimeTask\n"));
|
||||
}
|
||||
}
|
||||
desc = next;
|
||||
}
|
||||
|
||||
#if PRECISE_TIMING
|
||||
// Look for next task to be called and set wakeup_time
|
||||
#if PRECISE_TIMING_BEOS
|
||||
while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
|
||||
suspend_thread(timer_thread);
|
||||
#endif
|
||||
#if PRECISE_TIMING_MACH
|
||||
semaphore_wait(wakeup_time_sem);
|
||||
thread_suspend(timer_thread);
|
||||
#endif
|
||||
#if PRECISE_TIMING_POSIX
|
||||
pthread_mutex_lock(&wakeup_time_lock);
|
||||
timer_thread_suspend();
|
||||
#endif
|
||||
wakeup_time = wakeup_time_max;
|
||||
for (TMDesc *d = tmDescList; d; d = d->next)
|
||||
if ((ReadMacInt16(d->task + qType) & 0x8000))
|
||||
if (timer_cmp_time(d->wakeup, wakeup_time) < 0)
|
||||
wakeup_time = d->wakeup;
|
||||
#if PRECISE_TIMING_BEOS
|
||||
release_sem(wakeup_time_sem);
|
||||
thread_info info;
|
||||
do {
|
||||
resume_thread(timer_thread); // This will unblock the thread
|
||||
get_thread_info(timer_thread, &info);
|
||||
} while (info.state == B_THREAD_SUSPENDED); // Sometimes, resume_thread() doesn't work (BeOS bug?)
|
||||
#endif
|
||||
#if PRECISE_TIMING_MACH
|
||||
semaphore_signal(wakeup_time_sem);
|
||||
thread_abort(timer_thread);
|
||||
thread_resume(timer_thread);
|
||||
#endif
|
||||
#if PRECISE_TIMING_POSIX
|
||||
pthread_mutex_unlock(&wakeup_time_lock);
|
||||
timer_thread_resume();
|
||||
assert(suspend_count == 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user