Compare commits
747 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6ed4adb0ed | ||
|
f16c24363c | ||
|
fd7e68573c | ||
|
f1873f0794 | ||
|
a01d98e584 | ||
|
c7a53a5be6 | ||
|
4633631d7e | ||
|
100608e0ac | ||
|
35a0b36a0d | ||
|
5470db3a5f | ||
|
d6802f3cb9 | ||
|
5b4e0c2b55 | ||
|
8175fae67a | ||
|
13c90eb542 | ||
|
f98665c577 | ||
|
8843f3feba | ||
|
514cf59398 | ||
|
03c133cd48 | ||
|
880abea32e | ||
|
fc9a8f2a89 | ||
|
40c467d958 | ||
|
4bde6385b8 | ||
|
688ef958e3 | ||
|
6da7223472 | ||
|
a1d4bc8375 | ||
|
197e2a91be | ||
|
4d9d628b67 | ||
|
f720feebbf | ||
|
6076808f5e | ||
|
0af17f0f40 | ||
|
81e5321bfc | ||
|
27d3666285 | ||
|
c6b794db3a | ||
|
1fa4c39a20 | ||
|
0ba148b6bb | ||
|
65540da3f7 | ||
|
e660757824 | ||
|
05a6d16dde | ||
|
79ec9af3f2 | ||
|
8f37df448f | ||
|
d710a71ba0 | ||
|
8dd211b662 | ||
|
398ed22b09 | ||
|
6f1da4335b | ||
|
c86dc364b1 | ||
|
70eb7a5eab | ||
|
c1cd2ba57e | ||
|
00da0ef87d | ||
|
be9abbf510 | ||
|
0b72e6b2f2 | ||
|
6ea39d7bfa | ||
|
c0abe031ee | ||
|
fe667863b2 | ||
|
e514e05dc8 | ||
|
d978d0a483 | ||
|
37cacdafa7 | ||
|
78e3696663 | ||
|
a0215a4f21 | ||
|
2310416c46 | ||
|
52db653ec1 | ||
|
6fe76e478f | ||
|
ba05ec743d | ||
|
05ef25a61e | ||
|
b26cc4ede7 | ||
|
8dc5f703e8 | ||
|
c05d7e47f4 | ||
|
9dc8489693 | ||
|
f443c97f70 | ||
|
4837ceb73f | ||
|
42299c9406 | ||
|
850bbfc31a | ||
|
1e95f51469 | ||
|
e525e5d62e | ||
|
18deb8846d | ||
|
34ce9afeae | ||
|
d0411b7d52 | ||
|
34fda8c9b5 | ||
|
b4a357e44f | ||
|
2b224f262b | ||
|
3c306e0899 | ||
|
e82ab0c7ca | ||
|
983064c694 | ||
|
9230d95bad | ||
|
8b0790588b | ||
|
0a9c43757a | ||
|
fccfe35c4f | ||
|
064fed63f5 | ||
|
f43f471124 | ||
|
f99abb32e2 | ||
|
18f044e90c | ||
|
5b961c031c | ||
|
500cce511f | ||
|
885d6ff706 | ||
|
efc182ce27 | ||
|
06ef87fe63 | ||
|
f3d8251072 | ||
|
0d5efc90ed | ||
|
30b8e4e970 | ||
|
3da1ddf5da | ||
|
bfdd1b85fb | ||
|
686d468d32 | ||
|
23b15678cd | ||
|
d1054abd90 | ||
|
d358c8359b | ||
|
9e9494ebf9 | ||
|
015ada7a33 | ||
|
12e832ebd3 | ||
|
e327d2a148 | ||
|
366f9686dd | ||
|
a2927401bc | ||
|
bbb339d641 | ||
|
8e76334c20 | ||
|
739f1e2161 | ||
|
4ee6ca5b94 | ||
|
347898ea53 | ||
|
6caed58be4 | ||
|
c4185832ba | ||
|
2b0994b086 | ||
|
f9acbc152d | ||
|
3eed21567e | ||
|
f3370cb149 | ||
|
494fb97e49 | ||
|
bd8786af0b | ||
|
f0a7499814 | ||
|
da4a90b724 | ||
|
96a9109915 | ||
|
f5a33edcf4 | ||
|
1bd98bdeb2 | ||
|
e4696a6539 | ||
|
74350d6133 | ||
|
cbf86b2e8f | ||
|
cb757dfaf9 | ||
|
5ad94d01d4 | ||
|
cdba71b353 | ||
|
01d187cf83 | ||
|
ab06ce74c5 | ||
|
1e2b227113 | ||
|
9d5dbe67fe | ||
|
9a409ca347 | ||
|
449acece05 | ||
|
ee3f6fc4a5 | ||
|
e95b51609c | ||
|
323589a484 | ||
|
33f4b25f28 | ||
|
538d965636 | ||
|
4b99110533 | ||
|
94f2489083 | ||
|
6de1b1fd96 | ||
|
80abcdfe95 | ||
|
0dc6588a66 | ||
|
65ad05c608 | ||
|
2db8890453 | ||
|
3f4268328e | ||
|
33cabb487b | ||
|
ab2ca897ce | ||
|
2c37e150a9 | ||
|
ee68f2575a | ||
|
4f100266c3 | ||
|
c22a67f95f | ||
|
e6bc6371c9 | ||
|
2acca6d7b1 | ||
|
fc2095301d | ||
|
32f0b8c6f3 | ||
|
10c9b735e9 | ||
|
fefb511404 | ||
|
bedafe7b6f | ||
|
242d7f1700 | ||
|
90e892dfa5 | ||
|
c98e0751b0 | ||
|
f3b4a4e5fc | ||
|
1c7d71cadb | ||
|
840050738f | ||
|
2ee5cc7bf4 | ||
|
490180f9dc | ||
|
2582f3076d | ||
|
0032d42b2c | ||
|
5c70c20c6e | ||
|
71236aa405 | ||
|
31a38e2a62 | ||
|
ee0e4d5428 | ||
|
f6296e83e5 | ||
|
39840b5fb1 | ||
|
fe0bfccfaa | ||
|
25ee4e9b2b | ||
|
9f7d4c0ab0 | ||
|
038928232c | ||
|
100affa083 | ||
|
e27075955d | ||
|
0959a15b10 | ||
|
4a87e4d97b | ||
|
9de7caa68d | ||
|
e23d78eb86 | ||
|
d0b45fce78 | ||
|
0126dd53a3 | ||
|
901c8459ec | ||
|
746fed6704 | ||
|
54c0f2a670 | ||
|
28ea8ef24f | ||
|
115129e1dd | ||
|
f41d594015 | ||
|
c8abb42c3c | ||
|
95732265f6 | ||
|
9f834c4232 | ||
|
d10d8bf7ae | ||
|
f6a2db7866 | ||
|
d2fdbd29f5 | ||
|
f5dff9620b | ||
|
28e75a8fa2 | ||
|
6170c81af3 | ||
|
3d578170db | ||
|
d99499b6e3 | ||
|
950c434157 | ||
|
d6362a305f | ||
|
38bb033328 | ||
|
87f1ddd27f | ||
|
9e994560a7 | ||
|
e37de95079 | ||
|
8e46ae95ec | ||
|
e7cece0f0f | ||
|
890a4b996e | ||
|
5b2ae228cc | ||
|
9fc8315f92 | ||
|
32935cd7a1 | ||
|
fd02382d38 | ||
|
4fce263228 | ||
|
50c7e10814 | ||
|
7c8ab991be | ||
|
067e169803 | ||
|
ccdbbe799a | ||
|
fac53cfd54 | ||
|
cfe2c7bed5 | ||
|
f0b9b5cce4 | ||
|
803b868356 | ||
|
907452d918 | ||
|
c12bca7b4e | ||
|
e1736c8214 | ||
|
d3e7a991a4 | ||
|
e7b0d17a83 | ||
|
df18dc273e | ||
|
b6341e402d | ||
|
3f2f703936 | ||
|
4acee4531c | ||
|
2a476d3372 | ||
|
0a41cb044c | ||
|
5a0f736d41 | ||
|
020534dbc8 | ||
|
cee2801847 | ||
|
51c38a4723 | ||
|
bb01d1024a | ||
|
903a5d9b8b | ||
|
e360dea558 | ||
|
582443ef5c | ||
|
80a42216c7 | ||
|
6576f4d090 | ||
|
55e983e5a1 | ||
|
a6f9c733a1 | ||
|
3c129ff4e5 | ||
|
db386a5958 | ||
|
179cc694e3 | ||
|
887a51b176 | ||
|
5b81379dac | ||
|
4fff9f7060 | ||
|
40c407782d | ||
|
5946f17632 | ||
|
7e0ff7449c | ||
|
d597219aea | ||
|
a311396cf8 | ||
|
94607cab7f | ||
|
4d193a30b0 | ||
|
c1ad265f47 | ||
|
4e2a2c99ba | ||
|
ea33f253d4 | ||
|
ebc41560d9 | ||
|
2d2c696aa4 | ||
|
b622c25a56 | ||
|
439cf499ed | ||
|
cd5f1daaba | ||
|
ec95f6dc98 | ||
|
66dfe5df46 | ||
|
9117827cfc | ||
|
ad115701d5 | ||
|
a15125d6af | ||
|
dadd8eb41c | ||
|
056b49e1d1 | ||
|
1f492e7820 | ||
|
4c687dfa54 | ||
|
e1f5bdf48b | ||
|
3ba7e0a8a4 | ||
|
a71fae5bb1 | ||
|
f6c78d57ef | ||
|
6af50f5eae | ||
|
62ab925e01 | ||
|
5126ba482e | ||
|
fb477b33f7 | ||
|
756fe9354a | ||
|
73c2206a1a | ||
|
c1071ecd3c | ||
|
534ddc3a4c | ||
|
ebce50320f | ||
|
cfd2e5142a | ||
|
581137ade7 | ||
|
c3b46d6a78 | ||
|
84a8bf22e8 | ||
|
daeb3ddfdd | ||
|
bf5f5a807c | ||
|
3dfba389ff | ||
|
a4f1341587 | ||
|
57d8747cb7 | ||
|
1fb68c1bf3 | ||
|
5613a719c5 | ||
|
bf6343616b | ||
|
861eeaefe2 | ||
|
db3c6a3135 | ||
|
4c7dafed25 | ||
|
b1440a9b3f | ||
|
21b5e75ddb | ||
|
49893f6976 | ||
|
c87887cbd1 | ||
|
bcd118a8b3 | ||
|
d7bfd0a668 | ||
|
aeceb36e2a | ||
|
f67d537c7c | ||
|
87d2163f2d | ||
|
639008b990 | ||
|
3c21ecb1d3 | ||
|
f764cf1936 | ||
|
44a9aaf89b | ||
|
925ee9d8f3 | ||
|
a04b09c737 | ||
|
2c9fd0e1a6 | ||
|
d7c9f15593 | ||
|
b61aa37f71 | ||
|
e80f9812ef | ||
|
84a0a9660f | ||
|
a93b495ac5 | ||
|
5d7dcf9373 | ||
|
2f5faaa5ab | ||
|
dfe233a95e | ||
|
92b72b19ec | ||
|
ff4a0802ea | ||
|
9adcbd2706 | ||
|
6981b28a64 | ||
|
7f41936df0 | ||
|
ccf72c6b77 | ||
|
c508d94d7c | ||
|
ce710fca5d | ||
|
ce0ac30280 | ||
|
dec7580d8d | ||
|
40001164d4 | ||
|
8bd5ec76c3 | ||
|
534a42d2fe | ||
|
226d8afc24 | ||
|
47531ac5e8 | ||
|
b3be121f41 | ||
|
e7e53580ea | ||
|
8a1eeee22d | ||
|
3e78933e9c | ||
|
637a10b234 | ||
|
c5dff3caf3 | ||
|
c529fc2b59 | ||
|
4886d0194f | ||
|
aae7d81cc6 | ||
|
8d18969940 | ||
|
68b57bb9a8 | ||
|
5aeec2fad4 | ||
|
73dece7b58 | ||
|
bfa1254eb7 | ||
|
e89aa11e86 | ||
|
4423837888 | ||
|
723f407757 | ||
|
f2338f1d13 | ||
|
235cbbc227 | ||
|
a2ca0de809 | ||
|
f7b00eff95 | ||
|
163354b33e | ||
|
7efd512ee9 | ||
|
7b7fe6c5a9 | ||
|
7abd615a18 | ||
|
14e5896e37 | ||
|
381aaa1509 | ||
|
f0f174e439 | ||
|
1f9226255a | ||
|
dcfa50e36e | ||
|
0b2c36ab1a | ||
|
0163fb729a | ||
|
d6c4828bef | ||
|
e7dbd39adf | ||
|
759a701df8 | ||
|
17ec90cfe7 | ||
|
e7ec859dfc | ||
|
da93410468 | ||
|
f38b366d81 | ||
|
8fbe96b9ac | ||
|
b48b8b836d | ||
|
967b315be5 | ||
|
ca995bf342 | ||
|
c58bb46e7e | ||
|
122dc12d40 | ||
|
cc576bd640 | ||
|
09641d16f5 | ||
|
552c4945bf | ||
|
34d6131471 | ||
|
9ecf1546cc | ||
|
7ffa623d92 | ||
|
8e81e6aad5 | ||
|
3a3a76a2e1 | ||
|
4027b2dbe0 | ||
|
62cede95ce | ||
|
abb2d7a417 | ||
|
f9afb3edb7 | ||
|
32c090880b | ||
|
be5626adc9 | ||
|
b1c68d04dd | ||
|
f9b7dd8418 | ||
|
8a6e3eb924 | ||
|
932c7ec222 | ||
|
e4e997fef2 | ||
|
3ec8a7bc06 | ||
|
d98c4b760f | ||
|
d67980d79f | ||
|
092592a05b | ||
|
586fab6b6b | ||
|
eab2a490f4 | ||
|
95992df67d | ||
|
89ba57e18d | ||
|
6f069946ba | ||
|
3df85b09fc | ||
|
fb5b69ae5c | ||
|
7350b11001 | ||
|
b7d7614471 | ||
|
f49027b2d7 | ||
|
d24e666f92 | ||
|
2ba46283b2 | ||
|
65b9c58504 | ||
|
02a2874a19 | ||
|
60868c71d3 | ||
|
9013952431 | ||
|
0b8304b40d | ||
|
1bc5a2ad7e | ||
|
5bb8ca0b89 | ||
|
7ecd6adb20 | ||
|
5b50389340 | ||
|
5f2e05d1dd | ||
|
3cc37acaa4 | ||
|
4680ee32f0 | ||
|
3dd23ec789 | ||
|
efd688320f | ||
|
d0fb062006 | ||
|
c229a27992 | ||
|
d3536a718e | ||
|
5909db71d5 | ||
|
96ada6e22a | ||
|
85f01b833c | ||
|
68a648440a | ||
|
a3bf7296bb | ||
|
dd1f5b9043 | ||
|
fcc2cbbebe | ||
|
470462fe8b | ||
|
301431f12a | ||
|
c0e524cd82 | ||
|
4068957442 | ||
|
bf89d7af33 | ||
|
d070e32b4d | ||
|
ad310f8484 | ||
|
7eb149a71b | ||
|
1c0db235a8 | ||
|
94181326ca | ||
|
cd7567452a | ||
|
2fec9f066f | ||
|
fe736289e6 | ||
|
715f295f5e | ||
|
a71c433fc4 | ||
|
9678814654 | ||
|
1598360b65 | ||
|
9d890228bf | ||
|
2d82727565 | ||
|
3851a4c2db | ||
|
17f56d0a69 | ||
|
1a6a98e57e | ||
|
5ddfc628dc | ||
|
bf5099f57b | ||
|
d4a381f71c | ||
|
17002e4c78 | ||
|
cf9a006005 | ||
|
1fa9828f6a | ||
|
3f9d042863 | ||
|
277afd156d | ||
|
b428b608b5 | ||
|
58361e39b8 | ||
|
3770a05aee | ||
|
5993f75c92 | ||
|
d7a2b98b4d | ||
|
02b28096af | ||
|
02e921364b | ||
|
4cf64ee170 | ||
|
c99c1756a9 | ||
|
5ccfab0342 | ||
|
42eea7f8f4 | ||
|
ff6bb8ccd5 | ||
|
2e3aea9d96 | ||
|
4954a285e7 | ||
|
46b52a57f7 | ||
|
41ba2e73f2 | ||
|
fbc9607e17 | ||
|
2e696d9e1a | ||
|
b09e9a2434 | ||
|
2e1c020db4 | ||
|
13629c70d4 | ||
|
b1b5ee737b | ||
|
884fe50dd7 | ||
|
af38f64a99 | ||
|
a22dfa6ba7 | ||
|
9fa8b644a7 | ||
|
375307822e | ||
|
c0152b1ce4 | ||
|
3460c06508 | ||
|
d3734a66e0 | ||
|
ccf13c78f0 | ||
|
2c28551ca3 | ||
|
4fb35a7af2 | ||
|
a2a22476ed | ||
|
1b22a5e3c5 | ||
|
ab06d85a91 | ||
|
80b1683fa2 | ||
|
d79aae3078 | ||
|
4c0e737508 | ||
|
86e0cbf9c2 | ||
|
142bc988b1 | ||
|
3ea44d1979 | ||
|
04d1abd803 | ||
|
ba1bc29b1a | ||
|
37776dfaee | ||
|
c28f342f3e | ||
|
354a420aa4 | ||
|
fb72e8baf8 | ||
|
976703f713 | ||
|
dc5afa6e79 | ||
|
740762d4a1 | ||
|
f0b7cddeb1 | ||
|
9b47a34840 | ||
|
bb8c31bf32 | ||
|
87ca43e5b7 | ||
|
411648b130 | ||
|
611f672b81 | ||
|
755c9234e1 | ||
|
c3c0583f19 | ||
|
55ddce2211 | ||
|
5971f9a80f | ||
|
fbfd597306 | ||
|
0184a550c5 | ||
|
2cdc95ba05 | ||
|
fefa462730 | ||
|
7b20e6cca0 | ||
|
ed82e3595b | ||
|
6cfdc0ce5f | ||
|
1f17f1c198 | ||
|
99da637734 | ||
|
afcc8bc101 | ||
|
4b2525b7a4 | ||
|
aa601a5727 | ||
|
85fad64e9c | ||
|
30d942478f | ||
|
89750c3f73 | ||
|
ee43223543 | ||
|
89ac4ee9b9 | ||
|
b411178aae | ||
|
45246a2f2d | ||
|
0c43952e37 | ||
|
f877e5b8c2 | ||
|
2d50d56606 | ||
|
bdecbe77e4 | ||
|
f39cb38eb3 | ||
|
148c288942 | ||
|
e2f822e7d1 | ||
|
0b58e9eaaf | ||
|
0a76a57f18 | ||
|
22ffbfa63c | ||
|
94a3097ba7 | ||
|
c05bd269ad | ||
|
aab71cbab3 | ||
|
1041ef03eb | ||
|
e2f36bbb9a | ||
|
5e9df61ffc | ||
|
cc5a90ac21 | ||
|
3900e1cf92 | ||
|
6b98a44fc0 | ||
|
2698595302 | ||
|
f6ab79319f | ||
|
264a80d88e | ||
|
020ab117a4 | ||
|
8457316815 | ||
|
58ffe2ad06 | ||
|
6f7efd9efc | ||
|
b84cce7609 | ||
|
8fc382c11e | ||
|
fadcb61bc7 | ||
|
7ebf71b161 | ||
|
003550337a | ||
|
c909995011 | ||
|
18cfbc713a | ||
|
806539a2d6 | ||
|
77f035e2b5 | ||
|
1d49e0a987 | ||
|
bcc20d3986 | ||
|
431c5d3282 | ||
|
ce5be92225 | ||
|
2ed3d8b445 | ||
|
f498da5e42 | ||
|
7d6eb36ee7 | ||
|
ecaab1b5b3 | ||
|
623b511ce6 | ||
|
80efe2351b | ||
|
91c907be7e | ||
|
fafbbe82d1 | ||
|
b3d80bcb0f | ||
|
4901e015f6 | ||
|
fdb52bcdc6 | ||
|
974688a8a5 | ||
|
2ad71ef867 | ||
|
c1083b44dc | ||
|
b0dc6fdd1e | ||
|
7f51d6330e | ||
|
3992b1d547 | ||
|
2c1a87ce02 | ||
|
529618ffa4 | ||
|
bcc5e9d362 | ||
|
6444ba58cf | ||
|
4fc3e019d5 | ||
|
dcebdeaa5f | ||
|
8a49ffd111 | ||
|
a19469d851 | ||
|
265be6e766 | ||
|
cac7db4358 | ||
|
4eaa6c8b1e | ||
|
9a0256449b | ||
|
299374aa50 | ||
|
5634abdba4 | ||
|
a6b3533e61 | ||
|
4ea3633b5a | ||
|
bcf19136d4 | ||
|
1abdd1476e | ||
|
7f31ee9c71 | ||
|
4ca9c82a2e | ||
|
0bc4e7cda6 | ||
|
36d6fc6760 | ||
|
7ea4356361 | ||
|
3821b228e9 | ||
|
d676ccc1bd | ||
|
1c1d7fefaa | ||
|
a7d7db37df | ||
|
5d51cf75e8 | ||
|
d9f81ad653 | ||
|
34947da898 | ||
|
0d7ffd787f | ||
|
fc6c83e9cd | ||
|
940cb4a5b9 | ||
|
c138c0f2ae | ||
|
2911321914 | ||
|
5a3cbff259 | ||
|
2ff3b6d3d5 | ||
|
da20b4d27a | ||
|
bc45bc08b9 | ||
|
064bf0f8e5 | ||
|
a305dbb1cd | ||
|
59b1d971d0 | ||
|
ef6598e94b | ||
|
5055635d3d | ||
|
04518e4ff3 | ||
|
4a8010a3a0 | ||
|
ae4b48c445 | ||
|
6cf8466dfd | ||
|
6bbf325720 | ||
|
2b0f074c94 | ||
|
f76599ac08 | ||
|
ee67c6dec1 | ||
|
16810b63d4 | ||
|
1e0450cd8a | ||
|
1d337f1244 | ||
|
cce2f272ef | ||
|
d48da32586 | ||
|
11f454390e | ||
|
8a33fe3e60 | ||
|
8ab46e29dd | ||
|
003306f961 | ||
|
cf28c1a618 | ||
|
8fd560a643 | ||
|
d5026ed9b0 | ||
|
57537cd43a | ||
|
eec4ed45d1 | ||
|
a9fc83d63c | ||
|
a5f4cf3252 | ||
|
6995f5a683 | ||
|
0309fcb286 | ||
|
38e1cd0bab | ||
|
157f9c00e5 | ||
|
44e6921842 | ||
|
ee03f08f52 | ||
|
a59f55c1f3 | ||
|
3be6d20006 | ||
|
70c6fb23cc | ||
|
e43c086545 | ||
|
06ab48461b | ||
|
8ea991db81 | ||
|
d9c84e3a15 | ||
|
8aeddf0316 | ||
|
8a27cba1f9 | ||
|
f808309058 | ||
|
ae15eca0ef | ||
|
781bb83dd1 | ||
|
1d4eb70414 | ||
|
75301fa12d | ||
|
f541cf3848 | ||
|
d9a8c5ea08 | ||
|
0889afbdae | ||
|
25a0c0b4ad | ||
|
0080a85345 | ||
|
50031f56af | ||
|
7d80dfac25 | ||
|
f6536a412e | ||
|
0f539d239c | ||
|
a0ef0b3be2 | ||
|
982fe17aed | ||
|
0a3ad006b7 | ||
|
f8f81f6d4c | ||
|
3377ac04fc | ||
|
aad35e0243 | ||
|
6e4bf52781 | ||
|
6cb15fd7d9 | ||
|
f7d6b52074 | ||
|
0f5e933002 | ||
|
9e3b014927 | ||
|
f5c13c02af | ||
|
63725f3511 | ||
|
da5326cc5f | ||
|
19e2498cc8 | ||
|
7858e32d12 | ||
|
454c4f5dbe | ||
|
eb16767bdb | ||
|
6e6e3b2adb | ||
|
3da58bf1ca | ||
|
4e76b34f53 | ||
|
d160b2ae65 | ||
|
4f76ffa311 | ||
|
9156db9c32 | ||
|
ecf8e69cf2 | ||
|
2027ac5d4c | ||
|
576d2a96cd |
|
@ -349,3 +349,8 @@ make/oscar64
|
|||
*.recipe
|
||||
*.exe
|
||||
*.dbj
|
||||
*.json
|
||||
*.mapd
|
||||
*.idb
|
||||
oscar64/Releasex64/oscar64.vcxproj.FileListAbsolute.txt
|
||||
/oscar64/Debugx64
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
# Project name and version
|
||||
project(oscar64 VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Define the executable
|
||||
add_executable(oscar64)
|
||||
|
||||
|
||||
# Glob all source files in the oscar64/ directory
|
||||
file(GLOB OSCAR64_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.h")
|
||||
|
||||
# Add the sources to the target
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${OSCAR64_SOURCES})
|
||||
|
||||
|
||||
# Add header files
|
||||
target_include_directories(oscar64 PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# Compiler settings based on configuration
|
||||
set_target_properties(oscar64 PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED YES
|
||||
CXX_EXTENSIONS NO
|
||||
)
|
||||
|
||||
# Set debug and release configurations
|
||||
target_compile_definitions(oscar64 PRIVATE $<$<CONFIG:Debug>:_DEBUG;_CONSOLE> $<$<CONFIG:Release>:NDEBUG;_CONSOLE>)
|
||||
target_compile_options(oscar64 PRIVATE $<$<CONFIG:Debug>:/W3 /WX> $<$<CONFIG:Release>:/O2 /W3>)
|
||||
|
||||
# Post-build steps (only for Release builds)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_custom_command(TARGET oscar64 POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:oscar64> ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(oscar64 PRIVATE kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32 version)
|
||||
elseif (APPLE)
|
||||
# Add macOS-specific frameworks to replace Windows libraries
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
"-framework Cocoa" # For GUI and application support
|
||||
"-framework CoreFoundation" # For Core Foundation utilities (similar to advapi32 or shell32)
|
||||
"-framework CoreGraphics" # For graphics and rendering (similar to gdi32)
|
||||
"-framework IOKit" # For hardware interaction
|
||||
"-framework AppKit" # For GUI (equivalent to user32)
|
||||
)
|
||||
elseif (UNIX)
|
||||
# Add Linux-specific libraries for equivalent functionality
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
pthread # For threading (similar to kernel32)
|
||||
dl # For dynamic library loading (similar to LoadLibrary)
|
||||
m # For math library (optional but common on Linux)
|
||||
X11 # For X Window System (similar to user32 for GUI support)
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
# Output directories
|
||||
set_target_properties(oscar64 PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release
|
||||
)
|
||||
|
|
@ -136,19 +136,17 @@ void test_member_assign(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
#if 0
|
||||
test_local_init();
|
||||
test_member_init();
|
||||
#endif
|
||||
|
||||
test_member_array_init();
|
||||
#if 0
|
||||
|
||||
test_local_copy();
|
||||
test_member_copy();
|
||||
|
||||
test_local_assign();
|
||||
test_member_assign();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct X
|
||||
{
|
||||
char t;
|
||||
long l;
|
||||
};
|
||||
|
||||
__striped X xs[16];
|
||||
X xf[16];
|
||||
char xp;
|
||||
|
||||
__noinline long tt(long n)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
inline auto & tas(void)
|
||||
{
|
||||
return xs[xp].l;
|
||||
}
|
||||
|
||||
inline auto & taf(void)
|
||||
{
|
||||
return xf[xp].l;
|
||||
}
|
||||
|
||||
long ts(char n)
|
||||
{
|
||||
return tt(tas());
|
||||
}
|
||||
|
||||
long tf(char n)
|
||||
{
|
||||
return tt(taf());
|
||||
}
|
||||
|
||||
inline auto bas(void)
|
||||
{
|
||||
return xs[xp].l;
|
||||
}
|
||||
|
||||
inline auto baf(void)
|
||||
{
|
||||
return xs[xp].l;
|
||||
}
|
||||
|
||||
long bs(char n)
|
||||
{
|
||||
return tt(bas());
|
||||
}
|
||||
|
||||
long bf(char n)
|
||||
{
|
||||
return tt(baf());
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(char i=0; i<16; i++)
|
||||
{
|
||||
xs[i].l = i * i;
|
||||
xf[i].l = i * i;
|
||||
}
|
||||
|
||||
for(char i=0; i<16; i++)
|
||||
{
|
||||
xp = i;
|
||||
assert(ts(0) == i * i);
|
||||
assert(tf(0) == i * i);
|
||||
assert(bs(0) == i * i);
|
||||
assert(bf(0) == i * i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,54 +1,75 @@
|
|||
rem @echo off
|
||||
|
||||
@call :test rolrortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test bitfields.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_string.cpp
|
||||
@call :testn autorefreturn.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_array.cpp
|
||||
@call :testh opp_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_vector.cpp
|
||||
@call :testh opp_array.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_vector_string.cpp
|
||||
@call :testh opp_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_streamtest.cpp
|
||||
@call :testh opp_static_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_pairtest.cpp
|
||||
@call :testh opp_vector_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test opp_parts.cpp
|
||||
@call :testh opp_string_init.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test operatoroverload.cpp
|
||||
@call :testh opp_streamtest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test virtualdestruct.cpp
|
||||
@call :testh opp_pairtest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test vcalltest.cpp
|
||||
@call :testh opp_parts.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test vcalltree.cpp
|
||||
@call :testh opp_list.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test constructortest.cpp
|
||||
@call :testn opp_functional.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test copyconstructor.cpp
|
||||
@call :testh operatoroverload.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test copyassign.cpp
|
||||
@call :testh virtualdestruct.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test arrayconstruct.cpp
|
||||
@call :testh vcalltest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test stdlibtest.c
|
||||
@call :testh vcalltree.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh constructortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testn copyconstructor.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyassign.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh arrayconstruct.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh stdlibtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test mathtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test testint16.c
|
||||
|
@ -75,6 +96,9 @@ rem @echo off
|
|||
@call :test fastcalltest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test strlen.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test strcmptest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -99,6 +123,9 @@ rem @echo off
|
|||
@call :test floatmultest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test floatinttest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test staticconsttest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -138,6 +165,9 @@ rem @echo off
|
|||
@call :test qsorttest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testn plasma.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test loopdomtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -165,6 +195,12 @@ rem @echo off
|
|||
@call :test divmodtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test divmod32test.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test fixmathtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test enumswitch.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -216,77 +252,149 @@ rem @echo off
|
|||
@call :testn stripedarraytest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testn mmultest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test tileexpand.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:error
|
||||
echo Failed with error #%errorlevel%.
|
||||
exit /b %errorlevel%
|
||||
|
||||
:testh
|
||||
..\bin\oscar64 -e -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O0 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O0 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -Os -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -Os -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O3 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O3 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O3 -n -dHEAPCHECK %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:test
|
||||
..\release\oscar64 -e -bc %~1
|
||||
..\bin\oscar64 -e -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -n %~1
|
||||
..\bin\oscar64 -e -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O2 -bc %~1
|
||||
..\bin\oscar64 -e -O2 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O2 -n %~1
|
||||
..\bin\oscar64 -e -O2 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O0 -bc %~1
|
||||
..\bin\oscar64 -e -O0 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O0 -n %~1
|
||||
..\bin\oscar64 -e -O0 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -Os -bc %~1
|
||||
..\bin\oscar64 -e -Os -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -Os -n %~1
|
||||
..\bin\oscar64 -e -Os -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O3 -bc %~1
|
||||
..\bin\oscar64 -e -O3 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O3 -n %~1
|
||||
..\bin\oscar64 -e -O3 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:testb
|
||||
..\release\oscar64 -e -bc %~1
|
||||
..\bin\oscar64 -e -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -bc -O2 %~1
|
||||
..\bin\oscar64 -e -bc -O2 %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -bc -O0 %~1
|
||||
..\bin\oscar64 -e -bc -O0 %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -bc -Os %~1
|
||||
..\bin\oscar64 -e -bc -Os %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -bc -O3 %~1
|
||||
..\bin\oscar64 -e -bc -O3 %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:testn
|
||||
..\release\oscar64 -e -n %~1
|
||||
..\bin\oscar64 -e -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O2 -n %~1
|
||||
..\bin\oscar64 -e -O2 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O0 -n %~1
|
||||
..\bin\oscar64 -e -O0 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -Os -n %~1
|
||||
..\bin\oscar64 -e -Os -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\release\oscar64 -e -O3 -n %~1
|
||||
..\bin\oscar64 -e -O3 -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
|
|
@ -232,7 +232,106 @@ void test_word_signed(void)
|
|||
}
|
||||
}
|
||||
|
||||
void test_inc_char_fit(void)
|
||||
{
|
||||
A ai;
|
||||
ai.x = 7;
|
||||
ai.y = 1;
|
||||
ai.z = 2;
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
assert(ai.x == ((7 + i) & 15));
|
||||
assert(ai.y == ((1 + i) & 1));
|
||||
assert(ai.z == ((2 + i) & 7));
|
||||
ai.x++;
|
||||
ai.y++;
|
||||
ai.z++;
|
||||
}
|
||||
}
|
||||
|
||||
void test_inc_char_cross(void)
|
||||
{
|
||||
B bi;
|
||||
bi.x = 11;
|
||||
bi.y = 22;
|
||||
bi.z = 33;
|
||||
bi.w = 44;
|
||||
|
||||
for(int i=0; i<64; i++)
|
||||
{
|
||||
assert(bi.x == ((11 + i) & 0x3f));
|
||||
assert(bi.y == ((22 + i) & 0x3f));
|
||||
assert(bi.z == ((33 + i) & 0x3f));
|
||||
assert(bi.w == ((44 + i) & 0x3f));
|
||||
bi.x++;
|
||||
bi.y++;
|
||||
bi.z++;
|
||||
bi.w++;
|
||||
}
|
||||
}
|
||||
|
||||
void test_add_char_cross(void)
|
||||
{
|
||||
B bi= {0};
|
||||
bi.x = 11;
|
||||
bi.y = 22;
|
||||
bi.z = 33;
|
||||
bi.w = 44;
|
||||
|
||||
for(int i=0; i<64; i++)
|
||||
{
|
||||
assert(bi.x == ((11 + 5 * i) & 0x3f));
|
||||
assert(bi.y == ((22 + 21 * i) & 0x3f));
|
||||
assert(bi.z == ((33 - 4 * i) & 0x3f));
|
||||
assert(bi.w == ((44 - 11 * i) & 0x3f));
|
||||
bi.x += 5;
|
||||
bi.y += 21;
|
||||
bi.z -= 4;
|
||||
bi.w -= 11;
|
||||
}
|
||||
}
|
||||
|
||||
void test_add_word_fit(void)
|
||||
{
|
||||
C ci = {0};
|
||||
|
||||
ci.x = 7;
|
||||
ci.y = 1;
|
||||
ci.z = 2;
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
assert(ci.x == ((7 + 5 * i) & 15));
|
||||
assert(ci.y == ((1 + 21 * i) & 1));
|
||||
assert(ci.z == ((2 - 4 * i) & 7));
|
||||
ci.x += 5;
|
||||
ci.y += 21;
|
||||
ci.z -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
void test_add_word_cross(void)
|
||||
{
|
||||
D di = {0};
|
||||
|
||||
di.x = 111;
|
||||
di.y = 222;
|
||||
di.z = 333;
|
||||
di.w = 444;
|
||||
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
assert(di.x == ((111 + 5 * i) & 0x3ff));
|
||||
assert(di.y == ((222 + 21 * i) & 0x3ff));
|
||||
assert(di.z == ((333 - 4 * i) & 0x3ff));
|
||||
assert(di.w == ((444 - 11 * i) & 0x3ff));
|
||||
di.x += 5;
|
||||
di.y += 21;
|
||||
di.z -= 4;
|
||||
di.w -= 11;
|
||||
}
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
test_char_fit();
|
||||
|
@ -244,5 +343,12 @@ int main(void)
|
|||
test_char_signed();
|
||||
test_word_signed();
|
||||
|
||||
test_inc_char_fit();
|
||||
test_inc_char_cross();
|
||||
test_add_char_cross();
|
||||
|
||||
test_add_word_fit();
|
||||
test_add_word_cross();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -303,6 +303,18 @@ void shr32n(unsigned long xu, long xi)
|
|||
}
|
||||
}
|
||||
|
||||
void shl1_32n(void)
|
||||
{
|
||||
static const unsigned long m[] = {
|
||||
#for(i, 32) 1ul << i,
|
||||
};
|
||||
|
||||
for(int i=0; i<32; i++)
|
||||
{
|
||||
assert(1ul << i == m[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(shl32n)
|
||||
#pragma native(shr32n)
|
||||
|
||||
|
@ -373,24 +385,30 @@ int main(void)
|
|||
shr16n(0xfedc, 0xfedc);
|
||||
|
||||
shl32b(0x00000000UL, 0x00000000L);
|
||||
shl32b(0x00000001UL, 0x00000001L);
|
||||
shl32b(0xffffffffUL, 0xffffffffL);
|
||||
shl32b(0x12345678UL, 0x12345678L);
|
||||
shl32b(0xfedcba98UL, 0xfedcba98L);
|
||||
|
||||
shr32b(0x00000000UL, 0x00000000L);
|
||||
shr32b(0x00000001UL, 0x00000001L);
|
||||
shr32b(0xffffffffUL, 0xffffffffL);
|
||||
shr32b(0x12345678UL, 0x12345678L);
|
||||
shr32b(0xfedcba98UL, 0xfedcba98L);
|
||||
|
||||
shl32n(0x00000000UL, 0x00000000L);
|
||||
shl32n(0x00000001UL, 0x00000001L);
|
||||
shl32n(0xffffffffUL, 0xffffffffL);
|
||||
shl32n(0x12345678UL, 0x12345678L);
|
||||
shl32n(0xfedcba98UL, 0xfedcba98L);
|
||||
|
||||
shr32n(0x00000000UL, 0x00000000L);
|
||||
shr32n(0x00000001UL, 0x00000001L);
|
||||
shr32n(0xffffffffUL, 0xffffffffL);
|
||||
shr32n(0x12345678UL, 0x12345678L);
|
||||
shr32n(0xfedcba98UL, 0xfedcba98L);
|
||||
|
||||
shl1_32n();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
|
@ -161,7 +162,7 @@ void test_return_value(void)
|
|||
C2 c(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_return_reference(void)
|
||||
|
@ -184,7 +185,7 @@ void test_retparam_value(void)
|
|||
test_param_fv(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_retparam_reference(void)
|
||||
|
@ -200,7 +201,6 @@ void test_retparam_reference(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
#if 0
|
||||
test_dcopy_init();
|
||||
test_copy_init();
|
||||
test_minit();
|
||||
|
@ -208,9 +208,8 @@ int main(void)
|
|||
test_param_value();
|
||||
test_param_ref();
|
||||
test_return_value();
|
||||
#endif
|
||||
test_retparam_value();
|
||||
// test_retparam_reference();
|
||||
test_retparam_reference();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#include <assert.h>
|
||||
|
||||
void check(unsigned long l, unsigned long r)
|
||||
{
|
||||
unsigned long d = l / r, m = l % r;
|
||||
|
||||
assert(d * r + m == l);
|
||||
assert(m < r);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(char i=0; i<28; i++)
|
||||
{
|
||||
for(char j=0; j<28; j++)
|
||||
{
|
||||
check(0xb3ul << i, 0x2bul << j);
|
||||
check(0xb3ul << i, 0x01ul << j);
|
||||
check(0x01ul << i, 0xc2ul << j);
|
||||
check(0xb31ful << i, 0x2bul << j);
|
||||
check(0xb354ul << i, 0x01ul << j);
|
||||
check(0xb3ul << i, 0x2b1cul << j);
|
||||
check(0xb3ul << i, 0x013ful << j);
|
||||
check(0xb31ful << i, 0x2b23ul << j);
|
||||
check(0xb354ul << i, 0x0145ul << j);
|
||||
check(0xb31f24ul << i, 0x2bul << j);
|
||||
check(0xb35421ul << i, 0x01ul << j);
|
||||
check(0xb31f24ul << i, 0x2b23ul << j);
|
||||
check(0xb35421ul << i, 0x0145ul << j);
|
||||
check(0xb31f24ul << i, 0x2b2356ul << j);
|
||||
check(0xb35421ul << i, 0x0145a7ul << j);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
#include <fixmath.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned tval[] = {
|
||||
1, 2, 16, 128, 255, 256, 4096, 32768, 65535
|
||||
};
|
||||
|
||||
void testmuldiv16u(void)
|
||||
{
|
||||
for (char i=0; i<9; i++)
|
||||
{
|
||||
assert(lmuldiv16u(tval[i], 0, tval[i]) == 0);
|
||||
assert(lmuldiv16u(0, tval[i], tval[i]) == 0);
|
||||
for(char j=0; j<9; j++)
|
||||
{
|
||||
assert(lmuldiv16u(tval[i], tval[j], tval[i]) == tval[j]);
|
||||
assert(lmuldiv16u(tval[j], tval[i], tval[i]) == tval[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<10000; i++)
|
||||
{
|
||||
unsigned a = rand();
|
||||
unsigned b = rand();
|
||||
unsigned c = rand();
|
||||
if (c > 0)
|
||||
{
|
||||
unsigned long d = (unsigned long)a * (unsigned long) b / c;
|
||||
if (d < 0x10000l)
|
||||
assert(lmuldiv16u(a, b, c) == d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ival[] = {
|
||||
1, 2, 16, 128, 255, 256, 4096, 32767,
|
||||
-1, -2, -16, -128, -255, -256, -4096, -32767
|
||||
};
|
||||
|
||||
void testmuldiv16s(void)
|
||||
{
|
||||
for (char i=0; i<16; i++)
|
||||
{
|
||||
assert(lmuldiv16s(ival[i], 0, ival[i]) == 0);
|
||||
assert(lmuldiv16s(0, ival[i], ival[i]) == 0);
|
||||
for(char j=0; j<16; j++)
|
||||
{
|
||||
assert(lmuldiv16s(ival[i], ival[j], ival[i]) == ival[j]);
|
||||
assert(lmuldiv16s(ival[j], ival[i], ival[i]) == ival[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<10000; i++)
|
||||
{
|
||||
int a = rand();
|
||||
int b = rand();
|
||||
int c = rand();
|
||||
|
||||
if (c > 0)
|
||||
{
|
||||
long d = (long)a * (long)b / c;
|
||||
if (d >= -32768 && d <= 32767)
|
||||
assert(lmuldiv16s(a, b, c) == d);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testlmul4f12s(void)
|
||||
{
|
||||
for(int i=0; i<20000; i++)
|
||||
{
|
||||
int a = rand();
|
||||
int b = rand();
|
||||
|
||||
long d = ((long)a * (long)b) >> 12;
|
||||
if (d >= -32768 && d <= 32767)
|
||||
assert(lmul4f12s(a, b) == d);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
testlmul4f12s();
|
||||
testmuldiv16u();
|
||||
testmuldiv16s();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
float a;
|
||||
int i;
|
||||
long li;
|
||||
unsigned u;
|
||||
unsigned long lu;
|
||||
|
||||
a = 1.0;
|
||||
i = 1;
|
||||
for(int j=0; j<15; j++)
|
||||
{
|
||||
assert(i == (int)a);
|
||||
assert(a == (float)i);
|
||||
a *= 2.0;
|
||||
i <<= 1;
|
||||
}
|
||||
|
||||
a = -1.0;
|
||||
i = -1;
|
||||
for(int j=0; j<15; j++)
|
||||
{
|
||||
assert(i == (int)a);
|
||||
assert(a == (float)i);
|
||||
a *= 2.0;
|
||||
i <<= 1;
|
||||
}
|
||||
|
||||
a = 1.0;
|
||||
u = 1;
|
||||
for(int j=0; j<16; j++)
|
||||
{
|
||||
assert(u == (unsigned)a);
|
||||
assert(a == (float)u);
|
||||
a *= 2.0;
|
||||
u <<= 1;
|
||||
}
|
||||
|
||||
a = 1.0;
|
||||
li = 1;
|
||||
for(int j=0; j<31; j++)
|
||||
{
|
||||
assert(li == (long)a);
|
||||
assert(a == (float)li);
|
||||
a *= 2.0;
|
||||
li <<= 1;
|
||||
}
|
||||
|
||||
a = -1.0;
|
||||
li = -1;
|
||||
for(int j=0; j<31; j++)
|
||||
{
|
||||
assert(li == (long)a);
|
||||
assert(a == (float)li);
|
||||
a *= 2.0;
|
||||
li <<= 1;
|
||||
}
|
||||
|
||||
a = 1.0;
|
||||
lu = 1;
|
||||
for(int j=0; j<32; j++)
|
||||
{
|
||||
assert(lu == (unsigned long)a);
|
||||
assert(a == (float)lu);
|
||||
a *= 2.0;
|
||||
lu <<= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,50 +1,60 @@
|
|||
CC=../bin/oscar64
|
||||
CXX=$(CC)
|
||||
SRCS=$(wildcard *.c *.cpp)
|
||||
SRCS=$(filter-out opp_part1.cpp opp_part2.cpp, $(wildcard *.c *.cpp))
|
||||
EXES=$(patsubst %.c,%,$(SRCS))
|
||||
EXES:=$(patsubst %.cpp,%,$(EXES))
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
%: %.c
|
||||
$(CC) -e -bc $<
|
||||
$(CC) -e -n $<
|
||||
$(CC) -e -O2 -bc $<
|
||||
$(CC) -e -O2 -n $<
|
||||
$(CC) -e -O0 -bc $<
|
||||
$(CC) -e -O0 -n $<
|
||||
$(CC) -e -Os -bc $<
|
||||
$(CC) -e -Os -n $<
|
||||
$(CC) -e -O3 -bc $<
|
||||
$(CC) -e -O3 -n $<
|
||||
$(OSCAR64_CC) -e -bc $<
|
||||
$(OSCAR64_CC) -e -n $<
|
||||
$(OSCAR64_CC) -e -O2 -bc $<
|
||||
$(OSCAR64_CC) -e -O2 -n $<
|
||||
$(OSCAR64_CC) -e -O0 -bc $<
|
||||
$(OSCAR64_CC) -e -O0 -n $<
|
||||
$(OSCAR64_CC) -e -Os -bc $<
|
||||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -bc $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
%: %.cpp
|
||||
$(CXX) -e -bc $<
|
||||
$(CXX) -e -n $<
|
||||
$(CXX) -e -O2 -bc $<
|
||||
$(CXX) -e -O2 -n $<
|
||||
$(CXX) -e -O0 -bc $<
|
||||
$(CXX) -e -O0 -n $<
|
||||
$(CXX) -e -Os -bc $<
|
||||
$(CXX) -e -Os -n $<
|
||||
$(CXX) -e -O3 -bc $<
|
||||
$(CXX) -e -O3 -n $<
|
||||
$(OSCAR64_CXX) -e -bc $<
|
||||
$(OSCAR64_CXX) -e -n $<
|
||||
$(OSCAR64_CXX) -e -O2 -bc $<
|
||||
$(OSCAR64_CXX) -e -O2 -n $<
|
||||
$(OSCAR64_CXX) -e -O0 -bc $<
|
||||
$(OSCAR64_CXX) -e -O0 -n $<
|
||||
$(OSCAR64_CXX) -e -Os -bc $<
|
||||
$(OSCAR64_CXX) -e -Os -n $<
|
||||
$(OSCAR64_CXX) -e -O3 -bc $<
|
||||
$(OSCAR64_CXX) -e -O3 -n $<
|
||||
|
||||
# testb
|
||||
bitshifttest: bitshifttest.c
|
||||
$(CC) -e -bc $<
|
||||
$(CC) -e -bc -O2 $<
|
||||
$(CC) -e -bc -O0 $<
|
||||
$(CC) -e -bc -Os $<
|
||||
$(CC) -e -bc -O3 $<
|
||||
$(CC) -e -n $<
|
||||
$(OSCAR64_CC) -e -bc $<
|
||||
$(OSCAR64_CC) -e -bc -O2 $<
|
||||
$(OSCAR64_CC) -e -bc -O0 $<
|
||||
$(OSCAR64_CC) -e -bc -Os $<
|
||||
$(OSCAR64_CC) -e -bc -O3 $<
|
||||
$(OSCAR64_CC) -e -n $<
|
||||
|
||||
# testn
|
||||
stripedarraytest: stripedarraytest.c
|
||||
$(CC) -e -O2 -n $<
|
||||
$(CC) -e -O0 -n $<
|
||||
$(CC) -e -Os -n $<
|
||||
$(CC) -e -O3 -n $<
|
||||
$(OSCAR64_CC) -e -O2 -n $<
|
||||
$(OSCAR64_CC) -e -O0 -n $<
|
||||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
autorefreturn: autorefreturn.cpp
|
||||
$(OSCAR64_CC) -e -O2 -n $<
|
||||
$(OSCAR64_CC) -e -O0 -n $<
|
||||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
copyconstructor: copyconstructor.cpp
|
||||
$(OSCAR64_CC) -e -O2 -n $<
|
||||
$(OSCAR64_CC) -e -O0 -n $<
|
||||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
clean:
|
||||
$(RM) *.asm *.bcs *.int *.lbl *.map *.prg
|
||||
@$(RM) *.asm *.bcs *.int *.lbl *.map *.prg
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include <gfx/vector3d.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Matrix4 ml, mr;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(char i=0; i<16; i++)
|
||||
{
|
||||
for(char j=0; j<16; j++)
|
||||
{
|
||||
for(char k=0; k<16; k++)
|
||||
{
|
||||
ml.m[k] = (i == k) ? 1.0 : 0.0;
|
||||
mr.m[k] = (j == k) ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
mat4_mmul(&ml, &mr);
|
||||
|
||||
#if 0
|
||||
printf("%d, %d\n", i, j);
|
||||
for(char k=0; k<16; k++)
|
||||
printf("%f ", ml.m[k]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
for(char k=0; k<16; k++)
|
||||
{
|
||||
char ix = i & 3, iy = i >> 2;
|
||||
char jx = j & 3, jy = j >> 2;
|
||||
char kx = k & 3, ky = k >> 2;
|
||||
|
||||
if (ky == jy && kx == ix && jx == iy)
|
||||
assert(ml.m[k] == 1.0);
|
||||
else
|
||||
assert(ml.m[k] == 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include <opp/functional.h>
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
virtual int eval(void) const = 0;
|
||||
};
|
||||
|
||||
class ConstNode : public Node
|
||||
{
|
||||
private:
|
||||
int v;
|
||||
public:
|
||||
ConstNode(int v_) : v(v_) {}
|
||||
virtual int eval(void) const
|
||||
{
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
class BinaryNode : public Node
|
||||
{
|
||||
private:
|
||||
opp::function<int(int, int)> op;
|
||||
Node * left, * right;
|
||||
public:
|
||||
BinaryNode(opp::function<int(int, int)> op_, Node * left_, Node * right_);
|
||||
|
||||
virtual int eval(void) const
|
||||
{
|
||||
return op(left->eval(), right->eval());
|
||||
}
|
||||
};
|
||||
|
||||
inline BinaryNode::BinaryNode(opp::function<int(int, int)> op_, Node * left_, Node * right_)
|
||||
: op(op_), left(left_), right(right_) {}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Node * s1 =
|
||||
new BinaryNode([=](int a, int b){return a + b;},
|
||||
new ConstNode(7), new ConstNode(11)
|
||||
);
|
||||
|
||||
return s1->eval() - 18;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#include <opp/list.h>
|
||||
#include <opp/algorithm.h>
|
||||
#include <assert.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::list<int> a;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
a.push_back(i);
|
||||
|
||||
int s = 0;
|
||||
for(auto i : a)
|
||||
s += i;
|
||||
|
||||
assert(s == 45);
|
||||
|
||||
auto li = a.begin();
|
||||
for(int i=0; i<5; i++)
|
||||
{
|
||||
li = a.erase(li);
|
||||
li++;
|
||||
}
|
||||
|
||||
s = 0;
|
||||
for(auto i : a)
|
||||
s += i;
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
opp::list<int> b;
|
||||
|
||||
b = a;
|
||||
|
||||
s = 0;
|
||||
for(auto i : b)
|
||||
s += i;
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
opp::list<int> c = opp::list<int>(b);
|
||||
|
||||
s = 0;
|
||||
for(auto i : c)
|
||||
s += i;
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
s = 0;
|
||||
for(auto i : b)
|
||||
s += i;
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
#include <opp/static_vector.h>
|
||||
#include <opp/algorithm.h>
|
||||
#include <assert.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::static_vector<int, 20> a;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
a.push_back(i);
|
||||
|
||||
int s = 0;
|
||||
for(int i=0; i<a.size(); i++)
|
||||
s += a[i];
|
||||
|
||||
assert(s == 45);
|
||||
|
||||
for(int i=0; i<5; i++)
|
||||
a.erase(i);
|
||||
|
||||
s = 0;
|
||||
for(int i=0; i<a.size(); i++)
|
||||
s += a[i];
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
opp::static_vector<int, 100> v;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
v.push_back(i);
|
||||
|
||||
assert(v.size() == 10);
|
||||
v.insert(0, 20);
|
||||
assert(v.size() == 11);
|
||||
v.insert(6, 21);
|
||||
assert(v.size() == 12);
|
||||
v.insert(12, 22);
|
||||
|
||||
int * fi = opp::find(v.begin(), v.end(), 21);
|
||||
|
||||
fi = v.insert(fi, 30);
|
||||
fi = v.insert(fi, 31);
|
||||
fi = v.insert(fi, 32);
|
||||
|
||||
assert(v.size() == 16);
|
||||
assert(v[0] == 20);
|
||||
assert(v[15] == 22);
|
||||
assert(v[8] == 32);
|
||||
|
||||
fi = opp::find(v.begin(), v.end(), 32);
|
||||
|
||||
for(int i=0; i<30; i++)
|
||||
{
|
||||
fi = v.insert(fi, i + 40);
|
||||
}
|
||||
|
||||
assert(v.size() == 46);
|
||||
assert(v[28] == 60);
|
||||
|
||||
v.erase(10, 10);
|
||||
|
||||
for(int i : v)
|
||||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -10,7 +10,7 @@ static const char AndBeyond[] = "And Beyond";
|
|||
static const char And[] = "And";
|
||||
static const char HelloWorldAndBeyond[] = "Hello World And Beyond";
|
||||
|
||||
void test_create(void)
|
||||
__noinline void test_create(void)
|
||||
{
|
||||
string s1();
|
||||
string s2(HelloWorld);
|
||||
|
@ -22,7 +22,7 @@ void test_create(void)
|
|||
assert(s4.size() == 1 && s4[0] == 'a');
|
||||
}
|
||||
|
||||
void test_concat(void)
|
||||
__noinline void test_concat(void)
|
||||
{
|
||||
string s1();
|
||||
string s2(HelloWorld);
|
||||
|
@ -51,7 +51,7 @@ __noinline void test_find(void)
|
|||
assert(s1.find(' ', 6) == 11);
|
||||
}
|
||||
|
||||
void test_assign(void)
|
||||
__noinline void test_assign(void)
|
||||
{
|
||||
string s1(HelloWorld);
|
||||
string s2(AndBeyond);
|
||||
|
@ -77,9 +77,12 @@ void test_assign(void)
|
|||
assert(!strcmp(s3.tocstr(), HelloWorld));
|
||||
}
|
||||
|
||||
static char * test;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char * p = new char;
|
||||
test = new char;
|
||||
|
||||
unsigned avail = heapfree();
|
||||
|
||||
test_create();
|
||||
|
@ -94,5 +97,7 @@ int main(void)
|
|||
test_assign();
|
||||
assert(avail == heapfree());
|
||||
|
||||
delete test;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
#include <opp/string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
using opp::string;
|
||||
|
||||
|
||||
const string s1;
|
||||
const string s2 = "Hello";
|
||||
const string s3{"World"};
|
||||
|
||||
const string a1[2];
|
||||
const string a2[2] = {"Hello", "World"};
|
||||
const string a3[2] = {opp::string("Hello"), opp::string("World")};
|
||||
|
||||
|
||||
const string d1[3][2];
|
||||
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
|
||||
const string d3[3][2] =
|
||||
{{opp::string("Hello"), opp::string("World")},
|
||||
{opp::string("aaa"), opp::string("bbb")},
|
||||
{opp::string("ccc"), opp::string("ddd")}};
|
||||
|
||||
void test_global_init(void)
|
||||
{
|
||||
assert(!strcmp(s1.tocstr(), ""));
|
||||
assert(!strcmp(s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
|
||||
void test_global_ainit(void)
|
||||
{
|
||||
assert(!strcmp(a1[0].tocstr(), ""));
|
||||
assert(!strcmp(a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a2[1].tocstr(), "World"));
|
||||
|
||||
assert(!strcmp(a3[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a3[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_global_dinit(void)
|
||||
{
|
||||
assert(!strcmp(d1[0][0].tocstr(), ""));
|
||||
assert(!strcmp(d1[2][1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(d2[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d2[2][1].tocstr(), "ddd"));
|
||||
|
||||
assert(!strcmp(d3[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d3[2][1].tocstr(), "ddd"));
|
||||
}
|
||||
|
||||
|
||||
void test_local_init(void)
|
||||
{
|
||||
const string s1;
|
||||
const string s2 = "Hello";
|
||||
const string s3{"World"};
|
||||
|
||||
assert(!strcmp(s1.tocstr(), ""));
|
||||
assert(!strcmp(s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
|
||||
void test_local_ainit(void)
|
||||
{
|
||||
const string a1[2];
|
||||
const string a2[2] = {"Hello", "World"};
|
||||
const string a3[2] = {opp::string("Hello"), opp::string("World")};
|
||||
|
||||
assert(!strcmp(a1[0].tocstr(), ""));
|
||||
assert(!strcmp(a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a2[1].tocstr(), "World"));
|
||||
|
||||
assert(!strcmp(a3[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a3[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_local_dinit(void)
|
||||
{
|
||||
const string d1[3][2];
|
||||
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
|
||||
const string d3[3][2] =
|
||||
{{opp::string("Hello"), opp::string("World")},
|
||||
{opp::string("aaa"), opp::string("bbb")},
|
||||
{opp::string("ccc"), opp::string("ddd")}};
|
||||
|
||||
assert(!strcmp(d1[0][0].tocstr(), ""));
|
||||
assert(!strcmp(d1[2][1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(d2[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d2[2][1].tocstr(), "ddd"));
|
||||
|
||||
assert(!strcmp(d3[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d3[2][1].tocstr(), "ddd"));
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
public:
|
||||
const string s1;
|
||||
const string s2 = "Hello";
|
||||
const string s3;
|
||||
|
||||
const string a1[2];
|
||||
const string a2[2] = {"Hello", "World"};
|
||||
|
||||
const string d1[3][2];
|
||||
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
|
||||
|
||||
X() : s3("World") {}
|
||||
};
|
||||
|
||||
void test_member_init(void)
|
||||
{
|
||||
X x;
|
||||
|
||||
assert(!strcmp(x.s1.tocstr(), ""));
|
||||
assert(!strcmp(x.s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(x.s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_member_ainit(void)
|
||||
{
|
||||
X x;
|
||||
|
||||
assert(!strcmp(x.a1[0].tocstr(), ""));
|
||||
assert(!strcmp(x.a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(x.a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(x.a2[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_member_dinit(void)
|
||||
{
|
||||
X x;
|
||||
|
||||
assert(!strcmp(x.d1[0][0].tocstr(), ""));
|
||||
assert(!strcmp(x.d1[2][1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(x.d2[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(x.d2[2][1].tocstr(), "ddd"));
|
||||
}
|
||||
|
||||
void test_copy_init(void)
|
||||
{
|
||||
X x;
|
||||
X y(x);
|
||||
|
||||
assert(!strcmp(y.s1.tocstr(), ""));
|
||||
assert(!strcmp(y.s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(y.s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_copy_ainit(void)
|
||||
{
|
||||
X x;
|
||||
X y(x);
|
||||
|
||||
assert(!strcmp(y.a1[0].tocstr(), ""));
|
||||
assert(!strcmp(y.a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(y.a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(y.a2[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_global_init();
|
||||
test_global_ainit();
|
||||
test_global_dinit();
|
||||
|
||||
for(int i=0; i<10000; i++)
|
||||
{
|
||||
test_local_init();
|
||||
test_local_ainit();
|
||||
}
|
||||
|
||||
test_member_init();
|
||||
test_member_ainit();
|
||||
|
||||
test_copy_init();
|
||||
test_copy_ainit();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#include <opp/vector.h>
|
||||
#include <opp/algorithm.h>
|
||||
#include <assert.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -23,5 +25,54 @@ int main(void)
|
|||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
opp::vector<int> v;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
v.push_back(i);
|
||||
|
||||
assert(v.size() == 10);
|
||||
v.insert(0, 20);
|
||||
assert(v.size() == 11);
|
||||
v.insert(6, 21);
|
||||
assert(v.size() == 12);
|
||||
v.insert(12, 22);
|
||||
|
||||
int * fi = opp::find(v.begin(), v.end(), 21);
|
||||
|
||||
fi = v.insert(fi, 30);
|
||||
fi = v.insert(fi, 31);
|
||||
fi = v.insert(fi, 32);
|
||||
|
||||
assert(v.size() == 16);
|
||||
assert(v[0] == 20);
|
||||
assert(v[15] == 22);
|
||||
assert(v[8] == 32);
|
||||
|
||||
fi = opp::find(v.begin(), v.end(), 32);
|
||||
|
||||
for(int i=0; i<30; i++)
|
||||
{
|
||||
fi = v.insert(fi, i + 40);
|
||||
}
|
||||
|
||||
assert(v.size() == 46);
|
||||
assert(v[28] == 60);
|
||||
|
||||
v.erase(10, 10);
|
||||
|
||||
for(int i : v)
|
||||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
static const char sintab[] = {
|
||||
128, 131, 134, 137, 140, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 179, 182, 185, 188, 191, 193, 196, 199, 201, 204, 206, 209, 211, 213, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 239, 240, 241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255,
|
||||
255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 239, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, 218, 216, 213, 211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179, 177, 174, 171, 168, 165, 162, 159, 156, 153, 150, 147, 144, 140, 137, 134, 131,
|
||||
128, 125, 122, 119, 116, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 77, 74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 21, 19, 17, 16, 15, 13, 12, 11, 10, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 2, 1, 1, 1,
|
||||
1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 19, 21, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 116, 119, 122, 125
|
||||
};
|
||||
|
||||
char Screen0[1024], Screen1[1024];
|
||||
|
||||
char colormap0[256], colormap1[256];
|
||||
|
||||
|
||||
char colors0[] = {0, 6, 14, 1, 13, 5, 0};
|
||||
char colors1[] = {0, 9, 7, 1, 15, 12, 0};
|
||||
|
||||
unsigned c1A, c1B, c2A, c2B, c3A, c3B;
|
||||
int d1A, d1B, d2A, d2B, d3A, d3B;
|
||||
|
||||
void inithires(void)
|
||||
{
|
||||
for(int i=0; i<256; i++)
|
||||
{
|
||||
colormap0[i] = colors0[i / 37];
|
||||
colormap1[i] = colors1[i / 37] << 4;
|
||||
}
|
||||
}
|
||||
|
||||
inline void doplasma(char * scrn)
|
||||
{
|
||||
char xbuf0[40], xbuf1[40];
|
||||
char ybuf0[25], ybuf1[25];
|
||||
|
||||
char c2a = c2A >> 8;
|
||||
char c2b = c2B >> 8;
|
||||
char c1a = c1A >> 8;
|
||||
char c1b = c1B >> 8;
|
||||
|
||||
for (char i = 0; i < 25; i++) {
|
||||
ybuf0[i] = sintab[(c1a + c2a) & 0xff] + sintab[c1b];
|
||||
c1a += 13;
|
||||
c1b -= 5;
|
||||
}
|
||||
|
||||
for (char i = 0; i < 40; i++) {
|
||||
xbuf0[i] = sintab[(c2a + c1b) & 0xff] + sintab[c2b];
|
||||
c2a += 11;
|
||||
c2b -= 7;
|
||||
}
|
||||
|
||||
c2a = c2B >> 8;
|
||||
c2b = c3A >> 8;
|
||||
c1a = c1B >> 8;
|
||||
c1b = c3B >> 8;
|
||||
|
||||
for (char i = 0; i < 25; i++) {
|
||||
ybuf1[i] = sintab[(c1b + c2a) & 0xff] + sintab[c1a];
|
||||
c1a += 4;
|
||||
c1b -= 6;
|
||||
}
|
||||
|
||||
for (char i = 0; i < 40; i++) {
|
||||
xbuf1[i] = sintab[(c2b + c1a) & 0xff] + sintab[c2a];
|
||||
c2a += 7;
|
||||
c2b -= 9;
|
||||
}
|
||||
|
||||
#pragma unroll(full)
|
||||
for (char k=0; k<5; k++)
|
||||
{
|
||||
char tbuf0[5], tbuf1[5];
|
||||
#pragma unroll(full)
|
||||
for (char i = 0; i < 4; i++)
|
||||
{
|
||||
tbuf0[i] = ybuf0[5 * k + i + 1] - ybuf0[5 * k + i];
|
||||
tbuf1[i] = ybuf1[5 * k + i + 1] - ybuf1[5 * k + i];
|
||||
}
|
||||
|
||||
for (signed char i = 39; i >= 0; i--)
|
||||
{
|
||||
char t = xbuf0[i] + ybuf0[5 * k];
|
||||
char u = xbuf1[i] + ybuf1[5 * k];
|
||||
|
||||
#pragma unroll(full)
|
||||
for (char j = 0; j < 5; j++)
|
||||
{
|
||||
scrn[40 * j + 200 * k + i] = colormap0[u] | colormap1[u];
|
||||
t += tbuf0[j];
|
||||
u += tbuf1[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c1A += 8 * ((int)sintab[d1A] - 128);
|
||||
c1B += 16 * ((int)sintab[d1B] - 128);
|
||||
c2A += 8 * ((int)sintab[d2A] - 128);
|
||||
c2B += 16 * ((int)sintab[d2B] - 128);
|
||||
c3A += 6 * ((int)sintab[d3A] - 128);
|
||||
c3B += 12 * ((int)sintab[d3B] - 128);
|
||||
|
||||
d1A += 3;
|
||||
d1B += rand() & 3;
|
||||
d2A += 5;
|
||||
d2B += rand() & 3;
|
||||
d3A += 2;
|
||||
d3B += rand() & 3;
|
||||
}
|
||||
|
||||
void doplasma0(void)
|
||||
{
|
||||
doplasma(Screen0);
|
||||
}
|
||||
|
||||
void doplasma1(void)
|
||||
{
|
||||
doplasma(Screen1);
|
||||
}
|
||||
|
||||
unsigned checksum(const char * scr)
|
||||
{
|
||||
unsigned s = 0x1234;
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
unsigned m = s & 1;
|
||||
s >>= 1;
|
||||
if (m)
|
||||
s ^= 0x2152;
|
||||
s ^= scr[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
inithires();
|
||||
|
||||
doplasma0();
|
||||
doplasma1();
|
||||
doplasma0();
|
||||
doplasma1();
|
||||
doplasma0();
|
||||
doplasma1();
|
||||
|
||||
return checksum(Screen0) + checksum(Screen1) - 16337;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
#include <assert.h>
|
||||
|
||||
__noinline unsigned long rollright32(unsigned long a) {
|
||||
unsigned long tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 31);
|
||||
}
|
||||
|
||||
__noinline unsigned rollright16(unsigned a) {
|
||||
unsigned tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 15);
|
||||
}
|
||||
|
||||
__noinline char rollright8(char a) {
|
||||
char tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 7);
|
||||
}
|
||||
|
||||
__noinline unsigned long rollleft32(unsigned long a) {
|
||||
unsigned long tmp = (a >> 31) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
__noinline unsigned rollleft16(unsigned a) {
|
||||
unsigned tmp = (a >> 15) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
__noinline char rollleft8(char a) {
|
||||
char tmp = (a >> 7) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
unsigned long lv = 0x12345678ul;
|
||||
unsigned val = 0x1234;
|
||||
char c=0x12;
|
||||
|
||||
unsigned long lvt[33];
|
||||
unsigned valt[17];
|
||||
char ct[9];
|
||||
|
||||
lvt[0] = lv;
|
||||
valt[0] = val;
|
||||
ct[0] = c;
|
||||
|
||||
assert(rollleft8(rollright8(c)) == c);
|
||||
assert(rollleft16(rollright16(val)) == val);
|
||||
assert(rollleft32(rollright32(lv)) == lv);
|
||||
|
||||
for(int i=0; i<32; i++)
|
||||
lvt[i + 1] = rollright32(lvt[i]);
|
||||
for(int i=0; i<16; i++)
|
||||
valt[i + 1] = rollright16(valt[i]);
|
||||
for(int i=0; i<8; i++)
|
||||
ct[i + 1] = rollright8(ct[i]);
|
||||
|
||||
for(int i=0; i<=32; i++)
|
||||
{
|
||||
assert(lvt[32 - i] == lv);
|
||||
lv = rollleft32(lv);
|
||||
}
|
||||
|
||||
for(int i=0; i<=16; i++)
|
||||
{
|
||||
assert(valt[16 - i] == val);
|
||||
val = rollleft16(val);
|
||||
}
|
||||
|
||||
for(int i=0; i<=8; i++)
|
||||
{
|
||||
assert(ct[8 - i] == c);
|
||||
c = rollleft8(c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
char lstr[1025];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#if 1
|
||||
assert(strlen("") == 0);
|
||||
assert(strlen("1") == 1);
|
||||
assert(strlen("12") == 2);
|
||||
assert(strlen("123") == 3);
|
||||
assert(strlen("1234") == 4);
|
||||
assert(strlen("12345") == 5);
|
||||
assert(strlen("123456") == 6);
|
||||
#endif
|
||||
#if 1
|
||||
char * dp = lstr;
|
||||
for(int i=0; i<1024; i++)
|
||||
{
|
||||
*dp = 0;
|
||||
assert(strlen(lstr) == i);
|
||||
*dp++ = 'a';
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -5,6 +5,11 @@ void testmuli(long a, long b, long ab)
|
|||
assert (a * b == ab);
|
||||
}
|
||||
|
||||
void testmulu(unsigned long a, unsigned long b, unsigned long ab)
|
||||
{
|
||||
assert (a * b == ab);
|
||||
}
|
||||
|
||||
void testdivi(long a, long b, long ab)
|
||||
{
|
||||
assert (a / b == ab);
|
||||
|
@ -80,6 +85,26 @@ int main(void)
|
|||
testmuli( -1024, 1237, -1266688l);
|
||||
testmuli( -1024,-1237, 1266688l);
|
||||
|
||||
testmulu(0x00000001, 0x0000003c, 0x0000003c);
|
||||
testmulu(0x00000100, 0x0000003c, 0x00003c00);
|
||||
testmulu(0x00010000, 0x0000003c, 0x003c0000);
|
||||
testmulu(0x01000000, 0x0000003c, 0x3c000000);
|
||||
|
||||
testmulu(0x0000003c, 0x00000001, 0x0000003c);
|
||||
testmulu(0x0000003c, 0x00000100, 0x00003c00);
|
||||
testmulu(0x0000003c, 0x00010000, 0x003c0000);
|
||||
testmulu(0x0000003c, 0x01000000, 0x3c000000);
|
||||
|
||||
testmulu(0x0000004b, 0x0000003c, 0x00001194);
|
||||
testmulu(0x00004b00, 0x0000003c, 0x00119400);
|
||||
testmulu(0x004b0000, 0x0000003c, 0x11940000);
|
||||
testmulu(0x4b000000, 0x0000003c, 0x94000000);
|
||||
|
||||
testmulu(0x0000003c, 0x0000004b, 0x00001194);
|
||||
testmulu(0x0000003c, 0x00004b00, 0x00119400);
|
||||
testmulu(0x0000003c, 0x004b0000, 0x11940000);
|
||||
testmulu(0x0000003c, 0x4b000000, 0x94000000);
|
||||
|
||||
testdivi( 1, 1, 1);
|
||||
testdivi(-1, 1, -1);
|
||||
testdivi( 1, -1, -1);
|
||||
|
|
|
@ -63,6 +63,33 @@ bool nge(long a, long b)
|
|||
|
||||
|
||||
|
||||
|
||||
inline bool ieq(long a, long b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
inline bool ilt(long a, long b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
inline bool igt(long a, long b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
inline bool ile(long a, long b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
inline bool ige(long a, long b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
|
||||
bool beqz(long a)
|
||||
{
|
||||
return a == 0;
|
||||
|
@ -188,7 +215,71 @@ bool nge1(long a)
|
|||
|
||||
|
||||
|
||||
void cmp(long a, long b)
|
||||
bool beqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
bool bltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
bool bgtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
bool blem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
bool bgem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool neqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
#pragma native(neqm)
|
||||
|
||||
bool nltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
#pragma native(nltm)
|
||||
|
||||
bool ngtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
#pragma native(ngtm)
|
||||
|
||||
bool nlem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
#pragma native(nlem)
|
||||
|
||||
bool ngem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
#pragma native(ngem)
|
||||
|
||||
|
||||
|
||||
void cmpc(long a, long b)
|
||||
{
|
||||
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
@ -203,6 +294,27 @@ void cmp(long a, long b)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpi(long a, long b)
|
||||
{
|
||||
bool ieqf = ieq(a, b), iltf = ilt(a, b), igtf = igt(a, b), ilef = ile(a, b), igef = ige(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
||||
printf("INLINE %ld, %ld : EQ %d LT %d GT %d\r", a, b, ieqf, iltf, igtf);
|
||||
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
|
||||
|
||||
assert(ieqf == neqf);
|
||||
assert(iltf == nltf);
|
||||
assert(igtf == ngtf);
|
||||
assert(ilef == nlef);
|
||||
assert(igef == ngef);
|
||||
}
|
||||
|
||||
void cmp(long a, long b)
|
||||
{
|
||||
cmpc(a, b);
|
||||
cmpi(a, b);
|
||||
}
|
||||
|
||||
void cmpz(long a)
|
||||
{
|
||||
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
|
||||
|
@ -233,6 +345,21 @@ void cmp1(long a)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpm(long a)
|
||||
{
|
||||
bool beqf = beqm(a), bltf = bltm(a), bgtf = bgtm(a), blef = blem(a), bgef = bgem(a);
|
||||
bool neqf = neqm(a), nltf = nltm(a), ngtf = ngtm(a), nlef = nlem(a), ngef = ngem(a);
|
||||
|
||||
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
|
||||
printf("NATIVE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
|
||||
|
||||
assert(beqf == neqf);
|
||||
assert(bltf == nltf);
|
||||
assert(bgtf == ngtf);
|
||||
assert(blef == nlef);
|
||||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cmp( 0, 1);
|
||||
|
@ -327,6 +454,10 @@ int main(void)
|
|||
cmp1(256);
|
||||
cmp1(10000);
|
||||
cmp1(20000);
|
||||
cmp1(1000000l);
|
||||
cmp1(2000000l);
|
||||
cmp1(100000000l);
|
||||
cmp1(200000000l);
|
||||
cmp1(-1);
|
||||
cmp1(-2);
|
||||
cmp1(-3);
|
||||
|
@ -334,6 +465,34 @@ int main(void)
|
|||
cmp1(-256);
|
||||
cmp1(-10000);
|
||||
cmp1(-20000);
|
||||
cmp1(-1000000l);
|
||||
cmp1(-2000000l);
|
||||
cmp1(-100000000l);
|
||||
cmp1(-200000000l);
|
||||
|
||||
cmpm(0);
|
||||
cmpm(1);
|
||||
cmpm(2);
|
||||
cmpm(3);
|
||||
cmpm(255);
|
||||
cmpm(256);
|
||||
cmpm(10000);
|
||||
cmpm(20000);
|
||||
cmpm(1000000l);
|
||||
cmpm(2000000l);
|
||||
cmpm(100000000l);
|
||||
cmpm(200000000l);
|
||||
cmpm(-1);
|
||||
cmpm(-2);
|
||||
cmpm(-3);
|
||||
cmpm(-255);
|
||||
cmpm(-256);
|
||||
cmpm(-10000);
|
||||
cmpm(-20000);
|
||||
cmpm(-1000000l);
|
||||
cmpm(-2000000l);
|
||||
cmpm(-100000000l);
|
||||
cmpm(-200000000l);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAP_WIDTH 10
|
||||
#define MAP_HEIGHT 2
|
||||
|
||||
#define TITLE_TILE_WIDTH 4
|
||||
#define TITLE_TILE_HEIGHT 4
|
||||
|
||||
#define PTR_SCREEN ((char *)0xc000)
|
||||
#define PTR_BUFFER ((char *)0xc400)
|
||||
#define PTR_COLOR ((char *)0xd800)
|
||||
#define PTR_FONTCHARSET ((char *)0xd800)
|
||||
|
||||
const char TitleMap[1024] = {
|
||||
#for(i, 1024) i * 17,
|
||||
};
|
||||
|
||||
const char TitleTiles[4096] = {
|
||||
#for(i, 4096) i * 31,
|
||||
};
|
||||
|
||||
// Custom screen address
|
||||
extern char* const Screen = PTR_SCREEN;
|
||||
|
||||
// Color mem address
|
||||
extern char* const Color = PTR_COLOR;
|
||||
|
||||
void RenderLogo(char screenY)
|
||||
{
|
||||
char * sp = Screen;
|
||||
char * cp = Color;
|
||||
const char * mp = TitleMap;
|
||||
|
||||
for(char ty=0; ty < MAP_HEIGHT; ty++)
|
||||
{
|
||||
for(char tx=0; tx< MAP_WIDTH; tx++)
|
||||
{
|
||||
char ti = mp[tx];
|
||||
const char* tp = TitleTiles + (TITLE_TILE_WIDTH * TITLE_TILE_HEIGHT) * ti;
|
||||
|
||||
for(char y=0; y<TITLE_TILE_HEIGHT; y++)
|
||||
{
|
||||
for(char x=0; x<TITLE_TILE_WIDTH; x++)
|
||||
{
|
||||
char c = tp[TITLE_TILE_WIDTH * y + x];
|
||||
sp[40 * (y + screenY) + x] = c;
|
||||
cp[40 * (y + screenY) + x] = 1;
|
||||
}
|
||||
}
|
||||
sp += TITLE_TILE_WIDTH;
|
||||
cp += TITLE_TILE_WIDTH;
|
||||
}
|
||||
sp += 120;
|
||||
cp += 120;
|
||||
mp += MAP_WIDTH;
|
||||
}
|
||||
}
|
||||
|
||||
void VerifyLogo(char screenY)
|
||||
{
|
||||
for(char dy=0; dy<MAP_HEIGHT * TITLE_TILE_HEIGHT; dy++)
|
||||
{
|
||||
for(char dx=0; dx<MAP_WIDTH * TITLE_TILE_WIDTH; dx++)
|
||||
{
|
||||
char ty = dy / TITLE_TILE_HEIGHT, iy = dy % TITLE_TILE_HEIGHT;
|
||||
char tx = dx / TITLE_TILE_WIDTH, ix = dx % TITLE_TILE_WIDTH;
|
||||
|
||||
int si = TitleMap[MAP_WIDTH * ty + tx] * TITLE_TILE_WIDTH * TITLE_TILE_HEIGHT + TITLE_TILE_WIDTH * iy + ix;
|
||||
int di = 40 * (dy + screenY) + dx;
|
||||
|
||||
assert(Screen[di] == TitleTiles[si]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
RenderLogo(1);
|
||||
VerifyLogo(1);
|
||||
return 0;
|
||||
}
|
|
@ -10,12 +10,13 @@ enum SIDFXState
|
|||
SIDFX_WAIT
|
||||
};
|
||||
|
||||
static struct SIDFXChannel
|
||||
__striped static struct SIDFXChannel
|
||||
{
|
||||
const SIDFX * com;
|
||||
byte delay, cnt, priority;
|
||||
volatile SIDFXState state;
|
||||
unsigned freq, pwm;
|
||||
const SIDFX * volatile com;
|
||||
byte delay, priority;
|
||||
volatile byte cnt;
|
||||
volatile SIDFXState state;
|
||||
unsigned freq, pwm;
|
||||
|
||||
} channels[3];
|
||||
|
||||
|
@ -26,9 +27,20 @@ void sidfx_init(void)
|
|||
channels[i].com = nullptr;
|
||||
channels[i].state = SIDFX_IDLE;
|
||||
channels[i].priority = 0;
|
||||
channels[i].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool sidfx_idle(byte chn)
|
||||
{
|
||||
return channels[chn].state == SIDFX_IDLE;
|
||||
}
|
||||
|
||||
char sidfx_cnt(byte chn)
|
||||
{
|
||||
return channels[chn].cnt;
|
||||
}
|
||||
|
||||
void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
||||
{
|
||||
SIDFXState ns = channels[chn].state;
|
||||
|
@ -41,6 +53,7 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
|||
return;
|
||||
|
||||
channels[chn].state = SIDFX_IDLE;
|
||||
channels[chn].delay = 1;
|
||||
|
||||
channels[chn].com = fx;
|
||||
channels[chn].cnt = cnt - 1;
|
||||
|
@ -53,103 +66,126 @@ void sidfx_stop(byte chn)
|
|||
{
|
||||
channels[chn].com = nullptr;
|
||||
if (channels[chn].state != SIDFX_IDLE)
|
||||
{
|
||||
channels[chn].state = SIDFX_RESET_0;
|
||||
channels[chn].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void sidfx_loop_ch(byte ch)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
if (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_RESET_1;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
if (channels[ch].com)
|
||||
{
|
||||
channels[ch].freq = channels[ch].com->freq;
|
||||
channels[ch].pwm = channels[ch].com->pwm;
|
||||
const SIDFX * com = channels[ch].com;
|
||||
|
||||
sid.voices[ch].freq = channels[ch].com->freq;
|
||||
sid.voices[ch].pwm = channels[ch].com->pwm;
|
||||
sid.voices[ch].attdec = channels[ch].com->attdec;
|
||||
sid.voices[ch].susrel = channels[ch].com->susrel;
|
||||
sid.voices[ch].ctrl = channels[ch].com->ctrl;
|
||||
|
||||
channels[ch].delay = channels[ch].com->time1;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
if (channels[ch].com->dfreq)
|
||||
channels[ch].delay--;
|
||||
if (channels[ch].delay)
|
||||
{
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += channels[ch].com->dfreq;
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (channels[ch].com->dpwm)
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += channels[ch].com->dpwm;
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (channels[ch].com->time0)
|
||||
while (!channels[ch].delay)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
{
|
||||
sid.voices[ch].ctrl = channels[ch].com->ctrl & ~SID_CTRL_GATE;
|
||||
channels[ch].delay = channels[ch].com->time0;
|
||||
channels[ch].state = SIDFX_WAIT;
|
||||
}
|
||||
else if (channels[ch].cnt)
|
||||
{
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com++;
|
||||
channels[ch].priority = channels[ch].com->priority;
|
||||
case SIDFX_IDLE:
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
if (com)
|
||||
channels[ch].state = SIDFX_READY;
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
if (channels[ch].com->dfreq)
|
||||
{
|
||||
channels[ch].freq += channels[ch].com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (channels[ch].com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += channels[ch].com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (channels[ch].cnt)
|
||||
{
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com++;
|
||||
channels[ch].priority = channels[ch].com->priority;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
sid.voices[ch].freq = com->freq;
|
||||
sid.voices[ch].pwm = com->pwm;
|
||||
sid.voices[ch].attdec = com->attdec;
|
||||
sid.voices[ch].susrel = com->susrel;
|
||||
sid.voices[ch].ctrl = com->ctrl;
|
||||
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
{
|
||||
channels[ch].delay = com->time1;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
channels[ch].delay = com->time0;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
if (com->time0)
|
||||
{
|
||||
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
|
||||
channels[ch].delay = com->time0 - 1;
|
||||
channels[ch].state = SIDFX_WAIT;
|
||||
}
|
||||
else if (channels[ch].cnt)
|
||||
{
|
||||
char sr = com->susrel & 0xf0;
|
||||
com++;
|
||||
char ctrl = com->ctrl;
|
||||
if ((com->attdec & 0xef) == 0 && (ctrl & SID_CTRL_GATE) && (com->susrel & 0xf0) > sr)
|
||||
{
|
||||
sid.voices[ch].ctrl = ctrl & ~SID_CTRL_GATE;
|
||||
sid.voices[ch].ctrl = ctrl | SID_CTRL_GATE;
|
||||
}
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
if (channels[ch].cnt)
|
||||
{
|
||||
com++;
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
else
|
||||
channels[ch].state = SIDFX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,14 @@ struct SIDFX
|
|||
|
||||
void sidfx_init(void);
|
||||
|
||||
inline bool sidfx_idle(byte chn);
|
||||
|
||||
inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
|
||||
|
||||
void sidfx_stop(byte chn);
|
||||
|
||||
char sidfx_cnt(byte chn);
|
||||
|
||||
void sidfx_loop(void);
|
||||
|
||||
void sidfx_loop_2(void);
|
||||
|
|
|
@ -10,22 +10,22 @@ void bnk1_init(void);
|
|||
|
||||
#pragma code(bnk1code)
|
||||
|
||||
char bnk1_readb(volatile char * p);
|
||||
__noinline char bnk1_readb(volatile char * p);
|
||||
|
||||
unsigned bnk1_readw(volatile unsigned * p);
|
||||
__noinline unsigned bnk1_readw(volatile unsigned * p);
|
||||
|
||||
unsigned long bnk1_readl(volatile unsigned long * p);
|
||||
__noinline unsigned long bnk1_readl(volatile unsigned long * p);
|
||||
|
||||
void bnk1_readm(char * dp, volatile char * sp, unsigned size);
|
||||
__noinline void bnk1_readm(char * dp, volatile char * sp, unsigned size);
|
||||
|
||||
|
||||
void bnk1_writeb(volatile char * p, char b);
|
||||
__noinline void bnk1_writeb(volatile char * p, char b);
|
||||
|
||||
void bnk1_writew(volatile unsigned * p, unsigned w);
|
||||
__noinline void bnk1_writew(volatile unsigned * p, unsigned w);
|
||||
|
||||
void bnk1_writel(volatile unsigned long * p, unsigned long l);
|
||||
__noinline void bnk1_writel(volatile unsigned long * p, unsigned long l);
|
||||
|
||||
void bnk1_writem(volatile char * dp, const char * sp, unsigned size);
|
||||
__noinline void bnk1_writem(volatile char * dp, const char * sp, unsigned size);
|
||||
|
||||
#pragma code(code)
|
||||
|
||||
|
|
|
@ -1 +1,8 @@
|
|||
#include "mmu.h"
|
||||
|
||||
inline char mmu_set(char cr)
|
||||
{
|
||||
char pcr = mmu.cr;
|
||||
mmu.cr = cr;
|
||||
return pcr;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ struct XMMU
|
|||
|
||||
#define xmmu (*((struct XMMU *)0xd500))
|
||||
|
||||
inline char mmu_set(char cr);
|
||||
|
||||
#pragma compile("mmu.c")
|
||||
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
inline void vdc_reg(VDCRegister reg)
|
||||
{
|
||||
vdc.addr = reg;
|
||||
do {} while (vdc.addr < 128);
|
||||
}
|
||||
|
||||
inline void vdc_write(byte data)
|
||||
{
|
||||
do {} while (vdc.addr < 128);
|
||||
vdc.data = data;
|
||||
}
|
||||
|
||||
inline byte vdc_read(void)
|
||||
{
|
||||
do {} while (vdc.addr < 128);
|
||||
return vdc.data;
|
||||
}
|
||||
|
||||
|
@ -33,8 +34,11 @@ byte vdc_reg_read(VDCRegister reg)
|
|||
|
||||
void vdc_mem_addr(unsigned addr)
|
||||
{
|
||||
#pragma callinline()
|
||||
vdc_reg_write(VDCR_ADDRH, addr >> 8);
|
||||
#pragma callinline()
|
||||
vdc_reg_write(VDCR_ADDRL, addr);
|
||||
#pragma callinline()
|
||||
vdc_reg(VDCR_DATA);
|
||||
}
|
||||
|
||||
|
@ -51,12 +55,14 @@ inline char vdc_mem_read(void)
|
|||
|
||||
void vdc_mem_write_at(unsigned addr, char data)
|
||||
{
|
||||
#pragma callinline()
|
||||
vdc_mem_addr(addr);
|
||||
vdc_write(data);
|
||||
}
|
||||
|
||||
char vdc_mem_read_at(unsigned addr)
|
||||
{
|
||||
#pragma callinline()
|
||||
vdc_mem_addr(addr);
|
||||
return vdc_read();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ void cia_init(void)
|
|||
cia2.ddrb = 0x00;
|
||||
cia1.ddra = 0xff;
|
||||
|
||||
cia2.prb = 0x07;
|
||||
cia2.pra = 0x07;
|
||||
cia2.ddra = 0x3f;
|
||||
|
||||
char i0 = cia1.icr;
|
||||
|
|
|
@ -18,6 +18,46 @@ struct EasyFlash
|
|||
|
||||
#define eflash (*(EasyFlash *)0xde00)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#ifdef EFPROX_SECTION
|
||||
#pragma code(EFPROX_SECTION)
|
||||
#endif
|
||||
|
||||
template<int back, class fn, class ... P>
|
||||
__noinline auto ef_call_p(P... p)
|
||||
{
|
||||
if (back != __bankof(fn))
|
||||
eflash.bank = __bankof(fn);
|
||||
auto r = fn(p...);
|
||||
if (back != 0xff && back != __bankof(fn))
|
||||
eflash.bank = back;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef EFPROX_SECTION
|
||||
#pragma code(code)
|
||||
#endif
|
||||
|
||||
template<class fn>
|
||||
class EFlashCall
|
||||
{
|
||||
public:
|
||||
template<class ... P>
|
||||
__forceinline auto operator()(P ... p) const
|
||||
{
|
||||
switch(__bankof(0))
|
||||
{
|
||||
#for(i,64) case i: return ef_call_p<i, fn, P...>(p...);
|
||||
default:
|
||||
return ef_call_p<0xff, fn, P...>(p...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define EF_CALL(fn) EFlashCall<fn##_p> fn
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,608 @@
|
|||
#include "flossiec.h"
|
||||
#include <c64/iecbus.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/cia.h>
|
||||
#include <c64/kernalio.h>
|
||||
|
||||
#ifndef FLOSSIEC_NODISPLAY
|
||||
#define FLOSSIEC_NODISPLAY 0
|
||||
#endif
|
||||
#ifndef FLOSSIEC_NOIRQ
|
||||
#define FLOSSIEC_NOIRQ 0
|
||||
#endif
|
||||
#ifndef FLOSSIEC_BORDER
|
||||
#define FLOSSIEC_BORDER 0
|
||||
#endif
|
||||
|
||||
|
||||
#define VIA_ATNIN 0x80
|
||||
#define VIA_ATNOUT 0x10
|
||||
|
||||
#define VIA_CLKOUT 0x08
|
||||
#define VIA_DATAOUT 0x02
|
||||
|
||||
#define VIA_CLKIN 0x04
|
||||
#define VIA_DATAIN 0x01
|
||||
|
||||
#define PORTB1 0x1800
|
||||
#define PORTB2 0x1c00
|
||||
|
||||
#define WR 0x1d
|
||||
|
||||
#ifdef FLOSSIEC_CODE
|
||||
#pragma code(FLOSSIEC_CODE)
|
||||
#endif
|
||||
#ifdef FLOSSIEC_BSS
|
||||
#pragma bss(FLOSSIEC_BSS)
|
||||
#endif
|
||||
|
||||
__asm diskcode
|
||||
{
|
||||
nop
|
||||
nop
|
||||
|
||||
lda #VIA_CLKOUT
|
||||
sta PORTB1
|
||||
|
||||
lda 0x0202
|
||||
sta 0x0c
|
||||
lda 0x0203
|
||||
sta 0x0d
|
||||
lda #$80
|
||||
sta 0x03
|
||||
|
||||
ldx #0
|
||||
l0:
|
||||
txa
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
sta 0x0700,x
|
||||
inx
|
||||
bne l0
|
||||
|
||||
lr:
|
||||
lda 0x03
|
||||
bmi lr
|
||||
|
||||
sei
|
||||
|
||||
ldx #0
|
||||
l2:
|
||||
lda #0
|
||||
sta PORTB1
|
||||
lda 0x0600, x
|
||||
tay
|
||||
and #0x0f
|
||||
ora #VIA_DATAIN
|
||||
l1:
|
||||
bit PORTB1
|
||||
bne l1
|
||||
|
||||
l3:
|
||||
sta PORTB1
|
||||
|
||||
tya
|
||||
asl
|
||||
and #0x0a
|
||||
sta PORTB1
|
||||
|
||||
lda 0x0700,y
|
||||
nop
|
||||
sta PORTB1
|
||||
|
||||
asl
|
||||
nop
|
||||
and #0x0a
|
||||
sta PORTB1
|
||||
|
||||
inx
|
||||
bne l2
|
||||
|
||||
lda #VIA_CLKOUT
|
||||
sta PORTB1
|
||||
|
||||
|
||||
lda 0x0600
|
||||
beq w1
|
||||
sta 0x0c
|
||||
lda 0x0601
|
||||
sta 0x0d
|
||||
lda #$80
|
||||
sta 0x03
|
||||
cli
|
||||
bne lr
|
||||
w1:
|
||||
sta PORTB1
|
||||
|
||||
cli
|
||||
rts
|
||||
}
|
||||
|
||||
#define CIA2B_ATNOUT 0x08
|
||||
#define CIA2B_CLKOUT 0x10
|
||||
#define CIA2B_DATAOUT 0x20
|
||||
|
||||
#define CIA2B_CLKIN 0x40
|
||||
#define CIA2B_DATAIN 0x80
|
||||
|
||||
#define CIA2PRA 0xdd00
|
||||
|
||||
static char remap[256];
|
||||
static char rbuffer[256];
|
||||
static char xbuffer[256];
|
||||
static char flpos;
|
||||
static char xcmd;
|
||||
static char xi, xj;
|
||||
static char fldrive;
|
||||
static char flvxor;
|
||||
|
||||
__noinline void fl_read_buf(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
#if FLOSSIEC_NOIRQ
|
||||
php
|
||||
sei
|
||||
#endif
|
||||
|
||||
lda CIA2PRA
|
||||
and #~CIA2B_CLKOUT
|
||||
sta accu
|
||||
sta CIA2PRA
|
||||
and #~CIA2B_DATAOUT
|
||||
sta accu + 1
|
||||
|
||||
l0:
|
||||
lda CIA2PRA
|
||||
and #CIA2B_CLKIN
|
||||
beq l0
|
||||
#if !FLOSSIEC_NOIRQ
|
||||
php
|
||||
pla
|
||||
and #$04
|
||||
beq iq
|
||||
#endif
|
||||
ldy #0
|
||||
sec
|
||||
l1:
|
||||
ldx accu + 1
|
||||
#if !FLOSSIEC_NODISPLAY
|
||||
l2:
|
||||
lda 0xd012
|
||||
sbc #50
|
||||
bcc w1
|
||||
and #7
|
||||
beq l2
|
||||
#endif
|
||||
w1:
|
||||
stx CIA2PRA
|
||||
|
||||
#if FLOSSIEC_BORDER
|
||||
inc 0xd020
|
||||
#else
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
ldx accu
|
||||
nop
|
||||
|
||||
lda CIA2PRA
|
||||
lsr
|
||||
lsr
|
||||
nop
|
||||
eor CIA2PRA
|
||||
lsr
|
||||
lsr
|
||||
nop
|
||||
eor CIA2PRA
|
||||
lsr
|
||||
lsr
|
||||
sec
|
||||
eor CIA2PRA
|
||||
stx CIA2PRA
|
||||
|
||||
sta rbuffer, y
|
||||
iny
|
||||
bne l1
|
||||
jmp done
|
||||
#if !FLOSSIEC_NOIRQ
|
||||
iq:
|
||||
ldy #0
|
||||
sec
|
||||
l1i:
|
||||
ldx accu + 1
|
||||
l2i:
|
||||
cli
|
||||
sei
|
||||
#if !FLOSSIEC_NODISPLAY
|
||||
lda 0xd012
|
||||
sbc #50
|
||||
bcc w1i
|
||||
and #7
|
||||
beq l2i
|
||||
w1i:
|
||||
#endif
|
||||
stx CIA2PRA
|
||||
|
||||
#if FLOSSIEC_BORDER
|
||||
inc 0xd020
|
||||
#else
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
ldx accu
|
||||
nop
|
||||
|
||||
lda CIA2PRA
|
||||
lsr
|
||||
lsr
|
||||
nop
|
||||
eor CIA2PRA
|
||||
lsr
|
||||
lsr
|
||||
nop
|
||||
eor CIA2PRA
|
||||
lsr
|
||||
lsr
|
||||
sec
|
||||
eor CIA2PRA
|
||||
stx CIA2PRA
|
||||
|
||||
sta rbuffer, y
|
||||
iny
|
||||
bne l1i
|
||||
cli
|
||||
#endif
|
||||
done:
|
||||
|
||||
#if FLOSSIEC_NOIRQ
|
||||
plp
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline char flossiec_get(void)
|
||||
{
|
||||
if (!flpos)
|
||||
{
|
||||
fl_read_buf();
|
||||
flpos = 2;
|
||||
}
|
||||
return remap[rbuffer[flpos++]];
|
||||
}
|
||||
|
||||
void flossiec_decompress(void)
|
||||
{
|
||||
char i = 0, j = xj, cmd = xcmd;
|
||||
xi = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if (cmd & 0x80)
|
||||
{
|
||||
if (i < cmd)
|
||||
{
|
||||
char t = i - cmd;
|
||||
do {
|
||||
char ch = xbuffer[j++];
|
||||
xbuffer[i++] = ch;
|
||||
} while (i != t);
|
||||
cmd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd -= i;
|
||||
do {
|
||||
char ch = xbuffer[j++];
|
||||
xbuffer[i++] = ch;
|
||||
} while (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char ch = flossiec_get();
|
||||
if (cmd)
|
||||
{
|
||||
xbuffer[i++] = ch;
|
||||
cmd--;
|
||||
if (!i)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = ch;
|
||||
if (!cmd)
|
||||
break;
|
||||
if (cmd & 0x80)
|
||||
{
|
||||
cmd ^= 0x7f;
|
||||
cmd++;
|
||||
j = i - flossiec_get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xj = j;
|
||||
xcmd = cmd;
|
||||
}
|
||||
|
||||
inline char flossiec_get_lzo(void)
|
||||
{
|
||||
if (!xi)
|
||||
flossiec_decompress();
|
||||
return xbuffer[xi++];
|
||||
}
|
||||
|
||||
inline bool flossiec_eof(void)
|
||||
{
|
||||
return !remap[rbuffer[0]] && flpos >= remap[rbuffer[1]];
|
||||
}
|
||||
|
||||
char * flossiec_read(char * dp, unsigned size)
|
||||
{
|
||||
while (size)
|
||||
{
|
||||
*dp++ = flossiec_get();
|
||||
size--;
|
||||
}
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
||||
char * flossiec_read_lzo(char * dp, unsigned size)
|
||||
{
|
||||
char i = xi;
|
||||
|
||||
dp -= i;
|
||||
size += i;
|
||||
|
||||
while (size)
|
||||
{
|
||||
if (!i)
|
||||
flossiec_decompress();
|
||||
|
||||
if (size >= 256)
|
||||
{
|
||||
do {
|
||||
dp[i] = xbuffer[i];
|
||||
i++;
|
||||
} while (i);
|
||||
dp += 256;
|
||||
size -= 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
do {
|
||||
dp[i] = xbuffer[i];
|
||||
i++;
|
||||
} while (i != (char)size);
|
||||
dp += i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xi = i;
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
||||
static void vxorcheck(void)
|
||||
{
|
||||
char vxor = cia2.pra & 7;
|
||||
vxor ^= vxor >> 2;
|
||||
vxor ^= 0xff;
|
||||
|
||||
if (vxor != flvxor)
|
||||
{
|
||||
flvxor = vxor;
|
||||
|
||||
for(int i=0; i<256; i++)
|
||||
{
|
||||
char j = i ^ vxor;
|
||||
char d = ((j & 0x11) << 3) |
|
||||
(j & 0x66) |
|
||||
((j & 0x88) >> 3);
|
||||
remap[i] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool flossiec_init(char drive)
|
||||
{
|
||||
fldrive = drive;
|
||||
flvxor = 0;
|
||||
|
||||
iec_open(drive, 2, "#2");
|
||||
iec_listen(drive, 2);
|
||||
for(char j=0; j<127; j++)
|
||||
iec_write(((char *)diskcode)[j]);
|
||||
iec_unlisten();
|
||||
|
||||
iec_close(drive, 2);
|
||||
|
||||
iec_open(drive, 15, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void flossiec_shutdown(void)
|
||||
{
|
||||
iec_close(fldrive, 15);
|
||||
}
|
||||
|
||||
|
||||
bool flossiec_open(char track, char sector)
|
||||
{
|
||||
iec_listen(fldrive, 15);
|
||||
iec_write(P'U');
|
||||
iec_write(P'4');
|
||||
iec_write(track);
|
||||
iec_write(sector);
|
||||
iec_unlisten();
|
||||
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
|
||||
|
||||
#if FLOSSIEC_NODISPLAY
|
||||
vic.ctrl1 &= ~VIC_CTRL1_DEN;
|
||||
#endif
|
||||
|
||||
vic_waitFrame();
|
||||
vxorcheck();
|
||||
vic_waitFrame();
|
||||
|
||||
flpos = 0;
|
||||
xi = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void flossiec_close(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
|
||||
#if FLOSSIEC_NODISPLAY
|
||||
vic.ctrl1 |= VIC_CTRL1_DEN;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool flosskio_init(char drive)
|
||||
{
|
||||
fldrive = drive;
|
||||
flvxor = 0;
|
||||
|
||||
krnio_setnam_n("#2", 2);
|
||||
krnio_open(2, drive, 2);
|
||||
krnio_write(2, (char *)diskcode, 128);
|
||||
krnio_close(2);
|
||||
|
||||
krnio_setnam_n(nullptr, 0);
|
||||
krnio_open(15, drive, 15);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void flosskio_shutdown(void)
|
||||
{
|
||||
krnio_close(15);
|
||||
}
|
||||
|
||||
|
||||
bool flosskio_open(char track, char sector)
|
||||
{
|
||||
krnio_chkout(15);
|
||||
krnio_chrout(P'U');
|
||||
krnio_chrout(P'4');
|
||||
krnio_chrout(track);
|
||||
krnio_chrout(sector);
|
||||
krnio_clrchn();
|
||||
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
|
||||
#if FLOSSIEC_NODISPLAY
|
||||
vic.ctrl1 &= ~VIC_CTRL1_DEN;
|
||||
#endif
|
||||
|
||||
vic_waitFrame();
|
||||
vxorcheck();
|
||||
vic_waitFrame();
|
||||
|
||||
flpos = 0;
|
||||
xi = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void flosskio_close(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
|
||||
#if FLOSSIEC_NODISPLAY
|
||||
vic.ctrl1 |= VIC_CTRL1_DEN;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool mapdir(const char * fnames, floss_blk * blks)
|
||||
{
|
||||
do {
|
||||
fl_read_buf();
|
||||
|
||||
char si = 0;
|
||||
do
|
||||
{
|
||||
if (remap[rbuffer[si + 2]] == 0x82)
|
||||
{
|
||||
char fname[17];
|
||||
char j = 0;
|
||||
while (j < 16 && remap[rbuffer[si + j + 5]] != 0xa0)
|
||||
{
|
||||
fname[j] = remap[rbuffer[si + j + 5]];
|
||||
j++;
|
||||
}
|
||||
fname[j] = 0;
|
||||
|
||||
char sj = 0;
|
||||
char k = 0;
|
||||
while (fnames[sj])
|
||||
{
|
||||
j = 0;
|
||||
while (fname[j] && fname[j] == fnames[sj])
|
||||
{
|
||||
j++;
|
||||
sj++;
|
||||
}
|
||||
if (!fname[j] && (!fnames[sj] || fnames[sj] == ','))
|
||||
{
|
||||
__assume(k < 128);
|
||||
blks[k].track = remap[rbuffer[si + 3]];
|
||||
blks[k].sector = remap[rbuffer[si + 4]];
|
||||
break;
|
||||
}
|
||||
|
||||
while (fnames[sj] && fnames[sj++] != ',')
|
||||
;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
si += 32;
|
||||
} while (si);
|
||||
|
||||
} while (remap[rbuffer[0]]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flosskio_mapdir(const char * fnames, floss_blk * blks)
|
||||
{
|
||||
if (flosskio_open(18, 1))
|
||||
{
|
||||
mapdir(fnames, blks);
|
||||
|
||||
flosskio_close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool flossiec_mapdir(const char * fnames, floss_blk * blks)
|
||||
{
|
||||
if (flossiec_open(18, 1))
|
||||
{
|
||||
mapdir(fnames, blks);
|
||||
|
||||
flossiec_close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef FLOSSIEC_H
|
||||
#define FLOSSIEC_H
|
||||
|
||||
// When building you can use various defines to change the behaviour
|
||||
|
||||
// FLOSSIEC_BORDER=1 Enable border flashing while loading
|
||||
// FLOSSIEC_NODISPLAY=1 Disable the display while loading
|
||||
// FLOSSIEC_NOIRQ=1 Disable IRQ during load
|
||||
// FLOSSIEC_CODE=cseg Code segment to be used, when defined
|
||||
// FLOSSIEC_BSS=bseg BSS segment to be used, when defined
|
||||
|
||||
// Initialize the fastloader to be used without the kernal
|
||||
bool flossiec_init(char drive);
|
||||
|
||||
// Shutdown the fastloader when used without the kernal
|
||||
void flossiec_shutdown(void);
|
||||
|
||||
// Open a file for read with the fastloader without the kernal.
|
||||
// The file has to be read to completion before you can close
|
||||
// it again,
|
||||
bool flossiec_open(char track, char sector);
|
||||
|
||||
// Close a file after reading
|
||||
void flossiec_close(void);
|
||||
|
||||
|
||||
// Initialize the fastloader to be used with the kernal
|
||||
bool flosskio_init(char drive);
|
||||
|
||||
// Shutdown the fastloader when used with the kernal
|
||||
void flosskio_shutdown(void);
|
||||
|
||||
|
||||
// Open a file for read with the fastloader with the kernal
|
||||
// The file has to be read to completion before you can close
|
||||
// it again,
|
||||
bool flosskio_open(char track, char sector);
|
||||
|
||||
// Close a file after reading
|
||||
void flosskio_close(void);
|
||||
|
||||
|
||||
// Track and sector start of a file
|
||||
struct floss_blk
|
||||
{
|
||||
char track, sector;
|
||||
};
|
||||
|
||||
// Map a comma separated list of filenames to an array of
|
||||
// block start positions by reading the directory, using the
|
||||
// kernal.
|
||||
bool flosskio_mapdir(const char * fnames, floss_blk * blks);
|
||||
|
||||
// Map a comma separated list of filenames to an array of
|
||||
// block start positions by reading the directory, without the
|
||||
// kernal.
|
||||
bool flossiec_mapdir(const char * fnames, floss_blk * blks);
|
||||
|
||||
// Check for end of file while reading
|
||||
inline bool flossiec_eof(void);
|
||||
|
||||
// Get one char from uncompressed file
|
||||
inline char flossiec_get(void);
|
||||
|
||||
// Get one char from compressed file
|
||||
inline char flossiec_get_lzo(void);
|
||||
|
||||
// Read a section of a file into memory up to size bytes,
|
||||
// returns the first address after the read
|
||||
char * flossiec_read(char * dp, unsigned size);
|
||||
|
||||
// Read and expand section of a file into memory up to size
|
||||
// bytes, returns the first address after the read
|
||||
char * flossiec_read_lzo(char * dp, unsigned size);
|
||||
|
||||
|
||||
#pragma compile("flossiec.c")
|
||||
|
||||
#endif
|
|
@ -2,7 +2,8 @@
|
|||
#include <c64/cia.h>
|
||||
#include <c64/vic.h>
|
||||
|
||||
IEC_STATUS iec_status;
|
||||
IEC_STATUS iec_status;
|
||||
char iec_queue;
|
||||
|
||||
#define CIA2B_ATNOUT 0x08
|
||||
#define CIA2B_CLKOUT 0x10
|
||||
|
@ -14,139 +15,180 @@ IEC_STATUS iec_status;
|
|||
#pragma optimize(push)
|
||||
#pragma optimize(1)
|
||||
|
||||
// multiples of 5us
|
||||
static void delay(char n)
|
||||
{
|
||||
while (n)
|
||||
{
|
||||
__asm {
|
||||
nop
|
||||
}
|
||||
n--;
|
||||
__asm {
|
||||
ldx n
|
||||
l1:
|
||||
dex
|
||||
bne l1
|
||||
}
|
||||
}
|
||||
|
||||
static inline void data_low(void)
|
||||
static inline void data_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_DATAOUT;
|
||||
}
|
||||
|
||||
static inline void data_high(void)
|
||||
static inline void data_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_DATAOUT;
|
||||
}
|
||||
|
||||
static inline void clock_low(void)
|
||||
static inline void clock_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_CLKOUT;
|
||||
}
|
||||
|
||||
static inline void cdata_low(void)
|
||||
static inline void cdata_true(void)
|
||||
{
|
||||
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
|
||||
}
|
||||
|
||||
static inline void clock_high(void)
|
||||
static inline void clock_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_CLKOUT;
|
||||
}
|
||||
|
||||
static inline void atn_low(void)
|
||||
static inline void atn_true(void)
|
||||
{
|
||||
cia2.pra &= ~CIA2B_ATNOUT;
|
||||
}
|
||||
|
||||
static inline void atn_high(void)
|
||||
static inline void atn_false(void)
|
||||
{
|
||||
cia2.pra |= CIA2B_ATNOUT;
|
||||
}
|
||||
|
||||
static inline bool data_in(void)
|
||||
{
|
||||
return (cia2.pra & CIA2B_DATAIN) != 0;
|
||||
}
|
||||
|
||||
static inline bool clock_in(void)
|
||||
{
|
||||
return (cia2.pra & CIA2B_CLKIN) != 0;
|
||||
}
|
||||
|
||||
static bool data_check(void)
|
||||
{
|
||||
char cnt = 100;
|
||||
while (cnt > 0 && (cia2.pra & CIA2B_DATAIN))
|
||||
char cnt = 200;
|
||||
while (cnt > 0 && data_in())
|
||||
{
|
||||
delay(5);
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (cnt)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
iec_status = IEC_TIMEOUT;
|
||||
iec_status = IEC_DATA_CHECK;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool iec_eoi(void)
|
||||
static bool iec_eoib(void)
|
||||
{
|
||||
cdata_low();
|
||||
clock_true();
|
||||
|
||||
while (!(cia2.pra & CIA2B_DATAIN))
|
||||
;
|
||||
delay(50);
|
||||
while (!data_in());
|
||||
|
||||
delay(40);
|
||||
|
||||
return data_check();
|
||||
}
|
||||
|
||||
static void iec_writeb(char b)
|
||||
{
|
||||
clock_true();
|
||||
|
||||
while (!data_in());
|
||||
|
||||
delay(5);
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
clock_false();
|
||||
delay(5);
|
||||
if (b & 1)
|
||||
data_true();
|
||||
else
|
||||
data_false();
|
||||
clock_true();
|
||||
b >>= 1;
|
||||
delay(5);
|
||||
}
|
||||
clock_false();
|
||||
data_true();
|
||||
}
|
||||
|
||||
bool iec_write(char b)
|
||||
{
|
||||
cdata_low();
|
||||
|
||||
while (!(cia2.pra & CIA2B_DATAIN))
|
||||
;
|
||||
|
||||
for(char i=0; i<8; i++)
|
||||
if (iec_status == IEC_QUEUED)
|
||||
{
|
||||
clock_high();
|
||||
if (b & 1)
|
||||
data_low();
|
||||
else
|
||||
data_high();
|
||||
clock_low();
|
||||
b >>= 1;
|
||||
__asm
|
||||
{
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
php
|
||||
sei
|
||||
}
|
||||
}
|
||||
data_low();
|
||||
clock_high();
|
||||
|
||||
return data_check();
|
||||
iec_status = IEC_OK;
|
||||
iec_writeb(iec_queue);
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
data_check();
|
||||
}
|
||||
if (iec_status < IEC_ERROR)
|
||||
{
|
||||
iec_queue = b;
|
||||
iec_status = IEC_QUEUED;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char iec_read(void)
|
||||
{
|
||||
while (!(cia2.pra & CIA2B_CLKIN))
|
||||
;
|
||||
while (!clock_in());
|
||||
|
||||
data_low();
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
data_true();
|
||||
|
||||
char cnt = 100;
|
||||
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
iec_status = IEC_EOF;
|
||||
data_high();
|
||||
__asm
|
||||
{
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
}
|
||||
data_low();
|
||||
data_false();
|
||||
delay(10);
|
||||
data_true();
|
||||
|
||||
cnt = 200;
|
||||
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
if (cnt == 0)
|
||||
{
|
||||
iec_status = IEC_TIMEOUT;
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -165,24 +207,36 @@ char iec_read(void)
|
|||
;
|
||||
}
|
||||
|
||||
data_high();
|
||||
data_false();
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void iec_atn(char dev, char sec)
|
||||
{
|
||||
atn_high();
|
||||
clock_high();
|
||||
{
|
||||
clock_true();
|
||||
data_true();
|
||||
atn_false();
|
||||
clock_false();
|
||||
|
||||
delay(100);
|
||||
delay(200);
|
||||
|
||||
iec_write(dev);
|
||||
while (data_in());
|
||||
|
||||
iec_writeb(dev);
|
||||
data_check();
|
||||
if (sec != 0xff)
|
||||
iec_write(sec);
|
||||
{
|
||||
iec_writeb(sec);
|
||||
data_check();
|
||||
}
|
||||
|
||||
data_high();
|
||||
atn_low();
|
||||
atn_true();
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,8 +244,26 @@ void iec_talk(char dev, char sec)
|
|||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x40, sec);
|
||||
clock_low();
|
||||
iec_atn(dev | 0x40, sec | 0x60);
|
||||
data_false();
|
||||
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
clock_true();
|
||||
char cnt = 200;
|
||||
while (cnt > 0 && clock_in())
|
||||
cnt--;
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void iec_untalk(void)
|
||||
|
@ -203,12 +275,32 @@ void iec_listen(char dev, char sec)
|
|||
{
|
||||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x20, sec);
|
||||
iec_atn(dev | 0x20, sec | 0x60);
|
||||
}
|
||||
|
||||
void iec_unlisten(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
php
|
||||
sei
|
||||
}
|
||||
|
||||
if (iec_status == IEC_QUEUED)
|
||||
{
|
||||
iec_status = IEC_OK;
|
||||
iec_eoib();
|
||||
iec_writeb(iec_queue);
|
||||
data_check();
|
||||
}
|
||||
|
||||
iec_atn(0x3f, 0xff);
|
||||
clock_true();
|
||||
|
||||
__asm
|
||||
{
|
||||
plp
|
||||
}
|
||||
}
|
||||
|
||||
void iec_open(char dev, char sec, const char * fname)
|
||||
|
@ -216,11 +308,10 @@ void iec_open(char dev, char sec, const char * fname)
|
|||
iec_status = IEC_OK;
|
||||
|
||||
iec_atn(dev | 0x20, sec | 0xf0);
|
||||
|
||||
char i = 0;
|
||||
while (fname[i])
|
||||
{
|
||||
if (!fname[i + 1])
|
||||
iec_eoi();
|
||||
iec_write(fname[i]);
|
||||
i++;
|
||||
}
|
||||
|
@ -245,12 +336,14 @@ int iec_write_bytes(const char * data, int num)
|
|||
|
||||
int iec_read_bytes(char * data, int num)
|
||||
{
|
||||
for(int i=0; i<num; i++)
|
||||
int i = 0;
|
||||
while (i < num)
|
||||
{
|
||||
char ch = iec_read();
|
||||
if (iec_status < IEC_ERROR)
|
||||
data[i++] = ch;
|
||||
if (iec_status != IEC_OK)
|
||||
return i;
|
||||
data[i] = ch;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
|
|
@ -5,15 +5,15 @@ enum IEC_STATUS
|
|||
{
|
||||
IEC_OK = 0x00,
|
||||
IEC_EOF = 0x01,
|
||||
IEC_QUEUED = 0x02,
|
||||
|
||||
IEC_ERROR = 0x80,
|
||||
IEC_TIMEOUT
|
||||
IEC_TIMEOUT,
|
||||
IEC_DATA_CHECK,
|
||||
};
|
||||
|
||||
extern IEC_STATUS iec_status;
|
||||
|
||||
bool iec_eoi(void);
|
||||
|
||||
bool iec_write(char b);
|
||||
|
||||
char iec_read(void);
|
||||
|
|
|
@ -2,7 +2,32 @@
|
|||
|
||||
krnioerr krnio_pstatus[16];
|
||||
|
||||
void krnio_setnam(const char * name)
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
void krnio_setbnk(char filebank, char namebank)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda filebank
|
||||
ldx namebank
|
||||
jsr $ff68 // setbnk
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(krnio_setbnk)
|
||||
#endif
|
||||
|
||||
#if defined(__PLUS4__)
|
||||
#pragma code(lowcode)
|
||||
#define BANKIN sta 0xff3e
|
||||
#define BANKOUT sta 0xff3f
|
||||
#define BANKINLINE __noinline
|
||||
#else
|
||||
#define BANKIN
|
||||
#define BANKOUT
|
||||
#define BANKINLINE
|
||||
#endif
|
||||
|
||||
BANKINLINE void krnio_setnam(const char * name)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
|
@ -17,22 +42,41 @@ void krnio_setnam(const char * name)
|
|||
tya
|
||||
W1: ldx name
|
||||
ldy name + 1
|
||||
BANKIN
|
||||
jsr $ffbd // setnam
|
||||
BANKOUT
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(krnio_setnam)
|
||||
|
||||
bool krnio_open(char fnum, char device, char channel)
|
||||
BANKINLINE void krnio_setnam_n(const char * name, char len)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda len
|
||||
ldx name
|
||||
ldy name + 1
|
||||
BANKIN
|
||||
jsr $ffbd // setnam
|
||||
BANKOUT
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(krnio_setnam_n)
|
||||
|
||||
BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
||||
{
|
||||
krnio_pstatus[fnum] = KRNIO_OK;
|
||||
|
||||
__asm
|
||||
return char(__asm
|
||||
{
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
|
||||
BANKIN
|
||||
|
||||
lda fnum
|
||||
ldx device
|
||||
ldy channel
|
||||
|
@ -47,46 +91,48 @@ bool krnio_open(char fnum, char device, char channel)
|
|||
W1:
|
||||
lda #1
|
||||
sta accu
|
||||
E2:
|
||||
}
|
||||
|
||||
BANKOUT
|
||||
E2:
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_open)
|
||||
|
||||
void krnio_close(char fnum)
|
||||
BANKINLINE void krnio_close(char fnum)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
BANKIN
|
||||
lda fnum
|
||||
jsr $ffc3 // close
|
||||
BANKOUT
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(krnio_close)
|
||||
|
||||
krnioerr krnio_status(void)
|
||||
BANKINLINE krnioerr krnio_status(void)
|
||||
{
|
||||
__asm
|
||||
return __asm
|
||||
{
|
||||
BANKIN
|
||||
jsr $ffb7 // readst
|
||||
BANKOUT
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#pragma native(krnio_status)
|
||||
|
||||
|
||||
bool krnio_load(char fnum, char device, char channel)
|
||||
BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
||||
{
|
||||
__asm
|
||||
return char(__asm
|
||||
{
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
|
||||
BANKIN
|
||||
lda fnum
|
||||
ldx device
|
||||
ldy channel
|
||||
|
@ -95,89 +141,123 @@ bool krnio_load(char fnum, char device, char channel)
|
|||
lda #0
|
||||
ldx #0
|
||||
ldy #0
|
||||
jsr $FFD5 // open
|
||||
bcc W1
|
||||
jsr $FFD5 // load
|
||||
BANKOUT
|
||||
|
||||
lda #0
|
||||
jmp E2
|
||||
W1:
|
||||
lda #1
|
||||
sta accu
|
||||
E2:
|
||||
}
|
||||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_load)
|
||||
|
||||
bool krnio_chkout(char fnum)
|
||||
BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
||||
{
|
||||
__asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda #0
|
||||
ldx device
|
||||
ldy #0
|
||||
jsr $ffba // setlfs
|
||||
|
||||
lda #start
|
||||
ldx end
|
||||
ldy end+1
|
||||
jsr $FFD8 // save
|
||||
|
||||
BANKOUT
|
||||
|
||||
lda #0
|
||||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_save)
|
||||
|
||||
BANKINLINE bool krnio_chkout(char fnum)
|
||||
{
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
jsr $ffc9 // chkout
|
||||
BANKOUT
|
||||
|
||||
lda #0
|
||||
sta accu + 1
|
||||
bcs W1
|
||||
lda #1
|
||||
W1: sta accu
|
||||
}
|
||||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkout)
|
||||
|
||||
bool krnio_chkin(char fnum)
|
||||
BANKINLINE bool krnio_chkin(char fnum)
|
||||
{
|
||||
__asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
jsr $ffc6 // chkin
|
||||
BANKOUT
|
||||
|
||||
lda #0
|
||||
sta accu + 1
|
||||
bcs W1
|
||||
lda #1
|
||||
W1: sta accu
|
||||
}
|
||||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkin)
|
||||
|
||||
void krnio_clrchn(void)
|
||||
BANKINLINE void krnio_clrchn(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
BANKIN
|
||||
jsr $ffcc // clrchn
|
||||
BANKOUT
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(krnio_clrchn)
|
||||
|
||||
bool krnio_chrout(char ch)
|
||||
BANKINLINE bool krnio_chrout(char ch)
|
||||
{
|
||||
__asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda ch
|
||||
jsr $ffd2 // chrout
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
BANKOUT
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chrout)
|
||||
|
||||
int krnio_chrin(void)
|
||||
BANKINLINE char krnio_chrin(void)
|
||||
{
|
||||
__asm
|
||||
return __asm
|
||||
{
|
||||
BANKIN
|
||||
jsr $ffcf // chrin
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
BANKOUT
|
||||
};
|
||||
}
|
||||
|
||||
#pragma native(krnio_chrin)
|
||||
|
||||
#if defined(__PLUS4__)
|
||||
#pragma code(code)
|
||||
#endif
|
||||
|
||||
int krnio_getch(char fnum)
|
||||
{
|
||||
if (krnio_pstatus[fnum] == KRNIO_EOF)
|
||||
|
@ -341,7 +421,7 @@ int krnio_gets(char fnum, char * data, int num)
|
|||
|
||||
if (krnio_chkin(fnum))
|
||||
{
|
||||
krnioerr err;
|
||||
krnioerr err = KRNIO_OK;
|
||||
int i = 0;
|
||||
int ch;
|
||||
while (i + 1 < num)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef C64_KERNALIO_H
|
||||
#ifndef C64_KERNALIO_H
|
||||
#define C64_KERNALIO_H
|
||||
|
||||
// Error and status codes returned by krnio_status
|
||||
|
||||
|
@ -18,11 +18,18 @@ enum krnioerr
|
|||
|
||||
extern krnioerr krnio_pstatus[16];
|
||||
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
// C128: Set bank for load/save and filename for next file operations
|
||||
void krnio_setbnk(char filebank, char namebank);
|
||||
#endif
|
||||
|
||||
// Set filename for next krnio_open operation, make sure
|
||||
// that the string is still valid when calling krnio_open
|
||||
|
||||
void krnio_setnam(const char * name);
|
||||
|
||||
void krnio_setnam_n(const char * name, char len);
|
||||
|
||||
// open a kernal file/stream/io channel, returns true on success
|
||||
|
||||
bool krnio_open(char fnum, char device, char channel);
|
||||
|
@ -37,6 +44,8 @@ krnioerr krnio_status(void);
|
|||
|
||||
bool krnio_load(char fnum, char device, char channel);
|
||||
|
||||
bool krnio_save(char device, const char* start, const char* end);
|
||||
|
||||
// select the given file for stream output
|
||||
|
||||
bool krnio_chkout(char fnum);
|
||||
|
@ -55,7 +64,7 @@ bool krnio_chrout(char ch);
|
|||
|
||||
// read a single byte from the current input channel
|
||||
|
||||
int krnio_chrin(void);
|
||||
char krnio_chrin(void);
|
||||
|
||||
// read a single byte from the given file/channel, returns
|
||||
// a negative result on failure. If this was the last byte
|
||||
|
|
|
@ -5,39 +5,42 @@
|
|||
#include <c64/asm6502.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile char npos = 1, tpos = 0;
|
||||
volatile byte rirq_count;
|
||||
static byte rirq_pcount;
|
||||
|
||||
byte rasterIRQRows[NUM_IRQS];
|
||||
byte rasterIRQIndex[NUM_IRQS];
|
||||
byte rasterIRQNext[NUM_IRQS + 1];
|
||||
byte rasterIRQLow[NUM_IRQS];
|
||||
byte rasterIRQRows[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
|
||||
#ifdef ZPAGE_IRQS
|
||||
__zeropage
|
||||
#endif
|
||||
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
|
||||
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
|
||||
byte rasterIRQHigh[NUM_IRQS];
|
||||
|
||||
#ifdef ZPAGE_IRQS
|
||||
__zeropage
|
||||
#endif
|
||||
byte nextIRQ;
|
||||
|
||||
__asm irq0
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
|
||||
|
||||
asl $d019
|
||||
__asm rirq_isr_ram_io
|
||||
{
|
||||
stx plrx + 1
|
||||
|
||||
ldx nextIRQ
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
bmi exi
|
||||
|
||||
ldy rasterIRQIndex, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
sta plra + 1
|
||||
sty plry + 1
|
||||
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -45,21 +48,82 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
dey
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
ex:
|
||||
plry:
|
||||
ldy #0
|
||||
plra:
|
||||
lda #0
|
||||
plrx:
|
||||
ldx #0
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp plrx
|
||||
|
||||
// No more interrupts to service
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq plry
|
||||
}
|
||||
|
||||
__asm rirq_isr_io
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
kentry:
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
|
@ -67,56 +131,44 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
e2:
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
jmp ex
|
||||
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq2
|
||||
__asm rirq_isr_noio
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
kentry:
|
||||
lda $01
|
||||
pha
|
||||
|
||||
lda #$35
|
||||
sta $01
|
||||
|
||||
asl $d019
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -124,21 +176,20 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
dey
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
ex:
|
||||
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
|
@ -149,45 +200,35 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
e2:
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
jmp ex
|
||||
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq1
|
||||
__asm rirq_isr_kernal_io
|
||||
{
|
||||
lda $d019
|
||||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -196,45 +237,36 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e2
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp $ea81
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
jmp $ea81
|
||||
|
||||
ex2:
|
||||
|
@ -243,6 +275,76 @@ ex2:
|
|||
jmp $ea31
|
||||
}
|
||||
|
||||
__asm rirq_isr_kernal_noio
|
||||
{
|
||||
lda $01
|
||||
pha
|
||||
lda #$36
|
||||
sta $01
|
||||
|
||||
lda $d019
|
||||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
jx:
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
|
||||
ex2:
|
||||
LDA $DC0D
|
||||
cli
|
||||
pla
|
||||
sta $01
|
||||
|
||||
jmp $ea31
|
||||
}
|
||||
|
||||
// 0 lda #data0
|
||||
// 2 ldy #data1
|
||||
// 4 cpx $d012
|
||||
|
@ -263,8 +365,8 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
ic->size = size;
|
||||
|
||||
asm_im(ic->code + 0, ASM_LDY, 0);
|
||||
asm_im(ic->code + 2, ASM_LDA, 0);
|
||||
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
|
||||
asm_im(ic->code + 2, ASM_LDX, 0);
|
||||
asm_ab(ic->code + 4, ASM_CMP, 0xd012);
|
||||
asm_rl(ic->code + 7, ASM_BCS, -5);
|
||||
asm_ab(ic->code + 9, ASM_STY, 0x0000);
|
||||
|
||||
|
@ -278,7 +380,7 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
}
|
||||
else
|
||||
{
|
||||
asm_ab(ic->code + 12, ASM_STA, 0x0000);
|
||||
asm_ab(ic->code + 12, ASM_STX, 0x0000);
|
||||
|
||||
byte p = 15;
|
||||
for(byte i=2; i<size; i++)
|
||||
|
@ -328,10 +430,17 @@ void rirq_addr(RIRQCode * ic, byte n, void * addr)
|
|||
ic->code[p + 1] = (unsigned)addr >> 8;
|
||||
}
|
||||
|
||||
void rirq_addrhi(RIRQCode * ic, byte n, byte hi)
|
||||
{
|
||||
byte p = irqai[n];
|
||||
ic->code[p + 1] = hi;
|
||||
}
|
||||
|
||||
void rirq_data(RIRQCode * ic, byte n, byte data)
|
||||
{
|
||||
byte p = irqdi[n];
|
||||
ic->code[p] = data;
|
||||
// ic->code[p] = data;
|
||||
(volatile char *)(ic->code)[p] = data;
|
||||
}
|
||||
|
||||
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
|
||||
|
@ -370,21 +479,81 @@ void rirq_clear(byte n)
|
|||
rasterIRQRows[n] = 255;
|
||||
}
|
||||
|
||||
void rirq_init_kernal(void)
|
||||
void rirq_init_tables(void)
|
||||
{
|
||||
for(byte i=0; i<NUM_IRQS; i++)
|
||||
{
|
||||
rasterIRQRows[i] = 255;
|
||||
rasterIRQIndex[i] = i;
|
||||
rasterIRQIndex[i + 1] = i;
|
||||
}
|
||||
rasterIRQIndex[0] = NUM_IRQS;
|
||||
rasterIRQRows[NUM_IRQS] = 0;
|
||||
rasterIRQNext[NUM_IRQS] = 255;
|
||||
}
|
||||
|
||||
void rirq_init_kernal(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq1;
|
||||
*(void **)0x0314 = rirq_isr_kernal_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
vic.raster = 255;
|
||||
|
||||
}
|
||||
|
||||
void rirq_init_kernal_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = rirq_isr_kernal_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
vic.raster = 255;
|
||||
|
||||
}
|
||||
|
||||
void rirq_init_crt(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = rirq_isr_io.kentry;
|
||||
*(void **)0xfffe = rirq_isr_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
vic.raster = 255;
|
||||
|
||||
}
|
||||
|
||||
void rirq_init_crt_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = rirq_isr_noio.kentry;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -394,19 +563,14 @@ void rirq_init_kernal(void)
|
|||
|
||||
void rirq_init_io(void)
|
||||
{
|
||||
for(byte i=0; i<NUM_IRQS; i++)
|
||||
{
|
||||
rasterIRQRows[i] = 255;
|
||||
rasterIRQIndex[i] = i;
|
||||
}
|
||||
rasterIRQNext[NUM_IRQS] = 255;
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq0;
|
||||
*(void **)0xfffe = rirq_isr_ram_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -416,19 +580,14 @@ void rirq_init_io(void)
|
|||
|
||||
void rirq_init_memmap(void)
|
||||
{
|
||||
for(byte i=0; i<NUM_IRQS; i++)
|
||||
{
|
||||
rasterIRQRows[i] = 255;
|
||||
rasterIRQIndex[i] = i;
|
||||
}
|
||||
rasterIRQNext[NUM_IRQS] = 255;
|
||||
rirq_init_tables();
|
||||
|
||||
__asm
|
||||
{
|
||||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq2;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -446,12 +605,39 @@ void rirq_init(bool kernalIRQ)
|
|||
|
||||
void rirq_wait(void)
|
||||
{
|
||||
while (tpos != npos) ;
|
||||
npos++;
|
||||
char i0 = rirq_pcount;
|
||||
char i1;
|
||||
do {
|
||||
i1 = rirq_count;
|
||||
} while (i0 == i1);
|
||||
rirq_pcount = i1;
|
||||
}
|
||||
|
||||
void rirq_sort(void)
|
||||
void rirq_sort(bool inirq)
|
||||
{
|
||||
// disable raster interrupts while sorting
|
||||
nextIRQ = 0xff;
|
||||
#if 1
|
||||
byte maxr = rasterIRQRows[rasterIRQIndex[1]];
|
||||
for(byte i = 2; i<NUM_IRQS + 1; i++)
|
||||
{
|
||||
byte ri = rasterIRQIndex[i];
|
||||
byte rr = rasterIRQRows[ri];
|
||||
if (rr < maxr)
|
||||
{
|
||||
rasterIRQIndex[i] = rasterIRQIndex[i - 1];
|
||||
byte j = i, rj;
|
||||
while (rr < rasterIRQRows[(rj = rasterIRQIndex[j - 2])])
|
||||
{
|
||||
rasterIRQIndex[j - 1] = rj;
|
||||
j--;
|
||||
}
|
||||
rasterIRQIndex[j - 1] = ri;
|
||||
}
|
||||
else
|
||||
maxr = rr;
|
||||
}
|
||||
#else
|
||||
for(byte i = 1; i<NUM_IRQS; i++)
|
||||
{
|
||||
byte ri = rasterIRQIndex[i];
|
||||
|
@ -464,14 +650,32 @@ void rirq_sort(void)
|
|||
}
|
||||
rasterIRQIndex[j] = ri;
|
||||
}
|
||||
#endif
|
||||
|
||||
for(byte i=0; i<NUM_IRQS; i++)
|
||||
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i]];
|
||||
#if NUM_IRQS & 3
|
||||
for(sbyte i=NUM_IRQS-1; i>=0; i--)
|
||||
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i + 1]];
|
||||
#else
|
||||
for(sbyte i=NUM_IRQS/4-1; i>=0; i--)
|
||||
{
|
||||
#pragma unroll(full)
|
||||
for(int j=0; j<4; j++)
|
||||
rasterIRQNext[i + j * NUM_IRQS / 4] = rasterIRQRows[rasterIRQIndex[i + j * NUM_IRQS / 4 + 1]];
|
||||
}
|
||||
#endif
|
||||
|
||||
npos++;
|
||||
byte yp = rasterIRQNext[nextIRQ];
|
||||
if (yp != 0xff)
|
||||
vic.raster = yp - 1;
|
||||
rirq_pcount = rirq_count;
|
||||
if (inirq)
|
||||
nextIRQ = NUM_IRQS - 1;
|
||||
else
|
||||
{
|
||||
byte yp = rasterIRQNext[0];
|
||||
if (yp != 0xff)
|
||||
{
|
||||
vic.raster = yp - 1;
|
||||
nextIRQ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rirq_start(void)
|
||||
|
@ -485,6 +689,7 @@ void rirq_start(void)
|
|||
lda #100
|
||||
sta $d012
|
||||
|
||||
asl $d019
|
||||
cli
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,13 +123,17 @@ inline void rirq_call(RIRQCode * ic, byte n, void * addr);
|
|||
// Change the address of a raster IRQ write command
|
||||
inline void rirq_addr(RIRQCode * ic, byte n, void * addr);
|
||||
|
||||
// Change the high byte of the address of a raster IRQ write command
|
||||
inline void rirq_addrhi(RIRQCode * ic, byte n, byte hi);
|
||||
|
||||
// Change the data of a raster IRQ write command
|
||||
inline void rirq_data(RIRQCode * ic, byte n, byte data);
|
||||
|
||||
// Add a delay of 5 * cycles to a raster IRQ
|
||||
inline void rirq_delay(RIRQCode * ic, byte cycles);
|
||||
|
||||
// Place a raster IRQ into one of the 16 slots
|
||||
// Place a raster IRQ into one of the 16 slots, the interrupt will fire
|
||||
// one line below the given row
|
||||
inline void rirq_set(byte n, byte row, RIRQCode * write);
|
||||
|
||||
// Remove a raster IRQ from one of the 16 slots
|
||||
|
@ -144,10 +148,28 @@ inline void rirq_move(byte n, byte row);
|
|||
// the less resource hungry option)
|
||||
inline void rirq_init(bool kernalIRQ);
|
||||
|
||||
// Raster IRQ through kernal, with IO range always enabled
|
||||
// calls kernal continuation
|
||||
void rirq_init_kernal(void);
|
||||
|
||||
// Raster IRQ through kernal, with IO range not always enabled
|
||||
// calls kernal continuation
|
||||
void rirq_init_kernal_noio(void);
|
||||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_crt(void);
|
||||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range not always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_crt_noio(void);
|
||||
|
||||
// Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_io(void);
|
||||
|
||||
// Raster IRQ through RAM vector, with ROM disabled and IO range not always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_memmap(void);
|
||||
|
||||
// Start raster IRQ
|
||||
|
@ -157,8 +179,9 @@ void rirq_start(void);
|
|||
void rirq_stop(void);
|
||||
|
||||
// Sort the raster IRQ, must be performed at the end of the frame after changing
|
||||
// the vertical position of one of the interrupt operatins.
|
||||
void rirq_sort(void);
|
||||
// the vertical position of one of the interrupt operations.
|
||||
// Set the inirq flag to true when calling this from an interrupt
|
||||
void rirq_sort(bool inirq = false);
|
||||
|
||||
// Wait for the last raster IRQ op to have completed. Must be called before a
|
||||
// sort if the raster IRQ system is active
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
static volatile char * vspriteScreen;
|
||||
|
||||
#ifdef VSPRITE_BSS
|
||||
#pragma bss(VSPRITE_BSS)
|
||||
#endif
|
||||
|
||||
void spr_init(char * screen)
|
||||
{
|
||||
|
@ -143,7 +146,11 @@ void vspr_init(char * screen)
|
|||
|
||||
for(int i=0; i<VSPRITES_MAX - 8; i++)
|
||||
{
|
||||
#ifdef VSPRITE_REVERSE
|
||||
int j = (i & 7) ^ 7;
|
||||
#else
|
||||
int j = i & 7;
|
||||
#endif
|
||||
|
||||
rirq_build(spirq + i, 5);
|
||||
rirq_write(spirq + i, 0, &vic.spr_color[j], 0);
|
||||
|
@ -164,6 +171,21 @@ void vspr_init(char * screen)
|
|||
}
|
||||
}
|
||||
|
||||
void vspr_shutdown(void)
|
||||
{
|
||||
for(int i=0; i<VSPRITES_MAX - 7; i++)
|
||||
rirq_clear(i);
|
||||
}
|
||||
|
||||
void vspr_screen(char * screen)
|
||||
{
|
||||
vspriteScreen = screen + 0x3f8;
|
||||
char hi = (unsigned)vspriteScreen >> 8;
|
||||
#pragma unroll(8)
|
||||
for(int i=0; i<VSPRITES_MAX - 8; i++)
|
||||
rirq_addrhi(spirq + i, 3, hi);
|
||||
}
|
||||
|
||||
#pragma native(vspr_init)
|
||||
|
||||
void vspr_set(char sp, int xpos, int ypos, char image, char color)
|
||||
|
@ -192,6 +214,21 @@ void vspr_move(char sp, int xpos, int ypos)
|
|||
vspriteXHigh[sp] = (char)(xpos >> 8);
|
||||
}
|
||||
|
||||
void vspr_movex(char sp, int xpos)
|
||||
{
|
||||
vspriteXLow[sp] = (char)xpos;
|
||||
vspriteXHigh[sp] = (char)(xpos >> 8);
|
||||
}
|
||||
|
||||
void vspr_movey(char sp, int ypos)
|
||||
{
|
||||
char yp = (char)ypos;
|
||||
if (ypos & 0xff00)
|
||||
yp = 0xff;
|
||||
|
||||
vspriteYLow[sp] = yp;
|
||||
}
|
||||
|
||||
void vspr_image(char sp, char image)
|
||||
{
|
||||
vspriteImage[sp] = image;
|
||||
|
@ -209,22 +246,30 @@ void vspr_hide(char sp)
|
|||
|
||||
void vspr_sort(void)
|
||||
{
|
||||
spriteYPos[1] = vspriteYLow[spriteOrder[0]];
|
||||
byte rm = vspriteYLow[spriteOrder[0]];
|
||||
spriteYPos[1] = rm;
|
||||
|
||||
for(char i = 1; i<VSPRITES_MAX; i++)
|
||||
{
|
||||
byte ri = spriteOrder[i];
|
||||
byte rr = vspriteYLow[ri];
|
||||
byte j = i, rj = spriteYPos[j];
|
||||
while (rr < rj)
|
||||
if (rr < rm)
|
||||
{
|
||||
spriteYPos[j + 1] = rj;
|
||||
spriteOrder[j] = spriteOrder[j - 1];
|
||||
rj = spriteYPos[j - 1];
|
||||
j--;
|
||||
byte j = i, rj = rm;
|
||||
do {
|
||||
spriteYPos[j + 1] = rj;
|
||||
spriteOrder[j] = spriteOrder[j - 1];
|
||||
rj = spriteYPos[j - 1];
|
||||
j--;
|
||||
} while (rr < rj);
|
||||
spriteOrder[j] = ri;
|
||||
spriteYPos[j + 1] = rr;
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteYPos[i + 1] = rr;
|
||||
rm = rr;
|
||||
}
|
||||
spriteOrder[j] = ri;
|
||||
spriteYPos[j + 1] = rr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,44 +279,67 @@ void vspr_update(void)
|
|||
{
|
||||
char xymask = 0;
|
||||
volatile char * vsprs = vspriteScreen;
|
||||
// char sypos[VSPRITES_MAX];
|
||||
|
||||
#pragma unroll(full)
|
||||
|
||||
for(char ui=0; ui<8; ui++)
|
||||
{
|
||||
byte ri = spriteOrder[ui];
|
||||
byte ri = spriteOrder[ui];
|
||||
#ifdef VSPRITE_REVERSE
|
||||
char uj = ui ^ 7;
|
||||
#else
|
||||
char uj = ui;
|
||||
#endif
|
||||
|
||||
vic.spr_color[ui] = vspriteColor[ri];
|
||||
vsprs[ui] = vspriteImage[ri];
|
||||
vic.spr_color[uj] = vspriteColor[ri];
|
||||
vsprs[uj] = vspriteImage[ri];
|
||||
#ifdef VSPRITE_REVERSE
|
||||
xymask = (xymask << 1) | (vspriteXHigh[ri] & 1);
|
||||
#else
|
||||
xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1;
|
||||
vic.spr_pos[ui].x = vspriteXLow[ri];
|
||||
vic.spr_pos[ui].y = vspriteYLow[ri];
|
||||
#endif
|
||||
vic.spr_pos[uj].x = vspriteXLow[ri];
|
||||
vic.spr_pos[uj].y = spriteYPos[ui + 1];
|
||||
|
||||
// sypos[ui] = vspriteYLow[ri];
|
||||
}
|
||||
|
||||
vic.spr_msbx = xymask;
|
||||
|
||||
#pragma unroll(full)
|
||||
bool done = false;
|
||||
|
||||
for(char ti=0; ti<VSPRITES_MAX - 8; ti++)
|
||||
{
|
||||
if (spriteYPos[ti + 8] < 250)
|
||||
if (!done && spriteYPos[ti + 9] < 250)
|
||||
{
|
||||
char m = 1 << (ti & 7);
|
||||
|
||||
byte ri = spriteOrder[ti + 8];
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 23);
|
||||
|
||||
#ifdef VSPRITE_REVERSE
|
||||
char m = 0x80 >> (ti & 7);
|
||||
#else
|
||||
char m = 1 << (ti & 7);
|
||||
#endif
|
||||
|
||||
xymask |= m;
|
||||
if (!vspriteXHigh[ri])
|
||||
if (!(vspriteXHigh[ri] & 1))
|
||||
xymask ^= m;
|
||||
|
||||
rirq_data(spirq + ti, 2, spriteYPos[ti + 9]);
|
||||
rirq_data(spirq + ti, 0, vspriteColor[ri]);
|
||||
rirq_data(spirq + ti, 1, vspriteXLow[ri]);
|
||||
rirq_data(spirq + ti, 2, vspriteYLow[ri]);
|
||||
rirq_data(spirq + ti, 3, vspriteImage[ri]);
|
||||
|
||||
rirq_data(spirq + ti, 4, xymask);
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 23);
|
||||
// spriteYPos[ti + 9] = vspriteYLow[ri];
|
||||
}
|
||||
else
|
||||
{
|
||||
rirq_clear(ti);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,10 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
|
|||
|
||||
void vspr_init(char * screen);
|
||||
|
||||
void vspr_shutdown(void);
|
||||
|
||||
void vspr_screen(char * screen);
|
||||
|
||||
// set one sprite with the given attribute
|
||||
|
||||
void vspr_set(char sp, int xpos, int ypos, char image, char color);
|
||||
|
@ -76,6 +80,11 @@ void vspr_set(char sp, int xpos, int ypos, char image, char color);
|
|||
|
||||
inline void vspr_move(char sp, int xpos, int ypos);
|
||||
|
||||
inline void vspr_movex(char sp, int xpos);
|
||||
|
||||
inline void vspr_movey(char sp, int ypos);
|
||||
|
||||
|
||||
// change the image of a virtual sprite
|
||||
|
||||
inline void vspr_image(char sp, char image);
|
||||
|
|
|
@ -73,6 +73,15 @@ void vic_waitFrame(void)
|
|||
;
|
||||
}
|
||||
|
||||
void vic_waitFrames(char n)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
vic_waitFrame();
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
void vic_waitLine(int line)
|
||||
{
|
||||
char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
|
||||
|
@ -85,4 +94,41 @@ void vic_waitLine(int line)
|
|||
} while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper);
|
||||
}
|
||||
|
||||
void vic_waitBelow(int line)
|
||||
{
|
||||
char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
|
||||
char lower = (char)line;
|
||||
|
||||
if (upper)
|
||||
{
|
||||
do
|
||||
{
|
||||
while (vic.raster <= lower)
|
||||
;
|
||||
} while (!(vic.ctrl1 & VIC_CTRL1_RST8));
|
||||
}
|
||||
else
|
||||
{
|
||||
while (vic.raster <= lower)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void vic_waitRange(char below, char above)
|
||||
{
|
||||
while (vic.ctrl1 & VIC_CTRL1_RST8)
|
||||
;
|
||||
|
||||
if (vic.raster >= above)
|
||||
{
|
||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
while (vic.ctrl1 & VIC_CTRL1_RST8)
|
||||
;
|
||||
}
|
||||
|
||||
while (vic.raster < below)
|
||||
;
|
||||
}
|
||||
|
||||
#pragma native(vic_waitLine)
|
||||
|
|
|
@ -109,9 +109,18 @@ inline void vic_waitTop(void);
|
|||
// wait for the top of the frame and then for the bottom of the visual area
|
||||
inline void vic_waitFrame(void);
|
||||
|
||||
// wait for n frames
|
||||
void vic_waitFrames(char n);
|
||||
|
||||
// wait for a specific raster line
|
||||
void vic_waitLine(int line);
|
||||
|
||||
// wait for beam to be below a line
|
||||
void vic_waitBelow(int line);
|
||||
|
||||
// wait for beam to be in a given range on screen
|
||||
void vic_waitRange(char below, char above);
|
||||
|
||||
// reference to the VIC chip
|
||||
#define vic (*((struct VIC *)0xd000))
|
||||
|
||||
|
|
385
include/conio.c
385
include/conio.c
|
@ -18,6 +18,13 @@ __asm bsin
|
|||
jsr 0xffe4
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsget
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xffcf
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
lda #0
|
||||
|
@ -39,6 +46,13 @@ __asm dswap
|
|||
sta 0xff01
|
||||
}
|
||||
#pragma code(code)
|
||||
#elif defined(__C128B__) || defined(__C128E__)
|
||||
#define dswap 0xff5f
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
#define bsget 0xffcf
|
||||
#define bsplot 0xfff0
|
||||
#define bsinit 0xff81
|
||||
#elif defined(__PLUS4__)
|
||||
#pragma code(lowcode)
|
||||
__asm bsout
|
||||
|
@ -53,6 +67,12 @@ __asm bsin
|
|||
jsr 0xffe4
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsget
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffcf
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
sta 0xff3e
|
||||
|
@ -85,6 +105,14 @@ __asm bsin
|
|||
pha
|
||||
}
|
||||
|
||||
__asm bsget
|
||||
{
|
||||
lda 0xe405
|
||||
pha
|
||||
lda 0xe404
|
||||
pha
|
||||
}
|
||||
|
||||
__asm bsplot
|
||||
{
|
||||
|
||||
|
@ -93,14 +121,37 @@ __asm bsinit
|
|||
{
|
||||
|
||||
}
|
||||
#elif defined(__VIC20__)
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
#define bsplot 0xfff0
|
||||
#define bsget 0xffcf
|
||||
__asm bsinit
|
||||
{
|
||||
lda #147
|
||||
jmp $ffd2
|
||||
}
|
||||
#elif defined(__CBMPET__)
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
__asm bsplot
|
||||
{
|
||||
/* no equivalent on PET */
|
||||
}
|
||||
__asm bsinit
|
||||
{
|
||||
/* no equivalent on PET */
|
||||
}
|
||||
#define bsget 0xffcf
|
||||
#else
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
#define bsplot 0xfff0
|
||||
#define bsinit 0xff81
|
||||
#define bsget 0xffcf
|
||||
#endif
|
||||
|
||||
#if defined(__C128__)
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
void dispmode40col(void)
|
||||
{
|
||||
if (*(volatile char *)0xd7 >= 128)
|
||||
|
@ -130,204 +181,246 @@ void iocharmap(IOCharMap chmap)
|
|||
giocharmap = chmap;
|
||||
#if !defined(__ATARI__)
|
||||
if (chmap == IOCHM_PETSCII_1)
|
||||
putch(128 + 14);
|
||||
putrch(128 + 14);
|
||||
else if (chmap == IOCHM_PETSCII_2)
|
||||
putch(14);
|
||||
putrch(14);
|
||||
#endif
|
||||
}
|
||||
|
||||
__asm putpch
|
||||
void putrch(char c)
|
||||
{
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
|
||||
cmp #10
|
||||
bne w1
|
||||
lda #13
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
|
||||
cmp #65
|
||||
bcc w3
|
||||
cmp #123
|
||||
bcs w3
|
||||
|
||||
#if defined(__CBMPET__)
|
||||
cmp #97
|
||||
bcs w4
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$a0
|
||||
w4:
|
||||
eor #$20
|
||||
__asm {
|
||||
lda c
|
||||
jsr bsout
|
||||
}
|
||||
}
|
||||
|
||||
void putpch(char c)
|
||||
{
|
||||
#if defined(__ATARI__)
|
||||
if (c == 10)
|
||||
c = 0x9b;
|
||||
#else
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
if (giocharmap >= IOCHM_ASCII)
|
||||
{
|
||||
if (c == '\n')
|
||||
c = 13;
|
||||
else if (c == '\t')
|
||||
{
|
||||
char n = wherex() & 3;
|
||||
do {
|
||||
putrch(' ');
|
||||
} while (++n < 4);
|
||||
return;
|
||||
}
|
||||
else if (giocharmap >= IOCHM_PETSCII_1)
|
||||
{
|
||||
if (c >= 65 && c < 123)
|
||||
{
|
||||
if (c >= 97 || c < 91)
|
||||
{
|
||||
#if defined(__CBMPET__)
|
||||
if (c >= 97)
|
||||
c ^= 0xa0;
|
||||
c ^= 0x20;
|
||||
#else
|
||||
c ^= 0x20;
|
||||
#endif
|
||||
|
||||
if (giocharmap == IOCHM_PETSCII_1)
|
||||
c &= 0xdf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
cpx #IOCHM_PETSCII_2
|
||||
beq w3
|
||||
and #$df
|
||||
w3:
|
||||
jmp bsout
|
||||
|
||||
putrch(c);
|
||||
}
|
||||
|
||||
__asm getpch
|
||||
static char convch(char ch)
|
||||
{
|
||||
jsr bsin
|
||||
#if !defined(__ATARI__)
|
||||
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
if (giocharmap >= IOCHM_ASCII)
|
||||
{
|
||||
if (ch == 13)
|
||||
ch = 10;
|
||||
else if (giocharmap >= IOCHM_PETSCII_1)
|
||||
{
|
||||
if (ch >= 65 && ch < 219)
|
||||
{
|
||||
if (ch >= 193)
|
||||
ch ^= 0xa0;
|
||||
if (ch < 123 && (ch >= 97 || ch < 91))
|
||||
ch ^= 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmp #13
|
||||
bne w1
|
||||
lda #10
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
||||
cmp #219
|
||||
bcs w3
|
||||
cmp #65
|
||||
bcc w3
|
||||
char getrch(void)
|
||||
{
|
||||
return __asm {
|
||||
jsr bsget
|
||||
sta accu
|
||||
};
|
||||
}
|
||||
|
||||
cmp #193
|
||||
bcc w4
|
||||
eor #$a0
|
||||
w4:
|
||||
cmp #123
|
||||
bcs w3
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
w3:
|
||||
char getpch(void)
|
||||
{
|
||||
return convch(getrch());
|
||||
}
|
||||
|
||||
|
||||
int kbhit(void)
|
||||
char kbhit(void)
|
||||
{
|
||||
__asm
|
||||
#if defined(__CBMPET__)
|
||||
return __asm
|
||||
{
|
||||
lda $9e
|
||||
sta accu
|
||||
};
|
||||
#else
|
||||
return __asm
|
||||
{
|
||||
lda $c6
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
int getche(void)
|
||||
char getche(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
L1:
|
||||
jsr getpch
|
||||
cmp #0
|
||||
beq L1
|
||||
char ch;
|
||||
do {
|
||||
ch = __asm {
|
||||
jsr bsin
|
||||
sta accu
|
||||
};
|
||||
} while (!ch);
|
||||
|
||||
sta accu
|
||||
jsr putpch
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int getch(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
L1:
|
||||
jsr getpch
|
||||
cmp #0
|
||||
beq L1
|
||||
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
}
|
||||
|
||||
int getchx(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr getpch
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
}
|
||||
|
||||
void putch(int c)
|
||||
{
|
||||
__asm {
|
||||
lda c
|
||||
lda ch
|
||||
jsr bsout
|
||||
}
|
||||
|
||||
return convch(ch);
|
||||
}
|
||||
|
||||
char getch(void)
|
||||
{
|
||||
char ch;
|
||||
do {
|
||||
ch = __asm {
|
||||
jsr bsin
|
||||
sta accu
|
||||
};
|
||||
} while (!ch);
|
||||
|
||||
return convch(ch);
|
||||
}
|
||||
|
||||
char getchx(void)
|
||||
{
|
||||
char ch = __asm {
|
||||
jsr bsin
|
||||
sta accu
|
||||
};
|
||||
|
||||
return convch(ch);
|
||||
}
|
||||
|
||||
void putch(char c)
|
||||
{
|
||||
putpch(c);
|
||||
}
|
||||
|
||||
void clrscr(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr bsinit
|
||||
}
|
||||
putrch(147);
|
||||
}
|
||||
|
||||
void textcursor(bool show)
|
||||
{
|
||||
*(char *)0xcc = show ? 0 : 1;
|
||||
*(volatile char *)0xcc = show ? 0 : 1;
|
||||
}
|
||||
|
||||
void gotoxy(int cx, int cy)
|
||||
void gotoxy(char cx, char cy)
|
||||
{
|
||||
#if defined(__CBMPET__)
|
||||
#define CURS_X 0xc6
|
||||
#define CURS_Y 0xd8
|
||||
#define SCREEN_PTR 0xc4
|
||||
#define SCR_LINELEN 0xd5
|
||||
|
||||
__assume(cy < 25);
|
||||
|
||||
*(volatile char *)CURS_X = cx;
|
||||
*(volatile char *)CURS_Y = cy;
|
||||
|
||||
if (*(volatile char *)SCR_LINELEN > 40)
|
||||
cy <<= 1;
|
||||
|
||||
const unsigned off = cy * 40;
|
||||
|
||||
* (volatile unsigned *)SCREEN_PTR = off + 0x8000;
|
||||
#else
|
||||
__asm
|
||||
{
|
||||
ldx cy
|
||||
ldy cx
|
||||
clc
|
||||
jsr bsplot
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void textcolor(int c)
|
||||
void textcolor(char c)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda c
|
||||
sta $0286
|
||||
}
|
||||
*(volatile char *)0x0286 = c;
|
||||
}
|
||||
|
||||
int wherex(void)
|
||||
void bgcolor(char c)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda $d3
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
*(volatile char *)0xd021 = c;
|
||||
}
|
||||
|
||||
int wherey(void)
|
||||
void bordercolor(char c)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda $d6
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
*(volatile char *)0xd020 = c;
|
||||
}
|
||||
|
||||
void revers(char r)
|
||||
{
|
||||
if (r)
|
||||
putrch(18);
|
||||
else
|
||||
putrch(18 + 128);
|
||||
}
|
||||
|
||||
char wherex(void)
|
||||
{
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
return *(volatile char *)0xec;
|
||||
#elif defined(__PLUS4__)
|
||||
return *(volatile char *)0xca;
|
||||
#else
|
||||
return *(volatile char *)0xd3;
|
||||
#endif
|
||||
}
|
||||
|
||||
char wherey(void)
|
||||
{
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
return *(volatile char *)0xeb;
|
||||
#elif defined(__PLUS4__)
|
||||
return *(volatile char *)0xcd;
|
||||
#else
|
||||
return *(volatile char *)0xd6;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -18,36 +18,95 @@ extern IOCharMap giocharmap;
|
|||
|
||||
void iocharmap(IOCharMap chmap);
|
||||
|
||||
#if defined(__C128__)
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
void dispmode40col(void);
|
||||
void dispmode80col(void);
|
||||
#endif
|
||||
|
||||
int kbhit(void);
|
||||
#define PETSCII_CURSOR_LEFT 0x9d
|
||||
#define PETSCII_CURSOR_RIGHT 0x1d
|
||||
#define PETSCII_CURSOR_UP 0x91
|
||||
#define PETSCII_CURSOR_DOWN 0x11
|
||||
#define PETSCII_HOME 0x13
|
||||
#define PETSCII_CLEAR 0x94
|
||||
#define PETSCII_DEL 0x14
|
||||
#define PETSCII_INSERT 0x94
|
||||
#define PETSCII_STOP 0x03
|
||||
#define PETSCII_RETURN 0x0d
|
||||
|
||||
int getche(void);
|
||||
#define PETSCII_F1 0x85
|
||||
#define PETSCII_F2 0x89
|
||||
#define PETSCII_F3 0x86
|
||||
#define PETSCII_F4 0x8a
|
||||
#define PETSCII_F5 0x87
|
||||
#define PETSCII_F6 0x8b
|
||||
#define PETSCII_F7 0x88
|
||||
#define PETSCII_F8 0x8c
|
||||
|
||||
int getch(void);
|
||||
enum ConioColors
|
||||
{
|
||||
COLOR_BLACK,
|
||||
COLOR_WHITE,
|
||||
COLOR_RED,
|
||||
COLOR_CYAN,
|
||||
COLOR_PURPLE,
|
||||
COLOR_GREEN,
|
||||
COLOR_BLUE,
|
||||
COLOR_YELLOW,
|
||||
|
||||
COLOR_ORANGE,
|
||||
COLOR_BROWN,
|
||||
COLOR_LT_RED,
|
||||
COLOR_DARK_GREY,
|
||||
COLOR_MED_GREY,
|
||||
COLOR_LT_GREEN,
|
||||
COLOR_LT_BLUE,
|
||||
COLOR_LT_GREY
|
||||
};
|
||||
// Lowlevel console in/out
|
||||
|
||||
// using petscii translation
|
||||
void putpch(char c);
|
||||
char getpch(void);
|
||||
|
||||
// using no translation
|
||||
inline void putrch(char c);
|
||||
inline char getrch(void);
|
||||
|
||||
|
||||
// Standard console in/out
|
||||
|
||||
char kbhit(void);
|
||||
|
||||
char getche(void);
|
||||
|
||||
char getch(void);
|
||||
|
||||
// like getch but does not wait, returns zero if no
|
||||
// key is pressed
|
||||
int getchx(void);
|
||||
char getchx(void);
|
||||
|
||||
void putch(int c);
|
||||
void putch(char c);
|
||||
|
||||
void clrscr(void);
|
||||
|
||||
void gotoxy(int x, int y);
|
||||
void gotoxy(char x, char y);
|
||||
|
||||
void textcolor(int c);
|
||||
inline void textcolor(char c);
|
||||
|
||||
int wherex(void);
|
||||
inline void bgcolor(char c);
|
||||
|
||||
int wherey(void);
|
||||
inline void bordercolor(char c);
|
||||
|
||||
inline void revers(char r);
|
||||
|
||||
inline char wherex(void);
|
||||
|
||||
inline char wherey(void);
|
||||
|
||||
// show or hide the text cursor
|
||||
|
||||
void textcursor(bool show);
|
||||
inline void textcursor(bool show);
|
||||
|
||||
#pragma compile("conio.c")
|
||||
|
||||
|
|
790
include/crt.c
790
include/crt.c
File diff suppressed because it is too large
Load Diff
|
@ -144,8 +144,8 @@ enum ByteCode
|
|||
BC_LOOP_U8,
|
||||
BC_MALLOC,
|
||||
BC_FREE,
|
||||
BC_UNUSED_4,
|
||||
BC_UNUSED_5,
|
||||
BC_FILL,
|
||||
BC_FILL_LONG,
|
||||
BC_UNUSED_6,
|
||||
|
||||
BC_JSR,
|
||||
|
@ -186,6 +186,11 @@ enum ByteCode
|
|||
BC_BINOP_SHR_I32,
|
||||
BC_BINOP_CMP_U32,
|
||||
BC_BINOP_CMP_S32,
|
||||
|
||||
BC_CONV_U32_F32,
|
||||
BC_CONV_I32_F32,
|
||||
BC_CONV_F32_U32,
|
||||
BC_CONV_F32_I32,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -116,31 +116,38 @@ int lmul4f12s(int x, int y)
|
|||
{
|
||||
__asm
|
||||
{
|
||||
bit y + 1
|
||||
bpl W0
|
||||
|
||||
sec
|
||||
lda #0
|
||||
sbc y
|
||||
sta y
|
||||
lda #0
|
||||
sbc y + 1
|
||||
sta y + 1
|
||||
lda x
|
||||
ror
|
||||
sta accu
|
||||
|
||||
sec
|
||||
lda #0
|
||||
sbc x
|
||||
sta x
|
||||
lda #0
|
||||
sbc x + 1
|
||||
sta x + 1
|
||||
W0:
|
||||
ldx #15
|
||||
lda #0
|
||||
sta accu + 1
|
||||
|
||||
L1: lsr x + 1
|
||||
ror x
|
||||
bcc W4
|
||||
L2:
|
||||
tay
|
||||
clc
|
||||
lda accu + 1
|
||||
adc y
|
||||
sta accu + 1
|
||||
tya
|
||||
adc y + 1
|
||||
W4:
|
||||
ror
|
||||
ror accu + 1
|
||||
|
||||
lsr accu
|
||||
bcc W4
|
||||
bne L2
|
||||
|
||||
ldx x + 1
|
||||
stx accu
|
||||
|
||||
ldx #7
|
||||
lsr accu
|
||||
|
||||
L1:
|
||||
bcc W1
|
||||
tay
|
||||
clc
|
||||
|
@ -156,23 +163,31 @@ W1:
|
|||
dex
|
||||
bne L1
|
||||
|
||||
lsr x
|
||||
bcc W2
|
||||
|
||||
tay
|
||||
sec
|
||||
// sec ; we know it is set here
|
||||
lda accu + 1
|
||||
sbc y
|
||||
sta accu + 1
|
||||
tya
|
||||
sbc y + 1
|
||||
|
||||
sec
|
||||
W2:
|
||||
ror
|
||||
ror accu + 1
|
||||
ror accu
|
||||
|
||||
bit y + 1
|
||||
bpl W3
|
||||
|
||||
tax
|
||||
sec
|
||||
lda accu + 1
|
||||
sbc x
|
||||
sta accu + 1
|
||||
txa
|
||||
sbc x + 1
|
||||
W3:
|
||||
lsr
|
||||
ror accu + 1
|
||||
ror accu
|
||||
|
@ -270,15 +285,17 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
|
|||
__asm
|
||||
{
|
||||
lda #0
|
||||
sta __tmp + 0
|
||||
sta __tmp + 1
|
||||
sta __tmp + 2
|
||||
sta __tmp + 3
|
||||
|
||||
ldx #16
|
||||
L1: lsr a + 1
|
||||
ror a
|
||||
lda a
|
||||
sec
|
||||
T1:
|
||||
ldy #8
|
||||
L1:
|
||||
ror
|
||||
bcc W1
|
||||
tax
|
||||
clc
|
||||
lda __tmp + 2
|
||||
adc b
|
||||
|
@ -286,20 +303,38 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
|
|||
lda __tmp + 3
|
||||
adc b + 1
|
||||
sta __tmp + 3
|
||||
txa
|
||||
W1:
|
||||
ror __tmp + 3
|
||||
ror __tmp + 2
|
||||
ror __tmp + 1
|
||||
ror __tmp
|
||||
dex
|
||||
dey
|
||||
bne L1
|
||||
ror
|
||||
bcc T2
|
||||
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
sta __tmp + 0
|
||||
lda a + 1
|
||||
clc
|
||||
bcc T1
|
||||
|
||||
ldx #17
|
||||
T2:
|
||||
sec
|
||||
L3:
|
||||
sta __tmp + 1
|
||||
ldx #8
|
||||
L2:
|
||||
rol __tmp + 1
|
||||
rol __tmp + 2
|
||||
rol __tmp + 3
|
||||
bcc W3
|
||||
lda __tmp + 2
|
||||
sbc c
|
||||
tay
|
||||
lda __tmp + 3
|
||||
sbc c + 1
|
||||
sec
|
||||
bcs W4
|
||||
W3:
|
||||
sec
|
||||
lda __tmp + 2
|
||||
sbc c
|
||||
|
@ -307,33 +342,23 @@ unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c)
|
|||
lda __tmp + 3
|
||||
sbc c + 1
|
||||
bcc W2
|
||||
W4:
|
||||
sta __tmp + 3
|
||||
sty __tmp + 2
|
||||
W2:
|
||||
rol accu
|
||||
rol accu + 1
|
||||
|
||||
asl __tmp
|
||||
rol __tmp + 1
|
||||
rol __tmp + 2
|
||||
rol __tmp + 3
|
||||
|
||||
dex
|
||||
beq E2
|
||||
bcc L2
|
||||
|
||||
lda __tmp + 2
|
||||
sbc c
|
||||
sta __tmp + 2
|
||||
lda __tmp + 3
|
||||
sbc c + 1
|
||||
sta __tmp + 3
|
||||
sec
|
||||
bcs W2
|
||||
E2:
|
||||
bne L2
|
||||
lda __tmp + 1
|
||||
rol
|
||||
bcc T3
|
||||
|
||||
sta accu + 1
|
||||
lda __tmp + 0
|
||||
clc
|
||||
bcc L3
|
||||
T3:
|
||||
sta accu
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int lmuldiv16s(int a, int b, int c)
|
||||
|
@ -358,15 +383,17 @@ int lmuldiv16s(int a, int b, int c)
|
|||
__asm
|
||||
{
|
||||
lda #0
|
||||
sta __tmp + 0
|
||||
sta __tmp + 1
|
||||
sta __tmp + 2
|
||||
sta __tmp + 3
|
||||
|
||||
ldx #16
|
||||
L1: lsr a + 1
|
||||
ror a
|
||||
lda a
|
||||
sec
|
||||
T1:
|
||||
ldy #8
|
||||
L1:
|
||||
ror
|
||||
bcc W1
|
||||
tax
|
||||
clc
|
||||
lda __tmp + 2
|
||||
adc b
|
||||
|
@ -374,20 +401,38 @@ int lmuldiv16s(int a, int b, int c)
|
|||
lda __tmp + 3
|
||||
adc b + 1
|
||||
sta __tmp + 3
|
||||
txa
|
||||
W1:
|
||||
ror __tmp + 3
|
||||
ror __tmp + 2
|
||||
ror __tmp + 1
|
||||
ror __tmp
|
||||
dex
|
||||
dey
|
||||
bne L1
|
||||
ror
|
||||
bcc T2
|
||||
|
||||
lda #0
|
||||
sta accu
|
||||
sta accu + 1
|
||||
sta __tmp + 0
|
||||
lda a + 1
|
||||
clc
|
||||
bcc T1
|
||||
|
||||
ldx #17
|
||||
T2:
|
||||
sec
|
||||
L3:
|
||||
sta __tmp + 1
|
||||
ldx #8
|
||||
L2:
|
||||
rol __tmp + 1
|
||||
rol __tmp + 2
|
||||
rol __tmp + 3
|
||||
bcc W3
|
||||
lda __tmp + 2
|
||||
sbc c
|
||||
tay
|
||||
lda __tmp + 3
|
||||
sbc c + 1
|
||||
sec
|
||||
bcs W4
|
||||
W3:
|
||||
sec
|
||||
lda __tmp + 2
|
||||
sbc c
|
||||
|
@ -395,30 +440,23 @@ int lmuldiv16s(int a, int b, int c)
|
|||
lda __tmp + 3
|
||||
sbc c + 1
|
||||
bcc W2
|
||||
W4:
|
||||
sta __tmp + 3
|
||||
sty __tmp + 2
|
||||
W2:
|
||||
rol accu
|
||||
rol accu + 1
|
||||
|
||||
asl __tmp
|
||||
rol __tmp + 1
|
||||
rol __tmp + 2
|
||||
rol __tmp + 3
|
||||
|
||||
dex
|
||||
beq E2
|
||||
bcc L2
|
||||
bne L2
|
||||
lda __tmp + 1
|
||||
rol
|
||||
bcc T3
|
||||
|
||||
sta accu + 1
|
||||
lda __tmp + 0
|
||||
clc
|
||||
bcc L3
|
||||
T3:
|
||||
sta accu
|
||||
|
||||
lda __tmp + 2
|
||||
sbc c
|
||||
sta __tmp + 2
|
||||
lda __tmp + 3
|
||||
sbc c + 1
|
||||
sta __tmp + 3
|
||||
sec
|
||||
bcs W2
|
||||
E2:
|
||||
lda sign
|
||||
beq E1
|
||||
|
||||
|
@ -610,3 +648,264 @@ unsigned usqrt(unsigned n)
|
|||
|
||||
return p;
|
||||
}
|
||||
|
||||
unsigned long lmul16f16(unsigned long x, unsigned long y)
|
||||
{
|
||||
unsigned long hh = lmul16u(x >> 16, y >> 16);
|
||||
unsigned long lh = lmul16u(x, y >> 16);
|
||||
unsigned long hl = lmul16u(x >> 16, y);
|
||||
unsigned long ll = lmul16u(x, y);
|
||||
|
||||
if (ll & 0x8000)
|
||||
lh++;
|
||||
ll >>= 16;
|
||||
ll |= hh << 16;
|
||||
ll += lh;
|
||||
ll += hl;
|
||||
|
||||
return ll;
|
||||
}
|
||||
|
||||
#if 1
|
||||
long lmul16f16s(long x, long y)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
lda #0
|
||||
// fractional
|
||||
sta __tmp + 0
|
||||
sta __tmp + 1
|
||||
|
||||
// result
|
||||
sta __accu + 0
|
||||
sta __accu + 1
|
||||
sta __accu + 2
|
||||
sta __accu + 3
|
||||
|
||||
lda x + 0
|
||||
ora x + 1
|
||||
ora y + 0
|
||||
ora y + 1
|
||||
bne w0b
|
||||
|
||||
l2:
|
||||
|
||||
lsr x + 2
|
||||
bcc ws1
|
||||
|
||||
clc
|
||||
lda y + 2
|
||||
adc __accu + 2
|
||||
sta __accu + 2
|
||||
lda y + 3
|
||||
adc __accu + 3
|
||||
sta __accu + 3
|
||||
ws1:
|
||||
|
||||
lsr x + 3
|
||||
bcc ws2
|
||||
|
||||
clc
|
||||
lda y + 2
|
||||
adc __accu + 3
|
||||
sta __accu + 3
|
||||
ws2:
|
||||
|
||||
asl y + 2
|
||||
rol y + 3
|
||||
|
||||
lda x + 2
|
||||
ora x + 3
|
||||
bne l2
|
||||
rts
|
||||
|
||||
w0b:
|
||||
|
||||
lda y + 3
|
||||
and #$80
|
||||
beq w0
|
||||
lda #$ff
|
||||
w0:
|
||||
// overflow
|
||||
sta __tmp + 2
|
||||
sta __tmp + 3
|
||||
|
||||
lda x + 3
|
||||
bpl w0a
|
||||
|
||||
sec
|
||||
lda #0
|
||||
sbc y + 0
|
||||
sta __accu + 2
|
||||
lda #0
|
||||
sbc y + 1
|
||||
sta __accu + 3
|
||||
w0a:
|
||||
|
||||
ldx #8
|
||||
|
||||
l1:
|
||||
lsr x + 0
|
||||
bcc w1
|
||||
|
||||
clc
|
||||
lda y + 0
|
||||
adc __tmp + 0
|
||||
sta __tmp + 0
|
||||
lda y + 1
|
||||
adc __tmp + 1
|
||||
sta __tmp + 1
|
||||
lda y + 2
|
||||
adc __accu + 0
|
||||
sta __accu + 0
|
||||
lda y + 3
|
||||
adc __accu + 1
|
||||
sta __accu + 1
|
||||
lda __tmp + 2
|
||||
adc __accu + 2
|
||||
sta __accu + 2
|
||||
lda __tmp + 3
|
||||
adc __accu + 3
|
||||
sta __accu + 3
|
||||
w1:
|
||||
|
||||
lsr x + 1
|
||||
bcc w2
|
||||
|
||||
clc
|
||||
lda y + 0
|
||||
adc __tmp + 1
|
||||
sta __tmp + 1
|
||||
lda y + 1
|
||||
adc __accu + 0
|
||||
sta __accu + 0
|
||||
lda y + 2
|
||||
adc __accu + 1
|
||||
sta __accu + 1
|
||||
lda y + 3
|
||||
adc __accu + 2
|
||||
sta __accu + 2
|
||||
lda __tmp + 2
|
||||
adc __accu + 3
|
||||
sta __accu + 3
|
||||
w2:
|
||||
|
||||
lsr x + 2
|
||||
bcc w3
|
||||
|
||||
clc
|
||||
lda y + 0
|
||||
adc __accu + 0
|
||||
sta __accu + 0
|
||||
lda y + 1
|
||||
adc __accu + 1
|
||||
sta __accu + 1
|
||||
lda y + 2
|
||||
adc __accu + 2
|
||||
sta __accu + 2
|
||||
lda y + 3
|
||||
adc __accu + 3
|
||||
sta __accu + 3
|
||||
w3:
|
||||
|
||||
lsr x + 3
|
||||
bcc w4
|
||||
|
||||
clc
|
||||
lda y + 0
|
||||
adc __accu + 1
|
||||
sta __accu + 1
|
||||
lda y + 1
|
||||
adc __accu + 2
|
||||
sta __accu + 2
|
||||
lda y + 2
|
||||
adc __accu + 3
|
||||
sta __accu + 3
|
||||
w4:
|
||||
|
||||
asl y + 0
|
||||
rol y + 1
|
||||
rol y + 2
|
||||
rol y + 3
|
||||
rol __tmp + 2
|
||||
rol __tmp + 3
|
||||
|
||||
dex
|
||||
beq w5
|
||||
jmp l1
|
||||
w5:
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
__native long lmul16f16s(long x, long y)
|
||||
{
|
||||
unsigned lox = x;
|
||||
int hix = x >> 16;
|
||||
unsigned loy = y;
|
||||
int hiy = y >> 16;
|
||||
|
||||
long r = (long)(hix * hiy) << 16;
|
||||
|
||||
if (lox)
|
||||
{
|
||||
r += lmul16u(lox, hiy);
|
||||
if (hiy < 0)
|
||||
r -= (unsigned long)lox << 16;
|
||||
}
|
||||
if (loy)
|
||||
{
|
||||
r += lmul16u(loy, hix);
|
||||
if (hix < 0)
|
||||
r -= (unsigned long)loy << 16;
|
||||
}
|
||||
if (lox && loy)
|
||||
{
|
||||
r += lmul16u(lox, loy) >> 16;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
__native unsigned long ldiv16f16(unsigned long x, unsigned long y)
|
||||
{
|
||||
unsigned long k = x >> 16, d = 0;
|
||||
x <<= 16;
|
||||
|
||||
for(char i=0; i<32; i++)
|
||||
{
|
||||
d <<= 1;
|
||||
k <<= 1;
|
||||
k |= (x >> 31);
|
||||
x <<= 1;
|
||||
if (k >= y)
|
||||
{
|
||||
k -= y;
|
||||
d |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
__native long ldiv16f16s(long x, long y)
|
||||
{
|
||||
bool sign = false;
|
||||
if (x < 0)
|
||||
{
|
||||
x = -x;
|
||||
sign = true;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
y = -y;
|
||||
sign = !sign;
|
||||
}
|
||||
|
||||
x = ldiv16f16(x, y);
|
||||
if (sign)
|
||||
return -x;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,15 @@ __native unsigned lmuldiv8by8(char a, char b, char c);
|
|||
|
||||
__native unsigned usqrt(unsigned n);
|
||||
|
||||
__native unsigned long lmul16f16(unsigned long x, unsigned long y);
|
||||
|
||||
__native long lmul16f16s(long x, long y);
|
||||
|
||||
__native unsigned long ldiv16f16(unsigned long x, unsigned long y);
|
||||
|
||||
__native long ldiv16f16s(long x, long y);
|
||||
|
||||
|
||||
#pragma compile("fixmath.c")
|
||||
|
||||
#endif
|
||||
|
|
|
@ -525,7 +525,7 @@ void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int
|
|||
static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
|
||||
{
|
||||
char ip = 0;
|
||||
bool delta16 = ((dx | dy) & 0xff80) != 0;
|
||||
bool delta16 =((dx | dy) & 0xff80) != 0;
|
||||
|
||||
// ylow
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly);
|
||||
|
@ -579,59 +579,105 @@ static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool
|
|||
break;
|
||||
}
|
||||
|
||||
// m >= 0
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, delta16 ? 5 + 15 + 13 + 2 : 5 + 15 + 7 + 2);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, up ? ASM_DEY : ASM_INY);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_CPY, up ? 0xff : 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 15);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, up ? 0x07 : 0x00);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
|
||||
if (delta16)
|
||||
if (dy)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
bool delta8 = false;
|
||||
|
||||
if (dx)
|
||||
{
|
||||
// m >= 0
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
|
||||
char n = delta16 ? 18 + 13 + 2 : 18 + 7 + 2;
|
||||
if (!up) n++;
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, n);
|
||||
delta8 = !delta16;
|
||||
}
|
||||
|
||||
if (up)
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_DEY);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta8 ? 17 : 15);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x07);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_INY);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_CPY, 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, delta8 ? 16 : 14);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x00);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
}
|
||||
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
|
||||
if (delta16)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 13 + 4 + 12);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We know regdp to be in the accu at this point
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 5 + 4 + 12);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
}
|
||||
}
|
||||
|
||||
// m < 0
|
||||
}
|
||||
|
||||
// m < 0
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta16 ? 4 + 15 + 13 : 4 + 15 + 7);
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 15);
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xf8 : 0x08);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xff : 0x00);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
if (delta16)
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12);
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
|
||||
if (left)
|
||||
{
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0xf8);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCS, 2);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_SP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 2);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_SP + 1);
|
||||
}
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
}
|
||||
|
||||
// l --
|
||||
|
@ -649,6 +695,7 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern)
|
|||
{
|
||||
__asm
|
||||
{
|
||||
|
||||
lda dst
|
||||
sta REG_SP
|
||||
lda dst + 1
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#include "inttypes.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
|
||||
intmax_t imaxabs(intmax_t n)
|
||||
{
|
||||
return n < 0 ? -n : n;
|
||||
}
|
||||
|
||||
imaxdiv_t imaxdiv(intmax_t l, intmax_t r)
|
||||
{
|
||||
imaxdiv_t t;
|
||||
t.quot = l / r;
|
||||
t.rem = l % r;
|
||||
return t;
|
||||
}
|
||||
|
||||
inline intmax_t strtoimax(const char * s, char ** endp, int base)
|
||||
{
|
||||
return strtol(s, endp, base);
|
||||
}
|
||||
|
||||
inline uintmax_t strtoumax(const char * s, char ** endp, int base)
|
||||
{
|
||||
return strtoul(s, endp, base);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef INTTYPES_H
|
||||
#define INTTYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PRId8 "d"
|
||||
#define PRId16 "d"
|
||||
#define PRId32 "ld"
|
||||
|
||||
#define PRIdLEAST8 "d"
|
||||
#define PRIdLEAST16 "d"
|
||||
#define PRIdLEAST32 "ld"
|
||||
|
||||
#define PRIdFAST8 "d"
|
||||
#define PRIdFAST16 "d"
|
||||
#define PRIdFAST32 "ld"
|
||||
|
||||
#define PRIdMAX "ld"
|
||||
#define PRIdPTR "d"
|
||||
|
||||
|
||||
#define PRIo8 "o"
|
||||
#define PRIo16 "o"
|
||||
#define PRIo32 "lo"
|
||||
|
||||
#define PRIoLEAST8 "o"
|
||||
#define PRIoLEAST16 "o"
|
||||
#define PRIoLEAST32 "lo"
|
||||
|
||||
#define PRIoFAST8 "o"
|
||||
#define PRIoFAST16 "o"
|
||||
#define PRIoFAST32 "lo"
|
||||
|
||||
#define PRIoMAX "lo"
|
||||
#define PRIoPTR "o"
|
||||
|
||||
#define PRIu8 "u"
|
||||
#define PRIu16 "u"
|
||||
#define PRIu32 "lu"
|
||||
|
||||
#define PRIuLEAST8 "u"
|
||||
#define PRIuLEAST16 "u"
|
||||
#define PRIuLEAST32 "lu"
|
||||
|
||||
#define PRIuFAST8 "u"
|
||||
#define PRIuFAST16 "u"
|
||||
#define PRIuFAST32 "lu"
|
||||
|
||||
#define PRIuMAX "lu"
|
||||
#define PRIuPTR "u"
|
||||
|
||||
|
||||
#define PRIx8 "x"
|
||||
#define PRIx16 "x"
|
||||
#define PRIx32 "lx"
|
||||
|
||||
#define PRIxLEAST8 "x"
|
||||
#define PRIxLEAST16 "x"
|
||||
#define PRIxLEAST32 "lx"
|
||||
|
||||
#define PRIxFAST8 "x"
|
||||
#define PRIxFAST16 "x"
|
||||
#define PRIxFAST32 "lx"
|
||||
|
||||
#define PRIxMAX "lx"
|
||||
#define PRIxPTR "x"
|
||||
|
||||
|
||||
#define PRIX8 "X"
|
||||
#define PRIX16 "X"
|
||||
#define PRIX32 "lX"
|
||||
|
||||
#define PRIXLEAST8 "X"
|
||||
#define PRIXLEAST16 "X"
|
||||
#define PRIXLEAST32 "lX"
|
||||
|
||||
#define PRIXFAST8 "X"
|
||||
#define PRIXFAST16 "X"
|
||||
#define PRIXFAST32 "lX"
|
||||
|
||||
#define PRIXMAX "lX"
|
||||
#define PRIXPTR "X"
|
||||
|
||||
|
||||
typedef struct {
|
||||
intmax_t quot;
|
||||
intmax_t rem;
|
||||
} imaxdiv_t;
|
||||
|
||||
intmax_t imaxabs(intmax_t n);
|
||||
imaxdiv_t imaxdiv(intmax_t l, intmax_t r);
|
||||
intmax_t strtoimax(const char * s, char ** endp, int base);
|
||||
uintmax_t strtoumax(const char * s, char ** endp, int base);
|
||||
|
||||
|
||||
#pragma compile("inttypes.c")
|
||||
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef ISO646_H
|
||||
#define ISO646_H
|
||||
|
||||
#define and &&
|
||||
#define and_eq &=
|
||||
#define bitand &
|
||||
#define bitor |
|
||||
#define compl ~
|
||||
#define not !
|
||||
#define not_eq !=
|
||||
#define or ||
|
||||
#define or_eq |=
|
||||
#define xor ^
|
||||
#define xor_eq ^=
|
||||
|
||||
#endif
|
|
@ -11,7 +11,7 @@
|
|||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
|
||||
#define INT_MIN -32767
|
||||
#define INT_MIN (-32767-1)
|
||||
#define INT_MAX 32767
|
||||
#define UINT_MAX 65535
|
||||
|
||||
|
|
|
@ -110,12 +110,12 @@ float atan2(float p, float q)
|
|||
return s;
|
||||
}
|
||||
|
||||
#define F_EXP_0 1.0000003
|
||||
#define F_EXP_1 0.693147059
|
||||
#define F_EXP_2 0.240173099
|
||||
#define F_EXP_3 0.055816392
|
||||
#define F_EXP_4 0.008965036
|
||||
#define F_EXP_5 0.001898429
|
||||
#define F_EXP_0 1.0
|
||||
#define F_EXP_1 0.69315668
|
||||
#define F_EXP_2 0.240132068
|
||||
#define F_EXP_3 0.055876024
|
||||
#define F_EXP_4 0.008940801
|
||||
#define F_EXP_5 0.001894414
|
||||
|
||||
float exp(float f)
|
||||
{
|
||||
|
@ -143,12 +143,12 @@ float exp(float f)
|
|||
return s * x.f;
|
||||
}
|
||||
|
||||
#define F_LOG_0 -3.78712618
|
||||
#define F_LOG_1 10.0957081
|
||||
#define F_LOG_2 -13.9747486
|
||||
#define F_LOG_3 12.7568806
|
||||
#define F_LOG_4 -6.48114552
|
||||
#define F_LOG_5 1.39045416
|
||||
#define F_LOG_0 -3.78717706
|
||||
#define F_LOG_1 10.0960498
|
||||
#define F_LOG_2 -13.975654
|
||||
#define F_LOG_3 12.7580616
|
||||
#define F_LOG_4 -6.48190725
|
||||
#define F_LOG_5 1.39064767
|
||||
|
||||
float log(float f)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,15 @@ bool isfinite(float f);
|
|||
|
||||
#pragma intrinsic(sin)
|
||||
#pragma intrinsic(cos)
|
||||
#pragma intrinsic(tan)
|
||||
#pragma intrinsic(atan)
|
||||
#pragma intrinsic(atan2)
|
||||
|
||||
#pragma intrinsic(log)
|
||||
#pragma intrinsic(exp)
|
||||
|
||||
#pragma intrinsic(pow)
|
||||
#pragma intrinsic(sqrt)
|
||||
|
||||
#pragma compile("math.c")
|
||||
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
#ifndef OPP_ALGORITHM_H
|
||||
#define OPP_ALGORITHM_H
|
||||
|
||||
#include "utility.h"
|
||||
namespace opp {
|
||||
|
||||
template <class T>
|
||||
inline void swap(T & x, T & y)
|
||||
{
|
||||
T t(x); x = y; y = t;
|
||||
}
|
||||
|
||||
template<class T, class LT>
|
||||
void sort(T s, T e)
|
||||
{
|
||||
|
@ -72,6 +67,18 @@ OI copy(II first, II last, OI result)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<class II, class T>
|
||||
II find (II first, II last, const T& val)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
if (*first == val) return first;
|
||||
++first;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef OPP_BOUNDINT_H
|
||||
#define OPP_BOUNDINT_H
|
||||
|
||||
namespace opp {
|
||||
|
||||
template<int tmin, int tmax>
|
||||
constexpr auto boundinttype(void)
|
||||
{
|
||||
if constexpr (tmin >= 0 && tmax <= 255)
|
||||
return (char)0;
|
||||
else if constexpr (tmin >= -128 && tmax <= 127)
|
||||
return (signed char)0;
|
||||
else
|
||||
return (int)0;
|
||||
}
|
||||
|
||||
template<int tmin, int tmax>
|
||||
class boundint
|
||||
{
|
||||
protected:
|
||||
decltype(boundinttype<tmin, tmax>()) v;
|
||||
public:
|
||||
boundint(int i)
|
||||
: v(i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void operator=(int k)
|
||||
{
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
v = k;
|
||||
}
|
||||
|
||||
void operator+=(int k)
|
||||
{
|
||||
k += v;
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
v = k;
|
||||
}
|
||||
|
||||
void operator-=(int k)
|
||||
{
|
||||
k = v - k;
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
v = k;
|
||||
}
|
||||
|
||||
operator int() const
|
||||
{
|
||||
int k = v;
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
return k;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef OPP_FUNCTIONAL_H
|
||||
#define OPP_FUNCTIONAL_H
|
||||
|
||||
namespace opp
|
||||
{
|
||||
template <class F>
|
||||
class function;
|
||||
|
||||
template <class R, class ... P>
|
||||
class function<R(P...)>
|
||||
{
|
||||
private:
|
||||
struct callif
|
||||
{
|
||||
virtual R call(P...) = 0;
|
||||
virtual ~callif() {}
|
||||
virtual callif * clone(void) const = 0;
|
||||
};
|
||||
|
||||
template<class CA>
|
||||
struct callable : callif
|
||||
{
|
||||
CA ca;
|
||||
|
||||
callable(CA ca_) : ca(ca_) {}
|
||||
|
||||
R call(P... p) {return ca(p...);}
|
||||
|
||||
callif * clone(void) const
|
||||
{
|
||||
return new callable(ca);
|
||||
}
|
||||
};
|
||||
|
||||
callif * c;
|
||||
public:
|
||||
template <class F>
|
||||
function(F f)
|
||||
{
|
||||
c = new callable<F>(f);
|
||||
}
|
||||
|
||||
function(const function & f)
|
||||
{
|
||||
c = f.c->clone();
|
||||
}
|
||||
|
||||
function(function && f)
|
||||
{
|
||||
c = f.c;
|
||||
f.c = nullptr;
|
||||
}
|
||||
|
||||
function(void)
|
||||
{
|
||||
c = nullptr;
|
||||
}
|
||||
|
||||
function & operator=(const function & f)
|
||||
{
|
||||
if (c != f.c)
|
||||
{
|
||||
delete c;
|
||||
c = f.c;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
function & operator=(function && f)
|
||||
{
|
||||
if (c != f.c)
|
||||
{
|
||||
c = f.c;
|
||||
f.c = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~function(void)
|
||||
{
|
||||
delete c;
|
||||
}
|
||||
|
||||
R operator()(P ... p) const
|
||||
{
|
||||
return c->call(p...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -6,7 +6,7 @@ namespace opp {
|
|||
ifstream::ifstream(char fnum, char device, char channel, const string & name)
|
||||
{
|
||||
this->fnum = fnum;
|
||||
krnio_setnam(name);
|
||||
krnio_setnam(name.tocstr());
|
||||
krnio_open(fnum, device, channel);
|
||||
}
|
||||
|
||||
|
|
|
@ -952,6 +952,13 @@ istream & istream::operator>>(float & val)
|
|||
return *this;
|
||||
}
|
||||
|
||||
istream & istream::operator>>(char & val)
|
||||
{
|
||||
doskipws();
|
||||
val = get();
|
||||
return *this;
|
||||
}
|
||||
|
||||
istream & istream::operator>>(char * p)
|
||||
{
|
||||
doskipws();
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
showpos = 0x0800,
|
||||
skipws = 0x1000,
|
||||
unitbuf = 0x2000,
|
||||
uppercase = 0x3000,
|
||||
uppercase = 0x4000,
|
||||
|
||||
adjustfield = 0x00b0,
|
||||
basefield = 0x004a,
|
||||
|
@ -124,6 +124,7 @@ public:
|
|||
istream & putback(char c);
|
||||
istream & unget(void);
|
||||
|
||||
istream & operator>>(char & val);
|
||||
istream & operator>>(bool & val);
|
||||
istream & operator>>(int & val);
|
||||
istream & operator>>(unsigned & val);
|
||||
|
|
|
@ -118,6 +118,31 @@ public:
|
|||
list(void)
|
||||
{}
|
||||
|
||||
list(const list & l);
|
||||
|
||||
list(list && l)
|
||||
{
|
||||
head.succ = l.head.succ;
|
||||
head.pred = l.head.pred;
|
||||
head.succ->pred = (listnode<T> *)&head;
|
||||
head.pred->succ = (listnode<T> *)&head;
|
||||
l.head.succ = (listnode<T> *)&(l.head);
|
||||
l.head.pred = (listnode<T> *)&(l.head);
|
||||
}
|
||||
|
||||
list & operator=(const list & l);
|
||||
|
||||
list & operator=(list && l)
|
||||
{
|
||||
head.succ = l.head.succ;
|
||||
head.pred = l.head.pred;
|
||||
head.succ->pred = (listnode<T> *)&head;
|
||||
head.pred->succ = (listnode<T> *)&head;
|
||||
l.head.succ = (listnode<T> *)&(l.head);
|
||||
l.head.pred = (listnode<T> *)&(l.head);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~list(void)
|
||||
{
|
||||
listnode<T> * n = head.succ;
|
||||
|
@ -175,11 +200,32 @@ public:
|
|||
|
||||
void push_back(T && t);
|
||||
|
||||
void clear(void);
|
||||
|
||||
void append(const list & l);
|
||||
|
||||
list_iterator<T> insert(list_iterator<T> it, const T & t);
|
||||
|
||||
list_iterator<T> insert(list_iterator<T> it, T && t);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
list<T>::list(const list<T> & l)
|
||||
{
|
||||
append(l);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
list<T> & list<T>::operator=(const list<T> & l)
|
||||
{
|
||||
if (&l != this)
|
||||
{
|
||||
clear();
|
||||
append(l);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::pop_front(void)
|
||||
{
|
||||
|
@ -293,6 +339,32 @@ list_iterator<T> list<T>::insert(list_iterator<T> it, T && t)
|
|||
return list_iterator<T>(n);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void list<T>::clear(void)
|
||||
{
|
||||
listnode<T> * n = head.succ;
|
||||
while (n != &head)
|
||||
{
|
||||
listnode<T> * m = n->succ;
|
||||
delete n;
|
||||
n = m;
|
||||
}
|
||||
head.succ = (listnode<T> *)&head;
|
||||
head.pred = (listnode<T> *)&head;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::append(const list<T> & l)
|
||||
{
|
||||
listnode<T> * n = l.head.succ;
|
||||
while (n != &(l.head))
|
||||
{
|
||||
push_back(n->data);
|
||||
n = n->succ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef OPP_SLAB_H
|
||||
#define OPP_SLAB_H
|
||||
|
||||
template<class T, int N>
|
||||
class slabptr
|
||||
{
|
||||
public:
|
||||
char index;
|
||||
|
||||
slabptr(void)
|
||||
: index(N)
|
||||
{}
|
||||
|
||||
slabptr(char i)
|
||||
: index(i)
|
||||
{}
|
||||
|
||||
slabptr(const slabptr & i)
|
||||
: index(i.index)
|
||||
{}
|
||||
|
||||
auto operator-> ();
|
||||
auto & operator* ();
|
||||
};
|
||||
|
||||
template <class T, int N>
|
||||
class slab
|
||||
{
|
||||
protected:
|
||||
static __striped T buffer[N];
|
||||
static char head;
|
||||
static char next[N];
|
||||
|
||||
public:
|
||||
typedef slabptr<T, N> ptr;
|
||||
|
||||
static void init(void);
|
||||
static auto alloc(void);
|
||||
static void free(ptr p);
|
||||
};
|
||||
|
||||
|
||||
template<class T, int N>
|
||||
inline auto slabptr<T, N>::operator-> ()
|
||||
{
|
||||
return slab<T, N>::buffer + index;
|
||||
}
|
||||
|
||||
template<class T, int N>
|
||||
inline auto & slabptr<T, N>::operator* ()
|
||||
{
|
||||
return slab<T, N>::buffer[index];
|
||||
}
|
||||
|
||||
|
||||
template <class T, int N>
|
||||
void slab<T, N>::init(void)
|
||||
{
|
||||
head = 0;
|
||||
for(char i=0; i<N; i++)
|
||||
next[i] = i + 1;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
auto slab<T, N>::alloc(void)
|
||||
{
|
||||
char i = head;
|
||||
head = next[head];
|
||||
return slabptr<T, N>(i);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void slab<T, N>::free(slabptr<T, N> p)
|
||||
{
|
||||
next[p.index] = head;
|
||||
head = p.index;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -20,12 +20,12 @@ void ostringstream::bput(char ch)
|
|||
{
|
||||
mBSize = 15;
|
||||
mBFill = 0;
|
||||
mBuffer = malloc(15);
|
||||
mBuffer = (char *)malloc(15);
|
||||
}
|
||||
else if (mBFill == mBSize)
|
||||
{
|
||||
mBSize *= 2;
|
||||
char * b = malloc(mBSize);
|
||||
char * b = (char *)malloc(mBSize);
|
||||
for(char i=0; i<mBFill; i++)
|
||||
b[i] = mBuffer[i];
|
||||
free(mBuffer);
|
||||
|
@ -46,7 +46,7 @@ void ostringstream::str(const string & str)
|
|||
{
|
||||
free(mBuffer);
|
||||
mBSize = mBFill;
|
||||
mBuffer = malloc(mBSize);
|
||||
mBuffer = (char *)malloc(mBSize);
|
||||
}
|
||||
str.copyseg(mBuffer, 0, mBFill);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
#ifndef OPP_STATIC_VECTOR_H
|
||||
#define OPP_STATIC_VECTOR_H
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <opp/utility.h>
|
||||
#include <oscar.h>
|
||||
|
||||
namespace opp {
|
||||
|
||||
template <class T, int N>
|
||||
class static_vector
|
||||
{
|
||||
protected:
|
||||
enum { m = N } _size;
|
||||
char _space[N * sizeof(T)];
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
static_vector(void) : _size(0) {}
|
||||
|
||||
static_vector(size_t n) : _size(n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i) T();
|
||||
}
|
||||
|
||||
static_vector(const static_vector & v)
|
||||
: _size(v._size)
|
||||
{
|
||||
size_t n = _size;
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
|
||||
~static_vector(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
}
|
||||
|
||||
static_vector & operator=(const static_vector & v)
|
||||
{
|
||||
if (this != &v)
|
||||
{
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
_size = v._size;
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t size(void) const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
size_t max_size(void) const
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
bool empty(void) const
|
||||
{
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
bool full(void) const
|
||||
{
|
||||
return _size == N;
|
||||
}
|
||||
|
||||
size_t capacity(void) const
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
void resize(size_t n);
|
||||
|
||||
void clear(void);
|
||||
|
||||
T & at(size_t at)
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
}
|
||||
|
||||
const T & at(size_t at) const
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
}
|
||||
|
||||
T & operator[](size_t at)
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
}
|
||||
|
||||
const T & operator[](size_t at) const
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
}
|
||||
|
||||
T * begin(void)
|
||||
{
|
||||
return (T*)_space;
|
||||
}
|
||||
|
||||
const T * begin(void) const
|
||||
{
|
||||
return (T*)_space;
|
||||
}
|
||||
|
||||
const T * cbegin(void) const
|
||||
{
|
||||
return (T*)_space;
|
||||
}
|
||||
|
||||
T * end(void)
|
||||
{
|
||||
return (T*)_space + _size;
|
||||
}
|
||||
|
||||
const T * end(void) const
|
||||
{
|
||||
return (T*)_space + _size;
|
||||
}
|
||||
|
||||
const T * cend(void) const
|
||||
{
|
||||
return (T*)_space + _size;
|
||||
}
|
||||
|
||||
T & front(void)
|
||||
{
|
||||
return ((T*)_space)[0];
|
||||
}
|
||||
|
||||
const T & front(void) const
|
||||
{
|
||||
return ((T*)_space)[0];
|
||||
}
|
||||
|
||||
T & back(void)
|
||||
{
|
||||
return ((T*)_space)[_size - 1];
|
||||
}
|
||||
|
||||
const T & back(void) const
|
||||
{
|
||||
return ((T*)_space)[_size - 1];
|
||||
}
|
||||
|
||||
T * data(void)
|
||||
{
|
||||
return (T*)_space;
|
||||
}
|
||||
|
||||
const T * at(void) const
|
||||
{
|
||||
return (T*)_space;
|
||||
}
|
||||
|
||||
void push_back(const T & t);
|
||||
|
||||
void push_back(T && t);
|
||||
|
||||
void pop_back(void)
|
||||
{
|
||||
_size--;
|
||||
((T*)_space)[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
||||
T * insert(T * at, const T & t);
|
||||
|
||||
template <typename ...P>
|
||||
void emplace_back(const P&... p);
|
||||
};
|
||||
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::clear(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::resize(size_t n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
if (n < _size)
|
||||
{
|
||||
for(size_t i=n; i<_size; i++)
|
||||
data[i].~T();
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(data + i)T();
|
||||
}
|
||||
_size = n;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(T && t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
template <typename ...P>
|
||||
void static_vector<T, N>::emplace_back(const P&... p)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(p...);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::assign(size_t count, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::insert(size_t at, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
new (data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
data[i] = move(data[i - 1]);
|
||||
data[at] = t;
|
||||
_size++;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::erase(size_t at, size_t n)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
_size -= n;
|
||||
for(size_t i=at; i<_size; i++)
|
||||
data[i] = move(data[i + n]);
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[_size + i].~T();
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
T * static_vector<T, N>::insert(T * at, const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
T * dp = data + _size;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
dp[1] = move(dp[0]);
|
||||
}
|
||||
dp[0] = t;
|
||||
_size++;
|
||||
return dp + 1;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -32,7 +32,7 @@ string::string(const string & s)
|
|||
if (s.cstr)
|
||||
{
|
||||
char l = s.cstr[0];
|
||||
cstr = malloc(char(l + 2));
|
||||
cstr = (char *)malloc(char(l + 2));
|
||||
smemcpy(cstr, s.cstr, l + 2);
|
||||
}
|
||||
else
|
||||
|
@ -52,7 +52,7 @@ string::string(const char * s)
|
|||
char l = sstrlen(s);
|
||||
if (l)
|
||||
{
|
||||
cstr = malloc(char(l + 2));
|
||||
cstr = (char *)malloc(char(l + 2));
|
||||
cstr[0] = l;
|
||||
smemcpy(cstr + 1, s, l + 1);
|
||||
}
|
||||
|
@ -67,9 +67,10 @@ string::string(const char * s, char size)
|
|||
{
|
||||
if (size)
|
||||
{
|
||||
cstr = malloc(char(size + 2));
|
||||
cstr = (char *)malloc(char(size + 2));
|
||||
cstr[0] = size;
|
||||
smemcpy(cstr + 1, s, size + 1);
|
||||
smemcpy(cstr + 1, s, size);
|
||||
cstr[size + 1] = 0;
|
||||
}
|
||||
else
|
||||
cstr = nullptr;
|
||||
|
@ -77,7 +78,7 @@ string::string(const char * s, char size)
|
|||
|
||||
string::string(char c)
|
||||
{
|
||||
cstr = malloc(3);
|
||||
cstr = (char *)malloc(3);
|
||||
cstr[0] = 1;
|
||||
cstr[1] = c;
|
||||
cstr[2] = 0;
|
||||
|
@ -114,7 +115,7 @@ string & string::operator=(const string & s)
|
|||
if (s.cstr)
|
||||
{
|
||||
char l = s.cstr[0];
|
||||
cstr = malloc(char(l + 2));
|
||||
cstr = (char *)malloc(char(l + 2));
|
||||
smemcpy(cstr, s.cstr, l + 2);
|
||||
}
|
||||
else
|
||||
|
@ -144,7 +145,7 @@ string & string::operator=(const char * s)
|
|||
char l = sstrlen(s);
|
||||
if (l)
|
||||
{
|
||||
cstr = malloc(char(l + 2));
|
||||
cstr = (char *)malloc(char(l + 2));
|
||||
cstr[0] = l;
|
||||
smemcpy(cstr + 1, s, l + 1);
|
||||
}
|
||||
|
@ -166,7 +167,7 @@ string & string::operator+=(const string & s)
|
|||
d = cstr[0];
|
||||
|
||||
char l = s.cstr[0] + d;
|
||||
char * c = malloc(char(l + 2));
|
||||
char * c = (char *)malloc(char(l + 2));
|
||||
c[0] = l;
|
||||
|
||||
if (d)
|
||||
|
@ -188,7 +189,7 @@ string & string::operator+=(const char * s)
|
|||
if (cstr)
|
||||
{
|
||||
char l = sl + cstr[0];
|
||||
char * c = malloc(char(l + 2));
|
||||
char * c = (char *)malloc(char(l + 2));
|
||||
c[0] = l;
|
||||
smemcpy(c + 1, cstr + 1, cstr[0]);
|
||||
smemcpy(c + 1 + cstr[0], s, sl + 1);
|
||||
|
@ -197,7 +198,7 @@ string & string::operator+=(const char * s)
|
|||
}
|
||||
else
|
||||
{
|
||||
cstr = malloc(char(sl + 2));
|
||||
cstr = (char *)malloc(char(sl + 2));
|
||||
cstr[0] = sl;
|
||||
smemcpy(cstr + 1, s, sl + 1);
|
||||
}
|
||||
|
@ -211,7 +212,7 @@ string & string::operator+=(char c)
|
|||
if (cstr)
|
||||
{
|
||||
char l = cstr[0] + 1;
|
||||
char * p = malloc(char(l + 2));
|
||||
char * p = (char *)malloc(char(l + 2));
|
||||
p[0] = l;
|
||||
smemcpy(p + 1, cstr + 1, cstr[0]);
|
||||
p[l] = c;
|
||||
|
@ -221,7 +222,7 @@ string & string::operator+=(char c)
|
|||
}
|
||||
else
|
||||
{
|
||||
cstr = malloc(3);
|
||||
cstr = (char *)malloc(3);
|
||||
cstr[0] = 1;
|
||||
cstr[1] = c;
|
||||
cstr[2] = 0;
|
||||
|
@ -229,6 +230,10 @@ string & string::operator+=(char c)
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline const char * string::c_str(void) const
|
||||
{
|
||||
return this->tocstr();
|
||||
}
|
||||
|
||||
inline const char * string::tocstr(void) const
|
||||
{
|
||||
|
@ -253,7 +258,7 @@ string string::operator+(const string & s) const
|
|||
if (s.cstr)
|
||||
{
|
||||
char l = cstr[0] + s.cstr[0];
|
||||
char * p = malloc(char(l + 2));
|
||||
char * p = (char *)malloc(char(l + 2));
|
||||
smemcpy(p + 1, cstr + 1, cstr[0]);
|
||||
smemcpy(p + 1 + cstr[0], s.cstr + 1, s.cstr[0]);
|
||||
return string(l, p);
|
||||
|
@ -275,7 +280,7 @@ string string::operator+(const char * s) const
|
|||
if (sl)
|
||||
{
|
||||
char l = cstr[0] + sl;
|
||||
char * p = malloc(char(l + 2));
|
||||
char * p = (char *)malloc(char(l + 2));
|
||||
smemcpy(p + 1, cstr + 1, cstr[0]);
|
||||
smemcpy(p + 1 + cstr[0], s, sl);
|
||||
return string(l, p);
|
||||
|
@ -295,7 +300,7 @@ string string::operator+(char c) const
|
|||
if (cstr)
|
||||
{
|
||||
char l = cstr[0] + 1;
|
||||
char * p = malloc(char(l + 2));
|
||||
char * p = (char *)malloc(char(l + 2));
|
||||
smemcpy(p + 1, cstr + 1, cstr[0]);
|
||||
p[l] = c;
|
||||
return string(l, p);
|
||||
|
@ -516,14 +521,14 @@ const char * string::cend(void) const
|
|||
string string::substr(char pos, char len) const
|
||||
{
|
||||
if (!cstr || len == 0 || pos >= cstr[0])
|
||||
return string;
|
||||
return string();
|
||||
else
|
||||
{
|
||||
char l = cstr[0];
|
||||
if (pos + len > l)
|
||||
len = l - pos;
|
||||
|
||||
char * p = malloc(len + 2);
|
||||
char * p = (char *)malloc(len + 2);
|
||||
memcpy(p + 1, cstr + 1 + pos, len);
|
||||
return string(len, p);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
const char * end(void) const;
|
||||
const char * cend(void) const;
|
||||
|
||||
const char * c_str(void) const;
|
||||
const char * tocstr(void) const;
|
||||
|
||||
string substr(char pos, char len) const;
|
||||
|
|
|
@ -4,11 +4,17 @@
|
|||
namespace opp {
|
||||
|
||||
template <class T>
|
||||
T && move(T & m)
|
||||
inline T && move(T & m)
|
||||
{
|
||||
return (T &&)m;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void swap(T & x, T & y)
|
||||
{
|
||||
T t(x); x = y; y = move(t);
|
||||
}
|
||||
|
||||
|
||||
template<class T1, class T2>
|
||||
struct pair
|
||||
|
|
|
@ -12,22 +12,23 @@ class vector
|
|||
{
|
||||
protected:
|
||||
T * _data;
|
||||
int _size, _capacity;
|
||||
size_t _size, _capacity;
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
vector(void) : _data(nullptr), _size(0), _capacity(0) {}
|
||||
|
||||
vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
|
||||
vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
|
||||
{
|
||||
for(int i=0; i<n; i++)
|
||||
new (_data + i) T;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i) T();
|
||||
}
|
||||
|
||||
vector(const vector & v)
|
||||
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
|
||||
{
|
||||
for(int i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
|
||||
|
@ -41,11 +42,41 @@ public:
|
|||
|
||||
~vector(void)
|
||||
{
|
||||
for(int i=0; i<_size; i++)
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
free(_data);
|
||||
}
|
||||
|
||||
vector & operator=(const vector & v)
|
||||
{
|
||||
if (this != &v)
|
||||
{
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
_data[i].~T();
|
||||
free(_data);
|
||||
|
||||
_data = (T*)malloc(v._size * sizeof(T));
|
||||
_size = v._size;
|
||||
_capacity = v._size;
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
vector & operator=(vector && v)
|
||||
{
|
||||
if (this != &v)
|
||||
{
|
||||
swap(_data, v._data);
|
||||
swap(_size, v._size);
|
||||
swap(_capacity, v._capacity);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
int size(void) const
|
||||
{
|
||||
return _size;
|
||||
|
@ -66,28 +97,30 @@ public:
|
|||
return _capacity;
|
||||
}
|
||||
|
||||
void resize(int n);
|
||||
void clear(void);
|
||||
|
||||
void reserve(int n);
|
||||
void resize(size_t n);
|
||||
|
||||
void reserve(size_t n);
|
||||
|
||||
void shrink_to_fit(void);
|
||||
|
||||
T & at(int at)
|
||||
T & at(size_t at)
|
||||
{
|
||||
return _data[at];
|
||||
}
|
||||
|
||||
const T & at(int at) const
|
||||
const T & at(size_t at) const
|
||||
{
|
||||
return _data[at];
|
||||
}
|
||||
|
||||
T & operator[](int at)
|
||||
T & operator[](size_t at)
|
||||
{
|
||||
return _data[at];
|
||||
}
|
||||
|
||||
const T & operator[](int at) const
|
||||
const T & operator[](size_t at) const
|
||||
{
|
||||
return _data[at];
|
||||
}
|
||||
|
@ -162,9 +195,13 @@ public:
|
|||
_data[_size].~T();
|
||||
}
|
||||
|
||||
void insert(int at, const T & t);
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void erase(int at, int n = 1);
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
||||
T * insert(T * at, const T & t);
|
||||
|
||||
template <typename ...P>
|
||||
void emplace_back(const P&... p);
|
||||
|
@ -174,13 +211,13 @@ protected:
|
|||
|
||||
|
||||
template <class T>
|
||||
void vector<T>::reserve(int n)
|
||||
__noinline void vector<T>::reserve(size_t n)
|
||||
{
|
||||
if (n > _capacity)
|
||||
{
|
||||
_capacity = n;
|
||||
T * d = (T *)malloc(_capacity * sizeof(T));
|
||||
for(int i=0; i<_size; i++)
|
||||
for(size_t i=0; i<_size; i++)
|
||||
{
|
||||
new (d + i)T(move(_data[i]));
|
||||
_data[i].~T();
|
||||
|
@ -191,18 +228,26 @@ void vector<T>::reserve(int n)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::resize(int n)
|
||||
void vector<T>::clear(void)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
__noinline void vector<T>::resize(size_t n)
|
||||
{
|
||||
if (n < _size)
|
||||
{
|
||||
for(int i=n; i<_size; i++)
|
||||
for(size_t i=n; i<_size; i++)
|
||||
_data[i].~T();
|
||||
_size = n;
|
||||
}
|
||||
else if (n < _capacity)
|
||||
{
|
||||
for(int i=_size; i<n; i++)
|
||||
new(_data + i)T;
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(_data + i)T();
|
||||
_size = n;
|
||||
}
|
||||
else
|
||||
|
@ -219,7 +264,7 @@ void vector<T>::shrink_to_fit(void)
|
|||
{
|
||||
_capacity = _size;
|
||||
T * d = (T *)malloc(_capacity * sizeof(T));
|
||||
for(int i=0; i<_size; i++)
|
||||
for(size_t i=0; i<_size; i++)
|
||||
{
|
||||
new (d + i)T(move(_data[i]));
|
||||
_data[i].~T();
|
||||
|
@ -257,23 +302,61 @@ void vector<T>::emplace_back(const P&... p)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::insert(int at, const T & t)
|
||||
void vector<T>::assign(size_t count, const T & t)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
reserve(_size + 1 + (_size >> 1));
|
||||
new (_data + _size)T;
|
||||
for(int i=_size; i>at; i--)
|
||||
_data[i] = move(_data[i - 1]);
|
||||
_data[at] = t;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
if (count > _capacity)
|
||||
{
|
||||
_size = 0;
|
||||
reserve(count);
|
||||
}
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (_data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::erase(int at, int n)
|
||||
void vector<T>::insert(size_t at, const T & t)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
reserve(_size + 1 + (_size >> 1));
|
||||
new (_data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
_data[i] = move(_data[i - 1]);
|
||||
_data[at] = t;
|
||||
_size++;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::erase(size_t at, size_t n)
|
||||
{
|
||||
_size -= n;
|
||||
for(int i=at; i<_size; i++)
|
||||
for(size_t i=at; i<_size; i++)
|
||||
_data[i] = move(_data[i + n]);
|
||||
_data[_size].~T();
|
||||
for(size_t i=0; i<n; i++)
|
||||
_data[_size + i].~T();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T * vector<T>::insert(T * at, const T & t)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
{
|
||||
unsigned f = unsigned(at) - unsigned(_data);
|
||||
reserve(_size + 1 + (_size >> 1));
|
||||
at = (T *)(f + unsigned(_data));
|
||||
}
|
||||
T * dp = _data + _size;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
dp[1] = move(dp[0]);
|
||||
}
|
||||
dp[0] = t;
|
||||
_size++;
|
||||
return dp + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,3 +86,53 @@ const char * oscar_expand_rle(char * dp, const char * sp)
|
|||
|
||||
return sp + 1;
|
||||
}
|
||||
|
||||
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
|
||||
{
|
||||
char buf[256];
|
||||
char b = 0;
|
||||
|
||||
char cmd = sp[0];
|
||||
do
|
||||
{
|
||||
if (cmd & 0x80)
|
||||
{
|
||||
char i = b - sp[1];
|
||||
cmd &= 0x7f;
|
||||
sp += 2;
|
||||
|
||||
char n = 0;
|
||||
do {
|
||||
buf[b] = dp[n] = buf[i];
|
||||
b++;
|
||||
i++;
|
||||
n++;
|
||||
} while (n != cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
sp += 1;
|
||||
|
||||
char n = 0;
|
||||
do {
|
||||
buf[b] = dp[n] = sp[n];
|
||||
b++;
|
||||
n++;
|
||||
} while (n != cmd);
|
||||
|
||||
sp += cmd;
|
||||
}
|
||||
dp += cmd;
|
||||
|
||||
cmd = sp[0];
|
||||
} while (cmd);
|
||||
|
||||
return sp + 1;
|
||||
}
|
||||
|
||||
void debugcrash(void)
|
||||
{
|
||||
__asm volatile {
|
||||
byt $02
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,19 @@ __native const char * oscar_expand_lzo(char * dp, const char * sp);
|
|||
|
||||
__native const char * oscar_expand_rle(char * dp, const char * sp);
|
||||
|
||||
// Same as oscar_expand_lzo, but does not need read access to the
|
||||
// target memory area. On the downside, it uses 256 bytes of stack
|
||||
// memory as buffer
|
||||
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp);
|
||||
|
||||
// Write a breakpoint instruction into the .lbl file for vice. This
|
||||
// intrinsic function will change the behaviour of the optimizer to ensure
|
||||
// that the breakpoint is not move around into wild places.
|
||||
void breakpoint(void);
|
||||
|
||||
#pragma intrinsic(breakpoint)
|
||||
|
||||
void debugcrash(void);
|
||||
|
||||
#pragma compile("oscar.c")
|
||||
|
||||
|
|
301
include/stdio.c
301
include/stdio.c
|
@ -2,237 +2,50 @@
|
|||
#include "conio.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#if defined(__C128__)
|
||||
#pragma code(lowcode)
|
||||
__asm bsout
|
||||
{
|
||||
ldx #0
|
||||
stx 0xff00
|
||||
jsr 0xffd2
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xfff0
|
||||
sta 0xff01
|
||||
}
|
||||
__asm bsin
|
||||
{
|
||||
lda #0
|
||||
sta 0xff00
|
||||
jsr 0xffcf
|
||||
sta 0xff01
|
||||
}
|
||||
|
||||
#pragma code(code)
|
||||
#elif defined(__PLUS4__)
|
||||
#pragma code(lowcode)
|
||||
__asm bsout
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffd2
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsin
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xffe4
|
||||
sta 0xff3f
|
||||
}
|
||||
__asm bsplot
|
||||
{
|
||||
sta 0xff3e
|
||||
jsr 0xfff0
|
||||
sta 0xff3f
|
||||
}
|
||||
#pragma code(code)
|
||||
#elif defined(__ATARI__)
|
||||
__asm bsout
|
||||
{
|
||||
tax
|
||||
lda 0xe407
|
||||
pha
|
||||
lda 0xe406
|
||||
pha
|
||||
txa
|
||||
}
|
||||
|
||||
__asm bsin
|
||||
{
|
||||
lda 0xe405
|
||||
pha
|
||||
lda 0xe404
|
||||
pha
|
||||
}
|
||||
|
||||
__asm bsplot
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#define bsout 0xffd2
|
||||
#define bsplot 0xfff0
|
||||
#define bsin 0xffcf
|
||||
#endif
|
||||
|
||||
__asm putpch
|
||||
{
|
||||
#if defined(__ATARI__)
|
||||
cmp #10
|
||||
bne w1
|
||||
lda #0x9b
|
||||
w1:
|
||||
jmp bsout
|
||||
#else
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
|
||||
cmp #10
|
||||
bne w1
|
||||
lda #13
|
||||
w1:
|
||||
cmp #9
|
||||
beq t1
|
||||
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
|
||||
cmp #65
|
||||
bcc w3
|
||||
cmp #123
|
||||
bcs w3
|
||||
#if defined(__CBMPET__)
|
||||
cmp #97
|
||||
bcs w4
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$a0
|
||||
w4:
|
||||
eor #$20
|
||||
|
||||
#else
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
#endif
|
||||
cpx #IOCHM_PETSCII_2
|
||||
beq w3
|
||||
and #$df
|
||||
w3:
|
||||
jmp bsout
|
||||
t1:
|
||||
sec
|
||||
jsr bsplot
|
||||
tya
|
||||
and #3
|
||||
eor #3
|
||||
tax
|
||||
lda #$20
|
||||
l1:
|
||||
jsr bsout
|
||||
dex
|
||||
bpl l1
|
||||
#endif
|
||||
}
|
||||
|
||||
__asm getpch
|
||||
{
|
||||
jsr bsin
|
||||
#if !defined(__ATARI__)
|
||||
ldx giocharmap
|
||||
cpx #IOCHM_ASCII
|
||||
bcc w3
|
||||
|
||||
cmp #13
|
||||
bne w1
|
||||
lda #10
|
||||
w1:
|
||||
cpx #IOCHM_PETSCII_1
|
||||
bcc w3
|
||||
|
||||
cmp #219
|
||||
bcs w3
|
||||
cmp #65
|
||||
bcc w3
|
||||
|
||||
cmp #193
|
||||
bcc w4
|
||||
eor #$a0
|
||||
w4:
|
||||
cmp #123
|
||||
bcs w3
|
||||
cmp #97
|
||||
bcs w2
|
||||
cmp #91
|
||||
bcs w3
|
||||
w2:
|
||||
eor #$20
|
||||
w3:
|
||||
#endif
|
||||
}
|
||||
|
||||
void putchar(char c)
|
||||
{
|
||||
__asm {
|
||||
lda c
|
||||
jsr putpch
|
||||
}
|
||||
putpch(c);
|
||||
}
|
||||
|
||||
char getchar(void)
|
||||
{
|
||||
__asm {
|
||||
jsr getpch
|
||||
sta accu
|
||||
lda #0
|
||||
sta accu + 1
|
||||
}
|
||||
return getpch();
|
||||
}
|
||||
|
||||
void puts(const char * str)
|
||||
{
|
||||
__asm {
|
||||
ploop:
|
||||
ldy #0
|
||||
lda (str), y
|
||||
beq pdone
|
||||
|
||||
jsr putpch
|
||||
|
||||
inc str
|
||||
bne ploop
|
||||
inc str + 1
|
||||
bne ploop
|
||||
pdone:
|
||||
}
|
||||
while (char ch = *str++)
|
||||
putpch(ch);
|
||||
}
|
||||
|
||||
char * gets(char * str)
|
||||
{
|
||||
__asm {
|
||||
gloop:
|
||||
jsr getpch
|
||||
ldy #0
|
||||
cmp #10
|
||||
beq gdone
|
||||
sta (str), y
|
||||
inc str
|
||||
bne gloop
|
||||
inc str + 1
|
||||
bne gloop
|
||||
gdone:
|
||||
lda #0
|
||||
sta (str), y
|
||||
char i = 0;
|
||||
while ((char ch = getpch()) != '\n')
|
||||
str[i++] = ch;
|
||||
str[i] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
char * gets_s(char * str, size_t n)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
if (n < 2)
|
||||
return NULL;
|
||||
char i = 0, t = n - 1;
|
||||
|
||||
while ((char ch = getpch()) != '\n')
|
||||
{
|
||||
if (i < t)
|
||||
str[i] = ch;
|
||||
++i;
|
||||
}
|
||||
|
||||
str[(i < t) ? i : t] = '\0';
|
||||
|
||||
if (i > t)
|
||||
return NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -279,10 +92,7 @@ int nformi(const sinfo * si, char * str, int v, bool s)
|
|||
while (u > 0)
|
||||
{
|
||||
int c = u % si->base;
|
||||
if (c >= 10)
|
||||
c += 'A' - 10;
|
||||
else
|
||||
c += '0';
|
||||
c += c >= 10 ? 'A' - 10 : '0';
|
||||
buffer[--i] = c;
|
||||
u /= si->base;
|
||||
}
|
||||
|
@ -340,10 +150,7 @@ int nforml(const sinfo * si, char * str, long v, bool s)
|
|||
while (u > 0)
|
||||
{
|
||||
int c = u % si->base;
|
||||
if (c >= 10)
|
||||
c += 'A' - 10;
|
||||
else
|
||||
c += '0';
|
||||
c += c >= 10 ? 'A' - 10 : '0';
|
||||
buffer[--i] = c;
|
||||
u /= si->base;
|
||||
}
|
||||
|
@ -589,7 +396,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
|
||||
if (c >= '0' && c <='9')
|
||||
{
|
||||
int i = 0;
|
||||
char i = 0;
|
||||
while (c >= '0' && c <='9')
|
||||
{
|
||||
i = i * 10 + c - '0';
|
||||
|
@ -600,7 +407,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
|
||||
if (c == '.')
|
||||
{
|
||||
int i = 0;
|
||||
char i = 0;
|
||||
c = *p++;
|
||||
while (c >= '0' && c <='9')
|
||||
{
|
||||
|
@ -610,36 +417,36 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
si.precision = i;
|
||||
}
|
||||
|
||||
if (c == 'd')
|
||||
if (c == 'd' || c == p'd' || c == 'i' || c == p'i')
|
||||
{
|
||||
bi = nformi(&si, bp, *fps++, true);
|
||||
}
|
||||
else if (c == 'u')
|
||||
else if (c == 'u' || c == p'u')
|
||||
{
|
||||
bi = nformi(&si, bp, *fps++, false);
|
||||
}
|
||||
else if (c == 'x')
|
||||
else if (c == 'x' || c == p'x')
|
||||
{
|
||||
si.base = 16;
|
||||
bi = nformi(&si, bp, *fps++, false);
|
||||
}
|
||||
#ifndef NOLONG
|
||||
else if (c == 'l')
|
||||
else if (c == 'l' || c == p'l')
|
||||
{
|
||||
long l = *(long *)fps;
|
||||
fps ++;
|
||||
fps ++;
|
||||
|
||||
c = *p++;
|
||||
if (c == 'd')
|
||||
if (c == 'd' || c == p'd')
|
||||
{
|
||||
bi = nforml(&si, bp, l, true);
|
||||
}
|
||||
else if (c == 'u')
|
||||
else if (c == 'u' || c == p'u')
|
||||
{
|
||||
bi = nforml(&si, bp, l, false);
|
||||
}
|
||||
else if (c == 'x')
|
||||
else if (c == 'x' || c == p'x')
|
||||
{
|
||||
si.base = 16;
|
||||
bi = nforml(&si, bp, l, false);
|
||||
|
@ -647,14 +454,14 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
}
|
||||
#endif
|
||||
#ifndef NOFLOAT
|
||||
else if (c == 'f' || c == 'g' || c == 'e')
|
||||
else if (c == 'f' || c == 'g' || c == 'e' || c == p'f' || c == p'g' || c == p'e')
|
||||
{
|
||||
bi = nformf(&si, bp, *(float *)fps, c);
|
||||
fps ++;
|
||||
fps ++;
|
||||
}
|
||||
#endif
|
||||
else if (c == 's')
|
||||
else if (c == 's' || c == p's')
|
||||
{
|
||||
char * sp = (char *)*fps++;
|
||||
|
||||
|
@ -700,7 +507,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (c == 'c')
|
||||
else if (c == 'c' || c == p'c')
|
||||
{
|
||||
bp[bi++] = *fps++;
|
||||
}
|
||||
|
@ -749,6 +556,17 @@ int sprintf(char * str, const char * fmt, ...)
|
|||
return d - str;
|
||||
}
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist)
|
||||
{
|
||||
char buff[50];
|
||||
sformat(buff, fmt, (int *)vlist, true);
|
||||
}
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist)
|
||||
{
|
||||
char * d = sformat(str, fmt, (int *)vlist, false);
|
||||
return d - str;
|
||||
}
|
||||
|
||||
static inline bool isspace(char c)
|
||||
{
|
||||
|
@ -862,7 +680,7 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
|
|||
}
|
||||
}
|
||||
|
||||
if (fc == 'l')
|
||||
if (fc == 'l' || fc == p'l')
|
||||
{
|
||||
islong = true;
|
||||
fc = *fmt++;
|
||||
|
@ -877,11 +695,15 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
|
|||
break;
|
||||
|
||||
case 'x':
|
||||
case p'x':
|
||||
base = 16;
|
||||
case 'u':
|
||||
case p'u':
|
||||
issigned = false;
|
||||
case 'i':
|
||||
case 'd':
|
||||
case p'i':
|
||||
case p'd':
|
||||
{
|
||||
bool sign = false;
|
||||
if (cs == '-')
|
||||
|
@ -962,6 +784,9 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
|
|||
case 'f':
|
||||
case 'e':
|
||||
case 'g':
|
||||
case p'f':
|
||||
case p'e':
|
||||
case p'g':
|
||||
{
|
||||
bool sign = false;
|
||||
if (cs == '-')
|
||||
|
@ -1068,6 +893,7 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
|
|||
} break;
|
||||
#endif
|
||||
case 's':
|
||||
case p's':
|
||||
{
|
||||
char * pch = (char *)*params;
|
||||
while (width > 0 && cs > 0 && !isspace(cs))
|
||||
|
@ -1110,6 +936,7 @@ int fpscanf(const char * fmt, int (* ffunc)(void * p), void * fparam, void ** pa
|
|||
} break;
|
||||
|
||||
case 'c':
|
||||
case p'c':
|
||||
{
|
||||
char * pch = (char *)*params;
|
||||
if (!ignore)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#define STDIO_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void putchar(char c);
|
||||
|
||||
|
@ -12,10 +13,16 @@ void puts(const char * str);
|
|||
|
||||
char * gets(char * str);
|
||||
|
||||
char * gets_s(char * str, size_t n);
|
||||
|
||||
void printf(const char * fmt, ...);
|
||||
|
||||
int sprintf(char * str, const char * fmt, ...);
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist);
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist);
|
||||
|
||||
int scanf(const char * fmt, ...);
|
||||
|
||||
int sscanf(const char * str, const char * fmt, ...);
|
||||
|
|
108
include/stdlib.c
108
include/stdlib.c
|
@ -7,20 +7,17 @@
|
|||
void itoa(int n, char * s, unsigned radix)
|
||||
{
|
||||
bool neg = n < 0;
|
||||
if (neg)
|
||||
{
|
||||
n = - n;
|
||||
}
|
||||
unsigned un = neg ? -n : n;
|
||||
|
||||
char i = 0;
|
||||
do {
|
||||
int d = n % radix;
|
||||
unsigned d = un % radix;
|
||||
if (d < 10)
|
||||
d += '0';
|
||||
else
|
||||
d += 'A' - 10;
|
||||
s[i++] = d;
|
||||
} while ((n /= radix) > 0);
|
||||
} while ((un /= radix) > 0);
|
||||
|
||||
if (neg)
|
||||
{
|
||||
|
@ -524,6 +521,12 @@ void exit(int status)
|
|||
}
|
||||
}
|
||||
|
||||
void abort(void)
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
extern struct Heap {
|
||||
Heap * next, * end;
|
||||
} HeapNode;
|
||||
|
@ -541,7 +544,7 @@ unsigned heapfree(void)
|
|||
}
|
||||
|
||||
#if 0
|
||||
struct Heap {
|
||||
struct Heap {q
|
||||
unsigned int size;
|
||||
Heap * next;
|
||||
} * freeHeap;
|
||||
|
@ -664,6 +667,97 @@ void * calloc(int num, int size)
|
|||
return p;
|
||||
}
|
||||
|
||||
void * realloc(void * ptr, unsigned size)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
#ifdef HEAPCHECK
|
||||
Heap * pheap = (Heap *)((char *)ptr - 6);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 6);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#else
|
||||
unsigned nsize = (size + 5) & ~3;
|
||||
|
||||
// Get heap info
|
||||
Heap * pheap = (Heap *)((char *)ptr - 2);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
Heap * h = HeapNode.next;
|
||||
Heap * hp = &HeapNode;
|
||||
while (h && h < pheap)
|
||||
{
|
||||
hp = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (nsize <= psize)
|
||||
{
|
||||
// check if we should free some memory
|
||||
if (nsize + sizeof(HeapNode) < psize)
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
|
||||
if (h == eheap)
|
||||
{
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
nheap->end = eheap;
|
||||
nheap->next = h;
|
||||
}
|
||||
|
||||
hp->next = nheap;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
else if (h == eheap)
|
||||
{
|
||||
// Free space after this
|
||||
|
||||
// Check if enough space if extending
|
||||
unsigned xsize = (char *)h->end - (char *)pheap;
|
||||
if (xsize >= nsize)
|
||||
{
|
||||
if (xsize > nsize + sizeof(HeapNode))
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
hp->next = nheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
pheap->next = h->end;
|
||||
hp->next = h->next;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 2);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static unsigned seed = 31232;
|
||||
|
||||
unsigned int rand(void)
|
||||
|
|
|
@ -37,12 +37,16 @@ long labs(long n);
|
|||
|
||||
void exit(int status);
|
||||
|
||||
void abort(void);
|
||||
|
||||
void * malloc(unsigned int size);
|
||||
|
||||
void free(void * ptr);
|
||||
|
||||
void * calloc(int num, int size);
|
||||
|
||||
void * realloc(void * ptr, unsigned size);
|
||||
|
||||
unsigned heapfree(void);
|
||||
|
||||
unsigned int rand(void);
|
||||
|
|
|
@ -130,13 +130,28 @@ char * strcat(char * dst, const char * src)
|
|||
|
||||
char * cpycat(char * dst, const char * src)
|
||||
{
|
||||
do {} while (*dst++ = *src++);
|
||||
while (*dst = *src++)
|
||||
dst++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
#pragma native(cpycat)
|
||||
|
||||
char* strchr( const char* str, int ch )
|
||||
{
|
||||
char * p = (char *)str;
|
||||
|
||||
while (*p != (char)ch)
|
||||
{
|
||||
if (!*p)
|
||||
return nullptr;
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void * memset(void * dst, int value, int size)
|
||||
{
|
||||
__asm
|
||||
|
@ -222,8 +237,8 @@ void * memmove(void * dst, const void * src, int size)
|
|||
int sz = size;
|
||||
if (sz > 0)
|
||||
{
|
||||
char * d = dst;
|
||||
const char * s = src;
|
||||
char * d = (char *)dst;
|
||||
const char * s = (const char *)src;
|
||||
if (d < s)
|
||||
{
|
||||
do {
|
||||
|
@ -244,7 +259,7 @@ void * memmove(void * dst, const void * src, int size)
|
|||
|
||||
int memcmp(const void * ptr1, const void * ptr2, int size)
|
||||
{
|
||||
const char * p = ptr1, * q = ptr2;
|
||||
const char * p = (const char *)ptr1, * q = (const char *)ptr2;
|
||||
char c, d;
|
||||
|
||||
while (size--)
|
||||
|
|
|
@ -21,10 +21,16 @@ int memcmp(const void * ptr1, const void * ptr2, int size);
|
|||
|
||||
void * memmove(void * dst, const void * src, int size);
|
||||
|
||||
char* strchr( const char* str, int ch );
|
||||
|
||||
#pragma intrinsic(strcpy)
|
||||
|
||||
#pragma intrinsic(memcpy)
|
||||
|
||||
#pragma intrinsic(memset)
|
||||
|
||||
#pragma intrinsic(memclr)
|
||||
|
||||
#pragma compile("string.c")
|
||||
|
||||
#endif
|
||||
|
|
116
make/makefile
116
make/makefile
|
@ -1,12 +1,25 @@
|
|||
|
||||
|
||||
sources = $(wildcard ../oscar64/*.cpp)
|
||||
objects = $(patsubst ../oscar64/%.cpp,%.o,$(sources))
|
||||
project_dir := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))/../)
|
||||
sources = $(wildcard $(project_dir)/oscar64/*.cpp)
|
||||
srcdir := $(if $(srcdir),$(srcdir),$(project_dir)/build)
|
||||
objects = $(patsubst $(project_dir)/oscar64/%.cpp,$(srcdir)/%.o,$(sources))
|
||||
|
||||
CXX = c++
|
||||
CPPFLAGS = -g -O2 -std=c++11 -Wno-switch
|
||||
|
||||
$(shell mkdir -p ../bin)
|
||||
SED = /usr/bin/sed
|
||||
REMOVE_FORCE_ALL = $(RM) --recursive --dir
|
||||
export OSCAR64_CC = $(project_dir)/bin/oscar64
|
||||
export OSCAR64_CFLAGS =
|
||||
export OSCAR64_CXX = $(project_dir)/bin/oscar64
|
||||
MKDIR_PARENT = /bin/mkdir -p -m 755
|
||||
INSTALL = /usr/bin/install
|
||||
INSTALL_PROGRAM = $(INSTALL) -m 755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
DESTDIR =
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
bindir = $(exec_prefix)/bin
|
||||
includedir = $(prefix)/include
|
||||
|
||||
|
||||
ifdef WINDIR
|
||||
linklibs = -lpthread
|
||||
|
@ -16,26 +29,87 @@ else
|
|||
ifeq ($(UNAME_S), Darwin)
|
||||
|
||||
linklibs = -lpthread
|
||||
else
|
||||
else
|
||||
# MSVC
|
||||
linklibs = -lrt -lpthread
|
||||
# MinGW
|
||||
#linklibs = -lversion -lpthread
|
||||
endif
|
||||
endif
|
||||
|
||||
%.o: ../oscar64/%.cpp
|
||||
$(CXX) -c $(CPPFLAGS) $< -o $@
|
||||
|
||||
%.d: ../oscar64/%.cpp
|
||||
@set -e; rm -f $@; \
|
||||
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
|
||||
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
||||
rm -f $@.$$$$
|
||||
|
||||
../bin/oscar64 : $(objects)
|
||||
$(CXX) $(CPPFLAGS) $(linklibs) $(objects) -o ../bin/oscar64
|
||||
all: compiler samples check
|
||||
|
||||
|
||||
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
|
||||
@echo "Compiling compiler file" $@ "..." $<
|
||||
@$(CXX) -c $(CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
$(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
|
||||
@$(MKDIR_PARENT) $(srcdir)
|
||||
@echo "Transforming file" $@ "..." $<
|
||||
@set -e; \
|
||||
$(RM) $@; \
|
||||
$(CC) -MM -MT $(patsubst %.d,%.o,$@) $(CPPFLAGS) $< > $@.$$$$; \
|
||||
$(SED) 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
||||
$(RM) $@.$$$$
|
||||
|
||||
|
||||
compiler: --prep-build-dir $(objects)
|
||||
@$(MKDIR_PARENT) $(srcdir)
|
||||
@echo "Linking compiler..."
|
||||
$(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64
|
||||
|
||||
|
||||
.PHONY : clean
|
||||
clean :
|
||||
-rm *.o *.d ../bin/oscar64
|
||||
@echo "Cleaning compiler..."
|
||||
@$(RM) $(srcdir)/*.o
|
||||
@$(RM) $(srcdir)/*.d
|
||||
@$(RM) $(project_dir)/bin/oscar64
|
||||
@$(MAKE) -C $(project_dir)/samples clean
|
||||
@$(MAKE) -C $(project_dir)/autotest clean
|
||||
|
||||
|
||||
.PHONY : distclean
|
||||
distclean :
|
||||
@echo "Distribution cleaning compiler..."
|
||||
@$(REMOVE_FORCE_ALL) $(srcdir)
|
||||
@$(REMOVE_FORCE_ALL) $(project_dir)/bin
|
||||
@$(MAKE) -C $(project_dir)/samples clean
|
||||
@$(MAKE) -C $(project_dir)/autotest clean
|
||||
|
||||
|
||||
samples: compiler
|
||||
@$(MAKE) -C $(project_dir)/samples all
|
||||
|
||||
|
||||
check: compiler
|
||||
@$(MAKE) -C $(project_dir)/autotest all
|
||||
|
||||
install: compiler
|
||||
@echo "Installing to" $(DESTDIR)$(prefix)
|
||||
@$(MKDIR_PARENT) $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) $(project_dir)/bin/oscar64 $(DESTDIR)$(bindir)
|
||||
@$(MKDIR_PARENT) $(DESTDIR)$(includedir)/oscar64/{audio,c64,c128,cx16,gfx,nes,opp,plus4,vic20}
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/*.h $(project_dir)/include/*.c) $(DESTDIR)$(includedir)/oscar64
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/audio/*.h $(project_dir)/include/audio/*.c) $(DESTDIR)$(includedir)/oscar64/audio
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/c64/*.h $(project_dir)/include/c64/*.c) $(DESTDIR)$(includedir)/oscar64/c64
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/c128/*.h $(project_dir)/include/c128/*.c) $(DESTDIR)$(includedir)/oscar64/c128
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/cx16/*.h $(project_dir)/include/cx16/*.c) $(DESTDIR)$(includedir)/oscar64/cx16
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/gfx/*.h $(project_dir)/include/gfx/*.c) $(DESTDIR)$(includedir)/oscar64/gfx
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/nes/*.h $(project_dir)/include/nes/*.c) $(DESTDIR)$(includedir)/oscar64/nes
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/opp/*.h $(project_dir)/include/opp/*.cpp) $(DESTDIR)$(includedir)/oscar64/opp
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/plus4/*.h $(project_dir)/include/plus4/*.c) $(DESTDIR)$(includedir)/oscar64/plus4
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/vic20/*.h $(project_dir)/include/vic20/*.c) $(DESTDIR)$(includedir)/oscar64/vic20
|
||||
|
||||
|
||||
uninstall:
|
||||
@echo "Uninstalling..."
|
||||
@$(RM) $(DESTDIR)$(bindir)/oscar64
|
||||
@$(REMOVE_FORCE_ALL) $(DESTDIR)$(includedir)/oscar64/
|
||||
|
||||
|
||||
ifeq ($(UNAME_S), Darwin)
|
||||
|
||||
|
@ -44,3 +118,9 @@ else
|
|||
include $(objects:.o=.d)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
--prep-build-dir:
|
||||
echo "makedir"
|
||||
@if [ ! -d $(srcdir) ]; then $(MKDIR_PARENT) $(srcdir); fi
|
||||
@if [ ! -d $(project_dir)/bin ]; then $(MKDIR_PARENT) $(project_dir)/bin; fi
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
mkdir r:\oscar64
|
||||
mkdir r:\oscar64\bin
|
||||
mkdir r:\oscar64\include
|
||||
|
||||
xcopy /y bin\oscar64.exe r:\oscar64\bin
|
||||
xcopy /y /e include r:\oscar64\include
|
||||
|
||||
tar -caf r:\oscar64.zip r:\oscar64
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
16
oscar64.sln
16
oscar64.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31624.102
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35931.197
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
|
||||
EndProject
|
||||
|
@ -23,10 +23,14 @@ Global
|
|||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64
|
||||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = Release|Win32
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.Build.0 = Debug|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.Build.0 = Debug|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.Build.0 = Release|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -153,8 +153,8 @@ template <class T>
|
|||
class GrowingArray
|
||||
{
|
||||
protected:
|
||||
int size, range;
|
||||
T* array;
|
||||
int size, range;
|
||||
T * array;
|
||||
T empty;
|
||||
|
||||
void Grow(int to, bool clear)
|
||||
|
@ -166,10 +166,15 @@ protected:
|
|||
|
||||
if (to > range)
|
||||
{
|
||||
if (to > range * 2)
|
||||
int trange = range * sizeof(T) < 65536 ? range * 2 : range + (range >> 2);
|
||||
|
||||
if (trange < 4)
|
||||
trange = 4;
|
||||
|
||||
if (to > trange)
|
||||
range = to;
|
||||
else
|
||||
range = range * 2;
|
||||
range = trange;
|
||||
|
||||
a2 = new T[range];
|
||||
if (to > size)
|
||||
|
@ -191,8 +196,8 @@ public:
|
|||
: empty(empty_)
|
||||
{
|
||||
size = 0;
|
||||
range = 4;
|
||||
array = new T[range];
|
||||
range = 0;
|
||||
array = nullptr;
|
||||
}
|
||||
|
||||
GrowingArray(const GrowingArray& a)
|
||||
|
@ -226,14 +231,22 @@ public:
|
|||
delete[] array;
|
||||
}
|
||||
|
||||
T& operator[](int n)
|
||||
void shrink(void)
|
||||
{
|
||||
size = 0;
|
||||
range = 0;
|
||||
delete[] array;
|
||||
array = nullptr;
|
||||
}
|
||||
|
||||
__forceinline T& operator[](int n)
|
||||
{
|
||||
assert(n >= 0);
|
||||
if (n >= size) Grow(n + 1, false);
|
||||
return array[n];
|
||||
}
|
||||
|
||||
const T & operator[](int n) const
|
||||
__forceinline const T & operator[](int n) const
|
||||
{
|
||||
assert(n >= 0);
|
||||
if (n >= size) return empty;
|
||||
|
@ -251,7 +264,7 @@ public:
|
|||
if (n < size)
|
||||
array[n] = empty;
|
||||
}
|
||||
|
||||
|
||||
void Push(T t)
|
||||
{
|
||||
(*this)[size] = t;
|
||||
|
@ -322,7 +335,7 @@ public:
|
|||
|
||||
bool IsEmpty(void) const { return size == 0; }
|
||||
|
||||
int Size(void) const { return size; }
|
||||
__forceinline int Size(void) const { return size; }
|
||||
|
||||
T Last() const
|
||||
{
|
||||
|
@ -408,9 +421,33 @@ protected:
|
|||
array = a2;
|
||||
}
|
||||
|
||||
for (int i = size; i < to; i++) array[i] = T{};
|
||||
|
||||
size = to;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Partition(const F & f, int l, int r)
|
||||
{
|
||||
if (r > l + 1)
|
||||
{
|
||||
int pi = l;
|
||||
T p(array[pi]);
|
||||
|
||||
for (int i = l + 1; i < r; i++)
|
||||
{
|
||||
if (f(array[i], p))
|
||||
{
|
||||
array[pi++] = array[i];
|
||||
array[i] = array[pi];
|
||||
}
|
||||
}
|
||||
array[pi] = p;
|
||||
|
||||
Partition(f, l, pi);
|
||||
Partition(f, pi + 1, r);
|
||||
}
|
||||
}
|
||||
public:
|
||||
ExpandingArray(void)
|
||||
{
|
||||
|
@ -583,6 +620,24 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void Fill(const T& t)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i] = t;
|
||||
}
|
||||
|
||||
void Clear(void)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i] = T{};
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Sort(const F & f)
|
||||
{
|
||||
Partition(f, 0, size);
|
||||
}
|
||||
|
||||
__forceinline T& operator[](int n)
|
||||
{
|
||||
assert(n >= 0 && n < size);
|
||||
|
|
|
@ -293,7 +293,7 @@ const char* AsmInstructionNames[NUM_ASM_INS_TYPES] = {
|
|||
"INV", "BYT"
|
||||
};
|
||||
|
||||
int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
||||
int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
|
@ -306,6 +306,8 @@ int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
|||
2,
|
||||
2,
|
||||
2,
|
||||
0,
|
||||
2
|
||||
};
|
||||
|
||||
void InitAssembler(void)
|
||||
|
|
|
@ -31,7 +31,9 @@ enum AsmInsMode
|
|||
|
||||
NUM_ASM_INS_MODES,
|
||||
|
||||
ASMIM_IMMEDIATE_ADDRESS
|
||||
ASMIM_IMMEDIATE_ADDRESS,
|
||||
|
||||
NUM_ASM_INS_MODES_X,
|
||||
};
|
||||
|
||||
struct AsmInsData
|
||||
|
@ -45,6 +47,8 @@ extern AsmInsData DecInsData[256];
|
|||
|
||||
extern short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES];
|
||||
|
||||
extern int AsmInsModeSize[NUM_ASM_INS_MODES_X];
|
||||
|
||||
extern const char* AsmInstructionNames[NUM_ASM_INS_TYPES];
|
||||
|
||||
AsmInsType FindAsmInstruction(const char * ins);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
class BitVector
|
||||
{
|
||||
|
|
|
@ -144,8 +144,8 @@ static const char* ByteCodeNames[] = {
|
|||
"LOOP_U8",
|
||||
"MALLOC",
|
||||
"FREE",
|
||||
nullptr,
|
||||
nullptr,
|
||||
"FILL",
|
||||
"FILL_LONG",
|
||||
nullptr,
|
||||
|
||||
"JSR", //114
|
||||
|
@ -623,6 +623,10 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
|
|||
case BC_OP_CEIL_F32:
|
||||
case BC_CONV_F32_U16:
|
||||
case BC_CONV_F32_I16:
|
||||
case BC_CONV_U32_F32:
|
||||
case BC_CONV_I32_F32:
|
||||
case BC_CONV_F32_U32:
|
||||
case BC_CONV_F32_I32:
|
||||
used = 0xffffffff;
|
||||
break;
|
||||
|
||||
|
@ -680,6 +684,8 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
|
|||
used = 0xffffffff;
|
||||
break;
|
||||
|
||||
case BC_FILL:
|
||||
case BC_FILL_LONG:
|
||||
case BC_COPY:
|
||||
case BC_COPY_LONG:
|
||||
case BC_STRCPY:
|
||||
|
@ -780,7 +786,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
|
|||
return true;
|
||||
if (mCode == BC_LEA_ACCU_INDEX)
|
||||
return true;
|
||||
if (mCode == BC_COPY || mCode == BC_STRCPY)
|
||||
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL)
|
||||
return true;
|
||||
if (mCode == BC_BINOP_ADDA_16)
|
||||
return true;
|
||||
|
@ -793,7 +799,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
|
|||
if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32)
|
||||
return true;
|
||||
|
||||
if (mCode == BC_COPY || mCode == BC_STRCPY)
|
||||
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL)
|
||||
return true;
|
||||
|
||||
if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS)
|
||||
|
@ -1212,6 +1218,20 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
block->PutByte(mValue);
|
||||
break;
|
||||
|
||||
case BC_FILL:
|
||||
case BC_FILL_LONG:
|
||||
if (mValue < 256)
|
||||
{
|
||||
block->PutCode(generator, BC_FILL);
|
||||
block->PutByte(uint8(mValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
block->PutCode(generator, BC_FILL_LONG);
|
||||
block->PutWord(uint16(mValue));
|
||||
}
|
||||
break;
|
||||
|
||||
case BC_COPY:
|
||||
case BC_COPY_LONG:
|
||||
if (mValue < 256)
|
||||
|
@ -1262,6 +1282,23 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
block->PutByte(mRegister);
|
||||
break;
|
||||
}
|
||||
case BC_CONV_U32_F32:
|
||||
case BC_CONV_I32_F32:
|
||||
case BC_CONV_F32_U32:
|
||||
case BC_CONV_F32_I32:
|
||||
{
|
||||
block->PutCode(generator, BC_EXTRT);
|
||||
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
|
||||
rl.mRefObject = generator->mExtByteCodes[mCode - 128];
|
||||
rl.mRefOffset = 0;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutWord(0);
|
||||
block->PutByte(mRegister);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -1567,6 +1604,30 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
|
|||
|
||||
}
|
||||
|
||||
void ByteCodeBasicBlock::FillValue(InterCodeProcedure* proc, const InterInstruction* ins)
|
||||
{
|
||||
LoadOperandAddress(proc, ins->mSrc[1], BC_REG_ADDR);
|
||||
|
||||
if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_CONST_8);
|
||||
cins.mRegister = BC_REG_ACCU;
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_8);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
}
|
||||
|
||||
ByteCodeInstruction cins(BC_FILL);
|
||||
cins.mValue = ins->mConst.mOperandSize;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
|
||||
void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins)
|
||||
{
|
||||
LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU);
|
||||
|
@ -3401,94 +3462,151 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
|
|||
{
|
||||
if (ins->mSrc[1].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[1].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
if (ins->mSrc[0].mType == IT_INT16 || ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[0].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3681,6 +3799,67 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
|||
|
||||
} break;
|
||||
|
||||
case IA_FLOAT2LINT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_F32_I32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
case IA_LINT2FLOAT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_I32_F32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
case IA_FLOAT2LUINT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_F32_U32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
case IA_LUINT2FLOAT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_U32_F32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
|
||||
case IA_EXT8TO16S:
|
||||
{
|
||||
if (ins->mSrc[0].mTemp == ins->mDst.mTemp)
|
||||
|
@ -4320,6 +4499,9 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
|
|||
else
|
||||
LoadDirectValue(iproc, ins);
|
||||
break;
|
||||
case IC_FILL:
|
||||
FillValue(iproc, ins);
|
||||
break;
|
||||
case IC_COPY:
|
||||
CopyValue(iproc, ins);
|
||||
break;
|
||||
|
@ -6423,7 +6605,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
|
|||
{
|
||||
mID = proc->mID;
|
||||
|
||||
mNumBlocks = proc->mBlocks.Size();
|
||||
mNumBlocks = proc->mNumBlocks;
|
||||
|
||||
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
|
||||
for (int i = 0; i < mNumBlocks; i++)
|
||||
|
|
|
@ -145,8 +145,8 @@ enum ByteCode
|
|||
BC_LOOP_U8,
|
||||
BC_MALLOC,
|
||||
BC_FREE,
|
||||
BC_UNUSED_4,
|
||||
BC_UNUSED_5,
|
||||
BC_FILL,
|
||||
BC_FILL_LONG,
|
||||
BC_UNUSED_6,
|
||||
|
||||
BC_JSR,
|
||||
|
@ -186,7 +186,12 @@ enum ByteCode
|
|||
BC_BINOP_SHR_U32,
|
||||
BC_BINOP_SHR_I32,
|
||||
BC_BINOP_CMP_U32,
|
||||
BC_BINOP_CMP_S32
|
||||
BC_BINOP_CMP_S32,
|
||||
|
||||
BC_CONV_U32_F32,
|
||||
BC_CONV_I32_F32,
|
||||
BC_CONV_F32_U32,
|
||||
BC_CONV_F32_I32,
|
||||
};
|
||||
|
||||
class ByteCodeProcedure;
|
||||
|
@ -281,6 +286,7 @@ public:
|
|||
void IntConstToAddr(int64 val);
|
||||
void FloatConstToAccu(double val);
|
||||
void FloatConstToWork(double val);
|
||||
void FillValue(InterCodeProcedure* proc, const InterInstruction* ins);
|
||||
void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins);
|
||||
void CallMalloc(InterCodeProcedure* proc, const InterInstruction* ins);
|
||||
|
|
|
@ -49,7 +49,7 @@ bool CompilationUnits::AddUnit(Location& location, const char* name, const char*
|
|||
else
|
||||
{
|
||||
strcpy_s(filename, from);
|
||||
int i = strlen(filename);
|
||||
ptrdiff_t i = strlen(filename);
|
||||
while (i > 0 && (filename[i - 1] != '/' && filename[i - 1] != '\\'))
|
||||
i--;
|
||||
while (name[0] == '.' && name[1] == '.' && name[2] == '/')
|
||||
|
|
|
@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
|
||||
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = int(bcdec->mInteger);
|
||||
|
@ -442,6 +442,8 @@ void Compiler::BuildVTables(void)
|
|||
mdec->mFlags |= DTF_DEFINED;
|
||||
mdec->mValue = ecall;
|
||||
}
|
||||
|
||||
mdec->mQualIdent = mdec->mQualIdent->Mangle("$vcall");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -464,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
|
|||
printf("Generate native code <%s>\n", proc->mIdent->mString);
|
||||
|
||||
ncproc->Compile(proc);
|
||||
mNativeProcedures.Push(ncproc);
|
||||
mNativeCodeGenerator->mProcedures.Push(ncproc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -506,6 +508,8 @@ bool Compiler::GenerateCode(void)
|
|||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
|
||||
else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES))
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
|
||||
else if (mTargetMachine == TMACH_PET_8K || mTargetMachine == TMACH_PET_16K || mTargetMachine == TMACH_PET_32K)
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00ed, 0x00f7);
|
||||
else
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff);
|
||||
}
|
||||
|
@ -519,6 +523,12 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2080);
|
||||
else
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2100);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
case TMACH_X16:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
|
@ -540,6 +550,7 @@ bool Compiler::GenerateCode(void)
|
|||
regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode);
|
||||
break;
|
||||
case TMACH_C128B:
|
||||
case TMACH_C128E:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x1c01, 0x1c80);
|
||||
else
|
||||
|
@ -549,12 +560,12 @@ bool Compiler::GenerateCode(void)
|
|||
if (mCompilerOptions & COPT_NATIVE)
|
||||
{
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
|
||||
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1100);
|
||||
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1180);
|
||||
}
|
||||
else
|
||||
{
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x1001, 0x1080);
|
||||
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1000);
|
||||
regionLowcode = mLinker->AddRegion(identLowcode, 0x1080, 0x1180);
|
||||
}
|
||||
regionLowcode->mSections.Push(mCompilationUnits->mSectionLowCode);
|
||||
break;
|
||||
|
@ -620,15 +631,21 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
case TMACH_X16:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
|
||||
break;
|
||||
case TMACH_C128:
|
||||
case TMACH_C128B:
|
||||
case TMACH_C128E:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x1d00, 0x1e00);
|
||||
break;
|
||||
case TMACH_PLUS4:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x1200, 0x1300);
|
||||
break;
|
||||
case TMACH_VIC20:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x1100, 0x1200);
|
||||
break;
|
||||
|
@ -678,6 +695,9 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x2300, 0xc000);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
|
||||
break;
|
||||
|
@ -690,8 +710,11 @@ bool Compiler::GenerateCode(void)
|
|||
case TMACH_C128B:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1e00, 0x4000);
|
||||
break;
|
||||
case TMACH_C128E:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1e00, 0xc000);
|
||||
break;
|
||||
case TMACH_PLUS4:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1200, 0xfc00);
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1300, 0xfc00);
|
||||
break;
|
||||
case TMACH_VIC20:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1200, 0x1e00);
|
||||
|
@ -726,6 +749,14 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
// TODO: Disable M65 cartridges for now.
|
||||
//
|
||||
// if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
|
||||
// regionMain = mLinker->AddRegion(identMain, 0x2666, 0xff00);
|
||||
// else
|
||||
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xc000);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
|
||||
if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
|
||||
|
@ -742,8 +773,11 @@ bool Compiler::GenerateCode(void)
|
|||
case TMACH_C128B:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1c80, 0x4000);
|
||||
break;
|
||||
case TMACH_C128E:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1c80, 0xc000);
|
||||
break;
|
||||
case TMACH_PLUS4:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1100, 0xfc00);
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1180, 0xfc00);
|
||||
break;
|
||||
case TMACH_VIC20:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x1080, 0x1e00);
|
||||
|
@ -879,7 +913,7 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
Declaration* dec = mCompilationUnits->mReferenced[i];
|
||||
if (dec->mType == DT_CONST_FUNCTION)
|
||||
mGlobalAnalyzer->AnalyzeProcedure(dec->mValue, dec);
|
||||
mGlobalAnalyzer->AnalyzeProcedure(nullptr, dec->mValue, dec);
|
||||
else
|
||||
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
|
||||
}
|
||||
|
@ -898,7 +932,7 @@ bool Compiler::GenerateCode(void)
|
|||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Generate intermediate code\n");
|
||||
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart, nullptr);
|
||||
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
|
||||
{
|
||||
Declaration* dec = mCompilationUnits->mReferenced[i];
|
||||
|
@ -907,13 +941,19 @@ bool Compiler::GenerateCode(void)
|
|||
if (!dec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateProcedure(mInterCodeModule, dec->mValue, dec);
|
||||
}
|
||||
else
|
||||
}
|
||||
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
|
||||
{
|
||||
Declaration* dec = mCompilationUnits->mReferenced[i];
|
||||
if (dec->mType != DT_CONST_FUNCTION)
|
||||
{
|
||||
if (!dec->mLinkerObject)
|
||||
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, dec);
|
||||
}
|
||||
}
|
||||
|
||||
mInterCodeGenerator->CompleteMainInit();
|
||||
|
||||
if (mErrors->mErrorCount != 0)
|
||||
return false;
|
||||
|
||||
|
@ -925,7 +965,8 @@ bool Compiler::GenerateCode(void)
|
|||
RegisterRuntime(loc, Ident::Unique("fsplitt"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsplitx"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsplita"));
|
||||
RegisterRuntime(loc, Ident::Unique("faddsub"));
|
||||
RegisterRuntime(loc, Ident::Unique("fadd"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsub"));
|
||||
RegisterRuntime(loc, Ident::Unique("fmul"));
|
||||
RegisterRuntime(loc, Ident::Unique("fdiv"));
|
||||
RegisterRuntime(loc, Ident::Unique("mul16"));
|
||||
|
@ -938,8 +979,12 @@ bool Compiler::GenerateCode(void)
|
|||
RegisterRuntime(loc, Ident::Unique("fceil"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftoi"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftou"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftoli"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftolu"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromi"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromu"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromli"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromlu"));
|
||||
RegisterRuntime(loc, Ident::Unique("fcmp"));
|
||||
RegisterRuntime(loc, Ident::Unique("bcexec"));
|
||||
RegisterRuntime(loc, Ident::Unique("jmpaddr"));
|
||||
|
@ -949,8 +994,12 @@ bool Compiler::GenerateCode(void)
|
|||
RegisterRuntime(loc, Ident::Unique("divu32"));
|
||||
RegisterRuntime(loc, Ident::Unique("modu32"));
|
||||
|
||||
RegisterRuntime(loc, Ident::Unique("store32"));
|
||||
RegisterRuntime(loc, Ident::Unique("load32"));
|
||||
|
||||
RegisterRuntime(loc, Ident::Unique("malloc"));
|
||||
RegisterRuntime(loc, Ident::Unique("free"));
|
||||
RegisterRuntime(loc, Ident::Unique("breakpoint"));
|
||||
}
|
||||
|
||||
// Register extended byte code functions
|
||||
|
@ -966,7 +1015,7 @@ bool Compiler::GenerateCode(void)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
|
||||
}
|
||||
}
|
||||
|
@ -1009,13 +1058,18 @@ bool Compiler::GenerateCode(void)
|
|||
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
|
||||
}
|
||||
|
||||
mNativeCodeGenerator->OutlineFunctions();
|
||||
|
||||
mNativeCodeGenerator->BuildFunctionProxies();
|
||||
|
||||
for (int i = 0; i < mNativeProcedures.Size(); i++)
|
||||
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE2)
|
||||
printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString);
|
||||
mNativeProcedures[i]->Assemble();
|
||||
{
|
||||
if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
|
||||
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
|
||||
}
|
||||
mNativeCodeGenerator->mProcedures[i]->Assemble();
|
||||
}
|
||||
|
||||
LinkerObject* byteCodeObject = nullptr;
|
||||
|
@ -1041,13 +1095,13 @@ bool Compiler::GenerateCode(void)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = int(bcdec->mInteger);
|
||||
}
|
||||
|
@ -1085,7 +1139,11 @@ bool Compiler::GenerateCode(void)
|
|||
mLinker->ReferenceObject(mCompilationUnits->mReferenced[i]->mLinkerObject);
|
||||
|
||||
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||
{
|
||||
mLinker->CombineSameConst();
|
||||
mLinker->InlineSimpleJumps();
|
||||
mLinker->CheckDirectJumps();
|
||||
}
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Link executable\n");
|
||||
|
@ -1129,7 +1187,7 @@ bool Compiler::BuildLZO(const char* targetPath)
|
|||
char prgPath[200];
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
int i = strlen(prgPath);
|
||||
ptrdiff_t i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
|
@ -1143,7 +1201,7 @@ bool Compiler::BuildLZO(const char* targetPath)
|
|||
fopen_s(&file, prgPath, "wb");
|
||||
if (file)
|
||||
{
|
||||
int done = fwrite(data, 1, n, file);
|
||||
ptrdiff_t done = fwrite(data, 1, n, file);
|
||||
fclose(file);
|
||||
delete[] data;
|
||||
return done == n;
|
||||
|
@ -1161,12 +1219,96 @@ bool Compiler::BuildLZO(const char* targetPath)
|
|||
}
|
||||
}
|
||||
|
||||
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
||||
bool Compiler::RemoveErrorFile(const char* targetPath)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200];
|
||||
char prgPath[200], mapPath[200], asmPath[200], intPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
ptrdiff_t i = strlen(basePath);
|
||||
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
|
||||
i--;
|
||||
if (i > 0)
|
||||
basePath[i] = 0;
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
int i = strlen(prgPath);
|
||||
i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
prgPath[i] = 0;
|
||||
|
||||
strcpy_s(mapPath, prgPath);
|
||||
strcpy_s(asmPath, prgPath);
|
||||
strcpy_s(intPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "error.map");
|
||||
strcat_s(asmPath, "error.asm");
|
||||
strcat_s(intPath, "error.int");
|
||||
|
||||
remove(mapPath);
|
||||
remove(asmPath);
|
||||
remove(intPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::WriteErrorFile(const char* targetPath)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], intPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
ptrdiff_t i = strlen(basePath);
|
||||
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
|
||||
i--;
|
||||
if (i > 0)
|
||||
basePath[i] = 0;
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
prgPath[i] = 0;
|
||||
|
||||
strcpy_s(mapPath, prgPath);
|
||||
strcpy_s(asmPath, prgPath);
|
||||
strcpy_s(intPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "error.map");
|
||||
strcat_s(asmPath, "error.asm");
|
||||
strcat_s(intPath, "error.int");
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", mapPath);
|
||||
mLinker->WriteMapFile(mapPath);
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", asmPath);
|
||||
mLinker->WriteAsmFile(asmPath, mVersion);
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", intPath);
|
||||
mInterCodeModule->Disassemble(intPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200], cszPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
ptrdiff_t i = strlen(basePath);
|
||||
while (i > 0 && basePath[i - 1] != '/' && basePath[i - 1] != '\\' && basePath[i - 1] != ':')
|
||||
i--;
|
||||
if (i > 0)
|
||||
basePath[i] = 0;
|
||||
|
||||
strcpy_s(prgPath, targetPath);
|
||||
i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
|
@ -1178,6 +1320,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcpy_s(intPath, prgPath);
|
||||
strcpy_s(bcsPath, prgPath);
|
||||
strcpy_s(dbjPath, prgPath);
|
||||
strcpy_s(cszPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "map");
|
||||
strcat_s(asmPath, "asm");
|
||||
|
@ -1185,6 +1328,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcat_s(intPath, "int");
|
||||
strcat_s(bcsPath, "bcs");
|
||||
strcat_s(dbjPath, "dbj");
|
||||
strcat_s(cszPath, "csz");
|
||||
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
{
|
||||
|
@ -1200,7 +1344,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcat_s(prgPath, "prg");
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", prgPath);
|
||||
mLinker->WritePrgFile(prgPath);
|
||||
mLinker->WritePrgFile(prgPath, basePath);
|
||||
}
|
||||
}
|
||||
else if (mCompilerOptions & COPT_TARGET_CRT)
|
||||
|
@ -1232,7 +1376,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
|
||||
if (d64)
|
||||
{
|
||||
int i = strlen(prgPath);
|
||||
ptrdiff_t i = strlen(prgPath);
|
||||
while (i > 0 && prgPath[i - 1] != '.')
|
||||
i--;
|
||||
if (i > 0)
|
||||
|
@ -1250,7 +1394,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", asmPath);
|
||||
mLinker->WriteAsmFile(asmPath);
|
||||
mLinker->WriteAsmFile(asmPath, mVersion);
|
||||
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Writing <%s>\n", lblPath);
|
||||
|
@ -1267,6 +1411,9 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||
WriteDbjFile(dbjPath);
|
||||
|
||||
if (mCompilerOptions & COPT_PROFILEINFO)
|
||||
WriteCszFile(cszPath);
|
||||
|
||||
if (!(mCompilerOptions & COPT_NATIVE))
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
|
@ -1284,6 +1431,9 @@ int Compiler::ExecuteCode(bool profile, int trace)
|
|||
printf("Running emulation...\n");
|
||||
Emulator* emu = new Emulator(mLinker);
|
||||
|
||||
if (mCompilerOptions & COPT_EXTENDED_ZERO_PAGE)
|
||||
emu->mJiffies = false;
|
||||
|
||||
int ecode = 20;
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
{
|
||||
|
@ -1313,6 +1463,128 @@ int Compiler::ExecuteCode(bool profile, int trace)
|
|||
return ecode;
|
||||
}
|
||||
|
||||
static void DumpReferences(FILE* file, Declaration* dec)
|
||||
{
|
||||
if (dec)
|
||||
{
|
||||
fprintf(file, ", \"references\": [");
|
||||
fprintf(file, "\n\t\t\t{\"source\": \"%s\", \"line\": %d, \"column\": %d}", dec->mLocation.mFileName, dec->mLocation.mLine, dec->mLocation.mColumn);
|
||||
for (int i = 0; i < dec->mReferences.Size(); i++)
|
||||
{
|
||||
fprintf(file, ",");
|
||||
Expression* exp = dec->mReferences[i];
|
||||
fprintf(file, "\n\t\t\t{\"source\": \"%s\", \"line\": %d, \"column\": %d}", exp->mLocation.mFileName, exp->mLocation.mLine, exp->mLocation.mColumn);
|
||||
}
|
||||
fprintf(file, "]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Compiler::WriteCszFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
{
|
||||
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
|
||||
{
|
||||
InterCodeProcedure* p(mInterCodeModule->mProcedures[i]);
|
||||
if (p->mLinkerObject && p->mIdent && p->mDeclaration)
|
||||
{
|
||||
LinkerObject* lo = p->mLinkerObject;
|
||||
|
||||
struct SourceCount
|
||||
{
|
||||
const char* mFileName;
|
||||
int mLine, mAddress;
|
||||
int mBytes;
|
||||
};
|
||||
|
||||
ExpandingArray<SourceCount> ea;
|
||||
|
||||
for (int j = 0; j < lo->mCodeLocations.Size(); j++)
|
||||
{
|
||||
const CodeLocation& co(lo->mCodeLocations[j]);
|
||||
const Location* ls = &(co.mLocation);
|
||||
while (ls->mFrom)
|
||||
ls = ls->mFrom;
|
||||
|
||||
int k = 0;
|
||||
while (k < ea.Size() && (ea[k].mFileName != ls->mFileName || ea[k].mLine != ls->mLine))
|
||||
k++;
|
||||
if (k == ea.Size())
|
||||
{
|
||||
SourceCount sc;
|
||||
sc.mFileName = ls->mFileName;
|
||||
sc.mLine = ls->mLine;
|
||||
sc.mBytes = 0;
|
||||
sc.mAddress = co.mStart + lo->mAddress;
|
||||
ea.Push(sc);
|
||||
}
|
||||
|
||||
ea[k].mBytes += co.mEnd - co.mStart;
|
||||
}
|
||||
|
||||
if (ea.Size())
|
||||
{
|
||||
ea.Sort([](const SourceCount& l, const SourceCount& r)->bool {
|
||||
return l.mFileName == r.mFileName ? l.mLine < r.mLine : l.mAddress < r.mAddress;
|
||||
});
|
||||
|
||||
FILE* fsrc;
|
||||
fopen_s(&fsrc, ea[0].mFileName, "r");
|
||||
if (fsrc)
|
||||
{
|
||||
fprintf(file, "<%s, %s>\n", p->mDeclaration->mQualIdent->mString, ea[0].mFileName);
|
||||
#if 0
|
||||
for (int i = 0; i < ea.Size(); i++)
|
||||
{
|
||||
fprintf(file, "%s:%d : %d\n", ea[i].mFileName, ea[i].mLine, ea[i].mBytes);
|
||||
}
|
||||
#endif
|
||||
int k = 0, l = 1;
|
||||
char line[1024];
|
||||
while (k < ea.Size() && fgets(line, 1024, fsrc))
|
||||
{
|
||||
size_t ll = strlen(line);
|
||||
while (ll > 0 && (line[ll - 1] == '\r' || line[ll - 1] == '\n'))
|
||||
ll--;
|
||||
line[ll] = 0;
|
||||
|
||||
if (l < ea[k].mLine)
|
||||
{
|
||||
if (k > 0)
|
||||
fprintf(file, "%5d,---- ( ) : %s\n", l, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ks = k, sum = 0;
|
||||
do {
|
||||
sum += ea[ks].mBytes;
|
||||
ks++;
|
||||
} while (ks < ea.Size() && ea[ks].mFileName != ea[0].mFileName);
|
||||
|
||||
fprintf(file, "%5d,%04x (%3d) : %s\n", l, ea[k].mAddress, ea[k].mBytes, line);
|
||||
|
||||
k = ks;
|
||||
}
|
||||
l++;
|
||||
}
|
||||
|
||||
fclose(fsrc);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::WriteDbjFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
@ -1338,7 +1610,9 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
fprintf(file, ",\n");
|
||||
first = false;
|
||||
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"typeid\": %d}", v->mIdent->mString, v->mLinkerObject->mAddress, v->mLinkerObject->mAddress + v->mLinkerObject->mSize, types.IndexOrPush(v->mDeclaration->mBase));
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"typeid\": %d", v->mIdent->mString, v->mLinkerObject->mAddress, v->mLinkerObject->mAddress + v->mLinkerObject->mSize, types.IndexOrPush(v->mDeclaration->mBase));
|
||||
DumpReferences(file, v->mDeclaration);
|
||||
fprintf(file, "}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1355,8 +1629,8 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
fprintf(file, ",\n");
|
||||
first = false;
|
||||
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"typeid\": %d, \"source\": \"%s\", \"line\": %d, \"lines\": [\n",
|
||||
p->mIdent->mString, p->mLinkerObject->mAddress, p->mLinkerObject->mAddress + p->mLinkerObject->mSize, types.IndexOrPush(p->mDeclaration->mBase),
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"xname\": \"%s\", \"start\": %d, \"end\": %d, \"typeid\": %d, \"source\": \"%s\", \"line\": %d, \"lines\": [\n",
|
||||
p->mIdent->mString, p->mLinkerObject->mFullIdent->mString, p->mLinkerObject->mAddress, p->mLinkerObject->mAddress + p->mLinkerObject->mSize, types.IndexOrPush(p->mDeclaration->mBase),
|
||||
p->mLocation.mFileName, p->mLocation.mLine);
|
||||
|
||||
bool lfirst = true;
|
||||
|
@ -1400,6 +1674,7 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
InterVariable* v(p->mLocalVars[i]);
|
||||
if (v && v->mIdent)
|
||||
{
|
||||
bool skipped = false;
|
||||
if (v->mLinkerObject)
|
||||
{
|
||||
if (v->mLinkerObject->mFlags & LOBJF_PLACED)
|
||||
|
@ -1408,18 +1683,20 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
fprintf(file, ",\n");
|
||||
vfirst = false;
|
||||
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"enter\": %d, \"leave\": %d, \"typeid\": %d}",
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"enter\": %d, \"leave\": %d, \"typeid\": %d",
|
||||
v->mIdent->mString, v->mLinkerObject->mAddress, v->mLinkerObject->mAddress + v->mLinkerObject->mSize,
|
||||
v->mDeclaration->mLocation.mLine, v->mDeclaration->mEndLocation.mLine,
|
||||
types.IndexOrPush(v->mDeclaration->mBase));
|
||||
}
|
||||
else
|
||||
{
|
||||
skipped = true;
|
||||
// Prepared space on the stack but not used
|
||||
}
|
||||
}
|
||||
else if (v->mTemp)
|
||||
{
|
||||
skipped = true;
|
||||
// Promoted to local variable
|
||||
}
|
||||
else if (p->mFramePointer)
|
||||
|
@ -1428,7 +1705,7 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
fprintf(file, ",\n");
|
||||
vfirst = false;
|
||||
|
||||
fprintf(file, "\t\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"base\": %d, \"enter\": %d, \"leave\": %d, \"typeid\": %d}",
|
||||
fprintf(file, "\t\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"base\": %d, \"enter\": %d, \"leave\": %d, \"typeid\": %d",
|
||||
v->mIdent->mString, v->mOffset, v->mOffset + v->mSize, BC_REG_LOCALS,
|
||||
v->mDeclaration->mLocation.mLine, v->mDeclaration->mEndLocation.mLine,
|
||||
types.IndexOrPush(v->mDeclaration->mBase));
|
||||
|
@ -1439,15 +1716,24 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
fprintf(file, ",\n");
|
||||
vfirst = false;
|
||||
|
||||
fprintf(file, "\t\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"base\": %d, \"enter\": %d, \"leave\": %d, \"typeid\": %d}",
|
||||
fprintf(file, "\t\t\t{\"name\": \"%s\", \"start\": %d, \"end\": %d, \"base\": %d, \"enter\": %d, \"leave\": %d, \"typeid\": %d",
|
||||
v->mIdent->mString, v->mOffset, v->mOffset + v->mSize, BC_REG_STACK,
|
||||
v->mDeclaration->mLocation.mLine, v->mDeclaration->mEndLocation.mLine,
|
||||
types.IndexOrPush(v->mDeclaration->mBase));
|
||||
}
|
||||
|
||||
if (!skipped)
|
||||
{
|
||||
if (v->mDeclaration)
|
||||
DumpReferences(file, v->mDeclaration);
|
||||
fprintf(file, "}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, "]}\n");
|
||||
fprintf(file, "]");
|
||||
DumpReferences(file, p->mDeclaration);
|
||||
fprintf(file, "}\n");
|
||||
}
|
||||
}
|
||||
fprintf(file, "\t],\n");
|
||||
|
|
|
@ -29,11 +29,11 @@ public:
|
|||
GlobalOptimizer* mGlobalOptimizer;
|
||||
|
||||
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
|
||||
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
|
||||
|
||||
TargetMachine mTargetMachine;
|
||||
uint64 mCompilerOptions;
|
||||
uint16 mCartridgeID;
|
||||
char mVersion[32];
|
||||
|
||||
struct Define
|
||||
{
|
||||
|
@ -47,6 +47,8 @@ public:
|
|||
bool ParseSource(void);
|
||||
bool GenerateCode(void);
|
||||
bool WriteOutputFile(const char* targetPath, DiskImage * d64);
|
||||
bool WriteErrorFile(const char* targetPath);
|
||||
bool RemoveErrorFile(const char* targetPath);
|
||||
int ExecuteCode(bool profile, int trace);
|
||||
|
||||
void AddDefine(const Ident* ident, const char* value);
|
||||
|
@ -58,4 +60,5 @@ public:
|
|||
void CompleteTemplateExpansion(void);
|
||||
|
||||
bool WriteDbjFile(const char* filename);
|
||||
bool WriteCszFile(const char* filename);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 1ULL << 8;
|
|||
static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9;
|
||||
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
|
||||
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11;
|
||||
static const uint64 COPT_OPTIMIZE_OUTLINE = 1ULL << 12;
|
||||
static const uint64 COPT_OPTIMIZE_PAGE_CROSSING = 1ULL << 13;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16;
|
||||
static const uint64 COPT_NATIVE = 1ULL << 17;
|
||||
|
@ -38,6 +40,11 @@ static const uint64 COPT_VERBOSE3 = 1ULL << 50;
|
|||
static const uint64 COPT_DEBUGINFO = 1ULL << 51;
|
||||
|
||||
static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
|
||||
static const uint64 COPT_PETSCII = 1ULL << 53;
|
||||
static const uint64 COPT_ERROR_FILES = 1ULL << 54;
|
||||
|
||||
static const uint64 COPT_PROFILEINFO = 1ULL << 55;
|
||||
static const uint64 COPT_STRICT = 1ULL << 56;
|
||||
|
||||
|
||||
|
||||
|
@ -45,7 +52,7 @@ static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE |
|
|||
|
||||
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;// | COPT_OPTIMIZE_OUTLINE;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_ASSEMBLER | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
|
||||
|
||||
|
@ -61,6 +68,7 @@ enum TargetMachine
|
|||
TMACH_VIC20_24K,
|
||||
TMACH_C128,
|
||||
TMACH_C128B,
|
||||
TMACH_C128E,
|
||||
TMACH_PET_8K,
|
||||
TMACH_PET_16K,
|
||||
TMACH_PET_32K,
|
||||
|
@ -71,7 +79,8 @@ enum TargetMachine
|
|||
TMACH_NES_MMC1,
|
||||
TMACH_NES_MMC3,
|
||||
TMACH_ATARI,
|
||||
TMACH_X16
|
||||
TMACH_X16,
|
||||
TMACH_MEGA65
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#include "Compression.h"
|
||||
|
||||
int CompressLZO(uint8* dst, const uint8* source, int size)
|
||||
{
|
||||
int csize = 0;
|
||||
|
||||
int pos = 0;
|
||||
while (pos < size)
|
||||
{
|
||||
int pi = 0;
|
||||
while (pi < 127 && pos < size)
|
||||
{
|
||||
int bi = pi, bj = 0;
|
||||
for (int i = 1; i <= (pos < 255 ? pos : 255); i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j])
|
||||
j++;
|
||||
|
||||
if (j > bj)
|
||||
{
|
||||
bi = i;
|
||||
bj = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (bj >= 4)
|
||||
{
|
||||
if (pi > 0)
|
||||
{
|
||||
dst[csize++] = pi;
|
||||
for (int i = 0; i < pi; i++)
|
||||
dst[csize++] = source[pos - pi + i];
|
||||
pi = 0;
|
||||
}
|
||||
|
||||
dst[csize++] = 128 + bj;
|
||||
dst[csize++] = bi;
|
||||
pos += bj;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos++;
|
||||
pi++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pi > 0)
|
||||
{
|
||||
dst[csize++] = pi;
|
||||
for (int i = 0; i < pi; i++)
|
||||
dst[csize++] = source[pos - pi + i];
|
||||
}
|
||||
}
|
||||
|
||||
dst[csize++] = 0;
|
||||
|
||||
return csize;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "CompilerTypes.h"
|
||||
|
||||
int CompressLZO(uint8* dst, const uint8* source, int size);
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#include <math.h>
|
||||
|
||||
ConstexprInterpreter::Value::Value(void)
|
||||
: mDecType(TheVoidTypeDeclaration),
|
||||
: mDecType(TheVoidTypeDeclaration), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mData(mShortData), mDataSize(0)
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ ConstexprInterpreter::Value::Value(void)
|
|||
|
||||
ConstexprInterpreter::Value::Value(const Location & location)
|
||||
: mLocation(location),
|
||||
mDecType(TheVoidTypeDeclaration),
|
||||
mDecType(TheVoidTypeDeclaration), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mData(mShortData), mDataSize(0)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ ConstexprInterpreter::Value::Value(const Location & location)
|
|||
|
||||
ConstexprInterpreter::Value::Value(Expression* exp)
|
||||
: mLocation(exp->mLocation),
|
||||
mDecType(exp->mDecType),
|
||||
mDecType(exp->mDecType), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mDataSize(exp->mDecType->mSize)
|
||||
{
|
||||
|
@ -51,12 +51,15 @@ void ConstexprInterpreter::Value::PutConst(int offset, Declaration* dec)
|
|||
for (int i = 0; i < dec->mBase->mSize; i++)
|
||||
PutIntAt(dec->mData[i], offset + i, TheConstCharTypeDeclaration);
|
||||
break;
|
||||
case DT_CONST_POINTER:
|
||||
PutPtrAt(new Value(mLocation, dec->mValue->mDecValue, dec->mBase, 0), offset, dec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec)
|
||||
: mLocation(location),
|
||||
mDecType(dec),
|
||||
mDecType(dec), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mDataSize(dec->mSize)
|
||||
{
|
||||
|
@ -68,7 +71,7 @@ ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec)
|
|||
|
||||
ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec, int size)
|
||||
: mLocation(location),
|
||||
mDecType(dec),
|
||||
mDecType(dec), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mDataSize(size)
|
||||
{
|
||||
|
@ -80,7 +83,7 @@ ConstexprInterpreter::Value::Value(const Location& location, Declaration* dec, i
|
|||
|
||||
ConstexprInterpreter::Value::Value(const Value& value)
|
||||
: mLocation(value.mLocation),
|
||||
mDecType(value.mDecType),
|
||||
mDecType(value.mDecType), mDecValue(nullptr),
|
||||
mBaseValue(value.mBaseValue), mOffset(value.mOffset),
|
||||
mDataSize(value.mDataSize)
|
||||
|
||||
|
@ -96,7 +99,7 @@ ConstexprInterpreter::Value::Value(const Value& value)
|
|||
|
||||
ConstexprInterpreter::Value::Value(Value&& value)
|
||||
: mLocation(value.mLocation),
|
||||
mDecType(value.mDecType),
|
||||
mDecType(value.mDecType), mDecValue(nullptr),
|
||||
mBaseValue(value.mBaseValue), mOffset(value.mOffset),
|
||||
mDataSize(value.mDataSize)
|
||||
{
|
||||
|
@ -115,7 +118,7 @@ ConstexprInterpreter::Value::Value(Value&& value)
|
|||
|
||||
ConstexprInterpreter::Value::Value(Value* value)
|
||||
: mLocation(value->mLocation),
|
||||
mDecType(value->mDecType),
|
||||
mDecType(value->mDecType), mDecValue(value->mDecValue),
|
||||
mBaseValue(value), mOffset(0),
|
||||
mDataSize(0), mData(mShortData)
|
||||
{
|
||||
|
@ -123,15 +126,23 @@ ConstexprInterpreter::Value::Value(Value* value)
|
|||
|
||||
ConstexprInterpreter::Value::Value(const Location& location, Value* value, Declaration* type, int offset)
|
||||
: mLocation(location),
|
||||
mDecType(type),
|
||||
mDecType(type), mDecValue(nullptr),
|
||||
mBaseValue(value), mOffset(offset),
|
||||
mDataSize(0), mData(mShortData)
|
||||
{
|
||||
}
|
||||
|
||||
ConstexprInterpreter::Value::Value(const Location& location, Declaration* value, Declaration* type, int offset)
|
||||
: mLocation(location),
|
||||
mDecType(type), mDecValue(value),
|
||||
mBaseValue(nullptr), mOffset(offset),
|
||||
mDataSize(0), mData(mShortData)
|
||||
{
|
||||
}
|
||||
|
||||
ConstexprInterpreter::Value::Value(const Location& location, const uint8* data, Declaration* type)
|
||||
: mLocation(location),
|
||||
mDecType(type),
|
||||
mDecType(type), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mDataSize(type->mSize)
|
||||
{
|
||||
|
@ -146,7 +157,7 @@ ConstexprInterpreter::Value::Value(const Location& location, const uint8* data,
|
|||
|
||||
ConstexprInterpreter::Value::Value(const Location& location, const ValueItem* data, Declaration* type)
|
||||
: mLocation(location),
|
||||
mDecType(type),
|
||||
mDecType(type), mDecValue(nullptr),
|
||||
mBaseValue(nullptr), mOffset(0),
|
||||
mDataSize(type->mSize)
|
||||
{
|
||||
|
@ -339,6 +350,14 @@ ConstexprInterpreter::Value ConstexprInterpreter::Value::GetPtrAt(int at, Declar
|
|||
return Value(mLocation, dp->mBaseValue, type, uint16(dp[0].mByte | ((uint32)(dp[1].mByte) << 8)));
|
||||
}
|
||||
|
||||
void ConstexprInterpreter::Value::PutVarAt(Declaration* var, int64 v, int at, Declaration* type)
|
||||
{
|
||||
ValueItem* dp = GetAddr() + at;
|
||||
dp[0].mByte = uint8(v & 0xff);
|
||||
dp[1].mByte = uint8((v >> 8) & 0xff);
|
||||
mDecValue = var;
|
||||
}
|
||||
|
||||
void ConstexprInterpreter::Value::PutIntAt(int64 v, int at, Declaration* type)
|
||||
{
|
||||
if (type->mType == DT_TYPE_FLOAT)
|
||||
|
@ -499,7 +518,10 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
|
|||
for (int i=0; i<type->mSize; i += type->mBase->mSize)
|
||||
{
|
||||
Declaration* cdec = GetConst(offset + i, type->mBase, dataSection);
|
||||
cdec->mOffset = i;
|
||||
if (type->mStride)
|
||||
cdec->mOffset = i / type->mBase->mSize;
|
||||
else
|
||||
cdec->mOffset = i;
|
||||
|
||||
if (ldec)
|
||||
ldec->mNext = cdec;
|
||||
|
@ -521,7 +543,26 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
|
|||
|
||||
Declaration* target;
|
||||
|
||||
if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
|
||||
if (vp.mBaseValue->mDecValue)
|
||||
{
|
||||
target = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
|
||||
if (vp.mBaseValue->mDecValue->mType == DT_VARIABLE_REF)
|
||||
{
|
||||
target->mBase = vp.mBaseValue->mDecValue->mBase;
|
||||
target->mOffset = vp.mBaseValue->mDecValue->mOffset;
|
||||
}
|
||||
else
|
||||
target->mBase = vp.mBaseValue->mDecValue;
|
||||
|
||||
target->mOffset += vp.mOffset;
|
||||
|
||||
dec->mValue = new Expression(mLocation, EX_CONSTANT);
|
||||
dec->mValue->mDecType = type;
|
||||
dec->mValue->mDecValue = target;
|
||||
return dec;
|
||||
}
|
||||
else if (vp.mBaseValue->mDecType->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
target = new Declaration(mLocation, DT_CONST_DATA);
|
||||
target->mSize = vp.mBaseValue->mDataSize;
|
||||
|
@ -540,6 +581,14 @@ Declaration* ConstexprInterpreter::Value::GetConst(int offset, Declaration* type
|
|||
dec->mValue->mDecType = target->mBase;
|
||||
dec->mValue->mDecValue = target;
|
||||
}
|
||||
else if (vp.mDecValue)
|
||||
{
|
||||
dec = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
dec->mBase = vp.mDecValue;
|
||||
dec->mFlags = 0;
|
||||
dec->mSize = type->mSize;
|
||||
dec->mOffset = vp.mOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
dec = new Declaration(mLocation, DT_CONST_ADDRESS);
|
||||
|
@ -602,6 +651,7 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
{
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
Declaration* cdec = exp->mLeft->mDecType->mParams;
|
||||
|
||||
int pos = 0;
|
||||
|
@ -610,6 +660,28 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
mParams[pos].PutPtr(Value(&mResult));
|
||||
pos = 2;
|
||||
|
||||
if (pex->mType == EX_LIST)
|
||||
pex = pex->mRight;
|
||||
else
|
||||
pex = nullptr;
|
||||
cdec = cdec->mNext;
|
||||
|
||||
while (pex && pex->mType == EX_LIST)
|
||||
{
|
||||
if (!AddParam(pos, pex->mLeft, cdec))
|
||||
return exp;
|
||||
|
||||
pex = pex->mRight;
|
||||
if (cdec)
|
||||
cdec = cdec->mNext;
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
if (!AddParam(pos, pex, cdec))
|
||||
return exp;
|
||||
}
|
||||
|
||||
mHeap = new ExpandingArray<Value*>();
|
||||
|
||||
Execute(exp->mLeft->mDecValue->mValue);
|
||||
|
@ -621,8 +693,93 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
return mResult.ToExpression(mDataSection);
|
||||
}
|
||||
|
||||
Expression* ConstexprInterpreter::EvalTempConstructor(Expression* exp)
|
||||
{
|
||||
Expression* cexp = exp->mLeft->mLeft;
|
||||
|
||||
mProcType = cexp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = cexp->mRight;
|
||||
Declaration* dec = cexp->mLeft->mDecType->mParams;
|
||||
|
||||
Value othis = Value(exp->mLocation, exp->mRight->mDecType);
|
||||
|
||||
mParams[0] = Value(exp->mLocation, dec->mBase);
|
||||
mParams[0].PutPtr(Value(&othis));
|
||||
|
||||
int pos = 2;
|
||||
if (pex->mType == EX_LIST)
|
||||
pex = pex->mRight;
|
||||
else
|
||||
pex = nullptr;
|
||||
dec = dec->mNext;
|
||||
|
||||
while (pex && pex->mType == EX_LIST)
|
||||
{
|
||||
if (!AddParam(pos, pex->mLeft, dec))
|
||||
return exp;
|
||||
|
||||
pex = pex->mRight;
|
||||
if (dec)
|
||||
dec = dec->mNext;
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
if (!AddParam(pos, pex, dec))
|
||||
return exp;
|
||||
}
|
||||
|
||||
mHeap = new ExpandingArray<Value*>();
|
||||
|
||||
Execute(cexp->mLeft->mDecValue->mValue);
|
||||
|
||||
if (mHeap->Size() > 0)
|
||||
mErrors->Error(exp->mLocation, EERR_UNBALANCED_HEAP_USE, "Unbalanced heap use in constexpr");
|
||||
delete mHeap;
|
||||
|
||||
return othis.ToExpression(mDataSection);
|
||||
}
|
||||
|
||||
bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
|
||||
{
|
||||
if (dec)
|
||||
pos = dec->mVarIndex;
|
||||
|
||||
if (pex->mType == EX_CONSTANT)
|
||||
{
|
||||
if (pex->mDecType->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Value* tmp = new Value(pex);
|
||||
mTemps.Push(tmp);
|
||||
mParams[pos] = Value(pex->mLocation, pex->mDecType->BuildArrayPointer());
|
||||
mParams[pos].PutPtr(Value(tmp));
|
||||
}
|
||||
else
|
||||
mParams[pos] = Value(pex);
|
||||
}
|
||||
else if (pex->mType == EX_VARIABLE && (pex->mDecValue->mFlags & DTF_CONST))
|
||||
{
|
||||
mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
|
||||
if (pex->mDecValue->mSize > 0)
|
||||
{
|
||||
if (pex->mDecValue->mValue)
|
||||
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||
{
|
||||
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
|
||||
return exp;
|
||||
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
|
@ -638,57 +795,17 @@ Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
|||
|
||||
while (pex && pex->mType == EX_LIST)
|
||||
{
|
||||
if (dec)
|
||||
pos = dec->mVarIndex;
|
||||
|
||||
if (pex->mLeft->mType == EX_CONSTANT)
|
||||
{
|
||||
if (pex->mLeft->mDecType->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Value * tmp = new Value(pex->mLeft);
|
||||
mTemps.Push(tmp);
|
||||
mParams[pos] = Value(pex->mLeft->mLocation, pex->mLeft->mDecType->BuildArrayPointer());
|
||||
mParams[pos].PutPtr(Value(tmp));
|
||||
}
|
||||
else
|
||||
mParams[pos] = Value(pex->mLeft);
|
||||
}
|
||||
else if (pex->mLeft->mType == EX_VARIABLE && (pex->mLeft->mDecValue->mFlags & DTF_CONST))
|
||||
{
|
||||
mParams[pos] = Value(pex->mLeft->mLocation, pex->mLeft->mDecValue->mBase);
|
||||
mParams[pos].PutConst(0, pex->mLeft->mDecValue->mValue->mDecValue);
|
||||
}
|
||||
else
|
||||
if (!AddParam(pos, pex->mLeft, dec))
|
||||
return exp;
|
||||
|
||||
pex = pex->mRight;
|
||||
if (dec)
|
||||
dec = dec->mNext;
|
||||
}
|
||||
if (pex)
|
||||
{
|
||||
if (dec)
|
||||
pos = dec->mVarIndex;
|
||||
|
||||
if (pex->mType == EX_CONSTANT)
|
||||
{
|
||||
if (pex->mDecType->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Value* tmp = new Value(pex);
|
||||
mTemps.Push(tmp);
|
||||
mParams[pos] = Value(pex->mLocation, pex->mDecType->BuildArrayPointer());
|
||||
mParams[pos].PutPtr(Value(tmp));
|
||||
}
|
||||
else
|
||||
mParams[pos] = Value(pex);
|
||||
}
|
||||
else if (pex->mType == EX_VARIABLE && (pex->mDecValue->mFlags & DTF_CONST))
|
||||
{
|
||||
mParams[pos] = Value(pex->mLocation, pex->mDecValue->mBase);
|
||||
if (pex->mDecValue->mSize > 0)
|
||||
mParams[pos].PutConst(0, pex->mDecValue->mValue->mDecValue);
|
||||
}
|
||||
else
|
||||
if (pex)
|
||||
{
|
||||
if (!AddParam(pos, pex, dec))
|
||||
return exp;
|
||||
}
|
||||
|
||||
|
@ -929,6 +1046,9 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
|
|||
break;
|
||||
case TK_MUL:
|
||||
return vl.GetPtr();
|
||||
case TK_SIZEOF:
|
||||
v.PutInt(vl.mDecType->mSize);
|
||||
break;
|
||||
default:
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
|
||||
}
|
||||
|
@ -1062,6 +1182,41 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
|
|||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(cos(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "tan"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(tan(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "log"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(log(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "exp"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::exp(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::sqrt(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "pow"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
|
||||
}
|
||||
|
|
|
@ -8,15 +8,19 @@ public:
|
|||
ConstexprInterpreter(const Location & loc, Errors * err, LinkerSection * dataSection);
|
||||
~ConstexprInterpreter(void);
|
||||
|
||||
Expression* EvalCall(Expression* exp);
|
||||
Expression* EvalConstructor(Expression* exp);
|
||||
Expression* EvalCall(Expression* exp);
|
||||
Expression* EvalTempConstructor(Expression* exp);
|
||||
protected:
|
||||
|
||||
bool AddParam(int& pos, Expression* pex, Declaration* dec);
|
||||
|
||||
struct Value;
|
||||
|
||||
struct ValueItem
|
||||
{
|
||||
uint8 mByte;
|
||||
Value* mBaseValue;
|
||||
uint8 mByte;
|
||||
Value * mBaseValue;
|
||||
|
||||
ValueItem(void);
|
||||
};
|
||||
|
@ -31,6 +35,7 @@ protected:
|
|||
Value(const Value& value);
|
||||
Value(Value&& value);
|
||||
Value(const Location& location, Value * value, Declaration * type, int offset);
|
||||
Value(const Location& location, Declaration * value, Declaration* type, int offset);
|
||||
Value(Value* value);
|
||||
Value(const Location& location, const uint8 * data, Declaration* type);
|
||||
Value(const Location& location, const ValueItem* data, Declaration* type);
|
||||
|
@ -44,7 +49,7 @@ protected:
|
|||
void Assign(const Value& v);
|
||||
|
||||
Location mLocation;
|
||||
Declaration * mDecType;
|
||||
Declaration * mDecType, * mDecValue;
|
||||
Value * mBaseValue;
|
||||
int mOffset;
|
||||
ValueItem * mData;
|
||||
|
@ -67,6 +72,7 @@ protected:
|
|||
void PutIntAt(int64 v, int at, Declaration* type);
|
||||
void PutFloatAt(double v, int at, Declaration* type);
|
||||
void PutPtrAt(const Value& v, int at, Declaration* type);
|
||||
void PutVarAt(Declaration* var, int64 v, int at, Declaration* type);
|
||||
|
||||
void PutConst(int offset, Declaration * dec);
|
||||
Declaration* GetConst(int offset, Declaration* type, LinkerSection* dataSection) const;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue